Project import generated by Copybara.
GitOrigin-RevId: a13be63c5ff99e1fd1c223991f26f4265e6fef3e
diff --git a/Makefile b/Makefile
old mode 100755
new mode 100644
index 7481eee..6640ff9
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,3 @@
-mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
-MEDIA_MODULE_PATH := $(dir $(mkfile_path))
-VERSION_CONTROL_CFLAGS := $(shell ${MEDIA_MODULE_PATH}/version_control.sh)
CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \
CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \
@@ -18,25 +15,21 @@
CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
- CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
- CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
- CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
- CONFIG_AMLOGIC_MEDIA_GE2D=y \
- CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
- CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+ CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_H265=m
+
EXTRA_INCLUDE := -I$(KERNEL_SRC)/$(M)/drivers/include
CONFIGS_BUILD := -Wno-parentheses-equality -Wno-pointer-bool-conversion \
-Wno-unused-const-variable -Wno-typedef-redefinition \
- -Wno-logical-not-parentheses -Wno-sometimes-uninitialized \
- -Wno-frame-larger-than=
+ -Wno-logical-not-parentheses -Wno-sometimes-uninitialized
-KBUILD_CFLAGS_MODULE += $(GKI_EXT_MODULE_PREDEFINE)
modules:
- $(MAKE) -C $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE) $(KBUILD_CFLAGS_MODULE) ${VERSION_CONTROL_CFLAGS}" $(CONFIGS)
+ $(MAKE) -C $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE)" $(CONFIGS)
all: modules
diff --git a/Media.mk b/Media.mk
index 58db63b..68b0778 100644
--- a/Media.mk
+++ b/Media.mk
@@ -18,13 +18,13 @@
CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \
CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
- CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
- CONFIG_AMLOGIC_MEDIA_GE2D=y \
- CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
- CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+ CONFIG_FRAME_WARN=4096
define copy-media-modules
$(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\
@@ -63,10 +63,11 @@
$(shell cp $(MEDIA_DRIVERS)/* $(MEDIA_MODULES) -rfa)
define media-modules
- PATH=$(KERNEL_TOOLPATHS):$$PATH \
- $(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) $(KERNEL_ARGS) $(CONFIGS) \
- "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error" modules; \
- find $(MEDIA_MODULES) -name "*.ko" | PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH xargs -i cp {} $(MODS_OUT)
+ PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+ $(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) ARCH=$(KERNEL_ARCH) \
+ CROSS_COMPILE=$(PREFIX_CROSS_COMPILE) $(CONFIGS) \
+ EXTRA_CFLAGS+=-I$(INCLUDE) modules;
+ sh $(TOP)/device/amlogic/common/copy_modules.sh $(MEDIA_MODULES) $(MODS_OUT)
endef
else
@@ -90,10 +91,18 @@
$(shell mkdir $(MODS_OUT) -p)
endif
+ifeq ($(KERNEL_A32_SUPPORT), true)
+TOOLS := /opt/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
+else
+TOOLS := /opt/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+endif
+
+
modules:
- CCACHE_NODIRECT="true" PATH=$(KERNEL_TOOLPATHS):$$PATH \
- $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) $(KERNEL_ARGS) $(CONFIGS) \
- EXTRA_CFLAGS+=-I$(INCLUDE) -j64
+ CCACHE_NODIRECT="true" PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+ $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) \
+ CROSS_COMPILE=$(TOOLS) $(CONFIGS) \
+ EXTRA_CFLAGS+=-I$(INCLUDE) -j64
copy-modules:
@echo "start copying media modules."
@@ -102,9 +111,8 @@
all: modules copy-modules
-
clean:
- PATH=$(KERNEL_TOOLPATHS):$$PATH \
- $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) $(KERNEL_ARGS) clean
+ PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+ $(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) clean
endif
diff --git a/VERSION b/VERSION
deleted file mode 100644
index 4b1504d..0000000
--- a/VERSION
+++ /dev/null
@@ -1,76 +0,0 @@
-Major_V=5
-Minor_V=3
-BaseChangeId=Ifc17e92ef9c9e211b8f01ebae1e97c5855fea084
-
-
-#history version
-#V5.2.104-g795aee00.003025 Release Notes
-#Release_ChangeId_V5_2=I34801cba60d54bfd9f459f7445d0362989c23496
-#V5.1.77-g0cdebf27.003009 Release Notes
-#Release_ChangeId_V5_1=Id7e315bbf379d166ca4b335cef13c983a8ca5078
-#Feature develop total count: 6
-# critical feature develop count: 0
-# important feature develop count: 4
-# normal feature develop count: 2
-#Feature develop detail information:
-# improve pip channel play
-# support decoder fence
-# fixed can't get hdr information correctly.
-# add multi-vdec info for new format av1 after revert
-# change ptsadjust and threshold from s64 to s32.
-# support dw 0x100
-#Fixed BUG total count: 30
-# fixed critical BUG count: 3
-# fixed important feature develop count: 15
-# fixed normal feature develop count: 12
-#Fixed BUG detail information:
-# add VIDTYPE_COMPRESS in vf for dw mode with afbc buffer
-# fix some the crash caused by null pointer
-# fixed vpp wrapper memory leak.
-# metadata lose the last byte every frame in frame mode
-# fix avs color abnormal.
-# fix gst secure v4l2 decoder not work
-# fix the playback stuck when resolution changed
-# h265 ucode send 2 interrupts cause playback stuck
-# fix av1 freeze when burn-in test.
-# fixed playback stuck after seek.
-# fix 8k display abnormal.
-# fixed irq-vdec-0 takes more cpu slice.
-# fixed AV1 seek freezing.
-# fixed failed to allocate tvp memory
-# fixed issue of reports resolution change.
-#V5.0 Release Notes
-#Release_ChangeId_V5_0=I6053e02900215d9006469c38ca375ace498b849f
-#upgrade Kernel version to 5.4
-#Android R + v4l2dec (no vpp) xts clean
-#v4ldec driver seperate from amports drivers
-#
-#V4.0.0 Release Notes
-#upgrade Kernel version to 4.19
-#v4l2 support for h264/h265/vp9
-#add fra support in decoder driver
-#
-#V3.0.0 Release Notes
-#upgrade Kernel version to 4.9
-#media_module remove from kernel
-#new firmware management
-#mjpeg/mpeg12/mpeg2 multi-instance decoder support
-#h264 4k afbc support
-#AVS2 decoder support
-#vdec double write support
-#add av1 decoder support
-#add decoder QOS info report
-#upgrade TA ucode to 0.2 version
-#
-#V2.0.0 Release Notes
-#upgrade Kernel version to 3.14
-#Introduce codec_mm memory managment
-#add afbc scatter memory support
-#add vp9 decoder support
-#add 264/265/vp9 multi-instance decoder support
-#
-#V1.0.0 Release Notes
-#based kernel to 3.10
-#add H264 4K decoder support
-#add H265 video decoder support
-#H265 decoder support afbc output
diff --git a/build_media.sh b/build_media.sh
new file mode 100755
index 0000000..63eaf1a
--- /dev/null
+++ b/build_media.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+# Builds the media driver and updates the workspace path with output files
+
+exec_name=$0
+
+cpu_num=$(grep -c processor /proc/cpuinfo)
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+CROSS_COMPILE=$DIR/../prebuilt/toolchain/aarch64/bin/aarch64-cros-linux-gnu-
+KERNEL_ARCH=arm64
+KDIR=$DIR/../kernel
+INCLUDE=$DIR/drivers/include
+MEDIA_MODULES=$DIR/drivers
+CONFIGS="CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4_MULTI=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_VC1=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H264=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_H265=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_VP9=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
+ CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+ CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
+ CONFIG_FRAME_WARN=4096"
+
+set -o errtrace
+trap 'echo Fatal error: script ${exec_name} aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
+
+function usage(){
+ echo "Usage: ${exec_name} <product> [workspace path]"
+ echo "supported products: sabrina"
+ echo "Note: if [workspace path] is not set, it still builds"
+}
+
+if (( $# < 1 ))
+then
+ usage
+ exit 2
+fi
+
+readonly product=$1
+readonly workspace_path=$2
+
+pushd $DIR
+
+
+make -C $KDIR M=$MEDIA_MODULES ARCH=$KERNEL_ARCH \
+CROSS_COMPILE=$CROSS_COMPILE $CONFIGS \
+EXTRA_CFLAGS+=-I$INCLUDE modules -j64
+
+case $product in
+ sabrina*)
+ ;;
+ *)
+ echo "unknown product: $product"
+ exit 1
+esac
+
+popd
+
+if [ ! -z $workspace_path ]; then
+ media_out_dir=${workspace_path}/device/google/${product}-kernel/lib/modules
+ mkdir -p ${media_out_dir}
+
+ for ko in aml_hardware_dmx.ko \
+ amvdec_avs2.ko \
+ amvdec_avs.ko \
+ amvdec_h264.ko \
+ amvdec_h264mvc.ko \
+ amvdec_h265.ko \
+ amvdec_mh264.ko \
+ amvdec_mjpeg.ko \
+ amvdec_mmjpeg.ko \
+ amvdec_mmpeg12.ko \
+ amvdec_mmpeg4.ko \
+ amvdec_mpeg12.ko \
+ amvdec_mpeg4.ko \
+ amvdec_real.ko \
+ amvdec_vc1.ko \
+ amvdec_vp9.ko \
+ decoder_common.ko \
+ encoder.ko \
+ firmware.ko \
+ media_clock.ko \
+ stream_input.ko \
+ vpu.ko \
+ amvdec_ports.ko \
+ video_framerate_adapter.ko \
+ media_sync.ko
+ do
+ find $MEDIA_MODULES -name $ko | xargs -i cp {} $media_out_dir
+ done
+ media_fw_out_dir=${workspace_path}/device/google/${product}-kernel/lib/firmware/video/
+ mkdir -p $media_fw_out_dir
+ cp -r firmware/* $media_fw_out_dir
+fi
diff --git a/drivers/Makefile b/drivers/Makefile
index e96ba44..3e487db 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -3,6 +3,6 @@
obj-y += frame_sink/
obj-y += stream_input/
obj-y += amvdec_ports/
+obj-y += fake_video_out/
obj-y += framerate_adapter/
obj-y += media_sync/
-obj-$(CONFIG_AMLOGIC_MEDIA_V4L_DEC) += amvdec_ports/
diff --git a/drivers/amvdec_ports/Makefile b/drivers/amvdec_ports/Makefile
index 2e7cff4..6395adf 100644
--- a/drivers/amvdec_ports/Makefile
+++ b/drivers/amvdec_ports/Makefile
@@ -3,10 +3,8 @@
amvdec_ports-objs += aml_vcodec_dec.o
amvdec_ports-objs += aml_vcodec_util.o
amvdec_ports-objs += aml_vcodec_adapt.o
-amvdec_ports-objs += aml_vcodec_vpp.o
-amvdec_ports-objs += aml_vcodec_ge2d.o
+amvdec_ports-objs += aml_vcodec_vfm.o
amvdec_ports-objs += vdec_drv_if.o
-amvdec_ports-objs += aml_task_chain.o
amvdec_ports-objs += decoder/vdec_h264_if.o
amvdec_ports-objs += decoder/vdec_hevc_if.o
amvdec_ports-objs += decoder/vdec_vp9_if.o
diff --git a/drivers/amvdec_ports/aml_task_chain.c b/drivers/amvdec_ports/aml_task_chain.c
deleted file mode 100644
index 8dfe014..0000000
--- a/drivers/amvdec_ports/aml_task_chain.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include "aml_vcodec_drv.h"
-#include "aml_task_chain.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-struct task_item_name_s {
- enum task_type_e type;
- const u8 *name;
-};
-
-static const struct task_item_name_s iname[] = {
- {TASK_TYPE_DEC, "dec"},
- {TASK_TYPE_VPP, "vpp"},
- {TASK_TYPE_V4L_SINK, "v4l-sink"},
- {TASK_TYPE_GE2D, "ge2d"},
- {TASK_TYPE_MAX, "unknown"},
-};
-
-static const u8 *type_to_name(enum task_type_e type)
-{
- const u8 *name = "unknown";
- int i, size = ARRAY_SIZE(iname);
-
- for (i = 0; i < size; i++) {
- if (type == iname[i].type)
- name = iname[i].name;
- }
-
- return name;
-}
-
-static struct task_item_s *find_task_item(struct task_chain_s *task,
- enum task_type_e type)
-{
- struct task_item_s *item = NULL;
- ulong flags;
-
- spin_lock_irqsave(&task->slock, flags);
-
- if (!list_empty(&task->list_item)) {
- struct task_item_s *p;
-
- list_for_each_entry(p, &task->list_item, node) {
- if (p->ops->type == type) {
- item = p;
- break;
- }
- }
- }
-
- if (item)
- kref_get(&item->ref);
-
- spin_unlock_irqrestore(&task->slock, flags);
-
- return item;
-}
-
-static void task_item_release(struct kref *kref);
-
-static void task_item_vframe_push(struct task_item_s *item, struct vframe_s *vframe)
-{
- int i = 0;
-
- for (i = 0 ; i < 3; i++) {
- if (item->vframe[i] == NULL) {
- item->vframe[i] = vframe;
- break;
- }
- }
-}
-
-static struct vframe_s *task_item_vframe_pop(struct task_item_s *item)
-{
- struct vframe_s *vframe = NULL;
- int i = 0;
-
- for (i = 0 ; i < 3; i++) {
- if (item->vframe[i] != NULL) {
- vframe = item->vframe[i];
- item->vframe[i] = NULL;
- break;
- }
- }
-
- return vframe;
-}
-
-static struct task_item_s *task_item_get(struct task_chain_s *task,
- enum task_type_e type)
-{
- struct task_item_s *item = NULL;
-
- item = find_task_item(task, type);
- if (!item) {
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
- "TSK(%px):%d get item:%d fail.\n", task, task->id, type);
- }
-
- return item;
-}
-
-static int task_item_put(struct task_item_s *item)
-{
- return kref_put(&item->ref, task_item_release);
-}
-
-static void task_buffer_submit(struct task_chain_s *task,
- enum task_type_e type)
-{
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
- struct task_item_s *item = NULL;
- struct task_item_s *item2 = NULL;
- struct vframe_s *vf = NULL;
-
- item = task_item_get(task, type);
- if (item) {
- item->ops->get_vframe(item->caller, &vf);
- fb->vframe = (void *)vf;
- task_item_vframe_push(item, vf);
- item->is_active = false;
-
- item2 = task_item_get(task, task->map[0][type]);
- if (item2) {
- item2->is_active = true;
- item2->ops->fill_buffer(task->ctx, fb);
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d, vf:%px, phy:%lx, submit %d => %d.\n",
- task, task->id, vf, fb->m.mem[0].addr,
- type, task->map[0][type]);
-
- task->direction = TASK_DIR_SUBMIT;
- task_item_put(item2);
- }
- task_item_put(item);
- }
-}
-
-static void task_buffer_recycle(struct task_chain_s *task,
- enum task_type_e type)
-{
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
- struct task_item_s *item = NULL;
- struct task_item_s *item2 = NULL;
-
- item = task_item_get(task, type);
- if (item) {
- item->is_active = false;
-
- item2 = task_item_get(task, task->map[1][type]);
- if (item2) {
- struct vframe_s *vf = NULL;
-
- item2->is_active = true;
-
- vf = task_item_vframe_pop(item2);
- item2->ops->put_vframe(item2->caller, vf);
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d, vf:%px, phy:%lx, recycle %d => %d.\n",
- task, task->id, vf, fb->m.mem[0].addr,
- type, task->map[1][type]);
-
- task->direction = TASK_DIR_RECYCLE;
- task_item_put(item2);
- }
- task_item_put(item);
- }
-}
-
-void task_chain_show(struct task_chain_s *task)
-{
- struct task_item_s *item = NULL;
- char buf[128] = {0};
- char *pbuf = buf;
- ulong flags;
-
- if (!task || !task->ctx)
- return;
-
- spin_lock_irqsave(&task->slock, flags);
-
- if (!list_empty(&task->list_item)) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)task->obj;
-
- list_for_each_entry(item, &task->list_item, node) {
- pbuf += sprintf(pbuf, "%s(%d)",
- item->name, item->is_active);
- if (item->node.next != &task->list_item) {
- if (task->direction == TASK_DIR_SUBMIT)
- pbuf += sprintf(pbuf, " ==> ");
- else
- pbuf += sprintf(pbuf, " <== ");
- }
- }
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_PRINFO,
- "vb:%2d, phy:%lx %s\n",
- task->id, fb->m.mem[0].addr, buf);
- }
-
- spin_unlock_irqrestore(&task->slock, flags);
-}
-EXPORT_SYMBOL(task_chain_show);
-
-static void task_chain_destroy(struct kref *kref)
-{
- struct task_chain_s *task;
-
- task = container_of(kref, struct task_chain_s, ref);
-
- task->cur_type = TASK_TYPE_MAX;
- memset(task->map, 0, sizeof(task->map));
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d task chain destroyed.\n", task, task->id);
-
- kfree(task);
-}
-
-static void task_item_release(struct kref *kref)
-{
- struct task_item_s *item;
-
- item = container_of(kref, struct task_item_s, ref);
- list_del(&item->node);
-
- v4l_dbg(item->task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d task item:(%px,%d) released.\n",
- item->task, item->task->id, item, item->ops->type);
-
- kref_put(&item->task->ref, task_chain_destroy);
-
- kfree(item);
-}
-
-void task_chain_clean(struct task_chain_s *task)
-{
- struct task_item_s *item, *tmp;
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d task chain clean.\n", task, task->id);
-
- if (!list_empty(&task->list_item)) {
- list_for_each_entry_safe(item, tmp, &task->list_item, node)
- kref_put(&item->ref, task_item_release);
- }
-}
-EXPORT_SYMBOL(task_chain_clean);
-
-void task_chain_release(struct task_chain_s *task)
-{
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d task chain release.\n", task, task->id);
-
- kref_put(&task->ref, task_chain_destroy);
-}
-EXPORT_SYMBOL(task_chain_release);
-
-void task_order_attach(struct task_chain_s *task,
- struct task_ops_s *ops,
- void *caller)
-{
- struct task_item_s *item;
-
- item = kzalloc(sizeof(struct task_item_s), GFP_ATOMIC);
- if (!item) {
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
- "TSK(%px):%d alloc item fail.\n", task, task->id);
- return;
- }
-
- item->task = task;
- item->ops = ops;
- item->caller = caller;
- item->name = type_to_name(ops->type);
- kref_init(&item->ref);
-
- task->map[0][ops->type] = task->cur_type;
- task->map[1][task->cur_type] = ops->type;
- task->cur_type = ops->type;
- kref_get(&task->ref);
-
- list_add(&item->node, &task->list_item);
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d attach item:(%px,%d).\n",
- task, task->id, item, ops->type);
-}
-EXPORT_SYMBOL(task_order_attach);
-
-void task_chain_update_object(struct task_chain_s *task, void *obj)
-{
- /*
- * Note: have to invoke this funtion
- * if the task object has been changed.
- */
- task->obj = obj;
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d update task obj:%px.\n",
- task, task->id, obj);
-}
-EXPORT_SYMBOL(task_chain_update_object);
-
-int task_chain_init(struct task_chain_s **task_out,
- void *v4l_ctx,
- void *obj,
- int vb_idx)
-{
- struct task_chain_s *task;
-
- task = kzalloc(sizeof(struct task_chain_s), GFP_ATOMIC);
- if (!task) {
- v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
- "TSK(%px):%d alloc task fail.\n", task, task->id);
- return -ENOMEM;
- }
-
- task->id = vb_idx;
- task->obj = obj;
- task->ctx = v4l_ctx;
- kref_init(&task->ref);
- spin_lock_init(&task->slock);
- INIT_LIST_HEAD(&task->list_item);
-
- task->attach = task_order_attach;
- task->submit = task_buffer_submit;
- task->recycle = task_buffer_recycle;
-
- *task_out = task;
-
- v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
- "TSK(%px):%d task chain creat success.\n", task, task->id);
- return 0;
-}
-EXPORT_SYMBOL(task_chain_init);
-
diff --git a/drivers/amvdec_ports/aml_task_chain.h b/drivers/amvdec_ports/aml_task_chain.h
deleted file mode 100644
index fdbe2fb..0000000
--- a/drivers/amvdec_ports/aml_task_chain.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#ifndef AML_TASK_CHAIN_H
-#define AML_TASK_CHAIN_H
-
-#include <linux/amlogic/media/vfm/vframe.h>
-
-enum task_type_e {
- TASK_TYPE_DEC,
- TASK_TYPE_VPP,
- TASK_TYPE_V4L_SINK,
- TASK_TYPE_GE2D,
- TASK_TYPE_MAX
-};
-
-enum task_dir_e {
- TASK_DIR_SUBMIT,
- TASK_DIR_RECYCLE,
- TASK_DIR_MAX
-};
-
-struct task_chain_s;
-
-/*
- * struct task_ops_s - interface of the task item.
- * @type : type of task ops involves dec, vpp, v4l sink etc.
- * @get_vframe : get the video frame from caller's fifo.
- * @put_vframe : put the video frame to caller's fifo.
- * @fill_buffer : submit the buffer into next process module.
- */
-struct task_ops_s {
- enum task_type_e type;
- void (*get_vframe) (void *caller, struct vframe_s **vf);
- void (*put_vframe) (void *caller, struct vframe_s *vf);
- void (*fill_buffer) (void *v4l_ctx, void *fb_ctx);
-};
-
-/*
- * struct task_item_s - items of the task chain.
- * @node : list node of the specific task item.
- * @ref : reference count of item be used by others.
- * @name : name of task item, map with task type.
- * @is_active : indicate this item whether is active.
- * @vframe[3] : store the vframes that get from caller.
- * @task : the context of the task chain.
- * @caller : it's the handle, meght it's dec, vpp or v4l-sink etc.
- * @ops : sets of interface which attach from task item.
- */
-struct task_item_s {
- struct list_head node;
- struct kref ref;
- const u8 *name;
- bool is_active;
- void *vframe[3];
- struct task_chain_s *task;
- void *caller;
- struct task_ops_s *ops;
-};
-
-/*
- * struct task_chain_s - the manager struct of the task chain.
- * @list_item : all task items be attached are store in the list.
- * @node : will register to the task chain pool.
- * @ref : reference count of task chain be used by others.
- * @slock : used for list item write and read safely.
- * @id : it's vb index to be a mark used for task chain.
- * @ctx : the context of the v4l driver.
- * @obj : the object managed by task chain.
- * @direction : direction incluse 2 flows submit & recycle.
- * @cur_type : the latest item type before a new item be attached.
- * @map : the map store the pipeline information.
- * @attach : attach a new item to task chain.
- * @submit : submit the finish item to next item module.
- * @recycle : if item's date was consumed will be recycled to item.
- */
-struct task_chain_s {
- struct list_head list_item;
- struct list_head node;
- struct kref ref;
- spinlock_t slock;
- int id;
- void *ctx;
- void *obj;
- enum task_dir_e direction;
- enum task_type_e cur_type;
- u8 map[2][8];
-
- void (*attach) (struct task_chain_s *, struct task_ops_s *, void *);
- void (*submit) (struct task_chain_s *, enum task_type_e);
- void (*recycle) (struct task_chain_s *, enum task_type_e);
-};
-
-
-int task_chain_init(struct task_chain_s **task_out,
- void *v4l_ctx,
- void *obj,
- int vb_idx);
-void task_order_attach(struct task_chain_s *task,
- struct task_ops_s *ops,
- void *caller);
-void task_chain_clean(struct task_chain_s *task);
-void task_chain_release(struct task_chain_s *task);
-void task_chain_show(struct task_chain_s *task);
-void task_chain_update_object(struct task_chain_s *task, void *obj);
-
-#endif //AML_TASK_CHAIN_H
-
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index 7e08371..95ee48a 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -56,11 +56,17 @@
//#define DATA_DEBUG
extern int dump_output_frame;
-extern u32 dump_output_start_position;
extern void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle);
+static int def_4k_vstreambuf_sizeM =
+ (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
+static int def_vstreambuf_sizeM =
+ (DEFAULT_VIDEO_BUFFER_SIZE >> 20);
static int slow_input = 0;
+static int use_bufferlevelx10000 = 10000;
+static unsigned int amstream_buf_num = BUF_MAX_NUM;
+
static struct stream_buf_s bufs[BUF_MAX_NUM] = {
{
.reg_base = VLD_MEM_VIFIFO_REG_BASE,
@@ -167,6 +173,60 @@
return 0;
}
+static int reset_canuse_buferlevel(int levelx10000)
+{
+ int i;
+ struct stream_buf_s *p = NULL;
+
+ if (levelx10000 >= 0 && levelx10000 <= 10000)
+ use_bufferlevelx10000 = levelx10000;
+ else
+ use_bufferlevelx10000 = 10000;
+ for (i = 0; i < amstream_buf_num; i++) {
+ p = &bufs[i];
+ p->canusebuf_size = ((p->buf_size / 1024) *
+ use_bufferlevelx10000 / 10000) * 1024;
+ p->canusebuf_size += 1023;
+ p->canusebuf_size &= ~1023;
+
+ if (p->canusebuf_size > p->buf_size)
+ p->canusebuf_size = p->buf_size;
+ }
+
+ return 0;
+}
+
+static void change_vbufsize(struct vdec_s *vdec,
+ struct stream_buf_s *pvbuf)
+{
+ if (pvbuf->buf_start != 0) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "streambuf is alloced before\n");
+ return;
+ }
+
+ if (vdec->port->is_4k) {
+ pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M;
+
+ if (vdec->port_flag & PORT_FLAG_DRM)
+ pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP;
+
+ if ((pvbuf->buf_size > 30 * SZ_1M)
+ && (codec_mm_get_total_size() < 220 * SZ_1M)) {
+ /*if less than 250M, used 20M for 4K & 265*/
+ pvbuf->buf_size = pvbuf->buf_size >> 1;
+ }
+ } else if (pvbuf->buf_size > def_vstreambuf_sizeM * SZ_1M) {
+ if (vdec->port_flag & PORT_FLAG_DRM)
+ pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
+ } else {
+ pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M;
+ if (vdec->port_flag & PORT_FLAG_DRM)
+ pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
+ }
+
+ reset_canuse_buferlevel(10000);
+}
+
static void user_buffer_init(void)
{
struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA];
@@ -177,14 +237,41 @@
pubuf->buf_rp = 0;
}
-static void video_component_release(struct stream_port_s *port)
+static void video_component_release(struct stream_port_s *port,
+struct stream_buf_s *pbuf, int release_num)
{
struct aml_vdec_adapt *ada_ctx
= container_of(port, struct aml_vdec_adapt, port);
struct vdec_s *vdec = ada_ctx->vdec;
- vdec_release(vdec);
+ struct vdec_s *slave = NULL;
+ switch (release_num) {
+ default:
+ case 0:
+ case 4: {
+ if ((port->type & PORT_TYPE_FRAME) == 0)
+ esparser_release(pbuf);
+ }
+
+ case 3: {
+ if (vdec->slave)
+ slave = vdec->slave;
+ vdec_release(vdec);
+
+ if (slave)
+ vdec_release(slave);
+ vdec = NULL;
+ }
+
+ case 2: {
+ if ((port->type & PORT_TYPE_FRAME) == 0)
+ stbuf_release(pbuf);
+ }
+
+ case 1:
+ ;
+ }
}
static int video_component_init(struct stream_port_s *port,
@@ -204,21 +291,69 @@
|| port->vformat == VFORMAT_H264_4K2K) {
port->is_4k = true;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
- && (port->vformat == VFORMAT_H264))
+ && port->vformat == VFORMAT_H264)
vdec_poweron(VDEC_HEVC);
} else
port->is_4k = false;
- if (port->type & PORT_TYPE_FRAME ||
- (port->type & PORT_TYPE_ES)) {
- ret = vdec_init(vdec, port->is_4k, true);
+ if (port->type & PORT_TYPE_FRAME) {
+ ret = vdec_init(vdec, port->is_4k);
if (ret < 0) {
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n");
- video_component_release(port);
+ video_component_release(port, pbuf, 2);
+ return ret;
+ }
+
+ return 0;
+ }
+
+ change_vbufsize(vdec, pbuf);
+
+ if (has_hevc_vdec()) {
+ if (port->type & PORT_TYPE_MPTS) {
+ if (pbuf->type == BUF_TYPE_HEVC)
+ vdec_poweroff(VDEC_1);
+ else
+ vdec_poweroff(VDEC_HEVC);
+ }
+ }
+
+ ret = stbuf_init(pbuf, vdec);
+ if (ret < 0) {
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n");
+ return ret;
+ }
+
+ /* todo: set path based on port flag */
+ ret = vdec_init(vdec, port->is_4k);
+ if (ret < 0) {
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
+ video_component_release(port, pbuf, 2);
+ return ret;
+ }
+
+ if (vdec_dual(vdec)) {
+ ret = vdec_init(vdec->slave, port->is_4k);
+ if (ret < 0) {
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
+ video_component_release(port, pbuf, 2);
return ret;
}
}
+ if (port->type & PORT_TYPE_ES) {
+ ret = esparser_init(pbuf, vdec);
+ if (ret < 0) {
+ video_component_release(port, pbuf, 3);
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n");
+ return ret;
+ }
+ }
+
+ pbuf->flag |= BUF_FLAG_IN_USE;
+
+ vdec_connect(vdec);
+
return 0;
}
@@ -227,8 +362,8 @@
struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
if (has_hevc_vdec()) {
- if (port->vformat == VFORMAT_HEVC ||
- port->vformat == VFORMAT_VP9)
+ if (port->vformat == VFORMAT_HEVC
+ || port->vformat == VFORMAT_VP9)
pvbuf = &bufs[BUF_TYPE_HEVC];
}
@@ -241,7 +376,7 @@
psparser_release();
if (port->type & PORT_TYPE_VIDEO)
- video_component_release(port);
+ video_component_release(port, pvbuf, 0);
port->pcr_inited = 0;
port->flag = 0;
@@ -256,6 +391,7 @@
vdec->port = &ada_ctx->port;
vdec->format = ada_ctx->video_type;
vdec->sys_info_store = ada_ctx->dec_prop;
+ vdec->vf_receiver_name = ada_ctx->recv_name;
/* binding v4l2 ctx to vdec. */
vdec->private = ada_ctx->ctx;
@@ -289,6 +425,7 @@
vdec->frame_base_video_path = aml_set_vfm_path;
vdec->port->flag = vdec->port_flag;
+ ada_ctx->vfm_path = vdec->frame_base_video_path;
vdec->config_len = ada_ctx->config.length >
PAGE_SIZE ? PAGE_SIZE : ada_ctx->config.length;
@@ -308,7 +445,6 @@
if (IS_ERR_OR_NULL(vdec))
return -1;
- vdec->disable_vfm = true;
set_vdec_properity(vdec, ada_ctx);
/* init hw and gate*/
@@ -325,8 +461,8 @@
&& (vdec->port_flag & PORT_FLAG_VFORMAT)) {
vdec->port->is_4k = false;
if (has_hevc_vdec()) {
- if (vdec->port->vformat == VFORMAT_HEVC ||
- vdec->port->vformat == VFORMAT_VP9)
+ if (vdec->port->vformat == VFORMAT_HEVC
+ || vdec->port->vformat == VFORMAT_VP9)
pvbuf = &bufs[BUF_TYPE_HEVC];
}
@@ -390,11 +526,9 @@
if (!IS_ERR(fp)) {
kernel_write(fp, data, size, 0);
filp_close(fp, NULL);
- } else {
- pr_info("Dump ES fail, should check RW permission, size:%x\n", size);
}
-}
+}
int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
const char *buf, unsigned int count)
{
@@ -445,11 +579,11 @@
{
struct vdec_s *vdec = ada_ctx->vdec;
- return (vdec->input.have_frame_num > 60) ? true : false;
+ return (vdec->input.have_frame_num > 600) ? true : false;
}
int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
- const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr)
+ const char *buf, unsigned int count, u64 timestamp)
{
int ret = -1;
struct vdec_s *vdec = ada_ctx->vdec;
@@ -457,9 +591,6 @@
/* set timestamp */
vdec_set_timestamp(vdec, timestamp);
- /* set metadata */
- vdec_set_metadata(vdec, meta_ptr);
-
ret = vdec_write_vframe(vdec, buf, count);
if (slow_input) {
@@ -468,12 +599,9 @@
msleep(30);
}
- if (dump_output_frame > 0 &&
- (!dump_output_start_position ||
- (dump_output_start_position == crc32_le(0, buf, count)))) {
+ if (dump_output_frame > 0) {
dump("/data/es.data", buf, count);
dump_output_frame--;
- dump_output_start_position = 0;
}
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
@@ -530,14 +658,23 @@
int ret = 0;
if (vdec) {
- if (ada_ctx->ctx->v4l_resolution_change)
- *mode = V4L_RESET_MODE_LIGHT;
- else
+ if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed)
vdec_set_eos(vdec, false);
-
+ if (*mode == V4L_RESET_MODE_NORMAL &&
+ vdec->input.have_frame_num == 0) {
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "no input reset mode: %d\n", *mode);
+ *mode = V4L_RESET_MODE_LIGHT;
+ }
+ if (ada_ctx->ctx->param_sets_from_ucode &&
+ *mode == V4L_RESET_MODE_NORMAL &&
+ ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) {
+ v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "resolution_changed reset mode: %d\n", *mode);
+ *mode = V4L_RESET_MODE_LIGHT;
+ }
v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
- "reset mode: %d, es frames buffering: %d\n",
- *mode, vdec_frame_number(ada_ctx));
+ "reset mode: %d\n", *mode);
ret = vdec_v4l2_reset(vdec, *mode);
*mode = V4L_RESET_MODE_NORMAL;
@@ -572,11 +709,6 @@
return -1;
}
-int vdec_get_instance_num(void)
-{
- return vdec_get_core_nr();
-}
-
void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
{
struct vdec_s *vdec = ada_ctx->vdec;
@@ -584,8 +716,3 @@
vdec->config_len = len > PAGE_SIZE ? PAGE_SIZE : len;
memcpy(vdec->config, data, vdec->config_len);
}
-
-void vdec_set_duration(s32 duration)
-{
- vdec_frame_rate_uevent(duration);
-}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h
index c8641ce..b86cbff 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.h
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -27,12 +27,13 @@
#include "aml_vcodec_drv.h"
struct aml_vdec_adapt {
- int format;
+ enum vformat_e format;
void *vsi;
int32_t failure;
uint32_t inst_addr;
unsigned int signaled;
struct aml_vcodec_ctx *ctx;
+ struct platform_device *dev;
wait_queue_head_t wq;
struct file *filp;
struct vdec_s *vdec;
@@ -40,7 +41,8 @@
struct dec_sysinfo dec_prop;
struct v4l2_config_parm config;
int video_type;
- char *frm_name;
+ char *recv_name;
+ int vfm_path;
};
int video_decoder_init(struct aml_vdec_adapt *ada_ctx);
@@ -51,7 +53,7 @@
const char *buf, unsigned int count);
int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
- const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr);
+ const char *buf, unsigned int count, u64 timestamp);
void vdec_vframe_input_free(void *priv, u32 handle);
@@ -71,9 +73,5 @@
int vdec_frame_number(struct aml_vdec_adapt *ada_ctx);
-int vdec_get_instance_num(void);
-
-void vdec_set_duration(s32 duration);
-
#endif /* VDEC_ADAPT_H */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 2bbfb6e..afebb7a 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -20,41 +20,27 @@
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
-#include <media/videobuf2-dma-sg.h>
-
-#include <linux/delay.h>
-#include <linux/atomic.h>
-#include <linux/crc32.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/amlogic/meson_uvm_core.h>
-#include <linux/scatterlist.h>
-#include <linux/sched/clock.h>
-#include <linux/highmem.h>
-#include <uapi/linux/sched/types.h>
#include "aml_vcodec_drv.h"
#include "aml_vcodec_dec.h"
+//#include "aml_vcodec_intr.h"
#include "aml_vcodec_util.h"
#include "vdec_drv_if.h"
+#include <linux/delay.h>
+#include <linux/atomic.h>
+#include <linux/crc32.h>
#include "aml_vcodec_adapt.h"
-#include "aml_vcodec_vpp.h"
-#include "aml_vcodec_ge2d.h"
+#include <linux/spinlock.h>
+#include "aml_vcodec_vfm.h"
#include "../frame_provider/decoder/utils/decoder_bmmu_box.h"
#include "../frame_provider/decoder/utils/decoder_mmu_box.h"
-#include "../common/chips/decoder_cpu_ver_info.h"
-#include "utils/common.h"
-#include "../frame_provider/decoder/utils/vdec_sync.h"
-
#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
#include <trace/events/meson_atrace.h>
-
-#define OUT_FMT_IDX (0) //default h264
-#define CAP_FMT_IDX (9) //capture nv21
-#define CAP_FMT_I420_IDX (12) //use for mjpeg
+#define OUT_FMT_IDX 0 //default h264
+#define CAP_FMT_IDX 8 //capture nv21
#define AML_VDEC_MIN_W 64U
#define AML_VDEC_MIN_H 64U
@@ -63,12 +49,8 @@
#define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100)
#define AML_V4L2_SET_DRMMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
-#define AML_V4L2_GET_INPUT_BUFFER_NUM (V4L2_CID_USER_AMLOGIC_BASE + 1)
-#define AML_V4L2_SET_DURATION (V4L2_CID_USER_AMLOGIC_BASE + 2)
-#define AML_V4L2_GET_FILMGRAIN_INFO (V4L2_CID_USER_AMLOGIC_BASE + 3)
#define WORK_ITEMS_MAX (32)
-#define MAX_DI_INSTANCE (2)
//#define USEC_PER_SEC 1000000
@@ -80,89 +62,70 @@
static struct aml_video_fmt aml_video_formats[] = {
{
- .name = "H.264",
.fourcc = V4L2_PIX_FMT_H264,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "H.265",
.fourcc = V4L2_PIX_FMT_HEVC,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "VP9",
.fourcc = V4L2_PIX_FMT_VP9,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "MPEG1",
.fourcc = V4L2_PIX_FMT_MPEG1,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "MPEG2",
.fourcc = V4L2_PIX_FMT_MPEG2,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "MPEG4",
.fourcc = V4L2_PIX_FMT_MPEG4,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "MJPEG",
.fourcc = V4L2_PIX_FMT_MJPEG,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "AV1",
.fourcc = V4L2_PIX_FMT_AV1,
.type = AML_FMT_DEC,
.num_planes = 1,
},
{
- .name = "NV21",
.fourcc = V4L2_PIX_FMT_NV21,
.type = AML_FMT_FRAME,
.num_planes = 1,
},
{
- .name = "NV21M",
.fourcc = V4L2_PIX_FMT_NV21M,
.type = AML_FMT_FRAME,
.num_planes = 2,
},
{
- .name = "NV12",
.fourcc = V4L2_PIX_FMT_NV12,
.type = AML_FMT_FRAME,
.num_planes = 1,
},
{
- .name = "NV12M",
.fourcc = V4L2_PIX_FMT_NV12M,
.type = AML_FMT_FRAME,
.num_planes = 2,
},
{
- .name = "YUV420",
.fourcc = V4L2_PIX_FMT_YUV420,
.type = AML_FMT_FRAME,
.num_planes = 1,
},
- {
- .name = "YUV420M",
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .type = AML_FMT_FRAME,
- .num_planes = 2,
- },
};
static const struct aml_codec_framesizes aml_vdec_framesizes[] = {
@@ -202,11 +165,6 @@
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
},
{
- .fourcc = V4L2_PIX_FMT_AV1,
- .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
- AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
- },
- {
.fourcc = V4L2_PIX_FMT_NV21,
.stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
@@ -226,44 +184,16 @@
.stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
},
- {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
- AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
- },
- {
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .stepwise = { AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
- AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
- },
};
#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes)
#define NUM_FORMATS ARRAY_SIZE(aml_video_formats)
extern bool multiplanar;
-extern int dump_capture_frame;
-extern int bypass_vpp;
-extern int bypass_ge2d;
-extern bool support_format_I420;
-extern bool support_mjpeg;
-extern int bypass_progressive;
-extern int force_enable_nr;
-extern int force_enable_di_local_buffer;
-extern int max_di_instance;
-extern int bypass_nr_flag;
+extern bool dump_capture_frame;
extern int dmabuf_fd_install_data(int fd, void* data, u32 size);
extern bool is_v4l2_buf_file(struct file *file);
-extern int get_double_write_ratio(int dw_mode);
-static void box_release(struct kref *kref);
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb);
-static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type);
-static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
- struct v4l2_pix_format *pix,
- struct aml_q_data *q_data,
- u32 type);
static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
{
@@ -279,23 +209,6 @@
spin_unlock_irqrestore(&ctx->slock, flags);
}
-static ulong dmabuf_contiguous_size(struct sg_table *sgt)
-{
- struct scatterlist *s;
- dma_addr_t expected = sg_dma_address(sgt->sgl);
- ulong size = 0;
- u32 i;
-
- for_each_sg(sgt->sgl, s, sgt->nents, i) {
- if (sg_dma_address(s) != expected)
- break;
- expected = sg_dma_address(s) + sg_dma_len(s);
- size += sg_dma_len(s);
- }
-
- return size;
-}
-
static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f)
{
struct aml_video_fmt *fmt;
@@ -323,6 +236,16 @@
{
struct v4l2_event event = {0};
+ if (ctx->receive_cmd_stop &&
+ changes != V4L2_EVENT_SRC_CH_RESOLUTION &&
+ changes != V4L2_EVENT_SEND_EOS) {
+ ctx->state = AML_STATE_ABORT;
+ ATRACE_COUNTER("v4l2_state", ctx->state);
+ changes = V4L2_EVENT_REQUEST_EXIT;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+ "vcodec state (AML_STATE_ABORT)\n");
+ }
+
switch (changes) {
case V4L2_EVENT_SRC_CH_RESOLUTION:
case V4L2_EVENT_SRC_CH_HDRINFO:
@@ -354,176 +277,11 @@
aml_decoder_flush(ctx->ada_ctx);
}
-/* Conditions:
- * Always connect VPP for mpeg2 and h264 when the stream size is under 2K.
- * Always connect VPP for hevc/av1/vp9 when color space is not SDR and
- * stream size is under 2K.
- * For DV, need application to notify V4L2 driver to enforce the color space
- * conversion. Plan to do it through a system node.
- * Do not connect VPP in other cases.
- */
-static bool vpp_needed(struct aml_vcodec_ctx *ctx, u32* mode)
+static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
{
- int width = ctx->picinfo.coded_width;
- int height = ctx->picinfo.coded_height;
- int size = 1920 * 1088;
+ unsigned int dpbsize = 0;
+ int ret;
- if (bypass_vpp)
- return false;
-
- if (!ctx->vpp_cfg.enable_nr &&
- (ctx->picinfo.field == V4L2_FIELD_NONE)) {
- return false;
- }
-
- if (!ctx->vpp_cfg.enable_nr &&
- (ctx->output_pix_fmt == V4L2_PIX_FMT_HEVC)) {
- if (is_over_size(width, height, size)) {
- return false;
- }
- }
-
- if ((ctx->output_pix_fmt == V4L2_PIX_FMT_H264) &&
- (ctx->picinfo.field != V4L2_FIELD_NONE)) {
- if (is_over_size(width, height, size)) {
- return false;
- }
- }
-
- if (ctx->vpp_cfg.enable_nr) {
- if (ctx->vpp_cfg.enable_local_buf)
- *mode = VPP_MODE_NOISE_REDUC_LOCAL;
- else
- *mode = VPP_MODE_NOISE_REDUC;
- } else {
- if (ctx->vpp_cfg.enable_local_buf)
- *mode = VPP_MODE_DI_LOCAL;
- else
- *mode = VPP_MODE_DI;
- }
-
-#if 0//enable later
- if (ctx->colorspace != V4L2_COLORSPACE_DEFAULT &&
- !is_over_size(width, height, size)) {
- if (ctx->vpp_cfg.enable_local_buf)
- *mode = VPP_MODE_COLOR_CONV_LOCAL;
- else
- *mode = VPP_MODE_COLOR_CONV;
- }
-#endif
-
- return true;
-}
-
-static bool ge2d_needed(struct aml_vcodec_ctx *ctx, u32* mode)
-{
- bool enable_fence = (ctx->config.parm.dec.cfg.low_latency_mode & 2) ? 1 : 0;
-
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) && enable_fence) {
- return false;
- }
-
- if (bypass_ge2d)
- return false;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
- return false;
- }
- } else if (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) {
- return false;
- }
-
- if (ctx->picinfo.field != V4L2_FIELD_NONE) {
- return false;
- }
-
- if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- *mode = GE2D_MODE_CONVERT_NV12;
- else if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
- (ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
- *mode = GE2D_MODE_CONVERT_NV21;
- else
- *mode = GE2D_MODE_CONVERT_NV21;
-
- *mode |= GE2D_MODE_CONVERT_LE;
-
- return true;
-}
-
-static u32 v4l_buf_size_decision(struct aml_vcodec_ctx *ctx)
-{
- u32 mode, total_size;
- struct vdec_pic_info *picinfo = &ctx->picinfo;
- struct aml_vpp_cfg_infos *vpp = &ctx->vpp_cfg;
- struct aml_ge2d_cfg_infos *ge2d = &ctx->ge2d_cfg;
-
- if (vpp_needed(ctx, &mode)) {
- vpp->mode = mode;
- vpp->fmt = ctx->cap_pix_fmt;
- vpp->is_drm = ctx->is_drm_mode;
- vpp->buf_size = aml_v4l2_vpp_get_buf_num(vpp->mode)
- + picinfo->vpp_margin;
-
- if (picinfo->field == V4L2_FIELD_NONE) {
- vpp->is_prog = true;
- vpp->buf_size = 0;
- } else {
- vpp->is_prog = false;
- /* for between with dec & vpp. */
- picinfo->dpb_margin = 2;
- }
-
- if (vpp->is_prog &&
- !vpp->enable_local_buf &&
- bypass_progressive) {
- vpp->is_bypass_p = true;
- }
- ctx->vpp_is_need = true;
- } else {
- vpp->buf_size = 0;
- ctx->vpp_is_need = false;
- }
-
- if (ge2d_needed(ctx, &mode)) {
- ge2d->mode = mode;
- ge2d->buf_size = 4 + picinfo->dpb_margin;
- ctx->ge2d_is_need = true;
- picinfo->dpb_margin = 2;
- } else {
- ge2d->buf_size = 0;
- ctx->ge2d_is_need = false;
- }
-
- ctx->dpb_size = picinfo->dpb_frames + picinfo->dpb_margin;
- ctx->vpp_size = vpp->buf_size;
- ctx->ge2d_size = ge2d->buf_size;
-
- total_size = ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size;
-
- if (total_size > V4L_CAP_BUFF_MAX) {
- if (ctx->ge2d_size) {
- ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->ge2d_size - ctx->vpp_size;
- } else if (ctx->vpp_size) {
- ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->vpp_size;
- } else {
- ctx->dpb_size = V4L_CAP_BUFF_MAX;
- }
- picinfo->dpb_margin = ctx->dpb_size - picinfo->dpb_frames;
- total_size = V4L_CAP_BUFF_MAX;
- }
- vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, picinfo);
-
- return total_size;
-}
-
-void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
-{
if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Cannot get param : GET_PARAM_PICTURE_INFO ERR\n");
@@ -551,277 +309,287 @@
ctx->last_decoded_picinfo.coded_width,
ctx->last_decoded_picinfo.coded_width);
+ ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
+ if (dpbsize == 0)
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "Incorrect dpb size, ret=%d\n", ret);
+
+ /* update picture information */
+ ctx->dpb_size = dpbsize;
ctx->picinfo = ctx->last_decoded_picinfo;
+}
- if (ctx->vpp_is_need)
- ctx->vpp_cfg.is_vpp_reset = true;
+static bool aml_check_inst_quit(struct aml_vcodec_dev *dev,
+ struct aml_vcodec_ctx * inst, u32 id)
+{
+ struct aml_vcodec_ctx *ctx = NULL;
+ bool ret = true;
- v4l_buf_size_decision(ctx);
+ if (dev == NULL)
+ return false;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Update picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
- ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
- ctx->picinfo.dpb_margin,
- CTX_BUF_TOTAL(ctx));
+ mutex_lock(&dev->dev_mutex);
+
+ if (list_empty(&dev->ctx_list)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "v4l inst list is empty.\n");
+ ret = true;
+ goto out;
+ }
+
+ list_for_each_entry(ctx, &dev->ctx_list, list) {
+ if ((ctx == inst) && (ctx->id == id)) {
+ ret = ctx->receive_cmd_stop ? true : false;
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&dev->dev_mutex);
+
+ return ret;
}
void vdec_frame_buffer_release(void *data)
{
struct file_private_data *priv_data =
(struct file_private_data *) data;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)
- priv_data->v4l_dec_ctx;
- struct aml_video_dec_buf *vb = (struct aml_video_dec_buf *)
+ struct aml_vcodec_dev *dev = (struct aml_vcodec_dev *)
priv_data->vb_handle;
- struct uvm_hook_mod_info *uvm = NULL;
+ struct aml_vcodec_ctx *inst = (struct aml_vcodec_ctx *)
+ priv_data->v4l_dec_ctx;
+ u32 id = priv_data->v4l_inst_id;
- if (ctx && ctx->uvm_proxy) {
- uvm = &ctx->uvm_proxy[vb->internal_index];
- uvm->free(uvm->arg);
+ if (aml_check_inst_quit(dev, inst, id)) {
+ struct vframe_s *vf = &priv_data->vf;
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "[%d]: vf idx: %d, bmmu idx: %d, bmmu_box: %lx\n",
+ id, vf->index, vf->mm_box.bmmu_idx,
+ (ulong) vf->mm_box.bmmu_box);
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+ "[%d]: vf idx: %d, mmu_idx: %d, mmu_box: %lx\n",
+ id, vf->index, vf->mm_box.mmu_idx,
+ (ulong) vf->mm_box.mmu_box);
+
+ if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) {
+ decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box,
+ vf->mm_box.bmmu_idx);
+ decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box);
+ }
+
+ if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) {
+ decoder_mmu_box_free_idx(vf->mm_box.mmu_box,
+ vf->mm_box.mmu_idx);
+ decoder_mmu_try_to_release_box(vf->mm_box.mmu_box);
+ }
+
}
memset(data, 0, sizeof(struct file_private_data));
kfree(data);
}
-static void v4l2_buff_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
+int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb)
{
- struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(buf->vb2_buf.vb2_queue);
-
- mutex_lock(&ctx->buff_done_lock);
- if (buf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "vb is not active state = %d!\n",
- buf->vb2_buf.state);
- mutex_unlock(&ctx->buff_done_lock);
- return;
- }
- v4l2_m2m_buf_done(buf, state);
- mutex_unlock(&ctx->buff_done_lock);
-}
-
-static void comp_buf_set_vframe(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb,
- struct vframe_s *vf)
-{
- dmabuf_set_vframe(vb->planes[0].dbuf, vf, VF_SRC_DECODER);
-}
-
-static void fb_map_table_clean(struct aml_vcodec_ctx *ctx)
-{
- int i;
ulong flags;
+ struct vb2_buffer *dst_buf = NULL;
+ struct vdec_v4l2_buffer *pfb;
+ struct aml_video_dec_buf *dst_buf_info, *info;
+ struct vb2_v4l2_buffer *dst_vb2_v4l2;
flags = aml_vcodec_ctx_lock(ctx);
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- ctx->fb_map[i].addr = 0;
- ctx->fb_map[i].vframe = NULL;
- ctx->fb_map[i].task = NULL;
- ctx->fb_map[i].icomp = 0;
+ if (ctx->state == AML_STATE_ABORT) {
+ aml_vcodec_ctx_unlock(ctx, flags);
+ return -1;
}
- aml_vcodec_ctx_unlock(ctx, flags);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static void fb_map_table_hold(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb,
- struct vframe_s *vf,
- struct task_chain_s *task,
- u32 icomp)
-{
- int i;
- ulong addr, flags;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (!ctx->fb_map[i].addr ||
- (addr == ctx->fb_map[i].addr)) {
- ctx->fb_map[i].task = task;
- ctx->fb_map[i].addr = addr;
- ctx->fb_map[i].vframe = vf;
- ctx->fb_map[i].icomp = icomp;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
- __func__, task, vf, addr, icomp);
- break;
- }
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ if (!dst_buf) {
+ aml_vcodec_ctx_unlock(ctx, flags);
+ return -1;
}
- aml_vcodec_ctx_unlock(ctx, flags);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "vbuf idx: %d, state: %d, ready: %d\n",
+ dst_buf->index, dst_buf->state,
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, table is full. addr:%lx, vf:%px\n",
- __func__, addr, vf);
- }
-}
+ dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
+ dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
-static void fb_map_table_fetch(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb,
- struct vframe_s **vf,
- struct task_chain_s **task,
- u32 *icomp)
-{
- int i;
- ulong addr, flags;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (addr == ctx->fb_map[i].addr) {
- *task = ctx->fb_map[i].task;
- *vf = ctx->fb_map[i].vframe;
- *icomp = ctx->fb_map[i].icomp;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
- __func__, task, vf, addr, *icomp);
-
- ctx->fb_map[i].task = NULL;
- ctx->fb_map[i].vframe = NULL;
- ctx->fb_map[i].addr = 0;
- ctx->fb_map[i].icomp = 0;
- break;
- }
- }
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
+ pfb = &dst_buf_info->frame_buffer;
+ pfb->buf_idx = dst_buf->index;
+ pfb->num_planes = dst_buf->num_planes;
+ pfb->status = FB_ST_NORMAL;
+ if (dst_buf->num_planes == 1) {
+ pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+ pfb->m.mem[0].size = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
+ pfb->m.mem[0].offset = ctx->picinfo.y_len_sz;
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, there is new addr:%lx.\n",
- __func__, addr);
+ "idx: %u, 1 plane, y:(0x%lx, %d)\n", dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size);
+ } else if (dst_buf->num_planes == 2) {
+ pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+ pfb->m.mem[0].size = ctx->picinfo.y_len_sz;
+ pfb->m.mem[0].offset = 0;
+
+ pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr);
+ pfb->m.mem[1].size = ctx->picinfo.c_len_sz;
+ pfb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)\n", dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size,
+ pfb->m.mem[1].addr, pfb->m.mem[1].size);
+ } else {
+ pfb->m.mem[0].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+ pfb->m.mem[0].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+ pfb->m.mem[0].size = ctx->picinfo.y_len_sz;
+ pfb->m.mem[0].offset = 0;
+
+ pfb->m.mem[1].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+ pfb->m.mem[1].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[2].dma_addr);
+ pfb->m.mem[1].size = ctx->picinfo.c_len_sz >> 1;
+ pfb->m.mem[1].offset = 0;
+
+ pfb->m.mem[2].dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 2);
+ pfb->m.mem[2].addr = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr);
+ pfb->m.mem[2].size = ctx->picinfo.c_len_sz >> 1;
+ pfb->m.mem[2].offset = 0;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)\n",
+ dst_buf->index,
+ pfb->m.mem[0].addr, pfb->m.mem[0].size,
+ pfb->m.mem[1].addr, pfb->m.mem[1].size,
+ pfb->m.mem[2].addr, pfb->m.mem[2].size);
}
-}
-static bool is_fb_mapped(struct aml_vcodec_ctx *ctx, ulong addr)
-{
- int i;
- ulong flags;
+ dst_buf_info->used = true;
+ ctx->buf_used_count++;
- flags = aml_vcodec_ctx_lock(ctx);
+ *out_fb = pfb;
- for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
- if (addr == ctx->fb_map[i].addr)
- break;
- }
+ info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
+
+ ctx->cap_pool.dec++;
+ ctx->cap_pool.seq[ctx->cap_pool.out++] =
+ (V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index);
+ v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
aml_vcodec_ctx_unlock(ctx, flags);
- if (i >= ARRAY_SIZE(ctx->fb_map)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, addr:%lx isn't output.\n",
- __func__, addr);
- return false;
+ return 0;
+}
+EXPORT_SYMBOL(get_fb_from_queue);
+
+int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb)
+{
+ struct aml_video_dec_buf *dstbuf;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
+
+ if (in_fb == NULL) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "No free frame buffer\n");
+ return -1;
}
- return true;
+ dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer);
+
+ mutex_lock(&ctx->lock);
+
+ if (!dstbuf->used)
+ goto out;
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "status=%x queue id=%d to rdy_queue\n",
+ in_fb->status, dstbuf->vb.vb2_buf.index);
+
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
+
+ dstbuf->used = false;
+out:
+ mutex_unlock(&ctx->lock);
+
+ return 0;
+
}
+EXPORT_SYMBOL(put_fb_to_queue);
- static void post_frame_to_upper(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb)
+void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb)
{
- struct aml_video_dec_buf *dstbuf =
- container_of(fb, struct aml_video_dec_buf, frame_buffer);
- struct vb2_buffer *vb2_buf = &dstbuf->vb.vb2_buf;
- struct vframe_s *vf = fb->vframe;
- struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
-
- vf->index_disp = ctx->index_disp;
- ctx->index_disp++;
- ctx->post_to_upper_done = false;
+ struct aml_video_dec_buf *dstbuf = NULL;
+ struct vb2_buffer *vb2_buf = NULL;
+ struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
- "OUT_BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+ "FROM (%s %s) vf: %lx, ts: %llu, idx: %d, "
"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
- ctx->ada_ctx->frm_name, fb->status, vf->index_disp,
- vb2_buf->index, vb2_buf,
- vf->index & 0xff, vf,
- vf->timestamp,
+ vf_get_provider(ctx->ada_ctx->recv_name)->name,
+ ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO",
+ (ulong) vf, vf->timestamp, vf->index,
fb->m.mem[0].addr, fb->m.mem[0].size,
fb->m.mem[1].addr, fb->m.mem[1].size,
fb->m.mem[2].addr, fb->m.mem[2].size);
- vb2_v4l2 = container_of(vb2_buf, struct vb2_v4l2_buffer, vb2_buf);
+ dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+ vb2_buf = &dstbuf->vb.vb2_buf;
if (dstbuf->frame_buffer.num_planes == 1) {
- vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
} else if (dstbuf->frame_buffer.num_planes == 2) {
- vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
- vb2_set_plane_payload(vb2_buf, 1, fb->m.mem[1].bytes_used);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->m.mem[1].bytes_used);
}
- vb2_buf->timestamp = vf->timestamp;
- dstbuf->vb.flags |= vf->frame_type;
+ dstbuf->vb.vb2_buf.timestamp = vf->timestamp;
+ dstbuf->ready_to_display = true;
- if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) {
- vb2_v4l2->field = V4L2_FIELD_INTERLACED;
- }
-
- do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ if (dump_capture_frame) {
struct file *fp;
- char file_name[32] = {0};
-
- if (!dump_capture_frame || ctx->is_drm_mode)
- break;
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
- break;
- if (dw_mode == VDEC_DW_AFBC_ONLY)
- break;
-
- snprintf(file_name, 32, "/data/dec_dump_%ux%u.raw", vf->width, vf->height);
-
- fp = filp_open(file_name,
+ fp = filp_open("/data/dec_dump.raw",
O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
-
if (!IS_ERR(fp)) {
- struct vb2_buffer *vb = vb2_buf;
-
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
+ struct vb2_buffer *vb = &dstbuf->vb.vb2_buf;
+ kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].bytesused, 0);
if (dstbuf->frame_buffer.num_planes == 2)
kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
+ vb->planes[1].bytesused, 0);
pr_info("dump idx: %d %dx%d\n", dump_capture_frame, vf->width, vf->height);
- dump_capture_frame--;
+ dump_capture_frame = false;
filp_close(fp, NULL);
}
- } while(0);
-
- ATRACE_COUNTER("VC_OUT_VSINK-1.submit", vb2_buf->index);
- ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
+ }
if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
if (dstbuf->frame_buffer.num_planes == 1) {
- vb2_set_plane_payload(vb2_buf, 0, 0);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
} else if (dstbuf->frame_buffer.num_planes == 2) {
- vb2_set_plane_payload(vb2_buf, 0, 0);
- vb2_set_plane_payload(vb2_buf, 1, 0);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
+ vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
}
ctx->has_receive_eos = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"recevie a empty frame. idx: %d, state: %d\n",
- vb2_buf->index, vb2_buf->state);
+ dstbuf->vb.vb2_buf.index,
+ dstbuf->vb.vb2_buf.state);
+ ATRACE_COUNTER("v4l2_eos", 0);
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"receive vbuf idx: %d, state: %d\n",
- vb2_buf->index, vb2_buf->state);
+ dstbuf->vb.vb2_buf.index,
+ dstbuf->vb.vb2_buf.state);
if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
- if (ctx->v4l_resolution_change) {
+ if (ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
/* make the run to stanby until new buffs to enque. */
ctx->v4l_codec_dpb_ready = false;
ctx->reset_flag = V4L_RESET_MODE_LIGHT;
- ctx->vpp_cfg.res_chg = true;
/*
* After all buffers containing decoded frames from
@@ -838,449 +606,50 @@
if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) {
/* binding vframe handle. */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
- if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
- (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- else {
- if (fb->status == FB_ST_GE2D)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- }
- } else {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
-
- vf->omx_index = vf->index_disp;
+ vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+ ATRACE_COUNTER("v4l2_from", vf->index_disp);
dstbuf->privdata.vf = *vf;
+ dstbuf->privdata.vf.omx_index =
+ dstbuf->vb.vb2_buf.index;
- if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
- struct dma_buf * dma;
-
- dma = dstbuf->vb.vb2_buf.planes[0].dbuf;
- if (dmabuf_is_uvm(dma)) {
- /* only Y will contain vframe */
- comp_buf_set_vframe(ctx, vb2_buf, vf);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "set vf(%px) into %dth buf\n",
- vf, vb2_buf->index);
- }
- }
-
- fb_map_table_hold(ctx, vb2_buf, vf, fb->task, dstbuf->internal_index);
-
- v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
-
- fb->status = FB_ST_DISPLAY;
+ v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
}
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_FLUSHING &&
ctx->has_receive_eos) {
ctx->state = AML_STATE_FLUSHED;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_FLUSHED)\n");
}
mutex_unlock(&ctx->state_lock);
- if (ctx->post_to_upper_done == false) {
- ctx->post_to_upper_done = true;
- wake_up_interruptible(&ctx->post_done_wq);
- }
-
ctx->decoded_frame_cnt++;
}
-static void fill_capture_done_cb(void *v4l_ctx, void *fb_ctx)
+static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out)
{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
- struct aml_video_dec_buf *aml_buff =
- container_of(fb, struct aml_video_dec_buf, frame_buffer);
- struct vb2_v4l2_buffer *vb = &aml_buff->vb;
+ int ret = -1;
- if (ctx->is_stream_off) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
- "ignore buff idx: %d streamoff\n", fb->buf_idx);
- return;
- }
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
- ATRACE_COUNTER("VC_OUT_VSINK-0.receive", vb->vb2_buf.index);
-
- mutex_lock(&ctx->capture_buffer_lock);
- kfifo_put(&ctx->capture_buffer, vb);
- mutex_unlock(&ctx->capture_buffer_lock);
-
- aml_thread_post_task(ctx, AML_THREAD_CAPTURE);
-}
-
-static void update_vdec_buf_plane(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb,
- struct vb2_buffer *vb)
-{
- int i;
- char plane_n[3] = {'Y','U','V'};
-
- fb->num_planes = vb->num_planes;
- fb->buf_idx = vb->index;
-
- for (i = 0 ; i < vb->num_planes ; i++) {
- fb->m.mem[i].addr = vb2_dma_contig_plane_dma_addr(vb, i);
- fb->m.mem[i].dbuf = vb->planes[i].dbuf;
- if (i == 0) {
- //Y
- if (vb->num_planes == 1) {
- fb->m.mem[0].size = ctx->picinfo.y_len_sz +
- ctx->picinfo.c_len_sz;
- fb->m.mem[0].offset = ctx->picinfo.y_len_sz;
- } else {
- fb->m.mem[0].size = ctx->picinfo.y_len_sz;
- fb->m.mem[0].offset = 0;
- }
- } else {
- if (vb->num_planes == 2) {
- //UV
- fb->m.mem[1].size = ctx->picinfo.c_len_sz;
- fb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
- } else {
- fb->m.mem[i].size = ctx->picinfo.c_len_sz >> 1;
- fb->m.mem[i].offset = 0;
- }
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "idx: %u, %c:(0x%lx, %d)\n", vb->index,
- plane_n[i], fb->m.mem[i].addr, fb->m.mem[i].size);
- }
-}
-
-static bool fb_token_insert(struct aml_vcodec_ctx *ctx,
- ulong *token)
-{
- ulong vb_handle;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (ctx->token_table[i] &&
- (ctx->token_table[i] == *token)) {
- return true;
- }
- }
-
- if (!v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx))
- return false;
-
- vb_handle = (ulong)v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (!ctx->token_table[i]) {
- ctx->token_table[i] = vb_handle;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(ctx->token_table)) {
+ ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out);
+ if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, table is full. token:%lx\n",
- __func__, vb_handle);
- return false;
+ "Cannot get param : GET_PARAM_DISP_FRAME_BUFFER\n");
+ return -1;
}
- *token = vb_handle;
-
- return true;
-}
-
-static void fb_token_remove(struct aml_vcodec_ctx *ctx,
- ulong token)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- if (token == ctx->token_table[i]) {
- ctx->token_table[i] = 0;
- break;
- }
- }
-
- if (i >= ARRAY_SIZE(ctx->token_table)) {
+ if (!*out) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s, remove token err, token:%lx.\n",
- __func__, token);
+ "No display frame buffer\n");
+ return -1;
}
-}
-
-static void fb_token_clean(struct aml_vcodec_ctx *ctx)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
- ctx->token_table[i] = 0;
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static bool fb_buff_query(struct aml_fb_ops *fb, ulong *token)
-{
- struct aml_vcodec_ctx *ctx =
- container_of(fb, struct aml_vcodec_ctx, fb_ops);
- struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
- bool ret = false;
- ulong flags;
-
- if (!que->streaming)
- return false;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- ret = fb_token_insert(ctx, token);
-
- aml_vcodec_ctx_unlock(ctx, flags);
return ret;
}
-static void aml_task_chain_remove(struct aml_vcodec_ctx *ctx)
-{
- struct task_chain_s *task, *tmp;
-
- list_for_each_entry_safe(task, tmp, &ctx->task_chain_pool, node) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "remove task chain:%d, %px\n", task->id, task);
- list_del(&task->node);
- task_chain_clean(task);
- task_chain_release(task);
- }
-}
-
-static struct task_ops_s *get_v4l_sink_ops(void);
-
-static void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
- struct vdec_v4l2_buffer *fb,
- u32 requester)
-{
- struct task_chain_s *task = fb->task;
- /*
- * line 1: dec <==> vpp <==> v4l-sink, for P / P + DI.NR.
- * line 2: dec <==> vpp, vpp <==> v4l-sink, for I / I + DI.NR.
- * line 3: dec <==> v4l-sink, only for P.
- * line 4: dec <==> ge2d, ge2d <==> v4l-sink, used for fmt convert.
- * line 5: dec <==> ge2d, ge2d <==>vpp, vpp <==> v4l-sink.
- * line 6: dec <==> ge2d, ge2d <==> vpp <==> v4l-sink.
- */
-
- switch (requester) {
- case AML_FB_REQ_DEC:
- if (ctx->ge2d) {
- /* dec <==> ge2d. */
- task->attach(task, get_ge2d_ops(), ctx->ge2d);
- } else if (ctx->vpp) {
- if (ctx->vpp->is_prog) {
- /* dec <==> vpp <==> v4l-sink. */
- task->attach(task, get_v4l_sink_ops(), ctx);
- task->attach(task, get_vpp_ops(), ctx->vpp);
- } else {
- /* dec <==> vpp. */
- task->attach(task, get_vpp_ops(), ctx->vpp);
- }
- } else {
- /* dec <==> v4l-sink. */
- task->attach(task, get_v4l_sink_ops(), ctx);
- }
- break;
-
- case AML_FB_REQ_GE2D:
- if (ctx->vpp) {
- if (ctx->vpp->is_prog) {
- /* ge2d <==> vpp <==> v4l-sink. */
- task->attach(task, get_v4l_sink_ops(), ctx);
- task->attach(task, get_vpp_ops(), ctx->vpp);
- task->attach(task, get_ge2d_ops(), ctx->ge2d);
- } else {
- /* ge2d <==> vpp. */
- task->attach(task, get_vpp_ops(), ctx->vpp);
- task->attach(task, get_ge2d_ops(), ctx->ge2d);
- }
- } else {
- /* ge2d <==> v4l-sink. */
- task->attach(task, get_v4l_sink_ops(), ctx);
- task->attach(task, get_ge2d_ops(), ctx->ge2d);
- }
- break;
-
- case AML_FB_REQ_VPP:
- /* vpp <==> v4l-sink. */
- task->attach(task, get_v4l_sink_ops(), ctx);
- task->attach(task, get_vpp_ops(), ctx->vpp);
- break;
-
- default:
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "unsupport requester %x\n", requester);
- }
-}
-
-static int fb_buff_from_queue(struct aml_fb_ops *fb_ops,
- ulong token, struct vdec_v4l2_buffer **out_fb,
- u32 requester)
-{
- struct aml_vcodec_ctx *ctx =
- container_of(fb_ops, struct aml_vcodec_ctx, fb_ops);
- struct aml_video_dec_buf *aml_buf = NULL;
- struct vb2_v4l2_buffer *v4l_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- u32 buf_status = 0;
- ulong flags;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- if (ctx->is_stream_off) {
- aml_vcodec_ctx_unlock(ctx, flags);
- return -1;
- }
-
- v4l_buf = (struct vb2_v4l2_buffer *) token;
- if (!v4l_buf) {
- aml_vcodec_ctx_unlock(ctx, flags);
- return -1;
- }
-
- aml_buf = container_of(v4l_buf, struct aml_video_dec_buf, vb);
-
- fb = &aml_buf->frame_buffer;
- fb->buf_idx = v4l_buf->vb2_buf.index;
- aml_buf->used = true;
- ctx->buf_used_count++;
-
- if (requester == AML_FB_REQ_VPP) {
- buf_status = V4L_CAP_BUFF_IN_VPP;
- ctx->cap_pool.vpp++;
- } else if (requester == AML_FB_REQ_DEC) {
- buf_status = V4L_CAP_BUFF_IN_DEC;
- ctx->cap_pool.dec++;
- } else if (requester == AML_FB_REQ_GE2D) {
- buf_status = V4L_CAP_BUFF_IN_GE2D;
- ctx->cap_pool.ge2d++;
- }
-
- ctx->cap_pool.seq[ctx->cap_pool.out++] =
- (buf_status << 16 | fb->buf_idx);
-
- update_vdec_buf_plane(ctx, fb, &v4l_buf->vb2_buf);
-
- aml_creat_pipeline(ctx, fb, requester);
-
- fb_token_remove(ctx, token);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "vid:%d, task:%px, phy:%lx, state:%d, ready:%d, requester:%d\n",
- fb->buf_idx, fb->task, fb->m.mem[0].addr, v4l_buf->vb2_buf.state,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), requester);
-
- ATRACE_COUNTER("VC_IN_VSINK-3.require", v4l_buf->vb2_buf.index);
-
- *out_fb = fb;
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- return 0;
-}
-
-static struct task_ops_s v4l_sink_ops = {
- .type = TASK_TYPE_V4L_SINK,
- .fill_buffer = fill_capture_done_cb,
-};
-
-static struct task_ops_s *get_v4l_sink_ops(void)
-{
- return &v4l_sink_ops;
-}
-
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx)
-{
- struct aml_q_data *outq = NULL;
- struct aml_q_data *capq = NULL;
- struct vdec_pic_info pic;
-
- if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &pic)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "get pic info err\n");
- return;
- }
-
- outq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
- capq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
- pr_info("\n==== Show Basic Information ==== \n");
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Format : %s\n",
- outq->fmt->name);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Color space: %s\n",
- capq->fmt->name);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Scan type : %s\n",
- (pic.field == V4L2_FIELD_NONE) ?
- "Progressive" : "Interlaced");
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Resolution : visible(%dx%d), coded(%dx%d)\n",
- pic.visible_width, pic.visible_height,
- pic.coded_width, pic.coded_height);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Buffer num : dec:%d, vpp:%d, ge2d:%d, margin:%d, total:%d\n",
- ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
- ctx->picinfo.dpb_margin, CTX_BUF_TOTAL(ctx));
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Config : dw:%d, drm:%d, byp:%d, lc:%d, nr:%d, ge2d:%x\n",
- ctx->config.parm.dec.cfg.double_write_mode,
- ctx->is_drm_mode,
- ctx->vpp_cfg.is_bypass_p,
- ctx->vpp_cfg.enable_local_buf,
- ctx->vpp_cfg.enable_nr,
- ctx->ge2d_cfg.mode);
-}
-
-void aml_buffer_status(struct aml_vcodec_ctx *ctx)
-{
- struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *aml_buff = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- struct vb2_queue *q = NULL;
- ulong flags;
- int i;
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- q = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!q->streaming) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "can't achieve buffers status before start streaming.\n");
- }
-
- pr_info("\n==== Show Buffer Status ======== \n");
- for (i = 0; i < q->num_buffers; ++i) {
- vb = to_vb2_v4l2_buffer(q->bufs[i]);
- aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
- fb = &aml_buff->frame_buffer;
-
- /* print out task chain status. */
- task_chain_show(fb->task);
- }
-
- aml_vcodec_ctx_unlock(ctx, flags);
-}
-
static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
{
if (!ctx->v4l_codec_dpb_ready) {
@@ -1291,26 +660,12 @@
ctx->v4l_codec_dpb_ready = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "dpb: %d, vpp: %d, ready: %d, used: %d, dpb is ready: %s\n",
- ctx->dpb_size, ctx->vpp_size,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
+ "dpb: %d, ready: %d, used: %d, dpb is ready: %s\n",
+ ctx->dpb_size, v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no");
}
}
-static void reconfig_vpp_status(struct aml_vcodec_ctx *ctx)
-{
- if (bypass_nr_flag &&
- !ctx->vpp_cfg.is_prog &&
- ((ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC_LOCAL) ||
- (ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC))) {
- ctx->vpp_cfg.enable_nr = 0;
- ctx->vpp_cfg.enable_local_buf = 0;
-
- ctx->vpp_cfg.mode = VPP_MODE_DI;
- }
-}
-
static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
{
struct aml_vcodec_dev *dev = ctx->dev;
@@ -1326,7 +681,7 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_PROBE) {
ctx->state = AML_STATE_READY;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_READY)\n");
}
@@ -1338,7 +693,7 @@
if (ctx->m2m_ctx->out_q_ctx.q.streaming &&
ctx->m2m_ctx->cap_q_ctx.q.streaming) {
ctx->state = AML_STATE_ACTIVE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ACTIVE)\n");
}
@@ -1363,7 +718,7 @@
return true;
}
-static void aml_wait_buf_ready(struct aml_vcodec_ctx *ctx)
+static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx)
{
ulong expires;
@@ -1378,75 +733,34 @@
}
ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if ((ready_num + ctx->buf_used_count) >= CTX_BUF_TOTAL(ctx))
+ if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size)
ctx->v4l_codec_dpb_ready = true;
}
}
-void dmabuff_recycle_worker(struct work_struct *work)
-{
- struct aml_vcodec_ctx *ctx =
- container_of(work, struct aml_vcodec_ctx, dmabuff_recycle_work);
- struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *buf = NULL;
- unsigned long flags;
-
- for (;;) {
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
- if (!kfifo_get(&ctx->dmabuff_recycle, &vb)) {
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
- break;
- }
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
- buf = container_of(vb, struct aml_video_dec_buf, vb);
-
- if (ctx->is_out_stream_off)
- continue;
-
- if (wait_event_interruptible_timeout
- (ctx->wq, buf->used == false,
- msecs_to_jiffies(200)) == 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "wait recycle dma buff timeout.\n");
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
- "recycle buff idx: %d, vbuf: %lx\n", vb->vb2_buf.index,
- (ulong)sg_dma_address(buf->out_sgt->sgl));
-
- ATRACE_COUNTER("VO_OUT_VSINK-2.write_secure_end", vb->vb2_buf.index);
-
- if (vb->vb2_buf.state != VB2_BUF_STATE_ERROR)
- v4l2_buff_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
- VB2_BUF_STATE_DONE);
- }
-}
-
void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle)
{
- struct aml_vcodec_dev *dev = ctx->dev;
- struct vb2_v4l2_buffer *vb = NULL;
- struct vb2_queue *q = NULL;
+ struct vb2_v4l2_buffer *vb;
+ struct aml_video_dec_buf *buf;
+ struct vb2_queue *q;
int index = handle & 0xf;
- unsigned long flags;
if (ctx->is_out_stream_off) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
"ignore buff idx: %d streamoff\n", index);
return;
}
-
q = v4l2_m2m_get_vq(ctx->m2m_ctx,
V4L2_BUF_TYPE_VIDEO_OUTPUT);
vb = to_vb2_v4l2_buffer(q->bufs[index]);
+ buf = container_of(vb, struct aml_video_dec_buf, vb);
+ v4l2_m2m_buf_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
+ VB2_BUF_STATE_DONE);
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
- kfifo_put(&ctx->dmabuff_recycle, vb);
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
- queue_work(dev->decode_workqueue, &ctx->dmabuff_recycle_work);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
+ "recycle buff idx: %d, vbuf: %lx\n", index,
+ (ulong)vb2_dma_contig_plane_dma_addr(q->bufs[index], 0));
}
static void aml_vdec_worker(struct work_struct *work)
@@ -1454,12 +768,12 @@
struct aml_vcodec_ctx *ctx =
container_of(work, struct aml_vcodec_ctx, decode_work);
struct aml_vcodec_dev *dev = ctx->dev;
- struct aml_video_dec_buf *aml_buf;
- struct vb2_v4l2_buffer *vb2_v4l2;
- struct vb2_buffer *vb;
+ struct vb2_buffer *src_buf;
struct aml_vcodec_mem buf;
bool res_chg = false;
int ret;
+ struct aml_video_dec_buf *src_buf_info;
+ struct vb2_v4l2_buffer *src_vb2_v4l2;
if (ctx->state < AML_STATE_INIT ||
ctx->state > AML_STATE_FLUSHED) {
@@ -1473,23 +787,21 @@
goto out;
}
- vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- if (vb2_v4l2 == NULL) {
+ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ if (src_buf == NULL) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"src_buf empty.\n");
goto out;
}
- vb = (struct vb2_buffer *)vb2_v4l2;
-
/*this case for google, but some frames are droped on ffmpeg, so disabled temp.*/
if (0 && !is_enough_work_items(ctx))
goto out;
- aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- if (aml_buf->lastframe) {
- ulong expires;
+ src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf);
+ src_buf_info = container_of(src_vb2_v4l2, struct aml_video_dec_buf, vb);
+ if (src_buf_info->lastframe) {
/*the empty data use to flushed the decoder.*/
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"Got empty flush input buffer.\n");
@@ -1497,34 +809,22 @@
/*
* when inputs a small amount of src buff, then soon to
* switch state FLUSHING, must to wait the DBP to be ready.
- * (!ctx->v4l_codec_dpb_ready) change to only need one buf
- * for run ready in new version.
*/
- expires = jiffies + msecs_to_jiffies(5000);
- while ((vdec_frame_number(ctx->ada_ctx) > 0) &&
- (ctx->cap_pool.in < 1)) {
- if (time_after(jiffies, expires)) {
- aml_vdec_flush_decoder(ctx);
- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "capture buffer waiting timeout.\n");
- goto out;
- }
- usleep_range(5000, 5500);
+ if (!ctx->v4l_codec_dpb_ready) {
+ v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+ goto out;
}
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_ACTIVE) {
ctx->state = AML_STATE_FLUSHING;// prepare flushing
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_FLUSHING-LASTFRM)\n");
}
mutex_unlock(&ctx->state_lock);
- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
/* sets eos data for vdec input. */
@@ -1533,22 +833,21 @@
goto out;
}
- buf.index = vb->index;
- buf.vaddr = vb2_plane_vaddr(vb, 0);
- buf.addr = sg_dma_address(aml_buf->out_sgt->sgl);
- buf.size = vb->planes[0].bytesused;
- buf.model = vb->memory;
- buf.timestamp = vb->timestamp;
- buf.meta_ptr = (ulong)aml_buf->meta_data;
+ buf.index = src_buf->index;
+ buf.vaddr = vb2_plane_vaddr(src_buf, 0);
+ buf.addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+ buf.size = src_buf->planes[0].bytesused;
+ buf.model = src_buf->memory;
+ buf.timestamp = src_buf->timestamp;
if (!buf.vaddr && !buf.addr) {
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "id=%d src_addr is NULL.\n", vb->index);
+ "id=%d src_addr is NULL.\n", src_buf->index);
goto out;
}
- aml_buf->used = true;
+ src_buf_info->used = true;
/* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"size: 0x%zx, crc: 0x%x\n",
@@ -1558,52 +857,29 @@
/*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"timestamp: 0x%llx\n", src_buf->timestamp);*/
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- ATRACE_COUNTER("VO_IN_VSINK-2.write_secure", buf.size);
- } else {
- ATRACE_COUNTER("VO_IN_VSINK-2.write", buf.size);
- }
-
- ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
-
ret = vdec_if_decode(ctx, &buf, &res_chg);
if (ret > 0) {
/*
* we only return src buffer with VB2_BUF_STATE_DONE
* when decode success without resolution change.
*/
- aml_buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
- ATRACE_COUNTER("VO_OUT_VSINK-0.wrtie_end", buf.size);
- v4l2_buff_done(&aml_buf->vb,
- VB2_BUF_STATE_DONE);
- }
+ if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF))
+ v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
} else if (ret && ret != -EAGAIN) {
- aml_buf->used = false;
+ src_buf_info->error = (ret == -EIO ? true : false);
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (buf.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
- ATRACE_COUNTER("VO_OUT_VSINK-3.write_error", buf.size);
- v4l2_buff_done(&aml_buf->vb,
- VB2_BUF_STATE_ERROR);
- }
+ if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF))
+ v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"error processing src data. %d.\n", ret);
} else if (res_chg) {
/* wait the DPB state to be ready. */
- aml_wait_buf_ready(ctx);
+ aml_wait_dpb_ready(ctx);
- aml_buf->used = false;
+ src_buf_info->used = false;
aml_vdec_pic_info_update(ctx);
/*
* On encountering a resolution change in the stream.
@@ -1614,13 +890,13 @@
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_ACTIVE) {
ctx->state = AML_STATE_FLUSHING;// prepare flushing
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_FLUSHING-RESCHG)\n");
}
mutex_unlock(&ctx->state_lock);
- ctx->v4l_resolution_change = true;
+ ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
}
@@ -1629,10 +905,8 @@
goto out;
} else {
- ATRACE_COUNTER("VO_OUT_VSINK-1.write_again", buf.size);
/* decoder is lack of resource, retry after short delay */
- if (vdec_get_instance_num() < 2)
- usleep_range(2000, 4000);
+ usleep_range(50000, 55000);
}
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
@@ -1650,10 +924,28 @@
if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) {
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT).\n");
+ goto out;
}
+
+ if (ctx->state == AML_STATE_RESET) {
+ ctx->state = AML_STATE_PROBE;
+ ATRACE_COUNTER("v4l2_state", ctx->state);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+ "vcodec state (AML_STATE_PROBE)\n");
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "dpb: %d, ready: %d, used: %d\n", ctx->dpb_size,
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
+ ctx->buf_used_count);
+
+ /* vdec has ready to decode subsequence data of new resolution. */
+ ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false;
+ v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
+ }
+
out:
complete(&ctx->comp);
return;
@@ -1661,13 +953,13 @@
void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
{
+ struct aml_vcodec_dev *dev = ctx->dev;
+
/* disable queue output item to worker. */
ctx->output_thread_ready = false;
- ctx->is_stream_off = true;
/* flush output buffer worker. */
- cancel_work_sync(&ctx->decode_work);
- cancel_work_sync(&ctx->dmabuff_recycle_work);
+ flush_workqueue(dev->decode_workqueue);
/* clean output cache and decoder status . */
if (ctx->state > AML_STATE_INIT)
@@ -1681,38 +973,33 @@
ctx->v4l_codec_dpb_ready = false;
}
-void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx)
+void try_to_capture(struct aml_vcodec_ctx *ctx)
{
- struct vb2_v4l2_buffer *vb = NULL;
- struct aml_video_dec_buf *aml_buff = NULL;
+ int ret = 0;
struct vdec_v4l2_buffer *fb = NULL;
- for (;;) {
- mutex_lock(&ctx->capture_buffer_lock);
- if (!kfifo_get(&ctx->capture_buffer, &vb)) {
- mutex_unlock(&ctx->capture_buffer_lock);
- break;
- }
- mutex_unlock(&ctx->capture_buffer_lock);
-
- aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
- fb = &aml_buff->frame_buffer;
-
- if (ctx->is_stream_off)
- continue;
-
- post_frame_to_upper(ctx, fb);
+ ret = get_display_buffer(ctx, &fb);
+ if (ret) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "the que have no disp buf,ret: %d\n", ret);
+ return;
}
-}
-EXPORT_SYMBOL_GPL(aml_thread_capture_worker);
-static int vdec_capture_thread(void *data)
+ trans_vframe_to_user(ctx, fb);
+}
+EXPORT_SYMBOL_GPL(try_to_capture);
+
+static int vdec_thread(void *data)
{
+ struct sched_param param =
+ {.sched_priority = MAX_RT_PRIO / 2};
struct aml_vdec_thread *thread =
(struct aml_vdec_thread *) data;
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *) thread->priv;
+ sched_setscheduler(current, SCHED_FIFO, ¶m);
+
for (;;) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"%s, state: %d\n", __func__, ctx->state);
@@ -1728,19 +1015,19 @@
}
while (!kthread_should_stop()) {
- usleep_range(1000, 2000);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
}
return 0;
}
-void aml_thread_post_task(struct aml_vcodec_ctx *ctx,
+void aml_thread_notify(struct aml_vcodec_ctx *ctx,
enum aml_thread_type type)
{
struct aml_vdec_thread *thread = NULL;
- ulong flags;
- spin_lock_irqsave(&ctx->tsplock, flags);
+ mutex_lock(&ctx->lock);
list_for_each_entry(thread, &ctx->vdec_thread_list, node) {
if (thread->task == NULL)
continue;
@@ -1748,9 +1035,9 @@
if (thread->type == type)
up(&thread->sem);
}
- spin_unlock_irqrestore(&ctx->tsplock, flags);
+ mutex_unlock(&ctx->lock);
}
-EXPORT_SYMBOL_GPL(aml_thread_post_task);
+EXPORT_SYMBOL_GPL(aml_thread_notify);
int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
enum aml_thread_type type, const char *thread_name)
@@ -1768,7 +1055,7 @@
thread->priv = ctx;
sema_init(&thread->sem, 0);
- thread->task = kthread_run(vdec_capture_thread, thread, "aml-%s-%d", thread_name, ctx->id);
+ thread->task = kthread_run(vdec_thread, thread, "aml-%s", thread_name);
if (IS_ERR(thread->task)) {
ret = PTR_ERR(thread->task);
thread->task = NULL;
@@ -1776,10 +1063,6 @@
}
sched_setscheduler_nocheck(thread->task, SCHED_FIFO, ¶m);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, policy is:%d priority is:%d\n",
- __func__, thread->task->policy, thread->task->rt_priority);
-
list_add(&thread->node, &ctx->vdec_thread_list);
return 0;
@@ -1794,14 +1077,13 @@
void aml_thread_stop(struct aml_vcodec_ctx *ctx)
{
struct aml_vdec_thread *thread = NULL;
- ulong flags;
while (!list_empty(&ctx->vdec_thread_list)) {
thread = list_entry(ctx->vdec_thread_list.next,
struct aml_vdec_thread, node);
- spin_lock_irqsave(&ctx->tsplock, flags);
+ mutex_lock(&ctx->lock);
list_del(&thread->node);
- spin_unlock_irqrestore(&ctx->tsplock, flags);
+ mutex_unlock(&ctx->lock);
thread->stop = true;
up(&thread->sem);
@@ -1823,17 +1105,7 @@
switch (cmd->cmd) {
case V4L2_DEC_CMD_STOP:
case V4L2_DEC_CMD_START:
- if (cmd->cmd == V4L2_DEC_CMD_START) {
- if (cmd->start.speed == ~0)
- cmd->start.speed = 0;
- if (cmd->start.format == ~0)
- cmd->start.format = 0;
- }
-
- if (cmd->flags == ~0)
- cmd->flags = 0;
-
- if ((cmd->flags != 0) && (cmd->flags != ~0)) {
+ if (cmd->flags != 0) {
v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"cmd->flags=%u\n", cmd->flags);
return -EINVAL;
@@ -1862,6 +1134,19 @@
switch (cmd->cmd) {
case V4L2_DEC_CMD_STOP:
+ ATRACE_COUNTER("v4l2_stop", 0);
+ if (ctx->state != AML_STATE_ACTIVE) {
+ if (ctx->state >= AML_STATE_IDLE &&
+ ctx->state < AML_STATE_PROBE) {
+ ctx->state = AML_STATE_ABORT;
+ ATRACE_COUNTER("v4l2_state", ctx->state);
+ aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+ "vcodec state (AML_STATE_ABORT)\n");
+ return 0;
+ }
+ }
+
src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
if (!vb2_is_streaming(src_vq)) {
@@ -1870,32 +1155,18 @@
return 0;
}
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
- V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!vb2_is_streaming(dst_vq)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "Capture stream is off. No need to flush.\n");
- return 0;
- }
-
/* flush pipeline */
v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
ctx->receive_cmd_stop = true;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "%s, receive cmd stop and prepare flush pipeline.\n", __func__);
break;
case V4L2_DEC_CMD_START:
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "CMD V4L2_DEC_CMD_START\n");
dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
V4L2_BUF_TYPE_VIDEO_CAPTURE);
vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "%s, receive cmd start.\n", __func__);
break;
default:
@@ -1905,20 +1176,6 @@
return 0;
}
-static void aml_wait_resource(struct aml_vcodec_ctx *ctx)
-{
- ulong expires = jiffies + msecs_to_jiffies(1000);
-
- while (atomic_read(&ctx->dev->vpp_count) >= max_di_instance) {
- if (time_after(jiffies, expires)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "wait resource timeout.\n");
- break;
- }
- usleep_range(2000, 4000);
- }
-}
-
static int vidioc_decoder_streamon(struct file *file, void *priv,
enum v4l2_buf_type i)
{
@@ -1927,80 +1184,26 @@
struct vb2_queue *q;
q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
- if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
- ctx->is_stream_off) {
- if (ctx->vpp_is_need) {
- int ret;
+ if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+ if (ctx->is_stream_off) {
+ mutex_lock(&ctx->state_lock);
+ if ((ctx->state == AML_STATE_ACTIVE ||
+ ctx->state == AML_STATE_FLUSHING ||
+ ctx->state == AML_STATE_FLUSHED) ||
+ (ctx->reset_flag == V4L_RESET_MODE_LIGHT)) {
+ ctx->state = AML_STATE_RESET;
+ ATRACE_COUNTER("v4l2_state", ctx->state);
+ ctx->v4l_codec_dpb_ready = false;
- if (ctx->vpp_cfg.fmt == 0)
- ctx->vpp_cfg.fmt = ctx->cap_pix_fmt;
-
- if (ctx->vpp == NULL)
- aml_wait_resource(ctx);
-
- if ((atomic_read(&ctx->dev->vpp_count) < max_di_instance) ||
- (ctx->vpp != NULL)) {
- if (ctx->vpp && ctx->vpp_cfg.is_vpp_reset &&
- (ctx->vpp->is_prog == ctx->vpp_cfg.is_prog) &&
- (ctx->vpp->is_bypass_p == ctx->vpp_cfg.is_bypass_p) &&
- (ctx->vpp->work_mode == ctx->vpp_cfg.mode)) {
- aml_v4l2_vpp_reset(ctx->vpp);
- } else {
- if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
- aml_v4l2_vpp_destroy(ctx->vpp);
- ctx->vpp = NULL;
- }
-
- ret = aml_v4l2_vpp_init(ctx, &ctx->vpp_cfg, &ctx->vpp);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "vpp_wrapper init err:%d vpp_cfg.fmt: %d\n",
- ret, ctx->vpp_cfg.fmt);
- return ret;
- }
-
- atomic_inc(&ctx->dev->vpp_count);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "vpp_wrapper instance count: %d\n",
- atomic_read(&ctx->dev->vpp_count));
- }
- } else {
- ctx->vpp_cfg.enable_local_buf = 0;
- ctx->vpp_cfg.enable_nr = 0;
- ctx->picinfo.dpb_margin += ctx->vpp_size;
- ctx->dpb_size = ctx->picinfo.dpb_margin + ctx->picinfo.dpb_frames;
- ctx->vpp_size = 0;
- vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo);
- ctx->vpp_is_need = false;
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+ "vcodec state (AML_STATE_RESET)\n");
+ aml_vdec_reset(ctx);
}
- ctx->vpp_cfg.is_vpp_reset = false;
- } else {
- if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
- aml_v4l2_vpp_destroy(ctx->vpp);
- ctx->vpp = NULL;
- }
+ mutex_unlock(&ctx->state_lock);
+
+ ctx->is_stream_off = false;
+ ctx->v4l_resolution_change = false;
}
-
- if (ctx->ge2d_is_need) {
- int ret;
-
- if (ctx->ge2d) {
- aml_v4l2_ge2d_destroy(ctx->ge2d);
- ctx->ge2d = NULL;
- }
-
- ret = aml_v4l2_ge2d_init(ctx, &ctx->ge2d_cfg, &ctx->ge2d);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d_wrapper init err:%d\n", ret);
- return ret;
- }
- }
-
- ctx->is_stream_off = false;
} else
ctx->is_out_stream_off = false;
@@ -2016,26 +1219,12 @@
struct v4l2_fh *fh = file->private_data;
struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
struct vb2_queue *q;
- ulong flags;
q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
-
- flags = aml_vcodec_ctx_lock(ctx);
-
- if (V4L2_TYPE_IS_OUTPUT(q->type))
- ctx->is_out_stream_off = true;
- else
+ if (!V4L2_TYPE_IS_OUTPUT(q->type))
ctx->is_stream_off = true;
-
- aml_vcodec_ctx_unlock(ctx, flags);
-
- if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
- if (ctx->vpp) {
- reconfig_vpp_status(ctx);
- }
- } else {
- ctx->index_disp = 0;
- }
+ else
+ ctx->is_out_stream_off = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d\n", __func__, q->type);
@@ -2052,38 +1241,19 @@
q = v4l2_m2m_get_vq(fh->m2m_ctx, rb->type);
- if (!rb->count) {
- if (!V4L2_TYPE_IS_OUTPUT(rb->type)) {
- if (wait_event_interruptible_timeout
- (ctx->post_done_wq, ctx->post_to_upper_done == true,
- msecs_to_jiffies(200)) == 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "wait post frame to upper finish timeout.\n");
- }
- }
+ if (!rb->count)
vb2_queue_release(q);
- }
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d, count: %d\n",
__func__, q->type, rb->count);
if (!V4L2_TYPE_IS_OUTPUT(rb->type)) {
- /* driver needs match v4l buffer number with total size*/
- if (rb->count > CTX_BUF_TOTAL(ctx)) {
+ /* driver needs match v4l buffer number with dpb_size */
+ if (rb->count > ctx->dpb_size) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"reqbufs (st:%d) %d -> %d\n",
- ctx->state, rb->count, CTX_BUF_TOTAL(ctx));
- ctx->picinfo.dpb_margin += (rb->count - CTX_BUF_TOTAL(ctx));
- ctx->dpb_size = ctx->picinfo.dpb_frames + ctx->picinfo.dpb_margin;
- vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
- "%s buf updated, dec: %d (%d + %d), vpp %d\n",
- __func__,
- ctx->dpb_size,
- ctx->picinfo.dpb_frames,
- ctx->picinfo.dpb_margin,
- ctx->vpp_size);
+ ctx->state, rb->count, ctx->dpb_size);
//rb->count = ctx->dpb_size;
}
} else {
@@ -2123,12 +1293,9 @@
{
ulong flags;
- if (kref_read(&ctx->box_ref))
- kref_put(&ctx->box_ref, box_release);
-
flags = aml_vcodec_ctx_lock(ctx);
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT)\n");
aml_vcodec_ctx_unlock(ctx, flags);
@@ -2154,8 +1321,6 @@
memset(q_data, 0, sizeof(struct aml_q_data));
q_data->visible_width = DFT_CFG_WIDTH;
q_data->visible_height = DFT_CFG_HEIGHT;
- q_data->coded_width = DFT_CFG_WIDTH;
- q_data->coded_height = DFT_CFG_HEIGHT;
q_data->fmt = &aml_video_formats[OUT_FMT_IDX];
q_data->field = V4L2_FIELD_NONE;
@@ -2169,9 +1334,6 @@
q_data->coded_width = DFT_CFG_WIDTH;
q_data->coded_height = DFT_CFG_HEIGHT;
q_data->fmt = &aml_video_formats[CAP_FMT_IDX];
- if (support_format_I420)
- q_data->fmt = &aml_video_formats[CAP_FMT_I420_IDX];
-
q_data->field = V4L2_FIELD_NONE;
v4l_bound_align_image(&q_data->coded_width,
@@ -2187,11 +1349,8 @@
q_data->bytesperline[1] = q_data->coded_width;
ctx->reset_flag = V4L_RESET_MODE_NORMAL;
- ctx->fb_ops.query = fb_buff_query;
- ctx->fb_ops.alloc = fb_buff_from_queue;
-
ctx->state = AML_STATE_IDLE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_IDLE)\n");
}
@@ -2215,24 +1374,11 @@
ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
- if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
- if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->m.planes[0].bytesused);
- else
- ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->m.planes[0].bytesused);
- } else {
- if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->length);
- else
- ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->length);
- }
- } else {
if (ret == -EAGAIN)
- ATRACE_COUNTER("VC_IN_VSINK-1.que_again", buf->index);
+ ATRACE_COUNTER("v4l2_qbuf_eagain", 0);
else
- ATRACE_COUNTER("VC_IN_VSINK-0.que", buf->index);
+ ATRACE_COUNTER("v4l2_qbuf_ok", 0);
}
-
return ret;
}
@@ -2254,47 +1400,39 @@
}
ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+ if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
+ if (ret == -EAGAIN)
+ ATRACE_COUNTER("v4l2_dqin_eagain", 0);
+ else
+ ATRACE_COUNTER("v4l2_dqin_ok", 0);
+ } else {
+ if (ret == -EAGAIN)
+ ATRACE_COUNTER("v4l2_dqout_eagain", 0);
+ }
+
if (!ret && !V4L2_TYPE_IS_OUTPUT(buf->type)) {
struct vb2_queue *vq;
struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
struct aml_video_dec_buf *aml_buf = NULL;
- struct file *file = NULL;
vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]);
aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- aml_buf->privdata.vb_handle = (ulong) aml_buf;
+ aml_buf->privdata.vb_handle = (ulong) ctx->dev;
aml_buf->privdata.v4l_dec_ctx = (ulong) ctx;
+ aml_buf->privdata.v4l_inst_id = ctx->id;
file = fget(vb2_v4l2->private);
- if (file && is_v4l2_buf_file(file)) {
+ if (is_v4l2_buf_file(file)) {
dmabuf_fd_install_data(vb2_v4l2->private,
(void*)&aml_buf->privdata,
sizeof(struct file_private_data));
+ ATRACE_COUNTER("v4l2_dqout_ok", aml_buf->privdata.vf.index_disp);
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "disp: %d, vf: %lx\n",
aml_buf->privdata.vf.index_disp,
(ulong) v4l_get_vf_handle(vb2_v4l2->private));
- fput(file);
}
- }
-
- if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
- if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
- if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->m.planes[0].bytesused);
- else
- ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->m.planes[0].bytesused);
- } else {
- if (ret == -EAGAIN)
- ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->length);
- else
- ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->length);
- }
- } else {
- if (ret == -EAGAIN)
- ATRACE_COUNTER("VC_OUT_VSINK-3.deque_again", buf->index);
- else
- ATRACE_COUNTER("VC_OUT_VSINK-2.deque", buf->index);
+ fput(file);
}
return ret;
@@ -2304,12 +1442,10 @@
struct v4l2_capability *cap)
{
struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct video_device *vfd_dec = video_devdata(file);
strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver));
strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info));
strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card));
- cap->device_caps = vfd_dec->device_caps;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, %s\n", __func__, cap->card);
@@ -2347,154 +1483,115 @@
static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
{
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
int i;
- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
- if (V4L2_TYPE_IS_OUTPUT(f->type)) {
- pix_mp->num_planes = 1;
- pix_mp->plane_fmt[0].bytesperline = 0;
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pix_fmt_mp->num_planes = 1;
+ pix_fmt_mp->plane_fmt[0].bytesperline = 0;
+ if (pix_fmt_mp->pixelformat != V4L2_PIX_FMT_MPEG2 &&
+ pix_fmt_mp->pixelformat != V4L2_PIX_FMT_H264)
+ pix_fmt_mp->field = V4L2_FIELD_NONE;
+ else if (pix_fmt_mp->field != V4L2_FIELD_NONE)
+ pr_info("%s, field: %u, fmt: %u\n",
+ __func__, pix_fmt_mp->field,
+ pix_fmt_mp->pixelformat);
+ } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
+ int tmp_w, tmp_h;
- if ((pix_mp->pixelformat != V4L2_PIX_FMT_MPEG2) &&
- (pix_mp->pixelformat != V4L2_PIX_FMT_H264) &&
- (pix_mp->pixelformat != V4L2_PIX_FMT_MPEG1)) {
- pix_mp->field = V4L2_FIELD_NONE;
- } else if (pix_mp->field != V4L2_FIELD_NONE) {
- if (pix_mp->field == V4L2_FIELD_ANY)
- pix_mp->field = V4L2_FIELD_NONE;
+ pix_fmt_mp->field = V4L2_FIELD_NONE;
+ pix_fmt_mp->height = clamp(pix_fmt_mp->height,
+ AML_VDEC_MIN_H,
+ AML_VDEC_MAX_H);
+ pix_fmt_mp->width = clamp(pix_fmt_mp->width,
+ AML_VDEC_MIN_W,
+ AML_VDEC_MAX_W);
- pr_info("%s, field: %u, fmt: %x\n",
- __func__, pix_mp->field,
- pix_mp->pixelformat);
- }
- } else {
- if (pix_mp->field != V4L2_FIELD_INTERLACED)
- pix_mp->field = V4L2_FIELD_NONE;
- pix_mp->height = clamp(pix_mp->height,
- AML_VDEC_MIN_H,
- AML_VDEC_MAX_H);
- pix_mp->width = clamp(pix_mp->width,
- AML_VDEC_MIN_W,
- AML_VDEC_MAX_W);
+ /*
+ * Find next closer width align 64, heign align 64, size align
+ * 64 rectangle
+ * Note: This only get default value, the real HW needed value
+ * only available when ctx in AML_STATE_PROBE state
+ */
+ tmp_w = pix_fmt_mp->width;
+ tmp_h = pix_fmt_mp->height;
+ v4l_bound_align_image(&pix_fmt_mp->width,
+ AML_VDEC_MIN_W,
+ AML_VDEC_MAX_W, 6,
+ &pix_fmt_mp->height,
+ AML_VDEC_MIN_H,
+ AML_VDEC_MAX_H, 6, 9);
- pix_mp->num_planes = fmt->num_planes;
+ if (pix_fmt_mp->width < tmp_w &&
+ (pix_fmt_mp->width + 64) <= AML_VDEC_MAX_W)
+ pix_fmt_mp->width += 64;
+ if (pix_fmt_mp->height < tmp_h &&
+ (pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H)
+ pix_fmt_mp->height += 64;
- pix_mp->plane_fmt[0].bytesperline = pix_mp->width;
- pix_mp->plane_fmt[0].sizeimage =
- pix_mp->width * pix_mp->height;
+ pix_fmt_mp->num_planes = fmt->num_planes;
+ pix_fmt_mp->plane_fmt[0].sizeimage =
+ pix_fmt_mp->width * pix_fmt_mp->height;
+ pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
- pix_mp->plane_fmt[1].bytesperline = pix_mp->width;
- pix_mp->plane_fmt[1].sizeimage =
- pix_mp->width * pix_mp->height / 2;
+ if (pix_fmt_mp->num_planes == 2) {
+ pix_fmt_mp->plane_fmt[1].sizeimage =
+ (pix_fmt_mp->width * pix_fmt_mp->height) / 2;
+ pix_fmt_mp->plane_fmt[1].bytesperline =
+ pix_fmt_mp->width;
}
-
- for (i = 0; i < pix_mp->num_planes; i++) {
- memset(&(pix_mp->plane_fmt[i].reserved[0]), 0x0,
- sizeof(pix_mp->plane_fmt[0].reserved));
- }
- memset(&pix_mp->reserved, 0x0, sizeof(pix_mp->reserved));
-
- pix_mp->flags = 0;
- } else {
- if (V4L2_TYPE_IS_OUTPUT(f->type)) {
- pix->bytesperline = 0;
- if ((pix->pixelformat != V4L2_PIX_FMT_MPEG2) &&
- (pix->pixelformat != V4L2_PIX_FMT_H264) &&
- (pix->pixelformat != V4L2_PIX_FMT_MPEG1)) {
- pix->field = V4L2_FIELD_NONE;
- } else if (pix->field != V4L2_FIELD_NONE) {
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
-
- pr_info("%s, field: %u, fmt: %x\n",
- __func__, pix->field,
- pix->pixelformat);
- }
- } else {
- if (pix->field != V4L2_FIELD_INTERLACED)
- pix->field = V4L2_FIELD_NONE;
-
- pix->height = clamp(pix->height,
- AML_VDEC_MIN_H,
- AML_VDEC_MAX_H);
- pix->width = clamp(pix->width,
- AML_VDEC_MIN_W,
- AML_VDEC_MAX_W);
-
- pix->bytesperline = pix->width;
- pix->sizeimage = pix->width * pix->height;
- }
- pix->flags = 0;
}
+ for (i = 0; i < pix_fmt_mp->num_planes; i++)
+ memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0,
+ sizeof(pix_fmt_mp->plane_fmt[0].reserved));
+
+ pix_fmt_mp->flags = 0;
+ memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved));
return 0;
}
-static int vidioc_try_fmt_vid_cap_out(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct aml_q_data *q_data = NULL;
struct aml_video_fmt *fmt = NULL;
struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct vb2_queue *dst_vq;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
- "%s, type: %u, planes: %u, fmt: %x\n",
- __func__, f->type,
- V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
- f->fmt.pix_mp.num_planes : 1,
+ "%s, type: %u, planes: %u, fmt: %u\n",
+ __func__, f->type, f->fmt.pix_mp.num_planes,
f->fmt.pix_mp.pixelformat);
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!dst_vq) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ fmt = aml_vdec_find_format(f);
+ if (!fmt)
return -EINVAL;
- }
- if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
- return -EINVAL;
+ return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ struct aml_video_fmt *fmt = NULL;
+ struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+ "%s, type: %u, planes: %u, fmt: %u\n",
+ __func__, f->type, f->fmt.pix_mp.num_planes,
+ f->fmt.pix_mp.pixelformat);
fmt = aml_vdec_find_format(f);
- if (!fmt) {
- if (V4L2_TYPE_IS_OUTPUT(f->type))
- f->fmt.pix.pixelformat = aml_video_formats[OUT_FMT_IDX].fourcc;
- else
- f->fmt.pix.pixelformat = aml_video_formats[CAP_FMT_IDX].fourcc;
- fmt = aml_vdec_find_format(f);
- }
-
- vidioc_try_fmt(f, fmt);
-
- q_data = aml_vdec_get_q_data(ctx, f->type);
- if (!q_data)
+ if (!fmt)
return -EINVAL;
- if (ctx->state >= AML_STATE_PROBE)
- update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
-
- if (!V4L2_TYPE_IS_OUTPUT(f->type))
- return 0;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
- if (pix_mp->plane_fmt[0].sizeimage == 0) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "sizeimage of output format must be given\n");
- return -EINVAL;
- }
- } else {
- if (pix->sizeimage == 0) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "sizeimage of output format must be given\n");
- return -EINVAL;
- }
+ if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "sizeimage of output format must be given\n");
+ return -EINVAL;
}
- return 0;
+ return vidioc_try_fmt(f, fmt);
}
static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -2502,36 +1599,29 @@
{
struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
struct aml_q_data *q_data;
- int ratio = 1;
if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
(s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
return -EINVAL;
- if (ctx->internal_dw_scale) {
- if (ctx->state >= AML_STATE_PROBE) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
- return -EBUSY;
- ratio = get_double_write_ratio(dw_mode);
- }
- }
-
q_data = &ctx->q_data[AML_Q_DATA_DST];
switch (s->target) {
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = ctx->picinfo.visible_width / ratio;
- s->r.height = ctx->picinfo.visible_height / ratio;
+ if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
+ /* set to default value if header info not ready yet*/
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = q_data->visible_width;
+ s->r.height = q_data->visible_height;
+ }
break;
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
s->r.left = 0;
s->r.top = 0;
- s->r.width = ctx->picinfo.coded_width / ratio;
- s->r.height = ctx->picinfo.coded_height / ratio;
+ s->r.width = ctx->picinfo.coded_width;
+ s->r.height = ctx->picinfo.coded_height;
break;
default:
return -EINVAL;
@@ -2555,7 +1645,6 @@
struct v4l2_selection *s)
{
struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
- int ratio = 1;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n",
__func__, s->type);
@@ -2563,21 +1652,12 @@
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- if (ctx->internal_dw_scale) {
- if (ctx->state >= AML_STATE_PROBE) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
- return -EBUSY;
- ratio = get_double_write_ratio(dw_mode);
- }
- }
-
switch (s->target) {
case V4L2_SEL_TGT_COMPOSE:
s->r.left = 0;
s->r.top = 0;
- s->r.width = ctx->picinfo.visible_width / ratio;
- s->r.height = ctx->picinfo.visible_height / ratio;
+ s->r.width = ctx->picinfo.visible_width;
+ s->r.height = ctx->picinfo.visible_height;
break;
default:
return -EINVAL;
@@ -2586,127 +1666,89 @@
return 0;
}
-/* called when it is beyong AML_STATE_PROBE */
-static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type)
-{
- struct aml_q_data *q_data;
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
- int ratio = 1;
-
- q_data = aml_vdec_get_q_data(ctx, type);
-
- if (ctx->internal_dw_scale) {
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
- return;
- ratio = get_double_write_ratio(dw_mode);
- }
-
- if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
- q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
- q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
-
- q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
- q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
-
- q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
- q_data->bytesperline[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
- } else {
- q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
- q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
- q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
- q_data->sizeimage[0] += ctx->picinfo.c_len_sz;
- q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
- }
-}
-
static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
- struct v4l2_pix_format *pix,
- struct aml_q_data *q_data,
- u32 type)
+ struct aml_q_data *q_data, u32 type)
{
- int i;
-
- if (!pix || !pix_mp || !q_data)
+ if (!pix_mp || !q_data)
return;
- if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
- pix_mp->width = q_data->coded_width;
- pix_mp->height = q_data->coded_height;
- pix_mp->num_planes = q_data->fmt->num_planes;
- pix_mp->pixelformat = q_data->fmt->fourcc;
-
- for (i = 0; i < q_data->fmt->num_planes; i++) {
- pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
- pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
- }
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pix_mp->width = q_data->visible_width;
+ pix_mp->height = q_data->visible_height;
} else {
- pix->width = q_data->coded_width;
- pix->height = q_data->coded_height;
- pix->pixelformat = q_data->fmt->fourcc;
- pix->bytesperline = q_data->bytesperline[0];
- pix->sizeimage = q_data->sizeimage[0];
+ /*
+ * Width and height are set to the dimensions
+ * of the movie, the buffer is bigger and
+ * further processing stages should crop to this
+ * rectangle.
+ */
+ pix_mp->width = q_data->coded_width;
+ pix_mp->height = q_data->coded_height;
+ }
+
+ /*
+ * Set pixelformat to the format in which mt vcodec
+ * outputs the decoded frame
+ */
+ pix_mp->num_planes = q_data->fmt->num_planes;
+ pix_mp->pixelformat = q_data->fmt->fourcc;
+ pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
+ pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
+ if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
+ pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
}
}
static int vidioc_vdec_s_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- int ret = 0;
struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct aml_q_data *q_data = NULL;
+ struct v4l2_pix_format_mplane *pix_mp;
+ struct aml_q_data *q_data;
+ int ret = 0;
struct aml_video_fmt *fmt;
- struct vb2_queue *dst_vq;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
- "%s, type: %u, planes: %u, fmt: %x\n",
- __func__, f->type,
- V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
- f->fmt.pix_mp.num_planes : 1,
+ "%s, type: %u, planes: %u, fmt: %u\n",
+ __func__, f->type, f->fmt.pix_mp.num_planes,
f->fmt.pix_mp.pixelformat);
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!dst_vq) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
- return -EINVAL;
- }
-
- if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
- return -EINVAL;
-
q_data = aml_vdec_get_q_data(ctx, f->type);
if (!q_data)
return -EINVAL;
+ pix_mp = &f->fmt.pix_mp;
if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"out_q_ctx buffers already requested\n");
- ret = -EBUSY;
}
if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"cap_q_ctx buffers already requested\n");
- ret = -EBUSY;
}
fmt = aml_vdec_find_format(f);
if (fmt == NULL) {
- if (V4L2_TYPE_IS_OUTPUT(f->type))
- fmt = &aml_video_formats[OUT_FMT_IDX];
- else
- fmt = &aml_video_formats[CAP_FMT_IDX];
- f->fmt.pix.pixelformat = fmt->fourcc;
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ f->fmt.pix.pixelformat =
+ aml_video_formats[OUT_FMT_IDX].fourcc;
+ fmt = aml_vdec_find_format(f);
+ } else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
+ f->fmt.pix.pixelformat =
+ aml_video_formats[CAP_FMT_IDX].fourcc;
+ fmt = aml_vdec_find_format(f);
+ }
}
q_data->fmt = fmt;
vidioc_try_fmt(f, q_data->fmt);
-
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (ctx->is_drm_mode)
+ pix_mp->plane_fmt[0].sizeimage = 1;
q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
q_data->coded_width = pix_mp->width;
q_data->coded_height = pix_mp->height;
@@ -2716,7 +1758,6 @@
pix_mp->width, pix_mp->height,
pix_mp->plane_fmt[0].sizeimage);
- ctx->output_pix_fmt = pix_mp->pixelformat;
ctx->colorspace = f->fmt.pix_mp.colorspace;
ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
ctx->quantization = f->fmt.pix_mp.quantization;
@@ -2732,38 +1773,7 @@
return -EINVAL;
}
ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
- "vcodec state (AML_STATE_INIT)\n");
- }
- mutex_unlock(&ctx->state_lock);
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- q_data->sizeimage[0] = pix->sizeimage;
- q_data->coded_width = pix->width;
- q_data->coded_height = pix->height;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "w: %d, h: %d, size: %d\n",
- pix->width, pix->height,
- pix->sizeimage);
-
- ctx->output_pix_fmt = pix->pixelformat;
- ctx->colorspace = f->fmt.pix.colorspace;
- ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
- ctx->quantization = f->fmt.pix.quantization;
- ctx->xfer_func = f->fmt.pix.xfer_func;
-
- mutex_lock(&ctx->state_lock);
- if (ctx->state == AML_STATE_IDLE) {
- ret = vdec_if_init(ctx, q_data->fmt->fourcc);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "vdec_if_init() fail ret=%d\n", ret);
- mutex_unlock(&ctx->state_lock);
- return -EINVAL;
- }
- ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_INIT)\n");
}
@@ -2771,13 +1781,9 @@
}
if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
- ctx->cap_pix_fmt = V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
- pix_mp->pixelformat : pix->pixelformat;
- if (ctx->state >= AML_STATE_PROBE) {
- update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
- v4l_buf_size_decision(ctx);
- }
+ ctx->cap_pix_fmt = pix_mp->pixelformat;
+ if (ctx->state >= AML_STATE_PROBE)
+ copy_v4l2_format_dimention(pix_mp, q_data, f->type);
}
return 0;
@@ -2827,31 +1833,16 @@
static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
{
struct aml_video_fmt *fmt;
- int i = 0, j = 0;
+ int i, j = 0;
- /* I420 only used for mjpeg. */
- if (!output_queue && support_mjpeg && support_format_I420) {
- for (i = 0; i < NUM_FORMATS; i++) {
- fmt = &aml_video_formats[i];
- if ((fmt->fourcc == V4L2_PIX_FMT_YUV420) ||
- (fmt->fourcc == V4L2_PIX_FMT_YUV420M)) {
- break;
- }
- }
- }
-
- for (; i < NUM_FORMATS; i++) {
- fmt = &aml_video_formats[i];
- if (output_queue && (fmt->type != AML_FMT_DEC))
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (output_queue && (aml_video_formats[i].type != AML_FMT_DEC))
continue;
- if (!output_queue && (fmt->type != AML_FMT_FRAME))
- continue;
- if (support_mjpeg && !support_format_I420 &&
- ((fmt->fourcc == V4L2_PIX_FMT_YUV420) ||
- (fmt->fourcc == V4L2_PIX_FMT_YUV420M)))
+ if (!output_queue && (aml_video_formats[i].type != AML_FMT_FRAME))
continue;
if (j == f->index) {
+ fmt = &aml_video_formats[i];
f->pixelformat = fmt->fourcc;
return 0;
}
@@ -2888,7 +1879,6 @@
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct vb2_queue *vq;
- struct vb2_queue *dst_vq;
struct aml_q_data *q_data;
int ret = 0;
@@ -2899,29 +1889,12 @@
return -EINVAL;
}
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!dst_vq) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
- return -EINVAL;
- }
-
- if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
- return -EINVAL;
-
q_data = aml_vdec_get_q_data(ctx, f->type);
ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"GET_PARAM_PICTURE_INFO err\n");
- } else {
- if ((ctx->picinfo.visible_height < 16 && ctx->picinfo.visible_height > 0) ||
- (ctx->picinfo.visible_width < 16 && ctx->picinfo.visible_width > 0)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "The width or height of the stream is less than 16\n");
- return -EPERM;
- }
}
if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
@@ -2940,8 +1913,24 @@
if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
(ctx->state >= AML_STATE_PROBE)) {
- update_ctx_dimension(ctx, f->type);
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ /* Until STREAMOFF is called on the CAPTURE queue
+ * (acknowledging the event), the driver operates as if
+ * the resolution hasn't changed yet.
+ * So we just return picinfo yet, and update picinfo in
+ * stop_streaming hook function
+ */
+ /* it is used for alloc the decode buffer size. */
+ q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
+ q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
+
+ /* it is used for alloc the EGL image buffer size. */
+ q_data->coded_width = ctx->picinfo.coded_width;
+ q_data->coded_height = ctx->picinfo.coded_height;
+
+ q_data->bytesperline[0] = ctx->picinfo.coded_width;
+ q_data->bytesperline[1] = ctx->picinfo.coded_width;
+
+ copy_v4l2_format_dimention(pix_mp, q_data, f->type);
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
/*
* This is run on OUTPUT
@@ -2949,21 +1938,20 @@
* so width and height have no meaning.
* Assign value here to pass v4l2-compliance test
*/
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimention(pix_mp, q_data, f->type);
} else {
- copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+ copy_v4l2_format_dimention(pix_mp, q_data, f->type);
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
"type=%d state=%d Format information could not be read, not ready yet!\n",
f->type, ctx->state);
+ return -EINVAL;
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
- "%s, type: %u, planes: %u, fmt: %x\n",
- __func__, f->type,
- V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
- q_data->fmt->num_planes : 1,
- q_data->fmt->fourcc);
+ "%s, type: %u, planes: %u, fmt: %u\n",
+ __func__, f->type, f->fmt.pix_mp.num_planes,
+ f->fmt.pix_mp.pixelformat);
return 0;
}
@@ -3019,32 +2007,21 @@
for (i = 0; i < *nplanes; i++) {
if (sizes[i] < q_data->sizeimage[i])
return -EINVAL;
- alloc_devs[i] = &ctx->dev->plat_dev->dev;
-
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
- alloc_devs[i] = v4l_get_dev_from_codec_mm();
+ //alloc_devs[i] = &ctx->dev->plat_dev->dev;
+ alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
}
} else {
- int dw_mode = VDEC_DW_NO_AFBC;
-
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
*nplanes = 2;
else
*nplanes = 1;
- if (!vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- if (dw_mode == VDEC_DW_AFBC_ONLY)
- *nplanes = 1;
- }
-
for (i = 0; i < *nplanes; i++) {
sizes[i] = q_data->sizeimage[i];
if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->output_dma_mode)
- sizes[i] = 1;
- alloc_devs[i] = &ctx->dev->plat_dev->dev;
-
- if (!V4L2_TYPE_IS_OUTPUT(vq->type))
- alloc_devs[i] = v4l_get_dev_from_codec_mm();
+ sizes[i] = 0;
+ //alloc_devs[i] = &ctx->dev->plat_dev->dev;
+ alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
}
}
@@ -3059,8 +2036,6 @@
{
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct aml_q_data *q_data;
- struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
- struct aml_video_dec_buf *buf = NULL;
int i;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
@@ -3082,710 +2057,65 @@
}
}
- vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-
- if (vb2_v4l2->meta_ptr && (copy_from_user(buf->meta_data,
- (void *)vb2_v4l2->meta_ptr, META_DATA_SIZE + 4))) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "%s:copy meta data error. ptr: %lx\n", __func__, vb2_v4l2->meta_ptr);
- }
-
return 0;
}
-static int init_mmu_bmmu_box(struct aml_vcodec_ctx *ctx)
-{
- int i;
- int mmu_flag = ctx->is_drm_mode? CODEC_MM_FLAGS_TVP:0;
- int bmmu_flag = mmu_flag;
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- ctx->comp_bufs = vzalloc(sizeof(*ctx->comp_bufs) * V4L_CAP_BUFF_MAX);
- if (!ctx->comp_bufs)
- return -ENOMEM;
-
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- goto free_comp_bufs;
- }
-
- /* init mmu box */
- ctx->mmu_box = decoder_mmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- ctx->comp_info.max_size * SZ_1M, mmu_flag);
- if (!ctx->mmu_box) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box\n");
- goto free_comp_bufs;
- }
-
- /* init bmmu box */
- bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
- ctx->bmmu_box = decoder_bmmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- 4 + PAGE_SHIFT, bmmu_flag);
- if (!ctx->bmmu_box) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box\n");
- goto free_mmubox;
- }
-
- if (dw_mode & 0x20) {
- /* init mmu box dw*/
- ctx->mmu_box_dw = decoder_mmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- ctx->comp_info.max_size * SZ_1M, mmu_flag);
- if (!ctx->mmu_box_dw) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box dw\n");
- goto free_bmmubox;
- }
-
- /* init bmmu box dw*/
- bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
- ctx->bmmu_box_dw = decoder_bmmu_box_alloc_box("v4l2_dec",
- ctx->id, V4L_CAP_BUFF_MAX,
- 4 + PAGE_SHIFT, bmmu_flag);
- if (!ctx->bmmu_box_dw) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box dw\n");
- goto free_mmubox_dw;
- }
- }
-
- kref_init(&ctx->box_ref);
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- struct internal_comp_buf *buf;
- buf = &ctx->comp_bufs[i];
- buf->index = i;
- buf->ref = 0;
- buf->box_ref = &ctx->box_ref;
- buf->mmu_box = ctx->mmu_box;
- buf->bmmu_box = ctx->bmmu_box;
- buf->mmu_box_dw = ctx->mmu_box_dw;
- buf->bmmu_box_dw = ctx->bmmu_box_dw;
- }
- kref_get(&ctx->ctx_ref);
-
- ctx->uvm_proxy = vzalloc(sizeof(*ctx->uvm_proxy) * V4L_CAP_BUFF_MAX);
- if (!ctx->uvm_proxy)
- goto free_mmubox;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "box init, bmmu: %px, mmu: %px, mmu_dw: %px bmmu_dw: %px\n",
- ctx->bmmu_box, ctx->mmu_box, ctx->mmu_box_dw, ctx->bmmu_box_dw);
-
- return 0;
-free_mmubox_dw:
- decoder_mmu_box_free(ctx->mmu_box_dw);
- ctx->mmu_box_dw = NULL;
-
-free_bmmubox:
- decoder_bmmu_box_free(ctx->bmmu_box);
- ctx->bmmu_box = NULL;
-
-free_mmubox:
- decoder_mmu_box_free(ctx->mmu_box);
- ctx->mmu_box = NULL;
-
-free_comp_bufs:
- vfree(ctx->comp_bufs);
- ctx->comp_bufs = NULL;
-
- return -1;
-}
-
-void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag)
-{
- int i = 0;
-
- if (flag & DV_TYPE) {
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- ctx->aux_infos.bufs[i].md_buf = vzalloc(MD_BUF_SIZE);
- if (ctx->aux_infos.bufs[i].md_buf == NULL) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "v4l2 alloc %dth dv md buffer fail\n", i);
- }
-
- ctx->aux_infos.bufs[i].comp_buf = vzalloc(COMP_BUF_SIZE);
- if (ctx->aux_infos.bufs[i].comp_buf == NULL) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "v4l2 alloc %dth dv comp buffer fail\n", i);
- }
- }
- }
-
- if (flag & SEI_TYPE) {
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- ctx->aux_infos.bufs[i].sei_buf = vzalloc(SEI_BUF_SIZE);
- if (ctx->aux_infos.bufs[i].sei_buf) {
- ctx->aux_infos.bufs[i].sei_size = 0;
- ctx->aux_infos.bufs[i].sei_state = 1;
- ctx->aux_infos.sei_need_free = false;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "v4l2 alloc %dth aux buffer:%px\n",
- i, ctx->aux_infos.bufs[i].sei_buf);
- } else {
- ctx->aux_infos.bufs[i].sei_buf = NULL;
- ctx->aux_infos.bufs[i].sei_state = 0;
- ctx->aux_infos.bufs[i].sei_size = 0;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "v4l2 alloc %dth aux buffer fail\n", i);
- }
- }
- }
-}
-
-void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag)
-{
- int i = 0;
-
- if (flag & DV_TYPE) {
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- if (ctx->aux_infos.bufs[i].md_buf != NULL) {
- vfree(ctx->aux_infos.bufs[i].md_buf);
- ctx->aux_infos.bufs[i].md_buf = NULL;
- }
-
- if (ctx->aux_infos.bufs[i].comp_buf != NULL) {
- vfree(ctx->aux_infos.bufs[i].comp_buf);
- ctx->aux_infos.bufs[i].comp_buf = NULL;
- }
- }
- }
-
- if (flag & SEI_TYPE) {
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- if (ctx->aux_infos.bufs[i].sei_buf != NULL) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "v4l2 free %dth aux buffer:%px\n",
- i, ctx->aux_infos.bufs[i].sei_buf);
- vfree(ctx->aux_infos.bufs[i].sei_buf);
- ctx->aux_infos.bufs[i].sei_state = 0;
- ctx->aux_infos.bufs[i].sei_size = 0;
- ctx->aux_infos.bufs[i].sei_buf = NULL;
- }
- }
- }
-}
-
-void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx)
-{
- if (ctx->aux_infos.bufs[idx].sei_buf != NULL) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "v4l2 free %dth aux buffer:%px\n",
- idx, ctx->aux_infos.bufs[idx].sei_buf);
-
- vfree(ctx->aux_infos.bufs[idx].sei_buf);
- ctx->aux_infos.bufs[idx].sei_state = 0;
- ctx->aux_infos.bufs[idx].sei_size = 0;
- ctx->aux_infos.bufs[idx].sei_buf = NULL;
- *addr = NULL;
- *size = 0;
- ctx->aux_infos.sei_need_free = true;
- }
-}
-
-void aml_bind_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx)
-{
- int index = ctx->aux_infos.sei_index;
- int count = 0;
-
- if (ctx->aux_infos.sei_need_free) {
- for (count = 0; count < V4L_CAP_BUFF_MAX; count++) {
- if ((ctx->aux_infos.bufs[index].sei_buf != NULL) &&
- (ctx->aux_infos.bufs[index].sei_state == 1)) {
- break;
- }
- index = (index + 1) % V4L_CAP_BUFF_MAX;
- }
- } else {
- for (count = 0; count < V4L_CAP_BUFF_MAX; count++) {
- if ((ctx->aux_infos.bufs[index].sei_buf != NULL) &&
- ((ctx->aux_infos.bufs[index].sei_state == 1) ||
- (ctx->aux_infos.bufs[index].sei_state == 2))) {
- memset(ctx->aux_infos.bufs[index].sei_buf, 0, SEI_BUF_SIZE);
- ctx->aux_infos.bufs[index].sei_size = 0;
- break;
- }
- index = (index + 1) % V4L_CAP_BUFF_MAX;
- }
- }
-
- if (count == V4L_CAP_BUFF_MAX) {
- *addr = NULL;
- *size = 0;
- } else {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "v4l2 bind %dth aux buffer:%px, count = %d\n",
- index, ctx->aux_infos.bufs[index].sei_buf, count);
- *addr = ctx->aux_infos.bufs[index].sei_buf;
- *size = ctx->aux_infos.bufs[index].sei_size;
- *idx = index;
- ctx->aux_infos.bufs[index].sei_state = 2;
- ctx->aux_infos.sei_index = (index + 1) % V4L_CAP_BUFF_MAX;
- }
-}
-
-void aml_bind_dv_buffer(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf)
-{
- int index = ctx->aux_infos.dv_index;
-
- if ((ctx->aux_infos.bufs[index].comp_buf != NULL) &&
- (ctx->aux_infos.bufs[index].md_buf != NULL)) {
- *comp_buf = ctx->aux_infos.bufs[index].comp_buf;
- *md_buf = ctx->aux_infos.bufs[index].md_buf;
- ctx->aux_infos.dv_index = (index + 1) % V4L_CAP_BUFF_MAX;
- }
-}
-
-void aml_v4l_ctx_release(struct kref *kref)
-{
- struct aml_vcodec_ctx * ctx;
-
- ctx = container_of(kref, struct aml_vcodec_ctx, ctx_ref);
-
- if (ctx->vpp) {
- atomic_dec(&ctx->dev->vpp_count);
- aml_v4l2_vpp_destroy(ctx->vpp);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "vpp destory inst count:%d.\n",
- atomic_read(&ctx->dev->vpp_count));
- }
-
- if (ctx->ge2d) {
- aml_v4l2_ge2d_destroy(ctx->ge2d);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "ge2d destory.\n");
- }
-
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- aml_task_chain_remove(ctx);
-
- vfree(ctx->meta_infos.meta_bufs);
- ctx->aux_infos.free_buffer(ctx, SEI_TYPE | DV_TYPE);
- ctx->aux_infos.free_buffer(ctx, 1);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "v4ldec has been destroyed.\n");
-
- if (ctx->sync) {
- vdec_clean_all_fence(ctx->sync);
- }
-
- kfree(ctx);
-}
-
-static void box_release(struct kref *kref)
-{
- struct aml_vcodec_ctx * ctx
- = container_of(kref, struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, bmmu: %px, mmu: %px mmu_dw: %pu\n",
- __func__, ctx->bmmu_box, ctx->mmu_box,ctx->mmu_box_dw);
-
- decoder_bmmu_box_free(ctx->bmmu_box);
- decoder_mmu_box_free(ctx->mmu_box);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free(ctx->mmu_box_dw);
- decoder_bmmu_box_free(ctx->bmmu_box_dw);
- }
- vfree(ctx->comp_bufs);
- vfree(ctx->uvm_proxy);
- kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
-}
-
-static void internal_buf_free(void *arg)
-{
- struct internal_comp_buf* ibuf =
- (struct internal_comp_buf*)arg;
- struct aml_vcodec_ctx * ctx
- = container_of(ibuf->box_ref,struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, idx:%d\n", __func__, ibuf->index);
-
- mutex_lock(&ctx->comp_lock);
-
- if (!(ibuf->ref & 0xff00)) {
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- }
- ibuf->ref = 0;
-
- mutex_unlock(&ctx->comp_lock);
-
- kref_put(ibuf->box_ref, box_release);
-}
-
-static void internal_buf_free2(void *arg)
-{
- struct internal_comp_buf *ibuf =
- container_of(arg, struct internal_comp_buf, priv_data);
- struct aml_vcodec_ctx * ctx
- = container_of(ibuf->box_ref, struct aml_vcodec_ctx, box_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, idx: %d\n", __func__, ibuf->index);
-
- mutex_lock(&ctx->comp_lock);
-
- if (!(ibuf->ref & 0xff00)) {
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
- if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
- decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- }
- ibuf->ref = 0;
-
- mutex_unlock(&ctx->comp_lock);
-
- kref_put(ibuf->box_ref, box_release);
-}
-
-static void aml_uvm_buf_free(void *arg)
-{
- struct aml_uvm_buff_ref * ubuf =
- (struct aml_uvm_buff_ref*)arg;
- struct aml_vcodec_ctx * ctx
- = container_of(ubuf->ref, struct aml_vcodec_ctx, ctx_ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, vb:%d, dbuf:%px, ino:%lu\n",
- __func__, ubuf->index, ubuf->dbuf,
- file_inode(ubuf->dbuf->file)->i_ino);
-
- kref_put(ubuf->ref, aml_v4l_ctx_release);
- vfree(ubuf);
-}
-
-static int uvm_attach_hook_mod_local(struct aml_vcodec_ctx *ctx,
- struct uvm_hook_mod_info *uvm)
-{
- struct internal_comp_buf* ibuf = uvm->arg;
-
- ctx->uvm_proxy[ibuf->index] = *uvm;
-
- return 0;
-}
-
-static int update_comp_buffer_to_reuse(struct aml_vcodec_ctx *ctx,
- struct aml_video_dec_buf *buf)
-{
- struct internal_comp_buf* ibuf = NULL;
-
- mutex_lock(&ctx->comp_lock);
-
- ibuf = vb_to_comp(ctx, &buf->vb.vb2_buf);
- if (!ibuf) {
- mutex_unlock(&ctx->comp_lock);
- return 0;
- }
-
- if (ibuf->ref & 0xff) {
- buf->internal_index = ibuf->index;
- ibuf->frame_buffer_size = ctx->comp_info.frame_buffer_size;
-
- if (ctx->comp_info.header_size != ibuf->header_size) {
- decoder_bmmu_box_free_idx(ctx->bmmu_box, ibuf->index);
- if (decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_addr) < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "fail to alloc %dth bmmu\n",
- ibuf->index);
- mutex_unlock(&ctx->comp_lock);
- return -ENOMEM;
- }
- ibuf->header_size = ctx->comp_info.header_size;
- }
-
- ibuf->ref |= (1 << 8);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, reuse comp buffer vb2:%d <--> internal: %d, header_addr 0x%lx, size: %u\n",
- __func__, buf->vb.vb2_buf.index,
- buf->internal_index,
- ibuf->header_addr,
- ibuf->header_size);
- }
-
- mutex_unlock(&ctx->comp_lock);
-
- return (ibuf->ref & 0xff00) ? 1 : 0;
-}
-
-static int bind_comp_buffer_to_uvm(struct aml_vcodec_ctx *ctx,
- struct aml_video_dec_buf *buf)
-{
- int ret, i;
- struct dma_buf * dma = buf->vb.vb2_buf.planes[0].dbuf;
- struct aml_dec_params *parms = &ctx->config.parm.dec;
- struct uvm_hook_mod_info u_info;
- struct internal_comp_buf* ibuf;
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- /* get header and page size */
- if (vdec_if_get_param(ctx, GET_PARAM_COMP_BUF_INFO, &ctx->comp_info)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to get comp info\n");
- return -EINVAL;
- }
-
- if (!ctx->bmmu_box || !ctx->mmu_box)
- if (init_mmu_bmmu_box(ctx))
- return -EINVAL;
-
- ret = update_comp_buffer_to_reuse(ctx, buf);
- if (ret < 0)
- return ret;
-
- if (ret == 1 /*reused*/)
- return 0;
-
- for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
- if (!ctx->comp_bufs[i].ref)
- break;
- }
-
- if (i == V4L_CAP_BUFF_MAX) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "out of internal buf\n");
- return -EINVAL;
- }
-
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- return -EINVAL;
- }
-
- buf->internal_index = i;
- ibuf = &ctx->comp_bufs[i];
- ibuf->frame_buffer_size = ctx->comp_info.frame_buffer_size;
- ibuf->header_size = ctx->comp_info.header_size;
-
- /* allocate header */
- ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_addr);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu\n", i);
- return -ENOMEM;
- }
-
- if (dw_mode & 0x20) {
- ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box_dw,
- ibuf->index, ctx->comp_info.header_size,
- "v4l2_dec", &ibuf->header_dw_addr);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu dw\n", i);
- return -ENOMEM;
- }
- }
-
- kref_get(&ctx->box_ref);
- ibuf->ref = 1;
-
- /* frame SG buffer need to be realloc inside decoder,
- * just before slice decoding to save memory
- */
- u_info.type = VF_SRC_DECODER;
- u_info.arg = ibuf;
- u_info.free = internal_buf_free;
-
- if (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO) {
- /* adapted video composer to use for hwc. */
- ibuf->priv_data.v4l_inst_id = ctx->id;
- u_info.type = VF_PROCESS_V4LVIDEO;
- u_info.arg = &ibuf->priv_data;
- u_info.free = internal_buf_free2;
- }
-
- ret = dmabuf_is_uvm(dma) ?
- uvm_attach_hook_mod(dma, &u_info) :
- uvm_attach_hook_mod_local(ctx, &u_info);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to set dmabuf priv buf\n");
- goto bmmu_box_free;
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, bind vb2:(%d, %px) <--> internal: (%d, %px) header_addr 0x%lx, size: %u\n",
- __func__, buf->vb.vb2_buf.index,
- dma, i, ibuf, ibuf->header_addr,
- ctx->comp_info.header_size);
-
- return 0;
-
-bmmu_box_free:
- if (dw_mode & 0x20) {
- decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
- }
- decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
- kref_put(&ctx->box_ref, box_release);
- ibuf->ref = 0;
- return -EINVAL;
-}
-
-static int aml_uvm_buff_attach(struct vb2_buffer * vb)
-{
- int ret = 0;
- struct dma_buf *dbuf = vb->planes[0].dbuf;
- struct uvm_hook_mod_info u_info;
- struct aml_vcodec_ctx *ctx =
- vb2_get_drv_priv(vb->vb2_queue);
- struct aml_uvm_buff_ref *ubuf = NULL;
-
- if (vb->memory != VB2_MEMORY_DMABUF || !dmabuf_is_uvm(dbuf))
- return 0;
-
- ubuf = vzalloc(sizeof(struct aml_uvm_buff_ref));
- if (ubuf == NULL)
- return -ENOMEM;
-
- ubuf->index = vb->index;
- ubuf->addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- ubuf->dbuf = dbuf;
- ubuf->ref = &ctx->ctx_ref;
-
- u_info.type = VF_PROCESS_DECODER;
- u_info.arg = (void *)ubuf;
- u_info.free = aml_uvm_buf_free;
- ret = uvm_attach_hook_mod(dbuf, &u_info);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "aml uvm buffer %d attach fail.\n",
- ubuf->index);
- return ret;
- }
-
- kref_get(ubuf->ref);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "%s, vb:%d, dbuf:%px, ino:%lu\n",
- __func__, ubuf->index, ubuf->dbuf,
- file_inode(ubuf->dbuf->file)->i_ino);
-
- return ret;
-}
-
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
- struct vb2_buffer *vb)
-{
- struct aml_dec_params *parms = &ctx->config.parm.dec;
- bool is_v4lvideo = (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO);
- enum uvm_hook_mod_type u_type =
- is_v4lvideo ? VF_PROCESS_V4LVIDEO : VF_SRC_DECODER;
- struct dma_buf *dbuf = vb->planes[0].dbuf;
- struct internal_comp_buf *ibuf = NULL;
- struct uvm_hook_mod *uhmod = NULL;
-
- uhmod = uvm_get_hook_mod(dbuf, u_type);
- if (IS_ERR_OR_NULL(uhmod))
- return NULL;
-
- ibuf = !is_v4lvideo ? (struct internal_comp_buf *) uhmod->arg :
- container_of(uhmod->arg, struct internal_comp_buf, priv_data);
-
- uvm_put_hook_mod(dbuf, u_type);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s, vb2: (%d, %px) --> comp: (%d, %px)\n",
- __func__, vb->index, dbuf, ibuf->index, ibuf);
-
- return ibuf;
-}
-
static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
{
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- struct aml_video_dec_buf *buf =
- container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
+ struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+ struct aml_video_dec_buf *buf = NULL;
struct aml_vcodec_mem src_mem;
+ unsigned int dpb = 0;
+
+ vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+ buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, vb: %lx, type: %d, idx: %d, state: %d, used: %d, ts: %llu\n",
__func__, (ulong) vb, vb->vb2_queue->type,
vb->index, vb->state, buf->used, vb->timestamp);
-
/*
* check if this buffer is ready to be used after decode
*/
if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+ if (vb->index >= ctx->dpb_size) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "enque capture buf idx %d/%d is invalid.\n",
+ vb->index, ctx->dpb_size);
return;
-
}
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+ "y_addr: %lx, vf_h: %lx, state: %d",
+ buf->frame_buffer.m.mem[0].addr,
+ buf->frame_buffer.vf_handle,
+ buf->frame_buffer.status);
+
if (!buf->que_in_m2m) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
"enque capture buf idx %d, vf: %lx\n",
vb->index, (ulong) v4l_get_vf_handle(vb2_v4l2->private));
- /* bind compressed buffer to uvm */
- if ((dw_mode != VDEC_DW_NO_AFBC) &&
- vb->memory == VB2_MEMORY_DMABUF &&
- bind_comp_buffer_to_uvm(ctx, buf)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to bind comp buffer\n");
- return;
- }
-
- /* DI hook must be detached if the dmabuff be reused. */
- if (ctx->vpp_cfg.enable_local_buf) {
- struct dma_buf *dma = vb->planes[0].dbuf;
-
- if (dmabuf_is_uvm(dma) &&
- uvm_detach_hook_mod(dma, VF_PROCESS_DI) < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "dmabuf without attach DI hook.\n");
- }
- }
-
- task_chain_clean(fb->task);
-
- ctx->cap_pool.seq[ctx->cap_pool.in++] =
- (V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
buf->que_in_m2m = true;
-
- fb->status = FB_ST_INIT;
- ATRACE_COUNTER("VC_IN_VSINK-2.storage", vb->index);
+ buf->queued_in_vb2 = true;
+ buf->queued_in_v4l2 = true;
+ buf->ready_to_display = false;
+ ctx->cap_pool.seq[ctx->cap_pool.in++] =
+ (V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
/* check dpb ready */
aml_check_dpb_ready(ctx);
- } else {
- struct vframe_s *vf = fb->vframe;
- struct task_chain_s *task = fb->task;
+ } else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
+ buf->queued_in_vb2 = false;
+ buf->queued_in_v4l2 = true;
+ buf->ready_to_display = false;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
- "IN__BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
- "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
- ctx->ada_ctx->frm_name, fb->status, vf ? vf->index_disp : -1,
- vb->index, vb,
- vf ? vf->index & 0xff : -1, vf,
- vf ? vf->timestamp : 0,
- fb->m.mem[0].addr, fb->m.mem[0].size,
- fb->m.mem[1].addr, fb->m.mem[1].size,
- fb->m.mem[2].addr, fb->m.mem[2].size);
-
- ATRACE_COUNTER("VC_IN_VSINK-4.recycle", vb->index);
-
- task->recycle(task, TASK_TYPE_V4L_SINK);
+ /* recycle vf */
+ video_vf_put(ctx->ada_ctx->recv_name,
+ &buf->frame_buffer, ctx->id);
}
-
- wake_up_interruptible(&ctx->cap_wq);
return;
}
@@ -3795,41 +2125,28 @@
return;
}
- buf->used = true;
vb2_v4l2 = to_vb2_v4l2_buffer(vb);
buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
if (buf->lastframe) {
/* This shouldn't happen. Just in case. */
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Invalid flush buffer.\n");
- buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode && (vb->memory == VB2_MEMORY_DMABUF))
- wake_up_interruptible(&ctx->wq);
-
return;
}
src_mem.index = vb->index;
src_mem.vaddr = vb2_plane_vaddr(vb, 0);
- src_mem.addr = sg_dma_address(buf->out_sgt->sgl);
+ src_mem.addr = vb2_dma_contig_plane_dma_addr(vb, 0);
src_mem.size = vb->planes[0].bytesused;
src_mem.model = vb->memory;
src_mem.timestamp = vb->timestamp;
- src_mem.meta_ptr = (ulong)buf->meta_data;
if (vdec_if_probe(ctx, &src_mem, NULL)) {
- buf->used = false;
v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ctx->is_drm_mode &&
- (src_mem.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
- } else {
- v4l2_buff_done(to_vb2_v4l2_buffer(vb),
- VB2_BUF_STATE_DONE);
- }
-
+ if (!(ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF))
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE);
return;
}
@@ -3837,14 +2154,11 @@
* If on model dmabuf must remove the buffer
* because this data has been consumed by hw.
*/
- buf->used = false;
- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
- if (ctx->is_drm_mode &&
- (src_mem.model == VB2_MEMORY_DMABUF)) {
- wake_up_interruptible(&ctx->wq);
+ if (ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF) {
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
} else if (ctx->param_sets_from_ucode) {
- v4l2_buff_done(to_vb2_v4l2_buffer(vb),
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb),
VB2_BUF_STATE_DONE);
}
@@ -3854,24 +2168,23 @@
return;
}
- if (!ctx->picinfo.dpb_frames)
+ if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "GET_PARAM_DPB_SIZE err\n");
+ return;
+ }
+
+ if (!dpb)
return;
- v4l_buf_size_decision(ctx);
+ ctx->dpb_size = dpb;
ctx->last_decoded_picinfo = ctx->picinfo;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "Picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
- ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
- ctx->picinfo.dpb_margin,
- CTX_BUF_TOTAL(ctx));
-
aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
mutex_lock(&ctx->state_lock);
if (ctx->state == AML_STATE_INIT) {
ctx->state = AML_STATE_PROBE;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_PROBE)\n");
}
@@ -3883,19 +2196,26 @@
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
struct aml_video_dec_buf *buf = NULL;
+ bool buf_error;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
"%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
- vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+ vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- if (buf->error) {
+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+ buf->queued_in_v4l2 = false;
+ buf->queued_in_vb2 = false;
+ }
+ buf_error = buf->error;
+
+ if (buf_error) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Unrecoverable error on buffer.\n");
ctx->state = AML_STATE_ABORT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+ ATRACE_COUNTER("v4l2_state", ctx->state);
v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
"vcodec state (AML_STATE_ABORT)\n");
}
@@ -3908,145 +2228,108 @@
struct vb2_v4l2_buffer, vb2_buf);
struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
- u32 size, phy_addr = 0;
- int i;
+ unsigned int size, phy_addr = 0;
+ char *owner = __getname();
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
__func__, vb->vb2_queue->type, vb->index);
- if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+ if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+ buf->used = false;
+ buf->ready_to_display = false;
+ buf->queued_in_v4l2 = false;
+ buf->frame_buffer.status = FB_ST_NORMAL;
+ } else {
buf->lastframe = false;
}
/* codec_mm buffers count */
- if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
+ if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
if (vb->memory == VB2_MEMORY_MMAP) {
- char *owner = __getname();
-
- snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
+ size = vb->planes[0].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id);
strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
- __putname(owner);
- for (i = 0; i < vb->num_planes; i++) {
- size = vb->planes[i].length;
- phy_addr = vb2_dma_contig_plane_dma_addr(vb, i);
- buf->mem[i] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
- phy_addr, size, vb->index);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "OUT %c alloc, addr: %x, size: %u, idx: %u\n",
- (i == 0? 'Y':'C'), phy_addr, size, vb->index);
- }
- } else if (vb->memory == VB2_MEMORY_DMABUF) {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
+ buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "IN alloc, addr: %x, size: %u, idx: %u\n",
+ phy_addr, size, vb->index);
+ }
+ } else {
+ snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
+ strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
+ buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
- for (i = 0; i < vb->num_planes; i++) {
- struct dma_buf * dma;
+ if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 1)) {
+ size = vb->planes[0].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "OUT Y alloc, addr: %x, size: %u, idx: %u\n",
+ phy_addr, size, vb->index);
+ } else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) {
+ size = vb->planes[0].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "OUT Y alloc, addr: %x, size: %u, idx: %u\n",
+ phy_addr, size, vb->index);
- if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
- return -EINVAL;
- }
- /* None-DW mode means single layer */
- if (dw_mode == VDEC_DW_AFBC_ONLY && i > 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "only support single plane in dw mode 0\n");
- return -EINVAL;
- }
- size = vb->planes[i].length;
- dma = vb->planes[i].dbuf;
-
- if (!dmabuf_is_uvm(dma))
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "non-uvm dmabuf\n");
- }
+ size = vb->planes[1].length;
+ phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
+ buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+ phy_addr, size, vb->index);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "OUT C alloc, addr: %x, size: %u, idx: %u\n",
+ phy_addr, size, vb->index);
}
}
- if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
- struct vframe_s *vf = NULL;
- struct task_chain_s *task = NULL;
- struct task_chain_s *task_pre = fb->task;
- u32 icomp = -1;
-
- fb_map_table_fetch(ctx, vb, &vf, &task, &icomp);
- if (vf) {
- fb->task = task;
- fb->vframe = vf;
- vf->v4l_mem_handle = (ulong)fb;
- buf->internal_index = icomp;
- task_chain_update_object(task, fb);
- } else {
- buf->que_in_m2m = false;
-
- if (aml_uvm_buff_attach(vb))
- return -EFAULT;
-
- if (task_chain_init(&fb->task, ctx, fb, vb->index))
- return -EFAULT;
-
- list_add(&fb->task->node, &ctx->task_chain_pool);
- }
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "init buffer(%s), vb idx:%d, task:(%px -> %px), addr:(%lx -> %lx), icomp:%d\n",
- vf ? "update" : "idel",
- vb->index, task_pre, fb->task,
- fb->m.mem[0].addr,
- (ulong) vb2_dma_contig_plane_dma_addr(vb, 0),
- (int)icomp);
-
- update_vdec_buf_plane(ctx, fb, vb);
- }
-
- if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
- ulong contig_size;
-
- buf->out_sgt = vb2_dma_sg_plane_desc(vb, 0);
-
- contig_size = dmabuf_contiguous_size(buf->out_sgt);
- if (contig_size < vb->planes[0].bytesused) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "contiguous mapping is too small %lu/%u\n",
- contig_size, size);
- return -EFAULT;
- }
- }
+ __putname(owner);
return 0;
}
-static void vb2ops_vdec_buf_cleanup(struct vb2_buffer *vb)
+static void codec_mm_bufs_cnt_clean(struct vb2_queue *q)
{
- struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
- struct vb2_v4l2_buffer, vb2_buf);
- struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
- struct aml_video_dec_buf, vb);
- struct vdec_v4l2_buffer *fb = &buf->frame_buffer;;
+ struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
+ struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+ struct aml_video_dec_buf *buf = NULL;
+ int i;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
- __func__, vb->vb2_queue->type, vb->index);
+ for (i = 0; i < q->num_buffers; ++i) {
+ vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
+ buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+ if (IS_ERR_OR_NULL(buf->mem[0]))
+ return;
- if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
- if (vb->memory == VB2_MEMORY_MMAP) {
- int i;
+ if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) {
+ v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
- for (i = 0; i < vb->num_planes ; i++) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
- "OUT %c clean, addr: %lx, size: %u, idx: %u\n",
- (i == 0)? 'Y':'C',
- buf->mem[i]->phy_addr, buf->mem[i]->buffer_size, vb->index);
- v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[i]);
- buf->mem[i] = NULL;
- }
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "IN clean, addr: %lx, size: %u, idx: %u\n",
+ buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
+ buf->mem[0] = NULL;
+ continue;
}
- if (ctx->output_thread_ready) {
- if (!is_fb_mapped(ctx, fb->m.mem[0].addr)) {
- list_del(&fb->task->node);
- task_chain_clean(fb->task);
- task_chain_release(fb->task);
- }
+
+ if (q->memory == VB2_MEMORY_MMAP) {
+ v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
+ v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "OUT Y clean, addr: %lx, size: %u, idx: %u\n",
+ buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+ "OUT C clean, addr: %lx, size: %u, idx: %u\n",
+ buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
+ buf->mem[0] = NULL;
+ buf->mem[1] = NULL;
}
}
}
@@ -4056,10 +2339,6 @@
struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
ctx->has_receive_eos = false;
- ctx->v4l_resolution_change = false;
-
- /* vdec has ready to decode subsequence data of new resolution. */
- v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
@@ -4080,81 +2359,40 @@
"%s, type: %d, state: %x, frame_cnt: %d\n",
__func__, q->type, ctx->state, ctx->decoded_frame_cnt);
- if (V4L2_TYPE_IS_OUTPUT(q->type))
- ctx->is_out_stream_off = true;
- else
- ctx->is_stream_off = true;
+ codec_mm_bufs_cnt_clean(q);
if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
- unsigned long flags;
-
- cancel_work_sync(&ctx->dmabuff_recycle_work);
- spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
- INIT_KFIFO(ctx->dmabuff_recycle);
- spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
- v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
for (i = 0; i < q->num_buffers; ++i) {
vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
- v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
- }
-
- /*
- * drop es frame was stored in the vdec_input
- * if the capture queue have not start streaming.
- */
- if (!que->streaming &&
- (vdec_frame_number(ctx->ada_ctx) > 0) &&
- (ctx->state < AML_STATE_ACTIVE)) {
- ctx->state = AML_STATE_INIT;
- ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
- ctx->v4l_resolution_change = false;
- ctx->reset_flag = V4L_RESET_MODE_NORMAL;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "force reset to drop es frames.\n");
- wake_up_interruptible(&ctx->cap_wq);
- aml_vdec_reset(ctx);
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
}
} else {
/* clean output cache and decoder status . */
- if (ctx->state > AML_STATE_INIT) {
- wake_up_interruptible(&ctx->cap_wq);
+ if (ctx->state > AML_STATE_INIT)
aml_vdec_reset(ctx);
- }
-
- cancel_work_sync(&ctx->decode_work);
- mutex_lock(&ctx->capture_buffer_lock);
- INIT_KFIFO(ctx->capture_buffer);
- mutex_unlock(&ctx->capture_buffer_lock);
while ((vb2_v4l2 = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)))
- v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
for (i = 0; i < q->num_buffers; ++i) {
vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
- buf->frame_buffer.status = FB_ST_FREE;
- buf->frame_buffer.vframe = NULL;
- buf->que_in_m2m = false;
- buf->used = false;
- buf->vb.flags = 0;
- ctx->cap_pool.seq[i] = 0;
+ buf->frame_buffer.status = FB_ST_NORMAL;
+ buf->que_in_m2m = false;
+ buf->vb.flags = 0;
+ ctx->cap_pool.seq[i] = 0;
if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
- v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
/*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "idx: %d, state: %d\n",
q->bufs[i]->index, q->bufs[i]->state);*/
}
- fb_map_table_clean(ctx);
-
- fb_token_clean(ctx);
-
ctx->buf_used_count = 0;
ctx->cap_pool.in = 0;
ctx->cap_pool.out = 0;
@@ -4172,6 +2410,15 @@
queue_work(dev->decode_workqueue, &ctx->decode_work);
}
+void vdec_device_vf_run(struct aml_vcodec_ctx *ctx)
+{
+ if (ctx->state < AML_STATE_INIT ||
+ ctx->state > AML_STATE_FLUSHED)
+ return;
+
+ aml_thread_notify(ctx, AML_THREAD_CAPTURE);
+}
+
static int m2mops_vdec_job_ready(void *m2m_priv)
{
struct aml_vcodec_ctx *ctx = m2m_priv;
@@ -4201,23 +2448,17 @@
switch (ctrl->id) {
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
if (ctx->state >= AML_STATE_PROBE) {
- ctrl->val = CTX_BUF_TOTAL(ctx);
+ ctrl->val = ctx->dpb_size;
} else {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Seqinfo not ready.\n");
ctrl->val = 0;
+ ret = -EINVAL;
}
break;
case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
ctrl->val = 4;
break;
- case AML_V4L2_GET_INPUT_BUFFER_NUM:
- if (ctx->ada_ctx != NULL)
- ctrl->val = vdec_frame_number(ctx->ada_ctx);
- break;
- case AML_V4L2_GET_FILMGRAIN_INFO:
- ctrl->val = ctx->film_grain_present;
- break;
default:
ret = -EINVAL;
}
@@ -4235,10 +2476,6 @@
ctx->param_sets_from_ucode = true;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
"set stream mode: %x\n", ctrl->val);
- } else if (ctrl->id == AML_V4L2_SET_DURATION) {
- vdec_set_duration(ctrl->val);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "set duration: %x\n", ctrl->val);
}
return 0;
@@ -4261,42 +2498,6 @@
.def = 0,
};
-static const struct v4l2_ctrl_config ctrl_gt_input_buffer_number = {
- .name = "input buffer number",
- .id = AML_V4L2_GET_INPUT_BUFFER_NUM,
- .ops = &aml_vcodec_dec_ctrl_ops,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_VOLATILE,
- .min = 0,
- .max = 128,
- .step = 1,
- .def = 0,
-};
-
-static const struct v4l2_ctrl_config ctrl_st_duration = {
- .name = "duration",
- .id = AML_V4L2_SET_DURATION,
- .ops = &aml_vcodec_dec_ctrl_ops,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
- .min = 0,
- .max = 96000,
- .step = 1,
- .def = 0,
-};
-
-static const struct v4l2_ctrl_config ctrl_gt_filmgrain_info = {
- .name = "filmgrain info",
- .id = AML_V4L2_GET_FILMGRAIN_INFO,
- .ops = &aml_vcodec_dec_ctrl_ops,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_VOLATILE,
- .min = 0,
- .max = 1,
- .step = 1,
- .def = 0,
-};
-
int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
{
int ret;
@@ -4307,42 +2508,24 @@
&aml_vcodec_dec_ctrl_ops,
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
0, 32, 1, 2);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ if (ctx->ctrl_hdl.error) {
ret = ctx->ctrl_hdl.error;
goto err;
}
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl,
&aml_vcodec_dec_ctrl_ops,
V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
0, 32, 1, 8);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ if (ctx->ctrl_hdl.error) {
ret = ctx->ctrl_hdl.error;
goto err;
}
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_mode, NULL);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
- ret = ctx->ctrl_hdl.error;
- goto err;
- }
-
- ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_input_buffer_number, NULL);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
- ret = ctx->ctrl_hdl.error;
- goto err;
- }
-
- ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_duration, NULL);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
- ret = ctx->ctrl_hdl.error;
- goto err;
- }
-
- ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_filmgrain_info, NULL);
- if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+ if (ctx->ctrl_hdl.error) {
ret = ctx->ctrl_hdl.error;
goto err;
}
@@ -4362,25 +2545,16 @@
struct v4l2_streamparm *a)
{
struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
- struct vb2_queue *dst_vq;
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!dst_vq) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
- return -EINVAL;
- }
-
- if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar)
- return -EINVAL;
-
- if ((a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) || (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
- if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO, &ctx->config.parm.dec))
+ if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO,
+ &ctx->config.parm.dec)) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"GET_PARAM_CONFIG_INFO err\n");
- else
- memcpy(a->parm.raw_data, ctx->config.parm.data,
- sizeof(a->parm.raw_data));
+ return -1;
+ }
+ memcpy(a->parm.raw_data, ctx->config.parm.data,
+ sizeof(a->parm.raw_data));
}
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
@@ -4388,65 +2562,22 @@
return 0;
}
-static int check_dec_cfginfo(struct aml_vdec_cfg_infos *cfg)
-{
- if (cfg->double_write_mode != 0 &&
- cfg->double_write_mode != 1 &&
- cfg->double_write_mode != 2 &&
- cfg->double_write_mode != 3 &&
- cfg->double_write_mode != 4 &&
- cfg->double_write_mode != 16 &&
- cfg->double_write_mode != 0x21 &&
- cfg->double_write_mode != 0x100 &&
- cfg->double_write_mode != 0x200) {
- pr_err("invalid double write mode %d\n", cfg->double_write_mode);
- return -1;
- }
- if (cfg->ref_buf_margin > 20) {
- pr_err("invalid margin %d\n", cfg->ref_buf_margin);
- return -1;
- }
-
- if (mandatory_dw_mmu) {
- cfg->double_write_mode = 0x21;
- }
-
- pr_info("double write mode %d margin %d\n",
- cfg->double_write_mode, cfg->ref_buf_margin);
- return 0;
-}
-
static int vidioc_vdec_s_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{
struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
- struct vb2_queue *dst_vq;
v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (!dst_vq) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
- return -EINVAL;
- }
-
- if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar)
- return -EINVAL;
-
- if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
- a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
struct aml_dec_params *in =
(struct aml_dec_params *) a->parm.raw_data;
struct aml_dec_params *dec = &ctx->config.parm.dec;
ctx->config.type = V4L2_CONFIG_PARM_DECODE;
- if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
- if (check_dec_cfginfo(&in->cfg))
- return -EINVAL;
+ if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
dec->cfg = in->cfg;
- }
if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
dec->ps = in->ps;
if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -4455,37 +2586,31 @@
dec->cnt = in->cnt;
dec->parms_status |= in->parms_status;
-
- /* aml v4l driver parms config. */
- ctx->vpp_cfg.enable_nr =
- (dec->cfg.metadata_config_flag & (1 << 15));
- if (force_enable_nr)
- ctx->vpp_cfg.enable_nr = true;
-
- ctx->vpp_cfg.enable_local_buf =
- (dec->cfg.metadata_config_flag & (1 << 14));
- if (force_enable_di_local_buffer)
- ctx->vpp_cfg.enable_local_buf = true;
-
- ctx->internal_dw_scale = dec->cfg.metadata_config_flag & (1 << 13);
- ctx->second_field_pts_mode = dec->cfg.metadata_config_flag & (1 << 12);
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s parms:%x metadata_config_flag: 0x%x\n",
- __func__, in->parms_status, dec->cfg.metadata_config_flag);
-
- memset(a->parm.output.reserved, 0, sizeof(a->parm.output.reserved));
- } else {
- memset(a->parm.capture.reserved, 0, sizeof(a->parm.capture.reserved));
}
return 0;
}
+static void m2mops_vdec_lock(void *m2m_priv)
+{
+ struct aml_vcodec_ctx *ctx = m2m_priv;
+
+ mutex_lock(&ctx->dev->dev_mutex);
+}
+
+static void m2mops_vdec_unlock(void *m2m_priv)
+{
+ struct aml_vcodec_ctx *ctx = m2m_priv;
+
+ mutex_unlock(&ctx->dev->dev_mutex);
+}
const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
.device_run = m2mops_vdec_device_run,
.job_ready = m2mops_vdec_job_ready,
.job_abort = m2mops_vdec_job_abort,
+ .lock = m2mops_vdec_lock,
+ .unlock = m2mops_vdec_unlock,
};
static const struct vb2_ops aml_vdec_vb2_ops = {
@@ -4495,7 +2620,6 @@
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
.buf_init = vb2ops_vdec_buf_init,
- .buf_cleanup = vb2ops_vdec_buf_cleanup,
.buf_finish = vb2ops_vdec_buf_finish,
.start_streaming = vb2ops_vdec_start_streaming,
.stop_streaming = vb2ops_vdec_stop_streaming,
@@ -4512,10 +2636,10 @@
.vidioc_qbuf = vidioc_vdec_qbuf,
.vidioc_dqbuf = vidioc_vdec_dqbuf,
- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_out,
- .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_out,
- .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_cap_out,
- .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_cap_out,
+ .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap_mplane,
+ .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out_mplane,
.vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
.vidioc_s_fmt_vid_cap = vidioc_vdec_s_fmt,
@@ -4528,18 +2652,17 @@
.vidioc_create_bufs = vidioc_vdec_create_bufs,
- //fixme
- //.vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane,
- //.vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
+ .vidioc_enum_fmt_vid_cap_mplane = vidioc_vdec_enum_fmt_vid_cap_mplane,
.vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
.vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out_mplane,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_querycap = vidioc_vdec_querycap,
.vidioc_subscribe_event = vidioc_vdec_subscribe_evt,
.vidioc_unsubscribe_event = vidioc_vdec_event_unsubscribe,
- .vidioc_g_selection = vidioc_vdec_g_selection,
- .vidioc_s_selection = vidioc_vdec_s_selection,
+ .vidioc_g_selection = vidioc_vdec_g_selection,
+ .vidioc_s_selection = vidioc_vdec_s_selection,
.vidioc_decoder_cmd = vidioc_decoder_cmd,
.vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
@@ -4557,11 +2680,11 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
+ src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
src_vq->drv_priv = ctx;
src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
src_vq->ops = &aml_vdec_vb2_ops;
- src_vq->mem_ops = &vb2_dma_sg_memops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
src_vq->lock = &ctx->dev->dev_mutex;
ret = vb2_queue_init(src_vq);
@@ -4580,7 +2703,6 @@
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
dst_vq->lock = &ctx->dev->dev_mutex;
- dst_vq->min_buffers_needed = 1;
ret = vb2_queue_init(dst_vq);
if (ret) {
vb2_queue_release(src_vq);
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index a23522c..3653ff0 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -20,14 +20,11 @@
#ifndef _AML_VCODEC_DEC_H_
#define _AML_VCODEC_DEC_H_
-#include <linux/kref.h>
-#include <linux/scatterlist.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
#include "aml_vcodec_util.h"
-#include "aml_task_chain.h"
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
@@ -41,25 +38,15 @@
#define VDEC_GATHER_MEMORY_TYPE 0
#define VDEC_SCATTER_MEMORY_TYPE 1
-#define META_DATA_SIZE (256)
-#define MD_BUF_SIZE (1024)
-#define COMP_BUF_SIZE (8196)
-#define SEI_BUF_SIZE (2 * 12 * 1024)
-#define SEI_TYPE (1)
-#define DV_TYPE (2)
-
-
-/*
- * struct vdec_v4l2_buffer - decoder frame buffer
+/**
+ * struct vdec_fb - decoder frame buffer
* @mem_type : gather or scatter memory.
* @num_planes : used number of the plane
* @mem[4] : array mem for used planes,
* mem[0]: Y, mem[1]: C/U, mem[2]: V
* @vf_fd : the file handle of video frame
+ * @vf_handle : video frame handle
* @status : frame buffer status (vdec_fb_status)
- * @buf_idx : the index from vb2 index.
- * @vframe : store the vframe that get from caller.
- * @task : the context of task chain manager.
*/
struct vdec_v4l2_buffer {
@@ -69,19 +56,22 @@
struct aml_vcodec_mem mem[4];
u32 vf_fd;
} m;
+ ulong vf_handle;
u32 status;
u32 buf_idx;
- void *vframe;
-
- struct task_chain_s *task;
};
+
/**
* struct aml_video_dec_buf - Private data related to each VB2 buffer.
* @b: VB2 buffer
* @list: link list
* @used: Capture buffer contain decoded frame data and keep in
* codec data structure
+ * @ready_to_display: Capture buffer not display yet
+ * @queued_in_vb2: Capture buffer is queue in vb2
+ * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2
+ * queue yet
* @lastframe: Intput buffer is last buffer - EOS
* @error: An unrecoverable error occurs on this buffer.
* @frame_buffer: Decode status, and buffer information of Capture buffer
@@ -97,21 +87,12 @@
struct codec_mm_s *mem[2];
char mem_onwer[32];
bool used;
+ bool ready_to_display;
bool que_in_m2m;
+ bool queued_in_vb2;
+ bool queued_in_v4l2;
bool lastframe;
bool error;
-
- /* internal compressed buffer */
- unsigned int internal_index;
-
- ulong vpp_buf_handle;
- ulong ge2d_buf_handle;
-
- /*4 bytes data for data len*/
- char meta_data[META_DATA_SIZE + 4];
-
- struct sg_table *out_sgt;
- struct sg_table *cap_sgt;
};
extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops;
@@ -130,19 +111,16 @@
void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx);
void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx);
int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx);
+void vdec_device_vf_run(struct aml_vcodec_ctx *ctx);
+void try_to_capture(struct aml_vcodec_ctx *ctx);
+void aml_thread_notify(struct aml_vcodec_ctx *ctx,
+ enum aml_thread_type type);
+int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
+ enum aml_thread_type type, const char *thread_name);
+void aml_thread_stop(struct aml_vcodec_ctx *ctx);
void wait_vcodec_ending(struct aml_vcodec_ctx *ctx);
void vdec_frame_buffer_release(void *data);
void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes);
void* v4l_get_vf_handle(int fd);
-void aml_v4l_ctx_release(struct kref *kref);
-void dmabuff_recycle_worker(struct work_struct *work);
-void aml_buffer_status(struct aml_vcodec_ctx *ctx);
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx);
-
-void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag);
-void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag);
-void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
-void aml_bind_sei_buffer(struct aml_vcodec_ctx *v4l, char **addr, int *size, int *idx);
-void aml_bind_dv_buffer(struct aml_vcodec_ctx *v4l, char **comp_buf, char **md_buf);
#endif /* _AML_VCODEC_DEC_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
index 18f0254..1ed0b97 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -29,11 +29,11 @@
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
#include <linux/kthread.h>
-#include <linux/compat.h>
+
#include "aml_vcodec_drv.h"
#include "aml_vcodec_dec.h"
#include "aml_vcodec_util.h"
-#include "aml_vcodec_vpp.h"
+#include "aml_vcodec_vfm.h"
#include <linux/file.h>
#include <linux/anon_inodes.h>
@@ -50,7 +50,6 @@
bool param_sets_from_ucode = 1;
bool enable_drm_mode;
-extern void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx);
static int fops_vcodec_open(struct file *file)
{
@@ -63,21 +62,12 @@
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
- kref_init(&ctx->ctx_ref);
-
aml_buf = kzalloc(sizeof(*aml_buf), GFP_KERNEL);
if (!aml_buf) {
kfree(ctx);
return -ENOMEM;
}
- ctx->meta_infos.meta_bufs = vzalloc(sizeof(struct meta_data) * V4L_CAP_BUFF_MAX);
- if (ctx->meta_infos.meta_bufs == NULL) {
- kfree(aml_buf);
- kfree(ctx);
- return -ENOMEM;
- }
-
mutex_lock(&dev->dev_mutex);
ctx->empty_flush_buf = aml_buf;
ctx->id = dev->id_counter++;
@@ -86,26 +76,14 @@
v4l2_fh_add(&ctx->fh);
INIT_LIST_HEAD(&ctx->list);
INIT_LIST_HEAD(&ctx->vdec_thread_list);
- INIT_LIST_HEAD(&ctx->task_chain_pool);
dev->filp = file;
ctx->dev = dev;
init_waitqueue_head(&ctx->queue);
- mutex_init(&ctx->capture_buffer_lock);
- mutex_init(&ctx->buff_done_lock);
mutex_init(&ctx->state_lock);
- mutex_init(&ctx->comp_lock);
+ mutex_init(&ctx->lock);
spin_lock_init(&ctx->slock);
- spin_lock_init(&ctx->tsplock);
- spin_lock_init(&ctx->dmabuff_recycle_lock);
init_completion(&ctx->comp);
- init_waitqueue_head(&ctx->wq);
- init_waitqueue_head(&ctx->cap_wq);
- init_waitqueue_head(&ctx->post_done_wq);
- INIT_WORK(&ctx->dmabuff_recycle_work, dmabuff_recycle_worker);
- INIT_KFIFO(ctx->dmabuff_recycle);
- INIT_KFIFO(ctx->capture_buffer);
- ctx->post_to_upper_done = true;
ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0;
if (enable_drm_mode) {
@@ -133,19 +111,9 @@
ctx->output_thread_ready = true;
ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
ctx->empty_flush_buf->lastframe = true;
- ctx->vdec_pic_info_update = aml_vdec_pic_info_update;
aml_vcodec_dec_set_default_params(ctx);
- ctx->is_stream_off = true;
- ctx->aux_infos.dv_index = 0;
- ctx->aux_infos.sei_index = 0;
- ctx->aux_infos.alloc_buffer = aml_alloc_buffer;
- ctx->aux_infos.free_buffer = aml_free_buffer;
- ctx->aux_infos.bind_sei_buffer = aml_bind_sei_buffer;
- ctx->aux_infos.bind_dv_buffer = aml_bind_dv_buffer;
- ctx->aux_infos.free_one_sei_buffer = aml_free_one_sei_buffer;
-
- ret = aml_thread_start(ctx, aml_thread_capture_worker, AML_THREAD_CAPTURE, "cap");
+ ret = aml_thread_start(ctx, try_to_capture, AML_THREAD_CAPTURE, "cap");
if (ret) {
v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
"Failed to creat capture thread.\n");
@@ -158,7 +126,7 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n",
dev_name(&dev->plat_dev->dev), (ulong)ctx);
- return 0;
+ return ret;
/* Deinit when failure occurred */
err_creat_thread:
@@ -168,7 +136,6 @@
err_ctrls_setup:
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
- vfree(ctx->meta_infos.meta_bufs);
kfree(ctx->empty_flush_buf);
kfree(ctx);
mutex_unlock(&dev->dev_mutex);
@@ -184,20 +151,24 @@
v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx);
mutex_lock(&dev->dev_mutex);
+ /*
+ * Call v4l2_m2m_ctx_release before aml_vcodec_dec_release. First, it
+ * makes sure the worker thread is not running after vdec_if_deinit.
+ * Second, the decoder will be flushed and all the buffers will be
+ * returned in stop_streaming.
+ */
aml_thread_stop(ctx);
wait_vcodec_ending(ctx);
- vb2_queue_release(&ctx->m2m_ctx->cap_q_ctx.q);
- vb2_queue_release(&ctx->m2m_ctx->out_q_ctx.q);
-
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
aml_vcodec_dec_release(ctx);
+
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
list_del_init(&ctx->list);
-
kfree(ctx->empty_flush_buf);
- kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
+ kfree(ctx);
mutex_unlock(&dev->dev_mutex);
return 0;
}
@@ -331,10 +302,8 @@
if (!is_v4l2_buf_file(file)) {
fput(file);
-#if 0
v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the buf file checked fail!\n");
-#endif
return NULL;
}
@@ -446,43 +415,6 @@
.mmap = v4l2_m2m_fop_mmap,
};
-static ssize_t status_show(struct class *cls,
- struct class_attribute *attr, char *buf)
-{
- struct aml_vcodec_dev *dev = container_of(cls,
- struct aml_vcodec_dev, v4ldec_class);
- struct aml_vcodec_ctx *ctx = NULL;
- char *pbuf = buf;
-
- mutex_lock(&dev->dev_mutex);
-
- if (list_empty(&dev->ctx_list)) {
- pbuf += sprintf(pbuf, "No v4ldec context.\n");
- goto out;
- }
-
- list_for_each_entry(ctx, &dev->ctx_list, list) {
- /* basic information. */
- aml_vdec_basic_information(ctx);
-
- /* buffers status. */
- aml_buffer_status(ctx);
- }
-out:
- mutex_unlock(&dev->dev_mutex);
-
- return pbuf - buf;
-}
-
-static CLASS_ATTR_RO(status);
-
-static struct attribute *v4ldec_class_attrs[] = {
- &class_attr_status.attr,
- NULL
-};
-
-ATTRIBUTE_GROUPS(v4ldec_class);
-
static int aml_vcodec_probe(struct platform_device *pdev)
{
struct aml_vcodec_dev *dev;
@@ -495,7 +427,6 @@
INIT_LIST_HEAD(&dev->ctx_list);
dev->plat_dev = pdev;
- atomic_set(&dev->vpp_count, 0);
mutex_init(&dev->dec_mutex);
mutex_init(&dev->dev_mutex);
@@ -506,7 +437,8 @@
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret) {
- dev_err(&pdev->dev, "v4l2_device_register err=%d\n", ret);
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "v4l2_device_register err=%d\n", ret);
goto err_res;
}
@@ -514,7 +446,8 @@
vfd_dec = video_device_alloc();
if (!vfd_dec) {
- dev_err(&pdev->dev, "Failed to allocate video device\n");
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "Failed to allocate video device\n");
ret = -ENOMEM;
goto err_dec_alloc;
}
@@ -526,7 +459,7 @@
vfd_dec->v4l2_dev = &dev->v4l2_dev;
vfd_dec->vfl_dir = VFL_DIR_M2M;
vfd_dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_STREAMING;
+ V4L2_CAP_STREAMING;
snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
AML_VCODEC_DEC_NAME);
@@ -536,16 +469,18 @@
dev->m2m_dev_dec = v4l2_m2m_init(&aml_vdec_m2m_ops);
if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
- dev_err(&pdev->dev, "Failed to init mem2mem dec device\n");
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "Failed to init mem2mem dec device\n");
ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
goto err_dec_mem_init;
}
dev->decode_workqueue =
- alloc_ordered_workqueue("output-worker",
- __WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
+ alloc_ordered_workqueue(AML_VCODEC_DEC_NAME,
+ WQ_MEM_RECLAIM | WQ_FREEZABLE);
if (!dev->decode_workqueue) {
- dev_err(&pdev->dev, "Failed to create decode workqueue\n");
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "Failed to create decode workqueue\n");
ret = -EINVAL;
goto err_event_workq;
}
@@ -554,26 +489,16 @@
ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26);
if (ret) {
- dev_err(&pdev->dev, "Failed to register video device\n");
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+ "Failed to register video device\n");
goto err_dec_reg;
}
- /*init class*/
- dev->v4ldec_class.name = "v4ldec";
- dev->v4ldec_class.owner = THIS_MODULE;
- dev->v4ldec_class.class_groups = v4ldec_class_groups;
- ret = class_register(&dev->v4ldec_class);
- if (ret) {
- dev_err(&pdev->dev, "v4l dec class create fail.\n");
- goto err_reg_class;
- }
-
- dev_info(&pdev->dev, "v4ldec registered as /dev/video%d\n", vfd_dec->num);
+ v4l_dbg(0, V4L_DEBUG_CODEC_PRINFO,
+ "decoder registered as /dev/video%d\n", vfd_dec->num);
return 0;
-err_reg_class:
- class_unregister(&dev->v4ldec_class);
err_dec_reg:
destroy_workqueue(dev->decode_workqueue);
err_event_workq:
@@ -587,6 +512,13 @@
return ret;
}
+static const struct of_device_id aml_vcodec_match[] = {
+ {.compatible = "amlogic, vcodec-dec",},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, aml_vcodec_match);
+
static int aml_vcodec_dec_remove(struct platform_device *pdev)
{
struct aml_vcodec_dev *dev = platform_get_drvdata(pdev);
@@ -594,8 +526,6 @@
flush_workqueue(dev->decode_workqueue);
destroy_workqueue(dev->decode_workqueue);
- class_unregister(&dev->v4ldec_class);
-
if (dev->m2m_dev_dec)
v4l2_m2m_release(dev->m2m_dev_dec);
@@ -604,17 +534,12 @@
v4l2_device_unregister(&dev->v4l2_dev);
- dev_info(&pdev->dev, "v4ldec removed.\n");
-
return 0;
}
-static const struct of_device_id aml_vcodec_match[] = {
- {.compatible = "amlogic, vcodec-dec",},
- {},
-};
-
-MODULE_DEVICE_TABLE(of, aml_vcodec_match);
+/*static void aml_vcodec_dev_release(struct device *dev)
+{
+}*/
static struct platform_driver aml_vcodec_dec_driver = {
.probe = aml_vcodec_probe,
@@ -625,36 +550,44 @@
},
};
+/*
+static struct platform_device aml_vcodec_dec_device = {
+ .name = AML_VCODEC_DEC_NAME,
+ .dev.release = aml_vcodec_dev_release,
+};*/
+
+module_platform_driver(aml_vcodec_dec_driver);
+
+/*
static int __init amvdec_ports_init(void)
{
- pr_info("v4l dec module init\n");
+ int ret;
- if (platform_driver_register(&aml_vcodec_dec_driver)) {
- pr_err("failed to register v4l dec driver\n");
- return -ENODEV;
- }
+ ret = platform_device_register(&aml_vcodec_dec_device);
+ if (ret)
+ return ret;
- return 0;
+ ret = platform_driver_register(&aml_vcodec_dec_driver);
+ if (ret)
+ platform_device_unregister(&aml_vcodec_dec_device);
+
+ return ret;
}
static void __exit amvdec_ports_exit(void)
{
- pr_info("v4l dec module exit\n");
-
platform_driver_unregister(&aml_vcodec_dec_driver);
+ platform_device_unregister(&aml_vcodec_dec_device);
}
module_init(amvdec_ports_init);
module_exit(amvdec_ports_exit);
+*/
u32 debug_mode;
EXPORT_SYMBOL(debug_mode);
module_param(debug_mode, uint, 0644);
-u32 mandatory_dw_mmu;
-EXPORT_SYMBOL(mandatory_dw_mmu);
-module_param(mandatory_dw_mmu, uint, 0644);
-
bool aml_set_vfm_enable;
EXPORT_SYMBOL(aml_set_vfm_enable);
module_param(aml_set_vfm_enable, bool, 0644);
@@ -683,72 +616,20 @@
EXPORT_SYMBOL(multiplanar);
module_param(multiplanar, bool, 0644);
-int dump_capture_frame;
+bool dump_capture_frame;
EXPORT_SYMBOL(dump_capture_frame);
-module_param(dump_capture_frame, int, 0644);
-
-int dump_vpp_input;
-EXPORT_SYMBOL(dump_vpp_input);
-module_param(dump_vpp_input, int, 0644);
-
-int dump_ge2d_input;
-EXPORT_SYMBOL(dump_ge2d_input);
-module_param(dump_ge2d_input, int, 0644);
+module_param(dump_capture_frame, bool, 0644);
int dump_output_frame;
EXPORT_SYMBOL(dump_output_frame);
module_param(dump_output_frame, int, 0644);
-u32 dump_output_start_position;
-EXPORT_SYMBOL(dump_output_start_position);
-module_param(dump_output_start_position, uint, 0644);
-
EXPORT_SYMBOL(param_sets_from_ucode);
module_param(param_sets_from_ucode, bool, 0644);
EXPORT_SYMBOL(enable_drm_mode);
module_param(enable_drm_mode, bool, 0644);
-int bypass_vpp;
-EXPORT_SYMBOL(bypass_vpp);
-module_param(bypass_vpp, int, 0644);
-
-int bypass_ge2d;
-EXPORT_SYMBOL(bypass_ge2d);
-module_param(bypass_ge2d, int, 0644);
-
-int max_di_instance = 2;
-EXPORT_SYMBOL(max_di_instance);
-module_param(max_di_instance, int, 0644);
-
-int bypass_progressive = 1;
-EXPORT_SYMBOL(bypass_progressive);
-module_param(bypass_progressive, int, 0644);
-
-bool support_mjpeg;
-EXPORT_SYMBOL(support_mjpeg);
-module_param(support_mjpeg, bool, 0644);
-
-bool support_format_I420;
-EXPORT_SYMBOL(support_format_I420);
-module_param(support_format_I420, bool, 0644);
-
-int force_enable_nr;
-EXPORT_SYMBOL(force_enable_nr);
-module_param(force_enable_nr, int, 0644);
-
-int force_enable_di_local_buffer;
-EXPORT_SYMBOL(force_enable_di_local_buffer);
-module_param(force_enable_di_local_buffer, int, 0644);
-
-int vpp_bypass_frames;
-EXPORT_SYMBOL(vpp_bypass_frames);
-module_param(vpp_bypass_frames, int, 0644);
-
-int bypass_nr_flag;
-EXPORT_SYMBOL(bypass_nr_flag);
-module_param(bypass_nr_flag, int, 0644);
-
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("AML video codec V4L2 decoder driver");
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 522fe67..2e9e576 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -20,19 +20,14 @@
#ifndef _AML_VCODEC_DRV_H_
#define _AML_VCODEC_DRV_H_
-#include <linux/kref.h>
#include <linux/platform_device.h>
#include <linux/videodev2.h>
-#include <linux/kfifo.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-core.h>
-#include <media/videobuf2-v4l2.h>
#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
#include "aml_vcodec_util.h"
-#include "aml_vcodec_dec.h"
#define AML_VCODEC_DRV_NAME "aml_vcodec_drv"
#define AML_VCODEC_DEC_NAME "aml-vcodec-dec"
@@ -71,8 +66,6 @@
#define V4L_CAP_BUFF_INVALID (0)
#define V4L_CAP_BUFF_IN_M2M (1)
#define V4L_CAP_BUFF_IN_DEC (2)
-#define V4L_CAP_BUFF_IN_VPP (3)
-#define V4L_CAP_BUFF_IN_GE2D (4)
/* v4l reset mode */
#define V4L_RESET_MODE_NORMAL (1 << 0) /* reset vdec_input and decoder. */
@@ -86,7 +79,6 @@
/* Instance is currently aborting */
#define TRANS_ABORT (1 << 2)
-#define CTX_BUF_TOTAL(ctx) (ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size)
/**
* enum aml_hw_reg_idx - AML hw register base index
*/
@@ -127,6 +119,7 @@
* @AML_STATE_ACTIVE - vdec is ready for work.
* @AML_STATE_FLUSHING - vdec is flushing. Only used by decoder
* @AML_STATE_FLUSHED - decoder has transacted the last frame.
+ * @AML_STATE_RESET - decoder has be reset after flush.
* @AML_STATE_ABORT - vcodec should be aborted
*/
enum aml_instance_state {
@@ -137,6 +130,7 @@
AML_STATE_ACTIVE,
AML_STATE_FLUSHING,
AML_STATE_FLUSHED,
+ AML_STATE_RESET,
AML_STATE_ABORT,
};
@@ -162,10 +156,9 @@
* struct aml_video_fmt - Structure used to store information about pixelformats
*/
struct aml_video_fmt {
- u32 fourcc;
+ u32 fourcc;
enum aml_fmt_type type;
- u32 num_planes;
- const u8 *name;
+ u32 num_planes;
};
/**
@@ -190,13 +183,13 @@
* struct aml_q_data - Structure used to store information about queue
*/
struct aml_q_data {
- u32 visible_width;
- u32 visible_height;
- u32 coded_width;
- u32 coded_height;
+ unsigned int visible_width;
+ unsigned int visible_height;
+ unsigned int coded_width;
+ unsigned int coded_height;
enum v4l2_field field;
- u32 bytesperline[AML_VCODEC_MAX_PLANES];
- u32 sizeimage[AML_VCODEC_MAX_PLANES];
+ unsigned int bytesperline[AML_VCODEC_MAX_PLANES];
+ unsigned int sizeimage[AML_VCODEC_MAX_PLANES];
struct aml_video_fmt *fmt;
bool resolution_changed;
};
@@ -221,19 +214,42 @@
* @force_intra: force/insert intra frame
*/
struct aml_enc_params {
- u32 bitrate;
- u32 num_b_frame;
- u32 rc_frame;
- u32 rc_mb;
- u32 seq_hdr_mode;
- u32 intra_period;
- u32 gop_size;
- u32 framerate_num;
- u32 framerate_denom;
- u32 h264_max_qp;
- u32 h264_profile;
- u32 h264_level;
- u32 force_intra;
+ unsigned int bitrate;
+ unsigned int num_b_frame;
+ unsigned int rc_frame;
+ unsigned int rc_mb;
+ unsigned int seq_hdr_mode;
+ unsigned int intra_period;
+ unsigned int gop_size;
+ unsigned int framerate_num;
+ unsigned int framerate_denom;
+ unsigned int h264_max_qp;
+ unsigned int h264_profile;
+ unsigned int h264_level;
+ unsigned int force_intra;
+};
+
+/**
+ * struct aml_vcodec_pm - Power management data structure
+ */
+struct aml_vcodec_pm {
+ struct clk *vdec_bus_clk_src;
+ struct clk *vencpll;
+
+ struct clk *vcodecpll;
+ struct clk *univpll_d2;
+ struct clk *clk_cci400_sel;
+ struct clk *vdecpll;
+ struct clk *vdec_sel;
+ struct clk *vencpll_d2;
+ struct clk *venc_sel;
+ struct clk *univpll1_d2;
+ struct clk *venc_lt_sel;
+ struct device *larbvdec;
+ struct device *larbvenc;
+ struct device *larbvenclt;
+ struct device *dev;
+ struct aml_vcodec_dev *amldev;
};
/**
@@ -250,38 +266,20 @@
* plane
* E.g. suppose picture size is 176x144,
* buffer size will be aligned to 176x160.
- * @profile_idc: source profile level
* @field: frame/field information.
- * @dpb_frames: used for DPB size of calculation.
- * @dpb_margin: extra buffers for decoder.
- * @vpp_margin: extra buffers for vpp.
*/
struct vdec_pic_info {
- u32 visible_width;
- u32 visible_height;
- u32 coded_width;
- u32 coded_height;
- u32 y_bs_sz;
- u32 c_bs_sz;
- u32 y_len_sz;
- u32 c_len_sz;
+ unsigned int visible_width;
+ unsigned int visible_height;
+ unsigned int coded_width;
+ unsigned int coded_height;
+ unsigned int y_bs_sz;
+ unsigned int c_bs_sz;
+ unsigned int y_len_sz;
+ unsigned int c_len_sz;
int profile_idc;
+ int ref_frame_count;
enum v4l2_field field;
- u32 dpb_frames;
- u32 dpb_margin;
- u32 vpp_margin;
-};
-
-/**
- * struct vdec_comp_buf_info - compressed buffer info
- * @max_size: max size needed for MMU Box in MB
- * @header_size: contineous size for the compressed header
- * @frame_buffer_size: SG page number to store the frame
- */
-struct vdec_comp_buf_info {
- u32 max_size;
- u32 header_size;
- u32 frame_buffer_size;
};
struct aml_vdec_cfg_infos {
@@ -292,20 +290,6 @@
u32 canvas_mem_mode;
u32 canvas_mem_endian;
u32 low_latency_mode;
- u32 uvm_hook_type;
- /*
- * bit 16 : force progressive output flag.
- * bit 15 : enable nr.
- * bit 14 : enable di local buff.
- * bit 13 : report downscale yuv buffer size flag.
- * bit 12 : for second field pts mode.
- * bit 11 : disable error policy
- * bit 1 : Non-standard dv flag.
- * bit 0 : dv two layer flag.
- */
- u32 metadata_config_flag; // for metadata config flag
- u32 duration;
- u32 data[4];
};
struct aml_vdec_hdr_infos {
@@ -339,10 +323,8 @@
u32 mb_height;
u32 dpb_size;
u32 ref_frames;
- u32 dpb_frames;
- u32 dpb_margin;
+ u32 reorder_frames;
u32 field;
- u32 data[3];
};
struct aml_vdec_cnt_infos {
@@ -379,7 +361,7 @@
*/
u32 seq[V4L_CAP_BUFF_MAX];
u32 in, out;
- u32 dec, vpp, ge2d;
+ u32 dec, vpp;
};
enum aml_thread_type {
@@ -390,203 +372,35 @@
typedef void (*aml_thread_func)(struct aml_vcodec_ctx *ctx);
struct aml_vdec_thread {
- struct list_head node;
- spinlock_t lock;
- struct semaphore sem;
- struct task_struct *task;
- enum aml_thread_type type;
- void *priv;
- int stop;
+ struct list_head node;
+ spinlock_t lock;
+ struct semaphore sem;
+ struct task_struct *task;
+ enum aml_thread_type type;
+ void *priv;
+ int stop;
- aml_thread_func func;
+ aml_thread_func func;
};
-/* struct internal_comp_buf - compressed buffer
- * @index: index of this buf within (B)MMU BOX
- * @ref: [0-7]:reference number of this buf
- * [8-15]: use for reuse.
- * @mmu_box: mmu_box of context
- * @bmmu_box: bmmu_box of context
- * @box_ref: box_ref of context
- * @header_addr: header for compressed buffer
- * @frame_buffer_size: SG buffer page number from
- * @priv_data use for video composer
- * struct vdec_comp_buf_info
- */
-struct internal_comp_buf {
- u32 index;
- u32 ref;
- void *mmu_box;
- void *bmmu_box;
- struct kref *box_ref;
-
- ulong header_addr;
- u32 header_size;
- u32 frame_buffer_size;
- struct file_private_data priv_data;
- ulong header_dw_addr;
- void *mmu_box_dw;
- void *bmmu_box_dw;
-};
-
-/*
- * struct aml_uvm_buff_ref - uvm buff is used reseve ctx ref count.
- * @index : index of video buffer.
- * @addr : physic address of video buffer.
- * @ref : reference of v4ldec context.
- * @dma : dma buf of associated with vb.
- */
-struct aml_uvm_buff_ref {
- int index;
- ulong addr;
- struct kref *ref;
- struct dma_buf *dbuf;
-};
-
-/*
- * enum aml_fb_requester - indicate which module request fb buffers.
- */
-enum aml_fb_requester {
- AML_FB_REQ_DEC,
- AML_FB_REQ_VPP,
- AML_FB_REQ_GE2D,
- AML_FB_REQ_MAX
-};
-
-/*
- * @query: try to achieved fb token.
- * @alloc: used for allocte fb buffer.
- */
-struct aml_fb_ops {
- bool (*query)(struct aml_fb_ops *, ulong *);
- int (*alloc)(struct aml_fb_ops *, ulong, struct vdec_v4l2_buffer **, u32);
-};
-
-/*
- * struct aml_fb_map_table - record some buffer map infos
- * @addr : yuv linear buffer address.
- * @header_addr : used for compress buffer.
- * @vframe : which is from decoder or vpp vf pool.
- * @task : context of task chain.
- * @icomp : compress buffer index.
- */
-struct aml_fb_map_table {
- ulong addr;
- ulong header_addr;
- struct vframe_s *vframe;
- struct task_chain_s *task;
- u32 icomp;
-};
-
-/*
- * struct aux_data - record sei data and dv data
- * @sei_size: sei data size.
- * @sei_buf: sei data addr.
- * @sei_state: sei buffer state. (0 free, 1 not used, 2 used)
- * @comp_buf: stores comp data parsed from sei data.
- * @md_buf: stores md data parsed from sei data.
- */
-struct aux_data {
- int sei_size;
- char* sei_buf;
- int sei_state;
- char* comp_buf;
- char* md_buf;
-};
-
-/*
- * struct aux_info - record aux data infos
- * @sei_index: sei data index.
- * @dv_index: dv data index.
- * @sei_need_free: sei buffer need to free.
- * @bufs: stores aux data.
- * @alloc_buffer: alloc aux buffer functions.
- * @free_buffer: free aux buffer functions.
- * @free_one_sei_buffer:free sei buffer with index functions.
- * @bind_sei_buffer: bind sei buffer functions.
- * @bind_dv_buffer: bind dv buffer functions.
- */
-struct aux_info {
- int sei_index;
- int dv_index;
- bool sei_need_free;
- struct aux_data bufs[V4L_CAP_BUFF_MAX];
- void (*alloc_buffer)(struct aml_vcodec_ctx *ctx, int flag);
- void (*free_buffer)(struct aml_vcodec_ctx *ctx, int flag);
- void (*free_one_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
- void (*bind_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx);
- void (*bind_dv_buffer)(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf);
-};
-
-/*
- * struct meta_data - record meta data.
- * @buf[META_DATA_SIZE]: meta data information.
- */
-struct meta_data {
- char buf[META_DATA_SIZE];
-};
-
-/*
- * struct meta_info - record some meta data infos
- * @index: meta data index.
- * @meta_bufs: record meta data.
- */
-struct meta_info {
- int index;
- struct meta_data *meta_bufs;
-};
-
-/*
- * struct aml_vpp_cfg_infos - config vpp init param
- * @mode : vpp work mode
- * @fmt : picture format used to switch nv21 or nv12.
- * @buf_size: config buffer size for vpp
- * @is_drm : is drm mode
- * @is_prog : is a progressive source.
- * @is_bypass_p : to set progressive bypass in vpp
- * @enable_nr : enable nosie reduce.
- * @enable_local_buf: DI used buff alloc by itself.
- * @res_chg : indicate resolution changed.
- * @is_vpp_reset: vpp reset just used to res chg.
- */
-struct aml_vpp_cfg_infos {
- u32 mode;
- u32 fmt;
- u32 buf_size;
- bool is_drm;
- bool is_prog;
- bool is_bypass_p;
- bool enable_nr;
- bool enable_local_buf;
- bool res_chg;
- bool is_vpp_reset;
-};
-
-struct aml_ge2d_cfg_infos {
- u32 mode;
- u32 buf_size;
- bool is_drm;
-};
-
-/*
+/**
* struct aml_vcodec_ctx - Context (instance) private data.
+ *
* @id: index of the context that this structure describes.
- * @ctx_ref: for deferred free of this context.
* @type: type of the instance - decoder or encoder.
* @dev: pointer to the aml_vcodec_dev of the device.
* @m2m_ctx: pointer to the v4l2_m2m_ctx of the context.
* @ada_ctx: pointer to the aml_vdec_adapt of the context.
- * @vpp: pointer to video post processor
* @dec_if: hooked decoder driver interface.
* @drv_handle: driver handle for specific decode instance
* @fh: struct v4l2_fh.
* @ctrl_hdl: handler for v4l2 framework.
* @slock: protect v4l2 codec context.
- * @tsplock: protect the vdec thread context.
* @empty_flush_buf: a fake size-0 capture buffer that indicates flush.
* @list: link to ctx_list of aml_vcodec_dev.
* @q_data: store information of input and output queue of the context.
* @queue: waitqueue that can be used to wait for this context to finish.
+ * @lock: protect the vdec thread.
* @state_lock: protect the codec status.
* @state: state of the context.
* @decode_work: decoder work be used to output buffer.
@@ -594,7 +408,6 @@
* @cap_pool: capture buffers are remark in the pool.
* @vdec_thread_list: vdec thread be used to capture.
* @dpb_size: store dpb count after header parsing
- * @vpp_size: store vpp buffer count after header parsing
* @param_change: indicate encode parameter type
* @param_sets_from_ucode: if true indicate ps from ucode.
* @v4l_codec_dpb_ready: queue buffer number greater than dpb.
@@ -617,46 +430,24 @@
* @reset_flag: reset mode includes lightly and normal mode.
* @decoded_frame_cnt: the capture buffer deque number to be count.
* @buf_used_count: means that decode allocate how many buffs from v4l.
- * @wq: wait recycle dma buffer finish.
- * @cap_wq: the wq used for wait capture buffer.
- * @dmabuff_recycle_lock: protect the lock dmabuff free.
- * @dmabuff_recycle_work: used for recycle dmabuff.
- * @dmabuff_recycle: kfifo used for store vb buff.
- * @capture_buffer: kfifo used for store capture vb buff.
- * @mmu_box: mmu_box of context.
- * @bmmu_box: bmmu_box of context.
- * @box_ref: box_ref of context.
- * @comp_info: compress buffer information.
- * @comp_bufs: compress buffer describe.
- * @comp_lock: used for lock ibuf free cb.
- * @fb_ops: frame buffer ops interface.
- * @dv_infos: dv data information.
- * @vpp_cfg: vpp init parms of configuration.
- * @vdec_pic_info_update: update pic info cb.
- * @vpp_is_need: the instance is need vpp.
- * @task_chain_pool: used to store task chain inst.
- * @index_disp: the number of frames output.
*/
struct aml_vcodec_ctx {
int id;
- struct kref ctx_ref;
enum aml_instance_type type;
struct aml_vcodec_dev *dev;
struct v4l2_m2m_ctx *m2m_ctx;
struct aml_vdec_adapt *ada_ctx;
- struct aml_v4l2_vpp *vpp;
const struct vdec_common_if *dec_if;
ulong drv_handle;
struct v4l2_fh fh;
struct v4l2_ctrl_handler ctrl_hdl;
spinlock_t slock;
- spinlock_t tsplock;
struct aml_video_dec_buf *empty_flush_buf;
struct list_head list;
struct aml_q_data q_data[2];
wait_queue_head_t queue;
- struct mutex state_lock;
+ struct mutex lock, state_lock;
enum aml_instance_state state;
struct work_struct decode_work;
bool output_thread_ready;
@@ -664,8 +455,6 @@
struct list_head vdec_thread_list;
int dpb_size;
- int vpp_size;
- int ge2d_size;
bool param_sets_from_ucode;
bool v4l_codec_dpb_ready;
bool v4l_resolution_change;
@@ -678,7 +467,6 @@
enum v4l2_quantization quantization;
enum v4l2_xfer_func xfer_func;
u32 cap_pix_fmt;
- u32 output_pix_fmt;
bool has_receive_eos;
bool is_drm_mode;
@@ -689,84 +477,81 @@
int reset_flag;
int decoded_frame_cnt;
int buf_used_count;
- wait_queue_head_t wq, cap_wq, post_done_wq;
- struct mutex capture_buffer_lock;
- spinlock_t dmabuff_recycle_lock;
- struct mutex buff_done_lock;
- struct work_struct dmabuff_recycle_work;
- DECLARE_KFIFO(dmabuff_recycle, struct vb2_v4l2_buffer *, 32);
- DECLARE_KFIFO(capture_buffer, struct vb2_v4l2_buffer *, 32);
-
- /* compressed buffer support */
- void *bmmu_box;
- void *mmu_box;
- struct kref box_ref;
- struct vdec_comp_buf_info comp_info;
- struct internal_comp_buf *comp_bufs;
- struct uvm_hook_mod_info *uvm_proxy;
- struct mutex comp_lock;
-
- struct aml_fb_ops fb_ops;
- ulong token_table[32];
-
- struct aml_fb_map_table fb_map[32];
- struct aml_vpp_cfg_infos vpp_cfg;
- void (*vdec_pic_info_update)(struct aml_vcodec_ctx *ctx);
- bool vpp_is_need;
- struct list_head task_chain_pool;
- struct meta_info meta_infos;
- struct vdec_sync *sync;
- u32 internal_dw_scale;
-
- /* ge2d field. */
- struct aml_v4l2_ge2d *ge2d;
- struct aml_ge2d_cfg_infos ge2d_cfg;
- bool ge2d_is_need;
-
- bool second_field_pts_mode;
- struct aux_info aux_infos;
- u32 index_disp;
- bool post_to_upper_done;
- bool film_grain_present;
- void *bmmu_box_dw;
- void *mmu_box_dw;
};
/**
- * struct aml_vcodec_dev - driver data.
- * @v4l2_dev : V4L2 device to register video devices for.
- * @vfd_dec : Video device for decoder.
- * @plat_dev : platform device.
- * @m2m_dev_dec : m2m device for decoder.
- * @curr_ctx : The context that is waiting for codec hardware.
- * @id_counter : used to identify current opened instance.
- * @dec_capability : used to identify decode capability, ex: 4k
- * @decode_workqueue : the worker used to output buffer schedule.
- * @ctx_list : list of struct aml_vcodec_ctx.
- * @irqlock : protect data access by irq handler and work thread.
- * @dev_mutex : video_device lock.
- * @dec_mutex : decoder hardware lock.
- * @queue : waitqueue for waiting for completion of device commands.
- * @vpp_count : count the number of open vpp.
- * @v4ldec_class : creat class sysfs uesd to show some information.
+ * struct aml_vcodec_dev - driver data
+ * @v4l2_dev: V4L2 device to register video devices for.
+ * @vfd_dec: Video device for decoder
+ * @vfd_enc: Video device for encoder.
+ *
+ * @m2m_dev_dec: m2m device for decoder
+ * @m2m_dev_enc: m2m device for encoder.
+ * @plat_dev: platform device
+ * @vpu_plat_dev: aml vpu platform device
+ * @alloc_ctx: VB2 allocator context
+ * (for allocations without kernel mapping).
+ * @ctx_list: list of struct aml_vcodec_ctx
+ * @irqlock: protect data access by irq handler and work thread
+ * @curr_ctx: The context that is waiting for codec hardware
+ *
+ * @reg_base: Mapped address of AML Vcodec registers.
+ *
+ * @id_counter: used to identify current opened instance
+ *
+ * @encode_workqueue: encode work queue
+ *
+ * @int_cond: used to identify interrupt condition happen
+ * @int_type: used to identify what kind of interrupt condition happen
+ * @dev_mutex: video_device lock
+ * @queue: waitqueue for waiting for completion of device commands
+ *
+ * @dec_irq: decoder irq resource
+ * @enc_irq: h264 encoder irq resource
+ * @enc_lt_irq: vp8 encoder irq resource
+ *
+ * @dec_mutex: decoder hardware lock
+ * @enc_mutex: encoder hardware lock.
+ *
+ * @pm: power management control
+ * @dec_capability: used to identify decode capability, ex: 4k
+ * @enc_capability: used to identify encode capability
*/
struct aml_vcodec_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vfd_dec;
- struct platform_device *plat_dev;
- struct v4l2_m2m_dev *m2m_dev_dec;
- struct aml_vcodec_ctx *curr_ctx;
- ulong id_counter;
- u32 dec_capability;
- struct workqueue_struct *decode_workqueue;
- struct list_head ctx_list;
- struct file *filp;
- spinlock_t irqlock;
- struct mutex dev_mutex;
- struct mutex dec_mutex;
- wait_queue_head_t queue;
- atomic_t vpp_count;
- struct class v4ldec_class;
+ struct v4l2_device v4l2_dev;
+ struct video_device *vfd_dec;
+ struct video_device *vfd_enc;
+ struct file *filp;
+
+ struct v4l2_m2m_dev *m2m_dev_dec;
+ struct v4l2_m2m_dev *m2m_dev_enc;
+ struct platform_device *plat_dev;
+ struct platform_device *vpu_plat_dev;//??
+ struct vb2_alloc_ctx *alloc_ctx;//??
+ struct list_head ctx_list;
+ spinlock_t irqlock;
+ struct aml_vcodec_ctx *curr_ctx;
+ void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE];
+
+ unsigned long id_counter;
+
+ struct workqueue_struct *decode_workqueue;
+ struct workqueue_struct *encode_workqueue;
+ int int_cond;
+ int int_type;
+ struct mutex dev_mutex;
+ wait_queue_head_t queue;
+
+ int dec_irq;
+ int enc_irq;
+ int enc_lt_irq;
+
+ struct mutex dec_mutex;
+ struct mutex enc_mutex;
+
+ struct aml_vcodec_pm pm;
+ unsigned int dec_capability;
+ unsigned int enc_capability;
};
static inline struct aml_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
@@ -779,10 +564,4 @@
return container_of(ctrl->handler, struct aml_vcodec_ctx, ctrl_hdl);
}
-void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx);
-void aml_thread_post_task(struct aml_vcodec_ctx *ctx, enum aml_thread_type type);
-int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
- enum aml_thread_type type, const char *thread_name);
-void aml_thread_stop(struct aml_vcodec_ctx *ctx);
-
#endif /* _AML_VCODEC_DRV_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.c b/drivers/amvdec_ports/aml_vcodec_ge2d.c
deleted file mode 100644
index 2d331ed..0000000
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/sched/clock.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/amlogic/meson_uvm_core.h>
-#include <linux/amlogic/media/ge2d/ge2d.h>
-#include <linux/amlogic/media/canvas/canvas_mgr.h>
-
-#include "../common/chips/decoder_cpu_ver_info.h"
-#include "aml_vcodec_ge2d.h"
-#include "aml_vcodec_adapt.h"
-#include "vdec_drv_if.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-#define GE2D_BUF_GET_IDX(ge2d_buf) (ge2d_buf->aml_buf->vb.vb2_buf.index)
-#define INPUT_PORT 0
-#define OUTPUT_PORT 1
-
-extern int dump_ge2d_input;
-extern int ge2d_bypass_frames;
-
-enum GE2D_FLAG {
- GE2D_FLAG_P = 0x1,
- GE2D_FLAG_I = 0x2,
- GE2D_FLAG_EOS = 0x4,
- GE2D_FLAG_BUF_BY_PASS = 0x8,
- GE2D_FLAG_MAX = 0x7FFFFFFF,
-};
-
-enum videocom_source_type {
- DECODER_8BIT_NORMAL = 0,
- DECODER_8BIT_BOTTOM,
- DECODER_8BIT_TOP,
- DECODER_10BIT_NORMAL,
- DECODER_10BIT_BOTTOM,
- DECODER_10BIT_TOP
-};
-
-#ifndef CONFIG_AMLOGIC_MEDIA_GE2D
-inline void stretchblt_noalpha(struct ge2d_context_s *wq,
- int src_x, int src_y, int src_w, int src_h,
- int dst_x, int dst_y, int dst_w, int dst_h) { return; }
-inline int ge2d_context_config_ex(struct ge2d_context_s *context,
- struct config_para_ex_s *ge2d_config) { return -1; }
-inline struct ge2d_context_s *create_ge2d_work_queue(void) { return NULL; }
-inline int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { return -1; }
-#endif
-
-static int get_source_type(struct vframe_s *vf)
-{
- enum videocom_source_type ret;
- int interlace_mode;
-
- interlace_mode = vf->type & VIDTYPE_TYPEMASK;
-
- if ((vf->bitdepth & BITDEPTH_Y10) &&
- (!(vf->type & VIDTYPE_COMPRESS)) &&
- (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) {
- if (interlace_mode == VIDTYPE_INTERLACE_TOP)
- ret = DECODER_10BIT_TOP;
- else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
- ret = DECODER_10BIT_BOTTOM;
- else
- ret = DECODER_10BIT_NORMAL;
- } else {
- if (interlace_mode == VIDTYPE_INTERLACE_TOP)
- ret = DECODER_8BIT_TOP;
- else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
- ret = DECODER_8BIT_BOTTOM;
- else
- ret = DECODER_8BIT_NORMAL;
- }
-
- return ret;
-}
-
-static int get_input_format(struct vframe_s *vf)
-{
- int format = GE2D_FORMAT_M24_YUV420;
- enum videocom_source_type soure_type;
-
- soure_type = get_source_type(vf);
-
- switch (soure_type) {
- case DECODER_8BIT_NORMAL:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422;
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21;
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12;
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444;
- else
- format = GE2D_FORMAT_M24_YUV420;
- break;
- case DECODER_8BIT_BOTTOM:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422
- | (GE2D_FORMAT_S16_YUV422B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21
- | (GE2D_FORMAT_M24_NV21B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12
- | (GE2D_FORMAT_M24_NV12B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444
- | (GE2D_FORMAT_S24_YUV444B & (3 << 3));
- else
- format = GE2D_FORMAT_M24_YUV420
- | (GE2D_FMT_M24_YUV420B & (3 << 3));
- break;
- case DECODER_8BIT_TOP:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422
- | (GE2D_FORMAT_S16_YUV422T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21
- | (GE2D_FORMAT_M24_NV21T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12
- | (GE2D_FORMAT_M24_NV12T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444
- | (GE2D_FORMAT_S24_YUV444T & (3 << 3));
- else
- format = GE2D_FORMAT_M24_YUV420
- | (GE2D_FMT_M24_YUV420T & (3 << 3));
- break;
- case DECODER_10BIT_NORMAL:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422;
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422;
- }
- break;
- case DECODER_10BIT_BOTTOM:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422
- | (GE2D_FORMAT_S16_10BIT_YUV422B
- & (3 << 3));
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422
- | (GE2D_FORMAT_S16_12BIT_YUV422B
- & (3 << 3));
- }
- break;
- case DECODER_10BIT_TOP:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422
- | (GE2D_FORMAT_S16_10BIT_YUV422T
- & (3 << 3));
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422
- | (GE2D_FORMAT_S16_12BIT_YUV422T
- & (3 << 3));
- }
- break;
- default:
- format = GE2D_FORMAT_M24_YUV420;
- }
- return format;
-}
-
-static int v4l_ge2d_empty_input_done(struct aml_v4l2_ge2d_buf *buf)
-{
- struct aml_v4l2_ge2d *ge2d = buf->caller_data;
- struct vdec_v4l2_buffer *fb = NULL;
- bool eos = false;
-
- if (!ge2d || !ge2d->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d ge2d:%px\n",
- __func__, __LINE__, ge2d);
- return -1;
- }
-
- fb = &buf->aml_buf->frame_buffer;
- eos = (buf->flag & GE2D_FLAG_EOS);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d_input done: vf:%px, idx: %d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- buf->vf,
- buf->vf->index,
- buf->vf->flag,
- buf->flag,
- eos ? "eos" : "",
- buf->vf->timestamp,
- kfifo_len(&ge2d->input),
- kfifo_len(&ge2d->output),
- kfifo_len(&ge2d->frame),
- kfifo_len(&ge2d->in_done_q),
- kfifo_len(&ge2d->out_done_q));
-
- fb->task->recycle(fb->task, TASK_TYPE_GE2D);
-
- kfifo_put(&ge2d->input, buf);
-
- ATRACE_COUNTER("VC_IN_GE2D-1.recycle", fb->buf_idx);
-
- return 0;
-}
-
-static int v4l_ge2d_fill_output_done(struct aml_v4l2_ge2d_buf *buf)
-{
- struct aml_v4l2_ge2d *ge2d = buf->caller_data;
- struct vdec_v4l2_buffer *fb = NULL;
- bool bypass = false;
- bool eos = false;
-
- if (!ge2d || !ge2d->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d ge2d:%px\n",
- __func__, __LINE__, ge2d);
- return -1;
- }
-
- fb = &buf->aml_buf->frame_buffer;
- eos = (buf->flag & GE2D_FLAG_EOS);
- bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-
- /* recovery fb handle. */
- buf->vf->v4l_mem_handle = (ulong)fb;
-
- kfifo_put(&ge2d->out_done_q, buf);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d_output done: vf:%px, idx:%d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d, wxh:%ux%u\n",
- buf->vf,
- buf->vf->index,
- buf->vf->flag,
- buf->flag,
- eos ? "eos" : "",
- buf->vf->timestamp,
- kfifo_len(&ge2d->input),
- kfifo_len(&ge2d->output),
- kfifo_len(&ge2d->frame),
- kfifo_len(&ge2d->in_done_q),
- kfifo_len(&ge2d->out_done_q),
- buf->vf->width, buf->vf->height);
-
- ATRACE_COUNTER("VC_OUT_GE2D-2.submit", fb->buf_idx);
-
- fb->task->submit(fb->task, TASK_TYPE_GE2D);
-
- ge2d->out_num[OUTPUT_PORT]++;
-
- return 0;
-}
-
-static void ge2d_vf_get(void *caller, struct vframe_s **vf_out)
-{
- struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
- struct aml_v4l2_ge2d_buf *buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- struct vframe_s *vf = NULL;
- bool bypass = false;
- bool eos = false;
-
- if (!ge2d || !ge2d->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d ge2d:%px\n",
- __func__, __LINE__, ge2d);
- return;
- }
-
- if (kfifo_get(&ge2d->out_done_q, &buf)) {
- fb = &buf->aml_buf->frame_buffer;
- eos = (buf->flag & GE2D_FLAG_EOS);
- bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
- vf = buf->vf;
-
- if (eos) {
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
- "%s %d got eos\n",
- __func__, __LINE__);
- vf->type |= VIDTYPE_V4L_EOS;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- }
-
- *vf_out = vf;
-
- ATRACE_COUNTER("VC_OUT_GE2D-3.vf_get", fb->buf_idx);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld, type:%x, wxh:%ux%u\n",
- __func__, vf,
- vf->index,
- vf->flag,
- buf->flag,
- vf->timestamp, vf->type, vf->width, vf->height);
- }
-}
-
-static void ge2d_vf_put(void *caller, struct vframe_s *vf)
-{
- struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- struct aml_v4l2_ge2d_buf *buf = NULL;
- bool bypass = false;
- bool eos = false;
-
- fb = (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
- aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- buf = (struct aml_v4l2_ge2d_buf *) aml_buf->ge2d_buf_handle;
- eos = (buf->flag & GE2D_FLAG_EOS);
- bypass = (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld\n",
- __func__, vf,
- vf->index,
- vf->flag,
- buf->flag,
- vf->timestamp);
-
- ATRACE_COUNTER("VC_IN_GE2D-0.vf_put", fb->buf_idx);
-
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->frame, vf);
- kfifo_put(&ge2d->output, buf);
- mutex_unlock(&ge2d->output_lock);
- up(&ge2d->sem_out);
-}
-
-static int aml_v4l2_ge2d_thread(void* param)
-{
- struct aml_v4l2_ge2d* ge2d = param;
- struct aml_vcodec_ctx *ctx = ge2d->ctx;
- struct config_para_ex_s ge2d_config;
- u32 src_fmt = 0, dst_fmt = 0;
- struct canvas_s cd;
- ulong start_time;
-
- v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "enter ge2d thread\n");
- while (ge2d->running) {
- struct aml_v4l2_ge2d_buf *in_buf;
- struct aml_v4l2_ge2d_buf *out_buf = NULL;
- struct vframe_s *vf_out = NULL;
- struct vdec_v4l2_buffer *fb;
-
- if (down_interruptible(&ge2d->sem_in))
- goto exit;
-retry:
- if (!ge2d->running)
- break;
-
- if (kfifo_is_empty(&ge2d->output)) {
- if (down_interruptible(&ge2d->sem_out))
- goto exit;
- goto retry;
- }
-
- mutex_lock(&ge2d->output_lock);
- if (!kfifo_get(&ge2d->output, &out_buf)) {
- mutex_unlock(&ge2d->output_lock);
- v4l_dbg(ctx, 0, "ge2d can not get output\n");
- goto exit;
- }
- mutex_unlock(&ge2d->output_lock);
-
- /* bind v4l2 buffers */
- if (!out_buf->aml_buf) {
- struct vdec_v4l2_buffer *out;
-
- if (!ctx->fb_ops.query(&ctx->fb_ops, &ge2d->fb_token)) {
- usleep_range(500, 550);
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->output, out_buf);
- mutex_unlock(&ge2d->output_lock);
- goto retry;
- }
-
- if (ctx->fb_ops.alloc(&ctx->fb_ops, ge2d->fb_token, &out, AML_FB_REQ_GE2D)) {
- usleep_range(5000, 5500);
- mutex_lock(&ge2d->output_lock);
- kfifo_put(&ge2d->output, out_buf);
- mutex_unlock(&ge2d->output_lock);
- goto retry;
- }
-
- out_buf->aml_buf = container_of(out,
- struct aml_video_dec_buf, frame_buffer);
- out_buf->aml_buf->ge2d_buf_handle = (ulong) out_buf;
- v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d bind buf:%d to ge2d_buf:%px\n",
- GE2D_BUF_GET_IDX(out_buf), out_buf);
-
- out->m.mem[0].bytes_used = out->m.mem[0].size;
- out->m.mem[1].bytes_used = out->m.mem[1].size;
- }
-
- /* safe to pop in_buf */
- if (!kfifo_get(&ge2d->in_done_q, &in_buf)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d can not get input\n");
- goto exit;
- }
-
- mutex_lock(&ge2d->output_lock);
- if (!kfifo_get(&ge2d->frame, &vf_out)) {
- mutex_unlock(&ge2d->output_lock);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d can not get frame\n");
- goto exit;
- }
- mutex_unlock(&ge2d->output_lock);
-
- fb = &out_buf->aml_buf->frame_buffer;
- fb->status = FB_ST_GE2D;
-
- /* fill output vframe information. */
- memcpy(vf_out, in_buf->vf, sizeof(*vf_out));
- memcpy(vf_out->canvas0_config,
- in_buf->vf->canvas0_config,
- 2 * sizeof(struct canvas_config_s));
-
- vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1) {
- vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset;
- vf_out->canvas0_config[2].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset
- + (fb->m.mem[0].offset >> 2);
- } else {
- vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[1].addr;
- vf_out->canvas0_config[2].phy_addr =
- fb->m.mem[2].addr;
- }
-
- /* fill outbuf parms. */
- out_buf->vf = vf_out;
- out_buf->flag = 0;
- out_buf->caller_data = ge2d;
-
- /* fill inbuf parms. */
- in_buf->caller_data = ge2d;
-
- memset(&ge2d_config, 0, sizeof(ge2d_config));
-
- src_fmt = get_input_format(in_buf->vf);
- if (in_buf->vf->canvas0_config[0].endian == 7)
- src_fmt |= GE2D_BIG_ENDIAN;
- else
- src_fmt |= GE2D_LITTLE_ENDIAN;
-
- /* negotiate format of destination */
- dst_fmt = get_input_format(in_buf->vf);
- if (ge2d->work_mode & GE2D_MODE_CONVERT_NV12)
- dst_fmt |= GE2D_FORMAT_M24_NV12;
- else if (ge2d->work_mode & GE2D_MODE_CONVERT_NV21)
- dst_fmt |= GE2D_FORMAT_M24_NV21;
-
- if (ge2d->work_mode & GE2D_MODE_CONVERT_LE)
- dst_fmt |= GE2D_LITTLE_ENDIAN;
- else
- dst_fmt |= GE2D_BIG_ENDIAN;
-
- if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV12) {
- vf_out->type |= VIDTYPE_VIU_NV12;
- vf_out->type &= ~VIDTYPE_VIU_NV21;
- } else if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV21) {
- vf_out->type |= VIDTYPE_VIU_NV21;
- vf_out->type &= ~VIDTYPE_VIU_NV12;
- }
- if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_LITTLE_ENDIAN) {
- vf_out->canvas0_config[0].endian = 0;
- vf_out->canvas0_config[1].endian = 0;
- vf_out->canvas0_config[2].endian = 0;
- } else if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_BIG_ENDIAN){
- vf_out->canvas0_config[0].endian = 7;
- vf_out->canvas0_config[1].endian = 7;
- vf_out->canvas0_config[2].endian = 7;
- }
-
- start_time = local_clock();
- /* src canvas configure. */
- if ((in_buf->vf->canvas0Addr == 0) ||
- (in_buf->vf->canvas0Addr == (u32)-1)) {
- canvas_config_config(ge2d->src_canvas_id[0], &in_buf->vf->canvas0_config[0]);
- canvas_config_config(ge2d->src_canvas_id[1], &in_buf->vf->canvas0_config[1]);
- canvas_config_config(ge2d->src_canvas_id[2], &in_buf->vf->canvas0_config[2]);
- ge2d_config.src_para.canvas_index =
- ge2d->src_canvas_id[0] |
- ge2d->src_canvas_id[1] << 8 |
- ge2d->src_canvas_id[2] << 16;
-
- ge2d_config.src_planes[0].addr =
- in_buf->vf->canvas0_config[0].phy_addr;
- ge2d_config.src_planes[0].w =
- in_buf->vf->canvas0_config[0].width;
- ge2d_config.src_planes[0].h =
- in_buf->vf->canvas0_config[0].height;
- ge2d_config.src_planes[1].addr =
- in_buf->vf->canvas0_config[1].phy_addr;
- ge2d_config.src_planes[1].w =
- in_buf->vf->canvas0_config[1].width;
- ge2d_config.src_planes[1].h =
- in_buf->vf->canvas0_config[1].height;
- ge2d_config.src_planes[2].addr =
- in_buf->vf->canvas0_config[2].phy_addr;
- ge2d_config.src_planes[2].w =
- in_buf->vf->canvas0_config[2].width;
- ge2d_config.src_planes[2].h =
- in_buf->vf->canvas0_config[2].height;
- } else {
- ge2d_config.src_para.canvas_index = in_buf->vf->canvas0Addr;
- }
- ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.src_para.format = src_fmt;
- ge2d_config.src_para.fill_color_en = 0;
- ge2d_config.src_para.fill_mode = 0;
- ge2d_config.src_para.x_rev = 0;
- ge2d_config.src_para.y_rev = 0;
- ge2d_config.src_para.color = 0xffffffff;
- ge2d_config.src_para.top = 0;
- ge2d_config.src_para.left = 0;
- ge2d_config.src_para.width = in_buf->vf->width;
- if (in_buf->vf->type & VIDTYPE_INTERLACE)
- ge2d_config.src_para.height = in_buf->vf->height >> 1;
- else
- ge2d_config.src_para.height = in_buf->vf->height;
-
- /* dst canvas configure. */
- canvas_config_config(ge2d->dst_canvas_id[0], &vf_out->canvas0_config[0]);
- if ((ge2d_config.src_para.format & 0xfffff) == GE2D_FORMAT_M24_YUV420) {
- vf_out->canvas0_config[1].width <<= 1;
- }
- canvas_config_config(ge2d->dst_canvas_id[1], &vf_out->canvas0_config[1]);
- canvas_config_config(ge2d->dst_canvas_id[2], &vf_out->canvas0_config[2]);
- ge2d_config.dst_para.canvas_index =
- ge2d->dst_canvas_id[0] |
- ge2d->dst_canvas_id[1] << 8;
- canvas_read(ge2d->dst_canvas_id[0], &cd);
- ge2d_config.dst_planes[0].addr = cd.addr;
- ge2d_config.dst_planes[0].w = cd.width;
- ge2d_config.dst_planes[0].h = cd.height;
- canvas_read(ge2d->dst_canvas_id[1], &cd);
- ge2d_config.dst_planes[1].addr = cd.addr;
- ge2d_config.dst_planes[1].w = cd.width;
- ge2d_config.dst_planes[1].h = cd.height;
-
- ge2d_config.dst_para.format = dst_fmt;
- ge2d_config.dst_para.width = in_buf->vf->width;
- ge2d_config.dst_para.height = in_buf->vf->height;
- ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.dst_para.fill_color_en = 0;
- ge2d_config.dst_para.fill_mode = 0;
- ge2d_config.dst_para.x_rev = 0;
- ge2d_config.dst_para.y_rev = 0;
- ge2d_config.dst_para.color = 0;
- ge2d_config.dst_para.top = 0;
- ge2d_config.dst_para.left = 0;
-
- /* other ge2d parameters configure. */
- ge2d_config.src_key.key_enable = 0;
- ge2d_config.src_key.key_mask = 0;
- ge2d_config.src_key.key_mode = 0;
- ge2d_config.alu_const_color = 0;
- ge2d_config.bitmask_en = 0;
- ge2d_config.src1_gb_alpha = 0;
- ge2d_config.dst_xy_swap = 0;
- ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
-
- ATRACE_COUNTER("VC_OUT_GE2D-1.handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
-
- v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d_handle start: dec vf:%px/%d, ge2d vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, vf:%ux%u, fmt(src:%x, dst:%x), "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- in_buf->vf, in_buf->vf->index,
- out_buf->vf, GE2D_BUF_GET_IDX(out_buf),
- in_buf->vf->canvas0_config[0].phy_addr,
- in_buf->vf->canvas0_config[1].phy_addr,
- in_buf->vf->canvas0_config[0].width,
- in_buf->vf->canvas0_config[0].height,
- vf_out->canvas0_config[0].phy_addr,
- vf_out->canvas0_config[1].phy_addr,
- vf_out->canvas0_config[0].width,
- vf_out->canvas0_config[0].height,
- vf_out->width, vf_out->height,
- src_fmt, dst_fmt,
- kfifo_len(&ge2d->input),
- kfifo_len(&ge2d->output),
- kfifo_len(&ge2d->frame),
- kfifo_len(&ge2d->in_done_q),
- kfifo_len(&ge2d->out_done_q));
-
- if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d_context_config_ex error.\n");
- goto exit;
- }
-
- if (!(in_buf->flag & GE2D_FLAG_EOS)) {
- if (in_buf->vf->type & VIDTYPE_INTERLACE) {
- stretchblt_noalpha(ge2d->ge2d_context,
- 0, 0, in_buf->vf->width, in_buf->vf->height / 2,
- 0, 0, in_buf->vf->width, in_buf->vf->height);
- } else {
- stretchblt_noalpha(ge2d->ge2d_context,
- 0, 0, in_buf->vf->width, in_buf->vf->height,
- 0, 0, in_buf->vf->width, in_buf->vf->height);
- }
- }
-
- //pr_info("consume time %d us\n", div64_u64(local_clock() - start_time, 1000));
-
- v4l_ge2d_fill_output_done(out_buf);
- v4l_ge2d_empty_input_done(in_buf);
-
- ge2d->in_num[INPUT_PORT]++;
- ge2d->out_num[INPUT_PORT]++;
- }
-exit:
- while (!kthread_should_stop()) {
- usleep_range(1000, 2000);
- }
-
- v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "exit ge2d thread\n");
-
- return 0;
-}
-
-int aml_v4l2_ge2d_get_buf_num(u32 mode)
-{
- return 4;
-}
-
-int aml_v4l2_ge2d_init(
- struct aml_vcodec_ctx *ctx,
- struct aml_ge2d_cfg_infos *cfg,
- struct aml_v4l2_ge2d** ge2d_handle)
-{
- struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
- struct aml_v4l2_ge2d *ge2d;
- u32 work_mode = cfg->mode;
- u32 buf_size;
- int i, ret;
-
- if (!cfg || !ge2d_handle)
- return -EINVAL;
-
- ge2d = kzalloc(sizeof(*ge2d), GFP_KERNEL);
- if (!ge2d)
- return -ENOMEM;
-
- ge2d->work_mode = work_mode;
-
- /* default convert little endian. */
- if (!ge2d->work_mode) {
- ge2d->work_mode = GE2D_MODE_CONVERT_LE;
- }
-
- ge2d->ge2d_context = create_ge2d_work_queue();
- if (!ge2d->ge2d_context) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d_create_instance fail\n");
- ret = -EINVAL;
- goto error;
- }
-
- INIT_KFIFO(ge2d->input);
- INIT_KFIFO(ge2d->output);
- INIT_KFIFO(ge2d->frame);
- INIT_KFIFO(ge2d->out_done_q);
- INIT_KFIFO(ge2d->in_done_q);
-
- ge2d->ctx = ctx;
- buf_size = cfg->buf_size;
- ge2d->buf_size = buf_size;
-
- /* setup output fifo */
- ret = kfifo_alloc(&ge2d->output, buf_size, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc output fifo fail.\n");
- ret = -ENOMEM;
- goto error2;
- }
-
- ge2d->ovbpool = vzalloc(buf_size * sizeof(*ge2d->ovbpool));
- if (!ge2d->ovbpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc output vb pool fail.\n");
- ret = -ENOMEM;
- goto error3;
- }
-
- /* setup vframe fifo */
- ret = kfifo_alloc(&ge2d->frame, buf_size, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc ge2d vframe fifo fail.\n");
- ret = -ENOMEM;
- goto error4;
- }
-
- ge2d->vfpool = vzalloc(buf_size * sizeof(*ge2d->vfpool));
- if (!ge2d->vfpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc vf pool fail.\n");
- ret = -ENOMEM;
- goto error5;
- }
-
- ret = kfifo_alloc(&ge2d->input, GE2D_FRAME_SIZE, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc input fifo fail.\n");
- ret = -ENOMEM;
- goto error6;
- }
-
- ge2d->ivbpool = vzalloc(GE2D_FRAME_SIZE * sizeof(*ge2d->ivbpool));
- if (!ge2d->ivbpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc input vb pool fail.\n");
- ret = -ENOMEM;
- goto error7;
- }
-
- for (i = 0 ; i < GE2D_FRAME_SIZE ; i++) {
- kfifo_put(&ge2d->input, &ge2d->ivbpool[i]);
- }
-
- for (i = 0 ; i < buf_size ; i++) {
- kfifo_put(&ge2d->output, &ge2d->ovbpool[i]);
- kfifo_put(&ge2d->frame, &ge2d->vfpool[i]);
- }
-
- ge2d->src_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->src_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->src_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- ge2d->dst_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
- if ((ge2d->src_canvas_id[0] <= 0) ||
- (ge2d->src_canvas_id[1] <= 0) ||
- (ge2d->src_canvas_id[2] <= 0) ||
- (ge2d->dst_canvas_id[0] <= 0) ||
- (ge2d->dst_canvas_id[1] <= 0) ||
- (ge2d->dst_canvas_id[2] <= 0)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "canvas pool alloc fail. src(%d, %d, %d) dst(%d, %d, %d).\n",
- ge2d->src_canvas_id[0],
- ge2d->src_canvas_id[1],
- ge2d->src_canvas_id[2],
- ge2d->dst_canvas_id[0],
- ge2d->dst_canvas_id[1],
- ge2d->dst_canvas_id[2]);
- goto error8;
- }
-
- mutex_init(&ge2d->output_lock);
- sema_init(&ge2d->sem_in, 0);
- sema_init(&ge2d->sem_out, 0);
-
- ge2d->running = true;
- ge2d->task = kthread_run(aml_v4l2_ge2d_thread, ge2d,
- "%s", "aml-v4l2-ge2d");
- if (IS_ERR(ge2d->task)) {
- ret = PTR_ERR(ge2d->task);
- goto error9;
- }
- sched_setscheduler_nocheck(ge2d->task, SCHED_FIFO, ¶m);
-
- *ge2d_handle = ge2d;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "GE2D_CFG bsize:%d, wkm:%x, bm:%x, drm:%d\n",
- ge2d->buf_size,
- ge2d->work_mode,
- ge2d->buffer_mode,
- cfg->is_drm);
-
- return 0;
-
-error9:
- if (ge2d->src_canvas_id[0] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
- if (ge2d->src_canvas_id[1] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
- if (ge2d->src_canvas_id[2] > 0)
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
- if (ge2d->dst_canvas_id[0] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
- if (ge2d->dst_canvas_id[1] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
- if (ge2d->dst_canvas_id[2] > 0)
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
-error8:
- vfree(ge2d->ivbpool);
-error7:
- kfifo_free(&ge2d->input);
-error6:
- vfree(ge2d->vfpool);
-error5:
- kfifo_free(&ge2d->frame);
-error4:
- vfree(ge2d->ovbpool);
-error3:
- kfifo_free(&ge2d->output);
-error2:
- destroy_ge2d_work_queue(ge2d->ge2d_context);
-error:
- kfree(ge2d);
-
- return ret;
-}
-EXPORT_SYMBOL(aml_v4l2_ge2d_init);
-
-int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d)
-{
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
- "ge2d destroy begin\n");
-
- ge2d->running = false;
- up(&ge2d->sem_in);
- up(&ge2d->sem_out);
- kthread_stop(ge2d->task);
-
- destroy_ge2d_work_queue(ge2d->ge2d_context);
- /* no more ge2d callback below this line */
-
- kfifo_free(&ge2d->frame);
- vfree(ge2d->vfpool);
- kfifo_free(&ge2d->output);
- vfree(ge2d->ovbpool);
- kfifo_free(&ge2d->input);
- vfree(ge2d->ivbpool);
- mutex_destroy(&ge2d->output_lock);
-
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
- canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
- canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
- "ge2d destroy done\n");
-
- kfree(ge2d);
-
- return 0;
-}
-EXPORT_SYMBOL(aml_v4l2_ge2d_destroy);
-
-static int aml_v4l2_ge2d_push_vframe(struct aml_v4l2_ge2d* ge2d, struct vframe_s *vf)
-{
- struct aml_v4l2_ge2d_buf* in_buf;
- struct vdec_v4l2_buffer *fb = NULL;
-
- if (!ge2d)
- return -EINVAL;
-
- if (!kfifo_get(&ge2d->input, &in_buf)) {
- v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_ERROR,
- "cat not get free input buffer.\n");
- return -1;
- }
-
- if (vf->type & VIDTYPE_V4L_EOS)
- in_buf->flag |= GE2D_FLAG_EOS;
-
- v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
- "ge2d_push_vframe: vf:%px, idx:%d, type:%x, ts:%lld\n",
- vf, vf->index, vf->type, vf->timestamp);
-
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- in_buf->vf = vf;
-
- do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
- struct file *fp;
-
- if (!dump_ge2d_input || ge2d->ctx->is_drm_mode)
- break;
-
- if (vdec_if_get_param(ge2d->ctx, GET_PARAM_DW_MODE, &dw_mode))
- break;
-
- if (dw_mode == VDEC_DW_AFBC_ONLY)
- break;
-
- fp = filp_open("/data/dec_dump_before.raw",
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
- if (!IS_ERR(fp)) {
- struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
-
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
- if (in_buf->aml_buf->frame_buffer.num_planes == 2)
- kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
- dump_ge2d_input--;
- filp_close(fp, NULL);
- }
- } while(0);
-
- ATRACE_COUNTER("VC_OUT_GE2D-0.receive", fb->buf_idx);
-
- kfifo_put(&ge2d->in_done_q, in_buf);
- up(&ge2d->sem_in);
-
- return 0;
-}
-
-static void fill_ge2d_buf_cb(void *v4l_ctx, void *fb_ctx)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
- int ret = -1;
-
- ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, fb->vframe);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "ge2d push vframe err, ret: %d\n", ret);
- }
-}
-
-static struct task_ops_s ge2d_ops = {
- .type = TASK_TYPE_GE2D,
- .get_vframe = ge2d_vf_get,
- .put_vframe = ge2d_vf_put,
- .fill_buffer = fill_ge2d_buf_cb,
-};
-
-struct task_ops_s *get_ge2d_ops(void)
-{
- return &ge2d_ops;
-}
-EXPORT_SYMBOL(get_ge2d_ops);
-
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.h b/drivers/amvdec_ports/aml_vcodec_ge2d.h
deleted file mode 100644
index a12931d..0000000
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef _AML_VCODEC_GE2D_H_
-#define _AML_VCODEC_GE2D_H_
-
-#include <linux/kfifo.h>
-#include "aml_vcodec_drv.h"
-#include "aml_vcodec_dec.h"
-
-/* define ge2d work mode. */
-#define GE2D_MODE_CONVERT_NV12 (1 << 0)
-#define GE2D_MODE_CONVERT_NV21 (1 << 1)
-#define GE2D_MODE_CONVERT_LE (1 << 2)
-#define GE2D_MODE_CONVERT_BE (1 << 3)
-#define GE2D_MODE_SEPARATE_FIELD (1 << 4)
-#define GE2D_MODE_422_TO_420 (1 << 5)
-
-#define GE2D_FRAME_SIZE 64
-
-struct aml_v4l2_ge2d_buf {
- u32 flag;
- struct vframe_s *vf;
- void *caller_data;
- struct aml_video_dec_buf *aml_buf;
-};
-
-struct aml_v4l2_ge2d {
- struct ge2d_context_s *ge2d_context; /* handle of GE2D */
- u32 buf_size; /* buffer size for ge2d */
- u32 work_mode; /* enum ge2d_work_mode */
- u32 buffer_mode;
- struct aml_vcodec_ctx *ctx;
-
- DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_ge2d_buf*));
- DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_ge2d_buf*));
- DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *));
- DECLARE_KFIFO(out_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE);
- DECLARE_KFIFO(in_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE);
-
- struct vframe_s *vfpool;
- struct aml_v4l2_ge2d_buf *ovbpool;
- struct aml_v4l2_ge2d_buf *ivbpool;
- struct task_struct *task;
- bool running;
- struct semaphore sem_in, sem_out;
-
- /* In p to i transition, output/frame can be multi writer */
- struct mutex output_lock;
-
- /* for debugging */
- /*
- * in[0] --> ge2d <-- in[1]
- * out[0]<-- ge2d --> out[1]
- */
- int in_num[2];
- int out_num[2];
- ulong fb_token;
-
- int src_canvas_id[3];
- int dst_canvas_id[3];
-};
-
-struct task_ops_s *get_ge2d_ops(void);
-
-int aml_v4l2_ge2d_init(
- struct aml_vcodec_ctx *ctx,
- struct aml_ge2d_cfg_infos *cfg,
- struct aml_v4l2_ge2d** ge2d_handle);
-
-int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d);
-
-#endif
diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c
index 54b0d06..509a42a 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.c
+++ b/drivers/amvdec_ports/aml_vcodec_util.c
@@ -22,6 +22,72 @@
#include "aml_vcodec_drv.h"
#include "aml_vcodec_util.h"
+void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data,
+ unsigned int reg_idx)
+{
+ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+
+ if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "Invalid arguments, reg_idx=%d\n", reg_idx);
+ return NULL;
+ }
+ return ctx->dev->reg_base[reg_idx];
+}
+EXPORT_SYMBOL(aml_vcodec_get_reg_addr);
+
+int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data,
+ struct aml_vcodec_mem *mem)
+{
+ unsigned long size = mem->size;
+ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+ struct device *dev = &ctx->dev->plat_dev->dev;
+
+ mem->vaddr = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL);
+ //mem->vaddr = codec_mm_dma_alloc_coherent(dev_name(dev), size,
+ // &mem->dma_addr, GFP_KERNEL, 0);
+ if (!mem->vaddr) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s dma_alloc size=%ld failed!\n", dev_name(dev),
+ size);
+ return -ENOMEM;
+ }
+
+ memset(mem->vaddr, 0, size);
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size);
+
+ return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_mem_alloc);
+
+void aml_vcodec_mem_free(struct aml_vcodec_ctx *data,
+ struct aml_vcodec_mem *mem)
+{
+ unsigned long size = mem->size;
+ struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+ struct device *dev = &ctx->dev->plat_dev->dev;
+
+ if (!mem->vaddr) {
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+ "%s dma_free size=%ld failed!\n", dev_name(dev),
+ size);
+ return;
+ }
+
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr);
+ v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size);
+
+ dma_free_coherent(dev, size, mem->vaddr, mem->dma_addr);
+ mem->vaddr = NULL;
+ mem->dma_addr = 0;
+ mem->size = 0;
+}
+EXPORT_SYMBOL(aml_vcodec_mem_free);
+
void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev,
struct aml_vcodec_ctx *ctx)
{
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h
index 96c5453..312ee40 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.h
+++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -23,14 +23,14 @@
#include <linux/types.h>
#include <linux/dma-direction.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-/*
+
typedef unsigned long long u64;
typedef signed long long s64;
typedef unsigned int u32;
typedef unsigned short int u16;
typedef short int s16;
typedef unsigned char u8;
-*/
+
#define CODEC_MODE(a, b, c, d)\
(((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d))
@@ -45,16 +45,14 @@
u32 bytes_used;
u32 offset;
u64 timestamp;
+ dma_addr_t dma_addr;
u32 model;
- ulong meta_ptr;
- struct dma_buf *dbuf;
};
struct aml_vcodec_ctx;
struct aml_vcodec_dev;
extern u32 debug_mode;
-extern u32 mandatory_dw_mmu;
#ifdef v4l_dbg
#undef v4l_dbg
@@ -71,11 +69,6 @@
#define V4L_DEBUG_CODEC_PARSER (1 << 6)
#define V4L_DEBUG_CODEC_PROT (1 << 7)
#define V4L_DEBUG_CODEC_EXINFO (1 << 8)
-#define V4L_DEBUG_VPP_BUFMGR (1 << 9)
-#define V4L_DEBUG_VPP_DETAIL (1 << 10)
-#define V4L_DEBUG_TASK_CHAIN (1 << 11)
-#define V4L_DEBUG_GE2D_BUFMGR (1 << 12)
-#define V4L_DEBUG_GE2D_DETAIL (1 << 13)
#define __v4l_dbg(h, id, fmt, args...) \
do { \
@@ -99,6 +92,12 @@
} \
} while (0)
+void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data,
+ unsigned int reg_idx);
+int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data,
+ struct aml_vcodec_mem *mem);
+void aml_vcodec_mem_free(struct aml_vcodec_ctx *data,
+ struct aml_vcodec_mem *mem);
void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev,
struct aml_vcodec_ctx *ctx);
struct aml_vcodec_ctx *aml_vcodec_get_curr_ctx(struct aml_vcodec_dev *dev);
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.c b/drivers/amvdec_ports/aml_vcodec_vfm.c
new file mode 100644
index 0000000..62896ea
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.c
@@ -0,0 +1,245 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#include "aml_vcodec_vfm.h"
+#include "aml_vcodec_vfq.h"
+#include "aml_vcodec_util.h"
+#include "aml_vcodec_adapt.h"
+#include <media/v4l2-mem2mem.h>
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_VIDEO_COMPOSER
+#include <trace/events/meson_atrace.h>
+
+#define RECEIVER_NAME "v4l2-video"
+#define PROVIDER_NAME "v4l2-video"
+
+static struct vframe_s *vdec_vf_peek(void *op_arg)
+{
+ struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+ return vfq_peek(&vfm->vf_que);
+}
+
+static struct vframe_s *vdec_vf_get(void *op_arg)
+{
+ struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+ return vfq_pop(&vfm->vf_que);
+}
+
+static void vdec_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+ /* If the video frame from amvide that means */
+ /* the data has been processed and finished, */
+ /* then push back to VDA. thus we don't put the */
+ /* buffer to the decoder directly.*/
+
+ //vf_put(vf, vfm->recv_name);
+ //vf_notify_provider(vfm->recv_name, VFRAME_EVENT_RECEIVER_PUT, NULL);
+
+ if (vfq_level(&vfm->vf_que_recycle) > POOL_SIZE - 1) {
+ v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "vfq full.\n");
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ vfq_push(&vfm->vf_que_recycle, vf);
+
+ /* schedule capture work. */
+ vdec_device_vf_run(vfm->ctx);
+}
+
+static int vdec_event_cb(int type, void *data, void *private_data)
+{
+
+ if (type & VFRAME_EVENT_RECEIVER_PUT) {
+ } else if (type & VFRAME_EVENT_RECEIVER_GET) {
+ } else if (type & VFRAME_EVENT_RECEIVER_FRAME_WAIT) {
+ }
+ return 0;
+}
+
+static int vdec_vf_states(struct vframe_states *states, void *op_arg)
+{
+ struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+ states->vf_pool_size = POOL_SIZE;
+ states->buf_recycle_num = 0;
+ states->buf_free_num = POOL_SIZE - vfq_level(&vfm->vf_que);
+ states->buf_avail_num = vfq_level(&vfm->vf_que);
+
+ return 0;
+}
+
+void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id)
+{
+ struct vframe_provider_s *vfp = vf_get_provider(receiver);
+ struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
+
+ ATRACE_COUNTER("v4l2_to", vf->index_disp);
+
+ v4l_dbg(0, V4L_DEBUG_CODEC_OUTPUT,
+ "[%d]: TO (%s) vf: %p, idx: %d, "
+ "Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
+ id, vfp->name, vf, vf->index,
+ fb->m.mem[0].addr, fb->m.mem[0].size,
+ fb->m.mem[1].addr, fb->m.mem[1].size,
+ fb->m.mem[2].addr, fb->m.mem[2].size);
+
+ if (vfp && vf && atomic_dec_and_test(&vf->use_cnt))
+ vf_put(vf, receiver);
+}
+
+static const struct vframe_operations_s vf_provider = {
+ .peek = vdec_vf_peek,
+ .get = vdec_vf_get,
+ .put = vdec_vf_put,
+ .event_cb = vdec_event_cb,
+ .vf_states = vdec_vf_states,
+};
+
+static int video_receiver_event_fun(int type, void *data, void *private_data)
+{
+ int ret = 0;
+ struct vframe_states states;
+ struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)private_data;
+
+ switch (type) {
+ case VFRAME_EVENT_PROVIDER_UNREG: {
+ if (vf_get_receiver(vfm->prov_name)) {
+ v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "unreg %s provider.\n",
+ vfm->prov_name);
+ vf_unreg_provider(&vfm->vf_prov);
+ }
+
+ break;
+ }
+
+ case VFRAME_EVENT_PROVIDER_START: {
+ if (vf_get_receiver(vfm->prov_name)) {
+ v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "reg %s provider.\n",
+ vfm->prov_name);
+ vf_provider_init(&vfm->vf_prov, vfm->prov_name,
+ &vf_provider, vfm);
+ vf_reg_provider(&vfm->vf_prov);
+ vf_notify_receiver(vfm->prov_name,
+ VFRAME_EVENT_PROVIDER_START, NULL);
+ }
+
+ vfq_init(&vfm->vf_que, POOL_SIZE + 1, &vfm->pool[0]);
+ vfq_init(&vfm->vf_que_recycle, POOL_SIZE + 1, &vfm->pool_recycle[0]);
+
+ break;
+ }
+
+ case VFRAME_EVENT_PROVIDER_QUREY_STATE: {
+ vdec_vf_states(&states, vfm);
+ if (states.buf_avail_num > 0)
+ ret = RECEIVER_ACTIVE;
+ break;
+ }
+
+ case VFRAME_EVENT_PROVIDER_VFRAME_READY: {
+ if (vfq_level(&vfm->vf_que) > POOL_SIZE - 1)
+ ret = -1;
+
+ if (!vf_peek(vfm->recv_name))
+ ret = -1;
+
+ vfm->vf = vf_get(vfm->recv_name);
+ if (!vfm->vf)
+ ret = -1;
+
+ if (ret < 0) {
+ v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "receiver vf err.\n");
+ break;
+ }
+
+ vfq_push(&vfm->vf_que, vfm->vf);
+
+ if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) {
+ vf_notify_receiver(vfm->prov_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ break;
+ }
+
+ /* schedule capture work. */
+ vdec_device_vf_run(vfm->ctx);
+
+ break;
+ }
+
+ default:
+ v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+ "the vf event is %d", type);
+ }
+
+ return ret;
+}
+
+static const struct vframe_receiver_op_s vf_receiver = {
+ .event_cb = video_receiver_event_fun
+};
+
+struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm)
+{
+ if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
+ return vfq_peek(&vfm->vf_que_recycle);
+ else
+ return vfq_peek(&vfm->vf_que);
+}
+
+struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm)
+{
+ if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
+ return vfq_pop(&vfm->vf_que_recycle);
+ else
+ return vfq_pop(&vfm->vf_que);
+}
+
+int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
+{
+ int ret;
+
+ snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d",
+ RECEIVER_NAME, vfm->ctx->id);
+ snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d",
+ PROVIDER_NAME, vfm->ctx->id);
+
+ vfm->ada_ctx->recv_name = vfm->recv_name;
+
+ vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm);
+ ret = vf_reg_receiver(&vfm->vf_recv);
+
+ vfm->vfm_initialized = ret ? false : true;
+
+ return ret;
+}
+
+void vcodec_vfm_release(struct vcodec_vfm_s *vfm)
+{
+ if (vfm->vfm_initialized)
+ vf_unreg_receiver(&vfm->vf_recv);
+}
+
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.h b/drivers/amvdec_ports/aml_vcodec_vfm.h
new file mode 100644
index 0000000..141e9a7
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef __AML_VCODEC_VFM_H_
+#define __AML_VCODEC_VFM_H_
+
+#include "aml_vcodec_vfq.h"
+#include "aml_vcodec_drv.h"
+#include "aml_vcodec_dec.h"
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
+#define VF_NAME_SIZE (32)
+#define POOL_SIZE (32)
+
+struct vcodec_vfm_s {
+ struct aml_vcodec_ctx *ctx;
+ struct aml_vdec_adapt *ada_ctx;
+ struct vfq_s vf_que;
+ struct vfq_s vf_que_recycle;
+ struct vframe_s *vf;
+ struct vframe_s *pool[POOL_SIZE + 1];
+ struct vframe_s *pool_recycle[POOL_SIZE + 1];
+ char recv_name[VF_NAME_SIZE];
+ char prov_name[VF_NAME_SIZE];
+ struct vframe_provider_s vf_prov;
+ struct vframe_receiver_s vf_recv;
+ bool vfm_initialized;
+};
+
+int vcodec_vfm_init(struct vcodec_vfm_s *vfm);
+
+void vcodec_vfm_release(struct vcodec_vfm_s *vfm);
+
+struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm);
+
+struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm);
+
+int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb);
+int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb);
+
+void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id);
+
+#endif /* __AML_VCODEC_VFM_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_vfq.h b/drivers/amvdec_ports/aml_vcodec_vfq.h
new file mode 100644
index 0000000..e19c53c
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfq.h
@@ -0,0 +1,112 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef __AML_VCODEC_VFQ_H_
+#define __AML_VCODEC_VFQ_H_
+
+#include <linux/types.h>
+#include <asm/barrier.h>
+
+struct vfq_s {
+ int rp;
+ int wp;
+ int size;
+ int pre_rp;
+ int pre_wp;
+ struct vframe_s **pool;
+};
+
+static inline void vfq_lookup_start(struct vfq_s *q)
+{
+ q->pre_rp = q->rp;
+ q->pre_wp = q->wp;
+}
+static inline void vfq_lookup_end(struct vfq_s *q)
+{
+ q->rp = q->pre_rp;
+ q->wp = q->pre_wp;
+}
+
+static inline void vfq_init(struct vfq_s *q, u32 size, struct vframe_s **pool)
+{
+ q->rp = q->wp = 0;
+ q->size = size;
+ q->pool = pool;
+}
+
+static inline bool vfq_empty(struct vfq_s *q)
+{
+ return q->rp == q->wp;
+}
+
+static inline void vfq_push(struct vfq_s *q, struct vframe_s *vf)
+{
+ int wp = q->wp;
+
+ /*ToDo*/
+ smp_mb();
+
+ q->pool[wp] = vf;
+
+ /*ToDo*/
+ smp_wmb();
+
+ q->wp = (wp == (q->size - 1)) ? 0 : (wp + 1);
+}
+
+static inline struct vframe_s *vfq_pop(struct vfq_s *q)
+{
+ struct vframe_s *vf;
+ int rp;
+
+ if (vfq_empty(q))
+ return NULL;
+
+ rp = q->rp;
+
+ /*ToDo*/
+ smp_rmb();
+
+ vf = q->pool[rp];
+
+ /*ToDo*/
+ smp_mb();
+
+ q->rp = (rp == (q->size - 1)) ? 0 : (rp + 1);
+
+ return vf;
+}
+
+static inline struct vframe_s *vfq_peek(struct vfq_s *q)
+{
+ return (vfq_empty(q)) ? NULL : q->pool[q->rp];
+}
+
+static inline int vfq_level(struct vfq_s *q)
+{
+ int level = q->wp - q->rp;
+
+ if (level < 0)
+ level += q->size;
+
+ return level;
+}
+
+#endif /* __AML_VCODEC_VFQ_H_ */
+
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.c b/drivers/amvdec_ports/aml_vcodec_vpp.c
deleted file mode 100644
index 9f4e960..0000000
--- a/drivers/amvdec_ports/aml_vcodec_vpp.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/amlogic/meson_uvm_core.h>
-
-#include "aml_vcodec_vpp.h"
-#include "aml_vcodec_adapt.h"
-#include "vdec_drv_if.h"
-#include "../common/chips/decoder_cpu_ver_info.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-#define VPP_BUF_GET_IDX(vpp_buf) (vpp_buf->aml_buf->vb.vb2_buf.index)
-#define INPUT_PORT 0
-#define OUTPUT_PORT 1
-
-extern int dump_vpp_input;
-extern int vpp_bypass_frames;
-
-static void di_release_keep_buf_wrap(void *arg)
-{
- struct di_buffer *buf = (struct di_buffer *)arg;
-
- v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,
- "%s release di local buffer %px, vf:%px, comm:%s, pid:%d\n",
- __func__ , buf, buf->vf,
- current->comm, current->pid);
-
- di_release_keep_buf(buf);
-
- ATRACE_COUNTER("VC_OUT_VPP_LC-2.lc_release", buf->mng.index);
-}
-
-static int attach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf)
-{
- struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
- struct dma_buf *dma = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- struct uvm_hook_mod_info u_info;
- int ret;
-
- aml_buf = vpp_buf->aml_buf;
- if (!aml_buf)
- return -EINVAL;
-
- dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
- if (!dma || !dmabuf_is_uvm(dma)) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "attach_DI_buffer err\n");
- return -EINVAL;
- }
-
- if (!vpp_buf->di_local_buf) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "attach_DI_buffer nothing\n");
- return 0;
- }
-
- if (uvm_get_hook_mod(dma, VF_PROCESS_DI)) {
- uvm_put_hook_mod(dma, VF_PROCESS_DI);
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "attach_DI_buffer exist hook\n");
- return -EINVAL;
- }
- u_info.type = VF_PROCESS_DI;
- u_info.arg = (void *)vpp_buf->di_local_buf;
- u_info.free = di_release_keep_buf_wrap;
-
- ret = uvm_attach_hook_mod(dma, &u_info);
- if (ret < 0) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "fail to set dmabuf DI hook\n");
- }
-
- ATRACE_COUNTER("VC_OUT_VPP_LC-0.lc_attach", vpp_buf->di_local_buf->mng.index);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "%s attach di local buffer %px, dbuf:%px\n",
- __func__ , vpp_buf->di_local_buf, dma);
-
- return ret;
-}
-
-static int detach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf)
-{
- struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
- struct dma_buf *dma = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- int ret;
-
- aml_buf = vpp_buf->aml_buf;
- if (!aml_buf)
- return -EINVAL;
-
- dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
- if (!dma || !dmabuf_is_uvm(dma)) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "detach_DI_buffer err\n");
- return -EINVAL;
- }
-
- if (!vpp_buf->di_local_buf) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "detach_DI_buffer nothing\n");
- return 0;
- }
-
- ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_detach", vpp_buf->di_local_buf->mng.index);
-
- ret = uvm_detach_hook_mod(dma, VF_PROCESS_DI);
- if (ret < 0) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "fail to remove dmabuf DI hook\n");
- }
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "%s detach di local buffer %px, dbuf:%px\n",
- __func__ , vpp_buf->di_local_buf, dma);
-
- return ret;
-}
-
-static void release_DI_buff(struct aml_v4l2_vpp* vpp)
-{
- struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-
- while (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
- if (vpp_buf->di_buf.private_data) {
- di_release_keep_buf(vpp_buf->di_local_buf);
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "%s release di local buffer %px\n",
- __func__ , vpp_buf->di_local_buf);
- }
- }
-}
-
-static int is_di_input_buff_full(struct aml_v4l2_vpp *vpp)
-{
- return ((vpp->in_num[INPUT_PORT] - vpp->in_num[OUTPUT_PORT])
- > vpp->di_ibuf_num) ? true : false;
-}
-
-static int is_di_output_buff_full(struct aml_v4l2_vpp *vpp)
-{
- return ((vpp->out_num[INPUT_PORT] - vpp->out_num[OUTPUT_PORT])
- > vpp->di_obuf_num) ? true : false;
-}
-
-static enum DI_ERRORTYPE
- v4l_vpp_fill_output_done_alloc_buffer(struct di_buffer *buf)
-{
- struct aml_v4l2_vpp *vpp = buf->caller_data;
- struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- bool bypass = false;
- bool eos = false;
-
- if (!vpp || !vpp->ctx) {
- pr_err("fatal %s %d vpp:%p\n",
- __func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
- return DI_ERR_UNDEFINED;
- }
-
- if (vpp->ctx->is_stream_off) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
- "vpp discard submit frame %s %d vpp:%p\n",
- __func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
- return DI_ERR_UNDEFINED;
- }
-
- if (!kfifo_get(&vpp->processing, &vpp_buf)) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
- "vpp doesn't get output %s %d vpp:%p\n",
- __func__, __LINE__, vpp);
- di_release_keep_buf_wrap(buf);
- return DI_ERR_UNDEFINED;
- }
-
- fb = &vpp_buf->aml_buf->frame_buffer;
- eos = (buf->flag & DI_FLAG_EOS);
- bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
-
- vpp_buf->di_buf.vf->timestamp = buf->vf->timestamp;
- vpp_buf->di_buf.private_data = buf->private_data;
- vpp_buf->di_buf.vf->vf_ext = buf->vf;
- vpp_buf->di_buf.flag = buf->flag;
- vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)fb;
-
- if (!eos && !bypass) {
- vpp_buf->di_local_buf = buf;
- vpp_buf->di_buf.vf->vf_ext = buf->vf;
- vpp_buf->di_buf.vf->flag |= VFRAME_FLAG_CONTAIN_POST_FRAME;
- }
-
- kfifo_put(&vpp->out_done_q, vpp_buf);
-
- if (vpp->is_prog)
- kfifo_put(&vpp->input, vpp_buf->inbuf);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_output local done: idx:%d, vf:%px, ext vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
- vpp_buf->di_buf.vf,
- vpp_buf->di_buf.vf->vf_ext,
- vpp_buf->di_buf.vf->index,
- vpp_buf->di_buf.vf->flag,
- buf->flag,
- vpp->is_prog ? "P" : "I",
- eos ? "eos" : "",
- vpp_buf->di_buf.vf->timestamp,
- kfifo_len(&vpp->input),
- kfifo_len(&vpp->output),
- kfifo_len(&vpp->frame),
- kfifo_len(&vpp->in_done_q),
- kfifo_len(&vpp->out_done_q));
-
- ATRACE_COUNTER("VC_OUT_VPP-2.lc_submit", fb->buf_idx);
-
- fb->task->submit(fb->task, TASK_TYPE_VPP);
-
- vpp->out_num[OUTPUT_PORT]++;
- vpp->in_num[OUTPUT_PORT]++;
-
- return DI_ERR_NONE;
-}
-
-static enum DI_ERRORTYPE
- v4l_vpp_empty_input_done(struct di_buffer *buf)
-{
- struct aml_v4l2_vpp *vpp = buf->caller_data;
- struct aml_v4l2_vpp_buf *vpp_buf;
- struct vdec_v4l2_buffer *fb = NULL;
- bool eos = false;
-
- if (!vpp || !vpp->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d vpp:%px\n",
- __func__, __LINE__, vpp);
- return DI_ERR_UNDEFINED;
- }
-
- if (vpp->ctx->is_stream_off) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
- "vpp discard recycle frame %s %d vpp:%p\n",
- __func__, __LINE__, vpp);
- return DI_ERR_UNDEFINED;
- }
-
- vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
- fb = &vpp_buf->aml_buf->frame_buffer;
- eos = (buf->flag & DI_FLAG_EOS);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_input done: idx:%d, vf:%px, idx: %d, flag(vf:%x di:%x) %s %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
- buf->vf,
- buf->vf->index,
- buf->vf->flag,
- buf->flag,
- vpp->is_prog ? "P" : "I",
- eos ? "eos" : "",
- buf->vf->timestamp,
- kfifo_len(&vpp->input),
- kfifo_len(&vpp->output),
- kfifo_len(&vpp->frame),
- kfifo_len(&vpp->in_done_q),
- kfifo_len(&vpp->out_done_q));
-
- if (!vpp->is_prog) {
- /* recycle vf only in non-bypass mode */
- fb->task->recycle(fb->task, TASK_TYPE_VPP);
-
- kfifo_put(&vpp->input, vpp_buf);
- }
-
- if (vpp->buffer_mode != BUFFER_MODE_ALLOC_BUF)
- vpp->in_num[OUTPUT_PORT]++;
-
- ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
-
- return DI_ERR_NONE;
-}
-
-static enum DI_ERRORTYPE
- v4l_vpp_fill_output_done(struct di_buffer *buf)
-{
- struct aml_v4l2_vpp *vpp = buf->caller_data;
- struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- bool bypass = false;
- bool eos = false;
-
- if (!vpp || !vpp->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d vpp:%px\n",
- __func__, __LINE__, vpp);
- return DI_ERR_UNDEFINED;
- }
-
- if (vpp->ctx->is_stream_off) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
- "vpp discard submit frame %s %d vpp:%p\n",
- __func__, __LINE__, vpp);
- return DI_ERR_UNDEFINED;
- }
-
- vpp_buf = container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
- fb = &vpp_buf->aml_buf->frame_buffer;
- eos = (buf->flag & DI_FLAG_EOS);
- bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
-
- /* recovery fb handle. */
- buf->vf->v4l_mem_handle = (ulong)fb;
-
- kfifo_put(&vpp->out_done_q, vpp_buf);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_output done: idx:%d, vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
- fb->buf_idx,
- buf->vf,
- buf->vf->index,
- buf->vf->flag,
- buf->flag,
- vpp->is_prog ? "P" : "I",
- eos ? "eos" : "",
- buf->vf->timestamp,
- kfifo_len(&vpp->input),
- kfifo_len(&vpp->output),
- kfifo_len(&vpp->frame),
- kfifo_len(&vpp->in_done_q),
- kfifo_len(&vpp->out_done_q));
-
- ATRACE_COUNTER("VC_OUT_VPP-2.submit", fb->buf_idx);
-
- fb->task->submit(fb->task, TASK_TYPE_VPP);
-
- vpp->out_num[OUTPUT_PORT]++;
-
- /* count for bypass nr */
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
- vpp->in_num[OUTPUT_PORT]++;
-
- return DI_ERR_NONE;
-}
-
-static void vpp_vf_get(void *caller, struct vframe_s **vf_out)
-{
- struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
- struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- struct di_buffer *buf = NULL;
- struct vframe_s *vf = NULL;
- bool bypass = false;
- bool eos = false;
-
- if (!vpp || !vpp->ctx) {
- v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
- "fatal %s %d vpp:%px\n",
- __func__, __LINE__, vpp);
- return;
- }
-
- if (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
- fb = &vpp_buf->aml_buf->frame_buffer;
- buf = &vpp_buf->di_buf;
- eos = (buf->flag & DI_FLAG_EOS);
- bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
- vf = buf->vf;
-
- if (eos) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
- "%s %d got eos\n",
- __func__, __LINE__);
- vf->type |= VIDTYPE_V4L_EOS;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- }
-
- if (!eos && !bypass) {
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
- attach_DI_buffer(vpp_buf);
- }
- }
-
- *vf_out = vf;
-
- ATRACE_COUNTER("VC_OUT_VPP-3.vf_get", fb->buf_idx);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
- __func__, vf,
- vf->index,
- vf->flag,
- buf->flag,
- vf->timestamp);
- }
-}
-
-static void vpp_vf_put(void *caller, struct vframe_s *vf)
-{
- struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_video_dec_buf *aml_buf = NULL;
- struct aml_v4l2_vpp_buf *vpp_buf = NULL;
- struct di_buffer *buf = NULL;
- bool bypass = false;
- bool eos = false;
-
- fb = (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
- aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
-
- vpp_buf = (struct aml_v4l2_vpp_buf *) aml_buf->vpp_buf_handle;
- buf = &vpp_buf->di_buf;
- eos = (buf->flag & DI_FLAG_EOS);
- bypass = (buf->flag & DI_FLAG_BUF_BY_PASS);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
- __func__, vf,
- vf->index,
- vf->flag,
- buf->flag,
- vf->timestamp);
-
- ATRACE_COUNTER("VC_IN_VPP-0.vf_put", fb->buf_idx);
-
- if (vpp->is_prog) {
- ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
- fb->task->recycle(fb->task, TASK_TYPE_VPP);
- }
-
- if (!eos && !bypass) {
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
- detach_DI_buffer(vpp_buf);
- }
- }
-
- mutex_lock(&vpp->output_lock);
- kfifo_put(&vpp->frame, vf);
- kfifo_put(&vpp->output, vpp_buf);
- mutex_unlock(&vpp->output_lock);
- up(&vpp->sem_out);
-}
-
-static int aml_v4l2_vpp_thread(void* param)
-{
- struct aml_v4l2_vpp* vpp = param;
- struct aml_vcodec_ctx *ctx = vpp->ctx;
-
- v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "enter vpp thread\n");
- while (vpp->running) {
- struct aml_v4l2_vpp_buf *in_buf;
- struct aml_v4l2_vpp_buf *out_buf = NULL;
- struct vframe_s *vf_out = NULL;
- struct vdec_v4l2_buffer *fb;
-
- if (down_interruptible(&vpp->sem_in))
- goto exit;
-retry:
- if (!vpp->running)
- break;
-
- if (kfifo_is_empty(&vpp->output)) {
- if (down_interruptible(&vpp->sem_out))
- goto exit;
- goto retry;
- }
-
- if ((vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) &&
- (is_di_input_buff_full(vpp) || is_di_output_buff_full(vpp))) {
- usleep_range(500, 550);
- goto retry;
- }
-
- mutex_lock(&vpp->output_lock);
- if (!kfifo_get(&vpp->output, &out_buf)) {
- mutex_unlock(&vpp->output_lock);
- v4l_dbg(ctx, 0, "vpp can not get output\n");
- goto exit;
- }
- mutex_unlock(&vpp->output_lock);
-
- /* bind v4l2 buffers */
- if (!vpp->is_prog && !out_buf->aml_buf) {
- struct vdec_v4l2_buffer *out;
-
- if (!ctx->fb_ops.query(&ctx->fb_ops, &vpp->fb_token)) {
- usleep_range(500, 550);
- mutex_lock(&vpp->output_lock);
- kfifo_put(&vpp->output, out_buf);
- mutex_unlock(&vpp->output_lock);
- goto retry;
- }
-
- if (ctx->fb_ops.alloc(&ctx->fb_ops, vpp->fb_token, &out, AML_FB_REQ_VPP)) {
- usleep_range(5000, 5500);
- mutex_lock(&vpp->output_lock);
- kfifo_put(&vpp->output, out_buf);
- mutex_unlock(&vpp->output_lock);
- goto retry;
- }
-
- out_buf->aml_buf = container_of(out,
- struct aml_video_dec_buf, frame_buffer);
- out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
- v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp bind buf:%d to vpp_buf:%px\n",
- VPP_BUF_GET_IDX(out_buf), out_buf);
-
- out->m.mem[0].bytes_used = out->m.mem[0].size;
- out->m.mem[1].bytes_used = out->m.mem[1].size;
- }
-
- /* safe to pop in_buf */
- if (!kfifo_get(&vpp->in_done_q, &in_buf)) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "vpp can not get input\n");
- goto exit;
- }
-
- mutex_lock(&vpp->output_lock);
- if (!kfifo_get(&vpp->frame, &vf_out)) {
- mutex_unlock(&vpp->output_lock);
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "vpp can not get frame\n");
- goto exit;
- }
- mutex_unlock(&vpp->output_lock);
-
- if (!vpp->is_prog) {
- /* submit I to DI. */
- fb = &out_buf->aml_buf->frame_buffer;
- fb->status = FB_ST_VPP;
-
- memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
- memcpy(vf_out->canvas0_config,
- in_buf->di_buf.vf->canvas0_config,
- 2 * sizeof(struct canvas_config_s));
-
- vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1)
- vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[0].addr + fb->m.mem[0].offset;
- else
- vf_out->canvas0_config[1].phy_addr =
- fb->m.mem[1].addr;
-
- if (in_buf->di_buf.flag & DI_FLAG_EOS)
- memset(vf_out, 0, sizeof(*vf_out));
-
- vf_out->meta_data_size = in_buf->di_buf.vf->meta_data_size;
- vf_out->meta_data_buf = in_buf->di_buf.vf->meta_data_buf;
- } else {
- /* submit P to DI. */
- out_buf->aml_buf = in_buf->aml_buf;
- out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
-
- memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
- }
-
- /* fill outbuf parms. */
- out_buf->di_buf.vf = vf_out;
- out_buf->di_buf.flag = 0;
- out_buf->di_local_buf = NULL;
- out_buf->di_buf.caller_data = vpp;
-
- /* fill inbuf parms. */
- in_buf->di_buf.caller_data = vpp;
-
- /*
- * HWC or SF should hold di buffres refcnt after resolution changed
- * that might cause stuck, thus sumbit 10 frames from dec to display directly.
- * then frames will be pushed out from these buffer queuen and
- * recycle local buffers to DI module.
- */
- if (/*(ctx->vpp_cfg.res_chg) && */(vpp->is_prog) &&
- (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)) {
- if (vpp->in_num[INPUT_PORT] < vpp_bypass_frames) {
- vpp->is_bypass_p = true;
- } else {
- vpp->is_bypass_p = false;
- ctx->vpp_cfg.res_chg = false;
- }
- }
-
- v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_handle start: idx:(%d, %d), dec vf:%px/%d, vpp vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, %s %s "
- "in:%d, out:%d, vf:%d, in done:%d, out done:%d",
- in_buf->aml_buf->frame_buffer.buf_idx,
- out_buf->aml_buf->frame_buffer.buf_idx,
- in_buf->di_buf.vf, in_buf->di_buf.vf->index,
- out_buf->di_buf.vf, VPP_BUF_GET_IDX(out_buf),
- in_buf->di_buf.vf->canvas0_config[0].phy_addr,
- in_buf->di_buf.vf->canvas0_config[1].phy_addr,
- in_buf->di_buf.vf->canvas0_config[0].width,
- in_buf->di_buf.vf->canvas0_config[0].height,
- vf_out->canvas0_config[0].phy_addr,
- vf_out->canvas0_config[1].phy_addr,
- vf_out->canvas0_config[0].width,
- vf_out->canvas0_config[0].height,
- vpp->is_prog ? "P" : "",
- vpp->is_bypass_p ? "bypass-prog" : "",
- kfifo_len(&vpp->input),
- kfifo_len(&vpp->output),
- kfifo_len(&vpp->frame),
- kfifo_len(&vpp->in_done_q),
- kfifo_len(&vpp->out_done_q));
-
- if (vpp->is_bypass_p) {
- ATRACE_COUNTER("V4L_OUT_VPP-1.direct_handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- out_buf->di_buf.flag = in_buf->di_buf.flag;
- out_buf->di_buf.vf->vf_ext = in_buf->di_buf.vf;
-
- v4l_vpp_fill_output_done(&out_buf->di_buf);
- v4l_vpp_empty_input_done(&in_buf->di_buf);
- } else {
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
- /*
- * the flow of DI local buffer:
- * empty input -> output done cb -> fetch processing fifo.
- */
- ATRACE_COUNTER("VC_OUT_VPP-1.lc_handle_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- out_buf->inbuf = in_buf;
- kfifo_put(&vpp->processing, out_buf);
-
- di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
- } else {
- ATRACE_COUNTER("VC_OUT_VPP-1.fill_output_start",
- out_buf->aml_buf->frame_buffer.buf_idx);
- di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
-
- ATRACE_COUNTER("VC_OUT_VPP-1.empty_input_start",
- in_buf->aml_buf->frame_buffer.buf_idx);
- di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
- }
- }
- vpp->in_num[INPUT_PORT]++;
- vpp->out_num[INPUT_PORT]++;
- }
-exit:
- while (!kthread_should_stop()) {
- usleep_range(1000, 2000);
- }
-
- v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "exit vpp thread\n");
-
- return 0;
-}
-
-int aml_v4l2_vpp_get_buf_num(u32 mode)
-{
- if ((mode == VPP_MODE_DI) ||
- (mode == VPP_MODE_COLOR_CONV) ||
- (mode == VPP_MODE_NOISE_REDUC)) {
- return 4;
- }
- //TODO: support more modes
- return 2;
-}
-
-int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp)
-{
- int i;
- struct sched_param param =
- { .sched_priority = MAX_RT_PRIO - 1 };
-
- vpp->running = false;
- up(&vpp->sem_in);
- up(&vpp->sem_out);
- kthread_stop(vpp->task);
-
- kfifo_reset(&vpp->input);
- kfifo_reset(&vpp->output);
- kfifo_reset(&vpp->frame);
- kfifo_reset(&vpp->out_done_q);
- kfifo_reset(&vpp->in_done_q);
- kfifo_reset(&vpp->processing);
-
- for (i = 0 ; i < VPP_FRAME_SIZE ; i++) {
- memset(&vpp->ivbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf));
-
- kfifo_put(&vpp->input, &vpp->ivbpool[i]);
- }
-
- for (i = 0 ; i < vpp->buf_size ; i++) {
- memset(&vpp->ovbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf));
- memset(&vpp->vfpool[i], 0, sizeof(struct vframe_s));
-
- kfifo_put(&vpp->output, &vpp->ovbpool[i]);
- kfifo_put(&vpp->frame, &vpp->vfpool[i]);
- }
-
- vpp->in_num[0] = 0;
- vpp->in_num[1] = 0;
- vpp->out_num[0] = 0;
- vpp->out_num[1] = 0;
- vpp->fb_token = 0;
- sema_init(&vpp->sem_in, 0);
- sema_init(&vpp->sem_out, 0);
-
- vpp->running = true;
- vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp,
- "%s", "aml-v4l2-vpp");
- if (IS_ERR(vpp->task)) {
- return PTR_ERR(vpp->task);
- }
-
- sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, ¶m);
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PRINFO, "vpp wrapper reset.\n");
-
- return 0;
-
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_reset);
-
-int aml_v4l2_vpp_init(
- struct aml_vcodec_ctx *ctx,
- struct aml_vpp_cfg_infos *cfg,
- struct aml_v4l2_vpp** vpp_handle)
-{
- struct di_init_parm init;
- u32 buf_size;
- int i, ret;
- struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
- struct aml_v4l2_vpp *vpp;
- u32 work_mode = cfg->mode;
-
- if (!cfg || work_mode > VPP_MODE_MAX || !ctx || !vpp_handle)
- return -EINVAL;
- if (cfg->fmt != V4L2_PIX_FMT_NV12 && cfg->fmt != V4L2_PIX_FMT_NV12M &&
- cfg->fmt != V4L2_PIX_FMT_NV21 && cfg->fmt != V4L2_PIX_FMT_NV21M)
- return -EINVAL;
-
- vpp = kzalloc(sizeof(*vpp), GFP_KERNEL);
- if (!vpp)
- return -ENOMEM;
-
- vpp->work_mode = work_mode;
- if (vpp->work_mode >= VPP_MODE_DI_LOCAL &&
- vpp->work_mode <= VPP_MODE_NOISE_REDUC_LOCAL)
- vpp->buffer_mode = BUFFER_MODE_ALLOC_BUF;
- else
- vpp->buffer_mode = BUFFER_MODE_USE_BUF;
-
- init.work_mode = WORK_MODE_PRE_POST;
- init.buffer_mode = vpp->buffer_mode;
- init.ops.fill_output_done = v4l_vpp_fill_output_done;
- init.ops.empty_input_done = v4l_vpp_empty_input_done;
- init.caller_data = (void *)vpp;
-
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
- init.ops.fill_output_done =
- v4l_vpp_fill_output_done_alloc_buffer;
- }
-
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
- init.output_format = DI_OUTPUT_BY_DI_DEFINE;
- else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
- ((cfg->fmt == V4L2_PIX_FMT_NV21M) || (cfg->fmt == V4L2_PIX_FMT_NV21)))
- init.output_format = DI_OUTPUT_NV21 | DI_OUTPUT_LINEAR;
- else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
- ((cfg->fmt == V4L2_PIX_FMT_NV12M) || (cfg->fmt == V4L2_PIX_FMT_NV12)))
- init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
- else /* AFBC deocde case, NV12 as default */
- init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
-
- if (cfg->is_drm)
- init.output_format |= DI_OUTPUT_TVP;
-
- vpp->di_handle = di_create_instance(init);
- if (vpp->di_handle < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "di_create_instance fail\n");
- ret = -EINVAL;
- goto error;
- }
-
- INIT_KFIFO(vpp->input);
- INIT_KFIFO(vpp->output);
- INIT_KFIFO(vpp->frame);
- INIT_KFIFO(vpp->out_done_q);
- INIT_KFIFO(vpp->in_done_q);
- INIT_KFIFO(vpp->processing);
-
- vpp->ctx = ctx;
- vpp->is_prog = cfg->is_prog;
- vpp->is_bypass_p = cfg->is_bypass_p;
-
- buf_size = vpp->is_prog ? 16 : cfg->buf_size;
- vpp->buf_size = buf_size;
-
- /* setup output fifo */
- ret = kfifo_alloc(&vpp->output, buf_size, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc output fifo fail.\n");
- ret = -ENOMEM;
- goto error2;
- }
-
- vpp->ovbpool = vzalloc(buf_size * sizeof(*vpp->ovbpool));
- if (!vpp->ovbpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc output vb pool fail.\n");
- ret = -ENOMEM;
- goto error3;
- }
-
- /* setup vframe fifo */
- ret = kfifo_alloc(&vpp->frame, buf_size, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc vpp vframe fifo fail.\n");
- ret = -ENOMEM;
- goto error4;
- }
-
- vpp->vfpool = vzalloc(buf_size * sizeof(*vpp->vfpool));
- if (!vpp->vfpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc vf pool fail.\n");
- ret = -ENOMEM;
- goto error5;
- }
-
- /* setup processing fifo */
- ret = kfifo_alloc(&vpp->processing, buf_size, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc processing fifo fail.\n");
- ret = -ENOMEM;
- goto error6;
- }
-
- ret = kfifo_alloc(&vpp->input, VPP_FRAME_SIZE, GFP_KERNEL);
- if (ret) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc input fifo fail.\n");
- ret = -ENOMEM;
- goto error7;
- }
-
- vpp->ivbpool = vzalloc(VPP_FRAME_SIZE * sizeof(*vpp->ivbpool));
- if (!vpp->ivbpool) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "alloc input vb pool fail.\n");
- ret = -ENOMEM;
- goto error8;
- }
-
- for (i = 0 ; i < VPP_FRAME_SIZE ; i++) {
- kfifo_put(&vpp->input, &vpp->ivbpool[i]);
- }
-
- for (i = 0 ; i < buf_size ; i++) {
- kfifo_put(&vpp->output, &vpp->ovbpool[i]);
- kfifo_put(&vpp->frame, &vpp->vfpool[i]);
- }
-
- mutex_init(&vpp->output_lock);
- sema_init(&vpp->sem_in, 0);
- sema_init(&vpp->sem_out, 0);
-
- vpp->running = true;
- vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp,
- "aml-%s", "aml-v4l2-vpp");
- if (IS_ERR(vpp->task)) {
- ret = PTR_ERR(vpp->task);
- goto error9;
- }
- sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, ¶m);
-
- vpp->di_ibuf_num = di_get_input_buffer_num(vpp->di_handle);
- vpp->di_obuf_num = di_get_output_buffer_num(vpp->di_handle);
-
- *vpp_handle = vpp;
-
- v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
- "vpp_wrapper init bsize:%d, di(i:%d, o:%d), wkm:%x, bm:%x, fmt:%x, drm:%d, prog:%d, byp:%d, local:%d, NR:%d\n",
- vpp->buf_size,
- vpp->di_ibuf_num,
- vpp->di_obuf_num,
- vpp->work_mode,
- vpp->buffer_mode,
- init.output_format,
- cfg->is_drm,
- cfg->is_prog,
- cfg->is_bypass_p,
- cfg->enable_local_buf,
- cfg->enable_nr);
-
- return 0;
-
-error9:
- vfree(vpp->ivbpool);
-error8:
- kfifo_free(&vpp->input);
-error7:
- kfifo_free(&vpp->processing);
-error6:
- vfree(vpp->vfpool);
-error5:
- kfifo_free(&vpp->frame);
-error4:
- vfree(vpp->ovbpool);
-error3:
- kfifo_free(&vpp->output);
-error2:
- di_destroy_instance(vpp->di_handle);
-error:
- kfree(vpp);
- return ret;
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_init);
-
-int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp)
-{
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
- "vpp destroy begin\n");
- vpp->running = false;
- up(&vpp->sem_in);
- up(&vpp->sem_out);
- kthread_stop(vpp->task);
-
- di_destroy_instance(vpp->di_handle);
- /* no more vpp callback below this line */
-
- if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
- release_DI_buff(vpp);
-
- kfifo_free(&vpp->processing);
- kfifo_free(&vpp->frame);
- vfree(vpp->vfpool);
- kfifo_free(&vpp->output);
- vfree(vpp->ovbpool);
- kfifo_free(&vpp->input);
- vfree(vpp->ivbpool);
- mutex_destroy(&vpp->output_lock);
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
- "vpp_wrapper destroy done\n");
- kfree(vpp);
-
- return 0;
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_destroy);
-
-static int aml_v4l2_vpp_push_vframe(struct aml_v4l2_vpp* vpp, struct vframe_s *vf)
-{
- struct aml_v4l2_vpp_buf *in_buf;
- struct vdec_v4l2_buffer *fb = NULL;
-
- if (!vpp)
- return -EINVAL;
-
- if (!kfifo_get(&vpp->input, &in_buf)) {
- v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
- "cat not get free input buffer.\n");
- return -1;
- }
-
-#if 0 //to debug di by frame
- if (vpp->in_num[INPUT_PORT] > 2)
- return 0;
- if (vpp->in_num[INPUT_PORT] == 2)
- vf->type |= VIDTYPE_V4L_EOS;
-#endif
-
- in_buf->di_buf.vf = vf;
- in_buf->di_buf.flag = 0;
- if (vf->type & VIDTYPE_V4L_EOS) {
- u32 dw_mode = VDEC_DW_NO_AFBC;
-
- in_buf->di_buf.flag |= DI_FLAG_EOS;
-
- if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
- return -1;
-
- vf->type |= vpp->ctx->vpp_cfg.is_prog ?
- VIDTYPE_PROGRESSIVE :
- VIDTYPE_INTERLACE;
-
- if (dw_mode != VDEC_DW_NO_AFBC)
- vf->type |= VIDTYPE_COMPRESS;
- }
-
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
- if ((vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
- (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
- (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
- (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
- (vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- else {
- if (fb->status == FB_ST_GE2D)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
- }
- } else {
- if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
- vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
- }
-
- v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
- "vpp_push_vframe: idx:%d, vf:%px, idx:%d, type:%x, ts:%lld\n",
- fb->buf_idx, vf, vf->index, vf->type, vf->timestamp);
-
- do {
- unsigned int dw_mode = VDEC_DW_NO_AFBC;
- struct file *fp;
-
- if (!dump_vpp_input || vpp->ctx->is_drm_mode)
- break;
- if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
- break;
- if (dw_mode == VDEC_DW_AFBC_ONLY)
- break;
-
- fp = filp_open("/data/dec_dump_before.raw",
- O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
- if (!IS_ERR(fp)) {
- struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
-
- kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
- if (in_buf->aml_buf->frame_buffer.num_planes == 2)
- kernel_write(fp,vb2_plane_vaddr(vb, 1),
- vb->planes[1].length, 0);
- dump_vpp_input--;
- filp_close(fp, NULL);
- }
- } while(0);
-
- ATRACE_COUNTER("VC_OUT_VPP-0.receive", fb->buf_idx);
-
- kfifo_put(&vpp->in_done_q, in_buf);
- up(&vpp->sem_in);
-
- return 0;
-}
-
-static void fill_vpp_buf_cb(void *v4l_ctx, void *fb_ctx)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)v4l_ctx;
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)fb_ctx;
- int ret = -1;
-
- ret = aml_v4l2_vpp_push_vframe(ctx->vpp, fb->vframe);
- if (ret < 0) {
- v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
- "vpp push vframe err, ret: %d\n", ret);
- }
-}
-
-static struct task_ops_s vpp_ops = {
- .type = TASK_TYPE_VPP,
- .get_vframe = vpp_vf_get,
- .put_vframe = vpp_vf_put,
- .fill_buffer = fill_vpp_buf_cb,
-};
-
-struct task_ops_s *get_vpp_ops(void)
-{
- return &vpp_ops;
-}
-EXPORT_SYMBOL(get_vpp_ops);
-
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.h b/drivers/amvdec_ports/aml_vcodec_vpp.h
deleted file mode 100644
index 7a5771d..0000000
--- a/drivers/amvdec_ports/aml_vcodec_vpp.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef _AML_VCODEC_VPP_H_
-#define _AML_VCODEC_VPP_H_
-
-#define SUPPORT_V4L_VPP
-
-#include <linux/kfifo.h>
-#ifdef SUPPORT_V4L_VPP
-#include <linux/amlogic/media/di/di_interface.h>
-#endif
-#include "aml_vcodec_drv.h"
-#include "aml_vcodec_dec.h"
-
-enum vpp_work_mode {
- VPP_MODE_DI,
- VPP_MODE_COLOR_CONV,
- VPP_MODE_NOISE_REDUC,
- VPP_MODE_DI_LOCAL = 0x81,
- VPP_MODE_COLOR_CONV_LOCAL = 0x82,
- VPP_MODE_NOISE_REDUC_LOCAL = 0x83,
- VPP_MODE_MAX = 0xff
-};
-
-#define VPP_FRAME_SIZE 64
-
-struct aml_v4l2_vpp_buf {
-#ifdef SUPPORT_V4L_VPP
- struct di_buffer di_buf;
- struct di_buffer *di_local_buf;
-#endif
- struct aml_video_dec_buf *aml_buf;
- struct aml_v4l2_vpp_buf *inbuf;
-};
-
-struct aml_v4l2_vpp {
- int di_handle; /* handle of DI */
- struct aml_vcodec_ctx *ctx;
- u32 buf_size; /* buffer size for vpp */
- u32 work_mode; /* enum vpp_work_mode */
- u32 buffer_mode;
-
- DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_vpp_buf*));
- DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_vpp_buf*));
- DECLARE_KFIFO_PTR(processing, typeof(struct aml_v4l2_vpp_buf*));
- DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *));
- DECLARE_KFIFO(out_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE);
- DECLARE_KFIFO(in_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE);
-
- struct vframe_s *vfpool;
- struct aml_v4l2_vpp_buf *ovbpool;
- struct aml_v4l2_vpp_buf *ivbpool;
- struct task_struct *task;
- bool running;
- struct semaphore sem_in, sem_out;
-
- /* In p to i transition, output/frame can be multi writer */
- struct mutex output_lock;
-
- /* for debugging */
- /*
- * in[0] --> vpp <-- in[1]
- * out[0]<-- vpp --> out[1]
- */
- int in_num[2];
- int out_num[2];
- ulong fb_token;
-
- bool is_prog;
- bool is_bypass_p;
- int di_ibuf_num;
- int di_obuf_num;
-};
-
-struct task_ops_s *get_vpp_ops(void);
-
-#ifdef SUPPORT_V4L_VPP
-/* get number of buffer needed for a working mode */
-int aml_v4l2_vpp_get_buf_num(u32 mode);
-int aml_v4l2_vpp_init(
- struct aml_vcodec_ctx *ctx,
- struct aml_vpp_cfg_infos *cfg,
- struct aml_v4l2_vpp** vpp_handle);
-int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp);
-int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp);
-#else
-static inline int aml_v4l2_vpp_get_buf_num(u32 mode) { return -1; }
-static inline int aml_v4l2_vpp_init(
- struct aml_vcodec_ctx *ctx,
- struct aml_vpp_cfg_infos *cfg,
- struct aml_v4l2_vpp** vpp_handle) { return -1; }
-static inline int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp) { return -1; }
-#endif
-
-#endif
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
index d0d0198..c9da299 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
index 24977a8..4ea76b9 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.h b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
index 9223639..0c81cb5 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
@@ -22,6 +22,7 @@
#include "../aml_vcodec_drv.h"
#include "../utils/common.h"
+
#define MAX_DPB_SIZE 16 // A.4.1
#define MAX_REFS 16
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
index c582ab0..fd56755 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
index 4704ba0..bbc9282 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
#ifndef AML_MJPEG_PARSER_H
#define AML_MJPEG_PARSER_H
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
index 748a83f..2720446 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
index c06d632..8abbc78 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
#ifndef AML_MPEG12_PARSER_H
#define AML_MPEG12_PARSER_H
@@ -7,6 +23,7 @@
#include "../utils/pixfmt.h"
#endif
+
/* Start codes. */
#define SEQ_END_CODE 0x000001b7
#define SEQ_START_CODE 0x000001b3
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
index 9c47c08..f680b12 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
index f9b71cf..3e5bf62 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
#ifndef AVCODEC_MPEG4VIDEO_H
#define AVCODEC_MPEG4VIDEO_H
diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.c b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
index 21d5283..b027b8a 100644
--- a/drivers/amvdec_ports/decoder/aml_vp9_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c
index c28ca10..e8693d4 100644
--- a/drivers/amvdec_ports/decoder/vdec_av1_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -29,6 +29,7 @@
#include "../aml_vcodec_drv.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "../utils/common.h"
#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
@@ -117,9 +118,9 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_av1_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
- struct vdec_comp_buf_info comp_info;
};
/*!\brief OBU types. */
@@ -206,7 +207,6 @@
static int vdec_write_nalu(struct vdec_av1_inst *inst,
u8 *buf, u32 size, u64 ts);
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode);
static void get_pic_info(struct vdec_av1_inst *inst,
struct vdec_pic_info *pic)
@@ -246,12 +246,12 @@
u8 *pbuf = parm;
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
- pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
- pbuf += sprintf(pbuf, "av1_double_write_mode:1;");
+ pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:11;");
+ pbuf += sprintf(pbuf, "av1_double_write_mode:3;");
pbuf += sprintf(pbuf, "av1_buf_width:1920;");
pbuf += sprintf(pbuf, "av1_buf_height:1088;");
- pbuf += sprintf(pbuf, "av1_max_pic_w:4096;");
- pbuf += sprintf(pbuf, "av1_max_pic_h:2304;");
+ pbuf += sprintf(pbuf, "av1_max_pic_w:8192;");
+ pbuf += sprintf(pbuf, "av1_max_pic_h:4608;");
pbuf += sprintf(pbuf, "save_buffer_mode:0;");
pbuf += sprintf(pbuf, "no_head:0;");
pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
@@ -264,10 +264,6 @@
{
struct aml_vcodec_ctx *ctx = inst->ctx;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s:parms_status = 0x%x, present_flag = %d\n",
- __func__, ctx->config.parm.dec.parms_status,
- ctx->config.parm.dec.hdr.color_parms.present_flag);
if (ctx->config.parm.dec.parms_status &
V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
@@ -277,8 +273,10 @@
ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "av1_double_write_mode:%d;",
ctx->config.parm.dec.cfg.double_write_mode);
- pbuf += sprintf(pbuf, "av1_buf_width:1920;");
- pbuf += sprintf(pbuf, "av1_buf_height:1088;");
+ pbuf += sprintf(pbuf, "av1_buf_width:%d;",
+ ctx->config.parm.dec.cfg.init_width);
+ pbuf += sprintf(pbuf, "av1_buf_height:%d;",
+ ctx->config.parm.dec.cfg.init_height);
pbuf += sprintf(pbuf, "save_buffer_mode:0;");
pbuf += sprintf(pbuf, "no_head:0;");
pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
@@ -287,23 +285,19 @@
ctx->config.parm.dec.cfg.canvas_mem_endian);
pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
ctx->config.parm.dec.cfg.low_latency_mode);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
- ctx->config.parm.dec.cfg.double_write_mode = 1;
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
if ((ctx->config.parm.dec.parms_status &
V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
- ctx->config.parm.dec.hdr.color_parms.present_flag) {
+ inst->parms.hdr.color_parms.present_flag) {
u8 *pbuf = ctx->config.buf + ctx->config.length;
pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
- pbuf += sprintf(pbuf, "signal_type:%d;",
- ctx->config.parm.dec.hdr.signal_type);
pbuf += sprintf(pbuf, "mG.x:%d;",
ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
pbuf += sprintf(pbuf, "mG.y:%d;",
@@ -332,8 +326,6 @@
inst->parms.hdr = ctx->config.parm.dec.hdr;
inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
}
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "config.buf = %s\n", ctx->config.buf);
inst->vdec.config = ctx->config;
inst->parms.cfg = ctx->config.parm.dec.cfg;
@@ -349,7 +341,6 @@
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "AV1";
inst->vdec.video_type = VFORMAT_AV1;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.ctx = ctx;
@@ -364,6 +355,16 @@
/* to eable av1 hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
+ goto err;
+ }
+
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_av1_vsi), GFP_KERNEL);
if (!inst->vsi) {
@@ -372,7 +373,7 @@
}
/* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi->header_buf) {
ret = -ENOMEM;
goto err;
@@ -380,6 +381,9 @@
init_completion(&inst->comp);
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "av1 Instance >> %lx\n", (ulong) inst);
+
ctx->ada_ctx = &inst->vdec;
*h_vdec = (unsigned long)inst;
@@ -391,13 +395,14 @@
goto err;
}
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "av1 Instance >> %lx\n", (ulong) inst);
+ //dump_init();
return 0;
err:
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -423,7 +428,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_av1_inst *inst,
@@ -444,7 +449,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_av1_inst *inst, u8 *buf, u32 size)
@@ -499,13 +504,19 @@
static void vdec_av1_deinit(unsigned long h_vdec)
{
+ ulong flags;
struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
struct aml_vcodec_ctx *ctx = inst->ctx;
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
+ spin_lock_irqsave(&ctx->slock, flags);
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -513,6 +524,42 @@
kfree(inst);
ctx->drv_handle = 0;
+ spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_av1_get_fb(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_av1_get_vf(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
}
// Returns 1 when OBU type is valid, and 0 otherwise.
@@ -589,7 +636,7 @@
int i;
const size_t leb_size = uleb_size_in_bytes(value);
- if (value > kMaximumLeb128Value || leb_size > kMaximumLeb128Size ||
+ if (leb_size > kMaximumLeb128Size ||
leb_size > available || !coded_value || !coded_size) {
return -1;
}
@@ -657,12 +704,13 @@
static int read_obu_header(struct read_bit_buffer *rb,
int is_annexb, struct ObuHeader *header)
{
- const int bit_buffer_byte_length =
- rb->bit_buffer_end - rb->bit_buffer;
+ int bit_buffer_byte_length;
if (!rb || !header)
return -1;
+ bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer;
+
if (bit_buffer_byte_length < 1)
return -1;
@@ -1000,13 +1048,13 @@
parser_frame(0, src, src + size, data, &length, meta_buffer, &meta_size);
if (length)
- ret = vdec_vframe_write(vdec, data, length, ts, 0);
+ ret = vdec_vframe_write(vdec, data, length, ts);
else
ret = -1;
vfree(data);
} else {
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
}
return ret;
@@ -1040,14 +1088,18 @@
{
struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
- u8 *buf = (u8 *) bs->vaddr;
- u32 size = bs->size;
+ u8 *buf;
+ u32 size;
int ret = -1;
if (bs == NULL)
return -1;
+ buf = (u8 *) bs->vaddr;
+ size = bs->size;
+
if (vdec_input_full(vdec)) {
+ ATRACE_COUNTER("vdec_input_full", 0);
return -EAGAIN;
}
@@ -1069,8 +1121,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -1086,6 +1137,7 @@
ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
}
+ ATRACE_COUNTER("v4l2_decode_write", ret);
return ret;
}
@@ -1093,12 +1145,8 @@
static void get_param_config_info(struct vdec_av1_inst *inst,
struct aml_dec_params *parms)
{
- if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
- /* dw use v4l cfg */
- inst->parms.cfg.double_write_mode =
- inst->ctx->config.parm.dec.cfg.double_write_mode;
- parms->cfg = inst->parms.cfg;
- }
+ if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+ parms->cfg = inst->parms.cfg;
if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
parms->ps = inst->parms.ps;
if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -1108,16 +1156,10 @@
parms->parms_status |= inst->parms.parms_status;
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"parms status: %u\n", parms->parms_status);
}
-static void get_param_comp_buf_info(struct vdec_av1_inst *inst,
- struct vdec_comp_buf_info *params)
-{
- memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
static int vdec_av1_get_param(unsigned long h_vdec,
enum vdec_get_param_type type, void *out)
{
@@ -1125,12 +1167,20 @@
struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the av1 inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_av1_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_av1_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -1147,20 +1197,6 @@
get_param_config_info(inst, out);
break;
- case GET_PARAM_DW_MODE:
- {
- u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
- break;
- }
- case GET_PARAM_COMP_BUF_INFO:
- get_param_comp_buf_info(inst, out);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -1175,69 +1211,12 @@
complete(&inst->comp);
}
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode)
-{
- u32 valid_dw_mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
- u32 dw = 0x1; /*1:1*/
-
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
-
- return dw;
-}
-
-static int vdec_pic_scale(struct vdec_av1_inst *inst, int length, int dw_mode)
-{
- int ret = 64;
-
- switch (vdec_get_dw_mode(inst, dw_mode)) {
- case 0x0: /* only afbc, output afbc */
- case 0x21: /* only afbc, output afbc */
- ret = 64;
- break;
- case 0x1: /* afbc and (w x h), output YUV420 */
- ret = length;
- break;
- case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
- case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
- ret = length >> 2;
- break;
- case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
- ret = length >> 1;
- break;
- case 0x10: /* (w x h), output YUV420-8bit) */
- default:
- ret = length;
- break;
- }
-
- return ret;
-}
-
static void set_param_ps_info(struct vdec_av1_inst *inst,
struct aml_vdec_ps_infos *ps)
{
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_av1_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.cfg.double_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -1253,16 +1232,11 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
- pic->field = ps->field;
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -1272,27 +1246,23 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
ps->visible_width, ps->visible_height,
- ps->coded_width, ps->coded_height);
-}
-
-static void set_param_comp_buf_info(struct vdec_av1_inst *inst,
- struct vdec_comp_buf_info *info)
-{
- memcpy(&inst->comp_info, info, sizeof(*info));
+ ps->coded_width, ps->coded_height,
+ ps->dpb_size);
}
static void set_param_hdr_info(struct vdec_av1_inst *inst,
struct aml_vdec_hdr_infos *hdr)
{
- if (hdr->signal_type != 0) {
+ if ((inst->parms.parms_status &
+ V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
inst->parms.hdr = *hdr;
inst->parms.parms_status |=
V4L2_CONFIG_PARM_DECODE_HDRINFO;
aml_vdec_dispatch_event(inst->ctx,
V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"av1 set HDR infos\n");
}
}
@@ -1304,12 +1274,6 @@
"av1 post event: %d\n", *event);
}
-static void set_pic_info(struct vdec_av1_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static int vdec_av1_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -1317,7 +1281,7 @@
struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the av1 inst of dec is invalid.\n");
return -1;
}
@@ -1331,10 +1295,6 @@
set_param_ps_info(inst, in);
break;
- case SET_PARAM_COMP_BUF_INFO:
- set_param_comp_buf_info(inst, in);
- break;
-
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
@@ -1342,11 +1302,6 @@
case SET_PARAM_POST_EVENT:
set_param_post_event(inst, in);
break;
-
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 911c91d..d13fc34 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -30,6 +30,7 @@
#include "../aml_vcodec_drv.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_h264_parser.h"
#include "../utils/common.h"
@@ -149,6 +150,7 @@
struct aml_vcodec_mem mv_buf[H264_MAX_FB_NUM];
struct aml_vdec_adapt vdec;
struct vdec_h264_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
};
@@ -279,10 +281,6 @@
ctx->config.parm.dec.cfg.canvas_mem_endian);
pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
ctx->config.parm.dec.cfg.low_latency_mode);
- pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
- ctx->config.parm.dec.cfg.metadata_config_flag);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.parm.dec.cfg.double_write_mode = 16;
@@ -299,13 +297,14 @@
{
struct vdec_h264_inst *inst = NULL;
int ret = -1;
+ bool dec_init = false;
- inst = vzalloc(sizeof(*inst));
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "H.264";
inst->vdec.video_type = VFORMAT_H264;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.ctx = ctx;
inst->ctx = ctx;
@@ -316,43 +315,60 @@
if (ctx->is_drm_mode)
inst->vdec.port.flag |= PORT_FLAG_DRM;
- /* probe info from the stream */
- inst->vsi = vzalloc(sizeof(struct vdec_h264_vsi));
- if (!inst->vsi) {
- ret = -ENOMEM;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
goto err;
}
- /* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
- if (!inst->vsi->header_buf) {
- ret = -ENOMEM;
- goto err;
- }
-
- init_completion(&inst->comp);
-
- ctx->ada_ctx = &inst->vdec;
- *h_vdec = (unsigned long)inst;
-
ret = video_decoder_init(&inst->vdec);
if (ret) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"vdec_h264 init err=%d\n", ret);
goto err;
}
+ dec_init = true;
+
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ init_completion(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"H264 Instance >> %lx", (ulong) inst);
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ //dump_init();
+
return 0;
err:
- if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
- if (inst && inst->vsi)
- vfree(inst->vsi);
+ if (dec_init)
+ video_decoder_release(&inst->vdec);
if (inst)
- vfree(inst);
+ vcodec_vfm_release(&inst->vfm);
+ if (inst && inst->vsi && inst->vsi->header_buf)
+ kfree(inst->vsi->header_buf);
+ if (inst && inst->vsi)
+ kfree(inst->vsi);
+ if (inst)
+ kfree(inst);
*h_vdec = 0;
return ret;
@@ -481,6 +497,7 @@
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
pic->profile_idc = sps->profile_idc;
+ pic->ref_frame_count= sps->ref_frame_count;
/* calc DPB size */
dec->dpb_sz = sps->num_reorder_frames + margin;
@@ -492,7 +509,7 @@
inst->parms.ps.mb_width = sps->mb_width;
inst->parms.ps.mb_height = sps->mb_height;
inst->parms.ps.ref_frames = sps->ref_frame_count;
- inst->parms.ps.dpb_frames = sps->num_reorder_frames;
+ inst->parms.ps.reorder_frames = sps->num_reorder_frames;
inst->parms.ps.dpb_size = dec->dpb_sz;
inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_PSINFO;
@@ -554,7 +571,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -565,7 +582,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_h264_inst *inst,
@@ -586,7 +603,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_h264_inst *inst, u8 *buf, u32 size)
@@ -671,20 +688,71 @@
static void vdec_h264_deinit(unsigned long h_vdec)
{
+ ulong flags;
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
struct aml_vcodec_ctx *ctx = inst->ctx;
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
+ spin_lock_irqsave(&ctx->slock, flags);
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
- vfree(inst->vsi);
+ kfree(inst->vsi);
- vfree(inst);
+ kfree(inst);
ctx->drv_handle = 0;
+ spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ if (fb) {
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+ }
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.vaddr, fb->base_c.size);
}
static int vdec_write_nalu(struct vdec_h264_inst *inst,
@@ -734,7 +802,7 @@
inst->vsi->head_offset += inst->vsi->sei_size;
ret = size;
} else if (inst->vsi->head_offset == 0) {
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
} else {
char *write_buf = vmalloc(inst->vsi->head_offset + size);
if (!write_buf) {
@@ -746,7 +814,7 @@
memcpy(write_buf + inst->vsi->head_offset, buf, size);
ret = vdec_vframe_write(vdec, write_buf,
- inst->vsi->head_offset + size, ts, 0);
+ inst->vsi->head_offset + size, ts);
memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
inst->vsi->head_offset = 0;
@@ -794,7 +862,9 @@
inst->vsi->cur_pic.coded_height !=
inst->vsi->pic.coded_height) ||
(inst->vsi->pic.profile_idc !=
- inst->vsi->cur_pic.profile_idc))) {
+ inst->vsi->cur_pic.profile_idc) ||
+ (inst->vsi->pic.ref_frame_count !=
+ inst->vsi->cur_pic.ref_frame_count))) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n");
inst->vsi->cur_pic = inst->vsi->pic;
return true;
@@ -808,13 +878,16 @@
{
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
- u8 *buf = (u8 *) bs->vaddr;
- u32 size = bs->size;
+ u8 *buf;
+ u32 size;
int ret = -1;
if (bs == NULL)
return -1;
+ buf = (u8 *) bs->vaddr;
+ size = bs->size;
+
if (vdec_input_full(vdec))
return -EAGAIN;
@@ -836,8 +909,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -889,12 +961,20 @@
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the h264 inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_h264_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_h264_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -910,14 +990,6 @@
case GET_PARAM_CONFIG_INFO:
get_param_config_info(inst, out);
break;
-
- case GET_PARAM_DW_MODE:
- {
- unsigned int* mode = out;
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- break;
- }
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -956,10 +1028,8 @@
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
pic->profile_idc = ps->profile;
+ pic->ref_frame_count = ps->ref_frames;
pic->field = ps->field;
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
inst->parms.ps = *ps;
@@ -972,9 +1042,10 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, visible(%d x %d), coded(%d x %d) dpb: %d, scan: %s\n",
ps->visible_width, ps->visible_height,
ps->coded_width, ps->coded_height,
+ dec->dpb_sz,
ps->field == V4L2_FIELD_NONE ? "P" : "I");
}
@@ -994,12 +1065,6 @@
}
}
-static void set_pic_info(struct vdec_h264_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
{
aml_vdec_dispatch_event(inst->ctx, *event);
@@ -1014,7 +1079,7 @@
struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the h264 inst of dec is invalid.\n");
return -1;
}
@@ -1035,11 +1100,6 @@
case SET_PARAM_POST_EVENT:
set_param_post_event(inst, in);
break;
-
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index 56d492a..2a41276 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -29,6 +29,7 @@
#include "../aml_vcodec_drv.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_hevc_parser.h"
#define HEVC_NAL_TYPE(value) ((value >> 1) & 0x3F)
@@ -111,9 +112,9 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_hevc_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
- struct vdec_comp_buf_info comp_info;
};
static void get_pic_info(struct vdec_hevc_inst *inst,
@@ -154,7 +155,7 @@
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
- pbuf += sprintf(pbuf, "hevc_double_write_mode:1;");
+ pbuf += sprintf(pbuf, "hevc_double_write_mode:16;");
pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -186,13 +187,9 @@
ctx->config.parm.dec.cfg.canvas_mem_endian);
pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
ctx->config.parm.dec.cfg.low_latency_mode);
- pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
- ctx->config.parm.dec.cfg.metadata_config_flag);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
- ctx->config.parm.dec.cfg.double_write_mode = 1;
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
@@ -206,13 +203,14 @@
{
struct vdec_hevc_inst *inst = NULL;
int ret = -1;
+ bool dec_init = false;
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "H.265";
inst->vdec.video_type = VFORMAT_HEVC;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.ctx = ctx;
inst->ctx = ctx;
@@ -226,6 +224,24 @@
/* to eable hevc hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
+ goto err;
+ }
+
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_hevc init err=%d\n", ret);
+ goto err;
+ }
+ dec_init = true;
+
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL);
if (!inst->vsi) {
@@ -234,7 +250,7 @@
}
/* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi->header_buf) {
ret = -ENOMEM;
goto err;
@@ -242,23 +258,22 @@
init_completion(&inst->comp);
- ctx->ada_ctx = &inst->vdec;
- *h_vdec = (unsigned long)inst;
-
- ret = video_decoder_init(&inst->vdec);
- if (ret) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
- "vdec_hevc init err=%d\n", ret);
- goto err;
- }
-
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"hevc Instance >> %lx\n", (ulong) inst);
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ //dump_init();
+
return 0;
err:
+ if (dec_init)
+ video_decoder_release(&inst->vdec);
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -302,8 +317,8 @@
static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
{
u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
+ int w = inst->parms.cfg.init_width;
+ int h = inst->parms.cfg.init_height;
u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
@@ -406,7 +421,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -417,7 +432,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_hevc_inst *inst,
@@ -438,7 +453,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_hevc_inst *inst, u8 *buf, u32 size)
@@ -511,13 +526,19 @@
static void vdec_hevc_deinit(unsigned long h_vdec)
{
+ ulong flags;
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
struct aml_vcodec_ctx *ctx = inst->ctx;
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
+ spin_lock_irqsave(&ctx->slock, flags);
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -525,6 +546,49 @@
kfree(inst);
ctx->drv_handle = 0;
+ spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_hevc_get_fb(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_hevc_get_vf(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.vaddr, fb->base_c.size);
}
static int vdec_write_nalu(struct vdec_hevc_inst *inst,
@@ -533,7 +597,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
return ret;
}
@@ -580,13 +644,16 @@
{
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
- u8 *buf = (u8 *) bs->vaddr;
- u32 size = bs->size;
+ u8 *buf;
+ u32 size;
int ret = -1;
if (bs == NULL)
return -1;
+ buf = (u8 *) bs->vaddr;
+ size = bs->size;
+
if (vdec_input_full(vdec))
return -EAGAIN;
@@ -608,8 +675,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -647,12 +713,6 @@
"parms status: %u\n", parms->parms_status);
}
-static void get_param_comp_buf_info(struct vdec_hevc_inst *inst,
- struct vdec_comp_buf_info *params)
-{
- memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
static int vdec_hevc_get_param(unsigned long h_vdec,
enum vdec_get_param_type type, void *out)
{
@@ -660,12 +720,20 @@
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the hevc inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_hevc_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_hevc_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -681,21 +749,6 @@
case GET_PARAM_CONFIG_INFO:
get_param_config_info(inst, out);
break;
-
- case GET_PARAM_DW_MODE:
- {
- u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
- break;
- }
- case GET_PARAM_COMP_BUF_INFO:
- get_param_comp_buf_info(inst, out);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -716,7 +769,6 @@
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.cfg.double_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -732,14 +784,9 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
-
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
@@ -751,27 +798,13 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d, scan: %s\n",
pic->visible_width, pic->visible_height,
pic->coded_width, pic->coded_height,
+ dec->dpb_sz,
pic->field == V4L2_FIELD_NONE ? "P" : "I");
}
-static void set_cfg_info(struct vdec_hevc_inst *inst,
- struct aml_vdec_cfg_infos *cfg)
-{
- memcpy(&inst->ctx->config.parm.dec.cfg,
- cfg, sizeof(struct aml_vdec_cfg_infos));
- memcpy(&inst->parms.cfg,
- cfg, sizeof(struct aml_vdec_cfg_infos));
-}
-
-static void set_param_comp_buf_info(struct vdec_hevc_inst *inst,
- struct vdec_comp_buf_info *info)
-{
- memcpy(&inst->comp_info, info, sizeof(*info));
-}
-
static void set_param_hdr_info(struct vdec_hevc_inst *inst,
struct aml_vdec_hdr_infos *hdr)
{
@@ -794,12 +827,6 @@
"H265 post event: %d\n", *event);
}
-static void set_pic_info(struct vdec_hevc_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static int vdec_hevc_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -807,7 +834,7 @@
struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the hevc inst of dec is invalid.\n");
return -1;
}
@@ -817,18 +844,10 @@
set_param_write_sync(inst);
break;
- case SET_PARAM_CFG_INFO:
- set_cfg_info(inst, in);
- break;
-
case SET_PARAM_PS_INFO:
set_param_ps_info(inst, in);
break;
- case SET_PARAM_COMP_BUF_INFO:
- set_param_comp_buf_info(inst, in);
- break;
-
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
@@ -836,10 +855,6 @@
case SET_PARAM_POST_EVENT:
set_param_post_event(inst, in);
break;
-
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 8332956..f9816cc 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -28,6 +28,7 @@
#include "../aml_vcodec_dec.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_mjpeg_parser.h"
#include <media/v4l2-mem2mem.h>
@@ -111,6 +112,7 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_mjpeg_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
};
@@ -156,7 +158,6 @@
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;");
- pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
return pbuf - parm;
}
@@ -176,8 +177,6 @@
ctx->config.parm.dec.cfg.ref_buf_margin);
pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
ctx->config.parm.dec.cfg.canvas_mem_endian);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -193,13 +192,14 @@
{
struct vdec_mjpeg_inst *inst = NULL;
int ret = -1;
+ bool dec_init = false;
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "MJPEG";
inst->vdec.video_type = VFORMAT_MJPEG;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.config = ctx->config;
inst->vdec.ctx = ctx;
@@ -213,6 +213,24 @@
/* to eable mjpeg hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
+ goto err;
+ }
+
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_mjpeg init err=%d\n", ret);
+ goto err;
+ }
+ dec_init = true;
+
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_mjpeg_vsi), GFP_KERNEL);
if (!inst->vsi) {
@@ -221,31 +239,30 @@
}
/* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi->header_buf) {
ret = -ENOMEM;
goto err;
}
- init_completion(&inst->comp);
- ctx->ada_ctx = &inst->vdec;
- *h_vdec = (unsigned long)inst;
-
- ret = video_decoder_init(&inst->vdec);
- if (ret) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
- "vdec_mjpeg init err=%d\n", ret);
- goto err;
- }
-
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"mjpeg Instance >> %lx\n", (ulong) inst);
+ init_completion(&inst->comp);
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ //dump_init();
+
return 0;
err:
+ if (dec_init)
+ video_decoder_release(&inst->vdec);
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -291,9 +308,9 @@
dec->dpb_sz = 8;
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
- "The stream infos, coded:(%d x %d), visible:(%d x %d)\n",
+ "The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n",
pic->coded_width, pic->coded_height,
- pic->visible_width, pic->visible_height);
+ pic->visible_width, pic->visible_height, dec->dpb_sz);
}
static int parse_stream_ucode(struct vdec_mjpeg_inst *inst,
@@ -302,7 +319,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -313,7 +330,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_mjpeg_inst *inst,
@@ -334,7 +351,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size)
@@ -414,8 +431,12 @@
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -423,13 +444,55 @@
kfree(inst);
}
+static int vdec_mjpeg_get_fb(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mjpeg_get_vf(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.va, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
static int vdec_write_nalu(struct vdec_mjpeg_inst *inst,
u8 *buf, u32 size, u64 ts)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
return ret;
}
@@ -457,8 +520,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -480,12 +542,20 @@
struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mjpeg inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_mjpeg_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_mjpeg_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -498,13 +568,6 @@
get_crop_info(inst, out);
break;
- case GET_PARAM_DW_MODE:
- {
- unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
- break;
- }
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -536,13 +599,9 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
pic->y_len_sz = pic->coded_width * pic->coded_height;
- pic->c_len_sz = pic->y_len_sz >> 1;
+ pic->c_len_sz = pic->y_len_sz;
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
- pic->field = ps->field;
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -552,10 +611,10 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
ps->visible_width, ps->visible_height,
ps->coded_width, ps->coded_height,
- pic->field == V4L2_FIELD_NONE ? "P" : "I");
+ dec->dpb_sz);
}
static void set_param_write_sync(struct vdec_mjpeg_inst *inst)
@@ -563,12 +622,6 @@
complete(&inst->comp);
}
-static void set_pic_info(struct vdec_mjpeg_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static int vdec_mjpeg_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -576,7 +629,7 @@
struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mjpeg inst of dec is invalid.\n");
return -1;
}
@@ -585,15 +638,10 @@
case SET_PARAM_WRITE_FRAME_SYNC:
set_param_write_sync(inst);
break;
-
case SET_PARAM_PS_INFO:
set_param_ps_info(inst, in);
break;
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
index 2472ac1..9a38e71 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -28,6 +28,7 @@
#include "../aml_vcodec_dec.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_mpeg12_parser.h"
#define NAL_TYPE(value) ((value) & 0x1F)
@@ -110,6 +111,7 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_mpeg12_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
};
@@ -171,10 +173,6 @@
ctx->config.parm.dec.cfg.canvas_mem_mode);
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
ctx->config.parm.dec.cfg.ref_buf_margin);
- pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
- ctx->config.parm.dec.cfg.metadata_config_flag);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -189,13 +187,14 @@
{
struct vdec_mpeg12_inst *inst = NULL;
int ret = -1;
+ bool dec_init = false;
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "MPEG2";
inst->vdec.video_type = VFORMAT_MPEG12;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.config = ctx->config;
inst->vdec.ctx = ctx;
@@ -210,6 +209,24 @@
/* to eable mpeg12 hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
+ goto err;
+ }
+
+ ret = video_decoder_init(&inst->vdec);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "vdec_mpeg12 init err=%d\n", ret);
+ goto err;
+ }
+ dec_init = true;
+
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_mpeg12_vsi), GFP_KERNEL);
if (!inst->vsi) {
@@ -218,31 +235,29 @@
}
/* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi->header_buf) {
ret = -ENOMEM;
goto err;
}
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+ "mpeg12 Instance >> %lx\n", (ulong) inst);
init_completion(&inst->comp);
ctx->ada_ctx = &inst->vdec;
*h_vdec = (unsigned long)inst;
- ret = video_decoder_init(&inst->vdec);
- if (ret) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
- "vdec_mpeg12 init err=%d\n", ret);
- goto err;
- }
-
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "mpeg12 Instance >> %lx\n", (ulong) inst);
+ //dump_init();
return 0;
err:
+ if (dec_init)
+ video_decoder_release(&inst->vdec);
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -291,7 +306,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -302,7 +317,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_mpeg12_inst *inst,
@@ -323,7 +338,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size)
@@ -403,8 +418,12 @@
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -412,13 +431,55 @@
kfree(inst);
}
+static int vdec_mpeg12_get_fb(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mpeg12_get_vf(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.va, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
static int vdec_write_nalu(struct vdec_mpeg12_inst *inst,
u8 *buf, u32 size, u64 ts)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
return ret;
}
@@ -446,8 +507,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -462,19 +522,6 @@
return ret;
}
-static void get_param_config_info(struct vdec_mpeg12_inst *inst,
- struct aml_dec_params *parms)
-{
-
- if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
- parms->hdr = inst->parms.hdr;
-
- parms->parms_status |= inst->parms.parms_status;
-
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "parms status: %u\n", parms->parms_status);
-}
-
static int vdec_mpeg12_get_param(unsigned long h_vdec,
enum vdec_get_param_type type, void *out)
{
@@ -482,12 +529,20 @@
struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mpeg12 inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_mpeg12_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_mpeg12_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -500,17 +555,6 @@
get_crop_info(inst, out);
break;
- case GET_PARAM_CONFIG_INFO:
- get_param_config_info(inst, out);
- break;
-
- case GET_PARAM_DW_MODE:
- {
- unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
- break;
- }
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -525,12 +569,6 @@
complete(&inst->comp);
}
-static void set_pic_info(struct vdec_mpeg12_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static void set_param_ps_info(struct vdec_mpeg12_inst *inst,
struct aml_vdec_ps_infos *ps)
{
@@ -554,9 +592,6 @@
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
@@ -568,28 +603,13 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d scan: %s\n",
ps->visible_width, ps->visible_height,
ps->coded_width, ps->coded_height,
+ dec->dpb_sz,
pic->field == V4L2_FIELD_NONE ? "P" : "I");
}
-static void set_param_hdr_info(struct vdec_mpeg12_inst *inst,
- struct aml_vdec_hdr_infos *hdr)
-{
- inst->parms.hdr = *hdr;
- if (!(inst->parms.parms_status &
- V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
- inst->parms.hdr = *hdr;
- inst->parms.parms_status |=
- V4L2_CONFIG_PARM_DECODE_HDRINFO;
- aml_vdec_dispatch_event(inst->ctx,
- V4L2_EVENT_SRC_CH_HDRINFO);
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "mpeg12 set HDR infos\n");
- }
-}
-
static int vdec_mpeg12_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -597,7 +617,7 @@
struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mpeg12 inst of dec is invalid.\n");
return -1;
}
@@ -606,19 +626,10 @@
case SET_PARAM_WRITE_FRAME_SYNC:
set_param_write_sync(inst);
break;
-
- case SET_PARAM_HDR_INFO:
- set_param_hdr_info(inst, in);
- break;
-
case SET_PARAM_PS_INFO:
set_param_ps_info(inst, in);
break;
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
index bc0af24..c47bafc 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -28,6 +28,7 @@
#include "../aml_vcodec_dec.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_mpeg4_parser.h"
#define NAL_TYPE(value) ((value) & 0x1F)
@@ -110,6 +111,7 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_mpeg4_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
};
@@ -171,8 +173,6 @@
ctx->config.parm.dec.cfg.canvas_mem_mode);
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
ctx->config.parm.dec.cfg.ref_buf_margin);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -188,14 +188,15 @@
{
struct vdec_mpeg4_inst *inst = NULL;
int ret = -1;
+ bool dec_init = false;
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "MPEG4";
inst->vdec.video_type = VFORMAT_MPEG4;
inst->vdec.format = VIDEO_DEC_FORMAT_MPEG4_5;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.config = ctx->config;
inst->vdec.ctx = ctx;
@@ -209,23 +210,16 @@
/* to eable mpeg4 hw.*/
inst->vdec.port.type = PORT_TYPE_VIDEO;
- /* probe info from the stream */
- inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL);
- if (!inst->vsi) {
- ret = -ENOMEM;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
goto err;
}
-
- /* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
- if (!inst->vsi->header_buf) {
- ret = -ENOMEM;
- goto err;
- }
-
- init_completion(&inst->comp);
- ctx->ada_ctx = &inst->vdec;
- *h_vdec = (unsigned long)inst;
+ dec_init = true;
ret = video_decoder_init(&inst->vdec);
if (ret) {
@@ -234,14 +228,38 @@
goto err;
}
+ /* probe info from the stream */
+ inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL);
+ if (!inst->vsi) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* alloc the header buffer to be used cache sps or spp etc.*/
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
+ if (!inst->vsi->header_buf) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
"mpeg4 Instance >> %lx\n", (ulong) inst);
+ init_completion(&inst->comp);
+ ctx->ada_ctx = &inst->vdec;
+ *h_vdec = (unsigned long)inst;
+
+ //dump_init();
+
return 0;
err:
+ if (dec_init)
+ video_decoder_release(&inst->vdec);
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -298,7 +316,7 @@
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+ ret = vdec_vframe_write(vdec, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -309,7 +327,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_mpeg4_inst *inst,
@@ -330,7 +348,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size)
@@ -410,8 +428,12 @@
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -419,13 +441,55 @@
kfree(inst);
}
+static int vdec_mpeg4_get_fb(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mpeg4_get_vf(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.va, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
static int vdec_write_nalu(struct vdec_mpeg4_inst *inst,
u8 *buf, u32 size, u64 ts)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
- ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
return ret;
}
@@ -453,8 +517,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -476,12 +539,20 @@
struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mpeg4 inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_mpeg4_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_mpeg4_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -493,12 +564,6 @@
case GET_PARAM_CROP_INFO:
get_crop_info(inst, out);
break;
- case GET_PARAM_DW_MODE:
- {
- unsigned int* mode = out;
- *mode = VDEC_DW_NO_AFBC;
- break;
- }
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
@@ -533,9 +598,6 @@
pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
pic->field = ps->field;
@@ -547,9 +609,10 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d, scan:%s\n",
ps->visible_width, ps->visible_height,
ps->coded_width, ps->coded_height,
+ dec->dpb_sz,
pic->field == V4L2_FIELD_NONE ? "P" : "I");
}
@@ -558,12 +621,6 @@
complete(&inst->comp);
}
-static void set_pic_info(struct vdec_mpeg4_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static int vdec_mpeg4_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -571,7 +628,7 @@
struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the mpeg4 inst of dec is invalid.\n");
return -1;
}
@@ -580,15 +637,10 @@
case SET_PARAM_WRITE_FRAME_SYNC:
set_param_write_sync(inst);
break;
-
case SET_PARAM_PS_INFO:
set_param_ps_info(inst, in);
break;
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index fe81ddd..6704350 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -29,6 +29,7 @@
#include "../aml_vcodec_drv.h"
#include "../aml_vcodec_adapt.h"
#include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
#include "aml_vp9_parser.h"
#include "vdec_vp9_trigger.h"
@@ -122,13 +123,13 @@
struct aml_vcodec_ctx *ctx;
struct aml_vdec_adapt vdec;
struct vdec_vp9_vsi *vsi;
+ struct vcodec_vfm_s vfm;
struct aml_dec_params parms;
struct completion comp;
- struct vdec_comp_buf_info comp_info;
};
static int vdec_write_nalu(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 ts, ulong meta_ptr);
+ u8 *buf, u32 size, u64 ts);
static void get_pic_info(struct vdec_vp9_inst *inst,
struct vdec_pic_info *pic)
@@ -169,7 +170,7 @@
pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
- pbuf += sprintf(pbuf, "vp9_double_write_mode:1;");
+ pbuf += sprintf(pbuf, "vp9_double_write_mode:16;");
pbuf += sprintf(pbuf, "vp9_buf_width:1920;");
pbuf += sprintf(pbuf, "vp9_buf_height:1088;");
pbuf += sprintf(pbuf, "vp9_max_pic_w:4096;");
@@ -186,10 +187,6 @@
{
struct aml_vcodec_ctx *ctx = inst->ctx;
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "%s:parms_status = 0x%x, present_flag = %d\n",
- __func__, ctx->config.parm.dec.parms_status,
- ctx->config.parm.dec.hdr.color_parms.present_flag);
if (ctx->config.parm.dec.parms_status &
V4L2_CONFIG_PARM_DECODE_CFGINFO) {
u8 *pbuf = ctx->config.buf;
@@ -211,11 +208,9 @@
ctx->config.parm.dec.cfg.canvas_mem_endian);
pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
ctx->config.parm.dec.cfg.low_latency_mode);
- pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
- ctx->config.parm.dec.cfg.duration);
ctx->config.length = pbuf - ctx->config.buf;
} else {
- ctx->config.parm.dec.cfg.double_write_mode = 1;
+ ctx->config.parm.dec.cfg.double_write_mode = 16;
ctx->config.parm.dec.cfg.ref_buf_margin = 7;
ctx->config.length = vdec_config_default_parms(ctx->config.buf);
}
@@ -226,8 +221,6 @@
u8 *pbuf = ctx->config.buf + ctx->config.length;
pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
- pbuf += sprintf(pbuf, "signal_type:%d;",
- ctx->config.parm.dec.hdr.signal_type);
pbuf += sprintf(pbuf, "mG.x:%d;",
ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
pbuf += sprintf(pbuf, "mG.y:%d;",
@@ -256,8 +249,6 @@
inst->parms.hdr = ctx->config.parm.dec.hdr;
inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
}
- v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
- "config.buf = %s\n", ctx->config.buf);
inst->vdec.config = ctx->config;
inst->parms.cfg = ctx->config.parm.dec.cfg;
@@ -273,8 +264,8 @@
if (!inst)
return -ENOMEM;
- inst->vdec.frm_name = "VP9";
inst->vdec.video_type = VFORMAT_VP9;
+ inst->vdec.dev = ctx->dev->vpu_plat_dev;
inst->vdec.filp = ctx->dev->filp;
inst->vdec.ctx = ctx;
inst->ctx = ctx;
@@ -288,6 +279,16 @@
/* to eable vp9 hw.*/
inst->vdec.port.type = PORT_TYPE_HEVC;
+ /* init vfm */
+ inst->vfm.ctx = ctx;
+ inst->vfm.ada_ctx = &inst->vdec;
+ ret = vcodec_vfm_init(&inst->vfm);
+ if (ret) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "init vfm failed.\n");
+ goto err;
+ }
+
/* probe info from the stream */
inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
if (!inst->vsi) {
@@ -296,7 +297,7 @@
}
/* alloc the header buffer to be used cache sps or spp etc.*/
- inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+ inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
if (!inst->vsi->header_buf) {
ret = -ENOMEM;
goto err;
@@ -318,10 +319,14 @@
goto err;
}
+ //dump_init();
+
return 0;
err:
+ if (inst)
+ vcodec_vfm_release(&inst->vfm);
if (inst && inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst && inst->vsi)
kfree(inst->vsi);
if (inst)
@@ -342,8 +347,8 @@
static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
{
u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
- int w = inst->vsi->pic.coded_width;
- int h = inst->vsi->pic.coded_height;
+ int w = inst->parms.cfg.init_width;
+ int h = inst->parms.cfg.init_height;
u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
@@ -438,11 +443,11 @@
}
static int parse_stream_ucode(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 timestamp, ulong meta_ptr)
+ u8 *buf, u32 size, u64 timestamp)
{
int ret = 0;
- ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr);
+ ret = vdec_write_nalu(inst, buf, size, timestamp);
if (ret < 0) {
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"write frame data failed. err: %d\n", ret);
@@ -453,7 +458,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_ucode_dma(struct vdec_vp9_inst *inst,
@@ -474,7 +479,7 @@
wait_for_completion_timeout(&inst->comp,
msecs_to_jiffies(1000));
- return inst->vsi->pic.dpb_frames ? 0 : -1;
+ return inst->vsi->dec.dpb_sz ? 0 : -1;
}
static int parse_stream_cpu(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
@@ -523,7 +528,7 @@
if (inst->ctx->param_sets_from_ucode) {
ret = parse_stream_ucode(inst, s->data,
- s->len, bs->timestamp, 0);
+ s->len, bs->timestamp);
} else {
ret = parse_stream_cpu(inst, s->data, s->len);
}
@@ -534,7 +539,7 @@
}
} else {
if (inst->ctx->param_sets_from_ucode) {
- ret = parse_stream_ucode(inst, buf, size, bs->timestamp, bs->meta_ptr);
+ ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
} else {
ret = parse_stream_cpu(inst, buf, size);
}
@@ -547,13 +552,19 @@
static void vdec_vp9_deinit(unsigned long h_vdec)
{
+ ulong flags;
struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
struct aml_vcodec_ctx *ctx = inst->ctx;
video_decoder_release(&inst->vdec);
+ vcodec_vfm_release(&inst->vfm);
+
+ //dump_deinit();
+
+ spin_lock_irqsave(&ctx->slock, flags);
if (inst->vsi && inst->vsi->header_buf)
- vfree(inst->vsi->header_buf);
+ kfree(inst->vsi->header_buf);
if (inst->vsi)
kfree(inst->vsi);
@@ -561,11 +572,54 @@
kfree(inst);
ctx->drv_handle = 0;
+ spin_unlock_irqrestore(&ctx->slock, flags);
need_trigger = false;
dump_cnt = 0;
}
+static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
+{
+ struct vframe_s *vf = NULL;
+ struct vdec_v4l2_buffer *fb = NULL;
+
+ vf = peek_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "there is no vframe.\n");
+ *out = NULL;
+ return;
+ }
+
+ vf = get_video_frame(&inst->vfm);
+ if (!vf) {
+ v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ "the vframe is avalid.\n");
+ *out = NULL;
+ return;
+ }
+
+ atomic_set(&vf->use_cnt, 1);
+
+ fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+ fb->vf_handle = (unsigned long)vf;
+ fb->status = FB_ST_DISPLAY;
+
+ *out = fb;
+
+ //pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+ //dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+ //dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+ /* convert yuv format. */
+ //swap_uv(fb->base_c.vaddr, fb->base_c.size);
+}
+
static void add_prefix_data(struct vp9_superframe_split *s,
u8 **out, u32 *out_size)
{
@@ -716,7 +770,7 @@
for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
frame_size = vp9_trigger_framesize[i];
ret = vdec_vframe_write(vdec, p,
- frame_size, 0, 0);
+ frame_size, 0);
v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR,
"write trigger frame %d\n", ret);
p += frame_size;
@@ -724,7 +778,7 @@
}
static int vdec_write_nalu(struct vdec_vp9_inst *inst,
- u8 *buf, u32 size, u64 ts, ulong meta_ptr)
+ u8 *buf, u32 size, u64 ts)
{
int ret = 0;
struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -754,10 +808,10 @@
/*add headers.*/
add_prefix_data(&s, &data, &length);
- ret = vdec_vframe_write(vdec, data, length, ts, 0);
+ ret = vdec_vframe_write(vdec, data, length, ts);
vfree(data);
} else {
- ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr);
+ ret = vdec_vframe_write(vdec, buf, size, ts);
}
return ret;
@@ -791,14 +845,18 @@
{
struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
struct aml_vdec_adapt *vdec = &inst->vdec;
- u8 *buf = (u8 *) bs->vaddr;
- u32 size = bs->size;
+ u8 *buf;
+ u32 size;
int ret = -1;
if (bs == NULL)
return -1;
+ buf = (u8 *) bs->vaddr;
+ size = bs->size;
+
if (vdec_input_full(vdec)) {
+ ATRACE_COUNTER("vdec_input_full", 0);
return -EAGAIN;
}
@@ -820,8 +878,7 @@
ret = vdec_vframe_write(vdec,
s->data,
s->len,
- bs->timestamp,
- 0);
+ bs->timestamp);
} else if (bs->model == VB2_MEMORY_DMABUF ||
bs->model == VB2_MEMORY_USERPTR) {
ret = vdec_vframe_write_with_dma(vdec,
@@ -834,8 +891,10 @@
if ((!inst->ctx->param_sets_from_ucode) &&
(*res_chg = monitor_res_change(inst, buf, size)))
return 0;
- ret = vdec_write_nalu(inst, buf, size, bs->timestamp, bs->meta_ptr);
+
+ ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
}
+ ATRACE_COUNTER("v4l2_decode_write", ret);
return ret;
}
@@ -858,12 +917,6 @@
"parms status: %u\n", parms->parms_status);
}
-static void get_param_comp_buf_info(struct vdec_vp9_inst *inst,
- struct vdec_comp_buf_info *params)
-{
- memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
static int vdec_vp9_get_param(unsigned long h_vdec,
enum vdec_get_param_type type, void *out)
{
@@ -871,12 +924,20 @@
struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the vp9 inst of dec is invalid.\n");
return -1;
}
switch (type) {
+ case GET_PARAM_DISP_FRAME_BUFFER:
+ vdec_vp9_get_vf(inst, out);
+ break;
+
+ case GET_PARAM_FREE_FRAME_BUFFER:
+ ret = vdec_vp9_get_fb(inst, out);
+ break;
+
case GET_PARAM_PIC_INFO:
get_pic_info(inst, out);
break;
@@ -892,21 +953,6 @@
case GET_PARAM_CONFIG_INFO:
get_param_config_info(inst, out);
break;
-
- case GET_PARAM_DW_MODE:
- {
- u32 *mode = out;
- u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
- if (m <= 16)
- *mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
- else
- *mode = vdec_get_dw_mode(inst, 0);
- break;
- }
- case GET_PARAM_COMP_BUF_INFO:
- get_param_comp_buf_info(inst, out);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid get parameter type=%d\n", type);
@@ -927,7 +973,6 @@
struct vdec_pic_info *pic = &inst->vsi->pic;
struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
struct v4l2_rect *rect = &inst->vsi->crop;
- int dw = inst->parms.cfg.double_write_mode;
/* fill visible area size that be used for EGL. */
pic->visible_width = ps->visible_width;
@@ -943,16 +988,11 @@
pic->coded_width = ps->coded_width;
pic->coded_height = ps->coded_height;
- pic->y_len_sz = ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
- ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+ pic->y_len_sz = pic->coded_width * pic->coded_height;
pic->c_len_sz = pic->y_len_sz >> 1;
/* calc DPB size */
- pic->dpb_frames = ps->dpb_frames;
- pic->dpb_margin = ps->dpb_margin;
- pic->vpp_margin = ps->dpb_margin;
dec->dpb_sz = ps->dpb_size;
- pic->field = ps->field;
inst->parms.ps = *ps;
inst->parms.parms_status |=
@@ -962,15 +1002,10 @@
complete(&inst->comp);
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
- "Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
- pic->visible_width, pic->visible_height,
- pic->coded_width, pic->coded_height);
-}
-
-static void set_param_comp_buf_info(struct vdec_vp9_inst *inst,
- struct vdec_comp_buf_info *info)
-{
- memcpy(&inst->comp_info, info, sizeof(*info));
+ "Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
+ ps->visible_width, ps->visible_height,
+ ps->coded_width, ps->coded_height,
+ ps->dpb_size);
}
static void set_param_hdr_info(struct vdec_vp9_inst *inst,
@@ -995,12 +1030,6 @@
"VP9 post event: %d\n", *event);
}
-static void set_pic_info(struct vdec_vp9_inst *inst,
- struct vdec_pic_info *pic)
-{
- inst->vsi->pic = *pic;
-}
-
static int vdec_vp9_set_param(unsigned long h_vdec,
enum vdec_set_param_type type, void *in)
{
@@ -1008,7 +1037,7 @@
struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
if (!inst) {
- v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+ v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
"the vp9 inst of dec is invalid.\n");
return -1;
}
@@ -1022,10 +1051,6 @@
set_param_ps_info(inst, in);
break;
- case SET_PARAM_COMP_BUF_INFO:
- set_param_comp_buf_info(inst, in);
- break;
-
case SET_PARAM_HDR_INFO:
set_param_hdr_info(inst, in);
break;
@@ -1033,11 +1058,6 @@
case SET_PARAM_POST_EVENT:
set_param_post_event(inst, in);
break;
-
- case SET_PARAM_PIC_INFO:
- set_pic_info(inst, in);
- break;
-
default:
v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/utils/common.c b/drivers/amvdec_ports/utils/common.c
index 67cf93b..1d621da 100644
--- a/drivers/amvdec_ports/utils/common.c
+++ b/drivers/amvdec_ports/utils/common.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
@@ -221,12 +240,3 @@
_pr_hex("print hex ending. len %d\n\n", l);
}
-bool is_over_size(int w, int h, int size)
-{
- if (h != 0 && (w > size / h))
- return true;
-
- return false;
-}
-
-
diff --git a/drivers/amvdec_ports/utils/common.h b/drivers/amvdec_ports/utils/common.h
index 89ae50b..dd4c51f 100644
--- a/drivers/amvdec_ports/utils/common.h
+++ b/drivers/amvdec_ports/utils/common.h
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
#ifndef UTILS_COMMON_H
#define UTILS_COMMON_H
@@ -58,7 +77,7 @@
#ifndef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
/**
* YUV colorspace type.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.3.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3.
*/
enum AVColorSpace {
AVCOL_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
@@ -82,7 +101,7 @@
/**
* Chromaticity coordinates of the source primaries.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.1.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1.
*/
enum AVColorPrimaries {
AVCOL_PRI_RESERVED0 = 0,
@@ -106,7 +125,7 @@
/**
* Color Transfer Characteristic.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.2.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2.
*/
enum AVColorTransferCharacteristic {
AVCOL_TRC_RESERVED0 = 0,
@@ -132,8 +151,8 @@
AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma"
AVCOL_TRC_NB ///< Not part of ABI
};
-#endif
+#endif
//fmt
const char *av_color_space_name(enum AVColorSpace space);
const char *av_color_primaries_name(enum AVColorPrimaries primaries);
@@ -150,6 +169,4 @@
//debug
void print_hex_debug(u8 *data, u32 len, int max);
-bool is_over_size(int w, int h, int size);
-
-#endif
\ No newline at end of file
+#endif
diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c
index 01510c5..ed9f053 100644
--- a/drivers/amvdec_ports/vdec_drv_if.c
+++ b/drivers/amvdec_ports/vdec_drv_if.c
@@ -116,19 +116,6 @@
return ret;
}
-int vdec_if_set_param(struct aml_vcodec_ctx *ctx,
- enum vdec_set_param_type type, void *in)
-{
- int ret = 0;
-
- if (ctx->drv_handle == 0)
- return -EIO;
-
- ret = ctx->dec_if->set_param(ctx->drv_handle, type, in);
-
- return ret;
-}
-
void vdec_if_deinit(struct aml_vcodec_ctx *ctx)
{
if (ctx->drv_handle == 0)
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index 29911f8..a04d832 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -50,48 +50,33 @@
/**
* struct vdec_fb_status - decoder frame buffer status
- * @FB_ST_INIT : initial state
- * @FB_ST_DECODER : frame buffer be allocted by decoder.
- * @FB_ST_VPP : frame buffer be allocate by vpp.
- * @FB_ST_DISPLAY : frame buffer is ready to be displayed.
+ * @FB_ST_NORMAL : initial state
+ * @FB_ST_DISPLAY : frmae buffer is ready to be displayed
* @FB_ST_FREE : frame buffer is not used by decoder any more
*/
enum vdec_fb_status {
- FB_ST_INIT,
- FB_ST_DECODER,
- FB_ST_VPP,
- FB_ST_GE2D,
+ FB_ST_NORMAL,
FB_ST_DISPLAY,
FB_ST_FREE
};
-enum vdec_dw_mode {
- VDEC_DW_AFBC_ONLY = 0,
- VDEC_DW_AFBC_1_1_DW = 1,
- VDEC_DW_AFBC_1_4_DW = 2,
- VDEC_DW_AFBC_x2_1_4_DW = 3,
- VDEC_DW_AFBC_1_2_DW = 4,
- VDEC_DW_NO_AFBC = 16,
- VDEC_DW_AFBC_AUTO_1_2 = 0x100,
- VDEC_DW_AFBC_AUTO_1_4 = 0x200,
-};
-
-/*
+/* For GET_PARAM_DISP_FRAME_BUFFER and GET_PARAM_FREE_FRAME_BUFFER,
* the caller does not own the returned buffer. The buffer will not be
* released before vdec_if_deinit.
+ * GET_PARAM_DISP_FRAME_BUFFER : get next displayable frame buffer,
+ * struct vdec_fb**
+ * GET_PARAM_FREE_FRAME_BUFFER : get non-referenced framebuffer, vdec_fb**
* GET_PARAM_PIC_INFO : get picture info, struct vdec_pic_info*
* GET_PARAM_CROP_INFO : get crop info, struct v4l2_crop*
* GET_PARAM_DPB_SIZE : get dpb size, unsigned int*
- * GET_PARAM_DW_MODE: : get double write mode, unsigned int*
- * GET_PARAM_COMP_BUF_INFO : get compressed buf info, struct vdec_comp_buf_info*
*/
enum vdec_get_param_type {
+ GET_PARAM_DISP_FRAME_BUFFER,
+ GET_PARAM_FREE_FRAME_BUFFER,
GET_PARAM_PIC_INFO,
GET_PARAM_CROP_INFO,
GET_PARAM_DPB_SIZE,
- GET_PARAM_CONFIG_INFO,
- GET_PARAM_DW_MODE,
- GET_PARAM_COMP_BUF_INFO
+ GET_PARAM_CONFIG_INFO
};
/*
@@ -100,11 +85,8 @@
enum vdec_set_param_type {
SET_PARAM_WRITE_FRAME_SYNC,
SET_PARAM_PS_INFO,
- SET_PARAM_COMP_BUF_INFO,
SET_PARAM_HDR_INFO,
- SET_PARAM_POST_EVENT,
- SET_PARAM_PIC_INFO,
- SET_PARAM_CFG_INFO
+ SET_PARAM_POST_EVENT
};
/**
@@ -156,10 +138,7 @@
* @type : [in] input parameter type
* @out : [out] buffer to store query result
*/
-int vdec_if_get_param(struct aml_vcodec_ctx *ctx,
- enum vdec_get_param_type type, void *out);
-
-int vdec_if_set_param(struct aml_vcodec_ctx *ctx,
- enum vdec_set_param_type type, void *in);
+int vdec_if_get_param(struct aml_vcodec_ctx *ctx, enum vdec_get_param_type type,
+ void *out);
#endif
diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c
index 158e32c..d692ca8 100644
--- a/drivers/common/chips/chips.c
+++ b/drivers/common/chips/chips.c
@@ -25,7 +25,7 @@
#include <linux/mm.h>
#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include "../../stream_input/amports/amports_priv.h"
#include "../../frame_provider/decoder/utils/vdec.h"
#include "chips.h"
@@ -78,14 +78,6 @@
{AM_MESON_CPU_MAJOR_ID_TL1, "tl1"},
{AM_MESON_CPU_MAJOR_ID_TM2, "tm2"},
{AM_MESON_CPU_MAJOR_ID_SC2, "sc2"},
- {AM_MESON_CPU_MAJOR_ID_T5, "t5"},
- {AM_MESON_CPU_MAJOR_ID_T5D, "t5d"},
- {AM_MESON_CPU_MAJOR_ID_T7, "t7"},
- {AM_MESON_CPU_MAJOR_ID_S4, "s4"},
- {AM_MESON_CPU_MAJOR_ID_T3, "t3"},
- {AM_MESON_CPU_MAJOR_ID_P1, "p1"},
- {AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
- {AM_MESON_CPU_MAJOR_ID_T5W, "t5w"},
{0, NULL},
};
diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c
index af162b8..d74728c 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.c
+++ b/drivers/common/chips/decoder_cpu_ver_info.c
@@ -24,7 +24,7 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include "decoder_cpu_ver_info.h"
#define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
@@ -32,7 +32,6 @@
#define MAJOR_ID_START AM_MESON_CPU_MAJOR_ID_M6
static enum AM_MESON_CPU_MAJOR_ID cpu_ver_id = AM_MESON_CPU_MAJOR_ID_MAX;
-static int cpu_sub_id = 0;
static enum AM_MESON_CPU_MAJOR_ID cpu_ver_info[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START]=
{
@@ -58,22 +57,13 @@
AM_MESON_CPU_MAJOR_ID_G12B,
AM_MESON_CPU_MAJOR_ID_GXLX2,
AM_MESON_CPU_MAJOR_ID_SM1,
- AM_MESON_CPU_MAJOR_ID_A1,
+ AM_MESON_CPU_MAJOR_ID_RES_0x2c,
AM_MESON_CPU_MAJOR_ID_RES_0x2d,
AM_MESON_CPU_MAJOR_ID_TL1,
AM_MESON_CPU_MAJOR_ID_TM2,
- AM_MESON_CPU_MAJOR_ID_C1,
+ AM_MESON_CPU_MAJOR_ID_RES_0x30,
AM_MESON_CPU_MAJOR_ID_RES_0x31,
AM_MESON_CPU_MAJOR_ID_SC2,
- AM_MESON_CPU_MAJOR_ID_C2,
- AM_MESON_CPU_MAJOR_ID_T5,
- AM_MESON_CPU_MAJOR_ID_T5D,
- AM_MESON_CPU_MAJOR_ID_T7,
- AM_MESON_CPU_MAJOR_ID_S4,
- AM_MESON_CPU_MAJOR_ID_T3,
- AM_MESON_CPU_MAJOR_ID_P1,
- AM_MESON_CPU_MAJOR_ID_S4D,
- AM_MESON_CPU_MAJOR_ID_T5W,
};
static const struct of_device_id cpu_ver_of_match[] = {
@@ -124,90 +114,32 @@
.compatible = "amlogic, cpu-major-id-sc2",
.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
},
- {
- .compatible = "amlogic, cpu-major-id-t5",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-t5d",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-t7",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-s4",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-t3",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-p1",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_P1 - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-s4d",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START],
- },
- {
- .compatible = "amlogic, cpu-major-id-t5w",
- .data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
- },
{},
};
-static const int cpu_sub_info[] = {
- AM_MESON_CPU_MINOR_ID_REVB_G12B,
- AM_MESON_CPU_MINOR_ID_REVB_TM2,
- AM_MESON_CPU_MINOR_ID_S4_S805X2,
-};
-
-static const struct of_device_id cpu_sub_id_of_match[] = {
- {
- .compatible = "amlogic, cpu-major-id-g12b-b",
- .data = &cpu_sub_info[0],
- },
- {
- .compatible = "amlogic, cpu-major-id-tm2-b",
- .data = &cpu_sub_info[1],
- },
- {
- .compatible = "amlogic, cpu-major-id-s4-805x2",
- .data = &cpu_sub_info[2],
- },
-};
-
-static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pid_type, int *sub_id)
+static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pidType)
{
- struct device_node *pnode = NULL;
- struct platform_device *pdev = NULL;
- const struct of_device_id *pmatch = NULL;
+ struct device_node *pNode = NULL;
+ struct platform_device* pDev = NULL;
+ const struct of_device_id *pMatch = NULL;
- pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
- if (NULL == pnode) {
+ pNode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+ if (NULL == pNode) {
pr_err("No find node.\n");
return -EINVAL;
}
- pdev = of_find_device_by_node(pnode);
- if (NULL == pdev)
+ pDev = of_find_device_by_node(pNode);
+ if (NULL == pDev)
return -EINVAL;
- pmatch = of_match_device(cpu_ver_of_match, &pdev->dev);
- if (NULL == pmatch) {
- pmatch = of_match_device(cpu_sub_id_of_match, &pdev->dev);
- if (NULL == pmatch) {
- pr_err("No find of_match_device\n");
- return -EINVAL;
- }
+ pMatch = of_match_device(cpu_ver_of_match, &pDev->dev);
+ if (NULL == pMatch) {
+ pr_err("No find of_match_device\n");
+ return -EINVAL;
}
- *pid_type = (enum AM_MESON_CPU_MAJOR_ID)(*(int *)pmatch->data) & (MAJOY_ID_MASK);
-
- *sub_id = ((*(int *)pmatch->data) & (SUB_ID_MASK)) >> 8;
+ *pidType = *(enum AM_MESON_CPU_MAJOR_ID *)pMatch->data;
return AM_SUCESS;
}
@@ -215,20 +147,15 @@
static void initial_cpu_id(void)
{
enum AM_MESON_CPU_MAJOR_ID id_type = AM_MESON_CPU_MAJOR_ID_MAX;
- int sub_id = 0;
- if (AM_SUCESS == get_cpu_id_from_dtb(&id_type, &sub_id)) {
+ if (AM_SUCESS == get_cpu_id_from_dtb(&id_type))
cpu_ver_id = id_type;
- cpu_sub_id = sub_id;
- } else {
+ else
cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type();
- cpu_sub_id = (is_meson_rev_b()) ? CHIP_REVB : CHIP_REVA;
- }
- if ((AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) && (CHIP_REVB == cpu_sub_id))
- cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
-
- pr_info("vdec init cpu id: 0x%x(%d)", cpu_ver_id, cpu_sub_id);
+ if (AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id)
+ if (is_meson_rev_b())
+ cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
}
enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void)
@@ -240,32 +167,10 @@
}
EXPORT_SYMBOL(get_cpu_major_id);
-int get_cpu_sub_id(void)
-{
- return cpu_sub_id;
-}
-EXPORT_SYMBOL(get_cpu_sub_id);
-
-bool is_cpu_meson_revb(void)
-{
- if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
- initial_cpu_id();
-
- return (cpu_sub_id == CHIP_REVB);
-}
-EXPORT_SYMBOL(is_cpu_meson_revb);
-
bool is_cpu_tm2_revb(void)
{
- return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2)
- && (is_cpu_meson_revb()));
+ return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) &&
+ (is_meson_rev_b()));
}
EXPORT_SYMBOL(is_cpu_tm2_revb);
-bool is_cpu_s4_s805x2(void)
-{
- return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4)
- && (get_cpu_sub_id() == CHIP_REVX));
-}
-EXPORT_SYMBOL(is_cpu_s4_s805x2);
-
diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h
index 6129244..673b001 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.h
+++ b/drivers/common/chips/decoder_cpu_ver_info.h
@@ -19,11 +19,9 @@
*/
#ifndef DECODER_CPU_VER_INFO_H
#define DECODER_CPU_VER_INFO_H
-#include <linux/amlogic/media/registers/cpu_version.h>
-/* majoy chip id define */
-#define MAJOY_ID_MASK (0x000000ff)
-enum AM_MESON_CPU_MAJOR_ID {
+enum AM_MESON_CPU_MAJOR_ID
+{
AM_MESON_CPU_MAJOR_ID_M6 = 0x16,
AM_MESON_CPU_MAJOR_ID_M6TV = 0x17,
AM_MESON_CPU_MAJOR_ID_M6TVL = 0x18,
@@ -46,50 +44,18 @@
AM_MESON_CPU_MAJOR_ID_G12B = 0x29,
AM_MESON_CPU_MAJOR_ID_GXLX2 = 0x2a,
AM_MESON_CPU_MAJOR_ID_SM1 = 0x2b,
- AM_MESON_CPU_MAJOR_ID_A1 = 0x2c,
+ AM_MESON_CPU_MAJOR_ID_RES_0x2c,
AM_MESON_CPU_MAJOR_ID_RES_0x2d,
AM_MESON_CPU_MAJOR_ID_TL1 = 0x2e,
AM_MESON_CPU_MAJOR_ID_TM2 = 0x2f,
- AM_MESON_CPU_MAJOR_ID_C1 = 0x30,
+ AM_MESON_CPU_MAJOR_ID_RES_0x30,
AM_MESON_CPU_MAJOR_ID_RES_0x31,
AM_MESON_CPU_MAJOR_ID_SC2 = 0x32,
- AM_MESON_CPU_MAJOR_ID_C2 = 0x33,
- AM_MESON_CPU_MAJOR_ID_T5 = 0x34,
- AM_MESON_CPU_MAJOR_ID_T5D = 0x35,
- AM_MESON_CPU_MAJOR_ID_T7 = 0x36,
- AM_MESON_CPU_MAJOR_ID_S4 = 0x37,
- AM_MESON_CPU_MAJOR_ID_T3 = 0x38,
- AM_MESON_CPU_MAJOR_ID_P1 = 0x39,
- AM_MESON_CPU_MAJOR_ID_S4D = 0x3a,
- AM_MESON_CPU_MAJOR_ID_T5W = 0x3b,
+ AM_MESON_CPU_MAJOR_ID_RES_0x33,
+ AM_MESON_CPU_MAJOR_ID_T5,
AM_MESON_CPU_MAJOR_ID_MAX,
};
-/* chips sub id define */
-#define CHIP_REVA 0x0
-#define CHIP_REVB 0x1
-#define CHIP_REVC 0x2
-#define CHIP_REVX 0x10
-
-#define REVB_MASK (CHIP_REVB << 8)
-#define REVC_MASK (CHIP_REVC << 8)
-#define REVX_MASK (CHIP_REVX << 8)
-
-#define SUB_ID_MASK (REVB_MASK | REVC_MASK | REVX_MASK)
-
-#define AM_MESON_CPU_MINOR_ID_REVB_G12B (REVB_MASK | AM_MESON_CPU_MAJOR_ID_G12B)
-#define AM_MESON_CPU_MINOR_ID_REVB_TM2 (REVB_MASK | AM_MESON_CPU_MAJOR_ID_TM2)
-#define AM_MESON_CPU_MINOR_ID_S4_S805X2 (REVX_MASK | AM_MESON_CPU_MAJOR_ID_S4)
-
-/* export functions */
enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void);
-
-bool is_cpu_meson_revb(void);
-
bool is_cpu_tm2_revb(void);
-
-int get_cpu_sub_id(void);
-
-bool is_cpu_s4_s805x2(void);
-
#endif
diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c
index 9422198..85a81e6 100644
--- a/drivers/common/firmware/firmware_drv.c
+++ b/drivers/common/firmware/firmware_drv.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include "../../stream_input/amports/amports_priv.h"
#include "../../frame_provider/decoder/utils/vdec.h"
#include "firmware_priv.h"
@@ -34,14 +34,13 @@
#include <linux/amlogic/media/utils/log.h>
#include <linux/firmware.h>
#include <linux/amlogic/tee.h>
-//#include <linux/amlogic/major.h> //if kernel is 4.9 then use this one
-#include <uapi/linux/major.h>
+#include <linux/amlogic/major.h>
#include <linux/cdev.h>
#include <linux/crc32.h>
#include "../chips/decoder_cpu_ver_info.h"
/* major.minor */
-#define PACK_VERS "v0.3"
+#define PACK_VERS "v0.2"
#define CLASS_NAME "firmware_codec"
#define DEV_NAME "firmware_vdec"
@@ -76,7 +75,6 @@
struct fw_mgr_s *g_mgr;
struct fw_dev_s *g_dev;
-struct package_head_s package_head;
static u32 debug;
static u32 detail;
@@ -87,7 +85,7 @@
struct fw_mgr_s *mgr = g_mgr;
struct fw_info_s *info;
- pr_info("[%s], the fw (%s) will be loaded...\n",
+ pr_info("[%s], the fw (%s) will be loaded.\n",
tee_enabled() ? "TEE" : "LOCAL",
get_fw_format_name(format));
@@ -111,7 +109,6 @@
break;
}
-
out:
mutex_unlock(&mutex);
@@ -344,8 +341,6 @@
struct fw_info_s *info;
unsigned int secs = 0;
struct tm tm;
- char history_change_id[7] = {0};
- int i;
mutex_lock(&mutex);
@@ -355,21 +350,7 @@
}
/* shows version of driver. */
- pr_info("The ucode driver version is %s\n", PACK_VERS);
-
- pr_info("The firmware version is %d.%d.%d-g%s\n",
- (package_head.version >> 16) & 0xff,
- package_head.version & 0xff,
- package_head.submit_count,
- package_head.commit);
-
- pr_info("change id history:\n");
- for (i = 0; i < 5; i++) {
- memset(history_change_id, 0, sizeof(history_change_id));
- strncpy(history_change_id, &(package_head.history_change_id[i * 6]), 6);
- pr_info("\t%s\n", history_change_id);
-
- }
+ pr_info("The driver version is %s\n", PACK_VERS);
list_for_each_entry(info, &mgr->fw_head, node) {
if (IS_ERR_OR_NULL(info->data))
@@ -394,8 +375,7 @@
secs = info->data->head.time
- sys_tz.tz_minuteswest * 60;
- //time_to_tm(secs, 0, &tm);//kernel4.9
- time64_to_tm(secs, 0, &tm);
+ time_to_tm(secs, 0, &tm);
pr_info("%s %-16s, %02d:%02d:%02d %d/%d/%ld, %s %-8s, %s %-8s, %s %s\n",
"fmt:", info->data->head.format,
@@ -597,7 +577,6 @@
if (ret != 2)
return -1;
- package_head = pack->head;
major_fw = (pack->head.version >> 16) & 0xff;
minor_fw = pack->head.version & 0xff;
@@ -616,7 +595,7 @@
if (debug) {
pr_info("The package has %d fws totally.\n", pack->head.total);
pr_info("The driver ver is v%d.%d\n", major, minor);
- pr_info("The firmware ver is v%d.%d.%d\n", major_fw, minor_fw, pack->head.submit_count);
+ pr_info("The firmware ver is v%d.%d\n", major_fw, minor_fw);
}
return 0;
@@ -931,7 +910,6 @@
return count;
}
-#if 0 //kernel4.9
static struct class_attribute fw_class_attrs[] = {
__ATTR(info, 0664, info_show, info_store),
__ATTR(reload, 0664, reload_show, reload_store),
@@ -943,26 +921,7 @@
.name = CLASS_NAME,
.class_attrs = fw_class_attrs,
};
-#else //below is for kernel 4.19 and 5.4
-static CLASS_ATTR_RW(info);
-static CLASS_ATTR_RW(reload);
-static CLASS_ATTR_RW(debug);
-static struct attribute *fw_class_attrs[] = {
- &class_attr_info.attr,
- &class_attr_reload.attr,
- &class_attr_debug.attr,
- NULL
-};
-
-ATTRIBUTE_GROUPS(fw_class);
-
-static struct class fw_class = {
- .name = CLASS_NAME,
- .class_groups = fw_class_groups,
-};
-
-#endif
static int fw_driver_init(void)
{
int ret = -1;
diff --git a/drivers/common/firmware/firmware_priv.h b/drivers/common/firmware/firmware_priv.h
index d901f9d..410745b 100644
--- a/drivers/common/firmware/firmware_priv.h
+++ b/drivers/common/firmware/firmware_priv.h
@@ -85,11 +85,7 @@
int checksum;
int total;
int version;
- int submit_count;
- char change_id[16];
- char commit[16];
- char history_change_id[30];
- char reserved[62];
+ char reserved[128];
};
struct package_s {
diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c
index 8d95c12..c232020 100644
--- a/drivers/common/firmware/firmware_type.c
+++ b/drivers/common/firmware/firmware_type.c
@@ -76,13 +76,6 @@
{AM_MESON_CPU_MAJOR_ID_TL1, "tl1"},
{AM_MESON_CPU_MAJOR_ID_TM2, "tm2"},
{AM_MESON_CPU_MAJOR_ID_SC2, "sc2"},
- {AM_MESON_CPU_MAJOR_ID_T5, "t5"},
- {AM_MESON_CPU_MAJOR_ID_T5D, "t5d"},
- {AM_MESON_CPU_MAJOR_ID_T7, "t7"},
- {AM_MESON_CPU_MAJOR_ID_S4, "s4"},
- {AM_MESON_CPU_MAJOR_ID_T3, "t3"},
- {AM_MESON_CPU_MAJOR_ID_P1, "p1"},
- {AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
};
const char *get_fw_format_name(unsigned int format)
diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h
index 4615baf..e997057 100644
--- a/drivers/common/firmware/firmware_type.h
+++ b/drivers/common/firmware/firmware_type.h
@@ -80,7 +80,6 @@
#define OPTEE_VDEC_LEGENCY (0)
#define OPTEE_VDEC (1)
#define OPTEE_VDEC_HEVC (2)
-#define OPTEE_VDEC_HCDEC (3)
struct format_name_s {
unsigned int format;
diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c
index 6340c1a..972bcc1 100644
--- a/drivers/common/media_clock/clk/clk.c
+++ b/drivers/common/media_clock/clk/clk.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include "../../../stream_input/amports/amports_priv.h"
#include "../../../frame_provider/decoder/utils/vdec.h"
#include "../../chips/chips.h"
@@ -165,7 +165,7 @@
void hcodec_clock_enable(void)
{
- hcodec_clock_set(667);
+ hcodec_clock_set(1);
}
EXPORT_SYMBOL(hcodec_clock_enable);
@@ -311,21 +311,6 @@
}
EXPORT_SYMBOL(get_clk_with_source);
-bool is_hevc_front_back_clk_combined(void)
-{
- int cpu_id = get_cpu_major_id();
-
- if (cpu_id == AM_MESON_CPU_MAJOR_ID_T5 ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_T5D) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_S4) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_S4D) ||
- (cpu_id == AM_MESON_CPU_MAJOR_ID_T5W))
- return true;
-
- return false;
-}
-EXPORT_SYMBOL(is_hevc_front_back_clk_combined);
-
int vdec_source_changed_for_clk_set(int format, int width, int height, int fps)
{
int clk = get_clk_with_source(format, width * height * fps);
@@ -353,8 +338,7 @@
|| format == VFORMAT_AV1) {
ret_clk = hevc_clock_set(clk);
clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A &&
- !is_hevc_front_back_clk_combined()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
ret_clk = hevc_back_clock_set(clk);
clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps;
}
@@ -388,7 +372,7 @@
*/
return 0; /* ignore don't needed firmare. */
}
- mgr = kmalloc(sizeof(struct chip_vdec_clk_s), GFP_KERNEL);
+ mgr = vzalloc(sizeof(struct chip_vdec_clk_s));
if (!mgr)
return -ENOMEM;
*mgr = *t_mgr;
@@ -397,7 +381,7 @@
*/
if (mgr->clock_init) {
if (mgr->clock_init()) {
- kfree(mgr);
+ vfree(mgr);
return -ENOMEM;
}
}
@@ -420,7 +404,7 @@
int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type)
{
- kfree(get_current_vdec_chip()->clk_mgr[vdec_type]);
+ vfree(get_current_vdec_chip()->clk_mgr[vdec_type]);
return 0;
}
@@ -439,7 +423,7 @@
*/
return 0; /* ignore don't needed this setting . */
}
- p_setting = kmalloc(size, GFP_KERNEL);
+ p_setting = vzalloc(size);
if (!p_setting)
return -ENOMEM;
memcpy(p_setting, setting, size);
@@ -465,7 +449,7 @@
int unregister_vdec_clk_setting(void)
{
- kfree(get_current_vdec_chip()->clk_setting_array);
+ vfree(get_current_vdec_chip()->clk_setting_array);
return 0;
}
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h
index bbc3bee..82eec1d 100644
--- a/drivers/common/media_clock/clk/clk.h
+++ b/drivers/common/media_clock/clk/clk.h
@@ -52,8 +52,6 @@
int vdec_source_get(enum vdec_type_e core);
int vdec_clk_get(enum vdec_type_e core);
-bool is_hevc_front_back_clk_combined(void);
-
int vdec_source_changed_for_clk_set(int format, int width, int height, int fps);
int get_clk_with_source(int format, int w_x_h_fps);
@@ -132,7 +130,7 @@
#endif
#ifdef VDEC_HAS_HEVC
register_vdec_clk_mgr(cpus, VDEC_HEVC, &vdec_hevc_clk_mgr);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A)
register_vdec_clk_mgr(cpus, VDEC_HEVCB, &vdec_hevc_back_clk_mgr);
#endif
#ifdef VDEC_HAS_VDEC_HCODEC
diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c
index c49d150..be2401c 100644
--- a/drivers/common/media_clock/clk/clkg12.c
+++ b/drivers/common/media_clock/clk/clkg12.c
@@ -114,6 +114,11 @@
WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1);\
}while(0)
+#define CHECK_RET(_ret) if (ret) {debug_print(\
+ "%s:%d:function call failed with result: %d\n",\
+ __FUNCTION__, __LINE__, _ret);}
+
+
static int clock_real_clk[VDEC_MAX + 1];
static unsigned int set_frq_enable, vdec_frq, hevc_frq, hevcb_frq;
@@ -125,14 +130,19 @@
static int gp_pll_user_cb_vdec(struct gp_pll_user_handle_s *user,
int event)
{
+ int ret;
+
debug_print("gp_pll_user_cb_vdec call\n");
if (event == GP_PLL_USER_EVENT_GRANT) {
struct clk *clk = clk_get(NULL, "gp0_pll");
if (!IS_ERR(clk)) {
- if (is_gp0_div2)
- clk_set_rate(clk, 1296000000UL);
- else
- clk_set_rate(clk, 648000000UL);
+ if (is_gp0_div2) {
+ ret = clk_set_rate(clk, 1296000000UL);
+ CHECK_RET(ret);
+ } else {
+ ret = clk_set_rate(clk, 648000000UL);
+ CHECK_RET(ret);
+ }
VDEC1_SAFE_CLOCK();
VDEC1_CLOCK_OFF();
if (is_gp0_div2)
@@ -416,9 +426,7 @@
struct gate_switch_node *node = NULL;
char *hevc_mux_str = NULL;
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D))
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)
hevc_mux_str = "clk_hevc_mux";
else
hevc_mux_str = "clk_hevcf_mux";
@@ -458,6 +466,7 @@
static int vdec_set_clk(int dec, int rate)
{
struct clk *clk = NULL;
+ int ret;
switch (dec) {
case VDEC_1:
@@ -497,7 +506,8 @@
return -1;
}
- clk_set_rate(clk, rate);
+ ret = clk_set_rate(clk, rate);
+ CHECK_RET(ret);
return 0;
}
@@ -513,12 +523,12 @@
{
gp_pll_user_vdec = gp_pll_user_register("vdec", 0,
gp_pll_user_cb_vdec);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL)
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL)
is_gp0_div2 = false;
else
is_gp0_div2 = true;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) {
pr_info("used fix clk for vdec clk source!\n");
//update_vdec_clk_config_settings(1);
}
@@ -733,14 +743,9 @@
}
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)
+ get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)
clk = 800;
- if (is_cpu_s4_s805x2())
- clk = 500;
-
if (set_frq_enable && vdec_frq) {
pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
clk = vdec_frq;
@@ -836,15 +841,10 @@
if ((clk > 500 && clk != 667)) {
if (clock_real_clk[VDEC_HEVC] == 648)
return 648;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
clk = TL1_HEVC_MAX_CLK;
else
clk = 667;
-
- if (is_cpu_s4_s805x2())
- clk = 500;
}
if (set_frq_enable && hevc_frq) {
@@ -1042,14 +1042,6 @@
AM_MESON_CPU_MAJOR_ID_TL1,\
AM_MESON_CPU_MAJOR_ID_TM2,\
AM_MESON_CPU_MAJOR_ID_SC2,\
- AM_MESON_CPU_MAJOR_ID_T5,\
- AM_MESON_CPU_MAJOR_ID_T5D,\
- AM_MESON_CPU_MAJOR_ID_T7,\
- AM_MESON_CPU_MAJOR_ID_S4,\
- AM_MESON_CPU_MAJOR_ID_T3,\
- AM_MESON_CPU_MAJOR_ID_P1,\
- AM_MESON_CPU_MAJOR_ID_S4D,\
- AM_MESON_CPU_MAJOR_ID_T5W,\
0}
#include "clk.h"
diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c
index 58a0289..9d5f7b4 100644
--- a/drivers/common/media_clock/switch/amports_gate.c
+++ b/drivers/common/media_clock/switch/amports_gate.c
@@ -99,11 +99,11 @@
gates[i].clk = devm_clk_get(dev, gates[i].name);
if (IS_ERR_OR_NULL(gates[i].clk)) {
gates[i].clk = NULL;
- pr_info("get gate %s control failed %px\n",
+ pr_info("get gate %s control failed %p\n",
gates[i].name,
gates[i].clk);
} else {
- pr_info("get gate %s control ok %px\n",
+ pr_info("get gate %s control ok %p\n",
gates[i].name,
gates[i].clk);
}
diff --git a/drivers/fake_video_out/Makefile b/drivers/fake_video_out/Makefile
new file mode 100644
index 0000000..1dd937c
--- /dev/null
+++ b/drivers/fake_video_out/Makefile
@@ -0,0 +1 @@
+obj-m += fake_video.o
diff --git a/drivers/fake_video_out/fake_video.c b/drivers/fake_video_out/fake_video.c
new file mode 100644
index 0000000..e0e9b16
--- /dev/null
+++ b/drivers/fake_video_out/fake_video.c
@@ -0,0 +1,309 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
+#include <linux/sched.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/major.h>
+#include "../frame_provider/decoder/utils/vdec.h"
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#define RECEIVER_NAME "fake-amvideo"
+#define DEVICE_NAME "fake-amvideo"
+
+#define TUNNEL_MODE (0)
+#define NON_TUNNEL_MODE (1)
+
+static u32 display_mode = TUNNEL_MODE;
+module_param(display_mode, uint, 0664);
+MODULE_PARM_DESC(display_mode, "\n display_mode\n");
+
+static struct device *amvideo_dev = NULL;
+struct timer_list timer;
+struct task_struct *task;
+bool thread_stop = false;
+atomic_t frame_count;
+
+static struct vframe_receiver_s fake_video_vf_recv;
+static int video_receiver_event_fun(int type, void *data, void *);
+static const struct vframe_receiver_op_s fake_video_vf_receiver = {
+ .event_cb = video_receiver_event_fun
+};
+
+static struct vframe_s *video_vf_peek(void)
+{
+ return vf_peek(RECEIVER_NAME);
+}
+
+static struct vframe_s *video_vf_get(void)
+{
+ struct vframe_s *vf = NULL;
+
+ vf = vf_get(RECEIVER_NAME);
+
+ if (vf) {
+ atomic_set(&vf->use_cnt, 1);
+ /*pr_err("Get vframe w: %d, h: %d, fence: %lx, idx: %d\n",
+ vf->width, vf->height, (ulong)vf->fence, vf->index & 0xff);*/
+ }
+
+ return vf;
+}
+
+static void video_vf_put(struct vframe_s *vf)
+{
+ struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME);
+
+ if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) {
+ vf_put(vf, RECEIVER_NAME);
+ }
+}
+
+static int video_receiver_event_fun(int type, void *data, void *private_data)
+{
+ switch (type) {
+ case VFRAME_EVENT_PROVIDER_UNREG: {
+ atomic_set(&frame_count, 0);
+ pr_info("VFRAME_EVENT_PROVIDER_UNREG\n");
+ break;
+ }
+ case VFRAME_EVENT_PROVIDER_START: {
+ pr_info("VFRAME_EVENT_PROVIDER_START\n");
+ break;
+ }
+ case VFRAME_EVENT_PROVIDER_QUREY_STATE: {
+ break;
+ }
+ case VFRAME_EVENT_PROVIDER_VFRAME_READY: {
+ pr_info("VFRAME_EVENT_PROVIDER_VFRAME_READY\n");
+ atomic_inc(&frame_count);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void display_timer_func(unsigned long arg)
+{
+ struct vframe_s *vf = NULL;
+
+ if (display_mode != TUNNEL_MODE)
+ goto out;
+
+ vf = video_vf_peek();
+ if (!vf) {
+ goto out;
+ }
+
+ if (vf->fence) {
+ if (vdec_fence_status_get(vf->fence) == 1) {
+ pr_info("[VDEC-FENCE]: Display, idx: %d\n",
+ vf->index & 0xff);
+ vf = video_vf_get();
+ video_vf_put(vf);
+ } else {
+ pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n");
+ }
+ }
+
+out:
+ mod_timer(&timer, jiffies + msecs_to_jiffies(16));
+}
+
+static int display_thread(void *data)
+{
+ struct vframe_s *vf = NULL;
+
+ for (;;) {
+ if (thread_stop)
+ break;
+
+ if ((atomic_read(&frame_count) == 0) ||
+ display_mode != NON_TUNNEL_MODE)
+ continue;
+
+ if (video_vf_peek()) {
+ vf = video_vf_get();
+ if (!vf) {
+ pr_err("receiver vf err.\n");
+ break;
+ }
+
+ atomic_dec(&frame_count);
+
+ if (vf->fence) {
+ u64 timestamp = local_clock();
+ /* fence waiting until frame ready. */
+ vdec_fence_wait(vf->fence, msecs_to_jiffies(2000));
+
+ if (vdec_fence_status_get(vf->fence) == 1) {
+ pr_info("[VDEC-FENCE]: Display, idx: %d, dec cost: %lld\n",
+ vf->index & 0xff, local_clock() - timestamp);
+ } else {
+ pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n");
+ }
+ }
+
+ video_vf_put(vf);
+ }
+ msleep(16);
+ }
+ return 0;
+}
+
+static int amvideo_open(struct inode *inode, struct file *file)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+static int amvideo_release(struct inode *inode, struct file *file)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+#ifdef CONFIG_COMPAT
+static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+ file->private_data = NULL;
+ return 0;
+}
+#endif
+
+static const struct file_operations amvideo_fops = {
+ .owner = THIS_MODULE,
+ .open = amvideo_open,
+ .release = amvideo_release,
+ .unlocked_ioctl = amvideo_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = amvideo_compat_ioctl,
+#endif
+ //.poll = amvideo_poll,
+};
+
+static struct class amvideo_class = {
+ .name = "fake_video",
+};
+
+#define FAKEVIDEO_MAJOR (23 + (AML_BASE))
+
+static int __init fake_video_init(void)
+{
+ int ret = 0;
+
+ ret = class_register(&amvideo_class);
+ if (ret) {
+ pr_err("create video class fail.\n");
+ return 0;
+ }
+
+
+ /* create video device */
+ ret = register_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME, &amvideo_fops);
+ if (ret < 0) {
+ pr_err("Can't register major for amvideo device\n");
+ goto err1;
+ }
+
+ amvideo_dev = device_create(&amvideo_class, NULL,
+ MKDEV(FAKEVIDEO_MAJOR, 0), NULL, DEVICE_NAME);
+ if (IS_ERR(amvideo_dev)) {
+ pr_err("Can't create amvideo device\n");
+ goto err;
+ }
+
+ vf_receiver_init(&fake_video_vf_recv, RECEIVER_NAME,
+ &fake_video_vf_receiver, NULL);
+ vf_reg_receiver(&fake_video_vf_recv);
+
+ atomic_set(&frame_count, 0);
+
+ init_timer(&timer);
+ //timer.data = 0;
+ timer.function = display_timer_func;
+ timer.expires = jiffies + HZ;
+ add_timer(&timer);
+
+ thread_stop = false;
+ task = kthread_run(display_thread, NULL, "aml-%s", "fake-video-thread");
+ if (IS_ERR(task)) {
+ ret = PTR_ERR(task);
+ pr_err("Failed to creat display thread, ret: %d.\n", ret);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME);
+err1:
+ class_unregister(&amvideo_class);
+
+ return ret;
+}
+
+static void __exit fake_video_exit(void)
+{
+ thread_stop = true;
+ kthread_stop(task);
+
+ del_timer_sync(&timer);
+
+ vf_unreg_receiver(&fake_video_vf_recv);
+
+ device_destroy(&amvideo_class, MKDEV(FAKEVIDEO_MAJOR, 0));
+ unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME);
+ class_unregister(&amvideo_class);
+
+}
+
+
+module_init(fake_video_init);
+module_exit(fake_video_exit);
+
+
+MODULE_DESCRIPTION("AMLOGIC fake video output driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>");
+
diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile
index f30c4f1..371e088 100644
--- a/drivers/frame_provider/Makefile
+++ b/drivers/frame_provider/Makefile
@@ -1,2 +1 @@
obj-y += decoder/
-obj-y += decoder_v4l/
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile
index bb0079e..349d381 100644
--- a/drivers/frame_provider/decoder/Makefile
+++ b/drivers/frame_provider/decoder/Makefile
@@ -7,6 +7,7 @@
obj-y += h265/
obj-y += vp9/
obj-y += mjpeg/
+obj-y += real/
obj-y += avs/
obj-y += avs2/
obj-y += avs_multi/
diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c
index 5869eac..6314f9d 100644
--- a/drivers/frame_provider/decoder/avs/avs.c
+++ b/drivers/frame_provider/decoder/avs/avs.c
@@ -43,8 +43,8 @@
#include "../utils/decoder_bmmu_box.h"
#include "../utils/firmware.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
+
#define DRIVER_NAME "amvdec_avs"
#define MODULE_NAME "amvdec_avs"
@@ -162,6 +162,7 @@
int canvas_num = 3;
#endif
+
static struct vframe_s vfpool[VF_POOL_SIZE];
/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
static struct vframe_s *cur_vfpool;
@@ -412,7 +413,6 @@
}
}
-
#ifdef HANDLE_AVS_IRQ
static irqreturn_t vavs_isr(int irq, void *dev_id)
#else
@@ -654,7 +654,6 @@
decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
-
kfifo_put(&display_q,
(const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -741,6 +740,7 @@
decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
+
decoder_do_frame_check(NULL, vf);
kfifo_put(&display_q,
(const struct vframe_s *)vf);
@@ -945,35 +945,35 @@
else
endian = 0;
#ifdef NV21
- config_cav_lut_ex(canvas_base + canvas_num * i + 0,
+ canvas_config_ex(canvas_base + canvas_num * i + 0,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_base + canvas_num * i + 1,
+ vdec->canvas_mode, endian);
+ canvas_config_ex(canvas_base + canvas_num * i + 1,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
+ vdec->canvas_mode, endian);
#else
- config_cav_lut_ex(canvas_num * i + 0,
+ canvas_config_ex(canvas_num * i + 0,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 1,
+ vdec->canvas_mode, endian);
+ canvas_config_ex(canvas_num * i + 1,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 2,
+ vdec->canvas_mode, endian);
+ canvas_config_ex(canvas_num * i + 2,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- vdec->canvas_mode, endian, VDEC_1);
+ vdec->canvas_mode, endian);
#endif
if (debug_flag & AVS_DEBUG_PRINT) {
pr_info("canvas config %d, addr %p\n", i,
@@ -1353,8 +1353,10 @@
}
}
-static void vavs_put_timer_func(struct timer_list *timer)
+static void vavs_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
+
#ifndef HANDLE_AVS_IRQ
vavs_isr();
#endif
@@ -1571,6 +1573,7 @@
return -ENOMEM;
pr_info("vavs_init\n");
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -1654,8 +1657,10 @@
stat |= STAT_VF_HOOK;
- timer_setup(&recycle_timer, vavs_put_timer_func, 0);
+ recycle_timer.data = (ulong)(&recycle_timer);
+ recycle_timer.function = vavs_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
index de9a3d2..3da87e4 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
+++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
@@ -39,9 +39,7 @@
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../utils/decoder_mmu_box.h"
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h
index be35a5e..3e7fcb8 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_global.h
+++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -772,9 +772,6 @@
uint8_t bg_flag;
/**/
unsigned long header_adr;
- /*AVS2_10B_MMU_DW*/
- unsigned long dw_header_adr;
-
int buf_size;
int lcu_total;
int comp_body_size;
@@ -817,9 +814,6 @@
u32 hw_decode_time;
u32 frame_size; // For frame base mode
-
- char *cuva_data_buf;
- int cuva_data_size;
};
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c
index e21dc55..a5d550f 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.c
+++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -37,9 +37,7 @@
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../utils/decoder_mmu_box.h"
@@ -57,46 +55,26 @@
#include "../utils/config_parser.h"
#include "../utils/firmware.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../utils/vdec_feature.h"
+#include <linux/amlogic/tee.h>
+
#define I_ONLY_SUPPORT
#define MIX_STREAM_SUPPORT
+#define G12A_BRINGUP_DEBUG
#define CONSTRAIN_MAX_BUF_NUM
-#define CO_MV_COMPRESS
-
#include "vavs2.h"
#define HEVC_SHIFT_LENGTH_PROTECT 0x313a
-#define HEVC_MPRED_CTRL4 0x324c
#define HEVC_MPRED_CTRL9 0x325b
#define HEVC_DBLK_CFGD 0x350d
+
+
#define HEVC_CM_HEADER_START_ADDR 0x3628
#define HEVC_DBLK_CFGB 0x350b
#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
#define HEVC_SAO_MMU_VH1_ADDR 0x363b
#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-#define HEVC_CM_BODY_LENGTH2 0x3663
-#define HEVC_CM_HEADER_OFFSET2 0x3664
-#define HEVC_CM_HEADER_LENGTH2 0x3665
-
-#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_CM_HEADER_START_ADDR2 0x364a
-#define HEVC_SAO_MMU_VH1_ADDR 0x363b
-#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
-
-#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
-#define HEVC_SAO_MMU_STATUS2 0x3650
-#define HEVC_DW_VH0_ADDDR 0x365e
-#define HEVC_DW_VH1_ADDDR 0x365f
-
-#define HEVC_SAO_CTRL9 0x362d
-
-
/*
* AVS2_DEC_STATUS define
@@ -249,9 +227,6 @@
#define unlock_buffer(dec, flags) \
spin_unlock_irqrestore(&dec->buffer_lock, flags)
-static u32 debug_mask = 0xffffffff;
-#define get_dbg_flag(dec) ((debug_mask & (1 << dec->index)) ? debug : 0)
-
static unsigned int max_decode_instance_num
= MAX_DECODE_INSTANCE_NUM;
static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
@@ -261,11 +236,17 @@
static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
+#ifdef G12A_BRINGUP_DEBUG
static u32 decode_timeout_val = 200;
-
+#else
+static u32 decode_timeout_val = 200;
+#endif
static int start_decode_buf_level = 0x8000;
-
-static u32 work_buf_size;
+#ifdef AVS2_10B_MMU
+static u32 work_buf_size; /* = 24 * 1024 * 1024*/;
+#else
+static u32 work_buf_size = 32 * 1024 * 1024;
+#endif
static u32 mv_buf_margin;
static int pre_decode_buf_level = 0x1000;
@@ -279,7 +260,6 @@
* 2, (1/4):(1/4) ratio;
* 3, (1/4):(1/4) ratio, with both compressed frame included
* 4, (1/2):(1/2) ratio;
- * 8, (1/8):(1/8) ratio;
* 0x10, double write only
* 0x100, if > 1080p,use mode 4,else use mode 1;
* 0x200, if > 1080p,use mode 2,else use mode 1;
@@ -318,7 +298,7 @@
static s32 vavs2_init(struct vdec_s *vdec);
static void vavs2_prot_init(struct AVS2Decoder_s *dec);
static int vavs2_local_init(struct AVS2Decoder_s *dec);
-static void vavs2_put_timer_func(struct timer_list *timer);
+static void vavs2_put_timer_func(unsigned long arg);
static void dump_data(struct AVS2Decoder_s *dec, int size);
static unsigned char get_data_check_sum
(struct AVS2Decoder_s *dec, int size);
@@ -350,8 +330,6 @@
static u32 force_video_signal_type;
static u32 enable_force_video_signal_type;
#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
-#define HDR_CUVA_MASK 0x40000000
-
static const char * const video_format_names[] = {
"component", "PAL", "NTSC", "SECAM",
@@ -427,6 +405,11 @@
#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+
+typedef unsigned int u32;
+typedef unsigned short u16;
+
#define AVS2_DBG_BUFMGR 0x01
#define AVS2_DBG_BUFMGR_MORE 0x02
#define AVS2_DBG_BUFMGR_DETAIL 0x04
@@ -442,7 +425,6 @@
#define AVS2_DBG_PIC_LEAK 0x1000
#define AVS2_DBG_PIC_LEAK_WAIT 0x2000
#define AVS2_DBG_HDR_INFO 0x4000
-#define AVS2_DBG_HDR_DATA 0x8000
#define AVS2_DBG_DIS_LOC_ERROR_PROC 0x10000
#define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000
#define AVS2_DBG_DUMP_PIC_LIST 0x40000
@@ -515,9 +497,6 @@
static u32 force_disp_pic_index;
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-static u32 cuva_buf_size = 512;
-
#define DEBUG_REG
#ifdef DEBUG_REG
static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
@@ -532,6 +511,11 @@
#define WRITE_VREG WRITE_VREG_DBG2
#endif
+
+//#ifdef AVS2_10B_MMU
+//#define MMU_COMPRESS_HEADER_SIZE 0x48000
+//#define MMU_COMPRESS_8K_HEADER_SIZE 0x48000*4
+//#endif
#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
@@ -546,7 +530,7 @@
#define FRAME_CONTEXTS_LOG2 2
#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
/*buffer + header buffer + workspace*/
-
+#undef MV_USE_FIXED_BUF
#ifdef MV_USE_FIXED_BUF
#define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
#define VF_BUFFER_IDX(n) (n)
@@ -558,7 +542,6 @@
#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1)
#define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n+1)
#define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
-//#define DW_HEADER_BUFFER_IDX(n) ((FRAME_BUFFERS * 3) + n+1)
#endif
#define CO_MV_BUF_SIZE_1080P 0x3fc00
@@ -601,10 +584,6 @@
struct buff_s mmu_vbh;
struct buff_s cm_header;
#endif
-#ifdef AVS2_10B_MMU_DW
- struct buff_s mmu_vbh_dw;
- struct buff_s cm_header_dw;
-#endif
struct buff_s mpred_above;
#ifdef MV_USE_FIXED_BUF
struct buff_s mpred_mv;
@@ -689,22 +668,11 @@
unsigned short *lmem_ptr;
unsigned short *debug_ptr;
-#ifdef AVS2_10B_MMU
- bool mmu_enable;
-
- u32 cuva_size;
- void *cuva_addr;
- dma_addr_t cuva_phy_addr;
-
+#if 1
+ /*AVS2_10B_MMU*/
void *frame_mmu_map_addr;
dma_addr_t frame_mmu_map_phy_addr;
#endif
-#ifdef AVS2_10B_MMU_DW
- bool dw_mmu_enable;
- void *dw_mmu_box;
- void *dw_frame_mmu_map_addr;
- dma_addr_t dw_frame_mmu_map_phy_addr;
-#endif
unsigned int use_cma_flag;
struct BUF_s m_BUF[MAX_BUF_NUM];
@@ -807,14 +775,10 @@
u32 dynamic_buf_margin;
int sidebind_type;
int sidebind_channel_id;
- u32 endian;
char vdec_name[32];
char pts_name[32];
char new_q_name[32];
char disp_q_name[32];
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- int hdr_flag;
};
static int compute_losless_comp_body_size(
@@ -924,19 +888,10 @@
static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec)
{
- u32 dw_mode;
-
- dw_mode = (dec->m_ins_flag &&
+ return (dec->m_ins_flag &&
((double_write_mode & 0x80000000) == 0)) ?
dec->double_write_mode :
(double_write_mode & 0x7fffffff);
- if (dw_mode & 0x20) {
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
- && ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3))
- dw_mode = 0;
- }
-
- return dw_mode;
}
static int get_double_write_mode(struct AVS2Decoder_s *dec)
@@ -994,6 +949,18 @@
return dw;
}
+static int get_double_write_ratio(struct AVS2Decoder_s *dec,
+ int dw_mode)
+{
+ int ratio = 1;
+ if ((dw_mode == 2) ||
+ (dw_mode == 3))
+ ratio = 4;
+ else if (dw_mode == 4)
+ ratio = 2;
+ return ratio;
+}
+
//#define MAX_4K_NUM 0x1200
#ifdef AVS2_10B_MMU
int avs2_alloc_mmu(
@@ -1007,6 +974,25 @@
int bit_depth_10 = (bit_depth == AVS2_BITS_10);
int picture_size;
int cur_mmu_4k_number, max_frame_num;
+#ifdef DYNAMIC_ALLOC_HEAD
+ unsigned long buf_addr;
+ struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+ if (pic->header_adr == 0) {
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ HEADER_BUFFER_IDX(cur_buf_idx),
+ get_compress_header_size(dec),
+ DRIVER_HEADER_NAME,
+ &buf_addr) < 0){
+ avs2_print(dec, 0,
+ "%s malloc compress header failed %d\n",
+ DRIVER_HEADER_NAME, cur_buf_idx);
+ dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+ return -1;
+ } else
+ pic->header_adr = buf_addr;
+ }
+#endif
picture_size = compute_losless_comp_body_size(
dec, pic_width, pic_height,
@@ -1029,38 +1015,157 @@
}
#endif
-#ifdef AVS2_10B_MMU_DW
-int avs2_alloc_dw_mmu(
- struct AVS2Decoder_s *dec,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
+#if 0
+/*ndef MV_USE_FIXED_BUF*/
+static void dealloc_mv_bufs(struct AVS2Decoder_s *dec)
{
- int bit_depth_10 = (bit_depth == AVS2_BITS_10);
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-
- picture_size = compute_losless_comp_body_size(
- dec, pic_width, pic_height,
- bit_depth_10);
- cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- max_frame_num = MAX_FRAME_8K_NUM;
- else
- max_frame_num = MAX_FRAME_4K_NUM;
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, pic_width, pic_height);
- return -1;
+ int i;
+ for (i = 0; i < FRAME_BUFFERS; i++) {
+ if (dec->m_mv_BUF[i].start_adr) {
+ if (debug)
+ pr_info(
+ "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
+ i, dec->m_mv_BUF[i].start_adr,
+ dec->m_mv_BUF[i].size,
+ dec->m_mv_BUF[i].used_flag);
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ MV_BUFFER_IDX(i));
+ dec->m_mv_BUF[i].start_adr = 0;
+ dec->m_mv_BUF[i].size = 0;
+ dec->m_mv_BUF[i].used_flag = 0;
+ }
}
- return decoder_mmu_box_alloc_idx(
- dec->dw_mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
}
+
+static int alloc_mv_buf(struct AVS2Decoder_s *dec,
+ int i, int size)
+{
+ int ret = 0;
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ MV_BUFFER_IDX(i), size,
+ DRIVER_NAME,
+ &dec->m_mv_BUF[i].start_adr) < 0) {
+ dec->m_mv_BUF[i].start_adr = 0;
+ ret = -1;
+ } else {
+ dec->m_mv_BUF[i].size = size;
+ dec->m_mv_BUF[i].used_flag = 0;
+ ret = 0;
+ if (debug) {
+ pr_info(
+ "MV Buffer %d: start_adr %p size %x\n",
+ i,
+ (void *)dec->m_mv_BUF[i].start_adr,
+ dec->m_mv_BUF[i].size);
+ }
+ }
+ return ret;
+}
+
+static int init_mv_buf_list(struct AVS2Decoder_s *dec)
+{
+ int i;
+ int ret = 0;
+ int count = FRAME_BUFFERS;
+ int pic_width = dec->init_pic_w;
+ int pic_height = dec->init_pic_h;
+ int lcu_size = 64; /*fixed 64*/
+ int pic_width_64 = (pic_width + 63) & (~0x3f);
+ int pic_height_32 = (pic_height + 31) & (~0x1f);
+ int pic_width_lcu = (pic_width_64 % lcu_size) ?
+ pic_width_64 / lcu_size + 1
+ : pic_width_64 / lcu_size;
+ int pic_height_lcu = (pic_height_32 % lcu_size) ?
+ pic_height_32 / lcu_size + 1
+ : pic_height_32 / lcu_size;
+ int lcu_total = pic_width_lcu * pic_height_lcu;
+ int size = ((lcu_total * MV_MEM_UNIT) + 0xffff) &
+ (~0xffff);
+ if (mv_buf_margin > 0)
+ count = dec->avs2_dec.ref_maxbuffer + mv_buf_margin;
+ for (i = 0; i < count; i++) {
+ if (alloc_mv_buf(dec, i, size) < 0) {
+ ret = -1;
+ break;
+ }
+ }
+ return ret;
+}
+#if 0
+
+static int get_mv_buf(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic)
+{
+ int i;
+ int ret = -1;
+ for (i = 0; i < FRAME_BUFFERS; i++) {
+ if (dec->m_mv_BUF[i].start_adr &&
+ dec->m_mv_BUF[i].used_flag == 0) {
+ dec->m_mv_BUF[i].used_flag = 1;
+ ret = i;
+ break;
+ }
+ }
+
+ if (ret >= 0) {
+ pic->mv_buf_index = ret;
+ pic->mpred_mv_wr_start_addr =
+ (dec->m_mv_BUF[ret].start_adr + 0xffff) &
+ (~0xffff);
+ if (debug & AVS2_DBG_BUFMGR_MORE)
+ pr_info(
+ "%s => %d (%d) size 0x%x\n",
+ __func__, ret,
+ pic->mpred_mv_wr_start_addr,
+ dec->m_mv_BUF[ret].size);
+ } else {
+ pr_info(
+ "%s: Error, mv buf is not enough\n",
+ __func__);
+ }
+ return ret;
+}
+
+static void put_mv_buf(struct AVS2Decoder_s *dec,
+ struct avs2_frame_s *pic)
+{
+ int i = pic->mv_buf_index;
+ if (i >= FRAME_BUFFERS) {
+ if (debug & AVS2_DBG_BUFMGR_MORE)
+ pr_info(
+ "%s: index %d beyond range\n",
+ __func__, i);
+ return;
+ }
+ if (debug & AVS2_DBG_BUFMGR_MORE)
+ pr_info(
+ "%s(%d): used_flag(%d)\n",
+ __func__, i,
+ dec->m_mv_BUF[i].used_flag);
+
+ pic->mv_buf_index = -1;
+ if (dec->m_mv_BUF[i].start_adr &&
+ dec->m_mv_BUF[i].used_flag)
+ dec->m_mv_BUF[i].used_flag = 0;
+}
+
+static void put_un_used_mv_bufs(struct AVS2Decoder_s *dec)
+{
+ struct VP9_Common_s *const cm = &dec->common;
+ struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
+ int i;
+ for (i = 0; i < dec->used_buf_num; ++i) {
+ if ((frame_bufs[i].ref_count == 0) &&
+ (frame_bufs[i].buf.index != -1) &&
+ (frame_bufs[i].buf.mv_buf_index >= 0)
+ )
+ put_mv_buf(dec, &frame_bufs[i].buf);
+ }
+}
+#endif
+
#endif
static int get_free_buf_count(struct AVS2Decoder_s *dec)
@@ -1203,19 +1308,13 @@
const u32 avs2_version = 201602101;
+static u32 debug;
static u32 radr;
static u32 rval;
static u32 pop_shorts;
static u32 dbg_cmd;
static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
+static u32 endian = 0xff0;
#ifdef ERROR_HANDLE_DEBUG
static u32 dbg_nal_skip_flag;
/* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
@@ -1319,9 +1418,6 @@
#define VP9_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
#define VP9_SEG_MAP_BUFFER HEVC_ASSIST_SCRATCH_B
*/
-#define AVS2_CUVA_ADR HEVC_ASSIST_SCRATCH_A
-#define AVS2_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_B
-
//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
@@ -1380,10 +1476,7 @@
#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
+#define WORK_BUF_SPEC_NUM 3
static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = {
{
/* 8M bytes */
@@ -1392,283 +1485,6 @@
.ipp = {
/* IPP work space calculation :
4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- 32Kbytes (0x8000) */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x40000,
- },
- .dblk_data = {
- .buf_size = 0x40000,
- },
- .dblk_data2 = {
- .buf_size = 0x40000,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- (0x8000) */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x80000,
- },
- .dblk_data = {
- /*DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x80000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096 * 2,
- .max_height = 2304 * 2,
- .ipp = {
- /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
- round to 16k*/
- .buf_size = 0x4000 * 2,
- },
- .sao_abv = {
- .buf_size = 0x30000 * 2,
- },
- .sao_vb = {
- .buf_size = 0x30000 * 2,
- },
- .short_term_rps = {
- /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800)*/
- .buf_size = 0x800,
- },
- .rcs = {
- /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes*/
- .buf_size = 0x400,
- },
- .sps = {
- /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
- 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
- total 0x2800 bytes*/
- .buf_size = 0x2800 * 2,
- },
- .swap_buf = {
- /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
- .buf_size = 0x8000 * 2,
- },
- .dblk_para = {
- .buf_size = 0x40000 * 2,
- },
- .dblk_data = {
- .buf_size = 0x80000 * 2,
- },
- .dblk_data2 = {
- .buf_size = 0x80000 * 2,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000 * 2,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /*4k2k , 0x100000 per buffer*/
- .buf_size = 0x120000 * FRAME_BUFFERS * 4,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
.buf_size = 0x1e00,
},
.sao_abv = {
@@ -1740,16 +1556,6 @@
},
#endif
#endif
-#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_1080P, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x1e00, /* 2 * size of hevc*/
},
@@ -1845,16 +1651,6 @@
},
#endif
#endif
-#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_4K, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x4000, /* 2 * size of hevc*/
},
@@ -1943,16 +1739,6 @@
},
#endif
#endif
-#ifdef AVS2_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_8K, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x8000,
},
@@ -2054,70 +1840,64 @@
struct BuffInfo_s *buf_spec)
{
void *mem_start_virt;
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
+ buf_spec->ipp.buf_start = buf_spec->start_adr;
buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+ buf_spec->ipp.buf_start + buf_spec->ipp.buf_size;
+
buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+ buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size;
buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+ buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size;
buf_spec->rcs.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+ buf_spec->short_term_rps.buf_start +
+ buf_spec->short_term_rps.buf_size;
buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->rcs.buf_start + buf_spec->rcs.buf_size);
+ buf_spec->rcs.buf_start + buf_spec->rcs.buf_size;
buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+ buf_spec->sps.buf_start + buf_spec->sps.buf_size;
buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+ buf_spec->pps.buf_start + buf_spec->pps.buf_size;
buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+ buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size;
buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+ buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size;
buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+ buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size;
buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+ buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size;
buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+ buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size;
buf_spec->dblk_data2.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+ buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size;
#ifdef AVS2_10B_MMU
buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
- #ifdef AVS2_10B_MMU_DW
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size;
buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
- #else
+ buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size;
+#else
buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
- #endif
-#else /* AVS2_10B_MMU */
- #ifdef AVS2_10B_MMU_DW
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
- #else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
- #endif
-#endif /* AVS2_10B_MMU */
+ buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size;
+#endif
#ifdef MV_USE_FIXED_BUF
buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+ buf_spec->mpred_mv.buf_start +
+ buf_spec->mpred_mv.buf_size;
#else
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
#endif
buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->rpm.buf_start +
+ buf_spec->rpm.buf_size;
buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+ buf_spec->lmem.buf_start +
+ buf_spec->lmem.buf_size;
if (dec) {
mem_start_virt =
@@ -2170,10 +1950,6 @@
pr_info("mmu_vbh.buf_start :%x\n",
buf_spec->mmu_vbh.buf_start);
#endif
- #ifdef AVS2_10B_MMU_DW
- pr_info("mmu_vbh_dw.buf_start :%x\n",
- buf_spec->mmu_vbh_dw.buf_start);
- #endif
pr_info("mpred_above.buf_start :%x\n",
buf_spec->mpred_above.buf_start);
#ifdef MV_USE_FIXED_BUF
@@ -2191,11 +1967,9 @@
static void uninit_mmu_buffers(struct AVS2Decoder_s *dec)
{
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable && dec->dw_mmu_box) {
- decoder_mmu_box_free(dec->dw_mmu_box);
- dec->dw_mmu_box = NULL;
- }
+#if 0
+/*ndef MV_USE_FIXED_BUF*/
+ dealloc_mv_bufs(dec);
#endif
decoder_mmu_box_free(dec->mmu_box);
dec->mmu_box = NULL;
@@ -2236,9 +2010,9 @@
if (dw_mode) {
int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(dec, dw_mode);
int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(dec, dw_mode);
int lcu_size = 64; /*fixed 64*/
int pic_width_64 = (pic_width_dw + 63) & (~0x3f);
int pic_height_32 = (pic_height_dw + 31) & (~0x1f);
@@ -2269,7 +2043,7 @@
for (i = 0; i < dec->used_buf_num; i++) {
if (((i + 1) * buf_size) > dec->mc_buf->buf_size)
dec->use_cma_flag = 1;
-
+#ifndef AVS2_10B_MMU
dec->m_BUF[i].alloc_flag = 0;
dec->m_BUF[i].index = i;
@@ -2310,6 +2084,7 @@
"Buffer %d: start_adr %p size %x\n", i,
(void *)dec->m_BUF[i].start_adr,
dec->m_BUF[i].size);
+#endif
}
dec->buf_num = i;
}
@@ -2334,7 +2109,15 @@
pic_height_32 / lcu_size + 1
: pic_height_32 / lcu_size;
int lcu_total = pic_width_lcu * pic_height_lcu;
-
+#if 0
+ int32_t MV_MEM_UNIT =
+ (lcu_size_log2 == 6) ? 0x200 :
+ ((lcu_size_log2 == 5) ? 0x80 : 0x20);
+#endif
+#ifdef MV_USE_FIXED_BUF
+ u32 mpred_mv_end = dec->work_space_buf->mpred_mv.buf_start +
+ dec->work_space_buf->mpred_mv.buf_size;
+#endif
u32 y_adr = 0;
int buf_size = 0;
@@ -2350,11 +2133,11 @@
int mc_buffer_size_u_v_h = 0;
int dw_mode = get_double_write_mode_init(dec);
- if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ if (dw_mode) {
int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(dec, dw_mode);
int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(dec, dw_mode);
int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ?
@@ -2373,150 +2156,171 @@
}
if (mc_buffer_size & 0xffff) /*64k alignment*/
mc_buffer_size_h += 1;
-
-
-#ifdef AVS2_10B_MMU
- if (dec->mmu_enable) {
- pic->header_adr = decoder_bmmu_box_get_phy_addr(
- dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
-
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- pic->dw_header_adr = pic->header_adr
- + get_compress_header_size(dec);
- }
-#endif
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "buf_size %d, MMU header_adr %d: %ld\n",
- buf_size, pic->index, pic->header_adr);
- }
-#else
+#ifndef AVS2_10B_MMU
if ((dw_mode & 0x10) == 0)
buf_size += (mc_buffer_size_h << 16);
#endif
- i = pic->index;
-
-#ifndef AVS2_10B_MMU
- if (debug) {
- pr_err("start %x .size=%d\n",
- dec->mc_buf_spec.buf_start + i * buf_size, buf_size);
- }
- for (i = 0; i < dec->buf_num; i++) {
- y_adr = ((dec->m_BUF[i].free_start_adr
- + 0xffff) >> 16) << 16;
- /*64k alignment*/
- if ((y_adr+buf_size) <= (dec->m_BUF[i].start_adr+
- dec->m_BUF[i].size)) {
- dec->m_BUF[i].free_start_adr =
- y_adr + buf_size;
- break;
- }
- }
- if (i < dec->buf_num)
-#else
- /*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
- dec->mc_buf->buf_end)
- y_adr = dec->mc_buf->buf_start + i * buf_size;
- else {*/
- if (buf_size > 0 && pic->cma_alloc_addr == 0) {
- ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
- VF_BUFFER_IDX(i),
- buf_size, DRIVER_NAME,
- &pic->cma_alloc_addr);
- if (ret < 0) {
- avs2_print(dec, 0,
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return ret;
- }
-
- if (pic->cma_alloc_addr)
- y_adr = pic->cma_alloc_addr;
- else {
- avs2_print(dec, 0,
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return -1;
- }
- }
-#endif
- {
- /*ensure get_pic_by_POC()
- not get the buffer not decoded*/
- pic->BUF_index = i;
- pic->lcu_total = lcu_total;
-
- pic->comp_body_size = losless_comp_body_size;
- pic->buf_size = buf_size;
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
-#ifndef AVS2_10B_MMU
- pic->mc_y_adr = y_adr;
- if (dw_mode & 0x10) {
- pic->mc_u_v_adr = y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
-
- pic->mc_canvas_y =
- (pic->index << 1);
- pic->mc_canvas_u_v =
- (pic->index << 1) + 1;
-
- pic->dw_y_adr = y_adr;
- pic->dw_u_v_adr = pic->mc_u_v_adr;
- } else
-#endif
- if (dw_mode) {
#ifdef AVS2_10B_MMU
- pic->dw_y_adr = y_adr;
- pic->dw_u_v_adr = pic->dw_y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
- pic->mc_y_adr = pic->dw_y_adr;
- pic->mc_u_v_adr = pic->dw_u_v_adr;
-#else
- pic->dw_y_adr = y_adr + (mc_buffer_size_h << 16);
- pic->dw_u_v_adr = pic->dw_y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
+#ifndef DYNAMIC_ALLOC_HEAD
+ pic->header_adr = decoder_bmmu_box_get_phy_addr(
+ dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
+
+ avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+ "buf_size %d, MMU header_adr %d: %ld\n",
+ buf_size, pic->index, pic->header_adr);
#endif
+#endif
+
+ i = pic->index;
+#ifdef MV_USE_FIXED_BUF
+#ifdef G12A_BRINGUP_DEBUG
+ if (1) {
+#else
+ if ((dec->work_space_buf->mpred_mv.buf_start +
+ (((i + 1) * lcu_total) * MV_MEM_UNIT))
+ <= mpred_mv_end
+ ) {
+#endif
+#endif
+#ifndef AVS2_10B_MMU
+ if (debug) {
+ pr_err("start %x .size=%d\n",
+ dec->mc_buf_spec.buf_start + i * buf_size,
+ buf_size);
+ }
+#endif
+#ifndef AVS2_10B_MMU
+ for (i = 0; i < dec->buf_num; i++) {
+ y_adr = ((dec->m_BUF[i].free_start_adr
+ + 0xffff) >> 16) << 16;
+ /*64k alignment*/
+ if ((y_adr+buf_size) <= (dec->m_BUF[i].start_adr+
+ dec->m_BUF[i].size)) {
+ dec->m_BUF[i].free_start_adr =
+ y_adr + buf_size;
+ break;
+ }
+ }
+ if (i < dec->buf_num)
+#else
+ /*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
+ dec->mc_buf->buf_end)
+ y_adr = dec->mc_buf->buf_start + i * buf_size;
+ else {*/
+ if (buf_size > 0 && pic->cma_alloc_addr == 0) {
+ ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+ VF_BUFFER_IDX(i),
+ buf_size, DRIVER_NAME,
+ &pic->cma_alloc_addr);
+ if (ret < 0) {
+ avs2_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
+ VF_BUFFER_IDX(i),
+ buf_size
+ );
+ return ret;
+ }
+
+ if (pic->cma_alloc_addr)
+ y_adr = pic->cma_alloc_addr;
+ else {
+ avs2_print(dec, 0,
+ "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
+ VF_BUFFER_IDX(i),
+ buf_size
+ );
+ return -1;
+ }
+ }
+#endif
+ {
+ /*ensure get_pic_by_POC()
+ not get the buffer not decoded*/
+ pic->BUF_index = i;
+ pic->lcu_total = lcu_total;
+
+ pic->comp_body_size = losless_comp_body_size;
+ pic->buf_size = buf_size;
+#ifndef AVS2_10B_MMU
+ pic->mc_y_adr = y_adr;
+#endif
+ pic->mc_canvas_y = pic->index;
+ pic->mc_canvas_u_v = pic->index;
+#ifndef AVS2_10B_MMU
+ if (dw_mode & 0x10) {
+ pic->mc_u_v_adr = y_adr +
+ ((mc_buffer_size_u_v_h << 16) << 1);
+
+ pic->mc_canvas_y =
+ (pic->index << 1);
+ pic->mc_canvas_u_v =
+ (pic->index << 1) + 1;
+
+ pic->dw_y_adr = y_adr;
+ pic->dw_u_v_adr = pic->mc_u_v_adr;
+ } else
+#endif
+ if (dw_mode) {
+ pic->dw_y_adr = y_adr
+#ifndef AVS2_10B_MMU
+ + (mc_buffer_size_h << 16)
+#endif
+ ;
+ pic->dw_u_v_adr = pic->dw_y_adr +
+ ((mc_buffer_size_u_v_h << 16) << 1);
+#ifdef AVS2_10B_MMU
+ pic->mc_y_adr = pic->dw_y_adr;
+ pic->mc_u_v_adr = pic->dw_u_v_adr;
+#endif
+ }
+#ifdef MV_USE_FIXED_BUF
+#ifdef G12A_BRINGUP_DEBUG
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ pic->mpred_mv_wr_start_addr =
+ dec->work_space_buf->mpred_mv.buf_start +
+ (pic->index * 0x120000 * 4);
+ } else {
+ pic->mpred_mv_wr_start_addr =
+ dec->work_space_buf->mpred_mv.buf_start +
+ (pic->index * 0x120000);
+ }
+#else
+ pic->mpred_mv_wr_start_addr =
+ dec->work_space_buf->mpred_mv.buf_start +
+ ((pic->index * lcu_total)
+ * MV_MEM_UNIT);
+#endif
+#endif
+ if (debug) {
+ avs2_print(dec, AVS2_DBG_BUFMGR,
+ "%s index %d BUF_index %d mc_y_adr %x ",
+ __func__, pic->index,
+ pic->BUF_index,
+ pic->mc_y_adr);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "comp_body_size %x comp_buf_size %x ",
+ pic->comp_body_size,
+ pic->buf_size);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "mpred_mv_wr_start_adr %d\n",
+ pic->mpred_mv_wr_start_addr);
+ avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+ "dw_y_adr %d, pic->dw_u_v_adr =%d\n",
+ pic->dw_y_adr,
+ pic->dw_u_v_adr);
+ }
+ ret = 0;
}
#ifdef MV_USE_FIXED_BUF
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start +
- pic->index * (dec->work_space_buf->mpred_mv.buf_size / FRAME_BUFFERS);
- if (pic->mpred_mv_wr_start_addr >
- (dec->work_space_buf->mpred_mv.buf_start
- + dec->work_space_buf->mpred_mv.buf_size)) {
- avs2_print(dec, 0, "err: fixed mv buf out of size, 0x0%x\n",
- pic->mpred_mv_wr_start_addr);
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start;
- }
-#endif
- if (debug) {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index %d BUF_index %d mc_y_adr %x ",
- __func__, pic->index,
- pic->BUF_index,
- pic->mc_y_adr);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "comp_body_size %x comp_buf_size %x ",
- pic->comp_body_size,
- pic->buf_size);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "mpred_mv_wr_start_adr %d\n",
- pic->mpred_mv_wr_start_addr);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "dw_y_adr %d, pic->dw_u_v_adr =%d\n",
- pic->dw_y_adr,
- pic->dw_u_v_adr);
- }
- ret = 0;
+ } else {
+ avs2_print(dec, 0,
+ "mv buffer alloc fail %x > %x\n",
+ dec->work_space_buf->mpred_mv.buf_start +
+ (((i + 1) * lcu_total) * MV_MEM_UNIT),
+ mpred_mv_end);
}
-
+#endif
return ret;
}
@@ -2527,28 +2331,36 @@
struct avs2_decoder *avs2_dec = &dec->avs2_dec;
struct avs2_frame_s *pic;
#ifdef AVS2_10B_MMU
- if (dec->mmu_enable) {
- for (i = 0; i < dec->used_buf_num; i++) {
- unsigned long buf_addr;
- u32 header_size = get_compress_header_size(dec);
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable)
- header_size <<= 1;
-#endif
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- HEADER_BUFFER_IDX(i), header_size,
- DRIVER_HEADER_NAME,
- &buf_addr) < 0){
- avs2_print(dec, 0,
- "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, i);
- dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
+ unsigned long buf_addr1;
+ /*alloc AVS2 compress header first*/
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ HEADER_BUFFER_IDX(-1), get_compress_header_size(dec),
+ DRIVER_HEADER_NAME,
+ &buf_addr1) < 0){
+ avs2_print(dec, 0,
+ "%s malloc compress header failed %d\n",
+ DRIVER_HEADER_NAME, -1);
+ dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+ return;
+ }
+#ifndef DYNAMIC_ALLOC_HEAD
+ for (i = 0; i < dec->used_buf_num; i++) {
+ unsigned long buf_addr;
+ if (decoder_bmmu_box_alloc_buf_phy
+ (dec->bmmu_box,
+ HEADER_BUFFER_IDX(i), get_compress_header_size(dec),
+ DRIVER_HEADER_NAME,
+ &buf_addr) < 0){
+ avs2_print(dec, 0,
+ "%s malloc compress header failed %d\n",
+ DRIVER_HEADER_NAME, i);
+ dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+ return;
}
}
#endif
+#endif
dec->frame_height = avs2_dec->img.height;
dec->frame_width = avs2_dec->img.width;
@@ -3261,7 +3073,7 @@
if ((get_double_write_mode(dec) & 0x10) == 0)
WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr);
#endif
- if ((get_double_write_mode(dec) & 0x20) == 0) {
+ if (get_double_write_mode(dec)) {
WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
@@ -3273,14 +3085,6 @@
#ifdef AVS2_10B_MMU
WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, cur_pic->dw_header_adr);
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
- }
-#endif
-
data32 = (mc_buffer_size_u_v_h << 16) << 1;
/*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
data32, mc_buffer_size_u_v_h, cur_pic->lcu_total);*/
@@ -3297,22 +3101,6 @@
data32 |= (MEM_MAP_MODE << 12);
data32 &= (~0x3);
data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
-
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
-
WRITE_VREG(HEVC_SAO_CTRL1, data32);
/*[23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl
[17:16] dw_h0_ctrl*/
@@ -3344,41 +3132,23 @@
data32 &= ~(0xff << 16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
-
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/*[5:4] address_format 00:linear 01:32x32 10:64x32*/
data32 |= (MEM_MAP_MODE << 4);
data32 &= (~0xF);
data32 |= 0x8; /*Big-Endian per 64-bit*/
-
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#endif
#else
data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~(3 << 14));
- data32 |= (2 << 14); /* line align with 64*/
data32 &= (~0x3000);
- data32 |= (MEM_MAP_MODE << 12); /* [13:12] axi_aformat, 0-Linear,
+ data32 |= (MEM_MAP_MODE <<
+ 12); /* [13:12] axi_aformat, 0-Linear,
1-32x32, 2-64x32 */
data32 &= (~0xff0);
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable == 0)
- data32 |= ((dec->endian >> 8) & 0xfff);
-#else
- data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
-#endif
+ /* data32 |= 0x670; // Big-Endian per 64-bit */
+ data32 |= endian; /* Big-Endian per 64-bit */
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
#if 0
if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
@@ -3396,18 +3166,6 @@
else if (get_double_write_mode(dec) & 0x10)
data32 |= 0x1; /*disable cm*/
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
WRITE_VREG(HEVC_SAO_CTRL1, data32);
if (get_double_write_mode(dec) & 0x10) {
@@ -3421,55 +3179,26 @@
data32 &= ~(0xff << 16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
} else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
data32 = READ_VREG(HEVC_SAO_CTRL5);
data32 &= (~(0xff << 16));
- if ((get_double_write_mode(dec) & 0xf) == 8 ||
- (get_double_write_mode(dec) & 0xf) == 9) {
+ if (get_double_write_mode(dec) == 2 ||
+ get_double_write_mode(dec) == 3)
data32 |= (0xff<<16);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else if ((get_double_write_mode(dec) & 0xf) == 2 ||
- (get_double_write_mode(dec) & 0xf) == 3)
- data32 |= (0xff<<16);
- else if ((get_double_write_mode(dec) & 0xf) == 4)
+ else if (get_double_write_mode(dec) == 4)
data32 |= (0x33<<16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
}
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
-
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (mem_map_mode << 4);
+ data32 |= (mem_map_mode <<
+ 4);
data32 &= (~0xF);
- data32 |= (dec->endian & 0xf); /* valid only when double write only */
- /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
- data32 &= (~(3 << 8));
- data32 |= (2 << 8); /* line align with 64 for dw only */
+ data32 |= 0xf; /* valid only when double write only */
+ /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#endif
-#ifndef AVS2_10B_NV21
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- struct BuffInfo_s *buf_spec = NULL;
- buf_spec = &dec->work_space_buf_store;
- WRITE_VREG(HEVC_DW_VH0_ADDDR, buf_spec->mmu_vbh_dw.buf_start + (2 * DW_VBH_BUF_SIZE(buf_spec)));
- WRITE_VREG(HEVC_DW_VH1_ADDDR, buf_spec->mmu_vbh_dw.buf_start + (3 * DW_VBH_BUF_SIZE(buf_spec)));
- }
-#endif
-#endif
-
}
static void reconstructCoefficients(struct AVS2Decoder_s *dec,
@@ -3736,110 +3465,6 @@
#endif
}
-static u32 init_cuva_size;
-static int cuva_data_is_avaible(struct AVS2Decoder_s *dec)
-{
- u32 reg_val;
-
- reg_val = READ_VREG(AVS2_CUVA_DATA_SIZE);
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s:reg_val: %u \n",
- __func__, reg_val);
- if (reg_val != 0 && reg_val != init_cuva_size)
- return 1;
- else
- return 0;
-}
-
-static void config_cuva_buf(struct AVS2Decoder_s *dec)
-{
- WRITE_VREG(AVS2_CUVA_ADR, dec->cuva_phy_addr);
- init_cuva_size = (dec->cuva_size >> 4) << 16;
- WRITE_VREG(AVS2_CUVA_DATA_SIZE, init_cuva_size);
-}
-
-static void set_cuva_data(struct AVS2Decoder_s *dec)
-{
- int i;
- unsigned short *cuva_adr;
- unsigned int size_reg_val =
- READ_VREG(AVS2_CUVA_DATA_SIZE);
- unsigned int cuva_count = 0;
- int cuva_size = 0;
- struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
- if (pic == NULL || 0 == cuva_data_is_avaible(dec)) {
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "%s:pic 0x%p or data not avaible\n",
- __func__, pic);
- return;
- }
-
- cuva_adr = (unsigned short *)dec->cuva_addr;
- cuva_count = ((size_reg_val >> 16) << 4) >> 1;
- cuva_size = dec->cuva_size;
- dec->hdr_flag |= HDR_CUVA_MASK;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
- __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
- if (cuva_size > 0 && cuva_count > 0) {
- int new_size;
- char *new_buf;
-
- new_size = cuva_size;
- new_buf = vzalloc(new_size);
- if (new_buf) {
- unsigned char *p = new_buf;
- int len = 0;
- pic->cuva_data_buf = new_buf;
-
- for (i = 0; i < cuva_count; i += 4) {
- int j;
-
- for (j = 0; j < 4; j++) {
- unsigned short aa = cuva_adr[i + 3 - j];
- *p = aa & 0xff;
- p++;
- len++;
- }
- }
- if (len > 0) {
- pic->cuva_data_size = len;
- }
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "cuva: (size %d)\n",
- pic->cuva_data_size);
- if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) {
- for (i = 0; i < pic->cuva_data_size; i++) {
- pr_info("%02x ", pic->cuva_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- pr_info("\n");
- }
- pr_info("\n");
- }
-
- } else {
- avs2_print(dec, 0, "new buf alloc failed\n");
- if (pic->cuva_data_buf)
- vfree(pic->cuva_data_buf);
- pic->cuva_data_buf = NULL;
- pic->cuva_data_size = 0;
- }
- }
-}
-
-static void release_cuva_data(struct avs2_frame_s *pic)
-{
- if (pic == NULL)
- return;
- if (pic->cuva_data_buf) {
- vfree(pic->cuva_data_buf);
- }
- pic->cuva_data_buf = NULL;
- pic->cuva_data_size = 0;
-}
-
static void avs2_config_work_space_hw(struct AVS2Decoder_s *dec)
{
struct BuffInfo_s *buf_spec = dec->work_space_buf;
@@ -3886,12 +3511,6 @@
#else
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, dec->dw_frame_mmu_map_phy_addr);
- }
-#endif
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
//WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
@@ -3961,38 +3580,11 @@
#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- u32 data_tmp;
- data_tmp = READ_VREG(HEVC_SAO_CTRL9);
- data_tmp |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
-
- WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size);
-
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec));
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<15);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-#endif
-
-
WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
-
+#if 1
+/*MULTI_INSTANCE_SUPPORT*/
+ /*new added in simulation???*/
WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
-
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
#endif
}
@@ -4019,6 +3611,7 @@
unsigned int data32;
unsigned int decode_mode;
int i;
+
/*if (debug & AVS2_DBG_BUFMGR_MORE)
pr_info("%s\n", __func__);*/
data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
@@ -4073,13 +3666,11 @@
WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
/*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(dec->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
+
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
+
#ifdef ENABLE_SWAP_TEST
WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
@@ -4261,6 +3852,10 @@
}
#endif
+
+
+
+
static struct AVS2Decoder_s gAVS2Decoder;
static void avs2_local_uninit(struct AVS2Decoder_s *dec)
@@ -4273,14 +3868,6 @@
dec->rpm_phy_addr);
dec->rpm_addr = NULL;
}
-
- if (dec->cuva_addr) {
- dma_free_coherent(amports_get_dma_device(),
- dec->cuva_size, dec->cuva_addr,
- dec->cuva_phy_addr);
- dec->cuva_addr = NULL;
- }
-
if (dec->lmem_addr) {
if (dec->lmem_phy_addr)
dma_free_coherent(amports_get_dma_device(),
@@ -4298,17 +3885,6 @@
dec->frame_mmu_map_addr = NULL;
}
#endif
-
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_frame_mmu_map_addr) {
- if (dec->dw_frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(dec), dec->dw_frame_mmu_map_addr,
- dec->dw_frame_mmu_map_phy_addr);
- dec->dw_frame_mmu_map_addr = NULL;
- }
-#endif
-
if (dec->gvs)
vfree(dec->gvs);
dec->gvs = NULL;
@@ -4326,27 +3902,16 @@
memcpy(cur_buf_info, &amvavs2_workbuff_spec[force_bufspec & 0xf],
sizeof(struct BuffInfo_s));
pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */
- sizeof(struct BuffInfo_s));
- else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[0],/* 1080p */
- sizeof(struct BuffInfo_s));
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[5], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
+ } else if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */
+ sizeof(struct BuffInfo_s));
+ else
+ memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */
+ sizeof(struct BuffInfo_s));
+ } else
+ memcpy(cur_buf_info, &amvavs2_workbuff_spec[0],/* 1080p */
+ sizeof(struct BuffInfo_s));
cur_buf_info->start_adr = dec->buf_start;
#ifndef AVS2_10B_MMU
@@ -4372,15 +3937,14 @@
}
avs2_bufmgr_init(dec, cur_buf_info, &dec->mc_buf_spec);
#endif
- if ((buf_alloc_width & buf_alloc_height) == 0) {
- if (!vdec_is_support_4k()
- && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
- buf_alloc_width = 1920;
- buf_alloc_height = 1088;
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- buf_alloc_width = 3840;
- buf_alloc_height = 2160;
- }
+
+ if (!vdec_is_support_4k()
+ && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
+ buf_alloc_width = 1920;
+ buf_alloc_height = 1088;
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ buf_alloc_width = 8192;
+ buf_alloc_height = 4608;
}
dec->init_pic_w = buf_alloc_width ? buf_alloc_width :
(dec->vavs2_amstream_dec_info.width ?
@@ -4390,6 +3954,13 @@
(dec->vavs2_amstream_dec_info.height ?
dec->vavs2_amstream_dec_info.height :
dec->work_space_buf->max_height);
+#if 0
+/*ndef MV_USE_FIXED_BUF*/
+ if (init_mv_buf_list(dec) < 0) {
+ pr_err("%s: init_mv_buf_list fail\n", __func__);
+ return -1;
+ }
+#endif
#ifndef AVS2_10B_MMU
init_buf_list(dec);
@@ -4419,20 +3990,6 @@
dec->rpm_ptr = dec->rpm_addr;
}
- if (cuva_buf_size > 0) {
- dec->cuva_size = AUX_BUF_ALIGN(cuva_buf_size);
-
- dec->cuva_addr = dma_alloc_coherent(amports_get_dma_device(),
- dec->cuva_size, &dec->cuva_phy_addr, GFP_KERNEL);
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s, cuva_size = %d cuva_phy_addr %x dec->cuva_addr = %px\n",
- __func__, dec->cuva_size, (u32)dec->cuva_phy_addr, dec->cuva_addr);
- if (dec->cuva_addr == NULL) {
- pr_err("%s: failed to alloc cuva buffer\n", __func__);
- return -1;
- }
- }
-
dec->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
LMEM_BUF_SIZE,
&dec->lmem_phy_addr, GFP_KERNEL);
@@ -4443,33 +4000,21 @@
avs2_print(dec, AVS2_DBG_BUFMGR,
"%s, lmem_phy_addr %x\n",
__func__, (u32)dec->lmem_phy_addr);
+
dec->lmem_ptr = dec->lmem_addr;
+
#ifdef AVS2_10B_MMU
- if (dec->mmu_enable) {
- dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(dec),
- &dec->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (dec->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(dec->frame_mmu_map_addr, 0, get_frame_mmu_map_size(dec));
+ dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
+ get_frame_mmu_map_size(dec),
+ &dec->frame_mmu_map_phy_addr, GFP_KERNEL);
+ if (dec->frame_mmu_map_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
}
+ memset(dec->frame_mmu_map_addr, 0, get_frame_mmu_map_size(dec));
#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- dec->dw_frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(dec),
- &dec->dw_frame_mmu_map_phy_addr, GFP_KERNEL);
- if (dec->dw_frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(dec->dw_frame_mmu_map_addr, 0, get_frame_mmu_map_size(dec));
- }
-#endif
ret = 0;
return ret;
}
@@ -4505,11 +4050,16 @@
/*CANVAS_BLKMODE_64X32*/
if (pic->double_write_mode) {
canvas_w = pic->pic_w /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(dec,
+ pic->double_write_mode);
canvas_h = pic->pic_h /
- get_double_write_ratio(pic->double_write_mode);
- /*sao_crtl1 aligned with 64*/
- canvas_w = ALIGN(canvas_w, 64);
+ get_double_write_ratio(dec,
+ pic->double_write_mode);
+
+ if (mem_map_mode == 0)
+ canvas_w = ALIGN(canvas_w, 32);
+ else
+ canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
if (vdec->parallel_dec == 1) {
@@ -4522,23 +4072,31 @@
pic->uv_canvas_index = 128 + pic->index * 2 + 1;
}
- config_cav_lut_ex(pic->y_canvas_index,
+ canvas_config_ex(pic->y_canvas_index,
pic->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7);
+ canvas_config_ex(pic->uv_canvas_index,
pic->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7);
#ifdef MULTI_INSTANCE_SUPPORT
- pic->canvas_config[0].phy_addr = pic->dw_y_adr;
- pic->canvas_config[0].width = canvas_w;
- pic->canvas_config[0].height = canvas_h;
- pic->canvas_config[0].block_mode = blkmode;
+ pic->canvas_config[0].phy_addr =
+ pic->dw_y_adr;
+ pic->canvas_config[0].width =
+ canvas_w;
+ pic->canvas_config[0].height =
+ canvas_h;
+ pic->canvas_config[0].block_mode =
+ blkmode;
pic->canvas_config[0].endian = 7;
- pic->canvas_config[1].phy_addr = pic->dw_u_v_adr;
- pic->canvas_config[1].width = canvas_w;
- pic->canvas_config[1].height = canvas_h;
- pic->canvas_config[1].block_mode = blkmode;
+ pic->canvas_config[1].phy_addr =
+ pic->dw_u_v_adr;
+ pic->canvas_config[1].width =
+ canvas_w;
+ pic->canvas_config[1].height =
+ canvas_h;
+ pic->canvas_config[1].block_mode =
+ blkmode;
pic->canvas_config[1].endian = 7;
#endif
} else {
@@ -4553,12 +4111,12 @@
pic->uv_canvas_index = 128 + pic->index;
}
- config_cav_lut_ex(pic->y_canvas_index,
+ canvas_config_ex(pic->y_canvas_index,
pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index,
- pic->mc_u_v_adr,canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7);
+ canvas_config_ex(pic->uv_canvas_index,
+ pic->mc_u_v_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, 0x7);
#endif
}
}
@@ -4572,14 +4130,8 @@
vf->duration_pulldown = 0;
vf->flag = 0;
vf->prop.master_display_colour = dec->vf_dp;
- if (dec->hdr_flag & HDR_CUVA_MASK)
- dec->video_signal_type |= 1 << 31;
vf->signal_type = dec->video_signal_type;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "signal_typesignal_type 0x%x \n",
- vf->signal_type);
-
pixel_ratio = dec->vavs2_amstream_dec_info.ratio;
if (dec->vavs2_ratio == 0) {
@@ -4809,32 +4361,6 @@
req->req_result[0] = vdec_secure(hw_to_vdec(dec));
else
req->req_result[0] = 0xffffffff;
- } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
- struct provider_aux_req_s *req =
- (struct provider_aux_req_s *)data;
- unsigned char index;
- unsigned long flags;
- struct avs2_frame_s *pic;
-
- if (!req->vf) {
- req->aux_size = dec->vf_put_count;
- return 0;
- }
- lock_buffer(dec, flags);
- index = req->vf->index & 0xff;
- req->aux_buf = NULL;
- req->aux_size = 0;
- req->format = VFORMAT_AVS2;
- if (index < dec->used_buf_num) {
- pic = get_pic_by_index(dec, index);
- req->aux_buf = pic->cuva_data_buf;
- req->aux_size = pic->cuva_data_size;
- }
- unlock_buffer(dec, flags);
-
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s pic 0x%p index %d =>size %d\n",
- __func__, pic, index, req->aux_size);
}
return 0;
@@ -4936,7 +4462,7 @@
__func__, pic->index,
pic->imgtr_fwRefDistance);
- if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0)
+ if (pic->double_write_mode)
set_canvas(dec, pic);
display_frame_count[dec->index]++;
@@ -4949,7 +4475,7 @@
} else {
#endif
if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
+ /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
stream_offset, &vf->pts, 0) != 0) { */
if (pts_lookup_offset_us64
(PTS_TYPE_VIDEO, stream_offset,
@@ -5004,16 +4530,18 @@
if (vf->pts != 0)
dec->last_lookup_pts = vf->pts;
-
+#if 1
if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
&& ((pic->slice_type != I_IMG) || (!pts_discontinue &&
!first_pts_checkin_complete(PTS_TYPE_AUDIO))))
vf->pts = dec->last_pts + DUR2PTS(dec->frame_dur);
+#endif
dec->last_pts = vf->pts;
if (vf->pts_us64 != 0)
dec->last_lookup_pts_us64 = vf->pts_us64;
+#if 1
if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
&& ((pic->slice_type != I_IMG) || (!pts_discontinue &&
!first_pts_checkin_complete(PTS_TYPE_AUDIO)))) {
@@ -5021,7 +4549,7 @@
dec->last_pts_us64 +
(DUR2PTS(dec->frame_dur) * 100 / 9);
}
-
+#endif
dec->last_pts_us64 = vf->pts_us64;
avs2_print(dec, AVS2_DBG_OUT_PTS,
"avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n",
@@ -5036,30 +4564,16 @@
vf->compHeadAddr = 0;
} else {
#ifdef AVS2_10B_MMU
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic->header_adr;
-#ifdef AVS2_10B_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
- if (pic->double_write_mode & 0x20) {
- u32 mode = pic->double_write_mode & 0xf;
- if (mode == 5 || mode == 3)
- vf->dwHeadAddr = pic->dw_header_adr;
- else if ((mode == 1 || mode == 2 || mode == 4)
- && ((debug & AVS2_DBG_OUT_PTS) == 0)) {
- vf->compHeadAddr = pic->dw_header_adr;
- pr_info("Use dw mmu for display\n");
- }
- }
-#endif
-
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = pic->header_adr;
#else
- vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
- vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
+ vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+ vf->compHeadAddr = pic->mc_y_adr +
+ pic->comp_body_size;
+ /*head adr*/
#endif
}
- if (pic->double_write_mode &&
- ((pic->double_write_mode & 0x20) == 0)) {
+ if (pic->double_write_mode) {
vf->type = VIDTYPE_PROGRESSIVE |
VIDTYPE_VIU_FIELD;
vf->type |= VIDTYPE_VIU_NV21;
@@ -5123,26 +4637,17 @@
vf->width,vf->height, pic->width,
pic->height); */
vf->width = pic->pic_w /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(dec,
+ pic->double_write_mode);
vf->height = pic->pic_h /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(dec,
+ pic->double_write_mode);
if (force_w_h != 0) {
vf->width = (force_w_h >> 16) & 0xffff;
vf->height = force_w_h & 0xffff;
}
- if ((pic->double_write_mode & 0x20) &&
- ((pic->double_write_mode & 0xf) == 2 ||
- (pic->double_write_mode & 0xf) == 4)) {
- vf->compWidth = pic->pic_w /
- get_double_write_ratio(
- pic->double_write_mode & 0xf);
- vf->compHeight = pic->pic_h /
- get_double_write_ratio(
- pic->double_write_mode & 0xf);
- } else {
- vf->compWidth = pic->pic_w;
- vf->compHeight = pic->pic_h;
- }
+ vf->compWidth = pic->pic_w;
+ vf->compHeight = pic->pic_h;
if (force_fps & 0x100) {
u32 rate = force_fps & 0xff;
if (rate)
@@ -5152,26 +4657,12 @@
}
#ifdef AVS2_10B_MMU
if (vf->type & VIDTYPE_SCATTER) {
-#ifdef AVS2_10B_MMU_DW
- if (pic->double_write_mode & 0x20) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- dec->dw_mmu_box, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
- vf->mem_dw_handle = NULL;
- } else
-#endif
- {
vf->mem_handle = decoder_mmu_box_get_mem_handle(
dec->mmu_box,
pic->index);
vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
dec->bmmu_box,
HEADER_BUFFER_IDX(pic->index));
- }
} else {
vf->mem_handle = decoder_bmmu_box_get_mem_handle(
dec->bmmu_box,
@@ -5214,6 +4705,7 @@
dec->gvs->status = dec->stat | dec->fatal_error;
}
+
static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
{
#ifndef NO_DISPLAY
@@ -5233,8 +4725,7 @@
if (pic->error_mark) {
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "!!!error pic, skip\n",
- 0);
+ "!!!error pic, skip\n");
continue;
}
@@ -5243,7 +4734,7 @@
pic->slice_type != I_IMG) {
avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
"!!!slice type %d (not I) skip\n",
- 0, pic->slice_type);
+ pic->slice_type);
continue;
}
dec->skip_PB_before_I = 0;
@@ -5280,7 +4771,7 @@
memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info));
tmp4x.bit_depth_luma = bit_depth_luma;
tmp4x.bit_depth_chroma = bit_depth_chroma;
- tmp4x.double_write_mode = pic->double_write_mode;
+ tmp4x.double_write_mode = get_double_write_mode(dec);
vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, &tmp4x, vf, pic->hw_decode_time);
pvdec->vdec_fps_detec(pvdec->id);
if (without_display_mode == 0) {
@@ -5474,7 +4965,7 @@
struct vdec_s *vdec = hw_to_vdec(dec);
if (!picture) {
avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s decode picture is none exist\n");
+ "decode picture is none exist\n");
return;
}
@@ -5941,7 +5432,6 @@
PRINT_LINE();
dec->start_decoding_flag |= 0x3;
if (dec->m_ins_flag) {
- set_cuva_data(dec);
update_decoded_pic(dec);
get_picture_qos_info(dec);
reset_process_time(dec);
@@ -6071,19 +5561,31 @@
dec->avs2_dec.hc.cur_pic = NULL;
for (ii = 0; ii < dec->avs2_dec.ref_maxbuffer;
ii++) {
- struct avs2_frame_s *pic =
- dec->avs2_dec.fref[ii];
- if (pic->bg_flag == 0 &&
- pic->is_output == -1 &&
- pic->mmu_alloc_flag &&
- pic->vf_ref == 0) {
- if (pic->refered_by_others == 0) {
+ if (dec->avs2_dec.fref[ii]->
+ bg_flag == 0 &&
+ dec->avs2_dec.fref[ii]->
+ is_output == -1 &&
+ dec->avs2_dec.fref[ii]->
+ mmu_alloc_flag &&
+ dec->avs2_dec.fref[ii]->
+ vf_ref == 0) {
+ struct avs2_frame_s *pic =
+ dec->avs2_dec.fref[ii];
+ if (dec->avs2_dec.fref[ii]->
+ refered_by_others == 0) {
#ifdef AVS2_10B_MMU
- pic->mmu_alloc_flag = 0;
+ dec->avs2_dec.fref[ii]->
+ mmu_alloc_flag = 0;
/*release_buffer_4k(
dec->avs2_dec.fref[ii]->index);*/
decoder_mmu_box_free_idx(dec->mmu_box,
- pic->index);
+ dec->avs2_dec.fref[ii]->index);
+#ifdef DYNAMIC_ALLOC_HEAD
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ HEADER_BUFFER_IDX(pic->index));
+ pic->header_adr = 0;
+#endif
#endif
#ifndef MV_USE_FIXED_BUF
decoder_bmmu_box_free_idx(
@@ -6092,6 +5594,10 @@
pic->mpred_mv_wr_start_addr = 0;
#endif
}
+ decoder_bmmu_box_free_idx(
+ dec->bmmu_box,
+ VF_BUFFER_IDX(pic->index));
+ dec->cma_alloc_addr = 0;
}
}
}
@@ -6128,7 +5634,7 @@
debug_buffer_mgr_more(dec);
get_frame_rate(&dec->avs2_dec.param, dec);
-#if 1 // The video_signal_type is type of uint16_t and result false, so comment it out.
+#if 0 // The video_signal_type is type of uint16_t and result false, so comment it out.
if (dec->avs2_dec.param.p.video_signal_type
& (1<<30)) {
union param_u *pPara;
@@ -6212,9 +5718,9 @@
u32 convert_c = c;
if (v & 0x2000) {
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"video_signal_type present:\n");
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
" %s %s\n",
video_format_names[(v >> 10) & 7],
((v >> 9) & 1) ?
@@ -6223,21 +5729,21 @@
u32 transfer;
u32 maxtrix;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"color_description present:\n");
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"color_primarie = %d\n",
v & 0xff);
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"transfer_characteristic = %d\n",
(c >> 8) & 0xff);
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
" matrix_coefficient = %d\n",
c & 0xff);
transfer = (c >> 8) & 0xFF;
if (transfer >= 15)
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"unsupport transfer_characteristic\n");
else if (transfer == 14)
transfer = 18; /* HLG */
@@ -6250,7 +5756,7 @@
maxtrix = c & 0xFF;
if (maxtrix >= 10)
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
"unsupport matrix_coefficient\n");
else if (maxtrix == 9)
maxtrix = 10;
@@ -6259,7 +5765,7 @@
convert_c = (transfer << 8) | (maxtrix);
- avs2_print(dec, AVS2_DBG_HDR_INFO,
+ avs2_print(dec, 0,
" convered c:0x%x\n",
convert_c);
}
@@ -6318,58 +5824,34 @@
if (!dec->m_ins_flag)
dec->slice_idx++;
- if (dec->m_ins_flag && ret
- && dec->avs2_dec.hc.cur_pic->cuva_data_buf != NULL)
- release_cuva_data(dec->avs2_dec.hc.cur_pic);
-
PRINT_LINE();
#ifdef I_ONLY_SUPPORT
if ((start_code == PB_PICTURE_START_CODE) &&
(dec->i_only & 0x2))
ret = -2;
#endif
-
- if (ret >= 0) {
#ifdef AVS2_10B_MMU
- if (dec->mmu_enable) {
- ret = avs2_alloc_mmu(dec,
+ if (ret >= 0) {
+ ret = avs2_alloc_mmu(dec,
+ dec->avs2_dec.hc.cur_pic->index,
+ dec->avs2_dec.img.width,
+ dec->avs2_dec.img.height,
+ dec->avs2_dec.input.sample_bit_depth,
+ dec->frame_mmu_map_addr);
+ if (ret >= 0) {
+ dec->cur_fb_idx_mmu =
+ dec->avs2_dec.hc.cur_pic->index;
+ dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
+ } else
+ pr_err("can't alloc need mmu1,idx %d ret =%d\n",
dec->avs2_dec.hc.cur_pic->index,
- dec->avs2_dec.img.width,
- dec->avs2_dec.img.height,
- dec->avs2_dec.input.sample_bit_depth,
- dec->frame_mmu_map_addr);
- if (ret >= 0) {
- dec->cur_fb_idx_mmu =
- dec->avs2_dec.hc.cur_pic->index;
- dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
- } else
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- dec->avs2_dec.hc.cur_pic->index,
- ret);
- }
-#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- ret = avs2_alloc_dw_mmu(dec,
- dec->avs2_dec.hc.cur_pic->index,
- dec->avs2_dec.img.width,
- dec->avs2_dec.img.height,
- dec->avs2_dec.input.sample_bit_depth,
- dec->dw_frame_mmu_map_addr);
- if (ret >= 0) {
- dec->cur_fb_idx_mmu =
- dec->avs2_dec.hc.cur_pic->index;
- dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
- } else
- pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
- dec->avs2_dec.hc.cur_pic->index,
- ret);
- }
-#endif
+ ret);
}
+#endif
#ifndef MV_USE_FIXED_BUF
- if (ret >= 0 && dec->avs2_dec.hc.cur_pic->
+ if (ret >= 0 &&
+ dec->avs2_dec.hc.cur_pic->
mpred_mv_wr_start_addr == 0) {
unsigned long buf_addr;
unsigned mv_buf_size = get_mv_buf_size(
@@ -6398,8 +5880,7 @@
ret);
WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
#ifdef AVS2_10B_MMU
- if (dec->mmu_enable)
- avs2_recycle_mmu_buf(dec);
+ avs2_recycle_mmu_buf(dec);
#endif
if (dec->m_ins_flag) {
dec->dec_result = DEC_RESULT_DONE;
@@ -6594,10 +6075,10 @@
return IRQ_WAKE_THREAD;
}
-static void vavs2_put_timer_func(struct timer_list *timer)
+static void vavs2_put_timer_func(unsigned long arg)
{
- struct AVS2Decoder_s *dec = container_of(timer,
- struct AVS2Decoder_s, timer);
+ struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)arg;
+ struct timer_list *timer = &dec->timer;
uint8_t empty_flag;
unsigned int buf_level;
@@ -6715,7 +6196,6 @@
}
if (debug & AVS2_DBG_DUMP_RPM_BUF) {
int i;
-
pr_info("RPM:\n");
for (i = 0; i < RPM_BUF_SIZE; i += 4) {
int ii;
@@ -6732,7 +6212,6 @@
}
if (debug & AVS2_DBG_DUMP_LMEM_BUF) {
int i;
-
pr_info("LMEM:\n");
for (i = 0; i < LMEM_BUF_SIZE; i += 4) {
int ii;
@@ -6928,7 +6407,6 @@
WRITE_VREG(DECODE_STOP_POS, udebug_flag);
- config_cuva_buf(dec);
}
#ifdef I_ONLY_SUPPORT
@@ -7017,8 +6495,7 @@
int fw_size = 0x1000 * 16;
struct firmware_s *fw = NULL;
struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
-
- timer_setup(&dec->timer, vavs2_put_timer_func, 0);
+ init_timer(&dec->timer);
dec->stat |= STAT_TIMER_INIT;
if (vavs2_local_init(dec) < 0)
@@ -7040,6 +6517,8 @@
fw->len = fw_size;
if (dec->m_ins_flag) {
+ dec->timer.data = (ulong) dec;
+ dec->timer.function = vavs2_put_timer_func;
dec->timer.expires = jiffies + PUT_INTERVAL;
/*add_timer(&dec->timer);
@@ -7052,9 +6531,7 @@
return 0;
}
-
amhevc_enable();
-
ret = amhevc_loadmc_ex(VFORMAT_AVS2, NULL, fw->data);
if (ret < 0) {
amhevc_disable();
@@ -7097,7 +6574,11 @@
}
dec->stat |= STAT_VF_HOOK;
+ dec->timer.data = (ulong)dec;
+ dec->timer.function = vavs2_put_timer_func;
dec->timer.expires = jiffies + PUT_INTERVAL;
+
+
add_timer(&dec->timer);
dec->stat |= STAT_TIMER_ARM;
@@ -7189,32 +6670,17 @@
CODEC_MM_FLAGS_TVP : 0;
int buf_size = 48;
+#ifdef AVS2_10B_MMU
dec->need_cache_size = buf_size * SZ_1M;
dec->sc_start_time = get_jiffies_64();
-#ifdef AVS2_10B_MMU
- if (dec->mmu_enable) {
- dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- dec->index, FRAME_BUFFERS,
- dec->need_cache_size,
- tvp_flag
- );
- if (!dec->mmu_box) {
- pr_err("avs2 alloc mmu box failed!!\n");
- return -1;
- }
- }
-#endif
-#ifdef AVS2_10B_MMU_DW
- if (dec->dw_mmu_enable) {
- dec->dw_mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- dec->index, FRAME_BUFFERS,
- dec->need_cache_size,
- tvp_flag
- );
- if (!dec->dw_mmu_box) {
- pr_err("avs2 alloc dw mmu box failed!!\n");
- dec->dw_mmu_enable = 0;
- }
+ dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ dec->index, FRAME_BUFFERS,
+ dec->need_cache_size,
+ tvp_flag
+ );
+ if (!dec->mmu_box) {
+ pr_err("avs2 alloc mmu box failed!!\n");
+ return -1;
}
#endif
dec->bmmu_box = decoder_bmmu_box_alloc_box(
@@ -7235,20 +6701,16 @@
static int amvdec_avs2_probe(struct platform_device *pdev)
{
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- /*struct BUF_s BUF[MAX_BUF_NUM];*/
+ struct BUF_s BUF[MAX_BUF_NUM];
struct AVS2Decoder_s *dec = &gAVS2Decoder;
int ret;
pr_info("%s\n", __func__);
-
- dec = vzalloc(sizeof(struct AVS2Decoder_s));
- if (!dec)
- return -ENOMEM;
-
- pdata->private = dec;
- platform_set_drvdata(pdev, pdata);
-
mutex_lock(&vavs2_mutex);
+ memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ memset(dec, 0, sizeof(struct AVS2Decoder_s));
+ memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+
dec->init_flag = 0;
dec->first_sc_checked = 0;
dec->eos = 0;
@@ -7266,14 +6728,6 @@
dec->platform_dev = pdev;
platform_set_drvdata(pdev, pdata);
-#ifdef AVS2_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- dec->dw_mmu_enable =
- (get_double_write_mode(dec) & 0x20) ? 1 : 0;
- } else {
- dec->dw_mmu_enable = 0;
- }
-#endif
if (amvdec_avs2_mmu_init(dec) < 0) {
mutex_unlock(&vavs2_mutex);
pr_err("avs2 alloc bmmu box failed!!\n");
@@ -7309,12 +6763,6 @@
}
dec->cma_dev = pdata->cma_dev;
- dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- dec->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- dec->endian = endian;
-
pdata->private = dec;
pdata->dec_status = vavs2_dec_status;
/*pdata->set_isreset = vavs2_set_isreset;*/
@@ -7360,16 +6808,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int avs2_suspend(struct device *dev)
+{
+ amhevc_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int avs2_resume(struct device *dev)
+{
+ amhevc_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops avs2_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(avs2_suspend, avs2_resume)
+};
+#endif
static struct platform_driver amvdec_avs2_driver = {
.probe = amvdec_avs2_probe,
.remove = amvdec_avs2_remove,
-#ifdef CONFIG_PM
- .suspend = amhevc_suspend,
- .resume = amhevc_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &avs2_pm_ops,
+#endif
}
};
@@ -7537,8 +7001,8 @@
decode_frame_count[dec->index] = dec->frame_count;
#ifdef AVS2_10B_MMU
- if (dec->mmu_enable)
- dec->used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
+ dec->used_4k_num =
+ (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
#endif
avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
"%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
@@ -7912,7 +7376,7 @@
for (i = 0; i < MAX_BUF_NUM; i++) {
avs2_print(dec, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
+ "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n",
i,
dec->m_mv_BUF[i].start_adr,
dec->m_mv_BUF[i].size,
@@ -8001,18 +7465,12 @@
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
int ret;
int config_val;
- int i;
struct vframe_content_light_level_s content_light_level;
struct vframe_master_display_colour_s vf_dp;
- /*struct BUF_s BUF[MAX_BUF_NUM];*/
- struct AVS2Decoder_s *dec = NULL;
+ struct BUF_s BUF[MAX_BUF_NUM];
+ struct AVS2Decoder_s *dec = NULL;
pr_info("%s\n", __func__);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
- pr_info("%s, chip id %d is not support avs2\n",
- __func__, get_cpu_major_id());
- return -1;
- }
if (pdata == NULL) {
pr_info("\nammvdec_avs2 memory resource undefined.\n");
return -EFAULT;
@@ -8020,7 +7478,8 @@
/*dec = (struct AVS2Decoder_s *)devm_kzalloc(&pdev->dev,
sizeof(struct AVS2Decoder_s), GFP_KERNEL);*/
memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
- dec = vzalloc(sizeof(struct AVS2Decoder_s));
+ dec = vmalloc(sizeof(struct AVS2Decoder_s));
+ memset(dec, 0, sizeof(struct AVS2Decoder_s));
if (dec == NULL) {
pr_info("\nammvdec_avs2 device data allocation failed\n");
return -ENOMEM;
@@ -8044,26 +7503,12 @@
pdata->threaded_irq_handler = avs2_threaded_irq_cb;
pdata->dump_state = avs2_dump_state;
- /*
- * memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- * memset(dec, 0, sizeof(struct AVS2Decoder_s));
- * memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- */
+ memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ memset(dec, 0, sizeof(struct AVS2Decoder_s));
+ memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
dec->index = pdev->id;
dec->m_ins_flag = 1;
- if (is_rdma_enable()) {
- dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &dec->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- dec->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- dec->rdma_adr[i * 4 + 1] = i;
- dec->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- dec->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- dec->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
snprintf(dec->vdec_name, sizeof(dec->vdec_name),
"avs2-%d", dec->index);
@@ -8093,8 +7538,9 @@
dec->video_ori_signal_type = 0;
if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX)
dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
-
- if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
+#if 1
+ if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
+ pdata->config_len) {
/*use ptr config for doubel_write_mode, etc*/
avs2_print(dec, 0, "pdata->config=%s\n", pdata->config);
if (get_config_int(pdata->config, "avs2_double_write_mode",
@@ -8155,7 +7601,9 @@
| (9 << 0); /* 2020 */
}
dec->vf_dp = vf_dp;
- } else {
+ } else
+#endif
+ {
/*dec->vavs2_amstream_dec_info.width = 0;
dec->vavs2_amstream_dec_info.height = 0;
dec->vavs2_amstream_dec_info.rate = 30;*/
@@ -8164,21 +7612,10 @@
}
video_signal_type = dec->video_signal_type;
- if (double_write_mode) {
- dec->double_write_mode = get_double_write_mode(dec);
- }
-
- if ((dec->double_write_mode & 0x10) == 0)
- dec->mmu_enable = 1;
-
-#ifdef AVS2_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- dec->dw_mmu_enable =
- (get_double_write_mode(dec) & 0x20) ? 1 : 0;
- } else {
- dec->dw_mmu_enable = 0;
- }
-#endif
+#if 0
+ dec->buf_start = pdata->mem_start;
+ dec->buf_size = pdata->mem_end - pdata->mem_start + 1;
+#else
if (amvdec_avs2_mmu_init(dec) < 0) {
pr_err("avs2 alloc bmmu box failed!!\n");
/* devm_kfree(&pdev->dev, (void *)dec); */
@@ -8197,7 +7634,7 @@
}
dec->buf_start = dec->cma_alloc_addr;
dec->buf_size = work_buf_size;
-
+#endif
dec->init_flag = 0;
dec->first_sc_checked = 0;
dec->fatal_error = 0;
@@ -8219,12 +7656,6 @@
dec->vavs2_amstream_dec_info.rate = 30;
}
- dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- dec->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- dec->endian = endian;
-
dec->cma_dev = pdata->cma_dev;
if (vavs2_init(pdata) < 0) {
pr_info("\namvdec_avs2 init failed.\n");
@@ -8253,8 +7684,6 @@
struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)
(((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic;
int i;
if (debug)
@@ -8275,21 +7704,11 @@
}
}
- for (i = 0; i < dec->used_buf_num; i++) {
- if (i == (dec->used_buf_num - 1))
- pic = avs2_dec->m_bg;
- else
- pic = avs2_dec->fref[i];
- release_cuva_data(pic);
- }
-
#ifdef DEBUG_PTS
pr_info("pts missed %ld, pts hit %ld, duration %d\n",
dec->pts_missed, dec->pts_hit, dec->frame_dur);
#endif
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
/* devm_kfree(&pdev->dev, (void *)dec); */
vfree((void *)dec);
return 0;
@@ -8298,12 +7717,11 @@
static struct platform_driver ammvdec_avs2_driver = {
.probe = ammvdec_avs2_probe,
.remove = ammvdec_avs2_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = MULTI_DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &avs2_pm_ops,
+#endif
}
};
#endif
@@ -8349,22 +7767,16 @@
{
#ifdef AVS2_10B_MMU
+
struct BuffInfo_s *p_buf_info;
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvavs2_workbuff_spec[2];
- else
- p_buf_info = &amvavs2_workbuff_spec[1];
- } else
- p_buf_info = &amvavs2_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- p_buf_info = &amvavs2_workbuff_spec[5];
- } else
- p_buf_info = &amvavs2_workbuff_spec[3];
- }
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ p_buf_info = &amvavs2_workbuff_spec[2];
+ else
+ p_buf_info = &amvavs2_workbuff_spec[1];
+ } else
+ p_buf_info = &amvavs2_workbuff_spec[0];
init_buff_spec(NULL, p_buf_info);
work_buf_size =
@@ -8391,10 +7803,10 @@
return -ENODEV;
}
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
- amvdec_avs2_profile.name = "avs2_unsupport";
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ amvdec_avs2_profile.profile =
+ "8k, 10bit, dwrite, compressed";
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
if (vdec_is_support_4k())
amvdec_avs2_profile.profile =
"4k, 10bit, dwrite, compressed";
@@ -8402,9 +7814,7 @@
amvdec_avs2_profile.profile =
"10bit, dwrite, compressed";
} else {
- /* cpu id larger than sm1 support 8k */
- amvdec_avs2_profile.profile =
- "8k, 10bit, dwrite, compressed";
+ amvdec_avs2_profile.name = "avs2_unsupport";
}
vcodec_profile_register(&amvdec_avs2_profile);
@@ -8414,7 +7824,6 @@
INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node,
"avs2", avs2_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_AVS2, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.h b/drivers/frame_provider/decoder/avs2/vavs2.h
index 071bfb3..6b51f61 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.h
+++ b/drivers/frame_provider/decoder/avs2/vavs2.h
@@ -19,7 +19,7 @@
#define VAVS2_H
#define AVS2_10B_MMU
-#define AVS2_10B_MMU_DW
+#define MV_USE_FIXED_BUF
void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
index 7dd20bb..38e39d0 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -44,7 +44,6 @@
#include "../utils/firmware.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include <linux/amlogic/tee.h>
-#include "../utils/vdec_feature.h"
#define DEBUG_MULTI_FLAG 0
/*
@@ -124,6 +123,9 @@
#define DECODE_CFG AV_SCRATCH_K
+
+
+
#define VF_POOL_SIZE 64
#define PUT_INTERVAL (HZ/100)
@@ -151,7 +153,7 @@
#define DEBUG_REG2 AV_SCRATCH_D
-static void check_timer_func(struct timer_list *timer);
+static void check_timer_func(unsigned long arg);
static void vavs_work(struct work_struct *work);
#define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001
@@ -1270,35 +1272,35 @@
} else {
#ifdef NV21
- config_cav_lut_ex(canvas_base + canvas_num * i + 0,
+ canvas_config(canvas_base + canvas_num * i + 0,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_base + canvas_num * i + 1,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_base + canvas_num * i + 1,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_BLKMODE_32X32);
#else
- config_cav_lut_ex(canvas_num * i + 0,
+ canvas_config(canvas_num * i + 0,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 1,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 1,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 2,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(canvas_num * i + 2,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_BLKMODE_32X32);
#endif
debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
"canvas config %d, addr %p\n", i,
@@ -1390,7 +1392,6 @@
#ifdef NV21
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
#endif
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
#ifdef PIC_DC_NEED_CLEAR
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
@@ -1600,21 +1601,21 @@
vavs_restore_regs(hw);
for (i = 0; i < hw->vf_buf_num_used; i++) {
- config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
+ canvas_config_ex(canvas_y(hw->canvas_spec[i]),
hw->canvas_config[i][0].phy_addr,
hw->canvas_config[i][0].width,
hw->canvas_config[i][0].height,
CANVAS_ADDR_NOWRAP,
hw->canvas_config[i][0].block_mode,
- 0, VDEC_1);
+ 0);
- config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
+ canvas_config_ex(canvas_u(hw->canvas_spec[i]),
hw->canvas_config[i][1].phy_addr,
hw->canvas_config[i][1].width,
hw->canvas_config[i][1].height,
CANVAS_ADDR_NOWRAP,
hw->canvas_config[i][1].block_mode,
- 0, VDEC_1);
+ 0);
}
} else {
r = vavs_canvas_init(hw);
@@ -1694,7 +1695,6 @@
#ifdef NV21
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
#endif
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
#ifdef PIC_DC_NEED_CLEAR
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
@@ -1938,10 +1938,9 @@
#ifdef DEBUG_MULTI_WITH_AUTOMODE
int delay_count = 0;
#endif
-static void vavs_put_timer_func(struct timer_list *arg)
+static void vavs_put_timer_func(unsigned long arg)
{
- struct vdec_avs_hw_s *hw = container_of(arg,
- struct vdec_avs_hw_s, recycle_timer);
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg;
struct timer_list *timer = &hw->recycle_timer;
#ifndef HANDLE_AVS_IRQ
@@ -2216,10 +2215,9 @@
hw->fw = fw;
if (hw->m_ins_flag) {
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (ulong) hw;
- //hw->check_timer.function = check_timer_func;
+ init_timer(&hw->check_timer);
+ hw->check_timer.data = (ulong) hw;
+ hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
@@ -2289,9 +2287,8 @@
hw->stat |= STAT_VF_HOOK;
- timer_setup(&hw->recycle_timer, vavs_put_timer_func, 0);
- //hw->recycle_timer.data = (ulong)(hw);
- //hw->recycle_timer.function = vavs_put_timer_func;
+ hw->recycle_timer.data = (ulong)(hw);
+ hw->recycle_timer.function = vavs_put_timer_func;
hw->recycle_timer.expires = jiffies + PUT_INTERVAL;
add_timer(&hw->recycle_timer);
@@ -2513,7 +2510,7 @@
}
/****************************************/
-#if 0
+#ifdef DEBUG_WITH_SINGLE_MODE
static struct platform_driver amvdec_avs_driver = {
.probe = amvdec_avs_probe,
.remove = amvdec_avs_remove,
@@ -2522,7 +2519,6 @@
}
};
#endif
-
static void recycle_frames(struct vdec_avs_hw_s *hw);
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
@@ -2531,6 +2527,7 @@
(struct vdec_avs_hw_s *)vdec->private;
int ret = 1;
unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1;
+
#ifdef DEBUG_MULTI_FRAME_INS
if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] &&
run_count[1] < max_run_count[1])
@@ -2852,10 +2849,9 @@
}
-static void check_timer_func(struct timer_list *timer)
+static void check_timer_func(unsigned long arg)
{
- struct vdec_avs_hw_s *hw = container_of(timer,
- struct vdec_avs_hw_s, check_timer);
+ struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
unsigned int timeout_val = decode_timeout_val;
unsigned long flags;
@@ -3195,8 +3191,8 @@
"%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n",
__func__, READ_VREG(AVS_BUFFERIN),
kfifo_len(&hw->recycle_q));
-
WRITE_VREG(VIFF_BIT_CNT, size * 8);
+
if (hw->reset_decode_flag)
WRITE_VREG(DECODE_STATUS, 0);
else {
@@ -3839,6 +3835,7 @@
#endif
}
+
static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq)
{
@@ -4378,21 +4375,21 @@
vavs_restore_regs(hw);
for (i = 0; i < hw->vf_buf_num_used; i++) {
- config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
+ canvas_config_ex(canvas_y(hw->canvas_spec[i]),
hw->canvas_config[i][0].phy_addr,
hw->canvas_config[i][0].width,
hw->canvas_config[i][0].height,
CANVAS_ADDR_NOWRAP,
hw->canvas_config[i][0].block_mode,
- 0, VDEC_1);
+ 0);
- config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
+ canvas_config_ex(canvas_u(hw->canvas_spec[i]),
hw->canvas_config[i][1].phy_addr,
hw->canvas_config[i][1].width,
hw->canvas_config[i][1].height,
CANVAS_ADDR_NOWRAP,
hw->canvas_config[i][1].block_mode,
- 0, VDEC_1);
+ 0);
}
}
}
@@ -4452,8 +4449,6 @@
#ifdef NV21
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
#endif
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
if (start_decoding_delay & 0x20000)
msleep(start_decoding_delay&0xffff);
@@ -4867,8 +4862,6 @@
pr_info("failed to register amvdec_avs driver\n");
return -ENODEV;
}
-#else
- //amvdec_avs_driver = amvdec_avs_driver;
#endif
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
ammvdec_avs_profile.profile = "mavs+";
@@ -4876,7 +4869,6 @@
vcodec_profile_register(&ammvdec_avs_profile);
INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node,
"mavs", mavs_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_AVS, 0);
return 0;
}
@@ -4989,6 +4981,7 @@
module_param(udebug_pause_ins_id, uint, 0664);
MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n");
+
module_param(start_decoding_delay, uint, 0664);
MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n");
diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c
index 55f0581..03a1dba 100644
--- a/drivers/frame_provider/decoder/h264/vh264.c
+++ b/drivers/frame_provider/decoder/h264/vh264.c
@@ -23,6 +23,7 @@
#include <linux/timer.h>
#include <linux/kfifo.h>
#include <linux/platform_device.h>
+
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/vfm/vframe.h>
@@ -37,6 +38,7 @@
#include <linux/slab.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/canvas/canvas.h>
+
#include "../utils/vdec.h"
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../utils/amvdec.h"
@@ -44,17 +46,19 @@
#include "../../../stream_input/amports/streambuf.h"
#include <linux/delay.h>
#include <linux/amlogic/media/video_sink/video.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include <linux/amlogic/media/ge2d/ge2d.h>
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
+#include <linux/amlogic/tee.h>
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include <linux/uaccess.h>
+
+
#define DRIVER_NAME "amvdec_h264"
#define MODULE_NAME "amvdec_h264"
#define MEM_NAME "codec_264"
@@ -156,7 +160,7 @@
static void vh264_prot_init(void);
static int vh264_local_init(void);
-static void vh264_put_timer_func(struct timer_list *timer);
+static void vh264_put_timer_func(unsigned long arg);
static void stream_switching_done(void);
static const char vh264_dec_id[] = "vh264-dev";
@@ -249,6 +253,14 @@
#endif
static u32 enable_userdata_debug;
+/* if not define, must clear AV_SCRATCH_J in isr when
+ * ITU_T35 code enabled in ucode, otherwise may fatal
+ * error repeatly.
+ */
+//#define ENABLE_SEI_ITU_T35
+
+
+
static unsigned int enable_switch_fense = 1;
#define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k)
static struct vframe_qos_s s_vframe_qos;
@@ -460,15 +472,15 @@
int endian;
endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
- config_cav_lut_ex(spec->y_canvas_index,
+ canvas_config_ex(spec->y_canvas_index,
spec->y_addr,
width, height,
- CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
+ CANVAS_ADDR_NOWRAP, canvas_mode, endian);
- config_cav_lut_ex(spec->u_canvas_index,
+ canvas_config_ex(spec->u_canvas_index,
spec->u_addr,
width, height / 2,
- CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
+ CANVAS_ADDR_NOWRAP, canvas_mode, endian);
}
@@ -2196,16 +2208,16 @@
buffer_spec[i].v_canvas_height = mb_height << 4;
endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
- config_cav_lut_ex(128 + i * 2,
+ canvas_config_ex(128 + i * 2,
buffer_spec[i].y_addr,
mb_width << 4, mb_height << 4,
CANVAS_ADDR_NOWRAP,
- canvas_mode, endian, VDEC_1);
- config_cav_lut_ex(128 + i * 2 + 1,
+ canvas_mode, endian);
+ canvas_config_ex(128 + i * 2 + 1,
buffer_spec[i].u_addr,
mb_width << 4, mb_height << 3,
CANVAS_ADDR_NOWRAP,
- canvas_mode, endian, VDEC_1);
+ canvas_mode, endian);
WRITE_VREG(ANC0_CANVAS_ADDR + i,
spec2canvas(&buffer_spec[i]));
} else {
@@ -2587,6 +2599,7 @@
gvs->ratio_control = ratio_control;
}
+
#ifdef HANDLE_H264_IRQ
static irqreturn_t vh264_isr(int irq, void *dev_id)
#else
@@ -3335,8 +3348,9 @@
frame_width, frame_height, fps);
}
-static void vh264_put_timer_func(struct timer_list *timer)
+static void vh264_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
unsigned int wait_buffer_status;
unsigned int wait_i_pass_frames;
unsigned int reg_val;
@@ -3786,7 +3800,7 @@
int firmwareloaded = 0;
/* pr_info("\nvh264_init\n"); */
- timer_setup(&recycle_timer, vh264_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -3978,7 +3992,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong) &recycle_timer;
+ recycle_timer.function = vh264_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -4207,17 +4224,17 @@
canvas_read(y_index, &csy);
canvas_read(u_index, &csu);
- config_cav_lut_ex(fense_buffer_spec[i].y_canvas_index,
+ canvas_config(fense_buffer_spec[i].y_canvas_index,
fense_buffer_spec[i].phy_addr,
mb_width_num << 4, mb_height_num << 4,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex(fense_buffer_spec[i].u_canvas_index,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(fense_buffer_spec[i].u_canvas_index,
fense_buffer_spec[i].phy_addr +
(mb_total_num << 8),
mb_width_num << 4, mb_height_num << 3,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
+ CANVAS_BLKMODE_LINEAR);
y_desindex = fense_buffer_spec[i].y_canvas_index;
u_desindex = fense_buffer_spec[i].u_canvas_index;
@@ -4334,6 +4351,8 @@
INIT_WORK(&userdata_push_work, userdata_push_do_work);
INIT_WORK(&qos_work, qos_do_work);
+
+
atomic_set(&vh264_active, 1);
mutex_unlock(&vh264_mutex);
@@ -4376,16 +4395,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int h264_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int h264_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops h264_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(h264_suspend, h264_resume)
+};
+#endif
static struct platform_driver amvdec_h264_driver = {
.probe = amvdec_h264_probe,
.remove = amvdec_h264_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &h264_pm_ops,
+#endif
}
};
@@ -4425,8 +4460,7 @@
return -ENODEV;
}
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB
- && (codec_mm_get_total_size() > 80 * SZ_1M) &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D) {
+ && (codec_mm_get_total_size() > 80 * SZ_1M)) {
amvdec_h264_profile.profile = "4k";
}
vcodec_profile_register(&amvdec_h264_profile);
@@ -4456,7 +4490,7 @@
MODULE_PARM_DESC(dec_control, "\n amvdec_h264 decoder control\n");
module_param(frame_count, uint, 0664);
MODULE_PARM_DESC(frame_count,
- "\n amvdec_h264 decoded total count\n");
+ "\n amvdec_h264 decoded total count\n");
module_param(fatal_error_reset, uint, 0664);
MODULE_PARM_DESC(fatal_error_reset,
"\n amvdec_h264 decoder reset when fatal error happens\n");
diff --git a/drivers/frame_provider/decoder/h264/vh264_4k2k.c b/drivers/frame_provider/decoder/h264/vh264_4k2k.c
new file mode 100644
index 0000000..44465ad
--- /dev/null
+++ b/drivers/frame_provider/decoder/h264/vh264_4k2k.c
@@ -0,0 +1,1808 @@
+/*
+ * drivers/amlogic/amports/vh264_4k2k.c
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/kfifo.h>
+#include <linux/platform_device.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
+#include <linux/delay.h>
+
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/media/video_sink/video_keeper.h>
+#include "../utils/firmware.h"
+#include <linux/amlogic/tee.h>
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+
+
+
+#define MEM_NAME "codec_264_4k"
+
+/* #include <mach/am_regs.h> */
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
+
+#include <linux/amlogic/media/vpu/vpu.h>
+#endif
+
+#include <linux/amlogic/media/utils/vdec_reg.h>
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+
+
+
+#if 0 /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6TVD */
+#define DOUBLE_WRITE
+#endif
+
+#define DRIVER_NAME "amvdec_h264_4k2k"
+#define MODULE_NAME "amvdec_h264_4k2k"
+
+#define PUT_INTERVAL (HZ/100)
+#define ERROR_RESET_COUNT 500
+#define DECODE_BUFFER_NUM_MAX 32
+#define DISPLAY_BUFFER_NUM 6
+#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + DISPLAY_BUFFER_NUM)
+#define VF_BUFFER_IDX(n) (2 + n)
+#define DECODER_WORK_SPACE_SIZE 0x800000
+
+#if 1 /* MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV */
+#define H264_4K2K_SINGLE_CORE 1
+#else
+#define H264_4K2K_SINGLE_CORE IS_MESON_M8M2_CPU
+#endif
+
+#define SLICE_TYPE_I 2
+
+static int vh264_4k2k_vf_states(struct vframe_states *states, void *);
+static struct vframe_s *vh264_4k2k_vf_peek(void *);
+static struct vframe_s *vh264_4k2k_vf_get(void *);
+static void vh264_4k2k_vf_put(struct vframe_s *, void *);
+static int vh264_4k2k_event_cb(int type, void *data, void *private_data);
+
+static void vh264_4k2k_prot_init(void);
+static int vh264_4k2k_local_init(void);
+static void vh264_4k2k_put_timer_func(unsigned long arg);
+
+static const char vh264_4k2k_dec_id[] = "vh264_4k2k-dev";
+static const char vh264_4k2k_dec_id2[] = "vh264_4k2k-vdec2-dev";
+
+#define PROVIDER_NAME "decoder.h264_4k2k"
+
+static const struct vframe_operations_s vh264_4k2k_vf_provider = {
+ .peek = vh264_4k2k_vf_peek,
+ .get = vh264_4k2k_vf_get,
+ .put = vh264_4k2k_vf_put,
+ .event_cb = vh264_4k2k_event_cb,
+ .vf_states = vh264_4k2k_vf_states,
+};
+static void *mm_blk_handle;
+static struct vframe_provider_s vh264_4k2k_vf_prov;
+
+static u32 mb_width_old, mb_height_old;
+static u32 frame_width, frame_height, frame_dur, frame_ar;
+static u32 saved_resolution;
+static struct timer_list recycle_timer;
+static u32 stat;
+static u32 error_watchdog_count;
+static uint error_recovery_mode;
+static u32 sync_outside;
+static u32 vh264_4k2k_rotation;
+static u32 first_i_received;
+static struct vframe_s *p_last_vf;
+static struct work_struct set_clk_work;
+
+#ifdef DEBUG_PTS
+static unsigned long pts_missed, pts_hit;
+#endif
+
+static struct dec_sysinfo vh264_4k2k_amstream_dec_info;
+static dma_addr_t mc_dma_handle;
+static void *mc_cpu_addr;
+
+#define AMVDEC_H264_4K2K_CANVAS_INDEX 0x80
+#define AMVDEC_H264_4K2K_CANVAS_MAX 0xc6
+static DEFINE_SPINLOCK(lock);
+static int fatal_error;
+
+static atomic_t vh264_4k2k_active = ATOMIC_INIT(0);
+
+static DEFINE_MUTEX(vh264_4k2k_mutex);
+
+static void (*probe_callback)(void);
+static void (*remove_callback)(void);
+static struct device *cma_dev;
+
+/* bit[3:0] command : */
+/* 0 - command finished */
+/* (DATA0 - {level_idc_mmco, max_reference_frame_num, width, height} */
+/* 1 - alloc view_0 display_buffer and reference_data_area */
+/* 2 - alloc view_1 display_buffer and reference_data_area */
+#define MAILBOX_COMMAND AV_SCRATCH_0
+#define MAILBOX_DATA_0 AV_SCRATCH_1
+#define MAILBOX_DATA_1 AV_SCRATCH_2
+#define MAILBOX_DATA_2 AV_SCRATCH_3
+#define MAILBOX_DATA_3 AV_SCRATCH_4
+#define MAILBOX_DATA_4 AV_SCRATCH_5
+#define CANVAS_START AV_SCRATCH_6
+#define BUFFER_RECYCLE AV_SCRATCH_7
+#define PICTURE_COUNT AV_SCRATCH_9
+#define DECODE_STATUS AV_SCRATCH_A
+#define SPS_STATUS AV_SCRATCH_B
+#define PPS_STATUS AV_SCRATCH_C
+#define MS_ID AV_SCRATCH_D
+#define WORKSPACE_START AV_SCRATCH_E
+#define DECODED_PIC_NUM AV_SCRATCH_F
+#define DECODE_ERROR_CNT AV_SCRATCH_G
+#define CURRENT_UCODE AV_SCRATCH_H
+/* bit[15:9]-SPS, bit[8:0]-PPS */
+#define CURRENT_SPS_PPS AV_SCRATCH_I
+#define DECODE_SKIP_PICTURE AV_SCRATCH_J
+#define DECODE_MODE AV_SCRATCH_K
+#define RESERVED_REG_L AV_SCRATCH_L
+#define REF_START_VIEW_0 AV_SCRATCH_M
+#define REF_START_VIEW_1 AV_SCRATCH_N
+
+#define VDEC2_MAILBOX_COMMAND VDEC2_AV_SCRATCH_0
+#define VDEC2_MAILBOX_DATA_0 VDEC2_AV_SCRATCH_1
+#define VDEC2_MAILBOX_DATA_1 VDEC2_AV_SCRATCH_2
+#define VDEC2_MAILBOX_DATA_2 VDEC2_AV_SCRATCH_3
+#define VDEC2_MAILBOX_DATA_3 VDEC2_AV_SCRATCH_4
+#define VDEC2_MAILBOX_DATA_4 VDEC2_AV_SCRATCH_5
+#define VDEC2_CANVAS_START VDEC2_AV_SCRATCH_6
+#define VDEC2_BUFFER_RECYCLE VDEC2_AV_SCRATCH_7
+#define VDEC2_PICTURE_COUNT VDEC2_AV_SCRATCH_9
+#define VDEC2_DECODE_STATUS VDEC2_AV_SCRATCH_A
+#define VDEC2_SPS_STATUS VDEC2_AV_SCRATCH_B
+#define VDEC2_PPS_STATUS VDEC2_AV_SCRATCH_C
+#define VDEC2_MS_ID VDEC2_AV_SCRATCH_D
+#define VDEC2_WORKSPACE_START VDEC2_AV_SCRATCH_E
+#define VDEC2_DECODED_PIC_NUM VDEC2_AV_SCRATCH_F
+#define VDEC2_DECODE_ERROR_CNT VDEC2_AV_SCRATCH_G
+#define VDEC2_CURRENT_UCODE VDEC2_AV_SCRATCH_H
+/* bit[15:9]-SPS, bit[8:0]-PPS */
+#define VDEC2_CURRENT_SPS_PPS VDEC2_AV_SCRATCH_I
+#define VDEC2_DECODE_SKIP_PICTURE VDEC2_AV_SCRATCH_J
+#define VDEC2_RESERVED_REG_K VDEC2_AV_SCRATCH_K
+#define VDEC2_RESERVED_REG_L VDEC2_AV_SCRATCH_L
+#define VDEC2_REF_START_VIEW_0 VDEC2_AV_SCRATCH_M
+#define VDEC2_REF_START_VIEW_1 VDEC2_AV_SCRATCH_N
+
+/********************************************
+ * DECODE_STATUS Define
+ *******************************************
+ */
+#define DECODE_IDLE 0
+#define DECODE_START_HEADER 1
+#define DECODE_HEADER 2
+#define DECODE_START_MMCO 3
+#define DECODE_MMCO 4
+#define DECODE_START_SLICE 5
+#define DECODE_SLICE 6
+#define DECODE_WAIT_BUFFER 7
+
+/********************************************
+ * Dual Core Communication
+ ********************************************
+ */
+#define FATAL_ERROR DOS_SCRATCH16
+#define PRE_MASTER_UPDATE_TIMES DOS_SCRATCH20
+/* bit[31] - REQUEST */
+/* bit[30:0] - MASTER_UPDATE_TIMES */
+#define SLAVE_WAIT_DPB_UPDATE DOS_SCRATCH21
+/* [15:8] - current_ref, [7:0] current_dpb (0x80 means no buffer found) */
+#define SLAVE_REF_DPB DOS_SCRATCH22
+#define SAVE_MVC_ENTENSION_0 DOS_SCRATCH23
+#define SAVE_I_POC DOS_SCRATCH24
+/* bit[31:30] - core_status 0-idle, 1-mmco, 2-decoding, 3-finished */
+/* bit[29:0] - core_pic_count */
+#define CORE_STATUS_M DOS_SCRATCH25
+#define CORE_STATUS_S DOS_SCRATCH26
+#define SAVE_ref_status_view_0 DOS_SCRATCH27
+#define SAVE_ref_status_view_1 DOS_SCRATCH28
+#define ALLOC_INFO_0 DOS_SCRATCH29
+#define ALLOC_INFO_1 DOS_SCRATCH30
+
+/********************************************
+ * Mailbox command
+ ********************************************/
+#define CMD_FINISHED 0
+#define CMD_ALLOC_VIEW 1
+#define CMD_FRAME_DISPLAY 3
+#define CMD_DEBUG 10
+
+#define MC_TOTAL_SIZE (28*SZ_1K)
+#define MC_SWAP_SIZE (4*SZ_1K)
+
+static unsigned long work_space_adr, ref_start_addr;
+static unsigned long reserved_buffer;
+
+
+#define video_domain_addr(adr) (adr&0x7fffffff)
+
+
+struct buffer_spec_s {
+ unsigned int y_addr;
+ unsigned int uv_addr;
+#ifdef DOUBLE_WRITE
+ unsigned int y_dw_addr;
+ unsigned int uv_dw_addr;
+#endif
+
+ int y_canvas_index;
+ int uv_canvas_index;
+#ifdef DOUBLE_WRITE
+ int y_dw_canvas_index;
+ int uv_dw_canvas_index;
+#endif
+
+ struct page *alloc_pages;
+ unsigned long phy_addr;
+ int alloc_count;
+};
+
+static struct buffer_spec_s buffer_spec[MAX_BMMU_BUFFER_NUM];
+
+#ifdef DOUBLE_WRITE
+#define spec2canvas(x) \
+ (((x)->uv_dw_canvas_index << 16) | \
+ ((x)->uv_dw_canvas_index << 8) | \
+ ((x)->y_dw_canvas_index << 0))
+#else
+#define spec2canvas(x) \
+ (((x)->uv_canvas_index << 16) | \
+ ((x)->uv_canvas_index << 8) | \
+ ((x)->y_canvas_index << 0))
+#endif
+
+#define VF_POOL_SIZE 32
+
+static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
+
+static s32 vfbuf_use[DECODE_BUFFER_NUM_MAX];
+static struct vframe_s vfpool[VF_POOL_SIZE];
+
+static struct work_struct alloc_work;
+static struct vdec_info *gvs;
+
+static void set_frame_info(struct vframe_s *vf)
+{
+ unsigned int ar;
+
+#ifdef DOUBLE_WRITE
+ vf->width = frame_width / 2;
+ vf->height = frame_height / 2;
+#else
+ vf->width = frame_width;
+ vf->height = frame_height;
+#endif
+ vf->duration = frame_dur;
+ vf->duration_pulldown = 0;
+ vf->flag = 0;
+
+ ar = min_t(u32, frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
+ vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
+ vf->orientation = vh264_4k2k_rotation;
+
+}
+
+static int vh264_4k2k_vf_states(struct vframe_states *states, void *op_arg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ states->vf_pool_size = VF_POOL_SIZE;
+ states->buf_free_num = kfifo_len(&newframe_q);
+ states->buf_avail_num = kfifo_len(&display_q);
+ states->buf_recycle_num = kfifo_len(&recycle_q);
+
+ spin_unlock_irqrestore(&lock, flags);
+ return 0;
+}
+
+static struct vframe_s *vh264_4k2k_vf_peek(void *op_arg)
+{
+ struct vframe_s *vf;
+
+ if (kfifo_peek(&display_q, &vf))
+ return vf;
+
+ return NULL;
+}
+
+static struct vframe_s *vh264_4k2k_vf_get(void *op_arg)
+{
+ struct vframe_s *vf;
+
+ if (kfifo_get(&display_q, &vf))
+ return vf;
+
+ return NULL;
+}
+
+static void vh264_4k2k_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ kfifo_put(&recycle_q, (const struct vframe_s *)vf);
+}
+
+static int vh264_4k2k_event_cb(int type, void *data, void *private_data)
+{
+ if (type & VFRAME_EVENT_RECEIVER_RESET) {
+ unsigned long flags;
+
+ amvdec_stop();
+
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_stop();
+#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_light_unreg_provider(&vh264_4k2k_vf_prov);
+#endif
+ spin_lock_irqsave(&lock, flags);
+ vh264_4k2k_local_init();
+ vh264_4k2k_prot_init();
+ spin_unlock_irqrestore(&lock, flags);
+#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_reg_provider(&vh264_4k2k_vf_prov);
+#endif
+ amvdec_start();
+
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_start();
+ }
+
+ return 0;
+}
+
+static int init_canvas(int refbuf_size, long dpb_size, int dpb_number,
+ int mb_width, int mb_height,
+ struct buffer_spec_s *buffer_spec)
+{
+ unsigned long addr;
+ int i, j, ret = -1;
+ int mb_total;
+ int canvas_addr = ANC0_CANVAS_ADDR;
+ int vdec2_canvas_addr = VDEC2_ANC0_CANVAS_ADDR;
+ int index = AMVDEC_H264_4K2K_CANVAS_INDEX;
+
+ mb_total = mb_width * mb_height;
+ mutex_lock(&vh264_4k2k_mutex);
+
+ for (j = 0; j < (dpb_number + 1); j++) {
+ int page_count;
+ if (j == 0) {
+ ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, 1,
+ refbuf_size, DRIVER_NAME, &ref_start_addr);
+ if (ret < 0) {
+ mutex_unlock(&vh264_4k2k_mutex);
+ return ret;
+ }
+ continue;
+ }
+
+ WRITE_VREG(canvas_addr++, index | ((index + 1) << 8) |
+ ((index + 1) << 16));
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(vdec2_canvas_addr++,
+ index | ((index + 1) << 8) |
+ ((index + 1) << 16));
+ }
+
+ i = j - 1;
+#ifdef DOUBLE_WRITE
+ page_count =
+ PAGE_ALIGN((mb_total << 8) + (mb_total << 7) +
+ (mb_total << 6) + (mb_total << 5)) / PAGE_SIZE;
+#else
+ page_count =
+ PAGE_ALIGN((mb_total << 8) + (mb_total << 7)) / PAGE_SIZE;
+#endif
+
+ ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle,
+ VF_BUFFER_IDX(i), page_count << PAGE_SHIFT,
+ DRIVER_NAME, &buffer_spec[i].phy_addr);
+
+ if (ret < 0) {
+ buffer_spec[i].alloc_count = 0;
+ mutex_unlock(&vh264_4k2k_mutex);
+ return ret;
+ }
+ addr = buffer_spec[i].phy_addr;
+ buffer_spec[i].alloc_count = page_count;
+ buffer_spec[i].y_addr = addr;
+ buffer_spec[i].y_canvas_index = index;
+ canvas_config(index,
+ addr,
+ mb_width << 4,
+ mb_height << 4,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+
+ addr += mb_total << 8;
+ index++;
+
+ buffer_spec[i].uv_addr = addr;
+ buffer_spec[i].uv_canvas_index = index;
+ canvas_config(index,
+ addr,
+ mb_width << 4,
+ mb_height << 3,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+
+ addr += mb_total << 7;
+ index++;
+
+#ifdef DOUBLE_WRITE
+ buffer_spec[i].y_dw_addr = addr;
+ buffer_spec[i].y_dw_canvas_index = index;
+ canvas_config(index,
+ addr,
+ mb_width << 3,
+ mb_height << 3,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+
+ addr += mb_total << 6;
+ index++;
+
+ buffer_spec[i].uv_dw_addr = addr;
+ buffer_spec[i].uv_dw_canvas_index = index;
+ canvas_config(index,
+ addr,
+ mb_width << 3,
+ mb_height << 2,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+
+ index++;
+#endif
+ }
+
+ mutex_unlock(&vh264_4k2k_mutex);
+
+ pr_info
+ ("H264 4k2k decoder canvas allocation successful, ");
+
+ return 0;
+}
+
+static int get_max_dec_frame_buf_size(int level_idc,
+ int max_reference_frame_num, int mb_width,
+ int mb_height)
+{
+ int pic_size = mb_width * mb_height * 384;
+
+ int size = 0;
+
+ switch (level_idc) {
+ case 9:
+ size = 152064;
+ break;
+ case 10:
+ size = 152064;
+ break;
+ case 11:
+ size = 345600;
+ break;
+ case 12:
+ size = 912384;
+ break;
+ case 13:
+ size = 912384;
+ break;
+ case 20:
+ size = 912384;
+ break;
+ case 21:
+ size = 1824768;
+ break;
+ case 22:
+ size = 3110400;
+ break;
+ case 30:
+ size = 3110400;
+ break;
+ case 31:
+ size = 6912000;
+ break;
+ case 32:
+ size = 7864320;
+ break;
+ case 40:
+ size = 12582912;
+ break;
+ case 41:
+ size = 12582912;
+ break;
+ case 42:
+ size = 13369344;
+ break;
+ case 50:
+ size = 42393600;
+ break;
+ case 51:
+ case 52:
+ default:
+ size = 70778880;
+ break;
+ }
+
+ size /= pic_size;
+ size = size + 1; /* need one more buffer */
+
+ if (max_reference_frame_num > size)
+ size = max_reference_frame_num;
+
+ if (size > DECODE_BUFFER_NUM_MAX)
+ size = DECODE_BUFFER_NUM_MAX;
+
+ return size;
+}
+
+static void do_alloc_work(struct work_struct *work)
+{
+ int level_idc, max_reference_frame_num, mb_width, mb_height,
+ frame_mbs_only_flag;
+ int dpb_size, ref_size, refbuf_size;
+ int max_dec_frame_buffering,
+ total_dec_frame_buffering;
+ unsigned int chroma444;
+ unsigned int crop_infor, crop_bottom, crop_right;
+ int ret = READ_VREG(MAILBOX_COMMAND);
+
+
+ ret = READ_VREG(MAILBOX_DATA_0);
+ /* MAILBOX_DATA_1 :
+ * bit15 : frame_mbs_only_flag
+ * bit 0-7 : chroma_format_idc
+ * MAILBOX_DATA_2:
+ * bit31-16: (left << 8 | right ) << 1
+ * bit15-0 : (top << 8 | bottom ) << (2 - frame_mbs_only_flag)
+ */
+ frame_mbs_only_flag = READ_VREG(MAILBOX_DATA_1);
+ crop_infor = READ_VREG(MAILBOX_DATA_2);
+ level_idc = (ret >> 24) & 0xff;
+ max_reference_frame_num = (ret >> 16) & 0xff;
+ mb_width = (ret >> 8) & 0xff;
+ if (mb_width == 0)
+ mb_width = 256;
+ mb_height = (ret >> 0) & 0xff;
+ max_dec_frame_buffering =
+ get_max_dec_frame_buf_size(level_idc, max_reference_frame_num,
+ mb_width, mb_height);
+ total_dec_frame_buffering =
+ max_dec_frame_buffering + DISPLAY_BUFFER_NUM;
+
+ chroma444 = ((frame_mbs_only_flag&0xffff) == 3) ? 1 : 0;
+ frame_mbs_only_flag = (frame_mbs_only_flag >> 16) & 0x01;
+ crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag);
+ crop_right = ((crop_infor >> 16) & 0xff) >> 1;
+ pr_info("crop_right = 0x%x crop_bottom = 0x%x chroma_format_idc = 0x%x\n",
+ crop_right, crop_bottom, chroma444);
+
+ if ((frame_width == 0) || (frame_height == 0) || crop_infor ||
+ mb_width != mb_width_old ||
+ mb_height != mb_height_old) {
+ frame_width = mb_width << 4;
+ frame_height = mb_height << 4;
+ mb_width_old = mb_width;
+ mb_height_old = mb_height;
+ if (frame_mbs_only_flag) {
+ frame_height -= (2 >> chroma444) *
+ min(crop_bottom,
+ (unsigned int)((8 << chroma444) - 1));
+ frame_width -= (2 >> chroma444) *
+ min(crop_right,
+ (unsigned int)((8 << chroma444) - 1));
+ } else {
+ frame_height -= (4 >> chroma444) *
+ min(crop_bottom,
+ (unsigned int)((8 << chroma444) - 1));
+ frame_width -= (4 >> chroma444) *
+ min(crop_right,
+ (unsigned int)((8 << chroma444) - 1));
+ }
+ pr_info("frame_mbs_only_flag %d, crop_bottom %d frame_height %d, mb_height %d crop_right %d, frame_width %d, mb_width %d\n",
+ frame_mbs_only_flag, crop_bottom, frame_height,
+ mb_height, crop_right, frame_width, mb_height);
+ }
+
+ mb_width = (mb_width + 3) & 0xfffffffc;
+ mb_height = (mb_height + 3) & 0xfffffffc;
+
+ dpb_size = mb_width * mb_height * 384;
+ ref_size = mb_width * mb_height * 96;
+ refbuf_size = ref_size * (max_reference_frame_num + 1) * 2;
+
+
+ pr_info("mb_width=%d, mb_height=%d\n",
+ mb_width, mb_height);
+
+ ret = init_canvas(refbuf_size, dpb_size,
+ total_dec_frame_buffering, mb_width, mb_height,
+ buffer_spec);
+
+ if (ret == -1) {
+ pr_info(" Un-expected memory alloc problem\n");
+ return;
+ }
+
+ if (frame_width == 0)
+ frame_width = mb_width << 4;
+ if (frame_height == 0)
+ frame_height = mb_height << 4;
+
+ WRITE_VREG(REF_START_VIEW_0, video_domain_addr(ref_start_addr));
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(VDEC2_REF_START_VIEW_0,
+ video_domain_addr(ref_start_addr));
+ }
+
+ WRITE_VREG(MAILBOX_DATA_0,
+ (max_dec_frame_buffering << 8) |
+ (total_dec_frame_buffering << 0));
+ WRITE_VREG(MAILBOX_DATA_1, ref_size);
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+
+ /* ///////////// FAKE FIRST PIC */
+
+}
+
+static irqreturn_t vh264_4k2k_isr(int irq, void *dev_id)
+{
+ int drop_status, display_buff_id, display_POC, slice_type, error;
+ unsigned int stream_offset;
+ struct vframe_s *vf = NULL;
+ int ret = READ_VREG(MAILBOX_COMMAND);
+ u32 frame_size;
+
+ switch (ret & 0xff) {
+ case CMD_ALLOC_VIEW:
+ schedule_work(&alloc_work);
+ break;
+
+ case CMD_FRAME_DISPLAY:
+ ret >>= 8;
+ display_buff_id = (ret >> 0) & 0x3f;
+ drop_status = (ret >> 8) & 0x1;
+ slice_type = (ret >> 9) & 0x7;
+ error = (ret >> 12) & 0x1;
+ display_POC = READ_VREG(MAILBOX_DATA_0);
+ stream_offset = READ_VREG(MAILBOX_DATA_1);
+
+ smp_rmb();/* rmb smp */
+
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+
+ if (kfifo_get(&newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+
+ if (vf) {
+ vfbuf_use[display_buff_id]++;
+
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+
+ if ((!sync_outside)
+ || (sync_outside &&
+ (slice_type == SLICE_TYPE_I))) {
+ ret = pts_lookup_offset_us64(PTS_TYPE_VIDEO,
+ stream_offset,
+ &vf->pts,
+ &frame_size,
+ 0,
+ &vf->pts_us64);
+ if (ret != 0)
+ pr_debug(" vpts lookup failed\n");
+ }
+#ifdef H264_4K2K_SINGLE_CORE
+ if (READ_VREG(DECODE_MODE) & 1) {
+ /* for I only mode, ignore the PTS information
+ * and only uses 10fps for each
+ * I frame decoded
+ */
+ if (p_last_vf) {
+ vf->pts = 0;
+ vf->pts_us64 = 0;
+ }
+ frame_dur = 96000 / 10;
+ }
+#endif
+ vf->signal_type = 0;
+ vf->index = display_buff_id;
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
+ vf->type |= VIDTYPE_VIU_NV21;
+ vf->canvas0Addr = vf->canvas1Addr =
+ spec2canvas(&buffer_spec[display_buff_id]);
+ set_frame_info(vf);
+
+ if (error)
+ gvs->drop_frame_count++;
+
+ gvs->frame_dur = frame_dur;
+ vdec_count_info(gvs, error, stream_offset);
+
+ if (((error_recovery_mode & 2) && error)
+ || (!first_i_received
+ && (slice_type != SLICE_TYPE_I))) {
+ kfifo_put(&recycle_q,
+ (const struct vframe_s *)vf);
+ } else {
+ p_last_vf = vf;
+ first_i_received = 1;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ mm_blk_handle,
+ VF_BUFFER_IDX(display_buff_id));
+ kfifo_put(&display_q,
+ (const struct vframe_s *)vf);
+ ATRACE_COUNTER(MODULE_NAME, vf->pts);
+
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+ }
+ break;
+
+ case CMD_DEBUG:
+ pr_info("M: core_status 0x%08x 0x%08x; ",
+ READ_VREG(CORE_STATUS_M), READ_VREG(CORE_STATUS_S));
+ switch (READ_VREG(MAILBOX_DATA_0)) {
+ case 1:
+ pr_info("H264_BUFFER_INFO_INDEX = 0x%x\n",
+ READ_VREG(MAILBOX_DATA_1));
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 2:
+ pr_info("H264_BUFFER_INFO_DATA = 0x%x\n",
+ READ_VREG(MAILBOX_DATA_1));
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 3:
+ pr_info("REC_CANVAS_ADDR = 0x%x\n",
+ READ_VREG(MAILBOX_DATA_1));
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 4:
+ pr_info("after DPB_MMCO\n");
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 5:
+ pr_info("MBY = 0x%x, S_MBXY = 0x%x\n",
+ READ_VREG(MAILBOX_DATA_1),
+ READ_VREG(0x2c07));
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 6:
+ pr_info("after FIFO_OUT_FRAME\n");
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 7:
+ pr_info("after RELEASE_EXCEED_REF_BUFF\n");
+ WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 0x5a:
+ pr_info("\n");
+ break;
+ default:
+ pr_info("\n");
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
+static irqreturn_t vh264_4k2k_vdec2_isr(int irq, void *dev_id)
+{
+ int ret = READ_VREG(VDEC2_MAILBOX_COMMAND);
+
+ switch (ret & 0xff) {
+ case CMD_DEBUG:
+ pr_info("S: core_status 0x%08x 0x%08x; ",
+ READ_VREG(CORE_STATUS_M), READ_VREG(CORE_STATUS_S));
+ switch (READ_VREG(VDEC2_MAILBOX_DATA_0)) {
+ case 1:
+ pr_info("H264_BUFFER_INFO_INDEX = 0x%x\n",
+ READ_VREG(VDEC2_MAILBOX_DATA_1));
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 2:
+ pr_info("H264_BUFFER_INFO_DATA = 0x%x\n",
+ READ_VREG(VDEC2_MAILBOX_DATA_1));
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 3:
+ pr_info("REC_CANVAS_ADDR = 0x%x\n",
+ READ_VREG(VDEC2_MAILBOX_DATA_1));
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 4:
+ pr_info("after DPB_MMCO\n");
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 5:
+ pr_info("MBY = 0x%x, M/S_MBXY = 0x%x-0x%x\n",
+ READ_VREG(VDEC2_MAILBOX_DATA_1),
+ READ_VREG(0xc07), READ_VREG(0x2c07));
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 6:
+ pr_info("after FIFO_OUT_FRAME\n");
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 7:
+ pr_info("after RELEASE_EXCEED_REF_BUFF\n");
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, CMD_FINISHED);
+ break;
+ case 0x5a:
+ pr_info("\n");
+ break;
+ default:
+ pr_info("\n");
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static void vh264_4k2k_set_clk(struct work_struct *work)
+{
+ if (first_i_received &&/*do switch after first i frame ready.*/
+ frame_dur > 0 && saved_resolution !=
+ frame_width * frame_height * (96000 / frame_dur)) {
+ int fps = 96000 / frame_dur;
+
+ pr_info("H264 4k2k resolution changed!!\n");
+ if (vdec_source_changed(VFORMAT_H264_4K2K,
+ frame_width, frame_height, fps) > 0)/*changed clk ok*/
+ saved_resolution = frame_width * frame_height * fps;
+ }
+}
+
+static void vh264_4k2k_put_timer_func(unsigned long arg)
+{
+ struct timer_list *timer = (struct timer_list *)arg;
+ enum receviver_start_e state = RECEIVER_INACTIVE;
+
+ if (vf_get_receiver(PROVIDER_NAME)) {
+ state = vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE, NULL);
+ if ((state == RECEIVER_STATE_NULL)
+ || (state == RECEIVER_STATE_NONE))
+ state = RECEIVER_INACTIVE;
+ } else
+ state = RECEIVER_INACTIVE;
+
+ /* error watchdog */
+ if (((READ_VREG(VLD_MEM_VIFIFO_CONTROL) & 0x100) == 0) &&/* dec has in*/
+ (state == RECEIVER_INACTIVE) && /* rec has no buf to recycle */
+ (kfifo_is_empty(&display_q)) && /* no buf in display queue */
+ (kfifo_is_empty(&recycle_q)) && /* no buf to recycle */
+ (READ_VREG(MS_ID) & 0x100)
+#ifdef CONFIG_H264_2K4K_SINGLE_CORE
+ && (READ_VREG(VDEC2_MS_ID) & 0x100)
+
+/* with both decoder
+ * have started decoding
+ */
+#endif
+ && first_i_received) {
+ if (++error_watchdog_count == ERROR_RESET_COUNT) {
+ /* and it lasts for a while */
+ pr_info("H264 4k2k decoder fatal error watchdog.\n");
+ fatal_error = DECODER_FATAL_ERROR_UNKNOWN;
+ }
+ } else
+ error_watchdog_count = 0;
+
+ if (READ_VREG(FATAL_ERROR) != 0) {
+ pr_info("H264 4k2k decoder ucode fatal error.\n");
+ fatal_error = DECODER_FATAL_ERROR_UNKNOWN;
+ WRITE_VREG(FATAL_ERROR, 0);
+ }
+
+ while (!kfifo_is_empty(&recycle_q) &&
+ (READ_VREG(BUFFER_RECYCLE) == 0)) {
+ struct vframe_s *vf;
+
+ if (kfifo_get(&recycle_q, &vf)) {
+ if ((vf->index < DECODE_BUFFER_NUM_MAX)
+ && (--vfbuf_use[vf->index] == 0)) {
+ WRITE_VREG(BUFFER_RECYCLE, vf->index + 1);
+ vf->index = DECODE_BUFFER_NUM_MAX;
+ }
+
+ kfifo_put(&newframe_q, (const struct vframe_s *)vf);
+ }
+ }
+
+ schedule_work(&set_clk_work);
+
+ timer->expires = jiffies + PUT_INTERVAL;
+
+ add_timer(timer);
+}
+
+int vh264_4k2k_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+ vstatus->frame_width = frame_width;
+ vstatus->frame_height = frame_height;
+ if (frame_dur != 0)
+ vstatus->frame_rate = 96000 / frame_dur;
+ else
+ vstatus->frame_rate = -1;
+ vstatus->error_count = 0;
+ vstatus->status = stat | fatal_error;
+ vstatus->frame_dur = frame_dur;
+ vstatus->frame_data = gvs->frame_data;
+ vstatus->total_data = gvs->total_data;
+ vstatus->frame_count = gvs->frame_count;
+ vstatus->error_frame_count = gvs->error_frame_count;
+ vstatus->drop_frame_count = gvs->drop_frame_count;
+ vstatus->total_data = gvs->total_data;
+ vstatus->samp_cnt = gvs->samp_cnt;
+ vstatus->offset = gvs->offset;
+ snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
+ "%s", DRIVER_NAME);
+
+ return 0;
+}
+
+static int vh264_4k2k_vdec_info_init(void)
+{
+ gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
+ if (NULL == gvs) {
+ pr_info("the struct of vdec status malloc failed.\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int vh264_4k2k_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
+{
+ if (trickmode == TRICKMODE_I) {
+ WRITE_VREG(DECODE_MODE, 1);
+ trickmode_i = 1;
+ } else if (trickmode == TRICKMODE_NONE) {
+ WRITE_VREG(DECODE_MODE, 0);
+ trickmode_i = 0;
+ }
+
+ return 0;
+}
+
+static void H264_DECODE_INIT(void)
+{
+ int i;
+
+ WRITE_VREG(GCLK_EN, 0x3ff);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+
+ /* fill_weight_pred */
+ WRITE_VREG(MC_MPORT_CTRL, 0x0300);
+ for (i = 0; i < 192; i++)
+ WRITE_VREG(MC_MPORT_DAT, 0x100);
+ WRITE_VREG(MC_MPORT_CTRL, 0);
+
+ WRITE_VREG(MB_WIDTH, 0xff); /* invalid mb_width */
+
+ /* set slice start to 0x000000 or 0x000001 for check more_rbsp_data */
+ WRITE_VREG(SLICE_START_BYTE_01, 0x00000000);
+ WRITE_VREG(SLICE_START_BYTE_23, 0x01010000);
+ /* set to mpeg2 to enable mismatch logic */
+ WRITE_VREG(MPEG1_2_REG, 1);
+ WRITE_VREG(VLD_ERROR_MASK,
+ 0x1011);
+
+ /* Config MCPU Amrisc interrupt */
+ WRITE_VREG(ASSIST_AMR1_INT0, 0x1); /* viu_vsync_int */
+ WRITE_VREG(ASSIST_AMR1_INT1, 0x5); /* mbox_isr */
+ WRITE_VREG(ASSIST_AMR1_INT2, 0x8); /* vld_isr */
+ /* WRITE_VREG(ASSIST_AMR1_INT3, 0x15); // vififo_empty */
+ WRITE_VREG(ASSIST_AMR1_INT4, 0xd); /* rv_ai_mb_finished_int */
+ WRITE_VREG(ASSIST_AMR1_INT7, 0x14); /* dcac_dma_done */
+ WRITE_VREG(ASSIST_AMR1_INT8, 0x15); /* vififo_empty */
+
+ /* Config MCPU Amrisc interrupt */
+ WRITE_VREG(ASSIST_AMR1_INT5, 0x9); /* MCPU interrupt */
+ WRITE_VREG(ASSIST_AMR1_INT6, 0x17); /* CCPU interrupt */
+
+ WRITE_VREG(CPC_P, 0xc00); /* CCPU Code will start from 0xc00 */
+ WRITE_VREG(CINT_VEC_BASE, (0xc20 >> 5));
+ WRITE_VREG(POWER_CTL_VLD, (1 << 10) | /* disable cabac_step_2 */
+ (1 << 9) | /* viff_drop_flag_en */
+ (1 << 6)); /* h264_000003_en */
+ WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */
+
+ WRITE_VREG(CANVAS_START, AMVDEC_H264_4K2K_CANVAS_INDEX);
+ /* Start Address of Workspace (UCODE, temp_data...) */
+ WRITE_VREG(WORKSPACE_START,
+ video_domain_addr(work_space_adr));
+ /* Clear all sequence parameter set available */
+ WRITE_VREG(SPS_STATUS, 0);
+ /* Clear all picture parameter set available */
+ WRITE_VREG(PPS_STATUS, 0);
+ /* Set current microcode to NULL */
+ WRITE_VREG(CURRENT_UCODE, 0xff);
+ /* Set current SPS/PPS to NULL */
+ WRITE_VREG(CURRENT_SPS_PPS, 0xffff);
+ /* Set decode status to DECODE_START_HEADER */
+ WRITE_VREG(DECODE_STATUS, 1);
+}
+
+static void H264_DECODE2_INIT(void)
+{
+ int i;
+
+ WRITE_VREG(VDEC2_GCLK_EN, 0x3ff);
+
+ WRITE_VREG(DOS_SW_RESET2, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET2, 0);
+
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+
+ WRITE_VREG(DOS_SW_RESET2, (1 << 7) | (1 << 6) | (1 << 4));
+ WRITE_VREG(DOS_SW_RESET2, 0);
+
+ WRITE_VREG(DOS_SW_RESET2, (1 << 9) | (1 << 8));
+ WRITE_VREG(DOS_SW_RESET2, 0);
+
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+
+ /* fill_weight_pred */
+ WRITE_VREG(VDEC2_MC_MPORT_CTRL, 0x0300);
+ for (i = 0; i < 192; i++)
+ WRITE_VREG(VDEC2_MC_MPORT_DAT, 0x100);
+ WRITE_VREG(VDEC2_MC_MPORT_CTRL, 0);
+
+ WRITE_VREG(VDEC2_MB_WIDTH, 0xff); /* invalid mb_width */
+
+ /* set slice start to 0x000000 or 0x000001 for check more_rbsp_data */
+ WRITE_VREG(VDEC2_SLICE_START_BYTE_01, 0x00000000);
+ WRITE_VREG(VDEC2_SLICE_START_BYTE_23, 0x01010000);
+ /* set to mpeg2 to enable mismatch logic */
+ WRITE_VREG(VDEC2_MPEG1_2_REG, 1);
+ /* disable COEF_GT_64 , error_m4_table and voff_rw_err */
+ WRITE_VREG(VDEC2_VLD_ERROR_MASK,
+ 0x1011);
+
+ /* Config MCPU Amrisc interrupt */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT0, 0x1);/* viu_vsync_int */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT1, 0x5);/* mbox_isr */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT2, 0x8);/* vld_isr */
+ /* WRITE_VREG(VDEC2_ASSIST_AMR1_INT3, 0x15); // vififo_empty */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT4, 0xd);/* rv_ai_mb_finished_int */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT7, 0x14);/* dcac_dma_done */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT8, 0x15);/* vififo_empty */
+
+ /* Config MCPU Amrisc interrupt */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT5, 0x9);/* MCPU interrupt */
+ WRITE_VREG(VDEC2_ASSIST_AMR1_INT6, 0x17);/* CCPU interrupt */
+
+ WRITE_VREG(VDEC2_CPC_P, 0xc00); /* CCPU Code will start from 0xc00 */
+ WRITE_VREG(VDEC2_CINT_VEC_BASE, (0xc20 >> 5));
+ WRITE_VREG(VDEC2_POWER_CTL_VLD, (1 << 10) |/* disable cabac_step_2 */
+ (1 << 9) | /* viff_drop_flag_en */
+ (1 << 6)); /* h264_000003_en */
+ /* H264_DECODE_INFO - h264_en */
+ WRITE_VREG(VDEC2_M4_CONTROL_REG, (1 << 13));
+
+ WRITE_VREG(VDEC2_CANVAS_START, AMVDEC_H264_4K2K_CANVAS_INDEX);
+ /* Start Address of Workspace (UCODE, temp_data...) */
+ WRITE_VREG(VDEC2_WORKSPACE_START,
+ video_domain_addr(work_space_adr));
+ /* Clear all sequence parameter set available */
+ WRITE_VREG(VDEC2_SPS_STATUS, 0);
+ /* Clear all picture parameter set available */
+ WRITE_VREG(VDEC2_PPS_STATUS, 0);
+ /* Set current microcode to NULL */
+ WRITE_VREG(VDEC2_CURRENT_UCODE, 0xff);
+ /* Set current SPS/PPS to NULL */
+ WRITE_VREG(VDEC2_CURRENT_SPS_PPS, 0xffff);
+ /* Set decode status to DECODE_START_HEADER */
+ WRITE_VREG(VDEC2_DECODE_STATUS, 1);
+}
+
+static void vh264_4k2k_prot_init(void)
+{
+ /* clear mailbox interrupt */
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_ASSIST_MBOX0_CLR_REG, 1);
+#endif
+ WRITE_VREG(VDEC_ASSIST_MBOX1_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_ASSIST_MBOX0_MASK, 1);
+#endif
+ WRITE_VREG(VDEC_ASSIST_MBOX1_MASK, 1);
+
+ /* disable PSCALE for hardware sharing */
+ WRITE_VREG(PSCALE_CTRL, 0);
+
+ H264_DECODE_INIT();
+ if (!H264_4K2K_SINGLE_CORE)
+ H264_DECODE2_INIT();
+
+ WRITE_VREG(DOS_SW_RESET0, (1 << 11));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+ READ_VREG(DOS_SW_RESET0);
+
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(DOS_SW_RESET2, (1 << 11));
+ WRITE_VREG(DOS_SW_RESET2, 0);
+
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+ READ_VREG(DOS_SW_RESET2);
+ }
+
+ WRITE_VREG(MAILBOX_COMMAND, 0);
+ WRITE_VREG(BUFFER_RECYCLE, 0);
+
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(VDEC2_MAILBOX_COMMAND, 0);
+ WRITE_VREG(VDEC2_BUFFER_RECYCLE, 0);
+ }
+
+ CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
+ if (!H264_4K2K_SINGLE_CORE)
+ CLEAR_VREG_MASK(VDEC2_MDEC_PIC_DC_CTRL, 1 << 17);
+
+ /* set VDEC Master/ID 0 */
+ WRITE_VREG(MS_ID, (1 << 7) | (0 << 0));
+ if (!H264_4K2K_SINGLE_CORE) {
+ /* set VDEC2 Slave/ID 0 */
+ WRITE_VREG(VDEC2_MS_ID, (0 << 7) | (1 << 0));
+ }
+ WRITE_VREG(DECODE_SKIP_PICTURE, 0);
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_DECODE_SKIP_PICTURE, 0);
+
+ WRITE_VREG(PRE_MASTER_UPDATE_TIMES, 0);
+ WRITE_VREG(SLAVE_WAIT_DPB_UPDATE, 0);
+ WRITE_VREG(SLAVE_REF_DPB, 0);
+ WRITE_VREG(SAVE_MVC_ENTENSION_0, 0);
+ WRITE_VREG(SAVE_I_POC, 0);
+ WRITE_VREG(CORE_STATUS_M, 0);
+ WRITE_VREG(CORE_STATUS_S, 0);
+ WRITE_VREG(SAVE_ref_status_view_0, 0);
+ WRITE_VREG(SAVE_ref_status_view_1, 0);
+ WRITE_VREG(ALLOC_INFO_0, 0);
+ WRITE_VREG(ALLOC_INFO_1, 0);
+ WRITE_VREG(FATAL_ERROR, 0);
+
+ SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
+ if (!H264_4K2K_SINGLE_CORE)
+ SET_VREG_MASK(VDEC2_MDEC_PIC_DC_CTRL, 1 << 17);
+
+ WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(VDEC2_MDEC_PIC_DC_THRESH, 0x404038aa);
+ }
+#ifdef DOUBLE_WRITE
+ WRITE_VREG(MDEC_DOUBLEW_CFG0, (0 << 31) | /* half y address */
+ (1 << 30) | /* 0:No Merge 1:Automatic Merge */
+ (0 << 28) |
+
+/* Field Picture, 0x:no skip
+ * 10:top only
+ * 11:bottom only
+ */
+ (0 << 27) | /* Source from, 1:MCW 0:DBLK */
+ (0 << 24) | /* Endian Control for Chroma */
+ (0 << 18) | /* DMA ID */
+ (0 << 12) | /* DMA Burst Number */
+ (0 << 11) | /* DMA Urgent */
+ (0 << 10) | /* 1:Round 0:Truncation */
+ (1 << 9) |
+
+/* Size by vertical, 0:original size
+ * 1: 1/2 shrunken size
+ */
+ (1 << 8) |
+
+/* Size by horizontal, 0:original size
+ * 1: 1/2 shrunken size
+ */
+ (0 << 6) |
+
+/* Pixel sel by vertical, 0x:1/2
+ * 10:up
+ * 11:down
+ */
+ (0 << 4) |
+
+/* Pixel sel by horizontal, 0x:1/2
+ * 10:left
+ * 11:right
+ */
+ (0 << 1) | /* Endian Control for Luma */
+ (1 << 0)); /* Double Write Enable */
+ if (!H264_4K2K_SINGLE_CORE) {
+ WRITE_VREG(VDEC2_MDEC_DOUBLEW_CFG0,
+ (0 << 31) | /* half y address */
+ (1 << 30) |
+
+/* 0:No Merge
+ * 1:Automatic Merge
+ */
+ (0 << 28) |
+
+/* Field Picture, 0x:no skip
+ * 10:top only
+ * 11:bottom only
+ */
+ (0 << 27) | /* Source from, 1:MCW 0:DBLK */
+ (0 << 24) | /* Endian Control for Chroma */
+ (0 << 18) | /* DMA ID */
+ (0 << 12) | /* DMA Burst Number */
+ (0 << 11) | /* DMA Urgent */
+ (0 << 10) | /* 1:Round 0:Truncation */
+ (1 << 9) |
+
+/* Size by vertical,
+ * 0:original size
+ * 1: 1/2 shrunken size
+ */
+ (1 << 8) |
+
+/* Size by horizontal,
+ * 0:original size
+ * 1: 1/2 shrunken size
+ */
+ (0 << 6) |
+
+/* Pixel sel by vertical,
+ * 0x:1/2
+ * 10:up
+ * 11:down
+ */
+ (0 << 4) |
+
+/* Pixel sel by horizontal,
+ * 0x:1/2
+ * 10:left
+ * 11:right
+ */
+ (0 << 1) | /* Endian Control for Luma */
+ (1 << 0)); /* Double Write Enable */
+ }
+#endif
+}
+
+static int vh264_4k2k_local_init(void)
+{
+ int i, size, ret;
+
+#ifdef DEBUG_PTS
+ pts_missed = 0;
+ pts_hit = 0;
+#endif
+ mb_width_old = 0;
+ mb_height_old = 0;
+ saved_resolution = 0;
+ vh264_4k2k_rotation =
+ (((unsigned long) vh264_4k2k_amstream_dec_info.param) >> 16)
+ & 0xffff;
+ frame_width = vh264_4k2k_amstream_dec_info.width;
+ frame_height = vh264_4k2k_amstream_dec_info.height;
+ frame_dur =
+ (vh264_4k2k_amstream_dec_info.rate ==
+ 0) ? 3600 : vh264_4k2k_amstream_dec_info.rate;
+ if (frame_width && frame_height)
+ frame_ar = frame_height * 0x100 / frame_width;
+ sync_outside = ((unsigned long) vh264_4k2k_amstream_dec_info.param
+ & 0x02) >> 1;
+ error_watchdog_count = 0;
+
+ pr_info("H264_4K2K: decinfo: %dx%d rate=%d\n",
+ frame_width, frame_height,
+ frame_dur);
+
+ if (frame_dur == 0)
+ frame_dur = 96000 / 24;
+
+ INIT_KFIFO(display_q);
+ INIT_KFIFO(recycle_q);
+ INIT_KFIFO(newframe_q);
+
+ for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
+ vfbuf_use[i] = 0;
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ const struct vframe_s *vf = &vfpool[i];
+
+ vfpool[i].index = DECODE_BUFFER_NUM_MAX;
+ kfifo_put(&newframe_q, vf);
+ }
+
+ reserved_buffer = 0;
+ p_last_vf = NULL;
+ first_i_received = 0;
+ INIT_WORK(&alloc_work, do_alloc_work);
+
+ if (mm_blk_handle) {
+ decoder_bmmu_box_free(mm_blk_handle);
+ mm_blk_handle = NULL;
+ }
+
+ mm_blk_handle = decoder_bmmu_box_alloc_box(
+ DRIVER_NAME,
+ 0,
+ MAX_BMMU_BUFFER_NUM,
+ 4 + PAGE_SHIFT,
+ CODEC_MM_FLAGS_CMA_CLEAR |
+ CODEC_MM_FLAGS_FOR_VDECODER);
+
+ size = DECODER_WORK_SPACE_SIZE;
+ ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, 0,
+ size, DRIVER_NAME, &work_space_adr);
+ return ret;
+}
+
+static s32 vh264_4k2k_init(void)
+{
+ int ret = -1, size = -1;
+ char *buf = vmalloc(0x1000 * 16);
+
+ if (buf == NULL)
+ return -ENOMEM;
+
+ pr_info("\nvh264_4k2k_init\n");
+
+ init_timer(&recycle_timer);
+
+ stat |= STAT_TIMER_INIT;
+
+ ret = vh264_4k2k_local_init();
+ if (ret < 0) {
+ vfree(buf);
+ return ret;
+ }
+ amvdec_enable();
+
+ /* -- ucode loading (amrisc and swap code) */
+ mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(),
+ MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL);
+ if (!mc_cpu_addr) {
+ amvdec_disable();
+ vfree(buf);
+ pr_err("vh264_4k2k init: Can not allocate mc memory.\n");
+ return -ENOMEM;
+ }
+
+ WRITE_VREG(AV_SCRATCH_L, mc_dma_handle);
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_AV_SCRATCH_L, mc_dma_handle);
+
+ if (H264_4K2K_SINGLE_CORE)
+ size = get_firmware_data(VIDEO_DEC_H264_4k2K_SINGLE, buf);
+ else
+ size = get_firmware_data(VIDEO_DEC_H264_4k2K, buf);
+
+ if (size < 0) {
+ pr_err("get firmware fail.");
+ vfree(buf);
+ return -1;
+ }
+
+ if (H264_4K2K_SINGLE_CORE)
+ ret = amvdec_loadmc_ex(VFORMAT_H264_4K2K, "single_core", buf);
+ else
+ ret = amvdec_loadmc_ex(VFORMAT_H264_4K2K, NULL, buf);
+
+ if (ret < 0) {
+ amvdec_disable();
+ dma_free_coherent(amports_get_dma_device(),
+ MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle);
+ mc_cpu_addr = NULL;
+ pr_err("H264_4K2K: the %s fw loading failed, err: %x\n",
+ tee_enabled() ? "TEE" : "local", ret);
+ return -EBUSY;
+ }
+
+ if (!H264_4K2K_SINGLE_CORE) {
+ amvdec2_enable();
+
+ if (amvdec2_loadmc_ex(VFORMAT_H264_4K2K, NULL, buf) < 0) {
+ amvdec_disable();
+ amvdec2_disable();
+ dma_free_coherent(amports_get_dma_device(),
+ MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle);
+ mc_cpu_addr = NULL;
+ return -EBUSY;
+ }
+ }
+
+ /*header*/
+ memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000);
+
+ /*mmco*/
+ memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000);
+
+ /*slice*/
+ memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000);
+
+ stat |= STAT_MC_LOAD;
+
+ /* enable AMRISC side protocol */
+ vh264_4k2k_prot_init();
+
+ if (vdec_request_irq(VDEC_IRQ_1, vh264_4k2k_isr,
+ "vh264_4k2k-irq", (void *)vh264_4k2k_dec_id)) {
+ pr_info("vh264_4k2k irq register error.\n");
+ amvdec_disable();
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_disable();
+
+ return -ENOENT;
+ }
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
+ if (!H264_4K2K_SINGLE_CORE) {
+ if (vdec_request_irq(VDEC_IRQ_0, vh264_4k2k_vdec2_isr,
+ "vh264_4k2k-vdec2-irq",
+ (void *)vh264_4k2k_dec_id2)) {
+ pr_info("vh264_4k2k irq register error.\n");
+ vdec_free_irq(VDEC_IRQ_1, (void *)vh264_4k2k_dec_id);
+ amvdec_disable();
+ amvdec2_disable();
+ return -ENOENT;
+ }
+ }
+#endif
+
+ stat |= STAT_ISR_REG;
+
+ vf_provider_init(&vh264_4k2k_vf_prov, PROVIDER_NAME,
+ &vh264_4k2k_vf_provider, NULL);
+ vf_reg_provider(&vh264_4k2k_vf_prov);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
+
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)((unsigned long)
+ vh264_4k2k_amstream_dec_info.rate));
+
+ stat |= STAT_VF_HOOK;
+
+ recycle_timer.data = (ulong) (&recycle_timer);
+ recycle_timer.function = vh264_4k2k_put_timer_func;
+ recycle_timer.expires = jiffies + PUT_INTERVAL;
+
+ add_timer(&recycle_timer);
+
+ stat |= STAT_TIMER_ARM;
+
+ amvdec_start();
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_start();
+
+ stat |= STAT_VDEC_RUN;
+
+ ret = vh264_4k2k_vdec_info_init();
+ if (0 != ret)
+ return -ret;
+
+ return 0;
+}
+
+static int vh264_4k2k_stop(void)
+{
+
+ if (stat & STAT_VDEC_RUN) {
+ amvdec_stop();
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_stop();
+ stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (stat & STAT_ISR_REG) {
+ WRITE_VREG(VDEC_ASSIST_MBOX1_MASK, 0);
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_ASSIST_MBOX0_MASK, 0);
+
+ vdec_free_irq(VDEC_IRQ_1, (void *)vh264_4k2k_dec_id);
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
+ if (!H264_4K2K_SINGLE_CORE)
+ vdec_free_irq(VDEC_IRQ_0, (void *)vh264_4k2k_dec_id2);
+#endif
+ stat &= ~STAT_ISR_REG;
+ }
+
+ if (stat & STAT_TIMER_ARM) {
+ del_timer_sync(&recycle_timer);
+ stat &= ~STAT_TIMER_ARM;
+ }
+
+ if (stat & STAT_VF_HOOK) {
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
+
+ vf_unreg_provider(&vh264_4k2k_vf_prov);
+ stat &= ~STAT_VF_HOOK;
+ }
+#ifdef DOUBLE_WRITE
+ WRITE_VREG(MDEC_DOUBLEW_CFG0, 0);
+ if (!H264_4K2K_SINGLE_CORE)
+ WRITE_VREG(VDEC2_MDEC_DOUBLEW_CFG0, 0);
+#endif
+
+ if (stat & STAT_MC_LOAD) {
+ if (mc_cpu_addr != NULL) {
+ dma_free_coherent(amports_get_dma_device(),
+ MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle);
+ mc_cpu_addr = NULL;
+ }
+
+ stat &= ~STAT_MC_LOAD;
+ }
+
+ amvdec_disable();
+ if (!H264_4K2K_SINGLE_CORE)
+ amvdec2_disable();
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+ msleep(100);
+#endif
+ if (mm_blk_handle) {
+ decoder_bmmu_box_free(mm_blk_handle);
+ mm_blk_handle = NULL;
+ }
+
+ return 0;
+}
+
+void vh264_4k_free_cmabuf(void)
+{
+ int i;
+
+ if (atomic_read(&vh264_4k2k_active))
+ return;
+ mutex_lock(&vh264_4k2k_mutex);
+ for (i = 0; i < ARRAY_SIZE(buffer_spec); i++) {
+ if (buffer_spec[i].phy_addr) {
+ codec_mm_free_for_dma(MEM_NAME,
+ buffer_spec[i].phy_addr);
+ buffer_spec[i].phy_addr = 0;
+ buffer_spec[i].alloc_pages = NULL;
+ buffer_spec[i].alloc_count = 0;
+ pr_info("force free CMA buffer %d\n", i);
+ }
+ }
+ mutex_unlock(&vh264_4k2k_mutex);
+}
+
+static int amvdec_h264_4k2k_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+
+ pr_info("amvdec_h264_4k2k probe start.\n");
+
+ mutex_lock(&vh264_4k2k_mutex);
+
+ fatal_error = 0;
+
+ if (pdata == NULL) {
+ pr_info("\namvdec_h264_4k2k memory resource undefined.\n");
+ mutex_unlock(&vh264_4k2k_mutex);
+ return -EFAULT;
+ }
+
+ if (pdata->sys_info)
+ vh264_4k2k_amstream_dec_info = *pdata->sys_info;
+ cma_dev = pdata->cma_dev;
+
+ pr_info(" sysinfo: %dx%d, rate = %d, param = 0x%lx\n",
+ vh264_4k2k_amstream_dec_info.width,
+ vh264_4k2k_amstream_dec_info.height,
+ vh264_4k2k_amstream_dec_info.rate,
+ (unsigned long) vh264_4k2k_amstream_dec_info.param);
+
+ if (!H264_4K2K_SINGLE_CORE) {
+ if (vdec_on(VDEC_2)) { /* ++++ */
+ vdec_poweroff(VDEC_2); /* ++++ */
+ mdelay(10);
+ }
+ vdec_poweron(VDEC_2);
+ }
+
+
+ if (!H264_4K2K_SINGLE_CORE)
+ vdec2_power_mode(1);
+
+ pdata->dec_status = vh264_4k2k_dec_status;
+ if (H264_4K2K_SINGLE_CORE)
+ pdata->set_trickmode = vh264_4k2k_set_trickmode;
+
+ if (vh264_4k2k_init() < 0) {
+ pr_info("\namvdec_h264_4k2k init failed.\n");
+ mutex_unlock(&vh264_4k2k_mutex);
+ kfree(gvs);
+ gvs = NULL;
+
+ return -ENODEV;
+ }
+#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
+ request_vpu_clk_vmod(360000000, VPU_VIU_VD1);
+#endif
+
+ if (probe_callback)
+ probe_callback();
+ /*set the max clk for smooth playing...*/
+ vdec_source_changed(VFORMAT_H264_4K2K,
+ 4096, 2048, 30);
+ INIT_WORK(&set_clk_work, vh264_4k2k_set_clk);
+
+ atomic_set(&vh264_4k2k_active, 1);
+ mutex_unlock(&vh264_4k2k_mutex);
+
+ return 0;
+}
+
+static int amvdec_h264_4k2k_remove(struct platform_device *pdev)
+{
+ cancel_work_sync(&alloc_work);
+ cancel_work_sync(&set_clk_work);
+ mutex_lock(&vh264_4k2k_mutex);
+ atomic_set(&vh264_4k2k_active, 0);
+
+ vh264_4k2k_stop();
+
+ vdec_source_changed(VFORMAT_H264_4K2K, 0, 0, 0);
+
+ if (!H264_4K2K_SINGLE_CORE) {
+ vdec_poweroff(VDEC_2);
+ }
+#ifdef DEBUG_PTS
+ pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+ pts_missed, pts_hit, frame_dur);
+#endif
+
+ if (remove_callback)
+ remove_callback();
+
+ mutex_unlock(&vh264_4k2k_mutex);
+
+ kfree(gvs);
+ gvs = NULL;
+
+ pr_info("amvdec_h264_4k2k_remove\n");
+ return 0;
+}
+
+void vh264_4k2k_register_module_callback(void (*enter_func)(void),
+ void (*remove_func)(void))
+{
+ probe_callback = enter_func;
+ remove_callback = remove_func;
+}
+EXPORT_SYMBOL(vh264_4k2k_register_module_callback);
+
+/****************************************/
+
+static struct platform_driver amvdec_h264_4k2k_driver = {
+ .probe = amvdec_h264_4k2k_probe,
+ .remove = amvdec_h264_4k2k_remove,
+#ifdef CONFIG_PM
+ .suspend = amvdec_suspend,
+ .resume = amvdec_resume,
+#endif
+ .driver = {
+ .name = DRIVER_NAME,
+ }
+};
+
+static struct codec_profile_t amvdec_h264_4k2k_profile = {
+ .name = "h264_4k2k",
+ .profile = ""
+};
+static struct mconfig h264_4k2k_configs[] = {
+ MC_PU32("stat", &stat),
+ MC_PU32("error_recovery_mode", &error_recovery_mode),
+};
+static struct mconfig_node h264_4k2k_node;
+
+static int __init amvdec_h264_4k2k_driver_init_module(void)
+{
+ pr_debug("amvdec_h264_4k2k module init\n");
+
+ if (platform_driver_register(&amvdec_h264_4k2k_driver)) {
+ pr_err("failed to register amvdec_h264_4k2k driver\n");
+ return -ENODEV;
+ }
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXTVBB)
+ vcodec_profile_register(&amvdec_h264_4k2k_profile);
+ INIT_REG_NODE_CONFIGS("media.decoder", &h264_4k2k_node,
+ "h264_4k2k", h264_4k2k_configs, CONFIG_FOR_RW);
+ return 0;
+}
+
+static void __exit amvdec_h264_4k2k_driver_remove_module(void)
+{
+ pr_debug("amvdec_h264_4k2k module remove.\n");
+
+ platform_driver_unregister(&amvdec_h264_4k2k_driver);
+}
+
+/****************************************/
+
+module_param(stat, uint, 0664);
+MODULE_PARM_DESC(stat, "\n amvdec_h264_4k2k stat\n");
+
+module_param(error_recovery_mode, uint, 0664);
+MODULE_PARM_DESC(error_recovery_mode, "\n amvdec_h264 error_recovery_mode\n");
+
+module_init(amvdec_h264_4k2k_driver_init_module);
+module_exit(amvdec_h264_4k2k_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC h264_4k2k Video Decoder Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/h264/vh264_mvc.c b/drivers/frame_provider/decoder/h264/vh264_mvc.c
index 4827e38..0efd1a0 100644
--- a/drivers/frame_provider/decoder/h264/vh264_mvc.c
+++ b/drivers/frame_provider/decoder/h264/vh264_mvc.c
@@ -31,8 +31,11 @@
#include <linux/workqueue.h>
#include <linux/dma-mapping.h>
#include <linux/atomic.h>
+#include <linux/amlogic/tee.h>
+
#include <linux/module.h>
#include <linux/slab.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../stream_input/amports/amports_priv.h"
#include "../utils/vdec.h"
@@ -42,8 +45,8 @@
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
+#include <linux/amlogic/tee.h>
#include "../utils/config_parser.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
#define TIME_TASK_PRINT_ENABLE 0x100
#define PUT_PRINT_ENABLE 0x200
@@ -79,7 +82,7 @@
static void vh264mvc_prot_init(void);
static int vh264mvc_local_init(void);
-static void vh264mvc_put_timer_func(struct timer_list *timer);
+static void vh264mvc_put_timer_func(unsigned long arg);
static const char vh264mvc_dec_id[] = "vh264mvc-dev";
@@ -512,10 +515,10 @@
static struct vframe_s *vh264mvc_vf_get(void *op_arg)
{
+
struct vframe_s *vf;
int view0_buf_id;
int view1_buf_id;
- struct buffer_spec_s *buf_spec_0, *buf_spec_1;
if (get_ptr == fill_ptr)
return NULL;
@@ -527,27 +530,10 @@
if ((view0_buf_id >= 0) && (view1_buf_id >= 0)) {
if (view_mode == 0 || view_mode == 1) {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
-
- buf_spec_0 = (view_mode == 0) ? (&buffer_spec0[view0_buf_id]) :
- (&buffer_spec1[view1_buf_id]);
- vf->canvas0Addr = vf->canvas1Addr = spec2canvas(buf_spec_0);
-
- if (is_support_vdec_canvas()) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->canvas0_config[0].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[0].phy_addr = buf_spec_0->y_addr;
- vf->canvas0_config[0].width = vdec_cav_get_width(buf_spec_0->y_canvas_index);
- vf->canvas0_config[0].height = vdec_cav_get_height(buf_spec_0->y_canvas_index);
- vf->canvas0_config[1].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[1].phy_addr = buf_spec_0->u_addr;
- vf->canvas0_config[1].width = vdec_cav_get_width(buf_spec_0->u_canvas_index);
- vf->canvas0_config[1].height = vdec_cav_get_height(buf_spec_0->u_canvas_index);
- vf->canvas0_config[2].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[2].phy_addr = buf_spec_0->v_addr;
- vf->canvas0_config[2].width = vdec_cav_get_width(buf_spec_0->v_canvas_index);
- vf->canvas0_config[2].height = vdec_cav_get_height(buf_spec_0->v_canvas_index);
- vf->plane_num = 3;
- }
+ vf->canvas0Addr = vf->canvas1Addr =
+ (view_mode ==
+ 0) ? spec2canvas(&buffer_spec0[view0_buf_id]) :
+ spec2canvas(&buffer_spec1[view1_buf_id]);
} else {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_MVC;
@@ -559,50 +545,25 @@
vf->right_eye.start_y = 0;
vf->right_eye.width = vf->width;
vf->right_eye.height = vf->height;
- //vf->trans_fmt = TVIN_TFMT_3D_TB;
+ vf->trans_fmt = TVIN_TFMT_3D_TB;
if (view_mode == 2) {
- buf_spec_0 = &buffer_spec1[view1_buf_id];
- buf_spec_1 = &buffer_spec0[view0_buf_id];
+ vf->canvas0Addr =
+ spec2canvas(&buffer_spec1[
+ view1_buf_id]);
+ vf->canvas1Addr =
+ spec2canvas(&buffer_spec0[
+ view0_buf_id]);
} else {
- buf_spec_0 = &buffer_spec0[view0_buf_id];
- buf_spec_1 = &buffer_spec1[view1_buf_id];
- }
- if (is_support_vdec_canvas()) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->canvas0_config[0].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[0].phy_addr = buf_spec_0->y_addr;
- vf->canvas0_config[0].width = vdec_cav_get_width(buf_spec_0->y_canvas_index);
- vf->canvas0_config[0].height = vdec_cav_get_height(buf_spec_0->y_canvas_index);
- vf->canvas0_config[1].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[1].phy_addr = buf_spec_0->u_addr;
- vf->canvas0_config[1].width = vdec_cav_get_width(buf_spec_0->u_canvas_index);
- vf->canvas0_config[1].height = vdec_cav_get_height(buf_spec_0->u_canvas_index);
- vf->canvas0_config[2].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas0_config[2].phy_addr = buf_spec_0->v_addr;
- vf->canvas0_config[2].width = vdec_cav_get_width(buf_spec_0->v_canvas_index);
- vf->canvas0_config[2].height = vdec_cav_get_height(buf_spec_0->v_canvas_index);
-
- vf->canvas1_config[0].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas1_config[0].phy_addr = buf_spec_1->y_addr;
- vf->canvas1_config[0].width = vdec_cav_get_width(buf_spec_1->y_canvas_index);
- vf->canvas1_config[0].height = vdec_cav_get_height(buf_spec_1->y_canvas_index);
- vf->canvas1_config[1].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas1_config[1].phy_addr = buf_spec_1->u_addr;
- vf->canvas1_config[1].width = vdec_cav_get_width(buf_spec_1->u_canvas_index);
- vf->canvas1_config[1].height = vdec_cav_get_height(buf_spec_1->u_canvas_index);
- vf->canvas1_config[2].block_mode = CANVAS_BLKMODE_32X32;
- vf->canvas1_config[2].phy_addr = buf_spec_1->v_addr;
- vf->canvas1_config[2].width = vdec_cav_get_width(buf_spec_1->v_canvas_index);
- vf->canvas1_config[2].height = vdec_cav_get_height(buf_spec_1->v_canvas_index);
- vf->plane_num = 3;
- } else {
- vf->canvas0Addr = spec2canvas(buf_spec_0);
- vf->canvas1Addr = spec2canvas(buf_spec_1);
+ vf->canvas0Addr =
+ spec2canvas(&buffer_spec0[
+ view0_buf_id]);
+ vf->canvas1Addr =
+ spec2canvas(&buffer_spec1[
+ view1_buf_id]);
}
}
}
-
vf->type_original = vf->type;
if (((vfpool_idx[get_ptr].view0_drop != 0)
|| (vfpool_idx[get_ptr].view1_drop != 0))
@@ -743,23 +704,23 @@
buffer_spec[i].alloc_count = page_count;
buffer_spec[i].y_addr = addr;
buffer_spec[i].y_canvas_index = index;
- config_cav_lut_ex(index, addr,
+ canvas_config(index, addr,
mb_width << 4, mb_height << 4,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
addr += mb_total << 8;
index++;
buffer_spec[i].u_addr = addr;
buffer_spec[i].u_canvas_index = index;
- config_cav_lut_ex(index, addr, mb_width << 3, mb_height << 3,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ canvas_config(index, addr, mb_width << 3, mb_height << 3,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
addr += mb_total << 6;
index++;
buffer_spec[i].v_addr = addr;
buffer_spec[i].v_canvas_index = index;
- config_cav_lut_ex(index, addr, mb_width << 3, mb_height << 3,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ canvas_config(index, addr, mb_width << 3, mb_height << 3,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
index++;
}
@@ -897,10 +858,7 @@
refbuf_size
= ref_size * (max_reference_frame_num + 1) * 2;
- if (is_support_vdec_canvas())
- index = 0;
- else
- index = CANVAS_INDEX_START;
+ index = CANVAS_INDEX_START;
ANC_CANVAS_ADDR = ANC0_CANVAS_ADDR;
ret =
@@ -979,10 +937,7 @@
max_reference_frame_num);
}
- if (is_support_vdec_canvas())
- index = total_dec_frame_buffering[0] * 3;
- else
- index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3;
+ index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3;
ANC_CANVAS_ADDR =
ANC0_CANVAS_ADDR + total_dec_frame_buffering[0];
@@ -1233,8 +1188,10 @@
}
}
-static void vh264mvc_put_timer_func(struct timer_list *timer)
+static void vh264mvc_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
+
int valid_frame = 0;
mvc_set_rp();
@@ -1423,10 +1380,7 @@
#endif
WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */
- if (is_support_vdec_canvas())
- WRITE_VREG(CANVAS_START, 0);
- else
- WRITE_VREG(CANVAS_START, CANVAS_INDEX_START);
+ WRITE_VREG(CANVAS_START, CANVAS_INDEX_START);
#if 1
/* Start Address of Workspace (UCODE, temp_data...) */
WRITE_VREG(WORKSPACE_START,
@@ -1481,9 +1435,6 @@
WRITE_VREG(BUFFER_RECYCLE, 0);
WRITE_VREG(DROP_CONTROL, 0);
CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
#endif
@@ -1529,6 +1480,7 @@
max_dec_frame_buffering[1] = -1;
fill_ptr = get_ptr = put_ptr = putting_ptr = 0;
dirty_frame_num = 0;
+
for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
view0_vfbuf_use[i] = 0;
view1_vfbuf_use[i] = 0;
@@ -1572,12 +1524,11 @@
{
int ret = -1;
char *buf = vmalloc(0x1000 * 16);
-
if (buf == NULL)
return -ENOMEM;
pr_info("\nvh264mvc_init\n");
- timer_setup(&recycle_timer, vh264mvc_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -1667,7 +1618,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong) (&recycle_timer);
+ recycle_timer.function = vh264mvc_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -1834,16 +1788,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int h264mvc_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int h264mvc_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops h264mvc_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(h264mvc_suspend, h264mvc_resume)
+};
+#endif
static struct platform_driver amvdec_h264mvc_driver = {
.probe = amvdec_h264mvc_probe,
.remove = amvdec_h264mvc_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &h264mvc_pm_ops,
+#endif
}
};
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
old mode 100644
new mode 100755
index 52d9611..b583a82
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
@@ -37,19 +37,15 @@
if (((h264_debug_flag & debug_flag) &&
((1 << index) & h264_debug_mask))
|| (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
+ unsigned char buf[512];
int len = 0;
va_list args;
- if (!buf)
- return 0;
-
va_start(args, fmt);
len = sprintf(buf, "%d: ", index);
vsnprintf(buf + len, 512-len, fmt, args);
pr_debug("%s", buf);
va_end(args);
- kfree(buf);
}
return 0;
}
@@ -59,18 +55,13 @@
if (((h264_debug_flag & debug_flag) &&
((1 << index) & h264_debug_mask))
|| (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
+ unsigned char buf[512];
int len = 0;
va_list args;
-
- if (!buf)
- return 0;
-
va_start(args, fmt);
vsnprintf(buf + len, 512-len, fmt, args);
pr_info("%s", buf);
va_end(args);
- kfree(buf);
}
return 0;
}
@@ -421,8 +412,6 @@
pSlice->long_term_reference_flag,
pSlice->no_output_of_prior_pics_flag);
- p_H264_Dpb->long_term_reference_flag = pSlice->long_term_reference_flag;
-
dpb_print(p_H264_Dpb->decoder_index,
PRINT_FLAG_DPB_DETAIL,
"idr set pre_frame_num(%d) to frame_num (%d)\n",
@@ -663,7 +652,7 @@
(pSlice->toppoc < pSlice->bottompoc) ?
pSlice->toppoc : pSlice->bottompoc;
/* POC200301 */
- } else if (pSlice->bottom_field_flag == 0) {
+ } else if (pSlice->bottom_field_flag == FALSE) {
/* top field */
pSlice->ThisPOC = pSlice->toppoc =
pSlice->PicOrderCntMsb +
@@ -781,7 +770,7 @@
(pSlice->toppoc < pSlice->bottompoc) ?
pSlice->toppoc : pSlice->bottompoc;
/* POC200301 */
- } else if (pSlice->bottom_field_flag == 0) {
+ } else if (pSlice->bottom_field_flag == FALSE) {
/* top field */
pSlice->ThisPOC = pSlice->toppoc =
p_Vid->ExpectedPicOrderCnt +
@@ -835,7 +824,7 @@
if (pSlice->field_pic_flag == 0)
pSlice->toppoc = pSlice->bottompoc =
pSlice->framepoc = pSlice->ThisPOC;
- else if (pSlice->bottom_field_flag == 0)
+ else if (pSlice->bottom_field_flag == FALSE)
pSlice->toppoc = pSlice->framepoc =
pSlice->ThisPOC;
else
@@ -1850,35 +1839,6 @@
}
-static void unmark_for_long_term_reference(struct FrameStore *fs)
-{
- if (fs->is_used & 1) {
- if (fs->top_field) {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- }
- }
- if (fs->is_used & 2) {
- if (fs->bottom_field) {
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- }
- if (fs->is_used == 3) {
- if (fs->top_field && fs->bottom_field) {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- fs->frame->used_for_reference = 0;
- fs->frame->is_long_term = 0;
- }
-
- fs->is_reference = 0;
- fs->is_long_term = 0;
-}
-
int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb,
int buf_spec_num)
{
@@ -2093,7 +2053,7 @@
p_Dpb->used_size--;
}
-int is_used_for_reference(struct FrameStore *fs)
+static int is_used_for_reference(struct FrameStore *fs)
{
if (fs->is_reference)
return 1;
@@ -2204,6 +2164,7 @@
struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
int ret = 0;
unsigned char removed_flag = 0;
+
do {
ret = remove_unused_frame_from_dpb(p_H264_Dpb);
if (ret != 0)
@@ -2370,8 +2331,7 @@
"%s first_insert_frame %d \n", __func__, p_H264_Dpb->first_insert_frame);
}
if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) {
- if (!p_H264_Dpb->without_display_mode &&
- p_Dpb->fs[pos]->show_frame != false)
+ if (!p_H264_Dpb->without_display_mode)
p_Dpb->fs[pos]->pre_output = 1;
} else {
if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
@@ -2595,14 +2555,6 @@
if (p->no_output_of_prior_pics_flag) {
- int i;
- for (i = 0; i < p_Dpb->used_size; i++) {
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
- if (p_Dpb->fs[i]->is_long_term)
- unmark_for_long_term_reference(p_Dpb->fs[i]);
- if (!p_Dpb->fs[i]->is_output && !p_Dpb->fs[i]->pre_output)
- set_frame_output_flag(p_H264_Dpb, i);
- }
#if 0
/*???*/
/* free all stored pictures */
@@ -2701,90 +2653,108 @@
void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
{
- unsigned int i;
- unsigned char *buf = NULL;
- unsigned int buf_size = 512, len = 0;
+ unsigned i;
struct h264_dpb_stru *p_H264_Dpb =
container_of(p_Dpb, struct h264_dpb_stru, mDPB);
-
-#define DPB_STRCAT(args...) do { \
- len += snprintf(buf + len, \
- buf_size - len, ##args);\
- } while (0)
-
if ((h264_debug_flag & PRINT_FLAG_DUMP_DPB) == 0 &&
force == 0)
return;
-
- buf = kzalloc(buf_size, GFP_ATOMIC);
- if (buf == NULL)
- return;
-
for (i = 0; i < p_Dpb->used_size; i++) {
- len = 0;
- memset(buf, 0, buf_size);
- DPB_STRCAT("fn=%d is_used %d ",
+ dpb_print(p_H264_Dpb->decoder_index,
+ 0,
+ "(");
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "fn=%d is_used %d ",
p_Dpb->fs[i]->frame_num,
p_Dpb->fs[i]->is_used);
-
if (p_Dpb->fs[i]->is_used & 1) {
if (p_Dpb->fs[i]->top_field)
- DPB_STRCAT("T: poc=%d pic_num=%d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "T: poc=%d pic_num=%d ",
p_Dpb->fs[i]->top_field->poc,
p_Dpb->fs[i]->top_field->pic_num);
else
- DPB_STRCAT("T: poc=%d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "T: poc=%d ",
p_Dpb->fs[i]->frame->top_poc);
}
if (p_Dpb->fs[i]->is_used & 2) {
if (p_Dpb->fs[i]->bottom_field)
- DPB_STRCAT("B: poc=%d pic_num=%d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "B: poc=%d pic_num=%d ",
p_Dpb->fs[i]->bottom_field->poc,
p_Dpb->fs[i]->bottom_field->pic_num);
else
- DPB_STRCAT("B: poc=%d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "B: poc=%d ",
p_Dpb->fs[i]->frame->bottom_poc);
}
if (p_Dpb->fs[i]->is_used == 3) {
if (p_Dpb->fs[i]->frame != NULL)
- DPB_STRCAT("F: poc=%d pic_num=%d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "F: poc=%d pic_num=%d ",
p_Dpb->fs[i]->frame->poc,
p_Dpb->fs[i]->frame->pic_num);
else
- DPB_STRCAT("fs[%d] frame is null ", i);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0, "fs[%d] frame is null ", i);
}
- DPB_STRCAT("G: poc=%d) ", p_Dpb->fs[i]->poc);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "G: poc=%d) ", p_Dpb->fs[i]->poc);
if (p_Dpb->fs[i]->is_reference)
- DPB_STRCAT("ref (%d) ", p_Dpb->fs[i]->is_reference);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "ref (%d) ", p_Dpb->fs[i]->is_reference);
if (p_Dpb->fs[i]->is_long_term)
- DPB_STRCAT("lt_ref (%d) ", p_Dpb->fs[i]->is_reference);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "lt_ref (%d) ", p_Dpb->fs[i]->is_reference);
if (p_Dpb->fs[i]->is_output)
- DPB_STRCAT("out(displayed) ");
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "out(displayed) ");
if (p_Dpb->fs[i]->pre_output)
- DPB_STRCAT("pre_output(in dispq or displaying) ");
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "pre_output(in dispq or displaying) ");
if (p_Dpb->fs[i]->is_used == 3) {
if (p_Dpb->fs[i]->frame != NULL && p_Dpb->fs[i]->frame->non_existing)
- DPB_STRCAT("non_existing ");
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "non_existing ");
else
- DPB_STRCAT("fs[%d] frame is null ", i);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0, "fs[%d] frame is null ", i);
}
- DPB_STRCAT("dpb_frame_count %d ",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "dpb_frame_count %d ",
p_Dpb->fs[i]->dpb_frame_count);
#if (MVC_EXTENSION_ENABLE)
if (p_Dpb->fs[i]->is_reference)
- DPB_STRCAT("view_id (%d) ", p_Dpb->fs[i]->view_id);
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "view_id (%d) ", p_Dpb->fs[i]->view_id);
#endif
if (p_Dpb->fs[i]->data_flag) {
- DPB_STRCAT("data_flag(0x%x)",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ "data_flag(0x%x)",
p_Dpb->fs[i]->data_flag);
}
- DPB_STRCAT(" bufspec %d\n",
+ dpb_print_cont(p_H264_Dpb->decoder_index,
+ 0,
+ " bufspec %d\n",
p_Dpb->fs[i]->buf_spec_num);
- dpb_print(p_H264_Dpb->decoder_index, 0, "%s", buf);
}
-
- kfree(buf);
}
/*!
@@ -2902,6 +2872,35 @@
}
}
+static void unmark_for_long_term_reference(struct FrameStore *fs)
+{
+ if (fs->is_used & 1) {
+ if (fs->top_field) {
+ fs->top_field->used_for_reference = 0;
+ fs->top_field->is_long_term = 0;
+ }
+ }
+ if (fs->is_used & 2) {
+ if (fs->bottom_field) {
+ fs->bottom_field->used_for_reference = 0;
+ fs->bottom_field->is_long_term = 0;
+ }
+ }
+ if (fs->is_used == 3) {
+ if (fs->top_field && fs->bottom_field) {
+ fs->top_field->used_for_reference = 0;
+ fs->top_field->is_long_term = 0;
+ fs->bottom_field->used_for_reference = 0;
+ fs->bottom_field->is_long_term = 0;
+ }
+ fs->frame->used_for_reference = 0;
+ fs->frame->is_long_term = 0;
+ }
+
+ fs->is_reference = 0;
+ fs->is_long_term = 0;
+}
+
/*!
************************************************************************
* \brief
@@ -3688,7 +3687,8 @@
else
i = 0;
- if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)) {
+ if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE) ||
+ ((p_Dpb->size - frame_outside_count) == p_H264_Dpb->dec_dpb_size)) {
while (output_frames(p_H264_Dpb, i))
;
}
@@ -5066,7 +5066,7 @@
}
dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s: RefPicListX[ %d ] = pic %x (%d)\n", __func__,
+ "%s: RefPicListX[ %d ] = pic %px (%d)\n", __func__,
*refIdxLX, picLX, picNumLX);
RefPicListX[(*refIdxLX)++] = picLX;
@@ -5501,7 +5501,7 @@
p_old_slice->pps_id = INT_MAX;
p_old_slice->frame_num = INT_MAX;
p_old_slice->nal_ref_idc = INT_MAX;
- p_old_slice->idr_flag = 0;
+ p_old_slice->idr_flag = FALSE;
p_old_slice->pic_oder_cnt_lsb = UINT_MAX;
p_old_slice->delta_pic_oder_cnt_bottom = INT_MAX;
@@ -5836,7 +5836,11 @@
* p_Vid->height_cr,
*/
1);
- if (p_H264_Dpb->mVideo.dec_picture) {
+ if (!p_H264_Dpb->mVideo.dec_picture) {
+ dpb_print(p_H264_Dpb->decoder_index,
+ PRINT_FLAG_DPB_DETAIL, "p_H264_Dpb->decoder_index is null\n");
+ return -1;
+ } else {
u32 offset_lo, offset_hi;
struct DecodedPictureBuffer *p_Dpb =
&p_H264_Dpb->mDPB;
@@ -5888,13 +5892,12 @@
}
}
#endif
- if (post_picture_early(p_H264_Dpb->vdec,
- p_H264_Dpb->mVideo.dec_picture->buf_spec_num))
- return -1;
}
}
-
+ if (post_picture_early(p_H264_Dpb->vdec,
+ p_H264_Dpb->mVideo.dec_picture->buf_spec_num))
+ return -1;
if (p_H264_Dpb->mSlice.slice_type == P_SLICE)
init_lists_p_slice(&p_H264_Dpb->mSlice);
@@ -5946,15 +5949,8 @@
/*int j;*/
struct Slice *currSlice = &p_H264_Dpb->mSlice;
/* in first output, ignore ref check */
- if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) &&
- (p_H264_Dpb->mVideo.dec_picture) &&
- p_H264_Dpb->first_output_poc > p_H264_Dpb->mVideo.dec_picture->poc) {
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "p_H264_Dpb->first_output_poc %d, p_H264_Dpb->mVideo.dec_picture->poc %d\n",
- p_H264_Dpb->first_output_poc, p_H264_Dpb->mVideo.dec_picture->poc);
+ if (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)
return 0;
- }
if ((currSlice->slice_type != I_SLICE) &&
(currSlice->slice_type != SI_SLICE)) {
for (i = 0; i < currSlice->listXsize[0]; i++) {
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
old mode 100644
new mode 100755
index 8b3e8bb..8f90961
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
@@ -39,7 +39,6 @@
#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800
#define PRINT_FLAG_DUMP_BUFSPEC 0x1000
#define PRINT_FLAG_FCC_STATUS 0x2000
-#define PRINT_FLAG_SEI_DETAIL 0x4000
#define PRINT_FLAG_V4L_DETAIL 0x8000
#define DISABLE_ERROR_HANDLE 0x10000
#define DEBUG_DUMP_STAT 0x80000
@@ -65,7 +64,7 @@
#define H264_OUTPUT_MODE_NORMAL 0x4
#define H264_OUTPUT_MODE_FAST 0x8
-//#define FALSE 0
+#define FALSE 0
#define H264_SLICE_HEAD_DONE 0x01
#define H264_PIC_DATA_DONE 0x02
@@ -824,7 +823,7 @@
u32 hw_decode_time;
u32 frame_size2; // For recording the chunk->size in frame mode
bool show_frame;
- struct dma_fence *fence;
+ struct fence *fence;
u32 decoded_frame_size;
};
@@ -926,7 +925,6 @@
int first_output_poc;
int dpb_frame_count;
u32 without_display_mode;
- int long_term_reference_flag;
};
@@ -1000,6 +998,4 @@
int post_picture_early(struct vdec_s *vdec, int index);
-int is_used_for_reference(struct FrameStore *fs);
-
#endif
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
old mode 100644
new mode 100755
index 5932c91..04ac980
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -23,6 +23,7 @@
#include <linux/kfifo.h>
#include <linux/platform_device.h>
#include <linux/random.h>
+
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/canvas/canvas.h>
@@ -40,10 +41,10 @@
#include <linux/dma-contiguous.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
#include "../utils/vdec_input.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../utils/vdec.h"
#include "../utils/amvdec.h"
@@ -54,14 +55,13 @@
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
#include "../utils/firmware.h"
+#include <linux/amlogic/tee.h>
#include <linux/uaccess.h>
#include "../utils/config_parser.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../utils/vdec_v4l2_buffer_ops.h"
#include <linux/crc32.h>
#include <media/v4l2-mem2mem.h>
-#include "../utils/vdec_feature.h"
-
#define DETECT_WRONG_MULTI_SLICE
@@ -118,9 +118,6 @@
#define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96)
#define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2
-#define ALIGN_WIDTH(x) (ALIGN((x), 64))
-#define ALIGN_HEIGHT(x) (ALIGN((x), 32))
-
#define H264_DEV_NUM 9
#define CONSTRAIN_MAX_BUF_NUM
@@ -129,6 +126,7 @@
#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
#define INVALID_IDX -1 /* Invalid buffer index.*/
+
static int mmu_enable;
/*mmu do not support mbaff*/
static int force_enable_mmu = 0;
@@ -155,8 +153,6 @@
static int pre_decode_buf_level = 0x1000;
static int stream_mode_start_num = 4;
static int dirty_again_threshold = 100;
-static unsigned int colocate_old_cal;
-
static int check_dirty_data(struct vdec_s *vdec);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
@@ -290,7 +286,6 @@
bit[20] 1: fixed some error stream will lead to the diffusion of the error, resulting playback stuck.
bit[21] 1: fixed DVB loop playback cause jetter issue.
bit[22] 1: In streaming mode, support for discarding data.
- bit[23] 0: set error flag on frame number gap error and drop it, 1: ignore error.
*/
static unsigned int error_proc_policy = 0x7fCfb6; /*0x1f14*/
@@ -562,6 +557,7 @@
#define DEC_RESULT_EOS 7
#define DEC_RESULT_FORCE_EXIT 8
#define DEC_RESULT_TIMEOUT 9
+#define DEC_RESULT_DISCARD_DATA 10
/*
@@ -614,7 +610,6 @@
NAL_SEARCH_CTL: bit 0, enable itu_t35
NAL_SEARCH_CTL: bit 1, enable mmu
NAL_SEARCH_CTL: bit 2, detect frame_mbs_only_flag whether switch resolution
- NAL_SEARCH_CTL: bit 15,bitstream_restriction_flag
*/
#define NAL_SEARCH_CTL AV_SCRATCH_9
#define MBY_MBX MB_MOTION_MODE /*0xc07*/
@@ -626,6 +621,8 @@
#define DECODE_MODE_MULTI_DVENL 0x4
static DEFINE_MUTEX(vmh264_mutex);
+
+
#ifdef MH264_USERDATA_ENABLE
struct mh264_userdata_record_t {
@@ -654,11 +651,6 @@
#endif
-struct mh264_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
struct vdec_h264_hw_s {
spinlock_t lock;
spinlock_t bufspec_lock;
@@ -829,8 +821,8 @@
/**/
unsigned int last_frame_time;
u32 vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
+ u32 vf_get_count;
+ u32 vf_put_count;
/* timeout handle */
unsigned long int start_process_time;
@@ -938,7 +930,6 @@
bool enable_fence;
int fence_usage;
bool discard_dv_data;
- u32 metadata_config_flag;
int vdec_pg_enable_flag;
u32 save_reg_f;
u32 start_bit_cnt;
@@ -946,14 +937,11 @@
u32 wrong_frame_count;
u32 error_frame_width;
u32 error_frame_height;
- ulong fb_token;
+ char vdec_name[32];
+ char pts_name[32];
+ char new_q_name[32];
+ char disp_q_name[32];
int dec_again_cnt;
- struct mh264_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- u32 no_decoder_buffer_flag;
- u32 video_signal_type;
- struct trace_decoder_name trace;
- int csd_change_flag;
};
static u32 again_threshold;
@@ -1007,15 +995,11 @@
static u32 mem_map_mode = H265_MEM_MAP_MODE;
#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
static int is_oversize(int w, int h)
{
int max = MAX_SIZE_4K;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
if (w < 0 || h < 0)
return true;
@@ -1109,6 +1093,19 @@
return hsize;
}
+static int get_double_write_ratio(struct vdec_h264_hw_s *hw)
+{
+ int ratio = 1;
+ int dw_mode = hw->double_write_mode;
+ if ((dw_mode == 2) ||
+ (dw_mode == 3))
+ ratio = 4;
+ else if (dw_mode == 4)
+ ratio = 2;
+ return ratio;
+}
+
+
static int get_dw_size(struct vdec_h264_hw_s *hw, u32 *pdw_buffer_size_u_v_h)
{
int pic_width, pic_height;
@@ -1123,9 +1120,9 @@
if (dw_mode) {
int pic_width_dw = pic_width /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
int pic_height_dw = pic_height /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
pic_width_dw / lcu_size + 1 :
@@ -1160,7 +1157,6 @@
u32 dw_buffer_size_u_v_h;
u32 blkmode = hw->canvas_mode;
int dw_mode = hw->double_write_mode;
- struct vdec_s *vdec = hw_to_vdec(hw);
canvas_addr = ANC0_CANVAS_ADDR;
for (i = 0; i < num_buff; i++)
@@ -1195,11 +1191,6 @@
DRIVER_HEADER_NAME, i);
return;
}
- if (hw->enable_fence) {
- vdec_fence_buffer_count_increase((ulong)vdec->sync);
- INIT_LIST_HEAD(&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)].node);
- decoder_bmmu_box_add_callback_func(hw->bmmu_box, HEADER_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[i]);
- }
} else
maddr = hw->buffer_spec[i].alloc_header_addr;
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, maddr >> 5);
@@ -1214,9 +1205,9 @@
int canvas_h;
canvas_w = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
canvas_h = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
if (hw->canvas_mode == 0)
canvas_w = ALIGN(canvas_w, 32);
@@ -1383,9 +1374,7 @@
u32 mc_buffer_size_u_v_h;
int dw_mode = hw->double_write_mode;
- /*lcu_x_num = (width + 15) >> 4;*/
- // width need to be round to 64 pixel -- case0260 1/10/2020
- lcu_x_num = (((width + 63) >> 6) << 2);
+ lcu_x_num = (width + 15) >> 4;
lcu_y_num = (height + 15) >> 4;
lcu_total = lcu_x_num * lcu_y_num;
@@ -1434,7 +1423,7 @@
/* ipp_enable*/
WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1 << 1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(HEVC_DBLK_CFG1, 0x2); // set ctusize==16
WRITE_VREG(HEVC_DBLK_CFG2, ((height & 0xffff)<<16) | (width & 0xffff));
if (dw_mode & 0x10)
@@ -1602,7 +1591,7 @@
}
/*Reset SAO + Enable SAO slice_start*/
- if (hw->mmu_enable && get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ if (hw->mmu_enable && get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A)
WRITE_VREG(HEVC_DBLK_CFG0, 0x1); // reset buffer32x4 in lpf for every picture
WRITE_VREG(HEVC_SAO_INT_STATUS,
READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 28);
@@ -1611,7 +1600,7 @@
/*pr_info("hevc_sao_set_pic_buffer:mc_y_adr: %x\n", mc_y_adr);*/
/*Send coommand to hevc-code to supply 4k buffers to sao*/
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
+ if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(H265_SAO_4K_SET_BASE, (u32)hw->frame_mmu_map_phy_addr);
WRITE_VREG(H265_SAO_4K_SET_COUNT, MAX_FRAME_4K_NUM);
} else
@@ -1686,7 +1675,7 @@
}
timeout = jiffies + HZ;
if ((hw->frame_busy == 1) && (hw->frame_done == 1) ) {
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
+ if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET);
while ((READ_VREG(SYS_COMMAND) & 0xff) !=
H265_ABORT_SAO_4K_SET_DONE) {
@@ -1736,8 +1725,7 @@
vf->index = -1;
}
}
- /* buffers are alloced when error reset, v4l must find buffer by buffer_wrap[] */
- if (hw->reset_bufmgr_flag && buffer_reset_flag) {
+ if (buffer_reset_flag) {
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
if (hw->buffer_spec[i].used == 1 || hw->buffer_spec[i].used == 2)
hw->buffer_spec[i].used = 0;
@@ -1756,7 +1744,6 @@
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
}
-
/*is active in buf management */
static unsigned char is_buf_spec_in_use(struct vdec_h264_hw_s *hw,
int buf_spec_num)
@@ -1800,142 +1787,137 @@
buf_size += (hw->mb_total << 7) + (hw->mb_total << 6);
else if (IS_VDEC_DW(hw) == 2)
buf_size += (hw->mb_total << 6) + (hw->mb_total << 5);
- else if (IS_VDEC_DW(hw) == 4)
- buf_size += (hw->mb_total << 4) + (hw->mb_total << 3);
- else if (IS_VDEC_DW(hw) == 8)
- buf_size += (hw->mb_total << 2) + (hw->mb_total << 1);
- if (IS_VDEC_DW(hw)) {
- u32 align_size;
- /* add align padding size for blk64x32: (mb_w<<4)*32, (mb_h<<4)*64 */
- align_size = ((hw->mb_width << 9) + (hw->mb_height << 10)) / IS_VDEC_DW(hw);
- /* double align padding size for uv*/
- align_size <<= 1;
- buf_size += align_size + PAGE_SIZE;
- }
#endif
if (hw->buffer_spec[i].cma_alloc_addr)
return 0;
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i,
- PAGE_ALIGN(buf_size), DRIVER_NAME,
- &hw->buffer_spec[i].cma_alloc_addr) < 0) {
- hw->buffer_spec[i].cma_alloc_addr = 0;
- if (hw->no_mem_count++ > 3) {
- hw->stat |= DECODER_FATAL_ERROR_NO_MEM;
- hw->reset_bufmgr_flag = 1;
- }
- dpb_print(DECODE_ID(hw), 0,
- "%s, fail to alloc buf for bufspec%d, try later\n",
- __func__, i
- );
- return -1;
- } else {
- if (hw->enable_fence) {
- vdec_fence_buffer_count_increase((ulong)vdec->sync);
- INIT_LIST_HEAD(&vdec->sync->release_callback[i].node);
- decoder_bmmu_box_add_callback_func(hw->bmmu_box, i, (void *)&vdec->sync->release_callback[i]);
- }
- hw->no_mem_count = 0;
- hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM;
+ if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i,
+ PAGE_ALIGN(buf_size), DRIVER_NAME,
+ &hw->buffer_spec[i].cma_alloc_addr) < 0) {
+ hw->buffer_spec[i].cma_alloc_addr = 0;
+ if (hw->no_mem_count++ > 3) {
+ hw->stat |= DECODER_FATAL_ERROR_NO_MEM;
+ hw->reset_bufmgr_flag = 1;
}
- if (!vdec_secure(vdec)) {
- /*init internal buf*/
- char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr);
+ dpb_print(DECODE_ID(hw), 0,
+ "%s, fail to alloc buf for bufspec%d, try later\n",
+ __func__, i
+ );
+ return -1;
+ } else {
+ hw->no_mem_count = 0;
+ hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM;
+ }
+ if (!vdec_secure(vdec)) {
+ /*init internal buf*/
+ char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr);
+ if (tmpbuf) {
+ memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
+ codec_mm_dma_flush(tmpbuf,
+ PAGE_ALIGN(buf_size),
+ DMA_TO_DEVICE);
+ } else {
+ tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size));
if (tmpbuf) {
memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
codec_mm_dma_flush(tmpbuf,
PAGE_ALIGN(buf_size),
DMA_TO_DEVICE);
- } else {
- tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size));
- if (tmpbuf) {
- memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
- codec_mm_dma_flush(tmpbuf,
- PAGE_ALIGN(buf_size),
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(tmpbuf);
- }
+ codec_mm_unmap_phyaddr(tmpbuf);
}
}
- hw->buffer_spec[i].buf_adr =
- hw->buffer_spec[i].cma_alloc_addr;
- addr = hw->buffer_spec[i].buf_adr;
+ }
+ hw->buffer_spec[i].buf_adr =
+ hw->buffer_spec[i].cma_alloc_addr;
+ addr = hw->buffer_spec[i].buf_adr;
- hw->buffer_spec[i].y_addr = addr;
- addr += hw->mb_total << 8;
- hw->buffer_spec[i].u_addr = addr;
- hw->buffer_spec[i].v_addr = addr;
- addr += hw->mb_total << 7;
+ hw->buffer_spec[i].y_addr = addr;
+ addr += hw->mb_total << 8;
+ hw->buffer_spec[i].u_addr = addr;
+ hw->buffer_spec[i].v_addr = addr;
+ addr += hw->mb_total << 7;
- hw->buffer_spec[i].canvas_config[0].phy_addr =
- hw->buffer_spec[i].y_addr;
- hw->buffer_spec[i].canvas_config[0].width =
+ hw->buffer_spec[i].canvas_config[0].phy_addr =
+ hw->buffer_spec[i].y_addr;
+ hw->buffer_spec[i].canvas_config[0].width =
+ hw->mb_width << 4;
+ hw->buffer_spec[i].canvas_config[0].height =
+ hw->mb_height << 4;
+ hw->buffer_spec[i].canvas_config[0].block_mode =
+ hw->canvas_mode;
+
+ hw->buffer_spec[i].canvas_config[1].phy_addr =
+ hw->buffer_spec[i].u_addr;
+ hw->buffer_spec[i].canvas_config[1].width =
hw->mb_width << 4;
- hw->buffer_spec[i].canvas_config[0].height =
- hw->mb_height << 4;
- hw->buffer_spec[i].canvas_config[0].block_mode =
+ hw->buffer_spec[i].canvas_config[1].height =
+ hw->mb_height << 3;
+ hw->buffer_spec[i].canvas_config[1].block_mode =
hw->canvas_mode;
-
- hw->buffer_spec[i].canvas_config[1].phy_addr =
- hw->buffer_spec[i].u_addr;
- hw->buffer_spec[i].canvas_config[1].width =
- hw->mb_width << 4;
- hw->buffer_spec[i].canvas_config[1].height =
- hw->mb_height << 3;
- hw->buffer_spec[i].canvas_config[1].block_mode =
- hw->canvas_mode;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, alloc buf for bufspec%d\n",
- __func__, i);
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "%s, alloc buf for bufspec%d\n",
+ __func__, i
+ );
#ifdef VDEC_DW
- if (!IS_VDEC_DW(hw))
- return 0;
- else {
- int w_shift = 3, h_shift = 3;
- if (IS_VDEC_DW(hw) == 1) {
- w_shift = 3;
- h_shift = 4;
- } else if (IS_VDEC_DW(hw) == 2) {
- w_shift = 3;
- h_shift = 3;
- } else if (IS_VDEC_DW(hw) == 4) {
- w_shift = 2;
- h_shift = 2;
- } else if (IS_VDEC_DW(hw) == 8) {
- w_shift = 1;
- h_shift = 1;
- }
+ if (!IS_VDEC_DW(hw))
+ return 0;
+ else if (IS_VDEC_DW(hw) == 1) {
+ addr = hw->buffer_spec[i].cma_alloc_addr + orig_buf_size;
+ hw->buffer_spec[i].vdec_dw_y_addr = addr;
+ addr += hw->mb_total << 7;
+ hw->buffer_spec[i].vdec_dw_u_addr = addr;
+ hw->buffer_spec[i].vdec_dw_v_addr = addr;
+ addr += hw->mb_total << 6;
- addr = hw->buffer_spec[i].cma_alloc_addr + PAGE_ALIGN(orig_buf_size);
- hw->buffer_spec[i].vdec_dw_y_addr = addr;
- addr += ALIGN_WIDTH(hw->mb_width << w_shift) * ALIGN_HEIGHT(hw->mb_height << h_shift);
- hw->buffer_spec[i].vdec_dw_u_addr = addr;
- hw->buffer_spec[i].vdec_dw_v_addr = addr;
- addr += hw->mb_total << (w_shift + h_shift - 1);
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr =
+ hw->buffer_spec[i].vdec_dw_y_addr;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].width =
+ hw->mb_width << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].height =
+ hw->mb_height << 4;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode =
+ CANVAS_BLKMODE_32X32;
- hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr =
- hw->buffer_spec[i].vdec_dw_y_addr;
- hw->buffer_spec[i].vdec_dw_canvas_config[0].width =
- ALIGN_WIDTH(hw->mb_width << w_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[0].height =
- ALIGN_HEIGHT(hw->mb_height << h_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode =
- hw->canvas_mode;
-
- hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr =
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr =
hw->buffer_spec[i].vdec_dw_u_addr;
- hw->buffer_spec[i].vdec_dw_canvas_config[1].width =
- ALIGN_WIDTH(hw->mb_width << w_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[1].height =
- ALIGN_HEIGHT(hw->mb_height << (h_shift - 1));
- hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode =
- hw->canvas_mode;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, vdec_dw: alloc buf for bufspec%d blkmod %d\n",
- __func__, i, hw->canvas_mode);
- }
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].width =
+ hw->mb_width << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].height =
+ hw->mb_height << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode =
+ CANVAS_BLKMODE_32X32;
+ }else {
+ addr = hw->buffer_spec[i].cma_alloc_addr + orig_buf_size;
+ hw->buffer_spec[i].vdec_dw_y_addr = addr;
+ addr += hw->mb_total << 6;
+ hw->buffer_spec[i].vdec_dw_u_addr = addr;
+ hw->buffer_spec[i].vdec_dw_v_addr = addr;
+ addr += hw->mb_total << 5;
+
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr =
+ hw->buffer_spec[i].vdec_dw_y_addr;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].width =
+ hw->mb_width << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].height =
+ hw->mb_height << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode =
+ CANVAS_BLKMODE_32X32;
+
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr =
+ hw->buffer_spec[i].vdec_dw_u_addr;
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].width =
+ hw->mb_width << 3;
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].height =
+ hw->mb_height << 2;
+ hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode =
+ CANVAS_BLKMODE_32X32;
+ }
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "%s, vdec_dw: alloc buf for bufspec%d\n",
+ __func__, i
+ );
#endif
}
return 0;
@@ -1965,7 +1947,7 @@
ctx->id, __func__,
(hw->mb_total << 8) + (hw->mb_total << 7));
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
if (ret < 0) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
"[%d] get fb fail.\n", ctx->id);
@@ -1974,7 +1956,7 @@
bs->cma_alloc_addr = (unsigned long)fb;
dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), cma alloc addr: 0x%x, out %d dec %d\n",
+ "[%d] %s(), cma alloc addr: 0x%lx, out %d dec %d\n",
ctx->id, __func__, bs->cma_alloc_addr,
ctx->cap_pool.out, ctx->cap_pool.dec);
@@ -1989,8 +1971,6 @@
fb->m.mem[1].bytes_used = fb->m.mem[1].size;
}
- fb->status = FB_ST_DECODER;
-
dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
"[%d] %s(), y_addr: %x, size: %u\n",
ctx->id, __func__, y_addr, fb->m.mem[0].size);
@@ -2044,15 +2024,14 @@
if (hw->is_used_v4l)
endian = 7;
- config_cav_lut_ex(hw->buffer_spec[i].
+ canvas_config_ex(hw->buffer_spec[i].
y_canvas_index,
hw->buffer_spec[i].y_addr,
hw->mb_width << 4,
hw->mb_height << 4,
CANVAS_ADDR_NOWRAP,
blkmode,
- endian,
- VDEC_1);
+ endian);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
@@ -2063,15 +2042,14 @@
);
}
- config_cav_lut_ex(hw->buffer_spec[i].
+ canvas_config_ex(hw->buffer_spec[i].
u_canvas_index,
hw->buffer_spec[i].u_addr,
hw->mb_width << 4,
hw->mb_height << 3,
CANVAS_ADDR_NOWRAP,
blkmode,
- endian,
- VDEC_1);
+ endian);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
@@ -2088,16 +2066,46 @@
#ifdef VDEC_DW
if (!IS_VDEC_DW(hw))
return;
- else {
- config_cav_lut_ex(hw->buffer_spec[i].
+ else if (IS_VDEC_DW(hw) == 1) {
+ canvas_config_ex(hw->buffer_spec[i].
vdec_dw_y_canvas_index,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].width,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].height,
+ hw->buffer_spec[i].vdec_dw_y_addr,
+ hw->mb_width << 3,
+ hw->mb_height << 4,
CANVAS_ADDR_NOWRAP,
blkmode,
- endian,
- VDEC_1);
+ endian);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
+ (1 << 11) |
+ (blkmode << 10) |
+ (1 << 8) |
+ (hw->buffer_spec[i].vdec_dw_y_canvas_index << 0));
+ }
+ canvas_config_ex(hw->buffer_spec[i].
+ vdec_dw_u_canvas_index,
+ hw->buffer_spec[i].vdec_dw_u_addr,
+ hw->mb_width << 3,
+ hw->mb_height << 3,
+ CANVAS_ADDR_NOWRAP,
+ blkmode,
+ endian);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
+ (1 << 11) |
+ (blkmode << 10) |
+ (1 << 8) |
+ (hw->buffer_spec[i].vdec_dw_u_canvas_index << 0));
+ }
+ } else {
+ canvas_config_ex(hw->buffer_spec[i].
+ vdec_dw_y_canvas_index,
+ hw->buffer_spec[i].vdec_dw_y_addr,
+ hw->mb_width << 3,
+ hw->mb_height << 3,
+ CANVAS_ADDR_NOWRAP,
+ blkmode,
+ endian);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
(1 << 11) |
@@ -2106,15 +2114,14 @@
(hw->buffer_spec[i].vdec_dw_y_canvas_index << 0));
}
- config_cav_lut_ex(hw->buffer_spec[i].
+ canvas_config_ex(hw->buffer_spec[i].
vdec_dw_u_canvas_index,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].width,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].height,
+ hw->buffer_spec[i].vdec_dw_u_addr,
+ hw->mb_width << 3,
+ hw->mb_height << 2,
CANVAS_ADDR_NOWRAP,
blkmode,
- endian,
- VDEC_1);
+ endian);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
(1 << 11) |
@@ -2133,9 +2140,9 @@
int canvas_h;
canvas_w = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
canvas_h = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
if (hw->canvas_mode == 0)
canvas_w = ALIGN(canvas_w, 32);
@@ -2143,27 +2150,26 @@
canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
- config_cav_lut_ex(hw->buffer_spec[i].
+ canvas_config_ex(hw->buffer_spec[i].
y_canvas_index,
hw->buffer_spec[i].dw_y_adr,
canvas_w,
canvas_h,
CANVAS_ADDR_NOWRAP,
blkmode,
- 7,
- VDEC_HEVC);
+ 7);
- config_cav_lut_ex(hw->buffer_spec[i].
+ canvas_config_ex(hw->buffer_spec[i].
u_canvas_index,
hw->buffer_spec[i].dw_u_v_adr,
canvas_w,
canvas_h,
CANVAS_ADDR_NOWRAP,
blkmode,
- 7,
- VDEC_HEVC);
+ 7);
}
+
static int v4l_get_free_buffer_spec(struct vdec_h264_hw_s *hw)
{
int i;
@@ -2195,7 +2201,7 @@
struct buffer_spec_s *pic = NULL;
int i, rt, idx = INVALID_IDX;
ulong flags;
- u32 state = 0, index;
+ u32 state, index;
spin_lock_irqsave(&hw->bufspec_lock, flags);
for (i = 0; i < pool->in; ++i) {
@@ -2228,6 +2234,7 @@
}
break;
default:
+ pr_err("v4l buffer state err %d.\n", state);
break;
}
@@ -2239,17 +2246,12 @@
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
if (idx < 0) {
- dpb_print(DECODE_ID(hw), 0, "%s fail, state %d\n", __func__, state);
+ dpb_print(DECODE_ID(hw), 0, "%s fail\n", __func__);
for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
dpb_print(DECODE_ID(hw), 0, "%s, %d\n",
__func__, hw->buffer_wrap[i]);
}
vmh264_dump_state(vdec);
- } else {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)pic->cma_alloc_addr;
-
- fb->status = FB_ST_DECODER;
}
return idx;
@@ -2300,7 +2302,6 @@
}
}
}
-
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
if (hw->start_search_pos >= buf_total)
hw->start_search_pos = 0;
@@ -2548,7 +2549,7 @@
int i;
unsigned long addr;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx * ctx = hw->v4l2_ctx;
+ struct aml_vcodec_ctx * v4l = hw->v4l2_ctx;
int canvas_pos_min = BUFSPEC_POOL_SIZE;
int index = -1;
int ret = 0;
@@ -2557,10 +2558,6 @@
if (hw->is_used_v4l) {
struct h264_dpb_stru *dpb = &hw->dpb;
- /* trigger to parse head data. */
- if (!hw->v4l_params_parsed)
- return 1;
-
if (dpb->mDPB.used_size >= dpb->mDPB.size - 1)
return 0;
@@ -2572,13 +2569,10 @@
}
}
- if (ctx->cap_pool.dec < hw->dpb.mDPB.size) {
- if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) >=
- run_ready_min_buf_num) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token))
- return 1;
- }
- }
+ if (v4l->cap_pool.dec < hw->dpb.mDPB.size &&
+ v4l2_m2m_num_dst_bufs_ready(v4l->m2m_ctx)
+ >= run_ready_min_buf_num)
+ return 1;
return 0;
}
@@ -2661,9 +2655,6 @@
if (vdec_secure(hw_to_vdec(hw)))
return 0;
- if (hw->i_only)
- return 0;
-
if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE)
&& hw->bitstream_restriction_flag
&& (hw->frame_width == 1920)
@@ -2677,7 +2668,9 @@
&& (hw->frame_dur == 3840)) {
bForceInterlace = 1;
}
-
+ if ((frame->frame) && (hw->is_used_v4l) && (bForceInterlace == 0)) {
+ bForceInterlace = (frame->frame->mb_aff_frame_flag)?1:0;
+ }
return bForceInterlace;
}
@@ -2779,22 +2772,23 @@
if (frame->frame == NULL &&
((frame->is_used == 1 && frame->top_field)
|| (frame->is_used == 2 && frame->bottom_field))) {
- if (hw->i_only) {
- if (frame->is_used == 1)
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s No bottom_field !! frame_num %d used %d\n",
- __func__, frame->frame_num, frame->is_used);
- if (frame->is_used == 2)
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s No top_field !! frame_num %d used %d\n",
- __func__, frame->frame_num, frame->is_used);
- }
- else {
- frame->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "%s Error frame_num %d used %d\n",
+ if (hw->i_only) {
+ if (frame->is_used == 1)
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "%s No bottom_field !! frame_num %d used %d\n",
__func__, frame->frame_num, frame->is_used);
- }
+ if (frame->is_used == 2)
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
+ "%s No top_field !! frame_num %d used %d\n",
+ __func__, frame->frame_num, frame->is_used);
+ }
+ else {
+ frame->data_flag |= ERROR_FLAG;
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
+ "%s Error frame_num %d used %d\n",
+ __func__, frame->frame_num, frame->is_used);
+ }
+
}
if (vdec_stream_based(vdec) && !(frame->data_flag & NODISP_FLAG)) {
if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
@@ -2815,7 +2809,6 @@
hw->wrong_frame_count++;
}
}
-
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s error= 0x%x poc = %d offset= 0x%x pts= 0x%x last_pts =0x%x pts64 = %lld last_pts64= %lld duration = %d\n",
__func__, (frame->data_flag & ERROR_FLAG), frame->poc,
@@ -2874,13 +2867,13 @@
}
- if ((!hw->enable_fence) &&
- ((frame->data_flag & NODISP_FLAG) ||
+ if ((frame->data_flag & NODISP_FLAG) ||
(frame->data_flag & NULL_FLAG) ||
((!hw->send_error_frame_flag) &&
(frame->data_flag & ERROR_FLAG)) ||
((hw->i_only & 0x1) &&
- (!(frame->data_flag & I_FLAG))))) {
+ (!(frame->data_flag & I_FLAG)))) {
+ set_frame_output_flag(&hw->dpb, frame->index);
frame->show_frame = false;
return 0;
}
@@ -2909,7 +2902,6 @@
struct vframe_s *vf = NULL;
int buffer_index = frame->buf_spec_num;
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
ulong nv_order = VIDTYPE_VIU_NV21;
int bForceInterlace = 0;
int vf_count = 1;
@@ -2930,15 +2922,12 @@
bForceInterlace = check_force_interlace(hw, frame);
if (bForceInterlace)
vf_count = 2;
-
+ if (hw->is_used_v4l)
+ vf_count = 1;
if (!hw->enable_fence)
hw->buffer_spec[buffer_index].vf_ref = 0;
fill_frame_info(hw, frame);
- if ((hw->is_used_v4l) &&
- (vdec->prog_only))
- vf_count = 1;
-
for (i = 0; i < vf_count; i++) {
if (kfifo_get(&hw->newframe_q, &vf) == 0 ||
vf == NULL) {
@@ -2963,7 +2952,6 @@
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->buffer_spec[buffer_index].cma_alloc_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
}
if (hw->enable_fence) {
@@ -3029,14 +3017,9 @@
vf->canvas0Addr = vf->canvas1Addr =
spec2canvas(&hw->buffer_spec[buffer_index]);
#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw))
- vf->canvas0Addr = vf->canvas1Addr =
- vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]);
- } else {
- if (IS_VDEC_DW(hw))
- vf->canvas0Addr = vf->canvas1Addr = -1;
- }
+ if (IS_VDEC_DW(hw))
+ vf->canvas0Addr = vf->canvas1Addr =
+ vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]);
#endif
}
@@ -3047,17 +3030,9 @@
if (hw->mmu_enable && hw->double_write_mode) {
vf->width = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
vf->height = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
- }
-
- if (frame->slice_type == I_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME;
- } else if (frame->slice_type == P_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_PFRAME;
- } else if (frame->slice_type == B_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_BFRAME;
+ get_double_write_ratio(hw);
}
vf->flag = 0;
@@ -3148,30 +3123,6 @@
}
}
- /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
- vf->sar_width = hw->width_aspect_ratio;
- vf->sar_height = hw->height_aspect_ratio;
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- /* offset for tsplayer pts lookup */
- if (i == 0) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) &
- 0xffffffff00000000) | frame->offset_delimiter;
- vf->pts = 0;
- } else {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- }
-
- hw->vf_pre_count++;
- vdec_vframe_ready(hw_to_vdec(hw), vf);
- if (!frame->show_frame) {
- vh264_vf_put(vf, vdec);
- atomic_add(1, &hw->vf_get_count);
- continue;
- }
-
if (i == 0) {
struct vdec_s *pvdec;
struct vdec_info vs;
@@ -3187,49 +3138,41 @@
__func__, __LINE__,vs.i_decoded_frames,vs.p_decoded_frames,vs.b_decoded_frames);
}
+ /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
+ vf->sar_width = hw->width_aspect_ratio;
+ vf->sar_height = hw->height_aspect_ratio;
+ if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
+ /* offset for tsplayer pts lookup */
+ if (i == 0) {
+ vf->pts_us64 =
+ (((u64)vf->duration << 32) &
+ 0xffffffff00000000) | frame->offset_delimiter;
+ vf->pts = 0;
+ } else {
+ vf->pts_us64 = (u64)-1;
+ vf->pts = 0;
+ }
+ }
+ vdec_vframe_ready(hw_to_vdec(hw), vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.pts_name, vf->pts);
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
+ ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
hw->vf_pre_count++;
vdec->vdec_fps_detec(vdec->id);
#ifdef AUX_DATA_CRC
decoder_do_aux_data_check(vdec, hw->buffer_spec[buffer_index].aux_data_buf,
hw->buffer_spec[buffer_index].aux_data_size);
#endif
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL, "aux_data_size: %d, signal_type: 0x%x\n",
- hw->buffer_spec[buffer_index].aux_data_size, hw->video_signal_type);
-
- if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL)) {
- int i = 0;
- PR_INIT(128);
-
- for (i = 0; i < hw->buffer_spec[buffer_index].aux_data_size; i++) {
- PR_FILL("%02x ", hw->buffer_spec[buffer_index].aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hw->id);
- }
- PR_INFO(hw->id);
- }
-
- if (hw->is_used_v4l) {
+ if (hw->is_used_v4l)
update_vframe_src_fmt(vf,
hw->buffer_spec[buffer_index].aux_data_buf,
hw->buffer_spec[buffer_index].aux_data_size,
false, vdec->vf_provider_name, NULL);
- }
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vh264_vf_put(vh264_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
} else
vh264_vf_put(vh264_vf_get(vdec), vdec);
}
@@ -3251,13 +3194,13 @@
return 0;
/* create fence for each buffers. */
- if (vdec_timeline_create_fence(vdec->sync))
+ if (vdec_timeline_create_fence(&vdec->sync))
return -1;
memset(&fs, 0, sizeof(fs));
fs.buf_spec_num = index;
- fs.fence = vdec->sync->fence;
+ fs.fence = vdec->sync.fence;
fs.slice_type = dpb_stru->mSlice.slice_type;
fs.dpb_frame_count = dpb_stru->dpb_frame_count;
@@ -3270,7 +3213,7 @@
fs.pts64 = hw->chunk->pts64;
fs.timestamp = hw->chunk->timestamp;
}
- fs.show_frame = true;
+
post_video_frame(vdec, &fs);
display_frame_count[DECODE_ID(hw)]++;
@@ -3283,10 +3226,6 @@
(struct vdec_h264_hw_s *)vdec->private;
if (hw->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
-
post_prepare_process(vdec, frame);
if (!frame->show_frame)
@@ -3297,36 +3236,16 @@
hw->buffer_spec[frame->buf_spec_num].fs_idx = frame->index;
/* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
-
- mutex_lock(&hw->fence_mutex);
- used_size = hw->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (hw->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(hw->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = hw->fence_vf_s.fence_vf[i];
- hw->fence_vf_s.fence_vf[i] = NULL;
- hw->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&hw->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vh264_vf_put(signed_fence[i], vdec);
- }
-
+ vdec_timeline_increase(&vdec->sync, 1);
return 0;
}
if (post_prepare_process(vdec, frame))
return -1;
+ if (!frame->show_frame)
+ return 0;
+
if (post_video_frame(vdec, frame))
return -1;
@@ -3353,8 +3272,7 @@
}
if (index == INVALID_IDX) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
pr_err("[%d] EOS get free buff fail.\n", ctx->id);
return -1;
}
@@ -3366,18 +3284,12 @@
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
hw->buffer_spec[index].cma_alloc_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER(hw->trace.pts_name, vf->pts);
-
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
pr_info("[%d] H264 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
@@ -3484,7 +3396,7 @@
hw_buf->prefix_aux_size;
}
if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL)) {
+ PRINT_FLAG_DEC_DETAIL)) {
dpb_print(DECODE_ID(hw), 0,
"%s:poc %d old size %d count %d,suf %d dv_flag %d\r\n",
__func__, pic->poc, AUX_DATA_SIZE(pic),
@@ -3583,7 +3495,7 @@
h[7] = (padding_len) & 0xff;
}
if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL)) {
+ PRINT_FLAG_DEC_DETAIL)) {
dpb_print(DECODE_ID(hw), 0,
"aux: (size %d) suffix_flag %d\n",
AUX_DATA_SIZE(pic), suffix_flag);
@@ -3663,98 +3575,6 @@
}
}
-#ifdef VDEC_DW
-
-struct vdec_dw_param_set{
- char dw_x_shrink_1st;
- char dw_x_shrink_2nd;
- char dw_x_shrink_3rd;
- char dw_y_shrink_1st;
- char dw_y_shrink_2nd;
- char dw_y_shrink_3rd;
- char dw_merge_8to16;
- char dw_merge_16to32;
- char dw_dma_blk_mode;
- char dw_bwsave_mode;
-};
-//#define FOR_LPDDR4_EFFICIENCY
-
-static void h264_vdec_dw_cfg(struct vdec_h264_hw_s *hw, int canvas_pos)
-{
- u32 data32 = 0, stride = 0;
- struct vdec_dw_param_set *p = NULL;
- struct vdec_dw_param_set dw_param_set_pool[] = {
- /*x1, x2, x3, y1, y2, y3, m8t6, m16to32 */
- //{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/1, 1/1 */
- {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/1 */
- {1, 0, 0, 1, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/2 */
- //{1, 0, 0, 1, 1, 0, 0, 0, 0, 1}, /* 1/4, 1/2 */
- {2, 0, 1, 1, 3, 0, 0, 1, 0, 1}, /* 1/4, 1/4 */
- //{1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/4 */
- {1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/8 */
- };
-
- if (IS_VDEC_DW(hw))
- p = &dw_param_set_pool[__ffs(IS_VDEC_DW(hw))];
- else
- return;
-
- WRITE_VREG(MDEC_DOUBLEW_CFG3,
- hw->buffer_spec[canvas_pos].vdec_dw_y_addr); // luma start address
- WRITE_VREG(MDEC_DOUBLEW_CFG4,
- hw->buffer_spec[canvas_pos].vdec_dw_u_addr); // chroma start address
-
- stride = ALIGN_WIDTH((hw->mb_width << 4) / (IS_VDEC_DW(hw)));
- if ((IS_VDEC_DW(hw)) == 1) //width 1/2
- stride >>= 1;
- data32 = (stride << 16) | stride;
- WRITE_VREG(MDEC_DOUBLEW_CFG5, data32); // chroma stride | luma stride
-
- data32 = 0;
- p->dw_dma_blk_mode = hw->canvas_mode;
- data32 |= ((p->dw_x_shrink_1st << 0 ) | // 1st down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_1st << 2 ) | // 1st down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_x_shrink_2nd << 4 ) | // 2nd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_2nd << 6 ) | // 2nd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_x_shrink_3rd << 8 ) | // 3rd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_3rd << 10) | // 3rd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_merge_8to16 << 12 ) | // 8->16 horizontal block merge for better ddr efficiency
- (p->dw_merge_16to32 << 13) | // 16->32 horizontal block merge for better ddr efficiency
- (p->dw_dma_blk_mode << 14) | // DMA block mode, 0:linear 1:32x32 2:64x32
-#ifdef FOR_LPDDR4_EFFICIENCY
- (1 << 19) |
-#endif
- (p->dw_bwsave_mode << 22)); // Save line buffers to save band width
- WRITE_VREG(MDEC_DOUBLEW_CFG1, data32); // add some special tests here
-
- data32 = 0;
- data32 |= (1 << 0) | (0 << 27);
- WRITE_VREG(MDEC_DOUBLEW_CFG0, data32); // Double Write Enable | source from dblk
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "vdec_double_write mode %d\n",
- IS_VDEC_DW(hw));
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "param {%d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
- p->dw_x_shrink_1st,
- p->dw_y_shrink_1st,
- p->dw_x_shrink_2nd,
- p->dw_y_shrink_2nd,
- p->dw_x_shrink_3rd,
- p->dw_y_shrink_3rd,
- p->dw_merge_8to16,
- p->dw_merge_16to32,
- p->dw_dma_blk_mode);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "cfg0,1,3,4,5 = {%x, %x, %x, %x, %x}\n",
- READ_VREG(MDEC_DOUBLEW_CFG0),
- READ_VREG(MDEC_DOUBLEW_CFG1),
- READ_VREG(MDEC_DOUBLEW_CFG3),
- READ_VREG(MDEC_DOUBLEW_CFG4),
- READ_VREG(MDEC_DOUBLEW_CFG5));
-}
-#endif
-
static void config_decode_mode(struct vdec_h264_hw_s *hw)
{
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
@@ -3785,7 +3605,6 @@
else
WRITE_VREG(INIT_FLAG_REG, 1);
}
-
int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
{
/* static int count = 0; */
@@ -3847,11 +3666,9 @@
print_pic_info(DECODE_ID(hw), "cur", pic, pSlice->slice_type);
#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag)
- WRITE_VREG(MDEC_DOUBLEW_CFG0,
- (READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30))));
- }
+ if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag)
+ WRITE_VREG(MDEC_DOUBLEW_CFG0,
+ ( READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30))));
#endif
WRITE_VREG(CURR_CANVAS_CTRL, canvas_pos << 24);
canvas_adr = READ_VREG(CURR_CANVAS_CTRL) & 0xffffff;
@@ -3861,13 +3678,9 @@
WRITE_VREG(DBKR_CANVAS_ADDR, canvas_adr);
WRITE_VREG(DBKW_CANVAS_ADDR, canvas_adr);
#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- WRITE_VREG(MDEC_DOUBLEW_CFG1,
- (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index |
- (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8)));
- } else {
- h264_vdec_dw_cfg(hw, canvas_pos);
- }
+ WRITE_VREG(MDEC_DOUBLEW_CFG1,
+ (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index
+ | (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8)));
#endif
} else
hevc_sao_set_pic_buffer(hw, pic);
@@ -4187,16 +4000,12 @@
* 00 - top field, 01 - bottom field,
* 10 - frame, 11 - mbaff frame
*/
- int l10_structure, cur_structure;
+ int l10_structure;
int cur_colocate_ref_type;
/* H264_CO_MB_RD_ADDR[bit 29], top/bot for B field pciture,
* 0 - top, 1 - bot
*/
unsigned int val;
- unsigned int colocate_rd_adr_offset;
- unsigned int mby_mbx;
- unsigned int mby, mbx;
-
#ifdef ERROR_CHECK
if (colocate_pic == NULL) {
hw->data_flag |= ERROR_FLAG;
@@ -4222,60 +4031,6 @@
l10_structure = (colocate_pic->structure ==
BOTTOM_FIELD) ? 1 : 0;
}
-
- //ALLEGRO_FIX, ported from single mode ucode
- mby_mbx = READ_VREG(MBY_MBX);
- mby = pSlice->first_mb_in_slice / hw->mb_width;
- mbx = pSlice->first_mb_in_slice % hw->mb_width;
- if (pic->mb_aff_frame_flag)
- cur_structure = 3;
- else {
- if (pic->coded_frame)
- cur_structure = 2;
- else
- cur_structure = (pic->structure ==
- BOTTOM_FIELD) ? 1 : 0;
- }
- if (cur_structure < 2) {
- //current_field_structure
- if (l10_structure != 2) {
- colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2;
- } else {
- // field_ref_from_frame co_mv_rd_addr :
- // mby*2*mb_width + mbx
- colocate_rd_adr_offset = mby * 2 * hw->mb_width + mbx;
- }
-
- } else {
- //current_frame_structure
- if (l10_structure < 2) {
- //calculate_co_mv_offset_frame_ref_field:
- // frame_ref_from_field co_mv_rd_addr :
- // (mby/2*mb_width+mbx)*2
- colocate_rd_adr_offset = ((mby / 2) * hw->mb_width + mbx) * 2;
- } else if (cur_structure == 2) {
- colocate_rd_adr_offset = pSlice->first_mb_in_slice;
- } else {
- //mbaff frame case1196
- colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2;
- }
-
- }
-
- colocate_rd_adr_offset *= 96;
- if (use_direct_8x8)
- colocate_rd_adr_offset >>= 2;
-
- if (colocate_old_cal)
- colocate_rd_adr_offset = colocate_adr_offset;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "first_mb_in_slice 0x%x 0x%x 0x%x (MBY_MBX reg 0x%x) use_direct_8x8 %d cur %d (mb_aff_frame_flag %d, coded_frame %d structure %d) col %d (mb_aff_frame_flag %d, coded_frame %d structure %d) offset 0x%x rdoffset 0x%x\n",
- pSlice->first_mb_in_slice, mby, mbx, mby_mbx, use_direct_8x8,
- cur_structure, pic->mb_aff_frame_flag, pic->coded_frame, pic->structure,
- l10_structure, colocate_pic->mb_aff_frame_flag, colocate_pic->coded_frame, colocate_pic->structure,
- colocate_adr_offset,
- colocate_rd_adr_offset);
-
#if 0
/*case0016, p16,
*cur_colocate_ref_type should be configured base on current pic
@@ -4335,14 +4090,14 @@
* [2:0] will set to 3'b000
*/
/* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */
- val = ((colocate_rd_adr+colocate_rd_adr_offset) >> 3) |
+ val = ((colocate_rd_adr+colocate_adr_offset) >> 3) |
(l10_structure << 30) |
(cur_colocate_ref_type << 29);
WRITE_VREG(H264_CO_MB_RD_ADDR, val);
dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
"co idx %d, WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, addr %x L1(0) pic_structure %d mbaff %d\n",
colocate_pic->colocated_buf_index,
- val, colocate_rd_adr + colocate_rd_adr_offset,
+ val, colocate_rd_adr + colocate_adr_offset,
colocate_pic->structure,
colocate_pic->mb_aff_frame_flag);
} else {
@@ -4374,7 +4129,7 @@
* [2:0] will set to 3'b000
*/
/* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */
- val = ((colocate_rd_adr+colocate_rd_adr_offset)>>3) |
+ val = ((colocate_rd_adr+colocate_adr_offset)>>3) |
(l10_structure << 30) | (cur_colocate_ref_type << 29);
WRITE_VREG(H264_CO_MB_RD_ADDR, val);
dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
@@ -4442,12 +4197,14 @@
struct vframe_s *vf;
struct vdec_s *vdec = op_arg;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
+ struct aml_vcodec_ctx * v4l2_ctx;
ulong nv_order = VIDTYPE_VIU_NV21;
if (!hw)
return NULL;
+ v4l2_ctx = hw->v4l2_ctx;
+
/* swap uv */
if (hw->is_used_v4l) {
if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
@@ -4517,9 +4274,9 @@
if (hw->double_write_mode) {
vf->width = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
vf->height = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
+ get_double_write_ratio(hw);
}
} else {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
@@ -4540,7 +4297,7 @@
unsigned int frame_interval =
1000*(time - hw->last_frame_time)/HZ;
struct vframe_s *next_vf = NULL;
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
+ ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_VDEC_DETAIL)) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
@@ -4552,10 +4309,10 @@
__func__, vf->index);
} else {
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms, ts: %lld\n",
+ "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms\n",
__func__, BUFSPEC_INDEX(vf->index), vf,
p_H264_Dpb->mFrameStore[frame_index].poc,
- vf->duration, vf->pts, frame_interval, vf->timestamp);
+ vf->duration, vf->pts, frame_interval);
}
}
if (hw->last_frame_time > 0) {
@@ -4565,14 +4322,13 @@
= frame_interval;
}
hw->last_frame_time = time;
- vf->index_disp = atomic_read(&hw->vf_get_count);
- atomic_add(1, &hw->vf_get_count);
+ vf->index_disp = hw->vf_get_count;
+ hw->vf_get_count++;
if (kfifo_peek(&hw->display_q, &next_vf) && next_vf) {
vf->next_vf_pts_valid = true;
vf->next_vf_pts = next_vf->pts;
} else
vf->next_vf_pts_valid = false;
-
return vf;
}
@@ -4618,24 +4374,6 @@
return;
}
- if (hw->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&hw->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (hw->fence_vf_s.fence_vf[i] == NULL) {
- hw->fence_vf_s.fence_vf[i] = vf;
- hw->fence_vf_s.used_size++;
- mutex_unlock(&hw->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&hw->fence_mutex);
- }
-
buf_spec_num = BUFSPEC_INDEX(vf->index);
if (hw->enable_fence)
frame_index = hw->buffer_spec[buf_spec_num].fs_idx;
@@ -4691,17 +4429,10 @@
}
- if (hw->is_used_v4l) {
- struct buffer_spec_s *pic = &hw->buffer_spec[buf_spec_num];
-
- if (vf->v4l_mem_handle != pic->cma_alloc_addr)
- pic->cma_alloc_addr = vf->v4l_mem_handle;
- }
-
- atomic_add(1, &hw->vf_put_count);
- if (vf && (vf_valid_check(vf, hw) == true)) {
+ hw->vf_put_count++;
+ if (vf_valid_check(vf, hw) == true) {
kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
+ ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
}
#define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG
@@ -4709,7 +4440,6 @@
WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1);
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
}
-
void * vh264_get_bufspec_lock(struct vdec_s *vdec)
{
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
@@ -4730,7 +4460,7 @@
int buf_spec_num;
if (!req->vf) {
- req->aux_size = atomic_read(&hw->vf_put_count);
+ req->aux_size = hw->vf_put_count;
return 0;
}
buf_spec_num = BUFSPEC_INDEX(req->vf->index);
@@ -4793,7 +4523,6 @@
}
} else
vf->signal_type = 0;
- hw->video_signal_type = vf->signal_type;
vf->width = hw->frame_width;
vf->height = hw->frame_height;
@@ -4823,11 +4552,9 @@
#endif
if (IS_VDEC_DW(hw)) {
- if (IS_VDEC_DW(hw) == 1)
- vf->width = hw->frame_width / 2;
- else
- vf->width = (hw->frame_width / IS_VDEC_DW(hw));
- vf->height = (hw->frame_height / IS_VDEC_DW(hw));
+ vf->width = (hw->frame_width /2);
+ if (IS_VDEC_DW(hw) == 2)
+ vf->height = (hw->frame_height /2);
p_canvas_config = &hw->buffer_spec[index].vdec_dw_canvas_config[0];
} else
p_canvas_config = &hw->buffer_spec[index].canvas_config[0];
@@ -5320,68 +5047,11 @@
size = size_vui;
}
- size += 2; /* need two more buffer */
+ size += 1; /* need one more buffer */
return size;
}
-static int get_dec_dpb_size_active(struct vdec_h264_hw_s *hw, u32 param1)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hw);
-#endif
- int mb_width, mb_total;
- int mb_height = 0;
- int active_buffer_spec_num, dec_dpb_size;
- u32 used_reorder_dpb_size_margin
- = hw->reorder_dpb_size_margin;
-
- mb_width = param1 & 0xff;
- mb_total = (param1 >> 8) & 0xffff;
- if (!mb_width && mb_total) /*for 4k2k*/
- mb_width = 256;
- if (mb_width)
- mb_height = mb_total/mb_width;
- if (mb_width <= 0 || mb_height <= 0 ||
- is_oversize(mb_width << 4, mb_height << 4)) {
- dpb_print(DECODE_ID(hw), 0,
- "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
- param1,
- mb_width,
- mb_height);
- hw->error_frame_width = mb_width << 4;
- hw->error_frame_height = mb_height << 4;
- return -1;
- }
- hw->error_frame_width = 0;
- hw->error_frame_height = 0;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master || vdec->slave)
- used_reorder_dpb_size_margin =
- reorder_dpb_size_margin_dv;
-#endif
-
- dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height);
-
- active_buffer_spec_num =
- dec_dpb_size
- + used_reorder_dpb_size_margin;
-
- if (active_buffer_spec_num > MAX_VF_BUF_NUM) {
- active_buffer_spec_num = MAX_VF_BUF_NUM;
- dec_dpb_size = active_buffer_spec_num
- - used_reorder_dpb_size_margin;
- }
-
- hw->dpb.mDPB.size = active_buffer_spec_num;
-
- if (hw->no_poc_reorder_flag)
- dec_dpb_size = 1;
-
- return dec_dpb_size;
-}
-
static void vh264_config_canvs_for_mmu(struct vdec_h264_hw_s *hw)
{
int i, j;
@@ -5419,7 +5089,6 @@
unsigned int used_reorder_dpb_size_margin
= hw->reorder_dpb_size_margin;
u8 *colocate_vaddr = NULL;
- int dec_dpb_size_change = 0;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (vdec->master || vdec->slave)
@@ -5438,7 +5107,7 @@
if (mb_width <= 0 || mb_height <= 0 ||
is_oversize(mb_width << 4, mb_height << 4)) {
dpb_print(DECODE_ID(hw), 0,
- "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
+ "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x)\r\n",
seq_info2,
mb_width,
mb_height);
@@ -5449,28 +5118,11 @@
hw->error_frame_width = 0;
hw->error_frame_height = 0;
- dec_dpb_size_change = hw->csd_change_flag && (hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1));
-
- if (((seq_info2 != 0 &&
- hw->seq_info2 != seq_info2) || hw->csd_change_flag) &&
+ if (seq_info2 != 0 &&
+ hw->seq_info2 != seq_info2 &&
hw->seq_info2 != 0
- ) {
- if (hw->seq_info2 != seq_info2 || dec_dpb_size_change) { /*picture size changed*/
- h264_reconfig(hw);
- } else {
- /*someting changes and not including dpb_size, width, height, ...*/
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- u32 reg_val = param4;
- max_reference_size = (reg_val >> 8) & 0xff;
- hw->dpb.reorder_output = max_reference_size;
-
- if (p_H264_Dpb->bitstream_restriction_flag &&
- p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering &&
- p_H264_Dpb->num_reorder_frames >= 0) {
- hw->dpb.reorder_output = hw->num_reorder_frames + 1;
- }
- }
- }
+ ) /*picture size changed*/
+ h264_reconfig(hw);
if (hw->config_bufmgr_done == 0) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
@@ -5492,8 +5144,7 @@
p_H264_Dpb->fast_output_enable = fast_output_enable;
/*mb_mv_byte = (seq_info2 & 0x80000000) ? 24 : 96;*/
- if (hw->enable_fence)
- p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST;
+
#if 1
/*crop*/
/* AV_SCRATCH_2
@@ -5579,6 +5230,10 @@
hevc_mcr_sao_global_hw_init(hw,
(hw->mb_width << 4), (hw->mb_height << 4));
+ reg_val = param4;
+ level_idc = reg_val & 0xff;
+ max_reference_size = (reg_val >> 8) & 0xff;
+ hw->dpb.reorder_output = max_reference_size;
dpb_print(DECODE_ID(hw), 0,
"mb height/widht/total: %x/%x/%x level_idc %x max_ref_num %x\n",
mb_height, mb_width, mb_total,
@@ -5595,6 +5250,11 @@
used_reorder_dpb_size_margin);
if (p_H264_Dpb->bitstream_restriction_flag &&
+ p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering) {
+ hw->dpb.reorder_output = hw->num_reorder_frames + 1;
+ }
+
+ if (p_H264_Dpb->bitstream_restriction_flag &&
p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering &&
p_H264_Dpb->num_reorder_frames >= 0) {
hw->dpb.reorder_output = hw->num_reorder_frames + 1;
@@ -6079,19 +5739,13 @@
((p_H264_Dpb->mDPB.used_size >=
(p_H264_Dpb->mDPB.size - 1)) ||
(!have_free_buf_spec(vdec)))) {
- unsigned long flags;
- spin_lock_irqsave(&hw->bufspec_lock, flags);
+ bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
for (i = 0; i < p_Dpb->used_size; i++) {
if (p_Dpb->fs[i]->pre_output)
frame_outside_count++;
- else if (p_Dpb->fs[i]->is_output && !is_used_for_reference(p_Dpb->fs[i])) {
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
- return 0;
- }
}
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
+
inner_size = p_Dpb->size - frame_outside_count;
if (inner_size >= p_H264_Dpb->dec_dpb_size) {
@@ -6105,7 +5759,6 @@
}
}
}
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
} else if ((error_proc_policy & 0x8) &&
(p_Dpb->ref_frames_in_buffer >
(imax(
@@ -6118,11 +5771,10 @@
if (hw->reset_bufmgr_flag == 1)
buffer_available = 1;
+ else if (hw->is_used_v4l)
+ buffer_available = have_free_buf_spec(vdec);
}
- if (hw->is_used_v4l)
- buffer_available = have_free_buf_spec(vdec);
-
return buffer_available;
}
@@ -6348,11 +6000,8 @@
mb_width = 256;
decode_mb_count = ((mby_mbx & 0xff) * mb_width +
(((mby_mbx >> 8) & 0xff) + 1));
- if ((mby_mbx == 0) && (p_H264_Dpb->dec_dpb_status != H264_SLICE_HEAD_DONE)) {
- dpb_print(DECODE_ID(hw), 0,
- "mby_mbx is zero\n");
+ if (mby_mbx == 0)
return;
- }
if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME)
mb_total /= 2;
@@ -6361,11 +6010,11 @@
p->data_flag |= ERROR_FLAG;
}
- if (error_proc_policy & 0x100 && !(p->data_flag & ERROR_FLAG)) {
+ if (error_proc_policy & 0x100) {
if (decode_mb_count < mb_total) {
p->data_flag |= ERROR_FLAG;
- if (((error_proc_policy & 0x20000) &&
- decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100)) {
+ if ((error_proc_policy & 0x20000) &&
+ decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100) {
p->data_flag &= ~ERROR_FLAG;
}
}
@@ -6556,7 +6205,6 @@
p_H264_Dpb->mVideo.dec_picture->data_flag);
-
if (ret == -1) {
release_cur_decoding_buf(hw);
bufmgr_force_recover(p_H264_Dpb);
@@ -6601,6 +6249,61 @@
return 0;
}
+#ifdef VDEC_FCC_SUPPORT
+static void fcc_discard_mode_process(struct vdec_s *vdec)
+{
+ struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
+
+ if (vdec->fcc_status == AGAIN_STATUS) {
+ vdec->stream_offset = (p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_LO] |
+ p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_HI] << 16);
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Notify stream_offset: %d\n",
+ vdec->id, vdec->stream_offset);
+ vdec_wakeup_fcc_poll(vdec);
+ amvdec_stop();
+ vdec->mc_loaded = 0;
+ hw->init_flag = 0;
+ vdec->fcc_status = WAIT_MSG_STATUS;
+ hw->dec_result = DEC_RESULT_AGAIN;
+ vdec_schedule_work(&hw->work);
+ } else if (vdec->fcc_status == DISCARD_STATUS) {
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Discard current gop and to find next gop!\n",
+ vdec->id);
+ amvdec_stop();
+ vdec->mc_loaded = 0;
+ hw->init_flag = 0;
+ vdec->fcc_status = AGAIN_STATUS;
+ hw->dec_result = DEC_RESULT_DISCARD_DATA;
+ vdec_schedule_work(&hw->work);
+ }
+}
+
+static int vh264_fcc_process(struct vdec_s *vdec)
+{
+ struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
+
+ if (input_stream_based(vdec)) {
+ switch (vdec->fcc_mode) {
+ case FCC_DISCARD_MODE:
+ fcc_discard_mode_process(vdec);
+ return 1;
+ case FCC_DEC_MODE:
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Current is Dec mode.\n", vdec->id);
+ break;
+ case FCC_BUTT:
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
+
static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
{
int i;
@@ -6609,18 +6312,6 @@
unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status;
u32 debug_tag;
- if (dec_dpb_status == H264_SLICE_HEAD_DONE ||
- p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_dpb_status == H264_PIC_DATA_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
- else if (dec_dpb_status == H264_SEI_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_SEI_START);
- else if (dec_dpb_status == H264_AUX_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_AUX_START);
-
if (dec_dpb_status == H264_CONFIG_REQUEST) {
#if 1
unsigned short *p = (unsigned short *)hw->lmem_addr;
@@ -6645,13 +6336,7 @@
}
}
}
- if (p_H264_Dpb->bitstream_restriction_flag !=
- ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "p_H264_Dpb->bitstream_restriction_flag 0x%x, new 0x%x\n",
- p_H264_Dpb->bitstream_restriction_flag, ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1));
- hw->csd_change_flag = 1;
- }
+
p_H264_Dpb->bitstream_restriction_flag =
(p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1;
p_H264_Dpb->num_reorder_frames =
@@ -6678,7 +6363,7 @@
p_H264_Dpb->frame_crop_top_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_top_offset;
p_H264_Dpb->frame_crop_bottom_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_bottom_offset;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
"%s chroma_format_idc %d crop offset: left %d right %d top %d bottom %d\n",
__func__, p_H264_Dpb->chroma_format_idc,
p_H264_Dpb->frame_crop_left_offset,
@@ -6687,6 +6372,11 @@
p_H264_Dpb->frame_crop_bottom_offset);
#endif
+#ifdef VDEC_FCC_SUPPORT
+ if (vh264_fcc_process(vdec) > 0)
+ return IRQ_HANDLED;
+#endif
+
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE);
reset_process_time(hw);
hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
@@ -6706,7 +6396,6 @@
hw->multi_slice_pic_flag = 0;
hw->picture_slice_count = 0;
#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
vdec_schedule_work(&hw->work);
} else if (dec_dpb_status == H264_SLICE_HEAD_DONE) {
u16 data_hight;
@@ -6722,27 +6411,18 @@
unsigned mb_width = hw->seq_info2 & 0xff;
unsigned short first_mb_in_slice;
unsigned int decode_mb_count, mby_mbx;
- struct StorablePicture *pic = p_H264_Dpb->mVideo.dec_picture;
reset_process_time(hw);
- hw->frmbase_cont_flag = 0;
-
- if ((pic != NULL) && (pic->mb_aff_frame_flag == 1))
- first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3] * 2;
- else
- first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3];
#ifdef DETECT_WRONG_MULTI_SLICE
hw->cur_picture_slice_count++;
-
- if ((error_proc_policy & 0x10000) &&
- (hw->cur_picture_slice_count > 1) &&
- (first_mb_in_slice == 0) &&
- (hw->multi_slice_pic_flag == 0))
- hw->multi_slice_pic_check_count = 0;
-
- if ((error_proc_policy & 0x10000) &&
- (hw->cur_picture_slice_count > 1) &&
- (hw->multi_slice_pic_flag == 1)) {
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count == 1 &&
+ (error_proc_policy & 0x10000)) {
+ hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num;
+ }
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count > 1 &&
+ (error_proc_policy & 0x10000)) {
dpb_print(DECODE_ID(hw), 0,
"%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n",
__func__,
@@ -6751,6 +6431,7 @@
hw->cur_picture_slice_count,
hw->multi_slice_pic_flag);
+ first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3];
mby_mbx = READ_VREG(MBY_MBX);
decode_mb_count = ((mby_mbx & 0xff) * mb_width +
(((mby_mbx >> 8) & 0xff) + 1));
@@ -6763,19 +6444,8 @@
hw->multi_slice_pic_flag = 0;
hw->multi_slice_pic_check_count = 0;
- } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count) {
+ } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count)
vh264_pic_done_proc(vdec);
- //if (p_H264_Dpb->mDPB.used_size == p_H264_Dpb->mDPB.size) {
- if (!have_free_buf_spec(vdec)) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "dpb full, wait buffer\n");
- p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num;
- hw->last_picture_slice_count = hw->cur_picture_slice_count;
- hw->no_decoder_buffer_flag = 1;
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
else {
if (p_H264_Dpb->mVideo.dec_picture) {
if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) {
@@ -6842,9 +6512,6 @@
}
#else
dpb_param_bak = p_H264_Dpb->dpb_param;
-
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_START);
-
for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
int ii;
@@ -6867,7 +6534,6 @@
}
}
}
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_END);
#endif
#ifdef DETECT_WRONG_MULTI_SLICE
@@ -7006,9 +6672,6 @@
else
p_H264_Dpb->fast_output_enable
= fast_output_enable;
- if (hw->enable_fence)
- p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST;
-
hw->data_flag = I_flag;
if ((p_H264_Dpb->
dpb_param.dpb.NAL_info_mmco & 0x1f)
@@ -7050,15 +6713,13 @@
}*/
}
- if (!I_flag && frame_num_gap && !p_H264_Dpb->long_term_reference_flag) {
- if (!(error_proc_policy & 0x800000)) {
- hw->data_flag |= ERROR_FLAG;
- p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), 0, "frame number gap error\n");
- }
+ if (!I_flag && frame_num_gap) {
+ hw->data_flag |= ERROR_FLAG;
+ p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
+ dpb_print(DECODE_ID(hw), 0, "frame number gap error\n");
}
- if ((error_proc_policy & 0x400) && !hw->enable_fence) {
+ if (error_proc_policy & 0x400) {
int ret = dpb_check_ref_list_error(p_H264_Dpb);
if (ret != 0) {
hw->reflist_error_count ++;
@@ -7101,10 +6762,9 @@
return IRQ_HANDLED;
}
}
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_START);
+
cfg_ret = config_decode_buf(hw,
p_H264_Dpb->mVideo.dec_picture);
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_END);
if (cfg_ret < 0) {
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
"config_decode_buf fail (%d)\n",
@@ -7122,12 +6782,11 @@
}
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
-
- if (slice_header_process_status == 1)
+ if (slice_header_process_status == 1) {
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_NEWPIC);
- else
+ } else {
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_SLICE);
+ }
hw->last_mby_mbx = 0;
hw->last_vld_level = 0;
start_process_time(hw);
@@ -7162,16 +6821,6 @@
pic_done_proc:
reset_process_time(hw);
- if ((dec_dpb_status == H264_SEARCH_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_TIMEOUT) ||
- ((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) {
- hw->data_flag |= ERROR_FLAG;
- if (hw->dpb.mVideo.dec_picture)
- hw->dpb.mVideo.dec_picture->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s, mark err_frame\n", __func__);
- }
vh264_pic_done_proc(vdec);
if (hw->frmbase_cont_flag) {
@@ -7223,7 +6872,6 @@
hw->got_valid_nal = 1;
}
#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
hw->dec_result = DEC_RESULT_DONE;
vdec_schedule_work(&hw->work);
@@ -7238,7 +6886,7 @@
reset_process_time(hw);
if (READ_VREG(H264_AUX_DATA_SIZE) != 0) {
if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL))
+ PRINT_FLAG_DPB_DETAIL))
dump_aux_buf(hw);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (vdec_frame_based(vdec)) {
@@ -7276,7 +6924,6 @@
#endif
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s H264_AUX_DATA_READY\n", __func__);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
hw->dec_result = DEC_RESULT_DONE;
vdec_schedule_work(&hw->work);
} else if (/*(dec_dpb_status == H264_DATA_REQUEST) ||*/
@@ -7286,8 +6933,7 @@
empty_proc:
reset_process_time(hw);
if ((error_proc_policy & 0x40000) &&
- ((dec_dpb_status == H264_DECODE_TIMEOUT) ||
- (!hw->frmbase_cont_flag && (dec_dpb_status == H264_SEARCH_BUFEMPTY || dec_dpb_status == H264_DECODE_BUFEMPTY) && input_frame_based(vdec))))
+ dec_dpb_status == H264_DECODE_TIMEOUT)
goto pic_done_proc;
if (!hw->frmbase_cont_flag)
release_cur_decoding_buf(hw);
@@ -7328,7 +6974,7 @@
(p_H264_Dpb->mSlice.slice_type != B_SLICE))) {
dpb_print(DECODE_ID(hw),
PRINT_FLAG_ERROR, "%s last dpb status 0x%x need bugmgr reset \n",
- p_H264_Dpb->last_dpb_status, __func__);
+ __func__, p_H264_Dpb->last_dpb_status);
hw->reset_bufmgr_flag = 1;
}
}
@@ -7341,7 +6987,9 @@
} else {
/* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */
#ifdef DETECT_WRONG_MULTI_SLICE
- if (error_proc_policy & 0x10000) {
+ if (hw->multi_slice_pic_flag == 1 &&
+ hw->cur_picture_slice_count > 1 &&
+ (error_proc_policy & 0x10000)) {
p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num;
}
hw->last_picture_slice_count = hw->cur_picture_slice_count;
@@ -7438,7 +7086,6 @@
left_len);
}
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
WRITE_VREG(DPB_STATUS_REG, H264_SEI_DATA_DONE);
return IRQ_HANDLED;
@@ -7519,17 +7166,6 @@
p_H264_Dpb->vdec = vdec;
p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG);
- if (p_H264_Dpb->dec_dpb_status == H264_SLICE_HEAD_DONE ||
- p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (p_H264_Dpb->dec_dpb_status == H264_PIC_DATA_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
- else if (p_H264_Dpb->dec_dpb_status == H264_SEI_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_SEI_DONE);
- else if (p_H264_Dpb->dec_dpb_status == H264_AUX_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_AUX_DONE);
dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
"%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n",
@@ -7550,7 +7186,6 @@
WRITE_VREG(DPB_STATUS_REG, H264_WRRSP_DONE);
return IRQ_HANDLED;
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END);
return IRQ_WAKE_THREAD;
}
@@ -7571,6 +7206,7 @@
pr_err("%s h264[%d] work pending, do nothing.\n",__func__, vdec->id);
return;
}
+
hw->timeout_num++;
amvdec_stop();
vdec->mc_loaded = 0;
@@ -7579,7 +7215,7 @@
hevc_sao_wait_done(hw);
}
dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR, "%s decoder timeout, DPB_STATUS_REG 0x%x\n", __func__, READ_VREG(DPB_STATUS_REG));
+ PRINT_FLAG_ERROR, "%s decoder timeout\n", __func__);
release_cur_decoding_buf(hw);
hw->dec_result = DEC_RESULT_TIMEOUT;
hw->data_flag |= ERROR_FLAG;
@@ -7625,7 +7261,7 @@
dpb_print(DECODE_ID(hw), 0,
"====== %s\n", __func__);
dpb_print(DECODE_ID(hw), 0,
- "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d video_signal_type 0x%x send_err %d \n",
+ "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d send_err %d\n",
hw->frame_width,
hw->frame_height,
hw->num_reorder_frames,
@@ -7633,7 +7269,6 @@
hw->dpb.mDPB.size,
hw->max_reference_size,
hw->i_only,
- hw->video_signal_type,
hw->send_error_frame_flag
);
@@ -7661,7 +7296,9 @@
hw->cur_picture_slice_count,
hw->multi_slice_pic_flag);
#endif
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+
+
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -7767,10 +7404,9 @@
}
-static void check_timer_func(struct timer_list *timer)
+static void check_timer_func(unsigned long arg)
{
- struct vdec_h264_hw_s *hw = container_of(timer,
- struct vdec_h264_hw_s, check_timer);
+ struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
int error_skip_frame_count = error_skip_count & 0xfff;
unsigned int timeout_val = decode_timeout_val;
@@ -7824,9 +7460,7 @@
if ((dpb_status == H264_ACTION_DECODE_NEWPIC) ||
(dpb_status == H264_ACTION_DECODE_SLICE) ||
(dpb_status == H264_SEI_DATA_DONE) ||
- (dpb_status == H264_STATE_SEARCH_HEAD) ||
- (dpb_status == H264_SLICE_HEAD_DONE) ||
- (dpb_status == H264_SEI_DATA_READY)) {
+ (dpb_status == H264_STATE_SEARCH_HEAD)) {
if (h264_debug_flag & DEBUG_TIMEOUT_DEC_STAT)
pr_debug("%s dpb_status = 0x%x last_mby_mbx = %u mby_mbx = %u\n",
__func__, dpb_status, hw->last_mby_mbx, mby_mbx);
@@ -7927,7 +7561,6 @@
int i, j;
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- hw->frmbase_cont_flag = 0;
/* if (hw->init_flag == 0) { */
if (h264_debug_flag & 0x40000000) {
/* if (1) */
@@ -8019,14 +7652,12 @@
#endif
#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw)) {
- u32 data = ((1 << 30) |(1 << 0) |(1 << 8));
+ if (IS_VDEC_DW(hw)) {
+ u32 data = ((1 << 30) |(1 << 0) |(1 << 8));
- if (IS_VDEC_DW(hw) == 2)
- data |= (1 << 9);
- WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/
- }
+ if (IS_VDEC_DW(hw) == 2)
+ data |= (1 << 9);
+ WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/
}
#endif
if (hw->dpb.mDPB.size > 0) {
@@ -8052,8 +7683,9 @@
if (hw->init_flag == 0)
WRITE_VREG(DPB_STATUS_REG, 0);
- else
+ else {
WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_START);
+ }
WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count);
WRITE_VREG(AV_SCRATCH_8, hw->buf_offset);
@@ -8222,7 +7854,10 @@
/* init_timer(&hw->recycle_timer); */
/* timer init */
- timer_setup(&hw->check_timer, check_timer_func, 0);
+ init_timer(&hw->check_timer);
+
+ hw->check_timer.data = (unsigned long)hw;
+ hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
/* add_timer(&hw->check_timer); */
@@ -8358,13 +7993,13 @@
return -1;
}
- hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL);
+ hw->sei_data_buf = vzalloc(SEI_DATA_SIZE);
if (hw->sei_data_buf == NULL) {
pr_err("%s: failed to alloc sei itu data buffer\n",
__func__);
return -1;
}
- hw->sei_itu_data_buf = kmalloc(SEI_ITU_DATA_SIZE, GFP_KERNEL);
+ hw->sei_itu_data_buf = vzalloc(SEI_ITU_DATA_SIZE);
if (hw->sei_itu_data_buf == NULL) {
pr_err("%s: failed to alloc sei itu data buffer\n",
__func__);
@@ -8372,15 +8007,14 @@
hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
hw->aux_phy_addr);
hw->aux_addr = NULL;
- kfree(hw->sei_data_buf);
+ vfree(hw->sei_data_buf);
hw->sei_data_buf = NULL;
return -1;
}
if (NULL == hw->sei_user_data_buffer) {
- hw->sei_user_data_buffer = kmalloc(USER_DATA_SIZE,
- GFP_KERNEL);
+ hw->sei_user_data_buffer = vzalloc(USER_DATA_SIZE);
if (!hw->sei_user_data_buffer) {
pr_info("%s: Can not allocate sei_data_buffer\n",
__func__);
@@ -8388,9 +8022,9 @@
hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
hw->aux_phy_addr);
hw->aux_addr = NULL;
- kfree(hw->sei_data_buf);
+ vfree(hw->sei_data_buf);
hw->sei_data_buf = NULL;
- kfree(hw->sei_itu_data_buf);
+ vfree(hw->sei_itu_data_buf);
hw->sei_itu_data_buf = NULL;
return -1;
@@ -8416,7 +8050,6 @@
}
#ifdef VDEC_DW
WRITE_VREG(MDEC_DOUBLEW_CFG0, 0);
- WRITE_VREG(MDEC_DOUBLEW_CFG1, 0);
#endif
#ifdef MH264_USERDATA_ENABLE
cancel_work_sync(&hw->user_data_ready_work);
@@ -8425,6 +8058,7 @@
cancel_work_sync(&hw->timeout_work);
cancel_work_sync(&hw->work);
+
if (hw->stat & STAT_MC_LOAD) {
if (hw->mc_cpu_addr != NULL) {
dma_free_coherent(amports_get_dma_device(),
@@ -8458,15 +8092,15 @@
hw->aux_addr = NULL;
}
if (hw->sei_data_buf != NULL) {
- kfree(hw->sei_data_buf);
+ vfree(hw->sei_data_buf);
hw->sei_data_buf = NULL;
}
if (hw->sei_itu_data_buf != NULL) {
- kfree(hw->sei_itu_data_buf);
+ vfree(hw->sei_itu_data_buf);
hw->sei_itu_data_buf = NULL;
}
if (hw->sei_user_data_buffer != NULL) {
- kfree(hw->sei_user_data_buffer);
+ vfree(hw->sei_user_data_buffer);
hw->sei_user_data_buffer = NULL;
}
/* amvdec_disable(); */
@@ -8509,10 +8143,6 @@
struct vdec_h264_hw_s *hw = container_of(work,
struct vdec_h264_hw_s, notify_work);
struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (hw->is_used_v4l)
- return;
-
if (vdec->fr_hint_state == VDEC_NEED_HINT) {
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
@@ -8807,7 +8437,7 @@
static int vmh264_init_userdata_dump(void)
{
- user_data_buf = kmalloc(MAX_USER_DATA_SIZE, GFP_KERNEL);
+ user_data_buf = vzalloc(MAX_USER_DATA_SIZE);
if (user_data_buf)
return 1;
else
@@ -8818,7 +8448,7 @@
{
if (user_data_buf) {
show_user_data_buf();
- kfree(user_data_buf);
+ vfree(user_data_buf);
user_data_buf = NULL;
}
}
@@ -9180,7 +8810,7 @@
if (mb_width <= 0 || mb_height <= 0 ||
is_oversize(mb_width << 4, mb_height << 4)) {
dpb_print(DECODE_ID(hw), 0,
- "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
+ "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x)\r\n",
param1,
mb_width,
mb_height);
@@ -9211,8 +8841,6 @@
- used_reorder_dpb_size_margin;
}
- hw->dpb.mDPB.size = active_buffer_spec_num;
-
if (hw->no_poc_reorder_flag)
dec_dpb_size = 1;
@@ -9222,7 +8850,6 @@
* bit 15: frame_mbs_only_flag
* bit 13-14: chroma_format_idc
*/
- hw->seq_info = param2;
frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01;
if (hw->dpb.mSPS.profile_idc != 100 &&
hw->dpb.mSPS.profile_idc != 110 &&
@@ -9281,8 +8908,9 @@
ps->visible_height = frame_height;
ps->coded_width = ALIGN(mb_width << 4, 64);
ps->coded_height = ALIGN(mb_height << 4, 64);
- ps->dpb_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */
+ ps->reorder_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */
ps->dpb_size = active_buffer_spec_num;
+ ps->field = frame_mbs_only_flag ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
return 0;
}
@@ -9295,36 +8923,34 @@
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int ret = 0;
- int dec_dpb_size_change = hw->csd_change_flag && (hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1));
if (ctx->param_sets_from_ucode &&
hw->res_ch_flag == 0) {
- if (((param1 != 0 &&
- hw->seq_info2 != param1) || hw->csd_change_flag) &&
- hw->seq_info2 != 0) {
- if (hw->seq_info2 != param1 || dec_dpb_size_change) { /*picture size changed*/
- struct aml_vdec_ps_infos ps;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "h264 res_change\n");
- if (vmh264_get_ps_info(hw, param1,
- param2, param3, param4, &ps) < 0) {
- dpb_print(DECODE_ID(hw), 0,
- "set parameters error\n");
- }
- hw->v4l_params_parsed = false;
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- hw->eos = 1;
- flush_dpb(p_H264_Dpb);
- //del_timer_sync(&hw->check_timer);
- notify_v4l_eos(hw_to_vdec(hw));
- ret = 1;
+ if (param1 != 0 &&
+ hw->seq_info2 != param1 &&
+ hw->seq_info2 != 0) /*picture size changed*/ {
+ struct aml_vdec_ps_infos ps;
+ dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
+ "h264 res_change\n");
+ if (vmh264_get_ps_info(hw, param1,
+ param2, param3, param4, &ps) < 0) {
+ dpb_print(DECODE_ID(hw), 0,
+ "set parameters error\n");
}
+ hw->v4l_params_parsed = false;
+ vdec_v4l_set_ps_infos(ctx, &ps);
+ vdec_v4l_res_ch_event(ctx);
+ hw->res_ch_flag = 1;
+ ctx->v4l_resolution_change = 1;
+ amvdec_stop();
+ if (hw->mmu_enable)
+ amhevc_stop();
+ hw->eos = 1;
+ flush_dpb(p_H264_Dpb);
+ //del_timer_sync(&hw->check_timer);
+ if (hw->is_used_v4l)
+ notify_v4l_eos(hw_to_vdec(hw));
+ ret = 1;
}
}
@@ -9363,13 +8989,6 @@
/* finished decoding one frame or error,
* notify vdec core to switch context
*/
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
- if (hw->dec_result == DEC_RESULT_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START);
- } else if (hw->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN);
-
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
"%s dec_result %d %x %x %x\n",
__func__,
@@ -9397,6 +9016,7 @@
if (!v4l_res_change(hw, param1, param2, param3, param4)) {
if (!hw->v4l_params_parsed) {
struct aml_vdec_ps_infos ps;
+
dpb_print(DECODE_ID(hw),
PRINT_FLAG_DEC_DETAIL,
"h264 parsered csd data\n");
@@ -9546,6 +9166,7 @@
return;
} else if (hw->dec_result == DEC_RESULT_DONE ||
hw->dec_result == DEC_RESULT_TIMEOUT) {
+
/* if (!hw->ctx_valid)
hw->ctx_valid = 1; */
hw->dec_again_cnt = 0;
@@ -9566,7 +9187,7 @@
for (i = 0; i < p_Dpb->used_size; i++) {
int i_flag = p_Dpb->fs[i]->bottom_field || p_Dpb->fs[i]->top_field;
- int threshold = (i_flag || (hw->max_reference_size >= 12)) ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size;
+ int threshold = i_flag ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size;
if ((p_Dpb->fs[i]->dpb_frame_count + threshold
< p_H264_Dpb->dpb_frame_count) &&
p_Dpb->fs[i]->is_reference &&
@@ -9610,7 +9231,17 @@
hw->gvs.b_decoded_frames++;
}
amvdec_stop();
-
+ if (!vdec_is_support_4k()) {
+ if (clk_adj_frame_count < VDEC_CLOCK_ADJUST_FRAME) {
+ clk_adj_frame_count++;
+ if (clk_adj_frame_count == VDEC_CLOCK_ADJUST_FRAME) {
+ if (hw->frame_height <= 144)
+ vdec_source_changed(VFORMAT_H264, 1920, 1080, 29);
+ else
+ vdec_source_changed(VFORMAT_H264, 3840, 2160, 60);
+ }
+ }
+ }
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s dec_result %d %x %x %x\n",
__func__,
@@ -9628,12 +9259,11 @@
frame base: vdec_prepare_input fail
*/
if (!vdec_has_more_input(vdec) && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED) && (hw->no_decoder_buffer_flag == 0)) {
+ VDEC_STATUS_DISCONNECTED)) {
hw->dec_result = DEC_RESULT_EOS;
vdec_schedule_work(&hw->work);
return;
}
-
if ((vdec_stream_based(vdec)) &&
(error_proc_policy & 0x400000) &&
check_dirty_data(vdec)) {
@@ -9641,7 +9271,6 @@
vdec_schedule_work(&hw->work);
return;
}
- hw->no_decoder_buffer_flag = 0;
hw->next_again_flag = 1;
} else if (hw->dec_result == DEC_RESULT_EOS) {
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
@@ -9670,14 +9299,12 @@
vdec_free_irq(VDEC_IRQ_1, (void *)hw);
hw->stat &= ~STAT_ISR_REG;
}
+ } else if (hw->dec_result == DEC_RESULT_DISCARD_DATA) {
+ mutex_lock(&hw->chunks_mutex);
+ vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+ hw->chunk = NULL;
+ mutex_unlock(&hw->chunks_mutex);
}
-
- if (p_H264_Dpb->mVideo.dec_picture) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, release decoded picture\n", __func__);
- release_cur_decoding_buf(hw);
- }
-
WRITE_VREG(ASSIST_MBOX1_MASK, 0);
del_timer_sync(&hw->check_timer);
hw->stat &= ~STAT_TIMER_ARM;
@@ -9685,9 +9312,7 @@
if (hw->dec_result != DEC_RESULT_AGAIN)
hw->last_picture_slice_count = 0;
#endif
- ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START);
wait_vmh264_search_done(hw);
- ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END);
/* mark itself has all HW resource released and input released */
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
@@ -9710,9 +9335,6 @@
return;
}
}
- if (hw->dec_result == DEC_RESULT_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END);
- }
/* mark itself has all HW resource released and input released */
if (vdec->parallel_dec == 1) {
@@ -9760,8 +9382,16 @@
hw->timeout_processing = 1;
vh264_work_implement(hw, vdec, 1);
+
}
+#ifdef VDEC_FCC_SUPPORT
+static void vmh264_wakeup_fcc_poll(struct vdec_s *vdec)
+{
+ amstream_wakeup_fcc_poll(vdec);
+}
+#endif
+
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
{
bool ret = 0;
@@ -9769,6 +9399,9 @@
(struct vdec_h264_hw_s *)vdec->private;
int tvp = vdec_secure(hw_to_vdec(hw)) ?
CODEC_MM_FLAGS_TVP : 0;
+#ifdef VDEC_FCC_SUPPORT
+ int get_msg = 1;
+#endif
if (hw->timeout_processing &&
(work_pending(&hw->work) || work_busy(&hw->work) ||
@@ -9841,7 +9474,7 @@
ret = is_buffer_available(vdec);
#ifdef CONSTRAIN_MAX_BUF_NUM
- if (ret && (hw->dpb.mDPB.size > 0)) { /*make sure initilized*/
+ if (hw->dpb.mDPB.size > 0) { /*make sure initilized*/
if (run_ready_max_vf_only_num > 0 &&
get_vf_ref_only_buf_count(hw) >=
run_ready_max_vf_only_num
@@ -9854,15 +9487,12 @@
/*avoid more buffers consumed when
switching resolution*/
if (run_ready_max_buf_num == 0xff &&
- get_used_buf_count(hw) >
- hw->dpb.mDPB.size)
+ !have_free_buf_spec(vdec))
ret = 0;
else if (run_ready_max_buf_num &&
get_used_buf_count(hw) >=
run_ready_max_buf_num)
ret = 0;
- if (ret == 0)
- bufmgr_h264_remove_unused_frame(&hw->dpb, 0);
}
#endif
if (hw->is_used_v4l) {
@@ -9871,12 +9501,13 @@
if (ctx->param_sets_from_ucode) {
if (hw->v4l_params_parsed) {
- if (ctx->cap_pool.dec < hw->dpb.mDPB.size) {
- if (is_buffer_available(vdec))
- ret = 1;
- else
- ret = 0;
- }
+ if (!ctx->v4l_codec_dpb_ready &&
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
+ else if (ctx->v4l_codec_dpb_ready &&
+ !is_buffer_available(vdec))
+ ret = 0;
} else {
if (ctx->v4l_resolution_change)
ret = 0;
@@ -9886,12 +9517,19 @@
run_ready_min_buf_num)
ret = 0;
}
+
}
+#ifdef VDEC_FCC_SUPPORT
+ get_msg = vdec_has_get_fcc_new_msg(vdec);
+ ret &= get_msg;
+#endif
+
if (ret)
not_run_ready[DECODE_ID(hw)] = 0;
else
not_run_ready[DECODE_ID(hw)]++;
+
if (vdec->parallel_dec == 1) {
if (hw->mmu_enable == 0)
return ret ? (CORE_MASK_VDEC_1) : 0;
@@ -9936,8 +9574,6 @@
if (hw->mmu_enable)
amhevc_enable();
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START);
-
run_count[DECODE_ID(hw)]++;
vdec_reset_core(vdec);
if (hw->mmu_enable)
@@ -9966,7 +9602,6 @@
((error_proc_policy & 0x40) &&
p_H264_Dpb->buf_alloc_fail)) {
h264_reset_bufmgr(vdec);
- //flag must clear after reset for v4l buf_spec_init use
hw->reset_bufmgr_flag = 0;
}
@@ -9998,7 +9633,6 @@
hw->dec_result = DEC_RESULT_NONE;
hw->get_data_count = 0;
- hw->csd_change_flag = 0;
#if 0
pr_info("VLD_MEM_VIFIFO_LEVEL = 0x%x, rp = 0x%x, wp = 0x%x\n",
READ_VREG(VLD_MEM_VIFIFO_LEVEL),
@@ -10068,7 +9702,7 @@
*/
WRITE_VREG(AV_SCRATCH_G, hw->reg_g_status);
} else {
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
+
ret = amvdec_vdec_loadmc_ex(VFORMAT_H264, "mh264", vdec, hw->fw->data);
if (ret < 0) {
amvdec_enable_flag = false;
@@ -10099,18 +9733,13 @@
vdec->mc_type = ((1 << 16) | VFORMAT_H264);
}
vdec->mc_loaded = 0;
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
}
vmh264_reset_udr_mgr(hw);
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
+
if (vh264_hw_ctx_restore(hw) < 0) {
vdec_schedule_work(&hw->work);
return;
}
- if (error_proc_policy & 0x10000) {
- hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num;
- }
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
if (input_frame_based(vdec)) {
int decode_size = 0;
@@ -10144,14 +9773,12 @@
WRITE_VREG(NAL_SEARCH_CTL,
READ_VREG(NAL_SEARCH_CTL) & (~0x2));
}
- WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | (1 << 2) | (hw->bitstream_restriction_flag << 15));
-
+ WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | (1 << 2));
if (udebug_flag)
WRITE_VREG(AV_SCRATCH_K, udebug_flag);
- hw->stat |= STAT_TIMER_ARM;
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) {
if (hw->mmu_enable)
SET_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3);
@@ -10176,7 +9803,6 @@
/* } */
hw->init_flag = 1;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END);
}
static void clear_refer_bufs(struct vdec_h264_hw_s *hw)
@@ -10293,12 +9919,6 @@
hw->buffer_spec[i].used = 4;
hw->buffer_spec[i].canvas_pos = -1;
-
- if (hw->buffer_spec[i].used == 4 &&
- hw->buffer_spec[i].vf_ref != 0 &&
- hw->buffer_spec[i].cma_alloc_addr) {
- hw->buffer_spec[i].used = 3;
- }
}
spin_unlock_irqrestore(&hw->bufspec_lock, flags);
hw->has_i_frame = 0;
@@ -10394,15 +10014,15 @@
__func__, hw->decode_pic_count+1,
hw->skip_frame_count);
- flush_dpb(&hw->dpb);
+ /* Only the caller from inside decoder we call flush_dbp */
+ if (!hw->reset_bufmgr_flag)
+ flush_dpb(&hw->dpb);
- if (!hw->is_used_v4l) {
- timeout = jiffies + HZ;
- while (kfifo_len(&hw->display_q) > 0) {
- if (time_after(jiffies, timeout))
- break;
- schedule();
- }
+ timeout = jiffies + HZ;
+ while (kfifo_len(&hw->display_q) > 0) {
+ if (time_after(jiffies, timeout))
+ break;
+ schedule();
}
buf_spec_init(hw, true);
@@ -10491,10 +10111,12 @@
struct vdec_h264_hw_s *hw = NULL;
char *tmpbuf;
int config_val;
+
if (pdata == NULL) {
pr_info("\nammvdec_h264 memory resource undefined.\n");
return -EFAULT;
}
+ pr_info("%s:cts test\n",__func__);
hw = (struct vdec_h264_hw_s *)h264_alloc_hw_stru(&pdev->dev,
sizeof(struct vdec_h264_hw_s), GFP_KERNEL);
@@ -10505,22 +10127,14 @@
hw->id = pdev->id;
hw->platform_dev = pdev;
- snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name),
+ snprintf(hw->vdec_name, sizeof(hw->vdec_name),
"h264-%d", hw->id);
- snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name),
- "%s-pts", hw->trace.vdec_name);
- snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name),
- "%s-newframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name),
- "%s-dispframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hw->trace.decode_header_time_name, sizeof(hw->trace.decode_header_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
+ snprintf(hw->pts_name, sizeof(hw->pts_name),
+ "%s-pts", hw->vdec_name);
+ snprintf(hw->new_q_name, sizeof(hw->new_q_name),
+ "%s-newframe_q", hw->vdec_name);
+ snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
+ "%s-dispframe_q", hw->vdec_name);
/* the ctx from v4l2 driver. */
hw->v4l2_ctx = pdata->private;
@@ -10557,7 +10171,6 @@
}
if (pdata->config_len) {
- dpb_print(DECODE_ID(hw), 0, "pdata->config=%s\n", pdata->config);
/*use ptr config for doubel_write_mode, etc*/
if (get_config_int(pdata->config,
"mh264_double_write_mode", &config_val) == 0)
@@ -10607,16 +10220,6 @@
hw->discard_dv_data = config_val;
dpb_print(DECODE_ID(hw), 0, "discard dv data\n");
}
-
- if (get_config_int(pdata->config,
- "parm_v4l_metadata_config_flag",
- &config_val) == 0) {
- hw->metadata_config_flag = config_val;
- hw->discard_dv_data = hw->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE;
- if (hw->discard_dv_data)
- dpb_print(DECODE_ID(hw), 0, "discard dv data\n");
- }
-
} else
hw->double_write_mode = double_write_mode;
@@ -10633,6 +10236,9 @@
hw->enable_fence, hw->fence_usage);
}
+ if (hw->enable_fence)
+ pdata->sync.usage = hw->fence_usage;
+
if (!hw->is_used_v4l) {
hw->reorder_dpb_size_margin = reorder_dpb_size_margin;
hw->canvas_mode = mem_map_mode;
@@ -10685,6 +10291,11 @@
pdata->user_data_read = NULL;
pdata->reset_userdata_fifo = NULL;
#endif
+
+#ifdef VDEC_FCC_SUPPORT
+ pdata->wakeup_fcc_poll = vmh264_wakeup_fcc_poll;
+#endif
+
if (pdata->use_vfm_path) {
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
VFM_DEC_PROVIDER_NAME);
@@ -10692,38 +10303,24 @@
}
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
else if (vdec_dual(pdata)) {
- if (!pdata->is_stream_mode_dv_multi) {
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
- VFM_DEC_DVEL_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
- VFM_DEC_DVBL_PROVIDER_NAME);
- } else {
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME2 :
- VFM_DEC_DVEL_PROVIDER_NAME2);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME2 :
- VFM_DEC_DVBL_PROVIDER_NAME2);
- }
+ if (dv_toggle_prov_name) /*debug purpose*/
+ snprintf(pdata->vf_provider_name,
+ VDEC_PROVIDER_NAME_SIZE,
+ (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
+ VFM_DEC_DVEL_PROVIDER_NAME);
+ else
+ snprintf(pdata->vf_provider_name,
+ VDEC_PROVIDER_NAME_SIZE,
+ (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
+ VFM_DEC_DVBL_PROVIDER_NAME);
}
#endif
else
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
PROVIDER_NAME ".%02x", pdev->id & 0xff);
- if (!hw->is_used_v4l)
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vf_provider_ops, pdata);
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vf_provider_ops, pdata);
platform_set_drvdata(pdev, pdata);
@@ -10746,7 +10343,7 @@
DCAC_READ_MARGIN;
if (hw->mmu_enable) {
u32 extif_size = EXTIF_BUF_SIZE;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A)
extif_size <<= 1;
if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_EXTIF_IDX,
extif_size, DRIVER_NAME, &hw->extif_addr) < 0) {
@@ -10809,8 +10406,19 @@
dpb_print(DECODE_ID(hw), 0, "ammvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx\n",
pdata->mem_start, hw->buf_offset, hw->cma_alloc_addr);
- vdec_source_changed(VFORMAT_H264, 3840, 2160, 60);
-
+ if (vdec_is_support_4k() ||
+ (clk_adj_frame_count > (VDEC_CLOCK_ADJUST_FRAME - 1)))
+ vdec_source_changed(VFORMAT_H264, 3840, 2160, 60);
+ else if (pdata->sys_info->height * pdata->sys_info->width < 1280 * 720)
+ {
+ vdec_source_changed(VFORMAT_H264, 1280, 720, 29);
+ } else if (pdata->sys_info->height * pdata->sys_info->width < 1920 * 1080)
+ {
+ vdec_source_changed(VFORMAT_H264, 1920, 1080, 29);
+ } else
+ {
+ vdec_source_changed(VFORMAT_H264, 3840, 2160, 60);
+ }
if (hw->mmu_enable)
hevc_source_changed(VFORMAT_HEVC, 3840, 2160, 60);
@@ -10848,19 +10456,10 @@
display_frame_count[DECODE_ID(hw)] = 0;
decode_frame_count[DECODE_ID(hw)] = 0;
hw->dpb.without_display_mode = without_display_mode;
- mutex_init(&hw->fence_mutex);
+
if (hw->enable_fence) {
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- dpb_print(DECODE_ID(hw), 0, "alloc fence timeline error\n");
- ammvdec_h264_mmu_release(hw);
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- pdata->sync->usage = hw->fence_usage;
/* creat timeline. */
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
+ vdec_timeline_create(&pdata->sync, DRIVER_NAME);
}
return 0;
@@ -10870,6 +10469,7 @@
struct vdec_sync *sync)
{
ulong expires;
+ int i;
/* clear display pool. */
clear_refer_bufs(hw);
@@ -10885,7 +10485,14 @@
}
}
- pr_info("fence start release\n");
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i];
+
+ if (vf->fence) {
+ vdec_fence_put(vf->fence);
+ vf->fence = NULL;
+ }
+ }
/* decreases refcnt of timeline. */
vdec_timeline_put(sync);
@@ -10959,7 +10566,7 @@
}
if (hw->enable_fence)
- vdec_fence_release(hw, vdec->sync);
+ vdec_fence_release(hw, &vdec->sync);
ammvdec_h264_mmu_release(hw);
h264_free_hw_stru(&pdev->dev, (void *)hw);
@@ -10969,16 +10576,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mh264_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mh264_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mh264_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mh264_suspend, mh264_resume)
+};
+#endif
static struct platform_driver ammvdec_h264_driver = {
.probe = ammvdec_h264_probe,
.remove = ammvdec_h264_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mh264_pm_ops,
+#endif
}
};
@@ -11017,7 +10640,6 @@
static int __init ammvdec_h264_driver_init_module(void)
{
-
pr_info("ammvdec_h264 module init\n");
if (platform_driver_register(&ammvdec_h264_driver)) {
pr_info("failed to register ammvdec_h264 driver\n");
@@ -11027,25 +10649,15 @@
if (vdec_is_support_4k()) {
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX) {
ammvdec_h264_profile.profile =
- "4k, dwrite, compressed, frame_dv, fence, v4l";
+ "4k, dwrite, compressed, frame_dv, fence";
} else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB) {
- ammvdec_h264_profile.profile = "4k, frame_dv, fence, v4l";
- }
- } else {
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) {
- ammvdec_h264_profile.profile =
- "dwrite, compressed, frame_dv, v4l";
- } else {
- ammvdec_h264_profile.profile =
- "dwrite, compressed, v4l";
+ ammvdec_h264_profile.profile = "4k, frame_dv, fence";
}
}
vcodec_profile_register(&ammvdec_h264_profile);
INIT_REG_NODE_CONFIGS("media.decoder", &hm264_node,
"mh264", hm264_configs, CONFIG_FOR_RW);
-
- vcodec_feature_register(VFORMAT_H264, 0);
return 0;
}
@@ -11206,9 +10818,6 @@
module_param(stream_mode_start_num, uint, 0664);
MODULE_PARM_DESC(stream_mode_start_num, "\n stream_mode_start_num\n");
-module_param(colocate_old_cal, uint, 0664);
-MODULE_PARM_DESC(colocate_old_cal, "\n amvdec_mh264 colocate_old_cal\n");
-
/*
module_param(trigger_task, uint, 0664);
MODULE_PARM_DESC(trigger_task, "\n amvdec_h264 trigger_task\n");
diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c
old mode 100644
new mode 100755
index d5945ce..2e9bafc
--- a/drivers/frame_provider/decoder/h265/vh265.c
+++ b/drivers/frame_provider/decoder/h265/vh265.c
@@ -38,10 +38,7 @@
#include <linux/dma-contiguous.h>
#include <linux/slab.h>
#include <linux/mm.h>
-#include <linux/timer.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../utils/decoder_mmu_box.h"
@@ -60,8 +57,6 @@
#define HEVC_8K_LFTOFFSET_FIX
#define SUPPORT_LONG_TERM_RPS
-//#define CO_MV_COMPRESS
-
#define CONSTRAIN_MAX_BUF_NUM
#define SWAP_HEVC_UCODE
@@ -86,7 +81,7 @@
#define DB_NUM 20
#define MAX_FRAME_4K_NUM 0x1200
-#define MAX_FRAME_8K_NUM ((MAX_FRAME_4K_NUM) * 4)
+#define MAX_FRAME_8K_NUM (0x1200*4)
//#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)
#define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
@@ -94,16 +89,8 @@
#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_CM_HEADER_START_ADDR2 0x364a
#define HEVC_SAO_MMU_VH1_ADDR 0x363b
#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
-
-#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
-#define HEVC_SAO_MMU_STATUS2 0x3650
-#define HEVC_DW_VH0_ADDDR 0x365e
-#define HEVC_DW_VH1_ADDDR 0x365f
#define HEVC_DBLK_CFGB 0x350b
#define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7
@@ -117,11 +104,9 @@
#include "../utils/amvdec.h"
#include <linux/amlogic/media/video_sink/video.h>
#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../utils/vdec_feature.h"
#define SEND_LMEM_WITH_RPM
#define SUPPORT_10BIT
-#define H265_10B_MMU_DW
/* #define ERROR_HANDLE_DEBUG */
#ifndef STAT_KTHREAD
@@ -148,7 +133,6 @@
#define MAX_SIZE_8K (8192 * 4608)
#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
@@ -183,11 +167,10 @@
#endif
static void vh265_prot_init(struct hevc_state_s *hevc);
static int vh265_local_init(struct hevc_state_s *hevc);
-static void vh265_check_timer_func(struct timer_list *timer);
+static void vh265_check_timer_func(unsigned long arg);
static void config_decode_mode(struct hevc_state_s *hevc);
static int check_data_size(struct vdec_s *vdec);
-
static const char vh265_dec_id[] = "vh265-dev";
#define PROVIDER_NAME "decoder.h265"
@@ -256,11 +239,6 @@
#define HEVC_CM_HEADER_LENGTH 0x3629
#define HEVC_CM_HEADER_OFFSET 0x362b
#define HEVC_SAO_CTRL9 0x362d
-
-#define HEVC_CM_BODY_LENGTH2 0x3663
-#define HEVC_CM_HEADER_OFFSET2 0x3664
-#define HEVC_CM_HEADER_LENGTH2 0x3665
-
#define LOSLESS_COMPRESS_MODE
/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
/* double_write_mode:
@@ -270,7 +248,6 @@
* 3, (1/4):(1/4) ratio, with both compressed frame included
* 4, (1/2):(1/2) ratio;
* 5, (1/2):(1/2) ratio, with both compressed frame included
- * 8, (1/8):(1/8) ratio, from t7
* 0x10, double write only
* 0x100, if > 1080p,use mode 4,else use mode 1;
* 0x200, if > 1080p,use mode 2,else use mode 1;
@@ -353,14 +330,7 @@
static u32 dbg_cmd;
static u32 dump_nal;
static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
+static u32 endian = 0xff0;
#ifdef ERROR_HANDLE_DEBUG
static u32 dbg_nal_skip_flag;
/* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
@@ -504,7 +474,8 @@
*bit 9: 0, discard dirty data on playback start
* 1, do not discard dirty data on playback start
*bit 10:0, when ucode always returns again, it supports discarding data
- * 1, When ucode always returns again, it does not support discarding data
+ * 1, When ucode always returns again, it does not support discarding data
+ *
*/
static u32 error_handle_policy;
@@ -989,10 +960,6 @@
struct buff_s dblk_data2;
struct buff_s mmu_vbh;
struct buff_s cm_header;
-#ifdef H265_10B_MMU_DW
- struct buff_s mmu_vbh_dw;
- struct buff_s cm_header_dw;
-#endif
struct buff_s mpred_above;
#ifdef MV_USE_FIXED_BUF
struct buff_s mpred_mv;
@@ -1004,7 +971,7 @@
//#define VBH_BUF_SIZE (2 * 16 * 2304)
//#define VBH_BUF_COUNT 4
-/*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
+ /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
#define VBH_BUF_SIZE_1080P 0x3000
#define VBH_BUF_SIZE_4K 0x5000
#define VBH_BUF_SIZE_8K 0xa000
@@ -1016,288 +983,12 @@
#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
+#define WORK_BUF_SPEC_NUM 3
static struct BuffInfo_s amvh265_workbuff_spec[WORK_BUF_SPEC_NUM] = {
{
/* 8M bytes */
.max_width = 1920,
.max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
-#ifdef SUPPORT_10BIT
- .buf_size = 0x40000,
-#else
- /* DBLK -> Max 256(4096/16) LCU, each para
- *512bytes(total:0x20000), data 1024bytes(total:0x40000)
- */
- .buf_size = 0x20000,
-#endif
- },
- .dblk_data = {
- .buf_size = 0x40000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000 * 2,
- }, /*dblk data for adapter*/
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2048,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x1e00,
- },
- .sao_abv = {
- .buf_size = 0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0, //0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU, each para
- * 512bytes(total:0x20000),
- * data 1024bytes(total:0x40000)
- */
- .buf_size = 0x20000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000,
- }, /*dblk data for adapter*/
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- }
- },
-
- {
- .max_width = 4096*2,
- .max_height = 2048*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0x30000*2,
- },
- .sao_vb = {
- .buf_size = 0x30000*2,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x2800*2,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x8000*2,
- },
- .dblk_para = {.buf_size = 0x40000*2, }, // dblk parameter
- .dblk_data = {.buf_size = 0x80000*2, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x80000*2, }, // dblk data for adapter
- .mmu_vbh = {
- .buf_size = 0x5000*2, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header = {
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE *
- MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000*2,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- },
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
.ipp = {/*checked*/
/* IPP work space calculation :
* 4096 * (Y+CbCr+Flags) = 12k, round to 16k
@@ -1367,16 +1058,6 @@
(MAX_REF_PIC_NUM + 1),
},
#endif
-#ifdef H265_10B_MMU_DW
- .mmu_vbh_dw = {/*checked*/
- .buf_size = DW_VBH_BUF_SIZE_1080P, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*2304/4, 4K
- },
-#ifdef USE_FIXED_MMU_DW_HEADER
- .cm_header_dw = {/*checked*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {/*checked*/
.buf_size = 0x1e00,
},
@@ -1454,7 +1135,7 @@
},
.dblk_para = {.buf_size = 0x19100, }, // dblk parameter
.dblk_data = {.buf_size = 0x88800, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x48800, }, // dblk data for adapter
+ .dblk_data2 = {.buf_size = 0x80000, }, // dblk data for adapter
.mmu_vbh = {
.buf_size = VBH_BUF_SIZE_4K, /*2*16*2304/4, 4K*/
},
@@ -1464,16 +1145,6 @@
(MAX_REF_PIC_NUM + 1),
},
#endif
-#ifdef H265_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_4K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K
- },
-#ifdef USE_FIXED_MMU_DW_HEADER
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_4K * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x4000,
},
@@ -1549,16 +1220,6 @@
MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
},
#endif
-#ifdef H265_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_8K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*2304/4, 4K
- },
-#ifdef USE_FIXED_MMU_DW_HEADER
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_8K * DB_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x8000,
},
@@ -1579,66 +1240,64 @@
static void init_buff_spec(struct hevc_state_s *hevc,
struct BuffInfo_s *buf_spec)
{
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
+ buf_spec->ipp.buf_start = buf_spec->start_adr;
buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+ buf_spec->ipp.buf_start + buf_spec->ipp.buf_size;
+
buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+ buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size;
buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+ buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size;
buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+ buf_spec->short_term_rps.buf_start +
+ buf_spec->short_term_rps.buf_size;
buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
+ buf_spec->vps.buf_start + buf_spec->vps.buf_size;
buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+ buf_spec->sps.buf_start + buf_spec->sps.buf_size;
buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+ buf_spec->pps.buf_start + buf_spec->pps.buf_size;
buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+ buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size;
buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+ buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size;
buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+ buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size;
buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+ buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size;
buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+ buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size;
buf_spec->dblk_data2.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+ buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size;
buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
-#ifdef H265_10B_MMU_DW
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
- buf_spec->cm_header_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
+ buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size;
buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size);
-#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-#endif
+ buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size;
#ifdef MV_USE_FIXED_BUF
buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+ buf_spec->mpred_mv.buf_start +
+ buf_spec->mpred_mv.buf_size;
#else
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
#endif
buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->rpm.buf_start +
+ buf_spec->rpm.buf_size;
buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+ buf_spec->lmem.buf_start +
+ buf_spec->lmem.buf_size;
if (hevc && get_dbg_flag2(hevc)) {
hevc_print(hevc, 0,
- "%s workspace (%x %x) size = %x\n", __func__,
- buf_spec->start_adr, buf_spec->end_adr,
- buf_spec->end_adr - buf_spec->start_adr);
+ "%s workspace (%x %x) size = %x\n", __func__,
+ buf_spec->start_adr, buf_spec->end_adr,
+ buf_spec->end_adr - buf_spec->start_adr);
hevc_print(hevc, 0,
"ipp.buf_start :%x\n",
@@ -1682,14 +1341,6 @@
hevc_print(hevc, 0,
"dblk_data2.buf_start :%x\n",
buf_spec->dblk_data2.buf_start);
-#ifdef H265_10B_MMU_DW
- hevc_print(hevc, 0,
- "mmu_vbh_dw.buf_start :%x\n",
- buf_spec->mmu_vbh_dw.buf_start);
- hevc_print(hevc, 0,
- "cm_header_dw.buf_start :%x\n",
- buf_spec->cm_header_dw.buf_start);
-#endif
hevc_print(hevc, 0,
"mpred_above.buf_start :%x\n",
buf_spec->mpred_above.buf_start);
@@ -1776,9 +1427,6 @@
unsigned int dw_y_adr;
unsigned int dw_u_v_adr;
#endif
- u32 luma_size;
- u32 chroma_size;
-
int mc_canvas_y;
int mc_canvas_u_v;
int width;
@@ -1797,9 +1445,6 @@
#ifdef LOSLESS_COMPRESS_MODE
unsigned int losless_comp_body_size;
#endif
-#ifdef H265_10B_MMU_DW
- u32 header_dw_adr;
-#endif
unsigned char pic_struct;
int vf_ref;
@@ -1832,10 +1477,11 @@
u32 hw_decode_time;
u32 frame_size; // For frame base mode
+ bool vframe_bound;
bool ip_mode;
u32 hdr10p_data_size;
char *hdr10p_data_buf;
- struct dma_fence *fence;
+ struct fence *fence;
bool show_frame;
} /*PIC_t */;
@@ -1854,8 +1500,6 @@
#define SEI_MASTER_DISPLAY_COLOR_MASK 0x00000001
#define SEI_CONTENT_LIGHT_LEVEL_MASK 0x00000002
#define SEI_HDR10PLUS_MASK 0x00000004
-#define SEI_HDR_CUVA_MASK 0x00000008
-
#define VF_POOL_SIZE 32
@@ -1872,6 +1516,7 @@
#define DEC_RESULT_EOS 9
#define DEC_RESULT_FORCE_EXIT 10
#define DEC_RESULT_FREE_CANVAS 11
+#define DEC_RESULT_DISCARD_DATA 12
static void vh265_work(struct work_struct *work);
@@ -1885,11 +1530,6 @@
uint8_t data; /*will alloc more size*/
};
-struct mh265_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
struct hevc_state_s {
#ifdef MULTI_INSTANCE_SUPPORT
struct platform_device *platform_dev;
@@ -2116,12 +1756,6 @@
void *mmu_box;
void *bmmu_box;
int mmu_enable;
-#ifdef H265_10B_MMU_DW
- void *frame_dw_mmu_map_addr;
- dma_addr_t frame_dw_mmu_map_phy_addr;
- void *mmu_box_dw;
- int dw_mmu_enable;
-#endif
unsigned int dec_status;
@@ -2147,8 +1781,8 @@
u32 start_shift_bytes;
u32 vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
+ u32 vf_get_count;
+ u32 vf_put_count;
#ifdef SWAP_HEVC_UCODE
dma_addr_t mc_dma_handle;
void *mc_cpu_addr;
@@ -2178,7 +1812,6 @@
u32 skip_nal_count;
bool is_swap;
bool is_4k;
-
int frameinfo_enable;
struct vframe_qos_s vframe_qos;
bool is_used_v4l;
@@ -2187,6 +1820,7 @@
u32 mem_map_mode;
u32 performance_profile;
struct vdec_info *gvs;
+ u32 res_ch_flag;
bool ip_mode;
u32 kpi_first_i_comming;
u32 kpi_first_i_decoded;
@@ -2201,21 +1835,18 @@
bool discard_dv_data;
bool enable_fence;
int fence_usage;
- int buffer_wrap[MAX_REF_PIC_NUM];
int low_latency_flag;
- u32 metadata_config_flag;
- int last_width;
- int last_height;
- int used_buf_num;
u32 dirty_shift_flag;
- u32 endian;
- ulong fb_token;
+ char vdec_name[32];
+ char set_canvas0_addr[32];
+ char get_canvas0_addr[32];
+ char put_canvas0_addr[32];
+ char vf_put_name[32];
+ char vf_get_name[32];
+ char new_q_name[32];
+ char disp_q_name[32];
+ char pts_name[32];
int dec_again_cnt;
- struct mh265_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- struct trace_decoder_name trace;
} /*hevc_stru_t */;
#ifdef AGAIN_HAS_THRESHOLD
@@ -2239,9 +1870,6 @@
int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
MAX_SIZE_8K : MAX_SIZE_4K;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
if (w < 0 || h < 0)
return true;
@@ -2307,7 +1935,7 @@
#ifdef SUPPORT_10BIT
/* Losless compression body buffer size 4K per 64x32 (jt) */
-static int compute_losless_comp_body_size(struct hevc_state_s *hevc,
+static int compute_losless_comp_body_size(struct hevc_state_s *hevc,
int width, int height, int mem_saving_mode)
{
int width_x64;
@@ -2330,7 +1958,7 @@
}
/* Losless compression header buffer size 32bytes per 128x64 (jt) */
-static int compute_losless_comp_header_size(int width, int height)
+static int compute_losless_comp_header_size(int width, int height)
{
int width_x128;
int height_x64;
@@ -2414,18 +2042,10 @@
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
static int get_valid_double_write_mode(struct hevc_state_s *hevc)
{
- u32 dw = (hevc->m_ins_flag &&
+ return (hevc->m_ins_flag &&
((double_write_mode & 0x80000000) == 0)) ?
hevc->double_write_mode :
(double_write_mode & 0x7fffffff);
- if (dw & 0x20) {
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
- && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) {
- pr_info("MMU doueble write 1:4 not supported !!!\n");
- dw = 0;
- }
- }
- return dw;
}
static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc)
@@ -2443,15 +2063,30 @@
int w = hevc->pic_w;
int h = hevc->pic_h;
u32 dw = 0x1; /*1:1*/
-
- if (hevc->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(hevc->v4l2_ctx, &out);
- dw = out;
- return dw;
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 720)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ dw = valid_dw_mode;
+ break;
}
+ return dw;
+}
+static int v4l_parser_get_double_write_mode(struct hevc_state_s *hevc, int w, int h)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(hevc);
+ u32 dw = 0x1; /*1:1*/
switch (valid_dw_mode) {
case 0x100:
if (w > 1920 && h > 1088)
@@ -2480,6 +2115,19 @@
return dw;
}
+
+static int get_double_write_ratio(struct hevc_state_s *hevc,
+ int dw_mode)
+{
+ int ratio = 1;
+ if ((dw_mode == 2) ||
+ (dw_mode == 3))
+ ratio = 4;
+ else if ((dw_mode == 4) ||
+ (dw_mode == 5))
+ ratio = 2;
+ return ratio;
+}
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
static unsigned char get_idx(struct hevc_state_s *hevc)
{
@@ -2492,7 +2140,7 @@
static int hevc_print(struct hevc_state_s *hevc,
int flag, const char *fmt, ...)
{
-#define HEVC_PRINT_BUF 512
+#define HEVC_PRINT_BUF 256
unsigned char buf[HEVC_PRINT_BUF];
int len = 0;
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
@@ -2591,7 +2239,7 @@
release_aux_data(hevc, hevc->decoding_pic);
hevc->decoding_pic = NULL;
}
- /*if (vdec_stream_based(vdec) &&
+ if (vdec_stream_based(vdec) &&
(hevc->decode_idx - hevc->decode_idx_bak > 1)) {
int i;
hevc_print(hevc, 0, "decode_idx %d, decode_idx_bak %d\n",
@@ -2617,7 +2265,7 @@
release_aux_data(hevc, pic);
}
}
- }*/
+ }
hevc->decode_idx = hevc->decode_idx_bak;
hevc->m_pocRandomAccess = hevc->m_pocRandomAccess_bak;
hevc->curr_POC = hevc->curr_POC_bak;
@@ -2743,10 +2391,6 @@
static int H265_alloc_mmu(struct hevc_state_s *hevc,
struct PIC_s *new_pic, unsigned short bit_depth,
unsigned int *mmu_index_adr);
-#ifdef H265_10B_MMU_DW
-static int H265_alloc_mmu_dw(struct hevc_state_s *hevc, struct PIC_s *new_pic,
- unsigned short bit_depth, unsigned int *mmu_index_adr);
-#endif
#ifdef DETREFILL_ENABLE
#define DETREFILL_BUF_SIZE (4 * 0x4000)
@@ -2943,7 +2587,7 @@
uint16_t ctuy = (ctuPosition>> 0) & 0xffff;
int32_t aboveCtuAvailable = (ctuy) ? 1 : 0;
- uint16_t *cmBodyBuf = NULL;
+ uint16_t cmBodyBuf[32 * 18];
uint32_t pic_width_x64_pre = picWidth + 0x3f;
uint32_t pic_width_x64 = pic_width_x64_pre >> 6;
@@ -2965,10 +2609,6 @@
int32_t blkIdx;
- cmBodyBuf = vzalloc(sizeof(uint16_t) * 32 * 18);
- if (!cmBodyBuf)
- return;
-
WRITE_VREG(HEVC_SAO_CTRL10, cmHeaderAddrAbv);
WRITE_VREG(HEVC_SAO_CTRL11, cmHeaderAddrCur);
WRITE_VREG(HEVC_SAO_DBG_MODE0, hevc->detbuf_adr);
@@ -3087,7 +2727,6 @@
} while (tmpData32);
hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
"%s, %d\n", __func__, __LINE__);
- vfree(cmBodyBuf);
}
static void delrefill(struct hevc_state_s *hevc)
@@ -3153,18 +2792,17 @@
struct PIC_s *pic;
int i;
- for (i = 0; i < hevc->used_buf_num; i++) {
+ for (i = 0; i < MAX_REF_PIC_NUM; i++) {
pic = hevc->m_PIC[i];
- if ((pic == NULL) ||
- (pic->index == -1) ||
- (pic->BUF_index == -1))
+ if (pic == NULL ||
+ pic->index == -1 ||
+ pic->BUF_index == -1)
continue;
- if ((pic->output_mark == 0) &&
- (pic->referenced == 0) &&
- (pic->output_ready == 0) &&
- (pic->vf_ref == 0) &&
- (pic->cma_alloc_addr)) {
+ if (pic->output_mark == 0 &&
+ pic->referenced == 0 &&
+ pic->output_ready == 0 &&
+ pic->cma_alloc_addr) {
pic->output_ready = 1;
index = i;
break;
@@ -3239,46 +2877,80 @@
static int init_buf_spec(struct hevc_state_s *hevc);
+static bool v4l_is_there_vframe_bound(struct hevc_state_s *hevc)
+{
+ int i;
+
+ for (i = 0; i < MAX_REF_PIC_NUM; i++) {
+ struct PIC_s *pic = hevc->m_PIC[i];
+
+ if (pic && pic->vframe_bound)
+ return true;
+ }
+
+ return false;
+}
+
+static void v4l_mmu_buffer_release(struct hevc_state_s *hevc)
+{
+ int i;
+
+ /* release workspace */
+ if (hevc->bmmu_box)
+ decoder_bmmu_box_free_idx(hevc->bmmu_box,
+ BMMU_WORKSPACE_ID);
+ /*
+ * it's only when vframe get back to driver, right now we can be sure
+ * that vframe and fd are related. if the playback exits, the capture
+ * requires the upper app to release when the fd is closed, and others
+ * buffers drivers are released by driver.
+ */
+ for (i = 0; i < MAX_REF_PIC_NUM; i++) {
+ struct PIC_s *pic = hevc->m_PIC[i];
+
+ if (pic && !pic->vframe_bound) {
+ if (hevc->bmmu_box)
+ decoder_bmmu_box_free_idx(hevc->bmmu_box,
+ VF_BUFFER_IDX(i));
+ if (hevc->mmu_box)
+ decoder_mmu_box_free_idx(hevc->mmu_box, i);
+
+ hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
+ "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n",
+ __func__, i, hevc->bmmu_box, hevc->mmu_box);
+ }
+ }
+}
static void uninit_mmu_buffers(struct hevc_state_s *hevc)
{
- if (hevc->mmu_box) {
+ if (hevc->is_used_v4l &&
+ v4l_is_there_vframe_bound(hevc)) {
+ if (get_double_write_mode(hevc) != 0x10) {
+ v4l_mmu_buffer_release(hevc);
+ return;
+ }
+ }
+
+ if (hevc->mmu_box)
decoder_mmu_box_free(hevc->mmu_box);
- hevc->mmu_box = NULL;
- }
-#ifdef H265_10B_MMU_DW
- if (hevc->mmu_box_dw) {
- decoder_mmu_box_free(hevc->mmu_box_dw);
- hevc->mmu_box_dw = NULL;
- }
-#endif
- if (hevc->bmmu_box) {
- /* release workspace */
- decoder_bmmu_box_free_idx(hevc->bmmu_box,
- BMMU_WORKSPACE_ID);
+ hevc->mmu_box = NULL;
+
+ if (hevc->bmmu_box)
decoder_bmmu_box_free(hevc->bmmu_box);
- hevc->bmmu_box = NULL;
- }
+ hevc->bmmu_box = NULL;
}
-/* return in MB */
-static int hevc_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 64;
-
- if ((max_w * max_h) > 0 &&
- (max_w * max_h) <= 1920*1088) {
- buf_size = 24;
- }
- return buf_size;
-}
-
-static int init_mmu_buffers(struct hevc_state_s *hevc, int bmmu_flag)
+static int init_mmu_box(struct hevc_state_s *hevc)
{
int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ?
CODEC_MM_FLAGS_TVP : 0;
- int buf_size = hevc_max_mmu_buf_size(hevc->max_pic_w,
- hevc->max_pic_h);
+ int buf_size = 64;
+
+ if ((hevc->max_pic_w * hevc->max_pic_h) > 0 &&
+ (hevc->max_pic_w * hevc->max_pic_h) <= 1920*1088) {
+ buf_size = 24;
+ }
if (get_dbg_flag(hevc)) {
hevc_print(hevc, 0, "%s max_w %d max_h %d\n",
@@ -3287,7 +2959,43 @@
hevc->need_cache_size = buf_size * SZ_1M;
hevc->sc_start_time = get_jiffies_64();
- if (hevc->mmu_enable && !hevc->is_used_v4l) {
+ if (hevc->mmu_enable
+ && ((get_double_write_mode(hevc) & 0x10) == 0)) {
+ hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
+ hevc->index,
+ MAX_REF_PIC_NUM,
+ buf_size * SZ_1M,
+ tvp_flag
+ );
+ if (!hevc->mmu_box) {
+ hevc_print(hevc, 0, "h265 alloc mmu box failed!!\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int init_mmu_buffers(struct hevc_state_s *hevc)
+{
+ int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ?
+ CODEC_MM_FLAGS_TVP : 0;
+ int buf_size = 64;
+
+ if ((hevc->max_pic_w * hevc->max_pic_h) > 0 &&
+ (hevc->max_pic_w * hevc->max_pic_h) <= 1920*1088) {
+ buf_size = 24;
+ }
+
+ if (get_dbg_flag(hevc)) {
+ hevc_print(hevc, 0, "%s max_w %d max_h %d\n",
+ __func__, hevc->max_pic_w, hevc->max_pic_h);
+ }
+
+ hevc->need_cache_size = buf_size * SZ_1M;
+ hevc->sc_start_time = get_jiffies_64();
+ if (hevc->mmu_enable
+ && ((get_double_write_mode(hevc) & 0x10) == 0)) {
hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
hevc->index,
MAX_REF_PIC_NUM,
@@ -3298,21 +3006,7 @@
pr_err("h265 alloc mmu box failed!!\n");
return -1;
}
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- hevc->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME,
- hevc->index,
- MAX_REF_PIC_NUM,
- buf_size * SZ_1M,
- tvp_flag
- );
- if (!hevc->mmu_box_dw)
- goto dw_mmu_box_failed;
- }
-#endif
}
- if (bmmu_flag)
- return 0;
hevc->bmmu_box = decoder_bmmu_box_alloc_box(DRIVER_NAME,
hevc->index,
@@ -3321,23 +3015,14 @@
CODEC_MM_FLAGS_CMA_CLEAR |
CODEC_MM_FLAGS_FOR_VDECODER |
tvp_flag);
- if (!hevc->bmmu_box)
- goto bmmu_box_failed;
-
- return 0;
-bmmu_box_failed:
-#ifdef H265_10B_MMU_DW
- if (hevc->mmu_box_dw)
- decoder_mmu_box_free(hevc->mmu_box_dw);
- hevc->mmu_box_dw = NULL;
-dw_mmu_box_failed:
-#endif
- if (hevc->mmu_box) {
- decoder_mmu_box_free(hevc->mmu_box);
+ if (!hevc->bmmu_box) {
+ if (hevc->mmu_box)
+ decoder_mmu_box_free(hevc->mmu_box);
+ hevc->mmu_box = NULL;
+ pr_err("h265 alloc mmu box failed!!\n");
+ return -1;
}
- hevc->mmu_box = NULL;
- pr_err("h265 %s failed!!\n", __func__);
- return -1;
+ return 0;
}
struct buf_stru_s
@@ -3355,7 +3040,7 @@
if (hevc->m_mv_BUF[i].start_adr) {
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
hevc_print(hevc, 0,
- "dealloc mv buf(%d) adr 0x%p size 0x%x used_flag %d\n",
+ "dealloc mv buf(%d) adr 0x%lx size 0x%x used_flag %d\n",
i, hevc->m_mv_BUF[i].start_adr,
hevc->m_mv_BUF[i].size,
hevc->m_mv_BUF[i].used_flag);
@@ -3553,20 +3238,10 @@
#endif
}
-static int hevc_get_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(w, h)))
- return MMU_COMPRESS_HEADER_SIZE_8K;
- else if (IS_4K_SIZE(w, h))
- return MMU_COMPRESS_HEADER_SIZE_4K;
- else
- return MMU_COMPRESS_HEADER_SIZE_1080P;
-}
-
static int cal_current_buf_size(struct hevc_state_s *hevc,
struct buf_stru_s *buf_stru)
{
+
int buf_size;
int pic_width = hevc->pic_w;
int pic_height = hevc->pic_h;
@@ -3588,21 +3263,22 @@
int dw_mode = get_double_write_mode(hevc);
- if (hevc->mmu_enable)
- buf_size = hevc_get_header_size(hevc->pic_w, hevc->pic_h);
- else
+ if (hevc->mmu_enable) {
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ (IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
+ buf_size = ((MMU_COMPRESS_HEADER_SIZE_8K + 0xffff) >> 16)
+ << 16;
+ else
+ buf_size = ((MMU_COMPRESS_HEADER_SIZE_4K + 0xffff) >> 16)
+ << 16;
+ } else
buf_size = 0;
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- buf_size = ((buf_size + 0xffff) >> 16) << 16;
- buf_size <<= 1;
- }
-#endif
- if (dw_mode && ((dw_mode & 0x20) == 0)) {
+
+ if (dw_mode) {
int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(hevc, dw_mode);
int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
+ get_double_write_ratio(hevc, dw_mode);
int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
pic_width_dw / lcu_size + 1 :
@@ -3643,48 +3319,40 @@
return buf_size;
}
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct hevc_state_s *hevc,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct hevc_state_s *hevc, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- hevc->m_BUF[index].v4l_ref_buf_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
{
int ret = -1;
int i = pic->index;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hevc->v4l2_ctx;
struct vdec_v4l2_buffer *fb = NULL;
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hevc->fb_token, &fb, AML_FB_REQ_DEC);
+ if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
+ return ret;
+
+ ret = vdec_v4l_get_buffer(hevc->v4l2_ctx, &fb);
if (ret < 0) {
- hevc_print(hevc, 0, "[%d] H265 get buffer fail.\n", ctx->id);
+ hevc_print(hevc, 0, "[%d] H265 get buffer fail.\n",
+ ((struct aml_vcodec_ctx *)(hevc->v4l2_ctx))->id);
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (hevc->mmu_enable) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hevc, fb);
- hevc->m_BUF[i].header_addr = ibuf->header_addr;
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ (IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
+ hevc->m_BUF[i].header_size =
+ ALIGN(MMU_COMPRESS_HEADER_SIZE_8K, 0x10000);
+ else
+ hevc->m_BUF[i].header_size =
+ ALIGN(MMU_COMPRESS_HEADER_SIZE_4K, 0x10000);
+
+ ret = decoder_bmmu_box_alloc_buf_phy(hevc->bmmu_box,
+ VF_BUFFER_IDX(i), hevc->m_BUF[i].header_size,
+ DRIVER_NAME, &hevc->m_BUF[i].header_addr);
+ if (ret < 0) {
+ hevc_print(hevc, PRINT_FLAG_ERROR,
+ "%s[%d], header size: %d, no mem fatal err\n",
+ __func__, i, hevc->m_BUF[i].header_size);
+ return ret;
+ }
}
hevc->m_BUF[i].used_flag = 0;
@@ -3697,8 +3365,6 @@
fb->m.mem[0].bytes_used = fb->m.mem[0].size;
pic->dw_y_adr = hevc->m_BUF[i].start_adr;
pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size;
- pic->luma_size = fb->m.mem[0].offset;
- pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset;
} else if (fb->num_planes == 2) {
hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
hevc->m_BUF[i].luma_size = fb->m.mem[0].size;
@@ -3709,8 +3375,6 @@
fb->m.mem[1].bytes_used = fb->m.mem[1].size;
pic->dw_y_adr = hevc->m_BUF[i].start_adr;
pic->dw_u_v_adr = hevc->m_BUF[i].chroma_addr;
- pic->luma_size = fb->m.mem[0].size;
- pic->chroma_size = fb->m.mem[1].size;
}
return ret;
@@ -3721,7 +3385,6 @@
int i;
int ret = -1;
int buf_size = cal_current_buf_size(hevc, NULL);
- struct vdec_s *vdec = hw_to_vdec(hevc);
if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
return ret;
@@ -3749,11 +3412,6 @@
}
if (ret >= 0) {
- if (hevc->enable_fence) {
- vdec_fence_buffer_count_increase((ulong)vdec->sync);
- INIT_LIST_HEAD(&vdec->sync->release_callback[VF_BUFFER_IDX(i)].node);
- decoder_bmmu_box_add_callback_func(hevc->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[VF_BUFFER_IDX(i)]);
- }
hevc->m_BUF[i].size = buf_size;
hevc->m_BUF[i].used_flag = 0;
ret = 0;
@@ -3788,7 +3446,7 @@
if (ret >= 0) {
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
hevc_print(hevc, 0,
- "alloc buf(%d) for %d/%d size 0x%x) => %p\n",
+ "alloc buf(%d) for %d/%d size 0x%x) => %lx\n",
i, hevc->pic_w, hevc->pic_h,
buf_size,
hevc->m_BUF[i].start_adr);
@@ -3818,7 +3476,7 @@
hevc->m_BUF[i].used_flag == 0) {
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
hevc_print(hevc, 0,
- "dealloc buf(%d) adr 0x%p size 0x%x\n",
+ "dealloc buf(%d) adr 0x%lx size 0x%x\n",
i, hevc->m_BUF[i].start_adr,
hevc->m_BUF[i].size);
}
@@ -3827,7 +3485,6 @@
hevc->bmmu_box,
VF_BUFFER_IDX(i));
hevc->m_BUF[i].start_adr = 0;
- hevc->m_BUF[i].header_addr = 0;
hevc->m_BUF[i].size = 0;
}
}
@@ -3843,7 +3500,7 @@
hevc->m_BUF[i].start_adr) {
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
hevc_print(hevc, 0,
- "dealloc buf(%d) adr 0x%p size 0x%x\n",
+ "dealloc buf(%d) adr 0x%lx size 0x%x\n",
i, hevc->m_BUF[i].start_adr,
hevc->m_BUF[i].size);
}
@@ -3854,7 +3511,6 @@
VF_BUFFER_IDX(i));
hevc->m_BUF[i].used_flag = 0;
hevc->m_BUF[i].start_adr = 0;
- hevc->m_BUF[i].header_addr = 0;
hevc->m_BUF[i].size = 0;
}
}
@@ -3945,8 +3601,10 @@
"save buf _mode : dynamic_buf_num_margin %d ----> %d \n",
dynamic_buf_num_margin, hevc->dynamic_buf_num_margin);
- if (sps_pic_buf_diff >= 3)
- used_buf_num += sps_pic_buf_diff;
+ if (sps_pic_buf_diff >= 4)
+ {
+ used_buf_num += sps_pic_buf_diff;;
+ }
/* for eos add more buffer to flush.*/
used_buf_num++;
@@ -4023,35 +3681,26 @@
if (hevc->mmu_enable) {
pic->header_adr = hevc->m_BUF[i].start_adr;
- y_adr = hevc->m_BUF[i].start_adr +
- hevc_get_header_size(hevc->pic_w, hevc->pic_h);
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ (IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
+ y_adr = hevc->m_BUF[i].start_adr +
+ MMU_COMPRESS_HEADER_SIZE_8K;
+ else
+ y_adr = hevc->m_BUF[i].start_adr +
+ MMU_COMPRESS_HEADER_SIZE_4K;
} else
y_adr = hevc->m_BUF[i].start_adr;
y_adr = ((y_adr + 0xffff) >> 16) << 16; /*64k alignment*/
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
-#ifdef USE_FIXED_MMU_DW_HEADER
- pic->header_dw_adr = hevc->work_space_buf->cm_header_dw.buf_start +
- (i * hevc_get_header_size(hevc->pic_w, hevc->pic_h));
-#else
- pic->header_dw_adr = y_adr;
- y_adr = pic->header_dw_adr +
- hevc_get_header_size(hevc->pic_w, hevc->pic_h);
-#endif
- hevc_print(hevc, H265_DEBUG_BUFMGR,
- "MMU header_dw_adr %d: %x\n", pic->header_dw_adr);
- }
-#endif
-
pic->POC = INVALID_POC;
/*ensure get_pic_by_POC()
not get the buffer not decoded*/
pic->BUF_index = i;
if ((!hevc->mmu_enable) &&
- ((dw_mode & 0x10) == 0)) {
+ ((dw_mode & 0x10) == 0)
+ ) {
pic->mc_y_adr = y_adr;
y_adr += (buf_stru.mc_buffer_size_h << 16);
}
@@ -4066,7 +3715,7 @@
pic->dw_y_adr = pic->mc_y_adr;
pic->dw_u_v_adr = pic->mc_u_v_adr;
- } else if (dw_mode && (dw_mode & 0x20) == 0) {
+ } else if (dw_mode) {
pic->dw_y_adr = y_adr;
pic->dw_u_v_adr = pic->dw_y_adr +
((buf_stru.mc_buffer_size_u_v_h << 16) << 1);
@@ -4077,7 +3726,8 @@
"%s index %d BUF_index %d mc_y_adr %x\n",
__func__, pic->index,
pic->BUF_index, pic->mc_y_adr);
- if (hevc->mmu_enable && dw_mode)
+ if (hevc->mmu_enable &&
+ dw_mode)
hevc_print(hevc, 0,
"mmu double write adr %ld\n",
pic->cma_alloc_addr);
@@ -4134,7 +3784,6 @@
pic->width = hevc->pic_w;
pic->height = hevc->pic_h;
pic->double_write_mode = dw_mode;
- pic->POC = INVALID_POC;
/*config canvas will be delay if work on v4l. */
if (!hevc->is_used_v4l) {
@@ -4225,34 +3874,7 @@
data32 |= (1<<10);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
}
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- u32 data_tmp;
- data_tmp = READ_VREG(HEVC_SAO_CTRL9);
- data_tmp |= (1 << 10);
- WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
- WRITE_VREG(HEVC_CM_BODY_LENGTH2,
- losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2,
- losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2,
- losless_comp_header_size);
-
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2,
- buf_spec->mmu_vbh_dw.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2,
- buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec));
- WRITE_VREG(HEVC_DW_VH0_ADDDR,
- buf_spec->mmu_vbh_dw.buf_start + (2 * DW_VBH_BUF_SIZE(buf_spec)));
- WRITE_VREG(HEVC_DW_VH1_ADDDR,
- buf_spec->mmu_vbh_dw.buf_start + (3 * DW_VBH_BUF_SIZE(buf_spec)));
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 |= (1 << 15);
- } else
- data32 &= ~(1 << 15);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-#endif
if (!hevc->m_ins_flag)
hevc_print(hevc, 0,
"%s: (%d, %d) body_size 0x%x header_size 0x%x\n",
@@ -4460,8 +4082,10 @@
decode_idx))
pic_display
= pic;
+
} else
pic_display = pic;
+
}
}
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
@@ -4474,6 +4098,7 @@
&& (!fisrt_pic_flag))
pic_display = NULL;
#endif
+
if (pic_display) {
if ((num_pic_not_yet_display >
pic_display->num_reorder_pic)
@@ -5228,12 +4853,6 @@
"write HEVC_DBLK_CFG3 to %x\n", READ_VREG(HEVC_DBLK_CFG3));
}
#endif
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, FRAME_MMU_MAP_ADDR_DW);
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, hevc->frame_dw_mmu_map_phy_addr);
- }
-#endif
/* cfg_p_addr */
WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
/* cfg_d_addr */
@@ -5373,13 +4992,9 @@
WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
/* Initial IQIT_SCALELUT memory -- just to avoid X in simulation */
- if (is_rdma_enable())
- rdma_back_end_work(hevc->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); /* cfg_p_addr */
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
#ifdef ENABLE_SWAP_TEST
WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
@@ -5525,6 +5140,7 @@
WRITE_VREG(HEVCD_IPP_TOP_CNTL, (1 << 1) | /* enable ipp */
(0 << 0) /* software reset ipp and mpp */
);
+
}
#ifdef CONFIG_HEVC_CLK_FORCED_ON
@@ -5911,7 +5527,6 @@
int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
struct PIC_s *cur_pic = hevc->cur_pic;
struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- int dw_mode = get_double_write_mode(hevc);
data32 = READ_VREG(HEVC_SAO_CTRL0);
data32 &= (~0xf);
@@ -5928,50 +5543,34 @@
WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
#ifdef LOSLESS_COMPRESS_MODE
/*SUPPORT_10BIT*/
- if ((dw_mode & 0x10) == 0) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
+ if ((get_double_write_mode(hevc) & 0x10) == 0) {
data32 = READ_VREG(HEVC_SAO_CTRL5);
data32 &= (~(0xff << 16));
- if (((dw_mode & 0xf) == 8) ||
- ((dw_mode & 0xf) == 9)) {
- data32 |= (0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else {
- if ((dw_mode & 0xf) == 2 ||
- (dw_mode & 0xf) == 3)
- data32 |= (0xff<<16);
- else if ((dw_mode & 0xf) == 4 ||
- (dw_mode & 0xf) == 5)
- data32 |= (0x33<<16);
- if (hevc->mem_saving_mode == 1)
- data32 |= (1 << 9);
- else
- data32 &= ~(1 << 9);
- if (workaround_enable & 1)
- data32 |= (1 << 7);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
+ if (get_double_write_mode(hevc) == 2 ||
+ get_double_write_mode(hevc) == 3)
+ data32 |= (0xff<<16);
+ else if (get_double_write_mode(hevc) == 4 ||
+ get_double_write_mode(hevc) == 5)
+ data32 |= (0x33<<16);
+
+ if (hevc->mem_saving_mode == 1)
+ data32 |= (1 << 9);
+ else
+ data32 &= ~(1 << 9);
+ if (workaround_enable & 1)
+ data32 |= (1 << 7);
+ WRITE_VREG(HEVC_SAO_CTRL5, data32);
}
data32 = cur_pic->mc_y_adr;
- if (dw_mode && ((dw_mode & 0x20) == 0))
+ if (get_double_write_mode(hevc))
WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
- if ((dw_mode & 0x10) == 0)
+ if ((get_double_write_mode(hevc) & 0x10) == 0)
WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32);
if (hevc->mmu_enable)
WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, cur_pic->header_dw_adr);
- }
-#endif
#else
data32 = cur_pic->mc_y_adr;
WRITE_VREG(HEVC_SAO_Y_START_ADDR, data32);
@@ -5981,7 +5580,7 @@
#ifdef LOSLESS_COMPRESS_MODE
/*SUPPORT_10BIT*/
- if (dw_mode && ((dw_mode & 0x20) == 0))
+ if (get_double_write_mode(hevc))
WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
#else
data32 = cur_pic->mc_u_v_adr;
@@ -5990,20 +5589,9 @@
data32 = (mc_buffer_size_u_v_h << 16);
WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
- if (hevc->is_used_v4l) {
- WRITE_VREG(HEVC_SAO_Y_LENGTH, cur_pic->luma_size);
- WRITE_VREG(HEVC_SAO_C_LENGTH, cur_pic->chroma_size);
- if (debug & PRINT_FLAG_V4L_DETAIL) {
- pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n",
- v4l2_ctx->id, cur_pic->index,
- cur_pic->dw_y_adr, cur_pic->luma_size,
- cur_pic->dw_u_v_adr, cur_pic->chroma_size);
- }
- }
-
#ifdef LOSLESS_COMPRESS_MODE
/*SUPPORT_10BIT*/
- if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ if (get_double_write_mode(hevc)) {
WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
WRITE_VREG(HEVC_SAO_C_WPTR, cur_pic->dw_u_v_adr);
}
@@ -6027,9 +5615,9 @@
if (hevc->pic_w >= 1280)
data32 |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
data32 &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (dw_mode == 0)
+ if (get_double_write_mode(hevc) == 0)
data32 |= (0x1 << 8); /*enable first write*/
- else if (dw_mode == 0x10)
+ else if (get_double_write_mode(hevc) == 0x10)
data32 |= (0x1 << 9); /*double write only*/
else
data32 |= ((0x1 << 8) |(0x1 << 9));
@@ -6056,7 +5644,7 @@
data32 |=
(hevc->lcu_size ==
64) ? 0 : ((hevc->lcu_size == 32) ? 1 : 2);
- data32 |= (hevc->pic_w <= 64) ? (1 << 20) : 0;
+
WRITE_VREG(HEVC_DBLK_CFG1, data32);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
@@ -6093,19 +5681,19 @@
/* m8baby test1902 */
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
- /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
- data32 |= (hevc->mem_map_mode << 12);
+ data32 |= (hevc->mem_map_mode <<
+ 12);
+
+/* [13:12] axi_aformat, 0-Linear,
+ * 1-32x32, 2-64x32
+ */
data32 &= (~0xff0);
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable == 0)
- data32 |= ((hevc->endian >> 8) & 0xfff);
-#else
- data32 |= ((hevc->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
-#endif
+ /* data32 |= 0x670; // Big-Endian per 64-bit */
+ data32 |= endian; /* Big-Endian per 64-bit */
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
- if (dw_mode == 0)
+ if (get_double_write_mode(hevc) == 0)
data32 |= 0x2; /*disable double write*/
- else if (dw_mode & 0x10)
+ else if (get_double_write_mode(hevc) & 0x10)
data32 |= 0x1; /*disable cm*/
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
unsigned int data;
@@ -6114,9 +5702,9 @@
if (hevc->pic_w >= 1280)
data |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (dw_mode == 0)
+ if (get_double_write_mode(hevc) == 0)
data |= (0x1 << 8); /*enable first write*/
- else if (dw_mode & 0x10)
+ else if (get_double_write_mode(hevc) & 0x10)
data |= (0x1 << 9); /*double write only*/
else
data |= ((0x1 << 8) |(0x1 << 9));
@@ -6133,8 +5721,7 @@
else
data32 |= (1 << 8); /* NV12 */
}
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
+
/*
* [31:24] ar_fifo1_axi_thred
* [23:16] ar_fifo0_axi_thred
@@ -6147,8 +5734,9 @@
* [1] dw_disable:disable double write output
* [0] cm_disable:disable compress output
*/
+
WRITE_VREG(HEVC_SAO_CTRL1, data32);
- if (dw_mode & 0x10) {
+ if (get_double_write_mode(hevc) & 0x10) {
/* [23:22] dw_v1_ctrl
*[21:20] dw_v0_ctrl
*[19:18] dw_h1_ctrl
@@ -6163,9 +5751,11 @@
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (hevc->mem_map_mode << 4);
+ data32 |= (hevc->mem_map_mode <<
+ 4);
data32 &= (~0xF);
- data32 |= (hevc->endian & 0xf); /* valid only when double write only */
+ data32 |= 0xf; /* valid only when double write only */
+ /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
/* swap uv */
if (hevc->is_used_v4l) {
@@ -6175,8 +5765,7 @@
else
data32 &= ~(1 << 12); /* NV12 */
}
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
+
/*
* [3:0] little_endian
* [5:4] address_format 00:linear 01:32x32 10:64x32
@@ -6298,9 +5887,7 @@
if (alloc_pic_count > work_pic_num) {
pic->width = 0;
pic->height = 0;
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
release_pic_mmu_buf(hevc, pic);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
pic->index = -1;
} else {
pic->width = hevc->pic_w;
@@ -6416,21 +6003,6 @@
return NULL;
}
}
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- ret = H265_alloc_mmu_dw(hevc, new_pic,
- rpm_param->p.bit_depth,
- hevc->frame_dw_mmu_map_addr);
- if (ret != 0) {
- put_mv_buf(hevc, new_pic);
- hevc_print(hevc, 0,
- "can't alloc need mmu_dw_1,idx %d ret =%d\n",
- new_pic->decode_idx,
- ret);
- return NULL;
- }
- }
-#endif
new_pic->referenced = 1;
new_pic->decode_idx = hevc->decode_idx;
new_pic->slice_idx = 0;
@@ -6486,24 +6058,6 @@
return new_pic;
}
-static int get_free_fb_idx(struct hevc_state_s *hevc)
-{
- int i;
-
- for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
- if (hevc->m_PIC[i] == NULL)
- continue;
-
- if ((hevc->m_PIC[i]->referenced == 0) &&
- (hevc->m_PIC[i]->vf_ref == 0) &&
- (!hevc->m_PIC[i]->cma_alloc_addr))
- break;
- }
-
- return (hevc->m_PIC[i] &&
- (i != MAX_REF_PIC_NUM)) ? i : -1;
-}
-
static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc,
union param_u *rpm_param)
{
@@ -6513,7 +6067,7 @@
struct v4l_buff_pool *pool = &v4l->cap_pool;
struct PIC_s *new_pic = NULL;
struct PIC_s *pic = NULL;
- int i, j, idx;
+ int i;
for (i = 0; i < pool->in; ++i) {
u32 state = (pool->seq[i] >> 16);
@@ -6521,37 +6075,22 @@
switch (state) {
case V4L_CAP_BUFF_IN_DEC:
- for (j = 0; j < MAX_REF_PIC_NUM; j++) {
- pic = hevc->m_PIC[j];
- if (pic == NULL || pic->index == -1)
- continue;
-
- if (pic->output_mark == 0 &&
- pic->referenced == 0 &&
- pic->output_ready == 0 &&
- pic->width == hevc->pic_w &&
- pic->height == hevc->pic_h &&
- pic->vf_ref == 0 &&
- pic->cma_alloc_addr) {
- if (new_pic) {
- if (new_pic->POC != INVALID_POC) {
- if (pic->POC == INVALID_POC ||
- pic->POC < new_pic->POC)
- new_pic = pic;
- }
- } else
- new_pic = pic;
- }
+ pic = hevc->m_PIC[i];
+ if (pic && (pic->index != -1) &&
+ (pic->output_mark == 0) &&
+ (pic->referenced == 0) &&
+ (pic->output_ready == 0) &&
+ (pic->width == hevc->pic_w) &&
+ (pic->height == hevc->pic_h) &&
+ (pic->vf_ref == 0) &&
+ pic->cma_alloc_addr) {
+ new_pic = pic;
}
break;
case V4L_CAP_BUFF_IN_M2M:
- idx = get_free_fb_idx(hevc);
- if (idx < 0)
- break;
- pic = hevc->m_PIC[idx];
+ pic = hevc->m_PIC[index];
pic->width = hevc->pic_w;
pic->height = hevc->pic_h;
- hevc->buffer_wrap[idx] = index;
if ((pic->index != -1) &&
!v4l_alloc_buf(hevc, pic)) {
v4l_config_pic(hevc, pic);
@@ -6601,10 +6140,10 @@
new_pic->dis_mark = 0;
/* new_pic->output_ready = 0; */
new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0;
- new_pic->ip_mode = hevc->low_latency_flag ? true :
- (!new_pic->num_reorder_pic &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
+ new_pic->ip_mode = (!new_pic->num_reorder_pic &&
+ !(vdec->slave || vdec->master) &&
+ !disable_ip_mode &&
+ hevc->low_latency_flag) ? true : false;
new_pic->losless_comp_body_size = hevc->losless_comp_body_size;
new_pic->POC = hevc->curr_POC;
new_pic->pic_struct = hevc->curr_pic_struct;
@@ -6633,14 +6172,7 @@
new_pic->chroma_format_idc =
hevc->param.p.chroma_format_idc;
- if (new_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)new_pic->cma_alloc_addr;
-
- fb->status = FB_ST_DECODER;
- }
-
- hevc_print(hevc, H265_DEBUG_BUFMGR,
+ hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
"%s: index %d, buf_idx %d, decode_idx %d, POC %d\n",
__func__, new_pic->index,
new_pic->BUF_index, new_pic->decode_idx,
@@ -6796,7 +6328,7 @@
aux_size =
hevc->prefix_aux_size;
}
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
+ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
hevc_print(hevc, 0,
"%s:pic 0x%p old size %d count %d,suf %d dv_flag %d\r\n",
__func__, pic, pic->aux_data_size,
@@ -6905,7 +6437,7 @@
h[6] = (padding_len >> 8) & 0xff;
h[7] = (padding_len) & 0xff;
}
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
+ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
hevc_print(hevc, 0,
"aux: (size %d) suffix_flag %d\n",
pic->aux_data_size, suffix_flag);
@@ -6941,39 +6473,6 @@
pic->aux_data_size = 0;
}
-static int recycle_mmu_buf_tail(struct hevc_state_s *hevc,
- bool check_dma)
-{
- hevc_print(hevc,
- H265_DEBUG_BUFMGR_MORE,
- "%s pic index %d scatter_alloc %d page_start %d\n",
- "decoder_mmu_box_free_idx_tail",
- hevc->cur_pic->index,
- hevc->cur_pic->scatter_alloc,
- hevc->used_4k_num);
- if (check_dma)
- hevc_mmu_dma_check(hw_to_vdec(hevc));
-
- if (hevc->is_used_v4l) {
- int index = hevc->cur_pic->BUF_index;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hevc, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- hevc->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- hevc->mmu_box,
- hevc->cur_pic->index,
- hevc->used_4k_num);
- }
- hevc->cur_pic->scatter_alloc = 2;
- hevc->used_4k_num = -1;
- return 0;
-}
-
static inline void hevc_pre_pic(struct hevc_state_s *hevc,
struct PIC_s *pic)
{
@@ -7022,10 +6521,22 @@
(hevc->used_4k_num >= 0) &&
(hevc->cur_pic->scatter_alloc
== 1)) {
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- recycle_mmu_buf_tail(hevc, true);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
+ hevc_print(hevc,
+ H265_DEBUG_BUFMGR_MORE,
+ "%s pic index %d scatter_alloc %d page_start %ld\n",
+ "decoder_mmu_box_free_idx_tail",
+ hevc->cur_pic->index,
+ hevc->cur_pic->scatter_alloc,
+ hevc->used_4k_num);
+ hevc_mmu_dma_check(hw_to_vdec(hevc));
+ decoder_mmu_box_free_idx_tail(
+ hevc->mmu_box,
+ hevc->cur_pic->index,
+ hevc->used_4k_num);
+ hevc->cur_pic->scatter_alloc
+ = 2;
+ }
+ hevc->used_4k_num = -1;
}
}
if (!pic->ip_mode)
@@ -7113,7 +6624,7 @@
hevc_print(hevc, 0,
"clear referenced flag of all buffers\n");
}
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
+ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
dump_pic_list(hevc);
if (hevc->vf_pre_count == 1 &&
hevc->first_pic_flag == 1) {
@@ -7674,14 +7185,17 @@
union param_u *rpm_param,
int decode_pic_begin)
{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
struct vdec_s *vdec = hw_to_vdec(hevc);
-#endif
int i;
int lcu_x_num_div;
int lcu_y_num_div;
int Col_ref;
int dbg_skip_flag = 0;
+ struct aml_vcodec_ctx *ctx =
+ (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
+
+ if (hevc->is_used_v4l && ctx->param_sets_from_ucode)
+ hevc->res_ch_flag = 0;
if (hevc->wait_buf == 0) {
hevc->sps_num_reorder_pics_0 =
@@ -7695,22 +7209,11 @@
(rpm_param->p.profile_etc >> 2) & 0x1;
hevc->curr_pic_struct =
(rpm_param->p.sei_frame_field_info >> 3) & 0xf;
- hevc->frame_field_info_present_flag =
- (rpm_param->p.sei_frame_field_info >> 8) & 0x1;
-
- if (hevc->frame_field_info_present_flag) {
- if (hevc->curr_pic_struct == 0
- || hevc->curr_pic_struct == 7
- || hevc->curr_pic_struct == 8)
- hevc->interlace_flag = 0;
+ if (parser_sei_enable & 0x4) {
+ hevc->frame_field_info_present_flag =
+ (rpm_param->p.sei_frame_field_info >> 8) & 0x1;
}
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "frame_field_info_present_flag = %d curr_pic_struct = %d interlace_flag = %d\n",
- hevc->frame_field_info_present_flag,
- hevc->curr_pic_struct,
- hevc->interlace_flag);
-
/* if (interlace_enable == 0 || hevc->m_ins_flag) */
if (interlace_enable == 0)
hevc->interlace_flag = 0;
@@ -7765,7 +7268,6 @@
rpm_param->p.pic_width_in_luma_samples,
rpm_param->p.pic_height_in_luma_samples,
hevc->interlace_flag);
-
hevc->pic_w = rpm_param->p.pic_width_in_luma_samples;
hevc->pic_h = rpm_param->p.pic_height_in_luma_samples;
hevc->frame_width = hevc->pic_w;
@@ -7932,7 +7434,7 @@
/**/
/* if((iPrevPOC != curr_POC)){ */
if (rpm_param->p.slice_segment_address == 0) {
- struct PIC_s *pic = NULL;
+ struct PIC_s *pic;
hevc->new_pic = 1;
#ifdef MULTI_INSTANCE_SUPPORT
@@ -7941,10 +7443,6 @@
check_pic_decoded_error_pre(hevc,
READ_VREG(HEVC_PARSER_LCU_START)
& 0xffffff);
- if (vdec_stream_based(vdec) && ((READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff) != 0)) {
- if (hevc->cur_pic)
- hevc->cur_pic->error_mark = 1;
- }
/**/ if (use_cma == 0) {
if (hevc->pic_list_init_flag == 0) {
init_pic_list(hevc);
@@ -8001,7 +7499,7 @@
v4l_get_new_pic(hevc, rpm_param) :
get_new_pic(hevc, rpm_param);
if (hevc->cur_pic == NULL) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
+ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
dump_pic_list(hevc);
hevc->wait_buf = 1;
return -1;
@@ -8323,7 +7821,7 @@
|| (dbg_skip_flag))
return 0xf;
#endif
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
+
config_mc_buffer(hevc, hevc->cur_pic);
if (is_skip_decoding(hevc,
@@ -8371,7 +7869,7 @@
config_mpred_hw(hevc);
config_sao_hw(hevc, rpm_param);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
+
if ((hevc->slice_type != 2) && (hevc->i_only & 0x2))
return 0xf;
@@ -8381,106 +7879,50 @@
return 0;
}
-/* return page number */
-static int hevc_mmu_page_num(struct hevc_state_s *hevc,
- int w, int h, int save_mode)
-{
- int picture_size;
- int page_num;
- int max_frame_num;
- picture_size = compute_losless_comp_body_size(hevc, w,
- h, save_mode);
- page_num = ((picture_size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+
+static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic,
+ unsigned short bit_depth, unsigned int *mmu_index_adr) {
+ int cur_buf_idx = new_pic->index;
+ int bit_depth_10 = (bit_depth != 0x00);
+ int picture_size;
+ int cur_mmu_4k_number;
+ int ret, max_frame_num;
+ picture_size = compute_losless_comp_body_size(hevc, new_pic->width,
+ new_pic->height, !bit_depth_10);
+ cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12);
+ if (get_double_write_mode(hevc) == 0x10)
+ return 0;
+ /*hevc_print(hevc, 0,
+ "alloc_mmu cur_idx : %d picture_size : %d mmu_4k_number : %d\r\n",
+ cur_buf_idx, picture_size, cur_mmu_4k_number);*/
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
max_frame_num = MAX_FRAME_8K_NUM;
else
max_frame_num = MAX_FRAME_4K_NUM;
-
- if (page_num > max_frame_num) {
+ if (cur_mmu_4k_number > max_frame_num) {
hevc_print(hevc, 0, "over max !! 0x%x width %d height %d\n",
- page_num, w, h);
+ cur_mmu_4k_number,
+ new_pic->width,
+ new_pic->height);
return -1;
}
- return page_num;
-}
-
-static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic,
- unsigned short bit_depth, unsigned int *mmu_index_adr) {
- int bit_depth_10 = (bit_depth != 0x00);
- int cur_mmu_4k_number;
- int ret;
-
- if (get_double_write_mode(hevc) == 0x10)
- return 0;
-
- cur_mmu_4k_number = hevc_mmu_page_num(hevc, new_pic->width,
- new_pic->height, !bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
-
- if (hevc->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hevc, new_pic->BUF_index);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- ret = decoder_mmu_box_alloc_idx(
- hevc->mmu_box,
- new_pic->index,
- cur_mmu_4k_number,
- mmu_index_adr);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
+ ret = decoder_mmu_box_alloc_idx(
+ hevc->mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
new_pic->scatter_alloc = 1;
hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
"%s pic index %d page count(%d) ret =%d\n",
- __func__, new_pic->index,
+ __func__, cur_buf_idx,
cur_mmu_4k_number, ret);
return ret;
}
-#ifdef H265_10B_MMU_DW
-static int H265_alloc_mmu_dw(struct hevc_state_s *hevc, struct PIC_s *new_pic,
- unsigned short bit_depth, unsigned int *mmu_index_adr) {
- int bit_depth_10 = (bit_depth != 0x00);
- int cur_mmu_4k_number;
- int ret;
- if (!hevc->mmu_box_dw) {
- hevc_print(hevc, 0,
- "%s, error no mmu box dw!\n", __func__);
- return -1;
- }
-
- if (get_double_write_mode(hevc) == 0x10)
- return 0;
-
- cur_mmu_4k_number = hevc_mmu_page_num(hevc, new_pic->width,
- new_pic->height, !bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
-
- ret = decoder_mmu_box_alloc_idx(
- hevc->mmu_box_dw,
- new_pic->index,
- cur_mmu_4k_number,
- mmu_index_adr);
-
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s pic index %d page count(%d) ret =%d\n",
- __func__, new_pic->index,
- cur_mmu_4k_number, ret);
- return ret;
-}
-#endif
static void release_pic_mmu_buf(struct hevc_state_s *hevc,
struct PIC_s *pic)
@@ -8491,20 +7933,9 @@
pic->scatter_alloc);
if (hevc->mmu_enable
- && !(hevc->double_write_mode & 0x10)
- && pic->scatter_alloc) {
- if (!hevc->is_used_v4l)
- decoder_mmu_box_free_idx(hevc->mmu_box, pic->index);
- else {
- struct internal_comp_buf *ibuf =
- ibuf = index_to_icomp_buf(hevc, pic->BUF_index);
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- }
- }
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable)
- decoder_mmu_box_free_idx(hevc->mmu_box_dw, pic->index);
-#endif
+ && ((hevc->double_write_mode & 0x10) == 0)
+ && pic->scatter_alloc)
+ decoder_mmu_box_free_idx(hevc->mmu_box, pic->index);
pic->scatter_alloc = 0;
}
@@ -8564,16 +7995,7 @@
hevc->frame_mmu_map_addr = NULL;
}
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable && hevc->frame_dw_mmu_map_addr) {
- if (hevc->frame_dw_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(), hevc->frame_dw_mmu_map_addr,
- hevc->frame_dw_mmu_map_phy_addr);
- hevc->frame_dw_mmu_map_addr = NULL;
- }
-#endif
//pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
}
@@ -8585,34 +8007,20 @@
memset(&hevc->param, 0, sizeof(union param_u));
cur_buf_info = &hevc->work_space_buf_store;
-
if (force_bufspec) {
memcpy(cur_buf_info, &amvh265_workbuff_spec[force_bufspec & 0xf],
sizeof(struct BuffInfo_s));
pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- memcpy(cur_buf_info, &amvh265_workbuff_spec[2], /* 4k */
- sizeof(struct BuffInfo_s));
- else
- memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[0], /* 1080p */
- sizeof(struct BuffInfo_s));
- }
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[5], /* 4k */
- sizeof(struct BuffInfo_s));
- } else {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[3], /* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
- }
+ } else if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ memcpy(cur_buf_info, &amvh265_workbuff_spec[2], /* 4k */
+ sizeof(struct BuffInfo_s));
+ else
+ memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k */
+ sizeof(struct BuffInfo_s));
+ } else
+ memcpy(cur_buf_info, &amvh265_workbuff_spec[0], /* 1080p */
+ sizeof(struct BuffInfo_s));
cur_buf_info->start_adr = hevc->buf_start;
init_buff_spec(hevc, cur_buf_info);
@@ -8671,19 +8079,6 @@
}
memset(hevc->frame_mmu_map_addr, 0, get_frame_mmu_map_size());
}
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- hevc->frame_dw_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(),
- &hevc->frame_dw_mmu_map_phy_addr, GFP_KERNEL);
- if (hevc->frame_dw_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(hevc->frame_dw_mmu_map_addr, 0, get_frame_mmu_map_size());
- }
-#endif
ret = 0;
return ret;
}
@@ -8720,14 +8115,16 @@
/*CANVAS_BLKMODE_64X32*/
#ifdef SUPPORT_10BIT
- if (pic->double_write_mode &&
- ((pic->double_write_mode & 0x20) == 0)) {
+ if (pic->double_write_mode) {
canvas_w = pic->width /
- get_double_write_ratio(pic->double_write_mode & 0xf);
+ get_double_write_ratio(hevc, pic->double_write_mode);
canvas_h = pic->height /
- get_double_write_ratio(pic->double_write_mode & 0xf);
+ get_double_write_ratio(hevc, pic->double_write_mode);
- canvas_w = ALIGN(canvas_w, 64);
+ if (hevc->mem_map_mode == 0)
+ canvas_w = ALIGN(canvas_w, 32);
+ else
+ canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
if (vdec->parallel_dec == 1) {
@@ -8740,12 +8137,12 @@
pic->uv_canvas_index = 128 + pic->index * 2 + 1;
}
- config_cav_lut_ex(pic->y_canvas_index,
+ canvas_config_ex(pic->y_canvas_index,
pic->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
+ canvas_config_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
#ifdef MULTI_INSTANCE_SUPPORT
pic->canvas_config[0].phy_addr =
pic->dw_y_adr;
@@ -8767,11 +8164,11 @@
blkmode;
pic->canvas_config[1].endian = hevc->is_used_v4l ? 0 : 7;
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr);
+ ATRACE_COUNTER(hevc->set_canvas0_addr, pic->canvas_config[0].phy_addr);
hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
__func__, pic->canvas_config[0].phy_addr);
#else
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
+ ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic));
hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
__func__, spec2canvas(pic));
#endif
@@ -8787,14 +8184,14 @@
pic->uv_canvas_index = 128 + pic->index;
}
- config_cav_lut_ex(pic->y_canvas_index,
+ canvas_config_ex(pic->y_canvas_index,
pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
+ canvas_config_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
}
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
+ ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic));
hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
__func__, spec2canvas(pic));
}
@@ -8810,13 +8207,13 @@
}
- config_cav_lut_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
+ canvas_config_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h,
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
+ canvas_config_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7);
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
+ ATRACE_COUNTER(hevc->set_canvas0_addr, spec2canvas(pic));
hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
__func__, spec2canvas(pic));
#endif
@@ -8850,8 +8247,8 @@
char *p = sei_buf;
char *p_sei;
uint16_t header;
- uint16_t nal_unit_type;
- uint16_t payload_type, payload_size;
+ uint8_t nal_unit_type;
+ uint8_t payload_type, payload_size;
int i, j;
if (size < 2)
@@ -8863,16 +8260,9 @@
if ((nal_unit_type != NAL_UNIT_SEI)
&& (nal_unit_type != NAL_UNIT_SEI_SUFFIX))
return 0;
- while (p+4 <= sei_buf+size) {
+ while (p+2 <= sei_buf+size) {
payload_type = *p++;
- if (payload_type == 0xff) {
- payload_type += *p++;
- }
payload_size = *p++;
- if (payload_size == 0xff) {
- payload_size += *p++;
- }
-
if (p+payload_size <= sei_buf+size) {
switch (payload_type) {
case SEI_PicTiming:
@@ -8911,25 +8301,6 @@
pic->hdr10p_data_buf = NULL;
pic->hdr10p_data_size = 0;
}
- } else if (p_sei[0] == 0x26
- && p_sei[1] == 0x00
- && p_sei[2] == 0x04
- && p_sei[3] == 0x00
- && p_sei[4] == 0x05) {
- hevc->sei_present_flag |= SEI_HDR_CUVA_MASK;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- hevc_print(hevc, 0,
- "hdr cuva data: (size %d)\n",
- payload_size);
- for (i = 0; i < payload_size; i++) {
- hevc_print_cont(hevc, 0,
- "%02x ", p_sei[i]);
- if (((i + 1) & 0xf) == 0)
- hevc_print_cont(hevc, 0, "\n");
- }
- hevc_print_cont(hevc, 0, "\n");
- }
}
break;
@@ -9089,9 +8460,9 @@
= &vf->prop.master_display_colour;
vf->width = pic->width /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(hevc, pic->double_write_mode);
vf->height = pic->height /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(hevc, pic->double_write_mode);
vf->duration = hevc->frame_dur;
vf->duration_pulldown = 0;
@@ -9149,14 +8520,6 @@
data = data | (0x30<<8);
vf->signal_type = data;
}
-
- if (hevc->sei_present_flag & SEI_HDR_CUVA_MASK) {
- u32 data;
- data = vf->signal_type;
- data = data & 0x7FFFFFFF;
- data = data | (1<<31);
- vf->signal_type = data;
- }
}
else
vf->signal_type = 0;
@@ -9187,8 +8550,7 @@
vf_dp->content_light_level.present_flag = 0;
if (hevc->is_used_v4l &&
- ((hevc->video_signal_type & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) ||
- (hevc->sei_present_flag & SEI_HDR10PLUS_MASK) ||
+ ((hevc->sei_present_flag & SEI_HDR10PLUS_MASK) ||
(vf_dp->present_flag) ||
(vf_dp->content_light_level.present_flag))) {
struct aml_vdec_hdr_infos hdr;
@@ -9203,34 +8565,32 @@
if ((hevc->sei_present_flag & SEI_HDR10PLUS_MASK) && (pic->hdr10p_data_buf != NULL)
&& (pic->hdr10p_data_size != 0)) {
- if (pic->hdr10p_data_size <= 128) {
- char *new_buf;
- new_buf = kzalloc(pic->hdr10p_data_size, GFP_ATOMIC);
+ char *new_buf;
+ new_buf = vzalloc(pic->hdr10p_data_size);
- if (new_buf) {
- memcpy(new_buf, pic->hdr10p_data_buf, pic->hdr10p_data_size);
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- hevc_print(hevc, 0,
- "hdr10p data: (size %d)\n",
- pic->hdr10p_data_size);
- for (i = 0; i < pic->hdr10p_data_size; i++) {
- hevc_print_cont(hevc, 0,
- "%02x ", pic->hdr10p_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- hevc_print_cont(hevc, 0, "\n");
- }
- hevc_print_cont(hevc, 0, "\n");
- }
-
- vf->hdr10p_data_size = pic->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
- } else {
+ if (new_buf) {
+ memcpy(new_buf, pic->hdr10p_data_buf, pic->hdr10p_data_size);
+ if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
hevc_print(hevc, 0,
- "%s:hdr10p data vzalloc size(%d) fail\n",
- __func__, pic->hdr10p_data_size);
- vf->hdr10p_data_buf = NULL;
- vf->hdr10p_data_size = 0;
+ "hdr10p data: (size %d)\n",
+ pic->hdr10p_data_size);
+ for (i = 0; i < pic->hdr10p_data_size; i++) {
+ hevc_print_cont(hevc, 0,
+ "%02x ", pic->hdr10p_data_buf[i]);
+ if (((i + 1) & 0xf) == 0)
+ hevc_print_cont(hevc, 0, "\n");
+ }
+ hevc_print_cont(hevc, 0, "\n");
}
+
+ vf->hdr10p_data_size = pic->hdr10p_data_size;
+ vf->hdr10p_data_buf = new_buf;
+ } else {
+ hevc_print(hevc, 0,
+ "%s:hdr10p data vzalloc size(%d) fail\n",
+ __func__, pic->hdr10p_data_size);
+ vf->hdr10p_data_buf = NULL;
+ vf->hdr10p_data_size = 0;
}
vfree(pic->hdr10p_data_buf);
@@ -9316,7 +8676,6 @@
return NULL;
else if (step == 1)
step = 2;
-
#if 0
if (force_disp_pic_index & 0x100) {
int buffer_index = force_disp_pic_index & 0xff;
@@ -9381,9 +8740,9 @@
set_frame_info(hevc, vf);
vf->width = pic->width /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(hevc, pic->double_write_mode);
vf->height = pic->height /
- get_double_write_ratio(pic->double_write_mode);
+ get_double_write_ratio(hevc, pic->double_write_mode);
force_disp_pic_index |= 0x200;
return vf;
@@ -9393,17 +8752,17 @@
if (kfifo_get(&hevc->display_q, &vf)) {
struct vframe_s *next_vf = NULL;
- ATRACE_COUNTER(hevc->trace.vf_get_name, (long)vf);
- ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q));
+ ATRACE_COUNTER(hevc->vf_get_name, (long)vf);
+ ATRACE_COUNTER(hevc->disp_q_name, kfifo_len(&hevc->display_q));
#ifdef MULTI_INSTANCE_SUPPORT
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr);
+ ATRACE_COUNTER(hevc->set_canvas0_addr, vf->canvas0_config[0].phy_addr);
#else
- ATRACE_COUNTER(hevc->trace.get_canvas0_addr, vf->canvas0Addr);
+ ATRACE_COUNTER(hevc->get_canvas0_addr, vf->canvas0Addr);
#endif
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) {
hevc_print(hevc, 0,
- "%s(vf 0x%p type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n",
+ "%s(vf 0x%p type %d index 0x%x poc %d/%d) pts(%d,%ld) dur %d\n",
__func__, vf, vf->type, vf->index,
get_pic_poc(hevc, vf->index & 0xff),
get_pic_poc(hevc, (vf->index >> 8) & 0xff),
@@ -9433,8 +8792,8 @@
}
#endif
hevc->show_frame_num++;
- vf->index_disp = atomic_read(&hevc->vf_get_count);
- atomic_add(1, &hevc->vf_get_count);
+ vf->index_disp = hevc->vf_get_count;
+ hevc->vf_get_count++;
if (kfifo_peek(&hevc->display_q, &next_vf) && next_vf) {
vf->next_vf_pts_valid = true;
@@ -9472,39 +8831,23 @@
unsigned char index_top;
unsigned char index_bot;
- if (!vf)
+ if (vf && (vf_valid_check(vf, hevc) == false))
return;
if (vf == (&hevc->vframe_dummy))
return;
- if (vf && (vf_valid_check(vf, hevc) == false))
+ if (!vf)
return;
- if (hevc->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&hevc->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (hevc->fence_vf_s.fence_vf[i] == NULL) {
- hevc->fence_vf_s.fence_vf[i] = vf;
- hevc->fence_vf_s.used_size++;
- mutex_unlock(&hevc->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&hevc->fence_mutex);
- }
-
- ATRACE_COUNTER(hevc->trace.vf_put_name, (long)vf);
+ ATRACE_COUNTER(hevc->vf_put_name, (long)vf);
#ifdef MULTI_INSTANCE_SUPPORT
- ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr);
+ ATRACE_COUNTER(hevc->put_canvas0_addr, vf->canvas0_config[0].phy_addr);
#else
- ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0Addr);
+ ATRACE_COUNTER(hevc->put_canvas0_addr, vf->canvas0Addr);
#endif
+
index_top = vf->index & 0xff;
index_bot = (vf->index >> 8) & 0xff;
+
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
hevc_print(hevc, 0,
"%s(vf 0x%p type %d index 0x%x put canvas0 addr:0x%x)\n",
@@ -9515,25 +8858,27 @@
, vf->canvas0Addr
#endif
);
- atomic_add(1, &hevc->vf_put_count);
+
+ hevc->vf_put_count++;
spin_lock_irqsave(&lock, flags);
kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q));
+ ATRACE_COUNTER(hevc->new_q_name, kfifo_len(&hevc->newframe_q));
if (hevc->enable_fence && vf->fence) {
vdec_fence_put(vf->fence);
vf->fence = NULL;
}
if (vf->hdr10p_data_buf) {
- kfree(vf->hdr10p_data_buf);
+ vfree(vf->hdr10p_data_buf);
vf->hdr10p_data_buf = NULL;
vf->hdr10p_data_size = 0;
}
-
if (index_top != 0xff
&& index_top < MAX_REF_PIC_NUM
&& hevc->m_PIC[index_top]) {
+ if (hevc->is_used_v4l)
+ hevc->m_PIC[index_top]->vframe_bound = true;
if (hevc->m_PIC[index_top]->vf_ref > 0) {
hevc->m_PIC[index_top]->vf_ref--;
@@ -9551,6 +8896,8 @@
if (index_bot != 0xff
&& index_bot < MAX_REF_PIC_NUM
&& hevc->m_PIC[index_bot]) {
+ if (hevc->is_used_v4l)
+ hevc->m_PIC[index_bot]->vframe_bound = true;
if (hevc->m_PIC[index_bot]->vf_ref > 0) {
hevc->m_PIC[index_bot]->vf_ref--;
@@ -9597,14 +8944,13 @@
unsigned char index;
if (!req->vf) {
- req->aux_size = atomic_read(&hevc->vf_put_count);
+ req->aux_size = hevc->vf_put_count;
return 0;
}
spin_lock_irqsave(&lock, flags);
index = req->vf->index & 0xff;
req->aux_buf = NULL;
req->aux_size = 0;
- req->format = VFORMAT_HEVC;
if (req->bot_flag)
index = (req->vf->index >> 8) & 0xff;
if (index != 0xff
@@ -9677,8 +9023,6 @@
if (kfifo_len(&hevc->pending_q) > 1) {
unsigned long flags;
- int index1;
- int index2;
/* do not pending more than 1 frame */
if (kfifo_get(&hevc->pending_q, &vf) == 0) {
hevc_print(hevc, 0,
@@ -9687,45 +9031,34 @@
}
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
hevc_print(hevc, 0,
- "%s warning(1), vf=>display_q: (index 0x%x), vf 0x%px\n",
- __func__, vf->index, vf);
+ "%s warning(1), vf=>display_q: (index 0x%x)\n",
+ __func__, vf->index);
if ((pair_pic->double_write_mode == 3) &&
(!(IS_8K_SIZE(vf->width, vf->height)))) {
vf->type |= VIDTYPE_COMPRESS;
if (hevc->mmu_enable)
vf->type |= VIDTYPE_SCATTER;
}
-
hevc->vf_pre_count++;
spin_lock_irqsave(&lock, flags);
kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf);
- index1 = vf->index & 0xff;
- index2 = (vf->index >> 8) & 0xff;
- if (index1 >= MAX_REF_PIC_NUM &&
- index2 >= MAX_REF_PIC_NUM) {
+ vf->index &= 0xff;
+ if (vf->index >= MAX_REF_PIC_NUM) {
spin_unlock_irqrestore(&lock, flags);
return -1;
}
-
- if (index1 < MAX_REF_PIC_NUM) {
- hevc->m_PIC[index1]->vf_ref = 0;
- hevc->m_PIC[index1]->output_ready = 0;
- }
- if (index2 < MAX_REF_PIC_NUM) {
- hevc->m_PIC[index2]->vf_ref = 0;
- hevc->m_PIC[index2]->output_ready = 0;
- }
-
+ hevc->m_PIC[vf->index]->vf_ref = 0;
+ hevc->m_PIC[vf->index]->output_ready = 0;
if (hevc->wait_buf != 0)
WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
0x1);
spin_unlock_irqrestore(&lock, flags);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(hevc->pts_name, vf->pts);
}
if (kfifo_peek(&hevc->pending_q, &vf)) {
- if (pair_pic == NULL || pair_pic->vf_ref <= 0) {
+ if (pair_pic->vf_ref <= 0) {
/*
*if pair_pic is recycled (pair_pic->vf_ref <= 0),
*do not use it
@@ -9750,7 +9083,7 @@
vdec_vframe_ready(hw_to_vdec(hevc), vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(hevc->pts_name, vf->pts);
}
} else if ((!pair_frame_top_flag) &&
(((vf->index >> 8) & 0xff) == 0xff)) {
@@ -9772,7 +9105,7 @@
vdec_vframe_ready(hw_to_vdec(hevc), vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(hevc->pts_name, vf->pts);
hevc->vf_pre_count++;
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
hevc_print(hevc, 0,
@@ -9799,7 +9132,7 @@
vdec_vframe_ready(hw_to_vdec(hevc), vf);
kfifo_put(&hevc->display_q,
(const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(hevc->pts_name, vf->pts);
hevc->vf_pre_count++;
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
hevc_print(hevc, 0,
@@ -9814,33 +9147,16 @@
static void update_vf_memhandle(struct hevc_state_s *hevc,
struct vframe_s *vf, struct PIC_s *pic)
{
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
-
- /* keeper not needed for v4l solution */
- if (hevc->is_used_v4l)
- return;
-
- if (vf->type & VIDTYPE_SCATTER) {
-#ifdef H265_10B_MMU_DW
- if (hevc->dw_mmu_enable) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hevc->mmu_box_dw, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- } else
-
-#endif
- {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hevc->mmu_box, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- }
+ if (pic->index < 0) {
+ vf->mem_handle = NULL;
+ vf->mem_head_handle = NULL;
+ } else if (vf->type & VIDTYPE_SCATTER) {
+ vf->mem_handle =
+ decoder_mmu_box_get_mem_handle(
+ hevc->mmu_box, pic->index);
+ vf->mem_head_handle =
+ decoder_bmmu_box_get_mem_handle(
+ hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
} else {
vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
@@ -9912,11 +9228,11 @@
}
-static inline void hevc_update_gvs(struct hevc_state_s *hevc, struct PIC_s *pic)
+static inline void hevc_update_gvs(struct hevc_state_s *hevc)
{
- if (hevc->gvs->frame_height != pic->height) {
- hevc->gvs->frame_width = pic->width;
- hevc->gvs->frame_height = pic->height;
+ if (hevc->gvs->frame_height != hevc->frame_height) {
+ hevc->gvs->frame_width = hevc->frame_width;
+ hevc->gvs->frame_height = hevc->frame_height;
}
if (hevc->gvs->frame_dur != hevc->frame_dur) {
hevc->gvs->frame_dur = hevc->frame_dur;
@@ -9938,7 +9254,7 @@
decoder_do_frame_check(hw_to_vdec(hevc), vf);
vdec_vframe_ready(hw_to_vdec(hevc), vf);
kfifo_put(&hevc->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->pts);
+ ATRACE_COUNTER(hevc->pts_name, vf->pts);
}
static int post_prepare_process(struct vdec_s *vdec, struct PIC_s *frame)
@@ -9950,7 +9266,7 @@
frame->output_ready = 0;
frame->show_frame = false;
hevc_print(hevc, 0, "discard show frame.\n");
- return 0;
+ return -1;
}
frame->show_frame = true;
@@ -9968,8 +9284,6 @@
u32 frame_size = 0;
struct vdec_info tmp4x;
struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- int index;
/* swap uv */
if (hevc->is_used_v4l) {
@@ -9992,12 +9306,11 @@
if (hevc->is_used_v4l) {
vf->v4l_mem_handle
= hevc->m_BUF[pic->BUF_index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
if (hevc->mmu_enable) {
vf->mm_box.bmmu_box = hevc->bmmu_box;
- vf->mm_box.bmmu_idx = VF_BUFFER_IDX(hevc->buffer_wrap[pic->BUF_index]);
+ vf->mm_box.bmmu_idx = VF_BUFFER_IDX(pic->BUF_index);
vf->mm_box.mmu_box = hevc->mmu_box;
- vf->mm_box.mmu_idx = hevc->buffer_wrap[pic->BUF_index];
+ vf->mm_box.mmu_idx = pic->index;
}
}
@@ -10027,8 +9340,7 @@
if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
if (pts_lookup_offset_us64
(PTS_TYPE_VIDEO, stream_offset, &vf->pts,
- &frame_size, 0,
- &vf->pts_us64) != 0) {
+ &frame_size, 0, &vf->pts_us64) != 0) {
#ifdef DEBUG_PTS
hevc->pts_missed++;
#endif
@@ -10076,8 +9388,8 @@
hevc->last_pts_us64 = vf->pts_us64;
if ((get_dbg_flag(hevc) & H265_DEBUG_OUT_PTS) != 0) {
hevc_print(hevc, 0,
- "H265 dec out pts: vf->pts=%d, vf->pts_us64 = %lld, ts: %llu\n",
- vf->pts, vf->pts_us64, vf->timestamp);
+ "H265 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n",
+ vf->pts, vf->pts_us64);
}
/*
@@ -10097,44 +9409,26 @@
/* double write only */
vf->compBodyAddr = 0;
vf->compHeadAddr = 0;
-#ifdef H265_10B_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
-#endif
} else {
- if (hevc->mmu_enable) {
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic->header_adr;
-#ifdef H265_10B_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
- if (pic->double_write_mode & 0x20) {
- u32 mode = pic->double_write_mode & 0xf;
- if (mode == 5 || mode == 3)
- vf->dwHeadAddr = pic->header_dw_adr;
- else if ((mode == 1 || mode == 2 || mode == 4)
- && (debug & H265_DEBUG_OUT_PTS) == 0) {
- vf->compHeadAddr = pic->header_dw_adr;
- pr_debug("Use dw mmu for display\n");
- }
- }
-#endif
- } else {
- vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
- vf->compHeadAddr = pic->mc_y_adr +
- pic->losless_comp_body_size;
- vf->mem_head_handle = NULL;
- }
- /*head adr*/
+
+ if (hevc->mmu_enable) {
+ vf->compBodyAddr = 0;
+ vf->compHeadAddr = pic->header_adr;
+ } else {
+ vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+ vf->compHeadAddr = pic->mc_y_adr +
+ pic->losless_comp_body_size;
+ vf->mem_head_handle = NULL;
+ }
+
+ /*head adr*/
vf->canvas0Addr = vf->canvas1Addr = 0;
}
- if (pic->double_write_mode &&
- ((pic->double_write_mode & 0x20) == 0)) {
+ if (pic->double_write_mode) {
vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
vf->type |= nv_order;
- if (((pic->double_write_mode == 3) || (pic->double_write_mode == 5) ||
- (pic->double_write_mode == 9)) &&
+ if (((pic->double_write_mode == 3) || (pic->double_write_mode == 5)) &&
(!(IS_8K_SIZE(pic->width, pic->height)))) {
vf->type |= VIDTYPE_COMPRESS;
if (hevc->mmu_enable)
@@ -10286,21 +9580,9 @@
vf->sar_height = hevc->cur_pic->sar_height;
}
vf->width = vf->width /
- get_double_write_ratio(pic->double_write_mode & 0xf);
+ get_double_write_ratio(hevc, pic->double_write_mode);
vf->height = vf->height /
- get_double_write_ratio(pic->double_write_mode & 0xf);
-
-#ifdef H265_10B_MMU_DW
- if ((pic->double_write_mode & 0x20) &&
- ((pic->double_write_mode & 0xf) == 2 ||
- (pic->double_write_mode & 0xf) == 4)) {
- vf->compWidth = vf->width;
- vf->compHeight = vf->height;
- }
-#endif
- if (hevc->is_used_v4l && vdec->prog_only)
- pic->pic_struct = 0;
-
+ get_double_write_ratio(hevc, pic->double_write_mode);
#ifdef HEVC_PIC_STRUCT_SUPPORT
if (pic->pic_struct == 3 || pic->pic_struct == 4) {
struct vframe_s *vf2;
@@ -10331,20 +9613,12 @@
vf2->type = VIDTYPE_INTERLACE_TOP
| nv_order;
}
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- hevc->vf_pre_count++;
- vdec_vframe_ready(hw_to_vdec(hevc), vf2);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf2);
- ATRACE_COUNTER(hevc->trace.pts_name, vf2->pts);
- } else {
- vh265_vf_put(vf, vdec);
- vh265_vf_put(vf2, vdec);
- atomic_add(2, &hevc->vf_get_count);
- hevc->vf_pre_count += 2;
- return 0;
- }
+ put_vf_to_display_q(hevc, vf);
+ hevc->vf_pre_count++;
+ vdec_vframe_ready(hw_to_vdec(hevc), vf2);
+ kfifo_put(&hevc->display_q,
+ (const struct vframe_s *)vf2);
+ ATRACE_COUNTER(hevc->pts_name, vf2->pts);
} else if (pic->pic_struct == 5
|| pic->pic_struct == 6) {
struct vframe_s *vf2, *vf3;
@@ -10385,26 +9659,18 @@
vf3->type = VIDTYPE_INTERLACE_BOTTOM
| nv_order;
}
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- hevc->vf_pre_count++;
- vdec_vframe_ready(hw_to_vdec(hevc), vf2);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf2);
- ATRACE_COUNTER(hevc->trace.pts_name, vf2->pts);
- hevc->vf_pre_count++;
- vdec_vframe_ready(hw_to_vdec(hevc), vf3);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf3);
- ATRACE_COUNTER(hevc->trace.pts_name, vf3->pts);
- } else {
- vh265_vf_put(vf, vdec);
- vh265_vf_put(vf2, vdec);
- vh265_vf_put(vf3, vdec);
- atomic_add(3, &hevc->vf_get_count);
- hevc->vf_pre_count += 3;;
- return 0;
- }
+ put_vf_to_display_q(hevc, vf);
+ hevc->vf_pre_count++;
+ vdec_vframe_ready(hw_to_vdec(hevc), vf2);
+ kfifo_put(&hevc->display_q,
+ (const struct vframe_s *)vf2);
+ ATRACE_COUNTER(hevc->pts_name, vf2->pts);
+ hevc->vf_pre_count++;
+ vdec_vframe_ready(hw_to_vdec(hevc), vf3);
+ kfifo_put(&hevc->display_q,
+ (const struct vframe_s *)vf3);
+ ATRACE_COUNTER(hevc->pts_name, vf3->pts);
+
} else if (pic->pic_struct == 9
|| pic->pic_struct == 10) {
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
@@ -10417,40 +9683,35 @@
/* process previous pending vf*/
process_pending_vframe(hevc,
pic, (pic->pic_struct == 9));
+
+ decoder_do_frame_check(vdec, vf);
+ vdec_vframe_ready(vdec, vf);
+ /* process current vf */
+ kfifo_put(&hevc->pending_q,
+ (const struct vframe_s *)vf);
vf->height <<= 1;
- if (pic->show_frame) {
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- /* process current vf */
- kfifo_put(&hevc->pending_q,
- (const struct vframe_s *)vf);
- if (pic->pic_struct == 9) {
- vf->type = VIDTYPE_INTERLACE_TOP
- | nv_order | VIDTYPE_VIU_FIELD;
- process_pending_vframe(hevc,
- hevc->pre_bot_pic, 0);
- } else {
- vf->type = VIDTYPE_INTERLACE_BOTTOM |
- nv_order | VIDTYPE_VIU_FIELD;
- vf->index = (pic->index << 8) | 0xff;
- process_pending_vframe(hevc,
- hevc->pre_top_pic, 1);
- }
-
- if (hevc->vf_pre_count == 0)
- hevc->vf_pre_count++;
-
- /**/
- if (pic->pic_struct == 9)
- hevc->pre_top_pic = pic;
- else
- hevc->pre_bot_pic = pic;
+ if (pic->pic_struct == 9) {
+ vf->type = VIDTYPE_INTERLACE_TOP
+ | nv_order | VIDTYPE_VIU_FIELD;
+ process_pending_vframe(hevc,
+ hevc->pre_bot_pic, 0);
} else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
- hevc->vf_pre_count++;
- return 0;
+ vf->type = VIDTYPE_INTERLACE_BOTTOM |
+ nv_order | VIDTYPE_VIU_FIELD;
+ vf->index = (pic->index << 8) | 0xff;
+ process_pending_vframe(hevc,
+ hevc->pre_top_pic, 1);
}
+
+ if (hevc->vf_pre_count == 0)
+ hevc->vf_pre_count++;
+
+ /**/
+ if (pic->pic_struct == 9)
+ hevc->pre_top_pic = pic;
+ else
+ hevc->pre_bot_pic = pic;
+
} else if (pic->pic_struct == 11
|| pic->pic_struct == 12) {
if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
@@ -10473,25 +9734,19 @@
nv_order | VIDTYPE_VIU_FIELD;
vf->index = (pic->index << 8) | 0xff;
}
- if (pic->show_frame) {
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hevc->pending_q,
- (const struct vframe_s *)vf);
- if (hevc->vf_pre_count == 0)
- hevc->vf_pre_count++;
-
- /**/
- if (pic->pic_struct == 11)
- hevc->pre_top_pic = pic;
- else
- hevc->pre_bot_pic = pic;
- } else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
+ decoder_do_frame_check(vdec, vf);
+ vdec_vframe_ready(vdec, vf);
+ kfifo_put(&hevc->pending_q,
+ (const struct vframe_s *)vf);
+ if (hevc->vf_pre_count == 0)
hevc->vf_pre_count++;
- return 0;
- }
+
+ /**/
+ if (pic->pic_struct == 11)
+ hevc->pre_top_pic = pic;
+ else
+ hevc->pre_bot_pic = pic;
+
} else {
pic->vf_ref = 1;
@@ -10524,81 +9779,50 @@
hevc->pre_bot_pic = pic;
break;
}
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- } else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
- hevc->vf_pre_count++;
- return 0;
- }
+ put_vf_to_display_q(hevc, vf);
}
#else
vf->type_original = vf->type;
pic->vf_ref = 1;
put_vf_to_display_q(hevc, vf);
#endif
- ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q));
- ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q));
+ ATRACE_COUNTER(hevc->new_q_name, kfifo_len(&hevc->newframe_q));
+ ATRACE_COUNTER(hevc->disp_q_name, kfifo_len(&hevc->display_q));
/*count info*/
vdec_count_info(hevc->gvs, 0, stream_offset);
- if (pic->slice_type == I_SLICE) {
- hevc->gvs->i_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME;
- } else if (pic->slice_type == P_SLICE) {
- hevc->gvs->p_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_PFRAME;
- } else if (pic->slice_type == B_SLICE) {
- hevc->gvs->b_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_BFRAME;
+ if (hevc->cur_pic != NULL) {
+ if (hevc->cur_pic->slice_type == I_SLICE) {
+ hevc->gvs->i_decoded_frames++;
+ } else if (hevc->cur_pic->slice_type == P_SLICE) {
+ hevc->gvs->p_decoded_frames++;
+ } else if (hevc->cur_pic->slice_type == B_SLICE) {
+ hevc->gvs->b_decoded_frames++;
+ }
}
- hevc_update_gvs(hevc, pic);
+ hevc_update_gvs(hevc);
memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = pic->bit_depth_luma;
- tmp4x.bit_depth_chroma = pic->bit_depth_chroma;
- tmp4x.double_write_mode = pic->double_write_mode;
+ tmp4x.bit_depth_luma = hevc->bit_depth_luma;
+ tmp4x.bit_depth_chroma = hevc->bit_depth_chroma;
+ tmp4x.double_write_mode = get_double_write_mode(hevc);
vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, &tmp4x, vf, pic->hw_decode_time);
vdec->vdec_fps_detec(vdec->id);
hevc_print(hevc, H265_DEBUG_BUFMGR,
- "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n",
+ "%s(type %d index 0x%x poc %d/%d) pts(%d,%lld) dur %d\n",
__func__, vf->type, vf->index,
get_pic_poc(hevc, vf->index & 0xff),
get_pic_poc(hevc, (vf->index >> 8) & 0xff),
vf->pts, vf->pts_us64,
vf->duration);
-
- if (pic->pic_struct == 10 || pic->pic_struct == 12) {
- index = (vf->index >> 8) & 0xff;
- } else {
- index = vf->index & 0xff;
- }
-
#ifdef AUX_DATA_CRC
- if (index <= MAX_REF_PIC_NUM)
- decoder_do_aux_data_check(vdec, hevc->m_PIC[index]->aux_data_buf,
- hevc->m_PIC[index]->aux_data_size);
+ if ((vf->index & 0xff) <= MAX_REF_PIC_NUM)
+ decoder_do_aux_data_check(vdec, hevc->m_PIC[vf->index & 0xff]->aux_data_buf,
+ hevc->m_PIC[vf->index & 0xff]->aux_data_size);
#endif
-
- hevc_print(hevc, H265_DEBUG_PRINT_SEI,
- "aux_data_size:%d, signal_type: %d, sei_present_flag: %d\n",
- hevc->m_PIC[index]->aux_data_size, hevc->video_signal_type, hevc->sei_present_flag);
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- int i = 0;
- PR_INIT(128);
- for (i = 0; i < hevc->m_PIC[index]->aux_data_size; i++) {
- PR_FILL("%02x ", hevc->m_PIC[index]->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
-
if (hevc->is_used_v4l)
update_vframe_src_fmt(vf,
- hevc->m_PIC[index]->aux_data_buf,
- hevc->m_PIC[index]->aux_data_size,
- hevc->dv_duallayer, hevc->provider_name, NULL);
+ hevc->m_PIC[vf->index & 0xff]->aux_data_buf,
+ hevc->m_PIC[vf->index & 0xff]->aux_data_size,
+ false, hevc->provider_name, NULL);
/*if (pic->vf_ref == hevc->vf_pre_count) {*/
if (hevc->kpi_first_i_decoded == 0) {
@@ -10608,16 +9832,8 @@
}
if (without_display_mode == 0) {
- if (hevc->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vh265_vf_put(vh265_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
+ vf_notify_receiver(hevc->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
}
else
vh265_vf_put(vh265_vf_get(vdec), vdec);
@@ -10635,10 +9851,10 @@
return 0;
/* create fence for each buffers. */
- if (vdec_timeline_create_fence(vdec->sync))
+ if (vdec_timeline_create_fence(&vdec->sync))
return -1;
- pic->fence = vdec->sync->fence;
+ pic->fence = vdec->sync.fence;
pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
if (hevc->chunk) {
@@ -10646,7 +9862,7 @@
pic->pts64 = hevc->chunk->pts64;
pic->timestamp = hevc->chunk->timestamp;
}
- pic->show_frame = true;
+
post_video_frame(vdec, pic);
display_frame_count[hevc->index]++;
@@ -10660,10 +9876,6 @@
(struct hevc_state_s *)vdec->private;
if (hevc->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
-
post_prepare_process(vdec, frame);
if (!frame->show_frame)
@@ -10672,35 +9884,16 @@
hevc->m_PIC[frame->index]->vf_ref = 1;
/* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
- mutex_lock(&hevc->fence_mutex);
- used_size = hevc->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (hevc->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(hevc->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = hevc->fence_vf_s.fence_vf[i];
- hevc->fence_vf_s.fence_vf[i] = NULL;
- hevc->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&hevc->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vh265_vf_put(signed_fence[i], vdec);
- }
-
+ vdec_timeline_increase(&vdec->sync, 1);
return 0;
}
if (post_prepare_process(vdec, frame))
return -1;
+ if (!frame->show_frame)
+ return 0;
+
if (post_video_frame(vdec, frame))
return -1;
@@ -10727,8 +9920,7 @@
}
if (index == INVALID_IDX) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
pr_err("[%d] EOS get free buff fail.\n", ctx->id);
return -1;
}
@@ -10740,16 +9932,10 @@
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
hw->m_BUF[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
-
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
pr_info("[%d] H265 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
@@ -11080,7 +10266,7 @@
struct vdec_s *vdec = hw_to_vdec(hevc);
if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
+ H265_DEBUG_BUFMGR_MORE)
dump_aux_buf(hevc);
if (vdec->dolby_meta_with_el || vdec->slave) {
set_aux_data(hevc,
@@ -11111,123 +10297,49 @@
hevc->rps_set_id = (decode_info >> 8) & 0xff;
}
-static int vh265_get_ps_info(struct hevc_state_s *hevc,
- union param_u *rpm_param,
- struct aml_vdec_ps_infos *ps)
+static int vh265_get_ps_info(struct hevc_state_s *hevc, int width, int height, struct aml_vdec_ps_infos *ps)
{
- u32 width = rpm_param->p.pic_width_in_luma_samples;
- u32 height = rpm_param->p.pic_height_in_luma_samples;
- u32 SubWidthC, SubHeightC;
+ int dw_mode = v4l_parser_get_double_write_mode(hevc, width, height);
- switch (rpm_param->p.chroma_format_idc) {
- case 1:
- SubWidthC = 2;
- SubHeightC = 2;
- break;
- case 2:
- SubWidthC = 2;
- SubHeightC = 1;
- break;
- default:
- SubWidthC = 1;
- SubHeightC = 1;
- break;
- }
-
- width -= SubWidthC *
- (rpm_param->p.conf_win_left_offset +
- rpm_param->p.conf_win_right_offset);
- height -= SubHeightC *
- (rpm_param->p.conf_win_top_offset +
- rpm_param->p.conf_win_bottom_offset);
-
- hevc->last_width = rpm_param->p.pic_width_in_luma_samples;
- hevc->last_height = rpm_param->p.pic_height_in_luma_samples;
- hevc->sps_num_reorder_pics_0 =
- rpm_param->p.sps_num_reorder_pics_0;
- hevc->used_buf_num = v4l_parser_work_pic_num(hevc);
-
- ps->visible_width = width;
- ps->visible_height = height;
- ps->coded_width = ALIGN(width, 64);
- ps->coded_height = ALIGN(height, 64);
+ ps->visible_width = width / get_double_write_ratio(hevc, dw_mode);
+ ps->visible_height = height / get_double_write_ratio(hevc, dw_mode);
+ ps->coded_width = ALIGN(width, 32) / get_double_write_ratio(hevc, dw_mode);
+ ps->coded_height = ALIGN(height, 32) / get_double_write_ratio(hevc, dw_mode);
ps->dpb_size = v4l_parser_work_pic_num(hevc);
+ ps->field = hevc->interlace_flag ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
return 0;
}
-static void get_comp_buf_info(struct hevc_state_s *hevc,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = hevc->param.p.bit_depth;
- int w = hevc->param.p.pic_width_in_luma_samples;
- int h = hevc->param.p.pic_height_in_luma_samples;
-
- info->max_size = hevc_max_mmu_buf_size(
- hevc->max_pic_w,
- hevc->max_pic_h);
- info->header_size = hevc_get_header_size(w,h);
- info->frame_buffer_size = hevc_mmu_page_num(
- hevc, w, h, bit_depth == 0);
-
- pr_info("hevc get comp info: %d %d %d\n",
- info->max_size, info->header_size,
- info->frame_buffer_size);
-}
-
static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param)
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- int i, ret = 0;
+ int ret = 0;
- if (ctx->param_sets_from_ucode) {
+ if (ctx->param_sets_from_ucode &&
+ hevc->res_ch_flag == 0) {
struct aml_vdec_ps_infos ps;
int width = rpm_param->p.pic_width_in_luma_samples;
int height = rpm_param->p.pic_height_in_luma_samples;
- if ((hevc->last_width != 0 &&
- hevc->last_height != 0) &&
- (hevc->last_width != width ||
- hevc->last_height != height)) {
+ if ((hevc->pic_w != 0 &&
+ hevc->pic_h != 0) &&
+ (hevc->pic_w != width ||
+ hevc->pic_h != height)) {
hevc_print(hevc, 0,
"v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n",
- hevc->last_width, hevc->last_height,
+ hevc->pic_w, hevc->pic_h,
width,
height,
hevc->interlace_flag);
- if (get_valid_double_write_mode(hevc) != 16) {
- struct vdec_comp_buf_info info;
-
- get_comp_buf_info(hevc, &info);
- vdec_v4l_set_comp_buf_info(ctx, &info);
- }
-
- vh265_get_ps_info(hevc, &hevc->param, &ps);
+ vh265_get_ps_info(hevc, width, height, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
vdec_v4l_res_ch_event(ctx);
hevc->v4l_params_parsed = false;
+ hevc->res_ch_flag = 1;
ctx->v4l_resolution_change = 1;
hevc->eos = 1;
-
- /*
- * marks frame valid on the dpb is the ouput state,
- * then via flush_output all frames can be flushed out.
- */
- for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
- if ((hevc->m_PIC[i] == NULL) ||
- (hevc->m_PIC[i]->index == -1) ||
- (hevc->m_PIC[i]->BUF_index == -1))
- continue;
-
- if ((hevc->m_PIC[i]->POC != INVALID_POC) &&
- (hevc->m_PIC[i]->output_ready == 0) &&
- hevc->m_PIC[i]->referenced &&
- (hevc->m_PIC[i]->POC >= hevc->decoded_poc)) {
- hevc->m_PIC[i]->output_mark = 1;
- }
- }
-
flush_output(hevc, NULL);
//del_timer_sync(&hevc->timer);
notify_v4l_eos(hw_to_vdec(hevc));
@@ -11254,6 +10366,55 @@
return 0;
}
+#ifdef VDEC_FCC_SUPPORT
+static void fcc_discard_mode_process(struct vdec_s *vdec, struct hevc_state_s *hevc)
+{
+ if (vdec->fcc_status == AGAIN_STATUS &&
+ hevc->param.p.slice_type == I_SLICE) {
+ vdec->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+ hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
+ "[%d][FCC]: Notify stream_offset: %u\n",
+ vdec->id, vdec->stream_offset);
+
+ vdec_wakeup_fcc_poll(vdec);
+ amhevc_stop();
+ vdec->fcc_status = WAIT_MSG_STATUS;
+ hevc->dec_result = DEC_RESULT_AGAIN;
+ vdec_schedule_work(&hevc->work);
+ } else if (vdec->fcc_status == DISCARD_STATUS ||
+ hevc->param.p.slice_type != I_SLICE) {
+ hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
+ "[%d][FCC]: Discard current gop and to find next gop!\n",
+ vdec->id);
+
+ amhevc_stop();
+ vdec->fcc_status = AGAIN_STATUS;
+ hevc->dec_result = DEC_RESULT_DISCARD_DATA;
+ vdec_schedule_work(&hevc->work);
+ }
+}
+
+static int vh265_fcc_process(struct vdec_s *vdec, struct hevc_state_s *hevc)
+{
+ if (input_stream_based(vdec)) {
+ switch (vdec->fcc_mode) {
+ case FCC_DISCARD_MODE:
+ fcc_discard_mode_process(vdec, hevc);
+ return 1;
+ case FCC_DEC_MODE:
+ hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
+ "[%d][FCC]: Current is Dec mode.\n", vdec->id);
+ break;
+ case FCC_BUTT:
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
+
static void aspect_ratio_set(struct hevc_state_s *hevc)
{
int aspect_ratio_idc = hevc->param.p.aspect_ratio_idc;
@@ -11356,13 +10517,6 @@
struct vdec_s *vdec = hw_to_vdec(hevc);
- if (dec_status == HEVC_SLICE_SEGMENT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
if (hevc->eos)
return IRQ_HANDLED;
if (
@@ -11548,20 +10702,11 @@
#endif
hevc->empty_flag = 0;
pic_done:
- if (vdec->master == NULL && vdec->slave == NULL &&
- hevc->empty_flag == 0) {
- hevc->over_decode =
- (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
- if (hevc->over_decode)
- hevc_print(hevc, 0,
- "!!!Over decode %d\n", __LINE__);
- }
if (input_frame_based(hw_to_vdec(hevc)) &&
frmbase_cont_bitlevel != 0 &&
(hevc->decode_size > READ_VREG(HEVC_SHIFT_BYTE_COUNT)) &&
(hevc->decode_size - (READ_VREG(HEVC_SHIFT_BYTE_COUNT))
> frmbase_cont_bitlevel)) {
- check_pic_decoded_error(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff);
/*handle the case: multi pictures in one packet*/
hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
"%s has more data index= %d, size=0x%x shiftcnt=0x%x)\n",
@@ -11617,12 +10762,27 @@
&& ((hevc->double_write_mode & 0x10) == 0)) {
if (!hevc->m_ins_flag) {
hevc->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+ READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+
if ((!is_skip_decoding(hevc, pic)) &&
(hevc->used_4k_num >= 0) &&
(hevc->cur_pic->scatter_alloc
- == 1))
- recycle_mmu_buf_tail(hevc, false);
+ == 1)) {
+ hevc_print(hevc,
+ H265_DEBUG_BUFMGR_MORE,
+ "%s pic index %d scatter_alloc %d page_start %ld\n",
+ "decoder_mmu_box_free_idx_tail",
+ hevc->cur_pic->index,
+ hevc->cur_pic->scatter_alloc,
+ hevc->used_4k_num);
+ decoder_mmu_box_free_idx_tail(
+ hevc->mmu_box,
+ hevc->cur_pic->index,
+ hevc->used_4k_num);
+ hevc->cur_pic->scatter_alloc
+ = 2;
+ }
+ hevc->used_4k_num = -1;
}
}
@@ -11636,7 +10796,7 @@
}
}
/*Detects the first frame whether has an over decode error*/
- if (vdec->master == NULL && vdec->slave == NULL &&
+ if ((!vdec_dual(vdec)) &&
hevc->empty_flag == 0) {
hevc->over_decode =
(READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
@@ -11688,7 +10848,7 @@
}
}
}
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
+
vdec_schedule_work(&hevc->work);
}
@@ -11828,7 +10988,7 @@
}
#endif
/*Detects frame whether has an over decode error*/
- if (vdec->master == NULL && vdec->slave == NULL &&
+ if ((!vdec_dual(vdec)) &&
hevc->empty_flag == 0 && input_stream_based(vdec)) {
hevc->over_decode =
(READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
@@ -12036,7 +11196,7 @@
if (get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG)
get_rpm_param(&hevc->param);
else {
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
+
for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
int ii;
@@ -12046,11 +11206,14 @@
- ii];
}
}
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
#ifdef SEND_LMEM_WITH_RPM
check_head_error(hevc);
#endif
}
+#ifdef VDEC_FCC_SUPPORT
+ if (vh265_fcc_process(vdec, hevc) > 0)
+ return IRQ_HANDLED;
+#endif
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
hevc_print(hevc, 0,
"rpm_param: (%d)\n", hevc->slice_idx);
@@ -12078,22 +11241,9 @@
struct aml_vdec_ps_infos ps;
int width = hevc->param.p.pic_width_in_luma_samples;
int height = hevc->param.p.pic_height_in_luma_samples;
- int log = hevc->param.p.log2_min_coding_block_size_minus3;
- int log_s = hevc->param.p.log2_diff_max_min_coding_block_size;
-
- hevc->pic_w = width;
- hevc->pic_h = height;
- hevc->lcu_size = 1 << (log + 3 + log_s);
pr_debug("set ucode parse\n");
- if (get_valid_double_write_mode(hevc) != 16) {
- struct vdec_comp_buf_info info;
-
- get_comp_buf_info(hevc, &info);
- vdec_v4l_set_comp_buf_info(ctx, &info);
- }
-
- vh265_get_ps_info(hevc, &hevc->param, &ps);
+ vh265_get_ps_info(hevc, width, height, &ps);
/*notice the v4l2 codec.*/
vdec_v4l_set_ps_infos(ctx, &ps);
hevc->v4l_params_parsed = true;
@@ -12112,6 +11262,7 @@
reset_process_time(hevc);
vdec_schedule_work(&hevc->work);
return IRQ_HANDLED;
+
}
}
@@ -12124,7 +11275,7 @@
) {
if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
+ H265_DEBUG_BUFMGR_MORE)
dump_aux_buf(hevc);
}
@@ -12250,16 +11401,15 @@
} else {
hevc->sps_num_reorder_pics_0 =
hevc->param.p.sps_num_reorder_pics_0;
- hevc->ip_mode = hevc->low_latency_flag ? true :
- (!hevc->sps_num_reorder_pics_0 &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
+ hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 &&
+ !(vdec->slave || vdec->master) &&
+ !disable_ip_mode &&
+ hevc->low_latency_flag) ? true : false;
hevc->pic_list_init_flag = 1;
if ((!IS_4K_SIZE(hevc->pic_w, hevc->pic_h)) &&
((hevc->param.p.profile_etc & 0xc) == 0x4)
&& (interlace_enable != 0)) {
hevc->double_write_mode = 1;
- hevc->mmu_enable = 1;
hevc->interlace_flag = 1;
hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2;
hevc_print(hevc, 0,
@@ -12267,7 +11417,7 @@
hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar,
get_double_write_mode(hevc));
/* When dw changed from 0x10 to 1, the mmu_box is NULL */
- if (!hevc->mmu_box && init_mmu_buffers(hevc, 1) != 0) {
+ if (!hevc->mmu_box && init_mmu_box(hevc) != 0) {
hevc->dec_result = DEC_RESULT_FORCE_EXIT;
hevc->fatal_error |=
DECODER_FATAL_ERROR_NO_MEM;
@@ -12276,17 +11426,6 @@
0, "can not alloc mmu box, force exit\n");
return IRQ_HANDLED;
}
- if (hevc->frame_mmu_map_addr == NULL) {
- hevc->frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(),
- &hevc->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hevc->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return IRQ_HANDLED;
- }
- memset(hevc->frame_mmu_map_addr, 0, get_frame_mmu_map_size());
- }
}
#ifdef MULTI_INSTANCE_SUPPORT
if (hevc->m_ins_flag) {
@@ -12296,7 +11435,6 @@
up(&h265_sema);
hevc_print(hevc, 0, "set pic_list_init_flag 1\n");
}
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
return IRQ_HANDLED;
}
@@ -12325,6 +11463,7 @@
hevc_print(hevc, H265_DEBUG_OUT_PTS,
"read stream_offset = 0x%x\n",
hevc->cur_pic->stream_offset);
+
hevc->cur_pic->aspect_ratio_idc =
hevc->param.p.aspect_ratio_idc;
hevc->cur_pic->sar_width =
@@ -12376,8 +11515,6 @@
WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
}
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
-
} else if (dec_status == HEVC_DECODE_OVER_SIZE) {
hevc_print(hevc, 0 , "hevc decode oversize !!\n");
#ifdef MULTI_INSTANCE_SUPPORT
@@ -12411,14 +11548,6 @@
u32 debug_tag;
dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
-
- if (dec_status == HEVC_SLICE_SEGMENT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
-
if (hevc->init_flag == 0)
return IRQ_HANDLED;
hevc->dec_status = dec_status;
@@ -12509,7 +11638,7 @@
return IRQ_HANDLED;
}
}
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_END);
+
return IRQ_WAKE_THREAD;
}
@@ -12527,10 +11656,10 @@
hevc->frame_height * fps;
}
-static void vh265_check_timer_func(struct timer_list *timer)
+static void vh265_check_timer_func(unsigned long arg)
{
- struct hevc_state_s *hevc = container_of(timer,
- struct hevc_state_s, timer);
+ struct hevc_state_s *hevc = (struct hevc_state_s *)arg;
+ struct timer_list *timer = &hevc->timer;
unsigned char empty_flag;
unsigned int buf_level;
@@ -12836,17 +11965,11 @@
96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1);
else
vstatus->frame_rate = -1;
- vstatus->error_count = hevc->gvs->error_frame_count;
- vstatus->status = hevc->stat | hevc->fatal_error;
- if (!vdec_is_support_4k() &&
- (IS_4K_SIZE(vstatus->frame_width, vstatus->frame_height)) &&
- (vstatus->frame_width <= 4096 && vstatus->frame_height <= 2304)) {
- vstatus->status |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- }
- vstatus->bit_rate = hevc->gvs->bit_rate;
+ vstatus->status = hevc->stat | hevc->fatal_error;
vstatus->frame_dur = hevc->frame_dur;
if (hevc->gvs) {
+ vstatus->error_count = hevc->gvs->error_frame_count;
vstatus->bit_rate = hevc->gvs->bit_rate;
vstatus->frame_data = hevc->gvs->frame_data;
vstatus->total_data = hevc->gvs->total_data;
@@ -12913,28 +12036,28 @@
int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
- hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode);
+ struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
+ hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode);
- if (trickmode == TRICKMODE_I) {
+ if (trickmode == TRICKMODE_I) {
trickmode_i = 1;
i_only_flag = 0x1;
- } else if (trickmode == TRICKMODE_NONE) {
+ } else if (trickmode == TRICKMODE_NONE) {
trickmode_i = 0;
i_only_flag = 0x0;
- } else if (trickmode == 0x02) {
+ } else if (trickmode == 0x02) {
trickmode_i = 0;
i_only_flag = 0x02;
- } else if (trickmode == 0x03) {
+ } else if (trickmode == 0x03) {
trickmode_i = 1;
i_only_flag = 0x03;
- } else if (trickmode == 0x07) {
+ } else if (trickmode == 0x07) {
trickmode_i = 1;
i_only_flag = 0x07;
- }
- //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i);
+ }
+ //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i);
- return 0;
+ return 0;
}
static void config_decode_mode(struct hevc_state_s *hevc)
@@ -13026,6 +12149,7 @@
} else {
/* check vps/sps/pps/i-slice in ucode */
unsigned ctl_val = 0x8;
+
if (hevc->PB_skip_mode == 0)
ctl_val = 0x4; /* check vps/sps/pps only in ucode */
else if (hevc->PB_skip_mode == 3)
@@ -13164,7 +12288,7 @@
int fw_size = 0x1000 * 16;
struct firmware_s *fw = NULL;
- timer_setup(&hevc->timer, vh265_check_timer_func, 0);
+ init_timer(&hevc->timer);
hevc->stat |= STAT_TIMER_INIT;
@@ -13183,11 +12307,11 @@
INIT_WORK(&hevc->notify_work, vh265_notify_work);
INIT_WORK(&hevc->set_clk_work, vh265_set_clk);
- fw = vzalloc(sizeof(struct firmware_s) + fw_size);
+ fw = vmalloc(sizeof(struct firmware_s) + fw_size);
if (IS_ERR_OR_NULL(fw))
return -ENOMEM;
- if (hevc->mmu_enable) {
+ if (hevc->mmu_enable)
if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM)
size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data);
else {
@@ -13206,7 +12330,7 @@
size = get_firmware_data(VIDEO_DEC_HEVC_MMU,
fw->data);
}
- } else
+ else
size = get_firmware_data(VIDEO_DEC_HEVC, fw->data);
if (size < 0) {
@@ -13236,7 +12360,7 @@
hevc->swap_size);
hevc_print(hevc, 0,
- "vh265 mmu ucode swap loaded %x\n",
+ "vh265 mmu ucode swap loaded %llx\n",
hevc->mc_dma_handle);
}
}
@@ -13244,8 +12368,8 @@
#ifdef MULTI_INSTANCE_SUPPORT
if (hevc->m_ins_flag) {
- //hevc->timer.data = (ulong) hevc;
- //hevc->timer.function = vh265_check_timer_func;
+ hevc->timer.data = (ulong) hevc;
+ hevc->timer.function = vh265_check_timer_func;
hevc->timer.expires = jiffies + PUT_INTERVAL;
hevc->fw = fw;
@@ -13311,23 +12435,21 @@
hevc->provider_name = PROVIDER_NAME;
#ifdef MULTI_INSTANCE_SUPPORT
- if (!hevc->is_used_v4l) {
- vf_provider_init(&vh265_vf_prov, hevc->provider_name,
- &vh265_vf_provider, vdec);
- vf_reg_provider(&vh265_vf_prov);
- vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START,
- NULL);
- if (hevc->frame_dur != 0) {
- if (!is_reset) {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- fr_hint_status = VDEC_HINTED;
- }
- } else
- fr_hint_status = VDEC_NEED_HINT;
- }
+ vf_provider_init(&vh265_vf_prov, hevc->provider_name,
+ &vh265_vf_provider, vdec);
+ vf_reg_provider(&vh265_vf_prov);
+ vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START,
+ NULL);
+ if (hevc->frame_dur != 0) {
+ if (!is_reset) {
+ vf_notify_receiver(hevc->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)
+ ((unsigned long)hevc->frame_dur));
+ fr_hint_status = VDEC_HINTED;
+ }
+ } else
+ fr_hint_status = VDEC_NEED_HINT;
#else
vf_provider_init(&vh265_vf_prov, PROVIDER_NAME, &vh265_vf_provider,
hevc);
@@ -13344,8 +12466,8 @@
#endif
hevc->stat |= STAT_VF_HOOK;
- //hevc->timer.data = (ulong) hevc;
- //hevc->timer.function = vh265_check_timer_func;
+ hevc->timer.data = (ulong) hevc;
+ hevc->timer.function = vh265_check_timer_func;
hevc->timer.expires = jiffies + PUT_INTERVAL;
add_timer(&hevc->timer);
@@ -13659,38 +12781,6 @@
}
#endif
-static bool is_avaliable_buffer(struct hevc_state_s *hevc)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- struct PIC_s *pic = NULL;
- int i, free_count = 0;
-
- if (ctx->cap_pool.dec < hevc->used_buf_num) {
- free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if (free_count &&
- !ctx->fb_ops.query(&ctx->fb_ops, &hevc->fb_token)) {
- return false;
- }
- }
-
- for (i = 0; i < hevc->used_buf_num; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- pic->index == -1 ||
- pic->BUF_index == -1)
- continue;
-
- if (pic->output_mark == 0 &&
- pic->referenced == 0 &&
- pic->output_ready == 0 &&
- pic->cma_alloc_addr) {
- free_count++;
- }
- }
-
- return free_count < run_ready_min_buf_num ? 0 : 1;
-}
static unsigned char is_new_pic_available(struct hevc_state_s *hevc)
{
@@ -13722,7 +12812,7 @@
new_pic = pic;
}
}
- if (!hevc->is_used_v4l && new_pic == NULL) {
+ if (new_pic == NULL) {
enum receviver_start_e state = RECEIVER_INACTIVE;
if (vf_get_receiver(vdec->vf_provider_name)) {
state =
@@ -13742,7 +12832,7 @@
if ((pic->referenced == 0) &&
(pic->error_mark == 1) &&
(pic->output_mark == 1)) {
- if (poc == INVALID_POC || (pic->POC < poc)) {
+ if (pic->POC < poc) {
new_pic = pic;
poc = pic->POC;
}
@@ -13785,7 +12875,7 @@
if (!(error_handle_policy & 0x400)) {
spin_unlock_irqrestore(&lock, flags);
flush_output(hevc, NULL);
- hevc_print(hevc, H265_DEBUG_BUFMGR, "flush dpb, ref_error_count %d, sps_max_dec_pic_buffering_minus1_0 %d\n",
+ hevc_print(hevc, H265_DEBUG_BUFMGR_MORE, "flush dpb, ref_error_count %d, sps_max_dec_pic_buffering_minus1_0 %d\n",
decode_count, hevc->param.p.sps_max_dec_pic_buffering_minus1_0);
return 0;
}
@@ -13803,10 +12893,6 @@
struct vdec_s *vdec = hw_to_vdec(hevc);
enum receviver_start_e state = RECEIVER_INACTIVE;
-
- if (hevc->is_used_v4l)
- return;
-
if (vf_get_receiver(vdec->vf_provider_name)) {
state =
vf_notify_receiver(vdec->vf_provider_name,
@@ -13834,7 +12920,7 @@
if ((pic->referenced == 0) &&
(pic->error_mark == 1) &&
(pic->output_mark == 1)) {
- if (poc == INVALID_POC || (pic->POC < poc)) {
+ if (pic->POC < poc) {
new_pic = pic;
poc = pic->POC;
}
@@ -13876,7 +12962,7 @@
hevc->stat &= ~STAT_ISR_REG;
}
- if (!hevc->is_used_v4l && hevc->stat & STAT_VF_HOOK) {
+ if (hevc->stat & STAT_VF_HOOK) {
if (fr_hint_status == VDEC_HINTED)
vf_notify_receiver(hevc->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -13939,14 +13025,6 @@
for (jj = 0; jj < size; jj++)
sum += data[jj];
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, sum,
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
-
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
@@ -13959,10 +13037,6 @@
struct hevc_state_s,
notify_work);
struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (hevc->is_used_v4l)
- return;
-
#ifdef MULTI_INSTANCE_SUPPORT
if (vdec->fr_hint_state == VDEC_NEED_HINT) {
vf_notify_receiver(hevc->provider_name,
@@ -13993,11 +13067,6 @@
static void vh265_work_implement(struct hevc_state_s *hevc,
struct vdec_s *vdec,int from)
{
- if (hevc->dec_result == DEC_RESULT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_START);
- } else if (hevc->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_AGAIN);
-
if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) {
/*USE_BUF_BLOCK*/
uninit_pic_list(hevc);
@@ -14179,20 +13248,34 @@
}
}
#endif
+
if (hevc->mmu_enable && ((hevc->double_write_mode & 0x10) == 0)) {
hevc->used_4k_num =
READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
if (hevc->used_4k_num >= 0 &&
hevc->cur_pic &&
hevc->cur_pic->scatter_alloc
- == 1)
- recycle_mmu_buf_tail(hevc, hevc->m_ins_flag);
+ == 1) {
+ hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
+ "%s pic index %d scatter_alloc %d page_start %ld\n",
+ "decoder_mmu_box_free_idx_tail",
+ hevc->cur_pic->index,
+ hevc->cur_pic->scatter_alloc,
+ hevc->used_4k_num);
+ if (hevc->m_ins_flag)
+ hevc_mmu_dma_check(hw_to_vdec(hevc));
+ decoder_mmu_box_free_idx_tail(
+ hevc->mmu_box,
+ hevc->cur_pic->index,
+ hevc->used_4k_num);
+ hevc->cur_pic->scatter_alloc = 2;
+ }
}
hevc->pic_decoded_lcu_idx =
READ_VREG(HEVC_PARSER_LCU_START)
& 0xffffff;
- if (vdec->master == NULL && vdec->slave == NULL &&
+ if ((!vdec_dual(vdec)) &&
hevc->empty_flag == 0) {
hevc->over_decode =
(READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
@@ -14203,7 +13286,7 @@
if (is_log_enable(hevc))
add_log(hevc,
- "%s dec_result %d lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x",
+ "%s dec_result %d lcu %d used_mmu %ld shiftbyte 0x%x decbytes 0x%x",
__func__,
hevc->dec_result,
hevc->pic_decoded_lcu_idx,
@@ -14214,7 +13297,7 @@
);
hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s dec_result %d (%x %x %x) lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x\n",
+ "%s dec_result %d (%x %x %x) lcu %d used_mmu %ld shiftbyte 0x%x decbytes 0x%x\n",
__func__,
hevc->dec_result,
READ_VREG(HEVC_STREAM_LEVEL),
@@ -14316,6 +13399,7 @@
stream base: stream buf empty or timeout
frame base: vdec_prepare_input fail
*/
+
if (!vdec_has_more_input(vdec)) {
hevc->dec_result = DEC_RESULT_EOS;
vdec_schedule_work(&hevc->work);
@@ -14391,6 +13475,11 @@
}
hevc_print(hevc, 0, "%s: force exit end\n",
__func__);
+ } else if (hevc->dec_result == DEC_RESULT_DISCARD_DATA) {
+ mutex_lock(&hevc->chunks_mutex);
+ vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk);
+ hevc->chunk = NULL;
+ mutex_unlock(&hevc->chunks_mutex);
}
if (hevc->stat & STAT_VDEC_RUN) {
@@ -14402,10 +13491,8 @@
del_timer_sync(&hevc->timer);
hevc->stat &= ~STAT_TIMER_ARM;
}
- ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START);
- wait_hevc_search_done(hevc);
- ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END);
+ wait_hevc_search_done(hevc);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (hevc->switch_dvlayer_flag) {
if (vdec->slave)
@@ -14427,9 +13514,6 @@
//cancel_work_sync(&hevc->work);//reserved for future considraion
}
}
- if (hevc->dec_result == DEC_RESULT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_END);
- }
/* mark itself has all HW resource released and input released */
if (vdec->parallel_dec == 1)
@@ -14471,6 +13555,12 @@
vh265_work_implement(hevc, vdec, 1);
}
+#ifdef VDEC_FCC_SUPPORT
+static void vh265_wakeup_fcc_poll(struct vdec_s *vdec)
+{
+ amstream_wakeup_fcc_poll(vdec);
+}
+#endif
static int vh265_hw_ctx_restore(struct hevc_state_s *hevc)
{
@@ -14485,6 +13575,9 @@
int tvp = vdec_secure(hw_to_vdec(hevc)) ?
CODEC_MM_FLAGS_TVP : 0;
bool ret = 0;
+#ifdef VDEC_FCC_SUPPORT
+ int get_msg = 1;
+#endif
if (step == 0x12)
return 0;
else if (step == 0x11)
@@ -14506,17 +13599,7 @@
}
hevc->timeout_processing = 0;
if (!hevc->first_sc_checked && hevc->mmu_enable) {
- int size;
- void * mmu_box;
-
- if (hevc->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = hevc->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
+ int size = decoder_mmu_box_sc_check(hevc->mmu_box, tvp);
hevc->first_sc_checked =1;
hevc_print(hevc, 0,
"vh265 cached=%d need_size=%d speed= %d ms\n",
@@ -14572,7 +13655,7 @@
}
#ifdef CONSTRAIN_MAX_BUF_NUM
- if (hevc->pic_list_init_flag == 3 && !hevc->is_used_v4l) {
+ if (hevc->pic_list_init_flag == 3) {
if (run_ready_max_vf_only_num > 0 &&
get_vf_ref_only_buf_count(hevc) >=
run_ready_max_vf_only_num
@@ -14604,12 +13687,10 @@
if (ctx->param_sets_from_ucode) {
if (hevc->v4l_params_parsed) {
- if (ctx->cap_pool.dec < hevc->used_buf_num) {
- if (is_avaliable_buffer(hevc))
- ret = 1;
- else
- ret = 0;
- }
+ if (!ctx->v4l_codec_dpb_ready &&
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
} else {
if (ctx->v4l_resolution_change)
ret = 0;
@@ -14621,6 +13702,10 @@
}
}
+#ifdef VDEC_FCC_SUPPORT
+ get_msg = vdec_has_get_fcc_new_msg(vdec);
+ ret &= get_msg;
+#endif
if (ret)
not_run_ready[hevc->index] = 0;
else
@@ -14643,8 +13728,6 @@
hevc->vdec_cb_arg = arg;
hevc->vdec_cb = callback;
hevc->aux_data_dirty = 1;
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_START);
hevc_reset_core(vdec);
#ifdef AGAIN_HAS_THRESHOLD
@@ -14722,7 +13805,6 @@
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
if (vdec->mc_loaded) {
/*firmware have load before,
and not changes to another.
@@ -14732,7 +13814,7 @@
get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->swap_addr);
} else {
- if (hevc->mmu_enable) {
+ if (hevc->mmu_enable)
if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM)
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
"h265_mmu", hevc->fw->data);
@@ -14757,10 +13839,9 @@
VFORMAT_HEVC, vdec,
"h265_mmu", hevc->fw->data);
}
- } else
+ else
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
NULL, hevc->fw->data);
-
if (loadr < 0) {
amhevc_disable();
hevc_print(hevc, 0, "H265: the %s fw loading failed, err: %x\n",
@@ -14781,14 +13862,10 @@
vdec->mc_loaded = 1;
vdec->mc_type = VFORMAT_HEVC;
}
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
-
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
if (vh265_hw_ctx_restore(hevc) < 0) {
vdec_schedule_work(&hevc->work);
return;
}
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
vdec_enable_input(vdec);
WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
@@ -14817,7 +13894,6 @@
if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
dump_pic_list(hevc);
backup_decode_state(hevc);
-
start_process_time(hevc);
mod_timer(&hevc->timer, jiffies);
hevc->stat |= STAT_TIMER_ARM;
@@ -14826,8 +13902,6 @@
vdec->mvfrm->hw_decode_start = local_clock();
amhevc_start();
hevc->stat |= STAT_VDEC_RUN;
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_END);
}
static void aml_free_canvas(struct vdec_s *vdec)
@@ -14845,7 +13919,6 @@
vdec->free_canvas_ex(pic->uv_canvas_index, vdec->id);
}
}
- hevc->buffer_wrap[i] = i;
}
}
@@ -14953,15 +14026,7 @@
else
hevc->mmu_enable = 1;
}
-#ifdef H265_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- hevc->dw_mmu_enable =
- get_double_write_mode(hevc) & 0x20 ? 1 : 0;
- } else {
- hevc->dw_mmu_enable = 0;
- }
-#endif
- if (init_mmu_buffers(hevc, 0)) {
+ if (init_mmu_buffers(hevc)) {
hevc_print(hevc, 0,
"\n 265 mmu init failed!\n");
vfree(hevc);
@@ -15015,13 +14080,6 @@
hevc->vh265_amstream_dec_info.height = 0;
hevc->vh265_amstream_dec_info.rate = 30;
}
-
- hevc->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- hevc->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- hevc->endian = endian;
-
#ifndef MULTI_INSTANCE_SUPPORT
if (pdata->flag & DEC_FLAG_HEVC_WORKAROUND) {
workaround_enable |= 3;
@@ -15154,7 +14212,7 @@
input_empty[hevc->index]
);
- if (hevc->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -15183,17 +14241,16 @@
for (i = 0; i < BUF_POOL_SIZE; i++) {
hevc_print(hevc, 0,
- "Buf(%d) start_adr 0x%x header_addr 0x%x size 0x%x used %d\n",
+ "Buf(%d) start_adr 0x%lx size 0x%x used %d\n",
i,
hevc->m_BUF[i].start_adr,
- hevc->m_BUF[i].header_addr,
hevc->m_BUF[i].size,
hevc->m_BUF[i].used_flag);
}
for (i = 0; i < MAX_REF_PIC_NUM; i++) {
hevc_print(hevc, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
+ "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n",
i,
hevc->m_mv_BUF[i].start_adr,
hevc->m_mv_BUF[i].size,
@@ -15290,17 +14347,17 @@
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
struct hevc_state_s *hevc = NULL;
int ret;
- int i;
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
int config_val;
#endif
-
+ //pr_err("[%s pid=%d tgid=%d] \n",__func__, current->pid, current->tgid);
if (pdata == NULL) {
pr_info("\nammvdec_h265 memory resource undefined.\n");
return -EFAULT;
}
-
+ /* hevc = (struct hevc_state_s *)devm_kzalloc(&pdev->dev,
+ sizeof(struct hevc_state_s), GFP_KERNEL); */
hevc = vmalloc(sizeof(struct hevc_state_s));
if (hevc == NULL) {
pr_info("\nammvdec_h265 device data allocation failed\n");
@@ -15320,48 +14377,30 @@
pdata->irq_handler = vh265_irq_cb;
pdata->threaded_irq_handler = vh265_threaded_irq_cb;
pdata->dump_state = vh265_dump_state;
-
+#ifdef VDEC_FCC_SUPPORT
+ pdata->wakeup_fcc_poll = vh265_wakeup_fcc_poll;
+#endif
hevc->index = pdev->id;
hevc->m_ins_flag = 1;
- if (is_rdma_enable()) {
- hevc->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hevc->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- hevc->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- hevc->rdma_adr[i * 4 + 1] = i;
- hevc->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- hevc->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- hevc->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
- snprintf(hevc->trace.vdec_name, sizeof(hevc->trace.vdec_name),
+ snprintf(hevc->vdec_name, sizeof(hevc->vdec_name),
"h265-%d", hevc->index);
- snprintf(hevc->trace.pts_name, sizeof(hevc->trace.pts_name),
- "%s-pts", hevc->trace.vdec_name);
- snprintf(hevc->trace.vf_get_name, sizeof(hevc->trace.vf_get_name),
- "%s-vf_get", hevc->trace.vdec_name);
- snprintf(hevc->trace.vf_put_name, sizeof(hevc->trace.vf_put_name),
- "%s-vf_put", hevc->trace.vdec_name);
- snprintf(hevc->trace.set_canvas0_addr, sizeof(hevc->trace.set_canvas0_addr),
- "%s-set_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.get_canvas0_addr, sizeof(hevc->trace.get_canvas0_addr),
- "%s-get_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.put_canvas0_addr, sizeof(hevc->trace.put_canvas0_addr),
- "%s-put_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.new_q_name, sizeof(hevc->trace.new_q_name),
- "%s-newframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.disp_q_name, sizeof(hevc->trace.disp_q_name),
- "%s-dispframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.decode_time_name, sizeof(hevc->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hevc->trace.decode_run_time_name, sizeof(hevc->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hevc->trace.decode_header_memory_time_name, sizeof(hevc->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hevc->trace.decode_work_time_name, sizeof(hevc->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
+ snprintf(hevc->pts_name, sizeof(hevc->pts_name),
+ "%s-pts", hevc->vdec_name);
+ snprintf(hevc->vf_get_name, sizeof(hevc->vf_get_name),
+ "%s-vf_get", hevc->vdec_name);
+ snprintf(hevc->vf_put_name, sizeof(hevc->vf_put_name),
+ "%s-vf_put", hevc->vdec_name);
+ snprintf(hevc->set_canvas0_addr, sizeof(hevc->set_canvas0_addr),
+ "%s-set_canvas0_addr", hevc->vdec_name);
+ snprintf(hevc->get_canvas0_addr, sizeof(hevc->get_canvas0_addr),
+ "%s-get_canvas0_addr", hevc->vdec_name);
+ snprintf(hevc->put_canvas0_addr, sizeof(hevc->put_canvas0_addr),
+ "%s-put_canvas0_addr", hevc->vdec_name);
+ snprintf(hevc->new_q_name, sizeof(hevc->new_q_name),
+ "%s-newframe_q", hevc->vdec_name);
+ snprintf(hevc->disp_q_name, sizeof(hevc->disp_q_name),
+ "%s-dispframe_q", hevc->vdec_name);
if (pdata->use_vfm_path) {
snprintf(pdata->vf_provider_name,
@@ -15373,30 +14412,16 @@
else if (vdec_dual(pdata)) {
struct hevc_state_s *hevc_pair = NULL;
- if (!pdata->is_stream_mode_dv_multi) {
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
- VFM_DEC_DVEL_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
- VFM_DEC_DVBL_PROVIDER_NAME);
- } else {
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME2 :
- VFM_DEC_DVEL_PROVIDER_NAME2);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME2 :
- VFM_DEC_DVBL_PROVIDER_NAME2);
- }
-
+ if (dv_toggle_prov_name) /*debug purpose*/
+ snprintf(pdata->vf_provider_name,
+ VDEC_PROVIDER_NAME_SIZE,
+ (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
+ VFM_DEC_DVEL_PROVIDER_NAME);
+ else
+ snprintf(pdata->vf_provider_name,
+ VDEC_PROVIDER_NAME_SIZE,
+ (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
+ VFM_DEC_DVBL_PROVIDER_NAME);
hevc->dolby_enhance_flag = pdata->master ? 1 : 0;
if (pdata->master)
hevc_pair = (struct hevc_state_s *)
@@ -15413,13 +14438,16 @@
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vh265_vf_provider, pdata);
+
hevc->provider_name = pdata->vf_provider_name;
platform_set_drvdata(pdev, pdata);
hevc->platform_dev = pdev;
if (((get_dbg_flag(hevc) & IGNORE_PARAM_FROM_CONFIG) == 0) &&
- pdata->config_len) {
+ pdata->config && pdata->config_len) {
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
/*use ptr config for doubel_write_mode, etc*/
hevc_print(hevc, 0, "pdata->config=%s\n", pdata->config);
@@ -15468,18 +14496,18 @@
&config_val) == 0)
hevc->mem_map_mode = config_val;
+ if (get_config_int(pdata->config, "dv_duallayer",
+ &config_val) == 0)
+ hevc->dv_duallayer = config_val;
+ else
+ hevc->dv_duallayer = false;
+
if (get_config_int(pdata->config, "negative_dv",
&config_val) == 0) {
hevc->discard_dv_data = config_val;
hevc_print(hevc, 0, "discard dv data\n");
}
- if (get_config_int(pdata->config, "dv_duallayer",
- &config_val) == 0) {
- hevc->dv_duallayer = config_val;
- hevc_print(hevc, 0, "dv dual layer\n");
- }
-
if (get_config_int(pdata->config,
"parm_enable_fence",
&config_val) == 0)
@@ -15495,17 +14523,6 @@
&config_val) == 0)
hevc->low_latency_flag = config_val;
- if (get_config_int(pdata->config,
- "parm_v4l_metadata_config_flag",
- &config_val) == 0) {
- hevc->metadata_config_flag = config_val;
- hevc->discard_dv_data = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE;
- hevc->dv_duallayer = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_TWOLARYER;
- if (hevc->discard_dv_data)
- hevc_print(hevc, 0, "discard dv data\n");
- if (hevc->dv_duallayer)
- hevc_print(hevc, 0, "dv_duallayer\n");
- }
#endif
} else {
if (pdata->sys_info)
@@ -15517,10 +14534,8 @@
}
hevc->double_write_mode = double_write_mode;
}
-
-
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vh265_vf_provider, pdata);
+ /* get valid double write from configure or node */
+ //hevc->double_write_mode = get_double_write_mode(hevc);
if (force_config_fence) {
hevc->enable_fence = true;
@@ -15532,45 +14547,31 @@
hevc->enable_fence, hevc->fence_usage);
}
- if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2)
- hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2;
- else
- hevc->dynamic_buf_num_margin = dynamic_buf_num_margin;
-
- hevc->mem_map_mode = mem_map_mode;
-
- hevc->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- hevc->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- hevc->endian = endian;
+ if (hevc->enable_fence)
+ pdata->sync.usage = hevc->fence_usage;
if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) &&
(hevc->double_write_mode == 3))
hevc->double_write_mode = 0x1000;
- /* get valid double write from node */
- if (double_write_mode)
- hevc->double_write_mode = get_double_write_mode(hevc);
+ if (!hevc->is_used_v4l) {
+ /* get valid double write from configure or node */
+ //hevc->double_write_mode = get_double_write_mode(hevc);
+ if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2)
+ hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2;
+ else
+ hevc->dynamic_buf_num_margin = dynamic_buf_num_margin;
+ hevc->mem_map_mode = mem_map_mode;
+ }
- if (mmu_enable_force) {
- hevc->mmu_enable = 1;
- } else {
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) ||
- (hevc->double_write_mode & 0x10))
+ if (mmu_enable_force == 0) {
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL)
hevc->mmu_enable = 0;
else
hevc->mmu_enable = 1;
}
-#ifdef H265_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- hevc->dw_mmu_enable =
- get_double_write_mode(hevc) & 0x20 ? 1 : 0;
- } else {
- hevc->dw_mmu_enable = 0;
- }
-#endif
- if (init_mmu_buffers(hevc, 0) < 0) {
+
+ if (init_mmu_buffers(hevc) < 0) {
hevc_print(hevc, 0,
"\n 265 mmu init failed!\n");
mutex_unlock(&vh265_mutex);
@@ -15659,25 +14660,9 @@
vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
| CORE_MASK_COMBINE);
- mutex_init(&hevc->fence_mutex);
if (hevc->enable_fence) {
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- hevc_print(hevc, 0, "alloc fence timeline error\n");
- hevc_local_uninit(hevc);
- if (hevc->gvs)
- kfree(hevc->gvs);
- hevc->gvs = NULL;
- uninit_mmu_buffers(hevc);
- /* devm_kfree(&pdev->dev, (void *)hevc); */
- if (hevc)
- vfree((void *)hevc);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- pdata->sync->usage = hevc->fence_usage;
/* creat timeline. */
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
+ vdec_timeline_create(&pdata->sync, DRIVER_NAME);
}
return 0;
@@ -15687,6 +14672,7 @@
struct vdec_sync *sync)
{
ulong expires;
+ int i;
/* notify signal to wake up all fences. */
vdec_timeline_increase(sync, VF_POOL_SIZE);
@@ -15699,6 +14685,15 @@
}
}
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ struct vframe_s *vf = &hw->vfpool[i];
+
+ if (vf->fence) {
+ vdec_fence_put(vf->fence);
+ vf->fence = NULL;
+ }
+ }
+
/* decreases refcnt of timeline. */
vdec_timeline_put(sync);
}
@@ -15733,9 +14728,8 @@
vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED);
if (hevc->enable_fence)
- vdec_fence_release(hevc, vdec->sync);
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hevc->rdma_adr, hevc->rdma_phy_adr);
+ vdec_fence_release(hevc, &vdec->sync);
+
vfree((void *)hevc);
return 0;
@@ -15822,20 +14816,13 @@
{
struct BuffInfo_s *p_buf_info;
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvh265_workbuff_spec[2];
- else
- p_buf_info = &amvh265_workbuff_spec[1];
- } else
- p_buf_info = &amvh265_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k())
- p_buf_info = &amvh265_workbuff_spec[5];
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ p_buf_info = &amvh265_workbuff_spec[2];
else
- p_buf_info = &amvh265_workbuff_spec[3];
- }
+ p_buf_info = &amvh265_workbuff_spec[1];
+ } else
+ p_buf_info = &amvh265_workbuff_spec[0];
init_buff_spec(NULL, p_buf_info);
work_buf_size =
@@ -15875,26 +14862,19 @@
amvdec_h265_profile.profile = "4k";
} else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
amvdec_h265_profile.profile =
- "8k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, v4l-uvm";
+ "8k, 8bit, 10bit, dwrite, compressed, frame_dv, fence";
}else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) {
amvdec_h265_profile.profile =
- "4k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, v4l-uvm";
+ "4k, 8bit, 10bit, dwrite, compressed, frame_dv, fence";
} else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_MG9TV)
amvdec_h265_profile.profile = "4k";
- } else {
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) {
- amvdec_h265_profile.profile =
- "8bit, 10bit, dwrite, compressed, frame_dv, v4l";
- } else {
- amvdec_h265_profile.profile =
- "8bit, 10bit, dwrite, compressed, v4l";
- }
}
#endif
if (codec_mm_get_total_size() < 80 * SZ_1M) {
pr_info("amvdec_h265 default mmu enabled.\n");
mmu_enable = 1;
}
+
vcodec_profile_register(&amvdec_h265_profile);
amvdec_h265_profile_single = amvdec_h265_profile;
amvdec_h265_profile_single.name = "h265";
@@ -15904,7 +14884,6 @@
vcodec_profile_register(&amvdec_h265_profile_mult);
INIT_REG_NODE_CONFIGS("media.decoder", &decoder_265_node,
"h265", h265_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_HEVC, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg.c
index 917a2a1..6b87d4a 100644
--- a/drivers/frame_provider/decoder/mjpeg/vmjpeg.c
+++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg.c
@@ -28,6 +28,7 @@
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/registers/register.h>
@@ -35,6 +36,9 @@
#include "../utils/decoder_bmmu_box.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/tee.h>
+
+
#ifdef CONFIG_AM_VDEC_MJPEG_LOG
#define AMLOG
@@ -393,8 +397,10 @@
}
}
-static void vmjpeg_put_timer_func(struct timer_list *timer)
+static void vmjpeg_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
+
while (!kfifo_is_empty(&recycle_q) &&
(READ_VREG(MREG_TO_AMRISC) == 0)) {
struct vframe_s *vf;
@@ -483,61 +489,61 @@
if (ret < 0)
return ret;
#ifdef NV21
- config_cav_lut_ex(index2canvas0(i) & 0xff,
+ canvas_config(index2canvas0(i) & 0xff,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas0(i) >> 8) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas0(i) >> 8) & 0xff,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex(index2canvas1(i) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(index2canvas1(i) & 0xff,
buf_start +
decbuf_size / 2, canvas_width,
canvas_height, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas1(i) >> 8) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas1(i) >> 8) & 0xff,
buf_start +
decbuf_y_size + decbuf_uv_size / 2,
canvas_width, canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
+ CANVAS_BLKMODE_LINEAR);
#else
- config_cav_lut_ex(index2canvas0(i) & 0xff,
+ canvas_config(index2canvas0(i) & 0xff,
buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas0(i) >> 8) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas0(i) >> 8) & 0xff,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas0(i) >> 16) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas0(i) >> 16) & 0xff,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex(index2canvas1(i) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(index2canvas1(i) & 0xff,
buf_start +
decbuf_size / 2, canvas_width,
canvas_height, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas1(i) >> 8) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas1(i) >> 8) & 0xff,
buf_start +
decbuf_y_size + decbuf_uv_size / 2,
canvas_width / 2, canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
- config_cav_lut_ex((index2canvas1(i) >> 16) & 0xff,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config((index2canvas1(i) >> 16) & 0xff,
buf_start +
decbuf_y_size + decbuf_uv_size +
decbuf_uv_size / 2, canvas_width / 2,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, 0, VDEC_1);
+ CANVAS_BLKMODE_LINEAR);
#endif
}
@@ -734,7 +740,7 @@
if (IS_ERR_OR_NULL(buf))
return -ENOMEM;
- timer_setup(&recycle_timer, vmjpeg_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -799,7 +805,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong)&recycle_timer;
+ recycle_timer.function = vmjpeg_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -902,16 +911,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mjpeg_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mjpeg_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mjpeg_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mjpeg_suspend, mjpeg_resume)
+};
+#endif
static struct platform_driver amvdec_mjpeg_driver = {
.probe = amvdec_mjpeg_probe,
.remove = amvdec_mjpeg_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mjpeg_pm_ops,
+#endif
}
};
diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
index 22d7dbd..108f5da 100644
--- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
+++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c
@@ -29,8 +29,7 @@
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/media/registers/register.h>
@@ -48,7 +47,6 @@
#include "../utils/vdec_v4l2_buffer_ops.h"
#include "../utils/config_parser.h"
#include <media/v4l2-mem2mem.h>
-#include "../utils/vdec_feature.h"
#define MEM_NAME "codec_mmjpeg"
@@ -98,7 +96,6 @@
static int vmjpeg_vf_states(struct vframe_states *states, void *);
static int vmjpeg_event_cb(int type, void *data, void *private_data);
static void vmjpeg_work(struct work_struct *work);
-static int notify_v4l_eos(struct vdec_s *vdec);
static int pre_decode_buf_level = 0x800;
static int start_decode_buf_level = 0x2000;
static u32 without_display_mode;
@@ -127,19 +124,14 @@
if (((debug_enable & debug_flag) &&
((1 << index) & mmjpeg_debug_mask))
|| (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
+ unsigned char buf[512];
int len = 0;
va_list args;
-
- if (!buf)
- return 0;
-
va_start(args, fmt);
len = sprintf(buf, "%d: ", index);
vsnprintf(buf + len, 512-len, fmt, args);
pr_info("%s", buf);
va_end(args);
- kfree(buf);
}
return 0;
}
@@ -216,7 +208,7 @@
struct firmware_s *fw;
struct timer_list check_timer;
u32 decode_timeout_count;
- u32 start_process_time;
+ unsigned long int start_process_time;
u32 last_vld_level;
u8 eos;
u32 frame_num;
@@ -237,7 +229,6 @@
u32 res_ch_flag;
u32 canvas_mode;
u32 canvas_endian;
- ulong fb_token;
char vdec_name[32];
char pts_name[32];
char new_q_name[32];
@@ -335,8 +326,7 @@
hw->res_ch_flag = 1;
ctx->v4l_resolution_change = 1;
hw->eos = 1;
- if (hw->is_used_v4l)
- notify_v4l_eos(hw_to_vdec(hw));
+ notify_v4l_eos(hw_to_vdec(hw));
ret = 1;
}
@@ -348,8 +338,6 @@
static irqreturn_t vmjpeg_isr_thread_fn(struct vdec_s *vdec, int irq)
{
struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)(vdec->private);
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
u32 reg;
struct vframe_s *vf = NULL;
u32 index, offset = 0, pts;
@@ -412,7 +400,6 @@
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->buffer_spec[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
"[%d] %s(), v4l mem handle: 0x%lx\n",
((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
@@ -468,17 +455,9 @@
vf->pts, vf->pts_us64, vf->duration);
vdec->vdec_fps_detec(vdec->id);
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- }
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
} else
vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec);
@@ -671,12 +650,12 @@
hw->buffer_spec[i].v_canvas_index = canvas_v(canvas);
}
- config_cav_lut_ex(hw->buffer_spec[i].y_canvas_index,
+ canvas_config_ex(hw->buffer_spec[i].y_canvas_index,
hw->buffer_spec[i].y_addr,
canvas_width,
canvas_height,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, endian, VDEC_1);
+ CANVAS_BLKMODE_LINEAR, endian);
hw->buffer_spec[i].canvas_config[0].phy_addr =
hw->buffer_spec[i].y_addr;
hw->buffer_spec[i].canvas_config[0].width =
@@ -688,12 +667,12 @@
hw->buffer_spec[i].canvas_config[0].endian =
endian;
- config_cav_lut_ex(hw->buffer_spec[i].u_canvas_index,
+ canvas_config_ex(hw->buffer_spec[i].u_canvas_index,
hw->buffer_spec[i].u_addr,
canvas_width / 2,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, endian, VDEC_1);
+ CANVAS_BLKMODE_LINEAR, endian);
hw->buffer_spec[i].canvas_config[1].phy_addr =
hw->buffer_spec[i].u_addr;
hw->buffer_spec[i].canvas_config[1].width =
@@ -705,12 +684,12 @@
hw->buffer_spec[i].canvas_config[1].endian =
endian;
- config_cav_lut_ex(hw->buffer_spec[i].v_canvas_index,
+ canvas_config_ex(hw->buffer_spec[i].v_canvas_index,
hw->buffer_spec[i].v_addr,
canvas_width / 2,
canvas_height / 2,
CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR, endian, VDEC_1);
+ CANVAS_BLKMODE_LINEAR, endian);
hw->buffer_spec[i].canvas_config[2].phy_addr =
hw->buffer_spec[i].v_addr;
hw->buffer_spec[i].canvas_config[2].width =
@@ -833,7 +812,7 @@
hw->not_run_ready,
hw->input_empty
);
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -936,10 +915,9 @@
vdec_schedule_work(&hw->work);
}
-static void check_timer_func(struct timer_list *timer)
+static void check_timer_func(unsigned long arg)
{
- struct vdec_mjpeg_hw_s *hw = container_of(timer,
- struct vdec_mjpeg_hw_s, check_timer);
+ struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
int timeout_val = decode_timeout_val;
@@ -1008,16 +986,10 @@
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (hw->buffer_spec[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->buffer_spec[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
+ if (hw->buffer_spec[i].v4l_ref_buf_addr)
return 0;
- }
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
if (ret < 0) {
mmjpeg_debug_print(DECODE_ID(hw), 0,
"[%d] get fb fail.\n",
@@ -1026,8 +998,6 @@
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (!hw->frame_width || !hw->frame_height) {
struct vdec_pic_info pic;
vdec_v4l_get_pic_info(ctx, &pic);
@@ -1053,7 +1023,7 @@
decbuf_start = fb->m.mem[0].addr;
decbuf_y_size = fb->m.mem[0].size;
decbuf_u_start = fb->m.mem[1].addr;
- decbuf_u_size = fb->m.mem[1].size >> 1;
+ decbuf_u_size = fb->m.mem[1].size;
decbuf_v_start = decbuf_u_start + decbuf_u_size;
decbuf_v_size = decbuf_u_size;
canvas_width = ALIGN(hw->frame_width, 64);
@@ -1075,7 +1045,7 @@
}
mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] v4l ref buf addr: 0x%x\n", ctx->id, fb);
+ "[%d] v4l ref buf addr: 0x%px\n", ctx->id, fb);
if (vdec->parallel_dec == 1) {
if (hw->buffer_spec[i].y_canvas_index == -1)
@@ -1105,8 +1075,8 @@
hw->buffer_spec[i].canvas_config[0].endian =
hw->canvas_endian;
- config_cav_lut(hw->buffer_spec[i].y_canvas_index,
- &hw->buffer_spec[i].canvas_config[0], VDEC_1);
+ canvas_config_config(hw->buffer_spec[i].y_canvas_index,
+ &hw->buffer_spec[i].canvas_config[0]);
hw->buffer_spec[i].canvas_config[1].phy_addr =
decbuf_u_start;
@@ -1119,8 +1089,8 @@
hw->buffer_spec[i].canvas_config[1].endian =
hw->canvas_endian;
- config_cav_lut(hw->buffer_spec[i].u_canvas_index,
- &hw->buffer_spec[i].canvas_config[1], VDEC_1);
+ canvas_config_config(hw->buffer_spec[i].u_canvas_index,
+ &hw->buffer_spec[i].canvas_config[1]);
hw->buffer_spec[i].canvas_config[2].phy_addr =
decbuf_v_start;
@@ -1133,8 +1103,8 @@
hw->buffer_spec[i].canvas_config[2].endian =
hw->canvas_endian;
- config_cav_lut(hw->buffer_spec[i].v_canvas_index,
- &hw->buffer_spec[i].canvas_config[2], VDEC_1);
+ canvas_config_config(hw->buffer_spec[i].v_canvas_index,
+ &hw->buffer_spec[i].canvas_config[2]);
/* mjpeg decoder canvas need to be revert to match display. */
hw->buffer_spec[i].canvas_config[0].endian = hw->canvas_endian ? 0 : 7;
@@ -1187,9 +1157,6 @@
/*run to parser csd data*/
i = 0;
} else {
- if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token))
- return -1;
-
if (vmjpeg_v4l_alloc_buff_config_canvas(hw, i))
return -1;
}
@@ -1216,12 +1183,12 @@
if (!hw->is_used_v4l) {
for (i = 0; i < hw->buf_num; i++) {
buff_spec = &hw->buffer_spec[i];
- config_cav_lut(buff_spec->y_canvas_index,
- &buff_spec->canvas_config[0], VDEC_1);
- config_cav_lut(buff_spec->u_canvas_index,
- &buff_spec->canvas_config[1], VDEC_1);
- config_cav_lut(buff_spec->v_canvas_index,
- &buff_spec->canvas_config[2], VDEC_1);
+ canvas_config_config(buff_spec->y_canvas_index,
+ &buff_spec->canvas_config[0]);
+ canvas_config_config(buff_spec->u_canvas_index,
+ &buff_spec->canvas_config[1]);
+ canvas_config_config(buff_spec->v_canvas_index,
+ &buff_spec->canvas_config[2]);
}
}
}
@@ -1317,7 +1284,10 @@
CODEC_MM_FLAGS_CMA_CLEAR |
CODEC_MM_FLAGS_FOR_VDECODER);
- timer_setup(&hw->check_timer, check_timer_func, 0);
+ init_timer(&hw->check_timer);
+
+ hw->check_timer.data = (unsigned long)hw;
+ hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
/*add_timer(&hw->check_timer);*/
hw->stat |= STAT_TIMER_ARM;
@@ -1520,12 +1490,9 @@
if (hw->is_used_v4l) {
index = find_free_buffer(hw);
- if (index == -1) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
- pr_err("[%d] get fb fail.\n", ctx->id);
- return -1;
- }
+ if ((index == -1) && vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) {
+ pr_err("[%d] get fb fail.\n", ctx->id);
+ return -1;
}
}
@@ -1534,18 +1501,13 @@
vf->v4l_mem_handle = (index == -1) ? (ulong)fb :
hw->buffer_spec[index].v4l_ref_buf_addr;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
-
- pr_info("[%d] mjpeg EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
+ pr_info("[%d] mpeg12 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
return 0;
@@ -1756,9 +1718,8 @@
hw->buf_num = vmjpeg_get_buf_num(hw);
- if (!hw->is_used_v4l)
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vf_provider_ops, pdata);
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vf_provider_ops, pdata);
platform_set_drvdata(pdev, pdata);
@@ -1813,7 +1774,6 @@
vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id);
}
}
-
vfree(hw);
pr_info("%s\n", __func__);
@@ -1821,22 +1781,38 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mmjpeg_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mmjpeg_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mmjpeg_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mmjpeg_suspend, mmjpeg_resume)
+};
+#endif
static struct platform_driver ammvdec_mjpeg_driver = {
.probe = ammvdec_mjpeg_probe,
.remove = ammvdec_mjpeg_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mmjpeg_pm_ops,
+#endif
}
};
static struct codec_profile_t ammvdec_mjpeg_profile = {
.name = "mmjpeg",
- .profile = "v4l"
+ .profile = ""
};
static int __init ammvdec_mjpeg_driver_init_module(void)
@@ -1846,7 +1822,6 @@
return -ENODEV;
}
vcodec_profile_register(&ammvdec_mjpeg_profile);
- vcodec_feature_register(VFORMAT_MJPEG, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c
index a813ac7..29757a0 100644
--- a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c
+++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c
@@ -29,7 +29,7 @@
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
@@ -41,8 +41,7 @@
#include "../utils/decoder_bmmu_box.h"
#include <linux/uaccess.h>
#include <linux/amlogic/media/codec_mm/configs.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
@@ -1311,9 +1310,11 @@
}
-static void vmpeg_put_timer_func(struct timer_list *timer)
+static void vmpeg_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
int fatal_reset = 0;
+
enum receviver_start_e state = RECEIVER_INACTIVE;
if (vf_get_receiver(PROVIDER_NAME)) {
@@ -1764,30 +1765,30 @@
} else {
#ifdef NV21
- config_cav_lut_ex(2 * i + 0,
+ canvas_config(2 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(2 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(2 * i + 1,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_BLKMODE_32X32);
#else
- config_cav_lut_ex(3 * i + 0,
+ canvas_config(3 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(3 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 1,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(3 * i + 2,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 2,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
#endif
}
}
@@ -1948,7 +1949,7 @@
if (IS_ERR_OR_NULL(buf))
return -ENOMEM;
- timer_setup(&recycle_timer, vmpeg_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -2013,7 +2014,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong)&recycle_timer;
+ recycle_timer.function = vmpeg_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -2155,16 +2159,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mpeg12_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mpeg12_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mpeg12_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mpeg12_suspend, mpeg12_resume)
+};
+#endif
static struct platform_driver amvdec_mpeg12_driver = {
.probe = amvdec_mpeg12_probe,
.remove = amvdec_mpeg12_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mpeg12_pm_ops,
+#endif
}
};
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
index f77bb7f..76a021e 100644
--- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
+++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c
@@ -15,7 +15,6 @@
*
*/
-#define DEBUG
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -27,19 +26,19 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/sched/clock.h>
+
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/media/registers/register.h>
#include "../../../stream_input/amports/amports_priv.h"
+
#include "../utils/vdec_input.h"
#include "../utils/vdec.h"
#include "../utils/amvdec.h"
@@ -52,7 +51,8 @@
#include "../utils/vdec_v4l2_buffer_ops.h"
#include "../utils/config_parser.h"
#include <media/v4l2-mem2mem.h>
-#include "../utils/vdec_feature.h"
+
+
#define MEM_NAME "codec_mmpeg12"
#define CHECK_INTERVAL (HZ/100)
@@ -88,6 +88,7 @@
#define PICINFO_RPT_FIRST 0x4000
#define PICINFO_TOP_FIRST 0x2000
#define PICINFO_FRAME 0x1000
+
#define TOP_FIELD 0x1000
#define BOTTOM_FIELD 0x2000
#define FRAME_PICTURE 0x3000
@@ -111,8 +112,6 @@
#define CTX_DECBUF_OFFSET (CTX_CO_MV_OFFSET + 0x11000)
#define DEFAULT_MEM_SIZE (32*SZ_1M)
-#define INVALID_IDX (-1) /* Invalid buffer index.*/
-
static u32 buf_size = 32 * 1024 * 1024;
static int pre_decode_buf_level = 0x800;
static int start_decode_buf_level = 0x4000;
@@ -180,6 +179,7 @@
#define DEC_RESULT_EOS 5
#define DEC_RESULT_GET_DATA 6
#define DEC_RESULT_GET_DATA_RETRY 7
+#define DEC_RESULT_DISCARD_DATA 8
#define DEC_DECODE_TIMEOUT 0x21
#define DECODE_ID(hw) (hw_to_vdec(hw)->id)
@@ -217,7 +217,6 @@
ulong v4l_ref_buf_addr;
u32 hw_decode_time;
u32 frame_size; // For frame base mode
- u64 timestamp;
};
struct vdec_mpeg12_hw_s {
@@ -271,7 +270,6 @@
s32 refs[2];
int dec_result;
u32 timeout_processing;
- wait_queue_head_t wait_q;
struct work_struct work;
struct work_struct timeout_work;
struct work_struct notify_work;
@@ -303,7 +301,6 @@
u32 pre_parser_wr_ptr;
u8 next_again_flag;
#endif
-
struct work_struct userdata_push_work;
struct mutex userdata_mutex;
struct mmpeg2_userdata_info_t userdata_info;
@@ -342,18 +339,17 @@
u32 level_idc;
int dec_again_cnt;
int vdec_pg_enable_flag;
- ulong fb_token;
char vdec_name[32];
char pts_name[32];
char new_q_name[32];
char disp_q_name[32];
- bool run_flag;
+ u32 last_frame_offset;
};
static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw);
static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw);
static void reset_process_time(struct vdec_mpeg12_hw_s *hw);
-static int vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw);
+static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw);
static void flush_output(struct vdec_mpeg12_hw_s *hw);
static struct vframe_s *vmpeg_vf_peek(void *);
static struct vframe_s *vmpeg_vf_get(void *);
@@ -363,12 +359,14 @@
static int notify_v4l_eos(struct vdec_s *vdec);
static void start_process_time_set(struct vdec_mpeg12_hw_s *hw);
static int check_dirty_data(struct vdec_s *vdec);
+
static int debug_enable;
/*static struct work_struct userdata_push_work;*/
#undef pr_info
#define pr_info printk
unsigned int mpeg12_debug_mask = 0xff;
/*static int counter_max = 5;*/
+
static u32 run_ready_min_buf_num = 2;
static int dirty_again_threshold = 100;
static int error_proc_policy = 0x1;
@@ -376,7 +374,7 @@
#define PRINT_FLAG_ERROR 0x0
#define PRINT_FLAG_RUN_FLOW 0X0001
#define PRINT_FLAG_TIMEINFO 0x0002
-#define PRINT_FLAG_UCODE_DETAIL 0x0004
+#define PRINT_FLAG_UCODE_DETAIL 0x0004
#define PRINT_FLAG_VLD_DETAIL 0x0008
#define PRINT_FLAG_DEC_DETAIL 0x0010
#define PRINT_FLAG_BUFFER_DETAIL 0x0020
@@ -390,28 +388,25 @@
#define PRINT_FLAG_USERDATA_DETAIL 0x2000
#define PRINT_FLAG_TIMEOUT_STATUS 0x4000
#define PRINT_FLAG_V4L_DETAIL 0x8000
+#define PRINT_FLAG_FCC_STATUS 0x10000
#define IGNORE_PARAM_FROM_CONFIG 0x8000000
+
int debug_print(int index, int debug_flag, const char *fmt, ...)
{
if (((debug_enable & debug_flag) &&
((1 << index) & mpeg12_debug_mask))
|| (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
+ unsigned char buf[512];
int len = 0;
va_list args;
-
- if (!buf)
- return 0;
-
va_start(args, fmt);
len = sprintf(buf, "%d: ", index);
vsnprintf(buf + len, 512-len, fmt, args);
pr_info("%s", buf);
va_end(args);
- kfree(buf);
}
return 0;
}
@@ -449,16 +444,10 @@
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (hw->pics[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->pics[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
+ if (hw->pics[i].v4l_ref_buf_addr)
return 0;
- }
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
if (ret < 0) {
debug_print(DECODE_ID(hw), 0,
"[%d] get fb fail %d/%d.\n",
@@ -466,8 +455,6 @@
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (!hw->frame_width || !hw->frame_height) {
struct vdec_pic_info pic;
vdec_v4l_get_pic_info(ctx, &pic);
@@ -498,7 +485,7 @@
fb->m.mem[1].bytes_used = decbuf_uv_size;
}
- debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n",
+ debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%px\n",
ctx->id, __func__, fb);
if (vdec->parallel_dec == 1) {
@@ -526,11 +513,7 @@
hw->canvas_config[i][0].block_mode = hw->canvas_mode;
hw->canvas_config[i][0].endian =
(hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- config_cav_lut(canvas_y(canvas), &hw->canvas_config[i][0], VDEC_1);
-
- /* mpeg2 decoder canvas need to be revert to match display canvas */
- hw->canvas_config[i][0].endian =
- (hw->canvas_mode != CANVAS_BLKMODE_LINEAR) ? 7 : 0;
+ canvas_config_config(canvas_y(canvas), &hw->canvas_config[i][0]);
hw->canvas_config[i][1].phy_addr = decbuf_uv_start;
hw->canvas_config[i][1].width = canvas_width;
@@ -538,14 +521,10 @@
hw->canvas_config[i][1].block_mode = hw->canvas_mode;
hw->canvas_config[i][1].endian =
(hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- config_cav_lut(canvas_u(canvas), &hw->canvas_config[i][1], VDEC_1);
-
- /* mpeg2 decoder canvas need to be revert to match display canvas */
- hw->canvas_config[i][1].endian =
- (hw->canvas_mode != CANVAS_BLKMODE_LINEAR) ? 7 : 0;
+ canvas_config_config(canvas_u(canvas), &hw->canvas_config[i][1]);
debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "[%d] %s(), canvas: 0x%x mode: %d y: %x uv: %x w: %d h: %d\n",
+ "[%d] %s(), canvas: 0x%x mode: %d y: %lx uv: %lx w: %d h: %d\n",
ctx->id, __func__, canvas, hw->canvas_mode,
decbuf_start, decbuf_uv_start,
canvas_width, canvas_height);
@@ -553,7 +532,6 @@
return 0;
}
-
static unsigned int vmpeg12_get_buf_num(struct vdec_mpeg12_hw_s *hw)
{
unsigned int buf_num = DECODE_BUFFER_NUM_DEF;
@@ -598,9 +576,6 @@
/*run to parser csd data*/
i = 0;
} else {
- if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token))
- return -1;
-
if (vmpeg12_v4l_alloc_buff_config_canvas(hw, i))
return -1;
}
@@ -1481,11 +1456,6 @@
offset = READ_VREG(AV_SCRATCH_I);
- codec_mm_dma_flush(
- hw->ccbuf_phyAddress_virt,
- CCBUF_SIZE,
- DMA_FROM_DEVICE);
-
mutex_lock(&hw->userdata_mutex);
if (hw->ccbuf_phyAddress_virt) {
pdata = (u8 *)hw->ccbuf_phyAddress_virt + hw->ucode_cc_last_wp;
@@ -1568,7 +1538,6 @@
if (pdata >= hw->userdata_info.data_buf_end)
pdata = hw->userdata_info.data_buf;
}
-
pcur_ud_rec = hw->ud_record + hw->cur_ud_idx;
pcur_ud_rec->meta_info = meta_info;
@@ -1595,6 +1564,7 @@
hw->cur_ud_idx++;
WRITE_VREG(AV_SCRATCH_J, 0);
+
}
@@ -1641,10 +1611,12 @@
u32 info = pic->buffer_info;
struct vdec_s *vdec = hw_to_vdec(hw);
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
ulong nv_order = VIDTYPE_VIU_NV21;
bool pb_skip = false;
+#ifdef NV21
+ type = nv_order;
+#endif
/* swap uv */
if (hw->is_used_v4l) {
if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
@@ -1652,9 +1624,6 @@
nv_order = VIDTYPE_VIU_NV12;
}
-#ifdef NV21
- type = nv_order;
-#endif
if (hw->i_only) {
pb_skip = 1;
}
@@ -1676,10 +1645,6 @@
field_num = (info & PICINFO_RPT_FIRST) ? 3 : 2;
}
- if ((hw->is_used_v4l) &&
- (vdec->prog_only))
- field_num = 1;
-
for (i = 0; i < field_num; i++) {
if (kfifo_get(&hw->newframe_q, &vf) == 0) {
debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
@@ -1692,7 +1657,6 @@
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->pics[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
"[%d] %s(), v4l mem handle: 0x%lx\n",
((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
@@ -1737,11 +1701,9 @@
if (i > 0) {
vf->pts = 0;
vf->pts_us64 = 0;
- vf->timestamp = 0;
} else {
vf->pts = (pic->pts_valid) ? pic->pts : 0;
vf->pts_us64 = (pic->pts_valid) ? pic->pts64 : 0;
- vf->timestamp = pic->timestamp;
}
vf->type_original = vf->type;
@@ -1818,17 +1780,9 @@
__func__);
}
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- }
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
} else
vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
@@ -1909,18 +1863,20 @@
return 0;
}
-static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps)
+static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height,
+ bool frame_prog, struct aml_vdec_ps_infos *ps)
{
ps->visible_width = width;
ps->visible_height = height;
ps->coded_width = ALIGN(width, 64);
ps->coded_height = ALIGN(height, 32);
ps->dpb_size = hw->buf_num;
+ ps->field = frame_prog ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
return 0;
}
-static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height)
+static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height, bool frame_prog)
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
@@ -1939,7 +1895,7 @@
hw->frame_width, hw->frame_height,
width,
height);
- vmpeg2_get_ps_info(hw, width, height, &ps);
+ vmpeg2_get_ps_info(hw, width, height, frame_prog, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
vdec_v4l_res_ch_event(ctx);
hw->v4l_params_parsed = false;
@@ -1947,8 +1903,7 @@
ctx->v4l_resolution_change = 1;
hw->eos = 1;
flush_output(hw);
- if (hw->is_used_v4l)
- notify_v4l_eos(hw_to_vdec(hw));
+ notify_v4l_eos(hw_to_vdec(hw));
ret = 1;
}
@@ -1957,6 +1912,65 @@
return ret;
}
+#ifdef VDEC_FCC_SUPPORT
+static void fcc_discard_mode_process(struct vdec_s *vdec)
+{
+ struct vdec_mpeg12_hw_s *hw =
+ (struct vdec_mpeg12_hw_s *)(vdec->private);
+ int wrap_count;
+ u32 rp;
+ u32 first_ptr;
+
+ if (vdec->fcc_status == AGAIN_STATUS) {
+ wrap_count = READ_VREG(VLD_MEM_VIFIFO_WRAP_COUNT);
+ rp = READ_VREG(VLD_MEM_VIFIFO_RP);
+ first_ptr = vdec->vbuf.ext_buf_addr;
+
+ vdec->stream_offset = rp + vdec->input.size * wrap_count - first_ptr;
+ debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Notify stream_offset: %d\n",
+ vdec->id, vdec->stream_offset);
+
+ debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: rp : 0x%x size: 0x%x wrap_count:%d first_ptr: 0x%x\n",
+ vdec->id, rp, vdec->input.size, wrap_count, first_ptr);
+ vdec_wakeup_fcc_poll(vdec);
+ vdec->fcc_status = WAIT_MSG_STATUS;
+ hw->dec_result = DEC_RESULT_AGAIN;
+ vdec_schedule_work(&hw->work);
+ } else if (vdec->fcc_status == DISCARD_STATUS) {
+ debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Discard current gop and to find next gop!\n",
+ vdec->id);
+ vdec->fcc_status = AGAIN_STATUS;
+ hw->dec_result = DEC_RESULT_DISCARD_DATA;
+ vdec_schedule_work(&hw->work);
+ }
+}
+
+static int vmpeg2_fcc_process(struct vdec_s *vdec)
+{
+ struct vdec_mpeg12_hw_s *hw =
+ (struct vdec_mpeg12_hw_s *)(vdec->private);
+
+ if (input_stream_based(vdec)) {
+ switch (vdec->fcc_mode) {
+ case FCC_DISCARD_MODE:
+ fcc_discard_mode_process(vdec);
+ return 1;
+ case FCC_DEC_MODE:
+ debug_print(DECODE_ID(hw), PRINT_FLAG_FCC_STATUS,
+ "[%d][FCC]: Current is Dec mode.\n", vdec->id);
+ break;
+ case FCC_BUTT:
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
{
@@ -1988,16 +2002,26 @@
"[vdec_kpi][%s] First I frame coming.\n",
__func__);
}
+
+#ifdef VDEC_FCC_SUPPORT
+ if (vmpeg2_fcc_process(vdec) > 0) {
+ WRITE_VREG(AV_SCRATCH_G, 0);
+ return IRQ_HANDLED;
+ }
+#endif
if (hw->is_used_v4l) {
int frame_width = READ_VREG(MREG_PIC_WIDTH);
int frame_height = READ_VREG(MREG_PIC_HEIGHT);
- if (!v4l_res_change(hw, frame_width, frame_height)) {
+ int info = READ_VREG(MREG_SEQ_INFO);
+ bool frame_prog = info & 0x10000;
+
+ if (!v4l_res_change(hw, frame_width, frame_height, frame_prog)) {
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
struct aml_vdec_ps_infos ps;
- vmpeg2_get_ps_info(hw, frame_width, frame_height, &ps);
+ vmpeg2_get_ps_info(hw, frame_width, frame_height, frame_prog, &ps);
hw->v4l_params_parsed = true;
vdec_v4l_set_ps_infos(ctx, &ps);
userdata_pushed_drop(hw);
@@ -2019,7 +2043,7 @@
}
reg = READ_VREG(AV_SCRATCH_J);
- if (reg & (1<<16)) {
+ if (reg & (1 << 16)) {
vdec_schedule_work(&hw->userdata_push_work);
return IRQ_HANDLED;
}
@@ -2042,7 +2066,6 @@
READ_VREG(VLD_MEM_VIFIFO_LEVEL),
READ_VREG(VLD_MEM_VIFIFO_CONTROL),
READ_VREG(VIFF_BIT_CNT));
-
if (vdec_frame_based(vdec)) {
userdata_pushed_drop(hw);
hw->dec_result = DEC_RESULT_DONE;
@@ -2119,7 +2142,6 @@
new_pic->pts_valid = hw->chunk->pts_valid;
new_pic->pts = hw->chunk->pts;
new_pic->pts64 = hw->chunk->pts64;
- new_pic->timestamp = hw->chunk->timestamp;
if (hw->last_chunk_pts == hw->chunk->pts) {
new_pic->pts_valid = 0;
debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
@@ -2139,9 +2161,12 @@
} else {
if (hw->chunk) {
hw->last_chunk_pts = hw->chunk->pts;
- new_pic->timestamp = hw->chunk->timestamp;
+ new_pic->pts_valid = hw->chunk->pts_valid;
+ new_pic->pts = hw->chunk->pts;
+ new_pic->pts64 = hw->chunk->pts64;
+ } else {
+ new_pic->pts_valid = false;
}
- new_pic->pts_valid = false;
}
debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
@@ -2199,10 +2224,9 @@
}
debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "mmpeg12: disp_pic=%d(%c), ind=%d, offst=%x, pts=(%d,%lld,%llx)(%d)\n",
+ "mmpeg12: disp_pic=%d(%c), ind=%d, offst=%x, pts=(%d,%lld)(%d)\n",
hw->disp_num, GET_SLICE_TYPE(info), index, disp_pic->offset,
- disp_pic->pts, disp_pic->pts64,
- disp_pic->timestamp, disp_pic->pts_valid);
+ disp_pic->pts, disp_pic->pts64, disp_pic->pts_valid);
prepare_display_buf(hw, disp_pic);
vdec_schedule_work(&hw->work);
@@ -2214,30 +2238,32 @@
{
u32 info, offset;
struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)(vdec->private);
+ (struct vdec_mpeg12_hw_s *)(vdec->private);
if (hw->eos)
return IRQ_HANDLED;
info = READ_VREG(MREG_PIC_INFO);
offset = READ_VREG(MREG_FRAME_OFFSET);
-
- vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset);
- if (info &PICINFO_ERROR) {
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_concealed_frames++;
+ if (offset != hw->last_frame_offset) {
+ vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset);
+ if (info & PICINFO_ERROR) {
+ if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+ hw->gvs.i_concealed_frames++;
+ } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+ hw->gvs.p_concealed_frames++;
+ } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+ hw->gvs.b_concealed_frames++;
+ }
}
- }
- if (offset) {
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_decoded_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_decoded_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_decoded_frames++;
+ if (offset) {
+ if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
+ hw->gvs.i_decoded_frames++;
+ } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
+ hw->gvs.p_decoded_frames++;
+ } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
+ hw->gvs.b_decoded_frames++;
+ }
}
+ hw->last_frame_offset = offset;
}
WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
@@ -2251,7 +2277,7 @@
struct vdec_mpeg12_hw_s, notify_work);
struct vdec_s *vdec = hw_to_vdec(hw);
- if (!hw->is_used_v4l && vdec->fr_hint_state == VDEC_NEED_HINT) {
+ if (vdec->fr_hint_state == VDEC_NEED_HINT) {
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_FR_HINT,
(void *)((unsigned long)hw->frame_dur));
@@ -2303,7 +2329,7 @@
struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
struct vframe_s *vf = NULL;
struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
+ int index = -1;
if (hw->eos) {
if (kfifo_get(&hw->newframe_q, &vf) == 0 || vf == NULL) {
@@ -2314,31 +2340,24 @@
}
if (hw->is_used_v4l) {
index = find_free_buffer(hw);
- if (index == INVALID_IDX) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
- pr_err("[%d] get fb fail.\n", ctx->id);
- return -1;
- }
+ if ((index == -1) &&
+ vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) {
+ pr_err("[%d] get fb fail.\n", ctx->id);
+ return -1;
}
}
vf->type |= VIDTYPE_V4L_EOS;
vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
+ vf->v4l_mem_handle = (index == -1) ? (ulong)fb :
hw->pics[index].v4l_ref_buf_addr;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(hw->pts_name, vf->pts);
-
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
pr_info("[%d] mpeg12 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
@@ -2455,6 +2474,10 @@
debug_print(DECODE_ID(hw), 0,
"%s: end of stream, num %d(%d)\n",
__func__, hw->disp_num, hw->dec_num);
+ } else if (hw->dec_result == DEC_RESULT_DISCARD_DATA) {
+ hw->dec_again_cnt = 0;
+ vdec_vframe_dirty(vdec, hw->chunk);
+ hw->chunk = NULL;
}
if (hw->stat & STAT_VDEC_RUN) {
amvdec_stop();
@@ -2483,7 +2506,6 @@
else
vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- wake_up_interruptible(&hw->wait_q);
if (hw->is_used_v4l) {
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
@@ -2703,7 +2725,7 @@
/****************************************/
-static int vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw)
+static void vmpeg12_canvas_init(struct vdec_mpeg12_hw_s *hw)
{
int i, ret;
u32 canvas_width, canvas_height;
@@ -2740,9 +2762,9 @@
ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
decbuf_size, DRIVER_NAME, &decbuf_start);
if (ret < 0) {
- pr_err("bmmu alloc failed! size 0x%d idx %d\n",
+ pr_err("mmu alloc failed! size 0x%d idx %d\n",
decbuf_size, i);
- return ret;
+ return;
}
}
@@ -2753,7 +2775,7 @@
GFP_KERNEL);
if (hw->ccbuf_phyAddress_virt == NULL) {
pr_err("%s: failed to alloc cc buffer\n", __func__);
- return -ENOMEM;
+ return;
}
hw->buf_start = decbuf_start;
WRITE_VREG(MREG_CO_MV_START, hw->buf_start);
@@ -2791,8 +2813,8 @@
hw->canvas_config[i][0].endian =
(hw->canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
- config_cav_lut(canvas_y(canvas),
- &hw->canvas_config[i][0], VDEC_1);
+ canvas_config_config(canvas_y(canvas),
+ &hw->canvas_config[i][0]);
hw->canvas_config[i][1].phy_addr =
decbuf_start + decbuf_y_size;
@@ -2802,11 +2824,11 @@
hw->canvas_config[i][1].endian =
(hw->canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
- config_cav_lut(canvas_u(canvas),
- &hw->canvas_config[i][1], VDEC_1);
+ canvas_config_config(canvas_u(canvas),
+ &hw->canvas_config[i][1]);
}
}
- return 0;
+ return;
}
static void vmpeg2_dump_state(struct vdec_s *vdec)
@@ -2817,12 +2839,11 @@
debug_print(DECODE_ID(hw), 0,
"====== %s\n", __func__);
debug_print(DECODE_ID(hw), 0,
- "width/height (%d/%d),i_first %d, buf_num %d, run_flag %d\n",
+ "width/height (%d/%d),i_first %d, buf_num %d\n",
hw->frame_width,
hw->frame_height,
hw->first_i_frame_ready,
- hw->buf_num,
- hw->run_flag
+ hw->buf_num
);
debug_print(DECODE_ID(hw), 0,
"is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d,input_empty %d\n",
@@ -2843,7 +2864,7 @@
hw->vfbuf_use[i], hw->ref_use[i]);
}
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -2941,6 +2962,7 @@
hw->decode_timeout_count = 10;
hw->start_process_time = jiffies;
}
+
static void timeout_process(struct vdec_mpeg12_hw_s *hw)
{
struct vdec_s *vdec = hw_to_vdec(hw);
@@ -2972,10 +2994,9 @@
vdec_schedule_work(&hw->timeout_work);
}
-static void check_timer_func(struct timer_list *timer)
+static void check_timer_func(unsigned long arg)
{
- struct vdec_mpeg12_hw_s *hw = container_of(timer,
- struct vdec_mpeg12_hw_s, check_timer);
+ struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
unsigned int timeout_val = decode_timeout_val;
@@ -3015,26 +3036,24 @@
static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw)
{
- u32 index = -1, i;
+ int index = -1;
+ u32 i;
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
index = find_free_buffer(hw);
if (index < 0 || index >= hw->buf_num)
return -1;
- if (!hw->init_flag) {
- if (vmpeg12_canvas_init(hw) < 0) {
- debug_print(DECODE_ID(hw), 0, "vmpeg12_canvas_init failed\n");
- return -1;
- }
- } else {
+ if (!hw->init_flag)
+ vmpeg12_canvas_init(hw);
+ else {
WRITE_VREG(MREG_CO_MV_START, hw->buf_start);
WRITE_VREG(MREG_CC_ADDR, hw->ccbuf_phyAddress);
if (!hw->is_used_v4l) {
for (i = 0; i < hw->buf_num; i++) {
- config_cav_lut(canvas_y(hw->canvas_spec[i]),
- &hw->canvas_config[i][0], VDEC_1);
- config_cav_lut(canvas_u(hw->canvas_spec[i]),
- &hw->canvas_config[i][1], VDEC_1);
+ canvas_config_config(canvas_y(hw->canvas_spec[i]),
+ &hw->canvas_config[i][0]);
+ canvas_config_config(canvas_u(hw->canvas_spec[i]),
+ &hw->canvas_config[i][1]);
}
}
}
@@ -3059,7 +3078,6 @@
READ_VREG(MREG_REF1),
READ_VREG(REC_CANVAS_ADDR),
hw->ctx_valid, index);
-
/* set to mpeg1 default */
WRITE_VREG(MPEG1_2_REG,
(hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 0);
@@ -3207,7 +3225,6 @@
hw->dec_again_cnt = 0;
hw->error_frame_skip_level = error_frame_skip_level;
- init_waitqueue_head(&hw->wait_q);
if (dec_control)
hw->dec_control = dec_control;
}
@@ -3255,10 +3272,9 @@
USER_DATA_SIZE);
//amvdec_enable();
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (unsigned long)hw;
- //hw->check_timer.function = check_timer_func;
+ init_timer(&hw->check_timer);
+ hw->check_timer.data = (unsigned long)hw;
+ hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
hw->stat |= STAT_TIMER_ARM;
@@ -3270,6 +3286,13 @@
return 0;
}
+#ifdef VDEC_FCC_SUPPORT
+static void vmmpeg2_wakeup_fcc_poll(struct vdec_s *vdec)
+{
+ amstream_wakeup_fcc_poll(vdec);
+}
+#endif
+
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
{
struct vdec_mpeg12_hw_s *hw =
@@ -3283,7 +3306,6 @@
"mpeg12 work pending,not ready for run.\n");
return 0;
}
- hw->timeout_processing = 0;
if (vdec_stream_based(vdec) && (hw->init_flag == 0)
&& pre_decode_buf_level != 0) {
u32 rp, wp, level;
@@ -3341,10 +3363,17 @@
}
if (!is_enough_free_buffer(hw)) {
- hw->not_run_ready++;
hw->buffer_not_ready++;
return 0;
}
+
+#ifdef VDEC_FCC_SUPPORT
+ if (!vdec_has_get_fcc_new_msg(vdec)) {
+ hw->buffer_not_ready++;
+ return 0;
+ }
+#endif
+
hw->not_run_ready = 0;
hw->buffer_not_ready = 0;
if (vdec->parallel_dec == 1)
@@ -3391,7 +3420,6 @@
if (level > (vdec->input.size / 2))
hw->dec_again_cnt++;
-
if (hw->dec_again_cnt > dirty_again_threshold) {
debug_print(DECODE_ID(hw), 0, "mpeg12 data skipped %x\n", level);
hw->dec_again_cnt = 0;
@@ -3409,8 +3437,6 @@
(struct vdec_mpeg12_hw_s *)vdec->private;
int save_reg;
int size, ret;
-
- hw->run_flag = 1;
if (!hw->vdec_pg_enable_flag) {
hw->vdec_pg_enable_flag = 1;
amvdec_enable();
@@ -3441,7 +3467,6 @@
debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
"vdec_prepare_input: Insufficient data\n");
vdec_schedule_work(&hw->work);
- hw->run_flag = 0;
return;
}
@@ -3470,8 +3495,8 @@
u8 *data = NULL;
if (hw->chunk)
debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "run: chunk offset 0x%x, size %d\n",
- hw->chunk->offset, hw->chunk->size);
+ "run: chunk offset 0x%x, size %d, pts %d, pts64 %lld\n",
+ hw->chunk->offset, hw->chunk->size, hw->chunk->pts, hw->chunk->pts64);
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
@@ -3532,7 +3557,6 @@
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
hw->dec_result = DEC_RESULT_FORCE_EXIT;
vdec_schedule_work(&hw->work);
- hw->run_flag = 0;
return;
}
vdec->mc_loaded = 1;
@@ -3543,7 +3567,7 @@
hw->dec_result = DEC_RESULT_ERROR;
debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
"ammvdec_mpeg12: error HW context restore\n");
- hw->run_flag = 0;
+ vdec_schedule_work(&hw->work);
return;
}
/*wmb();*/
@@ -3556,29 +3580,14 @@
vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
hw->stat |= STAT_VDEC_RUN;
- hw->stat |= STAT_TIMER_ARM;
hw->init_flag = 1;
- if (hw->mm_blk_handle)
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
- hw->run_flag = 0;
+
+ mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
}
static void reset(struct vdec_s *vdec)
{
- struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private;
-
pr_info("ammvdec_mpeg12: reset.\n");
-
- vmpeg12_local_init(hw);
-
- if (hw->is_used_v4l) {
- u32 i, buf_num = vmpeg12_get_buf_num(hw);
- for (i = 0; i < buf_num; i++) {
- hw->pics[i].v4l_ref_buf_addr = 0;
- }
- }
-
- hw->ctx_valid = 0;
}
static int vmpeg12_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
@@ -3634,6 +3643,9 @@
pdata->reset_userdata_fifo = vmmpeg2_reset_userdata_fifo;
pdata->wakeup_userdata_poll = vmmpeg2_wakeup_userdata_poll;
+#ifdef VDEC_FCC_SUPPORT
+ pdata->wakeup_fcc_poll = vmmpeg2_wakeup_fcc_poll;
+#endif
snprintf(hw->vdec_name, sizeof(hw->vdec_name),
"mpeg12-%d", pdev->id);
snprintf(hw->pts_name, sizeof(hw->pts_name),
@@ -3726,6 +3738,7 @@
vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
| CORE_MASK_COMBINE);
}
+ hw->last_frame_offset = 0xFFFFFFFF;
#ifdef DUMP_USER_DATA
amvdec_mmpeg12_init_userdata_dump(hw);
reset_user_data_buf(hw);
@@ -3744,17 +3757,6 @@
struct vdec_s *vdec = hw_to_vdec(hw);
int i;
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED
- && (vdec->status == VDEC_STATUS_ACTIVE)) {
- debug_print(DECODE_ID(hw), 0,
- "%s, force exit %d\n", __func__, __LINE__);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- wait_event_interruptible_timeout(hw->wait_q,
- (vdec->status == VDEC_STATUS_CONNECTED),
- msecs_to_jiffies(1000)); /* wait for work done */
- }
-
if (hw->stat & STAT_VDEC_RUN) {
amvdec_stop();
hw->stat &= ~STAT_VDEC_RUN;
@@ -3775,12 +3777,8 @@
cancel_work_sync(&hw->timeout_work);
if (hw->mm_blk_handle) {
- void *bmmu_box_tmp = hw->mm_blk_handle;
+ decoder_bmmu_box_free(hw->mm_blk_handle);
hw->mm_blk_handle = NULL;
- while (hw->run_flag)
- usleep_range(1000, 2000);
- decoder_bmmu_box_free(bmmu_box_tmp);
- bmmu_box_tmp = NULL;
}
if (vdec->parallel_dec == 1)
vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
@@ -3825,22 +3823,38 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mmpeg12_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mmpeg12_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mmpeg12_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mmpeg12_suspend, mmpeg12_resume)
+};
+#endif
static struct platform_driver ammvdec_mpeg12_driver = {
.probe = ammvdec_mpeg12_probe,
.remove = ammvdec_mpeg12_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mmpeg12_pm_ops,
+#endif
}
};
static struct codec_profile_t ammvdec_mpeg12_profile = {
.name = "mmpeg12",
- .profile = "v4l"
+ .profile = ""
};
static struct mconfig mmpeg12_configs[] = {
@@ -3872,7 +3886,6 @@
vcodec_profile_register(&ammvdec_mpeg12_profile);
INIT_REG_NODE_CONFIGS("media.decoder", &mmpeg12_node,
"mmpeg12", mmpeg12_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_MPEG12, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c
index 7d33a75..b13ca9c 100644
--- a/drivers/frame_provider/decoder/mpeg4/vmpeg4.c
+++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4.c
@@ -26,10 +26,12 @@
#include <linux/dma-mapping.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
+
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
#include <linux/amlogic/media/canvas/canvas.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "vmpeg4.h"
#include <linux/amlogic/media/registers/register.h>
@@ -38,12 +40,10 @@
#include "../utils/decoder_bmmu_box.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include "../../../common/chips/decoder_cpu_ver_info.h"
-
/* #define CONFIG_AM_VDEC_MPEG4_LOG */
#ifdef CONFIG_AM_VDEC_MPEG4_LOG
#define AMLOG
@@ -182,6 +182,7 @@
static struct work_struct notify_work;
static struct work_struct set_clk_work;
static bool is_reset;
+static bool first_i_frame_ready;
static DEFINE_SPINLOCK(lock);
@@ -435,8 +436,8 @@
pts += vop_time_inc_since_last_anch *
PTS_UNIT / rate;
- pts_us64 += div_u64((u64)(vop_time_inc_since_last_anch *
- PTS_UNIT / rate) * 100, 9);
+ pts_us64 += (u64)(vop_time_inc_since_last_anch *
+ PTS_UNIT / rate) * 100 / 9;
if (vop_time_inc_since_last_anch > (1 << 14)) {
/* avoid overflow */
@@ -462,6 +463,11 @@
}
}
+ if ( (first_i_frame_ready == 0) &&
+ (picture_type == I_PICTURE)) {
+ first_i_frame_ready = 1;
+ }
+
if (reg & INTERLACE_FLAG) { /* interlace */
if (kfifo_get(&newframe_q, &vf) == 0) {
printk
@@ -492,17 +498,23 @@
set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO));
vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
+
+ if (first_i_frame_ready == 0) {
+ kfifo_put(&recycle_q, (const struct vframe_s *)vf);
+ } else {
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
- kfifo_put(&display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
+ kfifo_put(&display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(MODULE_NAME, vf->pts);
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+
+ }
if (kfifo_get(&newframe_q, &vf) == 0) {
printk(
@@ -533,23 +545,29 @@
set_aspect_ratio(vf, READ_VREG(MP4_PIC_RATIO));
- vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- mm_blk_handle,
- buffer_index);
-
amlog_mask(LOG_MASK_PTS,
"[%s:%d] [inte] dur=0x%x rate=%d picture_type=%d\n",
__func__, __LINE__, vf->duration,
vmpeg4_amstream_dec_info.rate, picture_type);
- kfifo_put(&display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
+ vfbuf_use[buffer_index]++;
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ if (first_i_frame_ready == 0) {
+ kfifo_put(&recycle_q, (const struct vframe_s *)vf);
+ } else {
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ mm_blk_handle,
+ buffer_index);
+
+ kfifo_put(&display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(MODULE_NAME, vf->pts);
+
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
NULL);
+ }
+
} else { /* progressive */
if (kfifo_get(&newframe_q, &vf) == 0) {
@@ -586,18 +604,25 @@
__func__, __LINE__, vf->duration,
vmpeg4_amstream_dec_info.rate, picture_type);
+
vfbuf_use[buffer_index]++;
- vf->mem_handle =
+
+ if (first_i_frame_ready == 0) {
+ kfifo_put(&recycle_q, (const struct vframe_s *)vf);
+ } else {
+ vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
- mm_blk_handle,
- buffer_index);
+ mm_blk_handle,
+ buffer_index);
- kfifo_put(&display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(MODULE_NAME, vf->pts);
+ kfifo_put(&display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(MODULE_NAME, vf->pts);
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY,
+ NULL);
+ }
+
}
total_frame += repeat_cnt + 1;
@@ -725,8 +750,10 @@
frame_width, frame_height, fps);
}
-static void vmpeg_put_timer_func(struct timer_list *timer)
+static void vmpeg_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
+
while (!kfifo_is_empty(&recycle_q) && (READ_VREG(MREG_BUFFERIN) == 0)) {
struct vframe_s *vf;
@@ -742,7 +769,7 @@
if (frame_dur > 0 && saved_resolution !=
frame_width * frame_height * (96000 / frame_dur))
- schedule_work(&set_clk_work);
+ schedule_work(&set_clk_work);
if (READ_VREG(AV_SCRATCH_L)) {
pr_info("mpeg4 fatal error happened,need reset !!\n");
@@ -872,30 +899,30 @@
#ifdef NV21
- config_cav_lut_ex(2 * i + 0,
+ canvas_config(2 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(2 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(2 * i + 1,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_BLKMODE_32X32);
#else
- config_cav_lut_ex(3 * i + 0,
+ canvas_config(3 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(3 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 1,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(3 * i + 2,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 2,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
#endif
}
@@ -997,6 +1024,7 @@
frame_num_since_last_anch = 0;
+ first_i_frame_ready = 0;
#ifdef CONFIG_AM_VDEC_MPEG4_LOG
pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0;
#endif
@@ -1073,7 +1101,7 @@
stat |= STAT_MC_LOAD;
query_video_status(0, &trickmode_fffb);
- timer_setup(&recycle_timer, vmpeg_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
if (vdec_request_irq(VDEC_IRQ_1, vmpeg4_isr,
@@ -1118,7 +1146,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong)&recycle_timer;
+ recycle_timer.function = vmpeg_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -1225,16 +1256,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mpeg4_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mpeg4_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mpeg4_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mpeg4_suspend, mpeg4_resume)
+};
+#endif
static struct platform_driver amvdec_mpeg4_driver = {
.probe = amvdec_mpeg4_probe,
.remove = amvdec_mpeg4_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mpeg4_pm_ops,
+#endif
}
};
diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
index 00ceb71..167204c 100644
--- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
+++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c
@@ -24,17 +24,15 @@
#include <linux/kfifo.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/delay.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
+
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/media/registers/register.h>
#include "../../../stream_input/amports/amports_priv.h"
@@ -49,8 +47,8 @@
#include "../utils/firmware.h"
#include "../utils/vdec_v4l2_buffer_ops.h"
#include "../utils/config_parser.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
#include <media/v4l2-mem2mem.h>
-#include "../utils/vdec_feature.h"
#define DRIVER_NAME "ammvdec_mpeg4"
@@ -187,19 +185,14 @@
if (((debug_enable & debug_flag) &&
((1 << index) & mpeg4_debug_mask))
|| (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
+ unsigned char buf[512];
int len = 0;
va_list args;
-
- if (!buf)
- return 0;
-
va_start(args, fmt);
len = sprintf(buf, "%d: ", index);
vsnprintf(buf + len, 512-len, fmt, args);
pr_info("%s", buf);
va_end(args);
- kfree(buf);
}
return 0;
}
@@ -216,7 +209,6 @@
ulong v4l_ref_buf_addr;
u32 hw_decode_time;
u32 frame_size; // For frame base mode;
- u64 timestamp;
u32 offset;
u32 height;
u32 width;
@@ -329,8 +321,6 @@
int sidebind_type;
int sidebind_channel_id;
u32 res_ch_flag;
- u32 profile_idc;
- u32 level_idc;
unsigned int i_decoded_frames;
unsigned int i_lost_frames;
unsigned int i_concealed_frames;
@@ -340,13 +330,13 @@
unsigned int b_decoded_frames;
unsigned int b_lost_frames;
unsigned int b_concealed_frames;
+ u32 profile_idc;
+ u32 level_idc;
int vdec_pg_enable_flag;
- ulong fb_token;
char vdec_name[32];
char pts_name[32];
char new_q_name[32];
char disp_q_name[32];
- bool run_flag;
};
static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw);
static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw);
@@ -381,6 +371,7 @@
static void reset_process_time(struct vdec_mpeg4_hw_s *hw);
+
static int vmpeg4_get_buf_num(struct vdec_mpeg4_hw_s *hw)
{
int buf_num = DECODE_BUFFER_NUM_DEF;
@@ -404,16 +395,10 @@
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (hw->pic[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->pic[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
+ if (hw->pic[i].v4l_ref_buf_addr)
return 0;
- }
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
if (ret < 0) {
mmpeg4_debug_print(DECODE_ID(hw), 0,
"[%d] get fb fail.\n",
@@ -422,8 +407,6 @@
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (!hw->frame_width || !hw->frame_height) {
struct vdec_pic_info pic;
vdec_v4l_get_pic_info(ctx, &pic);
@@ -454,8 +437,8 @@
fb->m.mem[1].bytes_used = decbuf_uv_size;
}
- mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%x\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id, __func__, fb);
+ mmpeg4_debug_print(DECODE_ID(hw), 0, "[%d] %s(), v4l ref buf addr: 0x%px\n",
+ ctx->id, __func__, fb);
if (vdec->parallel_dec == 1) {
u32 tmp;
@@ -484,11 +467,8 @@
hw->canvas_config[i][0].endian = 7;
else
hw->canvas_config[i][0].endian = 0;
- config_cav_lut(canvas_y(canvas),
- &hw->canvas_config[i][0], VDEC_1);
- /* mpeg4 decoder canvas need to be revert to match display canvas */
- hw->canvas_config[i][0].endian =
- (hw->blkmode != CANVAS_BLKMODE_LINEAR) ? 7 : 0;
+ canvas_config_config(canvas_y(canvas),
+ &hw->canvas_config[i][0]);
hw->canvas_config[i][1].phy_addr =
decbuf_uv_start;
@@ -499,11 +479,8 @@
hw->canvas_config[i][1].endian = 7;
else
hw->canvas_config[i][1].endian = 0;
- config_cav_lut(canvas_u(canvas),
- &hw->canvas_config[i][1], VDEC_1);
- /* mpeg4 decoder canvas need to be revert to match display canvas */
- hw->canvas_config[i][1].endian =
- (hw->blkmode != CANVAS_BLKMODE_LINEAR) ? 7 : 0;
+ canvas_config_config(canvas_u(canvas),
+ &hw->canvas_config[i][1]);
return 0;
}
@@ -537,16 +514,14 @@
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
/*run to parser csd data*/
- i = 0xffffff;
+ i = 0;
} else {
- if (!ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token))
- return -1;
-
if (vmpeg4_v4l_alloc_buff_config_canvas(hw, i))
return -1;
}
}
+
return i;
}
@@ -714,7 +689,6 @@
struct vframe_s *vf = NULL;
struct vdec_s *vdec = hw_to_vdec(hw);
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
ulong nv_order = VIDTYPE_VIU_NV21;
int index = pic->index;
bool pb_skip = false;
@@ -725,8 +699,6 @@
if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
(v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
nv_order = VIDTYPE_VIU_NV12;
- if (vdec->prog_only)
- pic->pic_info &= ~INTERLACE_FLAG;
}
if (hw->i_only)
@@ -742,7 +714,6 @@
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->pic[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
"[%d] %s(), v4l mem handle: 0x%lx\n",
((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
@@ -757,7 +728,6 @@
vf->orientation = hw->vmpeg4_rotation;
vf->pts = pic->pts;
vf->pts_us64 = pic->pts64;
- vf->timestamp = pic->timestamp;
vf->duration = pic->duration >> 1;
vf->duration_pulldown = 0;
vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ?
@@ -771,6 +741,7 @@
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
"field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n",
vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration);
+
if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
vf->pts_us64 =
(((u64)vf->duration << 32) &
@@ -808,20 +779,11 @@
hw->b_decoded_frames++;
}
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
} else
vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
}
-
if (kfifo_get(&hw->newframe_q, &vf) == 0) {
mmpeg4_debug_print(DECODE_ID(hw), 0,
"error, no available buf.\n");
@@ -829,6 +791,16 @@
return -1;
}
+ if (hw->is_used_v4l) {
+ vf->v4l_mem_handle
+ = hw->pic[index].v4l_ref_buf_addr;
+ mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
+ "[%d] %s(), v4l mem handle: 0x%lx\n",
+ ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
+ __func__, vf->v4l_mem_handle);
+ }
+
+
vf->index = pic->index;
vf->width = pic->width;
vf->height = pic->height;
@@ -837,7 +809,6 @@
vf->orientation = hw->vmpeg4_rotation;
vf->pts = 0;
vf->pts_us64 = 0;
- vf->timestamp = 0;
vf->duration = pic->duration >> 1;
vf->duration_pulldown = 0;
vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ?
@@ -856,6 +827,7 @@
vf->pts_us64 = (u64)-1;
vf->pts = 0;
}
+
if (((hw->first_i_frame_ready == 0) || pb_skip)
&& (pic->pic_type != I_PICTURE)) {
hw->drop_frame_count++;
@@ -890,16 +862,8 @@
hw->b_decoded_frames++;
}
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
} else
vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
}
@@ -911,7 +875,6 @@
hw->dec_result = DEC_RESULT_ERROR;
return -1;
}
-
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->pic[index].v4l_ref_buf_addr;
@@ -929,7 +892,6 @@
vf->orientation = hw->vmpeg4_rotation;
vf->pts = pic->pts;
vf->pts_us64 = pic->pts64;
- vf->timestamp = pic->timestamp;
vf->duration = pic->duration;
vf->duration_pulldown = pic->repeat_cnt *
pic->duration;
@@ -946,12 +908,14 @@
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
"prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n",
vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration);
+
if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
vf->pts_us64 =
(((u64)vf->duration << 32) &
0xffffffff00000000) | pic->offset;
vf->pts = 0;
}
+
if (((hw->first_i_frame_ready == 0) || pb_skip)
&& (pic->pic_type != I_PICTURE)) {
hw->drop_frame_count++;
@@ -992,16 +956,8 @@
vdec_fill_vdec_frame(vdec, NULL,
&vinfo, vf, pic->hw_decode_time);
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
} else
vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
}
@@ -1027,7 +983,8 @@
/* reset VLD fifo for all vdec */
WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3));
WRITE_VREG(DOS_SW_RESET0, 0);
-
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)
+ dummy = READ_RESET_REG(RESET0_REGISTER);
WRITE_VREG(POWER_CTL_VLD, 1 << 4);
/*
@@ -1069,18 +1026,19 @@
}
}
-static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps)
+static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace, struct aml_vdec_ps_infos *ps)
{
ps->visible_width = width;
ps->visible_height = height;
ps->coded_width = ALIGN(width, 64);
ps->coded_height = ALIGN(height, 64);
ps->dpb_size = hw->buf_num;
+ ps->field = interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
return 0;
}
-static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height)
+static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace)
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
@@ -1099,7 +1057,7 @@
hw->frame_width, hw->frame_height,
width,
height);
- vmpeg4_get_ps_info(hw, width, height, &ps);
+ vmpeg4_get_ps_info(hw, width, height, interlace, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
vdec_v4l_res_ch_event(ctx);
hw->v4l_params_parsed = false;
@@ -1107,8 +1065,7 @@
ctx->v4l_resolution_change = 1;
hw->eos = 1;
flush_output(hw);
- if (hw->is_used_v4l)
- notify_v4l_eos(hw_to_vdec(hw));
+ notify_v4l_eos(hw_to_vdec(hw));
ret = 1;
}
@@ -1130,6 +1087,7 @@
u32 repeat_cnt, duration = 3200;
struct pic_info_t *dec_pic, *disp_pic;
struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)(vdec->private);
+
if (hw->eos)
return IRQ_HANDLED;
@@ -1137,13 +1095,16 @@
if (hw->is_used_v4l) {
int frame_width = READ_VREG(MP4_PIC_WH)>> 16;
int frame_height = READ_VREG(MP4_PIC_WH) & 0xffff;
- if (!v4l_res_change(hw, frame_width, frame_height)) {
+ int interlace = (READ_VREG(MP4_PIC_RATIO) & 0x80000000) >> 31;
+ mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
+ "interlace = %d\n", interlace);
+ if (!v4l_res_change(hw, frame_width, frame_height, interlace)) {
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(hw->v4l2_ctx);
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
struct aml_vdec_ps_infos ps;
- vmpeg4_get_ps_info(hw, frame_width, frame_height, &ps);
+ vmpeg4_get_ps_info(hw, frame_width, frame_height, interlace, &ps);
hw->v4l_params_parsed = true;
vdec_v4l_set_ps_infos(ctx, &ps);
reset_process_time(hw);
@@ -1162,14 +1123,6 @@
return IRQ_HANDLED;
}
- if ((hw->is_used_v4l) && !hw->v4l_params_parsed) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "The head was not found, can not to decode\n");
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
-
WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
if (READ_VREG(AV_SCRATCH_M) != 0 &&
(debug_enable & PRINT_FLAG_UCODE_DETAIL)) {
@@ -1267,7 +1220,6 @@
dec_pic->pts_valid = false;
dec_pic->pts = 0;
dec_pic->pts64 = 0;
- dec_pic->timestamp = 0;
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
"new pic: index=%d, used=%d, repeat=%d, time_inc=%d\n",
index, hw->vfbuf_use[index], repeat_cnt, vop_time_inc);
@@ -1282,7 +1234,6 @@
hw->frame_height = dec_h;
dec_pic->height = dec_h;
}
- hw->res_ch_flag = 0;
if (hw->vmpeg4_amstream_dec_info.rate == 0) {
if (vop_time_inc < hw->last_vop_time_inc) {
@@ -1327,7 +1278,6 @@
dec_pic->pts_valid = hw->chunk->pts_valid;
dec_pic->pts = hw->chunk->pts;
dec_pic->pts64 = hw->chunk->pts64;
- dec_pic->timestamp = hw->chunk->timestamp;
if ((B_PICTURE == picture_type) ||
(hw->last_dec_pts == dec_pic->pts))
dec_pic->pts_valid = 0;
@@ -1340,7 +1290,6 @@
dec_pic->pts_valid = hw->chunk->pts_valid;
dec_pic->pts = hw->chunk->pts;
dec_pic->pts64 = hw->chunk->pts64;
- dec_pic->timestamp = hw->chunk->timestamp;
} else {
dec_pic->offset = offset;
if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
@@ -1368,11 +1317,10 @@
dec_pic->duration = duration;
hw->vfbuf_use[index] = 0;
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "mmpeg4: pic_num: %d, index %d, type %c, pts %x\n",
+ "mmpeg4: pic_num: %d, index %d, type %c, pts %x, pts64 %lld, height %d, width %d\n",
hw->frame_num, index,
GET_PIC_TYPE(picture_type),
- dec_pic->pts);
-
+ dec_pic->pts, dec_pic->pts64, dec_pic->height, dec_pic->width);
/* buffer management */
if ((picture_type == I_PICTURE) ||
(picture_type == P_PICTURE)) {
@@ -1492,17 +1440,15 @@
if (!disp_pic->pts_valid) {
disp_pic->pts = 0;
disp_pic->pts64 = 0;
- disp_pic->timestamp = 0;
}
}
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "disp: pic_type %c, pts %d(%lld), diff %d, cnt %d, disp_pic->timestamp %llu\n",
+ "disp: pic_type %c, pts %d(%lld), diff %d, cnt %d\n",
GET_PIC_TYPE(disp_pic->pic_type),
disp_pic->pts,
disp_pic->pts64,
disp_pic->pts - hw->last_pts,
- hw->chunk_frame_count,
- disp_pic->timestamp);
+ hw->chunk_frame_count);
hw->last_pts = disp_pic->pts;
hw->last_pts64 = disp_pic->pts64;
hw->frame_dur = duration;
@@ -1597,12 +1543,10 @@
if (hw->is_used_v4l) {
index = find_free_buffer(hw);
- if ((index == -1) || (index == 0xffffff)) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
- pr_err("[%d] get fb fail.\n", ctx->id);
- return -1;
- }
+ if ((index == -1) &&
+ vdec_v4l_get_buffer(hw->v4l2_ctx, &fb)) {
+ pr_err("[%d] get fb fail.\n", ctx->id);
+ return -1;
}
}
@@ -1611,17 +1555,12 @@
vf->v4l_mem_handle = (index == -1) ? (ulong)fb :
hw->pic[index].v4l_ref_buf_addr;;
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
ATRACE_COUNTER(hw->pts_name, vf->pts);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
pr_info("[%d] mpeg4 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
@@ -1648,7 +1587,7 @@
hw->ctx_valid = 1;
} else if ((hw->dec_result == DEC_RESULT_DONE) ||
- ((!hw->is_used_v4l) && (input_frame_based(&vdec->input)) && hw->chunk)) {
+ ((input_frame_based(&vdec->input)) && hw->chunk)) {
if (!hw->ctx_valid)
hw->ctx_valid = 1;
@@ -1683,7 +1622,6 @@
hw->chunk = NULL;
vdec_clean_input(vdec);
flush_output(hw);
-
notify_v4l_eos(vdec);
mmpeg4_debug_print(DECODE_ID(hw), 0,
@@ -1913,26 +1851,25 @@
ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
decbuf_size, DRIVER_NAME, &decbuf_start);
if (ret < 0) {
- pr_err("bmmu alloc failed! size %d idx %d\n",
+ pr_err("mmu alloc failed! size %d idx %d\n",
decbuf_size, i);
return ret;
}
- }
-
- if (!vdec_secure(vdec)) {
- /*init internal buf*/
- char *tmpbuf = (char *)codec_mm_phys_to_virt(decbuf_start);
- if (tmpbuf) {
- memset(tmpbuf, 0, decbuf_size);
- codec_mm_dma_flush(tmpbuf,
- decbuf_size, DMA_TO_DEVICE);
- } else {
- tmpbuf = codec_mm_vmap(decbuf_start, decbuf_size);
+ if (!vdec_secure(vdec)) {
+ /*init internal buf*/
+ char *tmpbuf = (char *)codec_mm_phys_to_virt(decbuf_start);
if (tmpbuf) {
memset(tmpbuf, 0, decbuf_size);
codec_mm_dma_flush(tmpbuf,
decbuf_size, DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(tmpbuf);
+ } else {
+ tmpbuf = codec_mm_vmap(decbuf_start, decbuf_size);
+ if (tmpbuf) {
+ memset(tmpbuf, 0, decbuf_size);
+ codec_mm_dma_flush(tmpbuf,
+ decbuf_size, DMA_TO_DEVICE);
+ codec_mm_unmap_phyaddr(tmpbuf);
+ }
}
}
}
@@ -1969,8 +1906,8 @@
hw->canvas_config[i][0].endian = 7;
else
hw->canvas_config[i][0].endian = 0;
- config_cav_lut(canvas_y(canvas),
- &hw->canvas_config[i][0], VDEC_1);
+ canvas_config_config(canvas_y(canvas),
+ &hw->canvas_config[i][0]);
hw->canvas_config[i][1].phy_addr =
decbuf_start + decbuf_y_size;
@@ -1981,8 +1918,8 @@
hw->canvas_config[i][1].endian = 7;
else
hw->canvas_config[i][1].endian = 0;
- config_cav_lut(canvas_u(canvas),
- &hw->canvas_config[i][1], VDEC_1);
+ canvas_config_config(canvas_u(canvas),
+ &hw->canvas_config[i][1]);
}
}
@@ -1997,13 +1934,12 @@
mmpeg4_debug_print(DECODE_ID(hw), 0,
"====== %s\n", __func__);
mmpeg4_debug_print(DECODE_ID(hw), 0,
- "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d, run_flag %d\n",
+ "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d\n",
hw->frame_width,
hw->frame_height,
hw->first_i_frame_ready,
hw->buffer_not_ready,
- hw->buf_num,
- hw->run_flag
+ hw->buf_num
);
for (i = 0; i < hw->buf_num; i++) {
mmpeg4_debug_print(DECODE_ID(hw), 0,
@@ -2028,7 +1964,7 @@
hw->drop_frame_count
);
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -2143,10 +2079,9 @@
}
-static void check_timer_func(struct timer_list *timer)
+static void check_timer_func(unsigned long arg)
{
- struct vdec_mpeg4_hw_s *hw = container_of(timer,
- struct vdec_mpeg4_hw_s, check_timer);
+ struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)arg;
struct vdec_s *vdec = hw_to_vdec(hw);
unsigned int timeout_val = decode_timeout_val;
@@ -2200,10 +2135,10 @@
} else {
if (!hw->is_used_v4l) {
for (i = 0; i < hw->buf_num; i++) {
- config_cav_lut(canvas_y(hw->canvas_spec[i]),
- &hw->canvas_config[i][0], VDEC_1);
- config_cav_lut(canvas_u(hw->canvas_spec[i]),
- &hw->canvas_config[i][1], VDEC_1);
+ canvas_config_config(canvas_y(hw->canvas_spec[i]),
+ &hw->canvas_config[i][0]);
+ canvas_config_config(canvas_u(hw->canvas_spec[i]),
+ &hw->canvas_config[i][1]);
}
}
}
@@ -2216,17 +2151,14 @@
WRITE_VREG(MREG_REF0, (hw->refs[1] == -1) ? 0xffffffff :
hw->canvas_spec[hw->refs[1]]);
} else {
- WRITE_VREG(MREG_REF0, hw->canvas_spec[hw->refs[0]]);
+ WRITE_VREG(MREG_REF0, (hw->refs[0] == -1) ? 0xffffffff :
+ hw->canvas_spec[hw->refs[0]]);
}
WRITE_VREG(MREG_REF1, (hw->refs[1] == -1) ? 0xffffffff :
hw->canvas_spec[hw->refs[1]]);
- if ((hw->is_used_v4l) && (index == 0xffffff)) {
- WRITE_VREG(REC_CANVAS_ADDR, 0xffffff);
- WRITE_VREG(ANC2_CANVAS_ADDR, 0xffffff);
- } else {
- WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]);
- WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]);
- }
+
+ WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]);
+ WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]);
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE,
"restore ref0=0x%x, ref1=0x%x, rec=0x%x, ctx_valid=%d,index=%d\n",
@@ -2322,7 +2254,7 @@
hw->unstable_pts =
(((unsigned long) hw->vmpeg4_amstream_dec_info.param & 0x40) >> 6);
mmpeg4_debug_print(DECODE_ID(hw), 0,
- "param = 0x%x unstable_pts = %d\n",
+ "param = 0x%px unstable_pts = %d\n",
hw->vmpeg4_amstream_dec_info.param,
hw->unstable_pts);
hw->last_dec_pts = -1;
@@ -2422,10 +2354,9 @@
//amvdec_enable();
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (unsigned long)hw;
- //hw->check_timer.function = check_timer_func;
+ init_timer(&hw->check_timer);
+ hw->check_timer.data = (unsigned long)hw;
+ hw->check_timer.function = check_timer_func;
hw->check_timer.expires = jiffies + CHECK_INTERVAL;
hw->stat |= STAT_TIMER_ARM;
hw->eos = 0;
@@ -2440,6 +2371,7 @@
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
{
struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
+
if (hw->eos)
return 0;
if (vdec_stream_based(vdec) && (hw->init_flag == 0)
@@ -2519,8 +2451,6 @@
{
struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
int size = 0, ret = 0;
-
- hw->run_flag = 1;
if (!hw->vdec_pg_enable_flag) {
hw->vdec_pg_enable_flag = 1;
amvdec_enable();
@@ -2540,7 +2470,6 @@
hw->input_empty++;
hw->dec_result = DEC_RESULT_AGAIN;
vdec_schedule_work(&hw->work);
- hw->run_flag = 0;
return;
}
if ((vdec_frame_based(vdec)) &&
@@ -2567,10 +2496,10 @@
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk_offset, size);
+ hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk_offset;
+ hw->chunk->offset;
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
@@ -2625,7 +2554,6 @@
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
hw->dec_result = DEC_RESULT_FORCE_EXIT;
vdec_schedule_work(&hw->work);
- hw->run_flag = 0;
return;
}
vdec->mc_loaded = 1;
@@ -2635,7 +2563,7 @@
hw->dec_result = DEC_RESULT_ERROR;
mmpeg4_debug_print(DECODE_ID(hw), 0,
"amvdec_mpeg4: error HW context restore\n");
- hw->run_flag = 0;
+ vdec_schedule_work(&hw->work);
return;
}
if (vdec_frame_based(vdec)) {
@@ -2656,10 +2584,8 @@
vdec->mvfrm->hw_decode_start = local_clock();
amvdec_start();
hw->stat |= STAT_VDEC_RUN;
- hw->stat |= STAT_TIMER_ARM;
hw->init_flag = 1;
mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
- hw->run_flag = 0;
}
static int vmpeg4_stop(struct vdec_mpeg4_hw_s *hw)
@@ -2667,12 +2593,8 @@
cancel_work_sync(&hw->work);
if (hw->mm_blk_handle) {
- void *bmmu_box_tmp = hw->mm_blk_handle;
- hw->mm_blk_handle = NULL;
- while (hw->run_flag)
- usleep_range(1000, 2000);
- decoder_bmmu_box_free(bmmu_box_tmp);
- bmmu_box_tmp = NULL;
+ decoder_bmmu_box_free(hw->mm_blk_handle);
+ hw->mm_blk_handle = NULL;
}
if (hw->stat & STAT_TIMER_ARM) {
@@ -2694,12 +2616,6 @@
vmpeg4_local_init(hw);
- if (hw->is_used_v4l) {
- u32 i, buf_num = vmpeg4_get_buf_num(hw);
- for (i = 0; i < buf_num; i++) {
- hw->pic[i].v4l_ref_buf_addr = 0;
- }
- }
hw->ctx_valid = 0;
}
@@ -2771,24 +2687,15 @@
platform_set_drvdata(pdev, pdata);
hw->platform_dev = pdev;
- if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) {
- mmpeg4_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config);
- if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin = config_val;
- else
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- } else {
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- }
- hw->buf_num = vmpeg4_get_buf_num(hw);
-
if (pdata->parallel_dec == 1) {
int i;
for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
hw->canvas_spec[i] = 0xffffff;
}
+ vf_provider_init(&pdata->vframe_provider,
+ pdata->vf_provider_name, &vf_provider_ops, pdata);
+
hw->blkmode = pdata->canvas_mode;
if (pdata->sys_info) {
@@ -2810,6 +2717,7 @@
hw->vmpeg4_amstream_dec_info.height,
hw->vmpeg4_amstream_dec_info.rate);
}
+
if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) {
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
"pdata->config: %s\n", pdata->config);
@@ -2839,10 +2747,6 @@
} else
hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- if (!hw->is_used_v4l)
- vf_provider_init(&pdata->vframe_provider,
- pdata->vf_provider_name, &vf_provider_ops, pdata);
-
hw->buf_num = vmpeg4_get_buf_num(hw);
if (vmmpeg4_init(hw) < 0) {
@@ -2913,22 +2817,38 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int mmpeg4_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int mmpeg4_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops mmpeg4_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mmpeg4_suspend, mmpeg4_resume)
+};
+#endif
static struct platform_driver ammvdec_mpeg4_driver = {
.probe = ammvdec_mpeg4_probe,
.remove = ammvdec_mpeg4_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &mmpeg4_pm_ops,
+#endif
}
};
static struct codec_profile_t amvdec_mpeg4_profile = {
.name = "mmpeg4",
- .profile = "v4l, no_single"
+ .profile = ""
};
static int __init ammvdec_mpeg4_driver_init_module(void)
@@ -2940,7 +2860,6 @@
return -ENODEV;
}
vcodec_profile_register(&amvdec_mpeg4_profile);
- vcodec_feature_register(VFORMAT_MPEG4, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/real/Makefile b/drivers/frame_provider/decoder/real/Makefile
new file mode 100644
index 0000000..ab03ef2
--- /dev/null
+++ b/drivers/frame_provider/decoder/real/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_REAL) += amvdec_real.o
+amvdec_real-objs += vreal.o
diff --git a/drivers/frame_provider/decoder/real/vreal.c b/drivers/frame_provider/decoder/real/vreal.c
new file mode 100644
index 0000000..f6474b6
--- /dev/null
+++ b/drivers/frame_provider/decoder/real/vreal.c
@@ -0,0 +1,1069 @@
+/*
+ * drivers/amlogic/amports/vreal.c
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/kfifo.h>
+#include <linux/platform_device.h>
+
+#include <linux/amlogic/media/canvas/canvas.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/utils/vformat.h>
+#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../utils/vdec.h"
+#include <linux/amlogic/media/utils/vdec_reg.h>
+#include "../utils/amvdec.h"
+
+#include "../../../stream_input/amports/streambuf.h"
+#include "../../../stream_input/amports/streambuf_reg.h"
+#include "../../../stream_input/parser/rmparser.h"
+
+#include "vreal.h"
+#include <linux/amlogic/media/registers/register.h>
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include "../utils/firmware.h"
+#include <linux/amlogic/tee.h>
+
+
+
+#define DRIVER_NAME "amvdec_real"
+#define MODULE_NAME "amvdec_real"
+
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+#define NV21
+#endif
+
+#define RM_DEF_BUFFER_ADDR 0x01000000
+/* protocol registers */
+#define STATUS_AMRISC AV_SCRATCH_4
+
+#define RV_PIC_INFO AV_SCRATCH_5
+#define VPTS_TR AV_SCRATCH_6
+#define VDTS AV_SCRATCH_7
+#define FROM_AMRISC AV_SCRATCH_8
+#define TO_AMRISC AV_SCRATCH_9
+#define SKIP_B_AMRISC AV_SCRATCH_A
+#define INT_REASON AV_SCRATCH_B
+#define WAIT_BUFFER AV_SCRATCH_E
+
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+#define MDEC_WIDTH AV_SCRATCH_I
+#define MDEC_HEIGHT AV_SCRATCH_J
+#else
+#define MDEC_WIDTH HARM_ASB_MB2
+#define MDEC_HEIGHT HASB_ARM_MB0
+#endif
+
+#define PARC_FORBIDDEN 0
+#define PARC_SQUARE 1
+#define PARC_CIF 2
+#define PARC_10_11 3
+#define PARC_16_11 4
+#define PARC_40_33 5
+#define PARC_RESERVED 6
+/* values between 6 and 14 are reserved */
+#define PARC_EXTENDED 15
+
+#define VF_POOL_SIZE 16
+#define VF_BUF_NUM 4
+#define PUT_INTERVAL (HZ/100)
+#define WORKSPACE_SIZE (1 * SZ_1M)
+#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM + 1)
+#define RV_AI_BUFF_START_IP 0x01f00000
+
+static struct vframe_s *vreal_vf_peek(void *);
+static struct vframe_s *vreal_vf_get(void *);
+static void vreal_vf_put(struct vframe_s *, void *);
+static int vreal_vf_states(struct vframe_states *states, void *);
+static int vreal_event_cb(int type, void *data, void *private_data);
+
+static int vreal_prot_init(void);
+static void vreal_local_init(void);
+
+static const char vreal_dec_id[] = "vreal-dev";
+
+#define PROVIDER_NAME "decoder.real"
+
+/*
+ *int query_video_status(int type, int *value);
+ */
+static const struct vframe_operations_s vreal_vf_provider = {
+ .peek = vreal_vf_peek,
+ .get = vreal_vf_get,
+ .put = vreal_vf_put,
+ .event_cb = vreal_event_cb,
+ .vf_states = vreal_vf_states,
+};
+
+static struct vframe_provider_s vreal_vf_prov;
+static void *mm_blk_handle;
+
+static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
+static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
+
+static struct vframe_s vfpool[VF_POOL_SIZE];
+static s32 vfbuf_use[VF_BUF_NUM];
+
+static u32 frame_width, frame_height, frame_dur, frame_prog;
+static u32 saved_resolution;
+static struct timer_list recycle_timer;
+static u32 stat;
+static u32 buf_size = 32 * 1024 * 1024;
+static u32 buf_offset;
+static u32 vreal_ratio;
+u32 vreal_format;
+static u32 wait_key_frame;
+static u32 last_tr;
+static u32 frame_count;
+static u32 current_vdts;
+static u32 hold;
+static u32 decoder_state;
+static u32 real_err_count;
+
+static u32 fatal_flag;
+static s32 wait_buffer_counter;
+static struct work_struct set_clk_work;
+static bool is_reset;
+
+static DEFINE_SPINLOCK(lock);
+
+static unsigned short pic_sz_tbl[12] ____cacheline_aligned;
+static dma_addr_t pic_sz_tbl_map;
+static const unsigned char RPR_size[9] = { 0, 1, 1, 2, 2, 3, 3, 3, 3 };
+
+static struct dec_sysinfo vreal_amstream_dec_info;
+
+static unsigned char aspect_ratio_table[16] = {
+ PARC_FORBIDDEN,
+ PARC_SQUARE,
+ PARC_CIF,
+ PARC_10_11,
+ PARC_16_11,
+ PARC_40_33,
+ PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
+ PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
+ PARC_RESERVED, PARC_EXTENDED
+};
+
+static inline u32 index2canvas(u32 index)
+{
+ const u32 canvas_tab[4] = {
+#ifdef NV21
+ 0x010100, 0x030302, 0x050504, 0x070706
+#else
+ 0x020100, 0x050403, 0x080706, 0x0b0a09
+#endif
+ };
+
+ return canvas_tab[index];
+}
+
+static void set_aspect_ratio(struct vframe_s *vf, unsigned int pixel_ratio)
+{
+ int ar = 0;
+
+ if (vreal_ratio == 0) {
+ vf->ratio_control |= (0x90 <<
+ DISP_RATIO_ASPECT_RATIO_BIT);
+ /* always stretch to 16:9 */
+ } else {
+ switch (aspect_ratio_table[pixel_ratio]) {
+ case 0:
+ ar = vreal_amstream_dec_info.height * vreal_ratio /
+ vreal_amstream_dec_info.width;
+ break;
+ case 1:
+ case 0xff:
+ ar = vreal_ratio * vf->height / vf->width;
+ break;
+ case 2:
+ ar = (vreal_ratio * vf->height * 12) / (vf->width * 11);
+ break;
+ case 3:
+ ar = (vreal_ratio * vf->height * 11) / (vf->width * 10);
+ break;
+ case 4:
+ ar = (vreal_ratio * vf->height * 11) / (vf->width * 16);
+ break;
+ case 5:
+ ar = (vreal_ratio * vf->height * 33) / (vf->width * 40);
+ break;
+ default:
+ ar = vreal_ratio * vf->height / vf->width;
+ break;
+ }
+ }
+
+ ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
+
+ vf->ratio_control |= (ar << DISP_RATIO_ASPECT_RATIO_BIT);
+}
+
+static irqreturn_t vreal_isr(int irq, void *dev_id)
+{
+ u32 from;
+ struct vframe_s *vf = NULL;
+ u32 buffer_index;
+ unsigned int status;
+ unsigned int vdts;
+ unsigned int info;
+ unsigned int tr;
+ unsigned int pictype;
+ u32 r = READ_VREG(INT_REASON);
+
+ if (decoder_state == 0)
+ return IRQ_HANDLED;
+
+ status = READ_VREG(STATUS_AMRISC);
+ if (status & (PARSER_ERROR_WRONG_PACKAGE_SIZE |
+ PARSER_ERROR_WRONG_HEAD_VER |
+ DECODER_ERROR_VLC_DECODE_TBL)) {
+ /* decoder or parser error */
+ real_err_count++;
+ /* pr_info("real decoder or parser
+ *error, status 0x%x\n", status);
+ */
+ }
+
+ if (r == 2) {
+ pr_info("first vpts = 0x%x\n", READ_VREG(VDTS));
+ pts_checkin_offset(PTS_TYPE_AUDIO, 0, READ_VREG(VDTS) * 90);
+ WRITE_VREG(AV_SCRATCH_B, 0);
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+ return IRQ_HANDLED;
+ } else if (r == 3) {
+ pr_info("first apts = 0x%x\n", READ_VREG(VDTS));
+ pts_checkin_offset(PTS_TYPE_VIDEO, 0, READ_VREG(VDTS) * 90);
+ WRITE_VREG(AV_SCRATCH_B, 0);
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+ return IRQ_HANDLED;
+ }
+
+ from = READ_VREG(FROM_AMRISC);
+ if ((hold == 0) && from) {
+ tr = READ_VREG(VPTS_TR);
+ pictype = (tr >> 13) & 3;
+ tr = (tr & 0x1fff) * 96;
+
+ if (kfifo_get(&newframe_q, &vf) == 0) {
+ pr_info("fatal error, no available buffer slot.");
+ return IRQ_HANDLED;
+ }
+
+ vdts = READ_VREG(VDTS);
+ if (last_tr == -1) /* ignore tr for first time */
+ vf->duration = frame_dur;
+ else {
+ if (tr > last_tr)
+ vf->duration = tr - last_tr;
+ else
+ vf->duration = (96 << 13) + tr - last_tr;
+
+ if (vf->duration > 10 * frame_dur) {
+ /* not a reasonable duration,
+ *should not happen
+ */
+ vf->duration = frame_dur;
+ }
+#if 0
+ else {
+ if (check_frame_duration == 0) {
+ frame_dur = vf->duration;
+ check_frame_duration = 1;
+ }
+ }
+#endif
+ }
+
+ last_tr = tr;
+ buffer_index = from & 0x03;
+
+ if (pictype == 0) { /* I */
+ current_vdts = vdts * 90 + 1;
+ vf->pts = current_vdts;
+ if (wait_key_frame)
+ wait_key_frame = 0;
+ } else {
+ if (wait_key_frame) {
+ while (READ_VREG(TO_AMRISC))
+ ;
+ WRITE_VREG(TO_AMRISC, ~(1 << buffer_index));
+ WRITE_VREG(FROM_AMRISC, 0);
+ return IRQ_HANDLED;
+ } else {
+ current_vdts +=
+ vf->duration - (vf->duration >> 4);
+ vf->pts = current_vdts;
+ }
+ }
+
+ /* pr_info("pts %d, picture type %d\n", vf->pts, pictype); */
+
+ info = READ_VREG(RV_PIC_INFO);
+ vf->signal_type = 0;
+ vf->index = buffer_index;
+ vf->width = info >> 16;
+ vf->height = (info >> 4) & 0xfff;
+ vf->bufWidth = 1920;
+ vf->flag = 0;
+ vf->ratio_control = 0;
+ set_aspect_ratio(vf, info & 0x0f);
+ vf->duration_pulldown = 0;
+#ifdef NV21
+ vf->type = VIDTYPE_PROGRESSIVE |
+ VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21;
+#else
+ vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
+#endif
+ vf->canvas0Addr = vf->canvas1Addr = index2canvas(buffer_index);
+ vf->orientation = 0;
+ vf->type_original = vf->type;
+
+ vfbuf_use[buffer_index] = 1;
+ vf->mem_handle =
+ decoder_bmmu_box_get_mem_handle(
+ mm_blk_handle,
+ buffer_index);
+
+ kfifo_put(&display_q, (const struct vframe_s *)vf);
+ ATRACE_COUNTER(MODULE_NAME, vf->pts);
+
+ frame_count++;
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ WRITE_VREG(FROM_AMRISC, 0);
+ }
+
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+
+ return IRQ_HANDLED;
+}
+
+static struct vframe_s *vreal_vf_peek(void *op_arg)
+{
+ struct vframe_s *vf;
+
+ if (kfifo_peek(&display_q, &vf))
+ return vf;
+
+ return NULL;
+}
+
+static struct vframe_s *vreal_vf_get(void *op_arg)
+{
+ struct vframe_s *vf;
+
+ if (kfifo_get(&display_q, &vf))
+ return vf;
+
+ return NULL;
+}
+
+static void vreal_vf_put(struct vframe_s *vf, void *op_arg)
+{
+ kfifo_put(&recycle_q, (const struct vframe_s *)vf);
+}
+
+static int vreal_event_cb(int type, void *data, void *private_data)
+{
+ if (type & VFRAME_EVENT_RECEIVER_RESET) {
+ unsigned long flags;
+
+ amvdec_stop();
+#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_light_unreg_provider(&vreal_vf_prov);
+#endif
+ spin_lock_irqsave(&lock, flags);
+ vreal_local_init();
+ vreal_prot_init();
+ spin_unlock_irqrestore(&lock, flags);
+#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_reg_provider(&vreal_vf_prov);
+#endif
+ amvdec_start();
+ }
+ return 0;
+}
+
+static int vreal_vf_states(struct vframe_states *states, void *op_arg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ states->vf_pool_size = VF_POOL_SIZE;
+ states->buf_free_num = kfifo_len(&newframe_q);
+ states->buf_avail_num = kfifo_len(&display_q);
+ states->buf_recycle_num = kfifo_len(&recycle_q);
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ return 0;
+}
+#if 0
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+static void vreal_ppmgr_reset(void)
+{
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
+
+ vreal_local_init();
+
+ pr_info("vrealdec: vf_ppmgr_reset\n");
+}
+#endif
+#endif
+
+static void vreal_set_clk(struct work_struct *work)
+{
+ if (frame_dur > 0 &&
+ saved_resolution !=
+ frame_width * frame_height * (96000 / frame_dur)) {
+ int fps = 96000 / frame_dur;
+
+ saved_resolution = frame_width * frame_height * fps;
+ vdec_source_changed(VFORMAT_REAL,
+ frame_width, frame_height, fps);
+ }
+}
+
+static void vreal_put_timer_func(unsigned long arg)
+{
+ struct timer_list *timer = (struct timer_list *)arg;
+ /* unsigned int status; */
+
+#if 0
+ enum receviver_start_e state = RECEIVER_INACTIVE;
+
+ if (vf_get_receiver(PROVIDER_NAME)) {
+ state =
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_QUREY_STATE, NULL);
+ if ((state == RECEIVER_STATE_NULL)
+ || (state == RECEIVER_STATE_NONE)) {
+ /* receiver has no event_cb
+ *or receiver's event_cb does not process this event
+ */
+ state = RECEIVER_INACTIVE;
+ }
+ } else
+ state = RECEIVER_INACTIVE;
+
+ if ((READ_VREG(WAIT_BUFFER) != 0) &&
+ kfifo_is_empty(&display_q) &&
+ kfifo_is_empty(&recycle_q) && (state == RECEIVER_INACTIVE)) {
+ pr_info("$$$$$$decoder is waiting for buffer\n");
+ if (++wait_buffer_counter > 2) {
+ amvdec_stop();
+
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vreal_ppmgr_reset();
+#else
+ vf_light_unreg_provider(&vreal_vf_prov);
+ vreal_local_init();
+ vf_reg_provider(&vreal_vf_prov);
+#endif
+ vreal_prot_init();
+ amvdec_start();
+ }
+ }
+#endif
+
+ while (!kfifo_is_empty(&recycle_q) && (READ_VREG(TO_AMRISC) == 0)) {
+ struct vframe_s *vf;
+
+ if (kfifo_get(&recycle_q, &vf)) {
+ if ((vf->index < VF_BUF_NUM)
+ && (--vfbuf_use[vf->index] == 0)) {
+ WRITE_VREG(TO_AMRISC, ~(1 << vf->index));
+ vf->index = VF_BUF_NUM;
+ }
+
+ kfifo_put(&newframe_q, (const struct vframe_s *)vf);
+ }
+ }
+
+ schedule_work(&set_clk_work);
+
+ timer->expires = jiffies + PUT_INTERVAL;
+
+ add_timer(timer);
+}
+
+int vreal_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+ if (!(stat & STAT_VDEC_RUN))
+ return -1;
+
+ vstatus->frame_width = vreal_amstream_dec_info.width;
+ vstatus->frame_height = vreal_amstream_dec_info.height;
+ if (0 != vreal_amstream_dec_info.rate)
+ vstatus->frame_rate = 96000 / vreal_amstream_dec_info.rate;
+ else
+ vstatus->frame_rate = 96000;
+ vstatus->error_count = real_err_count;
+ vstatus->status =
+ ((READ_VREG(STATUS_AMRISC) << 16) | fatal_flag) | stat;
+ /* pr_info("vreal_dec_status 0x%x\n", vstatus->status); */
+ return 0;
+}
+
+int vreal_set_isreset(struct vdec_s *vdec, int isreset)
+{
+ is_reset = isreset;
+ return 0;
+}
+
+/****************************************/
+static int vreal_canvas_init(void)
+{
+ int i, ret;
+ unsigned long buf_start;
+ u32 canvas_width, canvas_height;
+ u32 alloc_size, decbuf_size, decbuf_y_size, decbuf_uv_size;
+
+ if (buf_size <= 0x00400000) {
+ /* SD only */
+ canvas_width = 768;
+ canvas_height = 576;
+ decbuf_y_size = 0x80000;
+ decbuf_uv_size = 0x20000;
+ decbuf_size = 0x100000;
+ } else {
+ /* HD & SD */
+ #if 1
+ int w = vreal_amstream_dec_info.width;
+ int h = vreal_amstream_dec_info.height;
+ int align_w, align_h;
+ int max, min;
+
+ align_w = ALIGN(w, 64);
+ align_h = ALIGN(h, 64);
+ if (align_w > align_h) {
+ max = align_w;
+ min = align_h;
+ } else {
+ canvas_width = 1920;
+ canvas_height = 1088;
+ max = align_h;
+ min = align_w;
+ }
+ /* HD & SD */
+ if ((max > 1920 || min > 1088) &&
+ ALIGN(align_w * align_h * 3/2, SZ_64K) * 9 <=
+ buf_size) {
+ canvas_width = align_w;
+ canvas_height = align_h;
+ decbuf_y_size = ALIGN(align_w * align_h, SZ_64K);
+ decbuf_uv_size = ALIGN(align_w * align_h/4, SZ_64K);
+ decbuf_size = ALIGN(align_w * align_h * 3/2, SZ_64K);
+ } else { /*1080p*/
+ if (h > w) {
+ canvas_width = 1088;
+ canvas_height = 1920;
+ } else {
+ canvas_width = 1920;
+ canvas_height = 1088;
+ }
+ decbuf_y_size = 0x200000;
+ decbuf_uv_size = 0x80000;
+ decbuf_size = 0x300000;
+ }
+ #endif
+ }
+
+ for (i = 0; i < MAX_BMMU_BUFFER_NUM; i++) {
+ /* workspace mem */
+ if (i == (MAX_BMMU_BUFFER_NUM - 1))
+ alloc_size = WORKSPACE_SIZE;
+ else
+ alloc_size = decbuf_size;
+
+ ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, i,
+ alloc_size, DRIVER_NAME, &buf_start);
+ if (ret < 0)
+ return ret;
+
+ if (i == (MAX_BMMU_BUFFER_NUM - 1)) {
+ buf_offset = buf_start - RV_AI_BUFF_START_IP;
+ continue;
+ }
+
+#ifdef NV21
+ canvas_config(2 * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(2 * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width,
+ canvas_height / 2, CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+#else
+ canvas_config(3 * i + 0,
+ buf_start,
+ canvas_width, canvas_height,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 1,
+ buf_start +
+ decbuf_y_size, canvas_width / 2,
+ canvas_height / 2, CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 2,
+ buf_start +
+ decbuf_y_size + decbuf_uv_size,
+ canvas_width / 2, canvas_height / 2,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+#endif
+ }
+
+ return 0;
+}
+
+static int vreal_prot_init(void)
+{
+ int r;
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+ WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+#else
+ WRITE_RESET_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC);
+#endif
+
+
+
+ r = vreal_canvas_init();
+
+ /* index v << 16 | u << 8 | y */
+#ifdef NV21
+ WRITE_VREG(AV_SCRATCH_0, 0x010100);
+ WRITE_VREG(AV_SCRATCH_1, 0x030302);
+ WRITE_VREG(AV_SCRATCH_2, 0x050504);
+ WRITE_VREG(AV_SCRATCH_3, 0x070706);
+#else
+ WRITE_VREG(AV_SCRATCH_0, 0x020100);
+ WRITE_VREG(AV_SCRATCH_1, 0x050403);
+ WRITE_VREG(AV_SCRATCH_2, 0x080706);
+ WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
+#endif
+
+ /* notify ucode the buffer offset */
+ WRITE_VREG(AV_SCRATCH_F, buf_offset);
+
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+ WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
+ WRITE_VREG(DOS_SW_RESET0, 0);
+#else
+ WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
+#endif
+
+ /* disable PSCALE for hardware sharing */
+ WRITE_VREG(PSCALE_CTRL, 0);
+
+ WRITE_VREG(FROM_AMRISC, 0);
+ WRITE_VREG(TO_AMRISC, 0);
+ WRITE_VREG(STATUS_AMRISC, 0);
+
+ WRITE_VREG(RV_PIC_INFO, 0);
+ WRITE_VREG(VPTS_TR, 0);
+ WRITE_VREG(VDTS, 0);
+ WRITE_VREG(SKIP_B_AMRISC, 0);
+
+ WRITE_VREG(MDEC_WIDTH, (frame_width + 15) & 0xfff0);
+ WRITE_VREG(MDEC_HEIGHT, (frame_height + 15) & 0xfff0);
+
+ /* clear mailbox interrupt */
+ WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
+
+ /* enable mailbox interrupt */
+ WRITE_VREG(ASSIST_MBOX1_MASK, 1);
+
+ /* clear wait buffer status */
+ WRITE_VREG(WAIT_BUFFER, 0);
+
+#ifdef NV21
+ SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
+#endif
+ return r;
+}
+
+static void vreal_local_init(void)
+{
+ int i;
+
+ /* vreal_ratio = vreal_amstream_dec_info.ratio; */
+ vreal_ratio = 0x100;
+
+ frame_prog = 0;
+
+ frame_width = vreal_amstream_dec_info.width;
+ frame_height = vreal_amstream_dec_info.height;
+ frame_dur = vreal_amstream_dec_info.rate;
+
+ for (i = 0; i < VF_BUF_NUM; i++)
+ vfbuf_use[i] = 0;
+
+ INIT_KFIFO(display_q);
+ INIT_KFIFO(recycle_q);
+ INIT_KFIFO(newframe_q);
+
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ const struct vframe_s *vf = &vfpool[i];
+ vfpool[i].index = VF_BUF_NUM;
+ kfifo_put(&newframe_q, vf);
+ }
+
+ if (mm_blk_handle) {
+ decoder_bmmu_box_free(mm_blk_handle);
+ mm_blk_handle = NULL;
+ }
+
+ mm_blk_handle = decoder_bmmu_box_alloc_box(
+ DRIVER_NAME,
+ 0,
+ MAX_BMMU_BUFFER_NUM,
+ 4 + PAGE_SHIFT,
+ CODEC_MM_FLAGS_CMA_CLEAR |
+ CODEC_MM_FLAGS_FOR_VDECODER);
+
+ decoder_state = 1;
+ hold = 0;
+ last_tr = -1;
+ wait_key_frame = 1;
+ frame_count = 0;
+ current_vdts = 0;
+ real_err_count = 0;
+
+ pic_sz_tbl_map = 0;
+ saved_resolution = 0;
+ fatal_flag = 0;
+ wait_buffer_counter = 0;
+}
+
+static void load_block_data(void *dest, unsigned int count)
+{
+ unsigned short *pdest = (unsigned short *)dest;
+ unsigned short src_tbl[12];
+ unsigned int i;
+
+ src_tbl[0] = RPR_size[vreal_amstream_dec_info.extra + 1];
+ memcpy((void *)&src_tbl[1], vreal_amstream_dec_info.param,
+ 2 << src_tbl[0]);
+
+#if 0
+ for (i = 0; i < 12; i++)
+ pr_info("src_tbl[%d]: 0x%x\n", i, src_tbl[i]);
+#endif
+
+ for (i = 0; i < count / 4; i++) {
+ pdest[i * 4] = src_tbl[i * 4 + 3];
+ pdest[i * 4 + 1] = src_tbl[i * 4 + 2];
+ pdest[i * 4 + 2] = src_tbl[i * 4 + 1];
+ pdest[i * 4 + 3] = src_tbl[i * 4];
+ }
+
+ pic_sz_tbl_map = dma_map_single(amports_get_dma_device(), &pic_sz_tbl,
+ sizeof(pic_sz_tbl), DMA_TO_DEVICE);
+
+}
+
+s32 vreal_init(struct vdec_s *vdec)
+{
+ int ret = -1, size = -1;
+ char fw_name[32] = {0};
+ char *buf = vmalloc(0x1000 * 16);
+
+ if (IS_ERR_OR_NULL(buf))
+ return -ENOMEM;
+
+ pr_info("vreal_init\n");
+
+ init_timer(&recycle_timer);
+
+ stat |= STAT_TIMER_INIT;
+
+ amvdec_enable();
+
+ vreal_local_init();
+
+ ret = rmparser_init(vdec);
+ if (ret) {
+ amvdec_disable();
+ vfree(buf);
+ pr_info("rm parser init failed\n");
+ return ret;
+ }
+
+ if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_8) {
+ if (vreal_amstream_dec_info.param == NULL) {
+ rmparser_release();
+ amvdec_disable();
+ vfree(buf);
+ return -1;
+ }
+ load_block_data((void *)pic_sz_tbl, 12);
+
+ /* TODO: need to load the table into lmem */
+ WRITE_VREG(LMEM_DMA_ADR, (unsigned int)pic_sz_tbl_map);
+ WRITE_VREG(LMEM_DMA_COUNT, 10);
+ WRITE_VREG(LMEM_DMA_CTRL, 0xc178 | (3 << 11));
+ while (READ_VREG(LMEM_DMA_CTRL) & 0x8000)
+ ;
+ size = get_firmware_data(VIDEO_DEC_REAL_V8, buf);
+ strncpy(fw_name, "vreal_mc_8", sizeof(fw_name));
+
+ pr_info("load VIDEO_DEC_FORMAT_REAL_8\n");
+ } else if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_9) {
+ size = get_firmware_data(VIDEO_DEC_REAL_V9, buf);
+ strncpy(fw_name, "vreal_mc_9", sizeof(fw_name));
+
+ pr_info("load VIDEO_DEC_FORMAT_REAL_9\n");
+ } else
+ pr_info("unsurpported real format\n");
+
+ if (size < 0) {
+ rmparser_release();
+ amvdec_disable();
+ pr_err("get firmware fail.");
+ vfree(buf);
+ return -1;
+ }
+
+ ret = amvdec_loadmc_ex(VFORMAT_REAL, fw_name, buf);
+ if (ret < 0) {
+ rmparser_release();
+ amvdec_disable();
+ vfree(buf);
+ pr_err("%s: the %s fw loading failed, err: %x\n",
+ fw_name, tee_enabled() ? "TEE" : "local", ret);
+ return -EBUSY;
+ }
+
+ vfree(buf);
+
+ stat |= STAT_MC_LOAD;
+
+ /* enable AMRISC side protocol */
+ ret = vreal_prot_init();
+ if (ret < 0) {
+ rmparser_release();
+ amvdec_disable();
+ return ret;
+ }
+ if (vdec_request_irq(VDEC_IRQ_1, vreal_isr,
+ "vreal-irq", (void *)vreal_dec_id)) {
+ rmparser_release();
+ amvdec_disable();
+
+ pr_info("vreal irq register error.\n");
+ return -ENOENT;
+ }
+
+ stat |= STAT_ISR_REG;
+#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
+ vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider,
+ NULL);
+ vf_reg_provider(&vreal_vf_prov);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
+#else
+ vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider,
+ NULL);
+ vf_reg_provider(&vreal_vf_prov);
+#endif
+
+ if (!is_reset)
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)((unsigned long)vreal_amstream_dec_info.rate));
+
+ stat |= STAT_VF_HOOK;
+
+ recycle_timer.data = (ulong)&recycle_timer;
+ recycle_timer.function = vreal_put_timer_func;
+ recycle_timer.expires = jiffies + PUT_INTERVAL;
+
+ add_timer(&recycle_timer);
+
+ stat |= STAT_TIMER_ARM;
+
+ amvdec_start();
+
+ stat |= STAT_VDEC_RUN;
+
+ pr_info("vreal init finished\n");
+
+ return 0;
+}
+
+void vreal_set_fatal_flag(int flag)
+{
+ if (flag)
+ fatal_flag = PARSER_FATAL_ERROR;
+}
+
+static int amvdec_real_probe(struct platform_device *pdev)
+{
+ struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+
+ if (pdata == NULL) {
+ pr_info("amvdec_real memory resource undefined.\n");
+ return -EFAULT;
+ }
+ if (pdata->sys_info)
+ vreal_amstream_dec_info = *pdata->sys_info;
+
+ pdata->dec_status = vreal_dec_status;
+ pdata->set_isreset = vreal_set_isreset;
+ is_reset = 0;
+
+ INIT_WORK(&set_clk_work, vreal_set_clk);
+ if (vreal_init(pdata) < 0) {
+ pr_info("amvdec_real init failed.\n");
+ pdata->dec_status = NULL;
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int amvdec_real_remove(struct platform_device *pdev)
+{
+ cancel_work_sync(&set_clk_work);
+ if (stat & STAT_VDEC_RUN) {
+ amvdec_stop();
+ stat &= ~STAT_VDEC_RUN;
+ }
+
+ if (stat & STAT_ISR_REG) {
+ vdec_free_irq(VDEC_IRQ_1, (void *)vreal_dec_id);
+ stat &= ~STAT_ISR_REG;
+ }
+
+ if (stat & STAT_TIMER_ARM) {
+ del_timer_sync(&recycle_timer);
+ stat &= ~STAT_TIMER_ARM;
+ }
+
+ if (stat & STAT_VF_HOOK) {
+ if (!is_reset)
+ vf_notify_receiver(PROVIDER_NAME,
+ VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
+
+ vf_unreg_provider(&vreal_vf_prov);
+ stat &= ~STAT_VF_HOOK;
+ }
+
+ if (pic_sz_tbl_map != 0) {
+ dma_unmap_single(NULL, pic_sz_tbl_map, sizeof(pic_sz_tbl),
+ DMA_TO_DEVICE);
+ }
+
+ rmparser_release();
+
+ vdec_source_changed(VFORMAT_REAL, 0, 0, 0);
+
+ amvdec_disable();
+
+ if (mm_blk_handle) {
+ decoder_bmmu_box_free(mm_blk_handle);
+ mm_blk_handle = NULL;
+ }
+ pr_info("frame duration %d, frames %d\n", frame_dur, frame_count);
+ return 0;
+}
+
+/****************************************/
+#ifdef CONFIG_PM
+static int real_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int real_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops real_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(real_suspend, real_resume)
+};
+#endif
+
+static struct platform_driver amvdec_real_driver = {
+ .probe = amvdec_real_probe,
+ .remove = amvdec_real_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &real_pm_ops,
+#endif
+ }
+};
+
+static struct codec_profile_t amvdec_real_profile = {
+ .name = "real",
+ .profile = "rmvb,1080p+"
+};
+static struct mconfig real_configs[] = {
+ MC_PU32("stat", &stat),
+};
+static struct mconfig_node real_node;
+
+static int __init amvdec_real_driver_init_module(void)
+{
+ pr_debug("amvdec_real module init\n");
+
+ if (platform_driver_register(&amvdec_real_driver)) {
+ pr_err("failed to register amvdec_real driver\n");
+ return -ENODEV;
+ }
+ vcodec_profile_register(&amvdec_real_profile);
+ INIT_REG_NODE_CONFIGS("media.decoder", &real_node,
+ "real", real_configs, CONFIG_FOR_R);
+ return 0;
+}
+
+static void __exit amvdec_real_driver_remove_module(void)
+{
+ pr_debug("amvdec_real module remove.\n");
+
+ platform_driver_unregister(&amvdec_real_driver);
+}
+
+/****************************************/
+
+module_init(amvdec_real_driver_init_module);
+module_exit(amvdec_real_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC REAL Video Decoder Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/frame_provider/decoder_v4l/vp9/vvp9.h b/drivers/frame_provider/decoder/real/vreal.h
similarity index 71%
rename from drivers/frame_provider/decoder_v4l/vp9/vvp9.h
rename to drivers/frame_provider/decoder/real/vreal.h
index 1db9d09..734cc6f 100644
--- a/drivers/frame_provider/decoder_v4l/vp9/vvp9.h
+++ b/drivers/frame_provider/decoder/real/vreal.h
@@ -1,5 +1,5 @@
/*
- * drivers/amlogic/amports/vvp9.h
+ * drivers/amlogic/amports/vreal.h
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
@@ -15,9 +15,12 @@
*
*/
-#ifndef VVP9_H
-#define VVP9_H
+#ifndef VREAL_H
+#define VREAL_H
-void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
-unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
+#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
+/* TODO: move to register headers */
+#define VPP_VD1_POSTBLEND (1 << 10)
#endif
+
+#endif /* VREAL_H */
diff --git a/drivers/frame_provider/decoder/utils/Makefile b/drivers/frame_provider/decoder/utils/Makefile
index 6f8540b..1e7552b 100644
--- a/drivers/frame_provider/decoder/utils/Makefile
+++ b/drivers/frame_provider/decoder/utils/Makefile
@@ -1,13 +1,10 @@
obj-m += decoder_common.o
decoder_common-objs += utils.o vdec.o vdec_input.o amvdec.o
decoder_common-objs += decoder_mmu_box.o decoder_bmmu_box.o
-decoder_common-objs += config_parser.o vdec_profile.o
+decoder_common-objs += config_parser.o secprot.o vdec_profile.o
decoder_common-objs += amstream_profile.o
decoder_common-objs += frame_check.o amlogic_fbc_hook.o
decoder_common-objs += vdec_v4l2_buffer_ops.o
decoder_common-objs += vdec_sync.o
decoder_common-objs += vdec_power_ctrl.o
-decoder_common-objs += vdec_canvas_utils.o
-decoder_common-objs += vdec_feature.o
-decoder_common-objs += vdec_ge2d_utils.o
diff --git a/drivers/frame_provider/decoder/utils/amstream_profile.c b/drivers/frame_provider/decoder/utils/amstream_profile.c
index 0e2b9c8..c8033ce 100644
--- a/drivers/frame_provider/decoder/utils/amstream_profile.c
+++ b/drivers/frame_provider/decoder/utils/amstream_profile.c
@@ -66,3 +66,5 @@
return ret;
}
EXPORT_SYMBOL(is_support_profile);
+
+
diff --git a/drivers/frame_provider/decoder/utils/amvdec.c b/drivers/frame_provider/decoder/utils/amvdec.c
index d525fe8..af36ef1 100644
--- a/drivers/frame_provider/decoder/utils/amvdec.c
+++ b/drivers/frame_provider/decoder/utils/amvdec.c
@@ -43,8 +43,7 @@
#include "amvdec.h"
#include <linux/amlogic/media/utils/amports_config.h>
#include "firmware.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include "../../../common/chips/decoder_cpu_ver_info.h"
#define MC_SIZE (4096 * 16)
@@ -485,16 +484,9 @@
} else
format = VIDEO_DEC_H264;
break;
- case VFORMAT_JPEG_ENC:
- format = VIDEO_ENC_JPEG;
- vdec = OPTEE_VDEC_HCDEC;
- break;
- case VFORMAT_H264_ENC:
- format = VIDEO_ENC_H264;
- vdec = OPTEE_VDEC_HCDEC;
- break;
+
default:
- pr_info("Unknow vdec format: %u\n", (u32)type);
+ pr_info("Unknow vdec format!\n");
break;
}
@@ -683,17 +675,13 @@
WRITE_VREG(HEVC_IMEM_DMA_ADR, mc_addr_map);
WRITE_VREG(HEVC_IMEM_DMA_COUNT, 0x1000);
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3))
- WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (0xf << 16)));
- else
- WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (0x7 << 16)));
+ WRITE_VREG(HEVC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
while (READ_VREG(HEVC_IMEM_DMA_CTRL) & 0x8000) {
if (time_before(jiffies, timeout))
schedule();
else {
- pr_err("hevc load mc error\n");
+ pr_err("vdec2 load mc error\n");
ret = -EBUSY;
break;
}
@@ -978,14 +966,6 @@
#ifdef CONFIG_PM
int amvdec_suspend(struct platform_device *dev, pm_message_t event)
{
- struct vdec_s *vdec = *(struct vdec_s **)dev->dev.platform_data;;
-
- if (vdec) {
- wait_event_interruptible_timeout(vdec->idle_wait,
- (vdec->status != VDEC_STATUS_ACTIVE),
- msecs_to_jiffies(100));
- }
-
amvdec_pg_enable(false);
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */
@@ -1020,14 +1000,6 @@
int amhevc_suspend(struct platform_device *dev, pm_message_t event)
{
- struct vdec_s *vdec = *(struct vdec_s **)dev->dev.platform_data;;
-
- if (vdec) {
- wait_event_interruptible_timeout(vdec->idle_wait,
- (vdec->status != VDEC_STATUS_ACTIVE),
- msecs_to_jiffies(100));
- }
-
if (has_hevc_vdec()) {
amhevc_pg_enable(false);
/*vdec_set_suspend_clk(1, 1);*//*DEBUG_TMP*/
@@ -1189,8 +1161,9 @@
module_init(amvdec_init);
module_exit(amvdec_exit);
-#endif
+
MODULE_DESCRIPTION("Amlogic Video Decoder Utility Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
+#endif
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
index 33a9e4b..461621b 100644
--- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
+++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.c
@@ -141,7 +141,7 @@
int memflags = mem_flags;
if (!box || idx < 0 || idx >= box->max_mm_num) {
- pr_err("can't alloc bmmu box(%p),idx:%d\n",
+ pr_err("can't alloc mmu box(%p),idx:%d\n",
box, idx);
return -1;
}
@@ -324,7 +324,7 @@
}
/*flags: &0x1 for wait,*/
-int decoder_bmmu_box_check_and_wait_size(int size, int flags, int mem_flags)
+int decoder_bmmu_box_check_and_wait_size(int size, int flags)
{
if ((flags & BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER) &&
codec_mm_get_free_size() < size) {
@@ -335,7 +335,7 @@
}
return codec_mm_enough_for_size(size,
- flags & BMMU_ALLOC_FLAGS_WAIT, mem_flags);
+ flags & BMMU_ALLOC_FLAGS_WAIT);
}
int decoder_bmmu_box_alloc_idx_wait(
@@ -361,8 +361,7 @@
}
have_space = decoder_bmmu_box_check_and_wait_size(
size,
- wait_flags,
- mem_flags);
+ wait_flags);
if (have_space) {
ret = decoder_bmmu_box_alloc_idx(handle,
idx, size, aligned_2n, mem_flags);
@@ -383,14 +382,9 @@
int size, unsigned char *driver_name,
unsigned long *buf_phy_addr)
{
- struct decoder_bmmu_box *bmmu_box = (struct decoder_bmmu_box *)handle;
-
- if (bmmu_box == NULL)
- return -EINVAL;
-
if (!decoder_bmmu_box_check_and_wait_size(
size,
- 1, bmmu_box->mem_flags)) {
+ 1)) {
pr_info("%s not enough buf for buf_idx = %d\n",
driver_name, idx);
return -ENOMEM;
@@ -400,8 +394,9 @@
idx,
size,
-1,
- bmmu_box->mem_flags,
- BMMU_ALLOC_FLAGS_WAITCLEAR)) {
+ -1,
+ BMMU_ALLOC_FLAGS_WAITCLEAR
+ )) {
*buf_phy_addr =
decoder_bmmu_box_get_phy_addr(
handle,
@@ -419,25 +414,6 @@
}
EXPORT_SYMBOL(decoder_bmmu_box_alloc_buf_phy);
-int decoder_bmmu_box_add_callback_func(
- void *handle, int idx,
- void *cb)
-{
- struct decoder_bmmu_box *box = handle;
- struct codec_mm_s *mm;
-
- if (!box || idx < 0 || idx >= box->max_mm_num)
- return 0;
-
- mutex_lock(&box->mutex);
- mm = box->mm_list[idx];
- codec_mm_add_release_callback(mm, (struct codec_mm_cb_s *)cb);
- mutex_unlock(&box->mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(decoder_bmmu_box_add_callback_func);
-
static int decoder_bmmu_box_dump(struct decoder_bmmu_box *box, void *buf,
int size)
{
@@ -446,7 +422,6 @@
int tsize = 0;
int s;
int i;
-
if (!buf) {
pbuf = sbuf;
size = 512;
@@ -491,7 +466,6 @@
int s;
int i;
struct list_head *head, *list;
-
if (!buf) {
pbuf = sbuf;
size = 512;
@@ -549,7 +523,7 @@
return ret;
}
-static ssize_t debug_show(struct class *class,
+static ssize_t box_debug_show(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -563,7 +537,8 @@
return size;
}
-static ssize_t debug_store(struct class *class,
+
+static ssize_t box_debug_store(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -584,21 +559,19 @@
}
-static CLASS_ATTR_RO(box_dump);
-static CLASS_ATTR_RW(debug);
-static struct attribute *decoder_bmmu_box_class_attrs[] = {
- &class_attr_box_dump.attr,
- &class_attr_debug.attr,
- NULL
+
+static struct class_attribute decoder_bmmu_box_class_attrs[] = {
+ __ATTR_RO(box_dump),
+ __ATTR(debug, S_IRUGO | S_IWUSR | S_IWGRP,
+ box_debug_show, box_debug_store),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(decoder_bmmu_box_class);
-
static struct class decoder_bmmu_box_class = {
- .name = "decoder_bmmu_box",
- .class_groups = decoder_bmmu_box_class_groups,
-};
+ .name = "decoder_bmmu_box",
+ .class_attrs = decoder_bmmu_box_class_attrs,
+ };
int decoder_bmmu_box_init(void)
{
diff --git a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
index 93974ec..778cb8e 100644
--- a/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
+++ b/drivers/frame_provider/decoder/utils/decoder_bmmu_box.h
@@ -41,17 +41,13 @@
/*flags: &0x1 for wait,*/
int decoder_bmmu_box_check_and_wait_size(
- int size, int flags, int mem_flags);
+ int size, int flags);
int decoder_bmmu_box_alloc_buf_phy(
void *handle, int idx,
int size, unsigned char *driver_name,
unsigned long *buf_phy_addr);
-int decoder_bmmu_box_add_callback_func(
- void *handle, int idx,
- void *cb);
-
#define BMMU_ALLOC_FLAGS_WAIT (1 << 0)
#define BMMU_ALLOC_FLAGS_CAN_CLEAR_KEEPER (1 << 1)
#define BMMU_ALLOC_FLAGS_WAITCLEAR \
diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c b/drivers/frame_provider/decoder/utils/decoder_mmu_box.c
index 57180dd..75862ec 100644
--- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.c
+++ b/drivers/frame_provider/decoder/utils/decoder_mmu_box.c
@@ -28,11 +28,13 @@
#include <linux/slab.h>
#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
#include <linux/platform_device.h>
+
struct decoder_mmu_box {
int max_sc_num;
const char *name;
int channel_id;
int tvp_mode;
+ int box_ref_cnt;
struct mutex mutex;
struct list_head list;
struct codec_mm_scatter *sc_list[1];
@@ -74,6 +76,51 @@
return 0;
}
+bool decoder_mmu_box_valide_check(void *box)
+{
+ struct decoder_mmu_box_mgr *mgr = get_decoder_mmu_box_mgr();
+ struct decoder_mmu_box *mmu_box = NULL;
+ bool is_valide = false;
+
+ mutex_lock(&mgr->mutex);
+ list_for_each_entry(mmu_box, &mgr->box_list, list) {
+ if (mmu_box && mmu_box == box) {
+ is_valide = true;
+ break;
+ }
+ }
+ mutex_unlock(&mgr->mutex);
+
+ return is_valide;
+}
+EXPORT_SYMBOL(decoder_mmu_box_valide_check);
+
+void decoder_mmu_try_to_release_box(void *handle)
+{
+ struct decoder_mmu_box *box = handle;
+ bool is_keep = false;
+ int i;
+
+ if (!box || box->box_ref_cnt)
+ return;
+
+ mutex_lock(&box->mutex);
+ for (i = 0; i < box->max_sc_num; i++) {
+ if (box->sc_list[i]) {
+ is_keep = true;
+ break;
+ }
+ }
+ mutex_unlock(&box->mutex);
+
+ if (!is_keep) {
+ decoder_mmu_box_mgr_del_box(box);
+ codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode);
+ kfree(box);
+ }
+}
+EXPORT_SYMBOL(decoder_mmu_try_to_release_box);
+
int decoder_mmu_box_sc_check(void *handle, int is_tvp)
{
struct decoder_mmu_box *box = handle;
@@ -115,7 +162,7 @@
mutex_init(&box->mutex);
INIT_LIST_HEAD(&box->list);
decoder_mmu_box_mgr_add_box(box);
- codec_mm_scatter_mgt_delay_free_switch(1, 2000,
+ codec_mm_scatter_mgt_delay_free_swith(1, 2000,
min_size_M, box->tvp_mode);
return (void *)box;
}
@@ -142,6 +189,7 @@
ret = codec_mm_scatter_alloc_want_pages(sc,
num_pages);
else {
+ box->box_ref_cnt--;
codec_mm_scatter_dec_owner_user(sc, 0);
box->sc_list[idx] = NULL;
sc = NULL;
@@ -158,6 +206,7 @@
return -1;
}
box->sc_list[idx] = sc;
+ box->box_ref_cnt++;
}
for (i = 0; i < num_pages; i++)
@@ -203,16 +252,18 @@
box ? (box->max_sc_num - 1) : 0);
return -1;
}
-
mutex_lock(&box->mutex);
sc = box->sc_list[idx];
if (sc && sc->page_cnt > 0) {
codec_mm_scatter_dec_owner_user(sc, 0);
box->sc_list[idx] = NULL;
+ box->box_ref_cnt--;
}
-
mutex_unlock(&box->mutex);
+ if (sc && box->box_ref_cnt == 0)
+ codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode);
+
return 0;
}
EXPORT_SYMBOL(decoder_mmu_box_free_idx);
@@ -227,24 +278,18 @@
pr_err("can't free box of NULL box!\n");
return -1;
}
-
mutex_lock(&box->mutex);
for (i = 0; i < box->max_sc_num; i++) {
sc = box->sc_list[i];
if (sc) {
codec_mm_scatter_dec_owner_user(sc, 0);
box->sc_list[i] = NULL;
-
}
}
-
- codec_mm_scatter_mgt_delay_free_switch(0, 0, 0, box->tvp_mode);
-
mutex_unlock(&box->mutex);
-
decoder_mmu_box_mgr_del_box(box);
+ codec_mm_scatter_mgt_delay_free_swith(0, 0, 0, box->tvp_mode);
kfree(box);
-
return 0;
}
EXPORT_SYMBOL(decoder_mmu_box_free);
@@ -366,18 +411,16 @@
return ret;
}
-static CLASS_ATTR_RO(box_dump);
-static struct attribute *decoder_mmu_box_class_attrs[] = {
- &class_attr_box_dump.attr,
- NULL
+
+static struct class_attribute decoder_mmu_box_class_attrs[] = {
+ __ATTR_RO(box_dump),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(decoder_mmu_box_class);
-
static struct class decoder_mmu_box_class = {
.name = "decoder_mmu_box",
- .class_groups = decoder_mmu_box_class_groups,
+ .class_attrs = decoder_mmu_box_class_attrs,
};
int decoder_mmu_box_init(void)
diff --git a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h b/drivers/frame_provider/decoder/utils/decoder_mmu_box.h
index 13b3dd9..029f91a 100644
--- a/drivers/frame_provider/decoder/utils/decoder_mmu_box.h
+++ b/drivers/frame_provider/decoder/utils/decoder_mmu_box.h
@@ -40,13 +40,11 @@
int decoder_mmu_box_move_keep_idx(void *box_handle,
int keep_idx);
int decoder_mmu_box_free_keep(int keep_id);
-
int decoder_mmu_box_free_all_keep(void);
-
void *decoder_mmu_box_get_mem_handle(void *box_handle, int idx);
-
+bool decoder_mmu_box_valide_check(void *box);
+void decoder_mmu_try_to_release_box(void *handle);
int decoder_mmu_box_init(void);
-
void decoder_mmu_box_exit(void);
#endif
diff --git a/drivers/frame_provider/decoder/utils/firmware.h b/drivers/frame_provider/decoder/utils/firmware.h
index cd48036..c799fd0 100644
--- a/drivers/frame_provider/decoder/utils/firmware.h
+++ b/drivers/frame_provider/decoder/utils/firmware.h
@@ -22,9 +22,6 @@
#include "../../../common/firmware/firmware_type.h"
#include <linux/amlogic/media/utils/vformat.h>
-#if defined(CONFIG_AMLOGIC_TEE) || defined(CONFIG_AMLOGIC_TEE_MODULE)
-#include <linux/amlogic/tee.h>
-#endif
#define FW_LOAD_FORCE (0x1)
#define FW_LOAD_TRY (0X2)
@@ -41,16 +38,4 @@
extern int get_firmware_data(unsigned int foramt, char *buf);
extern int video_fw_reload(int mode);
-#if !defined(CONFIG_AMLOGIC_TEE) && !defined(CONFIG_AMLOGIC_TEE_MODULE)
-static inline bool tee_enabled(void) { return false; }
-static inline int tee_load_video_fw_swap(u32 index, u32 vdec, bool is_swap)
-{
- return -1;
-}
-static inline int tee_load_video_fw(u32 index, u32 vdec)
-{
- return -1;
-}
-#endif
-
#endif
diff --git a/drivers/frame_provider/decoder/utils/frame_check.c b/drivers/frame_provider/decoder/utils/frame_check.c
index 0600f8e..4cd80c0 100644
--- a/drivers/frame_provider/decoder/utils/frame_check.c
+++ b/drivers/frame_provider/decoder/utils/frame_check.c
@@ -25,8 +25,9 @@
#include <linux/timer.h>
#include <linux/kfifo.h>
#include <linux/kthread.h>
-#include <linux/vmalloc.h>
#include <linux/platform_device.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/dma-mapping.h>
@@ -71,7 +72,7 @@
#define dbg_print(mask, ...) do { \
if ((fc_debug & mask) || \
(mask == FC_ERROR)) \
- printk("[FRAME_CHECK] "__VA_ARGS__);\
+ printk("[FRMAE_CHECK] "__VA_ARGS__);\
} while(0)
@@ -166,18 +167,6 @@
return false;
}
-unsigned long vdec_cav_get_addr(int index);
-unsigned int vdec_cav_get_width(int index);
-unsigned int vdec_cav_get_height(int index);
-#define canvas_0(v) ((v) & 0xff)
-#define canvas_1(v) (((v) >> 8) & 0xff)
-#define canvas_2(v) (((v) >> 16) & 0xff)
-#define canvas_3(v) (((v) >> 24) & 0xff)
-
-#define canvasY(v) canvas_0(v)
-#define canvasU(v) canvas_1(v)
-#define canvasV(v) canvas_2(v)
-#define canvasUV(v) canvas_1(v)
static int get_frame_size(struct pic_check_mgr_t *pic,
struct vframe_s *vf)
@@ -199,10 +188,10 @@
if ((vf->canvas0Addr == vf->canvas1Addr) &&
(vf->canvas0Addr != 0) &&
(vf->canvas0Addr != -1)) {
- pic->canvas_w = vdec_cav_get_width(canvasY(vf->canvas0Addr));
- //canvas_get_width(canvasY(vf->canvas0Addr));
- pic->canvas_h = vdec_cav_get_height(canvasY(vf->canvas0Addr));
- //canvas_get_height(canvasY(vf->canvas0Addr));
+ pic->canvas_w =
+ canvas_get_width(canvasY(vf->canvas0Addr));
+ pic->canvas_h =
+ canvas_get_height(canvasY(vf->canvas0Addr));
} else {
pic->canvas_w = vf->canvas0_config[0].width;
pic->canvas_h = vf->canvas0_config[0].height;
@@ -232,8 +221,8 @@
if ((vf->canvas0Addr == vf->canvas1Addr) &&
(vf->canvas0Addr != 0) &&
(vf->canvas0Addr != -1)) {
- phy_y_addr = vdec_cav_get_addr(canvasY(vf->canvas0Addr)); //canvas_get_addr(canvasY(vf->canvas0Addr));
- phy_uv_addr = vdec_cav_get_addr(canvasUV(vf->canvas0Addr)); //canvas_get_addr(canvasUV(vf->canvas0Addr));
+ phy_y_addr = canvas_get_addr(canvasY(vf->canvas0Addr));
+ phy_uv_addr = canvas_get_addr(canvasU(vf->canvas0Addr));
} else {
phy_y_addr = vf->canvas0_config[0].phy_addr;
phy_uv_addr = vf->canvas0_config[1].phy_addr;
@@ -437,14 +426,10 @@
static int write_crc_work(struct pic_check_mgr_t *mgr)
{
unsigned int wr_size;
- char *crc_buf, *crc_tmp = NULL;
+ char *crc_buf, crc_tmp[64*30];
mm_segment_t old_fs;
struct pic_check_t *check = &mgr->pic_check;
- crc_tmp = (char *)vzalloc(64 * 30);
- if (!crc_tmp)
- return -1;
-
if (mgr->enable & CRC_MASK) {
wr_size = 0;
while (kfifo_get(&check->wr_chk_q, &crc_buf) != 0) {
@@ -468,11 +453,10 @@
set_fs(old_fs);
}
}
-
- vfree(crc_tmp);
return 0;
}
+
static int write_aux_data_crc_work(struct aux_data_check_mgr_t *mgr)
{
unsigned int wr_size;
@@ -506,6 +490,8 @@
return 0;
}
+
+
static void do_check_work(struct work_struct *work)
{
struct pic_check_mgr_t *mgr = container_of(work,
@@ -1123,10 +1109,6 @@
single_mode_vdec = NULL;
}
- if (!single_mode_vdec &&
- unlikely(in_interrupt()))
- return 0;
-
if ((mgr == NULL) || (vf == NULL) ||
(mgr->enable == 0))
return 0;
@@ -1149,8 +1131,7 @@
resize = 0;
mgr->last_size_pic = mgr->size_pic;
- if ((vf->type & VIDTYPE_VIU_NV21) || (mgr->mjpeg_flag) ||
- (vf->type & VIDTYPE_VIU_NV12)) {
+ if ((vf->type & VIDTYPE_VIU_NV21) || (mgr->mjpeg_flag)) {
int flush_size;
if (canvas_get_virt_addr(mgr, vf) < 0)
diff --git a/drivers/frame_provider/decoder/utils/secprot.c b/drivers/frame_provider/decoder/utils/secprot.c
new file mode 100644
index 0000000..a1e7fa7
--- /dev/null
+++ b/drivers/frame_provider/decoder/utils/secprot.c
@@ -0,0 +1,75 @@
+/*
+ * drivers/amlogic/amports/arch/secprot.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <asm/compiler.h>
+#include "secprot.h"
+#ifndef CONFIG_ARM64
+#include <asm/opcodes-sec.h>
+#endif
+
+#ifdef CONFIG_ARM64
+
+int tee_config_device_secure(int dev_id, int secure)
+{
+ int ret = 0;
+ register unsigned x0 asm("x0");
+ register unsigned x1 asm("x1");
+ register unsigned x2 asm("x2");
+
+ x0 = OPTEE_SMC_CONFIG_DEVICE_SECURE;
+ x1 = dev_id;
+ x2 = secure;
+
+ asm volatile(
+ __asmeq("%0", "x0")
+ __asmeq("%1", "x0")
+ __asmeq("%2", "x1")
+ __asmeq("%3", "x2")
+ "smc #0\n"
+ : "=r"(x0)
+ : "r"(x0), "r"(x1), "r"(x2));
+ ret = x0;
+
+ return ret;
+}
+#else
+int tee_config_device_secure(int dev_id, int secure)
+{
+ int ret = 0;
+ register unsigned int r0 asm("r0");
+ register unsigned int r1 asm("r1");
+ register unsigned int r2 asm("r2");
+
+ r0 = OPTEE_SMC_CONFIG_DEVICE_SECURE;
+ r1 = dev_id;
+ r2 = secure;
+
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r1")
+ __asmeq("%3", "r2")
+ __SMC(0)
+ : "=r"(r0)
+ : "r"(r0), "r"(r1), "r"(r2));
+ ret = r0;
+
+ return ret;
+}
+#endif
+
diff --git a/drivers/frame_provider/decoder/utils/secprot.h b/drivers/frame_provider/decoder/utils/secprot.h
new file mode 100644
index 0000000..28ee477
--- /dev/null
+++ b/drivers/frame_provider/decoder/utils/secprot.h
@@ -0,0 +1,39 @@
+/*
+ * drivers/amlogic/amports/arch/secprot.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+*/
+
+#ifndef __SECPROT_H_
+#define __SECPROT_H_
+
+#define DMC_DEV_TYPE_NON_SECURE 0
+#define DMC_DEV_TYPE_SECURE 1
+
+#define DMC_DEV_ID_GPU 1
+#define DMC_DEV_ID_HEVC 4
+#define DMC_DEV_ID_PARSER 7
+#define DMC_DEV_ID_VPU 8
+#define DMC_DEV_ID_VDEC 13
+#define DMC_DEV_ID_HCODEC 14
+#define DMC_DEV_ID_GE2D 15
+
+#define OPTEE_SMC_CONFIG_DEVICE_SECURE 0xb200000e
+
+/*#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"*/
+
+extern int tee_config_device_secure(int dev_id, int secure);
+
+#endif /* __SECPROT_H_ */
+
diff --git a/drivers/frame_provider/decoder/utils/utils.c b/drivers/frame_provider/decoder/utils/utils.c
index 0372a18..44b1626 100644
--- a/drivers/frame_provider/decoder/utils/utils.c
+++ b/drivers/frame_provider/decoder/utils/utils.c
@@ -69,6 +69,5 @@
module_init(decoder_common_init);
module_exit(decoder_common_exit);
-
MODULE_DESCRIPTION("AMLOGIC decoder_common driver");
-MODULE_LICENSE("GPL");
\ No newline at end of file
+MODULE_LICENSE("GPL");
diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c
index 98f0e3c..69ec60c 100644
--- a/drivers/frame_provider/decoder/utils/vdec.c
+++ b/drivers/frame_provider/decoder/utils/vdec.c
@@ -37,11 +37,9 @@
#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
#endif
#include <linux/amlogic/media/vfm/vfm_ext.h>
-#include <linux/sched/clock.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/signal.h>
/*for VDEC_DEBUG_SUPPORT*/
#include <linux/time.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../stream_input/amports/streambuf.h"
#include "vdec.h"
@@ -49,7 +47,6 @@
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
#include "vdec_profile.h"
#endif
-#include <linux/sched/clock.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/libfdt_env.h>
@@ -68,27 +65,21 @@
#include "../../../common/media_clock/clk/clk.h"
#include <linux/reset.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/video_sink/video_keeper.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
+#include "secprot.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "frame_check.h"
-#include <linux/amlogic/tee.h>
-#include "vdec_canvas_utils.h"
-#include "../../../amvdec_ports/aml_vcodec_drv.h"
-
#ifdef CONFIG_AMLOGIC_POWER
#include <linux/amlogic/power_ctrl.h>
#endif
-#ifdef CONFIG_AMLOGIC_IONVIDEO
-#include <linux/amlogic/media/video_sink/ionvideo_ext.h>
-#endif
-//#include <dt-bindings/power/sc2-pd.h>
-//#include <linux/amlogic/pwr_ctrl.h>
+#include <dt-bindings/power/sc2-pd.h>
+#include <linux/amlogic/pwr_ctrl.h>
#include <linux/of_device.h>
#include "vdec_power_ctrl.h"
@@ -105,12 +96,10 @@
static unsigned int debug_trace_num = 16 * 20;
static int step_mode;
static unsigned int clk_config;
-/*
-0x1 : enable rdma
-0x2 : check rdma result
-*/
-static int rdma_mode = 0x1;
-
+#ifdef VDEC_FCC_SUPPORT
+static int fcc_debug;
+static void vdec_fcc_jump_back(struct vdec_s *vdec);
+#endif
/*
* 0x1 : sched_priority to MAX_RT_PRIO -1.
* 0x2 : always reload firmware.
@@ -122,36 +111,23 @@
#define VDEC_DBG_CANVAS_STATUS (0x4)
#define VDEC_DBG_ENABLE_FENCE (0x100)
+#define FRAME_BASE_PATH_DI_V4LVIDEO_0 (29)
+#define FRAME_BASE_PATH_DI_V4LVIDEO_1 (30)
+#define FRAME_BASE_PATH_DI_V4LVIDEO_2 (31)
-#define HEVC_RDMA_F_CTRL 0x30f0
-#define HEVC_RDMA_F_START_ADDR 0x30f1
-#define HEVC_RDMA_F_END_ADDR 0x30f2
-#define HEVC_RDMA_F_STATUS0 0x30f3
-
-#define HEVC_RDMA_B_CTRL 0x30f8
-#define HEVC_RDMA_B_START_ADDR 0x30f9
-#define HEVC_RDMA_B_END_ADDR 0x30fa
-#define HEVC_RDMA_B_STATUS0 0x30fb
-
-
-static u32 debug = VDEC_DBG_ALWAYS_LOAD_FW;
-
-u32 vdec_get_debug(void)
-{
- return debug;
-}
-EXPORT_SYMBOL(vdec_get_debug);
-
+u32 debug = VDEC_DBG_ALWAYS_LOAD_FW;
+EXPORT_SYMBOL(debug);
int hevc_max_reset_count;
EXPORT_SYMBOL(hevc_max_reset_count);
int no_powerdown;
EXPORT_SYMBOL(no_powerdown);
+
static int parallel_decode = 1;
static int fps_detection;
static int fps_clear;
-static bool prog_only;
+
static int force_nosecure_even_drm;
static int disable_switch_single_to_mult;
@@ -167,12 +143,8 @@
#define RESET7_REGISTER_LEVEL 0x1127
#define P_RESETCTRL_RESET5_LEVEL 0x15
-#define str(a) #a
-#define xstr(a) str(a)
-
static int frameinfo_flag = 0;
static int v4lvideo_add_di = 1;
-static int v4lvideo_add_ppmgr = 0;
static int max_di_instance = 2;
static int max_supported_di_instance = 4;
@@ -181,39 +153,12 @@
static int enable_mvdec_info = 1;
int decode_underflow = 0;
-u32 debug_meta;
static int enable_stream_mode_multi_dec;
-st_userdata userdata;
+#define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1)
-typedef void (*vdec_frame_rate_event_func)(int);
-
-#if 1
extern void vframe_rate_uevent(int duration);
-vdec_frame_rate_event_func frame_rate_notify = vframe_rate_uevent;
-#else
-vdec_frame_rate_event_func frame_rate_notify = NULL;
-#endif
-
-void vdec_frame_rate_uevent(int dur)
-{
- if (frame_rate_notify == NULL)
- return;
-
- if (unlikely(in_interrupt()))
- return;
- pr_info("vdec_frame_rate_uevent %d\n", dur);
- frame_rate_notify(dur);
-}
-EXPORT_SYMBOL(vdec_frame_rate_uevent);
-
-
-void register_frame_rate_uevent_func(vdec_frame_rate_event_func func)
-{
- frame_rate_notify = func;
-}
-EXPORT_SYMBOL(register_frame_rate_uevent_func);
struct am_reg {
char *name;
@@ -266,9 +211,15 @@
unsigned long stream_buff_flag;
struct power_manager_s *pm;
u32 vdec_resouce_status;
- struct post_task_mgr_s post;
};
+struct canvas_status_s {
+ int type;
+ int canvas_used_flag;
+ int id;
+};
+
+
static struct vdec_core_s *vdec_core;
static const char * const vdec_status_string[] = {
@@ -278,7 +229,6 @@
"VDEC_STATUS_ACTIVE"
};
/*
-bit [29] enable steam mode dv multi;
bit [28] enable print
bit [23:16] etc
bit [15:12]
@@ -336,6 +286,9 @@
"reserved",
};
+static struct canvas_status_s canvas_stat[AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1];
+
+
int vdec_get_debug_flags(void)
{
return debugflags;
@@ -349,6 +302,15 @@
}
EXPORT_SYMBOL(VDEC_PRINT_FUN_LINENO);
+bool is_support_no_parser(void)
+{
+ if ((enable_stream_mode_multi_dec) ||
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2))
+ return true;
+ return false;
+}
+EXPORT_SYMBOL(is_support_no_parser);
+
unsigned char is_mult_inc(unsigned int type)
{
unsigned char ret = 0;
@@ -361,16 +323,6 @@
}
EXPORT_SYMBOL(is_mult_inc);
-bool is_support_no_parser(void)
-{
- if ((enable_stream_mode_multi_dec) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_SC2) ||
- (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7))
- return true;
- return false;
-}
-EXPORT_SYMBOL(is_support_no_parser);
-
static const bool cores_with_input[VDEC_MAX] = {
true, /* VDEC_1 */
false, /* VDEC_HCODEC */
@@ -387,17 +339,17 @@
VDEC_IRQ_HEVC_BACK
};
-unsigned long vdec_canvas_lock(void)
+unsigned long vdec_canvas_lock(struct vdec_core_s *core)
{
unsigned long flags;
- spin_lock_irqsave(&vdec_core->canvas_lock, flags);
+ spin_lock_irqsave(&core->canvas_lock, flags);
return flags;
}
-void vdec_canvas_unlock(unsigned long flags)
+void vdec_canvas_unlock(struct vdec_core_s *core, unsigned long flags)
{
- spin_unlock_irqrestore(&vdec_core->canvas_lock, flags);
+ spin_unlock_irqrestore(&core->canvas_lock, flags);
}
unsigned long vdec_fps_lock(struct vdec_core_s *core)
@@ -463,9 +415,14 @@
up(&core->sem);
}
+
static u64 vdec_get_us_time_system(void)
{
- return div64_u64(local_clock(), 1000);
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+
+ return div64_u64(timeval_to_ns(&tv), 1000);
}
static void vdec_fps_clear(int id)
@@ -526,6 +483,130 @@
vdec_fps_unlock(vdec_core, flags);
}
+
+
+static int get_canvas(unsigned int index, unsigned int base)
+{
+ int start;
+ int canvas_index = index * base;
+ int ret;
+
+ if ((base > 4) || (base == 0))
+ return -1;
+
+ if ((AMVDEC_CANVAS_START_INDEX + canvas_index + base - 1)
+ <= AMVDEC_CANVAS_MAX1) {
+ start = AMVDEC_CANVAS_START_INDEX + base * index;
+ } else {
+ canvas_index -= (AMVDEC_CANVAS_MAX1 -
+ AMVDEC_CANVAS_START_INDEX + 1) / base * base;
+ if (canvas_index <= AMVDEC_CANVAS_MAX2)
+ start = canvas_index / base;
+ else
+ return -1;
+ }
+
+ if (base == 1) {
+ ret = start;
+ } else if (base == 2) {
+ ret = ((start + 1) << 16) | ((start + 1) << 8) | start;
+ } else if (base == 3) {
+ ret = ((start + 2) << 16) | ((start + 1) << 8) | start;
+ } else if (base == 4) {
+ ret = (((start + 3) << 24) | (start + 2) << 16) |
+ ((start + 1) << 8) | start;
+ }
+
+ return ret;
+}
+
+static int get_canvas_ex(int type, int id)
+{
+ int i;
+ unsigned long flags;
+
+ flags = vdec_canvas_lock(vdec_core);
+
+ for (i = 0; i < CANVAS_MAX_SIZE; i++) {
+ if ((canvas_stat[i].type == type) &&
+ (canvas_stat[i].id & (1 << id)) == 0) {
+ canvas_stat[i].canvas_used_flag++;
+ canvas_stat[i].id |= (1 << id);
+ if (debug & 4)
+ pr_debug("get used canvas %d\n", i);
+ vdec_canvas_unlock(vdec_core, flags);
+ if (i < AMVDEC_CANVAS_MAX2 + 1)
+ return i;
+ else
+ return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
+ }
+ }
+
+ for (i = 0; i < CANVAS_MAX_SIZE; i++) {
+ if (canvas_stat[i].type == 0) {
+ canvas_stat[i].type = type;
+ canvas_stat[i].canvas_used_flag = 1;
+ canvas_stat[i].id = (1 << id);
+ if (debug & 4) {
+ pr_debug("get canvas %d\n", i);
+ pr_debug("canvas_used_flag %d\n",
+ canvas_stat[i].canvas_used_flag);
+ pr_debug("canvas_stat[i].id %d\n",
+ canvas_stat[i].id);
+ }
+ vdec_canvas_unlock(vdec_core, flags);
+ if (i < AMVDEC_CANVAS_MAX2 + 1)
+ return i;
+ else
+ return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
+ }
+ }
+ vdec_canvas_unlock(vdec_core, flags);
+
+ pr_info("cannot get canvas\n");
+
+ return -1;
+}
+
+static void free_canvas_ex(int index, int id)
+{
+ unsigned long flags;
+ int offset;
+
+ flags = vdec_canvas_lock(vdec_core);
+ if (index >= 0 &&
+ index < AMVDEC_CANVAS_MAX2 + 1)
+ offset = index;
+ else if ((index >= AMVDEC_CANVAS_START_INDEX) &&
+ (index <= AMVDEC_CANVAS_MAX1))
+ offset = index + AMVDEC_CANVAS_MAX2 + 1 - AMVDEC_CANVAS_START_INDEX;
+ else {
+ vdec_canvas_unlock(vdec_core, flags);
+ return;
+ }
+
+ if ((canvas_stat[offset].canvas_used_flag > 0) &&
+ (canvas_stat[offset].id & (1 << id))) {
+ canvas_stat[offset].canvas_used_flag--;
+ canvas_stat[offset].id &= ~(1 << id);
+ if (canvas_stat[offset].canvas_used_flag == 0) {
+ canvas_stat[offset].type = 0;
+ canvas_stat[offset].id = 0;
+ }
+ if (debug & 4) {
+ pr_debug("free index %d used_flag %d, type = %d, id = %d\n",
+ offset,
+ canvas_stat[offset].canvas_used_flag,
+ canvas_stat[offset].type,
+ canvas_stat[offset].id);
+ }
+ }
+ vdec_canvas_unlock(vdec_core, flags);
+
+ return;
+
+}
+
static void vdec_dmc_pipeline_reset(void)
{
/*
@@ -576,143 +657,42 @@
}
}
-#define VDEC_ASSIST_DBUS_DISABLE 0x0046
-#define HEVC_ASSIST_AXI_STATUS2_LO 0x307f
-
-static void vdec_dbus_ctrl(bool enable)
-{
- if (enable) {
- WRITE_VREG(VDEC_ASSIST_DBUS_DISABLE, 0);
- } else {
- u32 nop_cnt = 200;
- WRITE_VREG(VDEC_ASSIST_DBUS_DISABLE, 0xffff);
- while (READ_VREG(VDEC_ASSIST_DBUS_DISABLE) != 0xffff);
- while (nop_cnt--);
- }
-}
-
-static void hevc_arb_ctrl(bool enable)
-{
- u32 axi_ctrl, axi_status, nop_cnt = 200;
-
- if (enable) {
- axi_ctrl = READ_VREG(HEVC_ASSIST_AXI_CTRL);
- axi_ctrl &= (~((1 << 6) | (1 << 14)));
- WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); //enable front/back arbitor
- } else {
- axi_ctrl = READ_VREG(HEVC_ASSIST_AXI_CTRL);
- axi_ctrl |= (1 << 6);
- WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); // disable front arbitor
-
- do {
- axi_status = READ_VREG(HEVC_ASSIST_AXI_STATUS);
- if (axi_status & ((1 << 15) | (1 << 11))) //read/write disable
- break;
- } while (1);
-
- axi_ctrl |= (1 << 14);
- WRITE_VREG(HEVC_ASSIST_AXI_CTRL, axi_ctrl); // disable back arbitor
-
- do {
- axi_status = READ_VREG(HEVC_ASSIST_AXI_STATUS2_LO);
- if (axi_status & ((1 << 15) | (1 << 11))) //read/write disable
- break;
- } while (1);
-
- while (nop_cnt--);
- }
-}
-
-static void dec_dmc_port_ctrl(bool dmc_on, u32 target)
-{
- unsigned long flags;
- unsigned int sts_reg_addr = DMC_CHAN_STS;
- unsigned int mask = 0;
- unsigned int cpu_type = get_cpu_major_id();
-
- if (target == VDEC_INPUT_TARGET_VLD) {
- mask = (1 << 13); /*bit13: DOS VDEC interface*/
- if (cpu_type >= AM_MESON_CPU_MAJOR_ID_G12A)
- mask = (1 << 21);
- } else if (target == VDEC_INPUT_TARGET_HEVC) {
- mask = (1 << 4); /*hevc*/
- if (cpu_type >= AM_MESON_CPU_MAJOR_ID_G12A)
- mask |= (1 << 8); /*hevcb */
- }
-
- if (!mask) {
- pr_info("debug dmc ctrl return\n");
- return;
- }
-
- if (dmc_on) {
- /* dmc async on requset */
- spin_lock_irqsave(&vdec_spin_lock, flags);
-
- codec_dmcbus_write(DMC_REQ_CTRL,
- codec_dmcbus_read(DMC_REQ_CTRL) | mask);
-
- spin_unlock_irqrestore(&vdec_spin_lock, flags);
- } else {
- /* dmc async off requset */
- spin_lock_irqsave(&vdec_spin_lock, flags);
-
- codec_dmcbus_write(DMC_REQ_CTRL,
- codec_dmcbus_read(DMC_REQ_CTRL) & ~mask);
-
- spin_unlock_irqrestore(&vdec_spin_lock, flags);
-
- switch (cpu_type) {
- case AM_MESON_CPU_MAJOR_ID_S4:
- case AM_MESON_CPU_MAJOR_ID_S4D:
- case AM_MESON_CPU_MAJOR_ID_T5W:
- sts_reg_addr = S4_DMC_CHAN_STS;
- break;
- case AM_MESON_CPU_MAJOR_ID_T5:
- case AM_MESON_CPU_MAJOR_ID_T5D:
- sts_reg_addr = T5_DMC_CHAN_STS;
- break;
- case AM_MESON_CPU_MAJOR_ID_SC2:
- sts_reg_addr = TM2_REVB_DMC_CHAN_STS;
- break;
- case AM_MESON_CPU_MAJOR_ID_TM2:
- if (is_cpu_meson_revb())
- sts_reg_addr = TM2_REVB_DMC_CHAN_STS;
- else
- sts_reg_addr = DMC_CHAN_STS;
- break;
- default:
- sts_reg_addr = DMC_CHAN_STS;
- break;
- }
- while (!(codec_dmcbus_read(sts_reg_addr)
- & mask))
- ;
- }
-}
-
static void vdec_disable_DMC(struct vdec_s *vdec)
{
/*close first,then wait pedding end,timing suggestion from vlsi*/
struct vdec_input_s *input = &vdec->input;
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ if (input->target == VDEC_INPUT_TARGET_VLD) {
+ mask = (1 << 13);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask = (1 << 21);
+ } else if (input->target == VDEC_INPUT_TARGET_HEVC) {
+ mask = (1 << 4); /*hevc*/
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask |= (1 << 8); /*hevcb */
+ }
/* need to stop armrisc. */
if (!IS_ERR_OR_NULL(vdec->dev))
vdec_stop_armrisc(input->target);
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) {
- if (input->target == VDEC_INPUT_TARGET_VLD) {
- if (!vdec_on(VDEC_1))
- return;
- vdec_dbus_ctrl(0);
- } else if (input->target == VDEC_INPUT_TARGET_HEVC) {
- if (!vdec_on(VDEC_HEVC))
- return;
- hevc_arb_ctrl(0);
- }
- } else
- dec_dmc_port_ctrl(0, input->target);
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) & ~mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
+
+ if (is_cpu_tm2_revb() ||
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) {
+ while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS)
+ & mask))
+ ;
+ } else {
+ while (!(codec_dmcbus_read(DMC_CHAN_STS)
+ & mask))
+ ;
+ }
pr_debug("%s input->target= 0x%x\n", __func__, input->target);
}
@@ -720,22 +700,27 @@
static void vdec_enable_DMC(struct vdec_s *vdec)
{
struct vdec_input_s *input = &vdec->input;
+ unsigned long flags;
+ unsigned int mask = 0;
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) {
- if (input->target == VDEC_INPUT_TARGET_VLD)
- vdec_dbus_ctrl(1);
- else if (input->target == VDEC_INPUT_TARGET_HEVC)
- hevc_arb_ctrl(1);
- return;
+ if (input->target == VDEC_INPUT_TARGET_VLD) {
+ mask = (1 << 13);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask = (1 << 21);
+ } else if (input->target == VDEC_INPUT_TARGET_HEVC) {
+ mask = (1 << 4); /*hevc*/
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask |= (1 << 8); /*hevcb */
}
/*must to be reset the dmc pipeline if it's g12b.*/
if (get_cpu_type() == AM_MESON_CPU_MAJOR_ID_G12B)
vdec_dmc_pipeline_reset();
- dec_dmc_port_ctrl(1, input->target);
-
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) | mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
pr_debug("%s input->target= 0x%x\n", __func__, input->target);
}
@@ -867,7 +852,6 @@
int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
{
int r;
-
if (vdec->set_trickmode) {
r = vdec->set_trickmode(vdec, trickmode);
@@ -876,7 +860,6 @@
trickmode);
return r;
}
-
return -1;
}
EXPORT_SYMBOL(vdec_set_trickmode);
@@ -938,9 +921,7 @@
EXPORT_SYMBOL(vdec_count_info);
int vdec_is_support_4k(void)
{
- return ((!is_meson_gxl_package_805X()) &&
- (!is_cpu_s4_s805x2()) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D));
+ return !is_meson_gxl_package_805X();
}
EXPORT_SYMBOL(vdec_is_support_4k);
@@ -967,12 +948,6 @@
return vdec_core->cma_dev;
}
-int vdec_get_core_nr(void)
-{
- return (int)atomic_read(&vdec_core->vdec_nr);
-}
-EXPORT_SYMBOL(vdec_get_core_nr);
-
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
static const char * const vdec_device_name[] = {
"amvdec_mpeg12", "ammvdec_mpeg12",
@@ -1132,6 +1107,7 @@
struct vdec_s *vdec;
int type = VDEC_TYPE_SINGLE;
int id;
+
if (is_mult_inc(port->type))
type = (port->type & PORT_TYPE_FRAME) ?
VDEC_TYPE_FRAME_BLOCK :
@@ -1155,14 +1131,11 @@
INIT_LIST_HEAD(&vdec->list);
- init_waitqueue_head(&vdec->idle_wait);
-
atomic_inc(&vdec_core->vdec_nr);
#ifdef CONFIG_AMLOGIC_V4L_VIDEO3
v4lvideo_dec_count_increase();
#endif
vdec->id = id;
- vdec->video_id = 0xffffffff;
vdec_input_init(&vdec->input, vdec);
vdec->input.vdec_is_input_frame_empty = vdec_is_input_frame_empty;
vdec->input.vdec_up = vdec_up;
@@ -1198,7 +1171,6 @@
vdec->slave->format = format;
vdec->slave->port_flag |= PORT_FLAG_VFORMAT;
}
-
//trace_vdec_set_format(vdec, format);/*DEBUG_TMP*/
return 0;
@@ -1222,34 +1194,6 @@
}
EXPORT_SYMBOL(vdec_set_timestamp);
-void vdec_set_metadata(struct vdec_s *vdec, ulong meta_ptr)
-{
- char *tmp_buf = NULL;
- u32 size = 0;
-
- if (!meta_ptr)
- return;
-
- tmp_buf = vmalloc(META_DATA_SIZE + 4);
- if (!tmp_buf) {
- pr_err("%s:vmalloc 256+4 fail\n", __func__);
- return;
- }
- memcpy(tmp_buf, (void *)meta_ptr, META_DATA_SIZE + 4);
-
- size = tmp_buf[0] + (tmp_buf[1] << 8) +
- (tmp_buf[2] << 16) + (tmp_buf[3] << 24);
-
- if ((size > 0) && (size <= META_DATA_SIZE)) {
- memcpy(vdec->hdr10p_data_buf, tmp_buf + 4, size);
- vdec->hdr10p_data_size = size;
- vdec->hdr10p_data_valid = true;
- }
-
- vfree(tmp_buf);
-}
-EXPORT_SYMBOL(vdec_set_metadata);
-
int vdec_set_pts64(struct vdec_s *vdec, u64 pts64)
{
vdec->pts64 = pts64;
@@ -1478,8 +1422,6 @@
}
EXPORT_SYMBOL(vdec_stream_skip_data);
-
-
/*
*get next frame from input chain
*/
@@ -1637,6 +1579,9 @@
while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7))
;
WRITE_VREG(VLD_MEM_SWAP_CTL, 0);
+#ifdef VDEC_FCC_SUPPORT
+ vdec_fcc_jump_back(vdec);
+#endif
/* restore wrap count */
WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT,
@@ -1670,7 +1615,9 @@
& (1<<7))
;
WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0);
-
+#ifdef VDEC_FCC_SUPPORT
+ vdec_fcc_jump_back(vdec);
+#endif
/* restore stream offset */
WRITE_VREG(HEVC_SHIFT_BYTE_COUNT,
input->stream_cookie);
@@ -1703,6 +1650,7 @@
else
first_set_rp = input->start;
}
+
if (input->target == VDEC_INPUT_TARGET_VLD) {
WRITE_VREG(VLD_MEM_VIFIFO_START_PTR,
input->start);
@@ -1764,57 +1712,6 @@
}
EXPORT_SYMBOL(vdec_prepare_input);
-u32 vdec_offset_prepare_input(struct vdec_s *vdec, u32 consume_byte, u32 data_offset, u32 data_size)
-{
- struct vdec_input_s *input = &vdec->input;
- u32 res_byte, header_offset, header_data_size, data_invalid;
-
- res_byte = data_size - consume_byte;
- header_offset = data_offset;
- header_data_size = data_size;
- data_offset += consume_byte;
- data_size = res_byte;
-
- if (input->target == VDEC_INPUT_TARGET_VLD) {
- //to do
- } else if (input->target == VDEC_INPUT_TARGET_HEVC) {
- data_invalid = data_offset - round_down(data_offset, 0x40);
- data_offset -= data_invalid;
- data_size += data_invalid;
-
- if (data_offset < header_offset) {
- data_invalid = consume_byte;
- data_offset = header_offset;
- data_size = header_data_size;
- }
-
- if (input_frame_based(input)) {
- struct vframe_chunk_s *chunk = vdec_input_next_chunk(&vdec->input);
- struct vframe_block_list_s *block = NULL;
- int dummy;
-
- block = chunk->block;
- WRITE_VREG(HEVC_STREAM_START_ADDR, block->start);
- WRITE_VREG(HEVC_STREAM_END_ADDR, block->start +
- block->size);
- WRITE_VREG(HEVC_STREAM_RD_PTR, block->start +
- data_offset);
- dummy = data_offset + data_size +
- HEVC_PADDING_SIZE;
- if (dummy >= block->size)
- dummy -= block->size;
- WRITE_VREG(HEVC_STREAM_WR_PTR,
- round_down(block->start + dummy,
- VDEC_FIFO_ALIGN));
-
- /* set endian */
- SET_VREG_MASK(HEVC_STREAM_CONTROL, 7 << 4);
- }
- }
- return data_invalid;
-}
-EXPORT_SYMBOL(vdec_offset_prepare_input);
-
void vdec_enable_input(struct vdec_s *vdec)
{
struct vdec_input_s *input = &vdec->input;
@@ -2012,13 +1909,29 @@
EXPORT_SYMBOL(vdec_need_more_data);
-static void hevc_wait_ddr(void)
+void hevc_wait_ddr(void)
{
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) {
- hevc_arb_ctrl(0);
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ mask = 1 << 4; /* hevc */
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask |= (1 << 8); /* hevcb */
+
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) & ~mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
+
+ if (is_cpu_tm2_revb() ||
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) {
+ while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS)
+ & mask))
+ ;
} else {
- dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_HEVC);
+ while (!(codec_dmcbus_read(DMC_CHAN_STS)
+ & mask))
+ ;
}
}
@@ -2335,18 +2248,7 @@
return 0;
discon_timeout:
pr_err("%s timeout!!! status: 0x%x force it to 2\n", __func__, vdec->status);
- if (vdec->status == VDEC_STATUS_ACTIVE) {
- if (vdec->input.target == VDEC_INPUT_TARGET_VLD) {
- amvdec_stop();
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- vdec_free_irq(VDEC_IRQ_1, NULL);
- } else if (vdec->input.target == VDEC_INPUT_TARGET_HEVC) {
- amhevc_stop();
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0);
- vdec_free_irq(VDEC_IRQ_0, NULL);
- }
- }
-
+ vdec_set_status(vdec, VDEC_STATUS_CONNECTED);
return 0;
}
EXPORT_SYMBOL(vdec_disconnect);
@@ -2382,10 +2284,41 @@
true : false;
}
-static bool is_res_locked(u32 pre, u32 cur)
+static bool is_nontunnel_pipeline(u32 pl)
{
- return is_tunnel_pipeline(pre) ?
- (is_tunnel_pipeline(cur) ? true : false) : false;
+ return (pl & BIT(FRAME_BASE_PATH_DI_V4LVIDEO)) ? true : false;
+}
+
+static bool is_v4lvideo_already_used(u32 pre, int vf_receiver_inst)
+{
+ if (vf_receiver_inst == 0) {
+ if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0)) {
+ return true;
+ }
+ } else if (vf_receiver_inst == 1) {
+ if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1)) {
+ return true;
+ }
+ } else if (vf_receiver_inst == 2) {
+ if (pre & BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool is_res_locked(u32 pre, u32 cur, int vf_receiver_inst)
+{
+ if (is_tunnel_pipeline(pre)) {
+ if (is_tunnel_pipeline(cur)) {
+ return true;
+ }
+ } else if (is_nontunnel_pipeline(cur)) {
+ if (is_v4lvideo_already_used(pre,vf_receiver_inst)) {
+ return true;
+ }
+ }
+ return false;
}
int vdec_resource_checking(struct vdec_s *vdec)
@@ -2396,9 +2329,9 @@
* pipeline these are being released.
*/
ulong expires = jiffies + msecs_to_jiffies(2000);
-
while (is_res_locked(vdec_core->vdec_resouce_status,
- BIT(vdec->frame_base_video_path))) {
+ BIT(vdec->frame_base_video_path),
+ vdec->vf_receiver_inst)) {
if (time_after(jiffies, expires)) {
pr_err("wait vdec resource timeout.\n");
return -EBUSY;
@@ -2414,32 +2347,29 @@
*register vdec_device
* create output, vfm or create ionvideo output
*/
-s32 vdec_init(struct vdec_s *vdec, int is_4k, bool is_v4l)
+s32 vdec_init(struct vdec_s *vdec, int is_4k)
{
int r = 0;
struct vdec_s *p = vdec;
- const char *pdev_name;
- char dev_name[32] = {0};
+ const char *dev_name;
int id = PLATFORM_DEVID_AUTO;/*if have used my self*/
int max_di_count = max_di_instance;
- char postprocess_name[64] = {0};
+
if (vdec_stream_based(vdec))
max_di_count = max_supported_di_instance;
- vdec->is_v4l = is_v4l ? 1 : 0;
- if (is_res_locked(vdec_core->vdec_resouce_status,
- BIT(vdec->frame_base_video_path)))
- return -EBUSY;
+ if (is_res_locked(vdec_core->vdec_resouce_status,
+ BIT(vdec->frame_base_video_path),
+ vdec->vf_receiver_inst))
+ return -EBUSY;
//pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
- pdev_name = get_dev_name(vdec_single(vdec), vdec->format);
- if (pdev_name == NULL)
+ dev_name = get_dev_name(vdec_single(vdec), vdec->format);
+
+ if (dev_name == NULL)
return -ENODEV;
- snprintf(dev_name, sizeof(dev_name),
- "%s%s", pdev_name, is_v4l ? "_v4l": "");
-
- pr_info("vdec_init, dev_name:%s, vdec_type=%s, format: %d\n",
- dev_name, vdec_type_str(vdec), vdec->format);
+ pr_info("vdec_init, dev_name:%s, vdec_type=%s id = %d\n",
+ dev_name, vdec_type_str(vdec), vdec->id);
snprintf(vdec->name, sizeof(vdec->name),
"vdec-%d", vdec->id);
@@ -2479,31 +2409,24 @@
if (vdec_single(vdec) || (vdec_get_debug_flags() & 0x2))
vdec_enable_DMC(vdec);
p->cma_dev = vdec_core->cma_dev;
-
- vdec_canvas_port_register(vdec);
-
+ p->get_canvas = get_canvas;
+ p->get_canvas_ex = get_canvas_ex;
+ p->free_canvas_ex = free_canvas_ex;
p->vdec_fps_detec = vdec_fps_detec;
/* todo */
if (!vdec_dual(vdec)) {
p->use_vfm_path =
- is_support_no_parser() ?
+ (is_support_no_parser()) ?
vdec_single(vdec) :
vdec_stream_based(vdec);
}
- if (debugflags & (1 << 29))
- p->is_stream_mode_dv_multi = true;
- else
- p->is_stream_mode_dv_multi = false;
-
if (debugflags & 0x4)
p->use_vfm_path = 1;
/* vdec_dev_reg.flag = 0; */
if (vdec->id >= 0)
id = vdec->id;
p->parallel_dec = parallel_decode;
- p->prog_only = prog_only;
-
vdec_core->parallel_dec = parallel_decode;
vdec->canvas_mode = CANVAS_BLKMODE_32X32;
#ifdef FRAME_CHECK
@@ -2566,7 +2489,7 @@
if (p->use_vfm_path) {
vdec->vf_receiver_inst = -1;
vdec->vfm_map_id[0] = 0;
- } else if (!vdec_dual(vdec) && !vdec->disable_vfm) {
+ } else if (!vdec_dual(vdec)) {
/* create IONVIDEO instance and connect decoder's
* vf_provider interface to it
*/
@@ -2686,32 +2609,21 @@
mutex_unlock(&vdec_mutex);
goto error;
}
- if (v4lvideo_add_ppmgr)
- snprintf(postprocess_name, sizeof(postprocess_name),
- "%s ", "ppmgr");
- if (debug_vdetect && (vdec->vf_receiver_inst == 0))
- snprintf(postprocess_name + strlen(postprocess_name), sizeof(postprocess_name),
- "%s ", "vdetect.0");
- /* 8K remove di */
- if ((vdec->sys_info->width * vdec->sys_info->height > (4096 * 2304))
- || (!v4lvideo_add_di))
+ if (!v4lvideo_add_di)
snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE,
- "%s %s%s", vdec->vf_provider_name,
- postprocess_name,
+ "%s %s", vdec->vf_provider_name,
vdec->vf_receiver_name);
else {
if ((vdec->vf_receiver_inst == 0)
&& (max_di_count > 0))
if (max_di_count == 1)
snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE,
- "%s %s%s %s", vdec->vf_provider_name,
- postprocess_name,
+ "%s %s %s", vdec->vf_provider_name,
"deinterlace",
vdec->vf_receiver_name);
else
snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE,
- "%s %s%s %s", vdec->vf_provider_name,
- postprocess_name,
+ "%s %s %s", vdec->vf_provider_name,
"dimulti.1",
vdec->vf_receiver_name);
else if ((vdec->vf_receiver_inst <
@@ -2773,27 +2685,6 @@
"amlvideo amvideo");
snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE,
"vdec-map-%d", vdec->id);
- } else if (p->frame_base_video_path ==
- FRAME_BASE_PATH_V4LVIDEO_FENCE) {
-#ifdef CONFIG_AMLOGIC_V4L_VIDEO3
- r = v4lvideo_assign_map(&vdec->vf_receiver_name,
- &vdec->vf_receiver_inst);
-#else
- r = -1;
-#endif
- if (r < 0) {
- pr_err("V4lVideo frame receiver allocation failed.\n");
- mutex_lock(&vdec_mutex);
- inited_vcodec_num--;
- mutex_unlock(&vdec_mutex);
- goto error;
- }
-
- snprintf(vdec->vfm_map_chain, VDEC_MAP_NAME_SIZE,
- "%s %s", vdec->vf_provider_name,
- vdec->vf_receiver_name);
- snprintf(vdec->vfm_map_id, VDEC_MAP_NAME_SIZE,
- "vdec-map-%d", vdec->id);
}
if (vfm_map_add(vdec->vfm_map_id,
@@ -2829,7 +2720,7 @@
}
- if (!vdec_single(vdec) && !vdec->disable_vfm) {
+ if (!vdec_single(vdec)) {
vf_reg_provider(&p->vframe_provider);
vf_notify_receiver(p->vf_provider_name,
@@ -2861,6 +2752,15 @@
mutex_lock(&vdec_mutex);
vdec_core->vdec_resouce_status |= BIT(p->frame_base_video_path);
+ if (p->frame_base_video_path == FRAME_BASE_PATH_DI_V4LVIDEO) {
+ if (p->vf_receiver_inst == 0) {
+ vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0);
+ } else if (p->vf_receiver_inst == 1) {
+ vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1);
+ } else if (p->vf_receiver_inst == 2) {
+ vdec_core->vdec_resouce_status |= BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2);
+ }
+ }
mutex_unlock(&vdec_mutex);
vdec_input_prepare_bufs(/*prepared buffer for fast playing.*/
@@ -2869,6 +2769,13 @@
vdec->sys_info->height);
/* vdec is now ready to be active */
vdec_set_status(vdec, VDEC_STATUS_DISCONNECTED);
+
+#ifdef VDEC_FCC_SUPPORT
+ init_waitqueue_head(&vdec->jump_back_wq);
+ mutex_init(&vdec->jump_back_mutex);
+ vdec->fcc_mode = FCC_BUTT;
+ vdec->fcc_status = STATUS_BUTT;
+#endif
return 0;
error:
@@ -2908,36 +2815,6 @@
vdec_core_unlock(core, flags);
}
-st_userdata *get_vdec_userdata_ctx()
-{
- return &userdata;
-}
-EXPORT_SYMBOL(get_vdec_userdata_ctx);
-
-static void vdec_userdata_ctx_release(struct vdec_s *vdec)
-{
- int i;
- st_userdata *userdata = get_vdec_userdata_ctx();
-
- mutex_lock(&userdata->mutex);
-
- for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
- if (userdata->used[i] == 1 && vdec->video_id != 0xffffffff) {
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("ctx_release i: %d userdata.id %d\n",
- i, userdata->id[i]);
- userdata->ready_flag[i] = 0;
- userdata->id[i] = -1;
- userdata->used[i] = 0;
- userdata->set_id_flag = 0;
- }
- }
-
- mutex_unlock(&userdata->mutex);
-
- return;
-}
-
/* vdec_create/init/release/destroy are applied to both dual running decoders
*/
void vdec_release(struct vdec_s *vdec)
@@ -2954,10 +2831,10 @@
}
#endif
/* When release, userspace systemctl need this duration 0 event */
- vdec_frame_rate_uevent(0);
+ vframe_rate_uevent(0);
vdec_disconnect(vdec);
- if (!vdec->disable_vfm && vdec->vframe_provider.name) {
+ if (vdec->vframe_provider.name) {
if (!vdec_single(vdec)) {
if (vdec_core->hint_fr_vdec == vdec
&& vdec->fr_hint_state == VDEC_HINTED)
@@ -3010,20 +2887,27 @@
if (vdec->vbuf.ops && !vdec->master)
vdec->vbuf.ops->release(&vdec->vbuf);
- vdec_userdata_ctx_release(vdec);
-
- pr_debug("vdec_release instance %p, total %d\n", vdec,
- atomic_read(&vdec_core->vdec_nr));
+ pr_debug("vdec_release instance %p, total %d id = %d\n", vdec,
+ atomic_read(&vdec_core->vdec_nr), vdec->id);
mutex_lock(&vdec_mutex);
+ if (vdec->frame_base_video_path == FRAME_BASE_PATH_DI_V4LVIDEO) {
+ if (vdec->vf_receiver_inst == 0) {
+ vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_0);
+ } else if (vdec->vf_receiver_inst == 1) {
+ vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_1);
+ } else if (vdec->vf_receiver_inst == 2) {
+ vdec_core->vdec_resouce_status &= ~BIT(FRAME_BASE_PATH_DI_V4LVIDEO_2);
+ }
+ }
vdec_core->vdec_resouce_status &= ~BIT(vdec->frame_base_video_path);
mutex_unlock(&vdec_mutex);
+
vdec_destroy(vdec);
mutex_lock(&vdec_mutex);
inited_vcodec_num--;
mutex_unlock(&vdec_mutex);
-
}
EXPORT_SYMBOL(vdec_release);
@@ -3035,13 +2919,11 @@
vdec_disconnect(vdec);
- if (!vdec->disable_vfm) {
- if (vdec->vframe_provider.name)
- vf_unreg_provider(&vdec->vframe_provider);
+ if (vdec->vframe_provider.name)
+ vf_unreg_provider(&vdec->vframe_provider);
- if ((vdec->slave) && (vdec->slave->vframe_provider.name))
- vf_unreg_provider(&vdec->slave->vframe_provider);
- }
+ if ((vdec->slave) && (vdec->slave->vframe_provider.name))
+ vf_unreg_provider(&vdec->slave->vframe_provider);
if (vdec->reset) {
vdec->reset(vdec);
@@ -3056,17 +2938,15 @@
vdec_input_prepare_bufs(&vdec->input, vdec->sys_info->width,
vdec->sys_info->height);
- if (!vdec->disable_vfm) {
- vf_reg_provider(&vdec->vframe_provider);
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_START, vdec);
+ vf_reg_provider(&vdec->vframe_provider);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_START, vdec);
- if (vdec->slave) {
- vf_reg_provider(&vdec->slave->vframe_provider);
- vf_notify_receiver(vdec->slave->vf_provider_name,
- VFRAME_EVENT_PROVIDER_START, vdec->slave);
- vdec->slave->mc_loaded = 0;/*clear for reload firmware*/
- }
+ if (vdec->slave) {
+ vf_reg_provider(&vdec->slave->vframe_provider);
+ vf_notify_receiver(vdec->slave->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_START, vdec->slave);
+ vdec->slave->mc_loaded = 0;/*clear for reload firmware*/
}
vdec_connect(vdec);
@@ -3081,13 +2961,11 @@
pr_debug("vdec_v4l2_reset %d\n", flag);
vdec_disconnect(vdec);
if (flag != 2) {
- if (!vdec->disable_vfm) {
- if (vdec->vframe_provider.name)
- vf_unreg_provider(&vdec->vframe_provider);
+ if (vdec->vframe_provider.name)
+ vf_unreg_provider(&vdec->vframe_provider);
- if ((vdec->slave) && (vdec->slave->vframe_provider.name))
- vf_unreg_provider(&vdec->slave->vframe_provider);
- }
+ if ((vdec->slave) && (vdec->slave->vframe_provider.name))
+ vf_unreg_provider(&vdec->slave->vframe_provider);
if (vdec->reset) {
vdec->reset(vdec);
@@ -3103,17 +2981,15 @@
vdec_input_prepare_bufs(&vdec->input, vdec->sys_info->width,
vdec->sys_info->height);
- if (!vdec->disable_vfm) {
- vf_reg_provider(&vdec->vframe_provider);
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_START, vdec);
+ vf_reg_provider(&vdec->vframe_provider);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_START, vdec);
- if (vdec->slave) {
- vf_reg_provider(&vdec->slave->vframe_provider);
- vf_notify_receiver(vdec->slave->vf_provider_name,
- VFRAME_EVENT_PROVIDER_START, vdec->slave);
- vdec->slave->mc_loaded = 0;/*clear for reload firmware*/
- }
+ if (vdec->slave) {
+ vf_reg_provider(&vdec->slave->vframe_provider);
+ vf_notify_receiver(vdec->slave->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_START, vdec->slave);
+ vdec->slave->mc_loaded = 0;/*clear for reload firmware*/
}
} else {
if (vdec->reset) {
@@ -3125,10 +3001,13 @@
vdec_connect(vdec);
+ vdec_frame_check_init(vdec);
+
return 0;
}
EXPORT_SYMBOL(vdec_v4l2_reset);
+
void vdec_free_cmabuf(void)
{
mutex_lock(&vdec_mutex);
@@ -3191,10 +3070,8 @@
t &= ~(1 << i);
}
- if (vdec->active_mask == 0) {
+ if (vdec->active_mask == 0)
vdec_set_status(vdec, VDEC_STATUS_CONNECTED);
- wake_up_interruptible(&vdec->idle_wait);
- }
mutex_unlock(&vdec_mutex);
}
@@ -3325,30 +3202,6 @@
return ret;
}
-int vdec_check_rec_num_enough(struct vdec_s *vdec) {
-
- if (vdec->vbuf.use_ptsserv) {
- return (pts_get_rec_num(PTS_TYPE_VIDEO,
- vdec->input.total_rd_count) >= 2);
- } else {
- u64 total_rd_count = vdec->input.total_rd_count;
-
- if (vdec->input.target == VDEC_INPUT_TARGET_VLD) {
- //total_rd_count -= vdec->input.start;
- /*just like use ptsserv, alway return true*/
- return 1;
- }
- if ((total_rd_count >= vdec->vbuf.last_offset[0]) &&
- (total_rd_count - vdec->vbuf.last_offset[0] < 0x80000000))
- return 0;
- else if ((total_rd_count >= vdec->vbuf.last_offset[1]) &&
- (total_rd_count - vdec->vbuf.last_offset[1] < 0x80000000))
- return 0;
-
- return 1;
- }
-}
-
unsigned long vdec_ready_to_run(struct vdec_s *vdec, unsigned long mask)
{
unsigned long ready_mask;
@@ -3376,6 +3229,7 @@
inc_profi_count(mask, vdec->check_count);
#endif
if (vdec_core_with_input(mask)) {
+
/* check frame based input underrun */
if (input && !input->eos && input_frame_based(input)
&& (!vdec_input_next_chunk(input))) {
@@ -3396,7 +3250,8 @@
level = wp - rp;
if ((level < input->prepare_level) &&
- !vdec_check_rec_num_enough(vdec)) {
+ (pts_get_rec_num(PTS_TYPE_VIDEO,
+ vdec->input.total_rd_count) < 2)) {
vdec->need_more_data |= VDEC_NEED_MORE_DATA;
#ifdef VDEC_DEBUG_SUPPORT
inc_profi_count(mask, vdec->input_underrun_count);
@@ -3465,9 +3320,6 @@
* Perform need_more_data checking and set flag is decoder
* is not consuming data.
*/
-#define DMC_DEV_TYPE_NON_SECURE 0
-#define DMC_DEV_TYPE_SECURE 1
-
void vdec_prepare_run(struct vdec_s *vdec, unsigned long mask)
{
struct vdec_input_s *input = &vdec->input;
@@ -3481,12 +3333,12 @@
if (vdec_stream_based(vdec) && !vdec_secure(vdec))
{
- tee_config_device_state(DMC_DEV_ID_PARSER, 0);
+ tee_config_device_secure(DMC_DEV_ID_PARSER, 0);
}
if (input->target == VDEC_INPUT_TARGET_VLD)
- tee_config_device_state(DMC_DEV_ID_VDEC, secure);
+ tee_config_device_secure(DMC_DEV_ID_VDEC, secure);
else if (input->target == VDEC_INPUT_TARGET_HEVC)
- tee_config_device_state(DMC_DEV_ID_HEVC, secure);
+ tee_config_device_secure(DMC_DEV_ID_HEVC, secure);
if (vdec_stream_based(vdec) &&
((vdec->need_more_data & VDEC_NEED_MORE_DATA_RUN) &&
@@ -3498,6 +3350,7 @@
vdec->need_more_data &= ~VDEC_NEED_MORE_DATA_DIRTY;
}
+
/* struct vdec_core_shread manages all decoder instance in active list. When
* a vdec is added into the active list, it can onlt be in two status:
* VDEC_STATUS_CONNECTED(the decoder does not own HW resource and ready to run)
@@ -3697,6 +3550,7 @@
inc_profi_count(mask, vdec->run_count);
update_profi_clk_run(vdec, mask, get_current_clk());
#endif
+
vdec->run(vdec, mask, vdec_callback, core);
@@ -3796,7 +3650,6 @@
}
EXPORT_SYMBOL(vdec_power_reset);
-
void vdec_poweron(enum vdec_type_e core)
{
if (core >= VDEC_MAX)
@@ -3944,12 +3797,27 @@
void vdec_reset_core(struct vdec_s *vdec)
{
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)) {
- /* t7 no dmc req for vdec only */
- vdec_dbus_ctrl(0);
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ mask = 1 << 13; /*bit13: DOS VDEC interface*/
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask = 1 << 21; /*bit21: DOS VDEC interface*/
+
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) & ~mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
+
+ if (is_cpu_tm2_revb() ||
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) {
+ while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS)
+ & mask))
+ ;
} else {
- dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_VLD);
+ while (!(codec_dmcbus_read(DMC_CHAN_STS)
+ & mask))
+ ;
}
/*
* 2: assist
@@ -3969,11 +3837,10 @@
WRITE_VREG(DOS_SW_RESET0, (1<<3)|(1<<4)|(1<<5)|(1<<7)|(1<<8)|(1<<9));
WRITE_VREG(DOS_SW_RESET0, 0);
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3))
- vdec_dbus_ctrl(1);
- else
- dec_dmc_port_ctrl(1, VDEC_INPUT_TARGET_VLD);
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) | mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
}
EXPORT_SYMBOL(vdec_reset_core);
@@ -4013,25 +3880,39 @@
void hevc_reset_core(struct vdec_s *vdec)
{
- int cpu_type = get_cpu_major_id();
+ unsigned long flags;
+ unsigned int mask = 0;
+ int cpu_type;
- if ((cpu_type == AM_MESON_CPU_MAJOR_ID_T7) ||
- (cpu_type == AM_MESON_CPU_MAJOR_ID_T3)) {
- /* t7 no dmc req for hevc only */
- hevc_arb_ctrl(0);
+ mask = 1 << 4; /*bit4: hevc*/
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ mask |= 1 << 8; /*bit8: hevcb*/
+
+ WRITE_VREG(HEVC_STREAM_CONTROL, 0);
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) & ~mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
+
+ if (is_cpu_tm2_revb() ||
+ (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) {
+ while (!(codec_dmcbus_read(TM2_REVB_DMC_CHAN_STS)
+ & mask))
+ ;
} else {
- WRITE_VREG(HEVC_STREAM_CONTROL, 0);
-
- dec_dmc_port_ctrl(0, VDEC_INPUT_TARGET_HEVC);
+ while (!(codec_dmcbus_read(DMC_CHAN_STS)
+ & mask))
+ ;
}
if (vdec == NULL || input_frame_based(vdec))
WRITE_VREG(HEVC_STREAM_CONTROL, 0);
+
WRITE_VREG(HEVC_SAO_MMU_RESET_CTRL,
READ_VREG(HEVC_SAO_MMU_RESET_CTRL) | 1);
- /*
+ /*
* 2: assist
* 3: parser
* 4: parser_state
@@ -4048,17 +3929,25 @@
* 24:hevc_afifo
* 26:rst_mmu_n
*/
- WRITE_VREG(DOS_SW_RESET3,
- (1<<3)|(1<<4)|(1<<8)|(1<<10)|(1<<11)|
- (1<<12)|(1<<13)|(1<<14)|(1<<15)|
- (1<<17)|(1<<18)|(1<<19)|(1<<24)|(1<<26));
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2) &&
+ (vdec->format == VFORMAT_AVS2)) {
+ WRITE_VREG(DOS_SW_RESET3,
+ (1<<3)|(1<<4)|(1<<8)|(1<<11)|
+ (1<<12)|(1<<14)|(1<<15)|
+ (1<<17)|(1<<18)|(1<<19));
+ } else {
+ WRITE_VREG(DOS_SW_RESET3,
+ (1<<3)|(1<<4)|(1<<8)|(1<<10)|(1<<11)|
+ (1<<12)|(1<<13)|(1<<14)|(1<<15)|
+ (1<<17)|(1<<18)|(1<<19)|(1<<24)|(1<<26));
+ }
WRITE_VREG(DOS_SW_RESET3, 0);
while (READ_VREG(HEVC_WRRSP_LMEM) & 0xfff)
;
WRITE_VREG(HEVC_SAO_MMU_RESET_CTRL,
READ_VREG(HEVC_SAO_MMU_RESET_CTRL) & (~1));
-
+ cpu_type = get_cpu_major_id();
if (cpu_type == AM_MESON_CPU_MAJOR_ID_TL1 &&
is_meson_rev_b())
cpu_type = AM_MESON_CPU_MAJOR_ID_G12B;
@@ -4073,17 +3962,12 @@
case AM_MESON_CPU_MAJOR_ID_SM1:
case AM_MESON_CPU_MAJOR_ID_TL1:
case AM_MESON_CPU_MAJOR_ID_TM2:
- case AM_MESON_CPU_MAJOR_ID_T5:
- case AM_MESON_CPU_MAJOR_ID_T5D:
- case AM_MESON_CPU_MAJOR_ID_T5W:
WRITE_RESET_REG((RESET7_REGISTER_LEVEL),
READ_RESET_REG(RESET7_REGISTER_LEVEL) & (~((1<<13))));
WRITE_RESET_REG((RESET7_REGISTER_LEVEL),
READ_RESET_REG((RESET7_REGISTER_LEVEL)) | ((1<<13)));
break;
case AM_MESON_CPU_MAJOR_ID_SC2:
- case AM_MESON_CPU_MAJOR_ID_S4:
- case AM_MESON_CPU_MAJOR_ID_S4D:
WRITE_RESET_REG(P_RESETCTRL_RESET5_LEVEL,
READ_RESET_REG(P_RESETCTRL_RESET5_LEVEL) & (~((1<<1)|(1<<12)|(1<<13))));
WRITE_RESET_REG(P_RESETCTRL_RESET5_LEVEL,
@@ -4093,11 +3977,12 @@
break;
}
- if ((cpu_type == AM_MESON_CPU_MAJOR_ID_T7) ||
- (cpu_type == AM_MESON_CPU_MAJOR_ID_T3))
- hevc_arb_ctrl(1);
- else
- dec_dmc_port_ctrl(1, VDEC_INPUT_TARGET_HEVC);
+
+ spin_lock_irqsave(&vdec_spin_lock, flags);
+ codec_dmcbus_write(DMC_REQ_CTRL,
+ codec_dmcbus_read(DMC_REQ_CTRL) | mask);
+ spin_unlock_irqrestore(&vdec_spin_lock, flags);
+
}
EXPORT_SYMBOL(hevc_reset_core);
@@ -4245,7 +4130,7 @@
int i;
char *pbuf = buf;
ssize_t ret;
- u16 *trace_buf = kmalloc(debug_trace_num * 2, GFP_KERNEL);
+ u16 *trace_buf = vzalloc(debug_trace_num * 2);
if (!trace_buf) {
pbuf += sprintf(pbuf, "No Memory bug\n");
@@ -4256,7 +4141,7 @@
mutex_lock(&vdec_mutex);
if (!vdec_on(VDEC_1)) {
mutex_unlock(&vdec_mutex);
- kfree(trace_buf);
+ vfree(trace_buf);
pbuf += sprintf(pbuf, "amrisc is power off\n");
ret = pbuf - buf;
return ret;
@@ -4312,7 +4197,7 @@
}
while (i < debug_trace_num)
;
- kfree(trace_buf);
+ vfree(trace_buf);
pbuf += sprintf(pbuf, "\n");
ret = pbuf - buf;
return ret;
@@ -4356,7 +4241,8 @@
return count;
}
-static ssize_t poweron_clock_level_store(struct class *class,
+
+static ssize_t store_poweron_clock_level(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4372,7 +4258,7 @@
return size;
}
-static ssize_t poweron_clock_level_show(struct class *class,
+static ssize_t show_poweron_clock_level(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", poweron_clock_level);
@@ -4383,7 +4269,7 @@
*always don't release
*vdec 64 memory for fast play.
*/
-static ssize_t keep_vdec_mem_store(struct class *class,
+static ssize_t store_keep_vdec_mem(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4398,14 +4284,15 @@
return size;
}
-static ssize_t keep_vdec_mem_show(struct class *class,
+static ssize_t show_keep_vdec_mem(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", keep_vdec_mem);
}
+
#ifdef VDEC_DEBUG_SUPPORT
-static ssize_t debug_store(struct class *class,
+static ssize_t store_debug(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4444,10 +4331,6 @@
"VDEC_DEBUG: HHI_VDEC4_CLK_CNTL = 0x%x, HHI_VDEC2_CLK_CNTL = 0x%x\n",
READ_HHI_REG(HHI_VDEC4_CLK_CNTL),
READ_HHI_REG(HHI_VDEC2_CLK_CNTL));
- } else if (strcmp(cbuf, "no_interlace") == 0) {
- prog_only ^= 1;
- pr_info("set prog only %d, %s output\n",
- prog_only, prog_only?"force one filed only":"interlace");
}
flags = vdec_core_lock(vdec_core);
@@ -4466,7 +4349,7 @@
return size;
}
-static ssize_t debug_show(struct class *class,
+static ssize_t show_debug(struct class *class,
struct class_attribute *attr, char *buf)
{
char *pbuf = buf;
@@ -4492,8 +4375,6 @@
pbuf += sprintf(pbuf,
"read_hevc_clk_reg - read HHI register for hevc clk\n");
pbuf += sprintf(pbuf,
- "no_interlace - force v4l no_interlace output. %d\n", prog_only);
- pbuf += sprintf(pbuf,
"===================\n");
pbuf += sprintf(pbuf,
@@ -4531,6 +4412,7 @@
}
#endif
+
int show_stream_buffer_status(char *buf,
int (*callback) (struct stream_buf_s *, char *))
{
@@ -4554,7 +4436,7 @@
}
EXPORT_SYMBOL(show_stream_buffer_status);
-static ssize_t vdec_vfm_path_store(struct class *class,
+static ssize_t store_vdec_vfm_path(struct class *class,
struct class_attribute *attr,
const char *buf, size_t count)
{
@@ -4613,7 +4495,7 @@
return count;
}
-static ssize_t vdec_vfm_path_show(struct class *class,
+static ssize_t show_vdec_vfm_path(struct class *class,
struct class_attribute *attr, char *buf)
{
int len = 0;
@@ -4668,6 +4550,7 @@
vdec_core->isr_context[num].dev_isr = handler;
vdec_core->isr_context[num].dev_threaded_isr = thread_fn;
vdec_core->isr_context[num].dev_id = dev;
+
ret = request_threaded_irq(res_irq,
vdec_isr,
vdec_thread_isr,
@@ -4725,20 +4608,6 @@
}
EXPORT_SYMBOL(vdec_free_irq);
-void vdec_sync_irq(enum vdec_irq_num num)
-{
-#if 0
- if (!vdec)
- return;
- if (vdec->input.target == VDEC_INPUT_TARGET_HEVC)
- synchronize_irq(vdec_core->isr_context[VDEC_IRQ_0].irq);
- else (vdec->input.target == VDEC_INPUT_TARGET_VLD)
- synchronize_irq(vdec_core->isr_context[VDEC_IRQ_1].irq);
-#endif
- synchronize_irq(vdec_core->isr_context[num].irq);
-}
-EXPORT_SYMBOL(vdec_sync_irq);
-
struct vdec_s *vdec_get_default_vdec_for_userdata(void)
{
struct vdec_s *vdec;
@@ -4865,6 +4734,192 @@
}
EXPORT_SYMBOL(vdec_set_profile_level);
+#ifdef VDEC_FCC_SUPPORT
+int vdec_wakeup_fcc_poll(struct vdec_s *vdec)
+{
+ if (vdec) {
+ if (vdec->wakeup_fcc_poll)
+ vdec->wakeup_fcc_poll(vdec);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(vdec_wakeup_fcc_poll);
+
+int vdec_has_get_fcc_new_msg(struct vdec_s *vdec)
+{
+ int ret = 1;
+
+ if (vdec == NULL) {
+ pr_info("Error, invalid vdec instance!\n");
+ return 0;
+ }
+
+ if (input_stream_based(vdec)) {
+ if (vdec->fcc_mode == FCC_DISCARD_MODE &&
+ vdec->fcc_status == STATUS_BUTT) {
+ ret = 1;
+ vdec->fcc_status = AGAIN_STATUS;
+ } else if (vdec->fcc_mode == FCC_DEC_MODE &&
+ vdec->fcc_status != SWITCH_DONE_STATUS) {
+ ret = 1;
+
+ if (wait_event_interruptible_timeout(vdec->jump_back_wq, vdec->jump_back_done | vdec->jump_back_error,
+ HZ / 2) <= 0) {
+ pr_info("[%d][FCC]: Error! Wait jump back wp timeout 500ms!\n",
+ vdec->id);
+ vdec->fcc_status = SWITCH_DONE_STATUS;
+ } else {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: jump_back_done = %d\n",
+ vdec->id, vdec->jump_back_done);
+ if (vdec->jump_back_done) {
+ vdec->fcc_status = JUMP_BACK_STATUS;
+ vdec->jump_back_done = 0;
+ } else {
+ vdec->fcc_status = SWITCH_DONE_STATUS;
+ vdec->jump_back_error = 0;
+ }
+ }
+
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: It is DEC mode now! fcc_status: %d\n",
+ vdec->id, vdec->fcc_status);
+ } else if (vdec->fcc_mode == FCC_DISCARD_MODE &&
+ !vdec->fcc_new_msg) {
+ if (vdec->fcc_status == WAIT_MSG_STATUS) {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Wait msg!\n", vdec->id);
+ ret = 0;
+ } else {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Continue to find header!\n", vdec->id);
+ ret = 1;
+ }
+ } else if (vdec->fcc_new_msg) {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Got discard msg!\n", vdec->id);
+ ret = 1;
+ vdec->fcc_new_msg = 0;
+ if (vdec->fcc_mode == FCC_DISCARD_MODE) {
+ vdec->fcc_status = DISCARD_STATUS;
+ }
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(vdec_has_get_fcc_new_msg);
+void vdec_set_dmc_urgent(struct vdec_s *vdec, int urgentType)
+{
+#ifndef DMC_AXI4_G12_CHAN_CTRL
+#define DMC_AXI4_G12_CHAN_CTRL (0x90 << 2)
+#endif
+#define DMC_URGENT_TYPE_NORMAL 1
+#define DMC_URGENT_TYPE_URGENT 2
+#define DMC_URGENT_TYPE_SUPERURGENT 4
+
+ if (vdec) {
+ if (urgentType == DMC_URGENT_TYPE_NORMAL ||
+ urgentType == DMC_URGENT_TYPE_URGENT ||
+ urgentType == DMC_URGENT_TYPE_SUPERURGENT) {
+ int type;
+ unsigned int val;
+
+ type = vdec_get_hw_type(vdec->port->vformat);
+ if (type == CORE_MASK_HEVC) {
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
+ val = READ_DMCREG(DMC_AXI4_CHAN_CTRL);
+ val &= (~(0x7 << 16));
+ val |= ((urgentType & 0x7) << 16);
+ WRITE_DMCREG(DMC_AXI4_CHAN_CTRL, val);
+ } else {
+ val = READ_DMCREG(DMC_AXI4_G12_CHAN_CTRL);
+ val &= (~(0x7 << 16));
+ val |= ((urgentType & 0x7) << 16);
+ WRITE_DMCREG(DMC_AXI4_G12_CHAN_CTRL, val);
+ }
+ }
+ }
+ }
+
+}
+EXPORT_SYMBOL(vdec_set_dmc_urgent);
+
+int fcc_debug_enable(void)
+{
+ return fcc_debug;
+}
+EXPORT_SYMBOL(fcc_debug_enable);
+
+static void vdec_fcc_jump_back(struct vdec_s *vdec)
+{
+ u32 cur_rp, set_rp;
+ struct vdec_input_s *input = &vdec->input;
+
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: fcc_mode = %d fcc_status = %d\n",
+ vdec->id, vdec->fcc_mode, vdec->fcc_status);
+
+ if (input->target == VDEC_INPUT_TARGET_VLD) {
+ if (vdec->fcc_mode == FCC_DEC_MODE &&
+ vdec->fcc_status == JUMP_BACK_STATUS) {
+ set_rp = vdec->jump_back_rp;
+ cur_rp =READ_VREG(VLD_MEM_VIFIFO_RP);
+ input->stream_cookie = READ_VREG(VLD_MEM_VIFIFO_WRAP_COUNT);
+ if (cur_rp < set_rp) {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Packet is wrapped! VLD_MEM_VIFIFO_WRAP_COUNT = %d\n",
+ vdec->id, input->stream_cookie);
+ input->stream_cookie = (input->stream_cookie - 1) < 0 ?
+ 0 : input->stream_cookie - 1;
+ }
+
+ WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR, set_rp);
+ WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1);
+ WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
+
+ WRITE_VREG(VLD_MEM_SWAP_ADDR,
+ input->swap_page_phys);
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 3);
+ while (READ_VREG(VLD_MEM_SWAP_CTL) & (1<<7))
+ ;
+ WRITE_VREG(VLD_MEM_SWAP_CTL, 0);
+ vdec->fcc_status = SWITCH_DONE_STATUS;
+ if (fcc_debug_enable()) {
+ pr_info("[%d][FCC]:Current VLD_MEM_VIFIFO_WRAP_COUNT = %d cur_rp = %x set_rp = %x\n",
+ vdec->id, input->stream_cookie, cur_rp, set_rp);
+ }
+ }
+ } else if (input->target == VDEC_INPUT_TARGET_HEVC) {
+ if (vdec->fcc_mode == FCC_DEC_MODE &&
+ vdec->fcc_status == JUMP_BACK_STATUS) {
+ set_rp = vdec->jump_back_rp;
+ cur_rp = READ_VREG(HEVC_STREAM_RD_PTR);
+ if (cur_rp < set_rp) {
+ input->stream_cookie = input->stream_cookie + set_rp - cur_rp - vdec->input.size;
+ } else {
+ input->stream_cookie = input->stream_cookie - cur_rp + set_rp;
+ }
+
+ WRITE_VREG(HEVC_STREAM_RD_PTR, set_rp);
+ vdec->fcc_status = SWITCH_DONE_STATUS;
+
+ WRITE_VREG(HEVC_STREAM_SWAP_ADDR,
+ input->swap_page_phys);
+ WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 3);
+
+ while (READ_VREG(HEVC_STREAM_SWAP_CTRL)
+ & (1<<7))
+ ;
+ WRITE_VREG(HEVC_STREAM_SWAP_CTRL, 0);
+ }
+ }
+
+ return;
+}
+#endif
+
static int dump_mode;
static ssize_t dump_risc_mem_store(struct class *class,
struct class_attribute *attr,
@@ -4981,11 +5036,10 @@
list_for_each_entry(vdec, &core->connected_vdec_list, list) {
pbuf += sprintf(pbuf,
- "\tvdec.%d (%p (%s%s)), status = %s,\ttype = %s, \tactive_mask = %lx\n",
+ "\tvdec.%d (%p (%s)), status = %s,\ttype = %s, \tactive_mask = %lx\n",
vdec->id,
vdec,
vdec_device_name[vdec->format * 2],
- (vdec->is_v4l == 1) ? "_v4l" : "",
vdec_status_str(vdec),
vdec_type_str(vdec),
vdec->active_mask);
@@ -5155,28 +5209,6 @@
return pbuf - buf;
}
-static ssize_t version_show(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- char *pbuf = buf;
-#ifdef DECODER_VERSION
- pbuf += sprintf(pbuf, "DECODER VERSION: V" xstr(DECODER_VERSION) "\n");
-#else
-#ifdef RELEASED_VERSION
- pbuf += sprintf(pbuf, "Due to project compilation environment problems,\
-the current decoder version could not be detected,\
-Please Use The DECODER BASE Version for traceability\n");
- pbuf += sprintf(pbuf, "DECODER BASE Version: " xstr(RELEASED_VERSION) "\n");
-#endif
-#endif
-
-#ifdef UCODE_VERSION
- pbuf += sprintf(pbuf, "UCODE VERSION: V" xstr(UCODE_VERSION) "\n");
-#endif
-
- return pbuf - buf;
-}
-
static char * parser_h264_profile(char *pbuf, struct vdec_s *vdec)
{
switch (vdec->profile_idc) {
@@ -5444,65 +5476,71 @@
return pbuf - buf;
}
-static CLASS_ATTR_RO(amrisc_regs);
-static CLASS_ATTR_RO(dump_trace);
-static CLASS_ATTR_RO(clock_level);
-static CLASS_ATTR_RW(poweron_clock_level);
-static CLASS_ATTR_RW(dump_risc_mem);
-static CLASS_ATTR_RW(keep_vdec_mem);
-static CLASS_ATTR_RW(enable_mvdec_info);
-static CLASS_ATTR_RO(core);
-static CLASS_ATTR_RO(vdec_status);
-static CLASS_ATTR_RO(dump_vdec_blocks);
-static CLASS_ATTR_RO(dump_vdec_chunks);
-static CLASS_ATTR_RO(dump_decoder_state);
-#ifdef VDEC_DEBUG_SUPPORT
-static CLASS_ATTR_RW(debug);
-#endif
-static CLASS_ATTR_RW(vdec_vfm_path);
-#ifdef FRAME_CHECK
-static CLASS_ATTR_RW(dump_yuv);
-static CLASS_ATTR_RW(frame_check);
-#endif
-static CLASS_ATTR_RO(dump_fps);
-static CLASS_ATTR_RO(profile_idc);
-static CLASS_ATTR_RO(level_idc);
-static CLASS_ATTR_RO(version);
+#ifdef VDEC_FCC_SUPPORT
+static ssize_t store_fcc_debug(struct class *class,
+ struct class_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned int val;
+ ssize_t ret;
-static struct attribute *vdec_class_attrs[] = {
- &class_attr_amrisc_regs.attr,
- &class_attr_dump_trace.attr,
- &class_attr_clock_level.attr,
- &class_attr_poweron_clock_level.attr,
- &class_attr_dump_risc_mem.attr,
- &class_attr_keep_vdec_mem.attr,
- &class_attr_enable_mvdec_info.attr,
- &class_attr_core.attr,
- &class_attr_vdec_status.attr,
- &class_attr_dump_vdec_blocks.attr,
- &class_attr_dump_vdec_chunks.attr,
- &class_attr_dump_decoder_state.attr,
+ ret = kstrtoint(buf, 0, &val);
+ if (ret != 0)
+ return -EINVAL;
+ fcc_debug = val;
+ return size;
+}
+
+static ssize_t show_fcc_debug(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", fcc_debug);
+}
+#endif
+
+static struct class_attribute vdec_class_attrs[] = {
+ __ATTR_RO(amrisc_regs),
+ __ATTR_RO(dump_trace),
+ __ATTR_RO(clock_level),
+ __ATTR(enable_mvdec_info, S_IRUGO | S_IWUSR | S_IWGRP,
+ enable_mvdec_info_show, enable_mvdec_info_store),
+ __ATTR(poweron_clock_level, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_poweron_clock_level, store_poweron_clock_level),
+ __ATTR(dump_risc_mem, S_IRUGO | S_IWUSR | S_IWGRP,
+ dump_risc_mem_show, dump_risc_mem_store),
+ __ATTR(keep_vdec_mem, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_keep_vdec_mem, store_keep_vdec_mem),
+ __ATTR_RO(core),
+ __ATTR_RO(vdec_status),
+ __ATTR_RO(dump_vdec_blocks),
+ __ATTR_RO(dump_vdec_chunks),
+ __ATTR_RO(dump_decoder_state),
#ifdef VDEC_DEBUG_SUPPORT
- &class_attr_debug.attr,
+ __ATTR(debug, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_debug, store_debug),
#endif
- &class_attr_vdec_vfm_path.attr,
#ifdef FRAME_CHECK
- &class_attr_dump_yuv.attr,
- &class_attr_frame_check.attr,
+ __ATTR(dump_yuv, S_IRUGO | S_IWUSR | S_IWGRP,
+ dump_yuv_show, dump_yuv_store),
+ __ATTR(frame_check, S_IRUGO | S_IWUSR | S_IWGRP,
+ frame_check_show, frame_check_store),
#endif
- &class_attr_dump_fps.attr,
- &class_attr_profile_idc.attr,
- &class_attr_level_idc.attr,
- &class_attr_version.attr,
- NULL
+ __ATTR_RO(dump_fps),
+ __ATTR_RO(profile_idc),
+ __ATTR_RO(level_idc),
+ __ATTR(vfm_path, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_vdec_vfm_path, store_vdec_vfm_path),
+#ifdef VDEC_FCC_SUPPORT
+ __ATTR(fcc_debug, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_fcc_debug, store_fcc_debug),
+#endif
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(vdec_class);
-
static struct class vdec_class = {
- .name = "vdec",
- .class_groups = vdec_class_groups,
-};
+ .name = "vdec",
+ .class_attrs = vdec_class_attrs,
+ };
struct device *get_vdec_device(void)
{
@@ -5510,119 +5548,6 @@
}
EXPORT_SYMBOL(get_vdec_device);
-static int vdec_post_task_recycle(void *args)
-{
- struct post_task_mgr_s *post =
- (struct post_task_mgr_s *)args;
-
- while (post->running &&
- down_interruptible(&post->sem) == 0) {
- if (kthread_should_stop())
- break;
- mutex_lock(&post->mutex);
- if (!list_empty(&post->task_recycle)) {
- struct vdec_post_task_parms_s *parms, *tmp;
- list_for_each_entry_safe(parms, tmp, &post->task_recycle, recycle) {
- if (parms->scheduled) {
- list_del(&parms->recycle);
- kthread_stop(parms->task);
- kfree(parms);
- parms = NULL;
- }
- }
- }
- mutex_unlock(&post->mutex);
- }
-
- return 0;
-}
-
-static void vdec_post_task_exit(void)
-{
- struct post_task_mgr_s *post = &vdec_core->post;
-
- post->running = false;
- up(&post->sem);
-
- kthread_stop(post->task);
-}
-
-static int vdec_post_task_init(void)
-{
- struct post_task_mgr_s *post = &vdec_core->post;
-
- sema_init(&post->sem, 0);
- INIT_LIST_HEAD(&post->task_recycle);
- mutex_init(&post->mutex);
- post->running = true;
-
- post->task = kthread_run(vdec_post_task_recycle,
- post, "task-post-daemon-thread");
- if (IS_ERR(post->task)) {
- pr_err("%s, creat task post daemon thread faild %ld\n",
- __func__, PTR_ERR(post->task));
- return PTR_ERR(post->task);
- }
-
- return 0;
-}
-
-static int vdec_post_handler(void *args)
-{
- struct vdec_post_task_parms_s *parms =
- (struct vdec_post_task_parms_s *) args;
- struct post_task_mgr_s *post = &vdec_core->post;
-
- complete(&parms->park);
-
- /* process client task. */
- parms->func(parms->private);
- parms->scheduled = 1;
- up(&post->sem);
-
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
- usleep_range(1000, 2000);
- }
-
- return 0;
-}
-
-int vdec_post_task(post_task_handler func, void *args)
-{
- struct vdec_post_task_parms_s *parms;
- struct post_task_mgr_s *post = &vdec_core->post;
-
- parms = kzalloc(sizeof(*parms), GFP_KERNEL);
- if (parms == NULL)
- return -ENOMEM;
-
- parms->func = func;
- parms->private = args;
- init_completion(&parms->park);
- parms->scheduled = 0;
- parms->task = kthread_run(vdec_post_handler,
- parms, "task-post-thread");
- if (IS_ERR(parms->task)) {
- pr_err("%s, creat task post thread faild %ld\n",
- __func__, PTR_ERR(parms->task));
- kfree(parms);
- return PTR_ERR(parms->task);
- }
- if (!__kthread_should_park(parms->task))
- wait_for_completion(&parms->park);
-
- mutex_lock(&post->mutex);
- /* add to list for resource recycle in post daemon kthread */
- list_add_tail(&parms->recycle, &post->task_recycle);
- mutex_unlock(&post->mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(vdec_post_task);
-
-
-
static int vdec_probe(struct platform_device *pdev)
{
s32 i, r;
@@ -5703,8 +5628,6 @@
WQ_MEM_RECLAIM |WQ_HIGHPRI/*high priority*/, "vdec-work");
/*work queue priority lower than vdec-core.*/
- vdec_post_task_init();
-
/* power manager init. */
vdec_core->pm = (struct power_manager_s *)
of_device_get_match_data(&pdev->dev);
@@ -5714,7 +5637,6 @@
pr_err("vdec power manager init failed\n");
return r;
}
- pr_err("vdec power init success!\n");
}
return 0;
@@ -5735,8 +5657,6 @@
}
}
- vdec_post_task_exit();
-
kthread_stop(vdec_core->thread);
destroy_workqueue(vdec_core->vdec_core_wq);
@@ -5892,9 +5812,9 @@
ready = (ready + fifo[slot].frame_dur) / 2;
else
ready = fifo[slot].frame_dur;
- pr_debug("%s inner driver dur%u \n",__func__, ready);
- }
- goto end_handle;
+ pr_debug("%s inner driver dur%u \n",__func__, ready);
+ }
+ goto end_handle;
}
if (slot == 1) {
@@ -5933,7 +5853,7 @@
end_handle:
if (must_send) {
++must_send;
- vdec_frame_rate_uevent(ready);
+ vframe_rate_uevent(ready);
}
}
@@ -5971,7 +5891,7 @@
fifo_buf[i].pts_us64 = vf->pts_us64;
/* Calculate the duration from pts */
- if (!vdec->is_v4l && (mvfrm->wr < MINIMUM_FRAMES && mvfrm->wr > 0))
+ if (mvfrm->wr < MINIMUM_FRAMES && mvfrm->wr > 0)
cal_dur_from_pts(vdec, i);
}
mvfrm->wr++;
@@ -5987,76 +5907,6 @@
}
EXPORT_SYMBOL(vdec_vframe_ready);
-void set_meta_data_to_vf(struct vframe_s *vf, u32 type, void *v4l2_ctx)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(v4l2_ctx);
- struct aml_meta_head_s head;
- struct aml_vf_base_info_s vfb_infos;
-
- if ((ctx == NULL) || (vf == NULL))
- return ;
-
- if (vf->meta_data_buf == NULL) {
- vf->meta_data_buf = ctx->meta_infos.meta_bufs[ctx->meta_infos.index].buf;
- ctx->meta_infos.index = (ctx->meta_infos.index + 1) % V4L_CAP_BUFF_MAX;
- }
-
- switch (type) {
- case UVM_META_DATA_VF_BASE_INFOS:
- if ((vf->meta_data_size + sizeof(struct aml_vf_base_info_s) + AML_META_HEAD_SIZE) <= META_DATA_SIZE) {
- head.magic = META_DATA_MAGIC;
- head.type = UVM_META_DATA_VF_BASE_INFOS;
- head.data_size = sizeof(struct aml_vf_base_info_s);
-
- memcpy(vf->meta_data_buf + vf->meta_data_size,
- &head, AML_META_HEAD_SIZE);
- vf->meta_data_size += AML_META_HEAD_SIZE;
-
- vfb_infos.width = vf->width;
- vfb_infos.height = vf->height;
- vfb_infos.duration = vf->duration;
- vfb_infos.frame_type = vf->frame_type;
- vfb_infos.type = vf->type;
-
- memcpy(vf->meta_data_buf + vf->meta_data_size,
- &vfb_infos, sizeof(struct aml_vf_base_info_s));
- vf->meta_data_size += sizeof(struct aml_vf_base_info_s);
-
- if (debug_meta) {
- pr_debug("vf->meta_data_size = %d\n", vf->meta_data_size);
- pr_debug("vf:width:%d height:%d duration:%d frame_type:%d type:%d\n",
- vfb_infos.width, vfb_infos.height, vfb_infos.duration,
- vfb_infos.frame_type, vfb_infos.type);
- }
- }
- break;
- case UVM_META_DATA_HDR10P_DATA:
- if ((vf->meta_data_size + vf->hdr10p_data_size + AML_META_HEAD_SIZE) <= META_DATA_SIZE) {
- head.magic = META_DATA_MAGIC;
- head.type = UVM_META_DATA_HDR10P_DATA;
- head.data_size = vf->hdr10p_data_size;
-
- memcpy(vf->meta_data_buf + vf->meta_data_size,
- &head, AML_META_HEAD_SIZE);
- vf->meta_data_size += AML_META_HEAD_SIZE;
-
- memcpy(vf->meta_data_buf + vf->meta_data_size,
- vf->hdr10p_data_buf, vf->hdr10p_data_size);
- vf->meta_data_size += vf->hdr10p_data_size;
-
- if (debug_meta) {
- pr_debug("vf->meta_data_size = %d\n", vf->meta_data_size);
- pr_debug("vf->hdr10p_data_size = %d\n", vf->hdr10p_data_size);
- }
- }
- break;
- default:
- break;
- }
-}
-EXPORT_SYMBOL(set_meta_data_to_vf);
-
/* In this function,if we use copy_to_user, we may encounter sleep,
which may block the vdec_fill_vdec_frame,this is not acceptable.
So, we should use a tmp buffer(passed by caller) to get the content */
@@ -6113,23 +5963,6 @@
}
EXPORT_SYMBOL(vdec_get_frame_vdec);
-int get_double_write_ratio(int dw_mode)
-{
- int ratio = 1;
-
- if ((dw_mode == 2) ||
- (dw_mode == 3))
- ratio = 4;
- else if ((dw_mode == 4) ||
- (dw_mode == 5))
- ratio = 2;
- else if ((dw_mode == 8) ||
- (dw_mode == 9))
- ratio = 8;
- return ratio;
-}
-EXPORT_SYMBOL(get_double_write_ratio);
-
void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp)
{
if (vdec_single(vdec)) {
@@ -6177,111 +6010,6 @@
}
EXPORT_SYMBOL(vdec_config_vld_reg);
-static void check_rdma_result(int num)
-{
- int i, wr,rd,data;
- int flag = 1;
- for (i = 0; i < num; i++) {
- wr = READ_VREG(HEVC_IQIT_SCALELUT_WR_ADDR);
- rd = READ_VREG(HEVC_IQIT_SCALELUT_RD_ADDR);
- data = READ_VREG(HEVC_IQIT_SCALELUT_DATA);
- if (wr != (num & 0x3ff)) {
- pr_info("--->HEVC_IQIT_SCALELUT_WR_ADDR = 0x%x\n", wr);
- flag = 0;
- break;
- }
- if (rd != i) {
- pr_info("--->HEVC_IQIT_SCALELUT_RD_ADDR = 0x%x\n", rd);
- flag = 0;
- break;
- }
-
- if (data != 0) {
- pr_info("--->HEVC_IQIT_SCALELUT_DATA = 0x%x\n", data);
- flag = 0;
- break;
- }
- }
- if (flag == 0)
- pr_info("-->%d--rdma flail\n", i);
- else
- pr_info("rdma ok\n");
- return;
-
-}
-
-int is_rdma_enable(void)
-{
- if (rdma_mode && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3))
- return 1;
- else
- return 0;
-}
-EXPORT_SYMBOL(is_rdma_enable);
-
-void rdma_front_end_wrok(dma_addr_t ddr_phy_addr, u32 size)
-{
- ulong expires;
-
- WRITE_VREG(HEVC_RDMA_F_CTRL,
- (0X0 << 7) | //axi id
- (0X7 << 3) | //axi length
- (0X0 << 2) | //rdma force cg en
- (0X1 << 1)); //rdma path en
- WRITE_VREG(HEVC_RDMA_F_START_ADDR, ddr_phy_addr); //rdma start address
- WRITE_VREG(HEVC_RDMA_F_END_ADDR, ddr_phy_addr + 0xff); //rdma end address
- WRITE_VREG(HEVC_RDMA_F_STATUS0, 0X1); //trigger rdma start to work
-
- expires = jiffies + msecs_to_jiffies(2000);
- while (1) {
- if ((READ_VREG(HEVC_RDMA_F_STATUS0) & 0x1) == 0) {
- //pr_info("rdma front_end done\n");
- break;
- }
- if (time_after(jiffies, expires)) {
- pr_info("wait rdma done timeout\n");
- break;
- }
- }
-
- if (rdma_mode & 0x2)
- check_rdma_result(SCALELUT_DATA_WRITE_NUM);
-
- return;
-}
-EXPORT_SYMBOL(rdma_front_end_wrok);
-
-void rdma_back_end_work(dma_addr_t back_ddr_phy_addr, u32 size)
-{
- ulong expires;
-
- WRITE_VREG(HEVC_RDMA_B_CTRL,
- (0X0 << 7) | //axi id
- (0X7 << 3) | //axi length
- (0X0 << 2) | //rdma force cg en
- (0X1 << 1)); //rdma path en
- WRITE_VREG(HEVC_RDMA_B_START_ADDR, back_ddr_phy_addr); //rdma start address
- WRITE_VREG(HEVC_RDMA_B_END_ADDR, back_ddr_phy_addr + size -1); //rdma end address
- WRITE_VREG(HEVC_RDMA_B_STATUS0, 0X1); //trigger rdma start to work
-
- expires = jiffies + msecs_to_jiffies(2000);
- while (1) {
- if ((READ_VREG(HEVC_RDMA_B_STATUS0) & 0x1) == 0) {
- //pr_info("rdma back_end done\n");
- break;
- }
- if (time_after(jiffies, expires)) {
- pr_info("wait rdma done timeout\n");
- break;
- }
- }
- if (rdma_mode & 0x2)
- check_rdma_result(SCALELUT_DATA_WRITE_NUM);
-
- return;
-}
-EXPORT_SYMBOL(rdma_back_end_work);
-
RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup);
/*
uint force_hevc_clock_cntl;
@@ -6301,8 +6029,6 @@
module_param(force_nosecure_even_drm, int, 0664);
module_param(disable_switch_single_to_mult, int, 0664);
-module_param(debug_meta, uint, 0664);
-
module_param(frameinfo_flag, int, 0664);
MODULE_PARM_DESC(frameinfo_flag,
"\n frameinfo_flag\n");
@@ -6310,10 +6036,6 @@
MODULE_PARM_DESC(v4lvideo_add_di,
"\n v4lvideo_add_di\n");
-module_param(v4lvideo_add_ppmgr, int, 0664);
-MODULE_PARM_DESC(v4lvideo_add_ppmgr,
- "\n v4lvideo_add_ppmgr\n");
-
module_param(max_di_instance, int, 0664);
MODULE_PARM_DESC(max_di_instance,
"\n max_di_instance\n");
@@ -6321,16 +6043,19 @@
module_param(max_supported_di_instance, int, 0664);
MODULE_PARM_DESC(max_supported_di_instance,
"\n max_supported_di_instance\n");
+
module_param(debug_vdetect, int, 0664);
MODULE_PARM_DESC(debug_vdetect, "\n debug_vdetect\n");
+#ifdef VDEC_FCC_SUPPORT
+module_param(fcc_debug, int, 0664);
+MODULE_PARM_DESC(fcc_debug, "\n fcc_debug\n");
+#endif
+
module_param(enable_stream_mode_multi_dec, int, 0664);
+EXPORT_SYMBOL(enable_stream_mode_multi_dec);
MODULE_PARM_DESC(enable_stream_mode_multi_dec,
"\n enable multi-decoding on stream mode. \n");
-
-module_param(rdma_mode, int, 0664);
-MODULE_PARM_DESC(rdma_mode, "\n rdma_enable\n");
-
/*
*module_init(vdec_module_init);
*module_exit(vdec_module_exit);
diff --git a/drivers/frame_provider/decoder/utils/vdec.h b/drivers/frame_provider/decoder/utils/vdec.h
index a50bdb5..302bfad 100644
--- a/drivers/frame_provider/decoder/utils/vdec.h
+++ b/drivers/frame_provider/decoder/utils/vdec.h
@@ -23,7 +23,7 @@
#include <linux/list.h>
#include <linux/completion.h>
#include <linux/irqreturn.h>
-#include <linux/videodev2.h>
+
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
@@ -37,7 +37,6 @@
#include "vdec_input.h"
#include "frame_check.h"
#include "vdec_sync.h"
-#include "vdec_canvas_utils.h"
s32 vdec_dev_register(void);
s32 vdec_dev_unregister(void);
@@ -57,84 +56,17 @@
#define VDEC_FIFO_ALIGN 8
+#define VDEC_FCC_SUPPORT
+
enum vdec_type_e {
VDEC_1 = 0,
VDEC_HCODEC,
VDEC_2,
VDEC_HEVC,
VDEC_HEVCB,
- VDEC_WAVE,
VDEC_MAX
};
-struct trace_decoder_name {
- char set_canvas0_addr[32];
- char get_canvas0_addr[32];
- char put_canvas0_addr[32];
- char vf_put_name[32];
- char vf_get_name[32];
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
- char decode_time_name[32];
- char decode_run_time_name[32];
- char decode_header_time_name[32];
- char decode_work_time_name[32];
- char decode_header_memory_time_name[32];
-};
-
-
-enum e_trace_decoder_status {
- DECODER_RUN_START = 1,
- DECODER_RUN_END = 2,
- DECODER_ISR_HEAD_DONE = 3,
- DECODER_ISR_PIC_DONE = 4,
- DECODER_ISR_END = 5,
- DECODER_ISR_THREAD_HEAD_START = 6,
- DECODER_ISR_THREAD_PIC_DONE_START = 7,
- DECODER_ISR_THREAD_EDN = 8,
- DECODER_WORKER_START = 9,
- DECODER_WORKER_END = 10,
- DECODER_WORKER_AGAIN = 11,
- DECODER_ISR_SEI_DONE = 12,
- DECODER_ISR_THREAD_SEI_START = 13,
- DECODER_ISR_AUX_DONE = 14,
- DECODER_ISR_THREAD_AUX_START = 15,
- DECODER_ISR_THREAD_HEAD_END = 16,
-};
-
-enum e_trace_run_status {
- TRACE_RUN_LOADING_FW_START = 1,
- TRACE_RUN_LOADING_FW_END = 2,
- TRACE_RUN_LOADING_RESTORE_START = 3,
- TRACE_RUN_LOADING_RESTORE_END = 4,
-};
-
-enum e_trace_header_status {
- TRACE_HEADER_MEMORY_START = 1,
- TRACE_HEADER_MEMORY_END = 2,
- TRACE_HEADER_REGISTER_START = 3,
- TRACE_HEADER_REGISTER_END = 4,
- TRACE_HEADER_RPM_START = 5,
- TRACE_HEADER_RPM_END = 6,
-};
-
-enum e_trace_work_status {
- TRACE_WORK_WAIT_SEARCH_DONE_START = 1,
- TRACE_WORK_WAIT_SEARCH_DONE_END = 2,
-};
-
-
-#define VDEC_CFG_FLAG_DV_TWOLARYER (1 << 0)
-#define VDEC_CFG_FLAG_DV_NEGATIVE (1 << 1)
-#define VDEC_CFG_FLAG_DIS_ERR_POLICY (1 << 11)
-
-#define VDEC_CFG_FLAG_PROG_ONLY (1 << 16)
-
-#define UVM_META_DATA_VF_BASE_INFOS (1 << 0)
-#define UVM_META_DATA_HDR10P_DATA (1 << 1)
-
#define CORE_MASK_VDEC_1 (1 << VDEC_1)
#define CORE_MASK_HCODEC (1 << VDEC_HCODEC)
#define CORE_MASK_VDEC_2 (1 << VDEC_2)
@@ -143,16 +75,14 @@
#define CORE_MASK_HEVC_BACK (1 << VDEC_HEVCB)
#define CORE_MASK_COMBINE (1UL << 31)
-#define META_DATA_SIZE (256)
-
-#define SEI_TYPE (1)
-#define DV_TYPE (2)
-
extern void vdec2_power_mode(int level);
extern void vdec_poweron(enum vdec_type_e core);
extern void vdec_poweroff(enum vdec_type_e core);
extern bool vdec_on(enum vdec_type_e core);
extern void vdec_power_reset(void);
+extern void vdec_set_dmc_urgent(struct vdec_s *vdec, int urgentType);
+
+
/*irq num as same as .dts*/
@@ -186,6 +116,19 @@
VDEC_NEED_HINT,
VDEC_HINTED,
};
+
+#ifdef VDEC_FCC_SUPPORT
+typedef enum {
+ DISCARD_STATUS = 1,
+ AGAIN_STATUS,
+ WAIT_MSG_STATUS,
+ SWITCHING_STATUS,
+ JUMP_BACK_STATUS,
+ SWITCH_DONE_STATUS,
+ STATUS_BUTT
+} FCC_STATUS;
+#endif
+
extern s32 vdec_request_threaded_irq(enum vdec_irq_num num,
irq_handler_t handler,
irq_handler_t thread_fn,
@@ -208,6 +151,7 @@
extern void vdec_vframe_ready(struct vdec_s *vdec, struct vframe_s *vf);
extern void vdec_set_vframe_comm(struct vdec_s *vdec, char *n);
+
struct vdec_s;
enum vformat_t;
@@ -246,9 +190,6 @@
#define VDEC_NEED_MORE_DATA_DIRTY 0x02
#define VDEC_NEED_MORE_DATA 0x04
-#define SCALELUT_DATA_WRITE_NUM 1024
-#define RDMA_SIZE (1024 * 4 * 4)
-
struct vdec_s {
u32 magic;
struct list_head list;
@@ -274,7 +215,7 @@
int flag;
int sched;
int need_more_data;
- u32 canvas_mode; //canvas block mode
+ u32 canvas_mode;
struct completion inactive_done;
@@ -336,6 +277,9 @@
struct userdata_param_t *puserdata_para);
void (*reset_userdata_fifo)(struct vdec_s *vdec, int bInit);
void (*wakeup_userdata_poll)(struct vdec_s *vdec);
+#ifdef VDEC_FCC_SUPPORT
+ void (*wakeup_fcc_poll)(struct vdec_s *vdec);
+#endif
/* private */
void *private; /* decoder per instance specific data */
#ifdef VDEC_DEBUG_SUPPORT
@@ -352,7 +296,7 @@
u64 irq_cnt;
int parallel_dec;
struct vdec_frames_s *mvfrm;
- struct vdec_sync *sync;
+ struct vdec_sync sync;
/*aux data check*/
struct aux_data_check_mgr_t adc;
@@ -362,90 +306,29 @@
bool hdr10p_data_valid;
u32 profile_idc;
u32 level_idc;
- bool prog_only;
- bool disable_vfm;
+#ifdef VDEC_FCC_SUPPORT
+ enum fcc_mode_e fcc_mode;
+ u32 stream_offset;
+ int fcc_new_msg;
+ FCC_STATUS fcc_status;
+ wait_queue_head_t jump_back_wq;
+ struct mutex jump_back_mutex;
+ u32 jump_back_done;
+ u32 jump_back_error;
+ u32 jump_back_rp;
+#endif
+ u32 video_id;
char name[32];
char dec_spend_time[32];
char dec_spend_time_ave[32];
u32 discard_start_data_flag;
- u32 video_id;
- int is_v4l;
- bool is_stream_mode_dv_multi;
- wait_queue_head_t idle_wait;
};
-#define CODEC_MODE(a, b, c, d)\
- (((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d))
-
-#define META_DATA_MAGIC CODEC_MODE('M', 'E', 'T', 'A')
-#define AML_META_HEAD_NUM 8
-#define AML_META_HEAD_SIZE (AML_META_HEAD_NUM * sizeof(u32))
-
-
-struct aml_meta_head_s {
- u32 magic;
- u32 type;
- u32 data_size;
- u32 data[5];
-};
-
-struct aml_vf_base_info_s {
- u32 width;
- u32 height;
- u32 duration;
- u32 frame_type;
- u32 type;
- u32 data[12];
-};
-
-struct aml_meta_info_s {
- union {
- struct aml_meta_head_s head;
- u32 buf[AML_META_HEAD_NUM];
- };
- u8 data[0];
-};
-
-typedef int (*post_task_handler)(void *args);
-
-struct post_task_mgr_s {
- struct list_head task_recycle;
- struct task_struct *task;
- struct semaphore sem;
- struct mutex mutex;
- bool running;
- void *private;
-};
-
-struct vdec_post_task_parms_s {
- struct list_head recycle;
- struct task_struct *task;
- struct completion park;
- post_task_handler func;
- void *private;
- int scheduled;
-};
-
-#define MAX_USERDATA_CHANNEL_NUM 9
-
-typedef struct {
- struct mutex mutex;
- wait_queue_head_t userdata_wait;
- u32 video_id;
- u32 set_id_flag;
- u32 ready_flag[MAX_USERDATA_CHANNEL_NUM];
- int used[MAX_USERDATA_CHANNEL_NUM];
- u32 id[MAX_USERDATA_CHANNEL_NUM];
-} st_userdata;
-
/* common decoder vframe provider name to use default vfm path */
#define VFM_DEC_PROVIDER_NAME "decoder"
#define VFM_DEC_DVBL_PROVIDER_NAME "dvbldec"
#define VFM_DEC_DVEL_PROVIDER_NAME "dveldec"
-#define VFM_DEC_DVBL_PROVIDER_NAME2 "dvbldec2"
-#define VFM_DEC_DVEL_PROVIDER_NAME2 "dveldec2"
-
#define hw_to_vdec(hw) ((struct vdec_s *) \
(platform_get_drvdata(hw->platform_dev)))
@@ -469,24 +352,6 @@
#define vdec_secure(vdec) \
(((vdec)->port_flag & PORT_FLAG_DRM))
-#define PR_INIT(s) \
- int __len = 0, __size = s; \
- u8 __buf[s] = {0}
-
-#define PR_FILL(args...) \
- do { \
- if ((__size - __len) <= 0) break; \
- __len += snprintf(__buf + __len, \
- __size - __len, ##args); \
- } while (0)
-
-#define PR_INFO(id) \
- do { \
- if (__len == 0) break; \
- pr_info("[%d] %s\n", id, __buf); \
- __len = 0; \
- } while (0)
-
/* construct vdec strcture */
extern struct vdec_s *vdec_create(struct stream_port_s *port,
struct vdec_s *master);
@@ -519,9 +384,6 @@
/* prepare decoder input */
extern int vdec_prepare_input(struct vdec_s *vdec, struct vframe_chunk_s **p);
-extern u32 vdec_offset_prepare_input(struct vdec_s *vdec, u32 consume_byte,
- u32 data_offset, u32 data_size);
-
/* clean decoder input */
extern void vdec_clean_input(struct vdec_s *vdec);
@@ -560,13 +422,14 @@
extern int vdec_reset(struct vdec_s *vdec);
extern int vdec_v4l2_reset(struct vdec_s *vdec, int flag);
+
extern void vdec_set_status(struct vdec_s *vdec, int status);
extern void vdec_set_next_status(struct vdec_s *vdec, int status);
extern int vdec_set_decinfo(struct vdec_s *vdec, struct dec_sysinfo *p);
-extern int vdec_init(struct vdec_s *vdec, int is_4k, bool is_v4l);
+extern int vdec_init(struct vdec_s *vdec, int is_4k);
extern void vdec_release(struct vdec_s *vdec);
@@ -621,9 +484,7 @@
#ifdef VDEC_DEBUG_SUPPORT
extern void vdec_set_step_mode(void);
#endif
-
extern void hevc_mmu_dma_check(struct vdec_s *vdec);
-
int vdec_read_user_data(struct vdec_s *vdec,
struct userdata_param_t *p_userdata_param);
@@ -635,6 +496,12 @@
struct vdec_s *vdec_get_vdec_by_id(int vdec_id);
+#ifdef VDEC_FCC_SUPPORT
+int vdec_wakeup_fcc_poll(struct vdec_s *vdec);
+int vdec_has_get_fcc_new_msg(struct vdec_s *vdec);
+int fcc_debug_enable(void);
+#endif
+
#ifdef VDEC_DEBUG_SUPPORT
extern void vdec_set_step_mode(void);
#endif
@@ -642,12 +509,12 @@
void VDEC_PRINT_FUN_LINENO(const char *fun, int line);
+
unsigned char is_mult_inc(unsigned int);
int vdec_get_status(struct vdec_s *vdec);
void vdec_set_timestamp(struct vdec_s *vdec, u64 timestamp);
-void vdec_set_metadata(struct vdec_s *vdec, ulong meta_ptr);
extern u32 vdec_get_frame_vdec(struct vdec_s *vdec, struct vframe_counter_s *tmpbuf);
@@ -656,13 +523,12 @@
int show_stream_buffer_status(char *buf,
int (*callback) (struct stream_buf_s *, char *));
-extern int get_double_write_ratio(int dw_mode);
-
bool is_support_no_parser(void);
+extern u32 timestamp_avsync_counter_get(void);
+
int vdec_resource_checking(struct vdec_s *vdec);
-void set_meta_data_to_vf(struct vframe_s *vf, u32 type, void *v4l2_ctx);
void vdec_set_profile_level(struct vdec_s *vdec, u32 profile_idc, u32 level_idc);
@@ -670,28 +536,4 @@
void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp);
void vdec_config_vld_reg(struct vdec_s *vdec, u32 addr, u32 size);
-extern u32 timestamp_avsync_counter_get(void);
-
-void vdec_canvas_unlock(unsigned long flags);
-
-unsigned long vdec_canvas_lock(void);
-
-int vdec_get_core_nr(void);
-
-
-int vdec_post_task(post_task_handler func, void *args);
-
-void rdma_front_end_wrok(dma_addr_t ddr_phy_addr, u32 size);
-
-void rdma_back_end_work(dma_addr_t back_ddr_phy_addr, u32 size);
-
-int is_rdma_enable(void);
-
-st_userdata *get_vdec_userdata_ctx(void);
-
-void vdec_frame_rate_uevent(int dur);
-
-void vdec_sync_irq(enum vdec_irq_num num);
-
-
#endif /* VDEC_H */
diff --git a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c b/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c
deleted file mode 100644
index 46fc003..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * drivers/amlogic/media/frame_provider/decoder/utils/vdec_canvas_utils.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#include <linux/types.h>
-#include "vdec_canvas_utils.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "vdec.h"
-
-static struct canvas_status_s canvas_stat[CANVAS_MAX_SIZE];
-static struct canvas_status_s mdec_cav_stat[MDEC_CAV_LUT_MAX];
-static struct canvas_config_s *mdec_cav_pool = NULL;
-
-extern u32 vdec_get_debug(void);
-
-
-bool is_support_vdec_canvas(void)
-{
- /* vdec canvas note:
- * 1. canvas params config to display, do not use
- * vf->canvasxAddr, should use vf->canvasxconfig[].
- * 2. the endian can not config with canvas. and hevc
- * core should not config canvas. config endian in
- * probe function like h265/vp9/av1/avs2.
- */
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5W))
- return true;
- return false;
-}
-EXPORT_SYMBOL(is_support_vdec_canvas);
-
-static int get_canvas(unsigned int index, unsigned int base)
-{
- int start;
- int canvas_index = index * base;
- int ret = 0;
-
- if ((base > 4) || (base == 0))
- return -1;
-
- if ((AMVDEC_CANVAS_START_INDEX + canvas_index + base - 1)
- <= AMVDEC_CANVAS_MAX1) {
- start = AMVDEC_CANVAS_START_INDEX + base * index;
- } else {
- canvas_index -= (AMVDEC_CANVAS_MAX1 -
- AMVDEC_CANVAS_START_INDEX + 1) / base * base;
- if (canvas_index <= AMVDEC_CANVAS_MAX2)
- start = canvas_index / base;
- else
- return -1;
- }
-
- if (base == 1) {
- ret = start;
- } else if (base == 2) {
- ret = ((start + 1) << 16) | ((start + 1) << 8) | start;
- } else if (base == 3) {
- ret = ((start + 2) << 16) | ((start + 1) << 8) | start;
- } else if (base == 4) {
- ret = (((start + 3) << 24) | (start + 2) << 16) |
- ((start + 1) << 8) | start;
- }
-
- return ret;
-}
-
-static int get_canvas_ex(int type, int id)
-{
- int i;
- unsigned long flags;
-
- flags = vdec_canvas_lock();
-
- for (i = 0; i < CANVAS_MAX_SIZE; i++) {
- /*0x10-0x15 has been used by rdma*/
- if ((i >= 0x10) && (i <= 0x15))
- continue;
- if ((canvas_stat[i].type == type) &&
- (canvas_stat[i].id & (1 << id)) == 0) {
- canvas_stat[i].canvas_used_flag++;
- canvas_stat[i].id |= (1 << id);
- if (vdec_get_debug() & 4)
- pr_debug("get used canvas %d\n", i);
- vdec_canvas_unlock(flags);
- if (i < AMVDEC_CANVAS_MAX2 + 1)
- return i;
- else
- return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
- }
- }
-
- for (i = 0; i < CANVAS_MAX_SIZE; i++) {
- /*0x10-0x15 has been used by rdma*/
- if ((i >= 0x10) && (i <= 0x15))
- continue;
- if (canvas_stat[i].type == 0) {
- canvas_stat[i].type = type;
- canvas_stat[i].canvas_used_flag = 1;
- canvas_stat[i].id = (1 << id);
- if (vdec_get_debug() & 4) {
- pr_debug("get canvas %d\n", i);
- pr_debug("canvas_used_flag %d\n",
- canvas_stat[i].canvas_used_flag);
- pr_debug("canvas_stat[i].id %d\n",
- canvas_stat[i].id);
- }
- vdec_canvas_unlock(flags);
- if (i < AMVDEC_CANVAS_MAX2 + 1)
- return i;
- else
- return (i + AMVDEC_CANVAS_START_INDEX - AMVDEC_CANVAS_MAX2 - 1);
- }
- }
- vdec_canvas_unlock(flags);
-
- pr_info("cannot get canvas\n");
-
- return -1;
-}
-
-static void free_canvas_ex(int index, int id)
-{
- unsigned long flags;
- int offset;
-
- flags = vdec_canvas_lock();
- if (index >= 0 &&
- index < AMVDEC_CANVAS_MAX2 + 1)
- offset = index;
- else if ((index >= AMVDEC_CANVAS_START_INDEX) &&
- (index <= AMVDEC_CANVAS_MAX1))
- offset = index + AMVDEC_CANVAS_MAX2 + 1 - AMVDEC_CANVAS_START_INDEX;
- else {
- vdec_canvas_unlock(flags);
- return;
- }
-
- if ((canvas_stat[offset].canvas_used_flag > 0) &&
- (canvas_stat[offset].id & (1 << id))) {
- canvas_stat[offset].canvas_used_flag--;
- canvas_stat[offset].id &= ~(1 << id);
- if (canvas_stat[offset].canvas_used_flag == 0) {
- canvas_stat[offset].type = 0;
- canvas_stat[offset].id = 0;
- }
- if (vdec_get_debug() & 4) {
- pr_debug("free index %d used_flag %d, type = %d, id = %d\n",
- offset,
- canvas_stat[offset].canvas_used_flag,
- canvas_stat[offset].type,
- canvas_stat[offset].id);
- }
- }
- vdec_canvas_unlock(flags);
-
- return;
-}
-
-
-static int get_internal_cav_lut(unsigned int index, unsigned int base)
-{
- int start;
- int canvas_index = index * base;
- int ret = 0;
-
- if ((base > 4) || (base == 0))
- return -1;
-
- if (canvas_index + base - 1 < MDEC_CAV_LUT_MAX)
- start = canvas_index;
- else
- return -1;
-
- if (base == 1) {
- ret = start;
- } else if (base == 2) {
- ret = ((start + 1) << 16) | ((start + 1) << 8) | start;
- } else if (base == 3) {
- ret = ((start + 2) << 16) | ((start + 1) << 8) | start;
- } else if (base == 4) {
- ret = (((start + 3) << 24) | (start + 2) << 16) |
- ((start + 1) << 8) | start;
- }
-
- return ret;
-}
-
-static int get_internal_cav_lut_ex(int type, int id)
-{
- int i;
- unsigned long flags;
-
- flags = vdec_canvas_lock();
-
- for (i = 0; i < MDEC_CAV_LUT_MAX; i++) {
- if ((mdec_cav_stat[i].type == type) &&
- (mdec_cav_stat[i].id & (1 << id)) == 0) {
- mdec_cav_stat[i].canvas_used_flag++;
- mdec_cav_stat[i].id |= (1 << id);
- if (vdec_get_debug() & 4)
- pr_debug("get used cav lut %d\n", i);
- vdec_canvas_unlock(flags);
- return i;
- }
- }
-
- for (i = 0; i < MDEC_CAV_LUT_MAX; i++) {
- if (mdec_cav_stat[i].type == 0) {
- mdec_cav_stat[i].type = type;
- mdec_cav_stat[i].canvas_used_flag = 1;
- mdec_cav_stat[i].id = (1 << id);
- if (vdec_get_debug() & 4)
- pr_debug("get cav lut %d\n", i);
- vdec_canvas_unlock(flags);
- return i;
- }
- }
- vdec_canvas_unlock(flags);
-
- pr_info("cannot get cav lut\n");
-
- return -1;
-}
-
-static void free_internal_cav_lut(int index, int id)
-{
- unsigned long flags;
- int offset;
-
- flags = vdec_canvas_lock();
- if (index > 0 && index < MDEC_CAV_LUT_MAX)
- offset = index;
- else {
- vdec_canvas_unlock(flags);
- return;
- }
- if ((mdec_cav_stat[offset].canvas_used_flag > 0) &&
- (mdec_cav_stat[offset].id & (1 << id))) {
- mdec_cav_stat[offset].canvas_used_flag--;
- mdec_cav_stat[offset].id &= ~(1 << id);
- if (mdec_cav_stat[offset].canvas_used_flag == 0) {
- mdec_cav_stat[offset].type = 0;
- mdec_cav_stat[offset].id = 0;
- }
- if (vdec_get_debug() & 4) {
- pr_debug("free index %d used_flag %d, type = %d, id = %d\n",
- offset,
- mdec_cav_stat[offset].canvas_used_flag,
- mdec_cav_stat[offset].type,
- mdec_cav_stat[offset].id);
- }
- }
- vdec_canvas_unlock(flags);
-
- return;
-}
-
-unsigned long vdec_cav_get_addr(int index)
-{
- if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
- pr_err("%s, error index %d\n", __func__, index);
- return -1;
- }
-
- return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].phy_addr;
-}
-EXPORT_SYMBOL(vdec_cav_get_addr);
-
-unsigned int vdec_cav_get_width(int index)
-{
- if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
- pr_err("%s, error index %d\n", __func__, index);
- return -1;
- }
-
- return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].width;
-}
-EXPORT_SYMBOL(vdec_cav_get_width);
-
-unsigned int vdec_cav_get_height(int index)
-{
- if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
- pr_err("%s, error index %d\n", __func__, index);
- return -1;
- }
- return mdec_cav_pool[index & MDEC_CAV_INDEX_MASK].height;
-}
-EXPORT_SYMBOL(vdec_cav_get_height);
-
-void cav_lut_info_store(u32 index, ulong addr, u32 width,
- u32 height, u32 wrap, u32 blkmode, u32 endian)
-{
- struct canvas_config_s *pool = NULL;
-
- if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
- pr_err("%s, error index %d\n", __func__, index);
- return;
- }
- if (mdec_cav_pool == NULL)
- mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s)
- * (MDEC_CAV_LUT_MAX + 1));
-
- if (mdec_cav_pool == NULL) {
- pr_err("%s failed, mdec_cav_pool null\n", __func__);
- return;
- }
- pool = &mdec_cav_pool[index];
- pool->width = width;
- pool->height = height;
- pool->block_mode = blkmode;
- pool->endian = endian;
- pool->phy_addr = addr;
-}
-
-void config_cav_lut_ex(u32 index, ulong addr, u32 width,
- u32 height, u32 wrap, u32 blkmode,
- u32 endian, enum vdec_type_e core)
-{
- unsigned long datah_temp, datal_temp;
-
- if (!is_support_vdec_canvas()) {
- canvas_config_ex(index, addr, width, height, wrap, blkmode, endian);
- if (vdec_get_debug() & 0x40000000) {
- pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
- __func__, index, addr, width, height, blkmode, endian);
- }
- } else {
- /*
- datal_temp = (cav_lut.start_addr & 0x1fffffff) |
- ((cav_lut.cav_width & 0x7 ) << 29 );
- datah_temp = ((cav_lut.cav_width >> 3) & 0x1ff) |
- (( cav_lut.cav_hight & 0x1fff) <<9 ) |
- ((cav_lut.x_wrap_en & 1) << 22 ) |
- (( cav_lut.y_wrap_en & 1) << 23) |
- (( cav_lut.blk_mode & 0x3) << 24);
- */
- u32 addr_bits_l = ((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) << CAV_WADDR_LBIT);
- u32 width_l = ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CAV_WIDTH_LBIT);
- u32 width_h = ((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) << CAV_WIDTH_HBIT);
- u32 height_h = (height & CANVAS_HEIGHT_MASK) << CAV_HEIGHT_HBIT;
- u32 blkmod_h = (blkmode & CANVAS_BLKMODE_MASK) << CAV_BLKMODE_HBIT;
- u32 switch_bits_ctl = (endian & 0xf) << CAV_ENDIAN_HBIT;
- u32 wrap_h = (0 << 23);
- datal_temp = addr_bits_l | width_l;
- datah_temp = width_h | height_h | wrap_h | blkmod_h | switch_bits_ctl;
-
- if (core == VDEC_1) {
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T3) && (endian == 7))
- WRITE_VREG(MDEC_CAV_CFG0, 0x1ff << 17);
- else
- WRITE_VREG(MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
- WRITE_VREG(MDEC_CAV_LUT_DATAL, datal_temp);
- WRITE_VREG(MDEC_CAV_LUT_DATAH, datah_temp);
- WRITE_VREG(MDEC_CAV_LUT_ADDR, index);
- }
-
- cav_lut_info_store(index, addr, width, height, wrap, blkmode, endian);
-
- if (vdec_get_debug() & 0x40000000) {
- pr_info("%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
- __func__, index, addr, width, height, blkmode, endian);
- pr_info("data(h,l): 0x%8lx, 0x%8lx\n", datah_temp, datal_temp);
- }
- }
-}
-EXPORT_SYMBOL(config_cav_lut_ex);
-
-void config_cav_lut(int index, struct canvas_config_s *cfg,
- enum vdec_type_e core)
-{
- config_cav_lut_ex(index,
- cfg->phy_addr,
- cfg->width,
- cfg->height,
- CANVAS_ADDR_NOWRAP,
- cfg->block_mode,
- cfg->endian,
- core);
-}
-EXPORT_SYMBOL(config_cav_lut);
-
-
-void vdec_canvas_port_register(struct vdec_s *vdec)
-{
- if (is_support_vdec_canvas()) {
- vdec->get_canvas = get_internal_cav_lut;
- vdec->get_canvas_ex = get_internal_cav_lut_ex;
- vdec->free_canvas_ex = free_internal_cav_lut;
- if (mdec_cav_pool == NULL) {
- mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s)
- * (MDEC_CAV_LUT_MAX + 1));
- }
- } else {
- vdec->get_canvas = get_canvas;
- vdec->get_canvas_ex = get_canvas_ex;
- vdec->free_canvas_ex = free_canvas_ex;
- }
-}
-EXPORT_SYMBOL(vdec_canvas_port_register);
diff --git a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h b/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h
deleted file mode 100644
index add83cf..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_canvas_utils.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * drivers/amlogic/media/frame_provider/decoder/utils/vdec_canvas_utils.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#ifndef __CANVAS_UTILS_H__
-#define __CANVAS_UTILS_H__
-
-#include "vdec.h"
-
-/* external canvas */
-struct canvas_status_s {
- int type;
- int canvas_used_flag;
- int id;
-};
-
-#define CANVAS_MAX_SIZE (AMVDEC_CANVAS_MAX1 - AMVDEC_CANVAS_START_INDEX + 1 + AMVDEC_CANVAS_MAX2 + 1)
-
-
-/* internal canvas */
-#define CANVAS_ADDR_LMASK 0x1fffffff
-#define CANVAS_WIDTH_LMASK 0x7
-#define CANVAS_WIDTH_LWID 3
-#define CANVAS_HEIGHT_MASK 0x1fff
-#define CANVAS_BLKMODE_MASK 3
-
-#define CAV_WADDR_LBIT 0
-#define CAV_WIDTH_LBIT 29
-#define CAV_WIDTH_HBIT 0
-#define CAV_HEIGHT_HBIT (41 - 32)
-#define CAV_WRAPX_HBIT (54 - 32)
-#define CAV_WRAPY_HBIT (55 - 32)
-#define CAV_BLKMODE_HBIT (56 - 32)
-#define CAV_ENDIAN_HBIT (58 - 32)
-
-#define MDEC_CAV_LUT_MAX 128
-#define MDEC_CAV_INDEX_MASK 0x7f
-
-enum vdec_type_e;
-
-void config_cav_lut(int index, struct canvas_config_s *cfg, enum vdec_type_e core);
-
-void config_cav_lut_ex(u32 index, ulong addr, u32 width,
- u32 height, u32 wrap, u32 blkmode,
- u32 endian, enum vdec_type_e core);
-
-unsigned int vdec_cav_get_width(int index);
-
-unsigned int vdec_cav_get_height(int index);
-
-unsigned long vdec_cav_get_addr(int index);
-
-bool is_support_vdec_canvas(void);
-
-void vdec_canvas_port_register(struct vdec_s *vdec);
-
-#endif
-
diff --git a/drivers/frame_provider/decoder/utils/vdec_feature.c b/drivers/frame_provider/decoder/utils/vdec_feature.c
deleted file mode 100644
index ea3a75d..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_feature.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * drivers/amlogic/media/stream_input/amports/amstream_profile.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "vdec.h"
-
-
-
-//static const struct codec_profile_t *vcodec_feature[SUPPORT_VDEC_NUM] = { 0 };
-
-struct vcodec_feature {
- int format;
- int is_v4l;
-};
-
-static struct vcodec_feature feature[SUPPORT_VDEC_NUM];
-
-static int vcodec_feature_idx;
-static ulong last_time;
-u8 buf[4096];
-
-
-static const char * const format_name[] = {
- "ammvdec_mpeg12",
- "ammvdec_mpeg4",
- "ammvdec_h264",
- "ammvdec_mjpeg",
- "ammvdec_real",
- "ammjpegdec",
- "ammvdec_vc1",
- "ammvdec_avs",
- "ammvdec_yuv",
- "ammvdec_h264mvc",
- "ammvdec_h264_4k2k",
- "ammvdec_h265",
- "amvenc_avc",
- "jpegenc",
- "ammvdec_vp9",
- "ammvdec_avs2",
- "ammvdec_av1",
-};
-
-static int vcodec_feature_CC(u8 *buf, int size, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
-
- if (!is_v4l) {
- switch (vformat) {
- case VFORMAT_MPEG12:
- case VFORMAT_H264:
- case VFORMAT_AVS:
- pbuf += snprintf(pbuf, size, " \"CC subtitle\" : \"true\"\n");
- break;
- default:
- break;
- }
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_report_information(u8 *buf, int size, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
-
- if (!is_v4l) {
- pbuf += snprintf(pbuf, size, " \"Decoder information report\" : \"true\"\n");
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_i_only_mode(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_MPEG12:
- case VFORMAT_H264:
- case VFORMAT_MPEG4:
- case VFORMAT_HEVC:
- case VFORMAT_AVS2:
- pbuf += snprintf(pbuf, size, " \"I only mode\" : \"true\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_dolbyVison(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_H264:
- case VFORMAT_HEVC:
- case VFORMAT_AV1:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_S4))
- pbuf += snprintf(pbuf, size, " \"DolbyVision\" : \"true\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_HDR(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_H264:
- case VFORMAT_HEVC:
- case VFORMAT_AV1:
- case VFORMAT_AVS2:
- case VFORMAT_VP9:
- pbuf += snprintf(pbuf, size, " \"HDR\" : \"true\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-
-static int vcodec_feature_doublewrite(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
- int tsize = 0;
- int s;
-
- switch (vformat) {
- case VFORMAT_HEVC:
- case VFORMAT_VP9:
- case VFORMAT_AVS2:
- case VFORMAT_AV1:
- s = snprintf(pbuf, size - tsize, " \"DoubleWrite\" ");
- tsize += s;
- pbuf += s;
- if ((get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T7) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T3)) {
- s = snprintf(pbuf, size - tsize, "[ \"0\", \"1\", \"2\", \"3\", \"4\", \"0x10\", \"0x10000\", \"0x20000\"]\n");
- tsize += s;
- pbuf += s;
- }
- else {
- s = snprintf(pbuf, size - tsize, "[ \"0\", \"1\", \"2\", \"3\", \"4\", \"8\", \"0x10\", \"0x10000\", \"0x20000\"]\n");
- tsize += s;
- pbuf += s;
- }
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_vdec_fence(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_H264:
- case VFORMAT_HEVC:
- case VFORMAT_VP9:
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- pbuf += snprintf(pbuf, size, " \"GameMode\" : \"true\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_bitdepth(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_HEVC:
- case VFORMAT_VP9:
- case VFORMAT_AVS2:
- case VFORMAT_AV1:
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- pbuf += snprintf(pbuf, size, " \"BitDepth\" : \"10\"\n");
- else
- pbuf += snprintf(pbuf, size, " \"BitDepth\" : \"8\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-
-static int vcodec_feature_MaxResolution(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_HEVC:
- case VFORMAT_VP9:
- case VFORMAT_AVS2:
- case VFORMAT_AV1:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"8k\"\n");
- else if (vdec_is_support_4k() &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"4k60\"\n");
- else
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n");
- break;
- case VFORMAT_H264:
- if (vdec_is_support_4k())
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"4k30\"\n");
- else
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n");
- break;
- case VFORMAT_MPEG12:
- case VFORMAT_MPEG4:
- case VFORMAT_MJPEG:
- case VFORMAT_VC1:
- case VFORMAT_AVS:
- pbuf += snprintf(pbuf, size, " \"MaximumResolution\" : \"1080p60\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_clock(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- switch (vformat) {
- case VFORMAT_HEVC:
- case VFORMAT_VP9:
- case VFORMAT_AVS2:
- case VFORMAT_AV1:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12B) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_GXLX2) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"800MHZ\"\n");
- else
- pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"667MHZ\"\n");
- break;
- case VFORMAT_H264:
- case VFORMAT_MPEG12:
- case VFORMAT_MPEG4:
- case VFORMAT_MJPEG:
- case VFORMAT_VC1:
- case VFORMAT_AVS:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_GXLX2) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"800MHZ\"\n");
- else
- pbuf += snprintf(pbuf, size, " \"ClockFrequency\" : \"667MHZ\"\n");
- break;
- default:
- break;
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_support_format(int vformat)
-{
-
- switch (vformat) {
- case VFORMAT_VP9:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5))
- return 1;
- else
- return 0;
- case VFORMAT_AVS2:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
- return 1;
- else
- return 0;
- case VFORMAT_AV1:
- if (((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) &&
- is_cpu_tm2_revb()) ||
- ((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5)))
- return 1;
- else
- return 0;
- case VFORMAT_AVS:
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM))
- return 1;
- else
- return 0;
- case VFORMAT_MJPEG:
- case VFORMAT_VC1:
- case VFORMAT_MPEG4:
- case VFORMAT_MPEG12:
- case VFORMAT_H264:
- case VFORMAT_HEVC:
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-static int vcodec_feature_FCC(u8 *buf, int size, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
-
- if (!is_v4l) {
- switch (vformat) {
- case VFORMAT_HEVC:
- case VFORMAT_H264:
- case VFORMAT_MPEG12:
- pbuf += snprintf(pbuf, size, " \"Decoder FCC support\" : \"true\"\n");
- break;
- default:
- break;
- }
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_RDMA(u8 *buf, int size, int vformat)
-{
- u8 *pbuf = buf;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3)
- pbuf += snprintf(pbuf, size, " \"Decoder RDMA support\" : \"true\"\n");
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_v4ldec_nr(u8 *buf, int size, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
-
- if (is_v4l) {
- pbuf += snprintf(pbuf, size, " \"V4ldec nr\" : \"true\"\n");
- }
-
- return pbuf - buf;
-}
-
-static int vcodec_feature_ge2d_wrapper(u8 *buf, int size, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
-
- if (is_v4l && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)) {
- pbuf += snprintf(pbuf, size, " \"Ge2d wrapper\" : \"true\"\n");
- }
-
- return pbuf - buf;
-}
-
-
-
-int vcodec_feature_get_feature(u8 *buf, int vformat, int is_v4l)
-{
- u8 *pbuf = buf;
- int size = PAGE_SIZE;
- int tsize = 0;
- int s;
-
- s = snprintf(pbuf, size - tsize, " \"%s%s\": ", format_name[vformat], is_v4l ? "_v4l" : "");
- tsize += s;
- pbuf += s;
-
- s = snprintf(pbuf, size - tsize, "{\n");
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_CC(pbuf, size - tsize, vformat, is_v4l);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_report_information(pbuf, size - tsize, vformat, is_v4l);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_vdec_fence(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_i_only_mode(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_dolbyVison(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_HDR(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_doublewrite(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_bitdepth(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_MaxResolution(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_clock(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_FCC(pbuf, size - tsize, vformat, is_v4l);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_RDMA(pbuf, size - tsize, vformat);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_v4ldec_nr(pbuf, size - tsize, vformat, is_v4l);
- tsize += s;
- pbuf += s;
-
- s = vcodec_feature_ge2d_wrapper(pbuf, size - tsize, vformat, is_v4l);
- tsize += s;
- pbuf += s;
-
- s = snprintf(pbuf, size - tsize, " \"UcodeVersionRequest\" : \"0.3.10\"\n");
- tsize += s;
- pbuf += s;
-
- s = snprintf(pbuf, size - tsize, " }\n");
- tsize += s;
- pbuf += s;
-
- return pbuf - buf;
-}
-
-
-ssize_t vcodec_feature_read(char *buf)
-{
- static int read_count;
- char *pbuf = buf;
-
- if (jiffies - last_time > 5 * HZ) {
- read_count = 0;
- /*timeout :not continue dump,dump from first. */
- }
-
- if (vcodec_feature_idx > 0) {
- if (read_count == 0)
- pbuf += snprintf(pbuf, PAGE_SIZE - (pbuf - buf), "{\n");
- pbuf += vcodec_feature_get_feature(pbuf, feature[read_count].format, feature[read_count].is_v4l);
- read_count++;
- if (read_count >= vcodec_feature_idx) {
- read_count = 0;
- pbuf += snprintf(pbuf, PAGE_SIZE - (pbuf - buf), "}");
- }
- }
- last_time = jiffies;
- return pbuf - buf;
-}
-EXPORT_SYMBOL(vcodec_feature_read);
-
-
-int vcodec_feature_register(int vformat, int is_v4l)
-{
- if ((vcodec_feature_idx < SUPPORT_VDEC_NUM) && vcodec_feature_support_format(vformat)) {
- feature[vcodec_feature_idx].format = vformat;
- feature[vcodec_feature_idx].is_v4l = is_v4l;
- vcodec_feature_idx++;
- //pr_debug("regist %s codec profile\n", vdec_profile->name);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(vcodec_feature_register);
-
-
-
diff --git a/drivers/frame_provider/decoder/utils/vdec_feature.h b/drivers/frame_provider/decoder/utils/vdec_feature.h
deleted file mode 100644
index a2918fd..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_feature.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * drivers/amlogic/amports/vdec_profile.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
-*/
-
-#ifndef VDEC_FEATURE_H
-#define VDEC_FEATURE_H
-
-int vcodec_feature_register(int vformat, int is_v4l);
-
-ssize_t vcodec_feature_read(char *buf);
-
-
-
-#endif /* VDEC_FEATURE_H */
diff --git a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c b/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c
deleted file mode 100644
index 08cd0d7..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Description:
- */
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/amlogic/media/ge2d/ge2d.h>
-#include <linux/amlogic/media/canvas/canvas_mgr.h>
-#include "vdec.h"
-#include "vdec_ge2d_utils.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-
-static u32 vdec_ge2d_debug = 0;
-
-#ifndef CONFIG_AMLOGIC_MEDIA_GE2D
-inline struct ge2d_context_s *create_ge2d_work_queue(void) { return NULL; }
-inline int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { return -1; }
-#endif
-
-enum videocom_source_type {
- DECODER_8BIT_NORMAL = 0,
- DECODER_8BIT_BOTTOM,
- DECODER_8BIT_TOP,
- DECODER_10BIT_NORMAL,
- DECODER_10BIT_BOTTOM,
- DECODER_10BIT_TOP
-};
-
-static void vdec_canvas_cache_free(struct vdec_canvas_cache *canche)
-{
- int i = -1;
-
- for (i = 0; i < ARRAY_SIZE(canche->res); i++) {
- if (canche->res[i].cid > 0) {
- if (vdec_ge2d_debug)
- pr_info("canvas-free, name:%s, canvas id:%d\n",
- canche->res[i].name,
- canche->res[i].cid);
-
- canvas_pool_map_free_canvas(canche->res[i].cid);
-
- canche->res[i].cid = 0;
- }
- }
-}
-
-static void vdec_canvas_cache_put(struct vdec_ge2d *ge2d)
-{
- struct vdec_canvas_cache *canche = &ge2d->canche;
-
- mutex_lock(&canche->lock);
-
- pr_info("canvas-put, ref:%d\n", canche->ref);
-
- canche->ref--;
-
- if (canche->ref == 0) {
- vdec_canvas_cache_free(canche);
- }
-
- mutex_unlock(&canche->lock);
-}
-
-static int vdec_canvas_cache_get(struct vdec_ge2d *ge2d, char *usr)
-{
- struct vdec_canvas_cache *canche = &ge2d->canche;
- int i;
-
- mutex_lock(&canche->lock);
-
- canche->ref++;
-
- for (i = 0; i < ARRAY_SIZE(canche->res); i++) {
- if (canche->res[i].cid <= 0) {
- snprintf(canche->res[i].name, 32, "%s-%d", usr, i);
- canche->res[i].cid =
- canvas_pool_map_alloc_canvas(canche->res[i].name);
- }
-
- if (vdec_ge2d_debug)
- pr_info("canvas-alloc, name:%s, canvas id:%d\n",
- canche->res[i].name,
- canche->res[i].cid);
-
- if (canche->res[i].cid <= 0) {
- pr_err("canvas-fail, name:%s, canvas id:%d.\n",
- canche->res[i].name,
- canche->res[i].cid);
-
- mutex_unlock(&canche->lock);
- goto err;
- }
- }
-
- if (vdec_ge2d_debug)
- pr_info("canvas-get, ref:%d\n", canche->ref);
-
- mutex_unlock(&canche->lock);
- return 0;
-err:
- vdec_canvas_cache_put(ge2d);
- return -1;
-}
-
-static int vdec_canvas_cache_init(struct vdec_ge2d *ge2d)
-{
- ge2d->canche.ref = 0;
- mutex_init(&ge2d->canche.lock);
-
- pr_info("canvas-init, ref:%d\n", ge2d->canche.ref);
-
- return 0;
-}
-
-static int get_source_type(struct vframe_s *vf)
-{
- enum videocom_source_type ret;
- int interlace_mode;
-
- interlace_mode = vf->type & VIDTYPE_TYPEMASK;
-
- if ((vf->bitdepth & BITDEPTH_Y10) &&
- (!(vf->type & VIDTYPE_COMPRESS)) &&
- (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) {
- if (interlace_mode == VIDTYPE_INTERLACE_TOP)
- ret = DECODER_10BIT_TOP;
- else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
- ret = DECODER_10BIT_BOTTOM;
- else
- ret = DECODER_10BIT_NORMAL;
- } else {
- if (interlace_mode == VIDTYPE_INTERLACE_TOP)
- ret = DECODER_8BIT_TOP;
- else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
- ret = DECODER_8BIT_BOTTOM;
- else
- ret = DECODER_8BIT_NORMAL;
- }
-
- return ret;
-}
-
-static int get_input_format(struct vframe_s *vf)
-{
- int format = GE2D_FORMAT_M24_YUV420;
- enum videocom_source_type soure_type;
-
- soure_type = get_source_type(vf);
-
- switch (soure_type) {
- case DECODER_8BIT_NORMAL:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422;
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21;
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12;
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444;
- else
- format = GE2D_FORMAT_M24_YUV420;
- break;
- case DECODER_8BIT_BOTTOM:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422
- | (GE2D_FORMAT_S16_YUV422B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21
- | (GE2D_FORMAT_M24_NV21B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12
- | (GE2D_FORMAT_M24_NV12B & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444
- | (GE2D_FORMAT_S24_YUV444B & (3 << 3));
- else
- format = GE2D_FORMAT_M24_YUV420
- | (GE2D_FMT_M24_YUV420B & (3 << 3));
- break;
- case DECODER_8BIT_TOP:
- if (vf->type & VIDTYPE_VIU_422)
- format = GE2D_FORMAT_S16_YUV422
- | (GE2D_FORMAT_S16_YUV422T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV21)
- format = GE2D_FORMAT_M24_NV21
- | (GE2D_FORMAT_M24_NV21T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_NV12)
- format = GE2D_FORMAT_M24_NV12
- | (GE2D_FORMAT_M24_NV12T & (3 << 3));
- else if (vf->type & VIDTYPE_VIU_444)
- format = GE2D_FORMAT_S24_YUV444
- | (GE2D_FORMAT_S24_YUV444T & (3 << 3));
- else
- format = GE2D_FORMAT_M24_YUV420
- | (GE2D_FMT_M24_YUV420T & (3 << 3));
- break;
- case DECODER_10BIT_NORMAL:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422;
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422;
- }
- break;
- case DECODER_10BIT_BOTTOM:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422
- | (GE2D_FORMAT_S16_10BIT_YUV422B
- & (3 << 3));
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422
- | (GE2D_FORMAT_S16_12BIT_YUV422B
- & (3 << 3));
- }
- break;
- case DECODER_10BIT_TOP:
- if (vf->type & VIDTYPE_VIU_422) {
- if (vf->bitdepth & FULL_PACK_422_MODE)
- format = GE2D_FORMAT_S16_10BIT_YUV422
- | (GE2D_FORMAT_S16_10BIT_YUV422T
- & (3 << 3));
- else
- format = GE2D_FORMAT_S16_12BIT_YUV422
- | (GE2D_FORMAT_S16_12BIT_YUV422T
- & (3 << 3));
- }
- break;
- default:
- format = GE2D_FORMAT_M24_YUV420;
- }
- return format;
-}
-
-int vdec_ge2d_init(struct vdec_ge2d** ge2d_handle, int mode)
-{
- int ret;
- struct vdec_ge2d *ge2d;
-
- if (!ge2d_handle)
- return -EINVAL;
-
- ge2d = kzalloc(sizeof(*ge2d), GFP_KERNEL);
- if (!ge2d)
- return -ENOMEM;
-
- vdec_canvas_cache_init(ge2d);
-
- ge2d->work_mode = mode;
- if (!ge2d->work_mode) {
- ge2d->work_mode = GE2D_MODE_CONVERT_LE;
- }
- pr_info("vdec_ge2d_init work_mode:%d\n", ge2d->work_mode);
-
- ge2d->ge2d_context = create_ge2d_work_queue();
- if (!ge2d->ge2d_context) {
- pr_err("ge2d_create_instance fail\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (vdec_canvas_cache_get(ge2d, "vdec-ge2d-dec") < 0) {
- pr_err("canvas pool alloc fail. src(%d, %d, %d) dst(%d, %d, %d).\n",
- ge2d->canche.res[0].cid,
- ge2d->canche.res[1].cid,
- ge2d->canche.res[2].cid,
- ge2d->canche.res[3].cid,
- ge2d->canche.res[4].cid,
- ge2d->canche.res[5].cid);
- ret = -ENOMEM;
- goto error1;
- }
-
- *ge2d_handle = ge2d;
-
- return 0;
-error1:
- destroy_ge2d_work_queue(ge2d->ge2d_context);
-error:
- kfree(ge2d);
-
- return ret;
-}
-EXPORT_SYMBOL(vdec_ge2d_init);
-
-int vdec_ge2d_copy_data(struct vdec_ge2d *ge2d, struct vdec_ge2d_info *ge2d_info)
-{
- struct config_para_ex_s ge2d_config;
- u32 src_fmt = 0, dst_fmt = 0;
- struct canvas_s cd;
-
- if (!ge2d)
- return -1;
-
- if (vdec_ge2d_debug)
- pr_info("vdec_ge2d_copy_data start\n");
-
- memset(&ge2d_config, 0, sizeof(ge2d_config));
-
- src_fmt = get_input_format(ge2d_info->dst_vf);
- if (ge2d_info->src_canvas0_config[0].endian == 7)
- src_fmt |= GE2D_BIG_ENDIAN;
- else
- src_fmt |= GE2D_LITTLE_ENDIAN;
-
- /* negotiate format of destination */
- dst_fmt = get_input_format(ge2d_info->dst_vf);
- if (ge2d->work_mode & GE2D_MODE_CONVERT_NV12)
- dst_fmt |= GE2D_FORMAT_M24_NV12;
- else if (ge2d->work_mode & GE2D_MODE_CONVERT_NV21)
- dst_fmt |= GE2D_FORMAT_M24_NV21;
-
- if (ge2d->work_mode & GE2D_MODE_CONVERT_LE)
- dst_fmt |= GE2D_LITTLE_ENDIAN;
- else
- dst_fmt |= GE2D_BIG_ENDIAN;
-
- if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV12) {
- ge2d_info->dst_vf->type |= VIDTYPE_VIU_NV12;
- ge2d_info->dst_vf->type &= ~VIDTYPE_VIU_NV21;
- } else if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV21) {
- ge2d_info->dst_vf->type |= VIDTYPE_VIU_NV21;
- ge2d_info->dst_vf->type &= ~VIDTYPE_VIU_NV12;
- }
- if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_LITTLE_ENDIAN) {
- ge2d_info->dst_vf->canvas0_config[0].endian = 0;
- ge2d_info->dst_vf->canvas0_config[1].endian = 0;
- ge2d_info->dst_vf->canvas0_config[2].endian = 0;
- } else if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_BIG_ENDIAN){
- ge2d_info->dst_vf->canvas0_config[0].endian = 7;
- ge2d_info->dst_vf->canvas0_config[1].endian = 7;
- ge2d_info->dst_vf->canvas0_config[2].endian = 7;
- }
-
- ge2d_info->dst_vf->mem_sec = ge2d_info->dst_vf->flag & VFRAME_FLAG_VIDEO_SECURE ? 1 : 0;
-
- mutex_lock(&ge2d->canche.lock);
-
- /* src canvas configure. */
- if ((ge2d_info->dst_vf->canvas0Addr == 0) ||
- (ge2d_info->dst_vf->canvas0Addr == (u32)-1)) {
- canvas_config_config(ge2d->canche.res[0].cid, &ge2d_info->src_canvas0_config[0]);
- canvas_config_config(ge2d->canche.res[1].cid, &ge2d_info->src_canvas0_config[1]);
- canvas_config_config(ge2d->canche.res[2].cid, &ge2d_info->src_canvas0_config[2]);
- ge2d_config.src_para.canvas_index =
- ge2d->canche.res[0].cid |
- ge2d->canche.res[1].cid << 8 |
- ge2d->canche.res[2].cid << 16;
-
- ge2d_config.src_planes[0].addr =
- ge2d_info->src_canvas0_config[0].phy_addr;
- ge2d_config.src_planes[0].w =
- ge2d_info->src_canvas0_config[0].width;
- ge2d_config.src_planes[0].h =
- ge2d_info->src_canvas0_config[0].height;
- ge2d_config.src_planes[1].addr =
- ge2d_info->src_canvas0_config[1].phy_addr;
- ge2d_config.src_planes[1].w =
- ge2d_info->src_canvas0_config[1].width;
- ge2d_config.src_planes[1].h =
- ge2d_info->src_canvas0_config[1].height;
- ge2d_config.src_planes[2].addr =
- ge2d_info->src_canvas0_config[2].phy_addr;
- ge2d_config.src_planes[2].w =
- ge2d_info->src_canvas0_config[2].width;
- ge2d_config.src_planes[2].h =
- ge2d_info->src_canvas0_config[2].height;
- } else {
- ge2d_config.src_para.canvas_index = ge2d_info->src_canvas0Addr;
- }
- ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.src_para.format = src_fmt;
- ge2d_config.src_para.fill_color_en = 0;
- ge2d_config.src_para.fill_mode = 0;
- ge2d_config.src_para.x_rev = 0;
- ge2d_config.src_para.y_rev = 0;
- ge2d_config.src_para.color = 0xffffffff;
- ge2d_config.src_para.top = 0;
- ge2d_config.src_para.left = 0;
- ge2d_config.src_para.width = ge2d_info->dst_vf->width;
- if (ge2d_info->dst_vf->type & VIDTYPE_INTERLACE)
- ge2d_config.src_para.height = ge2d_info->dst_vf->height >> 1;
- else
- ge2d_config.src_para.height = ge2d_info->dst_vf->height;
-
- /* dst canvas configure. */
- canvas_config_config(ge2d->canche.res[3].cid, &ge2d_info->dst_vf->canvas0_config[0]);
- if ((ge2d_config.src_para.format & 0xfffff) == GE2D_FORMAT_M24_YUV420) {
- ge2d_info->dst_vf->canvas0_config[1].width <<= 1;
- }
- canvas_config_config(ge2d->canche.res[4].cid, &ge2d_info->dst_vf->canvas0_config[1]);
- canvas_config_config(ge2d->canche.res[5].cid, &ge2d_info->dst_vf->canvas0_config[2]);
- ge2d_config.dst_para.canvas_index =
- ge2d->canche.res[3].cid |
- ge2d->canche.res[4].cid << 8;
- canvas_read(ge2d->canche.res[3].cid, &cd);
- ge2d_config.dst_planes[0].addr = cd.addr;
- ge2d_config.dst_planes[0].w = cd.width;
- ge2d_config.dst_planes[0].h = cd.height;
- canvas_read(ge2d->canche.res[4].cid, &cd);
- ge2d_config.dst_planes[1].addr = cd.addr;
- ge2d_config.dst_planes[1].w = cd.width;
- ge2d_config.dst_planes[1].h = cd.height;
-
- ge2d_config.dst_para.format = dst_fmt;
- ge2d_config.dst_para.width = ge2d_info->dst_vf->width;
- ge2d_config.dst_para.height = ge2d_info->dst_vf->height;
- ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.dst_para.fill_color_en = 0;
- ge2d_config.dst_para.fill_mode = 0;
- ge2d_config.dst_para.x_rev = 0;
- ge2d_config.dst_para.y_rev = 0;
- ge2d_config.dst_para.color = 0;
- ge2d_config.dst_para.top = 0;
- ge2d_config.dst_para.left = 0;
-
- /* other ge2d parameters configure. */
- ge2d_config.src_key.key_enable = 0;
- ge2d_config.src_key.key_mask = 0;
- ge2d_config.src_key.key_mode = 0;
- ge2d_config.alu_const_color = 0;
- ge2d_config.bitmask_en = 0;
- ge2d_config.src1_gb_alpha = 0;
- ge2d_config.dst_xy_swap = 0;
- ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
- ge2d_config.mem_sec = ge2d_info->dst_vf->flag & VFRAME_FLAG_VIDEO_SECURE ? 1 : 0;
-
- if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) {
- pr_err("vdec_ge2d_context_config_ex error.\n");
- mutex_unlock(&ge2d->canche.lock);
- return -1;
- }
-
- if (!(ge2d_info->dst_vf->type & VIDTYPE_V4L_EOS)) {
- if (ge2d_info->dst_vf->type & VIDTYPE_INTERLACE) {
- stretchblt_noalpha(ge2d->ge2d_context,
- 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height / 2,
- 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height);
- } else {
- stretchblt_noalpha(ge2d->ge2d_context,
- 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height,
- 0, 0, ge2d_info->dst_vf->width, ge2d_info->dst_vf->height);
- }
- }
- mutex_unlock(&ge2d->canche.lock);
- if (vdec_ge2d_debug)
- pr_info("vdec_ge2d_copy_data done\n");
-
- return 0;
-}
-EXPORT_SYMBOL(vdec_ge2d_copy_data);
-
-int vdec_ge2d_destroy(struct vdec_ge2d *ge2d)
-{
- if (!ge2d)
- return -1;
-
- pr_info("vdec ge2d destroy begin\n");
-
- destroy_ge2d_work_queue(ge2d->ge2d_context);
- vdec_canvas_cache_put(ge2d);
- kfree(ge2d);
-
- pr_info("vdec ge2d destroy done\n");
-
- return 0;
-}
-EXPORT_SYMBOL(vdec_ge2d_destroy);
-
-module_param(vdec_ge2d_debug, int, 0664);
-MODULE_PARM_DESC(vdec_ge2d_debug, "\n vdec_ge2d_debug\n");
diff --git a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h b/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h
deleted file mode 100644
index 31018f7..0000000
--- a/drivers/frame_provider/decoder/utils/vdec_ge2d_utils.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Description:
- */
-#ifndef __GE2D_UTILS_H__
-#define __GE2D_UTILS_H__
-
-//#include "../../../amvdec_ports/aml_vcodec_drv.h"
-#include <linux/amlogic/media/vfm/vframe.h>
-
-
-/* define ge2d work mode. */
-#define GE2D_MODE_CONVERT_NV12 (1 << 0)
-#define GE2D_MODE_CONVERT_NV21 (1 << 1)
-#define GE2D_MODE_CONVERT_LE (1 << 2)
-#define GE2D_MODE_CONVERT_BE (1 << 3)
-#define GE2D_MODE_SEPARATE_FIELD (1 << 4)
-#define GE2D_MODE_422_TO_420 (1 << 5)
-
-struct vdec_canvas_res {
- int cid;
- u8 name[32];
-};
-
-struct vdec_canvas_cache {
- int ref;
- struct vdec_canvas_res res[6];
- struct mutex lock;
-};
-
-struct vdec_ge2d {
- u32 work_mode; /* enum ge2d_work_mode */
- struct ge2d_context_s *ge2d_context; /* handle of GE2D */
- struct aml_vcodec_ctx *ctx;
- struct vdec_canvas_cache canche;
- void *hw;
-};
-
-struct vdec_ge2d_info {
- struct vframe_s *dst_vf;
- u32 src_canvas0Addr;
- u32 src_canvas1Addr;;
- struct canvas_config_s src_canvas0_config[3];
- struct canvas_config_s src_canvas1_config[3];
-};
-
-int vdec_ge2d_init(struct vdec_ge2d** ge2d_handle, int mode);
-
-int vdec_ge2d_copy_data(struct vdec_ge2d *ge2d, struct vdec_ge2d_info *ge2d_info);
-
-int vdec_ge2d_destroy(struct vdec_ge2d *ge2d);
-
-#endif
-
diff --git a/drivers/frame_provider/decoder/utils/vdec_input.c b/drivers/frame_provider/decoder/utils/vdec_input.c
index 6fec0ad..5deb374 100644
--- a/drivers/frame_provider/decoder/utils/vdec_input.c
+++ b/drivers/frame_provider/decoder/utils/vdec_input.c
@@ -20,12 +20,15 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
#include "../../../stream_input/amports/amports_priv.h"
#include "vdec.h"
#include "vdec_input.h"
+
#include <asm/cacheflush.h>
#include <linux/crc32.h>
+
#define VFRAME_BLOCK_SIZE (512 * SZ_1K)/*512 for 1080p default init.*/
#define VFRAME_BLOCK_SIZE_4K (2 * SZ_1M) /*2M for 4K default.*/
#define VFRAME_BLOCK_SIZE_MAX (4 * SZ_1M)
@@ -61,7 +64,7 @@
{
int ret =0;
- if (likely(access_ok(from, n)))
+ if (likely(access_ok(VERIFY_READ, from, n)))
ret = copy_from_user(to, from, n);
else
memcpy(to, from, n);
@@ -345,7 +348,6 @@
char sbuf[512];
int tsize = 0;
int s;
-
if (!pbuf) {
pbuf = sbuf;
size = 512;
@@ -432,7 +434,6 @@
s += vdec_input_dump_block_locked(block, lbuf, size - s);
}
vdec_input_unlock(input, flags);
-
return s;
}
@@ -445,7 +446,6 @@
char sbuf[512];
int tsize = 0;
int s;
-
if (!pbuf) {
pbuf = sbuf;
size = 512;
@@ -492,7 +492,6 @@
if (size <= 0)
return 0;
-
if (!bufs)
lbuf = sbuf;
s = snprintf(lbuf + s, size - s,
@@ -523,7 +522,6 @@
break;
}
vdec_input_unlock(input, flags);
-
return s;
}
@@ -551,7 +549,6 @@
if (input->swap_page_phys == 0)
return -ENOMEM;
-
return 0;
}
EXPORT_SYMBOL(vdec_input_set_buffer);
@@ -791,7 +788,6 @@
struct vframe_chunk_s *chunk;
struct vdec_s *vdec = input->vdec;
struct vframe_block_list_s *block;
-
int need_pading_size = MIN_FRAME_PADDING_SIZE;
if (vdec_secure(vdec)) {
@@ -1216,3 +1212,5 @@
return handle;
}
EXPORT_SYMBOL(vdec_input_get_freed_handle);
+
+
diff --git a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c
index e43c45a..9057a80 100644
--- a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c
+++ b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.c
@@ -19,10 +19,8 @@
#include "vdec_power_ctrl.h"
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/power_ctrl.h>
-//#include <dt-bindings/power/sc2-pd.h>
-//#include <linux/amlogic/pwr_ctrl.h>
-#include <linux/amlogic/power_domain.h>
#include <dt-bindings/power/sc2-pd.h>
+#include <linux/amlogic/pwr_ctrl.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../../../common/media_clock/switch/amports_gate.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
@@ -31,12 +29,6 @@
#define HEVC_TEST_LIMIT (100)
#define GXBB_REV_A_MINOR (0xa)
-#define PDID_DSP 0
-#define PDID_DOS_HCODEC 1
-#define PDID_DOS_HEVC 2
-#define PDID_DOS_VDEC 3
-#define PDID_DOS_WAVE 4
-
extern int no_powerdown;
extern int hevc_max_reset_count;
@@ -144,20 +136,14 @@
hcodec_clock_enable();
} else if (id == VDEC_HEVC) {
/* enable hevc clock */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2 &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)
amports_switch_gate("clk_hevcf_mux", 1);
else
amports_switch_gate("clk_hevc_mux", 1);
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- !is_hevc_front_back_clk_combined())
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
amports_switch_gate("clk_hevcb_mux", 1);
-
hevc_clock_hi_enable();
-
- if (!is_hevc_front_back_clk_combined())
- hevc_back_clock_hi_enable();
+ hevc_back_clock_hi_enable();
}
}
@@ -170,8 +156,7 @@
} else if (id == VDEC_HEVC) {
/* disable hevc clock */
hevc_clock_off();
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- !is_hevc_front_back_clk_combined())
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
hevc_back_clock_off();
}
}
@@ -708,6 +693,7 @@
pm_vdec_clock_on(id);
pwr_ctrl_psci_smc(pd_id, PWR_ON);
+
}
static void pm_vdec_pd_sec_api_power_off(struct device *dev, int id)
@@ -734,7 +720,7 @@
#if 0
int pd_id = (id == VDEC_1) ? PM_DOS_VDEC :
(id == VDEC_HEVC) ? PM_DOS_HEVC :
- PM_DOS_HCODEC;
+ PM_DOS_HCODEC;
pm_vdec_clock_on(id);
power_domain_switch(pd_id, PWR_ON);
diff --git a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h
index e7ab77e..53545f8 100644
--- a/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h
+++ b/drivers/frame_provider/decoder/utils/vdec_power_ctrl.h
@@ -90,10 +90,10 @@
#define DL_FLAG_RPM_ACTIVE BIT(3)
#define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4)
-struct device_link {
- u32 flags;
- /* ... */
-};
+//struct device_link {
+// u32 flags;
+// /* ... */
+//};
static inline struct device *dev_pm_domain_attach_by_name(struct device *dev,
const char *name)
diff --git a/drivers/frame_provider/decoder/utils/vdec_profile.c b/drivers/frame_provider/decoder/utils/vdec_profile.c
index dfffeb1..94f8b8f 100644
--- a/drivers/frame_provider/decoder/utils/vdec_profile.c
+++ b/drivers/frame_provider/decoder/utils/vdec_profile.c
@@ -20,12 +20,14 @@
#include <linux/types.h>
#include <linux/debugfs.h>
#include <linux/moduleparam.h>
-#include <linux/sched/clock.h>
+
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <trace/events/meson_atrace.h>
#include "vdec_profile.h"
#include "vdec.h"
+
#define ISA_TIMERE 0x2662
#define ISA_TIMERE_HI 0x2663
@@ -110,7 +112,11 @@
static u64 get_us_time_system(void)
{
- return div64_u64(local_clock(), 1000);
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+
+ return div64_u64(timeval_to_ns(&tv), 1000);
}
static void vdec_profile_update_alloc_time(
diff --git a/drivers/frame_provider/decoder/utils/vdec_sync.c b/drivers/frame_provider/decoder/utils/vdec_sync.c
index b4192f6..314a4f0 100644
--- a/drivers/frame_provider/decoder/utils/vdec_sync.c
+++ b/drivers/frame_provider/decoder/utils/vdec_sync.c
@@ -21,24 +21,15 @@
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/sched/clock.h>
#include <linux/sync_file.h>
#include "vdec_sync.h"
#define VDEC_DBG_ENABLE_FENCE (0x100)
-#define VDEC_SYNC_COUNT 32
-struct vdec_sync_core_s {
- struct vdec_sync s_vdec_sync[VDEC_SYNC_COUNT];
- spinlock_t vdec_sync_lock;
-};
+extern u32 debug;
-static struct vdec_sync_core_s vdec_sync_core;
-
-extern u32 vdec_get_debug(void);
-
-static const struct dma_fence_ops timeline_fence_ops;
-static inline struct sync_pt *fence_to_sync_pt(struct dma_fence *fence)
+static const struct fence_ops timeline_fence_ops;
+static inline struct sync_pt *fence_to_sync_pt(struct fence *fence)
{
if (fence->ops != &timeline_fence_ops)
return NULL;
@@ -61,7 +52,7 @@
return NULL;
kref_init(&obj->kref);
- obj->context = dma_fence_context_alloc(1);
+ obj->context = fence_context_alloc(1);
obj->timestamp = local_clock();
strlcpy(obj->name, name, sizeof(obj->name));
INIT_LIST_HEAD(&obj->active_list_head);
@@ -75,12 +66,9 @@
{
struct sync_timeline *obj =
container_of(kref, struct sync_timeline, kref);
- struct vdec_sync *sync = obj->parent_sync;
pr_info("[VDEC-FENCE] free timeline: %lx\n", (ulong) obj);
kfree(obj);
- atomic_set(&sync->use_flag, 0);
- sync->timeline = NULL;
}
static void sync_timeline_get(struct sync_timeline *obj)
@@ -93,21 +81,21 @@
kref_put(&obj->kref, sync_timeline_free);
}
-static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
+static const char *timeline_fence_get_driver_name(struct fence *fence)
{
struct sync_timeline *parent = fence_parent(fence);
return parent->name;
}
-static const char *timeline_fence_get_timeline_name(struct dma_fence *fence)
+static const char *timeline_fence_get_timeline_name(struct fence *fence)
{
struct sync_timeline *parent = fence_parent(fence);
return parent->name;
}
-static void timeline_fence_release(struct dma_fence *fence)
+static void timeline_fence_release(struct fence *fence)
{
struct sync_pt *pt = fence_to_sync_pt(fence);
struct sync_timeline *parent = fence_parent(fence);
@@ -121,15 +109,15 @@
list_del(&pt->active_list);
spin_unlock_irqrestore(fence->lock, flags);
sync_timeline_put(parent);
- dma_fence_free(fence);
+ fence_free(fence);
}
-static bool timeline_fence_signaled(struct dma_fence *fence)
+static bool timeline_fence_signaled(struct fence *fence)
{
struct sync_timeline *parent = fence_parent(fence);
struct sync_pt *pt = get_sync_pt(fence);
- if (__dma_fence_is_later(fence->seqno, parent->value, fence->ops))
+ if (__fence_is_later(fence->seqno, parent->value))
return false;
if (pt->timestamp > parent->timestamp)
@@ -138,7 +126,7 @@
return true;
}
-static bool timeline_fence_enable_signaling(struct dma_fence *fence)
+static bool timeline_fence_enable_signaling(struct fence *fence)
{
struct sync_pt *pt = container_of(fence, struct sync_pt, fence);
struct sync_timeline *parent = fence_parent(fence);
@@ -150,22 +138,20 @@
return true;
}
-#if 0
-static void timeline_fence_disable_signaling(struct dma_fence *fence)
+static void timeline_fence_disable_signaling(struct fence *fence)
{
struct sync_pt *pt = container_of(fence, struct sync_pt, fence);
list_del_init(&pt->active_list);
}
-#endif
-static void timeline_fence_value_str(struct dma_fence *fence,
+static void timeline_fence_value_str(struct fence *fence,
char *str, int size)
{
- snprintf(str, size, "%llu", fence->seqno);
+ snprintf(str, size, "%d", fence->seqno);
}
-static void timeline_fence_timeline_value_str(struct dma_fence *fence,
+static void timeline_fence_timeline_value_str(struct fence *fence,
char *str, int size)
{
struct sync_timeline *parent = fence_parent(fence);
@@ -173,13 +159,13 @@
snprintf(str, size, "%d", parent->value);
}
-static const struct dma_fence_ops timeline_fence_ops = {
+static const struct fence_ops timeline_fence_ops = {
.get_driver_name = timeline_fence_get_driver_name,
.get_timeline_name = timeline_fence_get_timeline_name,
.enable_signaling = timeline_fence_enable_signaling,
- //.disable_signaling = timeline_fence_disable_signaling,
+ .disable_signaling = timeline_fence_disable_signaling,
.signaled = timeline_fence_signaled,
- .wait = dma_fence_default_wait,
+ .wait = fence_default_wait,
.release = timeline_fence_release,
.fence_value_str = timeline_fence_value_str,
.timeline_value_str = timeline_fence_timeline_value_str,
@@ -202,7 +188,7 @@
obj->value += inc;
list_for_each_entry_safe(pt, next, &obj->active_list_head,
active_list) {
- if (dma_fence_is_signaled_locked(&pt->fence))
+ if (fence_is_signaled(&pt->fence))
list_del_init(&pt->active_list);
}
spin_unlock_irqrestore(&obj->lock, flags);
@@ -229,7 +215,7 @@
return NULL;
spin_lock_irqsave(&obj->lock, flags);
sync_timeline_get(obj);
- dma_fence_init(&pt->fence, &timeline_fence_ops, &obj->lock,
+ fence_init(&pt->fence, &timeline_fence_ops, &obj->lock,
obj->context, value);
list_add_tail(&pt->link, &obj->pt_list);
INIT_LIST_HEAD(&pt->active_list);
@@ -252,7 +238,7 @@
}
static int timeline_create_fence(struct vdec_sync *sync, int usage,
- struct dma_fence **fence, int *fd, u32 value)
+ struct fence **fence, int *fd, u32 value)
{
int ret;
struct sync_pt *pt;
@@ -270,7 +256,7 @@
if (usage == FENCE_USE_FOR_APP) {
*fd = get_unused_fd_flags(O_CLOEXEC);
if (*fd < 0) {
- return -EBADF;
+ ret = -EBADF;
goto err;
}
@@ -283,16 +269,16 @@
fd_install(*fd, sync_file->file);
/* decreases refcnt. */
- dma_fence_put(&pt->fence);
+ fence_put(&pt->fence);
}
*fence = &pt->fence;
pt->timestamp = local_clock();
- if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE)
+ if (debug & VDEC_DBG_ENABLE_FENCE)
pr_info("[VDEC-FENCE]: create fence: %lx, fd: %d, ref: %d, usage: %d\n",
- (ulong) &pt->fence, *fd, atomic_read(&pt->fence.refcount.refcount.refs), usage);
+ (ulong) &pt->fence, *fd, atomic_read(&pt->fence.refcount.refcount), usage);
return 0;
err:
put_unused_fd(*fd);
@@ -302,64 +288,35 @@
return ret;
}
-struct dma_fence *vdec_fence_get(int fd)
+struct fence *vdec_fence_get(int fd)
{
return sync_file_get_fence(fd);
}
EXPORT_SYMBOL(vdec_fence_get);
-void vdec_fence_put(struct dma_fence *fence)
+void vdec_fence_put(struct fence *fence)
{
- if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE)
+ if (debug & VDEC_DBG_ENABLE_FENCE)
pr_info("[VDEC-FENCE]: the fence (%px) cost time: %lld ns\n",
fence, local_clock() - get_sync_pt(fence)->timestamp);
- dma_fence_put(fence);
+ fence_put(fence);
}
EXPORT_SYMBOL(vdec_fence_put);
-int vdec_fence_wait(struct dma_fence *fence, long timeout)
+int vdec_fence_wait(struct fence *fence, long timeout)
{
- if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE)
+ if (debug & VDEC_DBG_ENABLE_FENCE)
pr_info("[VDEC-FENCE]: wait fence %lx.\n", (ulong) fence);
- return dma_fence_wait_timeout(fence, false, timeout);
+ return fence_wait_timeout(fence, false, timeout);
}
EXPORT_SYMBOL(vdec_fence_wait);
-struct vdec_sync *vdec_sync_get(void)
-{
- int i;
- struct vdec_sync_core_s *core = &vdec_sync_core;
- ulong flags;
-
- spin_lock_irqsave(&core->vdec_sync_lock, flags);
-
- for (i = 0; i < VDEC_SYNC_COUNT; i++) {
- if (atomic_read(&core->s_vdec_sync[i].use_flag) == 0) {
- int j;
- atomic_set(&core->s_vdec_sync[i].use_flag, 1);
- for (j = 0; j < 64; j++) {
- core->s_vdec_sync[i].release_callback[j].func = vdec_fence_buffer_count_decrease;
- core->s_vdec_sync[i].release_callback[j].private_data = (void *)&core->s_vdec_sync[i];
- }
- spin_unlock_irqrestore(&core->vdec_sync_lock, flags);
- return &core->s_vdec_sync[i];
- }
- }
- spin_unlock_irqrestore(&core->vdec_sync_lock, flags);
- return 0;
-}
-EXPORT_SYMBOL(vdec_sync_get);
-
void vdec_timeline_create(struct vdec_sync *sync, u8 *name)
{
- struct sync_timeline *obj;
snprintf(sync->name, sizeof(sync->name), "%s", name);
- obj = sync_timeline_create(sync->name);
- obj->parent_sync = sync;
- sync->timeline = (void *)obj;
-
+ sync->timeline = (void *)sync_timeline_create(sync->name);
if (sync->timeline)
pr_info("[VDEC-FENCE]: create timeline %lx, name: %s\n",
(ulong) sync->timeline, sync->name);
@@ -380,12 +337,13 @@
spin_lock_irqsave(&obj->lock, flags);
+ pt = list_last_entry(&obj->pt_list, struct sync_pt, link);
value = obj->value + 1;
if (!list_empty(&obj->pt_list)) {
pt = list_last_entry(&obj->pt_list, struct sync_pt, link);
- if (value <= pt->fence.seqno) {
- value = pt->fence.seqno + 1;
+ if (value == pt->fence.seqno) {
+ value++;
}
}
spin_unlock_irqrestore(&obj->lock, flags);
@@ -407,7 +365,7 @@
obj->timestamp = local_clock();
- if (vdec_get_debug() & VDEC_DBG_ENABLE_FENCE)
+ if (debug & VDEC_DBG_ENABLE_FENCE)
pr_info("[VDEC-FENCE]: update timeline %d.\n",
obj->value + value);
@@ -415,15 +373,6 @@
}
EXPORT_SYMBOL(vdec_timeline_increase);
-void vdec_timeline_get(struct vdec_sync *sync)
-{
- struct sync_timeline *obj = sync->timeline;
-
- sync_timeline_get(obj);
-}
-EXPORT_SYMBOL(vdec_timeline_get);
-
-
void vdec_timeline_put(struct vdec_sync *sync)
{
struct sync_timeline *obj = sync->timeline;
@@ -432,15 +381,15 @@
}
EXPORT_SYMBOL(vdec_timeline_put);
-void vdec_fence_status_set(struct dma_fence *fence, int status)
+void vdec_fence_status_set(struct fence *fence, int status)
{
fence->error = status;
}
EXPORT_SYMBOL(vdec_fence_status_set);
-int vdec_fence_status_get(struct dma_fence *fence)
+int vdec_fence_status_get(struct fence *fence)
{
- return dma_fence_get_status(fence);
+ return fence_get_status(fence);
}
EXPORT_SYMBOL(vdec_fence_status_get);
@@ -460,72 +409,19 @@
int vdec_clean_all_fence(struct vdec_sync *sync)
{
- /*struct sync_timeline *obj = sync->timeline;
+ struct sync_timeline *obj = sync->timeline;
struct sync_pt *pt, *next;
spin_lock_irq(&obj->lock);
list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
- dma_fence_set_error(&pt->fence, -ENOENT);
- dma_fence_signal_locked(&pt->fence);
+ fence_set_error(&pt->fence, -ENOENT);
+ fence_signal_locked(&pt->fence);
}
- spin_unlock_irq(&obj->lock);*/
-
- struct sync_pt *pt, *next;
- struct sync_timeline *obj = sync->timeline;
-
- list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
- pr_err("vdec_clean_all_fence %px\n" , obj->parent_sync);
- vdec_fence_put(&pt->fence);
- }
-
- sync_timeline_put(obj);
+ spin_unlock_irq(&obj->lock);
return 0;
}
EXPORT_SYMBOL(vdec_clean_all_fence);
-void vdec_fence_buffer_count_increase(ulong fence)
-{
- struct vdec_sync *sync = (struct vdec_sync *)fence;
- struct sync_timeline *obj = sync->timeline;
-
- spin_lock_irq(&obj->lock);
-
- if (atomic_read(&sync->buffer_count) == 0) {
- sync_timeline_get(obj);
- }
-
- atomic_inc(&sync->buffer_count);
-
- spin_unlock_irq(&obj->lock);
-}
-EXPORT_SYMBOL(vdec_fence_buffer_count_increase);
-
-void vdec_fence_buffer_count_decrease(struct codec_mm_s *mm, struct codec_mm_cb_s *cb)
-{
- struct vdec_sync *sync = (struct vdec_sync *)cb->private_data;
- struct sync_pt *pt, *next;
- struct sync_timeline *obj = sync->timeline;
-
- atomic_dec(&sync->buffer_count);
-
- if (atomic_read(&sync->buffer_count) == 0) {
- sync_timeline_put(obj);
- list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
- vdec_fence_put(&pt->fence);
- }
- return;
- }
- return ;
-}
-EXPORT_SYMBOL(vdec_fence_buffer_count_decrease);
-
-void vdec_sync_core_init(void)
-{
- spin_lock_init(&vdec_sync_core.vdec_sync_lock);
-}
-EXPORT_SYMBOL(vdec_sync_core_init);
-
-
diff --git a/drivers/frame_provider/decoder/utils/vdec_sync.h b/drivers/frame_provider/decoder/utils/vdec_sync.h
index 6637b42..0622341 100644
--- a/drivers/frame_provider/decoder/utils/vdec_sync.h
+++ b/drivers/frame_provider/decoder/utils/vdec_sync.h
@@ -20,11 +20,9 @@
#include <linux/list.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
-#include <linux/dma-fence.h>
+#include <linux/fence.h>
#include <linux/sync_file.h>
#include <uapi/linux/sync_file.h>
-#include <linux/device.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
#define FENCE_USE_FOR_DRIVER (0)
#define FENCE_USE_FOR_APP (1)
@@ -42,11 +40,10 @@
spinlock_t lock;
u64 timestamp;
- struct vdec_sync *parent_sync;
};
struct sync_pt {
- struct dma_fence fence;
+ struct fence fence;
struct list_head link;
struct list_head active_list;
u64 timestamp;
@@ -57,27 +54,24 @@
void *timeline;
int usage;
int fd;
- struct dma_fence *fence;
- atomic_t buffer_count;
- atomic_t use_flag;
- struct codec_mm_cb_s release_callback[64];
+ struct fence *fence;
};
-static inline struct sync_timeline *fence_parent(struct dma_fence *fence)
+static inline struct sync_timeline *fence_parent(struct fence *fence)
{
return container_of(fence->lock, struct sync_timeline, lock);
}
-static inline struct sync_pt *get_sync_pt(struct dma_fence *fence)
+static inline struct sync_pt *get_sync_pt(struct fence *fence)
{
return container_of(fence, struct sync_pt, fence);
}
-struct dma_fence *vdec_fence_get(int fd);
+struct fence *vdec_fence_get(int fd);
-void vdec_fence_put(struct dma_fence *fence);
+void vdec_fence_put(struct fence *fence);
-int vdec_fence_wait(struct dma_fence *fence, long timeout);
+int vdec_fence_wait(struct fence *fence, long timeout);
void vdec_timeline_create(struct vdec_sync *sync, u8 *name);
@@ -85,23 +79,13 @@
void vdec_timeline_increase(struct vdec_sync *sync, u32 value);
-void vdec_timeline_get(struct vdec_sync *sync);
-
void vdec_timeline_put(struct vdec_sync *sync);
-int vdec_fence_status_get(struct dma_fence *fence);
+int vdec_fence_status_get(struct fence *fence);
-void vdec_fence_status_set(struct dma_fence *fence, int status);
+void vdec_fence_status_set(struct fence *fence, int status);
bool check_objs_all_signaled(struct vdec_sync *sync);
int vdec_clean_all_fence(struct vdec_sync *sync);
-void vdec_fence_buffer_count_increase(ulong fence);
-
-void vdec_fence_buffer_count_decrease(struct codec_mm_s *mm, struct codec_mm_cb_s *cb);
-
-struct vdec_sync *vdec_sync_get(void);
-
-void vdec_sync_core_init(void);
-
diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
index 34bc21a..e892127 100644
--- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
+++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.c
@@ -21,6 +21,21 @@
#include <media/v4l2-mem2mem.h>
#include <linux/printk.h>
+int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx,
+ struct vdec_v4l2_buffer **out)
+{
+ int ret = -1;
+
+ if (ctx->drv_handle == 0)
+ return -EIO;
+
+ ret = ctx->dec_if->get_param(ctx->drv_handle,
+ GET_PARAM_FREE_FRAME_BUFFER, out);
+
+ return ret;
+}
+EXPORT_SYMBOL(vdec_v4l_get_buffer);
+
int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx,
struct vdec_pic_info *pic)
{
@@ -36,21 +51,6 @@
}
EXPORT_SYMBOL(vdec_v4l_get_pic_info);
-int vdec_v4l_set_cfg_infos(struct aml_vcodec_ctx *ctx,
- struct aml_vdec_cfg_infos *cfg)
-{
- int ret = 0;
-
- if (ctx->drv_handle == 0)
- return -EIO;
-
- ret = ctx->dec_if->set_param(ctx->drv_handle,
- SET_PARAM_CFG_INFO, cfg);
-
- return ret;
-}
-EXPORT_SYMBOL(vdec_v4l_set_cfg_infos);
-
int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx,
struct aml_vdec_ps_infos *ps)
{
@@ -66,22 +66,6 @@
}
EXPORT_SYMBOL(vdec_v4l_set_ps_infos);
-int vdec_v4l_set_comp_buf_info(struct aml_vcodec_ctx *ctx,
- struct vdec_comp_buf_info *info)
-{
- int ret = 0;
-
- if (ctx->drv_handle == 0)
- return -EIO;
-
- ret = ctx->dec_if->set_param(ctx->drv_handle,
- SET_PARAM_COMP_BUF_INFO, info);
-
- return ret;
-
-}
-EXPORT_SYMBOL(vdec_v4l_set_comp_buf_info);
-
int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx,
struct aml_vdec_hdr_infos *hdr)
{
@@ -97,10 +81,50 @@
}
EXPORT_SYMBOL(vdec_v4l_set_hdr_infos);
+static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx)
+{
+ ulong expires;
+
+ expires = jiffies + msecs_to_jiffies(1000);
+ while (!ctx->v4l_codec_dpb_ready) {
+ u32 ready_num = 0;
+
+ if (time_after(jiffies, expires)) {
+ pr_err("the DPB state has not ready.\n");
+ break;
+ }
+
+ ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
+ if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size)
+ ctx->v4l_codec_dpb_ready = true;
+ }
+}
+
void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
{
- if (ctx != NULL)
- ctx->vdec_pic_info_update(ctx);
+ unsigned int dpbsize = 0;
+ int ret;
+
+ if (ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
+ pr_err("Cannot get param : GET_PARAM_PICTURE_INFO ERR\n");
+ return;
+ }
+
+ if (ctx->last_decoded_picinfo.visible_width == 0 ||
+ ctx->last_decoded_picinfo.visible_height == 0 ||
+ ctx->last_decoded_picinfo.coded_width == 0 ||
+ ctx->last_decoded_picinfo.coded_height == 0) {
+ pr_err("Cannot get correct pic info\n");
+ return;
+ }
+
+ ret = ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_DPB_SIZE, &dpbsize);
+ if (dpbsize == 0)
+ pr_err("Incorrect dpb size, ret=%d\n", ret);
+
+ /* update picture information */
+ ctx->dpb_size = dpbsize;
+ ctx->picinfo = ctx->last_decoded_picinfo;
}
int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event)
@@ -126,6 +150,9 @@
if (ctx->drv_handle == 0)
return -EIO;
+ /* wait the DPB state to be ready. */
+ aml_wait_dpb_ready(ctx);
+
aml_vdec_pic_info_update(ctx);
mutex_lock(&ctx->state_lock);
@@ -136,9 +163,8 @@
mutex_unlock(&ctx->state_lock);
- while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
- v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
- }
+ ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
+ v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
return ret;
}
@@ -159,17 +185,3 @@
}
EXPORT_SYMBOL(vdec_v4l_write_frame_sync);
-int vdec_v4l_get_dw_mode(struct aml_vcodec_ctx *ctx,
- unsigned int *dw_mode)
-{
- int ret = -1;
-
- if (ctx->drv_handle == 0)
- return -EIO;
-
- ret = ctx->dec_if->get_param(ctx->drv_handle,
- GET_PARAM_DW_MODE, dw_mode);
-
- return ret;
-}
-EXPORT_SYMBOL(vdec_v4l_get_dw_mode);
diff --git a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
index 98513d9..1494f10 100644
--- a/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
+++ b/drivers/frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h
@@ -23,22 +23,18 @@
#include "../../../amvdec_ports/vdec_drv_base.h"
#include "../../../amvdec_ports/aml_vcodec_adapt.h"
+int vdec_v4l_get_buffer(
+ struct aml_vcodec_ctx *ctx,
+ struct vdec_v4l2_buffer **out);
+
int vdec_v4l_get_pic_info(
struct aml_vcodec_ctx *ctx,
struct vdec_pic_info *pic);
-int vdec_v4l_set_cfg_infos(
- struct aml_vcodec_ctx *ctx,
- struct aml_vdec_cfg_infos *cfg);
-
int vdec_v4l_set_ps_infos(
struct aml_vcodec_ctx *ctx,
struct aml_vdec_ps_infos *ps);
-int vdec_v4l_set_comp_buf_info(
- struct aml_vcodec_ctx *ctx,
- struct vdec_comp_buf_info *info);
-
int vdec_v4l_set_hdr_infos(
struct aml_vcodec_ctx *ctx,
struct aml_vdec_hdr_infos *hdr);
@@ -53,8 +49,4 @@
int vdec_v4l_res_ch_event(
struct aml_vcodec_ctx *ctx);
-int vdec_v4l_get_dw_mode(
- struct aml_vcodec_ctx *ctx,
- unsigned int *dw_mode);
-
#endif
diff --git a/drivers/frame_provider/decoder/vav1/av1_bufmgr.c b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c
index 1e45320..41a522f 100644
--- a/drivers/frame_provider/decoder/vav1/av1_bufmgr.c
+++ b/drivers/frame_provider/decoder/vav1/av1_bufmgr.c
@@ -530,23 +530,16 @@
void av1_bufmgr_ctx_reset(AV1Decoder *pbi, BufferPool *const pool, AV1_COMMON *cm)
{
- u32 save_w, save_h;
-
if (!pbi || !pool || !cm)
return;
reset_frame_buffers(pbi);
memset(pbi, 0, sizeof(*pbi));
- /*save w,h for resolution change after seek */
- save_w = cm->width;
- save_h = cm->height;
memset(cm, 0, sizeof(*cm));
cm->current_frame.frame_number = 0;
cm->seq_params.bit_depth = AOM_BITS_8;
cm->error.setjmp = 0;
- cm->width = save_w;
- cm->height = save_h;
pbi->bufmgr_proc_count = 0;
pbi->need_resync = 1;
@@ -592,17 +585,6 @@
}
}
-void clear_frame_buf_ref_count(AV1Decoder *pbi)
-{
- int i;
-
- for (i = 0; i < pbi->num_output_frames; i++) {
- decrease_ref_count(pbi, pbi->output_frames[i],
- pbi->common->buffer_pool);
- }
- pbi->num_output_frames = 0;
-}
-
static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) {
int ref_index = 0, mask;
AV1_COMMON *const cm = pbi->common;
@@ -976,10 +958,9 @@
#ifdef ORI_CODE
fail:
-#endif
// clear the mi_* values to force a realloc on resync
av1_set_mb_mi(cm, 0, 0);
-#ifdef ORI_CODE
+
av1_free_context_buffers(cm);
#endif
return 1;
@@ -2035,7 +2016,6 @@
// See if this frame can be used as show_existing_frame in future
cm->showable_frame = params->p.showable_frame;//aom_rb_read_bit(rb);
}
- cm->cur_frame->show_frame = cm->show_frame;
cm->cur_frame->showable_frame = cm->showable_frame;
cm->error_resilient_mode =
frame_is_sframe(cm) ||
@@ -2946,14 +2926,6 @@
// TODO(wtc): Verify that the frame_header_obu is identical to the
// original frame_header_obu. For now just skip frame_header_size
// bytes in the bit buffer.
- if (frame_header_size > payload_size) {
- cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
- return -1;
- }
- assert(rb.bit_offset == 0);
-#ifdef ORI_CODE
- rb.bit_offset = 8 * frame_header_size;
-#endif
}
decoded_payload_size = frame_header_size;
@@ -3012,6 +2984,7 @@
}
}
}
+
return i;
}
diff --git a/drivers/frame_provider/decoder/vav1/av1_global.h b/drivers/frame_provider/decoder/vav1/av1_global.h
index e12b224..75af688 100644
--- a/drivers/frame_provider/decoder/vav1/av1_global.h
+++ b/drivers/frame_provider/decoder/vav1/av1_global.h
@@ -52,6 +52,13 @@
#define AOMMIN(x, y) (((x) < (y)) ? (x) : (y))
#define AOMMAX(x, y) (((x) > (y)) ? (x) : (y))
+//typedef char int8_t;
+//#ifndef BUFMGR_FOR_SIM
+typedef unsigned char uint8_t;
+//#endif
+typedef unsigned int uint32_t;
+//typedef int int32_t;
+//typedef long long int64_t;
#ifdef AML
#define AOM_AV1_MMU
@@ -101,12 +108,9 @@
} BuffInfo_t;
#endif
-#if 0
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
-#endif
-
/*
mem.h
*/
@@ -1318,9 +1322,8 @@
int min_mv;
int avg_mv;
#endif
- u64 timestamp;
- u32 hw_decode_time;
- u32 frame_size2; // For frame base mode
+ bool vframe_bound;
+ u64 timestamp;
} PIC_BUFFER_CONFIG;
/*
@@ -1561,7 +1564,6 @@
FRAME_CONTEXT frame_context;
#endif
- int show_frame;
} RefCntBuffer;
typedef struct BufferPool_s {
@@ -2225,9 +2227,7 @@
unsigned short seg_lf_info_c[8];
unsigned short video_signal_type;
unsigned short color_description;
- unsigned short mmu_used_num;
- unsigned short dw_mmu_used_num;
- unsigned short seq_flags_2;
+
/*ucode end*/
/*other*/
unsigned short enable_superres;
@@ -2317,7 +2317,6 @@
#define AV1_DEBUG_DUMP_DATA 0x800000
#define AV1_DEBUG_CACHE 0x1000000
#define AV1_DEBUG_CACHE_HIT_RATE 0x2000000
-#define AV1_DEBUG_SEI_DETAIL 0x4000000
#define IGNORE_PARAM_FROM_CONFIG 0x8000000
#if 1
/*def MULTI_INSTANCE_SUPPORT*/
diff --git a/drivers/frame_provider/decoder/vav1/vav1.c b/drivers/frame_provider/decoder/vav1/vav1.c
index c67757a..8379316 100644
--- a/drivers/frame_provider/decoder/vav1/vav1.c
+++ b/drivers/frame_provider/decoder/vav1/vav1.c
@@ -25,7 +25,6 @@
#include <linux/timer.h>
#include <linux/kfifo.h>
#include <linux/kthread.h>
-#include <linux/sched/clock.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/amlogic/media/vfm/vframe.h>
@@ -74,7 +73,6 @@
#include <media/v4l2-mem2mem.h>
#endif
#include "../../../amvdec_ports/utils/common.h"
-#include "../utils/vdec_feature.h"
#define AML
#include "aom_av1_define.h"
@@ -90,8 +88,6 @@
#define USE_DEC_PIC_END
-#define SANITY_CHECK
-#define CO_MV_COMPRESS
#include "vav1.h"
@@ -172,7 +168,6 @@
#define AOM_AV1_DUMP_LMEM 7
#define AOM_AV1_FGS_PARAM_CONT 8
#define AOM_AV1_DISCARD_NAL 0x10
-#define AOM_AV1_RESULT_NEED_MORE_BUFFER 0x11
/*status*/
#define AOM_AV1_DEC_PIC_END 0xe0
@@ -197,6 +192,7 @@
#define AOM_EOS 0x24
#define AOM_NAL_DECODE_DONE 0x25
+
#define VF_POOL_SIZE 32
#undef pr_info
@@ -269,8 +265,8 @@
#ifdef AOM_AV1_MMU_DW
static unsigned int dw_mmu_enable[MAX_DECODE_INSTANCE_NUM];
#endif
-
-static u32 decode_timeout_val = 600;
+/* disable timeout for av1 mosaic JIRA SWPL-23326 */
+static u32 decode_timeout_val = 0;
static int start_decode_buf_level = 0x8000;
//static u32 work_buf_size;
static u32 force_pts_unstable;
@@ -285,10 +281,9 @@
* 2, (1/4):(1/4) ratio;
* 3, (1/4):(1/4) ratio, with both compressed frame included
* 4, (1/2):(1/2) ratio;
- * 5, (1/2):(1/2) ratio, with both compressed frame included
- * 8, (1/8):(1/8) ratio;
+ * 5, (1/2):(1/2) ratio, with both compressed frame included
* 0x10, double write only
- * 0x20, mmu double write
+ * 0x20, mmu double write
* 0x100, if > 1080p,use mode 4,else use mode 1;
* 0x200, if > 1080p,use mode 2,else use mode 1;
* 0x300, if > 720p, use mode 4, else use mode 1;
@@ -314,7 +309,7 @@
#define DUR2PTS(x) ((x)*90/96)
#define PTS2DUR(x) ((x)*96/90)
-#define PTS2DUR_u64(x) (div_u64((x)*96, 90))
+
struct AV1HW_s;
static int vav1_vf_states(struct vframe_states *states, void *);
@@ -331,7 +326,7 @@
#endif
static void vav1_prot_init(struct AV1HW_s *hw, u32 mask);
static int vav1_local_init(struct AV1HW_s *hw);
-static void vav1_put_timer_func(struct timer_list *timer);
+static void vav1_put_timer_func(unsigned long arg);
static void dump_data(struct AV1HW_s *hw, int size);
static unsigned int get_data_check_sum
(struct AV1HW_s *hw, int size);
@@ -376,8 +371,6 @@
static u32 video_signal_type;
static u32 on_no_keyframe_skiped;
static u32 without_display_mode;
-static u32 v4l_bitstream_id_enable = 1;
-
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
static u32 force_dv_enable;
#endif
@@ -439,6 +432,10 @@
#define LOSLESS_COMPRESS_MODE
#endif
+typedef unsigned int u32;
+typedef unsigned short u16;
+
+
static u32 get_picture_qos;
static u32 debug;
@@ -537,7 +534,6 @@
//#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4)
#define MAX_SIZE_8K (8192 * 4608)
#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
@@ -599,7 +595,7 @@
static int compute_losless_comp_body_size(int width, int height,
uint8_t is_bit_depth_10);
-void clear_frame_buf_ref_count(AV1Decoder *pbi);
+
#ifdef MULTI_INSTANCE_SUPPORT
#define DEC_RESULT_NONE 0
@@ -756,10 +752,23 @@
u32 video_signal_type;
u32 pts_unstable;
- u32 last_chunk_pts;
- u32 pts_diff_count;
- u64 pts_diff_sum;
+ bool av1_first_pts_ready;
+ bool dur_recalc_flag;
+ u8 first_pts_index;
+ u32 frame_mode_pts_save[FRAME_BUFFERS];
+ u64 frame_mode_pts64_save[FRAME_BUFFERS];
+ u64 frame_mode_timestamp_save[FRAME_BUFFERS];
+ u64 timestamp_duration;
+ int last_pts;
+ u64 last_pts_us64;
+ u64 last_timestamp;
+ u64 shift_byte_count;
+
+ u32 shift_byte_count_lo;
+ u32 shift_byte_count_hi;
+ int pts_mode_switching_count;
+ int pts_mode_recovery_count;
bool get_frame_dur;
u32 saved_resolution;
@@ -852,23 +861,17 @@
int buffer_wrap[FRAME_BUFFERS];
int sidebind_type;
int sidebind_channel_id;
- u32 cur_obu_type;
- u32 multi_frame_cnt;
- u32 endian;
- u32 run_ready_min_buf_num;
- int one_package_frame_cnt;
- ulong fb_token;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- struct trace_decoder_name trace;
+ char vdec_name[32];
+ char pts_name[32];
+ char new_q_name[32];
+ char disp_q_name[32];
};
-
static void av1_dump_state(struct vdec_s *vdec);
int av1_print(struct AV1HW_s *hw,
int flag, const char *fmt, ...)
{
-#define HEVC_PRINT_BUF 512
+#define HEVC_PRINT_BUF 256
unsigned char buf[HEVC_PRINT_BUF];
int len = 0;
@@ -918,9 +921,6 @@
int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
MAX_SIZE_8K : MAX_SIZE_4K;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
if (w <= 0 || h <= 0)
return true;
@@ -1015,16 +1015,48 @@
u32 dw = ((double_write_mode & 0x80000000) == 0) ?
hw->double_write_mode :
(double_write_mode & 0x7fffffff);
- if (dw & 0x20) {
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
- && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) {
- pr_info("MMU doueble write 1:4 not supported !!!\n");
- dw = 0;
- }
+ if ((dw & 0x20) &&
+ ((dw & 0xf) == 2 || (dw & 0xf) == 3)) {
+ pr_info("MMU doueble write 1:4 not supported !!!\n");
+ dw = 0;
}
return dw;
}
+static int v4l_parser_get_double_write_mode(struct AV1HW_s *hw)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(hw);
+ u32 dw;
+ int w, h;
+
+ /* mask for supporting double write value bigger than 0x100 */
+ if (valid_dw_mode & 0xffffff00) {
+ w = hw->frame_width;
+ h = hw->frame_height;
+
+ dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 720)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ break;
+ }
+ return dw;
+ }
+
+ return valid_dw_mode;
+}
+
static int get_double_write_mode(struct AV1HW_s *hw)
{
u32 valid_dw_mode = get_valid_double_write_mode(hw);
@@ -1035,15 +1067,6 @@
if (!cm->cur_frame)
return 1;/*no valid frame,*/
-
- if (hw->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(hw->v4l2_ctx, &out);
- dw = out;
- return dw;
- }
-
cur_pic_config = &cm->cur_frame->buf;
w = cur_pic_config->y_crop_width;
h = cur_pic_config->y_crop_height;
@@ -1099,6 +1122,19 @@
}
#endif
+static int get_double_write_ratio(struct AV1HW_s *hw,
+ int dw_mode)
+{
+ int ratio = 1;
+ int dw_mode_ratio = dw_mode & 0xf;
+ if ((dw_mode_ratio == 2) ||
+ (dw_mode_ratio == 3))
+ ratio = 4;
+ else if (dw_mode_ratio == 4)
+ ratio = 2;
+ return ratio;
+}
+
/* return page number */
static int av1_mmu_page_num(struct AV1HW_s *hw,
int w, int h, int save_mode)
@@ -1123,32 +1159,6 @@
return cur_mmu_4k_number;
}
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct AV1HW_s *hw,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct AV1HW_s *hw, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- hw->m_BUF[index].v4l_ref_buf_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
//#define MAX_4K_NUM 0x1200
int av1_alloc_mmu(
struct AV1HW_s *hw,
@@ -1162,6 +1172,11 @@
int bit_depth_10 = (bit_depth == AOM_BITS_10);
int cur_mmu_4k_number;
+ if (!hw->mmu_box) {
+ pr_err("error no mmu box!\n");
+ return -1;
+ }
+
if (hw->double_write_mode & 0x10)
return 0;
@@ -1178,22 +1193,11 @@
if (cur_mmu_4k_number < 0)
return -1;
- if (hw->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, cur_buf_idx);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ret = decoder_mmu_box_alloc_idx(
- hw->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
- }
+ ret = decoder_mmu_box_alloc_idx(
+ hw->mmu_box,
+ hw->buffer_wrap[cur_buf_idx],
+ cur_mmu_4k_number,
+ mmu_index_adr);
return ret;
}
@@ -1241,7 +1245,7 @@
}
ret = decoder_mmu_box_alloc_idx(
hw->mmu_box_dw,
- cur_buf_idx,
+ hw->buffer_wrap[cur_buf_idx],
cur_mmu_4k_number,
mmu_index_adr);
return ret;
@@ -1274,13 +1278,6 @@
int i, int size)
{
int ret = 0;
-
- if (hw->m_mv_BUF[i].start_adr &&
- size > hw->m_mv_BUF[i].size) {
- dealloc_mv_bufs(hw);
- } else if (hw->m_mv_BUF[i].start_adr)
- return 0;
-
if (decoder_bmmu_box_alloc_buf_phy
(hw->bmmu_box,
MV_BUFFER_IDX(i), size,
@@ -1356,7 +1353,10 @@
__func__, size);
if ((hw->is_used_v4l) && !IS_8K_SIZE(pic_width, pic_height)) {
- size = 0x100000;
+ if (vdec_is_support_4k())
+ size = 0xb0000;
+ else
+ size = 0x30000;
}
if (hw->init_pic_w > 4096 && hw->init_pic_h > 2048)
@@ -1502,26 +1502,6 @@
static void init_pic_list_hw(struct AV1HW_s *pbi);
-static void update_hide_frame_timestamp(struct AV1HW_s *hw)
-{
- RefCntBuffer *const frame_bufs = hw->common.buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((!frame_bufs[i].show_frame) &&
- (frame_bufs[i].showable_frame) &&
- (!frame_bufs[i].buf.vf_ref) &&
- (frame_bufs[i].buf.BUF_index != -1)) {
- frame_bufs[i].buf.timestamp = hw->chunk->timestamp;
- frame_bufs[i].buf.pts = hw->chunk->pts;
- frame_bufs[i].buf.pts64 = hw->chunk->pts64;
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "%s, update %d hide frame ts: %lld, pts %d, pts64 %lld\n",
- __func__, i, frame_bufs[i].buf.timestamp, hw->chunk->pts, hw->chunk->pts64);
- }
- }
-}
-
static int get_free_fb_idx(AV1_COMMON *cm)
{
int i;
@@ -1533,7 +1513,7 @@
break;
}
- return (i != FRAME_BUFFERS) ? i : -1;
+ return i;
}
static int v4l_get_free_fb(struct AV1HW_s *hw)
@@ -1565,9 +1545,6 @@
break;
case V4L_CAP_BUFF_IN_M2M:
idx = get_free_fb_idx(cm);
- if (idx < 0)
- break;
-
pic = &frame_bufs[idx].buf;
pic->y_crop_width = hw->frame_width;
pic->y_crop_height = hw->frame_height;
@@ -1601,30 +1578,8 @@
}
}
- if (free_pic && hw->chunk) {
- free_pic->timestamp = hw->chunk->timestamp;
- update_hide_frame_timestamp(hw);
- }
-
unlock_buffer_pool(cm->buffer_pool, flags);
- if (free_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->m_BUF[free_pic->index].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- }
-
- if (debug & AV1_DEBUG_OUT_PTS) {
- if (free_pic) {
- pr_debug("%s, idx: %d, ts: %lld\n",
- __func__, free_pic->index, free_pic->timestamp);
- } else {
- pr_debug("%s, av1 get free pic null\n", __func__);
- }
- }
-
return free_pic ? free_pic->index : INVALID_IDX;
}
@@ -1664,25 +1619,7 @@
i = INVALID_IDX;
}
- if (i != INVALID_IDX) {
- struct PIC_BUFFER_CONFIG_s *pic = &frame_bufs[i].buf;
- struct AV1HW_s *hw = container_of(cm, struct AV1HW_s, common);
-
- if (pic && hw->chunk) {
- pic->timestamp = hw->chunk->timestamp;
- pic->pts = hw->chunk->pts;
- pic->pts64 = hw->chunk->pts64;
- update_hide_frame_timestamp(hw);
- }
-
- if (pic)
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "%s, idx: %d, ts: %lld, pts %d, pts64 %lld\n",
- __func__, i, pic->timestamp, pic->pts, pic->pts64);
- }
-
unlock_buffer_pool(cm->buffer_pool, flags);
-
return i;
}
@@ -1697,42 +1634,14 @@
{
struct AV1_Common_s *const cm = &hw->common;
struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_buf_count = 0;
-
- if (hw->is_used_v4l) {
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_buf_count++;
- }
- }
-
- if (ctx->cap_pool.dec < hw->used_buf_num) {
- free_buf_count +=
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- }
- /* trigger to parse head data. */
- if (!hw->v4l_params_parsed) {
- free_buf_count = hw->run_ready_min_buf_num;
- }
- if ((debug & AV1_DEBUG_BUFMGR_MORE) &&
- (free_buf_count <= 0)) {
- pr_info("%s, free count %d, m2m_ready %d\n",
- __func__,
- free_buf_count,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
- }
- } else {
- for (i = 0; i < hw->used_buf_num; ++i)
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1)) {
- free_buf_count++;
- }
- }
-
+ int i;
+ int free_buf_count = 0;
+ for (i = 0; i < hw->used_buf_num; ++i)
+ if ((frame_bufs[i].ref_count == 0) &&
+ (frame_bufs[i].buf.vf_ref == 0) &&
+ (frame_bufs[i].buf.index != -1)
+ )
+ free_buf_count++;
return free_buf_count;
}
@@ -1778,13 +1687,18 @@
hw->wait_buf = 0;
hw->error_flag = 0;
+ hw->last_pts = 0;
+ hw->last_pts_us64 = 0;
+ hw->last_timestamp = 0;
+ hw->shift_byte_count = 0;
+ hw->shift_byte_count_lo = 0;
+ hw->shift_byte_count_hi = 0;
+ hw->pts_mode_switching_count = 0;
+ hw->pts_mode_recovery_count = 0;
+
hw->buf_num = 0;
hw->pic_num = 0;
- hw->last_chunk_pts = 0;
- hw->pts_diff_count = 0;
- hw->pts_diff_sum = 0;
-
return 0;
}
@@ -1826,14 +1740,7 @@
static u32 pop_shorts;
static u32 dbg_cmd;
static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
+static u32 endian = 0xff0;
static u32 multi_frames_in_one_pack = 1;
#ifdef ERROR_HANDLE_DEBUG
static u32 dbg_nal_skip_flag;
@@ -2025,12 +1932,9 @@
#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-/* necessary 4K page size align for t7/t3 decoder and after. fix case1440 dec timeout */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
#define WORK_BUF_SPEC_NUM 3
-static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM] = {
+static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM] = {
{ //8M bytes
.max_width = 1920,
.max_height = 1088,
@@ -2713,73 +2617,82 @@
{
void *mem_start_virt;
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
- buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
- buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
- buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
- buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
- buf_spec->seg_map.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
- buf_spec->daala_top.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
- buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->daala_top.buf_start + buf_spec->daala_top.buf_size);
- buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
- buf_spec->cdf_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
- buf_spec->gmc_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size);
- buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.buf_size);
- buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
- buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
- buf_spec->cdef_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
- buf_spec->ups_data.buf_start =
- WORKBUF_ALIGN(buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size);
- buf_spec->fgs_table.buf_start =
- WORKBUF_ALIGN(buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size);
+ buf_spec->ipp.buf_start =
+ buf_spec->start_adr;
+ buf_spec->sao_abv.buf_start =
+ buf_spec->ipp.buf_start + buf_spec->ipp.buf_size;
+
+ buf_spec->sao_vb.buf_start =
+ buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size;
+ buf_spec->short_term_rps.buf_start =
+ buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size;
+ buf_spec->vps.buf_start =
+ buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size;
+ buf_spec->seg_map.buf_start =
+ buf_spec->vps.buf_start + buf_spec->vps.buf_size;
+ buf_spec->daala_top.buf_start =
+ buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size;
+ buf_spec->sao_up.buf_start =
+ buf_spec->daala_top.buf_start + buf_spec->daala_top.buf_size;
+ buf_spec->swap_buf.buf_start =
+ buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size;
+ buf_spec->cdf_buf.buf_start =
+ buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size;
+ buf_spec->gmc_buf.buf_start =
+ buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size;
+ buf_spec->scalelut.buf_start =
+ buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.buf_size;
+ buf_spec->dblk_para.buf_start =
+ buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size;
+ buf_spec->dblk_data.buf_start =
+ buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size;
+ buf_spec->cdef_data.buf_start =
+ buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size;
+ buf_spec->ups_data.buf_start =
+ buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size;
+ buf_spec->fgs_table.buf_start =
+ buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size;
#ifdef AOM_AV1_MMU
- buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size);
- buf_spec->cm_header.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+ buf_spec->mmu_vbh.buf_start =
+ buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size;
+ buf_spec->cm_header.buf_start =
+ buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size;
#ifdef AOM_AV1_MMU_DW
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size);
- buf_spec->cm_header_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size);
+ buf_spec->mmu_vbh_dw.buf_start =
+ buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size;
+ buf_spec->cm_header_dw.buf_start =
+ buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size;
+ buf_spec->mpred_above.buf_start =
+ buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size;
#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size);
+ buf_spec->mpred_above.buf_start =
+ buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size;
#endif
#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size);
+ buf_spec->mpred_above.buf_start =
+ buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size;
#endif
+
#ifdef MV_USE_FIXED_BUF
buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+ buf_spec->mpred_mv.buf_start +
+ buf_spec->mpred_mv.buf_size;
#else
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
#endif
buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->rpm.buf_start +
+ buf_spec->rpm.buf_size;
buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+ buf_spec->lmem.buf_start +
+ buf_spec->lmem.buf_size;
if (!hw)
return;
@@ -2867,13 +2780,64 @@
}
}
+static bool v4l_is_there_vframe_bound(struct AV1HW_s *hw)
+{
+ int i;
+ struct AV1_Common_s *const cm = &hw->common;
+ struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
+ for (i = 0; i < hw->used_buf_num; ++i) {
+ if (frame_bufs[i].buf.vframe_bound)
+ return true;
+ }
+
+ return false;
+}
+
+static void v4l_mmu_buffer_release(struct AV1HW_s *hw)
+{
+ struct AV1_Common_s *const cm = &hw->common;
+ struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
+ int i;
+
+ /* release workspace */
+ if (hw->bmmu_box)
+ decoder_bmmu_box_free_idx(hw->bmmu_box,
+ WORK_SPACE_BUF_ID);
+ /*
+ * it's only when vframe get back to driver, right now we can be sure
+ * that vframe and fd are related. if the playback exits, the capture
+ * requires the upper app to release when the fd is closed, and others
+ * buffers drivers are released by driver.
+ */
+ for (i = 0; i < hw->used_buf_num; ++i) {
+ if (!frame_bufs[i].buf.vframe_bound) {
+ if (hw->bmmu_box)
+ decoder_bmmu_box_free_idx(hw->bmmu_box,
+ HEADER_BUFFER_IDX(hw->buffer_wrap[i]));
+ if (hw->mmu_box)
+ decoder_mmu_box_free_idx(hw->mmu_box, hw->buffer_wrap[i]);
+
+ av1_print(hw, PRINT_FLAG_V4L_DETAIL,
+ "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n",
+ __func__, i, hw->bmmu_box, hw->mmu_box);
+ }
+ }
+}
static void uninit_mmu_buffers(struct AV1HW_s *hw)
{
#ifndef MV_USE_FIXED_BUF
dealloc_mv_bufs(hw);
#endif
+ if (hw->is_used_v4l &&
+ v4l_is_there_vframe_bound(hw)) {
+ if (get_double_write_mode(hw) != 0x10) {
+ v4l_mmu_buffer_release(hw);
+ return;
+ }
+ }
+
if (hw->mmu_box)
decoder_mmu_box_free(hw->mmu_box);
hw->mmu_box = NULL;
@@ -2900,33 +2864,6 @@
return pic_width_lcu * pic_height_lcu;
}
-/* return in MB */
-static int av1_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 48;
-
- if ((max_w * max_h > 1280*736) &&
- (max_w * max_h <= 1920*1088)) {
- buf_size = 12;
- } else if ((max_w * max_h > 0) &&
- (max_w * max_h <= 1280*736)) {
- buf_size = 4;
- }
-
- return buf_size;
-}
-
-static int av1_get_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(w, h))
- return MMU_COMPRESS_HEADER_SIZE_8K;
- if (IS_4K_SIZE(w, h))
- return MMU_COMPRESS_HEADER_SIZE_4K;
-
- return MMU_COMPRESS_HEADER_SIZE_1080P;
-}
-
static int v4l_alloc_and_config_pic(struct AV1HW_s *hw,
struct PIC_BUFFER_CONFIG_s *pic)
{
@@ -2945,24 +2882,21 @@
int32_t mv_buffer_size = hw->max_one_mv_buffer_size;
//#endif
#endif
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hw->v4l2_ctx;
struct vdec_v4l2_buffer *fb = NULL;
if (i < 0)
return ret;
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(hw->v4l2_ctx, &fb);
if (ret < 0) {
- av1_print(hw, 0, "[%d] AV1 get buffer fail.\n", ctx->id);
+ av1_print(hw, 0, "[%d] AV1 get buffer fail.\n",
+ ((struct aml_vcodec_ctx *) (hw->v4l2_ctx))->id);
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (hw->mmu_enable) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hw, fb);
-
- hw->m_BUF[i].header_addr = ibuf->header_addr;
+ hw->m_BUF[i].header_addr = decoder_bmmu_box_get_phy_addr(
+ hw->bmmu_box, HEADER_BUFFER_IDX(hw->buffer_wrap[i]));
if (debug & AV1_DEBUG_BUFMGR_MORE) {
pr_info("MMU header_adr %d: %ld\n",
i, hw->m_BUF[i].header_addr);
@@ -3094,9 +3028,9 @@
if (dw_mode && (dw_mode & 0x20) == 0) {
int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode & 0xf);
+ get_double_write_ratio(hw, dw_mode);
int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode & 0xf);
+ get_double_write_ratio(hw, dw_mode);
int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
@@ -3139,26 +3073,26 @@
/*!USE_SPEC_BUF_FOR_MMU_HEAD*/
if (hw->mmu_enable) {
pic_config->header_adr = decoder_bmmu_box_get_phy_addr(
- hw->bmmu_box, HEADER_BUFFER_IDX(pic_config->index));
+ hw->bmmu_box, HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index]));
#ifdef AOM_AV1_MMU_DW
if (hw->dw_mmu_enable) {
pic_config->header_dw_adr = decoder_bmmu_box_get_phy_addr(
- hw->bmmu_box, DW_HEADER_BUFFER_IDX(pic_config->index));
+ hw->bmmu_box, DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index]));
}
if (debug & AV1_DEBUG_BUFMGR_MORE) {
pr_info("MMU dw header_adr (%d, %d) %d: %d\n",
hw->dw_mmu_enable,
- DW_HEADER_BUFFER_IDX(pic_config->index),
- pic_config->index,
+ DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->index]),
+ hw->buffer_wrap[pic_config->index],
pic_config->header_dw_adr);
}
#endif
if (debug & AV1_DEBUG_BUFMGR_MORE) {
pr_info("MMU header_adr %d: %d\n",
- pic_config->index, pic_config->header_adr);
+ hw->buffer_wrap[pic_config->index], pic_config->header_adr);
}
}
#endif
@@ -3172,13 +3106,13 @@
#endif
if (buf_size > 0) {
ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box,
- VF_BUFFER_IDX(i),
+ VF_BUFFER_IDX(hw->buffer_wrap[i]),
buf_size, DRIVER_NAME,
&pic_config->cma_alloc_addr);
if (ret < 0) {
pr_info(
"decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
- VF_BUFFER_IDX(i),
+ VF_BUFFER_IDX(hw->buffer_wrap[i]),
buf_size
);
return ret;
@@ -3189,7 +3123,7 @@
else {
pr_info(
"decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
- VF_BUFFER_IDX(i),
+ VF_BUFFER_IDX(hw->buffer_wrap[i]),
buf_size
);
return -1;
@@ -3622,10 +3556,8 @@
seg_map_size =
((frame_width + 127) >> 7) * ((frame_height + 127) >> 7) * 384 ;
*/
- if (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T3) {
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE,
- (frame_height << 16) | frame_width);
- }
+ WRITE_VREG(HEVC_PARSER_PICTURE_SIZE,
+ (frame_height << 16) | frame_width);
#ifdef DUAL_DECODE
#else
WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ,
@@ -3898,15 +3830,7 @@
cur_pic_config->index, last_frame_pic_config->index);*/
//WRITE_VREG(HEVC_MPRED_CTRL3,0x24122412);
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- WRITE_VREG(HEVC_MPRED_CTRL3,0x10151015); // 'd10, 'd21 for AV1
- } else {
- WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1
- }
-#else
- WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1
-#endif
+ WRITE_VREG(HEVC_MPRED_CTRL3, 0x13151315); // 'd19, 'd21 for AV1
WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,
hw->pbi->work_space_buf->mpred_above.buf_start);
@@ -3932,19 +3856,11 @@
"WRITE_VREG(HEVC_MPRED_CTRL4, 0x%x)\n", data32);
}
#if 1
- data32 = ((cm->seq_params.order_hint_info.enable_order_hint << 27) |
+ data32 = (
+ (cm->seq_params.order_hint_info.enable_order_hint << 27) |
(cm->seq_params.order_hint_info.order_hint_bits_minus_1 << 24) |
- (cm->cur_frame->order_hint << 16 ));
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- data32 |= (0x10 << 8) | (0x10 << 0);
- } else {
- data32 |= (0x13 << 8) | (0x13 << 0);
- }
-#else
- data32 |= (0x13 << 8) | (0x13 << 0);
-#endif
-
+ (cm->cur_frame->order_hint <<16 ) |
+ (0x13 << 8) | (0x13 << 0));
#else
data32 = READ_VREG(HEVC_MPRED_L0_REF00_POC);
data32 &= (~(0xff << 16));
@@ -4073,7 +3989,7 @@
WRITE_VREG(HEVC_MPRED_MV_WPTR,
cur_pic_config->mpred_mv_wr_start_addr);
- if (inter_flag) {
+ if ((inter_flag) && (mv_cal_tpl_count <= 3)) {
for (i = 0; i < mv_cal_tpl_count; i++) {
PIC_BUFFER_CONFIG *pic_config =
av1_get_ref_frame_spec_buf(cm, mv_ref_id[i]);
@@ -4094,9 +4010,6 @@
pic_config->mpred_mv_wr_start_addr);
WRITE_VREG(HEVC_MPRED_MV_RPTR_2,
pic_config->mpred_mv_wr_start_addr);
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: mv_ref_id error\n", __func__);
}
}
}
@@ -4136,7 +4049,7 @@
!!!!!!!!!!!!!!!!!!!!!!!!!TODO .... !!!!!!!!!!!
mem_map_mode, endian, get_double_write_mode
*/
- AV1_COMMON *cm = &hw->common;
+ AV1_COMMON *cm = &hw->common;
PIC_BUFFER_CONFIG* pic_config = &cm->cur_frame->buf;
uint32_t data32;
int32_t lcu_size =
@@ -4243,7 +4156,7 @@
#ifdef DOS_PROJECT
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
data32 &= (~0x3);
data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
WRITE_VREG(HEVC_SAO_CTRL1, data32);
@@ -4254,13 +4167,13 @@
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
- data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
+ data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
#else
// m8baby test1902
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
+ data32 |= (MEM_MAP_MODE << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
data32 &= (~0xff0);
//data32 |= 0x670; // Big-Endian per 64-bit
data32 |= 0x880; // Big-Endian per 64-bit
@@ -4274,7 +4187,7 @@
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
- data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
+ data32 |= (MEM_MAP_MODE << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
data32 &= (~0xF);
data32 |= 0x8; // Big-Endian per 64-bit
WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
@@ -4283,14 +4196,19 @@
/*CHANGE_DONE nnn*/
data32 = READ_VREG(HEVC_SAO_CTRL1);
data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+ data32 |= (mem_map_mode <<
+ 12);
+
+/* [13:12] axi_aformat, 0-Linear,
+ * 1-32x32, 2-64x32
+ */
data32 &= (~0xff0);
/* data32 |= 0x670; // Big-Endian per 64-bit */
#ifdef AOM_AV1_MMU_DW
if (hw->dw_mmu_enable == 0)
- data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
+ data32 |= endian; /* Big-Endian per 64-bit */
#else
- data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
+ data32 |= endian; /* Big-Endian per 64-bit */
#endif
data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
if (get_double_write_mode(hw) == 0)
@@ -4318,8 +4236,7 @@
else
data32 |= (1 << 8); /* NV12 */
}
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
+
/*
* [31:24] ar_fifo1_axi_thred
* [23:16] ar_fifo0_axi_thred
@@ -4345,14 +4262,9 @@
data32 &= ~(0xff << 16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
} else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
data32 = READ_VREG(HEVC_SAO_CTRL5);
data32 &= (~(0xff << 16));
- if ((get_double_write_mode(hw) & 0xf) == 8) {
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- data32 |= (0xff << 16);
- } else if ((get_double_write_mode(hw) & 0xf) == 2 ||
+ if ((get_double_write_mode(hw) & 0xf) == 2 ||
(get_double_write_mode(hw) & 0xf) == 3)
data32 |= (0xff<<16);
else if ((get_double_write_mode(hw) & 0xf) == 4 ||
@@ -4364,9 +4276,11 @@
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (hw->mem_map_mode << 4);
- data32 &= (~0xf);
- data32 |= (hw->endian & 0xf); /* valid only when double write only */
+ data32 |= (mem_map_mode <<
+ 4);
+ data32 &= (~0xF);
+ data32 |= 0xf; /* valid only when double write only */
+ /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
/* swap uv */
if (hw->is_used_v4l) {
@@ -4376,8 +4290,7 @@
else
data32 &= ~(1 << 12); /* NV12 */
}
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
+
/*
* [3:0] little_endian
* [5:4] address_format 00:linear 01:32x32 10:64x32
@@ -4942,7 +4855,7 @@
lf->sharpness_level =
hw->aom_param.p.loop_filter_sharpness_level;
if (((hw->aom_param.p.loop_filter_mode_ref_delta_enabled)&3) == 3) { // enabled but and update
- if (cm->prev_frame <= 0) {
+ if (cm->prev_frame == NULL) {
// already initialized in Microcode
lf->ref_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7);
lf->ref_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7);
@@ -4988,7 +4901,7 @@
}
} //else if (hw->aom_param.p.loop_filter_mode_ref_delta_enabled == 1) { // enabled but no update
else { // match c code -- not enabled, still need to copy prev to used for next
- if ((cm->prev_frame <= 0) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) {
+ if ((cm->prev_frame == NULL) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) {
av1_print(hw, AOM_DEBUG_HW_MORE,
"[test.c] mode_ref_delta set to default\n");
lf->ref_deltas[0] = conv2int8((uint8_t)1,7);
@@ -5004,16 +4917,18 @@
} else {
av1_print(hw, AOM_DEBUG_HW_MORE,
"[test.c] mode_ref_delta copy from prev_frame\n");
- lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0];
- lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1];
- lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2];
- lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3];
- lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4];
- lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5];
- lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6];
- lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7];
- lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0];
- lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1];
+ if (cm->prev_frame) {
+ lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0];
+ lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1];
+ lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2];
+ lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3];
+ lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4];
+ lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5];
+ lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6];
+ lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7];
+ lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0];
+ lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1];
+ }
}
}
lf->filter_level[0] = hw->aom_param.p.loop_filter_level_0;
@@ -5021,23 +4936,24 @@
lf->filter_level_u = hw->aom_param.p.loop_filter_level_u;
lf->filter_level_v = hw->aom_param.p.loop_filter_level_v;
- cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0];
- cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1];
- cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2];
- cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3];
- cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4];
- cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5];
- cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6];
- cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7];
- cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0];
- cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1];
+ if (cm->cur_frame) {
+ cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0];
+ cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1];
+ cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2];
+ cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3];
+ cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4];
+ cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5];
+ cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6];
+ cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7];
+ cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0];
+ cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1];
- // get seg_4lf parameters from parser
- seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1;
- cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1;
- cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1;
- cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1;
-
+ // get seg_4lf parameters from parser
+ seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1;
+ cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1;
+ cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1;
+ cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1;
+ }
if (hw->aom_param.p.segmentation_enabled & 1) { // segmentation_enabled
if (hw->aom_param.p.segmentation_enabled & 2) { // segmentation_update_data
for (i = 0; i < MAX_SEGMENTS; i++) {
@@ -5050,7 +4966,7 @@
}
} // segmentation_update_data
else { // no segmentation_update_data
- if (cm->prev_frame <= 0) {
+ if (cm->prev_frame == NULL) {
for (i=0;i<MAX_SEGMENTS;i++) {
seg_4lf->seg_lf_info_y[i] = 0;
seg_4lf->seg_lf_info_c[i] = 0;
@@ -5106,7 +5022,7 @@
av1_print(hw, AOM_DEBUG_HW_MORE,
"[test.c] cur_frame : %p prev_frame : %p - %p \n",
cm->cur_frame, cm->prev_frame, av1_get_primary_ref_frame_buf(cm));
- if (cm->cur_frame <= 0) {
+ if (cm->cur_frame == NULL) {
WRITE_VREG(AOM_AV1_CDF_BUFFER_W, buf_spec->cdf_buf.buf_start);
WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W, buf_spec->seg_map.buf_start);
}
@@ -5121,7 +5037,7 @@
}
cm->cur_frame->seg_mi_rows = cm->cur_frame->mi_rows;
cm->cur_frame->seg_mi_cols = cm->cur_frame->mi_cols;
- if (cm->prev_frame <= 0) {
+ if (cm->prev_frame == NULL) {
WRITE_VREG(AOM_AV1_CDF_BUFFER_R, buf_spec->cdf_buf.buf_start);
WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R, buf_spec->seg_map.buf_start);
} else {
@@ -5406,13 +5322,6 @@
}
#endif
#endif
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
-#endif
}
config_aux_buf(hw);
@@ -5518,13 +5427,10 @@
if (mask & HW_MASK_BACK) {
/*Initial IQIT_SCALELUT memory
-- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(hw->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
+
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
}
if (mask & HW_MASK_FRONT) {
@@ -5852,14 +5758,25 @@
buf_alloc_width = 8192;
buf_alloc_height = 4608;
}
-
+#if 0
+ hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w :
+ (buf_alloc_width ? buf_alloc_width :
+ (hw->vav1_amstream_dec_info.width ?
+ hw->vav1_amstream_dec_info.width :
+ hw->work_space_buf->max_width));
+ hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h :
+ (buf_alloc_height ? buf_alloc_height :
+ (hw->vav1_amstream_dec_info.height ?
+ hw->vav1_amstream_dec_info.height :
+ hw->work_space_buf->max_height));
+#else
hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w :
(hw->vav1_amstream_dec_info.width ? hw->vav1_amstream_dec_info.width :
(buf_alloc_width ? buf_alloc_width : hw->work_space_buf->max_width));
hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h :
(hw->vav1_amstream_dec_info.height ? hw->vav1_amstream_dec_info.height :
(buf_alloc_height ? buf_alloc_height : hw->work_space_buf->max_height));
-
+#endif
hw->pbi->frame_width = hw->init_pic_w;
hw->pbi->frame_height = hw->init_pic_h;
@@ -5872,9 +5789,9 @@
(hw->vav1_amstream_dec_info.width % 64) != 0)) {
if (hw_to_vdec(hw)->canvas_mode !=
CANVAS_BLKMODE_LINEAR)
- hw->mem_map_mode = 2;
+ mem_map_mode = 2;
else {
- hw->mem_map_mode = 0;
+ mem_map_mode = 0;
av1_print(hw, AOM_DEBUG_HW_MORE, "vdec blkmod linear, force mem_map_mode 0\n");
}
}
@@ -5978,7 +5895,6 @@
}
memset(hw->count_buffer_addr, 0, COUNT_BUF_SIZE);
- vdec_set_vframe_comm(hw_to_vdec(hw), DRIVER_NAME);
ret = vav1_mmu_map_alloc(hw);
if (ret < 0)
goto dma_alloc_fail;
@@ -6003,18 +5919,20 @@
struct vdec_s *vdec = hw_to_vdec(hw);
int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4;
int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4;
- int blkmode = hw->mem_map_mode;
+ int blkmode = mem_map_mode;
/*CANVAS_BLKMODE_64X32*/
if (pic_config->double_write_mode) {
canvas_w = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
canvas_h = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
- /* sao ctrl1 config aligned with 64, so aligned with 64 same */
- canvas_w = ALIGN(canvas_w, 64);
+ if (mem_map_mode == 0)
+ canvas_w = ALIGN(canvas_w, 32);
+ else
+ canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
if (vdec->parallel_dec == 1) {
@@ -6029,12 +5947,12 @@
pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1;
}
- config_cav_lut_ex(pic_config->y_canvas_index,
+ canvas_config_ex(pic_config->y_canvas_index,
pic_config->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic_config->uv_canvas_index,
+ CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7);
+ canvas_config_ex(pic_config->uv_canvas_index,
pic_config->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7);
#ifdef MULTI_INSTANCE_SUPPORT
pic_config->canvas_config[0].phy_addr =
@@ -6143,11 +6061,10 @@
if (kfifo_get(&hw->display_q, &vf)) {
struct vframe_s *next_vf = NULL;
uint8_t index = vf->index & 0xff;
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
+ ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
if (index < hw->used_buf_num ||
(vf->type & VIDTYPE_V4L_EOS)) {
hw->vf_get_count++;
- vf->index_disp = hw->vf_get_count;
if (debug & AOM_DEBUG_VFRAME) {
struct BufferPool_s *pool = hw->common.buffer_pool;
struct PIC_BUFFER_CONFIG_s *pic =
@@ -6193,14 +6110,16 @@
static void vav1_vf_put(struct vframe_s *vf, void *op_arg)
{
struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
- uint8_t index = vf->index & 0xff;
+ uint8_t index;
unsigned long flags;
if ((vf == NULL) || (hw == NULL))
return;
+ index = vf->index & 0xff;
+
kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
+ ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
hw->vf_put_count++;
if (debug & AOM_DEBUG_VFRAME) {
lock_buffer_pool(hw->common.buffer_pool, flags);
@@ -6222,6 +6141,10 @@
if (pool->frame_bufs[index].buf.vf_ref > 0)
pool->frame_bufs[index].buf.vf_ref--;
}
+
+ if (hw->is_used_v4l)
+ pool->frame_bufs[index].buf.vframe_bound = true;
+
if (hw->wait_buf)
WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
0x1);
@@ -6402,27 +6325,27 @@
(debug & AOM_DEBUG_DW_DISP_MAIN) == 0) {
vf->mem_handle =
decoder_mmu_box_get_mem_handle(
- hw->mmu_box_dw, pic->index);
+ hw->mmu_box_dw, hw->buffer_wrap[pic->index]);
vf->mem_head_handle =
decoder_bmmu_box_get_mem_handle(
hw->bmmu_box,
- DW_HEADER_BUFFER_IDX(pic->BUF_index));
+ DW_HEADER_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index]));
vf->mem_dw_handle = NULL;
} else
#endif
{
vf->mem_handle =
decoder_mmu_box_get_mem_handle(
- hw->mmu_box, pic->index);
+ hw->mmu_box, hw->buffer_wrap[pic->index]);
vf->mem_head_handle =
decoder_bmmu_box_get_mem_handle(
hw->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
+ HEADER_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index]));
if (hw->double_write_mode == 3)
vf->mem_dw_handle =
decoder_bmmu_box_get_mem_handle(
hw->bmmu_box,
- VF_BUFFER_IDX(pic->BUF_index));
+ VF_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index]));
else
vf->mem_dw_handle = NULL;
}
@@ -6432,7 +6355,7 @@
} else {
vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
+ hw->bmmu_box, VF_BUFFER_IDX(hw->buffer_wrap[pic->BUF_index]));
vf->mem_head_handle = NULL;
vf->mem_dw_handle = NULL;
/*vf->mem_head_handle =
@@ -6442,47 +6365,22 @@
}
}
-static inline void av1_update_gvs(struct AV1HW_s *hw, struct vframe_s *vf,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- if (hw->gvs->frame_height != pic_config->y_crop_height) {
- hw->gvs->frame_width = pic_config->y_crop_width;
- hw->gvs->frame_height = pic_config->y_crop_height;
- }
- if (hw->gvs->frame_dur != hw->frame_dur) {
- hw->gvs->frame_dur = hw->frame_dur;
- if (hw->frame_dur != 0)
- hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- hw->gvs->frame_rate = -1;
- }
- if (vf && hw->gvs->ratio_control != vf->ratio_control)
- hw->gvs->ratio_control = vf->ratio_control;
-
- hw->gvs->status = hw->stat | hw->fatal_error;
- hw->gvs->error_count = hw->gvs->error_frame_count;
-
-}
-
static int prepare_display_buf(struct AV1HW_s *hw,
struct PIC_BUFFER_CONFIG_s *pic_config)
{
struct vframe_s *vf = NULL;
- struct vdec_info tmp4x;
int stream_offset = pic_config->stream_offset;
struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
ulong nv_order = VIDTYPE_VIU_NV21;
u32 pts_valid = 0, pts_us64_valid = 0;
- u32 frame_size;
+ u32 frame_size = 0;
+ int i, reclac_flag = 0;
av1_print(hw, AOM_DEBUG_VFRAME, "%s index = %d\r\n", __func__, pic_config->index);
if (kfifo_get(&hw->newframe_q, &vf) == 0) {
av1_print(hw, 0, "fatal error, no available buffer slot.");
return -1;
}
-
/* swap uv */
if (hw->is_used_v4l) {
if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
@@ -6496,10 +6394,49 @@
display_frame_count[hw->index]++;
if (vf) {
+ if (!force_pts_unstable && (hw->av1_first_pts_ready)) {
+ if (hw->is_used_v4l) {
+ if ((pic_config->timestamp == 0) || (pic_config->timestamp <= hw->last_timestamp)) {
+ for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
+ if (hw->last_timestamp == hw->frame_mode_timestamp_save[i]) {
+ pic_config->timestamp = hw->frame_mode_timestamp_save[i - 1];
+ break;
+ }
+ }
+
+ if ((i == 0) || (pic_config->timestamp <= hw->last_timestamp)) {
+ av1_print(hw, AV1_DEBUG_OUT_PTS,
+ "no found timestamp %d, set 0. %lld, %lld\n",
+ i, pic_config->timestamp, hw->last_timestamp);
+ pic_config->timestamp = 0;
+ }
+ }
+ } else {
+ if ((pic_config->pts == 0) || ((pic_config->pts <= hw->last_pts) &&
+ (pic_config->pts64 <= hw->last_pts_us64))) {
+ for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
+ if ((hw->last_pts == hw->frame_mode_pts_save[i]) ||
+ (hw->last_pts_us64 == hw->frame_mode_pts64_save[i])) {
+ pic_config->pts = hw->frame_mode_pts_save[i - 1];
+ pic_config->pts64 = hw->frame_mode_pts64_save[i - 1];
+ break;
+ }
+ }
+
+ if ((i == 0) || (pic_config->pts <= hw->last_pts)) {
+ av1_print(hw, AV1_DEBUG_OUT_PTS,
+ "no found pts %d, set 0. %d, %d\n",
+ i, pic_config->pts, hw->last_pts);
+ pic_config->pts = 0;
+ pic_config->pts64 = 0;
+ }
+ }
+ }
+ }
+
if (hw->is_used_v4l) {
vf->v4l_mem_handle
= hw->m_BUF[pic_config->BUF_index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
if (hw->mmu_enable) {
vf->mm_box.bmmu_box = hw->bmmu_box;
vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->BUF_index]);
@@ -6512,12 +6449,7 @@
if (vdec_frame_based(hw_to_vdec(hw))) {
vf->pts = pic_config->pts;
vf->pts_us64 = pic_config->pts64;
-
- if (hw->is_used_v4l && v4l_bitstream_id_enable)
- vf->timestamp = pic_config->timestamp;
- else
- vf->timestamp = pic_config->pts64;
-
+ vf->timestamp = pic_config->timestamp;
if (vf->pts != 0 || vf->pts_us64 != 0) {
pts_valid = 1;
pts_us64_valid = 1;
@@ -6545,6 +6477,68 @@
pts_valid = 1;
pts_us64_valid = 1;
}
+
+ if (hw->av1_first_pts_ready) {
+ if (hw->is_used_v4l) {
+ if (hw->frame_dur && (vf->timestamp == 0)) {
+ vf->timestamp = hw->last_timestamp +
+ hw->timestamp_duration;
+ }
+
+ if (!close_to(vf->timestamp, (hw->last_timestamp +
+ hw->timestamp_duration), 100)) {
+ vf->timestamp = hw->last_timestamp +
+ hw->timestamp_duration;
+ }
+ } else {
+ if (hw->frame_dur && ((vf->pts == 0) || (vf->pts_us64 == 0))) {
+ vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
+ vf->pts_us64 = hw->last_pts_us64 +
+ (DUR2PTS(hw->frame_dur) * 100 / 9);
+ reclac_flag = 1;
+ }
+
+ if (!close_to(vf->pts, (hw->last_pts + DUR2PTS(hw->frame_dur)), 100)) {
+ vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
+ vf->pts_us64 = hw->last_pts_us64 +
+ (DUR2PTS(hw->frame_dur) * 100 / 9);
+ reclac_flag = 2;
+ }
+ }
+
+ /* try find the closed pts in saved pts pool */
+ if (reclac_flag) {
+ for (i = 0; i < FRAME_BUFFERS - 1; i++) {
+ if ((hw->frame_mode_pts_save[i] > vf->pts) &&
+ (hw->frame_mode_pts_save[i + 1] < vf->pts)) {
+ if ((hw->frame_mode_pts_save[i] - vf->pts) >
+ (vf->pts - hw->frame_mode_pts_save[i + 1])) {
+ vf->pts = hw->frame_mode_pts_save[i + 1];
+ vf->pts_us64 = hw->frame_mode_pts64_save[i + 1];
+ } else {
+ vf->pts = hw->frame_mode_pts_save[i];
+ vf->pts_us64 = hw->frame_mode_pts64_save[i];
+ }
+ break;
+ }
+ }
+ if (i == (FRAME_BUFFERS - 1))
+ hw->dur_recalc_flag = 1;
+ }
+ } else {
+ av1_print(hw, AV1_DEBUG_OUT_PTS,
+ "first pts %d change to save[%d] %d, ts: %llu\n",
+ vf->pts, hw->first_pts_index - 1,
+ hw->frame_mode_pts_save[hw->first_pts_index - 1],
+ hw->frame_mode_timestamp_save[hw->first_pts_index - 1]);
+ vf->pts = hw->frame_mode_pts_save[hw->first_pts_index - 1];
+ vf->pts_us64 = hw->frame_mode_pts64_save[hw->first_pts_index - 1];
+ vf->timestamp = hw->frame_mode_timestamp_save[hw->first_pts_index - 1];
+ }
+ hw->last_pts = vf->pts;
+ hw->last_pts_us64 = vf->pts_us64;
+ hw->last_timestamp = vf->timestamp;
+ hw->av1_first_pts_ready = true;
av1_print(hw, AV1_DEBUG_OUT_PTS,
"av1 output slice type %d, dur %d, pts %d, pts64 %lld, ts: %llu\n",
pic_config->slice_type, hw->frame_dur, vf->pts, vf->pts_us64, vf->timestamp);
@@ -6575,10 +6569,10 @@
vf->dwHeadAddr = pic_config->header_dw_adr;
else if ((mode == 1 || mode == 2 || mode == 4)
&& (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) {
- vf->compHeadAddr = pic_config->header_dw_adr;
- vf->fgs_valid = 0;
- av1_print(hw, 0,
- "Use dw mmu for display\n");
+ vf->compHeadAddr = pic_config->header_dw_adr;
+ vf->fgs_valid = 0;
+ av1_print(hw, AOM_DEBUG_VFRAME,
+ "Use dw mmu for display\n");
}
}
#endif
@@ -6594,7 +6588,7 @@
(pic_config->double_write_mode & 0x20) == 0) {
vf->type = VIDTYPE_PROGRESSIVE |
VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
+ vf->type |= VIDTYPE_VIU_NV21;
if ((pic_config->double_write_mode == 3 ||
pic_config->double_write_mode == 5) &&
(!IS_8K_SIZE(pic_config->y_crop_width,
@@ -6655,11 +6649,11 @@
vf->width,vf->height, pic_config->width,
pic_config->height); */
vf->width = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
vf->height = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
if (force_w_h != 0) {
vf->width = (force_w_h >> 16) & 0xffff;
vf->height = force_w_h & 0xffff;
@@ -6668,11 +6662,11 @@
((pic_config->double_write_mode & 0xf) == 2 ||
(pic_config->double_write_mode & 0xf) == 4)) {
vf->compWidth = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
vf->compHeight = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(hw,
+ pic_config->double_write_mode);
} else {
vf->compWidth = pic_config->y_crop_width;
vf->compHeight = pic_config->y_crop_height;
@@ -6692,60 +6686,20 @@
decoder_do_frame_check(hw_to_vdec(hw), vf);
vdec_vframe_ready(hw_to_vdec(hw), vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.pts_name, vf->pts);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
+ ATRACE_COUNTER(hw->pts_name, vf->pts);
+ ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
+ ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
hw->vf_pre_count++;
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
/*count info*/
- hw->gvs->frame_dur = hw->frame_dur;
- vdec_count_info(hw->gvs, 0, stream_offset);
-
- hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id);
-
-#ifdef AUX_DATA_CRC
- decoder_do_aux_data_check(hw_to_vdec(hw), pic_config->aux_data_buf,
- pic_config->aux_data_size);
+ gvs->frame_dur = hw->frame_dur;
+ vdec_count_info(gvs, 0, stream_offset);
#endif
-
- av1_print(hw, AV1_DEBUG_SEI_DETAIL, "%s aux_data_size = %d\n",
- __func__, pic_config->aux_data_size);
-
- if (debug & AV1_DEBUG_SEI_DETAIL) {
- int i = 0;
- PR_INIT(128);
- for (i = 0; i < pic_config->aux_data_size; i++) {
- PR_FILL("%02x ", pic_config->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hw->index);
- }
- PR_INFO(hw->index);
- }
-
- if (hw->is_used_v4l) {
- update_vframe_src_fmt(vf,
- pic_config->aux_data_buf,
- pic_config->aux_data_size,
- false, hw->provider_name, NULL);
- }
-
- av1_update_gvs(hw, vf, pic_config);
- memcpy(&tmp4x, hw->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = bit_depth_luma;
- tmp4x.bit_depth_chroma = bit_depth_chroma;
- tmp4x.double_write_mode = pic_config->double_write_mode;
- vdec_fill_vdec_frame(hw_to_vdec(hw), &hw->vframe_qos, &tmp4x, vf, pic_config->hw_decode_time);
+ hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id);
if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vav1_vf_put(vav1_vf_get(hw), hw);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
+ vf_notify_receiver(hw->provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
} else
vav1_vf_put(vav1_vf_get(hw), hw);
}
@@ -6779,8 +6733,7 @@
}
if (index == INVALID_IDX) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
pr_err("[%d] EOS get free buff fail.\n", ctx->id);
return -1;
}
@@ -6792,18 +6745,14 @@
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
hw->m_BUF[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
-
- av1_print(hw, 0, "[%d] AV1 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
+ av1_print(hw, PRINT_FLAG_V4L_DETAIL,
+ "[%d] AV1 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
return 0;
@@ -6844,21 +6793,10 @@
if (check_dma)
hevc_mmu_dma_check(hw_to_vdec(hw));
- if (hw->is_used_v4l) {
- int index = cm->cur_fb_idx_mmu;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- hw->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- hw->mmu_box,
- cm->cur_fb_idx_mmu,
- hw->used_4k_num);
- }
+ decoder_mmu_box_free_idx_tail(
+ hw->mmu_box,
+ hw->buffer_wrap[cm->cur_fb_idx_mmu],
+ hw->used_4k_num);
cm->cur_fb_idx_mmu = INVALID_IDX;
hw->used_4k_num = -1;
@@ -6893,7 +6831,7 @@
return;
if (cm->cur_fb_idx_mmu != INVALID_IDX) {
decoder_mmu_box_free_idx(hw->mmu_box,
- cm->cur_fb_idx_mmu);
+ hw->buffer_wrap[cm->cur_fb_idx_mmu]);
cm->cur_fb_idx_mmu = INVALID_IDX;
hw->used_4k_num = -1;
@@ -7164,12 +7102,12 @@
av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : %d\n", hitrate);
hitrate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt;
av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : %d\n", hitrate);
+ mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt;
+ mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt;
} else {
av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : na\n");
av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : na\n");
}
- mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt;
- mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt;
return;
}
@@ -7199,7 +7137,7 @@
if ( raw_mcr_cnt != 0 ) {
hitrate = 100*hit_mcr_cnt/raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %.2f\%\n", hitrate);
+ av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
} else {
av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : na\n");
}
@@ -7399,36 +7337,9 @@
#endif
-#if 0
-void release_unused_4k_ext(MMU_BUFF_MGR *mmumgr, int32_t cur_buf_idx, long used_4k_num)
-{
- int32_t release_4k_position;
- int32_t i;
-
- if(mmumgr->mmu_pic_count < 0) return;
-
- mmumgr->mmu_offset_seed = used_4k_num & 0xff;
- if(used_4k_num > mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number) {
- printk("[MMU MEM ERROR] : Use more 4K Page than allocated %d > ([%d] = %d)!!\r\n", used_4k_num, cur_buf_idx, mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number);
- }
- else printk("[MMU MEM RELEASE] : P%d(buffer %d) used %d of %d 4k buffer (%d%c)\r\n", mmumgr->mmu_pic_count, cur_buf_idx, used_4k_num, mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number, used_4k_num*100/mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number, '%');
-
- for(i = used_4k_num; i<mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number; i++){
- release_4k_position = mmumgr->mmu_buf[cur_buf_idx].mmu_4k_index[i] - mmumgr->MC_BUFFER_START_4K_ADR;
- printk("[MMU MEM RELEASE DEBUG] release_4k_position[%d] : 0x%x\n", i, release_4k_position+mmumgr->MC_BUFFER_START_4K_ADR);
- mmumgr->mmu_4k_status[release_4k_position] = 0;
- }
- mmumgr->cur_mem_usage -= (mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number - used_4k_num)*4096;
- mmumgr->mmu_buf[cur_buf_idx].mmu_4k_number = used_4k_num;
-}
-#endif
-
int av1_continue_decoding(struct AV1HW_s *hw, int obu_type)
{
- int ret = 0;
-#ifdef SANITY_CHECK
- param_t* params = &hw->aom_param;
-#endif
+ int ret;
#if 1
//def CHANGE_DONE
AV1Decoder *pbi = hw->pbi;
@@ -7472,70 +7383,18 @@
} else {
hw->new_compressed_data = 0;
}
-#ifdef SEND_MMU_USED_NUM
- if (cm->prev_fb_idx != INVALID_IDX) {
- long used_4k_num = aom_param.p.mmu_used_num;
- if (used_4k_num != 0) {
- printk("mmu free tail, index %d used_num 0x%x\n",
- cm->prev_fb_idx, used_4k_num);
- release_unused_4k_ext(&av1_mmumgr_m, cm->prev_fb_idx, used_4k_num);
- }
-
-#ifdef AOM_AV1_MMU_DW
- used_4k_num = aom_param.p.dw_mmu_used_num;
- if (used_4k_num != 0) {
- release_unused_4k_ext(&av1_mmumgr_dw, cm->prev_fb_idx, used_4k_num);
- printk("dw mmu free tail, index %d used_num 0x%x\n",
- cm->prev_fb_idx, used_4k_num);
- }
-#endif
- }
- cm->prev_fb_idx = INVALID_IDX;
-
-#endif
-#ifdef SANITY_CHECK
- ret = 0;
+ ret = av1_bufmgr_process(pbi, &hw->aom_param,
+ hw->new_compressed_data, obu_type);
av1_print(hw, AOM_DEBUG_HW_MORE,
- "Check Picture size, max (%d, %d), width/height (%d, %d), dec_width %d\n",
- params->p.max_frame_width,
- params->p.max_frame_height,
- params->p.frame_width_scaled,
- params->p.frame_height,
- params->p.dec_frame_width
- );
+ "%s: pbi %p cm %p cur_frame %p\n",
+ __func__, pbi, cm, cm->cur_frame);
- if (/*params->p.max_frame_width > MAX_PIC_WIDTH ||
- params->p.max_frame_height > MAX_PIC_HEIGHT ||*/
- (params->p.frame_width_scaled * params->p.frame_height) > MAX_SIZE_8K ||
- (params->p.dec_frame_width * params->p.frame_height) > MAX_SIZE_8K ||
- params->p.frame_width_scaled <= 0 ||
- params->p.dec_frame_width <= 0 ||
- params->p.frame_height <= 0) {
- av1_print(hw, 0, "!!Picture size error, max (%d, %d), width/height (%d, %d), dec_width %d\n",
- params->p.max_frame_width,
- params->p.max_frame_height,
- params->p.frame_width_scaled,
- params->p.frame_height,
- params->p.dec_frame_width
- );
- ret = -1;
- }
-#endif
- if (ret >= 0) {
- ret = av1_bufmgr_process(pbi, &hw->aom_param,
- hw->new_compressed_data, obu_type);
- if (ret < 0)
- return -1;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: pbi %p cm %p cur_frame %p\n",
- __func__, pbi, cm, cm->cur_frame);
+ av1_print(hw, AOM_DEBUG_HW_MORE,
+ "1+++++++++++++++++++++++++++++++++++%d %p\n",
+ ret, cm->cur_frame);
+ if (hw->new_compressed_data)
+ WRITE_VREG(PIC_END_LCU_COUNT, 0);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "1+++++++++++++++++++++++++++++++++++%d %p\n",
- ret, cm->cur_frame);
- if (hw->new_compressed_data)
- WRITE_VREG(PIC_END_LCU_COUNT, 0);
- }
if (ret > 0) {
/* the case when cm->show_existing_frame is 1 */
/*case 3016*/
@@ -7557,16 +7416,16 @@
av1_print(hw, AOM_DEBUG_HW_MORE,
"aom_bufmgr_process=> %d,decode done, AOM_AV1_SEARCH_HEAD\r\n", ret);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
pbi->decode_idx++;
pbi->bufmgr_proc_count++;
hw->frame_decoded = 1;
return 0;
- } else if (ret < 0) {
+ }
+ else if (ret < 0) {
hw->frame_decoded = 1;
av1_print(hw, AOM_DEBUG_HW_MORE,
- "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r. %d, AOM_AV1_SEARCH_HEAD\r\n",
- ret, cm->error.error_code);
+ "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r., AOM_AV1_SEARCH_HEAD\r\n", ret);
WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
return 0;
}
@@ -7628,25 +7487,18 @@
pbi->bufmgr_proc_count);
pbi->decode_idx++;
hw->frame_count++;
-#ifdef SEND_MMU_USED_NUM
- cm->prev_fb_idx = cm->cur_fb_idx_mmu;
- cm->cur_fb_idx_mmu = cm->cur_frame->buf.index;
-#endif
cur_pic_config->slice_type = cm->cur_frame->frame_type;
if (hw->chunk) {
av1_print(hw, AV1_DEBUG_OUT_PTS,
- "%s, config pic pts %d, pts64 %lld, ts: %lld\n",
- __func__, hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp);
+ "%s, config pic pts %d, pts64 %lld\n",
+ __func__, hw->chunk->pts, hw->chunk->pts64);
cur_pic_config->pts = hw->chunk->pts;
cur_pic_config->pts64 = hw->chunk->pts64;
cur_pic_config->timestamp = hw->chunk->timestamp;
-
- if (hw->is_used_v4l && !v4l_bitstream_id_enable) {
- cur_pic_config->pts64 = hw->chunk->timestamp;
- hw->chunk->timestamp = 0;
- }
+ hw->chunk->pts = 0;
+ hw->chunk->pts64 = 0;
+ hw->chunk->timestamp = 0;
}
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
#ifdef DUAL_DECODE
#else
config_pic_size(hw, hw->aom_param.p.bit_depth);
@@ -7659,14 +7511,12 @@
}
if (ret >= 0 && hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) {
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
ret = av1_alloc_mmu(hw,
cm->cur_frame->buf.index,
cur_pic_config->y_crop_width,
cur_pic_config->y_crop_height,
hw->aom_param.p.bit_depth,
hw->frame_mmu_map_addr);
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
if (ret >= 0)
cm->cur_fb_idx_mmu = cm->cur_frame->buf.index;
else
@@ -7717,16 +7567,6 @@
config_dblk_hw(hw);
- /* store segment_feature before shared sub-module run to fix mosaic on t5d */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index));
- else
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index));
- if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled
- WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO));
- else
- WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0);
-
av1_print(hw, AOM_DEBUG_HW_MORE, "HEVC_DEC_STATUS_REG <= AOM_AV1_DECODE_SLICE\n");
WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE);
@@ -7740,13 +7580,15 @@
cm->cur_frame->segment_feature[i] = (0x80000000 | (i << 22));
}
}
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE, "Sequence head, Search next start code\n");
- cm->prev_fb_idx = INVALID_IDX;
- //skip, search next start code
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)
+ WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index));
+ else
+ WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index));
+ if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled
+ WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO));
+ else
+ WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0);
}
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
return ret;
#else
@@ -7951,7 +7793,7 @@
frame->min_mv = a[0];
av1_print(hw, AV1_DEBUG_QOS_INFO,
- "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "mv data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
data = READ_VREG(HEVC_QP_INFO);
@@ -7978,7 +7820,7 @@
frame->min_qp = a[0];
av1_print(hw, AV1_DEBUG_QOS_INFO,
- "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "qp data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
data = READ_VREG(HEVC_SKIP_INFO);
@@ -8005,7 +7847,7 @@
frame->min_skip = a[0];
av1_print(hw, AV1_DEBUG_QOS_INFO,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "skip data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
} else {
uint32_t blk88_y_count;
@@ -8341,20 +8183,19 @@
//printf("Error, dec_status of 0x%x, not supported!!!\n", dec_status);
return -1;
}
- av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type);
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
- if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) {
- get_rpm_param(params);
- }
- else {
- for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
- int32_t ii;
- for (ii = 0; ii < 4; ii++) {
- params->l.data[i+ii]=hw->rpm_ptr[i+3-ii];
+ av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type);
+
+ if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) {
+ get_rpm_param(params);
+ }
+ else {
+ for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
+ int32_t ii;
+ for (ii = 0; ii < 4; ii++) {
+ params->l.data[i+ii]=hw->rpm_ptr[i+3-ii];
+ }
}
}
- }
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
params->p.enable_ref_frame_mvs = (params->p.seq_flags >> 7) & 0x1;
params->p.enable_superres = (params->p.seq_flags >> 15) & 0x1;
@@ -8381,29 +8222,14 @@
return av1_bufmgr_postproc(hw->pbi, hw->frame_decoded);
}
-static void vav1_get_comp_buf_info(struct AV1HW_s *hw,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = hw->param.p.bit_depth;
-
- info->max_size = av1_max_mmu_buf_size(
- hw->max_pic_w,
- hw->max_pic_h);
- info->header_size = av1_get_header_size(
- hw->frame_width,
- hw->frame_height);
- info->frame_buffer_size = av1_mmu_page_num(
- hw, hw->frame_width,
- hw->frame_height,
- bit_depth == 0);
-}
-
static int vav1_get_ps_info(struct AV1HW_s *hw, struct aml_vdec_ps_infos *ps)
{
- ps->visible_width = hw->frame_width;
- ps->visible_height = hw->frame_height;
- ps->coded_width = ALIGN(hw->frame_width, 64);
- ps->coded_height = ALIGN(hw->frame_height, 64);
+ int dw_mode = v4l_parser_get_double_write_mode(hw);
+
+ ps->visible_width = hw->frame_width / get_double_write_ratio(hw, dw_mode);
+ ps->visible_height = hw->frame_height / get_double_write_ratio(hw, dw_mode);
+ ps->coded_width = ALIGN(hw->frame_width, 32) / get_double_write_ratio(hw, dw_mode);
+ ps->coded_height = ALIGN(hw->frame_height, 32) / get_double_write_ratio(hw, dw_mode);
ps->dpb_size = hw->used_buf_num;
return 0;
@@ -8420,7 +8246,6 @@
if (ctx->param_sets_from_ucode &&
hw->res_ch_flag == 0) {
struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
if ((cm->width != 0 &&
cm->height != 0) &&
@@ -8431,11 +8256,6 @@
"%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width,
cm->height, hw->frame_width, hw->frame_height);
- if (get_valid_double_write_mode(hw) != 16) {
- vav1_get_comp_buf_info(hw, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
vav1_get_ps_info(hw, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
vdec_v4l_res_ch_event(ctx);
@@ -8459,16 +8279,9 @@
int obu_type;
int ret = 0;
- if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_FRAME_PARSER_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == AOM_AV1_DEC_PIC_END ||
- dec_status == AOM_NAL_DECODE_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
+ /*if (hw->wait_buf)
+ * pr_info("set wait_buf to 0\r\n");
+ */
if (hw->eos)
return IRQ_HANDLED;
hw->wait_buf = 0;
@@ -8482,7 +8295,6 @@
dec_again_process(hw);
else {
hw->dec_result = DEC_RESULT_DONE;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
vdec_schedule_work(&hw->work);
}
}
@@ -8490,8 +8302,6 @@
return IRQ_HANDLED;
} else if (dec_status == AOM_AV1_DEC_PIC_END) {
struct AV1_Common_s *const cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *frame = &cm->cur_frame->buf;
- struct vdec_s *vdec = hw_to_vdec(hw);
#if 1
u32 fg_reg0, fg_reg1, num_y_points, num_cb_points, num_cr_points;
WRITE_VREG(HEVC_FGS_IDX, 0);
@@ -8521,12 +8331,6 @@
#ifdef USE_DEC_PIC_END
if (READ_VREG(PIC_END_LCU_COUNT) != 0) {
hw->frame_decoded = 1;
- if (cm->cur_frame && vdec->mvfrm && frame) {
- frame->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- frame->frame_size2 = vdec->mvfrm->frame_size;
- }
- hw->gvs->frame_count = hw->frame_count;
/*
In c module, multi obus are put in one packet, which is decoded
with av1_receive_compressed_data().
@@ -8557,27 +8361,17 @@
if (cm->cur_frame != NULL) {
hevc_mmu_dma_check(hw_to_vdec(hw));
- av1_print(hw, AOM_DEBUG_HW_MORE, "mmu free tail, index %d used_num 0x%x\n",
+ av1_print(hw, AOM_DEBUG_HW_MORE, "mmu free tail, index %d used_num 0x%lx\n",
cm->cur_frame->buf.index, used_4k_num);
- if (hw->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, cm->cur_fb_idx_mmu);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(hw->mmu_box,
- cm->cur_frame->buf.index, used_4k_num);
- }
+ decoder_mmu_box_free_idx_tail(hw->mmu_box,
+ hw->buffer_wrap[cm->cur_frame->buf.index], used_4k_num);
#ifdef AOM_AV1_MMU_DW
if (hw->dw_mmu_enable) {
used_4k_num =
(READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16);
decoder_mmu_box_free_idx_tail(hw->mmu_box_dw,
- cm->cur_frame->buf.index, used_4k_num);
- av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%x\n",
+ hw->buffer_wrap[cm->cur_frame->buf.index], used_4k_num);
+ av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%lx\n",
cm->cur_frame->buf.index, used_4k_num);
}
#endif
@@ -8599,7 +8393,7 @@
hw->frame_decoded &&
READ_VREG(HEVC_SHIFT_BYTE_COUNT) < hw->data_size) {
#ifdef DEBUG_CRC_ERROR
- if ((crc_debug_flag & 0x40) && cm->cur_frame)
+ if (crc_debug_flag & 0x40)
dump_mv_buffer(hw, &cm->cur_frame->buf);
#endif
WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
@@ -8608,10 +8402,9 @@
hw->fgs_valid);
if (hw->config_next_ref_info_flag)
config_next_ref_info_hw(hw);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
} else {
#ifdef DEBUG_CRC_ERROR
- if ((crc_debug_flag & 0x40) && cm->cur_frame)
+ if (crc_debug_flag & 0x40)
dump_mv_buffer(hw, &cm->cur_frame->buf);
#endif
hw->dec_result = DEC_RESULT_DONE;
@@ -8620,13 +8413,13 @@
if (mcrcc_cache_alg_flag)
dump_hit_rate(hw);
#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
vdec_schedule_work(&hw->work);
}
} else {
av1_print(hw, AOM_DEBUG_HW_MORE,
"PIC_END, fgs_valid %d search head ...\n",
hw->fgs_valid);
+ WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
#ifdef USE_DEC_PIC_END
if (READ_VREG(PIC_END_LCU_COUNT) != 0) {
hw->frame_decoded = 1;
@@ -8637,13 +8430,11 @@
we assume each packet must and only include one picture of data (LCUs)
or cm->show_existing_frame is 1
*/
- if (cm->cur_frame)
- av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1);
+ av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
+ cm->cur_frame? cm->cur_frame->buf.index:-1);
config_next_ref_info_hw(hw);
}
#endif
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
/*
if (debug &
AV1_DEBUG_BUFMGR_MORE)
@@ -8721,9 +8512,8 @@
hw->mv_buf_margin = hw->used_buf_num - REF_FRAMES_4K + 1;
if (((hw->max_pic_w % 64) != 0) &&
(hw_to_vdec(hw)->canvas_mode != CANVAS_BLKMODE_LINEAR))
- hw->mem_map_mode = 2;
- av1_print(hw, 0,
- "force 8k double write 4, mem_map_mode %d\n", hw->mem_map_mode);
+ mem_map_mode = 2;
+ av1_print(hw, 0, "force 8k double write 4, mem_map_mode %d\n", mem_map_mode);
}
vav1_mmu_map_alloc(hw);
if (hw->mmu_enable)
@@ -8736,15 +8526,6 @@
WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
}
#endif
-
- /*v4l2 alloc new mv when max size changed */
- if (hw->is_used_v4l) {
- /* now less than 8k use fix mv buf size */
- if (IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h) && hw->pic_list_init_done) {
- if (init_mv_buf_list(hw) < 0)
- pr_err("%s: !!!!Error, reinit_mv_buf_list fail\n", __func__);
- }
- }
}
bit_depth_luma = hw->aom_param.p.bit_depth;
bit_depth_chroma = hw->aom_param.p.bit_depth;
@@ -8782,7 +8563,6 @@
"AOM_AV1_SEQ_HEAD_PARSER_DONE, search head ...\n");
WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
hw->process_busy = 0;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
return IRQ_HANDLED;
}
#ifndef USE_DEC_PIC_END
@@ -8797,9 +8577,8 @@
we assume each packet must and only include one picture of data (LCUs)
or cm->show_existing_frame is 1
*/
- if (cm->cur_frame)
- av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1);
+ av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
+ cm->cur_frame? cm->cur_frame->buf.index:-1);
}
}
#endif
@@ -8849,14 +8628,8 @@
if (!v4l_res_change(hw)) {
if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
pr_info("set ucode parse\n");
- if (get_valid_double_write_mode(hw) != 16) {
- vav1_get_comp_buf_info(hw, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
vav1_get_ps_info(hw, &ps);
/*notice the v4l2 codec.*/
vdec_v4l_set_ps_infos(ctx, &ps);
@@ -8874,18 +8647,6 @@
}
}
- if (hw->one_package_frame_cnt) {
- if (get_free_buf_count(hw) <= 0) {
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- hw->cur_obu_type = obu_type;
- hw->process_busy = 0;
- vdec_schedule_work(&hw->work);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
- }
- }
- hw->one_package_frame_cnt++;
-
ret = av1_continue_decoding(hw, obu_type);
hw->postproc_done = 0;
hw->process_busy = 0;
@@ -8899,7 +8660,7 @@
vdec_schedule_work(&hw->work);
}
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+
return IRQ_HANDLED;
}
@@ -8914,16 +8675,6 @@
WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
dec_status = READ_VREG(HEVC_DEC_STATUS_REG) & 0xff;
-
- if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_FRAME_PARSER_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == AOM_AV1_DEC_PIC_END ||
- dec_status == AOM_NAL_DECODE_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
if (!hw)
return IRQ_HANDLED;
if (hw->init_flag == 0)
@@ -9048,20 +8799,19 @@
hw->process_busy = 0;
return IRQ_HANDLED;
}
- if (get_free_buf_count(hw) <= 0) {
- /*
- if (hw->wait_buf == 0)
- pr_info("set wait_buf to 1\r\n");
- */
- hw->wait_buf = 1;
- hw->process_busy = 0;
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "free buf not enough = %d\n",
- get_free_buf_count(hw));
- return IRQ_HANDLED;
- }
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END);
+ if (get_free_buf_count(hw) <= 0) {
+ /*
+ if (hw->wait_buf == 0)
+ pr_info("set wait_buf to 1\r\n");
+ */
+ hw->wait_buf = 1;
+ hw->process_busy = 0;
+ av1_print(hw, AV1_DEBUG_BUFMGR,
+ "free buf not enough = %d\n",
+ get_free_buf_count(hw));
+ return IRQ_HANDLED;
+ }
return IRQ_WAKE_THREAD;
}
@@ -9077,10 +8827,10 @@
frame_height * fps;
}
-static void vav1_put_timer_func(struct timer_list *timer)
+static void vav1_put_timer_func(unsigned long arg)
{
- struct AV1HW_s *hw = container_of(timer,
- struct AV1HW_s, timer);
+ struct AV1HW_s *hw = (struct AV1HW_s *)arg;
+ struct timer_list *timer = &hw->timer;
uint8_t empty_flag;
unsigned int buf_level;
@@ -9286,18 +9036,19 @@
vstatus->error_count = 0;
vstatus->status = av1->stat | av1->fatal_error;
vstatus->frame_dur = av1->frame_dur;
-//#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vstatus->bit_rate = av1->gvs->bit_rate;
- vstatus->frame_data = av1->gvs->frame_data;
- vstatus->total_data = av1->gvs->total_data;
- vstatus->frame_count = av1->gvs->frame_count;
- vstatus->error_frame_count = av1->gvs->error_frame_count;
- vstatus->drop_frame_count = av1->gvs->drop_frame_count;
- vstatus->samp_cnt = av1->gvs->samp_cnt;
- vstatus->offset = av1->gvs->offset;
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+ vstatus->bit_rate = gvs->bit_rate;
+ vstatus->frame_data = gvs->frame_data;
+ vstatus->total_data = gvs->total_data;
+ vstatus->frame_count = gvs->frame_count;
+ vstatus->error_frame_count = gvs->error_frame_count;
+ vstatus->drop_frame_count = gvs->drop_frame_count;
+ vstatus->total_data = gvs->total_data;
+ vstatus->samp_cnt = gvs->samp_cnt;
+ vstatus->offset = gvs->offset;
snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
"%s", DRIVER_NAME);
-//#endif
+#endif
return 0;
}
@@ -9441,6 +9192,9 @@
hw->saved_resolution = 0;
hw->get_frame_dur = false;
on_no_keyframe_skiped = 0;
+ hw->first_pts_index = 0;
+ hw->dur_recalc_flag = 0;
+ hw->av1_first_pts_ready = false;
width = hw->vav1_amstream_dec_info.width;
height = hw->vav1_amstream_dec_info.height;
hw->frame_dur =
@@ -9521,10 +9275,12 @@
fw->len = fw_size;
INIT_WORK(&hw->set_clk_work, av1_set_clk);
- timer_setup(&hw->timer, vav1_put_timer_func, 0);
+ init_timer(&hw->timer);
#ifdef MULTI_INSTANCE_SUPPORT
if (hw->m_ins_flag) {
+ hw->timer.data = (ulong) hw;
+ hw->timer.function = vav1_put_timer_func;
hw->timer.expires = jiffies + PUT_INTERVAL;
/*add_timer(&hw->timer);
@@ -9574,18 +9330,16 @@
#endif
hw->provider_name = PROVIDER_NAME;
#ifdef MULTI_INSTANCE_SUPPORT
- if (!hw->is_used_v4l) {
- vf_provider_init(&vav1_vf_prov, hw->provider_name,
- &vav1_vf_provider, hw);
- vf_reg_provider(&vav1_vf_prov);
- vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL);
- if (hw->frame_dur != 0) {
- if (!is_reset)
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hw->frame_dur));
- }
+ vf_provider_init(&vav1_vf_prov, hw->provider_name,
+ &vav1_vf_provider, hw);
+ vf_reg_provider(&vav1_vf_prov);
+ vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL);
+ if (hw->frame_dur != 0) {
+ if (!is_reset)
+ vf_notify_receiver(hw->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)
+ ((unsigned long)hw->frame_dur));
}
#else
vf_provider_init(&vav1_vf_prov, hw->provider_name, &vav1_vf_provider,
@@ -9598,10 +9352,13 @@
#endif
hw->stat |= STAT_VF_HOOK;
+ hw->timer.data = (ulong)hw;
+ hw->timer.function = vav1_put_timer_func;
hw->timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&hw->timer);
hw->stat |= STAT_VDEC_RUN;
+
+ add_timer(&hw->timer);
hw->stat |= STAT_TIMER_ARM;
amhevc_start();
@@ -9630,7 +9387,7 @@
hw->stat &= ~STAT_TIMER_ARM;
}
- if (!hw->is_used_v4l && (hw->stat & STAT_VF_HOOK)) {
+ if (hw->stat & STAT_VF_HOOK) {
if (!is_reset)
vf_notify_receiver(hw->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -9674,7 +9431,7 @@
hw->stat &= ~STAT_TIMER_ARM;
}
- if (!hw->is_used_v4l && (hw->stat & STAT_VF_HOOK)) {
+ if (hw->stat & STAT_VF_HOOK) {
if (!is_reset)
vf_notify_receiver(hw->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -9715,7 +9472,7 @@
}
hw->need_cache_size = buf_size * SZ_1M;
hw->sc_start_time = get_jiffies_64();
- if (hw->mmu_enable && !hw->is_used_v4l) {
+ if (hw->mmu_enable) {
int count = FRAME_BUFFERS;
hw->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
hw->index /* * 2*/, count,
@@ -9775,12 +9532,13 @@
#ifndef MULTI_INSTANCE_SUPPORT
int i;
#endif
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TM2) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
- ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && !is_meson_rev_b())) {
- pr_err("av1 unsupported on cpu %d, is_tm2_revb %d\n",
+ pr_debug("%s\n", __func__);
+
+ if (!(is_cpu_tm2_revb() ||
+ (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2))) {
+ pr_err("unsupport av1, cpu %d, is_tm2_revb %d\n",
get_cpu_major_id(), is_cpu_tm2_revb());
- return -EINVAL;
+ return -EFAULT;
}
mutex_lock(&vav1_mutex);
@@ -9932,12 +9690,6 @@
cma_dev = pdata->cma_dev;
#endif
- hw->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- hw->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- hw->endian = endian;
-
#ifdef MULTI_INSTANCE_SUPPORT
pdata->private = hw;
pdata->dec_status = vav1_dec_status;
@@ -10110,12 +9862,6 @@
/* finished decoding one frame or error,
* notify vdec core to switch context
*/
- if (hw->dec_result != AOM_AV1_RESULT_NEED_MORE_BUFFER)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START);
-
- if (hw->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN);
-
av1_print(hw, PRINT_FLAG_VDEC_DETAIL,
"%s dec_result %d %x %x %x\n",
__func__,
@@ -10123,21 +9869,6 @@
READ_VREG(HEVC_STREAM_LEVEL),
READ_VREG(HEVC_STREAM_WR_PTR),
READ_VREG(HEVC_STREAM_RD_PTR));
-
- if (hw->dec_result == AOM_AV1_RESULT_NEED_MORE_BUFFER) {
- reset_process_time(hw);
- if (get_free_buf_count(hw) <= 0) {
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- } else {
- av1_release_bufs(hw);
- av1_continue_decoding(hw, hw->cur_obu_type);
- hw->postproc_done = 0;
- start_process_time(hw);
- }
- return;
- }
-
if (((hw->dec_result == DEC_RESULT_GET_DATA) ||
(hw->dec_result == DEC_RESULT_GET_DATA_RETRY))
&& (hw_to_vdec(hw)->next_status !=
@@ -10160,7 +9891,7 @@
}
if (get_free_buf_count(hw) >=
- hw->run_ready_min_buf_num) {
+ run_ready_min_buf_num) {
int r;
int decode_size;
r = vdec_prepare_input(vdec, &hw->chunk);
@@ -10273,7 +10004,6 @@
del_timer_sync(&hw->timer);
hw->stat &= ~STAT_TIMER_ARM;
}
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END);
/* mark itself has all HW resource released and input released */
if (vdec->parallel_dec == 1)
vdec_core_finish_run(vdec, CORE_MASK_HEVC);
@@ -10288,35 +10018,6 @@
vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK);
return 0;
}
-
-static bool is_avaliable_buffer(struct AV1HW_s *hw)
-{
- AV1_COMMON *cm = &hw->common;
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_count = 0;
-
- if (ctx->cap_pool.dec < hw->used_buf_num) {
- free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if (free_count &&
- !ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- return false;
- }
- }
-
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index >= 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_count++;
- }
- }
-
- return free_count < hw->run_ready_min_buf_num ? 0 : 1;
-}
-
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
{
struct AV1HW_s *hw =
@@ -10329,17 +10030,8 @@
return ret;
if (!hw->first_sc_checked && hw->mmu_enable) {
- int size;
- void * mmu_box;
+ int size = decoder_mmu_box_sc_check(hw->mmu_box, tvp);
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = hw->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
hw->first_sc_checked = 1;
av1_print(hw, 0, "av1 cached=%d need_size=%d speed= %d ms\n",
size, (hw->need_cache_size >> PAGE_SHIFT),
@@ -10353,7 +10045,7 @@
}
if (get_free_buf_count(hw) >=
- hw->run_ready_min_buf_num) {
+ run_ready_min_buf_num) {
if (vdec->parallel_dec == 1)
ret = CORE_MASK_HEVC;
else
@@ -10366,19 +10058,17 @@
if (ctx->param_sets_from_ucode) {
if (hw->v4l_params_parsed) {
- if (ctx->cap_pool.dec < hw->used_buf_num) {
- if (is_avaliable_buffer(hw))
- ret = CORE_MASK_HEVC;
- else
- ret = 0;
- }
+ if ((ctx->cap_pool.in < hw->used_buf_num) &&
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ run_ready_min_buf_num)
+ ret = 0;
} else {
if (ctx->v4l_resolution_change)
ret = 0;
}
} else if (ctx->cap_pool.in < ctx->dpb_size) {
if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
- hw->run_ready_min_buf_num)
+ run_ready_min_buf_num)
ret = 0;
}
}
@@ -10394,30 +10084,105 @@
return ret;
}
-static void av1_frame_mode_cal_dur(struct AV1HW_s *hw)
+static void av1_frame_mode_pts_save(struct AV1HW_s *hw)
{
+ u64 i, valid_pts_diff_cnt, pts_diff_sum;
+ u64 in_pts_diff, last_valid_pts_diff, calc_dur;
+
if (hw->chunk == NULL)
- return;
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "run_front: pts %d, pts64 %lld, ts: %llu\n",
- hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp);
+ return;
+ /* no return when first pts is 0 */
+ if (hw->first_pts_index) {
+ /* filtration pts 0 and continuous same pts */
+ if ((hw->chunk->pts == 0) ||
+ (hw->frame_mode_pts_save[0] == hw->chunk->pts))
+ return;
- if (hw->pts_diff_count > FRAME_BUFFERS)
- return ;
+ /* fps change, frame dur change to lower or higher,
+ * can't find closed pts in saved pool */
+ if ((hw->dur_recalc_flag) ||
+ (hw->last_pts > hw->chunk->pts)) {
+ hw->av1_first_pts_ready = 0;
+ hw->first_pts_index = 0;
+ hw->get_frame_dur = 0;
+ hw->dur_recalc_flag = 0;
+ memset(hw->frame_mode_pts_save, 0,
+ sizeof(hw->frame_mode_pts_save));
+ memset(hw->frame_mode_pts64_save, 0,
+ sizeof(hw->frame_mode_pts64_save));
+ /*v4l use*/
+ memset(hw->frame_mode_timestamp_save, 0,
+ sizeof(hw->frame_mode_timestamp_save));
+ }
+ }
+ av1_print(hw, AV1_DEBUG_OUT_PTS,
+ "run_front: pts %d, pts64 %lld, ts: %llu\n",
+ hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp);
- if ((hw->chunk->pts > hw->last_chunk_pts) && (hw->last_chunk_pts > 0)) {
- hw->pts_diff_count++;
- hw->pts_diff_sum = hw->pts_diff_sum + (hw->chunk->pts - hw->last_chunk_pts);
- if (hw->pts_diff_count > FRAME_BUFFERS) {
- u32 calc_dur = (u32)div_u64(div_u64(hw->pts_diff_sum, hw->pts_diff_count)*96, 90);
- if ((calc_dur <= 16000) && (calc_dur >= 800)) {
- av1_print(hw, 0, "change to calc dur %d, old dur %d\n", calc_dur, hw->frame_dur);
- hw->frame_dur = calc_dur;
- }
- }
+ for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
+ hw->frame_mode_pts_save[i] = hw->frame_mode_pts_save[i - 1];
+ hw->frame_mode_pts64_save[i] = hw->frame_mode_pts64_save[i - 1];
+ hw->frame_mode_timestamp_save[i] = hw->frame_mode_timestamp_save[i - 1];
+ }
+ hw->frame_mode_pts_save[0] = hw->chunk->pts;
+ hw->frame_mode_pts64_save[0] = hw->chunk->pts64;
+ hw->frame_mode_timestamp_save[0] = hw->chunk->timestamp;
+ if (hw->first_pts_index < ARRAY_SIZE(hw->frame_mode_pts_save))
+ hw->first_pts_index++;
+ /* frame duration check, vdec_secure return for nts problem */
+ if ((!hw->first_pts_index) || hw->get_frame_dur || vdec_secure(hw_to_vdec(hw)))
+ return;
+ valid_pts_diff_cnt = 0;
+ pts_diff_sum = 0;
+
+ for (i = 0; i < FRAME_BUFFERS - 1; i++) {
+ if (hw->is_used_v4l) {
+ if ((hw->frame_mode_timestamp_save[i] > hw->frame_mode_timestamp_save[i + 1]) &&
+ (hw->frame_mode_timestamp_save[i + 1] != 0))
+ in_pts_diff = hw->frame_mode_timestamp_save[i]
+ - hw->frame_mode_timestamp_save[i + 1];
+ else
+ in_pts_diff = 0;
+ } else {
+ if ((hw->frame_mode_pts_save[i] > hw->frame_mode_pts_save[i + 1]) &&
+ (hw->frame_mode_pts_save[i + 1] != 0))
+ in_pts_diff = hw->frame_mode_pts_save[i]
+ - hw->frame_mode_pts_save[i + 1];
+ else
+ in_pts_diff = 0;
}
- hw->last_chunk_pts = hw->chunk->pts;
+ if (in_pts_diff < 100 ||
+ (valid_pts_diff_cnt && (!close_to(in_pts_diff, last_valid_pts_diff, 100))))
+ in_pts_diff = 0;
+ else {
+ last_valid_pts_diff = in_pts_diff;
+ valid_pts_diff_cnt++;
+ }
+
+ pts_diff_sum += in_pts_diff;
+ }
+
+ if (!valid_pts_diff_cnt) {
+ av1_print(hw, 0, "checked no avaliable pts\n");
+ return;
+ }
+
+ calc_dur = PTS2DUR(pts_diff_sum / valid_pts_diff_cnt);
+ if ((!close_to(calc_dur, hw->frame_dur, 10)) &&
+ (calc_dur < 9601) && (calc_dur > 800)) {
+ av1_print(hw, 0, "change to calc dur %lld, old dur %d\n", calc_dur, hw->frame_dur);
+ hw->frame_dur = calc_dur;
+ hw->get_frame_dur = true;
+ } else {
+ if (hw->frame_count > FRAME_BUFFERS)
+ hw->get_frame_dur = true;
+ }
+
+ if (hw->is_used_v4l) {
+ hw->timestamp_duration =
+ pts_diff_sum / valid_pts_diff_cnt;
+ }
}
static void run_front(struct vdec_s *vdec)
@@ -10446,8 +10211,7 @@
hw->dec_result = DEC_RESULT_NONE;
hw->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- av1_frame_mode_cal_dur(hw);
-
+ av1_frame_mode_pts_save(hw);
if (debug & PRINT_FLAG_VDEC_STATUS) {
if (vdec_frame_based(vdec) && hw->chunk && !vdec_secure(vdec)) {
u8 *data = NULL;
@@ -10494,7 +10258,6 @@
hw->start_shift_bytes);
}
}
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
if (vdec->mc_loaded) {
/*firmware have load before,
and not changes to another.
@@ -10522,14 +10285,12 @@
vdec->mc_type = VFORMAT_AV1;
#endif
}
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
if (av1_hw_ctx_restore(hw) < 0) {
vdec_schedule_work(&hw->work);
return;
}
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
+
vdec_enable_input(vdec);
WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
@@ -10541,8 +10302,6 @@
WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
size = hw->chunk->size +
(hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hw->chunk->size;
}
hw->data_size = size;
WRITE_VREG(HEVC_DECODE_SIZE, size);
@@ -10575,19 +10334,14 @@
struct AV1HW_s *hw =
(struct AV1HW_s *)vdec->private;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START);
av1_print(hw,
PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n",
__func__, mask);
run_count[hw->index]++;
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
hw->vdec_cb_arg = arg;
hw->vdec_cb = callback;
- hw->one_package_frame_cnt = 0;
run_front(vdec);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END);
}
static void av1_decode_ctx_reset(struct AV1HW_s *hw)
@@ -10608,6 +10362,11 @@
for (i = 0; i < MV_BUFFER_NUM; i++) {
if (hw->m_mv_BUF[i].start_adr) {
+ if (mv_buf_dynamic_alloc) {
+ decoder_bmmu_box_free_idx(hw->bmmu_box, MV_BUFFER_IDX(i));
+ hw->m_mv_BUF[i].start_adr = 0;
+ hw->m_mv_BUF[i].size = 0;
+ }
hw->m_mv_BUF[i].used_flag = 0;
}
}
@@ -10700,7 +10459,7 @@
hw->no_head
);
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -10722,14 +10481,14 @@
hw->vf_get_count,
hw->vf_put_count,
get_free_buf_count(hw),
- hw->run_ready_min_buf_num
+ run_ready_min_buf_num
);
dump_pic_list(hw);
for (i = 0; i < MAX_BUF_NUM; i++) {
av1_print(hw, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
+ "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n",
i,
hw->m_mv_BUF[i].start_adr,
hw->m_mv_BUF[i].size,
@@ -10821,19 +10580,20 @@
struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
int ret;
int config_val;
- int i;
struct vframe_content_light_level_s content_light_level;
struct vframe_master_display_colour_s vf_dp;
u32 work_buf_size;
struct BuffInfo_s *p_buf_info;
- struct AV1HW_s *hw = NULL;
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TM2) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
- ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && !is_meson_rev_b())) {
- pr_err("av1 unsupported on cpu %d, is_tm2_revb %d\n",
+ struct BUF_s BUF[MAX_BUF_NUM];
+ struct AV1HW_s *hw = NULL;
+ pr_debug("%s\n", __func__);
+
+ if (!(is_cpu_tm2_revb() ||
+ (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2))) {
+ pr_err("unsupport av1, cpu %d, is_tm2_revb %d\n",
get_cpu_major_id(), is_cpu_tm2_revb());
- return -EINVAL;
+ return -EFAULT;
}
if (pdata == NULL) {
@@ -10876,35 +10636,19 @@
pdata->threaded_irq_handler = av1_threaded_irq_cb;
pdata->dump_state = av1_dump_state;
+ memcpy(&BUF[0], &hw->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ memcpy(&hw->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+
hw->index = pdev->id;
- if (is_rdma_enable()) {
- hw->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hw->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- hw->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- hw->rdma_adr[i * 4 + 1] = i;
- hw->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- hw->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- hw->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
- snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name),
+
+ snprintf(hw->vdec_name, sizeof(hw->vdec_name),
"av1-%d", hw->index);
- snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name),
- "%s-pts", hw->trace.vdec_name);
- snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name),
- "%s-newframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name),
- "%s-dispframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hw->trace.decode_header_memory_time_name, sizeof(hw->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
+ snprintf(hw->pts_name, sizeof(hw->pts_name),
+ "%s-pts", hw->vdec_name);
+ snprintf(hw->new_q_name, sizeof(hw->new_q_name),
+ "%s-newframe_q", hw->vdec_name);
+ snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
+ "%s-dispframe_q", hw->vdec_name);
if (pdata->use_vfm_path)
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
VFM_DEC_PROVIDER_NAME);
@@ -10926,12 +10670,18 @@
hevc_pair = (struct AV1HW_s *)pdata->master->private;
else if (pdata->slave)
hevc_pair = (struct AV1HW_s *)pdata->slave->private;
+
+ if (hevc_pair)
+ hw->shift_byte_count_lo = hevc_pair->shift_byte_count_lo;
}
#endif
else
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vav1_vf_provider, hw);
+
hw->provider_name = pdata->vf_provider_name;
platform_set_drvdata(pdev, pdata);
@@ -11069,38 +10819,25 @@
}
hw->vf_dp = vf_dp;
} else {
- u32 force_w, force_h;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
- force_w = 1920;
- force_h = 1088;
- } else {
- force_w = 8192;
- force_h = 4608;
- }
+ /*hw->vav1_amstream_dec_info.width = 0;
+ hw->vav1_amstream_dec_info.height = 0;
+ hw->vav1_amstream_dec_info.rate = 30;*/
if (hw->vav1_amstream_dec_info.width)
hw->max_pic_w = hw->vav1_amstream_dec_info.width;
else
- hw->max_pic_w = force_w;
+ hw->max_pic_w = 8192;
if (hw->vav1_amstream_dec_info.height)
hw->max_pic_h = hw->vav1_amstream_dec_info.height;
else
- hw->max_pic_h = force_h;
+ hw->max_pic_h = 4608;
hw->double_write_mode = double_write_mode;
}
- hw->endian = HEVC_CONFIG_LITTLE_ENDIAN;
if (!hw->is_used_v4l) {
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vav1_vf_provider, hw);
+ hw->mem_map_mode = mem_map_mode;
}
- hw->mem_map_mode = mem_map_mode;
- if (is_support_vdec_canvas())
- hw->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- hw->endian = endian;
-
if (is_oversize(hw->max_pic_w, hw->max_pic_h)) {
pr_err("over size: %dx%d, probe failed\n",
hw->max_pic_w, hw->max_pic_h);
@@ -11168,8 +10905,8 @@
#endif
av1_print(hw, 0,
- "no_head %d low_latency %d, signal_type 0x%x\n",
- hw->no_head, hw->low_latency_flag, hw->video_signal_type);
+ "no_head %d low_latency %d\n",
+ hw->no_head, hw->low_latency_flag);
#if 0
hw->buf_start = pdata->mem_start;
hw->buf_size = pdata->mem_end - pdata->mem_start + 1;
@@ -11201,7 +10938,6 @@
hw->first_sc_checked = 0;
hw->fatal_error = 0;
hw->show_frame_num = 0;
- hw->run_ready_min_buf_num = run_ready_min_buf_num;
if (debug) {
av1_print(hw, AOM_DEBUG_HW_MORE, "===AV1 decoder mem resource 0x%lx size 0x%x\n",
@@ -11219,11 +10955,6 @@
pdata->dec_status = NULL;
return -ENODEV;
}
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_init(pdata);
-#endif
-
vdec_set_prepare_level(pdata, start_decode_buf_level);
hevc_source_changed(VFORMAT_AV1, 4096, 2048, 60);
@@ -11246,10 +10977,6 @@
if (debug)
av1_print(hw, AOM_DEBUG_HW_MORE, "amvdec_av1_remove\n");
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_exit(vdec);
-#endif
-
vmav1_stop(hw);
if (vdec->parallel_dec == 1)
@@ -11275,8 +11002,6 @@
hw->pts_missed, hw->pts_hit, hw->frame_dur);
#endif
/* devm_kfree(&pdev->dev, (void *)hw); */
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hw->rdma_adr, hw->rdma_phy_adr);
vfree(hw->pbi);
release_dblk_struct(hw);
vfree((void *)hw);
@@ -11343,10 +11068,7 @@
#endif
/*
if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &aom_workbuff_spec[1];
- else
- p_buf_info = &aom_workbuff_spec[1];
+ p_buf_info = &aom_workbuff_spec[1];
} else
p_buf_info = &aom_workbuff_spec[0];
@@ -11380,13 +11102,10 @@
pr_err("failed to register amvdec_av1 driver\n");
return -ENODEV;
}
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+
+ if ((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) || is_cpu_tm2_revb()) {
amvdec_av1_profile.profile =
- "10bit, dwrite, compressed, no_head, v4l-uvm";
- } else if (((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) || is_cpu_tm2_revb())
- && (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5)) {
- amvdec_av1_profile.profile =
- "8k, 10bit, dwrite, compressed, no_head, frame_dv, v4l-uvm";
+ "8k, 10bit, dwrite, compressed, no_head, frame_dv";
} else {
amvdec_av1_profile.name = "av1_unsupport";
}
@@ -11406,7 +11125,6 @@
INIT_REG_NODE_CONFIGS("media.decoder", &av1_node,
"av1", av1_configs, CONFIG_FOR_RW);
#endif
- vcodec_feature_register(VFORMAT_AV1, 0);
return 0;
}
@@ -11645,9 +11363,6 @@
module_param(without_display_mode, uint, 0664);
MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-module_param(v4l_bitstream_id_enable, uint, 0664);
-MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n");
-
module_init(amvdec_av1_driver_init_module);
module_exit(amvdec_av1_driver_remove_module);
diff --git a/drivers/frame_provider/decoder/vc1/vvc1.c b/drivers/frame_provider/decoder/vc1/vvc1.c
index 1f0dfa9..aa215a9 100644
--- a/drivers/frame_provider/decoder/vc1/vvc1.c
+++ b/drivers/frame_provider/decoder/vc1/vvc1.c
@@ -30,6 +30,7 @@
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../utils/amvdec.h"
#include "../utils/vdec.h"
@@ -40,11 +41,10 @@
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include "../utils/firmware.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
#include <linux/delay.h>
#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../utils/vdec_feature.h"
+
#define DRIVER_NAME "amvdec_vc1"
#define MODULE_NAME "amvdec_vc1"
@@ -146,7 +146,6 @@
static bool is_reset;
static struct work_struct set_clk_work;
static struct work_struct error_wd_work;
-static struct canvas_config_s vc1_canvas_config[DECODE_BUFFER_NUM_MAX][3];
spinlock_t vc1_rp_lock;
@@ -517,9 +516,9 @@
}
if (next_pts_us64 != 0) {
next_pts_us64 +=
- div_u64((u64)((vf->duration) -
+ (u64)((vf->duration) -
((vf->duration) >> 4)) *
- 100, 9);
+ 100 / 9;
}
} else {
vf->duration =
@@ -551,17 +550,6 @@
decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
- if (is_support_vdec_canvas()) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0];
- vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1];
-#ifdef NV21
- vf->plane_num = 2;
-#else
- vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2];
- vf->plane_num = 3;
-#endif
- }
kfifo_put(&display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -594,8 +582,8 @@
((vf->duration) >> 4));
}
if (next_pts_us64 != 0) {
- next_pts_us64 += div_u64((u64)((vf->duration) -
- ((vf->duration) >> 4)) * 100, 9);
+ next_pts_us64 += (u64)((vf->duration) -
+ ((vf->duration) >> 4)) * 100 / 9;
}
} else {
vf->duration =
@@ -626,18 +614,6 @@
decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
-
- if (is_support_vdec_canvas()) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0];
- vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1];
-#ifdef NV21
- vf->plane_num = 2;
-#else
- vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2];
- vf->plane_num = 3;
-#endif
- }
kfifo_put(&display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -697,9 +673,9 @@
}
if (next_pts_us64 != 0) {
next_pts_us64 +=
- div_u64((u64)((vf->duration) -
+ (u64)((vf->duration) -
((vf->duration) >> 4)) *
- 100, 9);
+ 100 / 9;
}
} else {
vf->duration =
@@ -733,17 +709,7 @@
decoder_bmmu_box_get_mem_handle(
mm_blk_handle,
buffer_index);
- if (is_support_vdec_canvas()) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->canvas0_config[0] = vc1_canvas_config[buffer_index][0];
- vf->canvas0_config[1] = vc1_canvas_config[buffer_index][1];
-#ifdef NV21
- vf->plane_num = 2;
-#else
- vf->canvas0_config[2] = vc1_canvas_config[buffer_index][2];
- vf->plane_num = 3;
-#endif
- }
+
kfifo_put(&display_q, (const struct vframe_s *)vf);
ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -927,57 +893,30 @@
}
#ifdef NV21
- config_cav_lut_ex(2 * i + 0,
+ canvas_config(2 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- vc1_canvas_config[i][0].endian = 0;
- vc1_canvas_config[i][0].width = canvas_width;
- vc1_canvas_config[i][0].height = canvas_height;
- vc1_canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32;
- vc1_canvas_config[i][0].phy_addr = buf_start;
-
- config_cav_lut_ex(2 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(2 * i + 1,
buf_start +
decbuf_y_size, canvas_width,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- vc1_canvas_config[i][1].endian = 0;
- vc1_canvas_config[i][1].width = canvas_width;
- vc1_canvas_config[i][1].height = canvas_height >> 1;
- vc1_canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32;
- vc1_canvas_config[i][1].phy_addr = buf_start + decbuf_y_size;
+ CANVAS_BLKMODE_32X32);
#else
- config_cav_lut_ex(3 * i + 0,
+ canvas_config(3 * i + 0,
buf_start,
canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- vc1_canvas_config[i][0].endian = 0;
- vc1_canvas_config[i][0].width = canvas_width;
- vc1_canvas_config[i][0].height = canvas_height;
- vc1_canvas_config[i][0].block_mode = CANVAS_BLKMODE_32X32;
- vc1_canvas_config[i][0].phy_addr = buf_start;
- config_cav_lut_ex(3 * i + 1,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 1,
buf_start +
decbuf_y_size, canvas_width / 2,
canvas_height / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- vc1_canvas_config[i][1].endian = 0;
- vc1_canvas_config[i][1].width = canvas_width >> 1;
- vc1_canvas_config[i][1].height = canvas_height >> 1;
- vc1_canvas_config[i][1].block_mode = CANVAS_BLKMODE_32X32;
- vc1_canvas_config[i][1].phy_addr = buf_start + decbuf_y_size;
- config_cav_lut_ex(3 * i + 2,
+ CANVAS_BLKMODE_32X32);
+ canvas_config(3 * i + 2,
buf_start +
decbuf_y_size + decbuf_uv_size,
canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32, 0, VDEC_1);
- vc1_canvas_config[i][2].endian = 0;
- vc1_canvas_config[i][2].width = canvas_width >> 1;
- vc1_canvas_config[i][2].height = canvas_height >> 1;
- vc1_canvas_config[i][2].block_mode = CANVAS_BLKMODE_32X32;
- vc1_canvas_config[i][2].phy_addr = buf_start +
- decbuf_y_size + decbuf_uv_size;
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
#endif
}
@@ -1055,8 +994,6 @@
#ifdef NV21
SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
#endif
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
return r;
}
@@ -1163,8 +1100,11 @@
amvdec_start();
}
-static void vvc1_put_timer_func(struct timer_list *timer)
+
+static void vvc1_put_timer_func(unsigned long arg)
{
+ struct timer_list *timer = (struct timer_list *)arg;
+
if (READ_VREG(VC1_SOS_COUNT) > 10)
schedule_work(&error_wd_work);
@@ -1202,7 +1142,7 @@
return -ENOMEM;
pr_info("vvc1_init, format %d\n", vvc1_amstream_dec_info.format);
- timer_setup(&recycle_timer, vvc1_put_timer_func, 0);
+ init_timer(&recycle_timer);
stat |= STAT_TIMER_INIT;
@@ -1276,7 +1216,10 @@
stat |= STAT_VF_HOOK;
+ recycle_timer.data = (ulong)&recycle_timer;
+ recycle_timer.function = vvc1_put_timer_func;
recycle_timer.expires = jiffies + PUT_INTERVAL;
+
add_timer(&recycle_timer);
stat |= STAT_TIMER_ARM;
@@ -1384,16 +1327,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int vc1_suspend(struct device *dev)
+{
+ amvdec_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int vc1_resume(struct device *dev)
+{
+ amvdec_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops vc1_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(vc1_suspend, vc1_resume)
+};
+#endif
static struct platform_driver amvdec_vc1_driver = {
.probe = amvdec_vc1_probe,
.remove = amvdec_vc1_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &vc1_pm_ops,
+#endif
}
};
@@ -1418,7 +1377,6 @@
return -ENODEV;
}
vcodec_profile_register(&amvdec_vc1_profile);
- vcodec_feature_register(VFORMAT_VC1, 0);
return 0;
}
diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c
index e6a47fd..fa75afb 100644
--- a/drivers/frame_provider/decoder/vp9/vvp9.c
+++ b/drivers/frame_provider/decoder/vp9/vvp9.c
@@ -37,15 +37,14 @@
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
#include "../../../stream_input/amports/amports_priv.h"
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include "../utils/decoder_mmu_box.h"
#include "../utils/decoder_bmmu_box.h"
#define MEM_NAME "codec_vp9"
+/* #include <mach/am_regs.h> */
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../utils/vdec.h"
#include "../utils/amvdec.h"
@@ -60,17 +59,16 @@
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include "../utils/vdec_v4l2_buffer_ops.h"
#include <media/v4l2-mem2mem.h>
-#include "../utils/vdec_feature.h"
#define MIX_STREAM_SUPPORT
#include "vvp9.h"
-#define VP9_10B_MMU_DW
+
/*#define SUPPORT_FB_DECODING*/
/*#define FB_DECODING_TEST_SCHEDULE*/
-#define CO_MV_COMPRESS
+
#define HW_MASK_FRONT 0x1
#define HW_MASK_BACK 0x2
@@ -83,21 +81,11 @@
#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
#define HEVC_SAO_MMU_VH1_ADDR 0x363b
#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
+
#define HEVC_MV_INFO 0x310d
#define HEVC_QP_INFO 0x3137
#define HEVC_SKIP_INFO 0x3136
-#define HEVC_SAO_CTRL9 0x362d
-#define HEVC_CM_HEADER_START_ADDR2 0x364a
-#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
-#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
-#define HEVC_SAO_MMU_STATUS2 0x3650
-#define HEVC_DW_VH0_ADDDR 0x365e
-#define HEVC_DW_VH1_ADDDR 0x365f
-
#define VP9_10B_DEC_IDLE 0
#define VP9_10B_DEC_FRAME_HEADER 1
#define VP9_10B_DEC_SLICE_SEGMENT 2
@@ -160,7 +148,6 @@
#ifdef MULTI_INSTANCE_SUPPORT
#define MAX_DECODE_INSTANCE_NUM 9
#define MULTI_DRIVER_NAME "ammvdec_vp9"
-
static unsigned int max_decode_instance_num
= MAX_DECODE_INSTANCE_NUM;
static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
@@ -187,7 +174,6 @@
* 2, (1/4):(1/4) ratio;
* 3, (1/4):(1/4) ratio, with both compressed frame included
* 4, (1/2):(1/2) ratio;
- * 8, (1/8):(1/8) ratio;
* 0x10, double write only
* 0x100, if > 1080p,use mode 4,else use mode 1;
* 0x200, if > 1080p,use mode 2,else use mode 1;
@@ -225,7 +211,7 @@
#endif
static void vvp9_prot_init(struct VP9Decoder_s *pbi, u32 mask);
static int vvp9_local_init(struct VP9Decoder_s *pbi);
-static void vvp9_put_timer_func(struct timer_list *timer);
+static void vvp9_put_timer_func(unsigned long arg);
static void dump_data(struct VP9Decoder_s *pbi, int size);
static unsigned char get_data_check_sum
(struct VP9Decoder_s *pbi, int size);
@@ -237,15 +223,7 @@
int pic_height,
unsigned short bit_depth,
unsigned int *mmu_index_adr);
-#ifdef VP9_10B_MMU_DW
-int vp9_alloc_mmu_dw(
- struct VP9Decoder_s *pbi,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr);
-#endif
+
static const char vvp9_dec_id[] = "vvp9-dev";
@@ -278,20 +256,6 @@
#define MAX_FRAME_8K_NUM 0x4800
#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-// bit[31:20] -- fb_read_lcu_y
-// READ only// bit[19:8] -- fb_read_lcu_x
-// READ only// bit[7] -- fb_read_lcu_latch
-// bit[6:5] -- reserved
-// bit[4] -- fb_disable_wr_iqit_buf
-// bit[3] -- fb_read_avs2_enable
-// bit[2] -- fb_read_vp9_enable
-// bit[1] -- fb_avs2_enable
-// bit[0] -- fb_vp9_enable
-#define HEVC_ASSIST_HED_FB_CTL 0x300c
-// [31:16] height// [15:0] width
-#define HEVC_ASSIST_PIC_SIZE_FB_READ 0x300d
-#define HEVC_ASSIST_MMU_MAP_ADDR2 0x300e
-
#ifdef SUPPORT_FB_DECODING
/* register define */
@@ -305,7 +269,6 @@
#define MAX_STAGE_PAGE_NUM 0x1200
#define STAGE_MMU_MAP_SIZE (MAX_STAGE_PAGE_NUM * 4)
#endif
-
static inline int div_r32(int64_t m, int n)
{
/*
@@ -374,6 +337,11 @@
#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+
+typedef unsigned int u32;
+typedef unsigned short u16;
+
#define VP9_DEBUG_BUFMGR 0x01
#define VP9_DEBUG_BUFMGR_MORE 0x02
#define VP9_DEBUG_BUFMGR_DETAIL 0x04
@@ -433,8 +401,6 @@
static u32 without_display_mode;
-static u32 v4l_bitstream_id_enable = 1;
-
/*
*[3:0] 0: default use config from omx.
* 1: force enable fence.
@@ -475,12 +441,9 @@
//#define MMU_COMPRESS_8K_HEADER_SIZE (MMU_COMPRESS_HEADER_SIZE * 4)
#define MMU_COMPRESS_HEADER_SIZE 0x48000
-#define MMU_COMPRESS_HEADER_SIZE_DW 0x48000
-#define MMU_COMPRESS_8K_HEADER_SIZE (MMU_COMPRESS_HEADER_SIZE * 4)
-
+#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4)
#define MAX_SIZE_8K (8192 * 4608)
#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
@@ -584,9 +547,6 @@
int slice_idx;
/*buffer*/
unsigned long header_adr;
-#ifdef VP9_10B_MMU_DW
- unsigned long header_dw_adr;
-#endif
unsigned long mpred_mv_wr_start_addr;
int mv_size;
/*unsigned long mc_y_adr;
@@ -594,8 +554,6 @@
*/
unsigned int dw_y_adr;
unsigned int dw_u_v_adr;
- u32 luma_size;
- u32 chroma_size;
int mc_canvas_y;
int mc_canvas_u_v;
@@ -650,9 +608,10 @@
u32 hw_decode_time;
u32 frame_size2; // For frame base mode
+ bool vframe_bound;
/* vdec sync. */
- struct dma_fence *fence;
+ struct fence *fence;
/* hdr10 plus data */
u32 hdr10p_data_size;
@@ -748,8 +707,6 @@
*/
int row;
int col;
-
- int show_frame;
} RefCntBuffer;
struct RefBuffer_s {
@@ -903,6 +860,7 @@
struct BufferPool_s *buffer_pool;
int above_context_alloc_cols;
+
};
static void set_canvas(struct VP9Decoder_s *pbi,
@@ -1000,10 +958,6 @@
struct buff_s seg_map;
struct buff_s mmu_vbh;
struct buff_s cm_header;
-#ifdef VP9_10B_MMU_DW
- struct buff_s mmu_vbh_dw;
- struct buff_s cm_header_dw;
-#endif
struct buff_s mpred_above;
#ifdef MV_USE_FIXED_BUF
struct buff_s mpred_mv;
@@ -1063,11 +1017,6 @@
#endif
#endif
-struct vp9_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
struct VP9Decoder_s {
#ifdef MULTI_INSTANCE_SUPPORT
unsigned char index;
@@ -1135,10 +1084,7 @@
void *frame_mmu_map_addr;
dma_addr_t frame_mmu_map_phy_addr;
-#ifdef VP9_10B_MMU_DW
- void *frame_mmu_dw_map_addr;
- dma_addr_t frame_mmu_dw_map_phy_addr;
-#endif
+
unsigned int use_cma_flag;
struct BUF_s m_BUF[MAX_BUF_NUM];
@@ -1155,6 +1101,7 @@
int pic_num;
int lcu_size_log2;
unsigned int losless_comp_body_size;
+
u32 video_signal_type;
int pts_mode;
@@ -1232,10 +1179,6 @@
void *mmu_box;
void *bmmu_box;
int mmu_enable;
-#ifdef VP9_10B_MMU_DW
- void *mmu_box_dw;
- int dw_mmu_enable;
-#endif
struct vframe_master_display_colour_s vf_dp;
struct firmware_s *fw;
int max_pic_w;
@@ -1294,24 +1237,18 @@
u64 frame_mode_pts64_save[FRAME_BUFFERS];
int run_ready_min_buf_num;
int one_package_frame_cnt;
- int buffer_wrap[FRAME_BUFFERS];
- int last_width;
- int last_height;
u32 error_frame_width;
u32 error_frame_height;
- u32 endian;
- ulong fb_token;
- struct vp9_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- struct trace_decoder_name trace;
+ char vdec_name[32];
+ char pts_name[32];
+ char new_q_name[32];
+ char disp_q_name[32];
};
static int vp9_print(struct VP9Decoder_s *pbi,
int flag, const char *fmt, ...)
{
-#define HEVC_PRINT_BUF 512
+#define HEVC_PRINT_BUF 256
unsigned char buf[HEVC_PRINT_BUF];
int len = 0;
@@ -1335,9 +1272,6 @@
int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
MAX_SIZE_8K : MAX_SIZE_4K;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
if (w <= 0 || h <= 0)
return true;
@@ -1347,26 +1281,6 @@
return false;
}
-static int vvp9_mmu_compress_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(w, h))
- return (MMU_COMPRESS_HEADER_SIZE_8K);
- if (IS_4K_SIZE(w, h))
- return (MMU_COMPRESS_HEADER_SIZE_4K);
- return (MMU_COMPRESS_HEADER_SIZE_1080P);
-}
-
-/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/
-static int vvp9_frame_mmu_map_size(struct VP9Decoder_s *pbi)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h))
- return (MAX_FRAME_8K_NUM << 2);
-
- return (MAX_FRAME_4K_NUM << 2);
-}
-
static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi,
struct PIC_BUFFER_CONFIG_s *pic);
@@ -1379,9 +1293,8 @@
pbi->vp9_first_pts_ready = 0;
pbi->duration_from_pts_done = 0;
}
- pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__,
- cm->width, cm->height,
- width, height);
+ pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width,
+ cm->height, width, height);
cm->width = width;
cm->height = height;
}
@@ -1417,7 +1330,6 @@
struct VP9Decoder_s *pbi,
struct VP9_Common_s *cm, union param_u *params,
unsigned int *mmu_index_adr,
- unsigned int *mmu_dw_index_adr,
int print_header_info) {
int width, height;
struct BufferPool_s * const pool = cm->buffer_pool;
@@ -1461,19 +1373,7 @@
}
cm->cur_fb_idx_mmu = cm->new_fb_idx;
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable && (mmu_dw_index_adr != NULL)) {
- ret = vp9_alloc_mmu_dw(pbi, cm->new_fb_idx,
- params->p.width, params->p.height,
- params->p.bit_depth, mmu_dw_index_adr);
- if (ret != 0) {
- pr_err("can't alloc need mmu1 dw,idx %d ret =%d\n",
- cm->new_fb_idx,
- ret);
- return ret;
- }
- }
-#endif
+
resize_context_buffers(pbi, cm, width, height);
setup_display_size(cm, params, print_header_info);
#if 0
@@ -1516,7 +1416,6 @@
struct VP9_Common_s *cm,
union param_u *params,
unsigned int *mmu_index_adr,
- unsigned int *mmu_dw_index_adr,
int print_header_info) {
int width, height;
@@ -1602,18 +1501,7 @@
}
cm->cur_fb_idx_mmu = cm->new_fb_idx;
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable && (mmu_dw_index_adr != NULL)) {
- ret = vp9_alloc_mmu_dw(pbi, cm->new_fb_idx,
- params->p.width, params->p.height,
- params->p.bit_depth, mmu_dw_index_adr);
- if (ret != 0) {
- pr_err("can't alloc need mmu dw,idx %d\r\n",
- cm->new_fb_idx);
- return ret;
- }
- }
-#endif
+
/*Check to make sure at least one of frames that this frame references
*has valid dimensions.
*/
@@ -1756,19 +1644,46 @@
static u32 get_valid_double_write_mode(struct VP9Decoder_s *pbi)
{
- u32 dw = ((double_write_mode & 0x80000000) == 0) ?
+ return ((double_write_mode & 0x80000000) == 0) ?
pbi->double_write_mode :
(double_write_mode & 0x7fffffff);
- if (dw & 0x20) {
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
- && ((dw & 0xf) == 2 || (dw & 0xf) == 3)) {
- pr_info("MMU doueble write 1:4 not supported !!!\n");
- dw = 0;
- }
- }
- return dw;
}
+static int v4l_parser_get_double_write_mode(struct VP9Decoder_s *pbi)
+{
+ u32 valid_dw_mode = get_valid_double_write_mode(pbi);
+ u32 dw;
+ int w, h;
+
+ /* mask for supporting double write value bigger than 0x100 */
+ if (valid_dw_mode & 0xffffff00) {
+ w = pbi->frame_width;
+ h = pbi->frame_height;
+
+ dw = 0x1; /*1:1*/
+ switch (valid_dw_mode) {
+ case 0x100:
+ if (w > 1920 && h > 1088)
+ dw = 0x4; /*1:2*/
+ break;
+ case 0x200:
+ if (w > 1920 && h > 1088)
+ dw = 0x2; /*1:4*/
+ break;
+ case 0x300:
+ if (w > 1280 && h > 720)
+ dw = 0x4; /*1:2*/
+ break;
+ default:
+ break;
+ }
+ return dw;
+ }
+
+ return valid_dw_mode;
+}
+
+
static int get_double_write_mode(struct VP9Decoder_s *pbi)
{
u32 valid_dw_mode = get_valid_double_write_mode(pbi);
@@ -1777,14 +1692,6 @@
struct VP9_Common_s *cm = &pbi->common;
struct PIC_BUFFER_CONFIG_s *cur_pic_config;
- if (pbi->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(pbi->v4l2_ctx, &out);
- dw = out;
- return dw;
- }
-
/* mask for supporting double write value bigger than 0x100 */
if (valid_dw_mode & 0xffffff00) {
if (!cm->cur_frame)
@@ -1846,53 +1753,20 @@
}
#endif
+static int get_double_write_ratio(struct VP9Decoder_s *pbi,
+ int dw_mode)
+{
+ int ratio = 1;
+ if ((dw_mode == 2) ||
+ (dw_mode == 3))
+ ratio = 4;
+ else if (dw_mode == 4)
+ ratio = 2;
+ return ratio;
+}
+
//#define MAX_4K_NUM 0x1200
-/* return page number */
-static int vp9_mmu_page_num(struct VP9Decoder_s *pbi,
- int w, int h, int save_mode)
-{
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-
- picture_size = compute_losless_comp_body_size(w, h, save_mode);
- cur_mmu_4k_number = ((picture_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT);
-
- max_frame_num = (vvp9_frame_mmu_map_size(pbi) >> 2);
-
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, w, h);
- return -1;
- }
-
- return cur_mmu_4k_number;
-}
-
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct VP9Decoder_s *pbi,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct VP9Decoder_s *pbi, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- pbi->m_BUF[index].v4l_ref_buf_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
int vp9_alloc_mmu(
struct VP9Decoder_s *pbi,
int cur_buf_idx,
@@ -1901,90 +1775,42 @@
unsigned short bit_depth,
unsigned int *mmu_index_adr)
{
- int ret;
int bit_depth_10 = (bit_depth == VPX_BITS_10);
- int cur_mmu_4k_number;
-
+ int picture_size;
+ int cur_mmu_4k_number, max_frame_num;
+ if (!pbi->mmu_box) {
+ pr_err("error no mmu box!\n");
+ return -1;
+ }
if (get_double_write_mode(pbi) == 0x10)
return 0;
-
if (bit_depth >= VPX_BITS_12) {
pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
pr_err("fatal_error, un support bit depth 12!\n\n");
return -1;
}
+ picture_size = compute_losless_comp_body_size(pic_width, pic_height,
+ bit_depth_10);
+ cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
- cur_mmu_4k_number = vp9_mmu_page_num(pbi,
- pic_width,
- pic_height,
- bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ max_frame_num = MAX_FRAME_8K_NUM;
+ else
+ max_frame_num = MAX_FRAME_4K_NUM;
- if (pbi->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, cur_buf_idx);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- ret = decoder_mmu_box_alloc_idx(
- pbi->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
-
- return ret;
-}
-
-#ifdef VP9_10B_MMU_DW
-int vp9_alloc_mmu_dw(
- struct VP9Decoder_s *pbi,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
-{
- int ret;
- int bit_depth_10 = (bit_depth == VPX_BITS_10);
- int cur_mmu_4k_number;
-
- if (pbi->is_used_v4l)
- return -1;
-
- if (get_double_write_mode(pbi) == 0x10)
- return 0;
-
- if (bit_depth >= VPX_BITS_12) {
- pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- pr_err("fatal_error, un support bit depth 12!\n\n");
+ if (cur_mmu_4k_number > max_frame_num) {
+ pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
+ cur_mmu_4k_number, pic_width, pic_height);
return -1;
}
- cur_mmu_4k_number = vp9_mmu_page_num(pbi,
- pic_width,
- pic_height,
- bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
-
- ret = decoder_mmu_box_alloc_idx(
- pbi->mmu_box_dw,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
-
- return ret;
+ return decoder_mmu_box_alloc_idx(
+ pbi->mmu_box,
+ cur_buf_idx,
+ cur_mmu_4k_number,
+ mmu_index_adr);
}
-#endif
#ifndef MV_USE_FIXED_BUF
static void dealloc_mv_bufs(struct VP9Decoder_s *pbi)
@@ -2032,7 +1858,7 @@
ret = 0;
if (debug) {
pr_info(
- "MV Buffer %d: start_adr %px size %x\n",
+ "MV Buffer %d: start_adr %p size %x\n",
i,
(void *)pbi->m_mv_BUF[i].start_adr,
pbi->m_mv_BUF[i].size);
@@ -2156,7 +1982,7 @@
pic_config->mv_size = pbi->m_mv_BUF[ret].size;
if (debug & VP9_DEBUG_BUFMGR_MORE)
pr_info(
- "%s => %d (%lx) size 0x%x\n",
+ "%s => %d (%ld) size 0x%x\n",
__func__, ret,
pic_config->mpred_mv_wr_start_addr,
pic_config->mv_size);
@@ -2216,18 +2042,10 @@
struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
int i;
for (i = 0; i < pbi->used_buf_num; ++i) {
-#if 0
if ((frame_bufs[i].ref_count == 0) &&
(frame_bufs[i].buf.index != -1) &&
(frame_bufs[i].buf.mv_buf_index >= 0)
)
-#else
- if ((&frame_bufs[i] != cm->prev_frame) &&
- (frame_bufs[i].buf.index != -1) &&
- (frame_bufs[i].buf.mv_buf_index >= 0)
- )
-#endif
-
put_mv_buf(pbi, &frame_bufs[i].buf.mv_buf_index);
}
}
@@ -2508,8 +2326,7 @@
for (i = 0; i < pbi->used_buf_num; ++i) {
if ((frame_bufs[i].ref_count == 0) &&
(frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1) &&
- (cm->cur_frame != &frame_bufs[i])
+ (frame_bufs[i].buf.index != -1)
)
break;
}
@@ -2527,39 +2344,6 @@
return i;
}
-static void update_hide_frame_timestamp(struct VP9Decoder_s *pbi)
-{
- struct RefCntBuffer_s *const frame_bufs =
- pbi->common.buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((!frame_bufs[i].show_frame) &&
- (!frame_bufs[i].buf.vf_ref) &&
- (frame_bufs[i].buf.BUF_index != -1)) {
- frame_bufs[i].buf.timestamp = pbi->chunk->timestamp;
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "%s, update %d hide frame ts: %lld\n",
- __func__, i, frame_bufs[i].buf.timestamp);
- }
- }
-}
-
-static int get_free_fb_idx(struct VP9Decoder_s *pbi)
-{
- int i;
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0))
- break;
- }
-
- return i;
-}
-
static int v4l_get_free_fb(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
@@ -2567,9 +2351,8 @@
struct aml_vcodec_ctx * v4l = pbi->v4l2_ctx;
struct v4l_buff_pool *pool = &v4l->cap_pool;
struct PIC_BUFFER_CONFIG_s *pic = NULL;
- struct PIC_BUFFER_CONFIG_s *free_pic = NULL;
+ int i, idx = INVALID_IDX;
ulong flags;
- int idx, i;
lock_buffer_pool(cm->buffer_pool, flags);
@@ -2584,92 +2367,47 @@
(pic->vf_ref == 0) &&
(pic->index != -1) &&
pic->cma_alloc_addr) {
- free_pic = pic;
+ idx = i;
}
break;
case V4L_CAP_BUFF_IN_M2M:
- idx = get_free_fb_idx(pbi);
- pic = &frame_bufs[idx].buf;
+ pic = &frame_bufs[index].buf;
pic->y_crop_width = pbi->frame_width;
pic->y_crop_height = pbi->frame_height;
- pbi->buffer_wrap[idx] = index;
if (!v4l_alloc_and_config_pic(pbi, pic)) {
set_canvas(pbi, pic);
init_pic_list_hw(pbi);
- free_pic = pic;
+ idx = index;
}
break;
default:
+ pr_err("v4l buffer state err %d.\n", state);
break;
}
- if (free_pic) {
- frame_bufs[i].ref_count = 1;
+ if (idx != INVALID_IDX) {
+ frame_bufs[idx].ref_count = 1;
break;
}
}
- if (free_pic && pbi->chunk) {
- free_pic->timestamp = pbi->chunk->timestamp;
- update_hide_frame_timestamp(pbi);
- }
-
unlock_buffer_pool(cm->buffer_pool, flags);
- if (free_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- pbi->m_BUF[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- }
-
- if (debug & VP9_DEBUG_OUT_PTS) {
- if (free_pic) {
- pr_debug("%s, idx: %d, ts: %lld\n",
- __func__, free_pic->index, free_pic->timestamp);
- } else {
- pr_debug("%s, vp9 get free pic null\n", __func__);
- }
- }
-
- return free_pic ? free_pic->index : INVALID_IDX;
+ return idx;
}
static int get_free_buf_count(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- int i, free_buf_count = 0;
-
- if (pbi->is_used_v4l) {
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_buf_count++;
- }
- }
-
- if (ctx->cap_pool.dec < pbi->used_buf_num) {
- free_buf_count +=
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- }
-
- /* trigger to parse head data. */
- if (!pbi->v4l_params_parsed) {
- free_buf_count = pbi->run_ready_min_buf_num;
- }
- } else {
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1))
- free_buf_count++;
- }
- }
-
+ int i;
+ int free_buf_count = 0;
+ for (i = 0; i < pbi->used_buf_num; ++i)
+ if ((frame_bufs[i].ref_count == 0) &&
+ (frame_bufs[i].buf.vf_ref == 0) &&
+ (frame_bufs[i].buf.index != -1)
+ )
+ free_buf_count++;
return free_buf_count;
}
@@ -2790,11 +2528,9 @@
pbi->ready_for_new_data = 0;
- if ((pbi->has_keyframe == 0) &&
- (params->p.frame_type != KEY_FRAME) &&
- (!params->p.intra_only)){
+ if (pbi->has_keyframe == 0 &&
+ params->p.frame_type != KEY_FRAME){
on_no_keyframe_skiped++;
- pr_info("vp9_bufmgr_process no key frame return\n");
return -2;
}
pbi->has_keyframe = 1;
@@ -2895,7 +2631,6 @@
pbi->refresh_frame_flags = 0;
/*cm->lf.filter_level = 0;*/
cm->show_frame = 1;
- cm->cur_frame->show_frame = 1;
/*
*if (pbi->frame_parallel_decode) {
@@ -2911,7 +2646,7 @@
cm->show_frame = params->p.show_frame;
cm->bit_depth = params->p.bit_depth;
cm->error_resilient_mode = params->p.error_resilient_mode;
- cm->cur_frame->show_frame = cm->show_frame;
+
if (cm->frame_type == KEY_FRAME) {
pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
@@ -2920,19 +2655,10 @@
cm->frame_refs[i].idx = INVALID_IDX;
cm->frame_refs[i].buf = NULL;
}
-#ifdef VP9_10B_MMU_DW
+
ret = setup_frame_size(pbi,
- cm, params,
- pbi->frame_mmu_map_addr,
- pbi->frame_mmu_dw_map_addr,
- print_header_info);
-#else
- ret = setup_frame_size(pbi,
- cm, params,
- pbi->frame_mmu_map_addr,
- NULL,
- print_header_info);
-#endif
+ cm, params, pbi->frame_mmu_map_addr,
+ print_header_info);
if (ret)
return -1;
if (pbi->need_resync) {
@@ -2991,21 +2717,11 @@
* pr_info("*%d-bits refresh_frame read:0x%x\n",
* REF_FRAMES, pbi->refresh_frame_flags);
*/
-#ifdef VP9_10B_MMU_DW
ret = setup_frame_size(pbi,
cm,
params,
pbi->frame_mmu_map_addr,
- pbi->frame_mmu_dw_map_addr,
print_header_info);
-#else
- ret = setup_frame_size(pbi,
- cm,
- params,
- pbi->frame_mmu_map_addr,
- NULL,
- print_header_info);
-#endif
if (ret)
return -1;
if (pbi->need_resync) {
@@ -3051,23 +2767,13 @@
*/
}
-#ifdef VP9_10B_MMU_DW
+
ret = setup_frame_size_with_refs(
pbi,
cm,
params,
pbi->frame_mmu_map_addr,
- pbi->frame_mmu_dw_map_addr,
print_header_info);
-#else
- ret = setup_frame_size_with_refs(
- pbi,
- cm,
- params,
- pbi->frame_mmu_map_addr,
- NULL,
- print_header_info);
-#endif
if (ret)
return -1;
for (i = 0; i < REFS_PER_FRAME; ++i) {
@@ -3135,11 +2841,11 @@
struct vdec_s *vdec = hw_to_vdec(pbi);
/* create fence for each buffers. */
- ret = vdec_timeline_create_fence(vdec->sync);
+ ret = vdec_timeline_create_fence(&vdec->sync);
if (ret < 0)
return ret;
- pic->fence = vdec->sync->fence;
+ pic->fence = vdec->sync.fence;
pic->bit_depth = cm->bit_depth;
pic->slice_type = cm->frame_type;
pic->stream_offset = pbi->pre_stream_offset;
@@ -3301,9 +3007,6 @@
}
cm->last_width = cm->width;
cm->last_height = cm->height;
- pbi->last_width = cm->width;
- pbi->last_height = cm->height;
-
if (cm->show_frame)
cm->current_video_frame++;
@@ -3312,32 +3015,8 @@
sd.stream_offset = pbi->pre_stream_offset;
if (pbi->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
/* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
- mutex_lock(&pbi->fence_mutex);
- used_size = pbi->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (pbi->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(pbi->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = pbi->fence_vf_s.fence_vf[i];
- pbi->fence_vf_s.fence_vf[i] = NULL;
- pbi->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&pbi->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vvp9_vf_put(signed_fence[i], vdec);
- }
+ vdec_timeline_increase(&vdec->sync, 1);
} else {
prepare_display_buf(pbi, &sd);
}
@@ -3366,9 +3045,6 @@
#define HEVC_CM_HEADER_LENGTH 0x3629
#define HEVC_CM_HEADER_OFFSET 0x362b
-#define HEVC_CM_BODY_LENGTH2 0x3663
-#define HEVC_CM_HEADER_OFFSET2 0x3664
-#define HEVC_CM_HEADER_LENGTH2 0x3665
#define LOSLESS_COMPRESS_MODE
/*#define DECOMP_HEADR_SURGENT*/
@@ -3390,15 +3066,7 @@
static u32 pop_shorts;
static u32 dbg_cmd;
static u32 dbg_skip_decode_index;
-
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
+static u32 endian = 0xff0;
#ifdef ERROR_HANDLE_DEBUG
static u32 dbg_nal_skip_flag;
/* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
@@ -3408,10 +3076,18 @@
static u32 decode_pic_begin;
static uint slice_parse_begin;
static u32 step;
-static u32 vp9_max_pic_w;
-static u32 vp9_max_pic_h;
-static u32 dynamic_buf_num_margin;
+#ifdef MIX_STREAM_SUPPORT
+static u32 buf_alloc_width = 4096;
+static u32 buf_alloc_height = 2304;
+static u32 vp9_max_pic_w = 4096;
+static u32 vp9_max_pic_h = 2304;
+static u32 dynamic_buf_num_margin;
+#else
+static u32 buf_alloc_width;
+static u32 buf_alloc_height;
+static u32 dynamic_buf_num_margin = 7;
+#endif
static u32 buf_alloc_depth = 10;
static u32 buf_alloc_size;
/*
@@ -3557,10 +3233,7 @@
#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
+#define WORK_BUF_SPEC_NUM 3
static struct BuffInfo_s amvvp9_workbuff_spec[WORK_BUF_SPEC_NUM] = {
{
/* 8M bytes */
@@ -3570,292 +3243,6 @@
/* IPP work space calculation :
* 4096 * (Y+CbCr+Flags) = 12k, round to 16k
*/
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x80000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800,
- },
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x80000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800,
- },
- .mmu_vbh = {
- .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- * //4k2k , 0x100000 per buffer
- */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096*2,
- .max_height = 2304*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0x30000*2,
- },
- .sao_vb = {
- .buf_size = 0x30000*2,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x2800*2,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x8000*2,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0x80000*2,
- },
- .dblk_data = {
- .buf_size = 0x80000*2,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800*4,
- },
- .mmu_vbh = {
- .buf_size = 0x5000*2, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header = {
- //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- .buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000*2, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS * 4,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
.buf_size = 0x1e00,
},
.sao_abv = {
@@ -3934,16 +3321,6 @@
/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
},
#endif
-#ifdef VP9_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_1080P, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x2200, //0x21c0, /* 2 * size of hevc*/
},
@@ -4044,16 +3421,6 @@
/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
},
#endif
-#ifdef VP9_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_4K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x4800, /* 2 * size of hevc*/
},
@@ -4137,16 +3504,6 @@
.buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
},
#endif
-#ifdef VP9_10B_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_8K, //VBH_BUF_SIZE * VBH_BUF_COUNT, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header_dw = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_DW * 16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
-#endif
.mpred_above = {
.buf_size = 0x9000,
},
@@ -4168,7 +3525,7 @@
/*Losless compression body buffer size 4K per 64x32 (jt)*/
-static int compute_losless_comp_body_size(int width, int height,
+int compute_losless_comp_body_size(int width, int height,
uint8_t is_bit_depth_10)
{
int width_x64;
@@ -4189,7 +3546,7 @@
}
/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
-static int compute_losless_comp_header_size(int width, int height)
+static int compute_losless_comp_header_size(int width, int height)
{
int width_x128;
int height_x64;
@@ -4214,69 +3571,66 @@
{
void *mem_start_virt;
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
+ buf_spec->ipp.buf_start = buf_spec->start_adr;
buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+ buf_spec->ipp.buf_start + buf_spec->ipp.buf_size;
+
buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+ buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size;
buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+ buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size;
buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+ buf_spec->short_term_rps.buf_start +
+ buf_spec->short_term_rps.buf_size;
buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
+ buf_spec->vps.buf_start + buf_spec->vps.buf_size;
buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+ buf_spec->sps.buf_start + buf_spec->sps.buf_size;
buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+ buf_spec->pps.buf_start + buf_spec->pps.buf_size;
buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+ buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size;
buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+ buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size;
buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+ buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size;
buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+ buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size;
buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+ buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size;
buf_spec->seg_map.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+ buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size;
if (pbi == NULL || pbi->mmu_enable) {
buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
-#ifdef VP9_10B_MMU_DW
- if (pbi == NULL || pbi->dw_mmu_enable) {
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
- } else {
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
- }
-#else
+ buf_spec->seg_map.buf_start +
+ buf_spec->seg_map.buf_size;
buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-#endif
+ buf_spec->mmu_vbh.buf_start +
+ buf_spec->mmu_vbh.buf_size;
} else {
buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
+ buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size;
}
#ifdef MV_USE_FIXED_BUF
buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+ buf_spec->mpred_mv.buf_start +
+ buf_spec->mpred_mv.buf_size;
#else
buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+ buf_spec->mpred_above.buf_start +
+ buf_spec->mpred_above.buf_size;
+
#endif
buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+ buf_spec->rpm.buf_start +
+ buf_spec->rpm.buf_size;
buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+ buf_spec->lmem.buf_start +
+ buf_spec->lmem.buf_size;
if (!pbi)
return;
@@ -4347,16 +3701,6 @@
if (pbi->mmu_enable) {
pr_info("mmu_vbh.buf_start :%x\n",
buf_spec->mmu_vbh.buf_start);
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- pr_info("mmu_vbh_dw.buf_start :%x",
- buf_spec->mmu_vbh_dw.buf_start);
-#if 0
- pr_info("cm_header_dw.buf_start :%x",
- buf_spec->mmu_vbh_dw.buf_start);
-#endif
- }
-#endif
}
pr_info("mpred_above.buf_start :%x\n",
buf_spec->mpred_above.buf_start);
@@ -5554,25 +4898,71 @@
}
+static bool v4l_is_there_vframe_bound(struct VP9Decoder_s *pbi)
+{
+ int i;
+ struct VP9_Common_s *const cm = &pbi->common;
+ struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
+
+ for (i = 0; i < pbi->used_buf_num; ++i) {
+ if (frame_bufs[i].buf.vframe_bound)
+ return true;
+ }
+
+ return false;
+}
+
+static void v4l_mmu_buffer_release(struct VP9Decoder_s *pbi)
+{
+ struct VP9_Common_s *const cm = &pbi->common;
+ struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
+ int i;
+
+ /* release workspace */
+ if (pbi->bmmu_box)
+ decoder_bmmu_box_free_idx(pbi->bmmu_box,
+ WORK_SPACE_BUF_ID);
+ /*
+ * it's only when vframe get back to driver, right now we can be sure
+ * that vframe and fd are related. if the playback exits, the capture
+ * requires the upper app to release when the fd is closed, and others
+ * buffers drivers are released by driver.
+ */
+ for (i = 0; i < pbi->used_buf_num; ++i) {
+ if (!frame_bufs[i].buf.vframe_bound) {
+ if (pbi->bmmu_box)
+ decoder_bmmu_box_free_idx(pbi->bmmu_box,
+ HEADER_BUFFER_IDX(i));
+ if (pbi->mmu_box)
+ decoder_mmu_box_free_idx(pbi->mmu_box, i);
+
+ vp9_print(pbi, PRINT_FLAG_V4L_DETAIL,
+ "%s free buffer[%d], bmmu_box: %p, mmu_box: %p\n",
+ __func__, i, pbi->bmmu_box, pbi->mmu_box);
+ }
+ }
+}
+
static void uninit_mmu_buffers(struct VP9Decoder_s *pbi)
{
#ifndef MV_USE_FIXED_BUF
dealloc_mv_bufs(pbi);
#endif
- if (pbi->mmu_box) {
+ if (pbi->is_used_v4l &&
+ v4l_is_there_vframe_bound(pbi)) {
+ if (get_double_write_mode(pbi) != 0x10) {
+ v4l_mmu_buffer_release(pbi);
+ return;
+ }
+ }
+
+ if (pbi->mmu_box)
decoder_mmu_box_free(pbi->mmu_box);
- pbi->mmu_box = NULL;
- }
-#ifdef VP9_10B_MMU_DW
- if (pbi->mmu_box_dw) {
- decoder_mmu_box_free(pbi->mmu_box_dw);
- pbi->mmu_box_dw = NULL;
- }
-#endif
- if (pbi->bmmu_box) {
+ pbi->mmu_box = NULL;
+
+ if (pbi->bmmu_box)
decoder_bmmu_box_free(pbi->bmmu_box);
- pbi->bmmu_box = NULL;
- }
+ pbi->bmmu_box = NULL;
}
static int calc_luc_quantity(u32 w, u32 h)
@@ -5588,22 +4978,6 @@
return pic_width_lcu * pic_height_lcu;
}
-/* return in MB */
-static int vp9_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 48;
-
- if ((max_w * max_h > 1280*736) &&
- (max_w * max_h <= 1920*1088)) {
- buf_size = 12;
- } else if ((max_w * max_h > 0) &&
- (max_w * max_h <= 1280*736)) {
- buf_size = 4;
- }
-
- return buf_size;
-}
-
static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi,
struct PIC_BUFFER_CONFIG_s *pic)
{
@@ -5616,25 +4990,21 @@
pbi->work_space_buf->mpred_mv.buf_size;
int mv_size = cal_mv_buf_size(pbi, pbi->frame_width, pbi->frame_height);
#endif
- struct aml_vcodec_ctx * ctx = (struct aml_vcodec_ctx *)pbi->v4l2_ctx;
struct vdec_v4l2_buffer *fb = NULL;
if (i < 0)
return ret;
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, pbi->fb_token, &fb, AML_FB_REQ_DEC);
+ ret = vdec_v4l_get_buffer(pbi->v4l2_ctx, &fb);
if (ret < 0) {
vp9_print(pbi, 0, "[%d] VP9 get buffer fail.\n",
((struct aml_vcodec_ctx *) (pbi->v4l2_ctx))->id);
return ret;
}
- fb->status = FB_ST_DECODER;
-
if (pbi->mmu_enable) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(pbi, fb);
-
- pbi->m_BUF[i].header_addr = ibuf->header_addr;
+ pbi->m_BUF[i].header_addr = decoder_bmmu_box_get_phy_addr(
+ pbi->bmmu_box, HEADER_BUFFER_IDX(i));
if (debug & VP9_DEBUG_BUFMGR_MORE) {
pr_info("MMU header_adr %d: %ld\n",
i, pbi->m_BUF[i].header_addr);
@@ -5655,8 +5025,6 @@
fb->m.mem[0].bytes_used = fb->m.mem[0].size;
pic->dw_y_adr = pbi->m_BUF[i].start_adr;
pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size;
- pic->luma_size = fb->m.mem[0].offset;
- pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset;
} else if (fb->num_planes == 2) {
pbi->m_BUF[i].start_adr = fb->m.mem[0].addr;
pbi->m_BUF[i].size = fb->m.mem[0].size;
@@ -5666,8 +5034,6 @@
fb->m.mem[1].bytes_used = fb->m.mem[1].size;
pic->dw_y_adr = pbi->m_BUF[i].start_adr;
pic->dw_u_v_adr = pbi->m_BUF[i].chroma_addr;
- pic->luma_size = fb->m.mem[0].size;
- pic->chroma_size = fb->m.mem[1].size;
}
/* config frame buffer */
@@ -5744,15 +5110,14 @@
int mc_buffer_size_u_v = 0;
int mc_buffer_size_u_v_h = 0;
int dw_mode = get_double_write_mode_init(pbi);
- struct vdec_s *vdec = hw_to_vdec(pbi);
pbi->lcu_total = lcu_total;
- if (dw_mode && (dw_mode & 0x20) == 0) {
+ if (dw_mode) {
int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode & 0xf);
+ get_double_write_ratio(pbi, dw_mode);
int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode & 0xf);
+ get_double_write_ratio(pbi, dw_mode);
int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
@@ -5783,19 +5148,8 @@
pr_info("MMU header_adr %d: %ld\n",
pic_config->index, pic_config->header_adr);
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- pic_config->header_dw_adr = pic_config->header_adr +
- vvp9_mmu_compress_header_size(pbi->init_pic_w, pbi->init_pic_h);
-
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_dw_adr %d: %ld size 0x%x\n",
- pic_config->index, pic_config->header_dw_adr,
- vvp9_mmu_compress_header_size(pbi->init_pic_w, pbi->init_pic_h));
- }
- }
-#endif
}
+
i = pic_config->index;
#ifdef MV_USE_FIXED_BUF
if ((pbi->work_space_buf->mpred_mv.buf_start +
@@ -5817,13 +5171,6 @@
return ret;
}
- if (pbi->enable_fence) {
- //mm->fence_ref_release = vdec_fence_buffer_count_decrease;
- vdec_fence_buffer_count_increase((ulong)vdec->sync);
- INIT_LIST_HEAD(&vdec->sync->release_callback[VF_BUFFER_IDX(i)].node);
- decoder_bmmu_box_add_callback_func(pbi->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[VF_BUFFER_IDX(i)]);
- }
-
if (pic_config->cma_alloc_addr)
y_adr = pic_config->cma_alloc_addr;
else {
@@ -5855,7 +5202,7 @@
(pic_config->index << 1);
pic_config->mc_canvas_u_v =
(pic_config->index << 1) + 1;
- } else if (dw_mode && ((dw_mode & 0x20) == 0)) {
+ } else if (dw_mode) {
pic_config->dw_y_adr = y_adr;
pic_config->dw_u_v_adr = pic_config->dw_y_adr +
((mc_buffer_size_u_v_h << 16) << 1);
@@ -5890,6 +5237,24 @@
return ret;
}
+static int vvp9_mmu_compress_header_size(struct VP9Decoder_s *pbi)
+{
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h))
+ return (MMU_COMPRESS_8K_HEADER_SIZE);
+
+ return (MMU_COMPRESS_HEADER_SIZE);
+}
+
+/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/
+static int vvp9_frame_mmu_map_size(struct VP9Decoder_s *pbi)
+{
+ if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+ IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h))
+ return (MAX_FRAME_8K_NUM * 4);
+
+ return (MAX_FRAME_4K_NUM * 4);
+}
static void init_pic_list(struct VP9Decoder_s *pbi)
{
@@ -5899,13 +5264,8 @@
u32 header_size;
struct vdec_s *vdec = hw_to_vdec(pbi);
- if (!pbi->is_used_v4l && pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- header_size = vvp9_mmu_compress_header_size(
- pbi->max_pic_w, pbi->max_pic_h);
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable)
- header_size <<= 1;
-#endif
+ if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
+ header_size = vvp9_mmu_compress_header_size(pbi);
/*alloc VP9 compress header first*/
for (i = 0; i < pbi->used_buf_num; i++) {
unsigned long buf_addr;
@@ -5919,12 +5279,6 @@
pbi->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
return;
}
- if (pbi->enable_fence) {
- vdec_fence_buffer_count_increase((ulong)vdec->sync);
- INIT_LIST_HEAD(&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)].node);
- decoder_bmmu_box_add_callback_func(pbi->bmmu_box, HEADER_BUFFER_IDX(i), (void *)&vdec->sync->release_callback[HEADER_BUFFER_IDX(i)]);
- //mm->fence_ref_release = vdec_fence_buffer_count_decrease;
- }
}
}
for (i = 0; i < pbi->used_buf_num; i++) {
@@ -5949,8 +5303,7 @@
break;
}
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0) {
+ if (pic_config->double_write_mode) {
set_canvas(pbi, pic_config);
}
}
@@ -5978,12 +5331,14 @@
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
(0x1 << 1) | (0x1 << 2));
+
for (i = 0; i < pbi->used_buf_num; i++) {
pic_config = &cm->buffer_pool->frame_bufs[i].buf;
if (pic_config->index < 0)
break;
if (pbi->mmu_enable && ((pic_config->double_write_mode & 0x10) == 0)) {
+
WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
pic_config->header_adr >> 5);
} else {
@@ -6017,6 +5372,7 @@
WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
}
+
static void dump_pic_list(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
@@ -6025,7 +5381,7 @@
for (i = 0; i < FRAME_BUFFERS; i++) {
pic_config = &cm->buffer_pool->frame_bufs[i].buf;
vp9_print(pbi, 0,
- "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr: %x\n",
+ "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d dec_idx %d slice_type %d w/h %d/%d adr%ld\n",
i,
pic_config->index,
#ifndef MV_USE_FIXED_BUF
@@ -6096,14 +5452,6 @@
#else
WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
#endif
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- /*losless_comp_header_size_dw same as losless_comp_header_size*/
- WRITE_VREG(HEVC_CM_BODY_LENGTH2, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2, losless_comp_header_size);
- }
-#endif
return 0;
}
@@ -6248,45 +5596,26 @@
(mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
- if (get_double_write_mode(pbi) &&
- (get_double_write_mode(pbi) & 0x20) == 0) {
+ if (get_double_write_mode(pbi)) {
WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->dw_y_adr);
WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->dw_u_v_adr);
WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->dw_y_adr);
WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->dw_u_v_adr);
} else {
- if (!pbi->dw_mmu_enable) {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
- }
+ WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+ WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
}
if (pbi->mmu_enable)
WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->header_adr);
- if (pbi->is_used_v4l) {
- WRITE_VREG(HEVC_SAO_Y_LENGTH, pic_config->luma_size);
- WRITE_VREG(HEVC_SAO_C_LENGTH, pic_config->chroma_size);
- if (debug & PRINT_FLAG_V4L_DETAIL) {
- pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n",
- v4l2_ctx->id, pic_config->index,
- pic_config->dw_y_adr, pic_config->luma_size,
- pic_config->dw_u_v_adr, pic_config->chroma_size);
- }
- } else {
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic_config->header_dw_adr);
- }
-#endif
- data32 = (mc_buffer_size_u_v_h << 16) << 1;
- /*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
- data32, mc_buffer_size_u_v_h, pic_config->lcu_total);*/
+ data32 = (mc_buffer_size_u_v_h << 16) << 1;
+ /*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
+ * data32, mc_buffer_size_u_v_h, pic_config->lcu_total);
+ */
+ WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
- WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
-
- data32 = (mc_buffer_size_u_v_h << 16);
- WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
- }
+ data32 = (mc_buffer_size_u_v_h << 16);
+ WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
#ifdef VP9_10B_NV21
#ifdef DOS_PROJECT
@@ -6339,21 +5668,17 @@
#endif
#else
data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~(3 << 14));
- data32 |= (2 << 14); /* line align with 64*/
-
data32 &= (~0x3000);
- /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
- data32 |= (pbi->mem_map_mode << 12);
+ data32 |= (pbi->mem_map_mode <<
+ 12);
+/* [13:12] axi_aformat, 0-Linear,
+ * 1-32x32, 2-64x32
+ */
data32 &= (~0xff0);
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable == 0)
- data32 |= ((pbi->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
-#else
- data32 |= ((pbi->endian >> 8) & 0xfff);
-#endif
- data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+ /* data32 |= 0x670; // Big-Endian per 64-bit */
+ data32 |= endian; /* Big-Endian per 64-bit */
+ data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
if (get_double_write_mode(pbi) == 0)
data32 |= 0x2; /*disable double write*/
else if (get_double_write_mode(pbi) & 0x10)
@@ -6405,29 +5730,24 @@
data32 &= ~(0xff << 16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
} else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
data32 = READ_VREG(HEVC_SAO_CTRL5);
data32 &= (~(0xff << 16));
- if ((get_double_write_mode(pbi) & 0xf) == 8 ||
- (get_double_write_mode(pbi) & 0xf) == 9) {
- data32 |= (0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else if ((get_double_write_mode(pbi) & 0xf) == 2 ||
- (get_double_write_mode(pbi) & 0xf) == 3)
- data32 |= (0xff << 16);
- else if ((get_double_write_mode(pbi) & 0xf) == 4)
- data32 |= (0x33 << 16);
+ if (get_double_write_mode(pbi) == 2 ||
+ get_double_write_mode(pbi) == 3)
+ data32 |= (0xff<<16);
+ else if (get_double_write_mode(pbi) == 4)
+ data32 |= (0x33<<16);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
}
data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
data32 &= (~0x30);
/* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (pbi->mem_map_mode << 4);
- data32 &= (~0xf);
- data32 |= (pbi->endian & 0xf); /* valid only when double write only */
+ data32 |= (pbi->mem_map_mode <<
+ 4);
+ data32 &= (~0xF);
+ data32 |= 0xf; /* valid only when double write only */
+ /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
/* swap uv */
if (pbi->is_used_v4l) {
@@ -6437,8 +5757,7 @@
else
data32 &= ~(1 << 12); /* NV12 */
}
- data32 &= (~(3 << 8));
- data32 |= (2 << 8); /* line align with 64 for dw only */
+
/*
* [3:0] little_endian
* [5:4] address_format 00:linear 01:32x32 10:64x32
@@ -6455,7 +5774,7 @@
static void vp9_config_work_space_hw(struct VP9Decoder_s *pbi, u32 mask)
{
struct BuffInfo_s *buf_spec = pbi->work_space_buf;
- unsigned int data32, data_tmp;
+ unsigned int data32;
int losless_comp_header_size, losless_comp_body_size;
if (debug && pbi->init_flag == 0)
@@ -6493,32 +5812,29 @@
}
- if ((mask & HW_MASK_BACK) == 0)
- return;
-
+ if (mask & HW_MASK_BACK) {
#ifdef LOSLESS_COMPRESS_MODE
- losless_comp_header_size =
- compute_losless_comp_header_size(pbi->init_pic_w,
- pbi->init_pic_h);
- losless_comp_body_size =
- compute_losless_comp_body_size(pbi->init_pic_w,
- pbi->init_pic_h, buf_alloc_depth == 10);
+ losless_comp_header_size =
+ compute_losless_comp_header_size(pbi->init_pic_w,
+ pbi->init_pic_h);
+ losless_comp_body_size =
+ compute_losless_comp_body_size(pbi->init_pic_w,
+ pbi->init_pic_h, buf_alloc_depth == 10);
#endif
- WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,
- buf_spec->ipp.buf_start);
- //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
- //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- /* cfg_addr_adp*/
- WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start);
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("Write HEVC_DBLK_CFGE\n");
- }
- /* cfg_p_addr */
- WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
-
- /* cfg_d_addr */
- WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
+ WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,
+ buf_spec->ipp.buf_start);
+ //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+ //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
+ /* cfg_addr_adp*/
+ WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start);
+ if (debug & VP9_DEBUG_BUFMGR_MORE)
+ pr_info("Write HEVC_DBLK_CFGE\n");
+ }
+ /* cfg_p_addr */
+ WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
+ /* cfg_d_addr */
+ WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
/*
@@ -6558,7 +5874,6 @@
WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
-
if (get_double_write_mode(pbi) & 0x10)
WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
#else
@@ -6578,76 +5893,20 @@
data32 |= (1<<10);
WRITE_VREG(HEVC_SAO_CTRL5, data32);
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- data_tmp = READ_VREG(HEVC_SAO_CTRL9);
- data_tmp |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
- WRITE_VREG(HEVC_CM_BODY_LENGTH2, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2, losless_comp_header_size);
-
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start
- + DW_VBH_BUF_SIZE(buf_spec));
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- if (get_double_write_mode(pbi) & 0x20) {
- WRITE_VREG(HEVC_DW_VH0_ADDDR,
- buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec) * 2);
- WRITE_VREG(HEVC_DW_VH1_ADDDR,
- buf_spec->mmu_vbh_dw.buf_start + DW_VBH_BUF_SIZE(buf_spec) * 3);
- }
- }
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 |= (1<<15);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-#endif
-
- /* config mpred axi burst threshold */
- WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412);
-
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
-#endif
-
- WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start);
+ WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start);
WRITE_VREG(LMEM_DUMP_ADR, (u32)pbi->lmem_phy_addr);
-
- WRITE_VREG(VP9_PROB_SWAP_BUFFER, pbi->prob_buffer_phy_addr);
- WRITE_VREG(VP9_COUNT_SWAP_BUFFER, pbi->count_buffer_phy_addr);
- if (pbi->mmu_enable) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, pbi->frame_mmu_map_phy_addr);
- else
- WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr);
- }
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, pbi->frame_mmu_dw_map_phy_addr);
- //WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, pbi->frame_mmu_dw_map_phy_addr);
- } else {
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR2, pbi->frame_mmu_dw_map_phy_addr);
+ /**/
+ WRITE_VREG(VP9_PROB_SWAP_BUFFER, pbi->prob_buffer_phy_addr);
+ WRITE_VREG(VP9_COUNT_SWAP_BUFFER, pbi->count_buffer_phy_addr);
+ if (pbi->mmu_enable) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+ WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, pbi->frame_mmu_map_phy_addr);
+ else
+ WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr);
}
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
-#ifdef VP9_10B_HED_FB
- WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR2, FB_FRAME_MMU_MAP_ADDR);
- #ifdef VP9_10B_HED_SAME_FB
- WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR2, FB_FRAME_MMU_MAP_ADDR);
- #endif
-#endif
}
-#endif
}
@@ -7018,13 +6277,10 @@
if (mask & HW_MASK_BACK) {
/*Initial IQIT_SCALELUT memory
-- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(pbi->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
+
+ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
+ for (i = 0; i < 1024; i++)
+ WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
}
if (mask & HW_MASK_FRONT) {
@@ -7412,30 +6668,21 @@
pbi->lmem_phy_addr);
pbi->lmem_addr = NULL;
}
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- tee_vp9_prob_free((u32)pbi->prob_buffer_phy_addr);
- pbi->prob_buffer_phy_addr = 0;
- pbi->count_buffer_phy_addr = 0;
+ if (pbi->prob_buffer_addr) {
+ if (pbi->prob_buffer_phy_addr)
+ dma_free_coherent(amports_get_dma_device(),
+ PROB_BUF_SIZE, pbi->prob_buffer_addr,
+ pbi->prob_buffer_phy_addr);
+
pbi->prob_buffer_addr = NULL;
+ }
+ if (pbi->count_buffer_addr) {
+ if (pbi->count_buffer_phy_addr)
+ dma_free_coherent(amports_get_dma_device(),
+ COUNT_BUF_SIZE, pbi->count_buffer_addr,
+ pbi->count_buffer_phy_addr);
+
pbi->count_buffer_addr = NULL;
- } else {
- if (pbi->prob_buffer_addr) {
- if (pbi->prob_buffer_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- PROB_BUF_SIZE, pbi->prob_buffer_addr,
- pbi->prob_buffer_phy_addr);
-
- pbi->prob_buffer_addr = NULL;
- }
- if (pbi->count_buffer_addr) {
- if (pbi->count_buffer_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- COUNT_BUF_SIZE, pbi->count_buffer_addr,
- pbi->count_buffer_phy_addr);
-
- pbi->count_buffer_addr = NULL;
- }
}
if (pbi->mmu_enable) {
u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi);
@@ -7448,21 +6695,6 @@
pbi->frame_mmu_map_addr = NULL;
}
}
-
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- u32 dw_mmu_map_size = vvp9_frame_mmu_map_size(pbi);
- if (pbi->frame_mmu_dw_map_addr) {
- if (pbi->frame_mmu_dw_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- dw_mmu_map_size,
- pbi->frame_mmu_dw_map_addr,
- pbi->frame_mmu_dw_map_phy_addr);
- pbi->frame_mmu_dw_map_addr = NULL;
- }
- }
-#endif
-
#ifdef SUPPORT_FB_DECODING
if (pbi->stage_mmu_map_addr) {
if (pbi->stage_mmu_map_phy_addr)
@@ -7499,41 +6731,58 @@
memcpy(cur_buf_info, &amvvp9_workbuff_spec[force_bufspec & 0xf],
sizeof(struct BuffInfo_s));
pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[2], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[0],/* 1080p */
- sizeof(struct BuffInfo_s));
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[5], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[3],/* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
+ } else if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ memcpy(cur_buf_info, &amvvp9_workbuff_spec[2], /* 8k */
+ sizeof(struct BuffInfo_s));
+ } else
+ memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k */
+ sizeof(struct BuffInfo_s));
+ } else
+ memcpy(cur_buf_info, &amvvp9_workbuff_spec[0],/* 1080p */
+ sizeof(struct BuffInfo_s));
cur_buf_info->start_adr = pbi->buf_start;
if (!pbi->mmu_enable)
pbi->mc_buf_spec.buf_end = pbi->buf_start + pbi->buf_size;
+
+#else
+/*! MULTI_INSTANCE_SUPPORT*/
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ cur_buf_info = &amvvp9_workbuff_spec[2];/* 8k work space */
+ else
+ cur_buf_info = &amvvp9_workbuff_spec[1];/* 4k2k work space */
+ } else
+ cur_buf_info = &amvvp9_workbuff_spec[0];/* 1080p work space */
+
#endif
init_buff_spec(pbi, cur_buf_info);
vp9_bufmgr_init(pbi, cur_buf_info, NULL);
- /* vp9_max_pic_w/h for debug */
- pbi->init_pic_w = (vp9_max_pic_w) ? vp9_max_pic_w:
- ((pbi->max_pic_w) ? pbi->max_pic_w : pbi->work_space_buf->max_width);
- pbi->init_pic_h = (vp9_max_pic_h) ? vp9_max_pic_h:
- ((pbi->max_pic_h) ? pbi->max_pic_h : pbi->work_space_buf->max_height);
+ if (!vdec_is_support_4k()
+ && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
+ buf_alloc_width = 1920;
+ buf_alloc_height = 1088;
+ if (pbi->max_pic_w > 1920 && pbi->max_pic_h > 1088) {
+ pbi->max_pic_w = 1920;
+ pbi->max_pic_h = 1088;
+ }
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ buf_alloc_width = 8192;
+ buf_alloc_height = 4608;
+ }
+ pbi->init_pic_w = pbi->max_pic_w ? pbi->max_pic_w :
+ (buf_alloc_width ? buf_alloc_width :
+ (pbi->vvp9_amstream_dec_info.width ?
+ pbi->vvp9_amstream_dec_info.width :
+ pbi->work_space_buf->max_width));
+ pbi->init_pic_h = pbi->max_pic_h ? pbi->max_pic_h :
+ (buf_alloc_height ? buf_alloc_height :
+ (pbi->vvp9_amstream_dec_info.height ?
+ pbi->vvp9_amstream_dec_info.height :
+ pbi->work_space_buf->max_height));
/* video is not support unaligned with 64 in tl1
** vdec canvas mode will be linear when dump yuv is set
@@ -7552,11 +6801,9 @@
}
#ifndef MV_USE_FIXED_BUF
- if (!pbi->is_used_v4l) {
- if (init_mv_buf_list(pbi) < 0) {
- pr_err("%s: init_mv_buf_list fail\n", __func__);
- return -1;
- }
+ if (init_mv_buf_list(pbi) < 0) {
+ pr_err("%s: init_mv_buf_list fail\n", __func__);
+ return -1;
}
#endif
if (pbi->save_buffer_mode)
@@ -7595,38 +6842,24 @@
pr_err("%s: failed to alloc lmem buffer\n", __func__);
return -1;
}
- pbi->lmem_ptr = pbi->lmem_addr;
+ pbi->lmem_ptr = pbi->lmem_addr;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- u32 prob_addr, id;
- id = tee_vp9_prob_malloc(&prob_addr);
- if (prob_addr <= 0)
- pr_err("%s, tee[%d] malloc prob buf failed\n", __func__, id);
- else {
- pbi->prob_buffer_phy_addr = prob_addr;
- pbi->count_buffer_phy_addr = pbi->prob_buffer_phy_addr + PROB_BUF_SIZE;
- }
- pbi->prob_buffer_addr = NULL;
- pbi->count_buffer_addr = NULL;
- } else {
- pbi->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
- PROB_BUF_SIZE,
- &pbi->prob_buffer_phy_addr, GFP_KERNEL);
- if (pbi->prob_buffer_addr == NULL) {
- pr_err("%s: failed to alloc prob_buffer\n", __func__);
- return -1;
- }
- memset(pbi->prob_buffer_addr, 0, PROB_BUF_SIZE);
- pbi->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
- COUNT_BUF_SIZE,
- &pbi->count_buffer_phy_addr, GFP_KERNEL);
- if (pbi->count_buffer_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(pbi->count_buffer_addr, 0, COUNT_BUF_SIZE);
+ pbi->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
+ PROB_BUF_SIZE,
+ &pbi->prob_buffer_phy_addr, GFP_KERNEL);
+ if (pbi->prob_buffer_addr == NULL) {
+ pr_err("%s: failed to alloc prob_buffer\n", __func__);
+ return -1;
}
+ memset(pbi->prob_buffer_addr, 0, PROB_BUF_SIZE);
+ pbi->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
+ COUNT_BUF_SIZE,
+ &pbi->count_buffer_phy_addr, GFP_KERNEL);
+ if (pbi->count_buffer_addr == NULL) {
+ pr_err("%s: failed to alloc count_buffer\n", __func__);
+ return -1;
+ }
+ memset(pbi->count_buffer_addr, 0, COUNT_BUF_SIZE);
if (pbi->mmu_enable) {
u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi);
@@ -7640,20 +6873,6 @@
}
memset(pbi->frame_mmu_map_addr, 0, COUNT_BUF_SIZE);
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable) {
- u32 dw_mmu_map_size = vvp9_frame_mmu_map_size(pbi);
- pbi->frame_mmu_dw_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- dw_mmu_map_size,
- &pbi->frame_mmu_dw_map_phy_addr, GFP_KERNEL);
- if (pbi->frame_mmu_dw_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer mmu dw\n", __func__);
- return -1;
- }
- memset(pbi->frame_mmu_dw_map_addr, 0, COUNT_BUF_SIZE);
- }
-#endif
#ifdef SUPPORT_FB_DECODING
if (pbi->m_ins_flag && stage_buf_num > 0) {
pbi->stage_mmu_map_addr =
@@ -7706,14 +6925,16 @@
/*CANVAS_BLKMODE_64X32*/
if (pic_config->double_write_mode) {
canvas_w = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(pbi,
+ pic_config->double_write_mode);
canvas_h = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(pbi,
+ pic_config->double_write_mode);
- /* sao ctrl1 reg alignline with 64, align with 64 */
- canvas_w = ALIGN(canvas_w, 64);
+ if (pbi->mem_map_mode == 0)
+ canvas_w = ALIGN(canvas_w, 32);
+ else
+ canvas_w = ALIGN(canvas_w, 64);
canvas_h = ALIGN(canvas_h, 32);
if (vdec->parallel_dec == 1) {
@@ -7728,12 +6949,12 @@
pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1;
}
- config_cav_lut_ex(pic_config->y_canvas_index,
+ canvas_config_ex(pic_config->y_canvas_index,
pic_config->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic_config->uv_canvas_index,
+ CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7);
+ canvas_config_ex(pic_config->uv_canvas_index,
pic_config->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC);
+ CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7);
#ifdef MULTI_INSTANCE_SUPPORT
pic_config->canvas_config[0].phy_addr =
@@ -7783,42 +7004,37 @@
memset(&hdr, 0, sizeof(hdr));
hdr.signal_type = vf->signal_type;
hdr.color_parms = pbi->vf_dp;
-
- hdr.color_parms.luminance[0] = hdr.color_parms.luminance[0] / 10000;
-
vdec_v4l_set_hdr_infos(ctx, &hdr);
}
if ((pbi->chunk != NULL) && (pbi->chunk->hdr10p_data_buf != NULL)
&& (pbi->chunk->hdr10p_data_size != 0)) {
- if (pbi->chunk->hdr10p_data_size <= 128) {
- char *new_buf;
- int i = 0;
- new_buf = kzalloc(pbi->chunk->hdr10p_data_size, GFP_ATOMIC);
+ char *new_buf;
+ int i = 0;
+ new_buf = vzalloc(pbi->chunk->hdr10p_data_size);
- if (new_buf) {
- memcpy(new_buf, pbi->chunk->hdr10p_data_buf, pbi->chunk->hdr10p_data_size);
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
+ if (new_buf) {
+ memcpy(new_buf, pbi->chunk->hdr10p_data_buf, pbi->chunk->hdr10p_data_size);
+ if (debug & VP9_DEBUG_BUFMGR_MORE) {
+ vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
+ "hdr10p data: (size %d)\n",
+ pbi->chunk->hdr10p_data_size);
+ for (i = 0; i < pbi->chunk->hdr10p_data_size; i++) {
vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "hdr10p data: (size %d)\n",
- pbi->chunk->hdr10p_data_size);
- for (i = 0; i < pbi->chunk->hdr10p_data_size; i++) {
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "%02x ", pbi->chunk->hdr10p_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
- }
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
+ "%02x ", pbi->chunk->hdr10p_data_buf[i]);
+ if (((i + 1) & 0xf) == 0)
+ vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
}
-
- vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
- } else {
- vp9_print(pbi, 0, "%s:hdr10p data vzalloc size(%d) fail\n",
- __func__, pbi->chunk->hdr10p_data_size);
- vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
+ vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
}
+
+ vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
+ vf->hdr10p_data_buf = new_buf;
+ } else {
+ vp9_print(pbi, 0, "%s:hdr10p data vzalloc size(%d) fail\n",
+ __func__, pbi->chunk->hdr10p_data_size);
+ vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
+ vf->hdr10p_data_buf = new_buf;
}
vfree(pbi->chunk->hdr10p_data_buf);
@@ -7883,18 +7099,17 @@
if (kfifo_get(&pbi->display_q, &vf)) {
struct vframe_s *next_vf = NULL;
uint8_t index = vf->index & 0xff;
- ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q));
+ ATRACE_COUNTER(pbi->disp_q_name, kfifo_len(&pbi->display_q));
if (index < pbi->used_buf_num ||
(vf->type & VIDTYPE_V4L_EOS)) {
vf->index_disp = pbi->vf_get_count;
pbi->vf_get_count++;
if (debug & VP9_DEBUG_BUFMGR)
- pr_info("%s idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n",
- __func__, index, vf->type,
+ pr_info("%s type 0x%x w/h %d/%d, pts %d, %lld\n",
+ __func__, vf->type,
vf->width, vf->height,
vf->pts,
- vf->pts_us64,
- vf->timestamp);
+ vf->pts_us64);
if (kfifo_peek(&pbi->display_q, &next_vf) && next_vf) {
vf->next_vf_pts_valid = true;
@@ -7905,7 +7120,6 @@
return vf;
}
}
-
return NULL;
}
@@ -7920,24 +7134,6 @@
if (!vf)
return;
- if (pbi->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&pbi->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (pbi->fence_vf_s.fence_vf[i] == NULL) {
- pbi->fence_vf_s.fence_vf[i] = vf;
- pbi->fence_vf_s.used_size++;
- mutex_unlock(&pbi->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&pbi->fence_mutex);
- }
-
index = vf->index & 0xff;
if (pbi->enable_fence && vf->fence) {
@@ -7946,23 +7142,14 @@
}
if (vf->hdr10p_data_buf) {
- kfree(vf->hdr10p_data_buf);
+ vfree(vf->hdr10p_data_buf);
vf->hdr10p_data_buf = NULL;
vf->hdr10p_data_size = 0;
}
kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q));
+ ATRACE_COUNTER(pbi->new_q_name, kfifo_len(&pbi->newframe_q));
pbi->vf_put_count++;
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("%s idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n",
- __func__, index, vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64,
- vf->timestamp);
-
if (index < pbi->used_buf_num) {
struct VP9_Common_s *cm = &pbi->common;
struct BufferPool_s *pool = cm->buffer_pool;
@@ -7972,6 +7159,9 @@
if (pool->frame_bufs[index].buf.vf_ref > 0)
pool->frame_bufs[index].buf.vf_ref--;
+ if (pbi->is_used_v4l)
+ pool->frame_bufs[index].buf.vframe_bound = true;
+
if (pbi->wait_buf)
WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
0x1);
@@ -8100,29 +7290,11 @@
static void update_vf_memhandle(struct VP9Decoder_s *pbi,
struct vframe_s *vf, struct PIC_BUFFER_CONFIG_s *pic)
{
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
- vf->mem_dw_handle = NULL;
-
- /* keeper not needed for v4l solution */
- if (pbi->is_used_v4l)
- return;
-
- if (vf->type & VIDTYPE_SCATTER) {
-
-#ifdef VP9_10B_MMU_DW
- if (pic->double_write_mode & 0x20) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- pbi->mmu_box_dw, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- pbi->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
- vf->mem_dw_handle = NULL;
- } else
-#endif
- {
+ if (pic->index < 0) {
+ vf->mem_handle = NULL;
+ vf->mem_head_handle = NULL;
+ vf->mem_dw_handle = NULL;
+ } else if (vf->type & VIDTYPE_SCATTER) {
vf->mem_handle =
decoder_mmu_box_get_mem_handle(
pbi->mmu_box, pic->index);
@@ -8137,7 +7309,6 @@
VF_BUFFER_IDX(pic->BUF_index));
else
vf->mem_dw_handle = NULL;
- }
} else {
vf->mem_handle =
decoder_bmmu_box_get_mem_handle(
@@ -8151,12 +7322,11 @@
}
}
-static inline void pbi_update_gvs(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config)
+static inline void pbi_update_gvs(struct VP9Decoder_s *pbi)
{
- if (pbi->gvs->frame_height != pic_config->y_crop_height) {
- pbi->gvs->frame_width = pic_config->y_crop_width;
- pbi->gvs->frame_height = pic_config->y_crop_height;
+ if (pbi->gvs->frame_height != frame_height) {
+ pbi->gvs->frame_width = frame_width;
+ pbi->gvs->frame_height = frame_height;
}
if (pbi->gvs->frame_dur != pbi->frame_dur) {
pbi->gvs->frame_dur = pbi->frame_dur;
@@ -8177,7 +7347,6 @@
int stream_offset = pic_config->stream_offset;
unsigned short slice_type = pic_config->slice_type;
struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
ulong nv_order = VIDTYPE_VIU_NV21;
u32 pts_valid = 0, pts_us64_valid = 0;
u32 pts_save;
@@ -8192,7 +7361,6 @@
pr_info("fatal error, no available buffer slot.");
return -1;
}
-
/* swap uv */
if (pbi->is_used_v4l) {
if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
@@ -8200,8 +7368,7 @@
nv_order = VIDTYPE_VIU_NV12;
}
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0)
+ if (pic_config->double_write_mode)
set_canvas(pbi, pic_config);
display_frame_count[pbi->index]++;
@@ -8209,20 +7376,20 @@
if (!force_pts_unstable) {
if ((pic_config->pts == 0) || ((pic_config->pts <= pbi->last_pts) &&
(pic_config->pts64 <= pbi->last_pts_us64))) {
- for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- if ((pbi->last_pts == pbi->frame_mode_pts_save[i]) ||
- (pbi->last_pts_us64 == pbi->frame_mode_pts64_save[i])) {
- pic_config->pts = pbi->frame_mode_pts_save[i - 1];
- pic_config->pts64 = pbi->frame_mode_pts64_save[i - 1];
- break;
- }
+ for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
+ if ((pbi->last_pts == pbi->frame_mode_pts_save[i]) ||
+ (pbi->last_pts_us64 == pbi->frame_mode_pts64_save[i])) {
+ pic_config->pts = pbi->frame_mode_pts_save[i - 1];
+ pic_config->pts64 = pbi->frame_mode_pts64_save[i - 1];
+ break;
+ }
}
if ((i == 0) || (pic_config->pts <= pbi->last_pts)) {
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "no found pts %d, set 0. %d, %d\n",
- i, pic_config->pts, pbi->last_pts);
- pic_config->pts = 0;
- pic_config->pts64 = 0;
+ vp9_print(pbi, VP9_DEBUG_OUT_PTS,
+ "no found pts %d, set 0. %d, %d\n",
+ i, pic_config->pts, pbi->last_pts);
+ pic_config->pts = 0;
+ pic_config->pts64 = 0;
}
}
}
@@ -8230,12 +7397,11 @@
if (pbi->is_used_v4l) {
vf->v4l_mem_handle
= pbi->m_BUF[pic_config->BUF_index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
if (pbi->mmu_enable) {
vf->mm_box.bmmu_box = pbi->bmmu_box;
- vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(pbi->buffer_wrap[pic_config->BUF_index]);
+ vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(pic_config->BUF_index);
vf->mm_box.mmu_box = pbi->mmu_box;
- vf->mm_box.mmu_idx = pbi->buffer_wrap[pic_config->index];
+ vf->mm_box.mmu_idx = pic_config->index;
}
}
@@ -8249,12 +7415,7 @@
if (vdec_frame_based(pvdec)) {
vf->pts = pic_config->pts;
vf->pts_us64 = pic_config->pts64;
-
- if (pbi->is_used_v4l && v4l_bitstream_id_enable)
- vf->timestamp = pic_config->timestamp;
- else
- vf->timestamp = pic_config->pts64;
-
+ vf->timestamp = pic_config->timestamp;
if (vf->pts != 0 || vf->pts_us64 != 0) {
pts_valid = 1;
pts_us64_valid = 1;
@@ -8292,7 +7453,7 @@
pts_save = vf->pts;
pts_us64_save = vf->pts_us64;
- if (pbi->is_used_v4l || pbi->pts_unstable) {
+ if (pbi->pts_unstable) {
frame_duration_adapt(pbi, vf, pts_valid);
if (pbi->duration_from_pts_done) {
pbi->pts_mode = PTS_NONE_REF_USE_DURATION;
@@ -8364,28 +7525,10 @@
/* double write only */
vf->compBodyAddr = 0;
vf->compHeadAddr = 0;
-#ifdef VP9_10B_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
-#endif
} else {
if (pbi->mmu_enable) {
vf->compBodyAddr = 0;
vf->compHeadAddr = pic_config->header_adr;
-#ifdef VP9_10B_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
- if (pic_config->double_write_mode & 0x20) {
- u32 mode = pic_config->double_write_mode & 0xf;
- if (mode == 5 || mode == 3)
- vf->dwHeadAddr = pic_config->header_dw_adr;
- else if ((mode == 1 || mode == 2 || mode == 4)
- && (debug & VP9_DEBUG_OUT_PTS) == 0) {
- vf->compHeadAddr = pic_config->header_dw_adr;
- pr_debug("Use dw mmu for display\n");
- }
- }
-#endif
} else {
/*vf->compBodyAddr = pic_config->mc_y_adr;
*vf->compHeadAddr = pic_config->mc_y_adr +
@@ -8394,13 +7537,11 @@
}
vf->canvas0Addr = vf->canvas1Addr = 0;
}
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0) {
+ if (pic_config->double_write_mode) {
vf->type = VIDTYPE_PROGRESSIVE |
VIDTYPE_VIU_FIELD;
vf->type |= nv_order;
- if ((pic_config->double_write_mode == 3 ||
- pic_config->double_write_mode == 5) &&
+ if ((pic_config->double_write_mode == 3) &&
(!IS_8K_SIZE(pic_config->y_crop_width,
pic_config->y_crop_height))) {
vf->type |= VIDTYPE_COMPRESS;
@@ -8452,29 +7593,24 @@
if (pic_config->bit_depth == VPX_BITS_8)
vf->bitdepth |= BITDEPTH_SAVING_MODE;
+ /* if((vf->width!=pic_config->width)|
+ * (vf->height!=pic_config->height))
+ */
+ /* pr_info("aaa: %d/%d, %d/%d\n",
+ vf->width,vf->height, pic_config->width,
+ pic_config->height); */
vf->width = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(pbi,
+ pic_config->double_write_mode);
vf->height = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
+ get_double_write_ratio(pbi,
+ pic_config->double_write_mode);
if (force_w_h != 0) {
vf->width = (force_w_h >> 16) & 0xffff;
vf->height = force_w_h & 0xffff;
}
- if ((pic_config->double_write_mode & 0x20) &&
- ((pic_config->double_write_mode & 0xf) == 2 ||
- (pic_config->double_write_mode & 0xf) == 4)) {
- vf->compWidth = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- vf->compHeight = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- } else {
- vf->compWidth = pic_config->y_crop_width;
- vf->compHeight = pic_config->y_crop_height;
- }
+ vf->compWidth = pic_config->y_crop_width;
+ vf->compHeight = pic_config->y_crop_height;
set_frame_info(pbi, vf);
if (force_fps & 0x100) {
u32 rate = force_fps & 0xff;
@@ -8491,10 +7627,9 @@
}
if ((debug & VP9_DEBUG_OUT_PTS) != 0) {
pr_info
- ("VP9 dec out pts: pts_mode=%d,dur=%d,pts(%d,%lld,%lld)(%d,%lld)\n",
+ ("VP9 dec out pts: pts_mode=%d,dur=%d,pts(%d,%lld)(%d,%lld)\n",
pbi->pts_mode, pbi->frame_dur, vf->pts,
- vf->pts_us64, vf->timestamp, pts_save,
- pts_us64_save);
+ vf->pts_us64, pts_save, pts_us64_save);
}
if (!(pic_config->y_crop_width == 196
&& pic_config->y_crop_height == 196
@@ -8506,11 +7641,11 @@
decoder_do_frame_check(pvdec, vf);
vdec_vframe_ready(pvdec, vf);
kfifo_put(&pbi->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(pbi->trace.pts_name, vf->pts);
- ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q));
- ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q));
+ ATRACE_COUNTER(pbi->pts_name, vf->pts);
+ ATRACE_COUNTER(pbi->new_q_name, kfifo_len(&pbi->newframe_q));
+ ATRACE_COUNTER(pbi->disp_q_name, kfifo_len(&pbi->display_q));
pbi->vf_pre_count++;
- pbi_update_gvs(pbi, pic_config);
+ pbi_update_gvs(pbi);
/*count info*/
vdec_count_info(pbi->gvs, 0, stream_offset);
if (stream_offset) {
@@ -8525,21 +7660,13 @@
memcpy(&tmp4x, pbi->gvs, sizeof(struct vdec_info));
tmp4x.bit_depth_luma = pbi->vp9_param.p.bit_depth;
tmp4x.bit_depth_chroma = pbi->vp9_param.p.bit_depth;
- tmp4x.double_write_mode = pic_config->double_write_mode;
+ tmp4x.double_write_mode = get_double_write_mode(pbi);
vdec_fill_vdec_frame(pvdec, &pbi->vframe_qos, &tmp4x,
vf, pic_config->hw_decode_time);
pvdec->vdec_fps_detec(pvdec->id);
if (without_display_mode == 0) {
- if (pbi->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vvp9_vf_put(vvp9_vf_get(pbi), pbi);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(pbi->provider_name,
+ vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
} else
vvp9_vf_put(vvp9_vf_get(pbi), pbi);
} else {
@@ -8573,8 +7700,7 @@
}
if (index == INVALID_IDX) {
- ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token);
- if (ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC) < 0) {
+ if (vdec_v4l_get_buffer(hw->v4l2_ctx, &fb) < 0) {
pr_err("[%d] EOS get free buff fail.\n", ctx->id);
return -1;
}
@@ -8586,16 +7712,11 @@
vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
vf->v4l_mem_handle = (index == INVALID_IDX) ? (ulong)fb :
hw->m_BUF[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
vdec_vframe_ready(vdec, vf);
kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- if (hw->is_used_v4l)
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+ vf_notify_receiver(vdec->vf_provider_name,
+ VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
pr_info("[%d] VP9 EOS notify.\n", (hw->is_used_v4l)?ctx->id:vdec->id);
}
@@ -8693,43 +7814,6 @@
}
-static int recycle_mmu_buf_tail(struct VP9Decoder_s *pbi,
- bool check_dma)
-{
- struct VP9_Common_s *const cm = &pbi->common;
-
- if (pbi->used_4k_num == -1) {
- pbi->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
- }
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "pic index %d page_start %d\n",
- cm->cur_fb_idx_mmu, pbi->used_4k_num);
-
- if (check_dma)
- hevc_mmu_dma_check(hw_to_vdec(pbi));
-
- if (pbi->is_used_v4l) {
- int index = cm->cur_fb_idx_mmu;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- pbi->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- pbi->mmu_box,
- cm->cur_fb_idx_mmu,
- pbi->used_4k_num);
- }
-
- cm->cur_fb_idx_mmu = INVALID_IDX;
- pbi->used_4k_num = -1;
-
- return 0;
-}
static void vp9_recycle_mmu_buf_tail(struct VP9Decoder_s *pbi)
{
@@ -8737,9 +7821,16 @@
if (pbi->double_write_mode & 0x10)
return;
if (cm->cur_fb_idx_mmu != INVALID_IDX) {
- recycle_mmu_buf_tail(pbi,
- ((pbi->used_4k_num == -1) &&
- pbi->m_ins_flag) ? 1 : 0);
+ if (pbi->used_4k_num == -1) {
+ pbi->used_4k_num =
+ (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
+ if (pbi->m_ins_flag)
+ hevc_mmu_dma_check(hw_to_vdec(pbi));
+ }
+ decoder_mmu_box_free_idx_tail(pbi->mmu_box,
+ cm->cur_fb_idx_mmu, pbi->used_4k_num);
+ cm->cur_fb_idx_mmu = INVALID_IDX;
+ pbi->used_4k_num = -1;
}
}
@@ -8747,10 +7838,6 @@
static void vp9_recycle_mmu_buf(struct VP9Decoder_s *pbi)
{
struct VP9_Common_s *const cm = &pbi->common;
-
- if (pbi->is_used_v4l)
- return;
-
if (pbi->double_write_mode & 0x10)
return;
if (cm->cur_fb_idx_mmu != INVALID_IDX) {
@@ -8803,6 +7890,7 @@
if (pbi->is_used_v4l && ctx->param_sets_from_ucode)
pbi->res_ch_flag = 0;
+
bit_depth_luma = pbi->vp9_param.p.bit_depth;
bit_depth_chroma = pbi->vp9_param.p.bit_depth;
@@ -8833,22 +7921,6 @@
pr_err("can't alloc need mmu1,idx %d ret =%d\n",
cm->new_fb_idx,
ret);
-
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- ret = vp9_alloc_mmu_dw(pbi,
- cm->new_fb_idx,
- params->p.width,
- params->p.height,
- params->p.bit_depth,
- pbi->frame_mmu_dw_map_addr);
- if (ret < 0)
- pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
- cm->new_fb_idx,
- ret);
- }
-#endif
-
} else {
ret = 0;
}
@@ -8860,11 +7932,8 @@
ret);
WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL);
cm->show_frame = 0;
- if (pbi->mmu_enable) {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+ if (pbi->mmu_enable)
vp9_recycle_mmu_buf(pbi);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
#ifdef MULTI_INSTANCE_SUPPORT
if (pbi->m_ins_flag) {
pbi->dec_result = DEC_RESULT_DONE;
@@ -8891,14 +7960,11 @@
if (pbi->chunk) {
cur_pic_config->pts = pbi->chunk->pts;
cur_pic_config->pts64 = pbi->chunk->pts64;
-
- if (pbi->is_used_v4l && !v4l_bitstream_id_enable)
- cur_pic_config->pts64 = pbi->chunk->timestamp;
+ cur_pic_config->timestamp = pbi->chunk->timestamp;
}
#endif
}
/*pr_info("Decode Frame Data %d\n", pbi->frame_count);*/
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
config_pic_size(pbi, pbi->vp9_param.p.bit_depth);
if ((pbi->common.frame_type != KEY_FRAME)
@@ -8914,7 +7980,6 @@
#endif
clear_mpred_hw(pbi);
}
-
#ifdef MCRCC_ENABLE
if (mcrcc_cache_alg_flag)
config_mcrcc_axi_hw_new(pbi);
@@ -8980,28 +8045,11 @@
if ((frame_bufs[i].ref_count == 0) &&
(frame_bufs[i].buf.vf_ref == 0) &&
(frame_bufs[i].buf.index != -1)) {
- if (pbi->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, i);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- } else {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- decoder_mmu_box_free_idx(pbi->mmu_box, i);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
-
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable)
- decoder_mmu_box_free_idx(pbi->mmu_box_dw, i);
-#endif
-
- }
+ decoder_mmu_box_free_idx(pbi->mmu_box, i);
}
pbi->last_put_idx = -1;
}
}
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
return ret;
}
@@ -9103,7 +8151,7 @@
frame->min_mv = a[0];
vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "mv data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
data = READ_VREG(HEVC_QP_INFO);
@@ -9130,7 +8178,7 @@
frame->min_qp = a[0];
vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "qp data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
data = READ_VREG(HEVC_SKIP_INFO);
@@ -9157,7 +8205,7 @@
frame->min_skip = a[0];
vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
+ "skip data %lx a[0]= %x a[1]= %x a[2]= %x\n",
data, a[0], a[1], a[2]);
} else {
uint32_t blk88_y_count;
@@ -9476,29 +8524,14 @@
}
}
-static void vvp9_get_comp_buf_info(struct VP9Decoder_s *pbi,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = pbi->param.p.bit_depth;
-
- info->max_size = vp9_max_mmu_buf_size(
- pbi->max_pic_w,
- pbi->max_pic_h);
- info->header_size = vvp9_mmu_compress_header_size(
- pbi->frame_width,
- pbi->frame_height);
- info->frame_buffer_size = vp9_mmu_page_num(
- pbi, pbi->frame_width,
- pbi->frame_height,
- bit_depth == 0);
-}
-
static int vvp9_get_ps_info(struct VP9Decoder_s *pbi, struct aml_vdec_ps_infos *ps)
{
- ps->visible_width = pbi->frame_width;
- ps->visible_height = pbi->frame_height;
- ps->coded_width = ALIGN(pbi->frame_width, 64);
- ps->coded_height = ALIGN(pbi->frame_height, 64);
+ int dw_mode = v4l_parser_get_double_write_mode(pbi);
+
+ ps->visible_width = pbi->frame_width / get_double_write_ratio(pbi, dw_mode);
+ ps->visible_height = pbi->frame_height / get_double_write_ratio(pbi, dw_mode);
+ ps->coded_width = ALIGN(pbi->frame_width, 32) / get_double_write_ratio(pbi, dw_mode);
+ ps->coded_height = ALIGN(pbi->frame_height, 32) / get_double_write_ratio(pbi, dw_mode);
ps->dpb_size = pbi->used_buf_num;
return 0;
@@ -9509,34 +8542,22 @@
{
struct aml_vcodec_ctx *ctx =
(struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
+ struct VP9_Common_s *const cm = &pbi->common;
int ret = 0;
if (ctx->param_sets_from_ucode &&
pbi->res_ch_flag == 0) {
struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
+ if ((cm->width != 0 &&
+ cm->height != 0) &&
+ (pbi->frame_width != cm->width ||
+ pbi->frame_height != cm->height)) {
- if ((pbi->last_width != 0 &&
- pbi->last_height != 0) &&
- (pbi->frame_width != pbi->last_width ||
- pbi->frame_height != pbi->last_height)) {
-
- vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, pbi->last_width,
- pbi->last_height, pbi->frame_width, pbi->frame_height);
-
- if (get_valid_double_write_mode(pbi) != 16) {
- vvp9_get_comp_buf_info(pbi, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
+ vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width,
+ cm->height, pbi->frame_width, pbi->frame_height);
vvp9_get_ps_info(pbi, &ps);
vdec_v4l_set_ps_infos(ctx, &ps);
vdec_v4l_res_ch_event(ctx);
-
- pbi->init_pic_w = pbi->frame_width;
- pbi->init_pic_h = pbi->frame_height;
- init_mv_buf_list(pbi);
-
pbi->v4l_params_parsed = false;
pbi->res_ch_flag = 1;
ctx->v4l_resolution_change = 1;
@@ -9561,14 +8582,6 @@
/*if (pbi->wait_buf)
* pr_info("set wait_buf to 0\r\n");
*/
-
- if (dec_status == VP9_HEAD_PARSER_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
if (pbi->eos)
return IRQ_HANDLED;
pbi->wait_buf = 0;
@@ -9604,15 +8617,8 @@
if (!vdec_frame_based(hw_to_vdec(pbi)))
dec_again_process(pbi);
else {
- if (pbi->common.show_existing_frame) {
- pbi->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&pbi->work);
- }
- else {
- pbi->dec_result = DEC_RESULT_GET_DATA;
- vdec_schedule_work(&pbi->work);
- }
+ pbi->dec_result = DEC_RESULT_GET_DATA;
+ vdec_schedule_work(&pbi->work);
}
}
pbi->process_busy = 0;
@@ -9643,7 +8649,6 @@
amhevc_stop();
if (mcrcc_cache_alg_flag)
dump_hit_rate(pbi);
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
vdec_schedule_work(&pbi->work);
}
} else {
@@ -9728,11 +8733,9 @@
&& pbi->used_stage_buf_num == 0
#endif
) {
- if (pbi->mmu_enable) {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+ if (pbi->mmu_enable)
vp9_recycle_mmu_buf_tail(pbi);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
+
if (pbi->frame_count > 0)
vp9_bufmgr_postproc(pbi);
@@ -9791,14 +8794,12 @@
} else
#endif
{
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
int ii;
for (ii = 0; ii < 4; ii++)
pbi->vp9_param.l.data[i + ii] =
pbi->rpm_ptr[i + 3 - ii];
}
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
}
}
@@ -9821,22 +8822,11 @@
if (!v4l_res_change(pbi)) {
if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) {
struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
pr_debug("set ucode parse\n");
- if (get_valid_double_write_mode(pbi) != 16) {
- vvp9_get_comp_buf_info(pbi, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
vvp9_get_ps_info(pbi, &ps);
/*notice the v4l2 codec.*/
vdec_v4l_set_ps_infos(ctx, &ps);
-
- pbi->init_pic_w = pbi->frame_width;
- pbi->init_pic_h = pbi->frame_height;
- init_mv_buf_list(pbi);
-
pbi->v4l_params_parsed = true;
pbi->postproc_done = 0;
pbi->process_busy = 0;
@@ -9859,7 +8849,7 @@
if (pbi->m_ins_flag)
start_process_time(pbi);
#endif
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+
return IRQ_HANDLED;
}
@@ -9869,25 +8859,22 @@
unsigned int dec_status;
struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data;
unsigned int adapt_prob_status;
+ struct VP9_Common_s *const cm = &pbi->common;
uint debug_tag;
WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
- if (dec_status == VP9_HEAD_PARSER_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
-
adapt_prob_status = READ_VREG(VP9_ADAPT_PROB_REG);
if (!pbi)
return IRQ_HANDLED;
if (pbi->init_flag == 0)
return IRQ_HANDLED;
- if (pbi->process_busy)/*on process.*/
+ if (pbi->process_busy) {/*on process.*/
+ vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
+ "%s: process_busy isr return\n", __func__);
return IRQ_HANDLED;
+ }
pbi->dec_status = dec_status;
pbi->process_busy = 1;
if (debug & VP9_DEBUG_BUFMGR)
@@ -9977,44 +8964,34 @@
}
#endif
if ((adapt_prob_status & 0xff) == 0xfd) {
- struct VP9_Common_s *const cm = &pbi->common;
- int pre_fc = 0;
-
+ /*VP9_REQ_ADAPT_PROB*/
+ int pre_fc = (cm->frame_type == KEY_FRAME) ? 1 : 0;
+ uint8_t *prev_prob_b =
+ ((uint8_t *)pbi->prob_buffer_addr) +
+ ((adapt_prob_status >> 8) * 0x1000);
+ uint8_t *cur_prob_b =
+ ((uint8_t *)pbi->prob_buffer_addr) + 0x4000;
+ uint8_t *count_b = (uint8_t *)pbi->count_buffer_addr;
+#ifdef MULTI_INSTANCE_SUPPORT
if (pbi->m_ins_flag)
- reset_process_time(pbi);
+ reset_process_time(pbi);
+#endif
+ adapt_coef_probs(pbi->pic_count,
+ (cm->last_frame_type == KEY_FRAME),
+ pre_fc, (adapt_prob_status >> 8),
+ (unsigned int *)prev_prob_b,
+ (unsigned int *)cur_prob_b, (unsigned int *)count_b);
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only)) ? 0 : 1;
- tee_vp9_prob_process(pre_fc, cm->last_frame_type,
- adapt_prob_status, (unsigned int)pbi->prob_buffer_phy_addr);
- } else {
- uint8_t *prev_prob_b, *cur_prob_b, *count_b;
-
- /*VP9_REQ_ADAPT_PROB*/
- pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only));
- prev_prob_b = ((uint8_t *)pbi->prob_buffer_addr) +
- ((adapt_prob_status >> 8) * 0x1000);
- cur_prob_b = ((uint8_t *)pbi->prob_buffer_addr) + 0x4000;
- count_b = (uint8_t *)pbi->count_buffer_addr;
-
- adapt_coef_probs(pbi->pic_count,
- (cm->last_frame_type == KEY_FRAME),
- pre_fc, (adapt_prob_status >> 8),
- (unsigned int *)prev_prob_b,
- (unsigned int *)cur_prob_b, (unsigned int *)count_b);
-
- memcpy(prev_prob_b, cur_prob_b, PROB_SIZE);
- }
-
+ memcpy(prev_prob_b, cur_prob_b, PROB_SIZE);
WRITE_VREG(VP9_ADAPT_PROB_REG, 0);
pbi->pic_count += 1;
#ifdef MULTI_INSTANCE_SUPPORT
if (pbi->m_ins_flag)
start_process_time(pbi);
#endif
+
+ /*return IRQ_HANDLED;*/
}
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_END);
return IRQ_WAKE_THREAD;
}
@@ -10030,14 +9007,15 @@
frame_height * fps;
}
-static void vvp9_put_timer_func(struct timer_list *timer)
+static void vvp9_put_timer_func(unsigned long arg)
{
- struct VP9Decoder_s *pbi = container_of(timer,
- struct VP9Decoder_s, timer);
- enum receviver_start_e state = RECEIVER_INACTIVE;
+ struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)arg;
+ struct timer_list *timer = &pbi->timer;
uint8_t empty_flag;
unsigned int buf_level;
+ enum receviver_start_e state = RECEIVER_INACTIVE;
+
if (pbi->m_ins_flag) {
if (hw_to_vdec(pbi)->next_status
== VDEC_STATUS_DISCONNECTED &&
@@ -10539,10 +9517,12 @@
fw->len = fw_size;
INIT_WORK(&pbi->set_clk_work, vp9_set_clk);
- timer_setup(&pbi->timer, vvp9_put_timer_func, 0);
+ init_timer(&pbi->timer);
#ifdef MULTI_INSTANCE_SUPPORT
if (pbi->m_ins_flag) {
+ pbi->timer.data = (ulong) pbi;
+ pbi->timer.function = vvp9_put_timer_func;
pbi->timer.expires = jiffies + PUT_INTERVAL;
/*add_timer(&pbi->timer);
@@ -10599,18 +9579,16 @@
pbi->provider_name = PROVIDER_NAME;
#ifdef MULTI_INSTANCE_SUPPORT
- if (!pbi->is_used_v4l) {
- vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME,
- &vvp9_vf_provider, pbi);
- vf_reg_provider(&vvp9_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
- if (pbi->frame_dur != 0) {
- if (!is_reset)
- vf_notify_receiver(pbi->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)pbi->frame_dur));
- }
+ vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME,
+ &vvp9_vf_provider, pbi);
+ vf_reg_provider(&vvp9_vf_prov);
+ vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
+ if (pbi->frame_dur != 0) {
+ if (!is_reset)
+ vf_notify_receiver(pbi->provider_name,
+ VFRAME_EVENT_PROVIDER_FR_HINT,
+ (void *)
+ ((unsigned long)pbi->frame_dur));
}
#else
vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME, &vvp9_vf_provider,
@@ -10623,11 +9601,14 @@
#endif
pbi->stat |= STAT_VF_HOOK;
+ pbi->timer.data = (ulong)pbi;
+ pbi->timer.function = vvp9_put_timer_func;
pbi->timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&pbi->timer);
pbi->stat |= STAT_VDEC_RUN;
+ add_timer(&pbi->timer);
+
pbi->stat |= STAT_TIMER_ARM;
amhevc_start();
@@ -10656,7 +9637,7 @@
pbi->stat &= ~STAT_TIMER_ARM;
}
- if (!pbi->is_used_v4l && (pbi->stat & STAT_VF_HOOK)) {
+ if (pbi->stat & STAT_VF_HOOK) {
if (!is_reset)
vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -10705,7 +9686,7 @@
pbi->stat &= ~STAT_TIMER_ARM;
}
- if (!pbi->is_used_v4l && (pbi->stat & STAT_VF_HOOK)) {
+ if (pbi->stat & STAT_VF_HOOK) {
if (!is_reset)
vf_notify_receiver(pbi->provider_name,
VFRAME_EVENT_PROVIDER_FR_END_HINT,
@@ -10736,16 +9717,22 @@
pbi->fw = NULL;
return 0;
}
-
static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi)
{
int tvp_flag = vdec_secure(hw_to_vdec(pbi)) ?
CODEC_MM_FLAGS_TVP : 0;
- int buf_size = vp9_max_mmu_buf_size(pbi->max_pic_w, pbi->max_pic_h);
+ int buf_size = 48;
+ if ((pbi->max_pic_w * pbi->max_pic_h > 1280*736) &&
+ (pbi->max_pic_w * pbi->max_pic_h <= 1920*1088)) {
+ buf_size = 12;
+ } else if ((pbi->max_pic_w * pbi->max_pic_h > 0) &&
+ (pbi->max_pic_w * pbi->max_pic_h <= 1280*736)) {
+ buf_size = 4;
+ }
pbi->need_cache_size = buf_size * SZ_1M;
pbi->sc_start_time = get_jiffies_64();
- if (pbi->mmu_enable && !pbi->is_used_v4l) {
+ if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
pbi->index, FRAME_BUFFERS,
pbi->need_cache_size,
@@ -10756,18 +9743,6 @@
return -1;
}
}
-#ifdef VP9_10B_MMU_DW
- if (pbi->dw_mmu_enable && !pbi->is_used_v4l) {
- pbi->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME,
- pbi->index, FRAME_BUFFERS,
- pbi->need_cache_size,
- tvp_flag
- );
- if (!pbi->mmu_box_dw) {
- pr_err("vp9 alloc mmu dw box failed!!\n");
- }
- }
-#endif
pbi->bmmu_box = decoder_bmmu_box_alloc_box(
DRIVER_NAME,
pbi->index,
@@ -10794,16 +9769,10 @@
#ifndef MULTI_INSTANCE_SUPPORT
int i;
#endif
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) {
- pr_info("vp9 unsupported on cpu 0x%x\n", get_cpu_major_id());
- return -EINVAL;
- }
pr_debug("%s\n", __func__);
mutex_lock(&vvp9_mutex);
- pbi = vzalloc(sizeof(struct VP9Decoder_s));
+ pbi = vmalloc(sizeof(struct VP9Decoder_s));
if (pbi == NULL) {
pr_info("\namvdec_vp9 device data allocation failed\n");
mutex_unlock(&vvp9_mutex);
@@ -10817,29 +9786,12 @@
pbi->init_flag = 0;
pbi->first_sc_checked= 0;
-
- if (!vdec_is_support_4k()) {
- pbi->max_pic_w = 1920;
- pbi->max_pic_h = 1088;
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
- pbi->max_pic_w = 4096;
- pbi->max_pic_h = 2304;
- } else {
- pbi->max_pic_w = 8192;
- pbi->max_pic_h = 4608;
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+ vp9_max_pic_w = 8192;
+ vp9_max_pic_h = 4608;
}
- if (pdata->sys_info) {
- pbi->vvp9_amstream_dec_info = *pdata->sys_info;
- if ((pbi->vvp9_amstream_dec_info.width != 0) &&
- (pbi->vvp9_amstream_dec_info.height != 0)) {
- pbi->max_pic_w = pbi->vvp9_amstream_dec_info.width;
- pbi->max_pic_h = pbi->vvp9_amstream_dec_info.height;
- }
- } else {
- pbi->vvp9_amstream_dec_info.width = 0;
- pbi->vvp9_amstream_dec_info.height = 0;
- pbi->vvp9_amstream_dec_info.rate = 30;
- }
+ pbi->max_pic_w = vp9_max_pic_w;
+ pbi->max_pic_h = vp9_max_pic_h;
#ifdef MULTI_INSTANCE_SUPPORT
pbi->eos = 0;
@@ -10861,14 +9813,6 @@
#endif
pbi->double_write_mode = double_write_mode;
pbi->mmu_enable = 1;
-#ifdef VP9_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- pbi->dw_mmu_enable =
- (get_double_write_mode(pbi) & 0x20) ? 1 : 0;
- } else {
- pbi->dw_mmu_enable = 0;
- }
-#endif
if (amvdec_vp9_mmu_init(pbi) < 0) {
vfree(pbi);
mutex_unlock(&vvp9_mutex);
@@ -10901,18 +9845,20 @@
pr_info("===VP9 decoder mem resource 0x%lx size 0x%x\n",
pdata->mem_start, pbi->buf_size);
}
+
+ if (pdata->sys_info)
+ pbi->vvp9_amstream_dec_info = *pdata->sys_info;
+ else {
+ pbi->vvp9_amstream_dec_info.width = 0;
+ pbi->vvp9_amstream_dec_info.height = 0;
+ pbi->vvp9_amstream_dec_info.rate = 30;
+ }
pbi->no_head = no_head;
#ifdef MULTI_INSTANCE_SUPPORT
pbi->cma_dev = pdata->cma_dev;
#else
cma_dev = pdata->cma_dev;
#endif
- /* config endian */
- pbi->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (is_support_vdec_canvas())
- pbi->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- pbi->endian = endian;
#ifdef MULTI_INSTANCE_SUPPORT
pdata->private = pbi;
@@ -10943,6 +9889,7 @@
struct vdec_sync *sync)
{
ulong expires;
+ int i;
/* notify signal to wake up all fences. */
vdec_timeline_increase(sync, VF_POOL_SIZE);
@@ -10955,6 +9902,15 @@
}
}
+ for (i = 0; i < VF_POOL_SIZE; i++) {
+ struct vframe_s *vf = &pbi->vfpool[i];
+
+ if (vf->fence) {
+ vdec_fence_put(vf->fence);
+ vf->fence = NULL;
+ }
+ }
+
/* decreases refcnt of timeline. */
vdec_timeline_put(sync);
}
@@ -10990,7 +9946,7 @@
mem_map_mode = 0;
if (pbi->enable_fence)
- vdec_fence_release(pbi, vdec->sync);
+ vdec_fence_release(pbi, &vdec->sync);
vfree(pbi);
mutex_unlock(&vvp9_mutex);
@@ -10999,16 +9955,32 @@
}
/****************************************/
+#ifdef CONFIG_PM
+static int vp9_suspend(struct device *dev)
+{
+ amhevc_suspend(to_platform_device(dev), dev->power.power_state);
+ return 0;
+}
+
+static int vp9_resume(struct device *dev)
+{
+ amhevc_resume(to_platform_device(dev));
+ return 0;
+}
+
+static const struct dev_pm_ops vp9_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(vp9_suspend, vp9_resume)
+};
+#endif
static struct platform_driver amvdec_vp9_driver = {
.probe = amvdec_vp9_probe,
.remove = amvdec_vp9_remove,
-#ifdef CONFIG_PM
- .suspend = amhevc_suspend,
- .resume = amhevc_resume,
-#endif
.driver = {
.name = DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &vp9_pm_ops,
+#endif
}
};
@@ -11026,9 +9998,6 @@
int sum = 0;
u8 *data = NULL;
- if (vdec_secure(hw_to_vdec(pbi)))
- return 0;
-
if (!pbi->chunk->block->is_mapped)
data = codec_mm_vmap(pbi->chunk->block->start +
pbi->chunk->offset, size);
@@ -11039,20 +10008,6 @@
for (jj = 0; jj < size; jj++)
sum += data[jj];
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, sum,
- (size < 1) ? 0 : data[0],
- (size < 2) ? 0 : data[1],
- (size < 3) ? 0 : data[2],
- (size < 4) ? 0 : data[3],
- (size < 5) ? 0 : data[4],
- (size < 6) ? 0 : data[5],
- (size < 4) ? 0 : data[size - 4],
- (size < 3) ? 0 : data[size - 3],
- (size < 2) ? 0 : data[size - 2],
- (size < 1) ? 0 : data[size - 1]);
-
if (!pbi->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
@@ -11109,9 +10064,6 @@
/* finished decoding one frame or error,
* notify vdec core to switch context
*/
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_START);
- if (pbi->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_AGAIN);
vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
"%s dec_result %d %x %x %x\n",
__func__,
@@ -11129,6 +10081,7 @@
if (pbi->dec_result == DEC_RESULT_NEED_MORE_BUFFER) {
reset_process_time(pbi);
if (!get_free_buf_count(pbi)) {
+ pbi->process_busy = 0;
pbi->dec_result = DEC_RESULT_NEED_MORE_BUFFER;
vdec_schedule_work(&pbi->work);
} else {
@@ -11309,7 +10262,6 @@
pbi->stat &= ~STAT_TIMER_ARM;
}
/* mark itself has all HW resource released and input released */
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_END);
#ifdef SUPPORT_FB_DECODING
if (pbi->used_stage_buf_num > 0)
vdec_core_finish_run(hw_to_vdec(pbi), CORE_MASK_HEVC_BACK);
@@ -11344,34 +10296,6 @@
#endif
return 0;
}
-
-static bool is_avaliable_buffer(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- int i, free_count = 0;
-
- if (ctx->cap_pool.dec < pbi->used_buf_num) {
- free_count = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
- if (free_count &&
- !ctx->fb_ops.query(&ctx->fb_ops, &pbi->fb_token)) {
- return false;
- }
- }
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_count++;
- }
- }
-
- return free_count < pbi->run_ready_min_buf_num ? 0 : 1;
-}
-
static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
{
struct VP9Decoder_s *pbi =
@@ -11383,17 +10307,7 @@
if (!(pbi->pic_list_init_done && pbi->pic_list_init_done2) || pbi->eos)
return ret;
if (!pbi->first_sc_checked && pbi->mmu_enable) {
- int size;
- void * mmu_box;
-
- if (pbi->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = pbi->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
+ int size = decoder_mmu_box_sc_check(pbi->mmu_box, tvp);
pbi->first_sc_checked = 1;
vp9_print(pbi, 0, "vp9 cached=%d need_size=%d speed= %d ms\n",
size, (pbi->need_cache_size >> PAGE_SHIFT),
@@ -11463,12 +10377,10 @@
if (ctx->param_sets_from_ucode) {
if (pbi->v4l_params_parsed) {
- if (ctx->cap_pool.dec < pbi->used_buf_num) {
- if (is_avaliable_buffer(pbi))
- ret = CORE_MASK_HEVC;
- else
- ret = 0;
- }
+ if ((ctx->cap_pool.in < pbi->used_buf_num) &&
+ v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
+ pbi->run_ready_min_buf_num)
+ ret = 0;
} else {
if (ctx->v4l_resolution_change)
ret = 0;
@@ -11499,17 +10411,13 @@
if (pbi->chunk == NULL)
return;
vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "run front: pts %d, pts64 %lld, ts: %lld\n",
- pbi->chunk->pts, pbi->chunk->pts64, pbi->chunk->timestamp);
+ "run front: pts %d, pts64 %lld\n", pbi->chunk->pts, pbi->chunk->pts64);
for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- pbi->frame_mode_pts_save[i] = pbi->frame_mode_pts_save[i - 1];
- pbi->frame_mode_pts64_save[i] = pbi->frame_mode_pts64_save[i - 1];
+ pbi->frame_mode_pts_save[i] = pbi->frame_mode_pts_save[i - 1];
+ pbi->frame_mode_pts64_save[i] = pbi->frame_mode_pts64_save[i - 1];
}
pbi->frame_mode_pts_save[0] = pbi->chunk->pts;
pbi->frame_mode_pts64_save[0] = pbi->chunk->pts64;
-
- if (pbi->is_used_v4l && !v4l_bitstream_id_enable)
- pbi->frame_mode_pts64_save[0] = pbi->chunk->timestamp;
}
static void run_front(struct vdec_s *vdec)
@@ -11567,9 +10475,7 @@
READ_VREG(HEVC_STREAM_WR_PTR),
READ_VREG(HEVC_STREAM_RD_PTR),
pbi->start_shift_bytes);
-
- if (!vdec_secure(hw_to_vdec(pbi)) &&
- vdec_frame_based(vdec) && pbi->chunk) {
+ if (vdec_frame_based(vdec) && pbi->chunk) {
u8 *data = NULL;
if (!pbi->chunk->block->is_mapped)
@@ -11590,7 +10496,6 @@
}
vp9_print_cont(pbi, 0, "\r\n");
}
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
if (vdec->mc_loaded) {
/*firmware have load before,
and not changes to another.
@@ -11610,14 +10515,12 @@
vdec->mc_loaded = 1;
vdec->mc_type = VFORMAT_VP9;
}
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
if (vp9_hw_ctx_restore(pbi) < 0) {
vdec_schedule_work(&pbi->work);
return;
}
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
+
vdec_enable_input(vdec);
WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
@@ -11791,7 +10694,7 @@
{
struct VP9Decoder_s *pbi =
(struct VP9Decoder_s *)vdec->private;
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_START);
+
vp9_print(pbi,
PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n",
__func__, mask);
@@ -11813,36 +10716,23 @@
#else
run_front(vdec);
#endif
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_END);
}
-static void vp9_decoder_ctx_reset(struct VP9Decoder_s *pbi)
+static void init_frame_bufs(struct VP9Decoder_s *pbi)
{
struct vdec_s *vdec = hw_to_vdec(pbi);
struct VP9_Common_s *const cm = &pbi->common;
struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct BufferPool_s *buffer_pool = cm->buffer_pool;
int i;
- cm->buffer_pool = buffer_pool;
-
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- frame_bufs[i].buf.index = i;
- frame_bufs[i].ref_count = 0;
- frame_bufs[i].buf.vf_ref = 0;
- frame_bufs[i].buf.decode_idx = 0;
+ for (i = 0; i < pbi->used_buf_num; ++i) {
+ frame_bufs[i].ref_count = 0;
+ frame_bufs[i].buf.vf_ref = 0;
+ frame_bufs[i].buf.decode_idx = 0;
frame_bufs[i].buf.cma_alloc_addr = 0;
- frame_bufs[i].buf.BUF_index = -1;
- frame_bufs[i].buf.slice_type = 0;
- }
-
- for (i = 0; i < MV_BUFFER_NUM; ++i) {
- pbi->m_mv_BUF[i].used_flag = 0;
- }
-
- for (i = 0; i < FRAME_BUFFERS; i++) {
- pbi->buffer_wrap[i] = i;
+ frame_bufs[i].buf.index = i;
+ frame_bufs[i].buf.vframe_bound = 0;
}
if (vdec->parallel_dec == 1) {
@@ -11855,12 +10745,6 @@
vdec->id);
}
}
-
- pbi->init_flag = 0;
- pbi->first_sc_checked = 0;
- pbi->fatal_error = 0;
- pbi->show_frame_num = 0;
- pbi->eos = 0;
}
static void reset(struct vdec_s *vdec)
@@ -11868,7 +10752,6 @@
struct VP9Decoder_s *pbi =
(struct VP9Decoder_s *)vdec->private;
- cancel_work_sync(&pbi->set_clk_work);
cancel_work_sync(&pbi->work);
if (pbi->stat & STAT_VDEC_RUN) {
amhevc_stop();
@@ -11879,16 +10762,16 @@
del_timer_sync(&pbi->timer);
pbi->stat &= ~STAT_TIMER_ARM;
}
-
+ pbi->dec_result = DEC_RESULT_NONE;
reset_process_time(pbi);
-
vp9_local_uninit(pbi);
if (vvp9_local_init(pbi) < 0)
- vp9_print(pbi, 0, "%s local_init failed \r\n", __func__);
+ vp9_print(pbi, 0, "%s local_init failed \r\n", __func__);
+ init_frame_bufs(pbi);
- vp9_decoder_ctx_reset(pbi);
+ pbi->eos = 0;
- vp9_print(pbi, 0, "%s\r\n", __func__);
+ vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
}
static irqreturn_t vp9_irq_cb(struct vdec_s *vdec, int irq)
@@ -11935,7 +10818,7 @@
pbi->no_head
);
- if (!pbi->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
+ if (vf_get_receiver(vdec->vf_provider_name)) {
enum receviver_start_e state =
vf_notify_receiver(vdec->vf_provider_name,
VFRAME_EVENT_PROVIDER_QUREY_STATE,
@@ -11964,7 +10847,7 @@
for (i = 0; i < MAX_BUF_NUM; i++) {
vp9_print(pbi, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
+ "mv_Buf(%d) start_adr 0x%lx size 0x%x used %d\n",
i,
pbi->m_mv_BUF[i].start_adr,
pbi->m_mv_BUF[i].size,
@@ -12059,15 +10942,9 @@
int transfer_val;
struct vframe_content_light_level_s content_light_level;
struct vframe_master_display_colour_s vf_dp;
- struct VP9Decoder_s *pbi = NULL;
- int i;
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) {
- pr_info("vp9 unsupported on cpu 0x%x\n", get_cpu_major_id());
- return -EINVAL;
- }
+ struct BUF_s BUF[MAX_BUF_NUM];
+ struct VP9Decoder_s *pbi = NULL;
pr_debug("%s\n", __func__);
if (pdata == NULL) {
@@ -12097,35 +10974,19 @@
pdata->threaded_irq_handler = vp9_threaded_irq_cb;
pdata->dump_state = vp9_dump_state;
+ memcpy(&BUF[0], &pbi->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+ memcpy(&pbi->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+
pbi->index = pdev->id;
- if (is_rdma_enable()) {
- pbi->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &pbi->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- pbi->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- pbi->rdma_adr[i * 4 + 1] = i;
- pbi->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- pbi->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- pbi->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
-
- snprintf(pbi->trace.vdec_name, sizeof(pbi->trace.vdec_name),
+ snprintf(pbi->vdec_name, sizeof(pbi->vdec_name),
"vp9-%d", pbi->index);
- snprintf(pbi->trace.pts_name, sizeof(pbi->trace.pts_name),
- "%s-pts", pbi->trace.vdec_name);
- snprintf(pbi->trace.new_q_name, sizeof(pbi->trace.new_q_name),
- "%s-newframe_q", pbi->trace.vdec_name);
- snprintf(pbi->trace.disp_q_name, sizeof(pbi->trace.disp_q_name),
- "%s-dispframe_q", pbi->trace.vdec_name);
- snprintf(pbi->trace.decode_time_name, sizeof(pbi->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(pbi->trace.decode_run_time_name, sizeof(pbi->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(pbi->trace.decode_header_memory_time_name, sizeof(pbi->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
+ snprintf(pbi->pts_name, sizeof(pbi->pts_name),
+ "%s-pts", pbi->vdec_name);
+ snprintf(pbi->new_q_name, sizeof(pbi->new_q_name),
+ "%s-newframe_q", pbi->vdec_name);
+ snprintf(pbi->disp_q_name, sizeof(pbi->disp_q_name),
+ "%s-dispframe_q", pbi->vdec_name);
if (pdata->use_vfm_path)
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
@@ -12134,23 +10995,26 @@
snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+ vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+ &vvp9_vf_provider, pbi);
+
pbi->provider_name = pdata->vf_provider_name;
platform_set_drvdata(pdev, pdata);
pbi->platform_dev = pdev;
pbi->video_signal_type = 0;
pbi->m_ins_flag = 1;
- if (!vdec_is_support_4k()) {
- pbi->max_pic_w = 1920;
- pbi->max_pic_h = 1088;
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
- pbi->max_pic_w = 4096;
- pbi->max_pic_h = 2304;
- } else {
+ if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX)
+ pbi->stat |= VP9_TRIGGER_FRAME_ENABLE;
+
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
pbi->max_pic_w = 8192;
pbi->max_pic_h = 4608;
+ } else {
+ pbi->max_pic_w = 4096;
+ pbi->max_pic_h = 2304;
}
-
+#if 1
if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
pdata->config_len) {
#ifdef MULTI_INSTANCE_SUPPORT
@@ -12193,7 +11057,6 @@
&config_val) == 0) {
pbi->max_pic_h = config_val;
}
-
if ((pbi->max_pic_w * pbi->max_pic_h)
< (vp9_buf_width * vp9_buf_height)) {
pbi->max_pic_w = vp9_buf_width;
@@ -12242,8 +11105,6 @@
if (get_config_int(pdata->config, "HDRStaticInfo",
&vf_dp.present_flag) == 0
&& vf_dp.present_flag == 1) {
- get_config_int(pdata->config, "signal_type",
- &pbi->video_signal_type);
get_config_int(pdata->config, "mG.x",
&vf_dp.primaries[0][0]);
get_config_int(pdata->config, "mG.y",
@@ -12279,18 +11140,18 @@
vp9_print(pbi, 0, "transfer_val=%d\n",transfer_val);
vf_dp.content_light_level = content_light_level;
- if (!pbi->video_signal_type) {
- pbi->video_signal_type = (1 << 29)
+ pbi->video_signal_type = (1 << 29)
| (5 << 26) /* unspecified */
| (0 << 25) /* limit */
| (1 << 24) /* color available */
| (9 << 16) /* 2020 */
| (transfer_val << 8) /* 2084 */
| (9 << 0); /* 2020 */
- }
}
pbi->vf_dp = vf_dp;
- } else {
+ } else
+#endif
+ {
if (pdata->sys_info) {
pbi->vvp9_amstream_dec_info = *pdata->sys_info;
if ((pbi->vvp9_amstream_dec_info.width != 0) &&
@@ -12305,29 +11166,14 @@
pbi->double_write_mode = double_write_mode;
}
- if (!pbi->is_used_v4l) {
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vvp9_vf_provider, pbi);
- }
-
if (no_head & 0x10) {
pbi->no_head = (no_head & 0xf);
}
- pbi->endian = HEVC_CONFIG_LITTLE_ENDIAN;
if (!pbi->is_used_v4l) {
pbi->mem_map_mode = mem_map_mode;
- if (is_support_vdec_canvas())
- pbi->endian = HEVC_CONFIG_BIG_ENDIAN;
}
- if (endian)
- pbi->endian = endian;
-
- if (pbi->is_used_v4l)
- pbi->run_ready_min_buf_num = run_ready_min_buf_num - 1 ;
- else
- pbi->run_ready_min_buf_num = run_ready_min_buf_num;
-
+ pbi->run_ready_min_buf_num = run_ready_min_buf_num;
if (is_oversize(pbi->max_pic_w, pbi->max_pic_h)) {
pr_err("over size: %dx%d, probe failed\n",
pbi->max_pic_w, pbi->max_pic_h);
@@ -12344,20 +11190,10 @@
pbi->enable_fence, pbi->fence_usage);
}
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- pbi->double_write_mode == 0x10)
- pbi->mmu_enable = 0;
- else
- pbi->mmu_enable = 1;
+ if (pbi->enable_fence)
+ pdata->sync.usage = pbi->fence_usage;
-#ifdef VP9_10B_MMU_DW
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- pbi->dw_mmu_enable =
- (get_double_write_mode(pbi) & 0x20) ? 1 : 0;
- } else {
- pbi->dw_mmu_enable = 0;
- }
-#endif
+ pbi->mmu_enable = 1;
video_signal_type = pbi->video_signal_type;
if (pdata->sys_info) {
@@ -12370,8 +11206,8 @@
pbi->low_latency_flag = 1;
vp9_print(pbi, 0,
- "no_head %d low_latency %d, signal_type 0x%x\n",
- pbi->no_head, pbi->low_latency_flag, pbi->video_signal_type);
+ "no_head %d low_latency %d\n",
+ pbi->no_head, pbi->low_latency_flag);
#if 0
pbi->buf_start = pdata->mem_start;
pbi->buf_size = pdata->mem_end - pdata->mem_start + 1;
@@ -12411,27 +11247,8 @@
}
pbi->cma_dev = pdata->cma_dev;
-
- mutex_init(&pbi->fence_mutex);
-
- if (pbi->enable_fence) {
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- vp9_print(pbi, 0, "alloc fence timeline error\n");
- vp9_local_uninit(pbi);
- uninit_mmu_buffers(pbi);
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- pdata->dec_status = NULL;
- return -1;
- }
- pdata->sync->usage = pbi->fence_usage;
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
- }
-
if (vvp9_init(pdata) < 0) {
pr_info("\namvdec_vp9 init failed.\n");
- vdec_timeline_put(pdata->sync);
vp9_local_uninit(pbi);
uninit_mmu_buffers(pbi);
/* devm_kfree(&pdev->dev, (void *)pbi); */
@@ -12459,6 +11276,11 @@
#endif
pbi->pic_list_init_done2 = true;
+ if (pbi->enable_fence) {
+ /* creat timeline. */
+ vdec_timeline_create(&pdata->sync, DRIVER_NAME);
+ }
+
return 0;
}
@@ -12497,7 +11319,7 @@
}
if (pbi->enable_fence)
- vdec_fence_release(pbi, vdec->sync);
+ vdec_fence_release(pbi, &vdec->sync);
#ifdef DEBUG_PTS
pr_info("pts missed %ld, pts hit %ld, duration %d\n",
@@ -12506,8 +11328,6 @@
mem_map_mode = 0;
/* devm_kfree(&pdev->dev, (void *)pbi); */
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, pbi->rdma_adr, pbi->rdma_phy_adr);
vfree((void *)pbi);
return 0;
}
@@ -12515,12 +11335,11 @@
static struct platform_driver ammvdec_vp9_driver = {
.probe = ammvdec_vp9_probe,
.remove = ammvdec_vp9_remove,
-#ifdef CONFIG_PM
- .suspend = amhevc_suspend,
- .resume = amhevc_resume,
-#endif
.driver = {
.name = MULTI_DRIVER_NAME,
+#ifdef CONFIG_PM
+ .pm = &vp9_pm_ops,
+#endif
}
};
#endif
@@ -12542,6 +11361,8 @@
MC_PU32("slice_parse_begin", &slice_parse_begin),
MC_PU32("i_only_flag", &i_only_flag),
MC_PU32("error_handle_policy", &error_handle_policy),
+ MC_PU32("buf_alloc_width", &buf_alloc_width),
+ MC_PU32("buf_alloc_height", &buf_alloc_height),
MC_PU32("buf_alloc_depth", &buf_alloc_depth),
MC_PU32("buf_alloc_size", &buf_alloc_size),
MC_PU32("buffer_mode", &buffer_mode),
@@ -12567,20 +11388,13 @@
struct BuffInfo_s *p_buf_info;
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvvp9_workbuff_spec[2];
- else
- p_buf_info = &amvvp9_workbuff_spec[1];
- } else
- p_buf_info = &amvvp9_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k())
- p_buf_info = &amvvp9_workbuff_spec[5];
+ if (vdec_is_support_4k()) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
+ p_buf_info = &amvvp9_workbuff_spec[2];
else
- p_buf_info = &amvvp9_workbuff_spec[4];
- }
+ p_buf_info = &amvvp9_workbuff_spec[1];
+ } else
+ p_buf_info = &amvvp9_workbuff_spec[0];
init_buff_spec(NULL, p_buf_info);
work_buf_size =
@@ -12610,21 +11424,20 @@
return -ENODEV;
}
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) {
- amvdec_vp9_profile.name = "vp9_unsupport";
- } else if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) {
+ if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
amvdec_vp9_profile.profile =
- "8k, 10bit, dwrite, compressed, fence, v4l-uvm";
+ "8k, 10bit, dwrite, compressed, fence";
+ } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL
+ /*&& get_cpu_major_id() != MESON_CPU_MAJOR_ID_GXLX*/
+ && get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TXL) {
+ if (vdec_is_support_4k())
+ amvdec_vp9_profile.profile =
+ "4k, 10bit, dwrite, compressed, fence";
+ else
+ amvdec_vp9_profile.profile =
+ "10bit, dwrite, compressed, fence";
} else {
- if (vdec_is_support_4k())
- amvdec_vp9_profile.profile =
- "4k, 10bit, dwrite, compressed, fence, v4l-uvm";
- else
- amvdec_vp9_profile.profile =
- "10bit, dwrite, compressed, fence, v4l-uvm";
+ amvdec_vp9_profile.name = "vp9_unsupport";
}
if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
@@ -12636,7 +11449,6 @@
vcodec_profile_register(&amvdec_vp9_profile_mult);
INIT_REG_NODE_CONFIGS("media.decoder", &vp9_node,
"vp9", vp9_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_VP9, 0);
return 0;
}
@@ -12706,6 +11518,12 @@
module_param(error_handle_policy, uint, 0664);
MODULE_PARM_DESC(error_handle_policy, "\n amvdec_vp9 error_handle_policy\n");
+module_param(buf_alloc_width, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
+
+module_param(buf_alloc_height, uint, 0664);
+MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
+
module_param(buf_alloc_depth, uint, 0664);
MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
@@ -12829,9 +11647,6 @@
module_param(force_pts_unstable, uint, 0664);
MODULE_PARM_DESC(force_pts_unstable, "\n force_pts_unstable\n");
-module_param(v4l_bitstream_id_enable, uint, 0664);
-MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n");
-
module_init(amvdec_vp9_driver_init_module);
module_exit(amvdec_vp9_driver_remove_module);
diff --git a/drivers/frame_provider/decoder_v4l/Makefile b/drivers/frame_provider/decoder_v4l/Makefile
deleted file mode 100644
index 43e94df..0000000
--- a/drivers/frame_provider/decoder_v4l/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-y += mpeg12/
-obj-y += mpeg4/
-obj-y += h264_multi/
-obj-y += h265/
-obj-y += vp9/
-obj-y += mjpeg/
-obj-y += avs2/
-obj-y += avs_multi/
-obj-y += vav1/
diff --git a/drivers/frame_provider/decoder_v4l/avs2/Makefile b/drivers/frame_provider/decoder_v4l/avs2/Makefile
deleted file mode 100644
index 9995065..0000000
--- a/drivers/frame_provider/decoder_v4l/avs2/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += amvdec_avs2_v4l.o
-amvdec_avs2_v4l-objs += vavs2.o avs2_bufmgr.o
diff --git a/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c
deleted file mode 100644
index 91c3132..0000000
--- a/drivers/frame_provider/decoder_v4l/avs2/avs2_bufmgr.c
+++ /dev/null
@@ -1,2205 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include "avs2_global.h"
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-
-#undef pr_info
-#define pr_info printk
-
-#define assert(chk_cond) {\
- if (!(chk_cond))\
- pr_info("error line %d\n", __LINE__);\
- while (!(chk_cond))\
- ;\
-}
-
-int16_t get_param(uint16_t value, int8_t *print_info)
-{
- if (is_avs2_print_param())
- pr_info("%s = %x\n", print_info, value);
- return (int16_t)value;
-}
-
-void readAlfCoeff(struct avs2_decoder *avs2_dec, struct ALFParam_s *Alfp)
-{
- int32_t pos;
- union param_u *rpm_param = &avs2_dec->param;
-
- int32_t f = 0, symbol, pre_symbole;
- const int32_t numCoeff = (int32_t)ALF_MAX_NUM_COEF;
-
- switch (Alfp->componentID) {
- case ALF_Cb:
- case ALF_Cr: {
- for (pos = 0; pos < numCoeff; pos++) {
- if (Alfp->componentID == ALF_Cb)
- Alfp->coeffmulti[0][pos] =
- get_param(
- rpm_param->alf.alf_cb_coeffmulti[pos],
- "Chroma ALF coefficients");
- else
- Alfp->coeffmulti[0][pos] =
- get_param(
- rpm_param->alf.alf_cr_coeffmulti[pos],
- "Chroma ALF coefficients");
-#if Check_Bitstream
- if (pos <= 7)
- assert(Alfp->coeffmulti[0][pos] >= -64
- && Alfp->coeffmulti[0][pos] <= 63);
- if (pos == 8)
- assert(Alfp->coeffmulti[0][pos] >= -1088
- && Alfp->coeffmulti[0][pos] <= 1071);
-#endif
- }
- }
- break;
- case ALF_Y: {
- int32_t region_distance_idx = 0;
- Alfp->filters_per_group =
- get_param(rpm_param->alf.alf_filters_num_m_1,
- "ALF_filter_number_minus_1");
-#if Check_Bitstream
- assert(Alfp->filters_per_group >= 0
- && Alfp->filters_per_group <= 15);
-#endif
- Alfp->filters_per_group = Alfp->filters_per_group + 1;
-
- memset(Alfp->filterPattern, 0, NO_VAR_BINS * sizeof(int32_t));
- pre_symbole = 0;
- symbol = 0;
- for (f = 0; f < Alfp->filters_per_group; f++) {
- if (f > 0) {
- if (Alfp->filters_per_group != 16) {
- symbol =
- get_param(rpm_param->alf.region_distance
- [region_distance_idx++],
- "Region distance");
- } else {
- symbol = 1;
- }
- Alfp->filterPattern[symbol + pre_symbole] = 1;
- pre_symbole = symbol + pre_symbole;
- }
-
- for (pos = 0; pos < numCoeff; pos++) {
- Alfp->coeffmulti[f][pos] =
- get_param(
- rpm_param->alf.alf_y_coeffmulti[f][pos],
- "Luma ALF coefficients");
-#if Check_Bitstream
- if (pos <= 7)
- assert(
- Alfp->coeffmulti[f][pos]
- >= -64 &&
- Alfp->coeffmulti[f][pos]
- <= 63);
- if (pos == 8)
- assert(
- Alfp->coeffmulti[f][pos]
- >= -1088 &&
- Alfp->coeffmulti[f][pos]
- <= 1071);
-#endif
-
- }
- }
-
-#if Check_Bitstream
- assert(pre_symbole >= 0 && pre_symbole <= 15);
-
-#endif
- }
- break;
- default: {
- pr_info("Not a legal component ID\n");
- assert(0);
- return; /* exit(-1);*/
- }
- }
-}
-
-void Read_ALF_param(struct avs2_decoder *avs2_dec)
-{
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- union param_u *rpm_param = &avs2_dec->param;
- int32_t compIdx;
- if (input->alf_enable) {
- img->pic_alf_on[0] =
- get_param(
- rpm_param->alf.picture_alf_enable_Y,
- "alf_pic_flag_Y");
- img->pic_alf_on[1] =
- get_param(
- rpm_param->alf.picture_alf_enable_Cb,
- "alf_pic_flag_Cb");
- img->pic_alf_on[2] =
- get_param(
- rpm_param->alf.picture_alf_enable_Cr,
- "alf_pic_flag_Cr");
-
- avs2_dec->m_alfPictureParam[ALF_Y].alf_flag
- = img->pic_alf_on[ALF_Y];
- avs2_dec->m_alfPictureParam[ALF_Cb].alf_flag
- = img->pic_alf_on[ALF_Cb];
- avs2_dec->m_alfPictureParam[ALF_Cr].alf_flag
- = img->pic_alf_on[ALF_Cr];
- if (img->pic_alf_on[0]
- || img->pic_alf_on[1]
- || img->pic_alf_on[2]) {
- for (compIdx = 0;
- compIdx < NUM_ALF_COMPONENT;
- compIdx++) {
- if (img->pic_alf_on[compIdx]) {
- readAlfCoeff(
- avs2_dec,
- &avs2_dec->m_alfPictureParam[compIdx]);
- }
- }
- }
- }
-
-}
-
-void Get_SequenceHeader(struct avs2_decoder *avs2_dec)
-{
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- union param_u *rpm_param = &avs2_dec->param;
- /*int32_t i, j;*/
-
- /*fpr_info(stdout, "Sequence Header\n");*/
- /*memcpy(currStream->streamBuffer, buf, length);*/
- /*currStream->code_len = currStream->bitstream_length = length;*/
- /*currStream->read_len = currStream->frame_bitoffset = (startcodepos +
- 1) * 8;*/
-
- input->profile_id =
- get_param(rpm_param->p.profile_id, "profile_id");
- input->level_id =
- get_param(rpm_param->p.level_id, "level_id");
- hd->progressive_sequence =
- get_param(
- rpm_param->p.progressive_sequence,
- "progressive_sequence");
-#if INTERLACE_CODING
- hd->is_field_sequence =
- get_param(
- rpm_param->p.is_field_sequence,
- "field_coded_sequence");
-#endif
-#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
- img->is_field_sequence = hd->is_field_sequence;
-#endif
- hd->horizontal_size =
- get_param(rpm_param->p.horizontal_size, "horizontal_size");
- hd->vertical_size =
- get_param(rpm_param->p.vertical_size, "vertical_size");
- input->chroma_format =
- get_param(rpm_param->p.chroma_format, "chroma_format");
- input->output_bit_depth = 8;
- input->sample_bit_depth = 8;
- hd->sample_precision = 1;
- if (input->profile_id == BASELINE10_PROFILE) { /* 10bit profile (0x52)*/
- input->output_bit_depth =
- get_param(rpm_param->p.sample_precision,
- "sample_precision");
- input->output_bit_depth =
- 6 + (input->output_bit_depth) * 2;
- input->sample_bit_depth =
- get_param(rpm_param->p.encoding_precision,
- "encoding_precision");
- input->sample_bit_depth =
- 6 + (input->sample_bit_depth) * 2;
- } else { /* other profile*/
- hd->sample_precision =
- get_param(rpm_param->p.sample_precision,
- "sample_precision");
- }
- hd->aspect_ratio_information =
- get_param(rpm_param->p.aspect_ratio_information,
- "aspect_ratio_information");
- hd->frame_rate_code =
- get_param(rpm_param->p.frame_rate_code, "frame_rate_code");
-
- hd->bit_rate_lower =
- get_param(rpm_param->p.bit_rate_lower, "bit_rate_lower");
- /*hd->marker_bit = get_param(rpm_param->p.marker_bit,
- * "marker bit");*/
- /*CHECKMARKERBIT*/
- hd->bit_rate_upper =
- get_param(rpm_param->p.bit_rate_upper, "bit_rate_upper");
- hd->low_delay =
- get_param(rpm_param->p.low_delay, "low_delay");
- /*hd->marker_bit =
- get_param(rpm_param->p.marker_bit2,
- "marker bit");*/
- /*CHECKMARKERBIT*/
-#if M3480_TEMPORAL_SCALABLE
- hd->temporal_id_exist_flag =
- get_param(rpm_param->p.temporal_id_exist_flag,
- "temporal_id exist flag"); /*get
- Extention Flag*/
-#endif
- /*u_v(18, "bbv buffer size");*/
- input->g_uiMaxSizeInBit =
- get_param(rpm_param->p.g_uiMaxSizeInBit,
- "Largest Coding Block Size");
-
-
- /*hd->background_picture_enable = 0x01 ^
- (get_param(rpm_param->p.avs2_seq_flags,
- "background_picture_disable")
- >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1;*/
- /*rain???*/
- hd->background_picture_enable = 0x01 ^
- ((get_param(rpm_param->p.avs2_seq_flags,
- "background_picture_disable")
- >> BACKGROUND_PICTURE_DISABLE_BIT) & 0x1);
-
-
- hd->b_dmh_enabled = 1;
-
- hd->b_mhpskip_enabled =
- get_param(rpm_param->p.avs2_seq_flags >> B_MHPSKIP_ENABLED_BIT,
- "mhpskip enabled") & 0x1;
- hd->dhp_enabled =
- get_param(rpm_param->p.avs2_seq_flags >> DHP_ENABLED_BIT,
- "dhp enabled") & 0x1;
- hd->wsm_enabled =
- get_param(rpm_param->p.avs2_seq_flags >> WSM_ENABLED_BIT,
- "wsm enabled") & 0x1;
-
- img->inter_amp_enable =
- get_param(rpm_param->p.avs2_seq_flags >> INTER_AMP_ENABLE_BIT,
- "Asymmetric Motion Partitions") & 0x1;
- input->useNSQT =
- get_param(rpm_param->p.avs2_seq_flags >> USENSQT_BIT,
- "useNSQT") & 0x1;
- input->useSDIP =
- get_param(rpm_param->p.avs2_seq_flags >> USESDIP_BIT,
- "useNSIP") & 0x1;
-
- hd->b_secT_enabled =
- get_param(rpm_param->p.avs2_seq_flags >> B_SECT_ENABLED_BIT,
- "secT enabled") & 0x1;
-
- input->sao_enable =
- get_param(rpm_param->p.avs2_seq_flags >> SAO_ENABLE_BIT,
- "SAO Enable Flag") & 0x1;
- input->alf_enable =
- get_param(rpm_param->p.avs2_seq_flags >> ALF_ENABLE_BIT,
- "ALF Enable Flag") & 0x1;
- hd->b_pmvr_enabled =
- get_param(rpm_param->p.avs2_seq_flags >> B_PMVR_ENABLED_BIT,
- "pmvr enabled") & 0x1;
-
-
- hd->gop_size = get_param(rpm_param->p.num_of_RPS,
- "num_of_RPS");
-#if Check_Bitstream
- /*assert(hd->gop_size<=32);*/
-#endif
-
- if (hd->low_delay == 0) {
- hd->picture_reorder_delay =
- get_param(rpm_param->p.picture_reorder_delay,
- "picture_reorder_delay");
- }
-
- input->crossSliceLoopFilter =
- get_param(rpm_param->p.avs2_seq_flags
- >> CROSSSLICELOOPFILTER_BIT,
- "Cross Loop Filter Flag") & 0x1;
-
-#if BCBR
- if ((input->profile_id == SCENE_PROFILE ||
- input->profile_id == SCENE10_PROFILE) &&
- hd->background_picture_enable) {
- hd->bcbr_enable = u_v(1,
- "block_composed_background_picture_enable");
- u_v(1, "reserved bits");
- } else {
- hd->bcbr_enable = 0;
- u_v(2, "reserved bits");
- }
-#else
- /*u_v(2, "reserved bits");*/
-#endif
-
- img->width = hd->horizontal_size;
- img->height = hd->vertical_size;
- img->width_cr = (img->width >> 1);
-
- if (input->chroma_format == 1) {
- img->height_cr
- = (img->height >> 1);
- }
-
- img->PicWidthInMbs = img->width / MIN_CU_SIZE;
- img->PicHeightInMbs = img->height / MIN_CU_SIZE;
- img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
- img->buf_cycle = input->buf_cycle + 1;
- img->max_mb_nr = (img->width * img->height)
- / (MIN_CU_SIZE * MIN_CU_SIZE);
-
-#ifdef AML
-avs2_dec->lcu_size =
- get_param(rpm_param->p.lcu_size, "lcu_size");
-avs2_dec->lcu_size = 1<<(avs2_dec->lcu_size);
-#endif
-hc->seq_header++;
-}
-
-
-void Get_I_Picture_Header(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- union param_u *rpm_param = &avs2_dec->param;
-
-#if RD1501_FIX_BG /*//Longfei.Wang@mediatek.com*/
- hd->background_picture_flag = 0;
- hd->background_picture_output_flag = 0;
- img->typeb = 0;
-#endif
-
- hd->time_code_flag =
- get_param(rpm_param->p.time_code_flag,
- "time_code_flag");
-
- if (hd->time_code_flag) {
- hd->time_code =
- get_param(rpm_param->p.time_code,
- "time_code");
- }
- if (hd->background_picture_enable) {
- hd->background_picture_flag =
- get_param(rpm_param->p.background_picture_flag,
- "background_picture_flag");
-
- if (hd->background_picture_flag) {
- img->typeb =
- BACKGROUND_IMG;
- } else {
- img->typeb = 0;
- }
-
- if (img->typeb == BACKGROUND_IMG) {
- hd->background_picture_output_flag =
- get_param(
- rpm_param->p.background_picture_output_flag,
- "background_picture_output_flag");
- }
- }
-
-
- {
- img->coding_order =
- get_param(rpm_param->p.coding_order,
- "coding_order");
-
-
-
-#if M3480_TEMPORAL_SCALABLE
- if (hd->temporal_id_exist_flag == 1) {
- hd->cur_layer =
- get_param(rpm_param->p.cur_layer,
- "temporal_id");
- }
-#endif
-#if RD1501_FIX_BG /*Longfei.Wang@mediatek.com*/
- if (hd->low_delay == 0
- && !(hd->background_picture_flag &&
- !hd->background_picture_output_flag)) { /*cdp*/
-#else
- if (hd->low_delay == 0 &&
- !(hd->background_picture_enable &&
- !hd->background_picture_output_flag)) { /*cdp*/
-#endif
- hd->displaydelay =
- get_param(rpm_param->p.displaydelay,
- "picture_output_delay");
- }
-
- }
- {
- int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
- int32_t predict;
- int32_t j;
- predict =
- get_param(rpm_param->p.predict,
- "use RCS in SPS");
- /*if (predict) {*/
- RPS_idx =
- get_param(rpm_param->p.RPS_idx,
- "predict for RCS");
- /* hd->curr_RPS = hd->decod_RPS[RPS_idx];*/
- /*} else {*/
- /*gop size16*/
- hd->curr_RPS.referd_by_others =
- get_param(rpm_param->p.referd_by_others_cur,
- "refered by others");
- hd->curr_RPS.num_of_ref =
- get_param(rpm_param->p.num_of_ref_cur,
- "num of reference picture");
- for (j = 0; j < hd->curr_RPS.num_of_ref; j++) {
- hd->curr_RPS.ref_pic[j] =
- get_param(rpm_param->p.ref_pic_cur[j],
- "delta COI of ref pic");
- }
- hd->curr_RPS.num_to_remove =
- get_param(rpm_param->p.num_to_remove_cur,
- "num of removed picture");
-#ifdef SANITY_CHECK
- if (hd->curr_RPS.num_to_remove > MAXREF) {
- hd->curr_RPS.num_to_remove = MAXREF;
- pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n",
- __func__, hd->curr_RPS.num_to_remove);
- }
-#endif
-
- for (j = 0; j < hd->curr_RPS.num_to_remove; j++) {
- hd->curr_RPS.remove_pic[j] =
- get_param(
- rpm_param->p.remove_pic_cur[j],
- "delta COI of removed pic");
- }
- /*u_v(1, "marker bit");*/
-
- /*}*/
- }
- /*xyji 12.23*/
- if (hd->low_delay) {
- /*ue_v(
- "bbv check times");*/
- }
-
- hd->progressive_frame =
- get_param(rpm_param->p.progressive_frame,
- "progressive_frame");
-
- if (!hd->progressive_frame) {
- img->picture_structure =
- get_param(rpm_param->p.picture_structure,
- "picture_structure");
- } else {
- img->picture_structure
- = 1;
- }
-
- hd->top_field_first =
- get_param(rpm_param->p.top_field_first,
- "top_field_first");
- hd->repeat_first_field =
- get_param(rpm_param->p.repeat_first_field,
- "repeat_first_field");
-#if INTERLACE_CODING
- if (hd->is_field_sequence) {
- hd->is_top_field =
- get_param(rpm_param->p.is_top_field,
- "is_top_field");
-#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
- img->is_top_field = hd->is_top_field;
-#endif
- }
-#endif
-
-
- img->qp = hd->picture_qp;
-
- img->type = I_IMG;
-
-}
-
-/*
- * Function:pb picture header
- * Input:
- * Output:
- * Return:
- * Attention:
- */
-
-void Get_PB_Picture_Header(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- union param_u *rpm_param = &avs2_dec->param;
-
-
- /*u_v(32, "bbv delay");*/
-
- hd->picture_coding_type =
- get_param(rpm_param->p.picture_coding_type,
- "picture_coding_type");
-
- if (hd->background_picture_enable &&
- (hd->picture_coding_type == 1 ||
- hd->picture_coding_type == 3)) {
- if (hd->picture_coding_type == 1) {
- hd->background_pred_flag =
- get_param(
- rpm_param->p.background_pred_flag,
- "background_pred_flag");
- } else {
- hd->background_pred_flag = 0;
- }
- if (hd->background_pred_flag == 0) {
-
- hd->background_reference_enable =
- get_param(
- rpm_param->
- p.background_reference_enable,
- "background_reference_enable");
-
- } else {
-#if RD170_FIX_BG
- hd->background_reference_enable = 1;
-#else
- hd->background_reference_enable = 0;
-#endif
- }
-
- } else {
- hd->background_pred_flag = 0;
- hd->background_reference_enable = 0;
- }
-
-
-
- if (hd->picture_coding_type == 1) {
- img->type =
- P_IMG;
- } else if (hd->picture_coding_type == 3) {
- img->type =
- F_IMG;
- } else {
- img->type =
- B_IMG;
- }
-
-
- if (hd->picture_coding_type == 1 &&
- hd->background_pred_flag) {
- img->typeb = BP_IMG;
- } else {
- img->typeb = 0;
- }
-
-
- {
- img->coding_order =
- get_param(
- rpm_param->p.coding_order,
- "coding_order");
-
-
-#if M3480_TEMPORAL_SCALABLE
- if (hd->temporal_id_exist_flag == 1) {
- hd->cur_layer =
- get_param(rpm_param->p.cur_layer,
- "temporal_id");
- }
-#endif
-
- if (hd->low_delay == 0) {
- hd->displaydelay =
- get_param(rpm_param->p.displaydelay,
- "displaydelay");
- }
- }
- {
- int32_t RPS_idx;/* = (img->coding_order-1) % gop_size;*/
- int32_t predict;
- predict =
- get_param(rpm_param->p.predict,
- "use RPS in SPS");
- if (predict) {
- RPS_idx =
- get_param(rpm_param->p.RPS_idx,
- "predict for RPS");
- hd->curr_RPS = hd->decod_RPS[RPS_idx];
- } /*else*/
- {
- /*gop size16*/
- int32_t j;
- hd->curr_RPS.referd_by_others =
- get_param(
- rpm_param->p.referd_by_others_cur,
- "refered by others");
- hd->curr_RPS.num_of_ref =
- get_param(
- rpm_param->p.num_of_ref_cur,
- "num of reference picture");
- for (j = 0; j < hd->curr_RPS.num_of_ref; j++) {
- hd->curr_RPS.ref_pic[j] =
- get_param(
- rpm_param->p.ref_pic_cur[j],
- "delta COI of ref pic");
- }
- hd->curr_RPS.num_to_remove =
- get_param(
- rpm_param->p.num_to_remove_cur,
- "num of removed picture");
-#ifdef SANITY_CHECK
- if (hd->curr_RPS.num_to_remove > MAXREF) {
- hd->curr_RPS.num_to_remove = MAXREF;
- pr_info("Warning, %s: num_to_remove %d beyond range, force to MAXREF\n",
- __func__, hd->curr_RPS.num_to_remove);
- }
-#endif
- for (j = 0;
- j < hd->curr_RPS.num_to_remove; j++) {
- hd->curr_RPS.remove_pic[j] =
- get_param(
- rpm_param->p.remove_pic_cur[j],
- "delta COI of removed pic");
- }
- /*u_v(1, "marker bit");*/
-
- }
- }
- /*xyji 12.23*/
- if (hd->low_delay) {
- /*ue_v(
- "bbv check times");*/
- }
-
- hd->progressive_frame =
- get_param(rpm_param->p.progressive_frame,
- "progressive_frame");
-
- if (!hd->progressive_frame) {
- img->picture_structure =
- get_param(rpm_param->p.picture_structure,
- "picture_structure");
- } else {
- img->picture_structure = 1;
- }
-
- hd->top_field_first =
- get_param(rpm_param->p.top_field_first,
- "top_field_first");
- hd->repeat_first_field =
- get_param(rpm_param->p.repeat_first_field,
- "repeat_first_field");
-#if INTERLACE_CODING
- if (hd->is_field_sequence) {
- hd->is_top_field =
- get_param(rpm_param->p.is_top_field,
- "is_top_field");
-#if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
- img->is_top_field = hd->is_top_field;
-#endif
- /*u_v(1, "reserved bit for interlace coding");*/
- }
-#endif
-
-#if Check_Bitstream
- /*assert(hd->picture_qp>=0&&hd->picture_qp<=(63 + 8 *
- (input->sample_bit_depth - 8)));*/
-#endif
-
- img->random_access_decodable_flag =
- get_param(rpm_param->p.random_access_decodable_flag,
- "random_access_decodable_flag");
-
- img->qp = hd->picture_qp;
-}
-
-
-
-
-void calc_picture_distance(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- /*
- union param_u *rpm_param = &avs2_dec->param;
-
- for POC mode 0:
- uint32_t MaxPicDistanceLsb = (1 << 8);
- */
- if (img->coding_order < img->PrevPicDistanceLsb)
-
- {
- int32_t i, j;
-
- hc->total_frames++;
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if (
- avs2_dec->fref[i]->imgtr_fwRefDistance
- >= 0) {
- avs2_dec->fref[i]->
- imgtr_fwRefDistance -= 256;
- avs2_dec->fref[i]->
- imgcoi_ref -= 256;
- }
-#if RD170_FIX_BG
- for (j = 0; j < MAXREF; j++) {
-#else
- for (j = 0; j < 4; j++) {
-#endif
- avs2_dec->fref[i]->ref_poc[j] -= 256;
- }
- }
- for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
- avs2_dec->outprint.stdoutdata[i].framenum -= 256;
- avs2_dec->outprint.stdoutdata[i].tr -= 256;
- }
-
- hd->last_output -= 256;
- hd->curr_IDRtr -= 256;
- hd->curr_IDRcoi -= 256;
- hd->next_IDRtr -= 256;
- hd->next_IDRcoi -= 256;
- }
- if (hd->low_delay == 0) {
- img->tr = img->coding_order +
- hd->displaydelay - hd->picture_reorder_delay;
- } else {
- img->tr =
- img->coding_order;
- }
-
-#if REMOVE_UNUSED
- img->pic_distance = img->tr;
-#else
- img->pic_distance = img->tr % 256;
-#endif
- hc->picture_distance = img->pic_distance;
-
-}
-
-int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec)
-{
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
-
- int32_t refnum;
-
- int32_t memory_size = 0;
- /*
-int32_t img_height = (hd->vertical_size + img->auto_crop_bottom);
- */
- img->buf_cycle = input->buf_cycle + 1;
-
- img->buf_cycle *= 2;
-
- hc->background_ref = hc->backgroundReferenceFrame;
-
- for (refnum = 0; refnum < REF_MAXBUFFER; refnum++) {
- avs2_dec->fref[refnum] = &avs2_dec->frm_pool[refnum];
-
- /*//avs2_dec->fref[i] memory allocation*/
- if (is_avs2_print_bufmgr_detail())
- pr_info("[t] avs2_dec->fref[%d]@0x%p\n",
- refnum, avs2_dec->fref[refnum]);
- avs2_dec->fref[refnum]->imgcoi_ref = -257;
- avs2_dec->fref[refnum]->is_output = -1;
- avs2_dec->fref[refnum]->refered_by_others = -1;
- avs2_dec->fref[refnum]->
- imgtr_fwRefDistance = -256;
- init_frame_t(avs2_dec->fref[refnum]);
-#ifdef AML
- avs2_dec->fref[refnum]->index = refnum;
-#endif
- }
-#ifdef AML
- avs2_dec->f_bg = NULL;
-
- avs2_dec->m_bg = &avs2_dec->frm_pool[REF_MAXBUFFER];
- /*///avs2_dec->fref[i] memory allocation*/
- if (is_avs2_print_bufmgr_detail())
- pr_info("[t] avs2_dec->m_bg@0x%p\n",
- avs2_dec->m_bg);
- avs2_dec->m_bg->imgcoi_ref = -257;
- avs2_dec->m_bg->is_output = -1;
- avs2_dec->m_bg->refered_by_others = -1;
- avs2_dec->m_bg->imgtr_fwRefDistance = -256;
- init_frame_t(avs2_dec->m_bg);
- avs2_dec->m_bg->index = refnum;
-#endif
-
-#if BCBR
- /*init BCBR related*/
- img->iNumCUsInFrame =
- ((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
- * ((img->height + MAX_CU_SIZE - 1)
- / MAX_CU_SIZE);
- /*img->BLCUidx = (int32_t*) calloc(
- img->iNumCUsInFrame, sizeof(int32_t));*/
- /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/
-#endif
- return memory_size;
-}
-
-#ifdef AML
-static void free_unused_buffers(struct avs2_decoder *avs2_dec)
-{
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
-
- int32_t refnum;
-
- img->buf_cycle = input->buf_cycle + 1;
-
- img->buf_cycle *= 2;
-
- hc->background_ref = hc->backgroundReferenceFrame;
-
- for (refnum = 0; refnum < REF_MAXBUFFER; refnum++) {
-#ifndef NO_DISPLAY
- if (avs2_dec->fref[refnum]->vf_ref > 0 ||
- avs2_dec->fref[refnum]->to_prepare_disp)
- continue;
-#endif
- if (is_avs2_print_bufmgr_detail())
- pr_info("%s[t] avs2_dec->fref[%d]@0x%p\n",
- __func__, refnum, avs2_dec->fref[refnum]);
- avs2_dec->fref[refnum]->imgcoi_ref = -257;
- avs2_dec->fref[refnum]->is_output = -1;
- avs2_dec->fref[refnum]->refered_by_others = -1;
- avs2_dec->fref[refnum]->
- imgtr_fwRefDistance = -256;
- memset(avs2_dec->fref[refnum]->ref_poc, 0,
- sizeof(avs2_dec->fref[refnum]->ref_poc));
- }
- avs2_dec->f_bg = NULL;
-
- if (is_avs2_print_bufmgr_detail())
- pr_info("%s[t] avs2_dec->m_bg@0x%p\n",
- __func__, avs2_dec->m_bg);
- avs2_dec->m_bg->imgcoi_ref = -257;
- avs2_dec->m_bg->is_output = -1;
- avs2_dec->m_bg->refered_by_others = -1;
- avs2_dec->m_bg->imgtr_fwRefDistance = -256;
- memset(avs2_dec->m_bg->ref_poc, 0,
- sizeof(avs2_dec->m_bg->ref_poc));
-
-#if BCBR
- /*init BCBR related*/
- img->iNumCUsInFrame =
- ((img->width + MAX_CU_SIZE - 1) / MAX_CU_SIZE)
- * ((img->height + MAX_CU_SIZE - 1)
- / MAX_CU_SIZE);
- /*img->BLCUidx = (int32_t*) calloc(
- img->iNumCUsInFrame, sizeof(int32_t));*/
- /*memset( img->BLCUidx, 0, img->iNumCUsInFrame);*/
-#endif
-}
-#endif
-
-void init_frame_t(struct avs2_frame_s *currfref)
-{
- memset(currfref, 0, sizeof(struct avs2_frame_s));
- currfref->imgcoi_ref = -257;
- currfref->is_output = -1;
- currfref->refered_by_others = -1;
- currfref->imgtr_fwRefDistance = -256;
- memset(currfref->ref_poc, 0, sizeof(currfref->ref_poc));
-}
-
-void get_reference_list_info(struct avs2_decoder *avs2_dec, int8_t *str)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
-
- int8_t str_tmp[16];
- int32_t i;
- /* int32_t poc = hc->f_rec->imgtr_fwRefDistance;
- fred.chiu@mediatek.com*/
-
- if (img->num_of_references > 0) {
- strcpy(str, "[");
- for (i = 0; i < img->num_of_references; i++) {
-#if RD1510_FIX_BG
- if (img->type == B_IMG) {
- sprintf(str_tmp, "%4d ",
- hc->f_rec->
- ref_poc[
- img->num_of_references - 1 - i]);
- } else {
- sprintf(str_tmp, "%4d ",
- hc->f_rec->ref_poc[i]);
- }
-#else
- sprintf(str_tmp, "%4d ",
- avs2_dec->fref[i]->imgtr_fwRefDistance);
-#endif
-
- str_tmp[5] = '\0';
- strcat(str, str_tmp);
- }
- strcat(str, "]");
- } else {
- str[0] = '\0';
- }
-}
-
-void prepare_RefInfo(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
-
- int32_t i, j;
- int32_t ii;
- struct avs2_frame_s *tmp_fref;
-
- /*update IDR frame*/
- if (img->tr > hd->next_IDRtr && hd->curr_IDRtr != hd->next_IDRtr) {
- hd->curr_IDRtr = hd->next_IDRtr;
- hd->curr_IDRcoi = hd->next_IDRcoi;
- }
- /* re-order the ref buffer according to RPS*/
- img->num_of_references = hd->curr_RPS.num_of_ref;
-
-#if 1
- /*rain*/
- if (is_avs2_print_bufmgr_detail()) {
- pr_info("%s: coding_order is %d, curr_IDRcoi is %d\n",
- __func__, img->coding_order, hd->curr_IDRcoi);
- for (ii = 0; ii < MAXREF; ii++) {
- pr_info("ref_pic(%d)=%d\n",
- ii, hd->curr_RPS.ref_pic[ii]);
- }
- for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
- pr_info(
- "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d\n",
- ii, avs2_dec->fref[ii]->index,
- avs2_dec->fref[ii]->imgcoi_ref,
- avs2_dec->fref[ii]->imgtr_fwRefDistance);
- }
- }
-#endif
-
- for (i = 0; i < hd->curr_RPS.num_of_ref; i++) {
- /*int32_t accumulate = 0;*/
- /* copy tmp_fref from avs2_dec->fref[i] */
- tmp_fref = avs2_dec->fref[i];
-
-#if REMOVE_UNUSED
- for (j = i; j < avs2_dec->ref_maxbuffer; j++) {
- /*/////////////to be modified IDR*/
- if (avs2_dec->fref[j]->imgcoi_ref ==
- img->coding_order -
- hd->curr_RPS.ref_pic[i]) {
- break;
- }
- }
-#else
-
- for (j = i; j < avs2_dec->ref_maxbuffer; j++) {
- /*/////////////to be modified IDR*/
- int32_t k , tmp_tr;
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++) {
- if (((int32_t)img->coding_order -
- (int32_t)hd->curr_RPS.ref_pic[i]) ==
- avs2_dec->fref[k]->imgcoi_ref &&
- avs2_dec->fref[k]->imgcoi_ref >= -256) {
- break;
- }
- }
- if (k == avs2_dec->ref_maxbuffer) {
- tmp_tr =
- -1-1;
- } else {
- tmp_tr =
- avs2_dec->fref[k]->imgtr_fwRefDistance;
- }
- if (tmp_tr < hd->curr_IDRtr) {
- hd->curr_RPS.ref_pic[i] =
- img->coding_order - hd->curr_IDRcoi;
-
- for (k = 0; k < i; k++) {
- if (hd->curr_RPS.ref_pic[k] ==
- hd->curr_RPS.ref_pic[i]) {
- accumulate++;
- break;
- }
- }
- }
- if (avs2_dec->fref[j]->imgcoi_ref ==
- img->coding_order - hd->curr_RPS.ref_pic[i]) {
- break;
- }
- }
- if (j == avs2_dec->ref_maxbuffer || accumulate)
- img->num_of_references--;
-#endif
- if (j != avs2_dec->ref_maxbuffer) {
- /* copy avs2_dec->fref[i] from avs2_dec->fref[j] */
- avs2_dec->fref[i] = avs2_dec->fref[j];
- /* copy avs2_dec->fref[j] from ferf[tmp] */
- avs2_dec->fref[j] = tmp_fref;
- if (is_avs2_print_bufmgr_detail()) {
- pr_info("%s, switch %d %d: ", __func__, i, j);
- for (ii = 0; ii < hd->curr_RPS.num_of_ref
- || ii <= j; ii++)
- pr_info("%d ",
- avs2_dec->fref[ii]->index);
- pr_info("\n");
- }
- }
- }
- if (img->type == B_IMG &&
- (avs2_dec->fref[0]->imgtr_fwRefDistance <= img->tr
- || avs2_dec->fref[1]->imgtr_fwRefDistance >= img->tr)) {
-
- pr_info("wrong reference configuration for B frame\n");
- pr_info(
- "fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, img->tr %d\n",
- avs2_dec->fref[0]->imgtr_fwRefDistance,
- avs2_dec->fref[1]->imgtr_fwRefDistance,
- img->tr);
- hc->f_rec->error_mark = 1;
- avs2_dec->bufmgr_error_flag = 1;
- return; /* exit(-1);*/
- /*******************************************/
- }
-
-#if !FIX_PROFILE_LEVEL_DPB_RPS_1
- /* delete the frame that will never be used*/
- for (i = 0; i < hd->curr_RPS.num_to_remove; i++) {
- for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
- if (avs2_dec->fref[j]->imgcoi_ref >= -256
- && avs2_dec->fref[j]->imgcoi_ref
- == img->coding_order -
- hd->curr_RPS.remove_pic[i]) {
- break;
- }
- }
- if (j < avs2_dec->ref_maxbuffer &&
- j >= img->num_of_references) {
- avs2_dec->fref[j]->imgcoi_ref = -257;
-#if M3480_TEMPORAL_SCALABLE
- avs2_dec->fref[j]->temporal_id = -1;
-#endif
- if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->
- imgtr_fwRefDistance = -256;
- }
- }
- }
-#endif
-
- /* add inter-view reference picture*/
-
- /* add current frame to ref buffer*/
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref < -256
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128)
- && avs2_dec->fref[i]->is_output == -1
- && avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
- && avs2_dec->fref[i]->vf_ref == 0
- && avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
- ) {
- break;
- }
- }
- if (i == avs2_dec->ref_maxbuffer) {
- pr_info(
- "%s, warning, no enough buf\n",
- __func__);
- i--;
- }
-
- hc->f_rec = avs2_dec->fref[i];
- hc->currentFrame = hc->f_rec->ref;
- hc->f_rec->imgtr_fwRefDistance = img->tr;
- hc->f_rec->imgcoi_ref = img->coding_order;
-#if M3480_TEMPORAL_SCALABLE
- hc->f_rec->temporal_id = hd->cur_layer;
-#endif
- hc->f_rec->is_output = 1;
-#ifdef AML
- hc->f_rec->error_mark = 0;
- hc->f_rec->decoded_lcu = 0;
- hc->f_rec->slice_type = img->type;
-#endif
- hc->f_rec->refered_by_others = hd->curr_RPS.referd_by_others;
- if (is_avs2_print_bufmgr_detail())
- pr_info(
- "%s, set f_rec (cur_pic) <= fref[%d] img->tr %d coding_order %d img_type %d\n",
- __func__, i, img->tr, img->coding_order,
- img->type);
-
- if (img->type != B_IMG) {
- for (j = 0;
- j < img->num_of_references; j++) {
- hc->f_rec->ref_poc[j] =
- avs2_dec->fref[j]->imgtr_fwRefDistance;
- }
- } else {
- hc->f_rec->ref_poc[0] =
- avs2_dec->fref[1]->imgtr_fwRefDistance;
- hc->f_rec->ref_poc[1] =
- avs2_dec->fref[0]->imgtr_fwRefDistance;
- }
-
-#if M3480_TEMPORAL_SCALABLE
-
- for (j = img->num_of_references;
- j < 4; j++) {
- /**/
- hc->f_rec->ref_poc[j] = 0;
- }
-
- if (img->type == INTRA_IMG) {
- int32_t l;
- for (l = 0; l < 4; l++) {
- hc->f_rec->ref_poc[l]
- = img->tr;
- }
- }
-
-#endif
-
-/*////////////////////////////////////////////////////////////////////////*/
- /* updata ref pointer*/
-
- if (img->type != I_IMG) {
-
- img->imgtr_next_P = img->type == B_IMG ?
- avs2_dec->fref[0]->imgtr_fwRefDistance : img->tr;
- if (img->type == B_IMG) {
- hd->trtmp = avs2_dec->fref[0]->imgtr_fwRefDistance;
- avs2_dec->fref[0]->imgtr_fwRefDistance =
- avs2_dec->fref[1]->imgtr_fwRefDistance;
- }
- }
-#if 1
- /*rain*/
- if (is_avs2_print_bufmgr_detail()) {
- for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
- pr_info(
- "fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, is_out %d, bg %d, vf_ref %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
- ii, avs2_dec->fref[ii]->index,
- avs2_dec->fref[ii]->imgcoi_ref,
- avs2_dec->fref[ii]->imgtr_fwRefDistance,
- avs2_dec->fref[ii]->refered_by_others,
- avs2_dec->fref[ii]->is_output,
- avs2_dec->fref[ii]->bg_flag,
- avs2_dec->fref[ii]->vf_ref,
- avs2_dec->fref[ii]->ref_poc[0],
- avs2_dec->fref[ii]->ref_poc[1],
- avs2_dec->fref[ii]->ref_poc[2],
- avs2_dec->fref[ii]->ref_poc[3],
- avs2_dec->fref[ii]->ref_poc[4],
- avs2_dec->fref[ii]->ref_poc[5],
- avs2_dec->fref[ii]->ref_poc[6]
- );
- }
- }
-#endif
-}
-
-int32_t init_frame(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
-
-
-#if RD1510_FIX_BG
- if (img->type == I_IMG &&
- img->typeb == BACKGROUND_IMG) { /*G/GB frame*/
- img->num_of_references = 0;
- } else if (img->type == P_IMG && img->typeb == BP_IMG) {
- /* only one reference frame(G\GB) for S frame*/
- img->num_of_references = 1;
- }
-#endif
-
- if (img->typeb == BACKGROUND_IMG &&
- hd->background_picture_output_flag == 0) {
- hc->currentFrame = hc->background_ref;
-#ifdef AML
- hc->cur_pic = avs2_dec->m_bg;
-#endif
- } else {
- prepare_RefInfo(avs2_dec);
-#ifdef AML
- hc->cur_pic = hc->f_rec;
-#endif
- }
-
-
-#ifdef FIX_CHROMA_FIELD_MV_BK_DIST
- if (img->typeb == BACKGROUND_IMG
- && img->is_field_sequence) {
- avs2_dec->bk_img_is_top_field
- = img->is_top_field;
- }
-#endif
- return 0;
-}
-
-void delete_trbuffer(struct outdata_s *data, int32_t pos)
-{
- int32_t i;
- for (i = pos;
- i < data->buffer_num - 1; i++) {
- data->stdoutdata[i] =
- data->stdoutdata[i + 1];
- }
- data->buffer_num--;
-}
-
-#if RD170_FIX_BG
-void flushDPB(struct avs2_decoder *avs2_dec)
-{
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- int j, tmp_min, i, pos = -1;
- int search_times = avs2_dec->outprint.buffer_num;
-
- tmp_min = 1 << 20;
- i = 0, j = 0;
- pos = -1;
-
- for (j = 0; j < search_times; j++) {
- pos = -1;
- tmp_min = (1 << 20);
- /*search for min poi picture to display*/
- for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
- if (avs2_dec->outprint.stdoutdata[i].tr < tmp_min) {
- pos = i;
- tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
- }
- }
-
- if (pos != -1) {
- hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
- report_frame(avs2_dec, &avs2_dec->outprint, pos);
- if (avs2_dec->outprint.stdoutdata[pos].typeb
- == BACKGROUND_IMG &&
- avs2_dec->outprint.stdoutdata[pos].
- background_picture_output_flag
- == 0) {
- /*write_GB_frame(hd->p_out_background);*/
- } else {
- write_frame(avs2_dec,
- avs2_dec->outprint.stdoutdata[pos].tr);
- }
-
- delete_trbuffer(&avs2_dec->outprint, pos);
- }
- }
-
- /*clear dpb info*/
- for (j = 0; j < REF_MAXBUFFER; j++) {
- avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
- avs2_dec->fref[j]->imgcoi_ref = -257;
- avs2_dec->fref[j]->temporal_id = -1;
- avs2_dec->fref[j]->refered_by_others = 0;
- }
-}
-#endif
-
-
-
-#if M3480_TEMPORAL_SCALABLE
-void cleanRefMVBufRef(int pos)
-{
-#if 0
- int k, x, y;
- /*re-init mvbuf*/
- for (k = 0; k < 2; k++) {
- for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) {
- for (x = 0; x < img->width / MIN_BLOCK_SIZE; x++)
- fref[pos]->mvbuf[y][x][k] = 0;
-
- }
- }
- /*re-init refbuf*/
- for (y = 0; y < img->height / MIN_BLOCK_SIZE; y++) {
- for (x = 0; x < img->width / MIN_BLOCK_SIZE ; x++)
- fref[pos]->refbuf[y][x] = -1;
-
- }
-#endif
-}
-#endif
-
-static int frame_postprocessing(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
-
- int32_t pointer_tmp = avs2_dec->outprint.buffer_num;
- int32_t i;
- struct STDOUT_DATA_s *p_outdata;
-#if RD160_FIX_BG
- int32_t j, tmp_min, output_cur_dec_pic, pos = -1;
- int32_t search_times = avs2_dec->outprint.buffer_num;
-#endif
- /*pic dist by Grandview Semi. @ [06-07-20 15:25]*/
- img->PrevPicDistanceLsb = (img->coding_order % 256);
-
- pointer_tmp = avs2_dec->outprint.buffer_num;
- p_outdata = &avs2_dec->outprint.stdoutdata[pointer_tmp];
-
- p_outdata->type = img->type;
- p_outdata->typeb = img->typeb;
- p_outdata->framenum = img->tr;
- p_outdata->tr = img->tr;
-#if 0 /*def ORI*/
- p_outdata->qp = img->qp;
-#else
- p_outdata->qp = 0;
-#endif
- /*p_outdata->snr_y = snr->snr_y;*/
- /*p_outdata->snr_u = snr->snr_u;*/
- /*p_outdata->snr_v = snr->snr_v;*/
- p_outdata->tmp_time = hd->tmp_time;
- p_outdata->picture_structure = img->picture_structure;
- /*p_outdata->curr_frame_bits =
- StatBitsPtr->curr_frame_bits;*/
- /*p_outdata->emulate_bits = StatBitsPtr->emulate_bits;*/
-#if RD1501_FIX_BG
- p_outdata->background_picture_output_flag
- = hd->background_picture_output_flag;
- /*Longfei.Wang@mediatek.com*/
-#endif
-
-#if RD160_FIX_BG
- p_outdata->picture_reorder_delay = hd->picture_reorder_delay;
-#endif
- avs2_dec->outprint.buffer_num++;
-
-#if RD170_FIX_BG
- search_times = avs2_dec->outprint.buffer_num;
-#endif
- /* record the reference list*/
- strcpy(p_outdata->str_reference_list, hc->str_list_reference);
-
-#if !REF_OUTPUT
- #error "!!!REF_OUTPUT should be 1"
- for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
- min_tr(avs2_dec->outprint, &pos);
- if (avs2_dec->outprint.stdoutdata[pos].tr < img->tr
- || avs2_dec->outprint.stdoutdata[pos].tr
- == (hd->last_output + 1)) {
- hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
- report_frame(avs2_dec, &avs2_dec->outprint, pos);
-#if 0 /*def ORI*/
- write_frame(hd->p_out,
- avs2_dec->outprint.stdoutdata[pos].tr);
-#endif
- delete_trbuffer(&avs2_dec->outprint, pos);
- i--;
- } else {
- break;
- }
- }
-#else
-#if RD160_FIX_BG /*Longfei.Wang@mediatek.com*/
- tmp_min = 1 << 20;
- i = 0, j = 0;
- output_cur_dec_pic = 0;
- pos = -1;
- for (j = 0; j < search_times; j++) {
- pos = -1;
- tmp_min = (1 << 20);
- /*search for min poi picture to display*/
- for (i = 0; i < avs2_dec->outprint.buffer_num; i++) {
- if ((avs2_dec->outprint.stdoutdata[i].tr < tmp_min) &&
- ((avs2_dec->outprint.stdoutdata[i].tr
- + avs2_dec->outprint.stdoutdata[i].
- picture_reorder_delay)
- <= (int32_t)img->coding_order)) {
- pos = i;
- tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
- }
- }
-
- if ((0 == hd->displaydelay) && (0 == output_cur_dec_pic)) {
- if (img->tr <= tmp_min) {/*fred.chiu@mediatek.com*/
- /*output current decode picture
- right now*/
- pos = avs2_dec->outprint.buffer_num - 1;
- output_cur_dec_pic = 1;
- }
- }
- if (pos != -1) {
- hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
- report_frame(avs2_dec, &avs2_dec->outprint, pos);
-#if 1 /*def ORI*/
- if (avs2_dec->outprint.stdoutdata[pos].typeb
- == BACKGROUND_IMG &&
- avs2_dec->outprint.stdoutdata[pos].
- background_picture_output_flag == 0) {
- /**/
- /**/
- } else {
- write_frame(avs2_dec,
- avs2_dec->outprint.stdoutdata[pos].tr);
- }
-#endif
- delete_trbuffer(&avs2_dec->outprint, pos);
- }
-
- }
-
-#else
- #error "!!!RD160_FIX_BG should be defined"
- if (img->coding_order +
- (uint32_t)hc->total_frames * 256 >=
- (uint32_t)hd->picture_reorder_delay) {
- int32_t tmp_min, pos = -1;
- tmp_min = 1 << 20;
-
- for (i = 0; i <
- avs2_dec->outprint.buffer_num; i++) {
- if (avs2_dec->outprint.stdoutdata[i].tr
- < tmp_min &&
- avs2_dec->outprint.stdoutdata[i].tr
- >= hd->last_output) {
- /*GB has the same "tr" with "last_output"*/
- pos = i;
- tmp_min =
- avs2_dec->outprint.stdoutdata[i].tr;
- }
- }
-
- if (pos != -1) {
- hd->last_output = avs2_dec->outprint.stdoutdata[pos].tr;
- report_frame(avs2_dec, &avs2_dec->outprint, pos);
-#if RD1501_FIX_BG
- if (avs2_dec->outprint.stdoutdata[pos].typeb
- == BACKGROUND_IMG && avs2_dec->
- outprint.stdoutdata[pos].
- background_picture_output_flag == 0) {
-#else
- if (avs2_dec->outprint.stdoutdata[pos].typeb
- == BACKGROUND_IMG &&
- hd->background_picture_output_flag
- == 0) {
-#endif
- write_GB_frame(
- hd->p_out_background);
- } else {
- write_frame(avs2_dec,
- avs2_dec->outprint.stdoutdata[pos].tr);
- }
- delete_trbuffer(&avs2_dec->outprint, pos);
-
- }
-
- }
-#endif
-#endif
- return pos;
-
- }
-
-void write_frame(struct avs2_decoder *avs2_dec, int32_t pos)
-{
- int32_t j;
-
- if (is_avs2_print_bufmgr_detail())
- pr_info("%s(pos = %d)\n", __func__, pos);
-
- for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
- if (avs2_dec->fref[j]->imgtr_fwRefDistance == pos) {
- avs2_dec->fref[j]->imgtr_fwRefDistance_bak = pos;
- avs2_dec->fref[j]->is_output = -1;
- avs2_dec->fref[j]->to_prepare_disp =
- avs2_dec->to_prepare_disp_count++;
- if (avs2_dec->fref[j]->refered_by_others == 0
- || avs2_dec->fref[j]->imgcoi_ref
- == -257) {
- avs2_dec->fref[j]->imgtr_fwRefDistance
- = -256;
- avs2_dec->fref[j]->imgcoi_ref = -257;
-#if M3480_TEMPORAL_SCALABLE
- avs2_dec->fref[j]->temporal_id = -1;
-#endif
- if (is_avs2_print_bufmgr_detail())
- pr_info("%s, fref index %d\n",
- __func__, j);
- }
- break;
- }
- }
-}
-
-/*rain???, outdata *data*/
-void report_frame(struct avs2_decoder *avs2_dec,
- struct outdata_s *data, int32_t pos)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
-
- int8_t *Frmfld;
- int8_t Frm[] = "FRM";
- int8_t Fld[] = "FLD";
- struct STDOUT_DATA_s *p_stdoutdata
- = &data->stdoutdata[pos];
- const int8_t *typ;
-
-#if 0
- if (input->MD5Enable & 0x02) {
- sprintf(MD5str, "%08X%08X%08X%08X\0",
- p_stdoutdata->DecMD5Value[0],
- p_stdoutdata->DecMD5Value[1],
- p_stdoutdata->DecMD5Value[2],
- p_stdoutdata->DecMD5Value[3]);
- } else {
- memset(MD5val, 0, 16);
- memset(MD5str, 0, 33);
- }
-#endif
-
- if (p_stdoutdata->
- picture_structure) {
- Frmfld = Frm;
- } else {
- Frmfld = Fld;
- }
-#if INTERLACE_CODING
- if (img->is_field_sequence) { /*rcs??*/
- Frmfld = Fld;
- }
-#endif
- if ((p_stdoutdata->tr + hc->total_frames * 256)
- == hd->end_SeqTr) { /* I picture*/
- /*if ( img->new_sequence_flag == 1 )*/
- {
- img->sequence_end_flag = 0;
- /*fprintf(stdout, "Sequence
- End\n\n");*/
- }
- }
- if ((p_stdoutdata->tr + hc->total_frames * 256)
- == hd->next_IDRtr) {
-#if !RD170_FIX_BG
- if (hd->vec_flag) /**/
-#endif
- {
- hd->vec_flag = 0;
- /*fprintf(stdout, "Video Edit
- Code\n");*/
- }
- }
-
- if (p_stdoutdata->typeb == BACKGROUND_IMG) {
- typ = (hd->background_picture_output_flag != 0) ? "G" : "GB";
- } else {
-#if REMOVE_UNUSED
- typ = (p_stdoutdata->type == INTRA_IMG)
- ? "I" : (p_stdoutdata->type == INTER_IMG) ?
- ((p_stdoutdata->typeb == BP_IMG) ? "S" : "P")
- : (p_stdoutdata->type == F_IMG ? "F" : "B");
-#else
- typ = (p_stdoutdata->type == INTRA_IMG) ? "I" :
- (p_stdoutdata->type == INTER_IMG) ?
- ((p_stdoutdata->type == BP_IMG) ? "S" : "P")
- : (p_stdoutdata->type == F_IMG ? "F" : "B");
-#endif
- }
-
-#if 0
- /*rain???*/
- pr_info("%3d(%s) %3d %5d %7.4f %7.4f %7.4f %5d\t\t%s %8d %6d\t%s",
- p_stdoutdata->framenum + hc->total_frames * 256,
- typ, p_stdoutdata->tr + hc->total_frames * 256,
- p_stdoutdata->qp, p_stdoutdata->snr_y,
- p_stdoutdata->snr_u, p_stdoutdata->snr_v,
- p_stdoutdata->tmp_time, Frmfld,
- p_stdoutdata->curr_frame_bits,
- p_stdoutdata->emulate_bits,
- "");
-#endif
- if (is_avs2_print_bufmgr_detail())
- pr_info(" %s\n", p_stdoutdata->str_reference_list);
-
- /*fflush(stdout);*/
- hd->FrameNum++;
-}
-
-void avs2_prepare_header(struct avs2_decoder *avs2_dec, int32_t start_code)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
-
- switch (start_code) {
- case SEQUENCE_HEADER_CODE:
- img->new_sequence_flag = 1;
- if (is_avs2_print_bufmgr_detail())
- pr_info("SEQUENCE\n");
-#ifdef TO_CHECK
-#if SEQ_CHANGE_CHECKER
- if (seq_checker_buf == NULL) {
- seq_checker_buf = malloc(length);
- seq_checker_length = length;
- memcpy(seq_checker_buf, Buf, length);
- } else {
- if ((seq_checker_length != length) ||
- (memcmp(seq_checker_buf, Buf, length) != 0)) {
- free(seq_checker_buf);
- /*fprintf(stdout,
- "Non-conformance
- stream: sequence
- header cannot change
- !!\n");*/
-#if RD170_FIX_BG
- seq_checker_buf = NULL;
- seq_checker_length = 0;
- seq_checker_buf = malloc(length);
- seq_checker_length = length;
- memcpy(seq_checker_buf, Buf, length);
-#endif
- }
-
-
- }
-#endif
-#if RD170_FIX_BG
- if (input->alf_enable
- && alfParAllcoated == 1) {
- ReleaseAlfGlobalBuffer();
- alfParAllcoated = 0;
- }
-#endif
-/*TO_CHECK*/
-#endif
-#if FIX_FLUSH_DPB_BY_LF
- if (hd->vec_flag) {
- int32_t k;
- if (is_avs2_print_bufmgr_detail())
- pr_info("vec_flag is 1, flushDPB and reinit bugmgr\n");
-
- flushDPB(avs2_dec);
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
-
- hd->vec_flag = 0;
-#ifdef AML
- free_unused_buffers(avs2_dec);
-#else
- free_global_buffers(avs2_dec);
-#endif
- img->number = 0;
- img->PrevPicDistanceLsb = 0;
- avs2_dec->init_hw_flag = 0;
- }
-#endif
-
-#if FIX_SEQ_END_FLUSH_DPB_BY_LF
- if (img->new_sequence_flag
- && img->sequence_end_flag) {
- int32_t k;
- if (is_avs2_print_bufmgr_detail())
- pr_info(
- "new_sequence_flag after sequence_end_flag, flushDPB and reinit bugmgr\n");
- flushDPB(avs2_dec);
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
-
-#ifdef AML
- free_unused_buffers(avs2_dec);
-#else
- free_global_buffers(avs2_dec);
-#endif
- img->number = 0;
- img->PrevPicDistanceLsb = 0;
- avs2_dec->init_hw_flag = 0;
- }
-#endif
- img->seq_header_indicate = 1;
- break;
- case I_PICTURE_START_CODE:
- if (is_avs2_print_bufmgr_detail())
- pr_info("PIC-I\n");
- Get_SequenceHeader(avs2_dec);
- Get_I_Picture_Header(avs2_dec);
- calc_picture_distance(avs2_dec);
- Read_ALF_param(avs2_dec);
- if (!img->seq_header_indicate) {
- img->B_discard_flag = 1;
- /*fprintf(stdout, " I
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- break;
- }
- break;
- case PB_PICTURE_START_CODE:
- if (is_avs2_print_bufmgr_detail())
- pr_info("PIC-PB\n");
- Get_SequenceHeader(avs2_dec);
- Get_PB_Picture_Header(avs2_dec);
- calc_picture_distance(avs2_dec);
- Read_ALF_param(avs2_dec);
- /* xiaozhen zheng, 20071009*/
- if (!img->seq_header_indicate) {
- img->B_discard_flag = 1;
-
- if (img->type == P_IMG) {
- /*fprintf(stdout, " P
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- }
- if (img->type == F_IMG) {
- /*fprintf(stdout, " F
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- } else {
- /*fprintf(stdout, " B
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- }
-
- break;
- }
-
- if (img->seq_header_indicate == 1
- && img->type != B_IMG) {
- img->B_discard_flag = 0;
- }
- if (img->type == B_IMG && img->B_discard_flag == 1
- && !img->random_access_decodable_flag) {
- /*fprintf(stdout, " B
- %3d\t\tDIDSCARD!!\n",
- img->tr);*/
- break;
- }
-
- break;
- case SEQUENCE_END_CODE:
- if (is_avs2_print_bufmgr_detail())
- pr_info("SEQUENCE_END_CODE\n");
-#ifdef TO_CHECK
-#if SEQ_CHANGE_CHECKER
- if (seq_checker_buf != NULL) {
- free(seq_checker_buf);
- seq_checker_buf = NULL;
- seq_checker_length = 0;
- }
-#endif
-#endif
-img->new_sequence_flag = 1;
-img->sequence_end_flag = 1;
-break;
- case VIDEO_EDIT_CODE:
- if (is_avs2_print_bufmgr_detail())
- pr_info("VIDEO_EDIT_CODE\n");
- /*video_edit_code_data(Buf, startcodepos, length);*/
- hd->vec_flag = 1;
-#ifdef TO_CHECK
-#if SEQ_CHANGE_CHECKER
- if (seq_checker_buf != NULL) {
- free(seq_checker_buf);
- seq_checker_buf = NULL;
- seq_checker_length = 0;
- }
-#endif
-#endif
-
-break;
- }
-}
-
-#ifdef AML
-static uint32_t log2i(uint32_t val)
-{
- uint32_t ret = -1;
- while (val != 0) {
- val >>= 1;
- ret++;
- }
- return ret;
-}
-#endif
-
-int32_t avs2_process_header(struct avs2_decoder *avs2_dec)
-{
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- int32_t lcu_x_num_div;
- int32_t lcu_y_num_div;
-
- int32_t N8_SizeScale;
- /*pr_info("%s\n", __func__);*/
- {
- N8_SizeScale = 1;
-
- if (hd->horizontal_size %
- (MIN_CU_SIZE * N8_SizeScale) != 0) {
- img->auto_crop_right =
- (MIN_CU_SIZE * N8_SizeScale) -
- (hd->horizontal_size %
- (MIN_CU_SIZE * N8_SizeScale));
- } else
- img->auto_crop_right = 0;
-
-#if !INTERLACE_CODING
- if (hd->progressive_sequence) /**/
-#endif
- {
- if (hd->vertical_size %
- (MIN_CU_SIZE * N8_SizeScale) != 0) {
- img->auto_crop_bottom =
- (MIN_CU_SIZE * N8_SizeScale) -
- (hd->vertical_size %
- (MIN_CU_SIZE * N8_SizeScale));
- } else
- img->auto_crop_bottom = 0;
- }
-
- /* Reinit parameters (NOTE: need to do
- before init_frame //*/
- img->width =
- (hd->horizontal_size + img->auto_crop_right);
- img->height =
- (hd->vertical_size + img->auto_crop_bottom);
- img->width_cr = (img->width >> 1);
-
- if (input->chroma_format == 1)
- img->height_cr = (img->height >> 1);
-
- img->PicWidthInMbs = img->width / MIN_CU_SIZE;
- img->PicHeightInMbs = img->height / MIN_CU_SIZE;
- img->PicSizeInMbs = img->PicWidthInMbs * img->PicHeightInMbs;
- img->max_mb_nr = (img->width * img->height) /
- (MIN_CU_SIZE * MIN_CU_SIZE);
- }
-
- if (img->new_sequence_flag && img->sequence_end_flag) {
-#if 0/*RD170_FIX_BG //*/
- int32_t k;
- flushDPB();
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
-
- free_global_buffers();
- img->number = 0;
-#endif
- hd->end_SeqTr = img->tr;
- img->sequence_end_flag = 0;
- }
- if (img->new_sequence_flag) {
- hd->next_IDRtr = img->tr;
- hd->next_IDRcoi = img->coding_order;
- img->new_sequence_flag = 0;
- }
-#if 0/*RD170_FIX_BG*/
- if (hd->vec_flag) {
- int32_t k;
- flushDPB();
- for (k = 0; k < avs2_dec->ref_maxbuffer; k++)
- cleanRefMVBufRef(k);
-
- hd->vec_flag = 0;
- free_global_buffers();
- img->number = 0;
- }
-#endif
-/* allocate memory for frame buffers*/
-#if 0
-/* called in vavs2.c*/
- if (img->number == 0)
- avs2_init_global_buffers(avs2_dec);
-#endif
- img->current_mb_nr = 0;
-
- init_frame(avs2_dec);
-
- img->types = img->type; /* jlzheng 7.15*/
-
- if (img->type != B_IMG) {
- hd->pre_img_type = img->type;
- hd->pre_img_types = img->types;
- }
-
-#ifdef AML
- avs2_dec->lcu_size_log2 = log2i(avs2_dec->lcu_size);
- lcu_x_num_div = (img->width/avs2_dec->lcu_size);
- lcu_y_num_div = (img->height/avs2_dec->lcu_size);
- avs2_dec->lcu_x_num = ((img->width % avs2_dec->lcu_size) == 0) ?
- lcu_x_num_div : lcu_x_num_div+1;
- avs2_dec->lcu_y_num = ((img->height % avs2_dec->lcu_size) == 0) ?
- lcu_y_num_div : lcu_y_num_div+1;
- avs2_dec->lcu_total = avs2_dec->lcu_x_num*avs2_dec->lcu_y_num;
-#endif
- return SOP;
-}
-
-int avs2_post_process(struct avs2_decoder *avs2_dec)
-{
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- int32_t i;
- int ret;
- if (img->typeb == BACKGROUND_IMG && hd->background_picture_enable) {
-#ifdef AML
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if (avs2_dec->fref[i]->bg_flag != 0) {
- avs2_dec->fref[i]->bg_flag = 0;
- if (is_avs2_print_bufmgr_detail())
- pr_info(
- "clear old BACKGROUND_IMG for index %d\r\n",
- avs2_dec->fref[i]->index);
- }
- }
- if (is_avs2_print_bufmgr_detail())
- pr_info(
- "post_process: set BACKGROUND_IMG flag for %d\r\n",
- hc->cur_pic->index);
- avs2_dec->f_bg = hc->cur_pic;
- hc->cur_pic->bg_flag = 1;
-#endif
- }
-
-#if BCBR
- if (hd->background_picture_enable
- && hd->bcbr_enable && img->number > 0)
- updateBgReference();
-#endif
-
- if (img->typeb == BACKGROUND_IMG &&
- hd->background_picture_output_flag == 0)
- hd->background_number++;
-
- if (img->type == B_IMG) {
- avs2_dec->fref[0]->imgtr_fwRefDistance
- = hd->trtmp;
- }
-
- /* record the reference list information*/
- get_reference_list_info(avs2_dec, avs2_dec->hc.str_list_reference);
-
- /*pr_info("%s\n", __func__);*/
- ret = frame_postprocessing(avs2_dec);
-
-#if FIX_PROFILE_LEVEL_DPB_RPS_1
- /* delete the frame that will never be used*/
- {
- int32_t i, j;
- if (is_avs2_print_bufmgr_detail()) {
- pr_info(
- "%s, coding_order %d to remove %d buf: ",
- __func__,
- img->coding_order,
- hd->curr_RPS.num_to_remove);
- for (i = 0; i < hd->curr_RPS.num_to_remove; i++)
- pr_info("%d ", hd->curr_RPS.remove_pic[i]);
- pr_info("\n");
- }
- for (i = 0; i < hd->curr_RPS.num_to_remove; i++) {
- for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
-
- if (avs2_dec->fref[j]->imgcoi_ref >= -256
- && avs2_dec->fref[j]->imgcoi_ref ==
- img->coding_order -
- hd->curr_RPS.remove_pic[i])
- break;
- }
- if (j < avs2_dec->ref_maxbuffer) { /**/
-#if FIX_RPS_PICTURE_REMOVE
-/* Label new frames as "un-referenced" */
- avs2_dec->fref[j]->refered_by_others = 0;
-
- /* remove frames which have been outputted */
- if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->
- imgtr_fwRefDistance = -256;
- avs2_dec->fref[j]->imgcoi_ref = -257;
- avs2_dec->fref[j]->temporal_id = -1;
-
- }
-#else
- avs2_dec->fref[j]->imgcoi_ref = -257;
-#if M3480_TEMPORAL_SCALABLE
- avs2_dec->fref[j]->temporal_id = -1;
-#endif
- if (avs2_dec->fref[j]->is_output == -1) {
- avs2_dec->fref[j]->imgtr_fwRefDistance
- = -256;
- }
-#endif
- }
- }
- }
-#endif
-
-
- /*! TO 19.11.2001 Known Problem: for init_frame
- * we have to know the picture type of the
- * actual frame*/
- /*! in case the first slice of the P-Frame
- * following the I-Frame was lost we decode this
- * P-Frame but! do not write it because it
- * was
- * assumed to be an I-Frame in init_frame.So we
- * force the decoder to*/
- /*! guess the right picture type. This is a hack
- * a should be removed by the time there is a
- * clean*/
- /*! solution where we do not have to know the
- * picture type for the function init_frame.*/
- /*! End TO 19.11.2001//Lou*/
-
- {
- if (img->type == I_IMG ||
- img->type == P_IMG ||
- img->type == F_IMG)
- img->number++;
- else {
- hc->Bframe_ctr++; /* B
- pictures*/
- }
- }
- return ret;
-}
-
-void init_avs2_decoder(struct avs2_decoder *avs2_dec)
-{
- int32_t i, j, k;
-
- struct inp_par *input = &avs2_dec->input;
- struct ImageParameters_s *img = &avs2_dec->img;
- struct Video_Com_data_s *hc = &avs2_dec->hc;
- struct Video_Dec_data_s *hd = &avs2_dec->hd;
- if (is_avs2_print_bufmgr_detail())
- pr_info("[t] struct avs2_dec @0x%p\n", avs2_dec);
- memset(avs2_dec, 0, sizeof(struct avs2_decoder));
-#ifdef AML
- avs2_dec->to_prepare_disp_count = 1;
-#endif
- /*
- * ALFParam init
- */
- for (i = 0; i < 3; i++) {
- avs2_dec->m_alfPictureParam[i].alf_flag = 0; /*1*/
- avs2_dec->m_alfPictureParam[i].num_coeff = 9; /*1*/
- avs2_dec->m_alfPictureParam[i].filters_per_group = 3; /*1*/
- avs2_dec->m_alfPictureParam[i].componentID = i; /*1*/
- for (j = 0; j < 16; j++) {
- avs2_dec->m_alfPictureParam[i].filterPattern[j] = 0;
- /*16*/
- }
- for (j = 0; j < 16; j++) {
- for (k = 0; k < 9; k++) {
- avs2_dec->
- m_alfPictureParam[i].coeffmulti[j][k] = 0;
- /*16*9*/
- }
- }
- }
-
- img->seq_header_indicate = 0;
- img->B_discard_flag = 0;
-
- hd->eos = 0;
-
- if (input->ref_pic_order) { /*ref order*/
- hd->dec_ref_num = 0;
- }
-
- /*
- memset(g_log2size, -1, MAX_CU_SIZE + 1);
- c = 2;
- for (k = 4; k <= MAX_CU_SIZE; k *= 2) {
- g_log2size[k] = c;
- c++;
- }
- */
-
- avs2_dec->outprint.buffer_num = 0;
-
- hd->last_output = -1;
- hd->end_SeqTr = -1;
- hd->curr_IDRtr = 0;
- hd->curr_IDRcoi = 0;
- hd->next_IDRtr = 0;
- hd->next_IDRcoi = 0;
- /* Allocate Slice data struct*/
- img->number = 0;
- img->type = I_IMG;
-
- img->imgtr_next_P = 0;
-
- img->imgcoi_next_ref = 0;
-
-
- img->num_of_references = 0;
- hc->seq_header = 0;
-
- img->new_sequence_flag = 1;
-
- hd->vec_flag = 0;
-
- hd->FrameNum = 0;
-
- /* B pictures*/
- hc->Bframe_ctr = 0;
- hc->total_frames = 0;
-
- /* time for total decoding session*/
- hc->tot_time = 0;
-
-}
-
diff --git a/drivers/frame_provider/decoder_v4l/avs2/avs2_global.h b/drivers/frame_provider/decoder_v4l/avs2/avs2_global.h
deleted file mode 100644
index d9f85bd..0000000
--- a/drivers/frame_provider/decoder_v4l/avs2/avs2_global.h
+++ /dev/null
@@ -1,1687 +0,0 @@
-/* The copyright in this software is being made available under the BSD
- * License, included below. This software may be subject to other third party
- * and contributor rights, including patent rights, and no such rights are
- * granted under this license.
- *
- * Copyright (c) 2002-2016, Audio Video coding Standard Workgroup of China
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of Audio Video coding Standard Workgroup of China
- * nor the names of its contributors maybe
- * used to endorse or promote products
- * derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-
-/*
- * File name: global.h
- * Function: global definitions for for AVS decoder.
- *
- */
-
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-
-/* #include <stdio.h> //!< for FILE */
-/* #include <stdlib.h> */
-
-#define AML
-#define SANITY_CHECK
-#undef NO_DISPLAY
-
-/* #include "define.h" */
-#define RD "19.2"
-#define VERSION "19.2"
-
-#define RESERVED_PROFILE_ID 0x24
-#define BASELINE_PICTURE_PROFILE 18
-#define BASELINE_PROFILE 32 /* 0x20 */
-#define BASELINE10_PROFILE 34 /* 0x22 */
-
-
-#define SCENE_PROFILE 48 /* 0x21 */
-#define SCENE10_PROFILE 50 /* 0x23 */
-
-#define TRACE 0 /* !< 0:Trace off 1:Trace on */
-
-
-/* Type definitions and file operation for Windows/Linux
- * All file operations for windows are replaced with native (FILE *) operations
- * Falei LUO (falei.luo@vipl.ict.ac.cn)
- * */
-
-#define _FILE_OFFSET_BITS 64 /* for 64 bit fseeko */
-#define fseek fseeko
-
-#define int16 int16_t
-#define int64 int64_t
-
-/* ////////////////// bug fix ///////////////////////////// */
-#define ALFSliceFix 1
-#define WRITENBIT_FIX 1
-#define FIX_PROFILE_LEVEL_DPB_RPS_1 1
-#define FIX_PROFILE_LEVEL_DPB_RPS_2 1
-#define FIX_RPS_PICTURE_REMOVE 1 /* flluo@pku.edu.cn */
-#define Mv_Clip 1 /* yuquanhe@hisilicon.com */
-#define REMOVE_UNUSED 1 /* yuquanhe@hisilicon.com */
-#define SAO_Height_Fix 1 /* yuquanhe@hisilicon.com */
-#define B_BACKGROUND_Fix 1 /* yuquanhe@hisilicon.com */
-#define Check_Bitstream 1 /* yuquanhe@hisilicon.com */
-#define Wq_param_Clip 1 /* yuquanhe@hisilicon.com */
- /* luofalei flluo@pku.edu.cn , wlq15@mails.tsinghua.edu.cn ,
- Longfei.Wang@mediatek.com */
-#define RD1501_FIX_BG 1
- /* yuquanhe@hisilicon.com ; he-yuan.lin@mstarsemi.com */
-#define Mv_Rang 1
- /* Longfei.Wang@mediatek.com ;fred.chiu@mediatek.com
- jie1222.chen@samsung.com */
-#define RD160_FIX_BG 1
- /* Y_K_Tu@novatek.com.tw, he-yuan.lin@mstarsemi.com,
- victor.huang@montage-tech.com M4041 */
-#define RD1601_FIX_BG 1
-#define SEQ_CHANGE_CHECKER 1 /* he-yuan.lin@mstarsemi.com */
-#define M4140_END_OF_SLICE_CHECKER 1 /* he-yuan.lin@mstarsemi.com */
- /* wlq15@mails.tsinghua.edu.cn */
-#define Mv_check_bug 1
-#define SAO_ASSERTION_FIX 1 /* fred.chiu@mediatek.com */
-#define FIELD_HORI_MV_NO_SCALE_FIX 1 /* fred.chiu@mediatek.com */
-#define RD170_FIX_BG 1
-#define FIX_CHROMA_FIELD_MV_BK_DIST 1
-#define FIX_LUMA_FIELD_MV_BK_DIST 1
-#define FIX_CHROMA_FIELD_MV_CLIP 1
-#if 1
-#define FIX_FLUSH_DPB_BY_LF 1 /* fred.chiu@mediatek.com */
-#define FIX_SEQ_END_FLUSH_DPB_BY_LF 1 /* fred.chiu@mediatek.com */
-#else
-#define FIX_FLUSH_DPB_BY_LF 0 /* fred.chiu@mediatek.com */
-#define FIX_SEQ_END_FLUSH_DPB_BY_LF 0 /* fred.chiu@mediatek.com */
-#endif
-#define RD191_FIX_BUG 1 /* yuquanhe@hsilicon.com */
-#define SYM_MV_SCALE_FIX 1/* peisong.chen@broadcom.com */
-#define BUG_10BIT_REFINEQP 0 /* wangzhenyu */
-
-
-
-#if RD191_FIX_BUG
-#endif
-
-/************************
- * AVS2 macros start
- **************************/
-
-#define INTERLACE_CODING 1
-#if INTERLACE_CODING /* M3531: MV scaling compensation */
-/* Luma component */
-#define HALF_PIXEL_COMPENSATION 1 /* common functions definition */
-#define HALF_PIXEL_COMPENSATION_PMV 1 /* spacial MV prediction */
-#define HALF_PIXEL_COMPENSATION_DIRECT 1 /* B direct mode */
- /* MV derivation method 1, weighted P_skip mode */
-#define HALF_PIXEL_COMPENSATION_M1 1
- /* M1 related with mv-scaling function */
-#define HALF_PIXEL_COMPENSATION_M1_FUCTION 1
-#define HALF_PIXEL_COMPENSATION_MVD 1 /* MV scaling from FW->BW */
-/* Chroma components */
- /* chroma MV is scaled with luma MV for 4:2:0 format */
-#define HALF_PIXEL_CHROMA 1
- /* half pixel compensation for p skip/direct */
-#define HALF_PIXEL_PSKIP 1
-#define INTERLACE_CODING_FIX 1 /* HLS fix */
-#define OUTPUT_INTERLACE_MERGED_PIC 1
-
-#endif
-/*
- *******************************
-AVS2 10bit/12bit profile
- ********************************
- */
-
-#define DBFIX_10bit 1
-
-#define BUG_10bit 1
-
-/*
- ***************************************
-AVS2 HIGH LEVEL SYNTAX
- ***************************************
- */
-#define AVS2_HDR_HLS 1
- /* AVS2 HDR technology //yuquanhe@hisilicon.com */
-#define AVS2_HDR_Tec 1
-#if AVS2_HDR_Tec
-#define HDR_CHROMA_DELTA_QP 1 /* M3905 */
-#define HDR_ADPTIVE_UV_DELTA 1
-#endif
-/*
- *************************************
-AVS2 S2
- *************************************
- */
-#define AVS2_S2_FASTMODEDECISION 1
-#define RD1510_FIX_BG 1 /* 20160714, flluo@pku.edu.cn */
-
-
-/* ////////////////// prediction techniques ///////////////////////////// */
-#define LAM_2Level_TU 0.8
-
-
-#define DIRECTION 4
-#define DS_FORWARD 4
-#define DS_BACKWARD 2
-#define DS_SYM 3
-#define DS_BID 1
-
-#define MH_PSKIP_NUM 4
-#define NUM_OFFSET 0
-#define BID_P_FST 1
-#define BID_P_SND 2
-#define FW_P_FST 3
-#define FW_P_SND 4
-#define WPM_NUM 3
- /* M3330 changes it to 2, the original value is 3 */
-#define MAX_MVP_CAND_NUM 2
-
-#define DMH_MODE_NUM 5 /* Number of DMH mode */
-#define TH_ME 0 /* Threshold of ME */
-
-#define MV_SCALE 1
-
-/* ///// reference picture management // */
-#define FIX_MAX_REF 1 /* Falei LUO, flluo@pku.edu.cn */
-#if FIX_MAX_REF
- /* maximum number of reference frame for each frame */
-#define MAXREF 7
-#define MAXGOP 32
-#endif
-
-/* #define REF_MAXBUFFER 7 */
-/* more bufferes for displaying and background */
-/* #define REF_MAXBUFFER 15 */
-#if 1
-#define REF_MAXBUFFER 23
-#define REF_BUFFER 16
-#else
-#if RD170_FIX_BG
-#define REF_MAXBUFFER 16
-#else
-#define REF_MAXBUFFER 7
-#endif
-#endif
-
-#ifdef TO_PORTING
- /* block-composed background reference, fangdong@mail.ustc.edu.cn */
-#define BCBR 1
-#else
-#define BCBR 0
-#endif
-/* one more buffer for background when background_picture_output_flag is 0*/
-#define AVS2_MAX_BUFFER_NUM (REF_MAXBUFFER + 1)
-
-/* /////////////////Adaptive Loop Filter////////////////////////// */
-#define NUM_ALF_COEFF_CTX 1
-#define NUM_ALF_LCU_CTX 4
-
-#define LAMBDA_SCALE_LUMA (1.0)
-#define LAMBDA_SCALE_CHROMA (1.0)
-
-
-
-/* ////////////////// entropy coding ///////////////////////////// */
- /* M3090: Make sure rs1 will not overflow for 8-bit unsign char */
-#define NUN_VALUE_BOUND 254
-#define Encoder_BYPASS_Final 1 /* M3484 */
-#define Decoder_Bypass_Annex 0 /* M3484 */
-#define Decoder_Final_Annex 0 /* M3540 */
-
-
-/* ////////////////// coefficient coding ///// */
- /* M3035 size of an coefficient group, 4x4 */
-#define CG_SIZE 16
-
-#define SWAP(x, y) {\
- (y) = (y) ^ (x);\
- (x) = (y) ^ (x);\
- (y) = (x) ^ (y);\
-}
-
-/* ////////////////// encoder optimization /////// */
-#define TH 2
-
-#define M3624MDLOG /* reserved */
-
-#define TDRDO 1 /* M3528 */
-/* #define FIX_TDRDO_BG 1 // flluo@pku.edu.cn, 20160318// */
-#define RATECONTROL 1 /* M3580 M3627 M3689 */
-#define AQPO 1 /* M3623 */
-#define AQPOM3694 0
-#define AQPOM4063 1
-#define AQPOM3762 1
-#define BGQPO 1 /* M4061 */
-#if BGQPO
-#define LONGREFERENCE 32
-#endif
-
-/* #define REPORT */
-/* ////////////////// Quantization /////////////////////////////////////// */
- /* Adaptive frequency weighting quantization */
-#define FREQUENCY_WEIGHTING_QUANTIZATION 1
-#if FREQUENCY_WEIGHTING_QUANTIZATION
-#define CHROMA_DELTA_QP 1
-#define AWQ_WEIGHTING 1
-#define AWQ_LARGE_BLOCK_ENABLE 1
-#define COUNT_BIT_OVERHEAD 0
-#define AWQ_LARGE_BLOCK_EXT_MAPPING 1
-#endif
-
-#define QuantClip 1
-#define QuantMatrixClipFix 1 /* 20160418, fllu@pku.edu.cn */
-
-#define WQ_MATRIX_FCD 1
-#if !WQ_MATRIX_FCD
-#define WQ_FLATBASE_INBIT 7
-#else
-#define WQ_FLATBASE_INBIT 6
-#endif
-
-
-#define REFINED_QP 1
-
-
-/* ////////////////// delta QP ///// */
- /* M3122: the minimum dQP unit is Macro block */
-#define MB_DQP 1
- /* M3122: 1 represents left prediction
- and 0 represents previous prediction */
-#define LEFT_PREDICTION 1
-
-
-/* //////////////////////SAO///////// */
-#define NUM_BO_OFFSET 32
-#define MAX_NUM_SAO_CLASSES 32
-#define NUM_SAO_BO_CLASSES_LOG2 5
-#define NUM_SAO_BO_CLASSES_IN_BIT 5
-#define MAX_DOUBLE (1.7e + 308)
-#define NUM_SAO_EO_TYPES_LOG2 2
-#define NUM_SAO_BO_CLASSES (1<<NUM_SAO_BO_CLASSES_LOG2)
-#define SAO_RATE_THR 0.75
-#define SAO_RATE_CHROMA_THR 1
-#define SAO_SHIFT_PIX_NUM 4
-
-#define SAO_PARA_CROSS_SLICE 1
-#define SAO_MULSLICE_FTR_FIX 1
-
-/* /////////////////// Transform ///////////////////// */
-#define SEC_TR_SIZE 4
- /* apply secT to greater than or equal to 8x8 block, */
-#define SEC_TR_MIN_BITSIZE 3
-
-#define BUGFIXED_COMBINED_ST_BD 1
-
-/* /////////////////// Scalable ///////////////////// */
-#define M3480_TEMPORAL_SCALABLE 1
-#define TEMPORAL_MAXLEVEL 8
-#define TEMPORAL_MAXLEVEL_BIT 3
-
-
-
-
-/*
- *************************************
- * AVS2 macros end
- *
- *************************************
- */
-
-#define CHROMA 1
-#define LUMA_8x8 2
-#define NUM_BLOCK_TYPES 8
-
-#if (!defined clamp)
- /* !< clamp a to the range of [b;c] */
-#define clamp(a, b, c) ((a) < (b) ? (b) : ((a) > (c) ? (c) : (a)))
-#endif
-
- /* POC200301 moved from defines.h */
-#define LOG2_MAX_FRAME_NUM_MINUS4 4
- /* !< bytes for one frame */
-#define MAX_CODED_FRAME_SIZE 15000000
-
-/* ----------------------- */
-/* FLAGS and DEFINES for new chroma intra prediction, Dzung Hoang */
-/* Threshold values to zero out quantized transform coefficients. */
-/* Recommend that _CHROMA_COEFF_COST_ be low to improve chroma quality */
-#define _LUMA_COEFF_COST_ 4 /* !< threshold for luma coeffs */
- /* !< Number of pixels padded around the reference frame (>=4) */
-#define IMG_PAD_SIZE 64
-
-#define OUTSTRING_SIZE 255
-
- /* !< abs macro, faster than procedure */
-#define absm(A) ((A) < (0) ? (-(A)) : (A))
- /* !< used for start value for some variables */
-#define MAX_VALUE 999999
-
-#define Clip1(a) ((a) > 255 ? 255:((a) < 0 ? 0 : (a)))
-#define Clip3(min, max, val) (((val) < (min)) ?\
- (min) : (((val) > (max)) ? (max) : (val)))
-
-/* --------------------------------------------- */
-
-/* block size of block transformed by AVS */
-#define PSKIPDIRECT 0
-#define P2NX2N 1
-#define P2NXN 2
-#define PNX2N 3
-#define PHOR_UP 4
-#define PHOR_DOWN 5
-#define PVER_LEFT 6
-#define PVER_RIGHT 7
-#define PNXN 8
-#define I8MB 9
-#define I16MB 10
-#define IBLOCK 11
-#define InNxNMB 12
-#define INxnNMB 13
-#define MAXMODE 14 /* add yuqh 20130824 */
-#define LAMBDA_ACCURACY_BITS 16
-#define LAMBDA_FACTOR(lambda) ((int)((double)(1 << LAMBDA_ACCURACY_BITS)\
- * lambda + 0.5))
-#define WEIGHTED_COST(factor, bits) (((factor) * (bits))\
- >> LAMBDA_ACCURACY_BITS)
-#define MV_COST(f, s, cx, cy, px, py) (WEIGHTED_COST(f, mvbits[((cx) << (s))\
- - px] + mvbits[((cy) << (s)) - py]))
-#define REF_COST(f, ref) (WEIGHTED_COST(f, refbits[(ref)]))
-
-#define BWD_IDX(ref) (((ref) < 2) ? 1 - (ref) : (ref))
-#define REF_COST_FWD(f, ref) (WEIGHTED_COST(f,\
- ((img->num_ref_pic_active_fwd_minus1 == 0) ?\
- 0 : refbits[(ref)])))
-#define REF_COST_BWD(f, ef) (WEIGHTED_COST(f,\
- ((img->num_ref_pic_active_bwd_minus1 == 0) ?\
- 0 : BWD_IDX(refbits[ref]))))
-
-#define IS_INTRA(MB) ((MB)->cuType == I8MB ||\
- (MB)->cuType == I16MB ||\
- (MB)->cuType == InNxNMB || (MB)->cuType == INxnNMB)
-#define IS_INTER(MB) ((MB)->cuType != I8MB &&\
- (MB)->cuType != I16MB && (MB)->cuType != InNxNMB\
- && (MB)->cuType != INxnNMB)
-#define IS_INTERMV(MB) ((MB)->cuType != I8MB &&\
- (MB)->cuType != I16MB && (MB)->cuType != InNxNMB &&\
- (MB)->cuType != INxnNMB && (MB)->cuType != 0)
-
-
-#define IS_DIRECT(MB) ((MB)->cuType == PSKIPDIRECT && (img->type == B_IMG))
-#define IS_P_SKIP(MB) ((MB)->cuType == PSKIPDIRECT &&\
- (((img->type == F_IMG)) || ((img->type == P_IMG))))
-#define IS_P8x8(MB) ((MB)->cuType == PNXN)
-
-/* Quantization parameter range */
-#define MIN_QP 0
-#define MAX_QP 63
-#define SHIFT_QP 11
-
-/* Picture types */
-#define INTRA_IMG 0 /* !< I frame */
-#define INTER_IMG 1 /* !< P frame */
-#define B_IMG 2 /* !< B frame */
-#define I_IMG 0 /* !< I frame */
-#define P_IMG 1 /* !< P frame */
-#define F_IMG 4 /* !< F frame */
-
-#define BACKGROUND_IMG 3
-
-#define BP_IMG 5
-
-
-/* Direct Mode types */
-#define MIN_CU_SIZE 8
-#define MIN_BLOCK_SIZE 4
-#define MIN_CU_SIZE_IN_BIT 3
-#define MIN_BLOCK_SIZE_IN_BIT 2
-#define BLOCK_MULTIPLE (MIN_CU_SIZE/(MIN_BLOCK_SIZE))
-#define MAX_CU_SIZE 64
-#define MAX_CU_SIZE_IN_BIT 6
-#define B4X4_IN_BIT 2
-#define B8X8_IN_BIT 3
-#define B16X16_IN_BIT 4
-#define B32X32_IN_BIT 5
-#define B64X64_IN_BIT 6
- /* !< # luma intra prediction modes */
-#define NUM_INTRA_PMODE 33
- /* number of luma modes for full RD search */
-#define NUM_MODE_FULL_RD 9
- /* !< #chroma intra prediction modes */
-#define NUM_INTRA_PMODE_CHROMA 5
-
-/* luma intra prediction modes */
-
-#define DC_PRED 0
-#define PLANE_PRED 1
-#define BI_PRED 2
-#define VERT_PRED 12
-#define HOR_PRED 24
-
-
-/* chroma intra prediction modes */
-#define DM_PRED_C 0
-#define DC_PRED_C 1
-#define HOR_PRED_C 2
-#define VERT_PRED_C 3
-#define BI_PRED_C 4
-
-#define EOS 1 /* !< End Of Sequence */
- /* !< Start Of Picture */
-#define SOP 2
-
-#define DECODING_OK 0
-#define SEARCH_SYNC 1
-#define DECODE_MB 1
-
-#ifndef max
- /* !< Macro returning max value */
-#define max(a, b) ((a) > (b) ? (a) : (b))
- /* !< Macro returning min value */
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-
-#define XY_MIN_PMV 1
-#if XY_MIN_PMV
-#define MVPRED_xy_MIN 0
-#else
-#define MVPRED_MEDIAN 0
-#endif
-#define MVPRED_L 1
-#define MVPRED_U 2
-#define MVPRED_UR 3
-
-#define DUAL 4
-#define FORWARD 0
-#define BACKWARD 1
-#define SYM 2
-#define BID 3
-#define INTRA -1
-
-#define BUF_CYCLE 5
-
-#define ROI_M3264 1 /* ROI Information Encoding */
-
-#define PicExtensionData 1
-
-
-#define REF_OUTPUT 1 /* M3337 */
-
-
-/* MV scaling 14 bit */
-#define MULTI 16384
-#define HALF_MULTI 8192
-#define OFFSET 14
-/* end of MV scaling */
- /* store the middle pixel's mv in a motion information unit */
-#define MV_DECIMATION_FACTOR 4
-
-/* BUGFIX_AVAILABILITY_INTRA */
-#define NEIGHBOR_INTRA_LEFT 0
-#define NEIGHBOR_INTRA_UP 1
-#define NEIGHBOR_INTRA_UP_RIGHT 2
-#define NEIGHBOR_INTRA_UP_LEFT 3
-#define NEIGHBOR_INTRA_LEFT_DOWN 4
-/* end of BUGFIX_AVAILABILITY_INTRA */
-
-/* end #include "define.h" */
-
-/*#include "commonStructures.h"*/
-
-/*typedef uint16_t byte;*/ /* !< byte type definition */
-#define byte uint16_t
-#define pel_t byte
-
-enum BitCountType_e {
- BITS_HEADER,
- BITS_TOTAL_MB,
- BITS_MB_MODE,
- BITS_INTER_MB,
- BITS_CBP_MB,
- BITS_CBP01_MB,
- BITS_COEFF_Y_MB,
- BITS_COEFF_UV_MB,
- BITS_DELTA_QUANT_MB,
- BITS_SAO_MB,
- MAX_BITCOUNTER_MB
-};
-
-
-enum SAOEOClasses {
-/* EO Groups, the assignments depended on
-how you implement the edgeType calculation */
- SAO_CLASS_EO_FULL_VALLEY = 0,
- SAO_CLASS_EO_HALF_VALLEY = 1,
- SAO_CLASS_EO_PLAIN = 2,
- SAO_CLASS_EO_HALF_PEAK = 3,
- SAO_CLASS_EO_FULL_PEAK = 4,
- SAO_CLASS_BO = 5,
- NUM_SAO_EO_CLASSES = SAO_CLASS_BO,
- NUM_SAO_OFFSET
-};
-
-struct SAOstatdata {
- int32_t diff[MAX_NUM_SAO_CLASSES];
- int32_t count[MAX_NUM_SAO_CLASSES];
-};
-
-struct CopyRight_s {
- int32_t extension_id;
- int32_t copyright_flag;
- int32_t copyright_id;
- int32_t original_or_copy;
- int32_t reserved;
- int32_t copyright_number;
-};
-
-struct CameraParamters_s {
- int32_t reserved;
- int32_t camera_id;
- int32_t height_of_image_device;
- int32_t focal_length;
- int32_t f_number;
- int32_t vertical_angle_of_view;
- int32_t camera_position_x;
- int32_t camera_position_y;
- int32_t camera_position_z;
- int32_t camera_direction_x;
- int32_t camera_direction_y;
- int32_t camera_direction_z;
- int32_t image_plane_vertical_x;
- int32_t image_plane_vertical_y;
- int32_t image_plane_vertical_z;
-};
-
-/* ! SNRParameters */
-struct SNRParameters_s {
- double snr_y; /* !< current Y SNR */
- double snr_u; /* !< current U SNR */
- double snr_v; /* !< current V SNR */
- double snr_y1; /* !< SNR Y(dB) first frame */
- double snr_u1; /* !< SNR U(dB) first frame */
- double snr_v1; /* !< SNR V(dB) first frame */
- double snr_ya; /* !< Average SNR Y(dB) remaining frames */
- double snr_ua; /* !< Average SNR U(dB) remaining frames */
- double snr_va; /* !< Average SNR V(dB) remaining frames */
-#if INTERLACE_CODING
- double i_snr_ya; /* !< current Y SNR */
- double i_snr_ua; /* !< current U SNR */
- double i_snr_va; /* !< current V SNR */
-#endif
-};
-
-/* signal to noise ratio parameters */
-
-/* ! codingUnit */
-struct codingUnit {
- uint32_t ui_MbBitSize;
- int32_t uiBitSize; /* size of MB */
- /* !< number of current syntax element */
- int32_t currSEnr;
- int32_t slice_nr;
- int32_t delta_quant; /* !< for rate control */
- int32_t delta_qp;
- int32_t qp;
- int32_t bitcounter[MAX_BITCOUNTER_MB];
- struct codingUnit
- *mb_available[3][3]; /*!< pointer to neighboring MBs
- in a 3x3 window of current MB, which is located at [1][1] \n
- NULL pointer identifies neighboring MBs which are unavailable */
- /* some storage of codingUnit syntax elements for global access */
- int32_t cuType;
- int32_t weighted_skipmode;
-
- int32_t md_directskip_mode;
-
- int32_t trans_size;
- int
- /* !< indices correspond to [forw,backw][block_y][block_x][x,y, dmh] */
- mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][3];
-
- int32_t intra_pred_modes[BLOCK_MULTIPLE * BLOCK_MULTIPLE];
- int32_t real_intra_pred_modes[BLOCK_MULTIPLE * BLOCK_MULTIPLE];
- int32_t l_ipred_mode;
- int32_t cbp, cbp_blk;
- uint32_t cbp_bits;
-
- int32_t b8mode[4];
- int32_t b8pdir[4];
- /* !< chroma intra prediction mode */
- int32_t c_ipred_mode;
-
- /* !< pointer to neighboring MB (AEC) */
- struct codingUnit *mb_available_up;
- /* !< pointer to neighboring MB (AEC) */
- struct codingUnit *mb_available_left;
- int32_t mbAddrA, mbAddrB, mbAddrC, mbAddrD;
- /* !<added by mz, 2008.04 */
- int32_t slice_set_index;
- /* added by mz, 2008.04 */
- int32_t slice_header_flag;
- int32_t sliceqp; /* added by mz, 2008.04 */
-#if MB_DQP
- int32_t previouse_qp;
- int32_t left_cu_qp;
-#endif
- int32_t block_available_up;
- int32_t block_available_left;
-
-};
-
-
-/* image parameters */
-struct syntaxelement;
-struct slice;
-struct alfdatapart;
-struct SAOBlkParam_s {
- int32_t modeIdc; /* NEW, MERGE, OFF */
- /* NEW: EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, above */
- int32_t typeIdc;
- int32_t startBand; /* BO: starting band index */
- int32_t startBand2;
- int32_t deltaband;
- int32_t offset[MAX_NUM_SAO_CLASSES];
-};
-struct ALFParam_s {
- int32_t alf_flag;
- int32_t num_coeff;
- int32_t filters_per_group;
- int32_t componentID;
- int32_t filterPattern[16]; /* *filterPattern; */
- int32_t coeffmulti[16][9]; /* **coeffmulti; */
-};
-
-enum ALFComponentID {
- ALF_Y = 0,
- ALF_Cb,
- ALF_Cr,
- NUM_ALF_COMPONENT
-};
-struct ALF_APS_s {
- int32_t usedflag;
- int32_t cur_number;
- int32_t max_number;
- struct ALFParam_s alf_par[NUM_ALF_COMPONENT];
-};
-
-
-/* ------------------------------------------------------
- * frame data
- */
-struct avs2_frame_s {
- int32_t imgcoi_ref;
- byte * *referenceFrame[3];
- int32_t **refbuf;
- int32_t ***mvbuf;
-#if 0
- double saorate[NUM_SAO_COMPONENTS];
-#endif
- byte ***ref;
-
- int32_t imgtr_fwRefDistance;
- int32_t refered_by_others;
- int32_t is_output;
- int32_t to_prepare_disp;
-#if M3480_TEMPORAL_SCALABLE
- /* temporal level setted in configure file */
- int32_t temporal_id;
-#endif
- byte **oneForthRefY;
-#if FIX_MAX_REF
- int32_t ref_poc[MAXREF];
-#else
- int32_t ref_poc[4];
-#endif
-#ifdef AML
- int32_t index;
- int32_t mmu_alloc_flag;
- int32_t lcu_size_log2;
- /*uint32_t header_adr;*/
- uint32_t mc_y_adr;
- uint32_t mc_u_v_adr;
- uint32_t mc_canvas_y;
- uint32_t mc_canvas_u_v;
- uint32_t mpred_mv_wr_start_addr;
- uint8_t bg_flag;
- /**/
- unsigned long header_adr;
- int buf_size;
- int lcu_total;
- int comp_body_size;
- uint32_t dw_y_adr;
- uint32_t dw_u_v_adr;
- int y_canvas_index;
- int uv_canvas_index;
- struct canvas_config_s canvas_config[2];
- int double_write_mode;
- int bit_depth;
- unsigned long cma_alloc_addr;
- int BUF_index;
- int pic_w;
- int pic_h;
- int stream_offset;
- u32 pts;
- u64 pts64;
- /**/
- int vf_ref;
- int decode_idx;
- int slice_type;
- int32_t imgtr_fwRefDistance_bak;
- int32_t error_mark;
- int32_t decoded_lcu;
-#endif
-#ifndef MV_USE_FIXED_BUF
- int mv_buf_index;
-#endif
-
- /* picture qos infomation*/
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
-
- u32 hw_decode_time;
- u32 frame_size; // For frame base mode
-
- char *cuva_data_buf;
- int cuva_data_size;
-};
-
-
-struct ImageParameters_s {
- struct codingUnit *mb_data;
- int32_t number; /* <! frame number */
- int32_t numIPFrames;
-
- int32_t type;
- int32_t typeb;
- int32_t typeb_before;
-
- int32_t qp; /* <! quant for the current frame */
- int32_t current_mb_nr; /* bitstream order */
- int32_t current_slice_nr;
- int32_t tr; /* <! temporal reference, 8 bit, */
-
- int32_t width; /* !< Number of pels */
- int32_t width_cr; /* !< Number of pels chroma */
- int32_t height; /* !< Number of lines */
- int32_t height_cr; /* !< Number of lines chroma */
- int32_t PicWidthInMbs;
- int32_t PicSizeInMbs;
- int32_t block8_x, block8_y;
- int32_t subblock_x;
- int32_t subblock_y;
-
- int32_t num_of_references;
- /* <! Bug Fix: correct picture size for outputted reconstructed pictures */
- int32_t auto_crop_right;
- int32_t auto_crop_bottom;
- int32_t buf_cycle;
- int32_t picture_structure;
- /* <! pointer to current Slice data struct */
- struct slice *currentSlice;
-
- int32_t **predBlock; /* !< current best prediction mode */
- int32_t **predBlockTmp;
- /* !< the diff pixel values between orginal image and prediction */
- int32_t **resiY;
- /* !< Array containing square values,used for snr computation */
- int32_t *quad;
-
- /* //location of current MB////// */
- int32_t mb_y; /* !< current MB vertical */
- int32_t mb_x; /* !< current MB horizontal */
- int32_t pix_y; /* !< current pixel vertical */
- int32_t pix_x; /* !< current pixel horizontal */
- int32_t pix_c_y; /* !< current pixel chroma vertical */
- int32_t pix_c_x; /* !< current pixel chroma horizontal */
-
- int32_t imgtr_next_P;
-
- int32_t imgcoi_next_ref;
-
- /* !< GH ipredmode[90][74];prediction mode for inter frames */
- /* fix from ver 4.1 */
- int32_t **ipredmode;
- int32_t **rec_ipredmode;
-
-
- /* //////////////decoder////////////////////////// */
- int32_t max_mb_nr;
- int32_t **intra_block;
-
- int32_t block_y;
- int32_t block_x;
- /* <! final 4x4 block. Extended to 16x16 for AVS */
- int32_t resiUV[2][MAX_CU_SIZE][MAX_CU_SIZE];
-
- int32_t **fw_refFrArr; /* <! [72][88]; */
- int32_t **bw_refFrArr; /* <! [72][88]; */
-
- int32_t random_access_decodable_flag;
-
- int32_t seq_header_indicate;
- int32_t B_discard_flag;
-
- /* B pictures */
- uint32_t pic_distance;
-
- uint32_t coding_order;
-
- uint32_t PrevPicDistanceLsb;
- int32_t CurrPicDistanceMsb;
-
- int32_t PicHeightInMbs;
-
- int32_t types;
-
- int32_t new_sequence_flag;
- int32_t sequence_end_flag; /* <! rm52k_r2 */
-
- int32_t current_slice_set_index; /* <! added by mz, 2008.04 */
- int32_t current_slice_header_flag; /* <! added by mz, 2008.04 */
- int32_t slice_set_qp[64]; /* <! added by mz, 2008.04 */
-
-
- int32_t inter_amp_enable;
-
- /* ////////////////////////encoder////////////////////////// */
-
- /* int32_t nb_references; //!< replaced by "num_of_references" */
-
- int32_t framerate;
-
- int32_t ***predBlockY; /* !< all 9 prediction modes */
- /* !< new chroma 8x8 intra prediction modes */
- int32_t ****predBlockUV;
-
- int32_t **Coeff_all;/* qyu 0821 */
-
- struct syntaxelement *MB_SyntaxElements; /* !< by oliver 0612 */
-
- /* B pictures */
-
- int32_t b_frame_to_code;
- int32_t num_ref_pic_active_fwd_minus1;
- int32_t num_ref_pic_active_bwd_minus1;
- int32_t mv_range_flag;
-
- uint32_t frame_num; /* frame_num for this frame */
- int32_t slice_offset;
- /* the following are sent in the slice header */
- int32_t NoResidueDirect;
- int32_t coded_mb_nr;
- int32_t progressive_frame;
- int32_t tc_reserve_bit;
- /* the last MB no in current slice. Yulj 2004.07.15 */
- int32_t mb_no_currSliceLastMB;
- int32_t Seqheader_flag; /* Added by cjw, 20070327 */
- int32_t EncodeEnd_flag; /* Carmen, 2007/12/19 */
-
- uint16_t bbv_delay;
-
- int32_t tmp_fwBSkipMv[DIRECTION + 1][2];
- int32_t tmp_bwBSkipMv[DIRECTION + 1][2];
-
- int32_t tmp_pref_fst[MH_PSKIP_NUM + NUM_OFFSET + 1];
- int32_t tmp_pref_snd[MH_PSKIP_NUM + NUM_OFFSET + 1];
- int32_t tmp_fstPSkipMv[MH_PSKIP_NUM + NUM_OFFSET + 1][3];
- int32_t tmp_sndPSkipMv[MH_PSKIP_NUM + NUM_OFFSET + 1][3];
-#if BCBR
-byte *org_ref_y;
-byte *org_ref_u;
-byte *org_ref_v;
-int32_t *BLCUidx;
-int32_t *DQPList;
-int32_t iNumCUsInFrame;
-
-byte *org_ref2_y;
-byte *org_ref2_u;
-byte *org_ref2_v;
-int32_t ref2Num;
-#endif
-/* //////////////SAO parameter////////////////// */
-double *cur_saorate;
-#if 0
-int32_t slice_sao_on[NUM_SAO_COMPONENTS];
-#endif
-int32_t pic_alf_on[NUM_ALF_COMPONENT];
-struct alfdatapart *dp_ALF;
-
-#if INTERLACE_CODING
-int32_t is_field_sequence;
-int32_t is_top_field;
-#endif
-
-
-};
-
-
-
-/* ! struct for context management */
-struct BiContextType_s {
- uint8_t MPS; /* 1 bit */
- uint32_t LG_PMPS; /* 10 bits */
- uint8_t cycno; /* 2 bits */
-};
-
-/***********************************************************************
- * D a t a t y p e s f o r A E C
- ************************************************************************/
-
-
-
-struct pix_pos {
- int32_t available; /* ABCD */
- int32_t mb_addr; /* MB position */
- int32_t x;
- int32_t y;
- int32_t pos_x; /* 4x4 x-pos */
- int32_t pos_y;
-};
-
-
-
-struct STDOUT_DATA_s {
- int32_t type;
- int32_t typeb;
-
- int32_t framenum;
- int32_t tr;
- int32_t qp;
- double snr_y;
- double snr_u;
- double snr_v;
- int32_t tmp_time;
- int32_t picture_structure;
- int32_t curr_frame_bits;
- int32_t emulate_bits;
-
- uint32_t DecMD5Value[4];
-#if RD1501_FIX_BG
-int32_t background_picture_output_flag;/* Longfei.Wang@mediatek.com */
-#endif
-#if RD160_FIX_BG
-int32_t picture_reorder_delay;
-#endif
-int8_t str_reference_list[128]; /* reference list information */
-};
-
-/**********************************************************************
- * C O N T E X T S F O R T M L S Y N T A X E L E M E N T S
- **********************************************************************
- */
-#define NUM_CuType_CTX (11 + 10)
-#define NUM_B8_TYPE_CTX 9
-#define NUM_MVD_CTX 15
-#define NUM_PMV_IDX_CTX 10
-#define NUM_REF_NO_CTX 6
-#define NUM_DELTA_QP_CTX 4
-#define NUM_INTER_DIR_CTX 18
-#define NUM_INTER_DIR_DHP_CTX 3
-#define NUM_B8_TYPE_DHP_CTX 1
-#define NUM_AMP_CTX 2
-#define NUM_C_INTRA_MODE_CTX 4
-#define NUM_CBP_CTX 4
-#define NUM_BCBP_CTX 4
-#define NUM_MAP_CTX 17
-#define NUM_LAST_CTX 17
-
-#define NUM_INTRA_MODE_CTX 7
-
-#define NUM_ABS_CTX 5
-#define NUM_TU_CTX 3
-#define NUM_SPLIT_CTX 8 /* CU depth */
-#if BCBR
-#define NUM_BGBLCOK_CTX 1
-#endif
-
-#define NUM_BRP_CTX 8
-
-
-#define NUM_LAST_CG_CTX_LUMA 12
-#define NUM_LAST_CG_CTX_CHROMA 6
-#define NUM_SIGCG_CTX_LUMA 2
-#define NUM_SIGCG_CTX_CHROMA 1
-#define NUM_LAST_POS_CTX_LUMA 56
-#define NUM_LAST_POS_CTX_CHROMA 16
-#define NUM_LAST_CG_CTX (NUM_LAST_CG_CTX_LUMA + NUM_LAST_CG_CTX_CHROMA)
-#define NUM_SIGCG_CTX (NUM_SIGCG_CTX_LUMA + NUM_SIGCG_CTX_CHROMA)
-#define NUM_LAST_POS_CTX (NUM_LAST_POS_CTX_LUMA + NUM_LAST_POS_CTX_CHROMA)
-#define NUM_SAO_MERGE_FLAG_CTX 3
-#define NUM_SAO_MODE_CTX 1
-#define NUM_SAO_OFFSET_CTX 2
-#define NUM_INTER_DIR_MIN_CTX 2
-
-/*end #include "commonStructures.h"*/
-
-/*#include "commonVariables.h"*/
-
-/*
-extern struct CameraParamters_s *camera;
-extern struct SNRParameters_s *snr;
-extern struct ImageParameters_s *img;
- */
-
-/* avs2_frame_t *fref[REF_MAXBUFFER]; */
-
-
-#define ET_SIZE 300 /* !< size of error text buffer */
-
-
-/* ------------------------------------------------------
- * common data
- */
-struct Video_Com_data_s {
- int32_t Bframe_ctr;
-
- /* FILE *p_log; //!< SNR file */
- /* FILE *p_trace; //!< Trace file */
-
- int32_t tot_time;
-
- /* Tsinghua for picture_distance 200701 */
- int32_t picture_distance;
-
- /* M3178 PKU Reference Manage */
- int32_t coding_order;
- /* !< current encoding/decoding frame pointer */
- struct avs2_frame_s *f_rec;
- int32_t seq_header;
- /* !< Array for reference frames of each block */
- int32_t **refFrArr;
- int32_t **p_snd_refFrArr;
-
- byte ***currentFrame; /* [yuv][height][width] */
-#ifdef AML
- struct avs2_frame_s *cur_pic; /*either f_rec or m_bg*/
-#endif
- byte **backgroundReferenceFrame[3];
- byte ***background_ref;
-
-
- int32_t total_frames;
-
- /* mv_range, 20071009 */
- int32_t Min_V_MV;
- int32_t Max_V_MV;
- int32_t Min_H_MV;
- int32_t Max_H_MV;
- /* !< buffer for error message for exit with error(void) */
- int8_t errortext[ET_SIZE];
- int8_t str_list_reference[128];
-
-
-};
-/* extern Video_Com_data *hc; */
-
-
-/*end #include "commonVariables.h"*/
-/* #define USE_PARAM_TXT */
-/*
-#if FIX_CHROMA_FIELD_MV_BK_DIST
-int8_t bk_img_is_top_field;
-#endif
-*/
-/* void write_GB_frame(FILE *p_dec); */
-
-#if !FIX_MAX_REF
-#define MAXREF 4
-#define MAXGOP 32
-#endif
-
-struct StatBits {
- int32_t curr_frame_bits;
- int32_t prev_frame_bits;
- int32_t emulate_bits;
- int32_t prev_emulate_bits;
- int32_t last_unit_bits;
- int32_t bitrate;
- int32_t total_bitrate[1000];
- int32_t coded_pic_num;
- int32_t time_s;
-};
-
-struct reference_management {
- int32_t poc;
- int32_t qp_offset;
- int32_t num_of_ref;
- int32_t referd_by_others;
- int32_t ref_pic[MAXREF];
- int32_t predict;
- int32_t deltaRPS;
- int32_t num_to_remove;
- int32_t remove_pic[MAXREF];
-};
-
-
-/* ------------------------------------------------------
- * dec data
- */
-struct Video_Dec_data_s {
- byte **background_frame[3];
- int32_t background_reference_enable;
-
- int32_t background_picture_flag;
- int32_t background_picture_output_flag;
- int32_t background_picture_enable;
-
- int32_t background_number;
-
-#if BCBR
- int32_t bcbr_enable;
-#endif
-
- int32_t demulate_enable;
- int32_t currentbitoffset;
-
- int32_t aspect_ratio_information;
- int32_t frame_rate_code;
- int32_t bit_rate_lower;
- int32_t bit_rate_upper;
- int32_t marker_bit;
-
- int32_t video_format;
- int32_t color_description;
- int32_t color_primaries;
- int32_t transfer_characteristics;
- int32_t matrix_coefficients;
-
- int32_t progressive_sequence;
-#if INTERLACE_CODING
-int32_t is_field_sequence;
-#endif
-int32_t low_delay;
-int32_t horizontal_size;
-int32_t vertical_size;
-int32_t sample_precision;
-int32_t video_range;
-
-int32_t display_horizontal_size;
-int32_t display_vertical_size;
-int32_t TD_mode;
-int32_t view_packing_mode;
-int32_t view_reverse;
-
-int32_t b_pmvr_enabled;
-int32_t dhp_enabled;
-int32_t b_dmh_enabled;
-int32_t b_mhpskip_enabled;
-int32_t wsm_enabled;
-int32_t b_secT_enabled;
-
-int32_t tmp_time;
-int32_t FrameNum;
-int32_t eos;
-int32_t pre_img_type;
-int32_t pre_img_types;
-/* int32_t pre_str_vec; */
-int32_t pre_img_tr;
-int32_t pre_img_qp;
-int32_t pre_tmp_time;
-int32_t RefPicExist; /* 20071224 */
-int32_t BgRefPicExist;
-int32_t dec_ref_num; /* ref order */
-
-/* video edit code */ /* M1956 by Grandview 2006.12.12 */
-int32_t vec_flag;
-
-/* Copyright_extension(void) header */
-int32_t copyright_flag;
-int32_t copyright_identifier;
-int32_t original_or_copy;
-int64_t copyright_number_1;
-int64_t copyright_number_2;
-int64_t copyright_number_3;
-/* Camera_parameters_extension */
-int32_t camera_id;
-int32_t height_of_image_device;
-int32_t focal_length;
-int32_t f_number;
-int32_t vertical_angle_of_view;
-int32_t camera_position_x_upper;
-int32_t camera_position_x_lower;
-int32_t camera_position_y_upper;
-int32_t camera_position_y_lower;
-int32_t camera_position_z_upper;
-int32_t camera_position_z_lower;
-int32_t camera_direction_x;
-int32_t camera_direction_y;
-int32_t camera_direction_z;
-int32_t image_plane_vertical_x;
-int32_t image_plane_vertical_y;
-int32_t image_plane_vertical_z;
-
-#if AVS2_HDR_HLS
-/* mastering_display_and_content_metadata_extension(void) header */
-int32_t display_primaries_x0;
-int32_t display_primaries_y0;
-int32_t display_primaries_x1;
-int32_t display_primaries_y1;
-int32_t display_primaries_x2;
-int32_t display_primaries_y2;
-int32_t white_point_x;
-int32_t white_point_y;
-int32_t max_display_mastering_luminance;
-int32_t min_display_mastering_luminance;
-int32_t maximum_content_light_level;
-int32_t maximum_frame_average_light_level;
-#endif
-
-/* I_pictures_header(void) */
-int32_t top_field_first;
-int32_t repeat_first_field;
-int32_t progressive_frame;
-#if INTERLACE_CODING
-int32_t is_top_field;
-#endif
-/* int32_t fixed_picture_qp; //qyu 0927 */
-int32_t picture_qp;
-int32_t fixed_picture_qp;
-int32_t time_code_flag;
-int32_t time_code;
-int32_t loop_filter_disable;
-int32_t loop_filter_parameter_flag;
-/* int32_t alpha_offset; */
-/* int32_t beta_offset; */
-
-/* Pb_picture_header(void) */
-int32_t picture_coding_type;
-
-/*picture_display_extension(void)*/
-int32_t frame_centre_horizontal_offset[4];
-int32_t frame_centre_vertical_offset[4];
-
-/* slice_header(void) */
-int32_t img_width;
-int32_t slice_vertical_position;
-int32_t slice_vertical_position_extension;
-int32_t fixed_slice_qp;
-int32_t slice_qp;
-int32_t slice_horizontal_positon; /* added by mz, 2008.04 */
-int32_t slice_horizontal_positon_extension;
-
-int32_t StartCodePosition;
-int32_t background_pred_flag;
-
-
-/* Reference Manage */
-int32_t displaydelay;
-int32_t picture_reorder_delay;
-#if M3480_TEMPORAL_SCALABLE
-int32_t temporal_id_exist_flag;
-#endif
-
-int32_t gop_size;
-struct reference_management decod_RPS[MAXGOP];
-struct reference_management curr_RPS;
-int32_t last_output;
-int32_t trtmp;
-#if M3480_TEMPORAL_SCALABLE
-int32_t cur_layer;
-#endif
-
-/* Adaptive frequency weighting quantization */
-#if FREQUENCY_WEIGHTING_QUANTIZATION
-int32_t weight_quant_enable_flag;
-int32_t load_seq_weight_quant_data_flag;
-
-int32_t pic_weight_quant_enable_flag;
-int32_t pic_weight_quant_data_index;
-int32_t weighting_quant_param;
-int32_t weighting_quant_model;
-int16_t quant_param_undetail[6]; /* M2148 2007-09 */
-int16_t quant_param_detail[6]; /* M2148 2007-09 */
-int32_t WeightQuantEnable; /* M2148 2007-09 */
-int32_t mb_adapt_wq_disable; /* M2331 2008-04 */
-int32_t mb_wq_mode; /* M2331 2008-04 */
-#if CHROMA_DELTA_QP
-int32_t chroma_quant_param_disable;
-int32_t chroma_quant_param_delta_u;
-int32_t chroma_quant_param_delta_v;
-#endif
-
-int32_t b_pre_dec_intra_img;
-int32_t pre_dec_img_type;
-int32_t CurrentSceneModel;
-#endif
-
-int32_t curr_IDRcoi;
-int32_t curr_IDRtr;
-int32_t next_IDRtr;
-int32_t next_IDRcoi;
-int32_t end_SeqTr;
-
-#if MB_DQP
-int32_t lastQP;
-/* FILE * testQP; */
-#endif
-
-};
-/* extern Video_Dec_data *hd; */
-
-struct DecodingEnvironment_s {
- uint32_t Dbuffer;
- int32_t Dbits_to_go;
- uint8_t *Dcodestrm;
- int32_t *Dcodestrm_len;
-};
-
-/* added at rm52k version */
-
-struct inp_par;
-
-
-
-/* ! Slice */
-struct slice {
- int32_t picture_id;
- int32_t qp;
- int32_t picture_type; /* !< picture type */
- int32_t start_mb_nr;
- /* !< number of different partitions */
- int32_t max_part_nr;
-
- /* added by lzhang */
- /* !< pointer to struct of context models for use in AEC */
- struct SyntaxInfoContexts_s *syn_ctx;
-};
-
-struct alfdatapart {
- struct Bitstream_s *bitstream;
- struct DecodingEnvironment_s de_AEC;
- struct SyntaxInfoContexts_s *syn_ctx;
-};
-/* static int32_t alfParAllcoated = 0; */
-
-/* input parameters from configuration file */
-struct inp_par {
- int32_t buf_cycle; /* <! Frame buffer size */
- int32_t ref_pic_order; /* <! ref order */
- int32_t output_dec_pic; /* <! output_dec_pic */
- int32_t profile_id;
- int32_t level_id;
- int32_t chroma_format;
- int32_t g_uiMaxSizeInBit;
- int32_t alpha_c_offset;
- int32_t beta_offset;
- int32_t useNSQT;
-#if MB_DQP
- int32_t useDQP;
-#endif
- int32_t useSDIP;
- int32_t sao_enable;
-#if M3480_TEMPORAL_SCALABLE
- int32_t temporal_id_exist_flag;
-#endif
- int32_t alf_enable;
-
- int32_t crossSliceLoopFilter;
-
- int32_t sample_bit_depth; /* sample bit depth */
- /* decoded file bit depth (assuming output_bit_depth is
- less or equal to sample_bit_depth) */
- int32_t output_bit_depth;
-
-
- int32_t MD5Enable;
-
-#if OUTPUT_INTERLACE_MERGED_PIC
- int32_t output_interlace_merged_picture;
-#endif
-
-};
-
-/* extern struct inp_par *input; */
-
-struct outdata_s {
-#if RD170_FIX_BG
- struct STDOUT_DATA_s stdoutdata[REF_MAXBUFFER];
-#else
- struct STDOUT_DATA_s stdoutdata[8];
-#endif
- int32_t buffer_num;
-};
-/* outdata outprint; */
-
-#define PAYLOAD_TYPE_IDERP 8
-
-struct Bitstream_s *AllocBitstream(void);
-void FreeBitstream(void);
-#if TRACE
-void tracebits2(const int8_t *trace_str, int32_t len, int32_t info);
-#endif
-
-/* int32_t direct_mv[45][80][4][4][3]; // only to verify result */
-
-#define I_PICTURE_START_CODE 0xB3
-#define PB_PICTURE_START_CODE 0xB6
-#define SLICE_START_CODE_MIN 0x00
-#define SLICE_START_CODE_MAX 0x8F
-#define USER_DATA_START_CODE 0xB2
-#define SEQUENCE_HEADER_CODE 0xB0
-#define EXTENSION_START_CODE 0xB5
-#define SEQUENCE_END_CODE 0xB1
-#define VIDEO_EDIT_CODE 0xB7
-
-
-#define SEQUENCE_DISPLAY_EXTENSION_ID 2
-#define COPYRIGHT_EXTENSION_ID 4
-#define CAMERAPARAMETERS_EXTENSION_ID 11
-#define PICTURE_DISPLAY_EXTENSION_ID 7
-#if M3480_TEMPORAL_SCALABLE
-#define TEMPORAL_SCALABLE_EXTENSION_ID 3
-#endif
-
-#if ROI_M3264
-#if RD1501_FIX_BG
-#define LOCATION_DATA_EXTENSION_ID 12
-#else
-#define LOCATION_DATA_EXTENSION_ID 15
-#endif
-#endif
-
-#if AVS2_HDR_HLS
-#define MASTERING_DISPLAY_AND_CONTENT_METADATA_EXTENSION 10
-#endif
-
-void malloc_slice(void);
-void free_slice(void);
-
-
-void read_ipred_modes(void);
-
-int32_t AEC_startcode_follows(int32_t eos_bit);
-
-/* extern uint32_t max_value_s; */
-
-/*ComAdaptiveLoopFilter.h*/
-#define ALF_MAX_NUM_COEF 9
-#define NO_VAR_BINS 16
-
-
-#define RPM_BEGIN 0x100
-#define ALF_BEGIN 0x180
-#define RPM_END 0x280
-
-union param_u {
- struct {
- uint16_t data[RPM_END - RPM_BEGIN];
- } l;
- struct {
- /*sequence*/
- uint16_t profile_id;
- uint16_t level_id;
- uint16_t progressive_sequence;
- uint16_t is_field_sequence;
- uint16_t horizontal_size;
- uint16_t vertical_size;
- uint16_t chroma_format;
- uint16_t sample_precision;
- uint16_t encoding_precision;
- uint16_t aspect_ratio_information;
- uint16_t frame_rate_code;
- uint16_t bit_rate_lower;
- uint16_t bit_rate_upper;
- uint16_t low_delay;
- uint16_t temporal_id_exist_flag;
- uint16_t g_uiMaxSizeInBit;
-
-#define BACKGROUND_PICTURE_DISABLE_BIT 11
-#define B_MHPSKIP_ENABLED_BIT 10
-#define DHP_ENABLED_BIT 9
-#define WSM_ENABLED_BIT 8
-#define INTER_AMP_ENABLE_BIT 7
-#define USENSQT_BIT 6
-#define USESDIP_BIT 5
-#define B_SECT_ENABLED_BIT 4
-#define SAO_ENABLE_BIT 3
-#define ALF_ENABLE_BIT 2
-#define B_PMVR_ENABLED_BIT 1
-#define CROSSSLICELOOPFILTER_BIT 0
- uint16_t avs2_seq_flags;
-
- uint16_t num_of_RPS;
- uint16_t picture_reorder_delay;
- /*PIC*/
- uint16_t time_code_flag;
- uint16_t time_code;
- uint16_t background_picture_flag;
- uint16_t background_picture_output_flag;
- uint16_t coding_order;
- uint16_t cur_layer;
- uint16_t displaydelay; /*???*/
- uint16_t predict; /*???*/
- uint16_t RPS_idx; /*???*/
- uint16_t referd_by_others_cur;
- uint16_t num_of_ref_cur;
- uint16_t ref_pic_cur[8];
- uint16_t num_to_remove_cur;
- uint16_t remove_pic_cur[8];
- uint16_t progressive_frame;
- uint16_t picture_structure;
- uint16_t top_field_first;
- uint16_t repeat_first_field;
- uint16_t is_top_field;
-
- uint16_t picture_coding_type;
- uint16_t background_pred_flag;
- uint16_t background_reference_enable;
- uint16_t random_access_decodable_flag;
- uint16_t lcu_size;
- uint16_t alpha_c_offset;
- uint16_t beta_offset;
- uint16_t chroma_quant_param_delta_cb;
- uint16_t chroma_quant_param_delta_cr;
- uint16_t loop_filter_disable;
-
- uint16_t video_signal_type;
- uint16_t color_description;
- uint16_t display_primaries_x[3];
- uint16_t display_primaries_y[3];
- uint16_t white_point_x;
- uint16_t white_point_y;
- uint16_t max_display_mastering_luminance;
- uint16_t min_display_mastering_luminance;
- uint16_t max_content_light_level;
- uint16_t max_picture_average_light_level;
- } p;
- struct {
- uint16_t padding[ALF_BEGIN - RPM_BEGIN];
- uint16_t picture_alf_enable_Y;
- uint16_t picture_alf_enable_Cb;
- uint16_t picture_alf_enable_Cr;
- uint16_t alf_filters_num_m_1;
- uint16_t region_distance[16];
- uint16_t alf_cb_coeffmulti[9];
- uint16_t alf_cr_coeffmulti[9];
- uint16_t alf_y_coeffmulti[16][9];
- } alf;
-};
-
-
-struct avs2_decoder {
- uint8_t init_hw_flag;
- struct inp_par input;
- struct ImageParameters_s img;
- struct Video_Com_data_s hc;
- struct Video_Dec_data_s hd;
- union param_u param;
- struct avs2_frame_s frm_pool[AVS2_MAX_BUFFER_NUM];
- struct avs2_frame_s *fref[REF_MAXBUFFER];
-#ifdef AML
- /*used for background
- when background_picture_output_flag is 0*/
- struct avs2_frame_s *m_bg;
- /*current background picture, ether m_bg or fref[..]*/
- struct avs2_frame_s *f_bg;
-#endif
- struct outdata_s outprint;
- uint32_t cm_header_start;
- struct ALFParam_s m_alfPictureParam[NUM_ALF_COMPONENT];
-#ifdef FIX_CHROMA_FIELD_MV_BK_DIST
- int8_t bk_img_is_top_field;
-#endif
-#ifdef AML
- int32_t lcu_size;
- int32_t lcu_size_log2;
- int32_t lcu_x_num;
- int32_t lcu_y_num;
- int32_t lcu_total;
- int32_t ref_maxbuffer;
- int32_t to_prepare_disp_count;
- int8_t bufmgr_error_flag;
-#endif
-};
-
-
-extern void write_frame(struct avs2_decoder *avs2_dec, int32_t pos);
-extern void init_frame_t(struct avs2_frame_s *currfref);
-extern void report_frame(struct avs2_decoder *avs2_dec,
- struct outdata_s *data, int32_t pos);
-
-extern int avs2_post_process(struct avs2_decoder *avs2_dec);
-extern void avs2_prepare_header(struct avs2_decoder *avs2_dec,
- int32_t start_code);
-extern int32_t avs2_process_header(struct avs2_decoder *avs2_dec);
-
-extern void init_avs2_decoder(struct avs2_decoder *avs2_dec);
-
-extern int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec);
-
-extern bool is_avs2_print_param(void);
-extern bool is_avs2_print_bufmgr_detail(void);
-#endif
-
diff --git a/drivers/frame_provider/decoder_v4l/avs2/vavs2.c b/drivers/frame_provider/decoder_v4l/avs2/vavs2.c
deleted file mode 100644
index ce5ffde..0000000
--- a/drivers/frame_provider/decoder_v4l/avs2/vavs2.c
+++ /dev/null
@@ -1,8375 +0,0 @@
- /*
- * drivers/amlogic/amports/avs2.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
-*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/frame_sync/tsync.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include "avs2_global.h"
-
-#define MEM_NAME "codec_avs2"
-/* #include <mach/am_regs.h> */
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-
-#include <linux/amlogic/media/video_sink/video.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/config_parser.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/vdec_feature.h"
-
-
-#define I_ONLY_SUPPORT
-#define MIX_STREAM_SUPPORT
-#define G12A_BRINGUP_DEBUG
-#define CONSTRAIN_MAX_BUF_NUM
-
-#define CO_MV_COMPRESS
-
-#include "vavs2.h"
-#define HEVC_SHIFT_LENGTH_PROTECT 0x313a
-#define HEVC_MPRED_CTRL4 0x324c
-#define HEVC_MPRED_CTRL9 0x325b
-#define HEVC_DBLK_CFGD 0x350d
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_DBLK_CFGB 0x350b
-#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
-#define HEVC_SAO_MMU_VH1_ADDR 0x363b
-#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-
-
-/*
- * AVS2_DEC_STATUS define
-*/
-/*internal*/
-#define AVS2_DEC_IDLE 0
-#define AVS2_SEQUENCE 1
-#define AVS2_I_PICTURE 2
-#define AVS2_PB_PICTURE 3
-#define AVS2_DISCARD_STARTCODE 4
-#define AVS2_DISCARD_NAL 4
-
-#define AVS2_SLICE_DECODING 6
-
-#define SWAP_IN_CMD 0x10
-#define SWAP_OUT_CMD 0x11
-#define SWAP_OUTIN_CMD 0x12
-#define SWAP_DONE 0x13
-#define SWAP_POST_INIT 0x14
-
-/*head*/
-#define AVS2_HEAD_SEQ_READY 0x21
-#define AVS2_HEAD_PIC_I_READY 0x22
-#define AVS2_HEAD_PIC_PB_READY 0x23
-#define AVS2_HEAD_SEQ_END_READY 0x24
-#define AVS2_STARTCODE_SEARCH_DONE 0x25
-
-/*pic done*/
-#define HEVC_DECPIC_DATA_DONE 0x30
-#define HEVC_DECPIC_DATA_ERROR 0x31
-#define HEVC_NAL_DECODE_DONE 0x32
-#define AVS2_DECODE_BUFEMPTY 0x33
-#define AVS2_DECODE_TIMEOUT 0x34
-#define AVS2_DECODE_OVER_SIZE 0x35
-#define AVS2_EOS 0x36
-
-/*cmd*/
-#define AVS2_10B_DISCARD_NAL 0xf0
-#define AVS2_SEARCH_NEW_PIC 0xf1
-#define AVS2_ACTION_ERROR 0xfe
-#define HEVC_ACTION_ERROR 0xfe
-#define AVS2_ACTION_DONE 0xff
-/*AVS2_DEC_STATUS end*/
-
-
-#define VF_POOL_SIZE 32
-
-#undef pr_info
-#define pr_info printk
-
-#define DECODE_MODE_SINGLE (0 | (0x80 << 24))
-#define DECODE_MODE_MULTI_STREAMBASE (1 | (0x80 << 24))
-#define DECODE_MODE_MULTI_FRAMEBASE (2 | (0x80 << 24))
-
-
-#define VP9_TRIGGER_FRAME_DONE 0x100
-#define VP9_TRIGGER_FRAME_ENABLE 0x200
-
-/*#define MV_MEM_UNIT 0x240*/
-#define MV_MEM_UNIT 0x200
-/*---------------------------------------------------
- Include "parser_cmd.h"
----------------------------------------------------*/
-#define PARSER_CMD_SKIP_CFG_0 0x0000090b
-
-#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
-
-#define PARSER_CMD_SKIP_CFG_2 0x001b1910
-
-
-#define PARSER_CMD_NUMBER 37
-
-static unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
-0x0401,
-0x8401,
-0x0800,
-0x0402,
-0x9002,
-0x1423,
-0x8CC3,
-0x1423,
-0x8804,
-0x9825,
-0x0800,
-0x04FE,
-0x8406,
-0x8411,
-0x1800,
-0x8408,
-0x8409,
-0x8C2A,
-0x9C2B,
-0x1C00,
-0x840F,
-0x8407,
-0x8000,
-0x8408,
-0x2000,
-0xA800,
-0x8410,
-0x04DE,
-0x840C,
-0x840D,
-0xAC00,
-0xA000,
-0x08C0,
-0x08E0,
-0xA40E,
-0xFC00,
-0x7C00
-};
-
-static int32_t g_WqMDefault4x4[16] = {
- 64, 64, 64, 68,
- 64, 64, 68, 72,
- 64, 68, 76, 80,
- 72, 76, 84, 96
-};
-
-
-static int32_t g_WqMDefault8x8[64] = {
- 64, 64, 64, 64, 68, 68, 72, 76,
- 64, 64, 64, 68, 72, 76, 84, 92,
- 64, 64, 68, 72, 76, 80, 88, 100,
- 64, 68, 72, 80, 84, 92, 100, 112,
- 68, 72, 80, 84, 92, 104, 112, 128,
- 76, 80, 84, 92, 104, 116, 132, 152,
- 96, 100, 104, 116, 124, 140, 164, 188,
- 104, 108, 116, 128, 152, 172, 192, 216
-};
-/*#define HEVC_PIC_STRUCT_SUPPORT*/
-/* to remove, fix build error */
-
-/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/
-
-#define MULTI_INSTANCE_SUPPORT
-/* #define ERROR_HANDLE_DEBUG */
-
-#ifndef STAT_KTHREAD
-#define STAT_KTHREAD 0x40
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define MAX_DECODE_INSTANCE_NUM 12
-#define MULTI_DRIVER_NAME "ammvdec_avs2_v4l"
-
-#define lock_buffer(dec, flags) \
- spin_lock_irqsave(&dec->buffer_lock, flags)
-
-#define unlock_buffer(dec, flags) \
- spin_unlock_irqrestore(&dec->buffer_lock, flags)
-
-static u32 debug_mask = 0xffffffff;
-#define get_dbg_flag(dec) ((debug_mask & (1 << dec->index)) ? debug : 0)
-
-static unsigned int max_decode_instance_num
- = MAX_DECODE_INSTANCE_NUM;
-static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
-static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
-static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
-
-#ifdef G12A_BRINGUP_DEBUG
-static u32 decode_timeout_val = 200;
-#else
-static u32 decode_timeout_val = 200;
-#endif
-static int start_decode_buf_level = 0x8000;
-#ifdef AVS2_10B_MMU
-static u32 work_buf_size; /* = 24 * 1024 * 1024*/;
-#else
-static u32 work_buf_size = 32 * 1024 * 1024;
-#endif
-
-static u32 mv_buf_margin;
-static int pre_decode_buf_level = 0x1000;
-static u32 again_threshold;
-
-
-/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
-/* double_write_mode:
- * 0, no double write;
- * 1, 1:1 ratio;
- * 2, (1/4):(1/4) ratio;
- * 3, (1/4):(1/4) ratio, with both compressed frame included
- * 4, (1/2):(1/2) ratio;
- * 8, (1/8):(1/8) ratio;
- * 0x10, double write only
- * 0x100, if > 1080p,use mode 4,else use mode 1;
- * 0x200, if > 1080p,use mode 2,else use mode 1;
- * 0x300, if > 720p, use mode 4, else use mode 1;
- */
-static u32 double_write_mode;
-static u32 without_display_mode;
-
-static u32 mv_buf_dynamic_alloc;
-#define DRIVER_NAME "amvdec_avs2_v4l"
-#define DRIVER_HEADER_NAME "amvdec_avs2_header"
-
-
-#define PUT_INTERVAL (HZ/100)
-#define ERROR_SYSTEM_RESET_COUNT 200
-
-#define PTS_NORMAL 0
-#define PTS_NONE_REF_USE_DURATION 1
-
-#define PTS_MODE_SWITCHING_THRESHOLD 3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
-
-#define DUR2PTS(x) ((x)*90/96)
-
-struct AVS2Decoder_s;
-static int vavs2_vf_states(struct vframe_states *states, void *);
-static struct vframe_s *vavs2_vf_peek(void *);
-static struct vframe_s *vavs2_vf_get(void *);
-static void vavs2_vf_put(struct vframe_s *, void *);
-static int vavs2_event_cb(int type, void *data, void *private_data);
-static void set_vframe(struct AVS2Decoder_s *dec,
- struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy);
-static s32 vavs2_init(struct vdec_s *vdec);
-static void vavs2_prot_init(struct AVS2Decoder_s *dec);
-static int vavs2_local_init(struct AVS2Decoder_s *dec);
-static void vavs2_put_timer_func(struct timer_list *timer);
-static void dump_data(struct AVS2Decoder_s *dec, int size);
-static unsigned char get_data_check_sum
- (struct AVS2Decoder_s *dec, int size);
-static void dump_pic_list(struct AVS2Decoder_s *dec);
-
-static const char vavs2_dec_id[] = "vavs2-dev";
-
-#define PROVIDER_NAME "decoder.avs2"
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs2"
-
-static const struct vframe_operations_s vavs2_vf_provider = {
- .peek = vavs2_vf_peek,
- .get = vavs2_vf_get,
- .put = vavs2_vf_put,
- .event_cb = vavs2_event_cb,
- .vf_states = vavs2_vf_states,
-};
-
-static struct vframe_provider_s vavs2_vf_prov;
-
-static u32 bit_depth_luma;
-static u32 bit_depth_chroma;
-static u32 frame_width;
-static u32 frame_height;
-static u32 video_signal_type;
-static u32 pts_unstable;
-static u32 on_no_keyframe_skiped;
-
-static u32 force_video_signal_type;
-static u32 enable_force_video_signal_type;
-#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
-#define HDR_CUVA_MASK 0x40000000
-
-
-static const char * const video_format_names[] = {
- "component", "PAL", "NTSC", "SECAM",
- "MAC", "unspecified", "Reserved", "Reserved"
-};
-
-static inline int div_r32(int64_t m, int n)
-{
-/*
-return (int)(m/n)
-*/
-#ifndef CONFIG_ARM64
- int64_t qu = 0;
- qu = div_s64(m, n);
- return (int)qu;
-#else
- return (int)(m/n);
-#endif
-}
-
-enum vpx_bit_depth_t {
- AVS2_BITS_8 = 8, /**< 8 bits */
- AVS2_BITS_10 = 10, /**< 10 bits */
- AVS2_BITS_12 = 12, /**< 12 bits */
-};
-
-/*USE_BUF_BLOCK*/
-struct BUF_s {
- int index;
- unsigned int alloc_flag;
- /*buffer */
- unsigned int cma_page_count;
- unsigned long alloc_addr;
- unsigned long start_adr;
- unsigned int size;
-
- unsigned int free_start_adr;
-} /*BUF_t */;
-
-struct MVBUF_s {
- unsigned long start_adr;
- unsigned int size;
- int used_flag;
-} /*MVBUF_t */;
-
- /* #undef BUFMGR_ONLY to enable hardware configuration */
-
-/*#define TEST_WR_PTR_INC*/
-#define WR_PTR_INC_NUM 128
-
-#define SIMULATION
-#define DOS_PROJECT
-#undef MEMORY_MAP_IN_REAL_CHIP
-
-/*#undef DOS_PROJECT*/
-/*#define MEMORY_MAP_IN_REAL_CHIP*/
-
-/*#define BUFFER_MGR_ONLY*/
-/*#define CONFIG_HEVC_CLK_FORCED_ON*/
-/*#define ENABLE_SWAP_TEST*/
-
-#ifdef AVS2_10B_NV21
-#define MEM_MAP_MODE 2 /* 0:linear 1:32x32 2:64x32*/
-#else
-#define MEM_MAP_MODE 0 /* 0:linear 1:32x32 2:64x32*/
-#endif
-
-#ifdef AVS2_10B_NV21
-#else
-#define LOSLESS_COMPRESS_MODE
-#endif
-
-#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
-#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
-
-#define AVS2_DBG_BUFMGR 0x01
-#define AVS2_DBG_BUFMGR_MORE 0x02
-#define AVS2_DBG_BUFMGR_DETAIL 0x04
-#define AVS2_DBG_IRQ_EVENT 0x08
-#define AVS2_DBG_OUT_PTS 0x10
-#define AVS2_DBG_PRINT_SOURCE_LINE 0x20
-#define AVS2_DBG_PRINT_PARAM 0x40
-#define AVS2_DBG_PRINT_PIC_LIST 0x80
-#define AVS2_DBG_SEND_PARAM_WITH_REG 0x100
-#define AVS2_DBG_MERGE 0x200
-#define AVS2_DBG_DBG_LF_PRINT 0x400
-#define AVS2_DBG_REG 0x800
-#define AVS2_DBG_PIC_LEAK 0x1000
-#define AVS2_DBG_PIC_LEAK_WAIT 0x2000
-#define AVS2_DBG_HDR_INFO 0x4000
-#define AVS2_DBG_HDR_DATA 0x8000
-#define AVS2_DBG_DIS_LOC_ERROR_PROC 0x10000
-#define AVS2_DBG_DIS_SYS_ERROR_PROC 0x20000
-#define AVS2_DBG_DUMP_PIC_LIST 0x40000
-#define AVS2_DBG_TRIG_SLICE_SEGMENT_PROC 0x80000
-#define AVS2_DBG_FORCE_UNCOMPRESS 0x100000
-#define AVS2_DBG_LOAD_UCODE_FROM_FILE 0x200000
-#define AVS2_DBG_FORCE_SEND_AGAIN 0x400000
-#define AVS2_DBG_DUMP_DATA 0x800000
-#define AVS2_DBG_DUMP_LMEM_BUF 0x1000000
-#define AVS2_DBG_DUMP_RPM_BUF 0x2000000
-#define AVS2_DBG_CACHE 0x4000000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-/*MULTI_INSTANCE_SUPPORT*/
-#define PRINT_FLAG_ERROR 0
-#define PRINT_FLAG_VDEC_STATUS 0x20000000
-#define PRINT_FLAG_VDEC_DETAIL 0x40000000
-#define PRINT_FLAG_VDEC_DATA 0x80000000
-
-#define PRINT_LINE() \
- do { \
- if (debug & AVS2_DBG_PRINT_SOURCE_LINE)\
- pr_info("%s line %d\n", __func__, __LINE__);\
- } while (0)
-
-static u32 debug;
-
-static u32 debug_again;
-
-bool is_avs2_print_param(void)
-{
- bool ret = false;
- if (debug & AVS2_DBG_PRINT_PARAM)
- ret = true;
- return ret;
-}
-
-bool is_avs2_print_bufmgr_detail(void)
-{
- bool ret = false;
- if (debug & AVS2_DBG_BUFMGR_DETAIL)
- ret = true;
- return ret;
-}
-static bool is_reset;
-/*for debug*/
-static u32 force_bufspec;
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode detail print
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-static u32 force_disp_pic_index;
-
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-static u32 cuva_buf_size = 512;
-
-#define DEBUG_REG
-#ifdef DEBUG_REG
-static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
-{
- if (debug & AVS2_DBG_REG)
- pr_info("%s(%x, %x)\n", __func__, adr, val);
- if (adr != 0)
- WRITE_VREG(adr, val);
-}
-
-#undef WRITE_VREG
-#define WRITE_VREG WRITE_VREG_DBG2
-#endif
-
-
-//#ifdef AVS2_10B_MMU
-//#define MMU_COMPRESS_HEADER_SIZE 0x48000
-//#define MMU_COMPRESS_8K_HEADER_SIZE 0x48000*4
-//#endif
-#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
-#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
-#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
-
-#define INVALID_IDX -1 /* Invalid buffer index.*/
-
-
-#define FRAME_BUFFERS (AVS2_MAX_BUFFER_NUM)
-#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
-#define MAX_BUF_NUM (FRAME_BUFFERS)
-
-#define FRAME_CONTEXTS_LOG2 2
-#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
-/*buffer + header buffer + workspace*/
-#undef MV_USE_FIXED_BUF
-#ifdef MV_USE_FIXED_BUF
-#define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1)
-#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1)
-#else
-#define MAX_BMMU_BUFFER_NUM (((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1)
-#define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n+1)
-#define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
-#endif
-
-#define CO_MV_BUF_SIZE_1080P 0x3fc00
-#define CO_MV_BUF_SIZE_4K 0x120000
-#define CO_MV_BUF_SIZE_8K 0x480000
-/*
-static void set_canvas(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic);
-int avs2_prepare_display_buf(struct AVS2Decoder_s *dec,
- int pos);
-*/
-
-
-struct buff_s {
- u32 buf_start;
- u32 buf_size;
- u32 buf_end;
-};
-
-struct BuffInfo_s {
- u32 max_width;
- u32 max_height;
- u32 start_adr;
- u32 end_adr;
- struct buff_s ipp;
- struct buff_s sao_abv;
- struct buff_s sao_vb;
- struct buff_s short_term_rps;
- struct buff_s rcs;
- struct buff_s sps;
- struct buff_s pps;
- struct buff_s sao_up;
- struct buff_s swap_buf;
- struct buff_s swap_buf2;
- struct buff_s scalelut;
- struct buff_s dblk_para;
- struct buff_s dblk_data;
- struct buff_s dblk_data2;
-#ifdef AVS2_10B_MMU
- struct buff_s mmu_vbh;
- struct buff_s cm_header;
-#endif
- struct buff_s mpred_above;
-#ifdef MV_USE_FIXED_BUF
- struct buff_s mpred_mv;
-#endif
- struct buff_s rpm;
- struct buff_s lmem;
-};
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_CONFIG_PARAM 3
-#define DEC_RESULT_ERROR 4
-#define DEC_INIT_PICLIST 5
-#define DEC_UNINIT_PICLIST 6
-#define DEC_RESULT_GET_DATA 7
-#define DEC_RESULT_GET_DATA_RETRY 8
-#define DEC_RESULT_EOS 9
-#define DEC_RESULT_FORCE_EXIT 10
-
-static void avs2_work(struct work_struct *work);
-struct loop_filter_info_n;
-struct loopfilter;
-struct segmentation;
-
-struct AVS2Decoder_s {
- int pic_list_init_flag;
- unsigned char index;
- spinlock_t buffer_lock;
- struct device *cma_dev;
- struct platform_device *platform_dev;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- struct vframe_chunk_s *chunk;
- int dec_result;
- struct work_struct work;
- u32 start_shift_bytes;
-
- struct BuffInfo_s work_space_buf_store;
- unsigned long buf_start;
- u32 buf_size;
- u32 cma_alloc_count;
- unsigned long cma_alloc_addr;
- uint8_t eos;
- unsigned long int start_process_time;
- unsigned last_lcu_idx;
- int decode_timeout_count;
- unsigned timeout_num;
-
- int double_write_mode;
-
- unsigned char m_ins_flag;
- char *provider_name;
- int frame_count;
- u32 stat;
- struct timer_list timer;
- u32 frame_dur;
- u32 frame_ar;
- int fatal_error;
- uint8_t init_flag;
- uint8_t first_sc_checked;
- uint8_t process_busy;
-#define PROC_STATE_INIT 0
-#define PROC_STATE_HEAD_DONE 1
-#define PROC_STATE_DECODING 2
-#define PROC_STATE_HEAD_AGAIN 3
-#define PROC_STATE_DECODE_AGAIN 4
-#define PROC_STATE_TEST1 5
- uint8_t process_state;
- u32 ucode_pause_pos;
-
- int show_frame_num;
-#ifndef AVS2_10B_MMU
- struct buff_s mc_buf_spec;
-#endif
- struct dec_sysinfo vavs2_amstream_dec_info;
- void *rpm_addr;
- void *lmem_addr;
- dma_addr_t rpm_phy_addr;
- dma_addr_t lmem_phy_addr;
- unsigned short *lmem_ptr;
- unsigned short *debug_ptr;
-
- u32 cuva_size;
- void *cuva_addr;
- dma_addr_t cuva_phy_addr;
-
-#if 1
- /*AVS2_10B_MMU*/
- void *frame_mmu_map_addr;
- dma_addr_t frame_mmu_map_phy_addr;
-#endif
- unsigned int use_cma_flag;
-
- struct BUF_s m_BUF[MAX_BUF_NUM];
- struct MVBUF_s m_mv_BUF[MAX_BUF_NUM];
- u32 used_buf_num;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
- atomic_t vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
- int buf_num;
- unsigned int losless_comp_body_size;
-
- u32 video_signal_type;
- u32 video_ori_signal_type;
-
- int pts_mode;
- int last_lookup_pts;
- int last_pts;
- u64 last_lookup_pts_us64;
- u64 last_pts_us64;
- u64 shift_byte_count;
- u32 shift_byte_count_lo;
- u32 shift_byte_count_hi;
- int pts_mode_switching_count;
- int pts_mode_recovery_count;
-
- bool get_frame_dur;
- u32 saved_resolution;
-
- /**/
- int refresh_frame_flags;
- uint8_t hold_ref_buf;
- struct BuffInfo_s *work_space_buf;
-#ifndef AVS2_10B_MMU
- struct buff_s *mc_buf;
-#endif
- unsigned int frame_width;
- unsigned int frame_height;
-
- unsigned short *rpm_ptr;
- int init_pic_w;
- int init_pic_h;
-
- int slice_type;
-
- int decode_idx;
- int slice_idx;
- uint8_t wait_buf;
- uint8_t error_flag;
- unsigned int bufmgr_error_count;
-
- /* bit 0, for decoding; bit 1, for displaying */
- uint8_t ignore_bufmgr_error;
- uint8_t skip_PB_before_I;
- int PB_skip_mode;
- int PB_skip_count_after_decoding;
- /*hw*/
-
- /**/
- struct vdec_info *gvs;
-
-
- unsigned int dec_status;
- u32 last_put_idx;
- int new_frame_displayed;
- void *mmu_box;
- void *bmmu_box;
- struct vframe_master_display_colour_s vf_dp;
- struct firmware_s *fw;
-#ifdef AVS2_10B_MMU
- int cur_fb_idx_mmu;
- long used_4k_num;
-#endif
- struct avs2_decoder avs2_dec;
-#define ALF_NUM_BIT_SHIFT 6
-#define NO_VAR_BINS 16
- int32_t m_filterCoeffSym[16][9];
- int32_t m_varIndTab[NO_VAR_BINS];
-
- struct vframe_s vframe_dummy;
- /* start_decoding_flag,
- bit 0, SEQ ready
- bit 1, I ready
- */
- unsigned char start_decoding_flag;
- uint32_t mpred_abv_start_addr;
- uint32_t mpred_abv_start_addr_bak;
- u8 next_again_flag;
- u32 pre_parser_wr_ptr;
- int need_cache_size;
- u64 sc_start_time;
-#ifdef I_ONLY_SUPPORT
- u32 i_only;
-#endif
- int frameinfo_enable;
- struct vframe_qos_s vframe_qos;
- u32 dynamic_buf_margin;
- int sidebind_type;
- int sidebind_channel_id;
- u32 endian;
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- int hdr_flag;
-};
-
-static int compute_losless_comp_body_size(
- struct AVS2Decoder_s *dec, int width, int height,
- uint8_t is_bit_depth_10);
-
-static int avs2_print(struct AVS2Decoder_s *dec,
- int flag, const char *fmt, ...)
-{
-#define HEVC_PRINT_BUF 256
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
- if (dec == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
- va_start(args, fmt);
- if (dec)
- len = sprintf(buf, "[%d]", dec->index);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static int avs2_print_cont(struct AVS2Decoder_s *dec,
- int flag, const char *fmt, ...)
-{
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
- if (dec == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
- va_start(args, fmt);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-#define PROB_SIZE (496 * 2 * 4)
-#define PROB_BUF_SIZE (0x5000)
-#define COUNT_BUF_SIZE (0x300 * 4 * 4)
-/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/
-#define MAX_FRAME_4K_NUM 0x1200
-#define MAX_FRAME_8K_NUM 0x4800
-#define MAX_SIZE_4K (4096 * 2304)
-#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
-#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
-
-static int get_frame_mmu_map_size(struct AVS2Decoder_s *dec)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h)))
- return (MAX_FRAME_8K_NUM * 4);
- return (MAX_FRAME_4K_NUM * 4);
-}
-
-static int get_compress_header_size(struct AVS2Decoder_s *dec)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h)))
- return MMU_COMPRESS_HEADER_SIZE_8K;
- else if (IS_4K_SIZE(dec->init_pic_w, dec->init_pic_h))
- return MMU_COMPRESS_HEADER_SIZE_4K;
- return MMU_COMPRESS_HEADER_SIZE_1080P;
-}
-
-static void reset_process_time(struct AVS2Decoder_s *dec)
-{
- if (dec->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - dec->start_process_time) / HZ;
- dec->start_process_time = 0;
- if (process_time > max_process_time[dec->index])
- max_process_time[dec->index] = process_time;
- }
-}
-
-static void start_process_time(struct AVS2Decoder_s *dec)
-{
- dec->start_process_time = jiffies;
- dec->decode_timeout_count = 0;
- dec->last_lcu_idx = 0;
-}
-
-static void update_decoded_pic(struct AVS2Decoder_s *dec);
-
-static void timeout_process(struct AVS2Decoder_s *dec)
-{
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
- dec->timeout_num++;
- amhevc_stop();
- avs2_print(dec,
- 0, "%s decoder timeout\n", __func__);
- if (cur_pic)
- cur_pic->error_mark = 1;
- dec->dec_result = DEC_RESULT_DONE;
- update_decoded_pic(dec);
- reset_process_time(dec);
- vdec_schedule_work(&dec->work);
-}
-
-static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec)
-{
- return (dec->m_ins_flag &&
- ((double_write_mode & 0x80000000) == 0)) ?
- dec->double_write_mode :
- (double_write_mode & 0x7fffffff);
-}
-
-static int get_double_write_mode(struct AVS2Decoder_s *dec)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(dec);
- int w = dec->avs2_dec.img.width;
- int h = dec->avs2_dec.img.height;
- u32 dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-
-/* for double write buf alloc */
-static int get_double_write_mode_init(struct AVS2Decoder_s *dec)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(dec);
- u32 dw;
- int w = dec->init_pic_w;
- int h = dec->init_pic_h;
-
- dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-
-//#define MAX_4K_NUM 0x1200
-#ifdef AVS2_10B_MMU
-int avs2_alloc_mmu(
- struct AVS2Decoder_s *dec,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
-{
- int bit_depth_10 = (bit_depth == AVS2_BITS_10);
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-#ifdef DYNAMIC_ALLOC_HEAD
- unsigned long buf_addr;
- struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
- if (pic->header_adr == 0) {
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- HEADER_BUFFER_IDX(cur_buf_idx),
- get_compress_header_size(dec),
- DRIVER_HEADER_NAME,
- &buf_addr) < 0){
- avs2_print(dec, 0,
- "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, cur_buf_idx);
- dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return -1;
- } else
- pic->header_adr = buf_addr;
- }
-#endif
-
- picture_size = compute_losless_comp_body_size(
- dec, pic_width, pic_height,
- bit_depth_10);
- cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- max_frame_num = MAX_FRAME_8K_NUM;
- else
- max_frame_num = MAX_FRAME_4K_NUM;
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, pic_width, pic_height);
- return -1;
- }
- return decoder_mmu_box_alloc_idx(
- dec->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
-}
-#endif
-
-#if 0
-/*ndef MV_USE_FIXED_BUF*/
-static void dealloc_mv_bufs(struct AVS2Decoder_s *dec)
-{
- int i;
- for (i = 0; i < FRAME_BUFFERS; i++) {
- if (dec->m_mv_BUF[i].start_adr) {
- if (debug)
- pr_info(
- "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
- i, dec->m_mv_BUF[i].start_adr,
- dec->m_mv_BUF[i].size,
- dec->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- dec->bmmu_box,
- MV_BUFFER_IDX(i));
- dec->m_mv_BUF[i].start_adr = 0;
- dec->m_mv_BUF[i].size = 0;
- dec->m_mv_BUF[i].used_flag = 0;
- }
- }
-}
-
-static int alloc_mv_buf(struct AVS2Decoder_s *dec,
- int i, int size)
-{
- int ret = 0;
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- MV_BUFFER_IDX(i), size,
- DRIVER_NAME,
- &dec->m_mv_BUF[i].start_adr) < 0) {
- dec->m_mv_BUF[i].start_adr = 0;
- ret = -1;
- } else {
- dec->m_mv_BUF[i].size = size;
- dec->m_mv_BUF[i].used_flag = 0;
- ret = 0;
- if (debug) {
- pr_info(
- "MV Buffer %d: start_adr %p size %x\n",
- i,
- (void *)dec->m_mv_BUF[i].start_adr,
- dec->m_mv_BUF[i].size);
- }
- }
- return ret;
-}
-
-static int init_mv_buf_list(struct AVS2Decoder_s *dec)
-{
- int i;
- int ret = 0;
- int count = FRAME_BUFFERS;
- int pic_width = dec->init_pic_w;
- int pic_height = dec->init_pic_h;
- int lcu_size = 64; /*fixed 64*/
- int pic_width_64 = (pic_width + 63) & (~0x3f);
- int pic_height_32 = (pic_height + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1
- : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1
- : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
- int size = ((lcu_total * MV_MEM_UNIT) + 0xffff) &
- (~0xffff);
- if (mv_buf_margin > 0)
- count = dec->avs2_dec.ref_maxbuffer + mv_buf_margin;
- for (i = 0; i < count; i++) {
- if (alloc_mv_buf(dec, i, size) < 0) {
- ret = -1;
- break;
- }
- }
- return ret;
-}
-#if 0
-
-static int get_mv_buf(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic)
-{
- int i;
- int ret = -1;
- for (i = 0; i < FRAME_BUFFERS; i++) {
- if (dec->m_mv_BUF[i].start_adr &&
- dec->m_mv_BUF[i].used_flag == 0) {
- dec->m_mv_BUF[i].used_flag = 1;
- ret = i;
- break;
- }
- }
-
- if (ret >= 0) {
- pic->mv_buf_index = ret;
- pic->mpred_mv_wr_start_addr =
- (dec->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- if (debug & AVS2_DBG_BUFMGR_MORE)
- pr_info(
- "%s => %d (%d) size 0x%x\n",
- __func__, ret,
- pic->mpred_mv_wr_start_addr,
- dec->m_mv_BUF[ret].size);
- } else {
- pr_info(
- "%s: Error, mv buf is not enough\n",
- __func__);
- }
- return ret;
-}
-
-static void put_mv_buf(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic)
-{
- int i = pic->mv_buf_index;
- if (i >= FRAME_BUFFERS) {
- if (debug & AVS2_DBG_BUFMGR_MORE)
- pr_info(
- "%s: index %d beyond range\n",
- __func__, i);
- return;
- }
- if (debug & AVS2_DBG_BUFMGR_MORE)
- pr_info(
- "%s(%d): used_flag(%d)\n",
- __func__, i,
- dec->m_mv_BUF[i].used_flag);
-
- pic->mv_buf_index = -1;
- if (dec->m_mv_BUF[i].start_adr &&
- dec->m_mv_BUF[i].used_flag)
- dec->m_mv_BUF[i].used_flag = 0;
-}
-
-static void put_un_used_mv_bufs(struct AVS2Decoder_s *dec)
-{
- struct VP9_Common_s *const cm = &dec->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
- for (i = 0; i < dec->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.index != -1) &&
- (frame_bufs[i].buf.mv_buf_index >= 0)
- )
- put_mv_buf(dec, &frame_bufs[i].buf);
- }
-}
-#endif
-
-#endif
-
-static int get_free_buf_count(struct AVS2Decoder_s *dec)
-{
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- int i;
- int count = 0;
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref < -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) && avs2_dec->fref[i]->is_output == -1
- && avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
- && avs2_dec->fref[i]->vf_ref == 0
- && avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
- ) {
- count++;
- }
- }
-
- return count;
-}
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static int get_vf_ref_only_buf_count(struct AVS2Decoder_s *dec)
-{
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- int i;
- int count = 0;
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref < -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) && avs2_dec->fref[i]->is_output == -1
- && avs2_dec->fref[i]->bg_flag == 0
-#ifndef NO_DISPLAY
- && avs2_dec->fref[i]->vf_ref > 0
- && avs2_dec->fref[i]->to_prepare_disp == 0
-#endif
- ) {
- count++;
- }
- }
-
- return count;
-}
-
-static int get_used_buf_count(struct AVS2Decoder_s *dec)
-{
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- int i;
- int count = 0;
- for (i = 0; i < avs2_dec->ref_maxbuffer; i++) {
- if ((avs2_dec->fref[i]->imgcoi_ref >= -256
-#if 0
- || abs(avs2_dec->fref[i]->
- imgtr_fwRefDistance - img->tr) >= 128
-#endif
- ) || avs2_dec->fref[i]->is_output != -1
- || avs2_dec->fref[i]->bg_flag != 0
-#ifndef NO_DISPLAY
- || avs2_dec->fref[i]->vf_ref != 0
- || avs2_dec->fref[i]->to_prepare_disp != 0
-#endif
- ) {
- count++;
- }
- }
-
- return count;
-}
-#endif
-
-int avs2_bufmgr_init(struct AVS2Decoder_s *dec, struct BuffInfo_s *buf_spec_i,
- struct buff_s *mc_buf_i) {
-
- dec->frame_count = 0;
-#ifdef AVS2_10B_MMU
- dec->used_4k_num = -1;
- dec->cur_fb_idx_mmu = INVALID_IDX;
-#endif
-
-
- /* private init */
- dec->work_space_buf = buf_spec_i;
-#ifndef AVS2_10B_MMU
- dec->mc_buf = mc_buf_i;
-#endif
- dec->rpm_addr = NULL;
- dec->lmem_addr = NULL;
-
- dec->use_cma_flag = 0;
- dec->decode_idx = 0;
- dec->slice_idx = 0;
- /*int m_uiMaxCUWidth = 1<<7;*/
- /*int m_uiMaxCUHeight = 1<<7;*/
- dec->wait_buf = 0;
- dec->error_flag = 0;
- dec->skip_PB_before_I = 0;
-
- dec->pts_mode = PTS_NORMAL;
- dec->last_pts = 0;
- dec->last_lookup_pts = 0;
- dec->last_pts_us64 = 0;
- dec->last_lookup_pts_us64 = 0;
- dec->shift_byte_count = 0;
- dec->shift_byte_count_lo = 0;
- dec->shift_byte_count_hi = 0;
- dec->pts_mode_switching_count = 0;
- dec->pts_mode_recovery_count = 0;
-
- dec->buf_num = 0;
-
- dec->bufmgr_error_count = 0;
- return 0;
-}
-
-
-
-#define HEVC_CM_BODY_START_ADDR 0x3626
-#define HEVC_CM_BODY_LENGTH 0x3627
-#define HEVC_CM_HEADER_LENGTH 0x3629
-#define HEVC_CM_HEADER_OFFSET 0x362b
-
-#define LOSLESS_COMPRESS_MODE
-
-/*#define DECOMP_HEADR_SURGENT*/
-
-static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
-static u32 enable_mem_saving = 1;
-static u32 force_w_h;
-
-static u32 force_fps;
-
-
-const u32 avs2_version = 201602101;
-static u32 debug;
-static u32 radr;
-static u32 rval;
-static u32 pop_shorts;
-static u32 dbg_cmd;
-static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
-#ifdef ERROR_HANDLE_DEBUG
-static u32 dbg_nal_skip_flag;
- /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
-static u32 dbg_nal_skip_count;
-#endif
-/*for debug*/
-static u32 decode_pic_begin;
-static uint slice_parse_begin;
-static u32 step;
-#ifdef MIX_STREAM_SUPPORT
-static u32 buf_alloc_width = 4096;
-static u32 buf_alloc_height = 2304;
-
-static u32 dynamic_buf_num_margin;
-#else
-static u32 buf_alloc_width;
-static u32 buf_alloc_height;
-static u32 dynamic_buf_num_margin = 7;
-#endif
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static u32 run_ready_max_vf_only_num;
-static u32 run_ready_display_q_num;
- /*0: not check
- 0xff: avs2_dec.ref_maxbuffer
- */
-static u32 run_ready_max_buf_num = 0xff;
-#endif
-static u32 buf_alloc_depth = 10;
-static u32 buf_alloc_size;
-/*
-bit[0]: 0,
- bit[1]: 0, always release cma buffer when stop
- bit[1]: 1, never release cma buffer when stop
-bit[0]: 1, when stop, release cma buffer if blackout is 1;
-do not release cma buffer is blackout is not 1
-
-bit[2]: 0, when start decoding, check current displayed buffer
- (only for buffer decoded by vp9) if blackout is 0
- 1, do not check current displayed buffer
-
-bit[3]: 1, if blackout is not 1, do not release current
- displayed cma buffer always.
-*/
-/* set to 1 for fast play;
- set to 8 for other case of "keep last frame"
-*/
-static u32 buffer_mode = 1;
-/* buffer_mode_dbg: debug only*/
-static u32 buffer_mode_dbg = 0xffff0000;
-/**/
-
-/*
-bit 0, 1: only display I picture;
-bit 1, 1: only decode I picture;
-*/
-static u32 i_only_flag;
-
-
-static u32 max_decoding_time;
-/*
-error handling
-*/
-/*error_handle_policy:
-bit 0: search seq again if buffer mgr error occur
- (buffer mgr error count need big than
- re_search_seq_threshold)
-bit 1: 1, display from I picture;
- 0, display from any correct pic
-*/
-
-static u32 error_handle_policy = 1;
-/*
-re_search_seq_threshold:
- bit 7~0: buffer mgr error research seq count
- bit 15~8: frame count threshold
-*/
-static u32 re_search_seq_threshold = 0x800; /*0x8;*/
-/*static u32 parser_sei_enable = 1;*/
-
-static u32 max_buf_num = (REF_BUFFER + 1);
-
-static u32 run_ready_min_buf_num = 2;
-
-static DEFINE_MUTEX(vavs2_mutex);
-
-#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
-#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
-#define AVS2_ALF_SWAP_BUFFER HEVC_ASSIST_SCRATCH_2
-#define HEVC_RCS_BUFFER HEVC_ASSIST_SCRATCH_3
-#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
-#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
-//#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
-#ifdef AVS2_10B_MMU
-#define AVS2_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
-#else
-#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
-#endif
-#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
-/*
-#define VP9_PROB_SWAP_BUFFER HEVC_ASSIST_SCRATCH_9
-#define VP9_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
-#define VP9_SEG_MAP_BUFFER HEVC_ASSIST_SCRATCH_B
-*/
-//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
-#define AVS2_CUVA_ADR HEVC_ASSIST_SCRATCH_A
-#define AVS2_CUVA_DATA_SIZE HEVC_ASSIST_SCRATCH_B
-
-#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
-#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
-#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_9
-#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
-/*!!!*/
-#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M
-#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
-#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
-#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
-
-
-/*
-ucode parser/search control
-bit 0: 0, header auto parse; 1, header manual parse
-bit 1: 0, auto skip for noneseamless stream; 1, no skip
-bit [3:2]: valid when bit1==0;
-0, auto skip nal before first vps/sps/pps/idr;
-1, auto skip nal before first vps/sps/pps
-2, auto skip nal before first vps/sps/pps,
- and not decode until the first I slice (with slice address of 0)
-
-3, auto skip before first I slice (nal_type >=16 && nal_type<=21)
-bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
-bit [16]: for NAL_UNIT_EOS when bit0 is 0:
- 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
-bit [17]: for NAL_SEI when bit0 is 0:
- 0, do not parse SEI in ucode; 1, parse SEI in ucode
-bit [31:20]: used by ucode for debug purpose
-*/
-#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
- /*DECODE_MODE: set before start decoder
- bit 7~0: decode mode
- bit 23~16: start_decoding_flag
- bit [0] - SEQ_ready
- bit [2:1] - I Picture Count
- bit 31~24: chip feature
- */
-#define DECODE_MODE HEVC_ASSIST_SCRATCH_J
-#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
- /*read only*/
-#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J
-
-#define RPM_BUF_SIZE (0x600 * 2)
-#define LMEM_BUF_SIZE (0x600 * 2)
-
- /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
-#define VBH_BUF_SIZE_1080P 0x3000
-#define VBH_BUF_SIZE_4K 0x5000
-#define VBH_BUF_SIZE_8K 0xa000
-#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
- /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
- HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
-#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
-#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
-#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
-#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
-static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = {
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- 32Kbytes (0x8000) */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x40000,
- },
- .dblk_data = {
- .buf_size = 0x40000,
- },
- .dblk_data2 = {
- .buf_size = 0x40000,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- (0x8000) */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x80000,
- },
- .dblk_data = {
- /*DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x80000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096 * 2,
- .max_height = 2304 * 2,
- .ipp = {
- /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
- round to 16k*/
- .buf_size = 0x4000 * 2,
- },
- .sao_abv = {
- .buf_size = 0x30000 * 2,
- },
- .sao_vb = {
- .buf_size = 0x30000 * 2,
- },
- .short_term_rps = {
- /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800)*/
- .buf_size = 0x800,
- },
- .rcs = {
- /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes*/
- .buf_size = 0x400,
- },
- .sps = {
- /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
- 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
- total 0x2800 bytes*/
- .buf_size = 0x2800 * 2,
- },
- .swap_buf = {
- /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
- .buf_size = 0x8000 * 2,
- },
- .dblk_para = {
- .buf_size = 0x40000 * 2,
- },
- .dblk_data = {
- .buf_size = 0x80000 * 2,
- },
- .dblk_data2 = {
- .buf_size = 0x80000 * 2,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000 * 2,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /*4k2k , 0x100000 per buffer*/
- .buf_size = 0x120000 * FRAME_BUFFERS * 4,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x1e00,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- 32Kbytes (0x8000) */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x3d00, //0x3c80,
- },
- .dblk_data = {
- .buf_size = 0x62800,
- },
- .dblk_data2 = {
- .buf_size = 0x62800,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_1080P, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x1e00, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800) */
- .buf_size = 0x800,
- },
- .rcs = {
- /* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes */
- .buf_size = 0x400,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- total 0x2000 bytes */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- each has 16 bytes total 0x2800 bytes */
- .buf_size = 0,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- (only 144 cycles valid) */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- (0x8000) */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x8100, //0x8080,
- },
- .dblk_data = {
- /*DBLK -> Max 256(4096/16) LCU,
- each para 1024bytes(total:0x40000),
- data 1024bytes(total:0x40000)*/
- .buf_size = 0x88800,
- },
- .dblk_data2 = {
- .buf_size = 0x88800,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_4K,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x4000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096 * 2,
- .max_height = 2304 * 2,
- .ipp = {
- /*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
- round to 16k*/
- .buf_size = 0x4000 * 2,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- total 64x16x2 = 2048 bytes (0x800)*/
- .buf_size = 0x800,
- },
- .rcs = {
- /*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
- total 0x0400 bytes*/
- .buf_size = 0x400,
- },
- .sps = {
- /*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- total 0x0800 bytes*/
- .buf_size = 0x800,
- },
- .pps = {
- /*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
- 0x2000 bytes*/
- .buf_size = 0x2000,
- },
- .sao_up = {
- /*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
- total 0x2800 bytes*/
- .buf_size = 0,
- },
- .swap_buf = {
- /*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
- .buf_size = 0,
- },
- .dblk_para = {
- .buf_size = 0x10100, //0x10080,
- },
- .dblk_data = {
- .buf_size = 0x110800,
- },
- .dblk_data2 = {
- .buf_size = 0x110800,
- },
-#ifdef AVS2_10B_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_8K, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
- },
-#endif
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /*4k2k , 0x100000 per buffer*/
- .buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- }
-};
-
-#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
-#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
-#ifndef MV_USE_FIXED_BUF
-static uint32_t get_mv_buf_size(struct AVS2Decoder_s *dec, int width, int height) {
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- uint32_t size;
- if (mv_buf_dynamic_alloc == 1) {
- int mv_mem_unit =
- avs2_dec->lcu_size_log2 == 6 ? 0x200 : avs2_dec->lcu_size_log2 ==
- 5 ? 0x80 : 0x20;
- int extended_pic_width = (width + avs2_dec->lcu_size -1)
- & (~(avs2_dec->lcu_size - 1));
- int extended_pic_height = (height + avs2_dec->lcu_size -1)
- & (~(avs2_dec->lcu_size - 1));
- int lcu_x_num = extended_pic_width / avs2_dec->lcu_size;
- int lcu_y_num = extended_pic_height / avs2_dec->lcu_size;
- int new_size = lcu_x_num * lcu_y_num * mv_mem_unit;
- size = (new_size + 0xffff) & (~0xffff);
-
- } else {
- if (IS_8K_SIZE(width, height))
- size = CO_MV_BUF_SIZE_8K;
- else if (IS_4K_SIZE(width, height))
- size = CO_MV_BUF_SIZE_4K;
- else
- size = CO_MV_BUF_SIZE_1080P;
- }
- return size;
-}
-#endif
-
-/*Losless compression body buffer size 4K per 64x32 (jt)*/
-static int compute_losless_comp_body_size(struct AVS2Decoder_s *dec,
- int width, int height,
- uint8_t is_bit_depth_10)
-{
- int width_x64;
- int height_x32;
- int bsize;
- width_x64 = width + 63;
- width_x64 >>= 6;
- height_x32 = height + 31;
- height_x32 >>= 5;
-#ifdef AVS2_10B_MMU
- bsize = (is_bit_depth_10 ? 4096 : 3200)
- * width_x64 * height_x32;
-#else
- bsize = (is_bit_depth_10 ? 4096 : 3072)
- * width_x64 * height_x32;
-#endif
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s(%d,%d,%d)=>%d\n",
- __func__, width, height,
- is_bit_depth_10, bsize);
-
- return bsize;
-}
-
-/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
-static int compute_losless_comp_header_size(struct AVS2Decoder_s *dec,
- int width, int height)
-{
- int width_x128;
- int height_x64;
- int hsize;
- width_x128 = width + 127;
- width_x128 >>= 7;
- height_x64 = height + 63;
- height_x64 >>= 6;
-
- hsize = 32 * width_x128 * height_x64;
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s(%d,%d)=>%d\n",
- __func__, width, height,
- hsize);
-
- return hsize;
-}
-
-static void init_buff_spec(struct AVS2Decoder_s *dec,
- struct BuffInfo_s *buf_spec)
-{
- void *mem_start_virt;
-
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
- buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
- buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
- buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
- buf_spec->rcs.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
- buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->rcs.buf_start + buf_spec->rcs.buf_size);
- buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
- buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
- buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
- buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
- buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
- buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
- buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
- buf_spec->dblk_data2.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
-#ifdef AVS2_10B_MMU
- buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
-#endif
-#ifdef MV_USE_FIXED_BUF
- buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
-#else
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
-#endif
- buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
- buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
-
- if (dec) {
- mem_start_virt =
- codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
- if (mem_start_virt) {
- memset(mem_start_virt, 0, buf_spec->dblk_para.buf_size);
- codec_mm_dma_flush(mem_start_virt,
- buf_spec->dblk_para.buf_size,
- DMA_TO_DEVICE);
- } else {
- /*not virt for tvp playing,
- may need clear on ucode.*/
- pr_err("mem_start_virt failed\n");
- }
- if (debug) {
- pr_info("%s workspace (%x %x) size = %x\n", __func__,
- buf_spec->start_adr, buf_spec->end_adr,
- buf_spec->end_adr - buf_spec->start_adr);
- }
- if (debug) {
- pr_info("ipp.buf_start :%x\n",
- buf_spec->ipp.buf_start);
- pr_info("sao_abv.buf_start :%x\n",
- buf_spec->sao_abv.buf_start);
- pr_info("sao_vb.buf_start :%x\n",
- buf_spec->sao_vb.buf_start);
- pr_info("short_term_rps.buf_start :%x\n",
- buf_spec->short_term_rps.buf_start);
- pr_info("rcs.buf_start :%x\n",
- buf_spec->rcs.buf_start);
- pr_info("sps.buf_start :%x\n",
- buf_spec->sps.buf_start);
- pr_info("pps.buf_start :%x\n",
- buf_spec->pps.buf_start);
- pr_info("sao_up.buf_start :%x\n",
- buf_spec->sao_up.buf_start);
- pr_info("swap_buf.buf_start :%x\n",
- buf_spec->swap_buf.buf_start);
- pr_info("swap_buf2.buf_start :%x\n",
- buf_spec->swap_buf2.buf_start);
- pr_info("scalelut.buf_start :%x\n",
- buf_spec->scalelut.buf_start);
- pr_info("dblk_para.buf_start :%x\n",
- buf_spec->dblk_para.buf_start);
- pr_info("dblk_data.buf_start :%x\n",
- buf_spec->dblk_data.buf_start);
- pr_info("dblk_data2.buf_start :%x\n",
- buf_spec->dblk_data2.buf_start);
- #ifdef AVS2_10B_MMU
- pr_info("mmu_vbh.buf_start :%x\n",
- buf_spec->mmu_vbh.buf_start);
- #endif
- pr_info("mpred_above.buf_start :%x\n",
- buf_spec->mpred_above.buf_start);
-#ifdef MV_USE_FIXED_BUF
- pr_info("mpred_mv.buf_start :%x\n",
- buf_spec->mpred_mv.buf_start);
-#endif
- if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
- pr_info("rpm.buf_start :%x\n",
- buf_spec->rpm.buf_start);
- }
- }
- }
-
-}
-
-static void uninit_mmu_buffers(struct AVS2Decoder_s *dec)
-{
-#if 0
-/*ndef MV_USE_FIXED_BUF*/
- dealloc_mv_bufs(dec);
-#endif
- decoder_mmu_box_free(dec->mmu_box);
- dec->mmu_box = NULL;
-
- if (dec->bmmu_box)
- decoder_bmmu_box_free(dec->bmmu_box);
- dec->bmmu_box = NULL;
-}
-
-#ifndef AVS2_10B_MMU
-static void init_buf_list(struct AVS2Decoder_s *dec)
-{
- int i;
- int buf_size;
- int mc_buffer_end = dec->mc_buf->buf_start + dec->mc_buf->buf_size;
- dec->used_buf_num = max_buf_num;
-
- if (dec->used_buf_num > MAX_BUF_NUM)
- dec->used_buf_num = MAX_BUF_NUM;
- if (buf_alloc_size > 0) {
- buf_size = buf_alloc_size;
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "[Buffer Management] init_buf_list:\n");
- } else {
- int pic_width = dec->init_pic_w;
- int pic_height = dec->init_pic_h;
-
- /*SUPPORT_10BIT*/
- int losless_comp_header_size = compute_losless_comp_header_size
- (dec, pic_width, pic_height);
- int losless_comp_body_size = compute_losless_comp_body_size
- (dec, pic_width, pic_height, buf_alloc_depth == 10);
- int mc_buffer_size = losless_comp_header_size
- + losless_comp_body_size;
- int mc_buffer_size_h = (mc_buffer_size + 0xffff)>>16;
-
- int dw_mode = get_double_write_mode_init(dec);
-
- if (dw_mode) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
- int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
- int lcu_size = 64; /*fixed 64*/
- int pic_width_64 = (pic_width_dw + 63) & (~0x3f);
- int pic_height_32 = (pic_height_dw + 31) & (~0x1f);
- int pic_width_lcu =
- (pic_width_64 % lcu_size) ? pic_width_64 / lcu_size
- + 1 : pic_width_64 / lcu_size;
- int pic_height_lcu =
- (pic_height_32 % lcu_size) ? pic_height_32 / lcu_size
- + 1 : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
- int mc_buffer_size_u_v = lcu_total * lcu_size * lcu_size / 2;
- int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
- } else
- buf_size = 0;
-
- if (mc_buffer_size & 0xffff) { /*64k alignment*/
- mc_buffer_size_h += 1;
- }
- if ((dw_mode & 0x10) == 0)
- buf_size += (mc_buffer_size_h << 16);
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "init_buf_list num %d (width %d height %d):\n",
- dec->used_buf_num, pic_width, pic_height);
- }
-
- for (i = 0; i < dec->used_buf_num; i++) {
- if (((i + 1) * buf_size) > dec->mc_buf->buf_size)
- dec->use_cma_flag = 1;
-#ifndef AVS2_10B_MMU
- dec->m_BUF[i].alloc_flag = 0;
- dec->m_BUF[i].index = i;
-
- dec->use_cma_flag = 1;
- if (dec->use_cma_flag) {
- dec->m_BUF[i].cma_page_count =
- PAGE_ALIGN(buf_size) / PAGE_SIZE;
- if (decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
- VF_BUFFER_IDX(i), buf_size, DRIVER_NAME,
- &dec->m_BUF[i].alloc_addr) < 0) {
- dec->m_BUF[i].cma_page_count = 0;
- if (i <= 5) {
- dec->fatal_error |=
- DECODER_FATAL_ERROR_NO_MEM;
- }
- break;
- }
- dec->m_BUF[i].start_adr = dec->m_BUF[i].alloc_addr;
- } else {
- dec->m_BUF[i].cma_page_count = 0;
- dec->m_BUF[i].alloc_addr = 0;
- dec->m_BUF[i].start_adr =
- dec->mc_buf->buf_start + i * buf_size;
- }
- dec->m_BUF[i].size = buf_size;
- dec->m_BUF[i].free_start_adr = dec->m_BUF[i].start_adr;
-
- if (((dec->m_BUF[i].start_adr + buf_size) > mc_buffer_end)
- && (dec->m_BUF[i].alloc_addr == 0)) {
- if (debug) {
- avs2_print(dec, 0,
- "Max mc buffer or mpred_mv buffer is used\n");
- }
- break;
- }
-
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "Buffer %d: start_adr %p size %x\n", i,
- (void *)dec->m_BUF[i].start_adr,
- dec->m_BUF[i].size);
-#endif
- }
- dec->buf_num = i;
-}
-#endif
-
-static int config_pic(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic, int32_t lcu_size_log2)
-{
- int ret = -1;
- int i;
- int pic_width = dec->init_pic_w;
- int pic_height = dec->init_pic_h;
- /*struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- int32_t lcu_size_log2 = avs2_dec->lcu_size_log2;*/
- int32_t lcu_size = 1 << lcu_size_log2;
- int pic_width_64 = (pic_width + 63) & (~0x3f);
- int pic_height_32 = (pic_height + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1
- : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1
- : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
-#if 0
- int32_t MV_MEM_UNIT =
- (lcu_size_log2 == 6) ? 0x200 :
- ((lcu_size_log2 == 5) ? 0x80 : 0x20);
-#endif
-#ifdef MV_USE_FIXED_BUF
- u32 mpred_mv_end = dec->work_space_buf->mpred_mv.buf_start +
- dec->work_space_buf->mpred_mv.buf_size;
-#endif
- u32 y_adr = 0;
- int buf_size = 0;
-
- int losless_comp_header_size =
- compute_losless_comp_header_size(
- dec, pic_width, pic_height);
- int losless_comp_body_size = compute_losless_comp_body_size(
- dec, pic_width,
- pic_height, buf_alloc_depth == 10);
- int mc_buffer_size = losless_comp_header_size + losless_comp_body_size;
- int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16;
- int mc_buffer_size_u_v = 0;
- int mc_buffer_size_u_v_h = 0;
- int dw_mode = get_double_write_mode_init(dec);
-
- if (dw_mode) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
- int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
- int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
- int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
- int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ?
- pic_width_64_dw / lcu_size + 1
- : pic_width_64_dw / lcu_size;
- int pic_height_lcu_dw = (pic_height_32_dw % lcu_size) ?
- pic_height_32_dw / lcu_size + 1
- : pic_height_32_dw / lcu_size;
- int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
-
- mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2;
- mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
- buf_size = ((buf_size + 0xffff) >> 16) << 16;
- }
- if (mc_buffer_size & 0xffff) /*64k alignment*/
- mc_buffer_size_h += 1;
-#ifndef AVS2_10B_MMU
- if ((dw_mode & 0x10) == 0)
- buf_size += (mc_buffer_size_h << 16);
-#endif
-
-#ifdef AVS2_10B_MMU
-#ifndef DYNAMIC_ALLOC_HEAD
- pic->header_adr = decoder_bmmu_box_get_phy_addr(
- dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "buf_size %d, MMU header_adr %d: %ld\n",
- buf_size, pic->index, pic->header_adr);
-#endif
-#endif
-
- i = pic->index;
-#ifdef MV_USE_FIXED_BUF
-#ifdef G12A_BRINGUP_DEBUG
- if (1) {
-#else
- if ((dec->work_space_buf->mpred_mv.buf_start +
- (((i + 1) * lcu_total) * MV_MEM_UNIT))
- <= mpred_mv_end
- ) {
-#endif
-#endif
-#ifndef AVS2_10B_MMU
- if (debug) {
- pr_err("start %x .size=%d\n",
- dec->mc_buf_spec.buf_start + i * buf_size,
- buf_size);
- }
-#endif
-#ifndef AVS2_10B_MMU
- for (i = 0; i < dec->buf_num; i++) {
- y_adr = ((dec->m_BUF[i].free_start_adr
- + 0xffff) >> 16) << 16;
- /*64k alignment*/
- if ((y_adr+buf_size) <= (dec->m_BUF[i].start_adr+
- dec->m_BUF[i].size)) {
- dec->m_BUF[i].free_start_adr =
- y_adr + buf_size;
- break;
- }
- }
- if (i < dec->buf_num)
-#else
- /*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
- dec->mc_buf->buf_end)
- y_adr = dec->mc_buf->buf_start + i * buf_size;
- else {*/
- if (buf_size > 0 && pic->cma_alloc_addr == 0) {
- ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
- VF_BUFFER_IDX(i),
- buf_size, DRIVER_NAME,
- &pic->cma_alloc_addr);
- if (ret < 0) {
- avs2_print(dec, 0,
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return ret;
- }
-
- if (pic->cma_alloc_addr)
- y_adr = pic->cma_alloc_addr;
- else {
- avs2_print(dec, 0,
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return -1;
- }
- }
-#endif
- {
- /*ensure get_pic_by_POC()
- not get the buffer not decoded*/
- pic->BUF_index = i;
- pic->lcu_total = lcu_total;
-
- pic->comp_body_size = losless_comp_body_size;
- pic->buf_size = buf_size;
-#ifndef AVS2_10B_MMU
- pic->mc_y_adr = y_adr;
-#endif
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
-#ifndef AVS2_10B_MMU
- if (dw_mode & 0x10) {
- pic->mc_u_v_adr = y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
-
- pic->mc_canvas_y =
- (pic->index << 1);
- pic->mc_canvas_u_v =
- (pic->index << 1) + 1;
-
- pic->dw_y_adr = y_adr;
- pic->dw_u_v_adr = pic->mc_u_v_adr;
- } else
-#endif
- if (dw_mode) {
- pic->dw_y_adr = y_adr
-#ifndef AVS2_10B_MMU
- + (mc_buffer_size_h << 16)
-#endif
- ;
- pic->dw_u_v_adr = pic->dw_y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
-#ifdef AVS2_10B_MMU
- pic->mc_y_adr = pic->dw_y_adr;
- pic->mc_u_v_adr = pic->dw_u_v_adr;
-#endif
- }
-#ifdef MV_USE_FIXED_BUF
-#ifdef G12A_BRINGUP_DEBUG
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start +
- (pic->index * 0x120000 * 4);
- } else {
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start +
- (pic->index * 0x120000);
- }
-#else
- pic->mpred_mv_wr_start_addr =
- dec->work_space_buf->mpred_mv.buf_start +
- ((pic->index * lcu_total)
- * MV_MEM_UNIT);
-#endif
-#endif
- if (debug) {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index %d BUF_index %d mc_y_adr %x ",
- __func__, pic->index,
- pic->BUF_index,
- pic->mc_y_adr);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "comp_body_size %x comp_buf_size %x ",
- pic->comp_body_size,
- pic->buf_size);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "mpred_mv_wr_start_adr %d\n",
- pic->mpred_mv_wr_start_addr);
- avs2_print_cont(dec, AVS2_DBG_BUFMGR,
- "dw_y_adr %d, pic->dw_u_v_adr =%d\n",
- pic->dw_y_adr,
- pic->dw_u_v_adr);
- }
- ret = 0;
- }
-#ifdef MV_USE_FIXED_BUF
- } else {
- avs2_print(dec, 0,
- "mv buffer alloc fail %x > %x\n",
- dec->work_space_buf->mpred_mv.buf_start +
- (((i + 1) * lcu_total) * MV_MEM_UNIT),
- mpred_mv_end);
- }
-#endif
- return ret;
-}
-
-static void init_pic_list(struct AVS2Decoder_s *dec,
- int32_t lcu_size_log2)
-{
- int i;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic;
-#ifdef AVS2_10B_MMU
- unsigned long buf_addr1;
- /*alloc AVS2 compress header first*/
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- HEADER_BUFFER_IDX(-1), get_compress_header_size(dec),
- DRIVER_HEADER_NAME,
- &buf_addr1) < 0){
- avs2_print(dec, 0,
- "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, -1);
- dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
-#ifndef DYNAMIC_ALLOC_HEAD
- for (i = 0; i < dec->used_buf_num; i++) {
- unsigned long buf_addr;
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- HEADER_BUFFER_IDX(i), get_compress_header_size(dec),
- DRIVER_HEADER_NAME,
- &buf_addr) < 0){
- avs2_print(dec, 0,
- "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, i);
- dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
- }
-#endif
-#endif
- dec->frame_height = avs2_dec->img.height;
- dec->frame_width = avs2_dec->img.width;
-
- for (i = 0; i < dec->used_buf_num; i++) {
- if (i == (dec->used_buf_num - 1))
- pic = avs2_dec->m_bg;
- else
- pic = avs2_dec->fref[i];
- pic->index = i;
- pic->BUF_index = -1;
- pic->mv_buf_index = -1;
- if (config_pic(dec, pic, lcu_size_log2) < 0) {
- if (debug)
- avs2_print(dec, 0,
- "Config_pic %d fail\n",
- pic->index);
- pic->index = -1;
- break;
- }
- pic->pic_w = avs2_dec->img.width;
- pic->pic_h = avs2_dec->img.height;
- }
- for (; i < dec->used_buf_num; i++) {
- if (i == (dec->used_buf_num - 1))
- pic = avs2_dec->m_bg;
- else
- pic = avs2_dec->fref[i];
- pic->index = -1;
- pic->BUF_index = -1;
- pic->mv_buf_index = -1;
- }
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s ok, used_buf_num = %d\n",
- __func__, dec->used_buf_num);
- dec->pic_list_init_flag = 1;
-}
-
-
-static void init_pic_list_hw(struct AVS2Decoder_s *dec)
-{
- int i;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic;
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
-#if 0
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-
-#ifdef DUAL_CORE_64
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-#endif
-#endif
- for (i = 0; i < dec->used_buf_num; i++) {
- if (i == (dec->used_buf_num - 1))
- pic = avs2_dec->m_bg;
- else
- pic = avs2_dec->fref[i];
- if (pic->index < 0)
- break;
-#ifdef AVS2_10B_MMU
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->header_adr
- | (pic->mc_canvas_y << 8)|0x1);*/
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (pic->index << 8));
-
-#ifdef DUAL_CORE_64
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXLX2)
- WRITE_VREG(HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (pic->index << 8));
- else
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (pic->index << 8));
-#endif
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
-#else
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->mc_y_adr
- | (pic->mc_canvas_y << 8) | 0x1);*/
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
-#endif
-#ifndef LOSLESS_COMPRESS_MODE
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- pic->mc_u_v_adr
- | (pic->mc_canvas_u_v << 8)| 0x1);*/
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
-#endif
-#ifdef DUAL_CORE_64
-#ifdef AVS2_10B_MMU
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->header_adr >> 5);
-#else
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->mc_y_adr >> 5);
-#endif
-#ifndef LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic->mc_u_v_adr >> 5);
-#endif
-/*DUAL_CORE_64*/
-#endif
- }
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-#ifdef DUAL_CORE_64
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- 0x1);
-#endif
- /*Zero out canvas registers in IPP -- avoid simulation X*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
- for (i = 0; i < 32; i++) {
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
-#ifdef DUAL_CORE_64
- WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
-#endif
- }
-}
-
-
-static void dump_pic_list(struct AVS2Decoder_s *dec)
-{
- int ii;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- for (ii = 0; ii < avs2_dec->ref_maxbuffer; ii++) {
- avs2_print(dec, 0,
- "fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d refered %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d)\n",
- ii, avs2_dec->fref[ii]->index,
- avs2_dec->fref[ii]->decode_idx,
- avs2_dec->fref[ii]->mv_buf_index,
- avs2_dec->fref[ii]->imgcoi_ref,
- avs2_dec->fref[ii]->imgtr_fwRefDistance,
- avs2_dec->fref[ii]->refered_by_others,
- avs2_dec->fref[ii]->to_prepare_disp,
- avs2_dec->fref[ii]->is_output,
- avs2_dec->fref[ii]->bg_flag,
- avs2_dec->fref[ii]->vf_ref,
- avs2_dec->fref[ii]->error_mark,
- avs2_dec->fref[ii]->decoded_lcu,
- avs2_dec->fref[ii]->ref_poc[0],
- avs2_dec->fref[ii]->ref_poc[1],
- avs2_dec->fref[ii]->ref_poc[2],
- avs2_dec->fref[ii]->ref_poc[3],
- avs2_dec->fref[ii]->ref_poc[4],
- avs2_dec->fref[ii]->ref_poc[5],
- avs2_dec->fref[ii]->ref_poc[6]
- );
- }
- return;
-}
-
-static int config_mc_buffer(struct AVS2Decoder_s *dec)
-{
- int32_t i;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
-
- /*if (avs2_dec->img.type == I_IMG)
- return 0;
- */
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "Entered config_mc_buffer....\n");
- if (avs2_dec->f_bg != NULL) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
- avs2_dec->f_bg->mc_canvas_y, avs2_dec->f_bg->mc_canvas_u_v);
- /*WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (7 << 8) | (0<<1) | 1); L0:BG */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (15 << 8) | (0<<1) | 1); /* L0:BG*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (avs2_dec->f_bg->mc_canvas_u_v << 16) |
- (avs2_dec->f_bg->mc_canvas_u_v << 8) |
- avs2_dec->f_bg->mc_canvas_y);
- /*WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (23 << 8) | (0<<1) | 1); L1:BG*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (31 << 8) | (0<<1) | 1); /* L1:BG*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (avs2_dec->f_bg->mc_canvas_u_v << 16) |
- (avs2_dec->f_bg->mc_canvas_u_v << 8) |
- avs2_dec->f_bg->mc_canvas_y);
- }
-
- if (avs2_dec->img.type == I_IMG)
- return 0;
-
- if (avs2_dec->img.type == P_IMG) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "config_mc_buffer for P_IMG, img type %d\n",
- avs2_dec->img.type);
- /*refer to prepare_RefInfo()*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0<<1) | 1);
- for (i = 0; i < avs2_dec->img.num_of_references; i++) {
- pic = avs2_dec->fref[i];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16) |
- (pic->mc_canvas_u_v << 8) |
- pic->mc_canvas_y);
-
- if (pic->error_mark)
- cur_pic->error_mark = 1;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
- i, pic->mc_canvas_u_v, pic->mc_canvas_y,
- pic->error_mark);
- }
- } else if (avs2_dec->img.type == F_IMG) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "config_mc_buffer for F_IMG, img type %d\n",
- avs2_dec->img.type);
- /*refer to prepare_RefInfo()*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0<<1) | 1);
- for (i = 0; i < avs2_dec->img.num_of_references; i++) {
- pic = avs2_dec->fref[i];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16) |
- (pic->mc_canvas_u_v << 8) |
- pic->mc_canvas_y);
-
- if (pic->error_mark)
- cur_pic->error_mark = 1;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
- i, pic->mc_canvas_u_v, pic->mc_canvas_y,
- pic->error_mark);
- }
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (0<<1) | 1);
- for (i = 0; i < avs2_dec->img.num_of_references; i++) {
- pic = avs2_dec->fref[i];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16) |
- (pic->mc_canvas_u_v << 8) |
- pic->mc_canvas_y);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x\n",
- i, pic->mc_canvas_u_v, pic->mc_canvas_y);
- }
- } else {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "config_mc_buffer for B_IMG\n");
- /*refer to prepare_RefInfo()*/
- pic = avs2_dec->fref[1];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0<<1) | 1);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16) |
- (pic->mc_canvas_u_v << 8) |
- pic->mc_canvas_y);
-
- if (pic->error_mark)
- cur_pic->error_mark = 1;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
- 1, pic->mc_canvas_u_v, pic->mc_canvas_y,
- pic->error_mark);
-
- pic = avs2_dec->fref[0];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (0<<1) | 1);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v<<16) |
- (pic->mc_canvas_u_v<<8) |
- pic->mc_canvas_y);
-
- if (pic->error_mark)
- cur_pic->error_mark = 1;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "refid %x mc_canvas_u_v %x mc_canvas_y %x error_mark %x\n",
- 0, pic->mc_canvas_u_v, pic->mc_canvas_y,
- pic->error_mark);
- }
- return 0;
-}
-#if 0
-static void mcrcc_get_hitrate(void)
-{
- u32 tmp;
- u32 raw_mcr_cnt;
- u32 hit_mcr_cnt;
- u32 byp_mcr_cnt_nchoutwin;
- u32 byp_mcr_cnt_nchcanv;
- int hitrate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered mcrcc_get_hitrate...\n");
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
- byp_mcr_cnt_nchoutwin = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
- byp_mcr_cnt_nchcanv = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("raw_mcr_cnt_total: %d\n",raw_mcr_cnt);
- pr_info("hit_mcr_cnt_total: %d\n",hit_mcr_cnt);
- pr_info("byp_mcr_cnt_nchoutwin_total: %d\n",byp_mcr_cnt_nchoutwin);
- pr_info("byp_mcr_cnt_nchcanv_total: %d\n",byp_mcr_cnt_nchcanv);
- }
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("miss_mcr_0_cnt_total: %d\n", tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("miss_mcr_1_cnt_total: %d\n", tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("hit_mcr_0_cnt_total: %d\n",tmp);
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
- tmp= READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE)
- pr_info("hit_mcr_1_cnt_total: %d\n",tmp);
-
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("MCRCC_HIT_RATE : %d\n", hitrate);
- hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)
- /raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("MCRCC_BYP_RATE : %d\n", hitrate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("MCRCC_HIT_RATE : na\n");
- pr_info("MCRCC_BYP_RATE : na\n");
- }
- return;
-}
-
-
-static void decomp_get_hitrate(void)
-{
- u32 raw_mcr_cnt;
- u32 hit_mcr_cnt;
- int hitrate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_hitrate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
- pr_info("hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
- }
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
- } else {
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : na\n");
- }
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & AVS2_DBG_CACHE) {
- pr_info("dcache_raw_cnt_total: %d\n", raw_mcr_cnt);
- pr_info("dcache_hit_cnt_total: %d\n", hit_mcr_cnt);
- }
- if (raw_mcr_cnt != 0) {
- hitrate = (hit_mcr_cnt / raw_mcr_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("DECOMP_DCACHE_HIT_RATE : na\n");
- }
-return;
-}
-
-static void decomp_get_comprate(void)
-{
- u32 raw_ucomp_cnt;
- u32 fast_comp_cnt;
- u32 slow_comp_cnt;
- int comprate;
-
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_comprate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
- fast_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
- slow_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
- raw_ucomp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- if (debug & AVS2_DBG_CACHE) {
- pr_info("decomp_fast_comp_total: %d\n", fast_comp_cnt);
- pr_info("decomp_slow_comp_total: %d\n", slow_comp_cnt);
- pr_info("decomp_raw_uncomp_total: %d\n", raw_ucomp_cnt);
- }
-
- if (raw_ucomp_cnt != 0) {
- comprate = ((fast_comp_cnt + slow_comp_cnt)
- / raw_ucomp_cnt) * 100;
- if (debug & AVS2_DBG_CACHE)
- pr_info("DECOMP_COMP_RATIO : %d\n", comprate);
- } else if (debug & AVS2_DBG_CACHE) {
- pr_info("DECOMP_COMP_RATIO : na\n");
- }
- return;
-}
-#endif
-
-static void config_mcrcc_axi_hw(struct AVS2Decoder_s *dec)
-{
- uint32_t rdata32;
- uint32_t rdata32_2;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); /* reset mcrcc*/
-
- if (avs2_dec->img.type == I_IMG) { /* I-PIC*/
- /* remove reset -- disables clock */
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
- return;
- }
-/*
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- mcrcc_get_hitrate();
- decomp_get_hitrate();
- decomp_get_comprate();
- }
-*/
- if ((avs2_dec->img.type == B_IMG) ||
- (avs2_dec->img.type == F_IMG)) { /*B-PIC or F_PIC*/
- /*Programme canvas0 */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- /*Programme canvas1 */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (1 << 1) | 0);
- rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- if (rdata32 == rdata32_2) {
- rdata32_2 =
- READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- }
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32_2);
- } else { /* P-PIC */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (1 << 1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- /*Programme canvas1*/
- rdata32 =
- READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- }
- /*enable mcrcc progressive-mode */
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);
- return;
-}
-
-static void config_mpred_hw(struct AVS2Decoder_s *dec)
-{
- uint32_t data32;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
- struct avs2_frame_s *col_pic = avs2_dec->fref[0];
- int32_t mpred_mv_rd_start_addr;
- int32_t mpred_curr_lcu_x;
- int32_t mpred_curr_lcu_y;
- int32_t mpred_mv_rd_end_addr;
- int32_t above_en;
- int32_t mv_wr_en;
- int32_t mv_rd_en;
- int32_t col_isIntra;
- int mv_mem_unit;
- if (avs2_dec->img.type != I_IMG) {
- above_en = 1;
- mv_wr_en = 1;
- mv_rd_en = 1;
- col_isIntra = 0;
- } else {
- above_en = 1;
- mv_wr_en = 1;
- mv_rd_en = 0;
- col_isIntra = 0;
- }
-
- mpred_mv_rd_start_addr =
- col_pic->mpred_mv_wr_start_addr;
- data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
- mpred_curr_lcu_x = data32 & 0xffff;
- mpred_curr_lcu_y = (data32 >> 16) & 0xffff;
-
- mv_mem_unit = avs2_dec->lcu_size_log2 == 6 ?
- 0x200 : (avs2_dec->lcu_size_log2 == 5 ?
- 0x80 : 0x20);
-
- mpred_mv_rd_end_addr =
- mpred_mv_rd_start_addr +
- ((avs2_dec->lcu_x_num *
- avs2_dec->lcu_y_num) * mv_mem_unit);
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "cur pic index %d col pic index %d\n",
- cur_pic->index, col_pic->index);
-
-
- WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
- cur_pic->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
- col_pic->mpred_mv_wr_start_addr);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[MPRED CO_MV] write 0x%x read 0x%x\n",
- cur_pic->mpred_mv_wr_start_addr,
- col_pic->mpred_mv_wr_start_addr);
-
- data32 =
- ((avs2_dec->bk_img_is_top_field) << 13) |
- ((avs2_dec->hd.background_picture_enable & 1) << 12) |
- ((avs2_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
- ((avs2_dec->hd.b_pmvr_enabled & 1) << 6) |
- ((avs2_dec->img.is_top_field & 1) << 5) |
- ((avs2_dec->img.is_field_sequence & 1) << 4) |
- ((avs2_dec->img.typeb & 7) << 1) |
- (avs2_dec->hd.background_reference_enable & 0x1);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n",
- data32, avs2_dec->hd.curr_RPS.num_of_ref);
- WRITE_VREG(HEVC_MPRED_CTRL9, data32);
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "%s: dis %d %d %d %d %d %d %d fref0_ref_poc %d %d %d %d %d %d %d\n",
- __func__,
- avs2_dec->fref[0]->imgtr_fwRefDistance,
- avs2_dec->fref[1]->imgtr_fwRefDistance,
- avs2_dec->fref[2]->imgtr_fwRefDistance,
- avs2_dec->fref[3]->imgtr_fwRefDistance,
- avs2_dec->fref[4]->imgtr_fwRefDistance,
- avs2_dec->fref[5]->imgtr_fwRefDistance,
- avs2_dec->fref[6]->imgtr_fwRefDistance,
- avs2_dec->fref[0]->ref_poc[0],
- avs2_dec->fref[0]->ref_poc[1],
- avs2_dec->fref[0]->ref_poc[2],
- avs2_dec->fref[0]->ref_poc[3],
- avs2_dec->fref[0]->ref_poc[4],
- avs2_dec->fref[0]->ref_poc[5],
- avs2_dec->fref[0]->ref_poc[6]
- );
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "pic_distance %d, imgtr_next_P %d\n",
- avs2_dec->img.pic_distance, avs2_dec->img.imgtr_next_P);
-
-
- WRITE_VREG(HEVC_MPRED_CUR_POC, avs2_dec->img.pic_distance);
- WRITE_VREG(HEVC_MPRED_COL_POC, avs2_dec->img.imgtr_next_P);
-
- /*below MPRED Ref_POC_xx_Lx registers
- must follow Ref_POC_xx_L0 ->
- Ref_POC_xx_L1 in pair write order!!!*/
- WRITE_VREG(HEVC_MPRED_L0_REF00_POC,
- avs2_dec->fref[0]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF00_POC,
- avs2_dec->fref[0]->ref_poc[0]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF01_POC,
- avs2_dec->fref[1]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF01_POC,
- avs2_dec->fref[0]->ref_poc[1]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF02_POC,
- avs2_dec->fref[2]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF02_POC,
- avs2_dec->fref[0]->ref_poc[2]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF03_POC,
- avs2_dec->fref[3]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF03_POC,
- avs2_dec->fref[0]->ref_poc[3]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF04_POC,
- avs2_dec->fref[4]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF04_POC,
- avs2_dec->fref[0]->ref_poc[4]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF05_POC,
- avs2_dec->fref[5]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF05_POC,
- avs2_dec->fref[0]->ref_poc[5]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF06_POC,
- avs2_dec->fref[6]->imgtr_fwRefDistance);
- WRITE_VREG(HEVC_MPRED_L1_REF06_POC,
- avs2_dec->fref[0]->ref_poc[6]);
-
-
- WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,
- mpred_mv_rd_end_addr);
-}
-
-static void config_dblk_hw(struct AVS2Decoder_s *dec)
-{
- /*
- * Picture level de-block parameter configuration here
- */
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- union param_u *rpm_param = &avs2_dec->param;
- uint32_t data32;
-
- data32 = READ_VREG(HEVC_DBLK_CFG1);
- data32 = (((data32 >> 20) & 0xfff) << 20) |
- (((avs2_dec->input.sample_bit_depth == 10)
- ? 0xa : 0x0) << 16) | /*[16 +: 4]: {luma_bd[1:0],
- chroma_bd[1:0]}*/
- (((data32 >> 2) & 0x3fff) << 2) |
- (((rpm_param->p.lcu_size == 6)
- ? 0 : (rpm_param->p.lcu_size == 5)
- ? 1 : 2) << 0);/*[ 0 +: 2]: lcu_size*/
- WRITE_VREG(HEVC_DBLK_CFG1, data32);
-
- data32 = (avs2_dec->img.height << 16) |
- avs2_dec->img.width;
- WRITE_VREG(HEVC_DBLK_CFG2, data32);
- /*
- [27 +: 1]: cross_slice_loopfilter_enable_flag
- [26 +: 1]: loop_filter_disable
- [25 +: 1]: useNSQT
- [22 +: 3]: imgtype
- [17 +: 5]: alpha_c_offset (-8~8)
- [12 +: 5]: beta_offset (-8~8)
- [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
- [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
- */
- data32 = ((avs2_dec->input.crossSliceLoopFilter
- & 0x1) << 27) |
- ((rpm_param->p.loop_filter_disable & 0x1) << 26) |
- ((avs2_dec->input.useNSQT & 0x1) << 25) |
- ((avs2_dec->img.type & 0x7) << 22) |
- ((rpm_param->p.alpha_c_offset & 0x1f) << 17) |
- ((rpm_param->p.beta_offset & 0x1f) << 12) |
- ((rpm_param->p.chroma_quant_param_delta_cb & 0x3f) << 6) |
- ((rpm_param->p.chroma_quant_param_delta_cr & 0x3f) << 0);
-
- WRITE_VREG(HEVC_DBLK_CFG9, data32);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d),lcuSize(%d),NSQT(%d)\n",
- avs2_dec->input.crossSliceLoopFilter,
- rpm_param->p.loop_filter_disable,
- avs2_dec->input.sample_bit_depth,
- avs2_dec->lcu_size,
- avs2_dec->input.useNSQT);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgDBLK: alphaCOffset(%d),betaOffset(%d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
- rpm_param->p.alpha_c_offset,
- rpm_param->p.beta_offset,
- rpm_param->p.chroma_quant_param_delta_cb,
- rpm_param->p.chroma_quant_param_delta_cr);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgDBLK: .done.\n");
-}
-
-static void config_sao_hw(struct AVS2Decoder_s *dec)
-{
- uint32_t data32;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
-
- int lcu_size = 64;
- int mc_buffer_size_u_v =
- cur_pic->lcu_total * lcu_size*lcu_size/2;
- int mc_buffer_size_u_v_h =
- (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
-
- data32 = READ_VREG(HEVC_SAO_CTRL0);
- data32 &= (~0xf);
- data32 |= avs2_dec->lcu_size_log2;
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "%s, lcu_size_log2 = %d, config HEVC_SAO_CTRL0 0x%x\n",
- __func__,
- avs2_dec->lcu_size_log2,
- data32);
-
- WRITE_VREG(HEVC_SAO_CTRL0, data32);
-
-#ifndef AVS2_10B_MMU
- if ((get_double_write_mode(dec) & 0x10) == 0)
- WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr);
-#endif
- if (get_double_write_mode(dec)) {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
- WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, cur_pic->dw_u_v_adr);
- } else {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
- }
-#ifdef AVS2_10B_MMU
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
-#endif
- data32 = (mc_buffer_size_u_v_h << 16) << 1;
- /*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
- data32, mc_buffer_size_u_v_h, cur_pic->lcu_total);*/
- WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
-
- data32 = (mc_buffer_size_u_v_h << 16);
- WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
-
-#ifdef AVS2_10B_NV21
-#ifdef DOS_PROJECT
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (MEM_MAP_MODE << 12);
- data32 &= (~0x3);
- data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
-
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
-
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
- /*[23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl
- [17:16] dw_h0_ctrl*/
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- ata32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (MEM_MAP_MODE << 4);
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#else
- /*m8baby test1902*/
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (MEM_MAP_MODE << 12);
- data32 &= (~0xff0);
- /*data32 |= 0x670;*/ /*Big-Endian per 64-bit*/
- data32 |= 0x880; /*.Big-Endian per 64-bit */
- data32 &= (~0x3);
- data32 |= 0x1; /*[1]:dw_disable [0]:cm_disable*/
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
- /* [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl
- [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl*/
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /* set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (MEM_MAP_MODE << 4);
- data32 &= (~0xF);
- data32 |= 0x8; /*Big-Endian per 64-bit*/
-
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
-#else
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~(3 << 14));
- data32 |= (2 << 14); /* line align with 64*/
- data32 &= (~0x3000);
- data32 |= (MEM_MAP_MODE << 12); /* [13:12] axi_aformat, 0-Linear,
- 1-32x32, 2-64x32 */
- data32 &= (~0xff0);
- data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
- data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
-#if 0
- if (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
- if (get_double_write_mode(dec) == 0)
- data32 |= 0x2; /*disable double write*/
-#ifndef AVS2_10B_MMU
- else
- if (get_double_write_mode(dec) & 0x10)
- data32 |= 0x1; /*disable cm*/
-#endif
- }
-#endif
- if (get_double_write_mode(dec) == 0)
- data32 |= 0x2; /*disable double write*/
- else if (get_double_write_mode(dec) & 0x10)
- data32 |= 0x1; /*disable cm*/
-
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- if (get_double_write_mode(dec) & 0x10) {
- /* [23:22] dw_v1_ctrl
- [21:20] dw_v0_ctrl
- [19:18] dw_h1_ctrl
- [17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- } else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 &= (~(0xff << 16));
- if (get_double_write_mode(dec) == 8 ||
- get_double_write_mode(dec) == 9) {
- data32 |= (0xff<<16);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else if (get_double_write_mode(dec) == 2 ||
- get_double_write_mode(dec) == 3)
- data32 |= (0xff<<16);
- else if (get_double_write_mode(dec) == 4)
- data32 |= (0x33<<16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (mem_map_mode << 4);
- data32 &= (~0xF);
- data32 |= (dec->endian & 0xf); /* valid only when double write only */
- /*data32 |= 0x8;*/ /* Big-Endian per 64-bit */
- data32 &= (~(3 << 8));
- data32 |= (2 << 8); /* line align with 64 for dw only */
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
-}
-
-static void reconstructCoefficients(struct AVS2Decoder_s *dec,
- struct ALFParam_s *alfParam)
-{
- int32_t g, sum, i, coeffPred;
- for (g = 0; g < alfParam->filters_per_group; g++) {
- sum = 0;
- for (i = 0; i < alfParam->num_coeff - 1; i++) {
- sum += (2 * alfParam->coeffmulti[g][i]);
- dec->m_filterCoeffSym[g][i] =
- alfParam->coeffmulti[g][i];
- /*pr_info("[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n",
- g, i, dec->m_filterCoeffSym[g][i]);*/
- }
- coeffPred = (1 << ALF_NUM_BIT_SHIFT) - sum;
- dec->m_filterCoeffSym[g][alfParam->num_coeff - 1]
- = coeffPred +
- alfParam->coeffmulti[g][alfParam->num_coeff - 1];
- /*pr_info("[t] dec->m_filterCoeffSym[%d][%d]=0x%x\n",
- g, (alfParam->num_coeff - 1),
- dec->m_filterCoeffSym[g][alfParam->num_coeff - 1]);*/
- }
-}
-
-static void reconstructCoefInfo(struct AVS2Decoder_s *dec,
- int32_t compIdx, struct ALFParam_s *alfParam)
-{
- int32_t i;
- if (compIdx == ALF_Y) {
- if (alfParam->filters_per_group > 1) {
- for (i = 1; i < NO_VAR_BINS; ++i) {
- if (alfParam->filterPattern[i])
- dec->m_varIndTab[i] =
- dec->m_varIndTab[i - 1] + 1;
- else
- dec->m_varIndTab[i] =
- dec->m_varIndTab[i - 1];
- }
- }
- }
- reconstructCoefficients(dec, alfParam);
-}
-
-static void config_alf_hw(struct AVS2Decoder_s *dec)
-{
- /*
- * Picture level ALF parameter configuration here
- */
- uint32_t data32;
- int32_t i, j;
- int32_t m_filters_per_group;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct ALFParam_s *m_alfPictureParam_y =
- &avs2_dec->m_alfPictureParam[0];
- struct ALFParam_s *m_alfPictureParam_cb =
- &avs2_dec->m_alfPictureParam[1];
- struct ALFParam_s *m_alfPictureParam_cr =
- &avs2_dec->m_alfPictureParam[2];
-
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filterPattern[0]=0x%x,[15]=0x%x\n",
- m_alfPictureParam_y->componentID,
- m_alfPictureParam_y->alf_flag,
- m_alfPictureParam_y->filters_per_group,
- m_alfPictureParam_y->filterPattern[0],
- m_alfPictureParam_y->filterPattern[15]);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[t]alfy,num_coeff(%d),coeffmulti[0][0]=0x%x,[0][1]=0x%x,[1][0]=0x%x,[1][1]=0x%x\n",
- m_alfPictureParam_y->num_coeff,
- m_alfPictureParam_y->coeffmulti[0][0],
- m_alfPictureParam_y->coeffmulti[0][1],
- m_alfPictureParam_y->coeffmulti[1][0],
- m_alfPictureParam_y->coeffmulti[1][1]);
-
- /*Cr*/
- for (i = 0; i < 16; i++)
- dec->m_varIndTab[i] = 0;
- for (j = 0; j < 16; j++)
- for (i = 0; i < 9; i++)
- dec->m_filterCoeffSym[j][i] = 0;
- reconstructCoefInfo(dec, 2, m_alfPictureParam_cr);
- data32 =
- ((dec->m_filterCoeffSym[0][4] & 0xf) << 28) |
- ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
- ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
- ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
- ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- data32 =
- ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
- ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
- ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
- ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
- (((dec->m_filterCoeffSym[0][4] >> 4) & 0x7) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] pic_alf_on_cr(%d), alf_cr_coef(%d %d %d %d %d %d %d %d %d)\n",
- m_alfPictureParam_cr->alf_flag,
- dec->m_filterCoeffSym[0][0],
- dec->m_filterCoeffSym[0][1],
- dec->m_filterCoeffSym[0][2],
- dec->m_filterCoeffSym[0][3],
- dec->m_filterCoeffSym[0][4],
- dec->m_filterCoeffSym[0][5],
- dec->m_filterCoeffSym[0][6],
- dec->m_filterCoeffSym[0][7],
- dec->m_filterCoeffSym[0][8]);
-
- /* Cb*/
- for (j = 0; j < 16; j++)
- for (i = 0; i < 9; i++)
- dec->m_filterCoeffSym[j][i] = 0;
- reconstructCoefInfo(dec, 1, m_alfPictureParam_cb);
- data32 =
- ((dec->m_filterCoeffSym[0][4] & 0xf) << 28) |
- ((dec->m_filterCoeffSym[0][3] & 0x7f) << 21) |
- ((dec->m_filterCoeffSym[0][2] & 0x7f) << 14) |
- ((dec->m_filterCoeffSym[0][1] & 0x7f) << 7) |
- ((dec->m_filterCoeffSym[0][0] & 0x7f) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- data32 =
- ((dec->m_filterCoeffSym[0][8] & 0x7f) << 24) |
- ((dec->m_filterCoeffSym[0][7] & 0x7f) << 17) |
- ((dec->m_filterCoeffSym[0][6] & 0x7f) << 10) |
- ((dec->m_filterCoeffSym[0][5] & 0x7f) << 3) |
- (((dec->m_filterCoeffSym[0][4] >> 4) & 0x7) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] pic_alf_on_cb(%d), alf_cb_coef(%d %d %d %d %d %d %d %d %d)\n",
- m_alfPictureParam_cb->alf_flag,
- dec->m_filterCoeffSym[0][0],
- dec->m_filterCoeffSym[0][1],
- dec->m_filterCoeffSym[0][2],
- dec->m_filterCoeffSym[0][3],
- dec->m_filterCoeffSym[0][4],
- dec->m_filterCoeffSym[0][5],
- dec->m_filterCoeffSym[0][6],
- dec->m_filterCoeffSym[0][7],
- dec->m_filterCoeffSym[0][8]);
-
- /* Y*/
- for (j = 0; j < 16; j++)
- for (i = 0; i < 9; i++)
- dec->m_filterCoeffSym[j][i] = 0;
- reconstructCoefInfo(dec, 0, m_alfPictureParam_y);
- data32 =
- ((dec->m_varIndTab[7] & 0xf) << 28) |
- ((dec->m_varIndTab[6] & 0xf) << 24) |
- ((dec->m_varIndTab[5] & 0xf) << 20) |
- ((dec->m_varIndTab[4] & 0xf) << 16) |
- ((dec->m_varIndTab[3] & 0xf) << 12) |
- ((dec->m_varIndTab[2] & 0xf) << 8) |
- ((dec->m_varIndTab[1] & 0xf) << 4) |
- ((dec->m_varIndTab[0] & 0xf) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- data32 = ((dec->m_varIndTab[15] & 0xf) << 28) |
- ((dec->m_varIndTab[14] & 0xf) << 24) |
- ((dec->m_varIndTab[13] & 0xf) << 20) |
- ((dec->m_varIndTab[12] & 0xf) << 16) |
- ((dec->m_varIndTab[11] & 0xf) << 12) |
- ((dec->m_varIndTab[10] & 0xf) << 8) |
- ((dec->m_varIndTab[9] & 0xf) << 4) |
- ((dec->m_varIndTab[8] & 0xf) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] pic_alf_on_y(%d), alf_y_tab(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)\n",
- m_alfPictureParam_y->alf_flag,
- dec->m_varIndTab[0],
- dec->m_varIndTab[1],
- dec->m_varIndTab[2],
- dec->m_varIndTab[3],
- dec->m_varIndTab[4],
- dec->m_varIndTab[5],
- dec->m_varIndTab[6],
- dec->m_varIndTab[7],
- dec->m_varIndTab[8],
- dec->m_varIndTab[9],
- dec->m_varIndTab[10],
- dec->m_varIndTab[11],
- dec->m_varIndTab[12],
- dec->m_varIndTab[13],
- dec->m_varIndTab[14],
- dec->m_varIndTab[15]);
-
- m_filters_per_group =
- (m_alfPictureParam_y->alf_flag == 0) ?
- 1 : m_alfPictureParam_y->filters_per_group;
- for (i = 0; i < m_filters_per_group; i++) {
- data32 =
- ((dec->m_filterCoeffSym[i][4] & 0xf) << 28) |
- ((dec->m_filterCoeffSym[i][3] & 0x7f) << 21) |
- ((dec->m_filterCoeffSym[i][2] & 0x7f) << 14) |
- ((dec->m_filterCoeffSym[i][1] & 0x7f) << 7) |
- ((dec->m_filterCoeffSym[i][0] & 0x7f) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- data32 =
- /*[31] last indication*/
- ((i == m_filters_per_group-1) << 31) |
- ((dec->m_filterCoeffSym[i][8] & 0x7f) << 24) |
- ((dec->m_filterCoeffSym[i][7] & 0x7f) << 17) |
- ((dec->m_filterCoeffSym[i][6] & 0x7f) << 10) |
- ((dec->m_filterCoeffSym[i][5] & 0x7f) << 3) |
- (((dec->m_filterCoeffSym[i][4] >> 4) & 0x7) << 0);
- WRITE_VREG(HEVC_DBLK_CFGD, data32);
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] alf_y_coef[%d](%d %d %d %d %d %d %d %d %d)\n",
- i, dec->m_filterCoeffSym[i][0],
- dec->m_filterCoeffSym[i][1],
- dec->m_filterCoeffSym[i][2],
- dec->m_filterCoeffSym[i][3],
- dec->m_filterCoeffSym[i][4],
- dec->m_filterCoeffSym[i][5],
- dec->m_filterCoeffSym[i][6],
- dec->m_filterCoeffSym[i][7],
- dec->m_filterCoeffSym[i][8]);
- }
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "[c] cfgALF .done.\n");
-}
-
-static void config_other_hw(struct AVS2Decoder_s *dec)
-{
- uint32_t data32;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
- int bit_depth = cur_pic->bit_depth;
- int losless_comp_header_size =
- compute_losless_comp_header_size(
- dec, cur_pic->pic_w,
- cur_pic->pic_h);
- int losless_comp_body_size =
- compute_losless_comp_body_size(
- dec, cur_pic->pic_w,
- cur_pic->pic_h, (bit_depth == AVS2_BITS_10));
- cur_pic->comp_body_size = losless_comp_body_size;
-
-#ifdef LOSLESS_COMPRESS_MODE
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- if (bit_depth == AVS2_BITS_10)
- data32 &= ~(1 << 9);
- else
- data32 |= (1 << 9);
-
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
-#ifdef AVS2_10B_MMU
- /*bit[4] : paged_mem_mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
-#else
- /*bit[3] smem mdoe*/
- if (bit_depth == AVS2_BITS_10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0 << 3));
- else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1 << 3));
-#endif
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
-}
-
-static u32 init_cuva_size;
-static int cuva_data_is_avaible(struct AVS2Decoder_s *dec)
-{
- u32 reg_val;
-
- reg_val = READ_VREG(AVS2_CUVA_DATA_SIZE);
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s:reg_val: %u \n",
- __func__, reg_val);
- if (reg_val != 0 && reg_val != init_cuva_size)
- return 1;
- else
- return 0;
-}
-
-static void config_cuva_buf(struct AVS2Decoder_s *dec)
-{
- WRITE_VREG(AVS2_CUVA_ADR, dec->cuva_phy_addr);
- init_cuva_size = (dec->cuva_size >> 4) << 16;
- WRITE_VREG(AVS2_CUVA_DATA_SIZE, init_cuva_size);
-}
-
-static void set_cuva_data(struct AVS2Decoder_s *dec)
-{
- int i;
- unsigned short *cuva_adr;
- unsigned int size_reg_val =
- READ_VREG(AVS2_CUVA_DATA_SIZE);
- unsigned int cuva_count = 0;
- int cuva_size = 0;
- struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
- if (pic == NULL || 0 == cuva_data_is_avaible(dec)) {
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "%s:pic 0x%p or data not avaible\n",
- __func__, pic);
- return;
- }
-
- cuva_adr = (unsigned short *)dec->cuva_addr;
- cuva_count = ((size_reg_val >> 16) << 4) >> 1;
- cuva_size = dec->cuva_size;
- dec->hdr_flag |= HDR_CUVA_MASK;
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s:pic 0x%p cuva_count(%d) cuva_size(%d) hdr_flag 0x%x\n",
- __func__, pic, cuva_count, cuva_size, dec->hdr_flag);
- if (cuva_size > 0 && cuva_count > 0) {
- int new_size;
- char *new_buf;
-
- new_size = cuva_size;
- new_buf = vzalloc(new_size);
- if (new_buf) {
- unsigned char *p = new_buf;
- int len = 0;
- pic->cuva_data_buf = new_buf;
-
- for (i = 0; i < cuva_count; i += 4) {
- int j;
-
- for (j = 0; j < 4; j++) {
- unsigned short aa = cuva_adr[i + 3 - j];
- *p = aa & 0xff;
- p++;
- len++;
- }
- }
- if (len > 0) {
- pic->cuva_data_size = len;
- }
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "cuva: (size %d)\n",
- pic->cuva_data_size);
- if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) {
- for (i = 0; i < pic->cuva_data_size; i++) {
- pr_info("%02x ", pic->cuva_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- pr_info("\n");
- }
- pr_info("\n");
- }
-
- } else {
- avs2_print(dec, 0, "new buf alloc failed\n");
- if (pic->cuva_data_buf)
- vfree(pic->cuva_data_buf);
- pic->cuva_data_buf = NULL;
- pic->cuva_data_size = 0;
- }
- }
-}
-
-static void release_cuva_data(struct avs2_frame_s *pic)
-{
- if (pic == NULL)
- return;
- if (pic->cuva_data_buf) {
- vfree(pic->cuva_data_buf);
- }
- pic->cuva_data_buf = NULL;
- pic->cuva_data_size = 0;
-}
-
-static void avs2_config_work_space_hw(struct AVS2Decoder_s *dec)
-{
- struct BuffInfo_s *buf_spec = dec->work_space_buf;
-#ifdef LOSLESS_COMPRESS_MODE
- int losless_comp_header_size =
- compute_losless_comp_header_size(
- dec, dec->init_pic_w,
- dec->init_pic_h);
- int losless_comp_body_size =
- compute_losless_comp_body_size(dec,
- dec->init_pic_w,
- dec->init_pic_h, buf_alloc_depth == 10);
-#endif
-#ifdef AVS2_10B_MMU
- unsigned int data32;
-#endif
- if (debug && dec->init_flag == 0)
- avs2_print(dec, 0,
- "%s %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
- __func__,
- buf_spec->ipp.buf_start,
- buf_spec->start_adr,
- buf_spec->short_term_rps.buf_start,
- buf_spec->rcs.buf_start,
- buf_spec->sps.buf_start,
- buf_spec->pps.buf_start,
- buf_spec->sao_up.buf_start,
- buf_spec->swap_buf.buf_start,
- buf_spec->swap_buf2.buf_start,
- buf_spec->scalelut.buf_start,
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_data.buf_start,
- buf_spec->dblk_data2.buf_start);
- WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start);
- if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0)
- WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
- WRITE_VREG(AVS2_ALF_SWAP_BUFFER, buf_spec->short_term_rps.buf_start);
- WRITE_VREG(HEVC_RCS_BUFFER, buf_spec->rcs.buf_start);
- WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
- WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
- //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
-#ifdef AVS2_10B_MMU
- WRITE_VREG(AVS2_MMU_MAP_BUFFER, dec->frame_mmu_map_phy_addr);
-#else
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
-#endif
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
- //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
- WRITE_VREG(HEVC_DBLK_CFG3, 0x404010); //default value
- else
- WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); // make left storage 2 x 4k]
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "HEVC_DBLK_CFG3 = %x\n", READ_VREG(HEVC_DBLK_CFG3));
- }
-
- /* cfg_p_addr */
- WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
- /* cfg_d_addr */
- WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
-
- WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
-
-#ifdef LOSLESS_COMPRESS_MODE
- data32 = READ_VREG(HEVC_SAO_CTRL5);
-#if 1
- data32 &= ~(1<<9);
-#else
- if (params->p.bit_depth != 0x00)
- data32 &= ~(1<<9);
- else
- data32 |= (1<<9);
-#endif
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-#ifdef AVS2_10B_MMU
- /*bit[4] : paged_mem_mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0);
-#else
- /* bit[3] smem mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3));
-
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
-#endif
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));*/
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
-/*8-bit mode */
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
-
-#ifdef AVS2_10B_MMU
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start
- + VBH_BUF_SIZE(buf_spec));
- /*data32 = READ_VREG(HEVC_SAO_CTRL9);*/
- /*data32 |= 0x1;*/
- /*WRITE_VREG(HEVC_SAO_CTRL9, data32);*/
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<10);
-#if 1
- if (debug & AVS2_DBG_FORCE_UNCOMPRESS)
- data32 |= 0x80;
-#endif
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
-#endif
-
- WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
-#if 1
-/*MULTI_INSTANCE_SUPPORT*/
- /*new added in simulation???*/
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
-#endif
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
-#endif
-}
-
-static void decomp_perfcount_reset(void)
-{
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered decomp_perfcount_reset...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static void mcrcc_perfcount_reset(void)
-{
- if (debug & AVS2_DBG_CACHE)
- pr_info("[cache_util.c] Entered mcrcc_perfcount_reset...\n");
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static void avs2_init_decoder_hw(struct AVS2Decoder_s *dec)
-{
- unsigned int data32;
- unsigned int decode_mode;
- int i;
-
- /*if (debug & AVS2_DBG_BUFMGR_MORE)
- pr_info("%s\n", __func__);*/
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
-#if 1
- /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
- data32 &= ~(7 << 29);
- data32 |= (3 << 29);
-#endif
- data32 = data32 |
- (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
- (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
- (1 << 7) |/*dec_done_int_cpu_enable*/
- (1 << 4) |/*startcode_found_int_cpu_enable*/
- (0 << 3) |/*startcode_found_int_amrisc_enable*/
- (1 << 0) /*parser_int_enable*/
- ;
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STATUS);
- data32 = data32 |
- (0 << 1) |/*emulation_check_off VP9
- do not have emulation*/
- (1 << 0)/*startcode_check_on*/
- ;
- WRITE_VREG(HEVC_SHIFT_STATUS, data32);
- WRITE_VREG(HEVC_SHIFT_CONTROL,
- (6 << 20) | /* emu_push_bits (6-bits for AVS2)*/
- (0 << 19) | /* emu_3_enable, maybe turned on in microcode*/
- (0 << 18) | /* emu_2_enable, maybe turned on in microcode*/
- (0 << 17) | /* emu_1_enable, maybe turned on in microcode*/
- (0 << 16) | /* emu_0_enable, maybe turned on in microcode*/
- (0 << 14) | /*disable_start_code_protect*/
- (3 << 6) | /* sft_valid_wr_position*/
- (2 << 4) | /* emulate_code_length_sub_1*/
- (2 << 1) | /* start_code_length_sub_1*/
- (1 << 0) /* stream_shift_enable*/
- );
-
- WRITE_VREG(HEVC_SHIFT_LENGTH_PROTECT,
- (0 << 30) | /*data_protect_fill_00_enable*/
- (1 << 29) /*data_protect_fill_ff_enable*/
- );
- WRITE_VREG(HEVC_CABAC_CONTROL,
- (1 << 0)/*cabac_enable*/
- );
-
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
- (1 << 0)/* hevc_parser_core_clk_en*/
- );
-
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
-
- /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(dec->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
-
-#ifdef ENABLE_SWAP_TEST
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
-#else
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
-#endif
- if (!dec->m_ins_flag)
- decode_mode = DECODE_MODE_SINGLE;
- else if (vdec_frame_based(hw_to_vdec(dec)))
- decode_mode = DECODE_MODE_MULTI_FRAMEBASE;
- else
- decode_mode = DECODE_MODE_MULTI_STREAMBASE;
- if (dec->avs2_dec.bufmgr_error_flag &&
- (error_handle_policy & 0x1)) {
- dec->bufmgr_error_count++;
- dec->avs2_dec.bufmgr_error_flag = 0;
- if (dec->bufmgr_error_count >
- (re_search_seq_threshold & 0xff)
- && dec->frame_count >
- ((re_search_seq_threshold >> 8) & 0xff)) {
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- dec->start_decoding_flag = 0;
- avs2_dec->hd.vec_flag = 1;
- dec->skip_PB_before_I = 1;
- avs2_print(dec, 0,
- "!!Bufmgr error, search seq again (0x%x %d %d)\n",
- error_handle_policy,
- dec->frame_count,
- dec->bufmgr_error_count);
- dec->bufmgr_error_count = 0;
- }
- }
- decode_mode |= (dec->start_decoding_flag << 16);
-
- WRITE_VREG(DECODE_MODE, decode_mode);
- WRITE_VREG(HEVC_DECODE_SIZE, 0);
- WRITE_VREG(HEVC_DECODE_COUNT, 0);
-
- /*Send parser_cmd*/
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
- for (i = 0; i < PARSER_CMD_NUMBER; i++)
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
-
-
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- (1 << 9) | /* parser_alf_if_en*/
- /* (1 << 8) |*/ /*sao_sw_pred_enable*/
- (1 << 5) | /*parser_sao_if_en*/
- (1 << 2) | /*parser_mpred_if_en*/
- (1 << 0) /*parser_scaler_if_en*/
- );
-
-#ifdef MULTI_INSTANCE_SUPPORT
- WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
-
- WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
-
- for (i = 0; i < 8; i++)
- data32 = READ_VREG(HEVC_MPRED_ABV_START_ADDR);
-
- WRITE_VREG(DOS_SW_RESET3, (1<<18)); /* reset mpred */
- WRITE_VREG(DOS_SW_RESET3, 0);
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, data32);
-#endif
- /*End of Multi-instance*/
- /*Changed to Start MPRED in microcode*/
- /*
- pr_info("[test.c] Start MPRED\n");
- WRITE_VREG(HEVC_MPRED_INT_STATUS,
- (1<<31)
- );
- */
-
- /*AVS2 default seq_wq_matrix config*/
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "Config AVS2 default seq_wq_matrix ...\n");
- /*4x4*/
- /* default seq_wq_matrix_4x4 begin address*/
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64);
- for (i = 0; i < 16; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
-
- /*8x8*/
- /*default seq_wq_matrix_8x8 begin address*/
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);
- for (i = 0; i < 64; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
-
-
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (0 << 1) | /*enable ipp*/
- (1 << 0) /*software reset ipp and mpp*/
- );
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (1 << 1) | /*enable ipp*/
- (0 << 0) /*software reset ipp and mpp*/
- );
-#if 0
-/*AVS2_10B_NV21*/
- /*Enable NV21 reference read mode for MC*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
- /* Init dblk*/
- data32 = READ_VREG(HEVC_DBLK_CFGB);
- data32 |= (2 << 0);
- /* [3:0] cfg_video_type -> AVS2*/
-
- data32 &= (~0x300); /*[8]:first write enable (compress)
- [9]:double write enable (uncompress)*/
- if (get_double_write_mode(dec) == 0)
- data32 |= (0x1 << 8); /*enable first write*/
- else if (get_double_write_mode(dec) == 0x10)
- data32 |= (0x1 << 9); /*double write only*/
- else
- data32 |= ((0x1 << 8) | (0x1 << 9));
- WRITE_VREG(HEVC_DBLK_CFGB, data32);
-
- WRITE_VREG(HEVC_DBLK_CFG0, (1 << 0)); /* [0] rst_sync*/
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "Bitstream level Init for DBLK .Done.\n");
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- mcrcc_perfcount_reset();
- decomp_perfcount_reset();
- }
-
- return;
-}
-
-
-#ifdef CONFIG_HEVC_CLK_FORCED_ON
-static void config_avs2_clk_forced_on(void)
-{
- unsigned int rdata32;
- /*IQIT*/
- rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
- WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
-
- /* DBLK*/
- rdata32 = READ_VREG(HEVC_DBLK_CFG0);
- WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
-
- /* SAO*/
- rdata32 = READ_VREG(HEVC_SAO_CTRL1);
- WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
-
- /*MPRED*/
- rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
- WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
-
- /* PARSER*/
- rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
- WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
- WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
- WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
- rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1));
-
- /*IPP*/
- rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
- WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
-
- /* MCRCC*/
- rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
- WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
-}
-#endif
-
-static void avs2_local_uninit(struct AVS2Decoder_s *dec)
-{
- dec->rpm_ptr = NULL;
- dec->lmem_ptr = NULL;
- if (dec->rpm_addr) {
- dma_free_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE, dec->rpm_addr,
- dec->rpm_phy_addr);
- dec->rpm_addr = NULL;
- }
-
- if (dec->cuva_addr) {
- dma_free_coherent(amports_get_dma_device(),
- dec->cuva_size, dec->cuva_addr,
- dec->cuva_phy_addr);
- dec->cuva_addr = NULL;
- }
-
- if (dec->lmem_addr) {
- if (dec->lmem_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, dec->lmem_addr,
- dec->lmem_phy_addr);
- dec->lmem_addr = NULL;
- }
-
-#ifdef AVS2_10B_MMU
- if (dec->frame_mmu_map_addr) {
- if (dec->frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(dec), dec->frame_mmu_map_addr,
- dec->frame_mmu_map_phy_addr);
- dec->frame_mmu_map_addr = NULL;
- }
-#endif
- if (dec->gvs)
- vfree(dec->gvs);
- dec->gvs = NULL;
-}
-
-static int avs2_local_init(struct AVS2Decoder_s *dec)
-{
- int ret = -1;
- /*int losless_comp_header_size, losless_comp_body_size;*/
-
- struct BuffInfo_s *cur_buf_info = NULL;
-
- cur_buf_info = &dec->work_space_buf_store;
- if (force_bufspec) {
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[force_bufspec & 0xf],
- sizeof(struct BuffInfo_s));
- pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[2], /* 8k */
- sizeof(struct BuffInfo_s));
- else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[0],/* 1080p */
- sizeof(struct BuffInfo_s));
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[5], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
-
- cur_buf_info->start_adr = dec->buf_start;
-#ifndef AVS2_10B_MMU
- dec->mc_buf_spec.buf_end = dec->buf_start + dec->buf_size;
-#endif
-
- init_buff_spec(dec, cur_buf_info);
-
- init_avs2_decoder(&dec->avs2_dec);
-
-#ifdef AVS2_10B_MMU
- avs2_bufmgr_init(dec, cur_buf_info, NULL);
-#else
- dec->mc_buf_spec.buf_start = (cur_buf_info->end_adr + 0xffff)
- & (~0xffff);
- dec->mc_buf_spec.buf_size = (dec->mc_buf_spec.buf_end
- - dec->mc_buf_spec.buf_start);
- if (debug) {
- pr_err("dec->mc_buf_spec.buf_start %x-%x\n",
- dec->mc_buf_spec.buf_start,
- dec->mc_buf_spec.buf_start +
- dec->mc_buf_spec.buf_size);
- }
- avs2_bufmgr_init(dec, cur_buf_info, &dec->mc_buf_spec);
-#endif
-
- if (!vdec_is_support_4k()
- && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
- buf_alloc_width = 1920;
- buf_alloc_height = 1088;
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- buf_alloc_width = 8192;
- buf_alloc_height = 4608;
- }
- dec->init_pic_w = buf_alloc_width ? buf_alloc_width :
- (dec->vavs2_amstream_dec_info.width ?
- dec->vavs2_amstream_dec_info.width :
- dec->work_space_buf->max_width);
- dec->init_pic_h = buf_alloc_height ? buf_alloc_height :
- (dec->vavs2_amstream_dec_info.height ?
- dec->vavs2_amstream_dec_info.height :
- dec->work_space_buf->max_height);
-#if 0
-/*ndef MV_USE_FIXED_BUF*/
- if (init_mv_buf_list(dec) < 0) {
- pr_err("%s: init_mv_buf_list fail\n", __func__);
- return -1;
- }
-#endif
-
-#ifndef AVS2_10B_MMU
- init_buf_list(dec);
-#else
- dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin;
- if (dec->used_buf_num > MAX_BUF_NUM)
- dec->used_buf_num = MAX_BUF_NUM;
- if (dec->used_buf_num > FRAME_BUFFERS)
- dec->used_buf_num = FRAME_BUFFERS;
-#endif
- dec->avs2_dec.ref_maxbuffer = dec->used_buf_num - 1;
- /*init_pic_list(dec);*/
-
- pts_unstable = ((unsigned long)(dec->vavs2_amstream_dec_info.param)
- & 0x40) >> 6;
-
- if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
- dec->rpm_addr = dma_alloc_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE,
- &dec->rpm_phy_addr, GFP_KERNEL);
- if (dec->rpm_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "rpm_phy_addr %x\n", (u32) dec->rpm_phy_addr);
- dec->rpm_ptr = dec->rpm_addr;
- }
-
- if (cuva_buf_size > 0) {
- dec->cuva_size = AUX_BUF_ALIGN(cuva_buf_size);
-
- dec->cuva_addr = dma_alloc_coherent(amports_get_dma_device(),
- dec->cuva_size, &dec->cuva_phy_addr, GFP_KERNEL);
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s, cuva_size = %d cuva_phy_addr %x dec->cuva_addr = %px\n",
- __func__, dec->cuva_size, (u32)dec->cuva_phy_addr, dec->cuva_addr);
- if (dec->cuva_addr == NULL) {
- pr_err("%s: failed to alloc cuva buffer\n", __func__);
- return -1;
- }
- }
-
- dec->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE,
- &dec->lmem_phy_addr, GFP_KERNEL);
- if (dec->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- } else
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s, lmem_phy_addr %x\n",
- __func__, (u32)dec->lmem_phy_addr);
-/*
- dec->lmem_phy_addr = dma_map_single(amports_get_dma_device(),
- dec->lmem_addr, LMEM_BUF_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(amports_get_dma_device(),
- dec->lmem_phy_addr)) {
- pr_err("%s: failed to map lmem buffer\n", __func__);
- kfree(dec->lmem_addr);
- dec->lmem_addr = NULL;
- return -1;
- }
-*/
- dec->lmem_ptr = dec->lmem_addr;
-
-
-#ifdef AVS2_10B_MMU
- dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(dec),
- &dec->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (dec->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(dec->frame_mmu_map_addr, 0, get_frame_mmu_map_size(dec));
-/* dec->frame_mmu_map_phy_addr = dma_map_single(amports_get_dma_device(),
- dec->frame_mmu_map_addr, FRAME_MMU_MAP_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(amports_get_dma_device(),
- dec->frame_mmu_map_phy_addr)) {
- pr_err("%s: failed to map count_buffer\n", __func__);
- kfree(dec->frame_mmu_map_addr);
- dec->frame_mmu_map_addr = NULL;
- return -1;
- }*/
-#endif
-
- ret = 0;
- return ret;
-}
-
-/********************************************
- * Mailbox command
- ********************************************/
-#define CMD_FINISHED 0
-#define CMD_ALLOC_VIEW 1
-#define CMD_FRAME_DISPLAY 3
-#define CMD_DEBUG 10
-
-
-#define DECODE_BUFFER_NUM_MAX 32
-#define DISPLAY_BUFFER_NUM 6
-
-#define video_domain_addr(adr) (adr&0x7fffffff)
-#define DECODER_WORK_SPACE_SIZE 0x800000
-
-#define spec2canvas(x) \
- (((x)->uv_canvas_index << 16) | \
- ((x)->uv_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-
-static void set_canvas(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic)
-{
- int canvas_w = ALIGN(pic->pic_w, 64)/4;
- int canvas_h = ALIGN(pic->pic_h, 32)/4;
- int blkmode = mem_map_mode;
- struct vdec_s *vdec = hw_to_vdec(dec);
- /*CANVAS_BLKMODE_64X32*/
- if (pic->double_write_mode) {
- canvas_w = pic->pic_w /
- get_double_write_ratio(pic->double_write_mode);
- canvas_h = pic->pic_h /
- get_double_write_ratio(pic->double_write_mode);
- /*sao_crtl1 aligned with 64*/
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- if (vdec->parallel_dec == 1) {
- if (pic->y_canvas_index == -1)
- pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic->uv_canvas_index == -1)
- pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic->y_canvas_index = 128 + pic->index * 2;
- pic->uv_canvas_index = 128 + pic->index * 2 + 1;
- }
-
- config_cav_lut_ex(pic->y_canvas_index,
- pic->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index,
- pic->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
-#ifdef MULTI_INSTANCE_SUPPORT
- pic->canvas_config[0].phy_addr =
- pic->dw_y_adr;
- pic->canvas_config[0].width =
- canvas_w;
- pic->canvas_config[0].height =
- canvas_h;
- pic->canvas_config[0].block_mode =
- blkmode;
- pic->canvas_config[0].endian = 7;
-
- pic->canvas_config[1].phy_addr =
- pic->dw_u_v_adr;
- pic->canvas_config[1].width =
- canvas_w;
- pic->canvas_config[1].height =
- canvas_h;
- pic->canvas_config[1].block_mode =
- blkmode;
- pic->canvas_config[1].endian = 7;
-#endif
- } else {
- #ifndef AVS2_10B_MMU
- if (vdec->parallel_dec == 1) {
- if (pic->y_canvas_index == -1)
- pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic->uv_canvas_index == -1)
- pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic->y_canvas_index = 128 + pic->index;
- pic->uv_canvas_index = 128 + pic->index;
- }
-
- config_cav_lut_ex(pic->y_canvas_index,
- pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index,
- pic->mc_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, 0x7, VDEC_HEVC);
- #endif
- }
-}
-
-static void set_frame_info(struct AVS2Decoder_s *dec, struct vframe_s *vf)
-{
- unsigned int ar;
-
- vf->duration = dec->frame_dur;
- vf->duration_pulldown = 0;
- vf->flag = 0;
- vf->prop.master_display_colour = dec->vf_dp;
- if (dec->hdr_flag & HDR_CUVA_MASK)
- dec->video_signal_type |= 1 << 31;
- vf->signal_type = dec->video_signal_type;
-
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "signal_typesignal_type 0x%x \n",
- vf->signal_type);
-
- ar = min_t(u32, dec->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
-
- vf->sidebind_type = dec->sidebind_type;
- vf->sidebind_channel_id = dec->sidebind_channel_id;
-
- return;
-}
-
-static int vavs2_vf_states(struct vframe_states *states, void *op_arg)
-{
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&dec->newframe_q);
- states->buf_avail_num = kfifo_len(&dec->display_q);
-
- if (step == 2)
- states->buf_avail_num = 0;
- return 0;
-}
-
-static struct vframe_s *vavs2_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
- if (step == 2)
- return NULL;
-
- if (force_disp_pic_index & 0x100) {
- if (force_disp_pic_index & 0x200)
- return NULL;
- return &dec->vframe_dummy;
- }
-
- if (kfifo_peek(&dec->display_q, &vf))
- return vf;
-
- return NULL;
-}
-
-static struct avs2_frame_s *get_pic_by_index(
- struct AVS2Decoder_s *dec, int index)
-{
- int i;
- struct avs2_frame_s *pic = NULL;
- if (index == (dec->used_buf_num - 1))
- pic = dec->avs2_dec.m_bg;
- else if (index >= 0 && index < dec->used_buf_num) {
- for (i = 0; i < dec->used_buf_num; i++) {
- if (dec->avs2_dec.fref[i]->index == index)
- pic = dec->avs2_dec.fref[i];
- }
- }
- return pic;
-}
-
-static struct vframe_s *vavs2_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
- if (step == 2)
- return NULL;
- else if (step == 1)
- step = 2;
-
- if (force_disp_pic_index & 0x100) {
- int idx = force_disp_pic_index & 0xff;
- struct avs2_frame_s *pic = NULL;
- if (idx >= 0
- && idx < dec->avs2_dec.ref_maxbuffer)
- pic = get_pic_by_index(dec, idx);
- if (pic == NULL)
- return NULL;
- if (force_disp_pic_index & 0x200)
- return NULL;
-
- vf = &dec->vframe_dummy;
-
- set_vframe(dec, vf, pic, 1);
-
- force_disp_pic_index |= 0x200;
- return vf;
- }
-
- if (kfifo_get(&dec->display_q, &vf)) {
- uint8_t index = vf->index & 0xff;
- ATRACE_COUNTER(dec->disp_q_name, kfifo_len(&dec->display_q));
- if (index < dec->used_buf_num) {
- struct avs2_frame_s *pic = get_pic_by_index(dec, index);
- if (pic == NULL &&
- (debug & AVS2_DBG_PIC_LEAK)) {
- int i;
- avs2_print(dec, 0,
- "%s error index 0x%x pic not exist\n",
- __func__, index);
- dump_pic_list(dec);
- for (i = 0; i < 10; i++) {
- pic = get_pic_by_index(dec, index);
- pr_info("pic = %p\n", pic);
- }
-
- if (debug & AVS2_DBG_PIC_LEAK)
- debug |= AVS2_DBG_PIC_LEAK_WAIT;
- return NULL;
- }
- vf->index_disp = atomic_read(&dec->vf_get_count);
- atomic_add(1, &dec->vf_get_count);
- if (pic)
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index 0x%x pos %d getcount %d type 0x%x w/h %d/%d, pts %d, %lld\n",
- __func__, index,
- pic->imgtr_fwRefDistance_bak,
- dec->vf_get_count,
- vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64);
- return vf;
- }
- }
- return NULL;
-}
-
-static void vavs2_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
- uint8_t index;
-
- if (vf == (&dec->vframe_dummy))
- return;
-
- if (!vf)
- return;
-
- index = vf->index & 0xff;
-
- kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(dec->new_q_name, kfifo_len(&dec->newframe_q));
- atomic_add(1, &dec->vf_put_count);
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index putcount 0x%x %d\n",
- __func__, vf->index,
- dec->vf_put_count);
-
- if (index < dec->used_buf_num) {
- unsigned long flags;
- struct avs2_frame_s *pic;
-
- lock_buffer(dec, flags);
- pic = get_pic_by_index(dec, index);
- if (pic && pic->vf_ref > 0)
- pic->vf_ref--;
- else {
- if (pic)
- avs2_print(dec, 0,
- "%s, error pic (index %d) vf_ref is %d\n",
- __func__, index, pic->vf_ref);
- else
- avs2_print(dec, 0,
- "%s, error pic (index %d) is NULL\n",
- __func__, index);
- }
- if (dec->wait_buf)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- dec->last_put_idx = index;
- dec->new_frame_displayed++;
- unlock_buffer(dec, flags);
- }
-
-}
-
-static int vavs2_event_cb(int type, void *data, void *private_data)
-{
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)private_data;
-
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(hw_to_vdec(dec));
- else
- req->req_result[0] = 0xffffffff;
- } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
- struct provider_aux_req_s *req =
- (struct provider_aux_req_s *)data;
- unsigned char index;
- unsigned long flags;
- struct avs2_frame_s *pic;
-
- if (!req->vf) {
- req->aux_size = atomic_read(&dec->vf_put_count);
- return 0;
- }
- lock_buffer(dec, flags);
- index = req->vf->index & 0xff;
- req->aux_buf = NULL;
- req->aux_size = 0;
- req->format = VFORMAT_AVS2;
- if (index < dec->used_buf_num) {
- pic = get_pic_by_index(dec, index);
- req->aux_buf = pic->cuva_data_buf;
- req->aux_size = pic->cuva_data_size;
- }
- unlock_buffer(dec, flags);
-
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s pic 0x%p index %d =>size %d\n",
- __func__, pic, index, req->aux_size);
- }
-
- return 0;
-}
-
-static struct avs2_frame_s *get_disp_pic(struct AVS2Decoder_s *dec)
-{
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic = NULL;
- int32_t j;
- int32_t pre_disp_count_min = 0x7fffffff;
- for (j = 0; j < avs2_dec->ref_maxbuffer; j++) {
- if (avs2_dec->fref[j]->to_prepare_disp &&
- avs2_dec->fref[j]->to_prepare_disp <
- pre_disp_count_min) {
- pre_disp_count_min =
- avs2_dec->fref[j]->to_prepare_disp;
- pic = avs2_dec->fref[j];
- }
- }
- if (pic)
- pic->to_prepare_disp = 0;
-
- return pic;
-
-}
-
-
-
-static void fill_frame_info(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic, unsigned int framesize, unsigned int pts)
-{
- struct vframe_qos_s *vframe_qos = &dec->vframe_qos;
-
- if (pic->slice_type == I_IMG)
- vframe_qos->type = 1;
- else if (pic->slice_type == P_IMG)
- vframe_qos->type = 2;
- else if (pic->slice_type == B_IMG)
- vframe_qos->type = 3;
-/*
-#define SHOW_QOS_INFO
-*/
- if (input_frame_based(hw_to_vdec(dec)))
- vframe_qos->size = pic->frame_size;
- else
- vframe_qos->size = framesize;
- vframe_qos->pts = pts;
-#ifdef SHOW_QOS_INFO
- avs2_print(dec, 0, "slice:%d\n", pic->slice_type);
-#endif
-
-
- vframe_qos->max_mv = pic->max_mv;
- vframe_qos->avg_mv = pic->avg_mv;
- vframe_qos->min_mv = pic->min_mv;
-#ifdef SHOW_QOS_INFO
- avs2_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
-#endif
-
- vframe_qos->max_qp = pic->max_qp;
- vframe_qos->avg_qp = pic->avg_qp;
- vframe_qos->min_qp = pic->min_qp;
-#ifdef SHOW_QOS_INFO
- avs2_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
-#endif
-
- vframe_qos->max_skip = pic->max_skip;
- vframe_qos->avg_skip = pic->avg_skip;
- vframe_qos->min_skip = pic->min_skip;
-#ifdef SHOW_QOS_INFO
- avs2_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
-#endif
-
- vframe_qos->num++;
-
-}
-
-static void set_vframe(struct AVS2Decoder_s *dec,
- struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy)
-{
- unsigned long flags;
- int stream_offset;
- unsigned int frame_size = 0;
- int pts_discontinue;
- struct vdec_s *vdec = hw_to_vdec(dec);
- stream_offset = pic->stream_offset;
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s index = %d pos = %d\r\n",
- __func__, pic->index,
- pic->imgtr_fwRefDistance);
-
- if (pic->double_write_mode)
- set_canvas(dec, pic);
-
- display_frame_count[dec->index]++;
-
- if (!dummy) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(vdec)) {
- vf->pts = pic->pts;
- vf->pts_us64 = pic->pts64;
- } else {
-#endif
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
- stream_offset, &vf->pts, 0) != 0) { */
- if (pts_lookup_offset_us64
- (PTS_TYPE_VIDEO, stream_offset,
- &vf->pts, &frame_size, 0,
- &vf->pts_us64) != 0) {
-#ifdef DEBUG_PTS
- dec->pts_missed++;
-#endif
- vf->pts = 0;
- vf->pts_us64 = 0;
- }
- }
- }
-#ifdef DEBUG_PTS
- else
- dec->pts_hit++;
-#endif
- if (pts_unstable)
- dec->pts_mode = PTS_NONE_REF_USE_DURATION;
-
- fill_frame_info(dec, pic, frame_size, vf->pts);
-
- if ((dec->pts_mode == PTS_NORMAL) && (vf->pts != 0)
- && dec->get_frame_dur) {
- int pts_diff = (int)vf->pts - dec->last_lookup_pts;
-
- if (pts_diff < 0) {
- dec->pts_mode_switching_count++;
- dec->pts_mode_recovery_count = 0;
-
- if (dec->pts_mode_switching_count >=
- PTS_MODE_SWITCHING_THRESHOLD) {
- dec->pts_mode =
- PTS_NONE_REF_USE_DURATION;
- pr_info
- ("HEVC: switch to n_d mode.\n");
- }
-
- } else {
- int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD;
- dec->pts_mode_recovery_count++;
- if (dec->pts_mode_recovery_count > p) {
- dec->pts_mode_switching_count = 0;
- dec->pts_mode_recovery_count = 0;
- }
- }
- }
-
- pts_discontinue =
- (abs(dec->last_pts - vf->pts) >=
- tsync_vpts_discontinuity_margin());
-
- if (vf->pts != 0)
- dec->last_lookup_pts = vf->pts;
-#if 1
- if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
- && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
- !first_pts_checkin_complete(PTS_TYPE_AUDIO))))
- vf->pts = dec->last_pts + DUR2PTS(dec->frame_dur);
-#endif
- dec->last_pts = vf->pts;
-
- if (vf->pts_us64 != 0)
- dec->last_lookup_pts_us64 = vf->pts_us64;
-
-#if 1
- if ((dec->pts_mode == PTS_NONE_REF_USE_DURATION)
- && ((pic->slice_type != I_IMG) || (!pts_discontinue &&
- !first_pts_checkin_complete(PTS_TYPE_AUDIO)))) {
- vf->pts_us64 =
- dec->last_pts_us64 +
- (DUR2PTS(dec->frame_dur) * 100 / 9);
- }
-#endif
- dec->last_pts_us64 = vf->pts_us64;
- avs2_print(dec, AVS2_DBG_OUT_PTS,
- "avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld\n",
- vf->pts, vf->pts_us64);
- }
-
- vf->index = 0xff00 | pic->index;
-
- if (pic->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
- } else {
-#ifdef AVS2_10B_MMU
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic->header_adr;
-#else
- vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
- vf->compHeadAddr = pic->mc_y_adr +
- pic->comp_body_size;
- /*head adr*/
-#endif
- }
- if (pic->double_write_mode) {
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD;
- vf->type |= VIDTYPE_VIU_NV21;
- if (pic->double_write_mode == 3) {
- vf->type |= VIDTYPE_COMPRESS;
-#ifdef AVS2_10B_MMU
- vf->type |= VIDTYPE_SCATTER;
-#endif
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (dec->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic->canvas_config[0];
- vf->canvas0_config[1] =
- pic->canvas_config[1];
-
- vf->canvas1_config[0] =
- pic->canvas_config[0];
- vf->canvas1_config[1] =
- pic->canvas_config[1];
-
- } else
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(pic);
- } else {
- vf->canvas0Addr = vf->canvas1Addr = 0;
- vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
-#ifdef AVS2_10B_MMU
- vf->type |= VIDTYPE_SCATTER;
-#endif
- }
-
- switch (pic->bit_depth) {
- case AVS2_BITS_8:
- vf->bitdepth = BITDEPTH_Y8 |
- BITDEPTH_U8 | BITDEPTH_V8;
- break;
- case AVS2_BITS_10:
- case AVS2_BITS_12:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- default:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- }
- if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- if (pic->bit_depth == AVS2_BITS_8)
- vf->bitdepth |= BITDEPTH_SAVING_MODE;
-
- set_frame_info(dec, vf);
- /* if((vf->width!=pic->width)|
- (vf->height!=pic->height)) */
- /* pr_info("aaa: %d/%d, %d/%d\n",
- vf->width,vf->height, pic->width,
- pic->height); */
- vf->width = pic->pic_w /
- get_double_write_ratio(pic->double_write_mode);
- vf->height = pic->pic_h /
- get_double_write_ratio(pic->double_write_mode);
- if (force_w_h != 0) {
- vf->width = (force_w_h >> 16) & 0xffff;
- vf->height = force_w_h & 0xffff;
- }
- vf->compWidth = pic->pic_w;
- vf->compHeight = pic->pic_h;
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
-#ifdef AVS2_10B_MMU
- if (vf->type & VIDTYPE_SCATTER) {
- vf->mem_handle = decoder_mmu_box_get_mem_handle(
- dec->mmu_box,
- pic->index);
- vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- HEADER_BUFFER_IDX(pic->index));
- } else {
- vf->mem_handle = decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- VF_BUFFER_IDX(pic->index));
- vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- HEADER_BUFFER_IDX(pic->index));
- }
-#else
- vf->mem_handle = decoder_bmmu_box_get_mem_handle(
- dec->bmmu_box,
- VF_BUFFER_IDX(pic->index));
-#endif
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- vf->pts_us64 = stream_offset;
- vf->pts = 0;
- }
- if (!dummy) {
- lock_buffer(dec, flags);
- pic->vf_ref = 1;
- unlock_buffer(dec, flags);
- }
- atomic_add(1, &dec->vf_pre_count);
-}
-
-static inline void dec_update_gvs(struct AVS2Decoder_s *dec)
-{
- if (dec->gvs->frame_height != dec->frame_height) {
- dec->gvs->frame_width = dec->frame_width;
- dec->gvs->frame_height = dec->frame_height;
- }
- if (dec->gvs->frame_dur != dec->frame_dur) {
- dec->gvs->frame_dur = dec->frame_dur;
- if (dec->frame_dur != 0)
- dec->gvs->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
- 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
- else
- dec->gvs->frame_rate = -1;
- }
- dec->gvs->status = dec->stat | dec->fatal_error;
-}
-
-static int avs2_prepare_display_buf(struct AVS2Decoder_s *dec)
-{
-#ifndef NO_DISPLAY
- struct vframe_s *vf = NULL;
- /*unsigned short slice_type;*/
- struct avs2_frame_s *pic;
- struct vdec_s *pvdec = hw_to_vdec(dec);
- while (1) {
- pic = get_disp_pic(dec);
- if (pic == NULL)
- break;
-
- if (force_disp_pic_index & 0x100) {
- /*recycle directly*/
- continue;
- }
-
- if (pic->error_mark) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "!!!error pic, skip\n",
- 0);
- continue;
- }
-
- if (dec->start_decoding_flag != 0) {
- if (dec->skip_PB_before_I &&
- pic->slice_type != I_IMG) {
- avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
- "!!!slice type %d (not I) skip\n",
- 0, pic->slice_type);
- continue;
- }
- dec->skip_PB_before_I = 0;
- }
-
- if (kfifo_get(&dec->newframe_q, &vf) == 0) {
- pr_info("fatal error, no available buffer slot.");
- return -1;
- }
-
- if (vf) {
- struct vdec_info tmp4x;
- int stream_offset = pic->stream_offset;
- set_vframe(dec, vf, pic, 0);
- decoder_do_frame_check(pvdec, vf);
- vdec_vframe_ready(pvdec, vf);
- kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(dec->pts_name, vf->timestamp);
- ATRACE_COUNTER(dec->new_q_name, kfifo_len(&dec->newframe_q));
- ATRACE_COUNTER(dec->disp_q_name, kfifo_len(&dec->display_q));
-
- dec_update_gvs(dec);
- /*count info*/
- vdec_count_info(dec->gvs, 0, stream_offset);
- if (stream_offset) {
- if (pic->slice_type == I_IMG) {
- dec->gvs->i_decoded_frames++;
- } else if (pic->slice_type == P_IMG) {
- dec->gvs->p_decoded_frames++;
- } else if (pic->slice_type == B_IMG) {
- dec->gvs->b_decoded_frames++;
- }
- }
- memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = bit_depth_luma;
- tmp4x.bit_depth_chroma = bit_depth_chroma;
- tmp4x.double_write_mode = pic->double_write_mode;
- vdec_fill_vdec_frame(pvdec, &dec->vframe_qos, &tmp4x, vf, pic->hw_decode_time);
- pvdec->vdec_fps_detec(pvdec->id);
- if (without_display_mode == 0) {
- vf_notify_receiver(dec->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- } else
- vavs2_vf_put(vavs2_vf_get(dec), dec);
- }
- }
-/*!NO_DISPLAY*/
-#endif
- return 0;
-}
-
-static void get_rpm_param(union param_u *params)
-{
- int i;
- unsigned int data32;
- if (debug & AVS2_DBG_BUFMGR)
- pr_info("enter %s\r\n", __func__);
- for (i = 0; i < (RPM_END - RPM_BEGIN); i++) {
- do {
- data32 = READ_VREG(RPM_CMD_REG);
- /*pr_info("%x\n", data32);*/
- } while ((data32 & 0x10000) == 0);
- params->l.data[i] = data32&0xffff;
- /*pr_info("%x\n", data32);*/
- WRITE_VREG(RPM_CMD_REG, 0);
- }
- if (debug & AVS2_DBG_BUFMGR)
- pr_info("leave %s\r\n", __func__);
-}
-static void debug_buffer_mgr_more(struct AVS2Decoder_s *dec)
-{
- int i;
- if (!(debug & AVS2_DBG_BUFMGR_MORE))
- return;
- pr_info("avs2_param: (%d)\n", dec->avs2_dec.img.number);
- for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
- pr_info("%04x ", dec->avs2_dec.param.l.data[i]);
- if (((i + 1) & 0xf) == 0)
- pr_info("\n");
- }
-}
-
-#ifdef AVS2_10B_MMU
-static void avs2_recycle_mmu_buf_tail(struct AVS2Decoder_s *dec)
-{
- if (dec->cur_fb_idx_mmu != INVALID_IDX) {
- if (dec->used_4k_num == -1) {
- dec->used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- if (dec->m_ins_flag)
- hevc_mmu_dma_check(hw_to_vdec(dec));
- decoder_mmu_box_free_idx_tail(dec->mmu_box,
- dec->cur_fb_idx_mmu, dec->used_4k_num);
- }
- dec->cur_fb_idx_mmu = INVALID_IDX;
- dec->used_4k_num = -1;
- }
-}
-
-static void avs2_recycle_mmu_buf(struct AVS2Decoder_s *dec)
-{
- if (dec->cur_fb_idx_mmu != INVALID_IDX) {
- decoder_mmu_box_free_idx(dec->mmu_box,
- dec->cur_fb_idx_mmu);
-
- dec->cur_fb_idx_mmu = INVALID_IDX;
- dec->used_4k_num = -1;
- }
-}
-#endif
-
-static void dec_again_process(struct AVS2Decoder_s *dec)
-{
- amhevc_stop();
- dec->dec_result = DEC_RESULT_AGAIN;
- if (dec->process_state ==
- PROC_STATE_DECODING) {
- dec->process_state =
- PROC_STATE_DECODE_AGAIN;
- } else if (dec->process_state ==
- PROC_STATE_HEAD_DONE) {
- dec->process_state =
- PROC_STATE_HEAD_AGAIN;
- }
- dec->next_again_flag = 1;
- reset_process_time(dec);
- vdec_schedule_work(&dec->work);
-}
-
-static uint32_t log2i(uint32_t val)
-{
- uint32_t ret = -1;
- while (val != 0) {
- val >>= 1;
- ret++;
- }
- return ret;
-}
-
-static void check_pic_error(struct AVS2Decoder_s *dec,
- struct avs2_frame_s *pic)
-{
- if (pic->decoded_lcu == 0) {
- pic->decoded_lcu =
- (READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff) + 1;
- }
- if (pic->decoded_lcu != dec->avs2_dec.lcu_total) {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "%s error pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
- __func__, pic->index, pic->imgtr_fwRefDistance,
- pic->decoded_lcu, dec->avs2_dec.lcu_total);
- pic->error_mark = 1;
- } else {
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
- __func__, pic->index, pic->imgtr_fwRefDistance,
- pic->decoded_lcu, dec->avs2_dec.lcu_total);
-
- }
-}
-static void update_decoded_pic(struct AVS2Decoder_s *dec)
-{
- struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
- if (pic) {
- dec->avs2_dec.hc.cur_pic->decoded_lcu =
- (READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff) + 1;
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s pic(index %d imgtr_fwRefDistance %d) decoded lcu %d (total %d)\n",
- __func__, pic->index, pic->imgtr_fwRefDistance,
- pic->decoded_lcu, dec->avs2_dec.lcu_total);
- }
-}
-/* +[SE] [BUG][BUG-171463][chuanqi.wang]: get frame rate by video sequeue*/
-static int get_frame_rate(union param_u *params, struct AVS2Decoder_s *dec)
-{
- int tmp = 0;
-
- switch (params->p.frame_rate_code) {
- case 1:
- case 2:
- tmp = 24;
- break;
- case 3:
- tmp = 25;
- break;
- case 4:
- case 5:
- tmp = 30;
- break;
- case 6:
- tmp = 50;
- break;
- case 7:
- case 8:
- tmp = 60;
- break;
- case 9:
- tmp = 100;
- break;
- case 10:
- tmp = 120;
- break;
- default:
- tmp = 25;
- break;
- }
-
- if (!params->p.progressive_sequence)
- tmp = tmp / 2;
- dec->frame_dur = div_u64(96000ULL, tmp);
- dec->get_frame_dur = true;
- /*avs2_print(dec, 0, "avs2 frame_dur:%d,progressive:%d\n", dec->frame_dur, params->p.progressive_sequence);*/
- return 0;
-}
-
-
-#define HEVC_MV_INFO 0x310d
-#define HEVC_QP_INFO 0x3137
-#define HEVC_SKIP_INFO 0x3136
-
-/* only when we decoded one field or one frame,
-we can call this function to get qos info*/
-static void get_picture_qos_info(struct AVS2Decoder_s *dec)
-{
- struct avs2_frame_s *picture = dec->avs2_dec.hc.cur_pic;
- struct vdec_s *vdec = hw_to_vdec(dec);
- if (!picture) {
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s decode picture is none exist\n");
-
- return;
- }
- if (vdec->mvfrm) {
- picture->frame_size = vdec->mvfrm->frame_size;
- picture->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- }
-
-/*
-#define DEBUG_QOS
-*/
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
-
- data = READ_VREG(HEVC_MV_INFO);
- if (picture->slice_type == I_IMG)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_mv = a[2];
- picture->avg_mv = a[1];
- picture->min_mv = a[0];
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
-
- data = READ_VREG(HEVC_QP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_qp = a[2];
- picture->avg_qp = a[1];
- picture->min_qp = a[0];
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
-
- data = READ_VREG(HEVC_SKIP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_skip = a[2];
- picture->avg_skip = a[1];
- picture->min_skip = a[0];
-
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
- } else {
- uint32_t blk88_y_count;
- uint32_t blk88_c_count;
- uint32_t blk22_mv_count;
- uint32_t rdata32;
- int32_t mv_hi;
- int32_t mv_lo;
- uint32_t rdata32_l;
- uint32_t mvx_L0_hi;
- uint32_t mvy_L0_hi;
- uint32_t mvx_L1_hi;
- uint32_t mvy_L1_hi;
- int64_t value;
- uint64_t temp_value;
-#ifdef DEBUG_QOS
- int pic_number = 0;
-#endif
-
- picture->max_mv = 0;
- picture->avg_mv = 0;
- picture->min_mv = 0;
-
- picture->max_skip = 0;
- picture->avg_skip = 0;
- picture->min_skip = 0;
-
- picture->max_qp = 0;
- picture->avg_qp = 0;
- picture->min_qp = 0;
-
-
-
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "slice_type:%d, poc:%d\n",
- picture->slice_type,
- pic_number);
-#endif
- /* set rd_idx to 0 */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0);
-
- blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_y_count == 0) {
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_y_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_y_count,
- rdata32, blk88_y_count);
-#endif
- picture->avg_qp = rdata32/blk88_y_count;
- /* intra_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] Y intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- /* skipped_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- picture->avg_skip = rdata32*100/blk88_y_count;
- /* coeff_non_zero_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_y_count*1)),
- '%', rdata32);
-#endif
- /* blk66_c_count */
- blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_c_count == 0) {
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_c_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] C QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_c_count,
- rdata32, blk88_c_count);
-#endif
- /* intra_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] C intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* skipped_cu_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] C skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* coeff_non_zero_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_c_count*1)),
- '%', rdata32);
-#endif
-
- /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
- 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "[Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
-#endif
- picture->min_qp = (rdata32>>0)&0xff;
-
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "[Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
-#endif
- picture->max_qp = (rdata32>>8)&0xff;
-
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "[Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
- avs2_print(dec, 0, "[Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
-#endif
-
- /* blk22_mv_count */
- blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk22_mv_count == 0) {
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] NO MV Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* mvy_L1_count[39:32], mvx_L1_count[39:32],
- mvy_L0_count[39:32], mvx_L0_count[39:32] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- /* should all be 0x00 or 0xff */
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] MV AVG High Bits: 0x%X\n",
- pic_number, rdata32);
-#endif
- mvx_L0_hi = ((rdata32>>0)&0xff);
- mvy_L0_hi = ((rdata32>>8)&0xff);
- mvx_L1_hi = ((rdata32>>16)&0xff);
- mvy_L1_hi = ((rdata32>>24)&0xff);
-
- /* mvx_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvx_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
- value = div_s64(value, blk22_mv_count);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
- pic_number, (int)value,
- value, blk22_mv_count);
-#endif
- picture->avg_mv = value;
-
- /* mvy_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvy_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvx_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvx_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvy_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvy_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "[Picture %d Quality] MVX_L0 MAX : %d\n",
- pic_number, mv_hi);
-#endif
- picture->max_mv = mv_hi;
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
- avs2_print(dec, 0, "[Picture %d Quality] MVX_L0 MIN : %d\n",
- pic_number, mv_lo);
-#endif
- picture->min_mv = mv_lo;
-
-#ifdef DEBUG_QOS
- /* {mvy_L0_max, mvy_L0_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
- avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- avs2_print(dec, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvx_L1_max, mvx_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- avs2_print(dec, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvy_L1_max, mvy_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- avs2_print(dec, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n",
- pic_number, mv_lo);
-#endif
-
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL);
-#ifdef DEBUG_QOS
- avs2_print(dec, 0,
- "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
- pic_number, rdata32);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- }
-}
-
-static irqreturn_t vavs2_isr_thread_fn(int irq, void *data)
-{
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data;
- unsigned int dec_status = dec->dec_status;
- int i, ret;
- int32_t start_code = 0;
-
- /*if (dec->wait_buf)
- pr_info("set wait_buf to 0\r\n");
- */
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s decode_status 0x%x process_state %d lcu 0x%x\n",
- __func__, dec_status, dec->process_state,
- READ_VREG(HEVC_PARSER_LCU_START));
-
-#ifndef G12A_BRINGUP_DEBUG
- if (dec->eos) {
- PRINT_LINE();
- goto irq_handled_exit;
- }
-#endif
- dec->wait_buf = 0;
- if (dec_status == AVS2_DECODE_BUFEMPTY) {
- PRINT_LINE();
- if (dec->m_ins_flag) {
- reset_process_time(dec);
- if (!vdec_frame_based(hw_to_vdec(dec)))
- dec_again_process(dec);
- else {
- dec->dec_result = DEC_RESULT_DONE;
- reset_process_time(dec);
- amhevc_stop();
- vdec_schedule_work(&dec->work);
- }
- }
- goto irq_handled_exit;
- } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- PRINT_LINE();
- dec->start_decoding_flag |= 0x3;
- if (dec->m_ins_flag) {
- set_cuva_data(dec);
- update_decoded_pic(dec);
- get_picture_qos_info(dec);
- reset_process_time(dec);
- dec->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
-#if 0 /*def AVS2_10B_MMU*/
- if (dec->m_ins_flag) {
- /*avs2_recycle_mmu_buf_tail(dec);*/
- dec->used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- }
-#endif
-
-#if 0
- /*keep hardware state*/
- WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
- WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
- dec->mpred_abv_start_addr =
- READ_VREG(HEVC_MPRED_ABV_START_ADDR);
- /**/
-#endif
- vdec_schedule_work(&dec->work);
- }
- goto irq_handled_exit;
- }
- PRINT_LINE();
-#if 0
- if (dec_status == AVS2_EOS) {
- if (dec->m_ins_flag)
- reset_process_time(dec);
-
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "AVS2_EOS, flush buffer\r\n");
-
- avs2_post_process(&dec->avs2_dec);
- avs2_prepare_display_buf(dec);
-
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "send AVS2_10B_DISCARD_NAL\r\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
- if (dec->m_ins_flag) {
- update_decoded_pic(dec);
- dec->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&dec->work);
- }
- goto irq_handled_exit;
- } else
-#endif
- if (dec_status == AVS2_DECODE_OVER_SIZE) {
- avs2_print(dec, 0,
- "avs2 decode oversize !!\n");
- debug |= (AVS2_DBG_DIS_LOC_ERROR_PROC |
- AVS2_DBG_DIS_SYS_ERROR_PROC);
- dec->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- if (dec->m_ins_flag)
- reset_process_time(dec);
- goto irq_handled_exit;
- }
- PRINT_LINE();
-
- if (dec->m_ins_flag)
- reset_process_time(dec);
-
- if (dec_status == AVS2_HEAD_SEQ_READY)
- start_code = SEQUENCE_HEADER_CODE;
- else if (dec_status == AVS2_HEAD_PIC_I_READY)
- start_code = I_PICTURE_START_CODE;
- else if (dec_status == AVS2_HEAD_PIC_PB_READY)
- start_code = PB_PICTURE_START_CODE;
- else if (dec_status == AVS2_STARTCODE_SEARCH_DONE)
- /*SEQUENCE_END_CODE, VIDEO_EDIT_CODE*/
- start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
-
- if (dec->process_state ==
- PROC_STATE_HEAD_AGAIN
- ) {
- if ((start_code == I_PICTURE_START_CODE)
- || (start_code == PB_PICTURE_START_CODE)) {
- avs2_print(dec, 0,
- "PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n",
- start_code);
- goto irq_handled_exit;
- } else {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "PROC_STATE_HEAD_AGAIN, start_code 0x%x\r\n",
- start_code);
- dec->process_state = PROC_STATE_HEAD_DONE;
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
- goto irq_handled_exit;
- }
- } else if (dec->process_state ==
- PROC_STATE_DECODE_AGAIN) {
- if ((start_code == I_PICTURE_START_CODE)
- || (start_code == PB_PICTURE_START_CODE)) {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "PROC_STATE_DECODE_AGAIN=> decode_slice, start_code 0x%x\r\n",
- start_code);
- goto decode_slice;
- } else {
- avs2_print(dec, 0,
- "PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
- start_code);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
- goto irq_handled_exit;
- }
- }
-
- if ((start_code == I_PICTURE_START_CODE)
- || (start_code == PB_PICTURE_START_CODE)
- || (start_code == SEQUENCE_END_CODE)
- || (start_code == VIDEO_EDIT_CODE)) {
- PRINT_LINE();
-
- if (dec->avs2_dec.hc.cur_pic != NULL) {
- int32_t ii;
-#ifdef AVS2_10B_MMU
- avs2_recycle_mmu_buf_tail(dec);
-#endif
- check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
- avs2_post_process(&dec->avs2_dec);
-
- if (debug & AVS2_DBG_PRINT_PIC_LIST)
- dump_pic_list(dec);
-
- avs2_prepare_display_buf(dec);
- dec->avs2_dec.hc.cur_pic = NULL;
- for (ii = 0; ii < dec->avs2_dec.ref_maxbuffer;
- ii++) {
- struct avs2_frame_s *pic =
- dec->avs2_dec.fref[ii];
- if (pic->bg_flag == 0 &&
- pic->is_output == -1 &&
- pic->mmu_alloc_flag &&
- pic->vf_ref == 0) {
- if (pic->refered_by_others == 0) {
-#ifdef AVS2_10B_MMU
- pic->mmu_alloc_flag = 0;
- /*release_buffer_4k(
- dec->avs2_dec.fref[ii]->index);*/
- decoder_mmu_box_free_idx(dec->mmu_box,
- pic->index);
-#ifdef DYNAMIC_ALLOC_HEAD
- decoder_bmmu_box_free_idx(
- dec->bmmu_box,
- HEADER_BUFFER_IDX(pic->index));
- pic->header_adr = 0;
-#endif
-#endif
-#ifndef MV_USE_FIXED_BUF
- decoder_bmmu_box_free_idx(
- dec->bmmu_box,
- MV_BUFFER_IDX(pic->index));
- pic->mpred_mv_wr_start_addr = 0;
-#endif
- }
- /*
- decoder_bmmu_box_free_idx(
- dec->bmmu_box,
- VF_BUFFER_IDX(pic->index));
- dec->cma_alloc_addr = 0;*/
- }
- }
- }
- }
-
- if ((dec_status == AVS2_HEAD_PIC_I_READY)
- || (dec_status == AVS2_HEAD_PIC_PB_READY)) {
- PRINT_LINE();
-
- if (debug & AVS2_DBG_SEND_PARAM_WITH_REG) {
- get_rpm_param(
- &dec->avs2_dec.param);
- } else {
-
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++)
- dec->avs2_dec.param.l.data[i + ii] =
- dec->rpm_ptr[i + 3 - ii];
- }
- }
-#ifdef SANITY_CHECK
- if (dec->avs2_dec.param.p.num_of_ref_cur >
- dec->avs2_dec.ref_maxbuffer) {
- pr_info("Warning: Wrong num_of_ref_cur %d, force to %d\n",
- dec->avs2_dec.param.p.num_of_ref_cur,
- dec->avs2_dec.ref_maxbuffer);
- dec->avs2_dec.param.p.num_of_ref_cur =
- dec->avs2_dec.ref_maxbuffer;
- }
-#endif
- PRINT_LINE();
-
- debug_buffer_mgr_more(dec);
- get_frame_rate(&dec->avs2_dec.param, dec);
-
-#if 1 // The video_signal_type is type of uint16_t and result false, so comment it out.
- if (dec->avs2_dec.param.p.video_signal_type
- & (1<<30)) {
- union param_u *pPara;
-
- avs2_print(dec, 0,
- "avs2 HDR meta data present\n");
- pPara = &dec->avs2_dec.param;
-
- /*clean this flag*/
- pPara->p.video_signal_type
- &= ~(1<<30);
-
- dec->vf_dp.present_flag = 1;
-
- dec->vf_dp.white_point[0]
- = pPara->p.white_point_x;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "white_point[0]:0x%x\n",
- dec->vf_dp.white_point[0]);
-
- dec->vf_dp.white_point[1]
- = pPara->p.white_point_y;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "white_point[1]:0x%x\n",
- dec->vf_dp.white_point[1]);
-
- for (i = 0; i < 3; i++) {
- dec->vf_dp.primaries[i][0]
- = pPara->p.display_primaries_x[i];
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "primaries[%d][0]:0x%x\n",
- i,
- dec->vf_dp.primaries[i][0]);
- }
-
- for (i = 0; i < 3; i++) {
- dec->vf_dp.primaries[i][1]
- = pPara->p.display_primaries_y[i];
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "primaries[%d][1]:0x%x\n",
- i,
- dec->vf_dp.primaries[i][1]);
- }
-
- dec->vf_dp.luminance[0]
- = pPara->p.max_display_mastering_luminance;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "luminance[0]:0x%x\n",
- dec->vf_dp.luminance[0]);
-
- dec->vf_dp.luminance[1]
- = pPara->p.min_display_mastering_luminance;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "luminance[1]:0x%x\n",
- dec->vf_dp.luminance[1]);
-
-
- dec->vf_dp.content_light_level.present_flag
- = 1;
- dec->vf_dp.content_light_level.max_content
- = pPara->p.max_content_light_level;
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "max_content:0x%x\n",
- dec->vf_dp.content_light_level.max_content);
-
- dec->vf_dp.content_light_level.max_pic_average
- = pPara->p.max_picture_average_light_level;
-
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "max_pic_average:0x%x\n",
- dec->vf_dp.content_light_level.max_pic_average);
- }
-#endif
-
-
- if (dec->video_ori_signal_type !=
- ((dec->avs2_dec.param.p.video_signal_type << 16)
- | dec->avs2_dec.param.p.color_description)) {
- u32 v = dec->avs2_dec.param.p.video_signal_type;
- u32 c = dec->avs2_dec.param.p.color_description;
- u32 convert_c = c;
-
- if (v & 0x2000) {
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "video_signal_type present:\n");
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- " %s %s\n",
- video_format_names[(v >> 10) & 7],
- ((v >> 9) & 1) ?
- "full_range" : "limited");
- if (v & 0x100) {
- u32 transfer;
- u32 maxtrix;
-
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "color_description present:\n");
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "color_primarie = %d\n",
- v & 0xff);
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "transfer_characteristic = %d\n",
- (c >> 8) & 0xff);
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- " matrix_coefficient = %d\n",
- c & 0xff);
-
- transfer = (c >> 8) & 0xFF;
- if (transfer >= 15)
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "unsupport transfer_characteristic\n");
- else if (transfer == 14)
- transfer = 18; /* HLG */
- else if (transfer == 13)
- transfer = 32;
- else if (transfer == 12)
- transfer = 16;
- else if (transfer == 11)
- transfer = 15;
-
- maxtrix = c & 0xFF;
- if (maxtrix >= 10)
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- "unsupport matrix_coefficient\n");
- else if (maxtrix == 9)
- maxtrix = 10;
- else if (maxtrix == 8)
- maxtrix = 9;
-
- convert_c = (transfer << 8) | (maxtrix);
-
- avs2_print(dec, AVS2_DBG_HDR_INFO,
- " convered c:0x%x\n",
- convert_c);
- }
- }
-
- if (enable_force_video_signal_type)
- dec->video_signal_type
- = force_video_signal_type;
- else {
- dec->video_signal_type
- = (v << 16) | convert_c;
-
- dec->video_ori_signal_type
- = (v << 16) | c;
- }
-
- video_signal_type = dec->video_signal_type;
- }
- }
-#if 0
- if ((debug_again & 0x4) &&
- dec->process_state ==
- PROC_STATE_INIT) {
- if (start_code == PB_PICTURE_START_CODE) {
- dec->process_state = PROC_STATE_TEST1;
- dec_again_process(dec);
- goto irq_handled_exit;
- }
- }
-#endif
- PRINT_LINE();
- avs2_prepare_header(&dec->avs2_dec, start_code);
-
- if (start_code == SEQUENCE_HEADER_CODE ||
- start_code == VIDEO_EDIT_CODE ||
- start_code == SEQUENCE_END_CODE) {
- if (dec->m_ins_flag &&
- vdec_frame_based(hw_to_vdec(dec)))
- dec->start_decoding_flag |= 0x1;
- dec->process_state = PROC_STATE_HEAD_DONE;
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
- } else if (start_code == I_PICTURE_START_CODE ||
- start_code == PB_PICTURE_START_CODE) {
- ret = 0;
- if (dec->pic_list_init_flag == 0) {
- int32_t lcu_size_log2 =
- log2i(dec->avs2_dec.param.p.lcu_size);
-
- avs2_init_global_buffers(&dec->avs2_dec);
- /*avs2_dec->m_bg->index is
- set to dec->used_buf_num - 1*/
- init_pic_list(dec, lcu_size_log2);
- init_pic_list_hw(dec);
- }
- ret = avs2_process_header(&dec->avs2_dec);
- if (!dec->m_ins_flag)
- dec->slice_idx++;
-
- if (dec->m_ins_flag && ret
- && dec->avs2_dec.hc.cur_pic->cuva_data_buf != NULL)
- release_cuva_data(dec->avs2_dec.hc.cur_pic);
-
- PRINT_LINE();
-#ifdef I_ONLY_SUPPORT
- if ((start_code == PB_PICTURE_START_CODE) &&
- (dec->i_only & 0x2))
- ret = -2;
-#endif
-#ifdef AVS2_10B_MMU
- if (ret >= 0) {
- ret = avs2_alloc_mmu(dec,
- dec->avs2_dec.hc.cur_pic->index,
- dec->avs2_dec.img.width,
- dec->avs2_dec.img.height,
- dec->avs2_dec.input.sample_bit_depth,
- dec->frame_mmu_map_addr);
- if (ret >= 0) {
- dec->cur_fb_idx_mmu =
- dec->avs2_dec.hc.cur_pic->index;
- dec->avs2_dec.hc.cur_pic->mmu_alloc_flag = 1;
- } else
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- dec->avs2_dec.hc.cur_pic->index,
- ret);
- }
-#endif
-
-#ifndef MV_USE_FIXED_BUF
- if (ret >= 0 &&
- dec->avs2_dec.hc.cur_pic->
- mpred_mv_wr_start_addr == 0) {
- unsigned long buf_addr;
- unsigned mv_buf_size = get_mv_buf_size(
- dec,
- dec->avs2_dec.hc.cur_pic->pic_w,
- dec->avs2_dec.hc.cur_pic->pic_h);
- int i = dec->avs2_dec.hc.cur_pic->index;
- /*if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- mv_buf_size = 0x120000 * 4;*/
- if (decoder_bmmu_box_alloc_buf_phy
- (dec->bmmu_box,
- MV_BUFFER_IDX(i),
- mv_buf_size,
- DRIVER_NAME,
- &buf_addr) < 0)
- ret = -1;
- else
- dec->avs2_dec.hc.cur_pic->
- mpred_mv_wr_start_addr
- = buf_addr;
- }
-#endif
- if (ret < 0) {
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n",
- ret);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_10B_DISCARD_NAL);
- #ifdef AVS2_10B_MMU
- avs2_recycle_mmu_buf(dec);
- #endif
- if (dec->m_ins_flag) {
- dec->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&dec->work);
- }
-
- goto irq_handled_exit;
- } else {
- PRINT_LINE();
- dec->avs2_dec.hc.cur_pic->stream_offset =
- READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- /*
- struct PIC_BUFFER_CONFIG_s *cur_pic
- = &cm->cur_frame->buf;
- cur_pic->decode_idx = dec->frame_count;
- */
- if (!dec->m_ins_flag) {
- dec->frame_count++;
- decode_frame_count[dec->index]
- = dec->frame_count;
- }
- /*MULTI_INSTANCE_SUPPORT*/
- if (dec->chunk) {
- dec->avs2_dec.hc.cur_pic->pts =
- dec->chunk->pts;
- dec->avs2_dec.hc.cur_pic->pts64 =
- dec->chunk->pts64;
- }
- /**/
- dec->avs2_dec.hc.cur_pic->bit_depth
- = dec->avs2_dec.input.sample_bit_depth;
- dec->avs2_dec.hc.cur_pic->double_write_mode
- = get_double_write_mode(dec);
-decode_slice:
- PRINT_LINE();
-
- config_mc_buffer(dec);
- config_mcrcc_axi_hw(dec);
- config_mpred_hw(dec);
- config_dblk_hw(dec);
- config_sao_hw(dec);
- config_alf_hw(dec);
- config_other_hw(dec);
-
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "=>fref0 imgtr_fwRefDistance %d, fref1 imgtr_fwRefDistance %d, dis2/dis3/dis4 %d %d %d img->tr %d\n",
- dec->avs2_dec.fref[0]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[1]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[2]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[3]->imgtr_fwRefDistance,
- dec->avs2_dec.fref[4]->imgtr_fwRefDistance,
- dec->avs2_dec.img.tr);
-
- if ((debug_again & 0x2) &&
- dec->process_state ==
- PROC_STATE_INIT) {
- dec->process_state = PROC_STATE_DECODING;
- dec_again_process(dec);
- goto irq_handled_exit;
- }
-
- dec->process_state = PROC_STATE_DECODING;
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
-
- }
-
- if (dec->m_ins_flag)
- start_process_time(dec);
- }
-irq_handled_exit:
- PRINT_LINE();
- dec->process_busy = 0;
- return IRQ_HANDLED;
-}
-
-static irqreturn_t vavs2_isr(int irq, void *data)
-{
- int i;
- unsigned int dec_status;
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)data;
- uint debug_tag;
-
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
-
- if (!dec)
- return IRQ_HANDLED;
- if (dec->init_flag == 0)
- return IRQ_HANDLED;
- if (dec->process_busy)/*on process.*/
- return IRQ_HANDLED;
- dec->dec_status = dec_status;
- dec->process_busy = 1;
- if (debug & AVS2_DBG_IRQ_EVENT)
- avs2_print(dec, 0,
- "avs2 isr dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x)\n",
- dec_status, READ_VREG(HEVC_PARSER_LCU_START),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR)
- );
-
- debug_tag = READ_HREG(DEBUG_REG1);
- if (debug_tag & 0x10000) {
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- dec->lmem_phy_addr,
- LMEM_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- pr_info("LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- pr_info("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- dec->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- pr_info("\n");
- }
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == dec->decode_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- dec->ucode_pause_pos = udebug_pause_pos;
- } else if (debug_tag & 0x20000)
- dec->ucode_pause_pos = 0xffffffff;
- if (dec->ucode_pause_pos)
- reset_process_time(dec);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- } else if (debug_tag != 0) {
- pr_info(
- "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
- READ_HREG(DEBUG_REG2),
- READ_VREG(HEVC_PARSER_LCU_START));
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == dec->decode_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- dec->ucode_pause_pos = udebug_pause_pos;
- }
- if (dec->ucode_pause_pos)
- reset_process_time(dec);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- dec->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (!dec->m_ins_flag) {
- if (dec->error_flag == 1) {
- dec->error_flag = 2;
- dec->process_busy = 0;
- return IRQ_HANDLED;
- } else if (dec->error_flag == 3) {
- dec->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if ((dec->pic_list_init_flag) &&
- get_free_buf_count(dec) <= 0) {
- /*
- if (dec->wait_buf == 0)
- pr_info("set wait_buf to 1\r\n");
- */
- dec->wait_buf = 1;
- dec->process_busy = 0;
- if (debug & AVS2_DBG_IRQ_EVENT)
- avs2_print(dec, 0, "wait_buf\n");
- return IRQ_HANDLED;
- } else if (force_disp_pic_index) {
- dec->process_busy = 0;
- return IRQ_HANDLED;
- }
- }
- return IRQ_WAKE_THREAD;
-}
-
-static void vavs2_put_timer_func(struct timer_list *timer)
-{
- struct AVS2Decoder_s *dec = container_of(timer,
- struct AVS2Decoder_s, timer);
- uint8_t empty_flag;
- unsigned int buf_level;
-
- enum receviver_start_e state = RECEIVER_INACTIVE;
- if (dec->m_ins_flag) {
- if (hw_to_vdec(dec)->next_status
- == VDEC_STATUS_DISCONNECTED) {
- dec->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&dec->work);
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "vdec requested to be disconnected\n");
- return;
- }
- }
- if (dec->init_flag == 0) {
- if (dec->stat & STAT_TIMER_ARM) {
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(&dec->timer);
- }
- return;
- }
- if (dec->m_ins_flag == 0) {
- if (vf_get_receiver(dec->provider_name)) {
- state =
- vf_notify_receiver(dec->provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- } else
- state = RECEIVER_INACTIVE;
-
- empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
- /* error watchdog */
- if (empty_flag == 0) {
- /* decoder has input */
- if ((debug & AVS2_DBG_DIS_LOC_ERROR_PROC) == 0) {
-
- buf_level = READ_VREG(HEVC_STREAM_LEVEL);
- /* receiver has no buffer to recycle */
- if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&dec->display_q) &&
- buf_level > 0x200)
- ) {
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
-
- if ((debug & AVS2_DBG_DIS_SYS_ERROR_PROC) == 0) {
- /* receiver has no buffer to recycle */
- /*if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&dec->display_q))) {
- pr_info("avs2 something error,need reset\n");
- }*/
- }
- }
- } else {
- if (
- (decode_timeout_val > 0) &&
- (dec->start_process_time > 0) &&
- ((1000 * (jiffies - dec->start_process_time) / HZ)
- > decode_timeout_val)
- ) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- if (dec->last_lcu_idx == current_lcu_idx) {
- if (dec->decode_timeout_count > 0)
- dec->decode_timeout_count--;
- if (dec->decode_timeout_count == 0) {
- if (input_frame_based(
- hw_to_vdec(dec)) ||
- (READ_VREG(HEVC_STREAM_LEVEL) > 0x200))
- timeout_process(dec);
- else {
- avs2_print(dec, 0,
- "timeout & empty, again\n");
- dec_again_process(dec);
- }
- }
- } else {
- start_process_time(dec);
- dec->last_lcu_idx = current_lcu_idx;
- }
- }
- }
-
- if ((dec->ucode_pause_pos != 0) &&
- (dec->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != dec->ucode_pause_pos) {
- dec->ucode_pause_pos = 0;
- WRITE_HREG(DEBUG_REG1, 0);
- }
- if (debug & AVS2_DBG_DUMP_DATA) {
- debug &= ~AVS2_DBG_DUMP_DATA;
- avs2_print(dec, 0,
- "%s: chunk size 0x%x off 0x%x sum 0x%x\n",
- __func__,
- dec->chunk->size,
- dec->chunk->offset,
- get_data_check_sum(dec, dec->chunk->size)
- );
- dump_data(dec, dec->chunk->size);
- }
- if (debug & AVS2_DBG_DUMP_PIC_LIST) {
- dump_pic_list(dec);
- debug &= ~AVS2_DBG_DUMP_PIC_LIST;
- }
- if (debug & AVS2_DBG_TRIG_SLICE_SEGMENT_PROC) {
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- debug &= ~AVS2_DBG_TRIG_SLICE_SEGMENT_PROC;
- }
- if (debug & AVS2_DBG_DUMP_RPM_BUF) {
- int i;
-
- pr_info("RPM:\n");
- for (i = 0; i < RPM_BUF_SIZE; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- pr_info("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- dec->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- pr_info("\n");
- }
- debug &= ~AVS2_DBG_DUMP_RPM_BUF;
- }
- if (debug & AVS2_DBG_DUMP_LMEM_BUF) {
- int i;
-
- pr_info("LMEM:\n");
- for (i = 0; i < LMEM_BUF_SIZE; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- pr_info("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- dec->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- pr_info("\n");
- }
- debug &= ~AVS2_DBG_DUMP_LMEM_BUF;
- }
- /*if (debug & AVS2_DBG_HW_RESET) {
- }*/
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
- if (pop_shorts != 0) {
- int i;
- u32 sum = 0;
- pr_info("pop stream 0x%x shorts\r\n", pop_shorts);
- for (i = 0; i < pop_shorts; i++) {
- u32 data =
- (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- if ((i & 0xf) == 0)
- pr_info("%04x:", i);
- pr_info("%04x ", data);
- if (((i + 1) & 0xf) == 0)
- pr_info("\r\n");
- sum += data;
- }
- pr_info("\r\nsum = %x\r\n", sum);
- pop_shorts = 0;
- }
- if (dbg_cmd != 0) {
- if (dbg_cmd == 1) {
- u32 disp_laddr;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
- get_double_write_mode(dec) == 0) {
- disp_laddr =
- READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
- } else {
- struct canvas_s cur_canvas;
- canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
- & 0xff), &cur_canvas);
- disp_laddr = cur_canvas.addr;
- }
- pr_info("current displayed buffer address %x\r\n",
- disp_laddr);
- }
- dbg_cmd = 0;
- }
- /*don't changed at start.*/
- if (dec->get_frame_dur && dec->show_frame_num > 60 &&
- dec->frame_dur > 0 && dec->saved_resolution !=
- frame_width * frame_height *
- (96000 / dec->frame_dur)) {
- int fps = 96000 / dec->frame_dur;
- if (hevc_source_changed(VFORMAT_AVS2,
- frame_width, frame_height, fps) > 0)
- dec->saved_resolution = frame_width *
- frame_height * fps;
- }
-
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(timer);
-}
-
-
-int vavs2_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
-
- if (!dec)
- return -1;
-
- vstatus->frame_width = dec->frame_width;
- vstatus->frame_height = dec->frame_height;
-
- if (dec->frame_dur != 0)
- vstatus->frame_rate = ((96000 * 10 / dec->frame_dur) % 10) < 5 ?
- 96000 / dec->frame_dur : (96000 / dec->frame_dur +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = 0;
- vstatus->status = dec->stat | dec->fatal_error;
- vstatus->frame_dur = dec->frame_dur;
- vstatus->bit_rate = dec->gvs->bit_rate;
- vstatus->frame_data = dec->gvs->frame_data;
- vstatus->total_data = dec->gvs->total_data;
- vstatus->frame_count = dec->gvs->frame_count;
- vstatus->error_frame_count = dec->gvs->error_frame_count;
- vstatus->drop_frame_count = dec->gvs->drop_frame_count;
- vstatus->i_decoded_frames = dec->gvs->i_decoded_frames;
- vstatus->i_lost_frames = dec->gvs->i_lost_frames;
- vstatus->i_concealed_frames = dec->gvs->i_concealed_frames;
- vstatus->p_decoded_frames = dec->gvs->p_decoded_frames;
- vstatus->p_lost_frames = dec->gvs->p_lost_frames;
- vstatus->p_concealed_frames = dec->gvs->p_concealed_frames;
- vstatus->b_decoded_frames = dec->gvs->b_decoded_frames;
- vstatus->b_lost_frames = dec->gvs->b_lost_frames;
- vstatus->b_concealed_frames = dec->gvs->b_concealed_frames;
- vstatus->total_data = dec->gvs->total_data;
- vstatus->samp_cnt = dec->gvs->samp_cnt;
- vstatus->offset = dec->gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
- return 0;
-}
-
-int vavs2_set_isreset(struct vdec_s *vdec, int isreset)
-{
- is_reset = isreset;
- return 0;
-}
-
-static void vavs2_prot_init(struct AVS2Decoder_s *dec)
-{
- unsigned int data32;
-
- avs2_config_work_space_hw(dec);
- if (dec->pic_list_init_flag)
- init_pic_list_hw(dec);
-
- avs2_init_decoder_hw(dec);
-
-#if 1
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%s\n", __func__);
- data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 |
- (1 << 0)/*stream_fetch_enable*/
- ;
- WRITE_VREG(HEVC_STREAM_CONTROL, data32);
-#if 0
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- pr_info("avs2 prot init error %d\n", __LINE__);
- return;
- }
-#endif
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
-#endif
-
-
-
- WRITE_VREG(HEVC_WAIT_FLAG, 1);
-
- /* WRITE_VREG(HEVC_MPSR, 1); */
-
- /* clear mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(HEVC_PSCALE_CTRL, 0);
-
- WRITE_VREG(DEBUG_REG1, 0x0);
- /*check vps/sps/pps/i-slice in ucode*/
- WRITE_VREG(NAL_SEARCH_CTL, 0x8);
-
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-
- config_cuva_buf(dec);
-}
-
-#ifdef I_ONLY_SUPPORT
-static int vavs2_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- if (i_only_flag & 0x100)
- return 0;
- if (trickmode == TRICKMODE_I || trickmode == TRICKMODE_I_HEVC)
- dec->i_only = 0x3;
- else if (trickmode == TRICKMODE_NONE)
- dec->i_only = 0x0;
- return 0;
-}
-#endif
-
-static int vavs2_local_init(struct AVS2Decoder_s *dec)
-{
- int i;
- int ret;
- int width, height;
-
- dec->gvs = vzalloc(sizeof(struct vdec_info));
- if (NULL == dec->gvs) {
- avs2_print(dec, 0,
- "the struct of vdec status malloc failed.\n");
- return -1;
- }
-#ifdef DEBUG_PTS
- dec->pts_missed = 0;
- dec->pts_hit = 0;
-#endif
- dec->new_frame_displayed = 0;
- dec->last_put_idx = -1;
- dec->saved_resolution = 0;
- dec->get_frame_dur = false;
- on_no_keyframe_skiped = 0;
- width = dec->vavs2_amstream_dec_info.width;
- height = dec->vavs2_amstream_dec_info.height;
- dec->frame_dur =
- (dec->vavs2_amstream_dec_info.rate ==
- 0) ? 3600 : dec->vavs2_amstream_dec_info.rate;
- if (width && height)
- dec->frame_ar = height * 0x100 / width;
-/*
-TODO:FOR VERSION
-*/
- avs2_print(dec, AVS2_DBG_BUFMGR,
- "avs2: ver (%d,%d) decinfo: %dx%d rate=%d\n", avs2_version,
- 0, width, height, dec->frame_dur);
-
- if (dec->frame_dur == 0)
- dec->frame_dur = 96000 / 24;
-#ifdef I_ONLY_SUPPORT
- if (i_only_flag & 0x100)
- dec->i_only = i_only_flag & 0xff;
- else if ((unsigned long) dec->vavs2_amstream_dec_info.param
- & 0x08)
- dec->i_only = 0x7;
- else
- dec->i_only = 0x0;
-#endif
- INIT_KFIFO(dec->display_q);
- INIT_KFIFO(dec->newframe_q);
-
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &dec->vfpool[i];
- dec->vfpool[i].index = -1;
- kfifo_put(&dec->newframe_q, vf);
- }
-
-
- ret = avs2_local_init(dec);
-
- return ret;
-}
-
-
-static s32 vavs2_init(struct vdec_s *vdec)
-{
- int ret = -1, size = -1;
- int fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
-
- timer_setup(&dec->timer, vavs2_put_timer_func, 0);
-
- dec->stat |= STAT_TIMER_INIT;
- if (vavs2_local_init(dec) < 0)
- return -EBUSY;
-
- vdec_set_vframe_comm(vdec, DRIVER_NAME);
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- size = get_firmware_data(VIDEO_DEC_AVS2_MMU, fw->data);
- if (size < 0) {
- pr_err("get firmware fail.\n");
- vfree(fw);
- return -1;
- }
-
- fw->len = fw_size;
-
- if (dec->m_ins_flag) {
- dec->timer.expires = jiffies + PUT_INTERVAL;
-
- /*add_timer(&dec->timer);
-
- dec->stat |= STAT_TIMER_ARM;
- dec->stat |= STAT_ISR_REG;*/
-
- INIT_WORK(&dec->work, avs2_work);
- dec->fw = fw;
-
- return 0;
- }
-
- amhevc_enable();
-
- ret = amhevc_loadmc_ex(VFORMAT_AVS2, NULL, fw->data);
- if (ret < 0) {
- amhevc_disable();
- vfree(fw);
- pr_err("AVS2: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- vfree(fw);
-
- dec->stat |= STAT_MC_LOAD;
-
- /* enable AMRISC side protocol */
- vavs2_prot_init(dec);
-
- if (vdec_request_threaded_irq(VDEC_IRQ_0,
- vavs2_isr,
- vavs2_isr_thread_fn,
- IRQF_ONESHOT,/*run thread on this irq disabled*/
- "vavs2-irq", (void *)dec)) {
- pr_info("vavs2 irq register error.\n");
- amhevc_disable();
- return -ENOENT;
- }
-
- dec->stat |= STAT_ISR_REG;
-
- dec->provider_name = PROVIDER_NAME;
- vf_provider_init(&vavs2_vf_prov, PROVIDER_NAME,
- &vavs2_vf_provider, dec);
- vf_reg_provider(&vavs2_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
- if (dec->frame_dur != 0) {
- if (!is_reset)
- vf_notify_receiver(dec->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)dec->frame_dur));
- }
- dec->stat |= STAT_VF_HOOK;
-
- dec->timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&dec->timer);
-
- dec->stat |= STAT_TIMER_ARM;
-
- /* dec->stat |= STAT_KTHREAD; */
- dec->process_busy = 0;
- avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
- "%d, vavs2_init, RP=0x%x\n",
- __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
- return 0;
-}
-
-static int vmavs2_stop(struct AVS2Decoder_s *dec)
-{
- dec->init_flag = 0;
- dec->first_sc_checked = 0;
- if (dec->stat & STAT_TIMER_ARM) {
- del_timer_sync(&dec->timer);
- dec->stat &= ~STAT_TIMER_ARM;
- }
-
- if (dec->stat & STAT_VF_HOOK) {
- if (!is_reset)
- vf_notify_receiver(dec->provider_name,
- VFRAME_EVENT_PROVIDER_FR_END_HINT,
- NULL);
-
- vf_unreg_provider(&vavs2_vf_prov);
- dec->stat &= ~STAT_VF_HOOK;
- }
- avs2_local_uninit(dec);
- reset_process_time(dec);
- cancel_work_sync(&dec->work);
- uninit_mmu_buffers(dec);
- if (dec->fw) {
- vfree(dec->fw);
- dec->fw = NULL;
- }
-
- return 0;
-}
-
-static int amvdec_avs2_mmu_init(struct AVS2Decoder_s *dec)
-{
- int tvp_flag = vdec_secure(hw_to_vdec(dec)) ?
- CODEC_MM_FLAGS_TVP : 0;
- int buf_size = 48;
-
-#ifdef AVS2_10B_MMU
- dec->need_cache_size = buf_size * SZ_1M;
- dec->sc_start_time = get_jiffies_64();
- dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- dec->index, FRAME_BUFFERS,
- dec->need_cache_size,
- tvp_flag
- );
- if (!dec->mmu_box) {
- pr_err("avs2 alloc mmu box failed!!\n");
- return -1;
- }
-#endif
- dec->bmmu_box = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- dec->index,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
- if (!dec->bmmu_box) {
- pr_err("avs2 alloc bmmu box failed!!\n");
- return -1;
- }
- return 0;
-}
-
-/****************************************/
-static struct codec_profile_t amvdec_avs2_profile = {
- .name = "AVS2-V4L",
- .profile = ""
-};
-
-static unsigned char get_data_check_sum
- (struct AVS2Decoder_s *dec, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (!dec->chunk->block->is_mapped)
- data = codec_mm_vmap(dec->chunk->block->start +
- dec->chunk->offset, size);
- else
- data = ((u8 *)dec->chunk->block->start_virt) +
- dec->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- if (!dec->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void dump_data(struct AVS2Decoder_s *dec, int size)
-{
- int jj;
- u8 *data = NULL;
- int padding_size = dec->chunk->offset &
- (VDEC_FIFO_ALIGN - 1);
-
- if (!dec->chunk->block->is_mapped)
- data = codec_mm_vmap(dec->chunk->block->start +
- dec->chunk->offset, size);
- else
- data = ((u8 *)dec->chunk->block->start_virt) +
- dec->chunk->offset;
-
- avs2_print(dec, 0, "padding: ");
- for (jj = padding_size; jj > 0; jj--)
- avs2_print_cont(dec,
- 0,
- "%02x ", *(data - jj));
- avs2_print_cont(dec, 0, "data adr %p\n",
- data);
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- avs2_print(dec,
- 0,
- "%06x:", jj);
- avs2_print_cont(dec,
- 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- avs2_print(dec,
- 0,
- "\n");
- }
- avs2_print(dec,
- 0,
- "\n");
-
- if (!dec->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
-}
-
-static void avs2_work(struct work_struct *work)
-{
- struct AVS2Decoder_s *dec = container_of(work,
- struct AVS2Decoder_s, work);
- struct vdec_s *vdec = hw_to_vdec(dec);
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
- "%s dec_result %d %x %x %x\n",
- __func__,
- dec->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
-
- if (((dec->dec_result == DEC_RESULT_GET_DATA) ||
- (dec->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(dec)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(vdec)) {
- dec->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&dec->work);
- return;
- }
-
- if (dec->dec_result == DEC_RESULT_GET_DATA) {
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
- vdec_vframe_dirty(vdec, dec->chunk);
- vdec_clean_input(vdec);
- }
-
- if (get_free_buf_count(dec) >=
- run_ready_min_buf_num) {
- int r;
- int decode_size;
- r = vdec_prepare_input(vdec, &dec->chunk);
- if (r < 0) {
- dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- avs2_print(dec,
- PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&dec->work);
- return;
- }
- dec->dec_result = DEC_RESULT_NONE;
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s: chunk size 0x%x sum 0x%x\n",
- __func__, r,
- (debug & PRINT_FLAG_VDEC_STATUS) ?
- get_data_check_sum(dec, r) : 0
- );
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(dec, dec->chunk->size);
-
- decode_size = dec->chunk->size +
- (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
-
- WRITE_VREG(HEVC_DECODE_SIZE,
- READ_VREG(HEVC_DECODE_SIZE) + decode_size);
-
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
-
- start_process_time(dec);
-
- } else{
- dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&dec->work);
- }
- return;
- } else if (dec->dec_result == DEC_RESULT_DONE) {
- /* if (!dec->ctx_valid)
- dec->ctx_valid = 1; */
- dec->slice_idx++;
- dec->frame_count++;
- dec->process_state = PROC_STATE_INIT;
- decode_frame_count[dec->index] = dec->frame_count;
-
-#ifdef AVS2_10B_MMU
- dec->used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
-#endif
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
- __func__,
- dec->frame_count,
- dec->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- dec->start_shift_bytes
- );
- vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
- } else if (dec->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- dec->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&dec->work);
- return;
- }
- } else if (dec->dec_result == DEC_RESULT_EOS) {
- avs2_print(dec, 0,
- "%s: end of stream\n",
- __func__);
- dec->eos = 1;
- if ( dec->avs2_dec.hc.cur_pic != NULL) {
- check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
- avs2_post_process(&dec->avs2_dec);
- avs2_prepare_display_buf(dec);
- }
- vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
- } else if (dec->dec_result == DEC_RESULT_FORCE_EXIT) {
- avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
- if (dec->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- dec->stat &= ~STAT_VDEC_RUN;
- }
-
- if (dec->stat & STAT_ISR_REG) {
- if (!dec->m_ins_flag)
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0);
- vdec_free_irq(VDEC_IRQ_0, (void *)dec);
- dec->stat &= ~STAT_ISR_REG;
- }
- }
-
- if (dec->stat & STAT_TIMER_ARM) {
- del_timer_sync(&dec->timer);
- dec->stat &= ~STAT_TIMER_ARM;
- }
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec ==1)
- vdec_core_finish_run(vdec, CORE_MASK_HEVC);
- else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- if (dec->vdec_cb)
- dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg);
-}
-
-static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec)
-{
- /* new to do ... */
- vavs2_prot_init(dec);
- return 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- int tvp = vdec_secure(hw_to_vdec(dec)) ?
- CODEC_MM_FLAGS_TVP : 0;
- unsigned long ret = 0;
- avs2_print(dec,
- PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
- if (debug & AVS2_DBG_PIC_LEAK_WAIT)
- return ret;
-
- if (dec->eos)
- return ret;
- if (!dec->first_sc_checked) {
- int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp);
- dec->first_sc_checked = 1;
- avs2_print(dec, 0, "vavs2 cached=%d need_size=%d speed= %d ms\n",
- size, (dec->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - dec->sc_start_time) * 1000/HZ);
- }
-
- if (dec->next_again_flag &&
- (!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- if (parser_wr_ptr >= dec->pre_parser_wr_ptr &&
- (parser_wr_ptr - dec->pre_parser_wr_ptr) <
- again_threshold) {
- int r = vdec_sync_input(vdec);
- avs2_print(dec,
- PRINT_FLAG_VDEC_DETAIL, "%s buf lelvel:%x\n", __func__, r);
- return 0;
- }
- }
-/*
- if (vdec_stream_based(vdec) && (dec->pic_list_init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level)
- return 0;
- }
-*/
-
- if ((dec->pic_list_init_flag == 0) ||
- get_free_buf_count(dec) >=
- run_ready_min_buf_num)
- ret = 1;
-#ifdef CONSTRAIN_MAX_BUF_NUM
- if (dec->pic_list_init_flag) {
- if (run_ready_max_vf_only_num > 0 &&
- get_vf_ref_only_buf_count(dec) >=
- run_ready_max_vf_only_num
- )
- ret = 0;
- if (run_ready_display_q_num > 0 &&
- kfifo_len(&dec->display_q) >=
- run_ready_display_q_num)
- ret = 0;
-
- if (run_ready_max_buf_num == 0xff &&
- get_used_buf_count(dec) >=
- dec->avs2_dec.ref_maxbuffer)
- ret = 0;
- else if (run_ready_max_buf_num &&
- get_used_buf_count(dec) >=
- run_ready_max_buf_num)
- ret = 0;
- }
-#endif
- if (ret)
- not_run_ready[dec->index] = 0;
- else
- not_run_ready[dec->index]++;
-
- if (vdec->parallel_dec == 1)
- return ret ? CORE_MASK_HEVC : 0;
- else
- return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- int r;
-
- run_count[dec->index]++;
- dec->vdec_cb_arg = arg;
- dec->vdec_cb = callback;
- /* dec->chunk = vdec_prepare_input(vdec); */
- hevc_reset_core(vdec);
-
- if (vdec_stream_based(vdec)) {
- dec->pre_parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- dec->next_again_flag = 0;
- }
-
- r = vdec_prepare_input(vdec, &dec->chunk);
- if (r < 0) {
- input_empty[dec->index]++;
-
- dec->dec_result = DEC_RESULT_AGAIN;
-
- avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
- "ammvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&dec->work);
- return;
- }
- input_empty[dec->index] = 0;
- dec->dec_result = DEC_RESULT_NONE;
- dec->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-
- if (debug & PRINT_FLAG_VDEC_STATUS) {
- int ii;
- avs2_print(dec, 0,
- "%s (%d): size 0x%x (0x%x 0x%x) sum 0x%x (%x %x %x %x %x) bytes 0x%x",
- __func__,
- dec->frame_count, r,
- dec->chunk ? dec->chunk->size : 0,
- dec->chunk ? dec->chunk->offset : 0,
- dec->chunk ? ((vdec_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_STATUS)) ?
- get_data_check_sum(dec, r) : 0) : 0,
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- dec->start_shift_bytes);
- if (vdec_frame_based(vdec) && dec->chunk) {
- u8 *data = NULL;
- if (!dec->chunk->block->is_mapped)
- data = codec_mm_vmap(dec->chunk->block->start +
- dec->chunk->offset, 8);
- else
- data = ((u8 *)dec->chunk->block->start_virt) +
- dec->chunk->offset;
-
- avs2_print_cont(dec, 0, "data adr %p:",
- data);
- for (ii = 0; ii < 8; ii++)
- avs2_print_cont(dec, 0, "%02x ",
- data[ii]);
- if (!dec->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- avs2_print_cont(dec, 0, "\r\n");
- }
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else if (amhevc_loadmc_ex(VFORMAT_AVS2, NULL, dec->fw->data) < 0) {
- vdec->mc_loaded = 0;
- amhevc_disable();
- avs2_print(dec, 0,
- "%s: Error amvdec_loadmc fail\n", __func__);
- dec->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&dec->work);
- return;
- } else {
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_AVS2;
- }
-
-
- if (avs2_hw_ctx_restore(dec) < 0) {
- vdec_schedule_work(&dec->work);
- return;
- }
-
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_SEARCH_NEW_PIC);
-
- if (vdec_frame_based(vdec) && dec->chunk) {
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(dec, dec->chunk->size);
-
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
- r = dec->chunk->size +
- (dec->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = dec->chunk->size;
- }
-
- WRITE_VREG(HEVC_DECODE_SIZE, r);
- WRITE_VREG(HEVC_DECODE_COUNT, dec->slice_idx);
- dec->init_flag = 1;
-
- avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
- "%s: start hevc (%x %x %x)\n",
- __func__,
- READ_VREG(HEVC_DEC_STATUS_REG),
- READ_VREG(HEVC_MPC_E),
- READ_VREG(HEVC_MPSR));
-
- start_process_time(dec);
- mod_timer(&dec->timer, jiffies);
- dec->stat |= STAT_TIMER_ARM;
- dec->stat |= STAT_ISR_REG;
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- amhevc_start();
- dec->stat |= STAT_VDEC_RUN;
-}
-
-static void reset(struct vdec_s *vdec)
-{
-
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
-
- atomic_set(&dec->vf_pre_count, 0);
- atomic_set(&dec->vf_get_count, 0);
- atomic_set(&dec->vf_put_count, 0);
-
- avs2_print(dec,
- PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
-
-}
-
-static irqreturn_t avs2_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- return vavs2_isr(0, dec);
-}
-
-static irqreturn_t avs2_threaded_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- return vavs2_isr_thread_fn(0, dec);
-}
-
-static void avs2_dump_state(struct vdec_s *vdec)
-{
- struct AVS2Decoder_s *dec =
- (struct AVS2Decoder_s *)vdec->private;
- int i;
- avs2_print(dec, 0, "====== %s\n", __func__);
-
- avs2_print(dec, 0,
- "width/height (%d/%d), used_buf_num %d\n",
- dec->avs2_dec.img.width,
- dec->avs2_dec.img.height,
- dec->used_buf_num
- );
-
- avs2_print(dec, 0,
- "is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
- input_frame_based(vdec),
- dec->eos,
- dec->dec_result,
- decode_frame_count[dec->index],
- display_frame_count[dec->index],
- run_count[dec->index],
- not_run_ready[dec->index],
- input_empty[dec->index]
- );
-
- if (vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- avs2_print(dec, 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- avs2_print(dec, 0,
- "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
- __func__,
- kfifo_len(&dec->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&dec->display_q),
- VF_POOL_SIZE,
- dec->vf_pre_count,
- dec->vf_get_count,
- dec->vf_put_count,
- get_free_buf_count(dec),
- run_ready_min_buf_num
- );
-
- dump_pic_list(dec);
-
- for (i = 0; i < MAX_BUF_NUM; i++) {
- avs2_print(dec, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
- i,
- dec->m_mv_BUF[i].start_adr,
- dec->m_mv_BUF[i].size,
- dec->m_mv_BUF[i].used_flag);
- }
-
- avs2_print(dec, 0,
- "HEVC_DEC_STATUS_REG=0x%x\n",
- READ_VREG(HEVC_DEC_STATUS_REG));
- avs2_print(dec, 0,
- "HEVC_MPC_E=0x%x\n",
- READ_VREG(HEVC_MPC_E));
- avs2_print(dec, 0,
- "DECODE_MODE=0x%x\n",
- READ_VREG(DECODE_MODE));
- avs2_print(dec, 0,
- "NAL_SEARCH_CTL=0x%x\n",
- READ_VREG(NAL_SEARCH_CTL));
- avs2_print(dec, 0,
- "HEVC_PARSER_LCU_START=0x%x\n",
- READ_VREG(HEVC_PARSER_LCU_START));
- avs2_print(dec, 0,
- "HEVC_DECODE_SIZE=0x%x\n",
- READ_VREG(HEVC_DECODE_SIZE));
- avs2_print(dec, 0,
- "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- avs2_print(dec, 0,
- "HEVC_STREAM_START_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_START_ADDR));
- avs2_print(dec, 0,
- "HEVC_STREAM_END_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_END_ADDR));
- avs2_print(dec, 0,
- "HEVC_STREAM_LEVEL=0x%x\n",
- READ_VREG(HEVC_STREAM_LEVEL));
- avs2_print(dec, 0,
- "HEVC_STREAM_WR_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_WR_PTR));
- avs2_print(dec, 0,
- "HEVC_STREAM_RD_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_RD_PTR));
- avs2_print(dec, 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- avs2_print(dec, 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (input_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_DATA)
- ) {
- int jj;
- if (dec->chunk && dec->chunk->block &&
- dec->chunk->size > 0) {
- u8 *data = NULL;
- if (!dec->chunk->block->is_mapped)
- data = codec_mm_vmap(dec->chunk->block->start +
- dec->chunk->offset, dec->chunk->size);
- else
- data = ((u8 *)dec->chunk->block->start_virt) +
- dec->chunk->offset;
- avs2_print(dec, 0,
- "frame data size 0x%x\n",
- dec->chunk->size);
- for (jj = 0; jj < dec->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- avs2_print(dec, 0,
- "%06x:", jj);
- avs2_print_cont(dec, 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- avs2_print_cont(dec, 0,
- "\n");
- }
-
- if (!dec->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-
-}
-
-static int ammvdec_avs2_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- int ret;
- int config_val;
- int i;
- struct vframe_content_light_level_s content_light_level;
- struct vframe_master_display_colour_s vf_dp;
- /*struct BUF_s BUF[MAX_BUF_NUM];*/
- struct AVS2Decoder_s *dec = NULL;
-
- pr_info("%s\n", __func__);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
- pr_info("%s, chip id %d is not support avs2\n",
- __func__, get_cpu_major_id());
- return -1;
- }
- if (pdata == NULL) {
- pr_info("\nammvdec_avs2 memory resource undefined.\n");
- return -EFAULT;
- }
- /*dec = (struct AVS2Decoder_s *)devm_kzalloc(&pdev->dev,
- sizeof(struct AVS2Decoder_s), GFP_KERNEL);*/
- memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
- dec = vmalloc(sizeof(struct AVS2Decoder_s));
- memset(dec, 0, sizeof(struct AVS2Decoder_s));
- if (dec == NULL) {
- pr_info("\nammvdec_avs2 device data allocation failed\n");
- return -ENOMEM;
- }
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < AVS2_MAX_BUFFER_NUM; i++) {
- dec->avs2_dec.frm_pool[i].y_canvas_index = -1;
- dec->avs2_dec.frm_pool[i].uv_canvas_index = -1;
- }
- }
- pdata->private = dec;
- pdata->dec_status = vavs2_dec_status;
-#ifdef I_ONLY_SUPPORT
- pdata->set_trickmode = vavs2_set_trickmode;
-#endif
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = avs2_irq_cb;
- pdata->threaded_irq_handler = avs2_threaded_irq_cb;
- pdata->dump_state = avs2_dump_state;
-
- /*
- * memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- * memset(dec, 0, sizeof(struct AVS2Decoder_s));
- * memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
- */
-
- dec->index = pdev->id;
- dec->m_ins_flag = 1;
-
- if (is_rdma_enable()) {
- dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE , &dec->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- dec->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- dec->rdma_adr[i * 4 + 1] = i;
- dec->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- dec->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- dec->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
-
- snprintf(dec->vdec_name, sizeof(dec->vdec_name),
- "avs2-%d", dec->index);
- snprintf(dec->pts_name, sizeof(dec->pts_name),
- "%s-timestamp", dec->vdec_name);
- snprintf(dec->new_q_name, sizeof(dec->new_q_name),
- "%s-newframe_q", dec->vdec_name);
- snprintf(dec->disp_q_name, sizeof(dec->disp_q_name),
- "%s-dispframe_q", dec->vdec_name);
-
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- dec->frameinfo_enable = 1;
- } else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vavs2_vf_provider, dec);
-
- dec->provider_name = pdata->vf_provider_name;
- platform_set_drvdata(pdev, pdata);
-
- dec->platform_dev = pdev;
- dec->video_signal_type = 0;
- dec->video_ori_signal_type = 0;
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX)
- dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
-#if 1
- if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
- pdata->config_len) {
- /*use ptr config for doubel_write_mode, etc*/
- avs2_print(dec, 0, "pdata->config=%s\n", pdata->config);
- if (get_config_int(pdata->config, "avs2_double_write_mode",
- &config_val) == 0)
- dec->double_write_mode = config_val;
- else
- dec->double_write_mode = double_write_mode;
-
- if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
- &config_val) == 0)
- dec->dynamic_buf_margin = config_val;
- else
- dec->dynamic_buf_margin = 0;
-
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- dec->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- dec->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config, "HDRStaticInfo",
- &vf_dp.present_flag) == 0
- && vf_dp.present_flag == 1) {
- get_config_int(pdata->config, "mG.x",
- &vf_dp.primaries[0][0]);
- get_config_int(pdata->config, "mG.y",
- &vf_dp.primaries[0][1]);
- get_config_int(pdata->config, "mB.x",
- &vf_dp.primaries[1][0]);
- get_config_int(pdata->config, "mB.y",
- &vf_dp.primaries[1][1]);
- get_config_int(pdata->config, "mR.x",
- &vf_dp.primaries[2][0]);
- get_config_int(pdata->config, "mR.y",
- &vf_dp.primaries[2][1]);
- get_config_int(pdata->config, "mW.x",
- &vf_dp.white_point[0]);
- get_config_int(pdata->config, "mW.y",
- &vf_dp.white_point[1]);
- get_config_int(pdata->config, "mMaxDL",
- &vf_dp.luminance[0]);
- get_config_int(pdata->config, "mMinDL",
- &vf_dp.luminance[1]);
- vf_dp.content_light_level.present_flag = 1;
- get_config_int(pdata->config, "mMaxCLL",
- &content_light_level.max_content);
- get_config_int(pdata->config, "mMaxFALL",
- &content_light_level.max_pic_average);
- vf_dp.content_light_level = content_light_level;
- dec->video_signal_type = (1 << 29)
- | (5 << 26) /* unspecified */
- | (0 << 25) /* limit */
- | (1 << 24) /* color available */
- | (9 << 16) /* 2020 */
- | (16 << 8) /* 2084 */
- | (9 << 0); /* 2020 */
- }
- dec->vf_dp = vf_dp;
- } else
-#endif
- {
- /*dec->vavs2_amstream_dec_info.width = 0;
- dec->vavs2_amstream_dec_info.height = 0;
- dec->vavs2_amstream_dec_info.rate = 30;*/
- dec->double_write_mode = double_write_mode;
- dec->dynamic_buf_margin = dynamic_buf_num_margin;
- }
- video_signal_type = dec->video_signal_type;
-
-#if 0
- dec->buf_start = pdata->mem_start;
- dec->buf_size = pdata->mem_end - pdata->mem_start + 1;
-#else
- if (amvdec_avs2_mmu_init(dec) < 0) {
- pr_err("avs2 alloc bmmu box failed!!\n");
- /* devm_kfree(&pdev->dev, (void *)dec); */
- vfree((void *)dec);
- return -1;
- }
- dec->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE;
- ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
- dec->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
- &dec->cma_alloc_addr);
- if (ret < 0) {
- uninit_mmu_buffers(dec);
- /* devm_kfree(&pdev->dev, (void *)dec); */
- vfree((void *)dec);
- return ret;
- }
- dec->buf_start = dec->cma_alloc_addr;
- dec->buf_size = work_buf_size;
-#endif
- dec->init_flag = 0;
- dec->first_sc_checked = 0;
- dec->fatal_error = 0;
- dec->show_frame_num = 0;
-
- if (debug) {
- pr_info("===AVS2 decoder mem resource 0x%lx size 0x%x\n",
- dec->buf_start,
- dec->buf_size);
- }
-
- if (pdata->sys_info) {
- dec->vavs2_amstream_dec_info = *pdata->sys_info;
- dec->frame_width = dec->vavs2_amstream_dec_info.width;
- dec->frame_height = dec->vavs2_amstream_dec_info.height;
- } else {
- dec->vavs2_amstream_dec_info.width = 0;
- dec->vavs2_amstream_dec_info.height = 0;
- dec->vavs2_amstream_dec_info.rate = 30;
- }
-
- dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
- dec->endian = HEVC_CONFIG_BIG_ENDIAN;
- if (endian)
- dec->endian = endian;
-
- dec->cma_dev = pdata->cma_dev;
- if (vavs2_init(pdata) < 0) {
- pr_info("\namvdec_avs2 init failed.\n");
- avs2_local_uninit(dec);
- uninit_mmu_buffers(dec);
- /* devm_kfree(&pdev->dev, (void *)dec); */
- vfree((void *)dec);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- vdec_set_prepare_level(pdata, start_decode_buf_level);
- hevc_source_changed(VFORMAT_AVS2,
- 4096, 2048, 60);
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_HEVC);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
-
- return 0;
-}
-
-static int ammvdec_avs2_remove(struct platform_device *pdev)
-{
- struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct avs2_decoder *avs2_dec = &dec->avs2_dec;
- struct avs2_frame_s *pic;
- int i;
-
- if (debug)
- pr_info("amvdec_avs2_remove\n");
-
- vmavs2_stop(dec);
-
- if (pdata->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
- else
- vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC);
-
- vdec_set_status(hw_to_vdec(dec), VDEC_STATUS_DISCONNECTED);
- if (pdata->parallel_dec == 1) {
- for (i = 0; i < AVS2_MAX_BUFFER_NUM; i++) {
- pdata->free_canvas_ex(dec->avs2_dec.frm_pool[i].y_canvas_index, pdata->id);
- pdata->free_canvas_ex(dec->avs2_dec.frm_pool[i].uv_canvas_index, pdata->id);
- }
- }
-
- for (i = 0; i < dec->used_buf_num; i++) {
- if (i == (dec->used_buf_num - 1))
- pic = avs2_dec->m_bg;
- else
- pic = avs2_dec->fref[i];
- release_cuva_data(pic);
- }
-
-
-#ifdef DEBUG_PTS
- pr_info("pts missed %ld, pts hit %ld, duration %d\n",
- dec->pts_missed, dec->pts_hit, dec->frame_dur);
-#endif
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
- /* devm_kfree(&pdev->dev, (void *)dec); */
- vfree((void *)dec);
- return 0;
-}
-
-static struct platform_driver ammvdec_avs2_driver = {
- .probe = ammvdec_avs2_probe,
- .remove = ammvdec_avs2_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = MULTI_DRIVER_NAME,
- }
-};
-#endif
-static struct mconfig avs2_configs[] = {
- MC_PU32("bit_depth_luma", &bit_depth_luma),
- MC_PU32("bit_depth_chroma", &bit_depth_chroma),
- MC_PU32("frame_width", &frame_width),
- MC_PU32("frame_height", &frame_height),
- MC_PU32("debug", &debug),
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("pop_shorts", &pop_shorts),
- MC_PU32("dbg_cmd", &dbg_cmd),
- MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
- MC_PU32("endian", &endian),
- MC_PU32("step", &step),
- MC_PU32("udebug_flag", &udebug_flag),
- MC_PU32("decode_pic_begin", &decode_pic_begin),
- MC_PU32("slice_parse_begin", &slice_parse_begin),
- MC_PU32("i_only_flag", &i_only_flag),
- MC_PU32("error_handle_policy", &error_handle_policy),
- MC_PU32("buf_alloc_width", &buf_alloc_width),
- MC_PU32("buf_alloc_height", &buf_alloc_height),
- MC_PU32("buf_alloc_depth", &buf_alloc_depth),
- MC_PU32("buf_alloc_size", &buf_alloc_size),
- MC_PU32("buffer_mode", &buffer_mode),
- MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
- MC_PU32("max_buf_num", &max_buf_num),
- MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
- MC_PU32("mem_map_mode", &mem_map_mode),
- MC_PU32("double_write_mode", &double_write_mode),
- MC_PU32("enable_mem_saving", &enable_mem_saving),
- MC_PU32("force_w_h", &force_w_h),
- MC_PU32("force_fps", &force_fps),
- MC_PU32("max_decoding_time", &max_decoding_time),
- MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped),
- MC_PU32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
-};
-static struct mconfig_node avs2_node;
-
-static int __init amvdec_avs2_driver_init_module(void)
-{
-
-#ifdef AVS2_10B_MMU
-
- struct BuffInfo_s *p_buf_info;
-
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvavs2_workbuff_spec[2];
- else
- p_buf_info = &amvavs2_workbuff_spec[1];
- } else
- p_buf_info = &amvavs2_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- p_buf_info = &amvavs2_workbuff_spec[5];
- } else
- p_buf_info = &amvavs2_workbuff_spec[3];
- }
-
- init_buff_spec(NULL, p_buf_info);
- work_buf_size =
- (p_buf_info->end_adr - p_buf_info->start_adr
- + 0xffff) & (~0xffff);
-
-#endif
- pr_debug("amvdec_avs2 module init\n");
-
-#ifdef ERROR_HANDLE_DEBUG
- dbg_nal_skip_flag = 0;
- dbg_nal_skip_count = 0;
-#endif
- udebug_flag = 0;
- decode_pic_begin = 0;
- slice_parse_begin = 0;
- step = 0;
- buf_alloc_size = 0;
-
- if (platform_driver_register(&ammvdec_avs2_driver)) {
- pr_err("failed to register ammvdec_avs2 driver\n");
- return -ENODEV;
- }
-
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
- amvdec_avs2_profile.name = "avs2_unsupport";
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
- if (vdec_is_support_4k())
- amvdec_avs2_profile.profile =
- "4k, 10bit, dwrite, compressed";
- else
- amvdec_avs2_profile.profile =
- "10bit, dwrite, compressed";
- } else {
- /* cpu id larger than sm1 support 8k */
- amvdec_avs2_profile.profile =
- "8k, 10bit, dwrite, compressed";
- }
-
- vcodec_profile_register(&amvdec_avs2_profile);
-
- INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node,
- "avs2-v4l", avs2_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_AVS2, 1);
-
- return 0;
-}
-
-static void __exit amvdec_avs2_driver_remove_module(void)
-{
- pr_debug("amvdec_avs2 module remove.\n");
- platform_driver_unregister(&ammvdec_avs2_driver);
-}
-
-/****************************************/
-
-module_param(bit_depth_luma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\n");
-
-module_param(bit_depth_chroma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_avs2 bit_depth_chroma\n");
-
-module_param(frame_width, uint, 0664);
-MODULE_PARM_DESC(frame_width, "\n amvdec_avs2 frame_width\n");
-
-module_param(frame_height, uint, 0664);
-MODULE_PARM_DESC(frame_height, "\n amvdec_avs2 frame_height\n");
-
-module_param(debug, uint, 0664);
-MODULE_PARM_DESC(debug, "\n amvdec_avs2 debug\n");
-
-module_param(debug_again, uint, 0664);
-MODULE_PARM_DESC(debug_again, "\n amvdec_avs2 debug_again\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(pop_shorts, uint, 0664);
-MODULE_PARM_DESC(pop_shorts, "\nrval\n");
-
-module_param(dbg_cmd, uint, 0664);
-MODULE_PARM_DESC(dbg_cmd, "\ndbg_cmd\n");
-
-module_param(dbg_skip_decode_index, uint, 0664);
-MODULE_PARM_DESC(dbg_skip_decode_index, "\ndbg_skip_decode_index\n");
-
-module_param(endian, uint, 0664);
-MODULE_PARM_DESC(endian, "\nrval\n");
-
-module_param(step, uint, 0664);
-MODULE_PARM_DESC(step, "\n amvdec_avs2 step\n");
-
-module_param(decode_pic_begin, uint, 0664);
-MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_avs2 decode_pic_begin\n");
-
-module_param(slice_parse_begin, uint, 0664);
-MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_avs2 slice_parse_begin\n");
-
-module_param(i_only_flag, uint, 0664);
-MODULE_PARM_DESC(i_only_flag, "\n amvdec_avs2 i_only_flag\n");
-
-module_param(error_handle_policy, uint, 0664);
-MODULE_PARM_DESC(error_handle_policy, "\n amvdec_avs2 error_handle_policy\n");
-
-module_param(re_search_seq_threshold, uint, 0664);
-MODULE_PARM_DESC(re_search_seq_threshold, "\n amvdec_avs2 re_search_seq_threshold\n");
-
-module_param(buf_alloc_width, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
-
-module_param(buf_alloc_height, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
-
-module_param(buf_alloc_depth, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
-
-module_param(buf_alloc_size, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
-
-module_param(buffer_mode, uint, 0664);
-MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
-
-module_param(buffer_mode_dbg, uint, 0664);
-MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
-/*USE_BUF_BLOCK*/
-module_param(max_buf_num, uint, 0664);
-MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-module_param(run_ready_max_vf_only_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_vf_only_num, "\n run_ready_max_vf_only_num\n");
-
-module_param(run_ready_display_q_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_display_q_num, "\n run_ready_display_q_num\n");
-
-module_param(run_ready_max_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_buf_num, "\n run_ready_max_buf_num\n");
-#endif
-
-module_param(mv_buf_margin, uint, 0664);
-MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n");
-
-module_param(run_ready_min_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
-
-/**/
-
-module_param(mem_map_mode, uint, 0664);
-MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
-
-module_param(double_write_mode, uint, 0664);
-MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
-
-module_param(enable_mem_saving, uint, 0664);
-MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
-
-module_param(force_w_h, uint, 0664);
-MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
-
-module_param(force_fps, uint, 0664);
-MODULE_PARM_DESC(force_fps, "\n force_fps\n");
-
-module_param(max_decoding_time, uint, 0664);
-MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
-
-module_param(on_no_keyframe_skiped, uint, 0664);
-MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
-
-
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n avs2 start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val,
- "\n avs2 decode_timeout_val\n");
-
-module_param_array(decode_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(display_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(input_empty, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(not_run_ready, uint,
- &max_decode_instance_num, 0664);
-
-module_param(video_signal_type, uint, 0664);
-MODULE_PARM_DESC(video_signal_type, "\n amvdec_avs2 video_signal_type\n");
-
-module_param(force_video_signal_type, uint, 0664);
-MODULE_PARM_DESC(force_video_signal_type, "\n amvdec_avs2 force_video_signal_type\n");
-
-module_param(enable_force_video_signal_type, uint, 0664);
-MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs2 enable_force_video_signal_type\n");
-
-module_param(force_bufspec, uint, 0664);
-MODULE_PARM_DESC(force_bufspec, "\n amvdec_h265 force_bufspec\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level,
- "\n amvdec_avs2 pre_decode_buf_level\n");
-
-module_param(again_threshold, uint, 0664);
-MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-
-
-module_param(force_disp_pic_index, int, 0664);
-MODULE_PARM_DESC(force_disp_pic_index,
- "\n amvdec_h265 force_disp_pic_index\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-
-module_param(mv_buf_dynamic_alloc, uint, 0664);
-MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
-
-module_init(amvdec_avs2_driver_init_module);
-module_exit(amvdec_avs2_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC avs2 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder_v4l/avs2/vavs2.h b/drivers/frame_provider/decoder_v4l/avs2/vavs2.h
deleted file mode 100644
index 6b51f61..0000000
--- a/drivers/frame_provider/decoder_v4l/avs2/vavs2.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * drivers/amlogic/amports/vavs2.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
-*/
-
-#ifndef VAVS2_H
-#define VAVS2_H
-
-#define AVS2_10B_MMU
-#define MV_USE_FIXED_BUF
-
-void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
-unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
-#endif
diff --git a/drivers/frame_provider/decoder_v4l/avs_multi/Makefile b/drivers/frame_provider/decoder_v4l/avs_multi/Makefile
deleted file mode 100644
index 10da3ab..0000000
--- a/drivers/frame_provider/decoder_v4l/avs_multi/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs_v4l.o
-amvdec_mavs_v4l-objs += avs_multi.o
diff --git a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c b/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c
deleted file mode 100644
index 3ad9385..0000000
--- a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.c
+++ /dev/null
@@ -1,5016 +0,0 @@
-/*
- * drivers/amlogic/amports/vavs.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../stream_input/amports/streambuf_reg.h"
-#include "../../decoder/utils/amvdec.h"
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/dma-mapping.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/slab.h>
-#include "avs_multi.h"
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include <linux/amlogic/tee.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define DEBUG_MULTI_FLAG 0
-/*
-#define DEBUG_WITH_SINGLE_MODE
-#define DEBUG_MULTI_WITH_AUTOMODE
-#define DEBUG_MULTI_FRAME_INS
-*/
-
-
-#define USE_DYNAMIC_BUF_NUM
-
-#define DRIVER_NAME "ammvdec_avs_v4l"
-
-
-#define MULTI_DRIVER_NAME "ammvdec_avs_v4l"
-
-#define ENABLE_USER_DATA
-
-#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
-#define NV21
-#endif
-
-#define USE_AVS_SEQ_INFO
-#define HANDLE_AVS_IRQ
-#define DEBUG_PTS
-
-#define CHECK_INTERVAL (HZ/100)
-
-#define I_PICTURE 0
-#define P_PICTURE 1
-#define B_PICTURE 2
-
-#define LMEM_BUF_SIZE (0x500 * 2)
-
-/* #define ORI_BUFFER_START_ADDR 0x81000000 */
-#define ORI_BUFFER_START_ADDR 0x80000000
-
-#define INTERLACE_FLAG 0x80
-#define TOP_FIELD_FIRST_FLAG 0x40
-
-/* protocol registers */
-#define AVS_PIC_RATIO AV_SCRATCH_0
-#define AVS_PIC_WIDTH AV_SCRATCH_1
-#define AVS_PIC_HEIGHT AV_SCRATCH_2
-#define AVS_FRAME_RATE AV_SCRATCH_3
-
-/*#define AVS_ERROR_COUNT AV_SCRATCH_6*/
-#define AVS_SOS_COUNT AV_SCRATCH_7
-#define AVS_BUFFERIN AV_SCRATCH_8
-#define AVS_BUFFEROUT AV_SCRATCH_9
-#define AVS_REPEAT_COUNT AV_SCRATCH_A
-#define AVS_TIME_STAMP AV_SCRATCH_B
-#define AVS_OFFSET_REG AV_SCRATCH_C
-#define MEM_OFFSET_REG AV_SCRATCH_F
-#define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G
-#define DECODE_PIC_COUNT AV_SCRATCH_G
-
-#define DECODE_MODE AV_SCRATCH_6
-#define DECODE_MODE_SINGLE 0x0
-#define DECODE_MODE_MULTI_FRAMEBASE 0x1
-#define DECODE_MODE_MULTI_STREAMBASE 0x2
-#define DECODE_MODE_MULTI_STREAMBASE_CONT 0x3
-
-#define DECODE_STATUS AV_SCRATCH_H
-#define DECODE_STATUS_PIC_DONE 0x1
-#define DECODE_STATUS_DECODE_BUF_EMPTY 0x2
-#define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3
-#define DECODE_STATUS_SKIP_PIC_DONE 0x4
-#define DECODE_SEARCH_HEAD 0xff
-
-#define DECODE_STOP_POS AV_SCRATCH_J
-
-#define DECODE_LMEM_BUF_ADR AV_SCRATCH_I
-
-#define DECODE_CFG AV_SCRATCH_K
-
-#define VF_POOL_SIZE 64
-#define PUT_INTERVAL (HZ/100)
-
-#if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
-#define INT_AMVENCODER INT_DOS_MAILBOX_1
-#else
-/* #define AMVENC_DEV_VERSION "AML-MT" */
-#define INT_AMVENCODER INT_MAILBOX_1A
-#endif
-
-#ifdef USE_DYNAMIC_BUF_NUM
-static unsigned int buf_spec_reg[] = {
- AV_SCRATCH_0,
- AV_SCRATCH_1,
- AV_SCRATCH_2,
- AV_SCRATCH_3,
- AV_SCRATCH_7, /*AVS_SOS_COUNT*/
- AV_SCRATCH_D, /*DEBUG_REG2*/
- AV_SCRATCH_E, /*DEBUG_REG1*/
- AV_SCRATCH_M /*user_data_poc_number*/
-};
-#endif
-
-#define DEBUG_REG1 AV_SCRATCH_E
-#define DEBUG_REG2 AV_SCRATCH_D
-
-
-static void check_timer_func(struct timer_list *timer);
-static void vavs_work(struct work_struct *work);
-
-#define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001
-static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE;
-
-
-#define VPP_VD1_POSTBLEND (1 << 10)
-
-static int debug;
-static unsigned int debug_mask = 0xff;
-
-/*for debug*/
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode more print
- bit 3, enable ucdode detail print
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-
- avs only:
- bit [8], disable empty muitl-instance handling
- bit [9], enable writting of VC1_CONTROL_REG in ucode
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-static u32 udebug_pause_ins_id;
-
-static u32 force_fps;
-
-#ifdef DEBUG_MULTI_FRAME_INS
-static u32 delay;
-#endif
-
-static u32 step;
-
-static u32 start_decoding_delay;
-
-#define AVS_DEV_NUM 9
-static unsigned int max_decode_instance_num = AVS_DEV_NUM;
-static unsigned int max_process_time[AVS_DEV_NUM];
-static unsigned int max_get_frame_interval[AVS_DEV_NUM];
-static unsigned int run_count[AVS_DEV_NUM];
-static unsigned int ins_udebug_flag[AVS_DEV_NUM];
-#ifdef DEBUG_MULTI_FRAME_INS
-static unsigned int max_run_count[AVS_DEV_NUM];
-#endif
-/*
-error_handle_policy:
-*/
-static unsigned int error_handle_policy = 3;
-
-static u32 again_threshold = 0; /*0x40;*/
-
-static unsigned int decode_timeout_val = 200;
-static unsigned int start_decode_buf_level = 0x8000;
-
-/********************************
-firmware_sel
- 0: use avsp_trans long cabac ucode;
- 1: not use avsp_trans long cabac ucode
- in ucode:
- #define USE_EXT_BUFFER_ASSIGNMENT
- #undef USE_DYNAMIC_BUF_NUM
-********************************/
-static int firmware_sel;
-static int disable_longcabac_trans = 1;
-static int pre_decode_buf_level = 0x800;
-
-
-static struct vframe_s *vavs_vf_peek(void *);
-static struct vframe_s *vavs_vf_get(void *);
-static void vavs_vf_put(struct vframe_s *, void *);
-static int vavs_vf_states(struct vframe_states *states, void *);
-static int vavs_event_cb(int type, void *data, void *private_data);
-
-static const char vavs_dec_id[] = "vavs-dev";
-
-#define PROVIDER_NAME "decoder.avs"
-static DEFINE_SPINLOCK(lock);
-static DEFINE_MUTEX(vavs_mutex);
-
-static const struct vframe_operations_s vavs_vf_provider = {
- .peek = vavs_vf_peek,
- .get = vavs_vf_get,
- .put = vavs_vf_put,
- .event_cb = vavs_event_cb,
- .vf_states = vavs_vf_states,
-};
-/*
-static void *mm_blk_handle;
-*/
-static struct vframe_provider_s vavs_vf_prov;
-
-#define VF_BUF_NUM_MAX 16
-#ifdef DEBUG_MULTI_FRAME_INS
-#define WORKSPACE_SIZE (16 * SZ_1M)
-#else
-#define WORKSPACE_SIZE (4 * SZ_1M)
-#endif
-#ifdef AVSP_LONG_CABAC
-#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2)
-#define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE)
-#else
-#define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 1)
-#endif
-
-#define RV_AI_BUFF_START_ADDR 0x01a00000
-#define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000
-
-/* 4 buffers not enough for multi inc*/
-static u32 vf_buf_num = 8;
-/*static u32 vf_buf_num_used;*/
-static u32 canvas_base = 128;
-#ifdef NV21
-static int canvas_num = 2; /*NV21*/
-#else
-static int canvas_num = 3;
-#endif
-
-#if 0
-static struct vframe_s vfpool[VF_POOL_SIZE];
-/*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
-static struct vframe_s *cur_vfpool;
-static unsigned char recover_flag;
-static s32 vfbuf_use[VF_BUF_NUM_MAX];
-static u32 saved_resolution;
-static u32 frame_width, frame_height, frame_dur, frame_prog;
-static struct timer_list recycle_timer;
-static u32 stat;
-#endif
-static u32 buf_size = 32 * 1024 * 1024;
-#if 0
-static u32 buf_offset;
-static u32 avi_flag;
-static u32 vavs_ratio;
-static u32 pic_type;
-#endif
-static u32 pts_by_offset = 1;
-#if 0
-static u32 total_frame;
-static u32 next_pts;
-static unsigned char throw_pb_flag;
-#ifdef DEBUG_PTS
-static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed;
-#endif
-#endif
-static u32 radr, rval;
-static u32 dbg_cmd;
-#if 0
-static struct dec_sysinfo vavs_amstream_dec_info;
-static struct vdec_info *gvs;
-static u32 fr_hint_status;
-static struct work_struct notify_work;
-static struct work_struct set_clk_work;
-static bool is_reset;
-#endif
-/*static struct vdec_s *vdec;*/
-
-#ifdef AVSP_LONG_CABAC
-static struct work_struct long_cabac_wd_work;
-void *es_write_addr_virt;
-dma_addr_t es_write_addr_phy;
-
-void *bitstream_read_tmp;
-dma_addr_t bitstream_read_tmp_phy;
-void *avsp_heap_adr;
-static uint long_cabac_busy;
-#endif
-
-#if 0
-#ifdef ENABLE_USER_DATA
-static void *user_data_buffer;
-static dma_addr_t user_data_buffer_phys;
-#endif
-static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
-#endif
-static inline u32 index2canvas(u32 index)
-{
- const u32 canvas_tab[VF_BUF_NUM_MAX] = {
- 0x010100, 0x030302, 0x050504, 0x070706,
- 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e,
- 0x111110, 0x131312, 0x151514, 0x171716,
- 0x191918, 0x1b1b1a, 0x1d1d1c, 0x1f1f1e,
- };
- const u32 canvas_tab_3[4] = {
- 0x010100, 0x040403, 0x070706, 0x0a0a09
- };
-
- if (canvas_num == 2)
- return canvas_tab[index] + (canvas_base << 16)
- + (canvas_base << 8) + canvas_base;
-
- return canvas_tab_3[index] + (canvas_base << 16)
- + (canvas_base << 8) + canvas_base;
-}
-
-static const u32 frame_rate_tab[16] = {
- 96000 / 30, /* forbidden */
- 96000000 / 23976, /* 24000/1001 (23.967) */
- 96000 / 24,
- 96000 / 25,
- 9600000 / 2997, /* 30000/1001 (29.97) */
- 96000 / 30,
- 96000 / 50,
- 9600000 / 5994, /* 60000/1001 (59.94) */
- 96000 / 60,
- /* > 8 reserved, use 24 */
- 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24,
- 96000 / 24, 96000 / 24, 96000 / 24
-};
-
-#define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX
-#define PIC_PTS_NUM 64
-struct buf_pool_s {
- unsigned detached;
- struct vframe_s vf;
-};
-
-#define buf_of_vf(vf) container_of(vf, struct buf_pool_s, vf)
-
-struct pic_pts_s {
- u32 pts;
- u64 pts64;
- u64 timestamp;
- unsigned short decode_pic_count;
-};
-
-struct vdec_avs_hw_s {
- spinlock_t lock;
- unsigned char m_ins_flag;
- struct platform_device *platform_dev;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE);
- struct buf_pool_s vfpool[VF_POOL_SIZE];
- s32 vfbuf_use[VF_BUF_NUM_MAX];
- unsigned char again_flag;
- unsigned char recover_flag;
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 frame_prog;
- u32 saved_resolution;
- u32 avi_flag;
- u32 vavs_ratio;
- u32 pic_type;
-
- u32 vf_buf_num_used;
- u32 total_frame;
- u32 next_pts;
- unsigned char throw_pb_flag;
- struct pic_pts_s pic_pts[PIC_PTS_NUM];
- int pic_pts_wr_pos;
-
-#ifdef DEBUG_PTS
- u32 pts_hit;
- u32 pts_missed;
- u32 pts_i_hit;
- u32 pts_i_missed;
-#endif
-#ifdef ENABLE_USER_DATA
- struct work_struct userdata_push_work;
- void *user_data_buffer;
- dma_addr_t user_data_buffer_phys;
-#endif
- dma_addr_t lmem_addr;
- ulong lmem_phy_addr;
-
- u32 buf_offset;
-
- struct dec_sysinfo vavs_amstream_dec_info;
- struct vdec_info *gvs;
- u32 fr_hint_status;
- struct work_struct set_clk_work;
- bool is_reset;
-
- /*debug*/
- u32 ucode_pause_pos;
- /**/
- u32 decode_pic_count;
- u8 reset_decode_flag;
- u32 display_frame_count;
- u32 buf_status;
- u32 pre_parser_wr_ptr;
- /*
- buffer_status &= ~buf_recycle_status
- */
- u32 buf_recycle_status;
- u32 seqinfo;
- u32 ctx_valid;
- u32 dec_control;
- void *mm_blk_handle;
- struct vframe_chunk_s *chunk;
- u32 stat;
- u8 init_flag;
- unsigned long buf_start;
- u32 buf_size;
-
- u32 reg_scratch_0;
- u32 reg_scratch_1;
- u32 reg_scratch_2;
- u32 reg_scratch_3;
- u32 reg_scratch_4;
- u32 reg_scratch_5;
- u32 reg_scratch_6;
- u32 reg_scratch_7;
- u32 reg_scratch_8;
- u32 reg_scratch_9;
- u32 reg_scratch_A;
- u32 reg_scratch_B;
- u32 reg_scratch_C;
- u32 reg_scratch_D;
- u32 reg_scratch_E;
- u32 reg_scratch_F;
- u32 reg_scratch_G;
- u32 reg_scratch_H;
- u32 reg_scratch_I;
- u32 reg_mb_width;
- u32 reg_viff_bit_cnt;
- u32 reg_canvas_addr;
- u32 reg_dbkr_canvas_addr;
- u32 reg_dbkw_canvas_addr;
- u32 reg_anc2_canvas_addr;
- u32 reg_anc0_canvas_addr;
- u32 reg_anc1_canvas_addr;
- u32 reg_anc3_canvas_addr;
- u32 reg_anc4_canvas_addr;
- u32 reg_anc5_canvas_addr;
- u32 slice_ver_pos_pic_type;
- u32 vc1_control_reg;
- u32 avs_co_mb_wr_addr;
- u32 slice_start_byte_01;
- u32 slice_start_byte_23;
- u32 vcop_ctrl_reg;
- u32 iqidct_control;
- u32 rv_ai_mb_count;
- u32 slice_qp;
- u32 dc_scaler;
- u32 avsp_iq_wq_param_01;
- u32 avsp_iq_wq_param_23;
- u32 avsp_iq_wq_param_45;
- u32 avs_co_mb_rd_addr;
- u32 dblk_mb_wid_height;
- u32 mc_pic_w_h;
- u32 avs_co_mb_rw_ctl;
- u32 vld_decode_control;
-
- struct timer_list check_timer;
- u32 decode_timeout_count;
- unsigned long int start_process_time;
- u32 last_vld_level;
- u32 eos;
- u32 canvas_spec[DECODE_BUFFER_NUM_MAX];
- struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2];
-
- s32 refs[2];
- int dec_result;
- struct timer_list recycle_timer;
- struct work_struct work;
- struct work_struct notify_work;
- atomic_t error_handler_run;
- struct work_struct fatal_error_wd_work;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
-/* for error handling */
- u32 run_count;
- u32 not_run_ready;
- u32 input_empty;
- atomic_t prepare_num;
- atomic_t put_num;
- atomic_t peek_num;
- atomic_t get_num;
- u32 drop_frame_count;
- u32 buffer_not_ready;
- int frameinfo_enable;
- struct firmware_s *fw;
- u32 old_udebug_flag;
- u32 decode_status_skip_pic_done_flag;
- u32 decode_decode_cont_start_code;
- int vdec_pg_enable_flag;
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
-};
-
-static void reset_process_time(struct vdec_avs_hw_s *hw);
-static void start_process_time(struct vdec_avs_hw_s *hw);
-static void vavs_save_regs(struct vdec_avs_hw_s *hw);
-
-struct vdec_avs_hw_s *ghw;
-
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs"
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_ERROR 3
-#define DEC_RESULT_FORCE_EXIT 4
-#define DEC_RESULT_EOS 5
-#define DEC_RESULT_GET_DATA 6
-#define DEC_RESULT_GET_DATA_RETRY 7
-#define DEC_RESULT_USERDATA 8
-
-#define DECODE_ID(hw) (hw->m_ins_flag? hw_to_vdec(hw)->id : 0)
-
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_RUN_FLOW 0X0001
-#define PRINT_FLAG_DECODING 0x0002
-#define PRINT_FLAG_PTS 0x0004
-#define PRINT_FLAG_VFRAME_DETAIL 0x0010
-#define PRINT_FLAG_VLD_DETAIL 0x0020
-#define PRINT_FLAG_DEC_DETAIL 0x0040
-#define PRINT_FLAG_BUFFER_DETAIL 0x0080
-#define PRINT_FLAG_FORCE_DONE 0x0100
-#define PRINT_FLAG_COUNTER 0X0200
-#define PRINT_FRAMEBASE_DATA 0x0400
-#define PRINT_FLAG_PARA_DATA 0x1000
-#define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000
-#define DEBUG_FLAG_PRINT_REG 0x4000
-#define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000
-#define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000
-#define DEBUG_PIC_DONE_WHEN_UCODE_PAUSE 0x40000
-
-
-#undef DEBUG_REG
-#ifdef DEBUG_REG
-static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
-{
- if (debug & DEBUG_FLAG_PRINT_REG)
- pr_info("%s(%x, %x)\n", __func__, adr, val);
- if (adr != 0)
- WRITE_VREG(adr, val);
-}
-
-#undef WRITE_VREG
-#define WRITE_VREG WRITE_VREG_DBG2
-#endif
-
-#undef pr_info
-#define pr_info printk
-static int debug_print(struct vdec_avs_hw_s *hw,
- int flag, const char *fmt, ...)
-{
-#define AVS_PRINT_BUF 256
- unsigned char buf[AVS_PRINT_BUF];
- int len = 0;
- int index = 0;
- if (hw)
- index = hw->m_ins_flag ? DECODE_ID(hw) : 0;
- if (hw == NULL ||
- (flag == 0) ||
- ((debug_mask &
- (1 << index))
- && (debug & flag))) {
- va_list args;
-
- va_start(args, fmt);
- if (hw)
- len = sprintf(buf, "[%d]", index);
- vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static int debug_print_cont(struct vdec_avs_hw_s *hw,
- int flag, const char *fmt, ...)
-{
- unsigned char buf[AVS_PRINT_BUF];
- int len = 0;
- int index = 0;
- if (hw)
- index = hw->m_ins_flag ? DECODE_ID(hw) : 0;
- if (hw == NULL ||
- (flag == 0) ||
- ((debug_mask &
- (1 << index))
- && (debug & flag))) {
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static void avs_pts_check_in(struct vdec_avs_hw_s *hw,
- unsigned short decode_pic_count, struct vframe_chunk_s *chunk)
-{
- if (chunk)
- debug_print(hw, PRINT_FLAG_PTS,
- "%s %d (wr pos %d), pts %d pts64 %ld timestamp %ld\n",
- __func__, decode_pic_count, hw->pic_pts_wr_pos,
- chunk->pts, (u64)(chunk->pts64), (u64)(chunk->timestamp));
- else
- debug_print(hw, PRINT_FLAG_PTS,
- "%s %d, chunk is null\n",
- __func__, decode_pic_count);
-
- if (chunk) {
- hw->pic_pts[hw->pic_pts_wr_pos].pts = chunk->pts;
- hw->pic_pts[hw->pic_pts_wr_pos].pts64 = chunk->pts64;
- hw->pic_pts[hw->pic_pts_wr_pos].timestamp = chunk->timestamp;
- } else {
- hw->pic_pts[hw->pic_pts_wr_pos].pts = 0;
- hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0;
- hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0;
- }
- hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count
- = decode_pic_count;
- hw->pic_pts_wr_pos++;
- if (hw->pic_pts_wr_pos >= PIC_PTS_NUM)
- hw->pic_pts_wr_pos = 0;
- return;
-}
-
-static void clear_pts_buf(struct vdec_avs_hw_s *hw)
-{
- int i;
- debug_print(hw, PRINT_FLAG_PTS,
- "%s\n", __func__);
- hw->pic_pts_wr_pos = 0;
- for (i = 0; i < PIC_PTS_NUM; i++) {
- hw->pic_pts[hw->pic_pts_wr_pos].pts = 0;
- hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0;
- hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0;
- hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count = 0;
- }
-}
-
-static int set_vframe_pts(struct vdec_avs_hw_s *hw,
- unsigned short decode_pic_count, struct vframe_s *vf)
-{
- int i;
- int ret = -1;
- for (i = 0; i < PIC_PTS_NUM; i++) {
- if (hw->pic_pts[i].decode_pic_count == decode_pic_count) {
- vf->pts = hw->pic_pts[i].pts;
- vf->pts_us64 = hw->pic_pts[i].pts64;
- vf->timestamp = hw->pic_pts[i].timestamp;
- ret = 0;
- debug_print(hw, PRINT_FLAG_PTS,
- "%s %d (rd pos %d), pts %d pts64 %ld timestamp %ld\n",
- __func__, decode_pic_count, i,
- vf->pts, vf->pts_us64, vf->timestamp);
-
- break;
- }
- }
- return ret;
-}
-
-static void avs_vf_notify_receiver(struct vdec_avs_hw_s *hw,
- const char *provider_name, int event_type, void *data)
-{
- if (hw->m_ins_flag)
- vf_notify_receiver(hw_to_vdec(hw)->vf_provider_name,
- event_type, data);
- else
- vf_notify_receiver(provider_name, event_type, data);
-}
-
-static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf,
- unsigned int *duration)
-{
- int ar = 0;
-
- unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO);
- atomic_add(1, &hw->prepare_num);
-#ifndef USE_AVS_SEQ_INFO
- if (hw->vavs_amstream_dec_info.width > 0
- && hw->vavs_amstream_dec_info.height > 0) {
- vf->width = hw->vavs_amstream_dec_info.width;
- vf->height = hw->vavs_amstream_dec_info.height;
- } else
-#endif
- {
- vf->width = READ_VREG(AVS_PIC_WIDTH);
- vf->height = READ_VREG(AVS_PIC_HEIGHT);
- hw->frame_width = vf->width;
- hw->frame_height = vf->height;
- /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/
- }
-
-#ifndef USE_AVS_SEQ_INFO
- if (hw->vavs_amstream_dec_info.rate > 0)
- *duration = hw->vavs_amstream_dec_info.rate;
- else
-#endif
- {
- *duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf];
- /* pr_info("%s: duration = %d\n", __func__, *duration); */
- hw->frame_dur = *duration;
- schedule_work(&hw->notify_work);
- }
-
- if (hw->vavs_ratio == 0) {
- /* always stretch to 16:9 */
- vf->ratio_control |= (0x90 <<
- DISP_RATIO_ASPECT_RATIO_BIT);
- vf->sar_width = 1;
- vf->sar_height = 1;
- } else {
- switch (pixel_ratio) {
- case 1:
- vf->sar_width = 1;
- vf->sar_height = 1;
- ar = (vf->height * hw->vavs_ratio) / vf->width;
- break;
- case 2:
- vf->sar_width = 4;
- vf->sar_height = 3;
- ar = (vf->height * 3 * hw->vavs_ratio) / (vf->width * 4);
- break;
- case 3:
- vf->sar_width = 16;
- vf->sar_height = 9;
- ar = (vf->height * 9 * hw->vavs_ratio) / (vf->width * 16);
- break;
- case 4:
- vf->sar_width = 221;
- vf->sar_height = 100;
- ar = (vf->height * 100 * hw->vavs_ratio) / (vf->width *
- 221);
- break;
- default:
- vf->sar_width = 1;
- vf->sar_height = 1;
- ar = (vf->height * hw->vavs_ratio) / vf->width;
- break;
- }
- }
-
- ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
-
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
- /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */
-
- vf->flag = 0;
- buf_of_vf(vf)->detached = 0;
-
-}
-
-#ifdef ENABLE_USER_DATA
-
-/*static struct work_struct userdata_push_work;*/
-/*
-#define DUMP_LAST_REPORTED_USER_DATA
-*/
-static void userdata_push_process(struct vdec_avs_hw_s *hw)
-{
- unsigned int user_data_flags;
- unsigned int user_data_wp;
- unsigned int user_data_length;
- struct userdata_poc_info_t user_data_poc;
-#ifdef DUMP_LAST_REPORTED_USER_DATA
- int user_data_len;
- int wp_start;
- unsigned char *pdata;
- int nLeft;
-#endif
-
- user_data_flags = READ_VREG(AV_SCRATCH_N);
- user_data_wp = (user_data_flags >> 16) & 0xffff;
- user_data_length = user_data_flags & 0x7fff;
-
-#ifdef DUMP_LAST_REPORTED_USER_DATA
- dma_sync_single_for_cpu(amports_get_dma_device(),
- hw->user_data_buffer_phys, USER_DATA_SIZE,
- DMA_FROM_DEVICE);
-
- if (user_data_length & 0x07)
- user_data_len = (user_data_length + 8) & 0xFFFFFFF8;
- else
- user_data_len = user_data_length;
-
- if (user_data_wp >= user_data_len) {
- wp_start = user_data_wp - user_data_len;
-
- pdata = (unsigned char *)hw->user_data_buffer;
- pdata += wp_start;
- nLeft = user_data_len;
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
- } else {
- wp_start = user_data_wp +
- USER_DATA_SIZE - user_data_len;
-
- pdata = (unsigned char *)hw->user_data_buffer;
- pdata += wp_start;
- nLeft = USER_DATA_SIZE - wp_start;
-
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
-
- pdata = (unsigned char *)hw->user_data_buffer;
- nLeft = user_data_wp;
- while (nLeft >= 8) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
- }
-#endif
-
-/*
- pr_info("pocinfo 0x%x, poc %d, wp 0x%x, len %d\n",
- READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M),
- user_data_wp, user_data_length);
-*/
- user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L);
- user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M);
-
- WRITE_VREG(AV_SCRATCH_N, 0);
-/*
- wakeup_userdata_poll(user_data_poc, user_data_wp,
- (unsigned long)hw->user_data_buffer,
- USER_DATA_SIZE, user_data_length);
-*/
-}
-
-static void userdata_push_do_work(struct work_struct *work)
-{
- struct vdec_avs_hw_s *hw =
- container_of(work, struct vdec_avs_hw_s, userdata_push_work);
- userdata_push_process(hw);
-}
-
-static u8 UserDataHandler(struct vdec_avs_hw_s *hw)
-{
- unsigned int user_data_flags;
-
- user_data_flags = READ_VREG(AV_SCRATCH_N);
- if (user_data_flags & (1 << 15)) { /* data ready */
- if (hw->m_ins_flag) {
- hw->dec_result = DEC_RESULT_USERDATA;
- vdec_schedule_work(&hw->work);
- return 1;
- } else
- schedule_work(&hw->userdata_push_work);
- }
- return 0;
-}
-#endif
-
-
-static inline void avs_update_gvs(struct vdec_avs_hw_s *hw)
-{
- if (hw->gvs->frame_height != hw->frame_height) {
- hw->gvs->frame_width = hw->frame_width;
- hw->gvs->frame_height = hw->frame_height;
- }
- if (hw->gvs->frame_dur != hw->frame_dur) {
- hw->gvs->frame_dur = hw->frame_dur;
- if (hw->frame_dur != 0)
- hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- hw->gvs->frame_rate = -1;
- }
-
- hw->gvs->status = hw->stat;
- hw->gvs->error_count = READ_VREG(AV_SCRATCH_C);
- hw->gvs->drop_frame_count = hw->drop_frame_count;
-
-}
-
-#ifdef HANDLE_AVS_IRQ
-static irqreturn_t vavs_isr(int irq, void *dev_id)
-#else
-static void vavs_isr(void)
-#endif
-{
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- return IRQ_WAKE_THREAD;
-}
-/*
- *static int run_flag = 1;
- *static int step_flag;
- */
-static int error_recovery_mode; /*0: blocky 1: mosaic*/
-/*
- *static uint error_watchdog_threshold=10;
- *static uint error_watchdog_count;
- *static uint error_watchdog_buf_threshold = 0x4000000;
- */
-
-static struct vframe_s *vavs_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)op_arg;
- atomic_add(1, &hw->peek_num);
- if (step == 2)
- return NULL;
- if (hw->recover_flag)
- return NULL;
-
- if (kfifo_peek(&hw->display_q, &vf)) {
- if (vf) {
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
-
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
-
- }
- return vf;
- }
-
- return NULL;
-
-}
-
-static struct vframe_s *vavs_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)op_arg;
- unsigned long flags;
-
- if (hw->recover_flag)
- return NULL;
-
- if (step == 2)
- return NULL;
- else if (step == 1)
- step = 2;
-
- spin_lock_irqsave(&lock, flags);
- if (kfifo_get(&hw->display_q, &vf)) {
- if (vf) {
- vf->index_disp = atomic_read(&hw->get_num);
- atomic_add(1, &hw->get_num);
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
-
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "%s, index = %d, w %d h %d, type 0x%x detached %d\n",
- __func__,
- vf->index,
- vf->width,
- vf->height,
- vf->type,
- buf_of_vf(vf)->detached);
- }
- spin_unlock_irqrestore(&lock, flags);
- return vf;
- }
- spin_unlock_irqrestore(&lock, flags);
-
- return NULL;
-
-}
-
-static void vavs_vf_put(struct vframe_s *vf, void *op_arg)
-{
- int i;
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)op_arg;
-
- if (vf) {
- atomic_add(1, &hw->put_num);
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "%s, index = %d, w %d h %d, type 0x%x detached 0x%x\n",
- __func__,
- vf->index,
- vf->width,
- vf->height,
- vf->type,
- buf_of_vf(vf)->detached);
- }
- if (hw->recover_flag)
- return;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &hw->vfpool[i].vf)
- break;
- }
- if (i < VF_POOL_SIZE)
-
- kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf);
-
-}
-
-static int vavs_event_cb(int type, void *data, void *private_data)
-{
- struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)private_data;
-
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(hw_to_vdec(hw));
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- /*if (!(hw->stat & STAT_VDEC_RUN))
- return -1;*/
- if (!hw)
- return -1;
-
- vstatus->frame_width = hw->frame_width;
- vstatus->frame_height = hw->frame_height;
- if (hw->frame_dur != 0)
- vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = READ_VREG(AV_SCRATCH_C);
- vstatus->status = hw->stat;
- vstatus->bit_rate = hw->gvs->bit_rate;
- vstatus->frame_dur = hw->frame_dur;
- vstatus->frame_data = hw->gvs->frame_data;
- vstatus->total_data = hw->gvs->total_data;
- vstatus->frame_count = hw->gvs->frame_count;
- vstatus->error_frame_count = hw->gvs->error_frame_count;
- vstatus->drop_frame_count = hw->gvs->drop_frame_count;
- vstatus->i_decoded_frames = hw->gvs->i_decoded_frames;
- vstatus->i_lost_frames = hw->gvs->i_lost_frames;
- vstatus->i_concealed_frames = hw->gvs->i_concealed_frames;
- vstatus->p_decoded_frames = hw->gvs->p_decoded_frames;
- vstatus->p_lost_frames = hw->gvs->p_lost_frames;
- vstatus->p_concealed_frames = hw->gvs->p_concealed_frames;
- vstatus->b_decoded_frames = hw->gvs->b_decoded_frames;
- vstatus->b_lost_frames = hw->gvs->b_lost_frames;
- vstatus->b_concealed_frames = hw->gvs->b_concealed_frames;
- vstatus->total_data = hw->gvs->total_data;
- vstatus->samp_cnt = hw->gvs->samp_cnt;
- vstatus->offset = hw->gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
-
- return 0;
-}
-
-static int vavs_set_isreset(struct vdec_s *vdec, int isreset)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
-
- hw->is_reset = isreset;
- return 0;
-}
-
-static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw)
-{
-
- hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
- if (NULL == hw->gvs) {
- pr_info("the struct of vdec status malloc failed.\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-/****************************************/
-static int vavs_canvas_init(struct vdec_avs_hw_s *hw)
-{
- int i, ret;
- u32 canvas_width, canvas_height;
- u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
- unsigned long buf_start;
- int need_alloc_buf_num;
- struct vdec_s *vdec = NULL;
-
- if (hw->m_ins_flag)
- vdec = hw_to_vdec(hw);
-
- if (buf_size <= 0x00400000) {
- /* SD only */
- canvas_width = 768;
- canvas_height = 576;
- decbuf_y_size = 0x80000;
- decbuf_uv_size = 0x20000;
- decbuf_size = 0x100000;
- } else {
- /* HD & SD */
- canvas_width = 1920;
- canvas_height = 1088;
- decbuf_y_size = 0x200000;
- decbuf_uv_size = 0x80000;
- decbuf_size = 0x300000;
- }
-
-#ifdef AVSP_LONG_CABAC
- need_alloc_buf_num = hw->vf_buf_num_used + 2;
-#else
- need_alloc_buf_num = hw->vf_buf_num_used + 1;
-#endif
- for (i = 0; i < need_alloc_buf_num; i++) {
-
- if (i == (need_alloc_buf_num - 1))
- decbuf_size = WORKSPACE_SIZE;
-#ifdef AVSP_LONG_CABAC
- else if (i == (need_alloc_buf_num - 2))
- decbuf_size = WORKSPACE_SIZE_A;
-#endif
- ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i,
- decbuf_size, DRIVER_NAME, &buf_start);
- if (ret < 0)
- return ret;
- if (i == (need_alloc_buf_num - 1)) {
- if (firmware_sel == 1)
- hw->buf_offset = buf_start -
- RV_AI_BUFF_START_ADDR;
- else
- hw->buf_offset = buf_start -
- LONG_CABAC_RV_AI_BUFF_START_ADDR;
- continue;
- }
-#ifdef AVSP_LONG_CABAC
- else if (i == (need_alloc_buf_num - 2)) {
- avsp_heap_adr = codec_mm_phys_to_virt(buf_start);
- continue;
- }
-#endif
- if (hw->m_ins_flag) {
- unsigned canvas;
-
- if (vdec->parallel_dec == 1) {
- unsigned tmp;
- if (canvas_u(hw->canvas_spec[i]) == 0xff) {
- tmp =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~(0xffff << 8);
- hw->canvas_spec[i] |= tmp << 8;
- hw->canvas_spec[i] |= tmp << 16;
- }
- if (canvas_y(hw->canvas_spec[i]) == 0xff) {
- tmp =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~0xff;
- hw->canvas_spec[i] |= tmp;
- }
- canvas = hw->canvas_spec[i];
- } else {
- canvas = vdec->get_canvas(i, 2);
- hw->canvas_spec[i] = canvas;
- }
-
- hw->canvas_config[i][0].phy_addr =
- buf_start;
- hw->canvas_config[i][0].width =
- canvas_width;
- hw->canvas_config[i][0].height =
- canvas_height;
- hw->canvas_config[i][0].block_mode =
- CANVAS_BLKMODE_32X32;
-
- hw->canvas_config[i][1].phy_addr =
- buf_start + decbuf_y_size;
- hw->canvas_config[i][1].width =
- canvas_width;
- hw->canvas_config[i][1].height =
- canvas_height / 2;
- hw->canvas_config[i][1].block_mode =
- CANVAS_BLKMODE_32X32;
-
- } else {
-#ifdef NV21
- config_cav_lut_ex(canvas_base + canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_base + canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
-#else
- config_cav_lut_ex(canvas_num * i + 0,
- buf_start,
- canvas_width, canvas_height,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 1,
- buf_start +
- decbuf_y_size, canvas_width / 2,
- canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
- config_cav_lut_ex(canvas_num * i + 2,
- buf_start +
- decbuf_y_size + decbuf_uv_size,
- canvas_width / 2, canvas_height / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_32X32, 0, VDEC_1);
-#endif
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "canvas config %d, addr %p\n", i,
- (void *)buf_start);
- }
- }
- return 0;
-}
-
-static void vavs_recover(struct vdec_avs_hw_s *hw)
-{
- vavs_canvas_init(hw);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- if (firmware_sel == 1) {
- WRITE_VREG(POWER_CTL_VLD, 0x10);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2,
- MEM_FIFO_CNT_BIT, 2);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8,
- MEM_LEVEL_CNT_BIT, 6);
- }
-
-
- if (firmware_sel == 0) {
- /* fixed canvas index */
- WRITE_VREG(AV_SCRATCH_0, canvas_base);
- WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used);
- } else {
- int ii;
-#ifndef USE_DYNAMIC_BUF_NUM
- for (ii = 0; ii < 4; ii++) {
- WRITE_VREG(AV_SCRATCH_0 + ii,
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 1)
- << 16)
- );
- }
-#else
- for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) {
- WRITE_VREG(buf_spec_reg[ii >> 1],
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 2)
- << 16) |
- ((canvas_base + canvas_num * ii + 3)
- << 24)
- );
- }
-#endif
- }
-
- /* notify ucode the buffer offset */
- WRITE_VREG(AV_SCRATCH_F, hw->buf_offset);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
-#ifndef USE_DYNAMIC_BUF_NUM
- WRITE_VREG(AVS_SOS_COUNT, 0);
-#endif
- WRITE_VREG(AVS_BUFFERIN, 0);
- WRITE_VREG(AVS_BUFFEROUT, 0);
- if (error_recovery_mode)
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
- else
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */
- WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
-#ifdef PIC_DC_NEED_CLEAR
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
- WRITE_VREG(LONG_CABAC_REQ, 0);
- WRITE_VREG(LONG_CABAC_PIC_SIZE, 0);
- WRITE_VREG(LONG_CABAC_SRC_ADDR, 0);
- }
-#endif
- WRITE_VREG(AV_SCRATCH_5, 0);
-
-}
-
-#define MBY_MBX MB_MOTION_MODE /*0xc07*/
-#define AVS_CO_MB_WR_ADDR 0xc38
-#define AVS_CO_MB_RW_CTL 0xc3d
-#define AVS_CO_MB_RD_ADDR 0xc39
-#define AVSP_IQ_WQ_PARAM_01 0x0e19
-#define AVSP_IQ_WQ_PARAM_23 0x0e1a
-#define AVSP_IQ_WQ_PARAM_45 0x0e1b
-
-static void vavs_save_regs(struct vdec_avs_hw_s *hw)
-{
- hw->reg_scratch_0 = READ_VREG(AV_SCRATCH_0);
- hw->reg_scratch_1 = READ_VREG(AV_SCRATCH_1);
- hw->reg_scratch_2 = READ_VREG(AV_SCRATCH_2);
- hw->reg_scratch_3 = READ_VREG(AV_SCRATCH_3);
- hw->reg_scratch_4 = READ_VREG(AV_SCRATCH_4);
- hw->reg_scratch_5 = READ_VREG(AV_SCRATCH_5);
- hw->reg_scratch_6 = READ_VREG(AV_SCRATCH_6);
- hw->reg_scratch_7 = READ_VREG(AV_SCRATCH_7);
- hw->reg_scratch_8 = READ_VREG(AV_SCRATCH_8);
- hw->reg_scratch_9 = READ_VREG(AV_SCRATCH_9);
- hw->reg_scratch_A = READ_VREG(AV_SCRATCH_A);
- hw->reg_scratch_B = READ_VREG(AV_SCRATCH_B);
- hw->reg_scratch_C = READ_VREG(AV_SCRATCH_C);
- hw->reg_scratch_D = READ_VREG(AV_SCRATCH_D);
- hw->reg_scratch_E = READ_VREG(AV_SCRATCH_E);
- hw->reg_scratch_F = READ_VREG(AV_SCRATCH_F);
- hw->reg_scratch_G = READ_VREG(AV_SCRATCH_G);
- hw->reg_scratch_H = READ_VREG(AV_SCRATCH_H);
- hw->reg_scratch_I = READ_VREG(AV_SCRATCH_I);
-
- hw->reg_mb_width = READ_VREG(MB_WIDTH);
- hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT);
-
- hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR);
- hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR);
- hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR);
- hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR);
- hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR);
- hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR);
- hw->reg_anc3_canvas_addr = READ_VREG(ANC3_CANVAS_ADDR);
- hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR);
- hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR);
-
- hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE);
-
- hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG);
- hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR);
- hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01);
- hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23);
- hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
- hw->iqidct_control = READ_VREG(IQIDCT_CONTROL);
- hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT);
- hw->slice_qp = READ_VREG(SLICE_QP);
-
- hw->dc_scaler = READ_VREG(DC_SCALER);
- hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01);
- hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23);
- hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45);
- hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR);
- hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT);
- hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H);
- hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL);
-
- hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL);
-}
-
-static void vavs_restore_regs(struct vdec_avs_hw_s *hw)
-{
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s scratch_8 (AVS_BUFFERIN) 0x%x, decode_pic_count = %d\n",
- __func__, hw->reg_scratch_8, hw->decode_pic_count);
-
- WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0);
- WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1);
- WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2);
- WRITE_VREG(AV_SCRATCH_3, hw->reg_scratch_3);
- WRITE_VREG(AV_SCRATCH_4, hw->reg_scratch_4);
- WRITE_VREG(AV_SCRATCH_5, hw->reg_scratch_5);
- WRITE_VREG(AV_SCRATCH_6, hw->reg_scratch_6);
- WRITE_VREG(AV_SCRATCH_7, hw->reg_scratch_7);
- WRITE_VREG(AV_SCRATCH_8, hw->reg_scratch_8);
- WRITE_VREG(AV_SCRATCH_9, hw->reg_scratch_9);
- WRITE_VREG(AV_SCRATCH_A, hw->reg_scratch_A);
- WRITE_VREG(AV_SCRATCH_B, hw->reg_scratch_B);
- WRITE_VREG(AV_SCRATCH_C, hw->reg_scratch_C);
- WRITE_VREG(AV_SCRATCH_D, hw->reg_scratch_D);
- WRITE_VREG(AV_SCRATCH_E, hw->reg_scratch_E);
- WRITE_VREG(AV_SCRATCH_F, hw->reg_scratch_F);
- WRITE_VREG(AV_SCRATCH_G, hw->reg_scratch_G);
- WRITE_VREG(AV_SCRATCH_H, hw->reg_scratch_H);
- WRITE_VREG(AV_SCRATCH_I, hw->reg_scratch_I);
-
- WRITE_VREG(MB_WIDTH, hw->reg_mb_width);
- WRITE_VREG(VIFF_BIT_CNT, hw->reg_viff_bit_cnt);
-
- WRITE_VREG(REC_CANVAS_ADDR, hw->reg_canvas_addr);
- WRITE_VREG(DBKR_CANVAS_ADDR, hw->reg_dbkr_canvas_addr);
- WRITE_VREG(DBKW_CANVAS_ADDR, hw->reg_dbkw_canvas_addr);
- WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr);
- WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr);
- WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr);
- WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr);
- WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr);
- WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr);
-
- WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type);
-
- WRITE_VREG(VC1_CONTROL_REG, hw->vc1_control_reg);
- WRITE_VREG(AVS_CO_MB_WR_ADDR, hw->avs_co_mb_wr_addr);
- WRITE_VREG(SLICE_START_BYTE_01, hw->slice_start_byte_01);
- WRITE_VREG(SLICE_START_BYTE_23, hw->slice_start_byte_23);
- WRITE_VREG(VCOP_CTRL_REG, hw->vcop_ctrl_reg);
- WRITE_VREG(IQIDCT_CONTROL, hw->iqidct_control);
- WRITE_VREG(RV_AI_MB_COUNT, hw->rv_ai_mb_count);
- WRITE_VREG(SLICE_QP, hw->slice_qp);
-
- WRITE_VREG(DC_SCALER, hw->dc_scaler);
- WRITE_VREG(AVSP_IQ_WQ_PARAM_01, hw->avsp_iq_wq_param_01);
- WRITE_VREG(AVSP_IQ_WQ_PARAM_23, hw->avsp_iq_wq_param_23);
- WRITE_VREG(AVSP_IQ_WQ_PARAM_45, hw->avsp_iq_wq_param_45);
- WRITE_VREG(AVS_CO_MB_RD_ADDR, hw->avs_co_mb_rd_addr);
- WRITE_VREG(DBLK_MB_WID_HEIGHT, hw->dblk_mb_wid_height);
- WRITE_VREG(MC_PIC_W_H, hw->mc_pic_w_h);
- WRITE_VREG(AVS_CO_MB_RW_CTL, hw->avs_co_mb_rw_ctl);
-
- WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_decode_control);
-
-}
-
-static int vavs_prot_init(struct vdec_avs_hw_s *hw)
-{
- int r = 0;
-#if DEBUG_MULTI_FLAG > 0
- if (hw->decode_pic_count == 0) {
-#endif
-#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
-#else
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
- READ_RESET_REG(RESET0_REGISTER);
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
-
- WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
-#endif
-#if DEBUG_MULTI_FLAG > 0
- }
-#endif
- /***************** reset vld **********************************/
- WRITE_VREG(POWER_CTL_VLD, 0x10);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
- /*************************************************************/
- if (hw->m_ins_flag) {
- int i;
- if (hw->decode_pic_count == 0) {
- r = vavs_canvas_init(hw);
-#ifndef USE_DYNAMIC_BUF_NUM
- for (i = 0; i < 4; i++) {
- WRITE_VREG(AV_SCRATCH_0 + i,
- hw->canvas_spec[i]
- );
- }
-#else
- for (i = 0; i < hw->vf_buf_num_used; i++)
- WRITE_VREG(buf_spec_reg[i], 0);
- for (i = 0; i < hw->vf_buf_num_used; i += 2) {
- WRITE_VREG(buf_spec_reg[i >> 1],
- (hw->canvas_spec[i] & 0xffff) |
- ((hw->canvas_spec[i + 1] & 0xffff)
- << 16)
- );
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s WRITE_VREG(0x%x, 0x%x)\n",
- __func__, buf_spec_reg[i >> 1], READ_VREG(buf_spec_reg[i >> 1]));
- }
-#endif
- } else
- vavs_restore_regs(hw);
-
- for (i = 0; i < hw->vf_buf_num_used; i++) {
- config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
- hw->canvas_config[i][0].phy_addr,
- hw->canvas_config[i][0].width,
- hw->canvas_config[i][0].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][0].block_mode,
- 0, VDEC_1);
-
- config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
- hw->canvas_config[i][1].phy_addr,
- hw->canvas_config[i][1].width,
- hw->canvas_config[i][1].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][1].block_mode,
- 0, VDEC_1);
- }
- } else {
- r = vavs_canvas_init(hw);
-#ifdef NV21
- if (firmware_sel == 0) {
- /* fixed canvas index */
- WRITE_VREG(AV_SCRATCH_0, canvas_base);
- WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used);
- } else {
- int ii;
-#ifndef USE_DYNAMIC_BUF_NUM
- for (ii = 0; ii < 4; ii++) {
- WRITE_VREG(AV_SCRATCH_0 + ii,
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 1)
- << 16)
- );
- }
-#else
- for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) {
- WRITE_VREG(buf_spec_reg[ii >> 1],
- (canvas_base + canvas_num * ii) |
- ((canvas_base + canvas_num * ii + 1)
- << 8) |
- ((canvas_base + canvas_num * ii + 2)
- << 16) |
- ((canvas_base + canvas_num * ii + 3)
- << 24)
- );
- }
-#endif
- /*
- *WRITE_VREG(AV_SCRATCH_0, 0x010100);
- *WRITE_VREG(AV_SCRATCH_1, 0x040403);
- *WRITE_VREG(AV_SCRATCH_2, 0x070706);
- *WRITE_VREG(AV_SCRATCH_3, 0x0a0a09);
- */
- }
-#else
- /* index v << 16 | u << 8 | y */
- WRITE_VREG(AV_SCRATCH_0, 0x020100);
- WRITE_VREG(AV_SCRATCH_1, 0x050403);
- WRITE_VREG(AV_SCRATCH_2, 0x080706);
- WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
-#endif
- }
- /* notify ucode the buffer offset */
- if (hw->decode_pic_count == 0)
- WRITE_VREG(AV_SCRATCH_F, hw->buf_offset);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
- if (hw->decode_pic_count == 0) {
-#ifndef USE_DYNAMIC_BUF_NUM
- WRITE_VREG(AVS_SOS_COUNT, 0);
-#endif
- WRITE_VREG(AVS_BUFFERIN, 0);
- WRITE_VREG(AVS_BUFFEROUT, 0);
- }
- if (error_recovery_mode)
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
- else
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */
- if (hw->decode_pic_count == 0)
- WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
- /* V4L2_PIX_FMT_NV21 V4L2_PIX_FMT_NV21M */
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
-#ifdef PIC_DC_NEED_CLEAR
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
- if (hw->m_ins_flag && start_decoding_delay > 0)
- msleep(start_decoding_delay);
-
- //pr_info("+++++++++++++++++++++++++++++++\n");
- //pr_info("+++++++++++++++++++++++++++++++\n");
- //pr_info("+++++++++++++++++++++++++++++++\n");
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy);
- WRITE_VREG(LONG_CABAC_REQ, 0);
- WRITE_VREG(LONG_CABAC_PIC_SIZE, 0);
- WRITE_VREG(LONG_CABAC_SRC_ADDR, 0);
- }
-#endif
-
-#ifdef ENABLE_USER_DATA
- if (hw->decode_pic_count == 0) {
- WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset));
- pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N));
- } else
- WRITE_VREG(AV_SCRATCH_N, 0);
-#endif
- if (hw->m_ins_flag) {
- if (vdec_frame_based(hw_to_vdec(hw)))
- WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE);
- else {
- if (hw->decode_status_skip_pic_done_flag) {
- WRITE_VREG(DECODE_CFG, hw->decode_decode_cont_start_code);
- WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE_CONT);
- } else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE);
- }
- WRITE_VREG(DECODE_LMEM_BUF_ADR, (u32)hw->lmem_phy_addr);
- } else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
-
- if (ins_udebug_flag[DECODE_ID(hw)] &&
- (ins_udebug_flag[DECODE_ID(hw)] >> 16) == hw->decode_pic_count) {
- WRITE_VREG(DECODE_STOP_POS,
- ins_udebug_flag[DECODE_ID(hw)] & 0xffff);
- }
- else
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
- hw->old_udebug_flag = udebug_flag;
-
- return r;
-}
-
-
-#ifdef AVSP_LONG_CABAC
-static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64);
-#endif
-static void vavs_local_init(struct vdec_avs_hw_s *hw)
-{
- int i;
-
- hw->vf_buf_num_used = vf_buf_num;
-
- hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio;
-
- hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param;
-
- hw->frame_width = hw->frame_height = hw->frame_dur = hw->frame_prog = 0;
-
- hw->throw_pb_flag = 1;
-
- hw->total_frame = 0;
- hw->saved_resolution = 0;
- hw->next_pts = 0;
-
-#ifdef DEBUG_PTS
- hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0;
-#endif
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->recycle_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i].vf;
-
- hw->vfpool[i].vf.index = hw->vf_buf_num_used;
- hw->vfpool[i].vf.bufWidth = 1920;
- hw->vfpool[i].detached = 0;
- kfifo_put(&hw->newframe_q, vf);
- }
- for (i = 0; i < hw->vf_buf_num_used; i++)
- hw->vfbuf_use[i] = 0;
-
- /*cur_vfpool = vfpool;*/
-
- if (hw->recover_flag == 1)
- return;
-
- if (hw->mm_blk_handle) {
- pr_info("decoder_bmmu_box_free\n");
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-
- hw->mm_blk_handle = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- 0,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER);
- if (hw->mm_blk_handle == NULL)
- pr_info("Error, decoder_bmmu_box_alloc_box fail\n");
-
-}
-
-static int vavs_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)op_arg;
-
-
- spin_lock_irqsave(&lock, flags);
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
- states->buf_recycle_num = kfifo_len(&hw->recycle_q);
- if (step == 2)
- states->buf_avail_num = 0;
- spin_unlock_irqrestore(&lock, flags);
- return 0;
-}
-
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
-static void vavs_ppmgr_reset(void)
-{
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
-
- vavs_local_init(ghw);
-
- pr_info("vavs: vf_ppmgr_reset\n");
-}
-#endif
-
-static void vavs_local_reset(struct vdec_avs_hw_s *hw)
-{
- mutex_lock(&vavs_mutex);
- hw->recover_flag = 1;
- pr_info("error, local reset\n");
- amvdec_stop();
- msleep(100);
- avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
- vavs_local_init(hw);
- vavs_recover(hw);
-
-#ifdef ENABLE_USER_DATA
- reset_userdata_fifo(1);
-#endif
-
- amvdec_start();
- hw->recover_flag = 0;
-#if 0
- error_watchdog_count = 0;
-
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
-#endif
-
-
-
- mutex_unlock(&vavs_mutex);
-}
-
-#if 0
-static struct work_struct fatal_error_wd_work;
-static struct work_struct notify_work;
-static atomic_t error_handler_run = ATOMIC_INIT(0);
-#endif
-static void vavs_fatal_error_handler(struct work_struct *work)
-{
- struct vdec_avs_hw_s *hw =
- container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work);
- if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) {
- mutex_lock(&vavs_mutex);
- pr_info("vavs fatal error reset !\n");
- amvdec_stop();
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vavs_ppmgr_reset();
-#else
- vf_light_unreg_provider(&vavs_vf_prov);
- vavs_local_init(hw);
- vf_reg_provider(&vavs_vf_prov);
-#endif
- vavs_recover(hw);
- amvdec_start();
- mutex_unlock(&vavs_mutex);
- } else {
- pr_info("avs fatal_error_handler\n");
- vavs_local_reset(hw);
- }
- atomic_set(&hw->error_handler_run, 0);
-}
-
-static void vavs_notify_work(struct work_struct *work)
-{
- struct vdec_avs_hw_s *hw =
- container_of(work, struct vdec_avs_hw_s, notify_work);
- if (hw->fr_hint_status == VDEC_NEED_HINT) {
- avs_vf_notify_receiver(hw, PROVIDER_NAME ,
- VFRAME_EVENT_PROVIDER_FR_HINT ,
- (void *)((unsigned long)hw->frame_dur));
- hw->fr_hint_status = VDEC_HINTED;
- }
- return;
-}
-
-static void avs_set_clk(struct work_struct *work)
-{
- struct vdec_avs_hw_s *hw =
- container_of(work, struct vdec_avs_hw_s, set_clk_work);
- if (hw->frame_dur > 0 && hw->saved_resolution !=
- hw->frame_width * hw->frame_height * (96000 / hw->frame_dur)) {
- int fps = 96000 / hw->frame_dur;
-
- hw->saved_resolution = hw->frame_width * hw->frame_height * fps;
- if (firmware_sel == 0 &&
- (debug & AVS_DEBUG_USE_FULL_SPEED)) {
- vdec_source_changed(VFORMAT_AVS,
- 4096, 2048, 60);
- } else {
- vdec_source_changed(VFORMAT_AVS,
- hw->frame_width, hw->frame_height, fps);
- }
-
- }
-}
-
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
-int delay_count = 0;
-#endif
-static void vavs_put_timer_func(struct timer_list *arg)
-{
- struct vdec_avs_hw_s *hw = container_of(arg,
- struct vdec_avs_hw_s, recycle_timer);
- struct timer_list *timer = &hw->recycle_timer;
-
-#ifndef HANDLE_AVS_IRQ
- vavs_isr();
-#endif
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
- if (delay_count > 0) {
- if (delay_count == 1)
- amvdec_start();
- delay_count--;
- }
-#endif
- if (READ_VREG(AVS_SOS_COUNT)) {
- if (!error_recovery_mode) {
-#if 0
- if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) {
- mutex_lock(&vavs_mutex);
- pr_info("vavs fatal error reset !\n");
- amvdec_stop();
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vavs_ppmgr_reset();
-#else
- vf_light_unreg_provider(&vavs_vf_prov);
- vavs_local_init();
- vf_reg_provider(&vavs_vf_prov);
-#endif
- vavs_recover();
- amvdec_start();
- mutex_unlock(&vavs_mutex);
- } else {
- vavs_local_reset();
- }
-#else
- if (!atomic_read(&hw->error_handler_run)) {
- atomic_set(&hw->error_handler_run, 1);
- pr_info("AVS_SOS_COUNT = %d\n",
- READ_VREG(AVS_SOS_COUNT));
- pr_info("WP = 0x%x, RP = 0x%x, LEVEL = 0x%x, AVAIL = 0x%x, CUR_PTR = 0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL),
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
- schedule_work(&hw->fatal_error_wd_work);
- }
-#endif
- }
- }
-#if 0
- if (long_cabac_busy == 0 &&
- error_watchdog_threshold > 0 &&
- kfifo_len(&hw->display_q) == 0 &&
- READ_VREG(VLD_MEM_VIFIFO_LEVEL) >
- error_watchdog_buf_threshold) {
- pr_info("newq %d dispq %d recyq %d\r\n",
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q));
- pr_info("pc %x stream buf wp %x rp %x level %x\n",
- READ_VREG(MPC_E),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- error_watchdog_count++;
- if (error_watchdog_count >= error_watchdog_threshold)
- vavs_local_reset();
- } else
- error_watchdog_count = 0;
-#endif
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
- if ((hw->ucode_pause_pos != 0) &&
- (hw->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != hw->ucode_pause_pos) {
- hw->ucode_pause_pos = 0;
- WRITE_VREG(DEBUG_REG1, 0);
- }
-
- if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
- struct vframe_s *vf;
-
- if (kfifo_get(&hw->recycle_q, &vf)) {
- if ((vf->index < hw->vf_buf_num_used) &&
- (--hw->vfbuf_use[vf->index] == 0)) {
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n",
- __func__,
- ~(1 << vf->index), vf->index);
- WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
- vf->index = hw->vf_buf_num_used;
- }
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- }
-
- }
-
- schedule_work(&hw->set_clk_work);
-
- timer->expires = jiffies + PUT_INTERVAL;
-
- add_timer(timer);
-}
-
-#ifdef AVSP_LONG_CABAC
-
-static void long_cabac_do_work(struct work_struct *work)
-{
- int status = 0;
- struct vdec_avs_hw_s *hw = gw;
-#ifdef PERFORMANCE_DEBUG
- pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q)
- );
-#endif
- mutex_lock(&vavs_mutex);
- long_cabac_busy = 1;
- while (READ_VREG(LONG_CABAC_REQ)) {
- if (process_long_cabac() < 0) {
- status = -1;
- break;
- }
- }
- long_cabac_busy = 0;
- mutex_unlock(&vavs_mutex);
-#ifdef PERFORMANCE_DEBUG
- pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q),
- kfifo_len(&hw->recycle_q)
- );
-#endif
- if (status < 0) {
- pr_info("transcoding error, local reset\r\n");
- vavs_local_reset(hw);
- }
-
-}
-#endif
-
-#ifdef AVSP_LONG_CABAC
-static void init_avsp_long_cabac_buf(void)
-{
-#if 0
- es_write_addr_phy = (unsigned long)codec_mm_alloc_for_dma(
- "vavs",
- PAGE_ALIGN(MAX_CODED_FRAME_SIZE)/PAGE_SIZE,
- 0, CODEC_MM_FLAGS_DMA_CPU);
- es_write_addr_virt = codec_mm_phys_to_virt(es_write_addr_phy);
-
-#elif 0
- es_write_addr_virt =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- MAX_CODED_FRAME_SIZE, &es_write_addr_phy,
- GFP_KERNEL);
-#else
- /*es_write_addr_virt = kmalloc(MAX_CODED_FRAME_SIZE, GFP_KERNEL);
- * es_write_addr_virt = (void *)__get_free_pages(GFP_KERNEL,
- * get_order(MAX_CODED_FRAME_SIZE));
- */
- es_write_addr_virt = &es_write_addr[0];
- if (es_write_addr_virt == NULL) {
- pr_err("%s: failed to alloc es_write_addr_virt buffer\n",
- __func__);
- return;
- }
-
- es_write_addr_phy = dma_map_single(amports_get_dma_device(),
- es_write_addr_virt,
- MAX_CODED_FRAME_SIZE, DMA_BIDIRECTIONAL);
- if (dma_mapping_error(amports_get_dma_device(),
- es_write_addr_phy)) {
- pr_err("%s: failed to map es_write_addr_virt buffer\n",
- __func__);
- /*kfree(es_write_addr_virt);*/
- es_write_addr_virt = NULL;
- return;
- }
-#endif
-
-
-#ifdef BITSTREAM_READ_TMP_NO_CACHE
- bitstream_read_tmp =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy,
- GFP_KERNEL);
-
-#else
-
- bitstream_read_tmp = kmalloc(SVA_STREAM_BUF_SIZE, GFP_KERNEL);
- /*bitstream_read_tmp = (void *)__get_free_pages(GFP_KERNEL,
- *get_order(MAX_CODED_FRAME_SIZE));
- */
- if (bitstream_read_tmp == NULL) {
- pr_err("%s: failed to alloc bitstream_read_tmp buffer\n",
- __func__);
- return;
- }
-
- bitstream_read_tmp_phy = dma_map_single(amports_get_dma_device(),
- bitstream_read_tmp,
- SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- bitstream_read_tmp_phy)) {
- pr_err("%s: failed to map rpm buffer\n", __func__);
- kfree(bitstream_read_tmp);
- bitstream_read_tmp = NULL;
- return;
- }
-#endif
-}
-#endif
-
-
-static s32 vavs_init(struct vdec_avs_hw_s *hw)
-{
- int ret, size = -1;
- struct firmware_s *fw;
- u32 fw_size = 0x1000 * 16;
- /*char *buf = vmalloc(0x1000 * 16);
-
- if (IS_ERR_OR_NULL(buf))
- return -ENOMEM;
- */
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- pr_info("vavs_init\n");
- //init_timer(&hw->recycle_timer);
-
- //hw->stat |= STAT_TIMER_INIT;
-
- //amvdec_enable();
-
- //vdec_enable_DMC(NULL);
-
- vavs_local_init(hw);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
- else {
- if (firmware_sel == 1)
- size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data);
-#ifdef AVSP_LONG_CABAC
- else {
- init_avsp_long_cabac_buf();
- size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
- }
-#endif
- }
-
- if (size < 0) {
- amvdec_disable();
- pr_err("get firmware fail.");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
-
- if (hw->m_ins_flag) {
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (ulong) hw;
- //hw->check_timer.function = check_timer_func;
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
-
-
- //add_timer(&hw->check_timer);
- hw->stat |= STAT_TIMER_ARM;
-
- INIT_WORK(&hw->work, vavs_work);
-
- hw->fw = fw;
- return 0;
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data);
- else if (firmware_sel == 1)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", fw->data);
- else
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data);
-
- if (ret < 0) {
- amvdec_disable();
- /*vfree(buf);*/
- pr_err("AVS: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- /*vfree(buf);*/
-
- hw->stat |= STAT_MC_LOAD;
-
-
- /* enable AMRISC side protocol */
- ret = vavs_prot_init(hw);
- if (ret < 0)
- return ret;
-
-#ifdef HANDLE_AVS_IRQ
- if (vdec_request_irq(VDEC_IRQ_1, vavs_isr,
- "vavs-irq", (void *)hw)) {
- amvdec_disable();
- pr_info("vavs irq register error.\n");
- return -ENOENT;
- }
-#endif
-
- hw->stat |= STAT_ISR_REG;
-
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw);
- vf_reg_provider(&vavs_vf_prov);
- avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
-#else
- vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw);
- vf_reg_provider(&vavs_vf_prov);
-#endif
-
- if (hw->vavs_amstream_dec_info.rate != 0) {
- if (!hw->is_reset)
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)
- hw->vavs_amstream_dec_info.rate));
- hw->fr_hint_status = VDEC_HINTED;
- } else
- hw->fr_hint_status = VDEC_NEED_HINT;
-
- hw->stat |= STAT_VF_HOOK;
-
- timer_setup(&hw->recycle_timer, vavs_put_timer_func, 0);
- //hw->recycle_timer.data = (ulong)(hw);
- //hw->recycle_timer.function = vavs_put_timer_func;
- hw->recycle_timer.expires = jiffies + PUT_INTERVAL;
-
- add_timer(&hw->recycle_timer);
-
- hw->stat |= STAT_TIMER_ARM;
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0)
- INIT_WORK(&long_cabac_wd_work, long_cabac_do_work);
-#endif
- vdec_source_changed(VFORMAT_AVS,
- 1920, 1080, 30);
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
- if (start_decoding_delay == 0)
- amvdec_start();
- else
- delay_count = start_decoding_delay/10;
-#else
- amvdec_start();
-#endif
- hw->stat |= STAT_VDEC_RUN;
- return 0;
-}
-
-static int amvdec_avs_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_avs_hw_s *hw = NULL;
-
- if (pdata == NULL) {
- pr_info("amvdec_avs memory resource undefined.\n");
- return -EFAULT;
- }
-
- hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s));
- if (hw == NULL) {
- pr_info("\nammvdec_avs decoder driver alloc failed\n");
- return -ENOMEM;
- }
- pdata->private = hw;
- ghw = hw;
- atomic_set(&hw->error_handler_run, 0);
- hw->m_ins_flag = 0;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
- firmware_sel = 1;
-
- if (firmware_sel == 1) {
-#ifndef USE_DYNAMIC_BUF_NUM
- vf_buf_num = 4;
-#endif
- canvas_base = 0;
- canvas_num = 3;
- } else {
-
- canvas_base = 128;
- canvas_num = 2; /*NV21*/
- }
-
-
- if (pdata->sys_info)
- hw->vavs_amstream_dec_info = *pdata->sys_info;
-
- pr_info("%s (%d,%d) %d\n", __func__, hw->vavs_amstream_dec_info.width,
- hw->vavs_amstream_dec_info.height, hw->vavs_amstream_dec_info.rate);
-
- pdata->dec_status = vavs_dec_status;
- pdata->set_isreset = vavs_set_isreset;
- hw->is_reset = 0;
-
- pdata->user_data_read = NULL;
- pdata->reset_userdata_fifo = NULL;
-
- vavs_vdec_info_init(hw);
-
-#ifdef ENABLE_USER_DATA
- if (NULL == hw->user_data_buffer) {
- hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
- USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
- if (!hw->user_data_buffer) {
- pr_info("%s: Can not allocate hw->user_data_buffer\n",
- __func__);
- return -ENOMEM;
- }
- pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n",
- hw->user_data_buffer, (u32)hw->user_data_buffer_phys);
- }
-#endif
- INIT_WORK(&hw->set_clk_work, avs_set_clk);
- if (vavs_init(hw) < 0) {
- pr_info("amvdec_avs init failed.\n");
- kfree(hw->gvs);
- hw->gvs = NULL;
- pdata->dec_status = NULL;
- if (hw->fw)
- vfree(hw->fw);
- hw->fw = NULL;
- return -ENODEV;
- }
- /*vdec = pdata;*/
-
- INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler);
- atomic_set(&hw->error_handler_run, 0);
-#ifdef ENABLE_USER_DATA
- INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
-#endif
- INIT_WORK(&hw->notify_work, vavs_notify_work);
-
- return 0;
-}
-
-static int amvdec_avs_remove(struct platform_device *pdev)
-{
- struct vdec_avs_hw_s *hw = ghw;
-
- cancel_work_sync(&hw->fatal_error_wd_work);
- atomic_set(&hw->error_handler_run, 0);
-#ifdef ENABLE_USER_DATA
- cancel_work_sync(&hw->userdata_push_work);
-#endif
- cancel_work_sync(&hw->notify_work);
- cancel_work_sync(&hw->set_clk_work);
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id);
- hw->stat &= ~STAT_ISR_REG;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->recycle_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- mutex_lock(&vavs_mutex);
- cancel_work_sync(&long_cabac_wd_work);
- mutex_unlock(&vavs_mutex);
-
- if (es_write_addr_virt) {
-#if 0
- codec_mm_free_for_dma("vavs", es_write_addr_phy);
-#else
- dma_unmap_single(amports_get_dma_device(),
- es_write_addr_phy,
- MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE);
- /*kfree(es_write_addr_virt);*/
- es_write_addr_virt = NULL;
-#endif
- }
-
-#ifdef BITSTREAM_READ_TMP_NO_CACHE
- if (bitstream_read_tmp) {
- dma_free_coherent(amports_get_dma_device(),
- SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
- bitstream_read_tmp_phy);
- bitstream_read_tmp = NULL;
- }
-#else
- if (bitstream_read_tmp) {
- dma_unmap_single(amports_get_dma_device(),
- bitstream_read_tmp_phy,
- SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
- kfree(bitstream_read_tmp);
- bitstream_read_tmp = NULL;
- }
-#endif
- }
-#endif
- if (hw->stat & STAT_VF_HOOK) {
- if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset)
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
- hw->fr_hint_status = VDEC_NO_NEED_HINT;
- vf_unreg_provider(&vavs_vf_prov);
- hw->stat &= ~STAT_VF_HOOK;
- }
-
-#ifdef ENABLE_USER_DATA
- if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
- USER_DATA_SIZE,
- hw->user_data_buffer,
- hw->user_data_buffer_phys);
- hw->user_data_buffer = NULL;
- hw->user_data_buffer_phys = 0;
- }
-#endif
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
-
- //amvdec_disable();
- //vdec_disable_DMC(NULL);
-
- hw->pic_type = 0;
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-#ifdef DEBUG_PTS
- pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit,
- hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed);
- pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag,
- hw->vavs_amstream_dec_info.rate);
-#endif
- kfree(hw->gvs);
- hw->gvs = NULL;
- vfree(hw);
- return 0;
-}
-
-/****************************************/
-#if 0
-static struct platform_driver amvdec_avs_driver = {
- .probe = amvdec_avs_probe,
- .remove = amvdec_avs_remove,
- .driver = {
- .name = DRIVER_NAME,
- }
-};
-#endif
-
-static void recycle_frames(struct vdec_avs_hw_s *hw);
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- int ret = 1;
- unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1;
-#ifdef DEBUG_MULTI_FRAME_INS
- if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] &&
- run_count[1] < max_run_count[1])
- return 0;
-
- if ((DECODE_ID(hw) == 1) && run_count[1] >= run_count[0] &&
- run_count[0] < max_run_count[0])
- return 0;
-
- if (max_run_count[DECODE_ID(hw)] > 0 &&
- run_count[DECODE_ID(hw)] >= max_run_count[DECODE_ID(hw)])
- return 0;
-#endif
- if (vdec_stream_based(vdec) && (hw->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level) {
- hw->not_run_ready++;
- return 0;
- }
- }
-
- if (hw->reset_decode_flag == 0 &&
- hw->again_flag == 0 &&
- (hw->buf_status & buf_busy_mask) == buf_busy_mask) {
- recycle_frames(hw);
- if (hw->buf_recycle_status == 0)
- ret = 0;
- }
-
- if (again_threshold > 0 &&
- hw->pre_parser_wr_ptr != 0 &&
- hw->again_flag &&
- (!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_rp);
- if (parser_wr_ptr >= hw->pre_parser_wr_ptr &&
- (parser_wr_ptr - hw->pre_parser_wr_ptr) <
- again_threshold) {
- int r = vdec_sync_input(vdec);
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "%s buf lelvel:%x\n", __func__, r);
- ret = 0;
- }
- }
-
- if (ret)
- hw->not_run_ready = 0;
- else
- hw->not_run_ready++;
-
- if (ret != 0) {
- if (vdec->parallel_dec == 1)
- return (unsigned long)(CORE_MASK_VDEC_1);
- else
- return (unsigned long)(CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- } else
- return 0;
-}
-
-static void vavs_work(struct work_struct *work)
-{
- struct vdec_avs_hw_s *hw =
- container_of(work, struct vdec_avs_hw_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
- if (hw->dec_result != DEC_RESULT_AGAIN)
- debug_print(hw, PRINT_FLAG_RUN_FLOW,
- "ammvdec_avs: vavs_work,result=%d,status=%d\n",
- hw->dec_result, hw_to_vdec(hw)->next_status);
- hw->again_flag = 0;
- if (hw->dec_result == DEC_RESULT_USERDATA) {
- userdata_push_process(hw);
- return;
- } else if (hw->dec_result == DEC_RESULT_DONE) {
-
- if (!hw->ctx_valid)
- hw->ctx_valid = 1;
-#ifdef DEBUG_MULTI_FRAME_INS
- msleep(delay);
-#endif
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- } else if (hw->dec_result == DEC_RESULT_AGAIN
- && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- hw->again_flag = 1;
- if (!vdec_has_more_input(hw_to_vdec(hw))) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- } else if (hw->dec_result == DEC_RESULT_GET_DATA
- && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(hw_to_vdec(hw))) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- debug_print(hw, PRINT_FLAG_VLD_DETAIL,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- vdec_clean_input(hw_to_vdec(hw));
- return;
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- debug_print(hw, PRINT_FLAG_ERROR,
- "%s: force exit\n", __func__);
- if (hw->stat & STAT_ISR_REG) {
- amvdec_stop();
- /*disable mbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s: end of stream\n", __func__);
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- hw->eos = 1;
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- vdec_clean_input(hw_to_vdec(hw));
- }
- if (hw->stat & STAT_VDEC_RUN) {
-#if DEBUG_MULTI_FLAG == 1
-#else
- amvdec_stop();
-#endif
- hw->stat &= ~STAT_VDEC_RUN;
- }
- /*wait_vmmpeg12_search_done(hw);*/
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
- if (hw->dec_result == DEC_RESULT_DONE)
- hw->buf_recycle_status = 0;
- debug_print(hw, PRINT_FLAG_RUN_FLOW, "work end %d\n", hw->dec_result);
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else
- vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- if (hw->vdec_cb) {
- hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
- debug_print(hw, 0x80000,
- "%s:\n", __func__);
- }
-}
-
-
-static void reset_process_time(struct vdec_avs_hw_s *hw)
-{
- if (!hw->m_ins_flag)
- return;
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[DECODE_ID(hw)])
- max_process_time[DECODE_ID(hw)] = process_time;
- }
-}
-static void start_process_time(struct vdec_avs_hw_s *hw)
-{
- hw->decode_timeout_count = 2;
- hw->start_process_time = jiffies;
-}
-
-static void handle_decoding_error(struct vdec_avs_hw_s *hw)
-{
- int i;
- unsigned long flags;
- struct vframe_s *vf;
- spin_lock_irqsave(&lock, flags);
- for (i = 0; i < VF_POOL_SIZE; i++) {
- vf = &hw->vfpool[i].vf;
- if (vf->index < hw->vf_buf_num_used) {
- hw->vfpool[i].detached = 1;
- hw->vfbuf_use[vf->index] = 0;
- }
- }
- if (error_handle_policy & 0x2) {
- while (!kfifo_is_empty(&hw->display_q)) {
- if (kfifo_get(&hw->display_q, &vf)) {
- if (buf_of_vf(vf)->detached !=0) {
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s recycle %d => newframe_q\n",
- __func__,
- vf->index);
- vf->index = hw->vf_buf_num_used;
- buf_of_vf(vf)->detached = 0;
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- }
- }
-
- }
- }
- clear_pts_buf(hw);
- hw->decode_pic_count = 0;
- hw->reset_decode_flag = 1;
- hw->pre_parser_wr_ptr = 0;
- hw->buf_status = 0;
- hw->throw_pb_flag = 1;
- spin_unlock_irqrestore(&lock, flags);
-}
-
-static void timeout_process(struct vdec_avs_hw_s *hw)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
- amvdec_stop();
- if (error_handle_policy & 0x1) {
- handle_decoding_error(hw);
- } else {
- vavs_save_regs(hw);
-
- //if (hw->decode_pic_count == 0)
- hw->decode_pic_count++;
- if ((hw->decode_pic_count & 0xffff) == 0) {
- /*make ucode do not handle it as first picture*/
- hw->decode_pic_count++;
- }
- }
- hw->dec_result = DEC_RESULT_DONE;
-
- debug_print(hw, PRINT_FLAG_ERROR,
- "%s decoder timeout, status=%d, level=%d, bit_cnt=0x%x\n",
- __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VIFF_BIT_CNT));
- reset_process_time(hw);
- vdec_schedule_work(&hw->work);
-}
-
-
-static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw)
-{
- if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
- struct vframe_s *vf;
-
- if (kfifo_get(&hw->recycle_q, &vf)) {
- if (buf_of_vf(vf)->detached) {
- debug_print(hw, 0,
- "%s recycle detached vf, index=%d detched %d used %d\n",
- __func__, vf->index,
- buf_of_vf(vf)->detached,
- hw->vfbuf_use[vf->index]);
- }
- if ((vf->index < hw->vf_buf_num_used) &&
- (buf_of_vf(vf)->detached == 0) &&
- (--hw->vfbuf_use[vf->index] == 0)) {
- hw->buf_recycle_status |= (1 << vf->index);
- WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d => buf_recycle_status 0x%x\n",
- __func__,
- READ_VREG(AVS_BUFFERIN), vf->index,
- hw->buf_recycle_status);
- }
- vf->index = hw->vf_buf_num_used;
- buf_of_vf(vf)->detached = 0;
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- }
-
- }
-
-}
-
-static void recycle_frames(struct vdec_avs_hw_s *hw)
-{
- while (!kfifo_is_empty(&hw->recycle_q)) {
- struct vframe_s *vf;
-
- if (kfifo_get(&hw->recycle_q, &vf)) {
- if (buf_of_vf(vf)->detached) {
- debug_print(hw, 0,
- "%s recycle detached vf, index=%d detched %d used %d\n",
- __func__, vf->index,
- buf_of_vf(vf)->detached,
- hw->vfbuf_use[vf->index]);
- }
-
-
- if ((vf->index < hw->vf_buf_num_used) &&
- (buf_of_vf(vf)->detached == 0) &&
- (--hw->vfbuf_use[vf->index] == 0)) {
- hw->buf_recycle_status |= (1 << vf->index);
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s for vf index of %d => buf_recycle_status 0x%x\n",
- __func__,
- vf->index,
- hw->buf_recycle_status);
- }
- vf->index = hw->vf_buf_num_used;
- buf_of_vf(vf)->detached = 0;
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- }
-
- }
-
-}
-
-
-static void check_timer_func(struct timer_list *timer)
-{
- struct vdec_avs_hw_s *hw = container_of(timer,
- struct vdec_avs_hw_s, check_timer);
- struct vdec_s *vdec = hw_to_vdec(hw);
- unsigned int timeout_val = decode_timeout_val;
- unsigned long flags;
-
- if (hw->m_ins_flag &&
- (debug &
- DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 &&
- vdec->next_status ==
- VDEC_STATUS_DISCONNECTED) {
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- debug_print(hw,
- 0, "vdec requested to be disconnected\n");
- return;
- }
-
- /*recycle*/
- if (!hw->m_ins_flag) {
- spin_lock_irqsave(&lock, flags);
- recycle_frame_bufferin(hw);
- spin_unlock_irqrestore(&lock, flags);
- }
-
- if (hw->m_ins_flag) {
- if ((READ_VREG(AV_SCRATCH_5) & 0xf) != 0 &&
- (READ_VREG(AV_SCRATCH_5) & 0xff00) != 0){
- /*ucode buffer empty*/
- if ((kfifo_len(&hw->recycle_q) == 0) &&
- (kfifo_len(&hw->display_q) == 0)) {
- debug_print(hw,
- 0, "AV_SCRATCH_5=0x%x, recover ucode buffer_status\n",
- READ_VREG(AV_SCRATCH_5));
- WRITE_VREG(AV_SCRATCH_5, 0x10);
- /*let ucode to recover buffer_status*/
- }
- }
- }
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (udebug_flag != hw->old_udebug_flag) {
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
- hw->old_udebug_flag = udebug_flag;
- }
- if (dbg_cmd != 0) {
- if (dbg_cmd == 1) {
- int r = vdec_sync_input(vdec);
- dbg_cmd = 0;
- pr_info(
- "vdec_sync_input=>0x%x, (lev %x, wp %x rp %x, prp %x, pwp %x)\n",
- r,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp));
- }
- }
-
- if ((debug & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 &&
- (timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > timeout_val)) {
- if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- timeout_process(hw);
- }
- hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
- }
-
- if (READ_VREG(AVS_SOS_COUNT)) {
- if (!error_recovery_mode) {
- amvdec_stop();
- if (error_handle_policy & 0x1) {
- handle_decoding_error(hw);
- } else {
- vavs_save_regs(hw);
-
- //if (hw->decode_pic_count == 0)
- hw->decode_pic_count++;
- if ((hw->decode_pic_count & 0xffff) == 0) {
- /*make ucode do not handle it as first picture*/
- hw->decode_pic_count++;
- }
- }
- hw->dec_result = DEC_RESULT_DONE;
-
- debug_print(hw, PRINT_FLAG_ERROR,
- "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n",
- __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(AVS_SOS_COUNT));
- reset_process_time(hw);
- vdec_schedule_work(&hw->work);
- }
- }
-
- if ((hw->ucode_pause_pos != 0) &&
- (hw->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != hw->ucode_pause_pos) {
- hw->ucode_pause_pos = 0;
- WRITE_VREG(DEBUG_REG1, 0);
- }
-
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- pr_info("vdec requested to be disconnected\n");
- return;
- }
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw)
-{
- /*int r = 0;*/
- vavs_prot_init(hw);
-
- return 0;
-}
-
-static unsigned char get_data_check_sum
- (struct vdec_avs_hw_s *hw, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
-void (*callback)(struct vdec_s *, void *),
- void *arg)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- int save_reg;
- int size, ret;
- if (!hw->vdec_pg_enable_flag) {
- hw->vdec_pg_enable_flag = 1;
- amvdec_enable();
- }
- save_reg = READ_VREG(POWER_CTL_VLD);
- /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/
- debug_print(hw, PRINT_FLAG_RUN_FLOW,"run in\n");
- if (vdec_stream_based(vdec)) {
- hw->pre_parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- }
-#if 1
-#if DEBUG_MULTI_FLAG > 0
- if (hw->decode_pic_count == 0) {
-#endif
- WRITE_VREG(DOS_SW_RESET0, 0xfffffff0);
- WRITE_VREG(DOS_SW_RESET0, 0);
- WRITE_VREG(POWER_CTL_VLD, save_reg);
- hw->run_count++;
- run_count[DECODE_ID(hw)] = hw->run_count;
- vdec_reset_core(vdec);
-#if DEBUG_MULTI_FLAG > 0
- }
-#endif
-#else
- vdec_reset_core(vdec);
-#endif
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
-
- size = vdec_prepare_input(vdec, &hw->chunk);
- if (debug & DEBUG_FLAG_PREPARE_MORE_INPUT) {
- if (size < start_decode_buf_level) {
- /*debug_print(hw, PRINT_FLAG_VLD_DETAIL,
- "DEC_RESULT_AGAIN %x %x %x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));*/
-
- hw->input_empty++;
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- return;
- }
- } else {
- if (size < 0) {
- hw->input_empty++;
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- return;
- }
- }
- if (input_frame_based(vdec)) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- if (debug & PRINT_FLAG_RUN_FLOW
- ) {
- debug_print(hw, 0,
- "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, hw->decode_pic_count,
- hw->buf_recycle_status,
- size, get_data_check_sum(hw, size),
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
- }
- if (debug & PRINT_FRAMEBASE_DATA
- ) {
- int jj;
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- debug_print(hw,
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- debug_print(hw,
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- debug_print(hw,
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- } else
- debug_print(hw, PRINT_FLAG_RUN_FLOW,
- "%s decode_pic_count %d buf_recycle_status 0x%x: %x %x %x %x %x size 0x%x\n",
- __func__,
- hw->decode_pic_count,
- hw->buf_recycle_status,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp),
- size);
-
-
- hw->input_empty = 0;
- debug_print(hw, PRINT_FLAG_RUN_FLOW,
- "%s,%d, size=%d\n", __func__, __LINE__, size);
-
- /*vdec_enable_input(vdec);
- need run after VC1_CONTROL_REG is configured
- */
- hw->init_flag = 1;
-
- if (hw->chunk)
- debug_print(hw, PRINT_FLAG_RUN_FLOW,
- "input chunk offset %d, size %d\n",
- hw->chunk->offset, hw->chunk->size);
-
- hw->dec_result = DEC_RESULT_NONE;
- /*vdec->mc_loaded = 0;*/
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
- ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_AVS, "avs_multi", vdec,
- hw->fw->data, hw->fw->len);
- if (ret < 0) {
- pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
- hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_AVS;
- }
- if (avs_hw_ctx_restore(hw) < 0) {
- hw->dec_result = DEC_RESULT_ERROR;
- debug_print(hw, PRINT_FLAG_ERROR,
- "ammvdec_avs: error HW context restore\n");
- vdec_schedule_work(&hw->work);
- return;
- }
-
- /*
- This configureation of VC1_CONTROL_REG will
- pop bits (even no data in the stream buffer) if input is enabled,
- so it can only be configured before vdec_enable_input() is called.
- So move this code from ucode to here
- */
-#define DISABLE_DBLK_HCMD 0
-#define DISABLE_MC_HCMD 0
- WRITE_VREG(VC1_CONTROL_REG, (DISABLE_DBLK_HCMD<<6) |
- (DISABLE_MC_HCMD<<5) | (1 << 7) | (0xc <<8) | (1<<14));
- if (vdec_frame_based(vdec)) {
- size = hw->chunk->size +
- (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- }
-
-
- vdec_enable_input(vdec);
- /**/
-
- /*wmb();*/
- hw->stat |= STAT_MC_LOAD;
- hw->last_vld_level = 0;
-
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n",
- __func__, READ_VREG(AVS_BUFFERIN),
- kfifo_len(&hw->recycle_q));
-
- WRITE_VREG(VIFF_BIT_CNT, size * 8);
- if (hw->reset_decode_flag)
- WRITE_VREG(DECODE_STATUS, 0);
- else {
- recycle_frames(hw);
- avs_pts_check_in(hw,
- hw->decode_pic_count & 0xffff,
- hw->chunk);
-
- WRITE_VREG(DECODE_STATUS,
- (hw->decode_pic_count & 0xffff) |
- ((~hw->buf_recycle_status) << 16));
- }
-
- hw->reset_decode_flag = 0;
- //hw->decode_status_skip_pic_done_flag = 0;
- start_process_time(hw);
-#if DEBUG_MULTI_FLAG == 1
- if (hw->decode_pic_count > 0)
- WRITE_VREG(DECODE_STATUS, 0xff);
- else
-#endif
- amvdec_start();
- hw->stat |= STAT_VDEC_RUN;
-
- hw->stat |= STAT_TIMER_ARM;
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static void reset(struct vdec_s *vdec)
-{
-}
-
-static irqreturn_t vmavs_isr_thread_fn(struct vdec_s *vdec, int irq)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- u32 reg;
- struct vframe_s *vf = NULL;
- u32 dur;
- u32 repeat_count;
- u32 picture_type;
- u32 buffer_index;
- u32 frame_size;
- bool force_interlaced_frame = false;
- unsigned int pts, pts_valid = 0, offset = 0;
- u64 pts_us64;
- u32 debug_tag;
- u32 buffer_status_debug;
- //struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id;
-
- /*if (debug & AVS_DEBUG_UCODE) {
- if (READ_VREG(AV_SCRATCH_E) != 0) {
- pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E),
- READ_VREG(AV_SCRATCH_D));
- WRITE_VREG(AV_SCRATCH_E, 0);
- }
- }*/
-
- debug_print(hw, PRINT_FLAG_RUN_FLOW, "READ_VREG(AVS_BUFFEROUT) 0x%x, READ_VREG(DECODE_STATUS) 0x%x READ_VREG(AV_SCRATCH_N) 0x%x, READ_VREG(DEBUG_REG1) 0x%x\n",
- READ_VREG(AVS_BUFFEROUT),READ_VREG(DECODE_STATUS), READ_VREG(AV_SCRATCH_N), READ_VREG(DEBUG_REG1));
-
- debug_tag = READ_VREG(DEBUG_REG1);
- buffer_status_debug = debug_tag >> 16;
- debug_tag &= 0xffff;
- /* if (debug_tag & 0x10000) {
- int i;
- dma_sync_single_for_cpu(
- amports_get_dma_device(),
- hw->lmem_phy_addr,
- LMEM_BUF_SIZE,
- DMA_FROM_DEVICE);
-
- debug_print(hw, 0,
- "LMEM<tag %x>:\n", debug_tag);
-
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- unsigned short *lmem_ptr = hw->lmem_addr;
- if ((i & 0xf) == 0)
- debug_print_cont(hw, 0, "%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- debug_print_cont(hw, 0, "%04x ",
- lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- debug_print_cont(hw, 0, "\n");
- }
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hw->decode_pic_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_VREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- else if (debug_tag & 0x20000)
- hw->ucode_pause_pos = 0xffffffff;
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_VREG(DEBUG_REG1, 0);
- } else*/ if (debug_tag != 0) {
- debug_print(hw, 1,
- "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n",
- debug_tag,
- READ_VREG(DEBUG_REG2),
- buffer_status_debug,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VIFF_BIT_CNT),
- READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL));
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hw->decode_pic_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_VREG(DEBUG_REG2)) &&
- (udebug_pause_ins_id == 0 ||
- DECODE_ID(hw) == (udebug_pause_ins_id -1))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- if (debug & DEBUG_PIC_DONE_WHEN_UCODE_PAUSE) {
- hw->decode_pic_count++;
- if ((hw->decode_pic_count & 0xffff) == 0) {
- /*make ucode do not handle it as first picture*/
- hw->decode_pic_count++;
- }
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_DONE;
- amvdec_stop();
- vavs_save_regs(hw);
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s ucode pause, force done, decode_pic_count = %d, bit_cnt=0x%x\n",
- __func__,
- hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_VREG(DEBUG_REG1, 0);
- return IRQ_HANDLED;
- } else {
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s decode_status 0x%x, buffer_status 0x%x\n",
- __func__,
- READ_VREG(DECODE_STATUS),
- buffer_status_debug);
- }
-
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) {
-#ifdef PERFORMANCE_DEBUG
- pr_info("%s:schedule long_cabac_wd_work\r\n", __func__);
-#endif
- pr_info("schedule long_cabac_wd_work and requested from %d\n",
- (READ_VREG(LONG_CABAC_REQ) >> 8)&0xFF);
- schedule_work(&long_cabac_wd_work);
- }
-#endif
-
-#ifdef ENABLE_USER_DATA
- if (UserDataHandler(hw))
- return IRQ_HANDLED;
-#endif
- reg = READ_VREG(AVS_BUFFEROUT);
- if (reg) {
- unsigned short decode_pic_count
- = READ_VREG(DECODE_PIC_COUNT);
- debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n",
- reg, decode_pic_count);
- if (pts_by_offset) {
- offset = READ_VREG(AVS_OFFSET_REG);
- debug_print(hw, PRINT_FLAG_DECODING, "AVS OFFSET=%x\n", offset);
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
- &frame_size, 0, &pts_us64) == 0) {
- pts_valid = 1;
-#ifdef DEBUG_PTS
- hw->pts_hit++;
-#endif
- } else {
-#ifdef DEBUG_PTS
- hw->pts_missed++;
-#endif
- }
- }
- }
-
- repeat_count = READ_VREG(AVS_REPEAT_COUNT);
-#ifdef USE_DYNAMIC_BUF_NUM
- buffer_index =
- ((reg & 0x7) +
- (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
-#else
- if (firmware_sel == 0)
- buffer_index =
- ((reg & 0x7) +
- (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
- else
- buffer_index =
- ((reg & 0x7) - 1) & 3;
-#endif
- picture_type = (reg >> 3) & 7;
-#ifdef DEBUG_PTS
- if (picture_type == I_PICTURE) {
- /* pr_info("I offset 0x%x, pts_valid %d\n",
- * offset, pts_valid);
- */
- if (!pts_valid)
- hw->pts_i_missed++;
- else
- hw->pts_i_hit++;
- }
-#endif
-
- if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
- && hw->frame_width == 1920 && hw->frame_height == 1080) {
- force_interlaced_frame = true;
- }
-
- if (hw->throw_pb_flag && picture_type != I_PICTURE) {
-
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for throwing picture with type of %d\n",
- __func__,
- ~(1 << buffer_index), picture_type);
-
- WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index));
- } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */
- hw->throw_pb_flag = 0;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "interlace, picture type %d\n",
- picture_type);
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- hw->pic_type = 2;
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- vf->pts_us64 = pts_us64;
- if ((repeat_count > 1) && hw->avi_flag) {
- /* hw->next_pts = pts +
- * (hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1)*15/16;
- */
- hw->next_pts =
- pts +
- (dur * repeat_count >> 1) *
- 15 / 16;
- } else
- hw->next_pts = 0;
- } else {
- vf->pts = hw->next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate >> 1;
- */
- vf->duration = dur >> 1;
- hw->next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_TOP;
- }else{
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG)
- ? VIDTYPE_INTERLACE_TOP
- : VIDTYPE_INTERLACE_BOTTOM;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr);
- vf->pts = (pts_valid)?pts:0;
- //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
- vf->pts = 0;
- }
-
- debug_print(hw, PRINT_FLAG_PTS,
- "interlace1 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- if (force_interlaced_frame)
- vf->pts = 0;
- else
- vf->pts = hw->next_pts;
-
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
-
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration = hw->vavs_amstream_dec_info.rate *
- * repeat_count >> 1;
- */
- vf->duration = dur * repeat_count >> 1;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration = hw->vavs_amstream_dec_info.rate
- * >> 1;
- */
- vf->duration = dur >> 1;
- hw->next_pts = 0;
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- if (force_interlaced_frame) {
- vf->type = VIDTYPE_INTERLACE_BOTTOM;
- } else {
- vf->type =
- (reg & TOP_FIELD_FIRST_FLAG) ?
- VIDTYPE_INTERLACE_BOTTOM :
- VIDTYPE_INTERLACE_TOP;
- }
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
- vf->pts_us64 = 0;
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- debug_print(hw, PRINT_FLAG_PTS,
- "interlace2 vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- hw->total_frame++;
- } else { /* progressive */
- hw->throw_pb_flag = 0;
-
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "progressive picture type %d\n",
- picture_type);
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info
- ("fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
- set_frame_info(hw, vf, &dur);
- vf->bufWidth = 1920;
- hw->pic_type = 1;
-
- if ((picture_type == I_PICTURE) && pts_valid) {
- vf->pts = pts;
- if ((repeat_count > 1) && hw->avi_flag) {
- /* hw->next_pts = pts +
- * (hw->vavs_amstream_dec_info.rate *
- * repeat_count)*15/16;
- */
- hw->next_pts =
- pts +
- (dur * repeat_count) * 15 / 16;
- } else
- hw->next_pts = 0;
- } else {
- vf->pts = hw->next_pts;
- if (vf->pts == 0) {
- vf->pts_us64 = 0;
- }
- if ((repeat_count > 1) && hw->avi_flag) {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate *
- * repeat_count;
- */
- vf->duration = dur * repeat_count;
- if (hw->next_pts != 0) {
- hw->next_pts +=
- ((vf->duration) -
- ((vf->duration) >> 4));
- }
- } else {
- /* vf->duration =
- * hw->vavs_amstream_dec_info.rate;
- */
- vf->duration = dur;
- hw->next_pts = 0;
- }
- }
- vf->signal_type = 0;
- vf->index = buffer_index;
- vf->duration_pulldown = 0;
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
-#ifdef NV21
- vf->type |= VIDTYPE_VIU_NV21;
-#endif
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
- } else
- vf->canvas0Addr = vf->canvas1Addr =
- index2canvas(buffer_index);
- vf->type_original = vf->type;
-
- vf->pts = (pts_valid)?pts:0;
- //vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
- debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
- "buffer_index %d, canvas addr %x\n",
- buffer_index, vf->canvas0Addr);
- debug_print(hw, PRINT_FLAG_PTS,
- "progressive vf->pts = %d, vf->pts_us64 = %lld, pts_valid = %d\n", vf->pts, vf->pts_us64, pts_valid);
- hw->vfbuf_use[buffer_index]++;
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle,
- buffer_index);
-
- if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw)))
- set_vframe_pts(hw, decode_pic_count, vf);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
- vf->pts = 0;
- }
- decoder_do_frame_check(hw_to_vdec(hw), vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- hw->total_frame++;
- }
-
- /*count info*/
- vdec_count_info(hw->gvs, 0, offset);
- if (offset) {
- if (picture_type == I_PICTURE) {
- hw->gvs->i_decoded_frames++;
- } else if (picture_type == P_PICTURE) {
- hw->gvs->p_decoded_frames++;
- } else if (picture_type == B_PICTURE) {
- hw->gvs->b_decoded_frames++;
- }
- }
- avs_update_gvs(hw);
- vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0);
-
- /* pr_info("PicType = %d, PTS = 0x%x\n",
- * picture_type, vf->pts);
- */
- WRITE_VREG(AVS_BUFFEROUT, 0);
- }
- //WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
-
- if (hw->m_ins_flag) {
- u32 status_reg = READ_VREG(DECODE_STATUS);
- u32 decode_status = status_reg & 0xff;
- if (hw->dec_result == DEC_RESULT_DONE ||
- hw->dec_result == DEC_RESULT_AGAIN) {
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s !!! READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d bit_cnt=0x%x\n",
- __func__, status_reg, decode_status,
- hw->buf_status,
- hw->dec_result, hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
- return IRQ_HANDLED;
- } else if (decode_status == DECODE_STATUS_PIC_DONE ||
- decode_status == DECODE_STATUS_SKIP_PIC_DONE) {
- hw->buf_status = (status_reg >> 16) & 0xffff;
- if (decode_status == DECODE_STATUS_SKIP_PIC_DONE) {
- hw->decode_status_skip_pic_done_flag = 1;
- hw->decode_decode_cont_start_code = (status_reg >> 8) & 0xff;
- } else
- hw->decode_status_skip_pic_done_flag = 0;
- hw->decode_pic_count++;
- if ((hw->decode_pic_count & 0xffff) == 0) {
- /*make ucode do not handle it as first picture*/
- hw->decode_pic_count++;
- }
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_DONE;
-#if DEBUG_MULTI_FLAG == 1
- WRITE_VREG(DECODE_STATUS, 0);
-#else
- amvdec_stop();
-#endif
- vavs_save_regs(hw);
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n",
- __func__,
- (decode_status == DECODE_STATUS_PIC_DONE) ?
- "DECODE_STATUS_PIC_DONE" : "DECODE_STATUS_SKIP_PIC_DONE",
- status_reg, decode_status,
- hw->buf_status,
- hw->dec_result, hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
- decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) {
- hw->buf_status = (status_reg >> 16) & 0xffff;
- reset_process_time(hw);
-#if DEBUG_MULTI_FLAG == 1
- WRITE_VREG(DECODE_STATUS, 0);
-#else
- amvdec_stop();
-#endif
- if (vdec_frame_based(hw_to_vdec(hw))) {
- hw->dec_result = DEC_RESULT_DONE;
- //if (hw->decode_pic_count == 0) {
- hw->decode_pic_count++;
- //}
- if ((hw->decode_pic_count & 0xffff) == 0) {
- /*make ucode do not handle it as first picture*/
- hw->decode_pic_count++;
- }
- vavs_save_regs(hw);
- } else
- hw->dec_result = DEC_RESULT_AGAIN;
-
- debug_print(hw, PRINT_FLAG_DECODING,
- "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x, hw->decode_status_skip_pic_done_flag = %d, hw->decode_decode_cont_start_code = 0x%x\n",
- __func__, status_reg, decode_status,
- hw->buf_status,
- hw->reg_scratch_8,
- hw->dec_result, hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT), hw->decode_status_skip_pic_done_flag, hw->decode_decode_cont_start_code);
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
-
-
-#ifdef HANDLE_AVS_IRQ
- return IRQ_HANDLED;
-#else
- return;
-#endif
-}
-
-static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq)
-{
-
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- return IRQ_WAKE_THREAD;
- //return vavs_isr(0, hw);
-
-}
-
-static void vmavs_dump_state(struct vdec_s *vdec)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- int i;
- debug_print(hw, 0,
- "====== %s\n", __func__);
-
- debug_print(hw, 0,
- "width/height (%d/%d), dur %d\n",
- hw->frame_width,
- hw->frame_height,
- hw->frame_dur
- );
-
- debug_print(hw, 0,
- "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
- vdec_frame_based(vdec),
- READ_VREG(DECODE_STATUS) & 0xff,
- hw->buf_status,
- hw->buf_recycle_status,
- hw->throw_pb_flag,
- hw->eos,
- hw->stat,
- hw->dec_result,
- hw->decode_pic_count,
- hw->display_frame_count,
- hw->run_count,
- hw->not_run_ready,
- hw->input_empty
- );
-
- if (vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- debug_print(hw, 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- debug_print(hw, 0,
- "%s, newq(%d/%d), dispq(%d/%d)recycleq(%d/%d) drop %d vf peek %d, prepare/get/put (%d/%d/%d)\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->display_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->recycle_q),
- VF_POOL_SIZE,
- hw->drop_frame_count,
- hw->peek_num,
- hw->prepare_num,
- hw->get_num,
- hw->put_num
- );
-
- debug_print(hw, 0, "vfbuf_use:\n");
- for (i = 0; i < hw->vf_buf_num_used; i++)
- debug_print(hw, 0, "%d: vf_buf_use %d\n",
- i, hw->vfbuf_use[i]);
-
- debug_print(hw, 0,
- "DECODE_STATUS=0x%x\n",
- READ_VREG(DECODE_STATUS));
- debug_print(hw, 0,
- "MPC_E=0x%x\n",
- READ_VREG(MPC_E));
- debug_print(hw, 0,
- "DECODE_MODE=0x%x\n",
- READ_VREG(DECODE_MODE));
- debug_print(hw, 0,
- "wait_buf_status, AV_SCRATCH_5=0x%x\n",
- READ_VREG(AV_SCRATCH_5));
- debug_print(hw, 0,
- "MBY_MBX=0x%x\n",
- READ_VREG(MBY_MBX));
- debug_print(hw, 0,
- "VIFF_BIT_CNT=0x%x\n",
- READ_VREG(VIFF_BIT_CNT));
- debug_print(hw, 0,
- "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- debug_print(hw, 0,
- "VLD_MEM_VIFIFO_WP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- debug_print(hw, 0,
- "VLD_MEM_VIFIFO_RP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- debug_print(hw, 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- debug_print(hw, 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (vdec_frame_based(vdec) &&
- (debug & PRINT_FRAMEBASE_DATA)
- ) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, hw->chunk->size);
- else
- data = ((u8 *)hw->chunk->block->start_virt)
- + hw->chunk->offset;
-
- debug_print(hw, 0,
- "frame data size 0x%x\n",
- hw->chunk->size);
- for (jj = 0; jj < hw->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- debug_print(hw,
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- debug_print_cont(hw,
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- debug_print_cont(hw,
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-
-}
-
- int ammvdec_avs_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_avs_hw_s *hw = NULL;
- int r = 0;
-
- if (vdec_get_debug_flags() & 0x8)
- return amvdec_avs_probe(pdev);
-
- pr_info("ammvdec_avs probe start.\n");
-
- if (pdata == NULL) {
- pr_info("ammvdec_avs platform data undefined.\n");
- return -EFAULT;
- }
-
- hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s));
- if (hw == NULL) {
- pr_info("\nammvdec_avs decoder driver alloc failed\n");
- return -ENOMEM;
- }
- /*atomic_set(&hw->error_handler_run, 0);*/
- hw->m_ins_flag = 1;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
- firmware_sel = 1;
-
- if (firmware_sel == 1) {
-#ifndef USE_DYNAMIC_BUF_NUM
- vf_buf_num = 4;
-#endif
- canvas_base = 0;
- canvas_num = 3;
- } else {
- pr_info("Error, do not support longcabac work around!!!");
- r = -ENOMEM;
- goto error1;
- }
-
- if (pdata->sys_info)
- hw->vavs_amstream_dec_info = *pdata->sys_info;
-
- hw->is_reset = 0;
- pdata->user_data_read = NULL;
- pdata->reset_userdata_fifo = NULL;
-
- pdata->private = hw;
- pdata->dec_status = vavs_dec_status;
- pdata->set_isreset = vavs_set_isreset;
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vmavs_isr;
- pdata->threaded_irq_handler = vmavs_isr_thread_fn;
- pdata->dump_state = vmavs_dump_state;
-
- snprintf(hw->vdec_name, sizeof(hw->vdec_name),
- "avs-%d", pdev->id);
- snprintf(hw->pts_name, sizeof(hw->pts_name),
- "%s-timestamp", hw->vdec_name);
- snprintf(hw->new_q_name, sizeof(hw->new_q_name),
- "%s-newframe_q", hw->vdec_name);
- snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
- "%s-dispframe_q", hw->vdec_name);
-
- vavs_vdec_info_init(hw);
-
-#ifdef ENABLE_USER_DATA
- if (NULL == hw->user_data_buffer) {
- hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
- USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
- if (!hw->user_data_buffer) {
- pr_info("%s: Can not allocate hw->user_data_buffer\n",
- __func__);
- r = -ENOMEM;
- goto error2;
- }
- pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n",
- hw->user_data_buffer, (u32)hw->user_data_buffer_phys);
- }
-#endif
- /*hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL);
- if (hw->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- }
- hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(),
- hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- hw->lmem_phy_addr)) {
- pr_err("%s: failed to map lmem buffer\n", __func__);
- kfree(hw->lmem_addr);
- hw->lmem_addr = NULL;
- return -1;
- }*/
- /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/
- hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL);
- if (hw->lmem_addr == 0) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- r = -1;
- goto error3;
- }
-
- if (vavs_init(hw) < 0) {
- pr_info("amvdec_avs init failed.\n");
- r = -ENODEV;
- goto error4;
- }
-
- /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler);
- atomic_set(&hw->error_handler_run, 0);*/
-#if 0
-#ifdef ENABLE_USER_DATA
- INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
-#endif
-#endif
- INIT_WORK(&hw->notify_work, vavs_notify_work);
-
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- hw->frameinfo_enable = 1;
- }
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->canvas_spec[i] = 0xffffff;
- }
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vavs_vf_provider, hw);
-
- platform_set_drvdata(pdev, pdata);
-
- hw->platform_dev = pdev;
-
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- vdec_set_vframe_comm(pdata, DRIVER_NAME);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
-
- /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/
-
- return 0;
-
-error4:
- dma_free_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, (void *)hw->lmem_addr,
- hw->lmem_phy_addr);
-error3:
- dma_free_coherent(
- amports_get_dma_device(),
- USER_DATA_SIZE,
- hw->user_data_buffer,
- hw->user_data_buffer_phys);
-error2:
- kfree(hw->gvs);
- hw->gvs = NULL;
- pdata->dec_status = NULL;
-error1:
- vfree(hw);
- return r;
-}
-
- int ammvdec_avs_remove(struct platform_device *pdev)
-{
-
- if (vdec_get_debug_flags() & 0x8)
- return amvdec_avs_remove(pdev);
- else {
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int i;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-
- cancel_work_sync(&hw->work);
- cancel_work_sync(&hw->notify_work);
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
- vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
- }
- }
- #ifdef ENABLE_USER_DATA
- if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
- USER_DATA_SIZE,
- hw->user_data_buffer,
- hw->user_data_buffer_phys);
- hw->user_data_buffer = NULL;
- hw->user_data_buffer_phys = 0;
- }
- #endif
- /*if (hw->lmem_addr) {
- dma_unmap_single(amports_get_dma_device(),
- hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE);
- kfree(hw->lmem_addr);
- hw->lmem_addr = NULL;
- }*/
- if (hw->lmem_addr) {
- dma_free_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, (void *)hw->lmem_addr,
- hw->lmem_phy_addr);
- hw->lmem_addr = 0;
- }
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
-
- pr_info("ammvdec_avs removed.\n");
- if (hw->gvs) {
- kfree(hw->gvs);
- hw->gvs = NULL;
- }
-
- vfree(hw);
- return 0;
- }
-}
-
-
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
-struct stream_buf_s *get_vbuf(void);
-s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec);
-
-
-static s32 vavs_init2(struct vdec_avs_hw_s *hw)
-{
- int size = -1;
- struct firmware_s *fw;
- u32 fw_size = 0x1000 * 16;
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- pr_info("vavs_init\n");
-
- amvdec_enable();
-
-
- vavs_local_init(hw);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
- else {
- if (firmware_sel == 1)
- size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data);
-#ifdef AVSP_LONG_CABAC
- else {
- init_avsp_long_cabac_buf();
- size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data);
- }
-#endif
- }
-
- if (size < 0) {
- amvdec_disable();
- pr_err("get firmware fail.");
- /*vfree(buf);*/
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
- if (hw->m_ins_flag) {
- init_timer(&hw->check_timer);
- hw->check_timer.data = (ulong) hw;
- hw->check_timer.function = check_timer_func;
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
-
-
- //add_timer(&hw->check_timer);
- hw->stat |= STAT_TIMER_ARM;
-
- INIT_WORK(&hw->work, vavs_work);
-
- hw->fw = fw;
- }
- return 0;
-}
-
-unsigned int debug_flag2;
-static int vavs_prot_init2(struct vdec_avs_hw_s *hw, unsigned char post_flag)
-{
- int r = 0;
- /*
- * 2: assist
- * 3: vld_reset
- * 4: vld_part_reset
- * 5: vfifo reset
- * 6: iqidct
- * 7: mc
- * 8: dblk
- * 9: pic_dc
- * 10: psc
- * 11: mcpu
- * 12: ccpu
- * 13: ddr
- * 14: afifo
- */
- unsigned char run_flag;
-#ifdef OOO
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/);
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/);
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
- WRITE_VREG(DOS_SW_RESET0, 0);
-#endif
- /***************** reset vld **********************************/
-#ifdef OOO
- WRITE_VREG(POWER_CTL_VLD, 0x10);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2);
- WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6);
-#endif
- if (start_decoding_delay & 0x80000)
- msleep(start_decoding_delay&0xffff);
-
-if (debug_flag2 & 0x1)
- run_flag = post_flag;
-else
- run_flag = !post_flag;
-if (run_flag) {
- if (hw->m_ins_flag) {
- int i;
- if (hw->decode_pic_count == 0) {
- r = vavs_canvas_init(hw);
-#ifndef USE_DYNAMIC_BUF_NUM
- for (i = 0; i < 4; i++) {
- WRITE_VREG(AV_SCRATCH_0 + i,
- hw->canvas_spec[i]
- );
- }
-#else
- for (i = 0; i < hw->vf_buf_num_used; i += 2) {
- WRITE_VREG(buf_spec_reg[i >> 1],
- (hw->canvas_spec[i] & 0xffff) |
- ((hw->canvas_spec[i + 1] & 0xffff)
- << 16)
- );
- }
-#endif
- } else
- vavs_restore_regs(hw);
-
- for (i = 0; i < hw->vf_buf_num_used; i++) {
- config_cav_lut_ex(canvas_y(hw->canvas_spec[i]),
- hw->canvas_config[i][0].phy_addr,
- hw->canvas_config[i][0].width,
- hw->canvas_config[i][0].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][0].block_mode,
- 0, VDEC_1);
-
- config_cav_lut_ex(canvas_u(hw->canvas_spec[i]),
- hw->canvas_config[i][1].phy_addr,
- hw->canvas_config[i][1].width,
- hw->canvas_config[i][1].height,
- CANVAS_ADDR_NOWRAP,
- hw->canvas_config[i][1].block_mode,
- 0, VDEC_1);
- }
- }
-}
-
-if (debug_flag2 & 0x2)
- run_flag = post_flag;
-else
- run_flag = !post_flag;
-if (run_flag) {
-
- /* notify ucode the buffer offset */
- if (hw->decode_pic_count == 0)
- WRITE_VREG(AV_SCRATCH_F, hw->buf_offset);
-#ifdef OOO
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-#endif
- }
- if (start_decoding_delay & 0x40000)
- msleep(start_decoding_delay&0xffff);
-
- if (debug_flag2 & 0x4)
- run_flag = post_flag;
- else
- run_flag = !post_flag;
- if (run_flag) {
- if (hw->decode_pic_count == 0) {
-#ifndef USE_DYNAMIC_BUF_NUM
- WRITE_VREG(AVS_SOS_COUNT, 0);
-#endif
- WRITE_VREG(AVS_BUFFERIN, 0);
- WRITE_VREG(AVS_BUFFEROUT, 0);
- }
- if (error_recovery_mode)
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0);
- else
- WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-}
-
-if (debug_flag2 & 0x8)
- run_flag = post_flag;
-else
- run_flag = !post_flag;
-if (run_flag) {
-
-#ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */
- if (hw->decode_pic_count == 0)
- WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
- if (start_decoding_delay & 0x10000)
- msleep(start_decoding_delay&0xffff);
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
- /* V4L2_PIX_FMT_NV21 V4L2_PIX_FMT_NV21M */
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
-
- if (start_decoding_delay & 0x20000)
- msleep(start_decoding_delay&0xffff);
-
-
-#ifdef PIC_DC_NEED_CLEAR
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
-#endif
-}
-if (debug_flag2 & 0x10)
- run_flag = post_flag;
-else
- run_flag = !post_flag;
-if (run_flag) {
-#ifdef ENABLE_USER_DATA
- if (firmware_sel == 0) {
- pr_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! firmware_sel is 0\n");
- WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset));
- pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N));
- }
-#endif
-}
-
-if (debug_flag2 & 0x20)
- run_flag = post_flag;
-else
- run_flag = !post_flag;
-if (run_flag) {
- if (hw->m_ins_flag) {
- if (vdec_frame_based(hw_to_vdec(hw)))
- WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE);
- else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE);
- WRITE_VREG(DECODE_LMEM_BUF_ADR, (u32)hw->lmem_phy_addr);
- } else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
- hw->old_udebug_flag = udebug_flag;
-}
- return r;
-}
-
-static void init_hw(struct vdec_s *vdec)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- int ret;
- pr_info("%s, %d\n", __func__, __LINE__);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data);
- else if (firmware_sel == 1)
- ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", hw->fw->data);
- else
- ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data);
-
- if (ret < 0) {
- amvdec_disable();
- /*vfree(buf);*/
- pr_err("AVS: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- }
- pr_info("%s, %d\n", __func__, __LINE__);
-
- /*vfree(buf);*/
-
- hw->stat |= STAT_MC_LOAD;
-
- /* enable AMRISC side protocol */
- ret = vavs_prot_init2(hw, 0);
- if (ret < 0)
- return;
- pr_info("%s, %d\n", __func__, __LINE__);
-
-}
-
-
-static unsigned long run_ready2(struct vdec_s *vdec, unsigned long mask)
-{
- return 1;
-}
-
-static void run2(struct vdec_s *vdec, unsigned long mask,
-void (*callback)(struct vdec_s *, void *),
- void *arg)
-{
- struct vdec_avs_hw_s *hw =
- (struct vdec_avs_hw_s *)vdec->private;
- pr_info("%s, %d\n", __func__, __LINE__);
-
- vavs_prot_init2(hw, 1);
-
- vdec_source_changed(VFORMAT_AVS,
- 1920, 1080, 30);
-
- amvdec_start();
-
- hw->stat |= STAT_VDEC_RUN;
- pr_info("%s %d\n", __func__, __LINE__);
-
-}
-
-static int ammvdec_avs_probe2(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_avs_hw_s *hw = NULL;
-
- pr_info("ammvdec_avs probe start.\n");
-
- if (pdata == NULL) {
- pr_info("ammvdec_avs platform data undefined.\n");
- return -EFAULT;
- }
- pr_info("%s %d\n", __func__, __LINE__);
-
- hw = (struct vdec_avs_hw_s *)vzalloc(sizeof(struct vdec_avs_hw_s));
- if (hw == NULL) {
- pr_info("\nammvdec_avs decoder driver alloc failed\n");
- return -ENOMEM;
- }
- pr_info("%s %d\n", __func__, __LINE__);
- /*atomic_set(&hw->error_handler_run, 0);*/
- hw->m_ins_flag = 1;
- pr_info("%s %d\n", __func__, __LINE__);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
- firmware_sel = 1;
- pr_info("%s %d\n", __func__, __LINE__);
-
- if (firmware_sel == 1) {
-#ifndef USE_DYNAMIC_BUF_NUM
- vf_buf_num = 4;
-#endif
- canvas_base = 0;
- canvas_num = 3;
- } else {
- pr_info("Error, do not support longcabac work around!!!");
- return -ENOMEM;
- }
- pr_info("%s %d\n", __func__, __LINE__);
-
- if (pdata->sys_info)
- hw->vavs_amstream_dec_info = *pdata->sys_info;
- pr_info("%s %d\n", __func__, __LINE__);
-
- hw->is_reset = 0;
- pdata->user_data_read = NULL;
- pdata->reset_userdata_fifo = NULL;
-
- pr_info("%s %d\n", __func__, __LINE__);
-
- pdata->private = hw;
- pdata->dec_status = vavs_dec_status;
- pdata->set_isreset = vavs_set_isreset;
- pdata->run_ready = run_ready2;
- pdata->run = run2;
- pdata->reset = reset;
- pdata->irq_handler = vmavs_isr;
- pdata->threaded_irq_handler = vmavs_isr_thread_fn;
- pdata->dump_state = vmavs_dump_state;
-
- pr_info("%s %d\n", __func__, __LINE__);
-
- vavs_vdec_info_init(hw);
-
- pr_info("%s %d\n", __func__, __LINE__);
-
-#ifdef ENABLE_USER_DATA
- if (NULL == hw->user_data_buffer) {
- hw->user_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
- USER_DATA_SIZE,
- &hw->user_data_buffer_phys, GFP_KERNEL);
- if (!hw->user_data_buffer) {
- pr_info("%s: Can not allocate hw->user_data_buffer\n",
- __func__);
- return -ENOMEM;
- }
- pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n",
- hw->user_data_buffer, (u32)hw->user_data_buffer_phys);
- }
-#endif
- hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL);
- if (hw->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- }
- hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(),
- hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(amports_get_dma_device(),
- hw->lmem_phy_addr)) {
- pr_err("%s: failed to map lmem buffer\n", __func__);
- kfree(hw->lmem_addr);
- hw->lmem_addr = NULL;
- return -1;
- }
-
- pr_info("%s %d\n", __func__, __LINE__);
-
- /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/
-
- pr_info("%s %d\n", __func__, __LINE__);
-
- if (vavs_init2(hw) < 0) {
- pr_info("amvdec_avs init failed.\n");
- kfree(hw->gvs);
- hw->gvs = NULL;
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- /*vdec = pdata;*/
- pr_info("%s, %d\n", __func__, __LINE__);
-
-if (hw->m_ins_flag) {
- INIT_WORK(&hw->notify_work, vavs_notify_work);
-#if 1
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- hw->frameinfo_enable = 1;
- }
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->canvas_spec[i] = 0xffffff;
- }
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vavs_vf_provider, hw);
-
- platform_set_drvdata(pdev, pdata);
-
- hw->platform_dev = pdev;
-
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
- pr_info("%s, %d\n", __func__, __LINE__);
-#endif
-}else{
- /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler);
- atomic_set(&hw->error_handler_run, 0);*/
-#ifdef ENABLE_USER_DATA
- INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
-#endif
- INIT_WORK(&hw->notify_work, vavs_notify_work);
-}
-
- init_hw(pdata);
- return 0;
-}
-
-static int ammvdec_avs_remove2(struct platform_device *pdev)
-{
- struct vdec_avs_hw_s *hw = ghw;
-
- cancel_work_sync(&hw->fatal_error_wd_work);
- atomic_set(&hw->error_handler_run, 0);
-#ifdef ENABLE_USER_DATA
- cancel_work_sync(&hw->userdata_push_work);
-#endif
- cancel_work_sync(&hw->notify_work);
- cancel_work_sync(&hw->set_clk_work);
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id);
- hw->stat &= ~STAT_ISR_REG;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->recycle_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-#ifdef AVSP_LONG_CABAC
- if (firmware_sel == 0) {
- mutex_lock(&vavs_mutex);
- cancel_work_sync(&long_cabac_wd_work);
- mutex_unlock(&vavs_mutex);
-
- if (es_write_addr_virt) {
-#if 0
- codec_mm_free_for_dma("vavs", es_write_addr_phy);
-#else
- dma_unmap_single(amports_get_dma_device(),
- es_write_addr_phy,
- MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE);
- /*kfree(es_write_addr_virt);*/
- es_write_addr_virt = NULL;
-#endif
- }
-
-#ifdef BITSTREAM_READ_TMP_NO_CACHE
- if (bitstream_read_tmp) {
- dma_free_coherent(amports_get_dma_device(),
- SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
- bitstream_read_tmp_phy);
- bitstream_read_tmp = NULL;
- }
-#else
- if (bitstream_read_tmp) {
- dma_unmap_single(amports_get_dma_device(),
- bitstream_read_tmp_phy,
- SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE);
- kfree(bitstream_read_tmp);
- bitstream_read_tmp = NULL;
- }
-#endif
- }
-#endif
- if (hw->stat & STAT_VF_HOOK) {
- if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset)
- avs_vf_notify_receiver(hw, PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
- hw->fr_hint_status = VDEC_NO_NEED_HINT;
- vf_unreg_provider(&vavs_vf_prov);
- hw->stat &= ~STAT_VF_HOOK;
- }
-
-#ifdef ENABLE_USER_DATA
- if (hw->user_data_buffer != NULL) {
- dma_free_coherent(
- amports_get_dma_device(),
- USER_DATA_SIZE,
- hw->user_data_buffer,
- hw->user_data_buffer_phys);
- hw->user_data_buffer = NULL;
- hw->user_data_buffer_phys = 0;
- }
-#endif
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
-
- amvdec_disable();
- /*vdec_disable_DMC(NULL);*/
-
- hw->pic_type = 0;
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-#ifdef DEBUG_PTS
- pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit,
- hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed);
- pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag,
- hw->vavs_amstream_dec_info.rate);
-#endif
- kfree(hw->gvs);
- hw->gvs = NULL;
- vfree(hw);
- return 0;
-}
-#endif
-
-static struct platform_driver ammvdec_avs_driver = {
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
- .probe = ammvdec_avs_probe2,
- .remove = ammvdec_avs_remove2,
-#else
- .probe = ammvdec_avs_probe,
- .remove = ammvdec_avs_remove,
-#endif
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = MULTI_DRIVER_NAME,
- }
-};
-
-static struct codec_profile_t ammvdec_avs_profile = {
- .name = "AVS-V4L",
- .profile = ""
-};
-
-static struct mconfig mavs_configs[] = {
- /*MC_PU32("stat", &stat),
- MC_PU32("debug_flag", &debug_flag),
- MC_PU32("error_recovery_mode", &error_recovery_mode),
- MC_PU32("hw->pic_type", &hw->pic_type),
- MC_PU32("radr", &radr),
- MC_PU32("vf_buf_num", &vf_buf_num),
- MC_PU32("vf_buf_num_used", &vf_buf_num_used),
- MC_PU32("canvas_base", &canvas_base),
- MC_PU32("firmware_sel", &firmware_sel),
- */
-};
-static struct mconfig_node mavs_node;
-
-
-static int __init ammvdec_avs_driver_init_module(void)
-{
- pr_debug("ammvdec_avs module init\n");
-
- if (platform_driver_register(&ammvdec_avs_driver)) {
- pr_err("failed to register ammvdec_avs driver\n");
- return -ENODEV;
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- ammvdec_avs_profile.profile = "mavs+";
-
- vcodec_profile_register(&ammvdec_avs_profile);
- INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node,
- "mavs-v4l", mavs_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_AVS, 1);
- return 0;
-}
-
-
-
-static void __exit ammvdec_avs_driver_remove_module(void)
-{
- pr_debug("ammvdec_avs module remove.\n");
-
- platform_driver_unregister(&ammvdec_avs_driver);
-}
-
-/****************************************/
-/*
-module_param(stat, uint, 0664);
-MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n");
-*/
-/******************************************
- *module_param(run_flag, uint, 0664);
- *MODULE_PARM_DESC(run_flag, "\n run_flag\n");
- *
- *module_param(step_flag, uint, 0664);
- *MODULE_PARM_DESC(step_flag, "\n step_flag\n");
- *******************************************
- */
-module_param(step, uint, 0664);
-MODULE_PARM_DESC(step, "\n step\n");
-
-module_param(debug, uint, 0664);
-MODULE_PARM_DESC(debug, "\n debug\n");
-
-module_param(debug_mask, uint, 0664);
-MODULE_PARM_DESC(debug_mask, "\n debug_mask\n");
-
-module_param(error_recovery_mode, uint, 0664);
-MODULE_PARM_DESC(error_recovery_mode, "\n error_recovery_mode\n");
-
-/******************************************
- *module_param(error_watchdog_threshold, uint, 0664);
- *MODULE_PARM_DESC(error_watchdog_threshold, "\n error_watchdog_threshold\n");
- *
- *module_param(error_watchdog_buf_threshold, uint, 0664);
- *MODULE_PARM_DESC(error_watchdog_buf_threshold,
- * "\n error_watchdog_buf_threshold\n");
- *******************************************
- */
-/*
-module_param(pic_type, uint, 0444);
-MODULE_PARM_DESC(pic_type, "\n amdec_vas picture type\n");
-*/
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(dbg_cmd, uint, 0664);
-MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n");
-
-module_param(vf_buf_num, uint, 0664);
-MODULE_PARM_DESC(vf_buf_num, "\nvf_buf_num\n");
-
-/*
-module_param(vf_buf_num_used, uint, 0664);
-MODULE_PARM_DESC(vf_buf_num_used, "\nvf_buf_num_used\n");
-*/
-module_param(canvas_base, uint, 0664);
-MODULE_PARM_DESC(canvas_base, "\ncanvas_base\n");
-
-
-module_param(firmware_sel, uint, 0664);
-MODULE_PARM_DESC(firmware_sel, "\n firmware_sel\n");
-
-module_param(disable_longcabac_trans, uint, 0664);
-MODULE_PARM_DESC(disable_longcabac_trans, "\n disable_longcabac_trans\n");
-
-module_param(dec_control, uint, 0664);
-MODULE_PARM_DESC(dec_control, "\n amvdec_vavs decoder control\n");
-
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n avs start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val,
- "\n avs decode_timeout_val\n");
-
-module_param(error_handle_policy, uint, 0664);
-MODULE_PARM_DESC(error_handle_policy,
- "\n avs error_handle_policy\n");
-
-module_param(again_threshold, uint, 0664);
-MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-module_param(udebug_pause_ins_id, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n");
-
-module_param(start_decoding_delay, uint, 0664);
-MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n");
-
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level,
- "\n ammvdec_mavs pre_decode_buf_level\n");
-
-
-#ifdef DEBUG_MULTI_WITH_AUTOMODE
-module_param(debug_flag2, uint, 0664);
-MODULE_PARM_DESC(debug_flag2, "\n debug_flag2\n");
-#endif
-module_param(force_fps, uint, 0664);
-MODULE_PARM_DESC(force_fps, "\n force_fps\n");
-
-#ifdef DEBUG_MULTI_FRAME_INS
-module_param(delay, uint, 0664);
-MODULE_PARM_DESC(delay, "\n delay\n");
-
-module_param_array(max_run_count, uint, &max_decode_instance_num, 0664);
-
-#endif
-
-module_param_array(ins_udebug_flag, uint, &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint, &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint, &max_decode_instance_num, 0664);
-
-module_param_array(max_get_frame_interval, uint,
- &max_decode_instance_num, 0664);
-
-
-module_init(ammvdec_avs_driver_init_module);
-module_exit(ammvdec_avs_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC AVS Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>");
diff --git a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.h b/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.h
deleted file mode 100644
index 8922b40..0000000
--- a/drivers/frame_provider/decoder_v4l/avs_multi/avs_multi.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef AVS_H_
-#define AVS_H_
-
-#ifdef CONFIG_AMLOGIC_AVSP_LONG_CABAC
-#define AVSP_LONG_CABAC
-#endif
-/*#define BITSTREAM_READ_TMP_NO_CACHE*/
-
-#ifdef AVSP_LONG_CABAC
-#define MAX_CODED_FRAME_SIZE 1500000 /*!< bytes for one frame*/
-#define LOCAL_HEAP_SIZE (1024*1024*10)
-/*
- *#define MAX_CODED_FRAME_SIZE 240000
- *#define MAX_CODED_FRAME_SIZE 700000
- */
-#define SVA_STREAM_BUF_SIZE 1024
-
-extern void *es_write_addr_virt;
-extern dma_addr_t es_write_addr_phy;
-
-extern void *bitstream_read_tmp;
-extern dma_addr_t bitstream_read_tmp_phy;
-extern void *avsp_heap_adr;
-
-int avs_get_debug_flag(void);
-
-int process_long_cabac(void);
-
-/* bit [6] - skip_mode_flag
- * bit [5:4] - picture_type
- * bit [3] - picture_structure (0-Field, 1-Frame)
- * bit [2] - fixed_picture_qp
- * bit [1] - progressive_sequence
- * bit [0] - active
- */
-#define LONG_CABAC_REQ AV_SCRATCH_K
-#define LONG_CABAC_SRC_ADDR AV_SCRATCH_H
-#define LONG_CABAC_DES_ADDR AV_SCRATCH_I
-/* bit[31:16] - vertical_size
- * bit[15:0] - horizontal_size
- */
-#define LONG_CABAC_PIC_SIZE AV_SCRATCH_J
-
-#endif
-
-/*
- *#define PERFORMANCE_DEBUG
- *#define DUMP_DEBUG
- */
-#define AVS_DEBUG_PRINT 0x01
-#define AVS_DEBUG_OLD_ERROR_HANDLE 0x10
-#define AVS_DEBUG_USE_FULL_SPEED 0x80
-#define AEC_DUMP 0x100
-#define STREAM_INFO_DUMP 0x200
-#define SLICE_INFO_DUMP 0x400
-#define MB_INFO_DUMP 0x800
-#define MB_NUM_DUMP 0x1000
-#define BLOCK_NUM_DUMP 0x2000
-#define COEFF_DUMP 0x4000
-#define ES_DUMP 0x8000
-#define DQUANT_DUMP 0x10000
-#define STREAM_INFO_DUMP_MORE 0x20000
-#define STREAM_INFO_DUMP_MORE2 0x40000
-
-extern void *es_write_addr_virt;
-extern void *bitstream_read_tmp;
-extern dma_addr_t bitstream_read_tmp_phy;
-int read_bitstream(unsigned char *Buf, int size);
-int u_v(int LenInBits, char *tracestring);
-
-#endif
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/Makefile b/drivers/frame_provider/decoder_v4l/h264_multi/Makefile
deleted file mode 100644
index 48f2c5a..0000000
--- a/drivers/frame_provider/decoder_v4l/h264_multi/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI) += amvdec_mh264_v4l.o
-amvdec_mh264_v4l-objs += vmh264.o h264_dpb.o
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c
deleted file mode 100644
index 8ab097e..0000000
--- a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.c
+++ /dev/null
@@ -1,6036 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-
-#include "h264_dpb.h"
-
-#define FRAME_NUM_MAX_SIZE 0x10000
-
-#undef pr_info
-#define pr_info printk
-int dpb_print(int index, int debug_flag, const char *fmt, ...)
-{
- if (((h264_debug_flag & debug_flag) &&
- ((1 << index) & h264_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
- int len = 0;
- va_list args;
-
- if (!buf)
- return 0;
-
- va_start(args, fmt);
- len = sprintf(buf, "%d: ", index);
- vsnprintf(buf + len, 512-len, fmt, args);
- pr_debug("%s", buf);
- va_end(args);
- kfree(buf);
- }
- return 0;
-}
-
-int dpb_print_cont(int index, int debug_flag, const char *fmt, ...)
-{
- if (((h264_debug_flag & debug_flag) &&
- ((1 << index) & h264_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
- int len = 0;
- va_list args;
-
- if (!buf)
- return 0;
-
- va_start(args, fmt);
- vsnprintf(buf + len, 512-len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- kfree(buf);
- }
- return 0;
-}
-
-unsigned char dpb_is_debug(int index, int debug_flag)
-{
- if (((h264_debug_flag & debug_flag) &&
- ((1 << index) & h264_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR))
- return 1;
- return 0;
-}
-
-#define CHECK_VALID(list_size, mark) {\
- if (list_size > MAX_LIST_SIZE || list_size < 0) { \
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_ERROR, \
- "%s(%d): listXsize[%d] %d is larger than max size\r\n",\
- __func__, __LINE__, mark, list_size);\
- list_size = 0; \
- p_H264_Dpb->dpb_error_flag = __LINE__;\
- } \
- }
-
-static struct DecRefPicMarking_s
- dummy_dec_ref_pic_marking_buffer
- [DEC_REF_PIC_MARKING_BUFFER_NUM_MAX];
-static struct StorablePicture dummy_pic;
-static struct FrameStore dummy_fs;
-static struct StorablePicture *get_new_pic(
- struct h264_dpb_stru *p_H264_Dpb,
- enum PictureStructure structure, unsigned char is_output);
-
-
-static void init_dummy_fs(void)
-{
- dummy_fs.frame = &dummy_pic;
- dummy_fs.top_field = &dummy_pic;
- dummy_fs.bottom_field = &dummy_pic;
-
- dummy_pic.top_field = &dummy_pic;
- dummy_pic.bottom_field = &dummy_pic;
- dummy_pic.frame = &dummy_pic;
-
- dummy_pic.dec_ref_pic_marking_buffer =
- &dummy_dec_ref_pic_marking_buffer[0];
-}
-
-enum {
- LIST_0 = 0,
- LIST_1 = 1,
- BI_PRED = 2,
- BI_PRED_L0 = 3,
- BI_PRED_L1 = 4
-};
-
-void ref_pic_list_reordering(struct h264_dpb_stru *p_H264_Dpb,
- struct Slice *currSlice)
-{
- /* struct VideoParameters *p_Vid = currSlice->p_Vid;
- * byte dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];
- * DataPartition *partition = &(currSlice->partArr[dP_nr]);
- * Bitstream *currStream = partition->bitstream;
- */
- int i, j, val;
- unsigned short *reorder_cmd =
- &p_H264_Dpb->dpb_param.mmco.l0_reorder_cmd[0];
- /* alloc_ref_pic_list_reordering_buffer(currSlice); */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
- if (currSlice->slice_type != I_SLICE &&
- currSlice->slice_type != SI_SLICE) {
- /* val = currSlice->ref_pic_list_reordering_flag[LIST_0] =
- * read_u_1 ("SH: ref_pic_list_reordering_flag_l0",
- * currStream, &p_Dec->UsedBits);
- */
- if (reorder_cmd[0] != 3) {
- val = currSlice->
- ref_pic_list_reordering_flag[LIST_0] = 1;
- } else {
- val = currSlice->
- ref_pic_list_reordering_flag[LIST_0] = 0;
- }
- if (val) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%s, ref_pic_list_reordering_flag[LIST_0] is 1\n",
- __func__);
-
- j = 0;
- i = 0;
- do {
- val = currSlice->
- modification_of_pic_nums_idc[LIST_0][i] =
- reorder_cmd[j++];
- /* read_ue_v(
- * "SH: modification_of_pic_nums_idc_l0",
- * currStream, &p_Dec->UsedBits);
- */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%d(%d):val %x\n", i, j, val);
- if (j >= 66) {
- currSlice->
- ref_pic_list_reordering_flag[LIST_0] =
- 0; /* by rain */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s error\n", __func__);
- break;
- }
- if (val == 0 || val == 1) {
- currSlice->
- abs_diff_pic_num_minus1[LIST_0][i] =
- reorder_cmd[j++];
- /* read_ue_v("SH: "
- *"abs_diff_pic_num_minus1_l0",
- *currStream, &p_Dec->UsedBits);
- */
- } else {
- if (val == 2) {
- currSlice->
- long_term_pic_idx[LIST_0][i] =
- reorder_cmd[j++];
- /* read_ue_v(
- *"SH: long_term_pic_idx_l0",
- *currStream,
- *&p_Dec->UsedBits);
- */
- }
- }
- i++;
- /* assert (i>currSlice->
- * num_ref_idx_active[LIST_0]);
- */
- if (
-
-/*
- * i>currSlice->num_ref_idx_active[LIST_0] ||
- */
- i >= REORDERING_COMMAND_MAX_SIZE) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%s error %d %d\n",
- __func__, i,
- currSlice->
- num_ref_idx_active[LIST_0]);
- currSlice->
- ref_pic_list_reordering_flag[LIST_0] =
- 0; /* by rain */
- break;
- }
- if (j >= 66) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR, "%s error\n",
- __func__);
- currSlice->
- ref_pic_list_reordering_flag[LIST_0] =
- 0; /* by rain */
- break;
- }
-
- } while (val != 3);
- }
- }
-
- if (currSlice->slice_type == B_SLICE) {
- reorder_cmd = &p_H264_Dpb->dpb_param.mmco.l1_reorder_cmd[0];
- /* val = currSlice->ref_pic_list_reordering_flag[LIST_1]
- *= read_u_1 ("SH: ref_pic_list_reordering_flag_l1",
- *currStream,
- *&p_Dec->UsedBits);
- */
-
- if (reorder_cmd[0] != 3) {
- val =
- currSlice->ref_pic_list_reordering_flag[LIST_1] = 1;
- } else {
- val =
- currSlice->ref_pic_list_reordering_flag[LIST_1] = 0;
- }
-
- if (val) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%s, ref_pic_list_reordering_flag[LIST_1] is 1\n",
- __func__);
-
- j = 0;
- i = 0;
- do {
- val = currSlice->
- modification_of_pic_nums_idc[LIST_1][i] =
- reorder_cmd[j++];
- /* read_ue_v(
- *"SH: modification_of_pic_nums_idc_l1",
- *currStream,
- *&p_Dec->UsedBits);
- */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%d(%d):val %x\n",
- i, j, val);
- if (j >= 66) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR, "%s error\n",
- __func__);
- currSlice->
- ref_pic_list_reordering_flag[LIST_1] =
- 0; /* by rain */
- break;
- }
- if (val == 0 || val == 1) {
- currSlice->
- abs_diff_pic_num_minus1[LIST_1][i] =
- reorder_cmd[j++];
- /* read_ue_v(
- *"SH: abs_diff_pic_num_minus1_l1",
- *currStream, &p_Dec->UsedBits);
- */
- } else {
- if (val == 2) {
- currSlice->
- long_term_pic_idx[LIST_1][i] =
- reorder_cmd[j++];
- /* read_ue_v(
- *"SH: long_term_pic_idx_l1",
- *currStream,
- *&p_Dec->UsedBits);
- */
- }
- }
- i++;
- /* assert(i>currSlice->
- * num_ref_idx_active[LIST_1]);
- */
- if (
- /*i>currSlice->num_ref_idx_active[LIST_1] || */
- i >= REORDERING_COMMAND_MAX_SIZE) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%s error %d %d\n",
- __func__, i,
- currSlice->
- num_ref_idx_active[LIST_0]);
- currSlice->
- ref_pic_list_reordering_flag[LIST_1] =
- 0; /* by rain */
- break;
- }
- if (j >= 66) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s error\n", __func__);
- break;
- }
- } while (val != 3);
- }
- }
-
- /* set reference index of redundant slices. */
- /*
- *if (currSlice->redundant_pic_cnt &&
- *(currSlice->slice_type != I_SLICE))
- *{
- * currSlice->redundant_slice_ref_idx =
- * currSlice->abs_diff_pic_num_minus1[LIST_0][0] + 1;
- *}
- */
-}
-
-void slice_prepare(struct h264_dpb_stru *p_H264_Dpb,
- struct DecodedPictureBuffer *p_Dpb,
- struct VideoParameters *p_Vid,
- struct SPSParameters *sps, struct Slice *pSlice)
-{
- int i, j;
- /* p_Vid->active_sps = sps; */
- unsigned short *mmco_cmd = &p_H264_Dpb->dpb_param.mmco.mmco_cmd[0];
- /* for decode_poc */
- sps->pic_order_cnt_type =
- p_H264_Dpb->dpb_param.l.data[PIC_ORDER_CNT_TYPE];
- sps->log2_max_pic_order_cnt_lsb_minus4 =
- p_H264_Dpb->dpb_param.l.data[LOG2_MAX_PIC_ORDER_CNT_LSB] - 4;
- sps->num_ref_frames_in_pic_order_cnt_cycle =
- p_H264_Dpb->
- dpb_param.l.data[NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE];
- for (i = 0; i < 128; i++)
- sps->offset_for_ref_frame[i] =
- (short) p_H264_Dpb->
- dpb_param.mmco.offset_for_ref_frame_base[i];
- sps->offset_for_non_ref_pic =
- (short) p_H264_Dpb->dpb_param.l.data[OFFSET_FOR_NON_REF_PIC];
- sps->offset_for_top_to_bottom_field =
- (short) p_H264_Dpb->dpb_param.l.data
- [OFFSET_FOR_TOP_TO_BOTTOM_FIELD];
-
- pSlice->frame_num = p_H264_Dpb->dpb_param.dpb.frame_num;
- pSlice->idr_flag =
- (p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f)
- == 5 ? 1 : 0;
- pSlice->nal_reference_idc =
- (p_H264_Dpb->dpb_param.dpb.NAL_info_mmco >> 5)
- & 0x3;
- pSlice->pic_order_cnt_lsb =
- p_H264_Dpb->dpb_param.dpb.pic_order_cnt_lsb;
- pSlice->field_pic_flag = 0;
- pSlice->bottom_field_flag = 0;
- pSlice->delta_pic_order_cnt_bottom = val(
- p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_bottom);
- pSlice->delta_pic_order_cnt[0] = val(
- p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_0);
- pSlice->delta_pic_order_cnt[1] = val(
- p_H264_Dpb->dpb_param.dpb.delta_pic_order_cnt_1);
-
- p_Vid->last_has_mmco_5 = 0;
- /* last memory_management_control_operation is 5 */
- p_Vid->last_pic_bottom_field = 0;
- p_Vid->max_frame_num = 1 <<
- (p_H264_Dpb->dpb_param.l.data[LOG2_MAX_FRAME_NUM]);
-
- /**/
- pSlice->structure = (p_H264_Dpb->
- dpb_param.l.data[NEW_PICTURE_STRUCTURE] == 3) ?
- FRAME : p_H264_Dpb->dpb_param.l.data[NEW_PICTURE_STRUCTURE];
- if (pSlice->structure == FRAME) {
- pSlice->field_pic_flag = 0;
- pSlice->bottom_field_flag = 0;
- } else {
- pSlice->field_pic_flag = 1;
- if (pSlice->structure == TOP_FIELD)
- pSlice->bottom_field_flag = 0;
- else
- pSlice->bottom_field_flag = 1;
- }
- pSlice->pic_struct = p_H264_Dpb->dpb_param.l.data[PICTURE_STRUCT];
-
- sps->num_ref_frames = p_H264_Dpb->
- dpb_param.l.data[MAX_REFERENCE_FRAME_NUM];
- sps->profile_idc =
- (p_H264_Dpb->dpb_param.l.data[PROFILE_IDC_MMCO] >> 8) & 0xff;
- /*sps->max_dpb_size = p_H264_Dpb->dpb_param.l.data[MAX_DPB_SIZE];*/
- if (pSlice->idr_flag) {
- pSlice->long_term_reference_flag = mmco_cmd[0] & 1;
- pSlice->no_output_of_prior_pics_flag = (mmco_cmd[0] >> 1) & 1;
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "IDR: long_term_reference_flag %d no_output_of_prior_pics_flag %d\r\n",
- pSlice->long_term_reference_flag,
- pSlice->no_output_of_prior_pics_flag);
-
- p_H264_Dpb->long_term_reference_flag = pSlice->long_term_reference_flag;
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "idr set pre_frame_num(%d) to frame_num (%d)\n",
- p_Vid->pre_frame_num, pSlice->frame_num);
-
- p_Vid->pre_frame_num = pSlice->frame_num;
- } else if (p_H264_Dpb->mDPB.first_pic_done == 0) {
- /* by rain
- handle the case when first slice is I instead of IDR
- */
- p_Vid->pre_frame_num = pSlice->frame_num;
- }
- /* pSlice->adaptive_ref_pic_buffering_flag; */
- sps->log2_max_frame_num_minus4 =
- p_H264_Dpb->dpb_param.l.data[LOG2_MAX_FRAME_NUM] - 4;
- sps->frame_num_gap_allowed = p_H264_Dpb->dpb_param.l.data[FRAME_NUM_GAP_ALLOWED];
-
- p_Vid->non_conforming_stream =
- p_H264_Dpb->dpb_param.l.data[NON_CONFORMING_STREAM];
- p_Vid->recovery_point =
- p_H264_Dpb->dpb_param.l.data[RECOVERY_POINT];
- switch (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE]) {
- case I_Slice:
- pSlice->slice_type = I_SLICE;
- break;
- case P_Slice:
- pSlice->slice_type = P_SLICE;
- break;
- case B_Slice:
- pSlice->slice_type = B_SLICE;
- break;
- default:
- pSlice->slice_type = NUM_SLICE_TYPES;
- break;
- }
-
- pSlice->num_ref_idx_active[LIST_0] =
- p_H264_Dpb->dpb_param.dpb.num_ref_idx_l0_active_minus1 +
- 1;
- /* p_H264_Dpb->dpb_param.l.data[PPS_NUM_REF_IDX_L0_ACTIVE_MINUS1]; */
- pSlice->num_ref_idx_active[LIST_1] =
- p_H264_Dpb->dpb_param.dpb.num_ref_idx_l1_active_minus1 +
- 1;
- /* p_H264_Dpb->dpb_param.l.data[PPS_NUM_REF_IDX_L1_ACTIVE_MINUS1]; */
-
- pSlice->p_Vid = p_Vid;
- pSlice->p_Dpb = p_Dpb;
- /*
- p_H264_Dpb->colocated_buf_size =
- p_H264_Dpb->dpb_param.l.data[FRAME_SIZE_IN_MB] * 96;*/
- pSlice->first_mb_in_slice =
- p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE];
- pSlice->mode_8x8_flags = p_H264_Dpb->dpb_param.l.data[MODE_8X8_FLAGS];
- pSlice->picture_structure_mmco =
- p_H264_Dpb->dpb_param.dpb.picture_structure_mmco;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s slice_type is %d, num_ref_idx_active[0,1]=%d,%d nal_reference_idc %d pic struct 0x%x(mmco stru 0x%x)\n",
- __func__, pSlice->slice_type,
- pSlice->num_ref_idx_active[LIST_0],
- pSlice->num_ref_idx_active[LIST_1],
- pSlice->nal_reference_idc,
- pSlice->structure,
- pSlice->picture_structure_mmco);
-#ifdef ERROR_CHECK
- if (pSlice->num_ref_idx_active[LIST_0] >= MAX_LIST_SIZE) {
- pSlice->num_ref_idx_active[LIST_0] = MAX_LIST_SIZE - 1;
- p_H264_Dpb->dpb_error_flag = __LINE__;
- }
- if (pSlice->num_ref_idx_active[LIST_1] >= MAX_LIST_SIZE) {
- pSlice->num_ref_idx_active[LIST_1] = MAX_LIST_SIZE - 1;
- p_H264_Dpb->dpb_error_flag = __LINE__;
- }
-#endif
-
-#if 1
- /* dec_ref_pic_marking_buffer */
- pSlice->adaptive_ref_pic_buffering_flag = 0;
- if (pSlice->nal_reference_idc) {
- for (i = 0, j = 0; i < 44; j++) {
- unsigned short val;
- struct DecRefPicMarking_s *tmp_drpm =
- &pSlice->dec_ref_pic_marking_buffer[j];
- memset(tmp_drpm, 0, sizeof(struct DecRefPicMarking_s));
- val = tmp_drpm->
- memory_management_control_operation =
- mmco_cmd[i++];
- tmp_drpm->Next = NULL;
- if (j > 0) {
- pSlice->
- dec_ref_pic_marking_buffer[j - 1].Next =
- tmp_drpm;
- }
- if (val == 0 || i >= 44)
- break;
- pSlice->adaptive_ref_pic_buffering_flag = 1;
- if ((val == 1) || (val == 3)) {
- tmp_drpm->difference_of_pic_nums_minus1 =
- mmco_cmd[i++];
- }
- if (val == 2)
- tmp_drpm->long_term_pic_num = mmco_cmd[i++];
- if (i >= 44)
- break;
- if ((val == 3) || (val == 6))
- tmp_drpm->long_term_frame_idx = mmco_cmd[i++];
- if (val == 4) {
- tmp_drpm->max_long_term_frame_idx_plus1 =
- mmco_cmd[i++];
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "dec_ref_pic_marking_buffer[%d]:operation %x diff_pic_minus1 %x long_pic_num %x long_frame_idx %x max_long_frame_idx_plus1 %x\n",
- j,
- tmp_drpm->memory_management_control_operation,
- tmp_drpm->difference_of_pic_nums_minus1,
- tmp_drpm->long_term_pic_num,
- tmp_drpm->long_term_frame_idx,
- tmp_drpm->max_long_term_frame_idx_plus1);
- }
- }
-
- ref_pic_list_reordering(p_H264_Dpb, pSlice);
-#endif
-
- /*VUI*/
- p_H264_Dpb->vui_status = p_H264_Dpb->dpb_param.l.data[VUI_STATUS];
- p_H264_Dpb->aspect_ratio_idc =
- p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_IDC];
- p_H264_Dpb->aspect_ratio_sar_width =
- p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_SAR_WIDTH];
- p_H264_Dpb->aspect_ratio_sar_height =
- p_H264_Dpb->dpb_param.l.data[ASPECT_RATIO_SAR_HEIGHT];
-
- p_H264_Dpb->fixed_frame_rate_flag = p_H264_Dpb->dpb_param.l.data[
- FIXED_FRAME_RATE_FLAG];
- p_H264_Dpb->num_units_in_tick =
- p_H264_Dpb->dpb_param.l.data[NUM_UNITS_IN_TICK];
- p_H264_Dpb->time_scale = p_H264_Dpb->dpb_param.l.data[TIME_SCALE] |
- (p_H264_Dpb->dpb_param.l.data[TIME_SCALE + 1] << 16);
-
- p_H264_Dpb->bitstream_restriction_flag =
- (p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1;
- p_H264_Dpb->num_reorder_frames =
- p_H264_Dpb->dpb_param.l.data[NUM_REORDER_FRAMES];
- p_H264_Dpb->max_dec_frame_buffering =
- p_H264_Dpb->dpb_param.l.data[MAX_BUFFER_FRAME];
-
- /**/
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s return\n", __func__);
-}
-
-static void decode_poc(struct VideoParameters *p_Vid, struct Slice *pSlice)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid,
- struct h264_dpb_stru, mVideo);
- struct SPSParameters *active_sps = p_Vid->active_sps;
- int i;
- /* for POC mode 0: */
- unsigned int MaxPicOrderCntLsb = (1 <<
- (active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DEBUG_POC,
- "%s:pic_order_cnt_type %d, idr_flag %d last_has_mmco_5 %d last_pic_bottom_field %d pic_order_cnt_lsb %d PrevPicOrderCntLsb %d\r\n",
- __func__,
- active_sps->pic_order_cnt_type,
- pSlice->idr_flag,
- p_Vid->last_has_mmco_5,
- p_Vid->last_pic_bottom_field,
- pSlice->pic_order_cnt_lsb,
- p_Vid->PrevPicOrderCntLsb
- );
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DEBUG_POC,
- "%s:field_pic_flag %d, bottom_field_flag %d frame_num %d PreviousFrameNum %d PreviousFrameNumOffset %d ax_frame_num %d num_ref_frames_in_pic_order_cnt_cycle %d offset_for_non_ref_pic %d\r\n",
- __func__,
- pSlice->field_pic_flag,
- pSlice->bottom_field_flag,
- pSlice->frame_num,
- p_Vid->PreviousFrameNum,
- p_Vid->PreviousFrameNumOffset,
- p_Vid->max_frame_num,
- active_sps->num_ref_frames_in_pic_order_cnt_cycle,
- active_sps->offset_for_non_ref_pic
- );
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DEBUG_POC,
- "%s: delta_pic_order_cnt %d %d nal_reference_idc %d\r\n",
- __func__,
- pSlice->delta_pic_order_cnt[0], pSlice->delta_pic_order_cnt[1],
- pSlice->nal_reference_idc
- );
-
-
- switch (active_sps->pic_order_cnt_type) {
- case 0: /* POC MODE 0 */
- /* 1st */
- if (pSlice->idr_flag) {
- p_Vid->PrevPicOrderCntMsb = 0;
- p_Vid->PrevPicOrderCntLsb = 0;
- } else {
- if (p_Vid->last_has_mmco_5) {
- if (p_Vid->last_pic_bottom_field) {
- p_Vid->PrevPicOrderCntMsb = 0;
- p_Vid->PrevPicOrderCntLsb = 0;
- } else {
- p_Vid->PrevPicOrderCntMsb = 0;
- p_Vid->PrevPicOrderCntLsb =
- pSlice->toppoc;
- }
- }
- }
- /* Calculate the MSBs of current picture */
- if (pSlice->pic_order_cnt_lsb < p_Vid->PrevPicOrderCntLsb &&
- (p_Vid->PrevPicOrderCntLsb - pSlice->pic_order_cnt_lsb) >=
- (MaxPicOrderCntLsb / 2))
- pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb +
- MaxPicOrderCntLsb;
- else if (pSlice->pic_order_cnt_lsb >
- p_Vid->PrevPicOrderCntLsb &&
- (pSlice->pic_order_cnt_lsb -
- p_Vid->PrevPicOrderCntLsb) >
- (MaxPicOrderCntLsb / 2))
- pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb -
- MaxPicOrderCntLsb;
- else
- pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb;
-
- /* 2nd */
- if (pSlice->field_pic_flag == 0) {
- /* frame pix */
- pSlice->toppoc = pSlice->PicOrderCntMsb +
- pSlice->pic_order_cnt_lsb;
- pSlice->bottompoc = pSlice->toppoc +
- pSlice->delta_pic_order_cnt_bottom;
- pSlice->ThisPOC = pSlice->framepoc =
- (pSlice->toppoc < pSlice->bottompoc) ?
- pSlice->toppoc : pSlice->bottompoc;
- /* POC200301 */
- } else if (pSlice->bottom_field_flag == 0) {
- /* top field */
- pSlice->ThisPOC = pSlice->toppoc =
- pSlice->PicOrderCntMsb +
- pSlice->pic_order_cnt_lsb;
- } else {
- /* bottom field */
- pSlice->ThisPOC = pSlice->bottompoc =
- pSlice->PicOrderCntMsb +
- pSlice->pic_order_cnt_lsb;
- }
- pSlice->framepoc = pSlice->ThisPOC;
-
- p_Vid->ThisPOC = pSlice->ThisPOC;
-
- /* if ( pSlice->frame_num != p_Vid->PreviousFrameNum)
- * Seems redundant
- */
- p_Vid->PreviousFrameNum = pSlice->frame_num;
-
- if (pSlice->nal_reference_idc) {
- p_Vid->PrevPicOrderCntLsb = pSlice->pic_order_cnt_lsb;
- p_Vid->PrevPicOrderCntMsb = pSlice->PicOrderCntMsb;
- }
-
- break;
-
- case 1: /* POC MODE 1 */
- /* 1st */
- if (pSlice->idr_flag) {
- p_Vid->FrameNumOffset = 0; /* first pix of IDRGOP */
- if (pSlice->frame_num)
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "frame_num not equal to zero in IDR picture %d",
- -1020);
- } else {
- if (p_Vid->last_has_mmco_5) {
- p_Vid->PreviousFrameNumOffset = 0;
- p_Vid->PreviousFrameNum = 0;
- }
- if (pSlice->frame_num < p_Vid->PreviousFrameNum) {
- /* not first pix of IDRGOP */
- p_Vid->FrameNumOffset =
- p_Vid->PreviousFrameNumOffset +
- p_Vid->max_frame_num;
- } else {
- p_Vid->FrameNumOffset =
- p_Vid->PreviousFrameNumOffset;
- }
- }
-
- /* 2nd */
- if (active_sps->num_ref_frames_in_pic_order_cnt_cycle)
- pSlice->AbsFrameNum =
- p_Vid->FrameNumOffset + pSlice->frame_num;
- else
- pSlice->AbsFrameNum = 0;
- if ((!pSlice->nal_reference_idc) && pSlice->AbsFrameNum > 0)
- pSlice->AbsFrameNum--;
-
- /* 3rd */
- p_Vid->ExpectedDeltaPerPicOrderCntCycle = 0;
-
- if (active_sps->num_ref_frames_in_pic_order_cnt_cycle)
- for (i = 0; i < (int) active_sps->
- num_ref_frames_in_pic_order_cnt_cycle; i++) {
- p_Vid->ExpectedDeltaPerPicOrderCntCycle +=
- active_sps->offset_for_ref_frame[i];
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DEBUG_POC,
- "%s: offset_for_ref_frame %d\r\n",
- __func__,
- active_sps->
- offset_for_ref_frame[i]);
- }
-
- if (pSlice->AbsFrameNum) {
- p_Vid->PicOrderCntCycleCnt =
- (pSlice->AbsFrameNum - 1) /
- active_sps->
- num_ref_frames_in_pic_order_cnt_cycle;
- p_Vid->FrameNumInPicOrderCntCycle =
- (pSlice->AbsFrameNum - 1) %
- active_sps->
- num_ref_frames_in_pic_order_cnt_cycle;
- p_Vid->ExpectedPicOrderCnt =
- p_Vid->PicOrderCntCycleCnt *
- p_Vid->ExpectedDeltaPerPicOrderCntCycle;
- for (i = 0; i <= (int)p_Vid->
- FrameNumInPicOrderCntCycle; i++) {
- p_Vid->ExpectedPicOrderCnt +=
- active_sps->offset_for_ref_frame[i];
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DEBUG_POC,
- "%s: offset_for_ref_frame %d\r\n",
- __func__,
- active_sps->
- offset_for_ref_frame[i]);
- }
- } else
- p_Vid->ExpectedPicOrderCnt = 0;
-
- if (!pSlice->nal_reference_idc)
- p_Vid->ExpectedPicOrderCnt +=
- active_sps->offset_for_non_ref_pic;
-
- if (pSlice->field_pic_flag == 0) {
- /* frame pix */
- pSlice->toppoc = p_Vid->ExpectedPicOrderCnt +
- pSlice->delta_pic_order_cnt[0];
- pSlice->bottompoc = pSlice->toppoc +
- active_sps->offset_for_top_to_bottom_field +
- pSlice->delta_pic_order_cnt[1];
- pSlice->ThisPOC = pSlice->framepoc =
- (pSlice->toppoc < pSlice->bottompoc) ?
- pSlice->toppoc : pSlice->bottompoc;
- /* POC200301 */
- } else if (pSlice->bottom_field_flag == 0) {
- /* top field */
- pSlice->ThisPOC = pSlice->toppoc =
- p_Vid->ExpectedPicOrderCnt +
- pSlice->delta_pic_order_cnt[0];
- } else {
- /* bottom field */
- pSlice->ThisPOC = pSlice->bottompoc =
- p_Vid->ExpectedPicOrderCnt +
- active_sps->offset_for_top_to_bottom_field +
- pSlice->delta_pic_order_cnt[0];
- }
- pSlice->framepoc = pSlice->ThisPOC;
-
- p_Vid->PreviousFrameNum = pSlice->frame_num;
- p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset;
-
- break;
-
-
- case 2: /* POC MODE 2 */
- if (pSlice->idr_flag) { /* IDR picture */
- p_Vid->FrameNumOffset = 0; /* first pix of IDRGOP */
- pSlice->ThisPOC = pSlice->framepoc = pSlice->toppoc =
- pSlice->bottompoc = 0;
- if (pSlice->frame_num)
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "frame_num not equal to zero in IDR picture %d",
- -1020);
- } else {
- if (p_Vid->last_has_mmco_5) {
- p_Vid->PreviousFrameNum = 0;
- p_Vid->PreviousFrameNumOffset = 0;
- }
- if (pSlice->frame_num < p_Vid->PreviousFrameNum)
- p_Vid->FrameNumOffset =
- p_Vid->PreviousFrameNumOffset +
- p_Vid->max_frame_num;
- else
- p_Vid->FrameNumOffset =
- p_Vid->PreviousFrameNumOffset;
-
- pSlice->AbsFrameNum = p_Vid->FrameNumOffset +
- pSlice->frame_num;
- if (!pSlice->nal_reference_idc)
- pSlice->ThisPOC =
- (2 * pSlice->AbsFrameNum - 1);
- else
- pSlice->ThisPOC = (2 * pSlice->AbsFrameNum);
-
- if (pSlice->field_pic_flag == 0)
- pSlice->toppoc = pSlice->bottompoc =
- pSlice->framepoc = pSlice->ThisPOC;
- else if (pSlice->bottom_field_flag == 0)
- pSlice->toppoc = pSlice->framepoc =
- pSlice->ThisPOC;
- else
- pSlice->bottompoc = pSlice->framepoc =
- pSlice->ThisPOC;
- }
-
- p_Vid->PreviousFrameNum = pSlice->frame_num;
- p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset;
- break;
-
-
- default:
- /* error must occurs */
- /* assert( 1==0 ); */
- break;
- }
-}
-
-void fill_frame_num_gap(struct VideoParameters *p_Vid, struct Slice *currSlice)
-{
- struct h264_dpb_stru *p_H264_Dpb =
- container_of(p_Vid, struct h264_dpb_stru, mVideo);
- struct SPSParameters *active_sps = p_Vid->active_sps;
- int CurrFrameNum;
- int UnusedShortTermFrameNum;
- struct StorablePicture *picture = NULL;
- int tmp1 = currSlice->delta_pic_order_cnt[0];
- int tmp2 = currSlice->delta_pic_order_cnt[1];
- int ret;
-
- currSlice->delta_pic_order_cnt[0] =
- currSlice->delta_pic_order_cnt[1] = 0;
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "A gap in frame number is found, try to fill it.(pre_frame_num %d, max_frame_num %d\n",
- p_Vid->pre_frame_num, p_Vid->max_frame_num
- );
-
- UnusedShortTermFrameNum = (p_Vid->pre_frame_num + 1)
- % p_Vid->max_frame_num;
- CurrFrameNum = currSlice->frame_num; /*p_Vid->frame_num;*/
-
- while (CurrFrameNum != UnusedShortTermFrameNum) {
- /*pr_err("CurrFrameNum = %d, UnusedShortTermFrameNum = %d\n", CurrFrameNum, UnusedShortTermFrameNum);*/
- /*picture = alloc_storable_picture
- *(p_Vid, FRAME, p_Vid->width,
- *p_Vid->height,
- *p_Vid->width_cr,
- *p_Vid->height_cr, 1);
- */
- picture = get_new_pic(p_H264_Dpb,
- p_H264_Dpb->mSlice.structure,
- /*p_Vid->width, p_Vid->height,
- *p_Vid->width_cr,
- p_Vid->height_cr,*/ 1);
-
- if (picture == NULL) {
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s Error: get_new_pic return NULL\r\n",
- __func__);
- /*h264_debug_flag |= PRINT_FLAG_DUMP_DPB;*/
- dump_dpb(p_Dpb, 0);
- return;
- }
-
- picture->colocated_buf_index = -1;
- picture->buf_spec_num = -1;
- picture->buf_spec_is_alloced = 0;
-
- picture->coded_frame = 1;
- picture->pic_num = UnusedShortTermFrameNum;
- picture->frame_num = UnusedShortTermFrameNum;
- picture->non_existing = 1;
- picture->is_output = 1;
- picture->used_for_reference = 1;
- picture->adaptive_ref_pic_buffering_flag = 0;
- #if (MVC_EXTENSION_ENABLE)
- picture->view_id = currSlice->view_id;
- #endif
-
- currSlice->frame_num = UnusedShortTermFrameNum;
- if (active_sps->pic_order_cnt_type != 0) {
- /*decode_poc(p_Vid, p_Vid->ppSliceList[0]);*/
- decode_poc(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice);
- }
- picture->top_poc = currSlice->toppoc;
- picture->bottom_poc = currSlice->bottompoc;
- picture->frame_poc = currSlice->framepoc;
- picture->poc = currSlice->framepoc;
-
- ret = store_picture_in_dpb(p_H264_Dpb, picture, 0);
- if (ret == -1) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s Error: store_picture_in_dpb failed, break\n",
- __func__);
- release_picture(p_H264_Dpb, picture);
- bufmgr_force_recover(p_H264_Dpb);
- return;
- } else if (ret == -2)
- release_picture(p_H264_Dpb, picture);
-
- picture = NULL;
- p_Vid->pre_frame_num = UnusedShortTermFrameNum;
- UnusedShortTermFrameNum =
- (UnusedShortTermFrameNum + 1) %
- p_Vid->max_frame_num;
- }
- currSlice->delta_pic_order_cnt[0] = tmp1;
- currSlice->delta_pic_order_cnt[1] = tmp2;
- currSlice->frame_num = CurrFrameNum;
-}
-
-void dpb_init_global(struct h264_dpb_stru *p_H264_Dpb,
- int id, int actual_dpb_size, int max_reference_size)
-{
- int i;
-
- init_dummy_fs();
-
- memset(&p_H264_Dpb->mDPB, 0, sizeof(struct DecodedPictureBuffer));
-
- memset(&p_H264_Dpb->mSlice, 0, sizeof(struct Slice));
- memset(&p_H264_Dpb->mVideo, 0, sizeof(struct VideoParameters));
- memset(&p_H264_Dpb->mSPS, 0, sizeof(struct SPSParameters));
-
- for (i = 0; i < DPB_SIZE_MAX; i++) {
- memset(&(p_H264_Dpb->mFrameStore[i]), 0,
- sizeof(struct FrameStore));
- }
-
- for (i = 0; i < MAX_PIC_BUF_NUM; i++) {
- memset(&(p_H264_Dpb->m_PIC[i]), 0,
- sizeof(struct StorablePicture));
- p_H264_Dpb->m_PIC[i].index = i;
- }
- p_H264_Dpb->decoder_index = id;
-
- /* make sure dpb_init_global
- *can be called during decoding
- *(in DECODE_STATE_IDLE or DECODE_STATE_READY state)
- */
- p_H264_Dpb->mDPB.size = actual_dpb_size;
- p_H264_Dpb->max_reference_size = max_reference_size;
- p_H264_Dpb->poc_even_odd_flag = 0;
-}
-
-static void init_picture(struct h264_dpb_stru *p_H264_Dpb,
- struct Slice *currSlice,
- struct StorablePicture *dec_picture)
-{
- /* struct VideoParameters *p_Vid = &(p_H264_Dpb->mVideo); */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s dec_picture %p\n", __func__, dec_picture);
- dec_picture->top_poc = currSlice->toppoc;
- dec_picture->bottom_poc = currSlice->bottompoc;
- dec_picture->frame_poc = currSlice->framepoc;
- switch (currSlice->structure) {
- case TOP_FIELD: {
- dec_picture->poc = currSlice->toppoc;
- /* p_Vid->number *= 2; */
- break;
- }
- case BOTTOM_FIELD: {
- dec_picture->poc = currSlice->bottompoc;
- /* p_Vid->number = p_Vid->number * 2 + 1; */
- break;
- }
- case FRAME: {
- dec_picture->poc = currSlice->framepoc;
- break;
- }
- default:
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "p_Vid->structure not initialized %d\n", 235);
- }
-
- /* dec_picture->slice_type = p_Vid->type; */
- dec_picture->used_for_reference = (currSlice->nal_reference_idc != 0);
- dec_picture->idr_flag = currSlice->idr_flag;
- dec_picture->no_output_of_prior_pics_flag =
- currSlice->no_output_of_prior_pics_flag;
- dec_picture->long_term_reference_flag =
- currSlice->long_term_reference_flag;
-#if 1
- dec_picture->adaptive_ref_pic_buffering_flag =
- currSlice->adaptive_ref_pic_buffering_flag;
- dec_picture->dec_ref_pic_marking_buffer =
- &currSlice->dec_ref_pic_marking_buffer[0];
-#endif
- /* currSlice->dec_ref_pic_marking_buffer = NULL; */
-
- /* dec_picture->mb_aff_frame_flag = currSlice->mb_aff_frame_flag; */
- /* dec_picture->PicWidthInMbs = p_Vid->PicWidthInMbs; */
-
- /* p_Vid->get_mb_block_pos =
- * dec_picture->mb_aff_frame_flag ? get_mb_block_pos_mbaff :
- * get_mb_block_pos_normal;
- */
- /* p_Vid->getNeighbour =
- * dec_picture->mb_aff_frame_flag ? getAffNeighbour :
- * getNonAffNeighbour;
- */
-
- dec_picture->pic_num = currSlice->frame_num;
- dec_picture->frame_num = currSlice->frame_num;
-
- /* dec_picture->recovery_frame =
- * (unsigned int) ((int) currSlice->frame_num ==
- * p_Vid->recovery_frame_num);
- */
-
- dec_picture->coded_frame = (currSlice->structure == FRAME);
-
- /* dec_picture->chroma_format_idc = active_sps->chroma_format_idc; */
-
- /* dec_picture->frame_mbs_only_flag =
- * active_sps->frame_mbs_only_flag;
- */
- /* dec_picture->frame_cropping_flag =
- * active_sps->frame_cropping_flag;
- */
-
- if ((currSlice->picture_structure_mmco & 0x3) == 3) {
- dec_picture->mb_aff_frame_flag = 1;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s, picture_structure_mmco is %x, set mb_aff_frame_flag to 1\n",
- __func__,
- currSlice->picture_structure_mmco);
- }
-
- if (currSlice->pic_struct < PIC_INVALID) {
- dec_picture->pic_struct = currSlice->pic_struct;
- } else {
- dec_picture->pic_struct = PIC_INVALID;
- }
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s pic_struct = %d\n", __func__, dec_picture->pic_struct);
-}
-
-void dump_pic(struct h264_dpb_stru *p_H264_Dpb)
-{
- int ii;
- struct StorablePicture *pic;
- for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) {
- pic = &(p_H264_Dpb->m_PIC[ii]);
- if (pic->is_used) {
- dpb_print(p_H264_Dpb->decoder_index, 0,
- "pic(%d,%d) poc %d is_used %d bufspec %d colbuf %d for_ref %d long_term %d pre_out %d output %d nonexist %d data_flag 0x%x\n",
- ii, pic->index,
- pic->poc,
- pic->is_used,
- pic->buf_spec_num,
- pic->colocated_buf_index,
- pic->used_for_reference,
- pic->is_long_term,
- pic->pre_output,
- pic->is_output,
- pic->non_existing,
- pic->data_flag);
- }
- }
-}
-
-/*
-static void is_pic_used_by_dpb(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *pic)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- unsigned i;
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->top_field == pic ||
- p_Dpb->fs[i]->bottom_field == pic ||
- p_Dpb->fs[i]->frame == pic
- )
- break;
- }
- if (i < p_Dpb->used_size)
- return 1;
- return 0;
-}
-*/
-
-static struct StorablePicture *get_new_pic(struct h264_dpb_stru *p_H264_Dpb,
- enum PictureStructure structure, unsigned char is_output)
-{
- struct StorablePicture *s = NULL;
- struct StorablePicture *pic;
- struct VideoParameters *p_Vid = &(p_H264_Dpb->mVideo);
- /* recycle un-used pic */
- int ii = 0;
-
- for (ii = 0; ii < MAX_PIC_BUF_NUM; ii++) {
- pic = &(p_H264_Dpb->m_PIC[ii]);
- if (pic->is_used == 0) {
- pic->is_used = 1;
- s = pic;
- break;
- }
- }
-
- if (s) {
- s->buf_spec_is_alloced = 0;
- s->pic_num = 0;
- s->frame_num = 0;
- s->long_term_frame_idx = 0;
- s->long_term_pic_num = 0;
- s->used_for_reference = 0;
- s->is_long_term = 0;
- s->non_existing = 0;
- s->is_output = 0;
- s->pre_output = 0;
- s->max_slice_id = 0;
- s->data_flag &= ~(ERROR_FLAG | NODISP_FLAG);
-#if (MVC_EXTENSION_ENABLE)
- s->view_id = -1;
-#endif
-
- s->structure = structure;
-
-#if 0
- s->size_x = size_x;
- s->size_y = size_y;
- s->size_x_cr = size_x_cr;
- s->size_y_cr = size_y_cr;
- s->size_x_m1 = size_x - 1;
- s->size_y_m1 = size_y - 1;
- s->size_x_cr_m1 = size_x_cr - 1;
- s->size_y_cr_m1 = size_y_cr - 1;
-
- s->top_field = p_Vid->no_reference_picture;
- s->bottom_field = p_Vid->no_reference_picture;
- s->frame = p_Vid->no_reference_picture;
-#endif
- /* s->dec_ref_pic_marking_buffer = NULL; */
-
- s->coded_frame = 0;
- s->mb_aff_frame_flag = 0;
-
- s->top_poc = s->bottom_poc = s->poc = 0;
- s->seiHasTone_mapping = 0;
- s->frame_mbs_only_flag = p_Vid->active_sps->frame_mbs_only_flag;
-
- if (!p_Vid->active_sps->frame_mbs_only_flag &&
- structure != FRAME) {
- int i, j;
-
- for (j = 0; j < MAX_NUM_SLICES; j++) {
- for (i = 0; i < 2; i++) {
- /* s->listX[j][i] =
- *calloc(MAX_LIST_SIZE,
- *sizeof (struct StorablePicture *));
- *+1 for reordering ???
-
- *if (NULL == s->listX[j][i])
- *no_mem_exit("alloc_storable_picture:
- *s->listX[i]");
- */
- }
- }
- }
- } else
- p_H264_Dpb->buf_alloc_fail = 1;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s %p\n", __func__, s);
- return s;
-}
-
-static void free_picture(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *pic)
-{
- if (pic == NULL || pic->index < 0 ||
- pic->index >= MAX_PIC_BUF_NUM)
- return;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s %p %d\n", __func__, pic, pic->index);
- /* assert(pic->index<MAX_PIC_BUF_NUM); */
- p_H264_Dpb->m_PIC[pic->index].is_used = 0;
-}
-
-static void gen_field_ref_ids(struct VideoParameters *p_Vid,
- struct StorablePicture *p)
-{
- int i, j;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid,
- struct h264_dpb_stru, mVideo);
- /* ! Generate Frame parameters from field information. */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- /* copy the list; */
- for (j = 0; j < p_Vid->iSliceNumOfCurrPic; j++) {
- if (p->listX[j][LIST_0]) {
- p->listXsize[j][LIST_0] =
- p_Vid->ppSliceList[j]->listXsize[LIST_0];
- for (i = 0; i < p->listXsize[j][LIST_0]; i++)
- p->listX[j][LIST_0][i] =
- p_Vid->ppSliceList[j]->listX[LIST_0][i];
- }
- if (p->listX[j][LIST_1]) {
- p->listXsize[j][LIST_1] =
- p_Vid->ppSliceList[j]->listXsize[LIST_1];
- for (i = 0; i < p->listXsize[j][LIST_1]; i++)
- p->listX[j][LIST_1][i] =
- p_Vid->ppSliceList[j]->listX[LIST_1][i];
- }
- }
-}
-
-static void init_dpb(struct h264_dpb_stru *p_H264_Dpb, int type)
-{
- unsigned int i;
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- struct SPSParameters *active_sps = &p_H264_Dpb->mSPS;
-
- p_Vid->active_sps = active_sps;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- p_Dpb->p_Vid = p_Vid;
- if (p_Dpb->init_done) {
- /* free_dpb(p_Dpb); */
- if (p_Vid->no_reference_picture) {
- free_picture(p_H264_Dpb, p_Vid->no_reference_picture);
- p_Vid->no_reference_picture = NULL;
- }
- p_Dpb->init_done = 0;
- }
-
- /* p_Dpb->size = 10; //active_sps->max_dpb_size; //16;
- * getDpbSize(p_Vid, active_sps) +
- * p_Vid->p_Inp->dpb_plus[type==2? 1: 0];
- * p_Dpb->size = active_sps->max_dpb_size; //16;
- * getDpbSize(p_Vid, active_sps) +
- * p_Vid->p_Inp->dpb_plus[type==2? 1: 0];
- * p_Dpb->size initialzie in vh264.c
- */
- p_Dpb->num_ref_frames = active_sps->num_ref_frames;
- /* p_Dpb->num_ref_frames initialzie in vh264.c */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s dpb_size is %d num_ref_frames = %d (%d)\n",
- __func__, p_Dpb->size,
- p_Dpb->num_ref_frames,
- active_sps->num_ref_frames);
- if (active_sps->num_ref_frames == 0xffff) {
- dpb_print(p_H264_Dpb->decoder_index, 0,
- "!!!Warning, num_ref_frames = %d is invalid\n",
- active_sps->num_ref_frames);
- }
-
-#if 0
- /* ??? */
-#if (MVC_EXTENSION_ENABLE)
- if ((unsigned int)active_sps->max_dec_frame_buffering <
- active_sps->num_ref_frames) {
-#else
- if (p_Dpb->size < active_sps->num_ref_frames) {
-#endif
- error(
- "DPB size at specified level is smaller than the specified number of reference frames. This is not allowed.\n",
- 1000);
- }
-#endif
-
- p_Dpb->used_size = 0;
- p_Dpb->last_picture = NULL;
-
- p_Dpb->ref_frames_in_buffer = 0;
- p_Dpb->ltref_frames_in_buffer = 0;
-
-#if 0
- p_Dpb->fs = calloc(p_Dpb->size, sizeof(struct FrameStore *));
- if (NULL == p_Dpb->fs)
- no_mem_exit("init_dpb: p_Dpb->fs");
-
- p_Dpb->fs_ref = calloc(p_Dpb->size, sizeof(struct FrameStore *));
- if (NULL == p_Dpb->fs_ref)
- no_mem_exit("init_dpb: p_Dpb->fs_ref");
-
- p_Dpb->fs_ltref = calloc(p_Dpb->size, sizeof(struct FrameStore *));
- if (NULL == p_Dpb->fs_ltref)
- no_mem_exit("init_dpb: p_Dpb->fs_ltref");
-#endif
-
-#if (MVC_EXTENSION_ENABLE)
- p_Dpb->fs_ilref = calloc(1, sizeof(struct FrameStore *));
- if (NULL == p_Dpb->fs_ilref)
- no_mem_exit("init_dpb: p_Dpb->fs_ilref");
-#endif
-
- for (i = 0; i < p_Dpb->size; i++) {
- p_Dpb->fs[i] = &(p_H264_Dpb->mFrameStore[i]);
- /* alloc_frame_store(); */
- p_Dpb->fs[i]->index = i;
- p_Dpb->fs_ref[i] = NULL;
- p_Dpb->fs_ltref[i] = NULL;
- p_Dpb->fs[i]->layer_id = 0; /* MVC_INIT_VIEW_ID; */
-#if (MVC_EXTENSION_ENABLE)
- p_Dpb->fs[i]->view_id = MVC_INIT_VIEW_ID;
- p_Dpb->fs[i]->inter_view_flag[0] =
- p_Dpb->fs[i]->inter_view_flag[1] = 0;
- p_Dpb->fs[i]->anchor_pic_flag[0] =
- p_Dpb->fs[i]->anchor_pic_flag[1] = 0;
-#endif
- }
-#if (MVC_EXTENSION_ENABLE)
- if (type == 2) {
- p_Dpb->fs_ilref[0] = alloc_frame_store();
- /* These may need some cleanups */
- p_Dpb->fs_ilref[0]->view_id = MVC_INIT_VIEW_ID;
- p_Dpb->fs_ilref[0]->inter_view_flag[0] =
- p_Dpb->fs_ilref[0]->inter_view_flag[1] = 0;
- p_Dpb->fs_ilref[0]->anchor_pic_flag[0] =
- p_Dpb->fs_ilref[0]->anchor_pic_flag[1] = 0;
- /* given that this is in a different buffer,
- * do we even need proc_flag anymore?
- */
- } else
- p_Dpb->fs_ilref[0] = NULL;
-#endif
-
- /*
- *for (i = 0; i < 6; i++)
- *{
- *currSlice->listX[i] =
- * calloc(MAX_LIST_SIZE, sizeof (struct StorablePicture *));
- * +1 for reordering
- *if (NULL == currSlice->listX[i])
- *no_mem_exit("init_dpb: currSlice->listX[i]");
- *}
- */
- /* allocate a dummy storable picture */
- if (!p_Vid->no_reference_picture) {
- p_Vid->no_reference_picture = get_new_pic(p_H264_Dpb,
- FRAME,
- /*p_Vid->width, p_Vid->height,
- *p_Vid->width_cr, p_Vid->height_cr,
- */
- 1);
- p_Vid->no_reference_picture->top_field =
- p_Vid->no_reference_picture;
- p_Vid->no_reference_picture->bottom_field =
- p_Vid->no_reference_picture;
- p_Vid->no_reference_picture->frame =
- p_Vid->no_reference_picture;
- }
- p_Dpb->last_output_poc = INT_MIN;
-
-#if (MVC_EXTENSION_ENABLE)
- p_Dpb->last_output_view_id = -1;
-#endif
-
- p_Vid->last_has_mmco_5 = 0;
-
- init_colocate_buf(p_H264_Dpb, p_H264_Dpb->max_reference_size);
-
- p_Dpb->init_done = 1;
-
-#if 0
-/* ??? */
- /* picture error concealment */
- if (p_Vid->conceal_mode != 0 && !p_Vid->last_out_fs)
- p_Vid->last_out_fs = alloc_frame_store();
-#endif
-}
-
-static void dpb_split_field(struct h264_dpb_stru *p_H264_Dpb,
- struct FrameStore *fs)
-{
- struct StorablePicture *fs_top = NULL, *fs_btm = NULL;
- struct StorablePicture *frame = fs->frame;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s %p %p\n", __func__, fs, frame);
-
- fs->poc = frame->poc;
-
- if (!frame->frame_mbs_only_flag) {
- fs_top = fs->top_field = get_new_pic(p_H264_Dpb,
- TOP_FIELD,
- /* frame->size_x, frame->size_y,
- *frame->size_x_cr, frame->size_y_cr,
- */
- 1);
- fs_btm = fs->bottom_field = get_new_pic(p_H264_Dpb,
- BOTTOM_FIELD,
- /*frame->size_x, frame->size_y,
- *frame->size_x_cr, frame->size_y_cr,
- */
- 1);
- if (fs_top == NULL || fs_btm == NULL)
- return;
-#if 1
-/* rain */
- fs_top->buf_spec_num = frame->buf_spec_num;
- fs_btm->buf_spec_num = frame->buf_spec_num;
-
- fs_top->colocated_buf_index = frame->colocated_buf_index;
- fs_btm->colocated_buf_index = frame->colocated_buf_index;
-
- fs_top->data_flag = frame->data_flag;
- fs_btm->data_flag = frame->data_flag;
-#endif
- fs_top->poc = frame->top_poc;
- fs_btm->poc = frame->bottom_poc;
-
-#if (MVC_EXTENSION_ENABLE)
- fs_top->view_id = frame->view_id;
- fs_btm->view_id = frame->view_id;
-#endif
-
- fs_top->frame_poc = frame->frame_poc;
-
- fs_top->bottom_poc = fs_btm->bottom_poc = frame->bottom_poc;
- fs_top->top_poc = fs_btm->top_poc = frame->top_poc;
- fs_btm->frame_poc = frame->frame_poc;
-
- fs_top->used_for_reference = fs_btm->used_for_reference
- = frame->used_for_reference;
- fs_top->is_long_term = fs_btm->is_long_term
- = frame->is_long_term;
- fs->long_term_frame_idx = fs_top->long_term_frame_idx
- = fs_btm->long_term_frame_idx
- = frame->long_term_frame_idx;
-
- fs_top->coded_frame = fs_btm->coded_frame = 1;
- fs_top->mb_aff_frame_flag = fs_btm->mb_aff_frame_flag
- = frame->mb_aff_frame_flag;
-
- frame->top_field = fs_top;
- frame->bottom_field = fs_btm;
- frame->frame = frame;
- fs_top->bottom_field = fs_btm;
- fs_top->frame = frame;
- fs_top->top_field = fs_top;
- fs_btm->top_field = fs_top;
- fs_btm->frame = frame;
- fs_btm->bottom_field = fs_btm;
-
-#if (MVC_EXTENSION_ENABLE)
- fs_top->view_id = fs_btm->view_id = fs->view_id;
- fs_top->inter_view_flag = fs->inter_view_flag[0];
- fs_btm->inter_view_flag = fs->inter_view_flag[1];
-#endif
-
- fs_top->chroma_format_idc = fs_btm->chroma_format_idc =
- frame->chroma_format_idc;
- fs_top->iCodingType = fs_btm->iCodingType = frame->iCodingType;
- } else {
- fs->top_field = NULL;
- fs->bottom_field = NULL;
- frame->top_field = NULL;
- frame->bottom_field = NULL;
- frame->frame = frame;
- }
-
-}
-
-
-static void dpb_combine_field(struct h264_dpb_stru *p_H264_Dpb,
- struct FrameStore *fs)
-{
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- if (!fs->frame) {
- fs->frame = get_new_pic(p_H264_Dpb,
- FRAME,
- /* fs->top_field->size_x, fs->top_field->size_y*2,
- *fs->top_field->size_x_cr, fs->top_field->size_y_cr*2,
- */
- 1);
- }
- if (!fs->frame)
- return;
-#if 1
-/* rain */
- fs->frame->buf_spec_num = fs->top_field->buf_spec_num;
- fs->frame->colocated_buf_index = fs->top_field->colocated_buf_index;
- fs->frame->data_flag = fs->top_field->data_flag;
- fs->frame->slice_type = fs->top_field->slice_type;
- if (fs->bottom_field)
- fs->frame->data_flag |= (fs->bottom_field->data_flag & 0xf0);
-#endif
-
- if (fs->bottom_field) {
- fs->poc = fs->frame->poc = fs->frame->frame_poc = imin(
- fs->top_field->poc, fs->bottom_field->poc);
-
- fs->bottom_field->frame_poc = fs->top_field->frame_poc = fs->frame->poc;
-
- fs->bottom_field->top_poc = fs->frame->top_poc = fs->top_field->poc;
- fs->top_field->bottom_poc = fs->frame->bottom_poc =
- fs->bottom_field->poc;
-
- fs->frame->used_for_reference = (fs->top_field->used_for_reference &&
- fs->bottom_field->used_for_reference);
- fs->frame->is_long_term = (fs->top_field->is_long_term &&
- fs->bottom_field->is_long_term);
- }
-
- if (fs->frame->is_long_term)
- fs->frame->long_term_frame_idx = fs->long_term_frame_idx;
-
- fs->frame->top_field = fs->top_field;
- if (fs->bottom_field)
- fs->frame->bottom_field = fs->bottom_field;
- fs->frame->frame = fs->frame;
-
- fs->frame->coded_frame = 0;
-
- fs->frame->chroma_format_idc = fs->top_field->chroma_format_idc;
- fs->frame->frame_cropping_flag = fs->top_field->frame_cropping_flag;
- if (fs->frame->frame_cropping_flag) {
- fs->frame->frame_crop_top_offset =
- fs->top_field->frame_crop_top_offset;
- fs->frame->frame_crop_bottom_offset =
- fs->top_field->frame_crop_bottom_offset;
- fs->frame->frame_crop_left_offset =
- fs->top_field->frame_crop_left_offset;
- fs->frame->frame_crop_right_offset =
- fs->top_field->frame_crop_right_offset;
- }
- if (fs->bottom_field) {
- fs->top_field->frame = fs->bottom_field->frame = fs->frame;
- fs->top_field->top_field = fs->top_field;
- fs->top_field->bottom_field = fs->bottom_field;
- fs->bottom_field->top_field = fs->top_field;
- fs->bottom_field->bottom_field = fs->bottom_field;
- }
-
- /**/
-#if (MVC_EXTENSION_ENABLE)
- fs->frame->view_id = fs->view_id;
-#endif
- fs->frame->iCodingType = fs->top_field->iCodingType;
- if (fs->bottom_field && fs->top_field->poc < fs->bottom_field->poc) {
- fs->pts = fs->top_field->pts;
- fs->pts64 = fs->top_field->pts64;
- /*SWPL-7105 fix */
- if ((fs->frame->slice_type == B_SLICE)
- && (!fs->bottom_field->pts) &&(!fs->bottom_field->pts64)) {
- fs->pts = 0;
- fs->pts64 = 0;
- }
- fs->offset_delimiter = fs->top_field->offset_delimiter;
- fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size;
- } else if (fs->bottom_field) {
- fs->pts = fs->bottom_field->pts;
- fs->pts64 = fs->bottom_field->pts64;
- fs->offset_delimiter = fs->bottom_field->offset_delimiter;
- fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size;
- }
- /* FIELD_CODING ;*/
-}
-
-static void calculate_frame_no(struct VideoParameters *p_Vid,
- struct StorablePicture *p)
-{
-#if 0
-/* ??? */
- InputParameters *p_Inp = p_Vid->p_Inp;
- /* calculate frame number */
- int psnrPOC = p_Vid->active_sps->mb_adaptive_frame_field_flag ?
- p->poc / (p_Inp->poc_scale) : p->poc / (p_Inp->poc_scale);
-
- if (psnrPOC == 0) { /* && p_Vid->psnr_number) */
- p_Vid->idr_psnr_number =
- p_Vid->g_nFrame * p_Vid->ref_poc_gap / (p_Inp->poc_scale);
- }
- p_Vid->psnr_number = imax(p_Vid->psnr_number,
- p_Vid->idr_psnr_number + psnrPOC);
-
- p_Vid->frame_no = p_Vid->idr_psnr_number + psnrPOC;
-#endif
-}
-
-static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
- struct FrameStore *fs,
- struct StorablePicture *p,
- unsigned char data_flag)
-{
- struct vdec_frames_s *mvfrm = p_H264_Dpb->vdec->mvfrm;
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
- /* InputParameters *p_Inp = p_Vid->p_Inp;
- * dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- * "insert (%s) pic with frame_num #%d, poc %d\n",
- * (p->structure == FRAME)?"FRAME":
- * (p->structure == TOP_FIELD)?"TOP_FIELD":
- * "BOTTOM_FIELD", p->pic_num, p->poc);
- * assert (p!=NULL);
- * assert (fs!=NULL);
- */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s %p %p\n", __func__, fs, p);
- p_H264_Dpb->dpb_frame_count++;
- fs->dpb_frame_count = p_H264_Dpb->dpb_frame_count;
-#if 1
-/* rain */
-/* p->buf_spec_num = fs->index; */
- p->data_flag = data_flag;
- fs->data_flag |= data_flag;
- fs->buf_spec_num = p->buf_spec_num;
- fs->colocated_buf_index = p->colocated_buf_index;
-#endif
- p->slice_type = p_H264_Dpb->mSlice.slice_type;
- switch (p->structure) {
- case FRAME:
- fs->frame = p;
- fs->is_used = 3;
- fs->slice_type = p->slice_type;
- fs->frame_size = p->frame_size;
- fs->offset_delimiter = p->offset_delimiter;
- fs->decoded_frame_size = p->pic_size;
- if (p->used_for_reference) {
- fs->is_reference = 3;
- fs->is_orig_reference = 3;
- if (p->is_long_term) {
- fs->is_long_term = 3;
- fs->long_term_frame_idx =
- p->long_term_frame_idx;
- }
- }
- fs->pts = p->pts;
- fs->pts64 = p->pts64;
- fs->layer_id = p->layer_id;
-#if (MVC_EXTENSION_ENABLE)
- fs->view_id = p->view_id;
- fs->inter_view_flag[0] = fs->inter_view_flag[1] =
- p->inter_view_flag;
- fs->anchor_pic_flag[0] = fs->anchor_pic_flag[1] =
- p->anchor_pic_flag;
-#endif
- /* generate field views */
- /* return; */
- dpb_split_field(p_H264_Dpb, fs);
- /* return; */
- break;
- case TOP_FIELD:
- fs->top_field = p;
- fs->is_used |= 1;
- fs->layer_id = p->layer_id;
- if (fs->frame_size == 0) {
- fs->slice_type = p->slice_type;
-// fs->pts = p->pts;
-// fs->pts64 = p->pts64;
- }
- fs->frame_size += p->frame_size;
-#if (MVC_EXTENSION_ENABLE)
- fs->view_id = p->view_id;
- fs->inter_view_flag[0] = p->inter_view_flag;
- fs->anchor_pic_flag[0] = p->anchor_pic_flag;
-#endif
- if (p->used_for_reference) {
- fs->is_reference |= 1;
- fs->is_orig_reference |= 1;
- if (p->is_long_term) {
- fs->is_long_term |= 1;
- fs->long_term_frame_idx =
- p->long_term_frame_idx;
- }
- }
- if (fs->is_used == 3) {
- /* generate frame view */
- dpb_combine_field(p_H264_Dpb, fs);
- } else {
- fs->poc = p->poc;
- }
- gen_field_ref_ids(p_Vid, p);
- break;
- case BOTTOM_FIELD:
- fs->bottom_field = p;
- fs->is_used |= 2;
- fs->layer_id = p->layer_id;
- if (fs->frame_size == 0) {
- fs->slice_type = p->slice_type;
-// fs->pts = p->pts;
-// fs->pts64 = p->pts64;
- }
- fs->frame_size += p->frame_size;
-#if (MVC_EXTENSION_ENABLE)
- fs->view_id = p->view_id;
- fs->inter_view_flag[1] = p->inter_view_flag;
- fs->anchor_pic_flag[1] = p->anchor_pic_flag;
-#endif
- if (p->used_for_reference) {
- fs->is_reference |= 2;
- fs->is_orig_reference |= 2;
- if (p->is_long_term) {
- fs->is_long_term |= 2;
- fs->long_term_frame_idx =
- p->long_term_frame_idx;
- }
- }
- if (fs->is_used == 3) {
- /* generate frame view */
- dpb_combine_field(p_H264_Dpb, fs);
- } else {
- fs->poc = p->poc;
- }
- gen_field_ref_ids(p_Vid, p);
- break;
- }
- fs->frame_num = p->pic_num;
- fs->recovery_frame = p->recovery_frame;
-
- fs->is_output = p->is_output;
- fs->pre_output = p->pre_output;
-
- /* picture qos infomation*/
- fs->max_mv = p->max_mv;
- fs->avg_mv = p->avg_mv;
- fs->min_mv = p->min_mv;
-
- fs->max_qp = p->max_qp;
- fs->avg_qp = p->avg_qp;
- fs->min_qp = p->min_qp;
-
- fs->max_skip = p->max_skip;
- fs->avg_skip = p->avg_skip;
- fs->min_skip = p->min_skip;
-
- if (fs->is_used == 3) {
- calculate_frame_no(p_Vid, p);
-#if 0
-/* ??? */
- if (-1 != p_Vid->p_ref && !p_Inp->silent)
- find_snr(p_Vid, fs->frame, &p_Vid->p_ref);
-#endif
- //fs->pts = p->pts;
- //fs->pts64 = p->pts64;
- }
- if ((fs->frame != NULL) &&
- ((fs->bottom_field != NULL) || (fs->top_field != NULL))) {
- fs->last_field_timestamp = fs->timestamp;
- fs->timestamp = p->timestamp;
- } else {
- fs->timestamp = p->timestamp;
- }
- if (mvfrm) {
- fs->frame_size2 = mvfrm->frame_size;
- fs->hw_decode_time = mvfrm->hw_decode_time;
- }
-}
-
-void reset_frame_store(struct h264_dpb_stru *p_H264_Dpb,
- struct FrameStore *f)
-{
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- if (f) {
- if (f->frame) {
- free_picture(p_H264_Dpb, f->frame);
- f->frame = NULL;
- }
- if (f->top_field) {
- free_picture(p_H264_Dpb, f->top_field);
- f->top_field = NULL;
- }
- if (f->bottom_field) {
- free_picture(p_H264_Dpb, f->bottom_field);
- f->bottom_field = NULL;
- }
-
- /**/
- f->is_used = 0;
- f->is_reference = 0;
- f->is_long_term = 0;
- f->is_orig_reference = 0;
-
- f->is_output = 0;
- f->pre_output = 0;
- f->show_frame = false;
-
- f->frame = NULL;
- f->top_field = NULL;
- f->bottom_field = NULL;
-
- /* free(f); */
- }
-}
-
-void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb,
- struct FrameStore *fs)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s %p %p %p %p\n", __func__,
- fs, fs->frame, fs->top_field, fs->bottom_field);
- /* return; */
- if (fs->is_used & 1) {
- if (fs->top_field)
- fs->top_field->used_for_reference = 0;
- }
- if (fs->is_used & 2) {
- if (fs->bottom_field)
- fs->bottom_field->used_for_reference = 0;
- }
- if (fs->is_used == 3) {
- if (fs->top_field && fs->bottom_field) {
- fs->top_field->used_for_reference = 0;
- fs->bottom_field->used_for_reference = 0;
- }
- fs->frame->used_for_reference = 0;
- }
-
- fs->is_reference = 0;
-
-}
-
-static void unmark_for_long_term_reference(struct FrameStore *fs)
-{
- if (fs->is_used & 1) {
- if (fs->top_field) {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- }
- }
- if (fs->is_used & 2) {
- if (fs->bottom_field) {
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- }
- if (fs->is_used == 3) {
- if (fs->top_field && fs->bottom_field) {
- fs->top_field->used_for_reference = 0;
- fs->top_field->is_long_term = 0;
- fs->bottom_field->used_for_reference = 0;
- fs->bottom_field->is_long_term = 0;
- }
- fs->frame->used_for_reference = 0;
- fs->frame->is_long_term = 0;
- }
-
- fs->is_reference = 0;
- fs->is_long_term = 0;
-}
-
-int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb,
- int buf_spec_num)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- unsigned int i;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->buf_spec_num == buf_spec_num)
- return p_Dpb->fs[i]->is_long_term;
- }
- return -1;
-}
-
-static void update_pic_num(struct h264_dpb_stru *p_H264_Dpb)
-{
- unsigned int i;
- struct Slice *currSlice = &p_H264_Dpb->mSlice;
- struct VideoParameters *p_Vid = currSlice->p_Vid;
- struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
- struct SPSParameters *active_sps = p_Vid->active_sps;
- int add_top = 0, add_bottom = 0;
- int max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
-
- if (currSlice->structure == FRAME) {
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL ||
- p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_used == 3) {
- if ((p_Dpb->fs_ref[i]->frame->
- used_for_reference) &&
- (!p_Dpb->fs_ref[i]->frame->
- is_long_term)) {
- if (p_Dpb->fs_ref[i]->frame_num >
- currSlice->frame_num) {
- p_Dpb->fs_ref[i]->
- frame_num_wrap =
- p_Dpb->fs_ref[i]->frame_num
- - max_frame_num;
- } else {
- p_Dpb->fs_ref[i]->
- frame_num_wrap =
- p_Dpb->fs_ref[i]->frame_num;
- }
- p_Dpb->fs_ref[i]->frame->pic_num =
- p_Dpb->fs_ref[i]->frame_num_wrap;
- }
- }
- }
- /* update long_term_pic_num */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ltref[i] == NULL ||
- p_Dpb->fs_ltref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ltref[i]->is_used == 3) {
- if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
- p_Dpb->fs_ltref[i]->frame->
- long_term_pic_num =
- p_Dpb->fs_ltref[i]->frame->
- long_term_frame_idx;
- }
- }
- }
- } else {
- if (currSlice->structure == TOP_FIELD) {
- add_top = 1;
- add_bottom = 0;
- } else {
- add_top = 0;
- add_bottom = 1;
- }
-
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference) {
- if (p_Dpb->fs_ref[i]->frame_num > currSlice->
- frame_num) {
- p_Dpb->fs_ref[i]->frame_num_wrap =
- p_Dpb->fs_ref[i]->frame_num -
- max_frame_num;
- } else {
- p_Dpb->fs_ref[i]->frame_num_wrap =
- p_Dpb->fs_ref[i]->frame_num;
- }
- if (p_Dpb->fs_ref[i]->is_reference & 1) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->top_field
- == NULL) {
- p_H264_Dpb->dpb_error_flag =
- __LINE__;
- continue;
- }
-#endif
- p_Dpb->fs_ref[i]->top_field->
- pic_num = (2 * p_Dpb->fs_ref[i]->
- frame_num_wrap) + add_top;
- }
- if (p_Dpb->fs_ref[i]->is_reference & 2) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->bottom_field
- == NULL) {
- p_H264_Dpb->dpb_error_flag =
- __LINE__;
- continue;
- }
-#endif
- p_Dpb->fs_ref[i]->bottom_field->
- pic_num = (2 * p_Dpb->fs_ref[i]->
- frame_num_wrap) + add_bottom;
- }
- }
- }
- /* update long_term_pic_num */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ltref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ltref[i]->is_long_term & 1) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ltref[i]->top_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- p_Dpb->fs_ltref[i]->top_field->
- long_term_pic_num = 2 *
- p_Dpb->fs_ltref[i]->top_field->
- long_term_frame_idx + add_top;
- }
- if (p_Dpb->fs_ltref[i]->is_long_term & 2) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ltref[i]->bottom_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- p_Dpb->fs_ltref[i]->bottom_field->
- long_term_pic_num = 2 *
- p_Dpb->fs_ltref[i]->bottom_field->
- long_term_frame_idx + add_bottom;
- }
- }
- }
-}
-
-static void remove_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb, int pos)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- struct FrameStore *fs = p_Dpb->fs[pos];
- struct FrameStore *tmp;
- unsigned int i;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s pos %d %p\n", __func__, pos, fs);
-
- /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- * "remove frame with frame_num #%d\n", fs->frame_num);
- */
- switch (fs->is_used) {
- case 3:
- free_picture(p_H264_Dpb, fs->frame);
- free_picture(p_H264_Dpb, fs->top_field);
- free_picture(p_H264_Dpb, fs->bottom_field);
- fs->frame = NULL;
- fs->top_field = NULL;
- fs->bottom_field = NULL;
- break;
- case 2:
- free_picture(p_H264_Dpb, fs->bottom_field);
- fs->bottom_field = NULL;
- break;
- case 1:
- free_picture(p_H264_Dpb, fs->top_field);
- fs->top_field = NULL;
- break;
- case 0:
- break;
- default:
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "invalid frame store type %x", 500);
- }
- fs->data_flag = 0;
- fs->is_used = 0;
- fs->is_long_term = 0;
- fs->is_reference = 0;
- fs->is_orig_reference = 0;
- fs->frame_size = 0;
- /* move empty framestore to end of buffer */
- tmp = p_Dpb->fs[pos];
-
- for (i = pos; i < p_Dpb->used_size - 1; i++)
- p_Dpb->fs[i] = p_Dpb->fs[i + 1];
- p_Dpb->fs[p_Dpb->used_size - 1] = tmp;
-
- if (p_Dpb->used_size)
- p_Dpb->used_size--;
-}
-
-int is_used_for_reference(struct FrameStore *fs)
-{
- if (fs->is_reference)
- return 1;
-
- if (fs->is_used == 3) { /* frame */
- if (fs->frame->used_for_reference)
- return 1;
- }
-
- if (fs->is_used & 1) { /* top field */
- if (fs->top_field) {
- if (fs->top_field->used_for_reference)
- return 1;
- }
- }
-
- if (fs->is_used & 2) { /* bottom field */
- if (fs->bottom_field) {
- if (fs->bottom_field->used_for_reference)
- return 1;
- }
- }
- return 0;
-}
-
-static int remove_unused_frame_from_dpb(struct h264_dpb_stru *p_H264_Dpb)
-{
- unsigned int i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- /* check for frames that were already output and no longer
- * used for reference
- */
- for (i = 0; i < p_Dpb->used_size; i++) {
- if ((!is_used_for_reference(p_Dpb->fs[i])) &&
- (p_Dpb->fs[i]->colocated_buf_index >= 0)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "release_colocate_buf[%d] for fs[%d]\n",
- p_Dpb->fs[i]->colocated_buf_index, i);
-
- release_colocate_buf(p_H264_Dpb,
- p_Dpb->fs[i]->colocated_buf_index); /* rain */
- p_Dpb->fs[i]->colocated_buf_index = -1;
- }
- }
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->is_output &&
- (!is_used_for_reference(p_Dpb->fs[i]))) {
- release_buf_spec_num(p_H264_Dpb->vdec,
- p_Dpb->fs[i]->buf_spec_num);
- p_Dpb->fs[i]->buf_spec_num = -1;
- remove_frame_from_dpb(p_H264_Dpb, i);
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%s[%d]\n",
- __func__, i);
-
- return 1;
- }
- }
- return 0;
-}
-
-static int unmark_one_error_out_frame(struct h264_dpb_stru *p_H264_Dpb)
-{
- int ret = 0;
- unsigned i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->is_output &&
- ((p_Dpb->fs[i]->data_flag & ERROR_FLAG) ||
- (p_Dpb->fs[i]->data_flag & NULL_FLAG))
- ) {
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
-
- ret = 1;
- break;
- }
- }
- return ret;
-}
-
-static int unmark_one_out_frame(struct h264_dpb_stru *p_H264_Dpb)
-{
- int ret = 0;
- unsigned i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->is_output) {
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
-
- ret = 1;
- }
- }
- return ret;
-}
-/*
- force_flag,
- 1, remove one error buf (is_out is 1) if there is no un-used buf
- 2, remove one buf (is_out is 1) if there is no un-used buf
-*/
-void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb,
- u8 force_flag)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- int ret = 0;
- unsigned char removed_flag = 0;
- do {
- ret = remove_unused_frame_from_dpb(p_H264_Dpb);
- if (ret != 0)
- removed_flag = 1;
- } while (ret != 0);
- if (removed_flag) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%s\r\n", __func__);
- dump_dpb(p_Dpb, 0);
- } else if (force_flag == 2) {
- if (unmark_one_out_frame(p_H264_Dpb)) {
- dpb_print(p_H264_Dpb->decoder_index,
- 0, "%s, Warnning, force unmark one frame\r\n",
- __func__);
- update_ref_list(p_Dpb);
- remove_unused_frame_from_dpb(p_H264_Dpb);
- dump_dpb(p_Dpb, 0);
- }
- } else if (force_flag == 1) {
- if (unmark_one_error_out_frame(p_H264_Dpb)) {
- dpb_print(p_H264_Dpb->decoder_index,
- 0, "%s, unmark error frame\r\n",
- __func__);
- update_ref_list(p_Dpb);
- remove_unused_frame_from_dpb(p_H264_Dpb);
- dump_dpb(p_Dpb, 0);
- }
- }
-}
-
-#ifdef OUTPUT_BUFFER_IN_C
-int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb)
-{
- unsigned int i;
-
- /* check for frames that were already output and no longer
- * used for reference
- */
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->is_output &&
- (!is_used_for_reference(p_Dpb->fs[i]))) {
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc,
- int *pos)
-{
- unsigned int i;
- unsigned long flags;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- struct vdec_s *vdec= (struct vdec_s *)p_H264_Dpb->vdec;
- void *p = vh264_get_bufspec_lock(vdec);
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%s\n", __func__);
- if (p_Dpb->used_size < 1) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "Cannot determine smallest POC, DPB empty. %d\n",
- 150);
- }
-
- *pos = -1;
- *poc = INT_MAX;
- if (p == NULL)
- return;
- spin_lock_irqsave(p, flags);
- for (i = 0; i < p_Dpb->used_size; i++) {
-#ifdef OUTPUT_BUFFER_IN_C
- /* rain */
- if ((*poc > p_Dpb->fs[i]->poc) &&
- (!p_Dpb->fs[i]->is_output) &&
- (!p_Dpb->fs[i]->pre_output)) {
-#else
- if ((*poc > p_Dpb->fs[i]->poc) && (!p_Dpb->fs[i]->is_output)) {
-#endif
- *poc = p_Dpb->fs[i]->poc;
- *pos = i;
- }
- }
- spin_unlock_irqrestore(p, flags);
-}
-
-int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
-{
- int poc, pos;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- int i;
- int none_displayed_num = 0;
- unsigned char fast_output_flag = 0;
-
- /*
- * When the sei data(dv data) after the PIC done and no flush,
- * it is necessary to output a frame of data until
- * the number of frames not displayed is greater than the reorder.
- */
- if ((p_H264_Dpb->wait_aux_data_flag) && (!flush_flag)) {
- int no_output_num = 0;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if ((!p_Dpb->fs[i]->is_output) &&
- (!p_Dpb->fs[i]->pre_output) &&
- ((p_Dpb->fs[i]->is_used == 3) ||
- (p_Dpb->fs[i]->data_flag & ERROR_FLAG)))
- no_output_num++;
- }
-
- if (no_output_num <= p_H264_Dpb->reorder_output)
- return 0;
- }
-
- if (!flush_flag) {
- for (i = 0; i < p_Dpb->used_size; i++) {
- if ((!p_Dpb->fs[i]->is_output) &&
- (!p_Dpb->fs[i]->pre_output) &&((p_Dpb->fs[i]->is_used == 3
- ||p_Dpb->fs[i]->data_flag & ERROR_FLAG ))) {
- none_displayed_num++;
- if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE ||
- p_H264_Dpb->first_insert_frame == FirstInsertFrm_RESET)
- && (p_Dpb->fs[i]->is_used == 3)
- && (p_Dpb->last_output_poc == INT_MIN)) {
- if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE)
- fast_output_flag = 1;
- p_H264_Dpb->first_insert_frame = FirstInsertFrm_OUT;
- p_H264_Dpb->first_output_poc = p_Dpb->fs[i]->poc;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s first insert frame i %d poc %d frame_num %x\n",
- __func__, i, p_Dpb->fs[i]->poc, p_Dpb->fs[i]->frame_num);
- }
-
- /*check poc even/odd*/
- if (p_H264_Dpb->poc_even_odd_flag == 0 &&
- p_H264_Dpb->decode_pic_count >= 3)
- p_H264_Dpb->poc_even_odd_flag = 2;
- if (p_Dpb->fs[i]->poc & 0x1)
- p_H264_Dpb->poc_even_odd_flag = 1;
- /**/
-
- if ((p_H264_Dpb->fast_output_enable & 0x1) &&
- (p_Dpb->fs[i]->data_flag & IDR_FLAG))
- fast_output_flag = 1;
- if ((p_H264_Dpb->fast_output_enable & 0x2) &&
- ((p_Dpb->fs[i]->poc -
- p_Dpb->last_output_poc)
- == 1))
- fast_output_flag = 1;
- if ((p_H264_Dpb->fast_output_enable & 0x4) &&
- (p_H264_Dpb->poc_even_odd_flag == 2) &&
- (p_Dpb->fs[i]->is_used == 3) &&
- ((p_Dpb->fs[i]->poc -
- p_Dpb->last_output_poc)
- == 2))
- fast_output_flag = 1;
- }
- }
- if (fast_output_flag)
- ;
- else if (none_displayed_num <
- p_H264_Dpb->reorder_output)
- return 0;
- }
-
- get_smallest_poc(p_Dpb, &poc, &pos);
-
- if (pos == -1)
- return 0;
-#if 0
- if (is_used_for_reference(p_Dpb->fs[pos]))
- return 0;
-#endif
- if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s pos %d pos->poc %d first_output_poc %d \n",
- __func__, pos, p_Dpb->fs[pos]->poc, p_H264_Dpb->first_output_poc);
-
- if (p_Dpb->fs[pos]->poc < p_H264_Dpb->first_output_poc)
- p_Dpb->fs[pos]->data_flag |= NODISP_FLAG;
- else if (p_Dpb->last_output_poc != INT_MIN)
- p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s first_insert_frame %d \n", __func__, p_H264_Dpb->first_insert_frame);
- }
- if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0) {
- if (!p_H264_Dpb->without_display_mode &&
- p_Dpb->fs[pos]->show_frame != false)
- p_Dpb->fs[pos]->pre_output = 1;
- } else {
- if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
- dpb_print(p_H264_Dpb->decoder_index, 0,
- "%s[%d] poc:%d last_output_poc:%d poc_even_odd_flag:%d\n",
- __func__, pos, poc,
- p_Dpb->last_output_poc,
- p_H264_Dpb->poc_even_odd_flag);
- dump_dpb(p_Dpb, 1);
- }
- return 0;
- }
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s[%d] poc %d last_output_poc %d poc_even_odd_flag %d\n",
- __func__, pos, poc,
- p_Dpb->last_output_poc,
- p_H264_Dpb->poc_even_odd_flag);
-
- p_Dpb->last_output_poc = poc;
- return 1;
-
-}
-
-
-void flush_dpb(struct h264_dpb_stru *p_H264_Dpb)
-{
- /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- unsigned int i;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- /* diagnostics */
- /* dpb_print(p_H264_Dpb->decoder_index,
- *PRINT_FLAG_DPB_DETAIL,
- *"Flush remaining frames from the dpb."
- *"p_Dpb->size = %d, p_Dpb->used_size = %d\n",
- *p_Dpb->size, p_Dpb->used_size);
- */
-
- if (!p_Dpb->init_done)
- return;
-/* if(p_Vid->conceal_mode == 0) */
-#if 0
-/* ??? */
- if (p_Vid->conceal_mode != 0)
- conceal_non_ref_pics(p_Dpb, 0);
-#endif
- /* mark all frames unused */
- for (i = 0; i < p_Dpb->used_size; i++) {
-#if MVC_EXTENSION_ENABLE
- assert(p_Dpb->fs[i]->view_id == p_Dpb->layer_id);
-#endif
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
-
- }
-
- while (remove_unused_frame_from_dpb(p_H264_Dpb))
- ;
-
- /* output frames in POC order */
- while (output_frames(p_H264_Dpb, 1))
- ;
-
-
- p_Dpb->last_output_poc = INT_MIN;
-}
-
-static int is_short_term_reference(struct DecodedPictureBuffer *p_Dpb,
- struct FrameStore *fs)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- if (fs->is_used == 3) { /* frame */
- if ((fs->frame->used_for_reference) &&
- (!fs->frame->is_long_term)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "[[%s 1]]",
- __func__);
- return 1;
- }
- }
-
- if (fs->is_used & 1) { /* top field */
- if (fs->top_field) {
- if ((fs->top_field->used_for_reference) &&
- (!fs->top_field->is_long_term)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "[[%s 2]]",
- __func__);
- return 1;
- }
- }
- }
-
- if (fs->is_used & 2) { /* bottom field */
- if (fs->bottom_field) {
- if ((fs->bottom_field->used_for_reference) &&
- (!fs->bottom_field->is_long_term)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "[[%s 3]]",
- __func__);
- return 1;
- }
- }
- }
- return 0;
-}
-
-static int is_long_term_reference(struct FrameStore *fs)
-{
-
- if (fs->is_used == 3) { /* frame */
- if ((fs->frame->used_for_reference) &&
- (fs->frame->is_long_term)) {
- return 1;
- }
- }
-
- if (fs->is_used & 1) { /* top field */
- if (fs->top_field) {
- if ((fs->top_field->used_for_reference) &&
- (fs->top_field->is_long_term)) {
- return 1;
- }
- }
- }
-
- if (fs->is_used & 2) { /* bottom field */
- if (fs->bottom_field) {
- if ((fs->bottom_field->used_for_reference) &&
- (fs->bottom_field->is_long_term)) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-void update_ref_list(struct DecodedPictureBuffer *p_Dpb)
-{
- unsigned int i, j;
-
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s (%d, %d)\n", __func__, p_Dpb->size, p_Dpb->used_size);
- for (i = 0, j = 0; i < p_Dpb->used_size; i++) {
-#if 1
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "fs[%d]: fs %p frame %p is_reference %d %d %d\n",
- i, p_Dpb->fs[i], p_Dpb->fs[i]->frame,
- p_Dpb->fs[i]->frame != NULL ?
- p_Dpb->fs[i]->frame->used_for_reference : 0,
- p_Dpb->fs[i]->top_field != NULL ?
- p_Dpb->fs[i]->top_field->used_for_reference :
- 0,
- p_Dpb->fs[i]->bottom_field != NULL ?
- p_Dpb->fs[i]->bottom_field->used_for_reference : 0);
-#endif
- if (is_short_term_reference(p_Dpb, p_Dpb->fs[i])) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "fs_ref[%d]=fs[%d]: fs %p\n", j, i, p_Dpb->fs[i]);
- p_Dpb->fs_ref[j++] = p_Dpb->fs[i];
- }
- }
-
- p_Dpb->ref_frames_in_buffer = j;
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s dpb size is %d, %d\n", __func__, p_Dpb->size, j);
- while (j < p_Dpb->size) {
- /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- *"fs_ref[%d]=null\n", j);
- */
- p_Dpb->fs_ref[j++] = NULL;
- }
-#ifdef ERROR_CHECK
- for (i = 0; i < DPB_SIZE_MAX; i++) {
- if (p_Dpb->fs_ref[i] == NULL)
- p_Dpb->fs_ref[i] = &dummy_fs;
- }
-#endif
-}
-
-static void update_ltref_list(struct DecodedPictureBuffer *p_Dpb)
-{
- unsigned int i, j;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
- for (i = 0, j = 0; i < p_Dpb->used_size; i++) {
- if (is_long_term_reference(p_Dpb->fs[i]))
- p_Dpb->fs_ltref[j++] = p_Dpb->fs[i];
- }
-
- p_Dpb->ltref_frames_in_buffer = j;
-
- while (j < p_Dpb->size)
- p_Dpb->fs_ltref[j++] = NULL;
-#ifdef ERROR_CHECK
- for (i = 0; i < DPB_SIZE_MAX; i++) {
- if (p_Dpb->fs_ltref[i] == NULL)
- p_Dpb->fs_ltref[i] = &dummy_fs;
- }
-#endif
-}
-
-static void idr_memory_management(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *p)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s ref_frames_in_buffer %d ltref_frames_in_buffer %d\n",
- __func__, p_Dpb->ref_frames_in_buffer,
- p_Dpb->ltref_frames_in_buffer);
-
-
- if (p->no_output_of_prior_pics_flag) {
- int i;
- for (i = 0; i < p_Dpb->used_size; i++) {
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
- if (p_Dpb->fs[i]->is_long_term)
- unmark_for_long_term_reference(p_Dpb->fs[i]);
- if (!p_Dpb->fs[i]->is_output && !p_Dpb->fs[i]->pre_output)
- set_frame_output_flag(p_H264_Dpb, i);
- }
-#if 0
- /*???*/
- /* free all stored pictures */
- int i;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- /* reset all reference settings
- * free_frame_store(p_Dpb->fs[i]);
- * p_Dpb->fs[i] = alloc_frame_store();
- */
- reset_frame_store(p_H264_Dpb, p_Dpb->fs[i]); /* ??? */
- }
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++)
- p_Dpb->fs_ref[i] = NULL;
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++)
- p_Dpb->fs_ltref[i] = NULL;
- p_Dpb->used_size = 0;
-#endif
- } else {
- flush_dpb(p_H264_Dpb);
- }
- p_Dpb->last_picture = NULL;
-
- update_ref_list(p_Dpb);
- update_ltref_list(p_Dpb);
- p_Dpb->last_output_poc = INT_MIN;
-
- if (p->long_term_reference_flag) {
- p_Dpb->max_long_term_pic_idx = 0;
- p->is_long_term = 1;
- p->long_term_frame_idx = 0;
- } else {
- p_Dpb->max_long_term_pic_idx = -1;
- p->is_long_term = 0;
- }
-
-#if (MVC_EXTENSION_ENABLE)
- p_Dpb->last_output_view_id = -1;
-#endif
-
-}
-
-static void sliding_window_memory_management(
- struct DecodedPictureBuffer *p_Dpb,
- struct StorablePicture *p)
-{
- unsigned int i;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- unsigned char slide_flag = 0;
- unsigned int sliding_margin = imax(
- 1, p_Dpb->num_ref_frames) - p_Dpb->ltref_frames_in_buffer;
- /* assert (!p->idr_flag); */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s ref_frames_in_buffer %d ltref_frames_in_buffer %d\n",
- __func__, p_Dpb->ref_frames_in_buffer,
- p_Dpb->ltref_frames_in_buffer);
- /* if this is a reference pic with sliding window,
- unmark first ref frame */
- if (p_Dpb->ref_frames_in_buffer == sliding_margin)
- slide_flag = 1;
- /*else if ((h264_error_proc_policy & 0x8) &&
- (p_Dpb->ref_frames_in_buffer > sliding_margin))
- slide_flag = 1;*/
-
- if (slide_flag) {
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->is_reference &&
- (!(p_Dpb->fs[i]->is_long_term))) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "unmark %d\n", i);
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
- update_ref_list(p_Dpb);
- break;
- }
- }
- }
-
- p->is_long_term = 0;
-}
-
-static void check_num_ref(struct DecodedPictureBuffer *p_Dpb)
-{
- if ((int)(p_Dpb->ltref_frames_in_buffer +
- p_Dpb->ref_frames_in_buffer) >
- imax(1, p_Dpb->num_ref_frames)) {
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "Max. number of reference frames exceeded. Invalid stream. lt %d ref %d mum_ref %d\n",
- p_Dpb->ltref_frames_in_buffer,
- p_Dpb->ref_frames_in_buffer,
- p_Dpb->num_ref_frames);
- }
-}
-
-void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force)
-{
- unsigned int i;
- unsigned char *buf = NULL;
- unsigned int buf_size = 512, len = 0;
- struct h264_dpb_stru *p_H264_Dpb =
- container_of(p_Dpb, struct h264_dpb_stru, mDPB);
-
-#define DPB_STRCAT(args...) do { \
- len += snprintf(buf + len, \
- buf_size - len, ##args);\
- } while (0)
-
- if ((h264_debug_flag & PRINT_FLAG_DUMP_DPB) == 0 &&
- force == 0)
- return;
-
- buf = kzalloc(buf_size, GFP_ATOMIC);
- if (buf == NULL)
- return;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- len = 0;
- memset(buf, 0, buf_size);
- DPB_STRCAT("fn=%d is_used %d ",
- p_Dpb->fs[i]->frame_num,
- p_Dpb->fs[i]->is_used);
-
- if (p_Dpb->fs[i]->is_used & 1) {
- if (p_Dpb->fs[i]->top_field)
- DPB_STRCAT("T: poc=%d pic_num=%d ",
- p_Dpb->fs[i]->top_field->poc,
- p_Dpb->fs[i]->top_field->pic_num);
- else
- DPB_STRCAT("T: poc=%d ",
- p_Dpb->fs[i]->frame->top_poc);
- }
- if (p_Dpb->fs[i]->is_used & 2) {
- if (p_Dpb->fs[i]->bottom_field)
- DPB_STRCAT("B: poc=%d pic_num=%d ",
- p_Dpb->fs[i]->bottom_field->poc,
- p_Dpb->fs[i]->bottom_field->pic_num);
- else
- DPB_STRCAT("B: poc=%d ",
- p_Dpb->fs[i]->frame->bottom_poc);
- }
- if (p_Dpb->fs[i]->is_used == 3) {
- if (p_Dpb->fs[i]->frame != NULL)
- DPB_STRCAT("F: poc=%d pic_num=%d ",
- p_Dpb->fs[i]->frame->poc,
- p_Dpb->fs[i]->frame->pic_num);
- else
- DPB_STRCAT("fs[%d] frame is null ", i);
- }
- DPB_STRCAT("G: poc=%d) ", p_Dpb->fs[i]->poc);
- if (p_Dpb->fs[i]->is_reference)
- DPB_STRCAT("ref (%d) ", p_Dpb->fs[i]->is_reference);
- if (p_Dpb->fs[i]->is_long_term)
- DPB_STRCAT("lt_ref (%d) ", p_Dpb->fs[i]->is_reference);
- if (p_Dpb->fs[i]->is_output)
- DPB_STRCAT("out(displayed) ");
- if (p_Dpb->fs[i]->pre_output)
- DPB_STRCAT("pre_output(in dispq or displaying) ");
- if (p_Dpb->fs[i]->is_used == 3) {
- if (p_Dpb->fs[i]->frame != NULL && p_Dpb->fs[i]->frame->non_existing)
- DPB_STRCAT("non_existing ");
- else
- DPB_STRCAT("fs[%d] frame is null ", i);
- }
- DPB_STRCAT("dpb_frame_count %d ",
- p_Dpb->fs[i]->dpb_frame_count);
-
-#if (MVC_EXTENSION_ENABLE)
- if (p_Dpb->fs[i]->is_reference)
- DPB_STRCAT("view_id (%d) ", p_Dpb->fs[i]->view_id);
-#endif
- if (p_Dpb->fs[i]->data_flag) {
- DPB_STRCAT("data_flag(0x%x)",
- p_Dpb->fs[i]->data_flag);
- }
- DPB_STRCAT(" bufspec %d\n",
- p_Dpb->fs[i]->buf_spec_num);
- dpb_print(p_H264_Dpb->decoder_index, 0, "%s", buf);
- }
-
- kfree(buf);
-}
-
-/*!
- ************************************************************************
- * \brief
- * adaptive memory management
- *
- ************************************************************************
- */
-
-static int get_pic_num_x(struct StorablePicture *p,
- int difference_of_pic_nums_minus1)
-{
- int currPicNum;
-
- if (p->structure == FRAME)
- currPicNum = p->frame_num;
- else
- currPicNum = 2 * p->frame_num + 1;
-
- return currPicNum - (difference_of_pic_nums_minus1 + 1);
-}
-
-/*!
- ************************************************************************
- * \brief
- * Adaptive Memory Management: Mark short term picture unused
- ************************************************************************
- */
-static void mm_unmark_short_term_for_reference(struct DecodedPictureBuffer
- *p_Dpb, struct StorablePicture *p,
- int difference_of_pic_nums_minus1)
-{
- struct h264_dpb_stru *p_H264_Dpb =
- container_of(p_Dpb, struct h264_dpb_stru, mDPB);
- int picNumX;
-
- unsigned int i;
-
- picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
-
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p->structure == FRAME) {
- if ((p_Dpb->fs_ref[i]->is_reference == 3) &&
- (p_Dpb->fs_ref[i]->is_long_term == 0)) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->frame->pic_num ==
- picNumX) {
- unmark_for_reference(p_Dpb,
- p_Dpb->fs_ref[i]);
- return;
- }
- }
- } else {
- if ((p_Dpb->fs_ref[i]->is_reference & 1) &&
- (!(p_Dpb->fs_ref[i]->is_long_term & 1))) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->top_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->top_field->pic_num ==
- picNumX) {
- p_Dpb->fs_ref[i]->
- top_field->used_for_reference = 0;
- p_Dpb->fs_ref[i]->is_reference &= 2;
- if ((p_Dpb->fs_ref[i]->is_used == 3)
-#ifdef ERROR_CHECK
- && p_Dpb->fs_ref[i]->frame
-#endif
- ) {
- p_Dpb->fs_ref[i]->frame->
- used_for_reference = 0;
- }
- return;
- }
- }
- if ((p_Dpb->fs_ref[i]->is_reference & 2) &&
- (!(p_Dpb->fs_ref[i]->is_long_term & 2))) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->bottom_field->pic_num ==
- picNumX) {
- p_Dpb->fs_ref[i]->bottom_field->
- used_for_reference = 0;
- p_Dpb->fs_ref[i]->is_reference &= 1;
- if ((p_Dpb->fs_ref[i]->is_used == 3)
-#ifdef ERROR_CHECK
- && p_Dpb->fs_ref[i]->frame
-#endif
- ) {
- p_Dpb->fs_ref[i]->frame->
- used_for_reference = 0;
- }
- return;
- }
- }
- }
- }
-}
-
-/*!
- ************************************************************************
- * \brief
- * Adaptive Memory Management: Mark long term picture unused
- ************************************************************************
- */
-static void mm_unmark_long_term_for_reference(struct DecodedPictureBuffer
- *p_Dpb, struct StorablePicture *p, int long_term_pic_num)
-{
- unsigned int i;
-
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p->structure == FRAME) {
- if ((p_Dpb->fs_ltref[i]->is_reference == 3) &&
- (p_Dpb->fs_ltref[i]->is_long_term == 3)) {
- if (p_Dpb->fs_ltref[i]->frame->
- long_term_pic_num ==
- long_term_pic_num) {
- unmark_for_long_term_reference(
- p_Dpb->fs_ltref[i]);
- }
- }
- } else {
- if ((p_Dpb->fs_ltref[i]->is_reference & 1) &&
- ((p_Dpb->fs_ltref[i]->is_long_term & 1))) {
- if (p_Dpb->fs_ltref[i]->top_field->
- long_term_pic_num ==
- long_term_pic_num) {
- p_Dpb->fs_ltref[i]->top_field->
- used_for_reference = 0;
- p_Dpb->fs_ltref[i]->top_field->
- is_long_term = 0;
- p_Dpb->fs_ltref[i]->is_reference &= 2;
- p_Dpb->fs_ltref[i]->is_long_term &= 2;
- if (p_Dpb->fs_ltref[i]->is_used == 3) {
- p_Dpb->fs_ltref[i]->frame->
- used_for_reference = 0;
- p_Dpb->fs_ltref[i]->frame->
- is_long_term = 0;
- }
- return;
- }
- }
- if ((p_Dpb->fs_ltref[i]->is_reference & 2) &&
- ((p_Dpb->fs_ltref[i]->is_long_term & 2))) {
- if (p_Dpb->fs_ltref[i]->bottom_field->
- long_term_pic_num ==
- long_term_pic_num) {
- p_Dpb->fs_ltref[i]->bottom_field->
- used_for_reference = 0;
- p_Dpb->fs_ltref[i]->bottom_field->
- is_long_term = 0;
- p_Dpb->fs_ltref[i]->is_reference &= 1;
- p_Dpb->fs_ltref[i]->is_long_term &= 1;
- if (p_Dpb->fs_ltref[i]->is_used == 3) {
- p_Dpb->fs_ltref[i]->frame->
- used_for_reference = 0;
- p_Dpb->fs_ltref[i]->frame->
- is_long_term = 0;
- }
- return;
- }
- }
- }
- }
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * Mark a long-term reference frame or complementary
- * field pair unused for referemce
- ************************************************************************
- */
-static void unmark_long_term_frame_for_reference_by_frame_idx(
- struct DecodedPictureBuffer *p_Dpb, int long_term_frame_idx)
-{
- unsigned int i;
-
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ltref[i]->long_term_frame_idx ==
- long_term_frame_idx)
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- }
-}
-
-
-static void unmark1(struct DecodedPictureBuffer *p_Dpb,
- unsigned int curr_frame_num, int i)
-{
- if (p_Dpb->last_picture) {
- /*if ((p_Dpb->last_picture != p_Dpb->fs_ltref[i]) ||
- p_Dpb->last_picture->frame_num != curr_frame_num) {*/
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- /*} else {
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- }*/
- }
-}
-
-static void unmark2(struct DecodedPictureBuffer *p_Dpb,
- int curr_pic_num, int i)
-{
- if ((p_Dpb->fs_ltref[i]->frame_num) !=
- (unsigned int)(curr_pic_num >> 1))
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
-}
-
-static void unmark3_top(struct DecodedPictureBuffer *p_Dpb,
- unsigned int curr_frame_num, int curr_pic_num, int mark_current, int i)
-{
- if (p_Dpb->fs_ltref[i]->is_long_term == 3) {
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- } else {
- if (p_Dpb->fs_ltref[i]->is_long_term == 1) {
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- } else {
- if (mark_current)
- unmark1(p_Dpb, curr_frame_num, i);
- else
- unmark2(p_Dpb, curr_pic_num, i);
- }
- }
-}
-
-static void unmark3_bottom(struct DecodedPictureBuffer *p_Dpb,
- unsigned int curr_frame_num, int curr_pic_num, int mark_current, int i)
-{
- if (p_Dpb->fs_ltref[i]->is_long_term == 2) {
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- } else {
- if (mark_current)
- unmark1(p_Dpb, curr_frame_num, i);
- else
- unmark2(p_Dpb, curr_pic_num, i);
- }
-}
-
-static void unmark_long_term_field_for_reference_by_frame_idx(
- struct DecodedPictureBuffer *p_Dpb, enum PictureStructure structure,
- int long_term_frame_idx, int mark_current, unsigned int curr_frame_num,
- int curr_pic_num)
-{
- struct VideoParameters *p_Vid = p_Dpb->p_Vid;
- unsigned int i;
-
- /* assert(structure!=FRAME); */
- if (curr_pic_num < 0)
- curr_pic_num += (2 * p_Vid->max_frame_num);
-
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ltref[i]->long_term_frame_idx ==
- long_term_frame_idx) {
- if (structure == TOP_FIELD)
- unmark3_top(p_Dpb, curr_frame_num,
- curr_pic_num, mark_current, i);
-
- if (structure == BOTTOM_FIELD)
- unmark3_bottom(p_Dpb, curr_frame_num,
- curr_pic_num, mark_current, i);
- }
- }
-}
-
-/*!
- ************************************************************************
- * \brief
- * mark a picture as long-term reference
- ************************************************************************
- */
-static void mark_pic_long_term(struct DecodedPictureBuffer *p_Dpb,
- struct StorablePicture *p,
- int long_term_frame_idx, int picNumX)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- unsigned int i;
- int add_top, add_bottom;
-
- if (p->structure == FRAME) {
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference == 3) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->frame->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->frame->pic_num ==
- picNumX)) {
- p_Dpb->fs_ref[i]->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->frame->
- long_term_frame_idx =
- long_term_frame_idx;
- p_Dpb->fs_ref[i]->frame->
- long_term_pic_num =
- long_term_frame_idx;
- p_Dpb->fs_ref[i]->frame->
- is_long_term = 1;
-
- if (p_Dpb->fs_ref[i]->top_field &&
- p_Dpb->fs_ref[i]->bottom_field) {
- p_Dpb->fs_ref[i]->top_field->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->
- bottom_field->
- long_term_frame_idx =
- long_term_frame_idx;
- p_Dpb->fs_ref[i]->top_field->
- long_term_pic_num =
- long_term_frame_idx;
- p_Dpb->fs_ref[i]->
- bottom_field->
- long_term_pic_num =
- long_term_frame_idx;
-
- p_Dpb->fs_ref[i]->top_field->
- is_long_term =
- p_Dpb->fs_ref[i]->
- bottom_field->
- is_long_term
- = 1;
-
- }
- p_Dpb->fs_ref[i]->is_long_term = 3;
- return;
- }
- }
- }
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "Warning: reference frame for long term marking not found\n");
- } else {
- if (p->structure == TOP_FIELD) {
- add_top = 1;
- add_bottom = 0;
- } else {
- add_top = 0;
- add_bottom = 1;
- }
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference & 1) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->top_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->top_field->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->top_field->pic_num ==
- picNumX)) {
- if ((p_Dpb->fs_ref[i]->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->
- long_term_frame_idx !=
- long_term_frame_idx)) {
- dpb_print(p_H264_Dpb->
- decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "Warning: assigning long_term_frame_idx different from other field\n");
- }
-
- p_Dpb->fs_ref[i]->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->top_field->
- long_term_frame_idx
- = long_term_frame_idx;
- p_Dpb->fs_ref[i]->top_field->
- long_term_pic_num =
- 2 * long_term_frame_idx +
- add_top;
- p_Dpb->fs_ref[i]->top_field->
- is_long_term = 1;
- p_Dpb->fs_ref[i]->is_long_term |= 1;
- if ((p_Dpb->fs_ref[i]->is_long_term
- == 3)
-#ifdef ERROR_CHECK
- && p_Dpb->fs_ref[i]->frame
-#endif
- ) {
- p_Dpb->fs_ref[i]->frame->
- is_long_term = 1;
- p_Dpb->fs_ref[i]->frame->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->
- frame->
- long_term_pic_num =
- long_term_frame_idx;
- }
- return;
- }
- }
- if (p_Dpb->fs_ref[i]->is_reference & 2) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->bottom_field->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->bottom_field->pic_num
- == picNumX)) {
- if ((p_Dpb->fs_ref[i]->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->
- long_term_frame_idx !=
- long_term_frame_idx)) {
- dpb_print(p_H264_Dpb->
- decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "Warning: assigning long_term_frame_idx different from other field\n");
- }
-
- p_Dpb->fs_ref[i]->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->bottom_field
- ->long_term_frame_idx
- = long_term_frame_idx;
- p_Dpb->fs_ref[i]->bottom_field->
- long_term_pic_num = 2 *
- long_term_frame_idx +
- add_bottom;
- p_Dpb->fs_ref[i]->bottom_field->
- is_long_term = 1;
- p_Dpb->fs_ref[i]->is_long_term |= 2;
- if ((p_Dpb->fs_ref[i]->
- is_long_term == 3)
-#ifdef ERROR_CHECK
- && p_Dpb->fs_ref[i]->frame
-#endif
- ) {
- p_Dpb->fs_ref[i]->frame->
- is_long_term = 1;
- p_Dpb->fs_ref[i]->frame->
- long_term_frame_idx =
- p_Dpb->fs_ref[i]->
- frame->
- long_term_pic_num =
- long_term_frame_idx;
- }
- return;
- }
- }
- }
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "Warning: reference field for long term marking not found\n");
- }
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * Assign a long term frame index to a short term picture
- ************************************************************************
- */
-static void mm_assign_long_term_frame_idx(struct DecodedPictureBuffer *p_Dpb,
- struct StorablePicture *p, int difference_of_pic_nums_minus1,
- int long_term_frame_idx)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- int picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
-
- /* remove frames/fields with same long_term_frame_idx */
- if (p->structure == FRAME) {
- unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb,
- long_term_frame_idx);
- } else {
- unsigned int i;
- enum PictureStructure structure = FRAME;
-
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference & 1) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->top_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->top_field->
- pic_num == picNumX) {
- structure = TOP_FIELD;
- break;
- }
- }
- if (p_Dpb->fs_ref[i]->is_reference & 2) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->bottom_field->
- pic_num == picNumX) {
- structure = BOTTOM_FIELD;
- break;
- }
- }
- }
- if (structure == FRAME) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "field for long term marking not found %d",
- 200);
- }
-
- unmark_long_term_field_for_reference_by_frame_idx(p_Dpb,
- structure,
- long_term_frame_idx, 0, 0, picNumX);
- }
-
- mark_pic_long_term(p_Dpb, p, long_term_frame_idx, picNumX);
-}
-
-/*!
- ************************************************************************
- * \brief
- * Set new max long_term_frame_idx
- ************************************************************************
- */
-static void mm_update_max_long_term_frame_idx(struct DecodedPictureBuffer
- *p_Dpb, int max_long_term_frame_idx_plus1)
-{
- unsigned int i;
-
- p_Dpb->max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1;
-
- /* check for invalid frames */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ltref[i]->long_term_frame_idx >
- p_Dpb->max_long_term_pic_idx) {
- unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
- }
- }
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * Mark all long term reference pictures unused for reference
- ************************************************************************
- */
-static void mm_unmark_all_long_term_for_reference(struct DecodedPictureBuffer
- *p_Dpb)
-{
- mm_update_max_long_term_frame_idx(p_Dpb, 0);
-}
-
-/*!
- ************************************************************************
- * \brief
- * Mark all short term reference pictures unused for reference
- ************************************************************************
- */
-static void mm_unmark_all_short_term_for_reference(struct DecodedPictureBuffer
- *p_Dpb)
-{
- unsigned int i;
-
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++)
- unmark_for_reference(p_Dpb, p_Dpb->fs_ref[i]);
- update_ref_list(p_Dpb);
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * Mark the current picture used for long term reference
- ************************************************************************
- */
-static void mm_mark_current_picture_long_term(struct DecodedPictureBuffer
- *p_Dpb, struct StorablePicture *p, int long_term_frame_idx)
-{
- /* remove long term pictures with same long_term_frame_idx */
- if (p->structure == FRAME) {
- unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb,
- long_term_frame_idx);
- } else {
- unmark_long_term_field_for_reference_by_frame_idx(p_Dpb,
- p->structure, long_term_frame_idx,
- 1, p->pic_num, 0);
- }
-
- p->is_long_term = 1;
- p->long_term_frame_idx = long_term_frame_idx;
-}
-
-static void adaptive_memory_management(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *p)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- struct DecRefPicMarking_s *tmp_drpm;
- struct VideoParameters *p_Vid = p_Dpb->p_Vid;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
- p_Vid->last_has_mmco_5 = 0;
-
- /* assert (!p->idr_flag); */
- /* assert (p->adaptive_ref_pic_buffering_flag); */
-
- while (p->dec_ref_pic_marking_buffer) {
- tmp_drpm = p->dec_ref_pic_marking_buffer;
- switch (tmp_drpm->memory_management_control_operation) {
- case 0:
- if (tmp_drpm->Next != NULL)
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "error, memory_management_control_operation = 0 not last operation in buffer\n");
- break;
- case 1:
- mm_unmark_short_term_for_reference(p_Dpb, p,
- tmp_drpm->difference_of_pic_nums_minus1);
- update_ref_list(p_Dpb);
- break;
- case 2:
- mm_unmark_long_term_for_reference(p_Dpb, p,
- tmp_drpm->long_term_pic_num);
- update_ltref_list(p_Dpb);
- break;
- case 3:
- mm_assign_long_term_frame_idx(p_Dpb, p,
- tmp_drpm->difference_of_pic_nums_minus1,
- tmp_drpm->long_term_frame_idx);
- update_ref_list(p_Dpb);
- update_ltref_list(p_Dpb);
- break;
- case 4:
- mm_update_max_long_term_frame_idx(p_Dpb,
- tmp_drpm->max_long_term_frame_idx_plus1);
- update_ltref_list(p_Dpb);
- break;
- case 5:
- mm_unmark_all_short_term_for_reference(p_Dpb);
- mm_unmark_all_long_term_for_reference(p_Dpb);
- p_Vid->last_has_mmco_5 = 1;
- break;
- case 6:
- mm_mark_current_picture_long_term(p_Dpb, p,
- tmp_drpm->long_term_frame_idx);
- check_num_ref(p_Dpb);
- break;
- default:
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "error, invalid memory_management_control_operation in buffer\n");
- }
- p->dec_ref_pic_marking_buffer = tmp_drpm->Next;
- /* free (tmp_drpm); */
- }
- if (p_Vid->last_has_mmco_5) {
- p->pic_num = p->frame_num = 0;
-
- switch (p->structure) {
- case TOP_FIELD: {
- /* p->poc = p->top_poc = p_Vid->toppoc =0; */
- p->poc = p->top_poc = 0;
- break;
- }
- case BOTTOM_FIELD: {
- /* p->poc = p->bottom_poc = p_Vid->bottompoc = 0; */
- p->poc = p->bottom_poc = 0;
- break;
- }
- case FRAME: {
- p->top_poc -= p->poc;
- p->bottom_poc -= p->poc;
-
- /* p_Vid->toppoc = p->top_poc; */
- /* p_Vid->bottompoc = p->bottom_poc; */
-
- p->poc = imin(p->top_poc, p->bottom_poc);
- /* p_Vid->framepoc = p->poc; */
- break;
- }
- }
- /* currSlice->ThisPOC = p->poc; */
-#if (MVC_EXTENSION_ENABLE)
- if (p->view_id == 0) {
- flush_dpb(p_Vid->p_Dpb_layer[0]);
- flush_dpb(p_Vid->p_Dpb_layer[1]);
- } else {
- flush_dpb(p_Dpb);
- }
-#else
- flush_dpb(p_H264_Dpb);
-#endif
- }
-}
-
-
-int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *p,
- unsigned char data_flag)
-{
- /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- unsigned int i, frame_outside_count = 0;
-#if 0
- int poc, pos;
-#endif
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s p_Vid %p\n", __func__, p_Vid);
-
- /* picture error concealment */
-
- /* diagnostics */
- /* dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- * "Storing (%s) non-ref pic with frame_num #%d\n",
- * (p->type == FRAME)?"FRAME":(p->type == TOP_FIELD)?
- * "TOP_FIELD":"BOTTOM_FIELD", p->pic_num);
- */
- /* if frame, check for new store, */
- /* assert (p!=NULL); */
-
- p_Vid->last_has_mmco_5 = 0;
- p_Vid->last_pic_bottom_field = (p->structure == BOTTOM_FIELD);
- if (p->idr_flag) {
- idr_memory_management(p_H264_Dpb, p);
- if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT)
- p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE;
-#if 0
-/* ??? */
- /* picture error concealment */
- memset(p_Vid->pocs_in_dpb, 0, sizeof(int) * 100);
-#endif
- } else {
-#if 1
-/* ??? */
- /* adaptive memory management */
- if (p->used_for_reference &&
- (p->adaptive_ref_pic_buffering_flag))
- adaptive_memory_management(p_H264_Dpb, p);
-#endif
- }
-
- if ((p->structure == TOP_FIELD) || (p->structure == BOTTOM_FIELD)) {
- /* check for frame store with same pic_number */
- if (p_Dpb->last_picture) {
- if ((int)p_Dpb->last_picture->frame_num ==
- p->pic_num) {
- if (((p->structure == TOP_FIELD) &&
- (p_Dpb->last_picture->is_used == 2)) ||
- ((p->structure == BOTTOM_FIELD) &&
- (p_Dpb->last_picture->is_used == 1))) {
- if ((p->used_for_reference &&
- (p_Dpb->last_picture->
- is_orig_reference != 0)) ||
- (!p->used_for_reference &&
- (p_Dpb->last_picture->
- is_orig_reference == 0))) {
- insert_picture_in_dpb(
- p_H264_Dpb,
- p_Dpb->last_picture,
- p, data_flag);
- update_ref_list(p_Dpb);
- update_ltref_list(p_Dpb);
- dump_dpb(p_Dpb, 0);
- p_Dpb->last_picture = NULL;
- return 0;
- }
- }
- }
- }
- }
- /* this is a frame or a field which has no stored
- * complementary field
- */
-
- /* sliding window, if necessary */
- if ((!p->idr_flag) && (p->used_for_reference &&
- (!p->adaptive_ref_pic_buffering_flag))) {
- sliding_window_memory_management(p_Dpb, p);
- }
-
- /* picture error concealment */
- if (p_Vid->conceal_mode != 0) {
- for (i = 0; i < p_Dpb->size; i++)
- if (p_Dpb->fs[i]->is_reference)
- p_Dpb->fs[i]->concealment_reference = 1;
- }
-
- while (remove_unused_frame_from_dpb(p_H264_Dpb))
- ;
-
- while (output_frames(p_H264_Dpb, 0))
- ;
-
- /* check for duplicate frame number in short term reference buffer */
- if ((p->used_for_reference) && (!p->is_long_term)) {
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL)
- continue;
-#endif
- if (p_Dpb->fs_ref[i]->frame_num == p->frame_num) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "duplicate frame_num in short-term reference picture buffer %d\n",
- 500);
- if (p_Dpb->fs_ref[i]->dpb_frame_count == p_H264_Dpb->dpb_frame_count) {
- dpb_print(p_H264_Dpb->decoder_index,
- 0, "duplicate frame, no insert to dpb\n");
- return -2;
- } else {
- dpb_print(p_H264_Dpb->decoder_index,
- 0, "duplicate frame_num release defore ref\n");
- unmark_for_reference(p_Dpb, p_Dpb->fs_ref[i]);
- update_ref_list(p_Dpb);
- }
- }
- }
- }
- /* store at end of buffer */
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s p_Dpb->used_size %d\n", __func__, p_Dpb->used_size);
- if (p_Dpb->used_size >= p_Dpb->size) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s Error: used_sizd %d is large than dpb size\r\n",
- __func__, p_Dpb->used_size);
- /*h264_debug_flag |= PRINT_FLAG_DUMP_DPB;*/
- dump_dpb(p_Dpb, 0);
- return -1;
- }
-
- insert_picture_in_dpb(p_H264_Dpb, p_Dpb->fs[p_Dpb->used_size],
- p, data_flag);
-
- /* picture error concealment */
- if (p->idr_flag)
- p_Vid->earlier_missing_poc = 0;
-
- if (p->structure != FRAME)
- p_Dpb->last_picture = p_Dpb->fs[p_Dpb->used_size];
- else
- p_Dpb->last_picture = NULL;
-
- p_Dpb->used_size++;
-#if 0
-/* ??? */
- if (p_Vid->conceal_mode != 0)
- p_Vid->pocs_in_dpb[p_Dpb->used_size - 1] = p->poc;
-#endif
- update_ref_list(p_Dpb);
- update_ltref_list(p_Dpb);
-
- check_num_ref(p_Dpb);
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->pre_output)
- frame_outside_count++;
- }
-
- if (p_H264_Dpb->fast_output_enable == H264_OUTPUT_MODE_FAST)
- i = 1;
- else
- i = 0;
-
- if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)) {
- while (output_frames(p_H264_Dpb, i))
- ;
- }
-
- dump_dpb(p_Dpb, 0);
- p_Dpb->first_pic_done = 1; /*by rain*/
-
- return 0;
-}
-
-void bufmgr_post(struct h264_dpb_stru *p_H264_Dpb)
-{
- /*VideoParameters *p_Vid = p_Dpb->p_Vid;*/
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
-
- if (p_Vid->last_has_mmco_5)
- p_Vid->pre_frame_num = 0;
-}
-/**********************************
- *
- * Initialize reference lists
- **********************************
- */
-#define __COMPARE(context, p1, p2) comp(p1, p2)
-#define __SHORTSORT(lo, hi, width, comp, context) \
- shortsort(lo, hi, width, comp)
-#define CUTOFF 8 /* testing shows that this is good value */
-#define STKSIZ (8*sizeof(void *) - 2)
-
-#undef swap
-static void swap(
- char *a,
- char *b,
- size_t width
-)
-{
- char tmp;
-
- if (a != b)
- /* Do the swap one character at a time to avoid potential
- * alignment problems.
- */
- while (width--) {
- tmp = *a;
- *a++ = *b;
- *b++ = tmp;
- }
-}
-
-static void shortsort(
- char *lo,
- char *hi,
- size_t width,
- int (*comp)(const void *, const void *)
-)
-{
- char *p, *max;
-
- /* Note: in assertions below, i and j are alway inside original
- * bound of array to sort.
- */
-
- while (hi > lo) {
- /* A[i] <= A[j] for i <= j, j > hi */
- max = lo;
- for (p = lo + width; p <= hi; p += width) {
- /* A[i] <= A[max] for lo <= i < p */
- if (__COMPARE(context, p, max) > 0)
- max = p;
- /* A[i] <= A[max] for lo <= i <= p */
- }
-
- /* A[i] <= A[max] for lo <= i <= hi */
-
- swap(max, hi, width);
-
- /* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j,
- * j >= hi
- */
-
- hi -= width;
-
- /* A[i] <= A[j] for i <= j, j > hi, loop top condition
- * established
- */
- }
- /* A[i] <= A[j] for i <= j, j > lo, which implies A[i] <= A[j]
- * for i < j, so array is sorted
- */
-}
-
-static void qsort(
- void *base,
- size_t num,
- size_t width,
- int (*comp)(const void *, const void *)
-)
-{
- char *lo, *hi; /* ends of sub-array currently sorting */
- char *mid; /* points to middle of subarray */
- char *loguy, *higuy; /* traveling pointers for partition step */
- size_t size; /* size of the sub-array */
- char *lostk[STKSIZ], *histk[STKSIZ];
- int stkptr;
-
-/* stack for saving sub-array to be
- * processed
- */
-#if 0
- /* validation section */
- _VALIDATE_RETURN_VOID(base != NULL || num == 0, EINVAL);
- _VALIDATE_RETURN_VOID(width > 0, EINVAL);
- _VALIDATE_RETURN_VOID(comp != NULL, EINVAL);
-#endif
- if (num < 2)
- return; /* nothing to do */
-
- stkptr = 0; /* initialize stack */
-
- lo = (char *)base;
- hi = (char *)base + width * (num - 1); /* initialize limits */
-
- /* this entry point is for pseudo-recursion calling: setting
- * lo and hi and jumping to here is like recursion, but stkptr is
- * preserved, locals aren't, so we preserve stuff on the stack
- */
-recurse:
-
- size = (hi - lo) / width + 1; /* number of el's to sort */
-
- /* below a certain size, it is faster to use a O(n^2) sorting method */
- if (size <= CUTOFF) {
- __SHORTSORT(lo, hi, width, comp, context);
- } else {
- /* First we pick a partitioning element. The efficiency of
- * the algorithm demands that we find one that is approximately
- * the median of the values, but also that we select one fast.
- * We choose the median of the first, middle, and last
- * elements, to avoid bad performance in the face of already
- * sorted data, or data that is made up of multiple sorted
- * runs appended together. Testing shows that a
- * median-of-three algorithm provides better performance than
- * simply picking the middle element for the latter case.
- */
-
- mid = lo + (size / 2) * width; /* find middle element */
-
- /* Sort the first, middle, last elements into order */
- if (__COMPARE(context, lo, mid) > 0)
- swap(lo, mid, width);
- if (__COMPARE(context, lo, hi) > 0)
- swap(lo, hi, width);
- if (__COMPARE(context, mid, hi) > 0)
- swap(mid, hi, width);
-
- /* We now wish to partition the array into three pieces, one
- * consisting of elements <= partition element, one of elements
- * equal to the partition element, and one of elements > than
- * it. This is done below; comments indicate conditions
- * established at every step.
- */
-
- loguy = lo;
- higuy = hi;
-
- /* Note that higuy decreases and loguy increases on every
- * iteration, so loop must terminate.
- */
- for (;;) {
- /* lo <= loguy < hi, lo < higuy <= hi,
- * A[i] <= A[mid] for lo <= i <= loguy,
- * A[i] > A[mid] for higuy <= i < hi,
- * A[hi] >= A[mid]
- */
-
- /* The doubled loop is to avoid calling comp(mid,mid),
- * since some existing comparison funcs don't work
- * when passed the same value for both pointers.
- */
-
- if (mid > loguy) {
- do {
- loguy += width;
- } while (loguy < mid &&
- __COMPARE(context, loguy, mid) <= 0);
- }
- if (mid <= loguy) {
- do {
- loguy += width;
- } while (loguy <= hi &&
- __COMPARE(context, loguy, mid) <= 0);
- }
-
- /* lo < loguy <= hi+1, A[i] <= A[mid] for
- * lo <= i < loguy,
- * either loguy > hi or A[loguy] > A[mid]
- */
-
- do {
- higuy -= width;
- } while (higuy > mid &&
- __COMPARE(context, higuy, mid) > 0);
-
- /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi,
- * either higuy == lo or A[higuy] <= A[mid]
- */
-
- if (higuy < loguy)
- break;
-
- /* if loguy > hi or higuy == lo, then we would have
- * exited, so A[loguy] > A[mid], A[higuy] <= A[mid],
- * loguy <= hi, higuy > lo
- */
-
- swap(loguy, higuy, width);
-
- /* If the partition element was moved, follow it.
- * Only need to check for mid == higuy, since before
- * the swap, A[loguy] > A[mid] implies loguy != mid.
- */
-
- if (mid == higuy)
- mid = loguy;
-
- /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition
- * at top of loop is re-established
- */
- }
-
- /* A[i] <= A[mid] for lo <= i < loguy,
- * A[i] > A[mid] for higuy < i < hi,
- * A[hi] >= A[mid]
- * higuy < loguy
- * implying:
- * higuy == loguy-1
- * or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid]
- */
-
- /* Find adjacent elements equal to the partition element. The
- * doubled loop is to avoid calling comp(mid,mid), since some
- * existing comparison funcs don't work when passed the same
- * value for both pointers.
- */
-
- higuy += width;
- if (mid < higuy) {
- do {
- higuy -= width;
- } while (higuy > mid &&
- __COMPARE(context, higuy, mid) == 0);
- }
- if (mid >= higuy) {
- do {
- higuy -= width;
- } while (higuy > lo &&
- __COMPARE(context, higuy, mid) == 0);
- }
-
- /* OK, now we have the following:
- * higuy < loguy
- * lo <= higuy <= hi
- * A[i] <= A[mid] for lo <= i <= higuy
- * A[i] == A[mid] for higuy < i < loguy
- * A[i] > A[mid] for loguy <= i < hi
- * A[hi] >= A[mid]
- */
-
- /* We've finished the partition, now we want to sort the
- * subarrays [lo, higuy] and [loguy, hi].
- * We do the smaller one first to minimize stack usage.
- * We only sort arrays of length 2 or more.
- */
-
- if (higuy - lo >= hi - loguy) {
- if (lo < higuy) {
- lostk[stkptr] = lo;
- histk[stkptr] = higuy;
- ++stkptr;
- } /* save big recursion for later */
-
- if (loguy < hi) {
- lo = loguy;
- goto recurse; /* do small recursion */
- }
- } else {
- if (loguy < hi) {
- lostk[stkptr] = loguy;
- histk[stkptr] = hi;
- ++stkptr; /* save big recursion for later */
- }
-
- if (lo < higuy) {
- hi = higuy;
- goto recurse; /* do small recursion */
- }
- }
- }
-
- /* We have sorted the array, except for any pending sorts on the stack.
- * Check if there are any, and do them.
- */
-
- --stkptr;
- if (stkptr >= 0) {
- lo = lostk[stkptr];
- hi = histk[stkptr];
- goto recurse; /* pop subarray from stack */
- } else
- return; /* all subarrays done */
-}
-
-/*!
- ************************************************************************
- * \brief
- * compares two stored pictures by picture number for qsort in
- * descending order
- *
- ************************************************************************
- */
-static inline int compare_pic_by_pic_num_desc(const void *arg1,
- const void *arg2)
-{
- int pic_num1 = (*(struct StorablePicture **)arg1)->pic_num;
- int pic_num2 = (*(struct StorablePicture **)arg2)->pic_num;
-
- if (pic_num1 < pic_num2)
- return 1;
- if (pic_num1 > pic_num2)
- return -1;
- else
- return 0;
-}
-
-/*!
- ************************************************************************
- * \brief
- * compares two stored pictures by picture number for qsort in
- * descending order
- *
- ************************************************************************
- */
-static inline int compare_pic_by_lt_pic_num_asc(const void *arg1,
- const void *arg2)
-{
- int long_term_pic_num1 =
- (*(struct StorablePicture **)arg1)->long_term_pic_num;
- int long_term_pic_num2 =
- (*(struct StorablePicture **)arg2)->long_term_pic_num;
-
- if (long_term_pic_num1 < long_term_pic_num2)
- return -1;
- if (long_term_pic_num1 > long_term_pic_num2)
- return 1;
- else
- return 0;
-}
-
-/*!
- ************************************************************************
- * \brief
- * compares two frame stores by pic_num for qsort in descending order
- *
- ************************************************************************
- */
-static inline int compare_fs_by_frame_num_desc(const void *arg1,
- const void *arg2)
-{
- int frame_num_wrap1 = (*(struct FrameStore **)arg1)->frame_num_wrap;
- int frame_num_wrap2 = (*(struct FrameStore **)arg2)->frame_num_wrap;
-
- if (frame_num_wrap1 < frame_num_wrap2)
- return 1;
- if (frame_num_wrap1 > frame_num_wrap2)
- return -1;
- else
- return 0;
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * compares two frame stores by lt_pic_num for qsort in descending order
- *
- ************************************************************************
- */
-static inline int compare_fs_by_lt_pic_idx_asc(const void *arg1,
- const void *arg2)
-{
- int long_term_frame_idx1 =
- (*(struct FrameStore **)arg1)->long_term_frame_idx;
- int long_term_frame_idx2 =
- (*(struct FrameStore **)arg2)->long_term_frame_idx;
-
- if (long_term_frame_idx1 < long_term_frame_idx2)
- return -1;
- else if (long_term_frame_idx1 > long_term_frame_idx2)
- return 1;
- else
- return 0;
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * compares two stored pictures by poc for qsort in ascending order
- *
- ************************************************************************
- */
-static inline int compare_pic_by_poc_asc(const void *arg1, const void *arg2)
-{
- int poc1 = (*(struct StorablePicture **)arg1)->poc;
- int poc2 = (*(struct StorablePicture **)arg2)->poc;
-
- if (poc1 < poc2)
- return -1;
- else if (poc1 > poc2)
- return 1;
- else
- return 0;
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * compares two stored pictures by poc for qsort in descending order
- *
- ************************************************************************
- */
-static inline int compare_pic_by_poc_desc(const void *arg1, const void *arg2)
-{
- int poc1 = (*(struct StorablePicture **)arg1)->poc;
- int poc2 = (*(struct StorablePicture **)arg2)->poc;
-
- if (poc1 < poc2)
- return 1;
- else if (poc1 > poc2)
- return -1;
- else
- return 0;
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * compares two frame stores by poc for qsort in ascending order
- *
- ************************************************************************
- */
-static inline int compare_fs_by_poc_asc(const void *arg1, const void *arg2)
-{
- int poc1 = (*(struct FrameStore **)arg1)->poc;
- int poc2 = (*(struct FrameStore **)arg2)->poc;
-
- if (poc1 < poc2)
- return -1;
- else if (poc1 > poc2)
- return 1;
- else
- return 0;
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * compares two frame stores by poc for qsort in descending order
- *
- ************************************************************************
- */
-static inline int compare_fs_by_poc_desc(const void *arg1, const void *arg2)
-{
- int poc1 = (*(struct FrameStore **)arg1)->poc;
- int poc2 = (*(struct FrameStore **)arg2)->poc;
-
- if (poc1 < poc2)
- return 1;
- else if (poc1 > poc2)
- return -1;
- else
- return 0;
-}
-
-/*!
- ************************************************************************
- * \brief
- * returns true, if picture is short term reference picture
- *
- ************************************************************************
- */
-static inline int is_short_ref(struct StorablePicture *s)
-{
-#ifdef ERROR_CHECK
- return (s &&
- (s->used_for_reference) && (!(s->is_long_term)));
-#else
- return (s->used_for_reference) && (!(s->is_long_term));
-#endif
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * returns true, if picture is long term reference picture
- *
- ************************************************************************
- */
-static inline int is_long_ref(struct StorablePicture *s)
-{
-#ifdef ERROR_CHECK
- return (s &&
- s->used_for_reference) && (s->is_long_term);
-#else
- return (s->used_for_reference) && (s->is_long_term);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- * Initialize reference lists for a P Slice
- *
- ************************************************************************
- */
-/*!
- ************************************************************************
- * \brief
- * Generates a alternating field list from a given FrameStore list
- *
- ************************************************************************
- */
-static void gen_pic_list_from_frame_list(enum PictureStructure currStructure,
- struct FrameStore **fs_list, int list_idx,
- struct StorablePicture **list,
- char *list_size, int long_term)
-{
- int top_idx = 0;
- int bot_idx = 0;
-
- int (*is_ref)(struct StorablePicture *s) = (long_term) ? is_long_ref :
- is_short_ref;
-
-
- if (currStructure == TOP_FIELD) {
- while ((top_idx < list_idx) || (bot_idx < list_idx)) {
- for (; top_idx < list_idx; top_idx++) {
- if (fs_list[top_idx]->is_used & 1) {
- if (is_ref(fs_list[top_idx]->
- top_field)) {
- /* short term ref pic */
- list[(short) *list_size] =
- fs_list[top_idx]->top_field;
- (*list_size)++;
- top_idx++;
- break;
- }
- }
- }
- for (; bot_idx < list_idx; bot_idx++) {
- if (fs_list[bot_idx]->is_used & 2) {
- if (is_ref(fs_list[bot_idx]->
- bottom_field)) {
- /* short term ref pic */
- list[(short) *list_size] =
- fs_list[bot_idx]->bottom_field;
- (*list_size)++;
- bot_idx++;
- break;
- }
- }
- }
- }
- }
- if (currStructure == BOTTOM_FIELD) {
- while ((top_idx < list_idx) || (bot_idx < list_idx)) {
- for (; bot_idx < list_idx; bot_idx++) {
- if (fs_list[bot_idx]->is_used & 2) {
- if (is_ref(fs_list[bot_idx]->
- bottom_field)) {
- /* short term ref pic */
- list[(short) *list_size] =
- fs_list[bot_idx]->bottom_field;
- (*list_size)++;
- bot_idx++;
- break;
- }
- }
- }
- for (; top_idx < list_idx; top_idx++) {
- if (fs_list[top_idx]->is_used & 1) {
- if (is_ref(fs_list[top_idx]->
- top_field)) {
- /* short term ref pic */
- list[(short) *list_size] =
- fs_list[top_idx]->top_field;
- (*list_size)++;
- top_idx++;
- break;
- }
- }
- }
- }
- }
-}
-
-static void init_lists_p_slice(struct Slice *currSlice)
-{
- struct VideoParameters *p_Vid = currSlice->p_Vid;
- struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
-
- unsigned int i;
-
- int list0idx = 0;
- int listltidx = 0;
-
- struct FrameStore **fs_list0;
- struct FrameStore **fs_listlt;
-
-#if (MVC_EXTENSION_ENABLE)
- currSlice->listinterviewidx0 = 0;
- currSlice->listinterviewidx1 = 0;
-#endif
-
- if (currSlice->structure == FRAME) {
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL ||
- p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_used == 3) {
- if ((p_Dpb->fs_ref[i]->frame->
- used_for_reference) &&
- (!p_Dpb->fs_ref[i]->frame->
- is_long_term)) {
- currSlice->listX[0][list0idx++] =
- p_Dpb->fs_ref[i]->frame;
- }
- }
- }
- /* order list 0 by PicNum */
- qsort((void *)currSlice->listX[0], list0idx,
- sizeof(struct StorablePicture *),
- compare_pic_by_pic_num_desc);
- currSlice->listXsize[0] = (char) list0idx;
- CHECK_VALID(currSlice->listXsize[0], 0);
- if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "listX[0] (PicNum): ");
- for (i = 0; i < list0idx; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[0][i]->pic_num);
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- }
- /* long term handling */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ltref[i]->is_used == 3) {
- if (p_Dpb->fs_ltref[i]->frame->is_long_term) {
- currSlice->listX[0][list0idx++] =
- p_Dpb->fs_ltref[i]->frame;
- }
- }
- }
- qsort((void *)&currSlice->listX[0][
- (short) currSlice->listXsize[0]],
- list0idx - currSlice->listXsize[0],
- sizeof(struct StorablePicture *),
- compare_pic_by_lt_pic_num_asc);
- currSlice->listXsize[0] = (char) list0idx;
- CHECK_VALID(currSlice->listXsize[0], 0);
- } else {
-#if 0
- fs_list0 = calloc(p_Dpb->size, sizeof(struct FrameStore *));
- if (fs_list0 == NULL)
- no_mem_exit("init_lists: fs_list0");
- fs_listlt = calloc(p_Dpb->size, sizeof(struct FrameStore *));
- if (fs_listlt == NULL)
- no_mem_exit("init_lists: fs_listlt");
-#else
- fs_list0 = &(p_Dpb->fs_list0[0]);
- fs_listlt = &(p_Dpb->fs_listlt[0]);
-#endif
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference)
- fs_list0[list0idx++] = p_Dpb->fs_ref[i];
- }
-
- qsort((void *)fs_list0, list0idx, sizeof(struct FrameStore *),
- compare_fs_by_frame_num_desc);
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "fs_list0 (FrameNum): ");
- for (i = 0; i < list0idx; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- fs_list0[i]->frame_num_wrap);
- }
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "\n");
-
- currSlice->listXsize[0] = 0;
- gen_pic_list_from_frame_list(currSlice->structure, fs_list0,
- list0idx, currSlice->listX[0],
- &currSlice->listXsize[0], 0);
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "listX[0] (PicNum): ");
- for (i = 0; i < currSlice->listXsize[0]; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[0][i]->pic_num);
- }
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "\n");
-
- /* long term handling */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++)
- fs_listlt[listltidx++] = p_Dpb->fs_ltref[i];
-
- qsort((void *)fs_listlt, listltidx, sizeof(struct FrameStore *),
- compare_fs_by_lt_pic_idx_asc);
-
- gen_pic_list_from_frame_list(currSlice->structure, fs_listlt,
- listltidx, currSlice->listX[0],
- &currSlice->listXsize[0], 1);
-
- /* free(fs_list0); */
- /* free(fs_listlt); */
- }
- currSlice->listXsize[1] = 0;
-
-
- /* set max size */
- currSlice->listXsize[0] = (char) imin(currSlice->listXsize[0],
- currSlice->num_ref_idx_active[LIST_0]);
- currSlice->listXsize[1] = (char) imin(currSlice->listXsize[1],
- currSlice->num_ref_idx_active[LIST_1]);
- CHECK_VALID(currSlice->listXsize[0], 0);
- CHECK_VALID(currSlice->listXsize[1], 1);
-
- /* set the unused list entries to NULL */
- for (i = currSlice->listXsize[0]; i < (MAX_LIST_SIZE); i++)
- currSlice->listX[0][i] = p_Vid->no_reference_picture;
- for (i = currSlice->listXsize[1]; i < (MAX_LIST_SIZE); i++)
- currSlice->listX[1][i] = p_Vid->no_reference_picture;
-
-#if PRINTREFLIST
-#if (MVC_EXTENSION_ENABLE)
- /* print out for h264_debug_flag purpose */
- if ((p_Vid->profile_idc == MVC_HIGH ||
- p_Vid->profile_idc == STEREO_HIGH) &&
- currSlice->current_slice_nr == 0) {
- if (currSlice->listXsize[0] > 0) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (CurViewID:%d %d) %s Ref Pic List 0 ****\n",
- currSlice->view_id,
- currSlice->ThisPOC,
- currSlice->structure == FRAME ? "FRM" :
- (currSlice->structure == TOP_FIELD ?
- "TOP" : "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[0]); i++) { /* ref list 0 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[0][i]->poc,
- currSlice->listX[0][i]->pic_num,
- currSlice->listX[0][i]->view_id);
- }
- }
- }
-#endif
-#endif
-}
-
-
-/*!
- ************************************************************************
- * \brief
- * Initialize reference lists
- *
- ************************************************************************
- */
-static void init_mbaff_lists(struct h264_dpb_stru *p_H264_Dpb,
- struct Slice *currSlice)
-{
- unsigned int j;
- int i;
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
- for (i = 2; i < 6; i++) {
- for (j = 0; j < MAX_LIST_SIZE; j++)
- currSlice->listX[i][j] = p_Vid->no_reference_picture;
- currSlice->listXsize[i] = 0;
- }
-
- for (i = 0; i < currSlice->listXsize[0]; i++) {
-#ifdef ERROR_CHECK
- if (currSlice->listX[0][i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- pr_info(
- "error currSlice->listX[0][%d] is NULL\r\n", i);
- break;
- }
-#endif
- currSlice->listX[2][2 * i] =
- currSlice->listX[0][i]->top_field;
- currSlice->listX[2][2 * i + 1] =
- currSlice->listX[0][i]->bottom_field;
- currSlice->listX[4][2 * i] =
- currSlice->listX[0][i]->bottom_field;
- currSlice->listX[4][2 * i + 1] =
- currSlice->listX[0][i]->top_field;
- }
- currSlice->listXsize[2] = currSlice->listXsize[4] =
- currSlice->listXsize[0] * 2;
-
- for (i = 0; i < currSlice->listXsize[1]; i++) {
-#ifdef ERROR_CHECK
- if (currSlice->listX[1][i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- pr_info(
- "error currSlice->listX[1][%d] is NULL\r\n", i);
- break;
- }
-#endif
- currSlice->listX[3][2 * i] =
- currSlice->listX[1][i]->top_field;
- currSlice->listX[3][2 * i + 1] =
- currSlice->listX[1][i]->bottom_field;
- currSlice->listX[5][2 * i] =
- currSlice->listX[1][i]->bottom_field;
- currSlice->listX[5][2 * i + 1] =
- currSlice->listX[1][i]->top_field;
- }
- currSlice->listXsize[3] = currSlice->listXsize[5] =
- currSlice->listXsize[1] * 2;
-}
-
-
-
-static void init_lists_i_slice(struct Slice *currSlice)
-{
-
-#if (MVC_EXTENSION_ENABLE)
- currSlice->listinterviewidx0 = 0;
- currSlice->listinterviewidx1 = 0;
-#endif
-
- currSlice->listXsize[0] = 0;
- currSlice->listXsize[1] = 0;
-}
-
-static void init_lists_b_slice(struct Slice *currSlice)
-{
- struct VideoParameters *p_Vid = currSlice->p_Vid;
- struct DecodedPictureBuffer *p_Dpb = currSlice->p_Dpb;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
-
- unsigned int i;
- int j;
-
- int list0idx = 0;
- int list0idx_1 = 0;
- int listltidx = 0;
-
- struct FrameStore **fs_list0;
- struct FrameStore **fs_list1;
- struct FrameStore **fs_listlt;
-
-#if (MVC_EXTENSION_ENABLE)
- currSlice->listinterviewidx0 = 0;
- currSlice->listinterviewidx1 = 0;
-#endif
-
- {
- /* B-Slice */
- if (currSlice->structure == FRAME) {
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL ||
- p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((p_Dpb->fs_ref[i]->is_used == 3) &&
- ((p_Dpb->fs_ref[i]->frame->
- used_for_reference) &&
- (!p_Dpb->fs_ref[i]->frame->
- is_long_term)) &&
- (currSlice->framepoc >=
- p_Dpb->fs_ref[i]->frame->poc)) {
- /* !KS use >= for error
- * concealment
- */
- currSlice->listX[0][list0idx++] =
- p_Dpb->fs_ref[i]->frame;
- }
- }
- qsort((void *)currSlice->listX[0], list0idx,
- sizeof(struct StorablePicture *),
- compare_pic_by_poc_desc);
-
- /* get the backward reference picture
- * (POC>current POC) in list0;
- */
- list0idx_1 = list0idx;
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL ||
- p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((p_Dpb->fs_ref[i]->is_used == 3) &&
- ((p_Dpb->fs_ref[i]->frame->
- used_for_reference) &&
- (!p_Dpb->fs_ref[i]->frame->
- is_long_term)) &&
- (currSlice->framepoc <
- p_Dpb->fs_ref[i]->frame->poc)) {
- currSlice->
- listX[0][list0idx++] =
- p_Dpb->fs_ref[i]->frame;
- }
- }
- qsort((void *)&currSlice->listX[0][list0idx_1],
- list0idx - list0idx_1,
- sizeof(struct StorablePicture *),
- compare_pic_by_poc_asc);
-
- for (j = 0; j < list0idx_1; j++) {
- currSlice->
- listX[1][list0idx - list0idx_1 + j] =
- currSlice->listX[0][j];
- }
- for (j = list0idx_1; j < list0idx; j++) {
- currSlice->listX[1][j - list0idx_1] =
- currSlice->listX[0][j];
- }
-
- currSlice->listXsize[0] = currSlice->listXsize[1] =
- (char) list0idx;
- CHECK_VALID(currSlice->listXsize[0], 0);
- CHECK_VALID(currSlice->listXsize[1], 1);
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "listX[0] (PicNum): ");
- for (i = 0; i < currSlice->listXsize[0]; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[0][i]->pic_num);
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "listX[1] (PicNum): ");
- for (i = 0; i < currSlice->listXsize[1]; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[1][i]->pic_num);
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- /* dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "currSlice->listX[0] currPoc=%d (Poc): ",
- * p_Vid->framepoc);
- * for (i=0; i<currSlice->listXsize[0]; i++) {
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "%d ", currSlice->listX[0][i]->poc);
- * }
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL, "\n");
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "currSlice->listX[1] currPoc=%d (Poc): ",
- * p_Vid->framepoc);
- * for (i=0; i<currSlice->listXsize[1]; i++) {
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "%d ",
- * currSlice->listX[1][i]->poc);
- * }
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL, "\n");
- */
-
- /* long term handling */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ltref[i]->is_used == 3) {
- if (p_Dpb->fs_ltref[i]->frame->
- is_long_term) {
- currSlice->
- listX[0][list0idx] =
- p_Dpb->fs_ltref[i]->frame;
- currSlice->
- listX[1][list0idx++] =
- p_Dpb->fs_ltref[i]->frame;
- }
- }
- }
- qsort((void *)&currSlice->
- listX[0][(short) currSlice->listXsize[0]],
- list0idx - currSlice->listXsize[0],
- sizeof(struct StorablePicture *),
- compare_pic_by_lt_pic_num_asc);
- qsort((void *)&currSlice->
- listX[1][(short) currSlice->listXsize[0]],
- list0idx - currSlice->listXsize[0],
- sizeof(struct StorablePicture *),
- compare_pic_by_lt_pic_num_asc);
- currSlice->listXsize[0] = currSlice->listXsize[1] =
- (char) list0idx;
- CHECK_VALID(currSlice->listXsize[0], 0);
- CHECK_VALID(currSlice->listXsize[1], 1);
- } else {
-#if 0
- fs_list0 = calloc(p_Dpb->size,
- sizeof(struct FrameStore *));
- if (fs_list0 == NULL)
- no_mem_exit("init_lists: fs_list0");
- fs_list1 = calloc(p_Dpb->size,
- sizeof(struct FrameStore *));
- if (fs_list1 == NULL)
- no_mem_exit("init_lists: fs_list1");
- fs_listlt = calloc(p_Dpb->size,
- sizeof(struct FrameStore *));
- if (fs_listlt == NULL)
- no_mem_exit("init_lists: fs_listlt");
-#else
- fs_list0 = &(p_Dpb->fs_list0[0]);
- fs_list1 = &(p_Dpb->fs_list1[0]);
- fs_listlt = &(p_Dpb->fs_listlt[0]);
-
-#endif
- currSlice->listXsize[0] = 0;
- currSlice->listXsize[1] = 1;
-
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_used) {
- if (currSlice->ThisPOC >=
- p_Dpb->fs_ref[i]->poc) {
- fs_list0[list0idx++] =
- p_Dpb->fs_ref[i];
- }
- }
- }
- qsort((void *)fs_list0, list0idx,
- sizeof(struct FrameStore *),
- compare_fs_by_poc_desc);
- list0idx_1 = list0idx;
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_used) {
- if (currSlice->ThisPOC <
- p_Dpb->fs_ref[i]->poc) {
- fs_list0[list0idx++] =
- p_Dpb->fs_ref[i];
- }
- }
- }
- qsort((void *)&fs_list0[list0idx_1],
- list0idx - list0idx_1,
- sizeof(struct FrameStore *),
- compare_fs_by_poc_asc);
-
- for (j = 0; j < list0idx_1; j++) {
- fs_list1[list0idx - list0idx_1 + j] =
- fs_list0[j];
- }
- for (j = list0idx_1; j < list0idx; j++)
- fs_list1[j - list0idx_1] = fs_list0[j];
-
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "fs_list0 currPoc=%d (Poc): ",
- currSlice->ThisPOC);
- for (i = 0; i < list0idx; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- fs_list0[i]->poc);
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "fs_list1 currPoc=%d (Poc): ",
- currSlice->ThisPOC);
- for (i = 0; i < list0idx; i++) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- fs_list1[i]->poc);
- }
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
-
- currSlice->listXsize[0] = 0;
- currSlice->listXsize[1] = 0;
- gen_pic_list_from_frame_list(currSlice->structure,
- fs_list0, list0idx,
- currSlice->listX[0],
- &currSlice->listXsize[0], 0);
- gen_pic_list_from_frame_list(currSlice->structure,
- fs_list1, list0idx,
- currSlice->listX[1],
- &currSlice->listXsize[1], 0);
-
- /* dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "currSlice->listX[0] currPoc=%d (Poc): ",
- * p_Vid->framepoc);
- * for (i=0; i<currSlice->listXsize[0]; i++) {
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL, "%d ",
- * currSlice->listX[0][i]->poc);
- * }
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL, "\n");
- */
- /* dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "currSlice->listX[1] currPoc=%d (Poc): ",
- * p_Vid->framepoc);
- * for (i=0; i<currSlice->listXsize[1]; i++) {
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL, "%d ",
- * currSlice->listX[1][i]->poc);
- * }
- * dpb_print(p_H264_Dpb->decoder_index,
- * PRINT_FLAG_DPB_DETAIL,
- * "\n");
- */
-
- /* long term handling */
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++)
- fs_listlt[listltidx++] = p_Dpb->fs_ltref[i];
-
- qsort((void *)fs_listlt, listltidx,
- sizeof(struct FrameStore *),
- compare_fs_by_lt_pic_idx_asc);
-
- gen_pic_list_from_frame_list(currSlice->structure,
- fs_listlt, listltidx,
- currSlice->listX[0],
- &currSlice->listXsize[0], 1);
- gen_pic_list_from_frame_list(currSlice->structure,
- fs_listlt, listltidx,
- currSlice->listX[1],
- &currSlice->listXsize[1], 1);
-
- /* free(fs_list0); */
- /* free(fs_list1); */
- /* free(fs_listlt); */
- }
- }
-
- if ((currSlice->listXsize[0] == currSlice->listXsize[1]) &&
- (currSlice->listXsize[0] > 1)) {
- /* check if lists are identical,
- *if yes swap first two elements of currSlice->listX[1]
- */
- int diff = 0;
-
- for (j = 0; j < currSlice->listXsize[0]; j++) {
- if (currSlice->listX[0][j] !=
- currSlice->listX[1][j]) {
- diff = 1;
- break;
- }
- }
- if (!diff) {
- struct StorablePicture *tmp_s =
- currSlice->listX[1][0];
- currSlice->listX[1][0] = currSlice->listX[1][1];
- currSlice->listX[1][1] = tmp_s;
- }
- }
-
- /* set max size */
- currSlice->listXsize[0] = (char) imin(currSlice->listXsize[0],
- currSlice->num_ref_idx_active[LIST_0]);
- currSlice->listXsize[1] = (char) imin(currSlice->listXsize[1],
- currSlice->num_ref_idx_active[LIST_1]);
- CHECK_VALID(currSlice->listXsize[0], 0);
- CHECK_VALID(currSlice->listXsize[1], 1);
-
- /* set the unused list entries to NULL */
- for (i = currSlice->listXsize[0]; i < (MAX_LIST_SIZE); i++)
- currSlice->listX[0][i] = p_Vid->no_reference_picture;
- for (i = currSlice->listXsize[1]; i < (MAX_LIST_SIZE); i++)
- currSlice->listX[1][i] = p_Vid->no_reference_picture;
-
-#if PRINTREFLIST
-#if (MVC_EXTENSION_ENABLE)
- /* print out for h264_debug_flag purpose */
- if ((p_Vid->profile_idc == MVC_HIGH ||
- p_Vid->profile_idc == STEREO_HIGH) &&
- currSlice->current_slice_nr == 0) {
- if ((currSlice->listXsize[0] > 0) ||
- (currSlice->listXsize[1] > 0))
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- if (currSlice->listXsize[0] > 0) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (CurViewID:%d %d) %s Ref Pic List 0 ****\n",
- currSlice->view_id,
- currSlice->ThisPOC,
- currSlice->structure == FRAME ? "FRM" :
- (currSlice->structure == TOP_FIELD ?
- "TOP" : "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[0]); i++) { /* ref list 0 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[0][i]->poc,
- currSlice->listX[0][i]->pic_num,
- currSlice->listX[0][i]->view_id);
- }
- }
- if (currSlice->listXsize[1] > 0) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (CurViewID:%d %d) %s Ref Pic List 1 ****\n",
- currSlice->view_id,
- currSlice->ThisPOC,
- currSlice->structure == FRAME ? "FRM" :
- (currSlice->structure == TOP_FIELD ? "TOP" :
- "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[1]); i++) { /* ref list 1 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[1][i]->poc,
- currSlice->listX[1][i]->pic_num,
- currSlice->listX[1][i]->view_id);
- }
- }
- }
-#endif
-#endif
-}
-
-static struct StorablePicture *get_short_term_pic(struct Slice *currSlice,
- struct DecodedPictureBuffer *p_Dpb, int picNum)
-{
- unsigned int i;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Dpb,
- struct h264_dpb_stru, mDPB);
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
- if (currSlice->structure == FRAME) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference == 3) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->frame == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->frame->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->frame->
- pic_num == picNum))
- return p_Dpb->fs_ref[i]->frame;
- }
- } else {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i] == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if (p_Dpb->fs_ref[i]->is_reference & 1) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->top_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->top_field->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->top_field->
- pic_num == picNum))
- return p_Dpb->fs_ref[i]->top_field;
- }
- if (p_Dpb->fs_ref[i]->is_reference & 2) {
-#ifdef ERROR_CHECK
- if (p_Dpb->fs_ref[i]->bottom_field == NULL) {
- p_H264_Dpb->dpb_error_flag = __LINE__;
- continue;
- }
-#endif
- if ((!p_Dpb->fs_ref[i]->bottom_field->
- is_long_term) &&
- (p_Dpb->fs_ref[i]->bottom_field->
- pic_num == picNum))
- return p_Dpb->fs_ref[i]->bottom_field;
- }
- }
- }
-
- return currSlice->p_Vid->no_reference_picture;
-}
-
-
-static void reorder_short_term(struct Slice *currSlice, int cur_list,
- int num_ref_idx_lX_active_minus1,
- int picNumLX, int *refIdxLX)
-{
- struct h264_dpb_stru *p_H264_Dpb = container_of(currSlice->p_Vid,
- struct h264_dpb_stru, mVideo);
-
- struct StorablePicture **RefPicListX = currSlice->listX[cur_list];
- int cIdx, nIdx;
-
- struct StorablePicture *picLX;
-
- picLX = get_short_term_pic(currSlice, currSlice->p_Dpb, picNumLX);
-
- for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX;
- cIdx--) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s: RefPicListX[ %d ] = RefPicListX[ %d ]\n",
- __func__, cIdx, cIdx - 1);
- RefPicListX[cIdx] = RefPicListX[cIdx - 1];
- }
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s: RefPicListX[ %d ] = pic %x (%d)\n", __func__,
- *refIdxLX, picLX, picNumLX);
-
- RefPicListX[(*refIdxLX)++] = picLX;
-
- nIdx = *refIdxLX;
-
- for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1;
- cIdx++) {
- if (RefPicListX[cIdx])
- if ((RefPicListX[cIdx]->is_long_term) ||
- (RefPicListX[cIdx]->pic_num != picNumLX)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "%s: RefPicListX[ %d ] = RefPicListX[ %d ]\n",
- __func__, nIdx, cIdx);
- RefPicListX[nIdx++] = RefPicListX[cIdx];
- }
- }
-}
-
-
-static struct StorablePicture *get_long_term_pic(struct Slice *currSlice,
- struct DecodedPictureBuffer *p_Dpb, int LongtermPicNum)
-{
- unsigned int i;
-
- for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
- if (currSlice->structure == FRAME) {
- if (p_Dpb->fs_ltref[i]->is_reference == 3)
- if ((p_Dpb->fs_ltref[i]->frame) &&
- (p_Dpb->fs_ltref[i]->frame->
- is_long_term) &&
- (p_Dpb->fs_ltref[i]->frame->
- long_term_pic_num ==
- LongtermPicNum))
- return p_Dpb->fs_ltref[i]->frame;
- } else {
- if (p_Dpb->fs_ltref[i]->is_reference & 1)
- if ((p_Dpb->fs_ltref[i]->top_field) &&
- (p_Dpb->fs_ltref[i]->top_field->
- is_long_term) &&
- (p_Dpb->fs_ltref[i]->top_field->
- long_term_pic_num == LongtermPicNum))
- return p_Dpb->fs_ltref[i]->top_field;
-
- if (p_Dpb->fs_ltref[i]->is_reference & 2)
- if ((p_Dpb->fs_ltref[i]->bottom_field) &&
- (p_Dpb->fs_ltref[i]->bottom_field->
- is_long_term) &&
- (p_Dpb->fs_ltref[i]->bottom_field->
- long_term_pic_num ==
- LongtermPicNum))
- return p_Dpb->fs_ltref[i]->
- bottom_field;
- }
- }
- return NULL;
-}
-
-/*!
- ************************************************************************
- * \brief
- * Reordering process for long-term reference pictures
- *
- ************************************************************************
- */
-static void reorder_long_term(struct Slice *currSlice,
- struct StorablePicture **RefPicListX,
- int num_ref_idx_lX_active_minus1,
- int LongTermPicNum, int *refIdxLX)
-{
- int cIdx, nIdx;
-
- struct StorablePicture *picLX;
-
- picLX = get_long_term_pic(currSlice, currSlice->p_Dpb, LongTermPicNum);
-
- for (cIdx = num_ref_idx_lX_active_minus1 + 1; cIdx > *refIdxLX; cIdx--)
- RefPicListX[cIdx] = RefPicListX[cIdx - 1];
-
- RefPicListX[(*refIdxLX)++] = picLX;
-
- nIdx = *refIdxLX;
-
- for (cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1 + 1;
- cIdx++) {
- if (RefPicListX[cIdx]) {
- if ((!RefPicListX[cIdx]->is_long_term) ||
- (RefPicListX[cIdx]->long_term_pic_num !=
- LongTermPicNum))
- RefPicListX[nIdx++] = RefPicListX[cIdx];
- }
- }
-}
-
-static void reorder_ref_pic_list(struct Slice *currSlice, int cur_list)
-{
- int *modification_of_pic_nums_idc =
- currSlice->modification_of_pic_nums_idc[cur_list];
- int *abs_diff_pic_num_minus1 =
- currSlice->abs_diff_pic_num_minus1[cur_list];
- int *long_term_pic_idx = currSlice->long_term_pic_idx[cur_list];
- int num_ref_idx_lX_active_minus1 =
- currSlice->num_ref_idx_active[cur_list] - 1;
-
- struct VideoParameters *p_Vid = currSlice->p_Vid;
- int i;
-
- int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
- int refIdxLX = 0;
-
- if (currSlice->structure == FRAME) {
- maxPicNum = p_Vid->max_frame_num;
- currPicNum = currSlice->frame_num;
- } else {
- maxPicNum = 2 * p_Vid->max_frame_num;
- currPicNum = 2 * currSlice->frame_num + 1;
- }
-
- picNumLXPred = currPicNum;
-
- for (i = 0; i < REORDERING_COMMAND_MAX_SIZE &&
- modification_of_pic_nums_idc[i] != 3; i++) {
- if (modification_of_pic_nums_idc[i] > 3) {
- struct h264_dpb_stru *p_H264_Dpb =
- container_of(p_Vid, struct h264_dpb_stru, mVideo);
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "error, Invalid modification_of_pic_nums_idc command\n");
- /*h264_debug_flag = 0x1f;*/
- break;
- }
- if (modification_of_pic_nums_idc[i] < 2) {
- if (modification_of_pic_nums_idc[i] == 0) {
- if (picNumLXPred - (abs_diff_pic_num_minus1[i]
- + 1) < 0)
- picNumLXNoWrap = picNumLXPred -
- (abs_diff_pic_num_minus1[i] + 1) +
- maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred -
- (abs_diff_pic_num_minus1[i] + 1);
- } else { /* (modification_of_pic_nums_idc[i] == 1) */
- if (picNumLXPred + (abs_diff_pic_num_minus1[i]
- + 1) >= maxPicNum)
- picNumLXNoWrap = picNumLXPred +
- (abs_diff_pic_num_minus1[i] + 1) -
- maxPicNum;
- else
- picNumLXNoWrap = picNumLXPred +
- (abs_diff_pic_num_minus1[i] + 1);
- }
- picNumLXPred = picNumLXNoWrap;
-
- if (picNumLXNoWrap > currPicNum)
- picNumLX = picNumLXNoWrap - maxPicNum;
- else
- picNumLX = picNumLXNoWrap;
-
-#if (MVC_EXTENSION_ENABLE)
- reorder_short_term(currSlice, cur_list,
- num_ref_idx_lX_active_minus1, picNumLX,
- &refIdxLX, -1);
-#else
- reorder_short_term(currSlice, cur_list,
- num_ref_idx_lX_active_minus1, picNumLX,
- &refIdxLX);
-#endif
- } else { /* (modification_of_pic_nums_idc[i] == 2) */
-#if (MVC_EXTENSION_ENABLE)
- reorder_long_term(currSlice, currSlice->listX[cur_list],
- num_ref_idx_lX_active_minus1,
- long_term_pic_idx[i], &refIdxLX, -1);
-#else
- reorder_long_term(currSlice, currSlice->listX[cur_list],
- num_ref_idx_lX_active_minus1,
- long_term_pic_idx[i], &refIdxLX);
-#endif
- }
-
- }
- /* that's a definition */
- currSlice->listXsize[cur_list] =
- (char)(num_ref_idx_lX_active_minus1 + 1);
-}
-
-static void reorder_lists(struct Slice *currSlice)
-{
- struct VideoParameters *p_Vid = currSlice->p_Vid;
- struct h264_dpb_stru *p_H264_Dpb = container_of(p_Vid,
- struct h264_dpb_stru, mVideo);
- int i;
-
- if ((currSlice->slice_type != I_SLICE) &&
- (currSlice->slice_type != SI_SLICE)) {
- if (currSlice->ref_pic_list_reordering_flag[LIST_0])
- reorder_ref_pic_list(currSlice, LIST_0);
- if (p_Vid->no_reference_picture ==
- currSlice->
- listX[0][currSlice->num_ref_idx_active[LIST_0] - 1]) {
- if (p_Vid->non_conforming_stream)
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "RefPicList0[ %d ] is equal to 'no reference picture'\n",
- currSlice->
- num_ref_idx_active[LIST_0] - 1);
- else
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "RefPicList0 [ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream %d\n",
- 500);
- }
- /* that's a definition */
- currSlice->listXsize[0] =
- (char) imin(currSlice->listXsize[0],
- currSlice->num_ref_idx_active[LIST_0]);
- CHECK_VALID(currSlice->listXsize[0], 0);
- if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "listX[0] reorder (PicNum): ");
- for (i = 0; i < currSlice->listXsize[0]; i++) {
- dpb_print_cont(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[0][i]->pic_num);
- }
- dpb_print_cont(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- }
- }
-
- if (currSlice->slice_type == B_SLICE) {
- if (currSlice->ref_pic_list_reordering_flag[LIST_1])
- reorder_ref_pic_list(currSlice, LIST_1);
- if (p_Vid->no_reference_picture ==
- currSlice->listX[1][currSlice->
- num_ref_idx_active[LIST_1] - 1]) {
- if (p_Vid->non_conforming_stream)
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "RefPicList1[ %d ] is equal to 'no reference picture'\n",
- currSlice->
- num_ref_idx_active[LIST_1] - 1);
- else
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "RefPicList1 [ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture', invalid bitstream %d\n",
- 500);
- }
- /* that's a definition */
- currSlice->listXsize[1] =
- (char)currSlice->num_ref_idx_active[LIST_1];
- if (h264_debug_flag & PRINT_FLAG_DPB_DETAIL) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "listX[1] reorder (PicNum): ");
- for (i = 0; i < currSlice->listXsize[1]; i++) {
- if (currSlice->listX[1][i])
- dpb_print_cont(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "%d ",
- currSlice->listX[1][i]->pic_num);
- }
- dpb_print_cont(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- }
- }
-
- /* free_ref_pic_list_reordering_buffer(currSlice); */
-
- if (currSlice->slice_type == P_SLICE) {
-#if PRINTREFLIST
- unsigned int i;
-#if (MVC_EXTENSION_ENABLE)
- /* print out for h264_debug_flag purpose */
- if ((p_Vid->profile_idc == MVC_HIGH ||
- p_Vid->profile_idc == STEREO_HIGH) &&
- currSlice->current_slice_nr == 0) {
- if (currSlice->listXsize[0] > 0
- && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (FinalViewID:%d) %s Ref Pic List 0 ****\n",
- currSlice->view_id,
- currSlice->structure == FRAME ?
- "FRM" :
- (currSlice->structure == TOP_FIELD ?
- "TOP" : "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[0]); i++) { /* ref list 0 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[0][i]->poc,
- currSlice->listX[0][i]->
- pic_num,
- currSlice->listX[0][i]->
- view_id);
- }
- }
- }
-#endif
-#endif
- } else if (currSlice->slice_type == B_SLICE) {
-#if PRINTREFLIST
- unsigned int i;
-#if (MVC_EXTENSION_ENABLE)
- /* print out for h264_debug_flag purpose */
- if ((p_Vid->profile_idc == MVC_HIGH ||
- p_Vid->profile_idc == STEREO_HIGH) &&
- currSlice->current_slice_nr == 0) {
- if ((currSlice->listXsize[0] > 0) ||
- (currSlice->listXsize[1] > 0))
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL, "\n");
- if (currSlice->listXsize[0] > 0
- && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (FinalViewID:%d) %s Ref Pic List 0 ****\n",
- currSlice->view_id,
- currSlice->structure == FRAME ?
- "FRM" :
- (currSlice->structure == TOP_FIELD ?
- "TOP" : "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[0]); i++) { /* ref list 0 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[0][i]->poc,
- currSlice->listX[0][i]->
- pic_num,
- currSlice->listX[0][i]->
- view_id);
- }
- }
- if (currSlice->listXsize[1] > 0
- && (h264_debug_flag & PRINT_FLAG_DPB_DETAIL)) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " ** (FinalViewID:%d) %s Ref Pic List 1 ****\n",
- currSlice->view_id,
- currSlice->structure == FRAME ?
- "FRM" :
- (currSlice->structure == TOP_FIELD ?
- "TOP" : "BOT"));
- for (i = 0; i < (unsigned int)(currSlice->
- listXsize[1]); i++) { /* ref list 1 */
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- " %2d -> POC: %4d PicNum: %4d ViewID: %d\n",
- i,
- currSlice->listX[1][i]->poc,
- currSlice->listX[1][i]->
- pic_num,
- currSlice->listX[1][i]->
- view_id);
- }
- }
- }
-#endif
-
-#endif
- }
-}
-
-void init_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int count)
-{
- p_H264_Dpb->colocated_buf_map = 0;
- p_H264_Dpb->colocated_buf_count = count;
-}
-
-int allocate_colocate_buf(struct h264_dpb_stru *p_H264_Dpb)
-{
- int i;
-
- for (i = 0; i < p_H264_Dpb->colocated_buf_count; i++) {
- if (((p_H264_Dpb->colocated_buf_map >> i) & 0x1) == 0) {
- p_H264_Dpb->colocated_buf_map |= (1 << i);
- break;
- }
- }
- if (i == p_H264_Dpb->colocated_buf_count) {
- i = -1;
- p_H264_Dpb->buf_alloc_fail = 1;
- }
- return i;
-}
-
-int release_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int index)
-{
- if (index >= 0) {
- if (index >= p_H264_Dpb->colocated_buf_count) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_ERROR,
- "%s error, index %d is bigger than buf count %d\n",
- __func__, index,
- p_H264_Dpb->colocated_buf_count);
- } else {
- if (((p_H264_Dpb->colocated_buf_map >>
- index) & 0x1) == 0x1) {
- p_H264_Dpb->colocated_buf_map &=
- (~(1 << index));
- } else {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_ERROR,
- "%s error, index %d is not allocated\n",
- __func__, index);
- }
- }
- }
- return 0;
-}
-
-void set_frame_output_flag(struct h264_dpb_stru *p_H264_Dpb, int index)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- p_H264_Dpb->mFrameStore[index].is_output = 1;
- p_H264_Dpb->mFrameStore[index].pre_output = 0;
- p_H264_Dpb->mFrameStore[index].show_frame = false;
- dump_dpb(p_Dpb, 0);
-}
-
-#if 0
-void init_old_slice(OldSliceParams *p_old_slice)
-{
- p_old_slice->field_pic_flag = 0;
- p_old_slice->pps_id = INT_MAX;
- p_old_slice->frame_num = INT_MAX;
- p_old_slice->nal_ref_idc = INT_MAX;
- p_old_slice->idr_flag = 0;
-
- p_old_slice->pic_oder_cnt_lsb = UINT_MAX;
- p_old_slice->delta_pic_oder_cnt_bottom = INT_MAX;
-
- p_old_slice->delta_pic_order_cnt[0] = INT_MAX;
- p_old_slice->delta_pic_order_cnt[1] = INT_MAX;
-}
-
-
-void copy_slice_info(struct Slice *currSlice, OldSliceParams *p_old_slice)
-{
- struct VideoParameters *p_Vid = currSlice->p_Vid;
-
- p_old_slice->pps_id = currSlice->pic_parameter_set_id;
- p_old_slice->frame_num = currSlice->frame_num;
- /* p_Vid->frame_num; */
- p_old_slice->field_pic_flag =
- currSlice->field_pic_flag;
- /* p_Vid->field_pic_flag; */
-
- if (currSlice->field_pic_flag)
- p_old_slice->bottom_field_flag = currSlice->bottom_field_flag;
-
- p_old_slice->nal_ref_idc = currSlice->nal_reference_idc;
- p_old_slice->idr_flag = (byte) currSlice->idr_flag;
-
- if (currSlice->idr_flag)
- p_old_slice->idr_pic_id = currSlice->idr_pic_id;
-
- if (p_Vid->active_sps->pic_order_cnt_type == 0) {
- p_old_slice->pic_oder_cnt_lsb =
- currSlice->pic_order_cnt_lsb;
- p_old_slice->delta_pic_oder_cnt_bottom =
- currSlice->delta_pic_order_cnt_bottom;
- }
-
- if (p_Vid->active_sps->pic_order_cnt_type == 1) {
- p_old_slice->delta_pic_order_cnt[0] =
- currSlice->delta_pic_order_cnt[0];
- p_old_slice->delta_pic_order_cnt[1] =
- currSlice->delta_pic_order_cnt[1];
- }
-#if (MVC_EXTENSION_ENABLE)
- p_old_slice->view_id = currSlice->view_id;
- p_old_slice->inter_view_flag = currSlice->inter_view_flag;
- p_old_slice->anchor_pic_flag = currSlice->anchor_pic_flag;
-#endif
- p_old_slice->layer_id = currSlice->layer_id;
-}
-
-int is_new_picture(StorablePicture *dec_picture, struct Slice *currSlice,
- OldSliceParams *p_old_slice)
-{
- struct VideoParameters *p_Vid = currSlice->p_Vid;
-
- int result = 0;
-
- result |= (dec_picture == NULL);
-
- result |= (p_old_slice->pps_id != currSlice->pic_parameter_set_id);
-
- result |= (p_old_slice->frame_num != currSlice->frame_num);
-
- result |= (p_old_slice->field_pic_flag != currSlice->field_pic_flag);
-
- if (currSlice->field_pic_flag && p_old_slice->field_pic_flag) {
- result |= (p_old_slice->bottom_field_flag !=
- currSlice->bottom_field_flag);
- }
-
- result |= (p_old_slice->nal_ref_idc !=
- currSlice->nal_reference_idc) &&
- ((p_old_slice->nal_ref_idc == 0) ||
- (currSlice->nal_reference_idc == 0));
- result |= (p_old_slice->idr_flag != currSlice->idr_flag);
-
- if (currSlice->idr_flag && p_old_slice->idr_flag)
- result |= (p_old_slice->idr_pic_id != currSlice->idr_pic_id);
-
- if (p_Vid->active_sps->pic_order_cnt_type == 0) {
- result |= (p_old_slice->pic_oder_cnt_lsb !=
- currSlice->pic_order_cnt_lsb);
- if (p_Vid->active_pps->
- bottom_field_pic_order_in_frame_present_flag == 1 &&
- !currSlice->field_pic_flag) {
- result |= (p_old_slice->delta_pic_oder_cnt_bottom !=
- currSlice->delta_pic_order_cnt_bottom);
- }
- }
-
- if (p_Vid->active_sps->pic_order_cnt_type == 1) {
- if (!p_Vid->active_sps->delta_pic_order_always_zero_flag) {
- result |= (p_old_slice->delta_pic_order_cnt[0] !=
- currSlice->delta_pic_order_cnt[0]);
- if (p_Vid->active_pps->
- bottom_field_pic_order_in_frame_present_flag == 1 &&
- !currSlice->field_pic_flag) {
- result |= (p_old_slice->
- delta_pic_order_cnt[1] !=
- currSlice->delta_pic_order_cnt[1]);
- }
- }
- }
-
-#if (MVC_EXTENSION_ENABLE)
- result |= (currSlice->view_id != p_old_slice->view_id);
- result |= (currSlice->inter_view_flag != p_old_slice->inter_view_flag);
- result |= (currSlice->anchor_pic_flag != p_old_slice->anchor_pic_flag);
-#endif
- result |= (currSlice->layer_id != p_old_slice->layer_id);
- return result;
-}
-#else
-int is_new_picture(struct StorablePicture *dec_picture,
- struct h264_dpb_stru *p_H264_Dpb,
- struct OldSliceParams *p_old_slice)
-{
- int ret = 0;
-
- if (p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] == 0)
- ret = 1;
- return ret;
-}
-
-#endif
-
-/*
-* release bufspec and pic for picture not in dpb buf
-*/
-int release_picture(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *pic)
-{
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- if (p_Dpb->last_picture == NULL) {
- if (pic->colocated_buf_index >= 0) {
- release_colocate_buf(p_H264_Dpb,
- pic->colocated_buf_index);
- pic->colocated_buf_index = -1;
- }
- release_buf_spec_num(p_H264_Dpb->vdec, pic->buf_spec_num);
- } else {
- if (pic->buf_spec_is_alloced == 1)
- release_buf_spec_num(p_H264_Dpb->vdec,
- pic->buf_spec_num);
- }
-
- free_picture(p_H264_Dpb, pic);
- return 0;
-}
-
-#ifdef ERROR_HANDLE_TEST
-/*
-* remove all pictures in dpb and release bufspec/pic of them
-*/
-void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb)
-{
- /* struct VideoParameters *p_Vid = p_Dpb->p_Vid; */
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- struct Slice *currSlice = &p_H264_Dpb->mSlice;
- unsigned i, j;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s\n", __func__);
-
- if (!p_Dpb->init_done)
- return;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->colocated_buf_index >= 0) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "release_colocate_buf[%d] for fs[%d]\n",
- p_Dpb->fs[i]->colocated_buf_index, i);
-
- release_colocate_buf(p_H264_Dpb,
- p_Dpb->fs[i]->colocated_buf_index); /* rain */
- p_Dpb->fs[i]->colocated_buf_index = -1;
- }
- if (!p_Dpb->fs[i]->pre_output) {
- release_buf_spec_num(p_H264_Dpb->vdec,
- p_Dpb->fs[i]->buf_spec_num);
- p_Dpb->fs[i]->buf_spec_num = -1;
- }
- remove_frame_from_dpb(p_H264_Dpb, i);
- }
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- p_Dpb->fs_ref[i] = NULL;
- p_Dpb->fs_ltref[i] = NULL;
- p_Dpb->fs_list0[i] = NULL;
- p_Dpb->fs_list1[i] = NULL;
- p_Dpb->fs_listlt[i] = NULL;
- }
- for (i = 0; i < 2; i++) {
- currSlice->listXsize[i] = 0;
- for (j = 0; j < (MAX_LIST_SIZE * 2); j++)
- currSlice->listX[i][j] = NULL;
- }
- p_Dpb->ref_frames_in_buffer = 0;
- p_Dpb->ltref_frames_in_buffer = 0;
- p_Dpb->last_output_poc = INT_MIN;
-}
-#endif
-
-static void check_frame_store_same_pic_num(struct DecodedPictureBuffer *p_Dpb,
- struct StorablePicture *p, struct Slice *currSlice)
-{
- if (p_Dpb->last_picture) {
- if ((int)p_Dpb->last_picture->frame_num == p->pic_num) {
- if (((p->structure == TOP_FIELD) &&
- (p_Dpb->last_picture->is_used == 2)) ||
- ((p->structure == BOTTOM_FIELD) &&
- (p_Dpb->last_picture->is_used == 1))) {
- if ((p->used_for_reference &&
- (p_Dpb->last_picture->
- is_orig_reference != 0)) ||
- (!p->used_for_reference &&
- (p_Dpb->last_picture->
- is_orig_reference == 0))) {
- p->buf_spec_num =
- p_Dpb->last_picture->
- buf_spec_num;
- p->buf_spec_is_alloced = 0;
- p->colocated_buf_index = p_Dpb->
- last_picture->
- colocated_buf_index;
- if (currSlice->structure ==
- TOP_FIELD) {
- p->bottom_poc =
- p_Dpb->last_picture->
- bottom_field->poc;
- } else {
- p->top_poc =
- p_Dpb->last_picture->
- top_field->poc;
- }
- p->frame_poc = imin(p->bottom_poc,
- p->top_poc);
- }
- }
- }
- }
-}
-
-int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap)
-{
-
- int new_pic_flag = 0;
- struct Slice *currSlice = &p_H264_Dpb->mSlice;
- struct VideoParameters *p_Vid = &p_H264_Dpb->mVideo;
- struct DecodedPictureBuffer *p_Dpb =
- &p_H264_Dpb->mDPB;
-#if 0
- new_pic_flag = is_new_picture(p_H264_Dpb->mVideo.dec_picture,
- p_H264_Dpb,
- &p_H264_Dpb->mVideo.old_slice);
-
- if (new_pic_flag) { /* new picture */
- if (p_H264_Dpb->mVideo.dec_picture) {
- store_picture_in_dpb(p_H264_Dpb,
- p_H264_Dpb->mVideo.dec_picture);
- /* dump_dpb(&p_H264_Dpb->mDPB); */
- }
- }
-#else
- new_pic_flag = (p_H264_Dpb->mVideo.dec_picture == NULL);
-#endif
- p_H264_Dpb->buf_alloc_fail = 0;
- p_H264_Dpb->dpb_error_flag = 0;
- slice_prepare(p_H264_Dpb, &p_H264_Dpb->mDPB, &p_H264_Dpb->mVideo,
- &p_H264_Dpb->mSPS, &p_H264_Dpb->mSlice);
-
- if (p_Dpb->num_ref_frames != p_H264_Dpb->mSPS.num_ref_frames) {
- dpb_print(p_H264_Dpb->decoder_index, 0,
- "num_ref_frames change from %d to %d\r\n",
- p_Dpb->num_ref_frames, p_H264_Dpb->mSPS.num_ref_frames);
- p_Dpb->num_ref_frames = p_H264_Dpb->mSPS.num_ref_frames;
- }
- /* if (p_Vid->active_sps != sps) { */
- if (p_H264_Dpb->mDPB.init_done == 0) {
- /*init_global_buffers(p_Vid, 0);
- * ** * *if (!p_Vid->no_output_of_prior_pics_flag)
- ** * *{
- ** * * flush_dpb(p_Vid->p_Dpb_layer[0]);
- ** * *}
- ** * *init_dpb(p_Vid, p_Vid->p_Dpb_layer[0], 0);
- */
- init_dpb(p_H264_Dpb, 0);
- }
-
-
- if (new_pic_flag) { /* new picture */
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "check frame_num gap: cur frame_num %d pre_frame_num %d max_frmae_num %d\r\n",
- currSlice->frame_num,
- p_Vid->pre_frame_num,
- p_Vid->max_frame_num);
- if (p_Vid->recovery_point == 0 &&
- p_Vid->max_frame_num <= FRAME_NUM_MAX_SIZE &&
- currSlice->frame_num != p_Vid->pre_frame_num &&
- currSlice->frame_num !=
- (p_Vid->pre_frame_num + 1) % p_Vid->max_frame_num) {
- struct SPSParameters *active_sps = p_Vid->active_sps;
- /*if (active_sps->
- *gaps_in_frame_num_value_allowed_flag
- *== 0) {
- * error("An unintentional
- * loss of pictures occurs! Exit\n",
- * 100);
- *}
- *if (p_Vid->conceal_mode == 0)
- */
- if (active_sps->frame_num_gap_allowed)
- fill_frame_num_gap(p_Vid, currSlice);
- *frame_num_gap = 1;
- }
-
- if (currSlice->nal_reference_idc) {
- dpb_print(p_H264_Dpb->decoder_index,
- PRINT_FLAG_DPB_DETAIL,
- "nal_reference_idc not 0, set pre_frame_num(%d) to frame_num (%d)\n",
- p_Vid->pre_frame_num, currSlice->frame_num);
- p_Vid->pre_frame_num = currSlice->frame_num;
- }
-
- decode_poc(&p_H264_Dpb->mVideo, &p_H264_Dpb->mSlice);
- p_H264_Dpb->mVideo.dec_picture = get_new_pic(p_H264_Dpb,
- p_H264_Dpb->mSlice.structure,
- /*p_Vid->width, p_Vid->height,
- * p_Vid->width_cr,
- * p_Vid->height_cr,
- */
- 1);
- if (p_H264_Dpb->mVideo.dec_picture) {
- u32 offset_lo, offset_hi;
- struct DecodedPictureBuffer *p_Dpb =
- &p_H264_Dpb->mDPB;
- struct StorablePicture *p =
- p_H264_Dpb->mVideo.dec_picture;
- init_picture(p_H264_Dpb, &p_H264_Dpb->mSlice,
- p_H264_Dpb->mVideo.dec_picture);
-#if 1
- /* rain */
- offset_lo =
- p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_LO];
- offset_hi =
- p_H264_Dpb->dpb_param.l.data[OFFSET_DELIMITER_HI];
- p_H264_Dpb->mVideo.dec_picture->offset_delimiter =
- (offset_lo | offset_hi << 16);
- p_H264_Dpb->mVideo.dec_picture->buf_spec_num = -1;
- p_H264_Dpb->mVideo.dec_picture->
- colocated_buf_index = -1;
- update_pic_num(p_H264_Dpb);
-
- if ((currSlice->structure == TOP_FIELD) ||
- (currSlice->structure == BOTTOM_FIELD)) {
- /* check for frame store with same
- * pic_number
- */
- check_frame_store_same_pic_num(p_Dpb, p,
- currSlice);
- }
-
- if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num ==
- -1) {
- p_H264_Dpb->mVideo.dec_picture->buf_spec_num =
- get_free_buf_idx(p_H264_Dpb->vdec);
- if (p_H264_Dpb->mVideo.dec_picture->buf_spec_num
- < 0) {
- p_H264_Dpb->buf_alloc_fail = 1;
- p_H264_Dpb->mVideo.dec_picture->
- buf_spec_is_alloced = 0;
- } else
- p_H264_Dpb->mVideo.dec_picture->
- buf_spec_is_alloced = 1;
-
- if (p_H264_Dpb->mVideo.dec_picture->
- used_for_reference) {
- p_H264_Dpb->mVideo.dec_picture->
- colocated_buf_index =
- allocate_colocate_buf(
- p_H264_Dpb);
- }
- }
-#endif
- if (post_picture_early(p_H264_Dpb->vdec,
- p_H264_Dpb->mVideo.dec_picture->buf_spec_num))
- return -1;
- }
- }
-
- if (p_H264_Dpb->buf_alloc_fail)
- return -1;
-
- if (p_H264_Dpb->mSlice.slice_type == P_SLICE)
- init_lists_p_slice(&p_H264_Dpb->mSlice);
- else if (p_H264_Dpb->mSlice.slice_type == B_SLICE)
- init_lists_b_slice(&p_H264_Dpb->mSlice);
- else
- init_lists_i_slice(&p_H264_Dpb->mSlice);
-
- reorder_lists(&p_H264_Dpb->mSlice);
-
- if (p_H264_Dpb->mSlice.structure == FRAME)
- init_mbaff_lists(p_H264_Dpb, &p_H264_Dpb->mSlice);
-
- if (new_pic_flag)
- return 1;
-
- return 0;
-}
-
-enum PictureStructure get_cur_slice_picture_struct(
- struct h264_dpb_stru *p_H264_Dpb)
-{
- struct Slice *currSlice = &p_H264_Dpb->mSlice;
- return currSlice->structure;
-}
-
-static unsigned char is_pic_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *pic)
-{
- unsigned char ret = 0;
- int i;
- struct DecodedPictureBuffer *p_Dpb =
- &p_H264_Dpb->mDPB;
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->top_field == pic ||
- p_Dpb->fs[i]->bottom_field == pic ||
- p_Dpb->fs[i]->frame == pic) {
- ret = 1;
- break;
- }
- }
- return ret;
-}
-
-int dpb_check_ref_list_error(
- struct h264_dpb_stru *p_H264_Dpb)
-{
- int i;
- /*int j;*/
- struct Slice *currSlice = &p_H264_Dpb->mSlice;
- /* in first output, ignore ref check */
- if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) &&
- (p_H264_Dpb->mVideo.dec_picture) &&
- p_H264_Dpb->first_output_poc > p_H264_Dpb->mVideo.dec_picture->poc) {
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "p_H264_Dpb->first_output_poc %d, p_H264_Dpb->mVideo.dec_picture->poc %d\n",
- p_H264_Dpb->first_output_poc, p_H264_Dpb->mVideo.dec_picture->poc);
- return 0;
- }
- if ((currSlice->slice_type != I_SLICE) &&
- (currSlice->slice_type != SI_SLICE)) {
- for (i = 0; i < currSlice->listXsize[0]; i++) {
- /*for (j = i + 1; j < currSlice->listXsize[0]; j++) {
- if(currSlice->listX[0][i]->pic_num ==
- currSlice->listX[0][j]->pic_num)
- return 1;
- }*/
- if (currSlice->listX[0][i] == NULL)
- return 5;
- if (!is_pic_in_dpb(p_H264_Dpb,
- currSlice->listX[0][i]))
- return 1;
- if (currSlice->listX[0][i]->frame &&
- currSlice->listX[0][i]->frame->non_existing)
- return 3;
- }
- }
-
- if (currSlice->slice_type == B_SLICE) {
- for (i = 0; i < currSlice->listXsize[1]; i++) {
- /*for (j = i + 1; j < currSlice->listXsize[1]; j++) {
- if(currSlice->listX[1][i]->pic_num ==
- currSlice->listX[1][j]->pic_num)
- return 2;
- }
- for (j = 0; j < currSlice->listXsize[0]; j++) {
- if(currSlice->listX[1][i]->pic_num ==
- currSlice->listX[0][j]->pic_num)
- return 3;
- }*/
- if (currSlice->listX[1][i] == NULL)
- return 6;
- if (!is_pic_in_dpb(p_H264_Dpb,
- currSlice->listX[1][i]))
- return 2;
- if (currSlice->listX[1][i]->frame &&
- currSlice->listX[1][i]->frame->non_existing)
- return 4;
-#if 0
- if (currSlice->listXsize[0] == 1 &&
- currSlice->listXsize[1] == 1 &&
- currSlice->listX[1][0] ==
- currSlice->listX[0][0])
- return 3;
-#endif
- }
- }
- return 0;
-}
-
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h
deleted file mode 100644
index e1d1ab4..0000000
--- a/drivers/frame_provider/decoder_v4l/h264_multi/h264_dpb.h
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef H264_DPB_H_
-#define H264_DPB_H_
-
-#define ERROR_CHECK
-
-#define OUTPUT_BUFFER_IN_C
-
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_VDEC_STATUS 0X0001
-#define PRINT_FLAG_UCODE_EVT 0x0002
-#define PRINT_FLAG_MMU_DETAIL 0x0004
-#define PRINT_FLAG_ERRORFLAG_DBG 0x0008
-#define PRINT_FLAG_DPB_DETAIL 0x0010
-#define PRINT_FLAG_DEC_DETAIL 0x0020
-#define PRINT_FLAG_VDEC_DETAIL 0x0040
-#define PRINT_FLAG_DUMP_DPB 0x0080
-#define PRINT_FRAMEBASE_DATA 0x0100
-#define PRINT_FLAG_DEBUG_POC 0x0200
-#define RRINT_FLAG_RPM 0x0400
-#define DEBUG_DISABLE_RUNREADY_RMBUF 0x0800
-#define PRINT_FLAG_DUMP_BUFSPEC 0x1000
-#define PRINT_FLAG_FCC_STATUS 0x2000
-#define PRINT_FLAG_SEI_DETAIL 0x4000
-#define PRINT_FLAG_V4L_DETAIL 0x8000
-#define DISABLE_ERROR_HANDLE 0x10000
-#define DEBUG_DUMP_STAT 0x80000
-#define DEBUG_TIMEOUT_DEC_STAT 0x800000
-
-/*setting canvas mode and endian.
- if this flag is set, value of canvas mode
- will according to the value of mem_map_mode.
- endian will be forced set to 0 in
- CANVAS_BLKMODE_LINEAR mode.
- otherwise picture will display abnormal.
- if this flag is not set, value of canvas mode
- will be determined by the user speace config.
- endian will be set 7 in CANVAS_BLKMODE_LINEAR mode.
-*/
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-
-#define MVC_EXTENSION_ENABLE 0
-#define PRINTREFLIST 0
-
-#define MAX_LIST_SIZE 33
-
-#define H264_OUTPUT_MODE_NORMAL 0x4
-#define H264_OUTPUT_MODE_FAST 0x8
-
-//#define FALSE 0
-
-#define H264_SLICE_HEAD_DONE 0x01
-#define H264_PIC_DATA_DONE 0x02
-/*#define H264_SPS_DONE 0x03*/
-/*#define H264_PPS_DONE 0x04*/
-/*#define H264_SLICE_DATA_DONE 0x05*/
-/*#define H264_DATA_END 0x06*/
-
-#define H264_CONFIG_REQUEST 0x11
-#define H264_DATA_REQUEST 0x12
-#define H264_WRRSP_REQUEST 0x13
-#define H264_WRRSP_DONE 0x14
-
-#define H264_DECODE_BUFEMPTY 0x20
-#define H264_DECODE_TIMEOUT 0x21
-#define H264_SEARCH_BUFEMPTY 0x22
-#define H264_DECODE_OVER_SIZE 0x23
-
-#define VIDEO_SIGNAL_LOW 0x26
-#define VIDEO_SIGNAL_HIGHT 0x27
-
-
-#define H264_FIND_NEXT_PIC_NAL 0x50
-#define H264_FIND_NEXT_DVEL_NAL 0x51
-#define H264_AUX_DATA_READY 0x52
-
-#define H264_SEI_DATA_READY 0x53
-#define H264_SEI_DATA_DONE 0x54
-
- /* 0x8x, search state*/
-#define H264_STATE_SEARCH_AFTER_SPS 0x80
-#define H264_STATE_SEARCH_AFTER_PPS 0x81
-#define H264_STATE_PARSE_SLICE_HEAD 0x82
-#define H264_STATE_SEARCH_HEAD 0x83
- /**/
-#define H264_ACTION_SEARCH_HEAD 0xf0
-#define H264_ACTION_DECODE_SLICE 0xf1
-#define H264_ACTION_CONFIG_DONE 0xf2
-#define H264_ACTION_DECODE_NEWPIC 0xf3
-#define H264_ACTION_DECODE_START 0xff
-
-#define RPM_BEGIN 0x0
-#define RPM_END 0x400
-
-#define val(s) (s[0]|(s[1]<<16))
-
-#define FRAME_IN_DPB 24
-#define DPB_OFFSET 0x100
-#define MMCO_OFFSET 0x200
-union param {
-#if 0
-#define H_TIME_STAMP_START 0X00
-#define H_TIME_STAMP_END 0X17
-#define PTS_ZERO_0 0X18
-#define PTS_ZERO_1 0X19
-#endif
-#define FIXED_FRAME_RATE_FLAG 0X21
-
-#define OFFSET_DELIMITER_LO 0x2f
-#define OFFSET_DELIMITER_HI 0x30
-
-
-#define SLICE_IPONLY_BREAK 0X5C
-#define PREV_MAX_REFERENCE_FRAME_NUM 0X5D
-#define EOS 0X5E
-#define FRAME_PACKING_TYPE 0X5F
-#define OLD_POC_PAR_1 0X60
-#define OLD_POC_PAR_2 0X61
-#define PREV_MBX 0X62
-#define PREV_MBY 0X63
-#define ERROR_SKIP_MB_NUM 0X64
-#define ERROR_MB_STATUS 0X65
-#define L0_PIC0_STATUS 0X66
-#define TIMEOUT_COUNTER 0X67
-#define BUFFER_SIZE 0X68
-#define BUFFER_SIZE_HI 0X69
-#define CROPPING_LEFT_RIGHT 0X6A
-#define CROPPING_TOP_BOTTOM 0X6B
-#if 1
- /* sps_flags2:
- *bit 3, bitstream_restriction_flag
- *bit 2, pic_struct_present_flag
- *bit 1, vcl_hrd_parameters_present_flag
- *bit 0, nal_hrd_parameters_present_flag
- */
-#define SPS_FLAGS2 0x6c
-#define NUM_REORDER_FRAMES 0x6d
-#else
-#define POC_SELECT_NEED_SWAP 0X6C
-#define POC_SELECT_SWAP 0X6D
-#endif
-#define MAX_BUFFER_FRAME 0X6E
-
-#define NON_CONFORMING_STREAM 0X70
-#define RECOVERY_POINT 0X71
-#define POST_CANVAS 0X72
-#define POST_CANVAS_H 0X73
-#define SKIP_PIC_COUNT 0X74
-#define TARGET_NUM_SCALING_LIST 0X75
-#define FF_POST_ONE_FRAME 0X76
-#define PREVIOUS_BIT_CNT 0X77
-#define MB_NOT_SHIFT_COUNT 0X78
-#define PIC_STATUS 0X79
-#define FRAME_COUNTER 0X7A
-#define NEW_SLICE_TYPE 0X7B
-#define NEW_PICTURE_STRUCTURE 0X7C
-#define NEW_FRAME_NUM 0X7D
-#define NEW_IDR_PIC_ID 0X7E
-#define IDR_PIC_ID 0X7F
-
-/* h264 LOCAL */
-#define NAL_UNIT_TYPE 0X80
-#define NAL_REF_IDC 0X81
-#define SLICE_TYPE 0X82
-#define LOG2_MAX_FRAME_NUM 0X83
-#define FRAME_MBS_ONLY_FLAG 0X84
-#define PIC_ORDER_CNT_TYPE 0X85
-#define LOG2_MAX_PIC_ORDER_CNT_LSB 0X86
-#define PIC_ORDER_PRESENT_FLAG 0X87
-#define REDUNDANT_PIC_CNT_PRESENT_FLAG 0X88
-#define PIC_INIT_QP_MINUS26 0X89
-#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG 0X8A
-#define NUM_SLICE_GROUPS_MINUS1 0X8B
-#define MODE_8X8_FLAGS 0X8C
-#define ENTROPY_CODING_MODE_FLAG 0X8D
-#define SLICE_QUANT 0X8E
-#define TOTAL_MB_HEIGHT 0X8F
-#define PICTURE_STRUCTURE 0X90
-#define TOP_INTRA_TYPE 0X91
-#define RV_AI_STATUS 0X92
-#define AI_READ_START 0X93
-#define AI_WRITE_START 0X94
-#define AI_CUR_BUFFER 0X95
-#define AI_DMA_BUFFER 0X96
-#define AI_READ_OFFSET 0X97
-#define AI_WRITE_OFFSET 0X98
-#define AI_WRITE_OFFSET_SAVE 0X99
-#define RV_AI_BUFF_START 0X9A
-#define I_PIC_MB_COUNT 0X9B
-#define AI_WR_DCAC_DMA_CTRL 0X9C
-#define SLICE_MB_COUNT 0X9D
-#define PICTYPE 0X9E
-#define SLICE_GROUP_MAP_TYPE 0X9F
-#define MB_TYPE 0XA0
-#define MB_AFF_ADDED_DMA 0XA1
-#define PREVIOUS_MB_TYPE 0XA2
-#define WEIGHTED_PRED_FLAG 0XA3
-#define WEIGHTED_BIPRED_IDC 0XA4
-/* bit 3:2 - PICTURE_STRUCTURE
- * bit 1 - MB_ADAPTIVE_FRAME_FIELD_FLAG
- * bit 0 - FRAME_MBS_ONLY_FLAG
- */
-#define MBFF_INFO 0XA5
-#define TOP_INTRA_TYPE_TOP 0XA6
-
-#define RV_AI_BUFF_INC 0xa7
-
-#define DEFAULT_MB_INFO_LO 0xa8
-
-/* 0 -- no need to read
- * 1 -- need to wait Left
- * 2 -- need to read Intra
- * 3 -- need to read back MV
- */
-#define NEED_READ_TOP_INFO 0xa9
-/* 0 -- idle
- * 1 -- wait Left
- * 2 -- reading top Intra
- * 3 -- reading back MV
- */
-#define READ_TOP_INFO_STATE 0xaa
-#define DCAC_MBX 0xab
-#define TOP_MB_INFO_OFFSET 0xac
-#define TOP_MB_INFO_RD_IDX 0xad
-#define TOP_MB_INFO_WR_IDX 0xae
-
-#define VLD_NO_WAIT 0
-#define VLD_WAIT_BUFFER 1
-#define VLD_WAIT_HOST 2
-#define VLD_WAIT_GAP 3
-
-#define VLD_WAITING 0xaf
-
-#define MB_X_NUM 0xb0
-/* #define MB_WIDTH 0xb1 */
-#define MB_HEIGHT 0xb2
-#define MBX 0xb3
-#define TOTAL_MBY 0xb4
-#define INTR_MSK_SAVE 0xb5
-
-/* #define has_time_stamp 0xb6 */
-#define NEED_DISABLE_PPE 0xb6
-#define IS_NEW_PICTURE 0XB7
-#define PREV_NAL_REF_IDC 0XB8
-#define PREV_NAL_UNIT_TYPE 0XB9
-#define FRAME_MB_COUNT 0XBA
-#define SLICE_GROUP_UCODE 0XBB
-#define SLICE_GROUP_CHANGE_RATE 0XBC
-#define SLICE_GROUP_CHANGE_CYCLE_LEN 0XBD
-#define DELAY_LENGTH 0XBE
-#define PICTURE_STRUCT 0XBF
-/* #define pre_picture_struct 0xc0 */
-#define DCAC_PREVIOUS_MB_TYPE 0xc1
-
-#define TIME_STAMP 0XC2
-#define H_TIME_STAMP 0XC3
-#define VPTS_MAP_ADDR 0XC4
-#define H_VPTS_MAP_ADDR 0XC5
-
-/*#define MAX_DPB_SIZE 0XC6*/
-#define PIC_INSERT_FLAG 0XC7
-
-#define TIME_STAMP_START 0XC8
-#define TIME_STAMP_END 0XDF
-
-#define OFFSET_FOR_NON_REF_PIC 0XE0
-#define OFFSET_FOR_TOP_TO_BOTTOM_FIELD 0XE2
-#define MAX_REFERENCE_FRAME_NUM 0XE4
-#define FRAME_NUM_GAP_ALLOWED 0XE5
-#define NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE 0XE6
-#define PROFILE_IDC_MMCO 0XE7
-#define LEVEL_IDC_MMCO 0XE8
-#define FRAME_SIZE_IN_MB 0XE9
-#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG 0XEA
-#define PPS_NUM_REF_IDX_L0_ACTIVE_MINUS1 0XEB
-#define PPS_NUM_REF_IDX_L1_ACTIVE_MINUS1 0XEC
-#define CURRENT_SPS_ID 0XED
-#define CURRENT_PPS_ID 0XEE
-/* bit 0 - sequence parameter set may change
- * bit 1 - picture parameter set may change
- * bit 2 - new dpb just inited
- * bit 3 - IDR picture not decoded yet
- * bit 5:4 - 0: mb level code loaded 1: picture
- * level code loaded 2: slice level code loaded
- */
-#define DECODE_STATUS 0XEF
-#define FIRST_MB_IN_SLICE 0XF0
-#define PREV_MB_WIDTH 0XF1
-#define PREV_FRAME_SIZE_IN_MB 0XF2
-/*#define MAX_REFERENCE_FRAME_NUM_IN_MEM 0XF3*/
-/* bit 0 - aspect_ratio_info_present_flag
- * bit 1 - timing_info_present_flag
- * bit 2 - nal_hrd_parameters_present_flag
- * bit 3 - vcl_hrd_parameters_present_flag
- * bit 4 - pic_struct_present_flag
- * bit 5 - bitstream_restriction_flag
- */
-#define VUI_STATUS 0XF4
-#define ASPECT_RATIO_IDC 0XF5
-#define ASPECT_RATIO_SAR_WIDTH 0XF6
-#define ASPECT_RATIO_SAR_HEIGHT 0XF7
-#define NUM_UNITS_IN_TICK 0XF8
-#define TIME_SCALE 0XFA
-#define CURRENT_PIC_INFO 0XFC
-#define DPB_BUFFER_INFO 0XFD
-#define REFERENCE_POOL_INFO 0XFE
-#define REFERENCE_LIST_INFO 0XFF
- struct{
- unsigned short data[RPM_END-RPM_BEGIN];
- } l;
- struct{
- unsigned short dump[DPB_OFFSET];
- unsigned short dpb_base[FRAME_IN_DPB<<3];
-
- unsigned short dpb_max_buffer_frame;
- unsigned short actual_dpb_size;
-
- unsigned short colocated_buf_status;
-
- unsigned short num_forward_short_term_reference_pic;
- unsigned short num_short_term_reference_pic;
- unsigned short num_reference_pic;
-
- unsigned short current_dpb_index;
- unsigned short current_decoded_frame_num;
- unsigned short current_reference_frame_num;
-
- unsigned short l0_size;
- unsigned short l1_size;
-
- /* [6:5] : nal_ref_idc */
- /* [4:0] : nal_unit_type */
- unsigned short NAL_info_mmco;
-
- /* [1:0] : 00 - top field, 01 - bottom field,
- * 10 - frame, 11 - mbaff frame
- */
- unsigned short picture_structure_mmco;
-
- unsigned short frame_num;
- unsigned short pic_order_cnt_lsb;
-
- unsigned short num_ref_idx_l0_active_minus1;
- unsigned short num_ref_idx_l1_active_minus1;
-
- unsigned short PrevPicOrderCntLsb;
- unsigned short PreviousFrameNum;
-
- /* 32 bits variables */
- unsigned short delta_pic_order_cnt_bottom[2];
- unsigned short delta_pic_order_cnt_0[2];
- unsigned short delta_pic_order_cnt_1[2];
-
- unsigned short PrevPicOrderCntMsb[2];
- unsigned short PrevFrameNumOffset[2];
-
- unsigned short frame_pic_order_cnt[2];
- unsigned short top_field_pic_order_cnt[2];
- unsigned short bottom_field_pic_order_cnt[2];
-
- unsigned short colocated_mv_addr_start[2];
- unsigned short colocated_mv_addr_end[2];
- unsigned short colocated_mv_wr_addr[2];
-
- unsigned short frame_crop_left_offset;
- unsigned short frame_crop_right_offset;
- unsigned short frame_crop_top_offset;
- unsigned short frame_crop_bottom_offset;
- unsigned short chroma_format_idc;
- } dpb;
- struct {
- unsigned short dump[MMCO_OFFSET];
-
- /* array base address for offset_for_ref_frame */
- unsigned short offset_for_ref_frame_base[128];
-
- /* 0 - Index in DPB
- * 1 - Picture Flag
- * [ 2] : 0 - short term reference,
- * 1 - long term reference
- * [ 1] : bottom field
- * [ 0] : top field
- * 2 - Picture Number (short term or long term) low 16 bits
- * 3 - Picture Number (short term or long term) high 16 bits
- */
- unsigned short reference_base[128];
-
- /* command and parameter, until command is 3 */
- unsigned short l0_reorder_cmd[66];
- unsigned short l1_reorder_cmd[66];
-
- /* command and parameter, until command is 0 */
- unsigned short mmco_cmd[44];
-
- unsigned short l0_base[40];
- unsigned short l1_base[40];
- } mmco;
- struct {
- /* from ucode lmem, do not change this struct */
- } p;
-};
-
-
-struct StorablePicture;
-struct VideoParameters;
-struct DecodedPictureBuffer;
-
-/* New enum for field processing */
-enum PictureStructure {
- FRAME,
- TOP_FIELD,
- BOTTOM_FIELD
-};
-
-typedef enum {
- PIC_SINGLE_FRAME = 0,
- PIC_TOP,
- PIC_BOT,
- PIC_TOP_BOT,
- PIC_BOT_TOP,
- PIC_TOP_BOT_TOP = 5,
- PIC_BOT_TOP_BOT,
- PIC_DOUBLE_FRAME,
- PIC_TRIPLE_FRAME,
- PIC_INVALID,
-} PicStruct_E;
-
-#define I_Slice 2
-#define P_Slice 5
-#define B_Slice 6
-#define P_Slice_0 0
-#define B_Slice_1 1
-#define I_Slice_7 7
-
-enum SliceType {
- P_SLICE = 0,
- B_SLICE = 1,
- I_SLICE = 2,
- SP_SLICE = 3,
- SI_SLICE = 4,
- NUM_SLICE_TYPES = 5
-};
-
-enum ProfileIDC {
- FREXT_CAVLC444 = 44, /*!< YUV 4:4:4/14 "CAVLC 4:4:4"*/
- BASELINE = 66, /*!< YUV 4:2:0/8 "Baseline"*/
- MAIN = 77, /*!< YUV 4:2:0/8 "Main"*/
- EXTENDED = 88, /*!< YUV 4:2:0/8 "Extended"*/
- FREXT_HP = 100, /*!< YUV 4:2:0/8 "High"*/
- FREXT_Hi10P = 110, /*!< YUV 4:2:0/10 "High 10"*/
- FREXT_Hi422 = 122, /*!< YUV 4:2:2/10 "High 4:2:2"*/
- FREXT_Hi444 = 244, /*!< YUV 4:4:4/14 "High 4:4:4"*/
- MVC_HIGH = 118, /*!< YUV 4:2:0/8 "Multiview High"*/
- STEREO_HIGH = 128 /*!< YUV 4:2:0/8 "Stereo High"*/
-};
-
-enum FirstInsertFrm_State {
- FirstInsertFrm_IDLE = 0,
- FirstInsertFrm_OUT = 1,
- FirstInsertFrm_RESET = 2,
- FirstInsertFrm_SKIPDONE = 3,
-};
-
-
-struct SPSParameters {
- unsigned int profile_idc;
- unsigned int level_idc;
- int pic_order_cnt_type;
- int log2_max_pic_order_cnt_lsb_minus4;
- int num_ref_frames_in_pic_order_cnt_cycle;
- short offset_for_ref_frame[128];
- short offset_for_non_ref_pic;
- short offset_for_top_to_bottom_field;
-
- /**/
- int frame_mbs_only_flag;
- int num_ref_frames;
- int max_dpb_size;
- int log2_max_frame_num_minus4;
- int frame_num_gap_allowed;
-};
-
-#define DEC_REF_PIC_MARKING_BUFFER_NUM_MAX 45
-struct DecRefPicMarking_s {
- int memory_management_control_operation;
- int difference_of_pic_nums_minus1;
- int long_term_pic_num;
- int long_term_frame_idx;
- int max_long_term_frame_idx_plus1;
- struct DecRefPicMarking_s *Next;
-};
-
-#define REORDERING_COMMAND_MAX_SIZE 33
-struct Slice {
- int first_mb_in_slice;
- int mode_8x8_flags;
- int picture_structure_mmco;
-
- int frame_num;
- int idr_flag;
- int toppoc;
- int bottompoc;
- int framepoc;
- int pic_order_cnt_lsb;
- int PicOrderCntMsb;
- unsigned char field_pic_flag;
- unsigned char bottom_field_flag;
- int ThisPOC;
- int nal_reference_idc;
- int AbsFrameNum;
- int delta_pic_order_cnt_bottom;
- int delta_pic_order_cnt[2];
-
- /**/
- char listXsize[6];
- struct StorablePicture *listX[6][MAX_LIST_SIZE * 2];
-
- /**/
- enum PictureStructure structure;
- int long_term_reference_flag;
- int no_output_of_prior_pics_flag;
- int adaptive_ref_pic_buffering_flag;
-
- struct VideoParameters *p_Vid;
- struct DecodedPictureBuffer *p_Dpb;
- int num_ref_idx_active[2]; /* number of available list references */
-
- /*modification*/
- int slice_type; /* slice type */
- int ref_pic_list_reordering_flag[2];
- int modification_of_pic_nums_idc[2][REORDERING_COMMAND_MAX_SIZE];
- int abs_diff_pic_num_minus1[2][REORDERING_COMMAND_MAX_SIZE];
- int long_term_pic_idx[2][REORDERING_COMMAND_MAX_SIZE];
- /**/
- unsigned char dec_ref_pic_marking_buffer_valid;
- struct DecRefPicMarking_s
- dec_ref_pic_marking_buffer[DEC_REF_PIC_MARKING_BUFFER_NUM_MAX];
- int pic_struct;
-};
-
-struct OldSliceParams {
- unsigned int field_pic_flag;
- unsigned int frame_num;
- int nal_ref_idc;
- unsigned int pic_oder_cnt_lsb;
- int delta_pic_oder_cnt_bottom;
- int delta_pic_order_cnt[2];
- unsigned char bottom_field_flag;
- unsigned char idr_flag;
- int idr_pic_id;
- int pps_id;
-#if (MVC_EXTENSION_ENABLE)
- int view_id;
- int inter_view_flag;
- int anchor_pic_flag;
-#endif
- int layer_id;
-};
-
-struct VideoParameters {
- int PrevPicOrderCntMsb;
- int PrevPicOrderCntLsb;
- unsigned char last_has_mmco_5;
- unsigned char last_pic_bottom_field;
- int ThisPOC;
- int PreviousFrameNum;
- int FrameNumOffset;
- int PreviousFrameNumOffset;
- int max_frame_num;
- unsigned int pre_frame_num;
- int ExpectedDeltaPerPicOrderCntCycle;
- int PicOrderCntCycleCnt;
- int FrameNumInPicOrderCntCycle;
- int ExpectedPicOrderCnt;
-
- /**/
- struct SPSParameters *active_sps;
- struct Slice **ppSliceList;
- int iSliceNumOfCurrPic;
- int conceal_mode;
- int earlier_missing_poc;
- int pocs_in_dpb[100];
-
- struct OldSliceParams old_slice;
- /**/
- struct StorablePicture *dec_picture;
- struct StorablePicture *no_reference_picture;
-
- /*modification*/
- int non_conforming_stream;
- int recovery_point;
-};
-
-static inline int imin(int a, int b)
-{
- return ((a) < (b)) ? (a) : (b);
-}
-
-static inline int imax(int a, int b)
-{
- return ((a) > (b)) ? (a) : (b);
-}
-
-#define MAX_PIC_BUF_NUM 128
-#define MAX_NUM_SLICES 50
-
-struct StorablePicture {
-/**/
- int width;
- int height;
-
- int y_canvas_index;
- int u_canvas_index;
- int v_canvas_index;
-/**/
- int index;
- unsigned char is_used;
-
- enum PictureStructure structure;
-
- int poc;
- int top_poc;
- int bottom_poc;
- int frame_poc;
- unsigned int frame_num;
- unsigned int recovery_frame;
-
- int pic_num;
- int buf_spec_num;
- int buf_spec_is_alloced;
- int colocated_buf_index;
- int long_term_pic_num;
- int long_term_frame_idx;
-
- unsigned char is_long_term;
- int used_for_reference;
- int is_output;
-#if 1
- /* rain */
- int pre_output;
-#endif
- int non_existing;
- int separate_colour_plane_flag;
-
- short max_slice_id;
-
- int size_x, size_y, size_x_cr, size_y_cr;
- int size_x_m1, size_y_m1, size_x_cr_m1, size_y_cr_m1;
- int coded_frame;
- int mb_aff_frame_flag;
- unsigned int PicWidthInMbs;
- unsigned int PicSizeInMbs;
- int iLumaPadY, iLumaPadX;
- int iChromaPadY, iChromaPadX;
-
- /* for mb aff, if frame for referencing the top field */
- struct StorablePicture *top_field;
- /* for mb aff, if frame for referencing the bottom field */
- struct StorablePicture *bottom_field;
- /* for mb aff, if field for referencing the combined frame */
- struct StorablePicture *frame;
-
- int slice_type;
- int idr_flag;
- int no_output_of_prior_pics_flag;
- int long_term_reference_flag;
- int adaptive_ref_pic_buffering_flag;
-
- int chroma_format_idc;
- int frame_mbs_only_flag;
- int frame_cropping_flag;
- int frame_crop_left_offset;
- int frame_crop_right_offset;
- int frame_crop_top_offset;
- int frame_crop_bottom_offset;
- int qp;
- int chroma_qp_offset[2];
- int slice_qp_delta;
- /* stores the memory management control operations */
- struct DecRefPicMarking_s *dec_ref_pic_marking_buffer;
-
- /* picture error concealment */
- /*indicates if this is a concealed picture */
- int concealed_pic;
-
- /* variables for tone mapping */
- int seiHasTone_mapping;
- int tone_mapping_model_id;
- int tonemapped_bit_depth;
- /* imgpel* tone_mapping_lut; tone mapping look up table */
-
- int proc_flag;
-#if (MVC_EXTENSION_ENABLE)
- int view_id;
- int inter_view_flag;
- int anchor_pic_flag;
-#endif
- int iLumaStride;
- int iChromaStride;
- int iLumaExpandedHeight;
- int iChromaExpandedHeight;
- /* imgpel **cur_imgY; for more efficient get_block_luma */
- int no_ref;
- int iCodingType;
-
- char listXsize[MAX_NUM_SLICES][2];
- struct StorablePicture **listX[MAX_NUM_SLICES][2];
- int layer_id;
- u32 offset_delimiter;
- u32 pts;
- u64 pts64;
- u64 timestamp;
- unsigned char data_flag;
- int pic_struct;
-
- /* picture qos infomation*/
- int frame_size;
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
- u32 pic_size;
-};
-
-struct FrameStore {
- /* rain */
- int buf_spec_num;
- /* rain */
- int colocated_buf_index;
-
- /* 0=empty; 1=top; 2=bottom; 3=both fields (or frame) */
- int is_used;
- /* 0=not used for ref; 1=top used; 2=bottom used;
- * 3=both fields (or frame) used
- */
- int is_reference;
- /* 0=not used for ref; 1=top used; 2=bottom used;
- * 3=both fields (or frame) used
- */
- int is_long_term;
- /* original marking by nal_ref_idc: 0=not used for ref; 1=top used;
- * 2=bottom used; 3=both fields (or frame) used
- */
- int is_orig_reference;
-
- int is_non_existent;
-
- unsigned int frame_num;
- unsigned int recovery_frame;
-
- int frame_num_wrap;
- int long_term_frame_idx;
- int is_output;
-#if 1
- /* rain */
- int pre_output;
- /* index in gFrameStore */
- int index;
-#define I_FLAG 0x01
-#define IDR_FLAG 0x02
-#define ERROR_FLAG 0x10
-#define NULL_FLAG 0x20
-#define NODISP_FLAG 0x80
- unsigned char data_flag;
-#endif
- int poc;
-
- /* picture error concealment */
- int concealment_reference;
-
- struct StorablePicture *frame;
- struct StorablePicture *top_field;
- struct StorablePicture *bottom_field;
-
-#if (MVC_EXTENSION_ENABLE)
- int view_id;
- int inter_view_flag[2];
- int anchor_pic_flag[2];
-#endif
- int layer_id;
- u32 offset_delimiter;
- u32 pts;
- u64 pts64;
- u64 timestamp;
-
-
- /* picture qos infomation*/
- int slice_type;
- int frame_size;
-
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
- int dpb_frame_count;
- u32 hw_decode_time;
- u32 frame_size2; // For recording the chunk->size in frame mode
- bool show_frame;
- struct dma_fence *fence;
- u32 decoded_frame_size;
- u64 last_field_timestamp;
-};
-
-/* #define DPB_SIZE_MAX 16 */
-#define DPB_SIZE_MAX 32
-struct DecodedPictureBuffer {
- struct VideoParameters *p_Vid;
- /* InputParameters *p_Inp; ??? */
- struct FrameStore *fs[DPB_SIZE_MAX];
- struct FrameStore *fs_ref[DPB_SIZE_MAX];
- struct FrameStore *fs_ltref[DPB_SIZE_MAX];
- /* inter-layer reference (for multi-layered codecs) */
- struct FrameStore *fs_ilref[DPB_SIZE_MAX];
- /**/
- struct FrameStore *fs_list0[DPB_SIZE_MAX];
- struct FrameStore *fs_list1[DPB_SIZE_MAX];
- struct FrameStore *fs_listlt[DPB_SIZE_MAX];
-
- /**/
- unsigned int size;
- unsigned int used_size;
- unsigned int ref_frames_in_buffer;
- unsigned int ltref_frames_in_buffer;
- int last_output_poc;
-#if (MVC_EXTENSION_ENABLE)
- int last_output_view_id;
-#endif
- int max_long_term_pic_idx;
-
-
- int init_done;
- int first_pic_done; /*by rain*/
- int num_ref_frames;
-
- struct FrameStore *last_picture;
- unsigned int used_size_il;
- int layer_id;
-
- /* DPB related function; */
-};
-
-struct h264_dpb_stru {
- struct vdec_s *vdec;
- int decoder_index;
-
- union param dpb_param;
-
- int decode_idx;
- int buf_num;
- int curr_POC;
- int reorder_pic_num;
- unsigned int dec_dpb_size;
- u8 fast_output_enable;
- /*poc_even_flag:
- 0, init; 1, odd; 2, even*/
- u8 poc_even_odd_flag;
- u32 decode_pic_count;
- /**/
- unsigned int max_reference_size;
-
- unsigned int colocated_buf_map;
- unsigned int colocated_buf_count;
- unsigned int colocated_mv_addr_start;
- unsigned int colocated_mv_addr_end;
- unsigned int colocated_buf_size;
-
- struct DecodedPictureBuffer mDPB;
- struct Slice mSlice;
- struct VideoParameters mVideo;
- struct SPSParameters mSPS;
-
- struct StorablePicture m_PIC[MAX_PIC_BUF_NUM];
- struct FrameStore mFrameStore[DPB_SIZE_MAX];
-
- /*vui*/
- unsigned int vui_status;
- unsigned int num_units_in_tick;
- unsigned int time_scale;
- unsigned int fixed_frame_rate_flag;
- unsigned int aspect_ratio_idc;
- unsigned int aspect_ratio_sar_width;
- unsigned int aspect_ratio_sar_height;
- u8 bitstream_restriction_flag;
- u16 num_reorder_frames;
- u16 max_dec_frame_buffering;
-
- unsigned int frame_crop_left_offset;
- unsigned int frame_crop_right_offset;
- unsigned int frame_crop_top_offset;
- unsigned int frame_crop_bottom_offset;
- unsigned int chroma_format_idc;
-
- unsigned int dec_dpb_status;
- unsigned int last_dpb_status;
- unsigned char buf_alloc_fail;
- unsigned int dpb_error_flag;
- unsigned int reorder_output;
- unsigned int first_insert_frame;
- int first_output_poc;
- int dpb_frame_count;
- /* need wait aux data when there is data after pic done in dv stream */
- bool wait_aux_data_flag;
- u32 without_display_mode;
- int long_term_reference_flag;
-};
-
-
-extern unsigned int h264_debug_flag;
-extern unsigned int h264_debug_mask;
-
-int dpb_print(int indext, int debug_flag, const char *fmt, ...);
-
-int dpb_print_cont(int index, int debug_flag, const char *fmt, ...);
-
-unsigned char dpb_is_debug(int index, int debug_flag);
-
-int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame);
-
-int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num);
-
-void set_frame_output_flag(struct h264_dpb_stru *p_H264_Dpb, int index);
-
-int is_there_unused_frame_from_dpb(struct DecodedPictureBuffer *p_Dpb);
-
-int h264_slice_header_process(struct h264_dpb_stru *p_H264_Dpb, int *frame_num_gap);
-
-void dpb_init_global(struct h264_dpb_stru *p_H264_Dpb,
- int id, int actual_dpb_size, int max_reference_size);
-
-void init_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int count);
-
-int release_colocate_buf(struct h264_dpb_stru *p_H264_Dpb, int index);
-
-int get_free_buf_idx(struct vdec_s *vdec);
-
-int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *p, unsigned char data_flag);
-
-int release_picture(struct h264_dpb_stru *p_H264_Dpb,
- struct StorablePicture *pic);
-
-void remove_dpb_pictures(struct h264_dpb_stru *p_H264_Dpb);
-
-void bufmgr_post(struct h264_dpb_stru *p_H264_Dpb);
-
-void bufmgr_force_recover(struct h264_dpb_stru *p_H264_Dpb);
-
-int get_long_term_flag_by_buf_spec_num(struct h264_dpb_stru *p_H264_Dpb,
- int buf_spec_num);
-
-void bufmgr_h264_remove_unused_frame(struct h264_dpb_stru *p_H264_Dpb,
- u8 force_flag);
-
-void flush_dpb(struct h264_dpb_stru *p_H264_Dpb);
-
-void print_pic_info(int decindex, const char *info,
- struct StorablePicture *pic,
- int slice_type);
-void dump_dpb(struct DecodedPictureBuffer *p_Dpb, u8 force);
-
-void dump_pic(struct h264_dpb_stru *p_H264_Dpb);
-
-void * vh264_get_bufspec_lock(struct vdec_s *vdec);
-
-enum PictureStructure get_cur_slice_picture_struct(
- struct h264_dpb_stru *p_H264_Dpb);
-
-int dpb_check_ref_list_error(
- struct h264_dpb_stru *p_H264_Dpb);
-
-void unmark_for_reference(struct DecodedPictureBuffer *p_Dpb,
- struct FrameStore *fs);
-
-void update_ref_list(struct DecodedPictureBuffer *p_Dpb);
-
-int post_picture_early(struct vdec_s *vdec, int index);
-
-int is_used_for_reference(struct FrameStore *fs);
-
-#endif
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h b/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h
deleted file mode 100644
index 6c8e4ad..0000000
--- a/drivers/frame_provider/decoder_v4l/h264_multi/vh264.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * drivers/amlogic/media/frame_provider/decoder/h264/vh264.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef VH264_H
-#define VH264_H
-
-extern int query_video_status(int type, int *value);
-
-/* extern s32 vh264_init(void); */
-
-extern s32 vh264_release(void);
-
-#endif /* VMPEG4_H */
diff --git a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c b/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c
deleted file mode 100644
index 78539de..0000000
--- a/drivers/frame_provider/decoder_v4l/h264_multi/vmh264.c
+++ /dev/null
@@ -1,11464 +0,0 @@
-/*
- * drivers/amlogic/amports/vh264.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/platform_device.h>
-#include <linux/random.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/tsync.h>
-#include <linux/workqueue.h>
-#include <linux/dma-mapping.h>
-#include <linux/atomic.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/vdec_input.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#include "vh264.h"
-#include "../../../stream_input/amports/streambuf.h"
-#include <linux/delay.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include "../../decoder/utils/firmware.h"
-#include <linux/uaccess.h>
-#include "../../decoder/utils/config_parser.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include <linux/crc32.h>
-#include <media/v4l2-mem2mem.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define DETECT_WRONG_MULTI_SLICE
-
-/*
-to enable DV of frame mode
-#define DOLBY_META_SUPPORT in ucode
-*/
-
-#undef pr_info
-#define pr_info printk
-#define VDEC_DW
-#define DEBUG_UCODE
-#define MEM_NAME "codec_m264"
-#define MULTI_INSTANCE_FRAMEWORK
-/* #define ONE_COLOCATE_BUF_PER_DECODE_BUF */
-#include "h264_dpb.h"
-/* #define SEND_PARAM_WITH_REG */
-
-#define DRIVER_NAME "ammvdec_h264_v4l"
-#define DRIVER_HEADER_NAME "ammvdec_h264_header"
-
-#define CHECK_INTERVAL (HZ/100)
-
-#define SEI_DATA_SIZE (8*1024)
-#define SEI_ITU_DATA_SIZE (4*1024)
-
-#define RATE_MEASURE_NUM 8
-#define RATE_CORRECTION_THRESHOLD 5
-#define RATE_2397_FPS 4004 /* 23.97 */
-#define RATE_25_FPS 3840 /* 25 */
-#define RATE_2997_FPS 3203 /* 29.97 */
-#define RATE_5994_FPS 1601 /* 59.94 */
-#define RATE_11990_FPS 800 /* 119.90 */
-#define DUR2PTS(x) ((x)*90/96)
-#define PTS2DUR(x) ((x)*96/90)
-#define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96)
-#define FIX_FRAME_RATE_CHECK_IFRAME_NUM 2
-
-#define FIX_FRAME_RATE_OFF 0
-#define FIX_FRAME_RATE_ON 1
-#define FIX_FRAME_RATE_SMOOTH_CHECKING 2
-
-#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001
-#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002
-#define DEC_CONTROL_FLAG_FORCE_RATE_2397_FPS_FIX_FRAME_RATE 0x0010
-#define DEC_CONTROL_FLAG_FORCE_RATE_2997_FPS_FIX_FRAME_RATE 0x0020
-
-#define DECODE_ID(hw) (hw_to_vdec(hw)->id)
-
-#define RATE_MEASURE_NUM 8
-#define RATE_CORRECTION_THRESHOLD 5
-#define RATE_24_FPS 4004 /* 23.97 */
-#define RATE_25_FPS 3840 /* 25 */
-#define DUR2PTS(x) ((x)*90/96)
-#define PTS2DUR(x) ((x)*96/90)
-#define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96)
-#define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2
-
-#define ALIGN_WIDTH(x) (ALIGN((x), 64))
-#define ALIGN_HEIGHT(x) (ALIGN((x), 32))
-
-#define H264_DEV_NUM 9
-
-#define CONSTRAIN_MAX_BUF_NUM
-
-#define H264_MMU
-#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
-#define INVALID_IDX -1 /* Invalid buffer index.*/
-
-static int mmu_enable;
-/*mmu do not support mbaff*/
-static int force_enable_mmu = 0;
-unsigned int h264_debug_flag; /* 0xa0000000; */
-unsigned int h264_debug_mask = 0xff;
- /*
- *h264_debug_cmd:
- * 0x1xx, force decoder id of xx to be disconnected
- */
-unsigned int h264_debug_cmd;
-
-static int ref_b_frame_error_max_count = 50;
-
-static unsigned int dec_control =
- DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE |
- DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE;
-
-static unsigned int force_rate_streambase;
-static unsigned int force_rate_framebase;
-static unsigned int force_disp_bufspec_num;
-static unsigned int fixed_frame_rate_mode;
-static unsigned int error_recovery_mode_in;
-static int start_decode_buf_level = 0x4000;
-static int pre_decode_buf_level = 0x1000;
-static int stream_mode_start_num = 4;
-static unsigned int colocate_old_cal;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-/*to make reorder size difference of bl and el not too big*/
-static unsigned int reorder_dpb_size_margin_dv = 16;
-#endif
-static unsigned int reorder_dpb_size_margin = 6;
-static unsigned int reference_buf_margin = 4;
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static u32 run_ready_max_vf_only_num;
-static u32 run_ready_display_q_num;
- /*0: not check
- 0xff: mDPB.size
- */
-static u32 run_ready_max_buf_num = 0xff;
-#endif
-
-static u32 run_ready_min_buf_num = 2;
-
-#define VDEC_ASSIST_CANVAS_BLK32 0x5
-
-
-static unsigned int max_alloc_buf_count;
-static unsigned int decode_timeout_val = 100;
-static unsigned int errordata_timeout_val = 50;
-static unsigned int get_data_timeout_val = 2000;
-#if 1
-/* H264_DATA_REQUEST does not work, disable it,
-decode has error for data in none continuous address
-*/
-static unsigned int frame_max_data_packet;
-#else
-static unsigned int frame_max_data_packet = 8;
-#endif
-static unsigned int radr;
-static unsigned int rval;
-static u32 endian = 0xff0;
-
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode detail print
- bit 3, disable ucode watchdog
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-static unsigned int disp_vframe_valve_level;
-
-static unsigned int max_decode_instance_num = H264_DEV_NUM;
-static unsigned int decode_frame_count[H264_DEV_NUM];
-static unsigned int display_frame_count[H264_DEV_NUM];
-static unsigned int max_process_time[H264_DEV_NUM];
-static unsigned int max_get_frame_interval[H264_DEV_NUM];
-static unsigned int run_count[H264_DEV_NUM];
-static unsigned int input_empty[H264_DEV_NUM];
-static unsigned int not_run_ready[H264_DEV_NUM];
-static unsigned int ref_frame_mark_flag[H264_DEV_NUM] =
-{1, 1, 1, 1, 1, 1, 1, 1, 1};
-
-#define VDEC_CLOCK_ADJUST_FRAME 30
-static unsigned int clk_adj_frame_count;
-
-/*
- *bit[3:0]: 0, run ; 1, pause; 3, step
- *bit[4]: 1, schedule run
- */
-static unsigned int step[H264_DEV_NUM];
-
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-static u32 prefix_aux_buf_size = (16 * 1024);
-static u32 suffix_aux_buf_size;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static u32 dv_toggle_prov_name;
-
-static u32 dolby_meta_with_el;
-#endif
-
-/*
- bit[8]
- 0: use sys_info[bit 3]
- not 0:use i_only_flag[7:0]
- bit[7:0]:
- bit 0, 1: only display I picture;
- bit 1, 1: only decode I picture;
-*/
-static unsigned int i_only_flag;
-
-/*
- error_proc_policy:
- bit[0] send_error_frame_flag;
- (valid when bit[31] is 1, otherwise use sysinfo)
- bit[1] do not decode if config_decode_buf() fail
- bit[2] force release buf if in deadlock
- bit[3] force sliding window ref_frames_in_buffer > num_ref_frames
- bit[4] check inactive of receiver
- bit[5] reset buffmgr if in deadlock
- bit[6] reset buffmgr if bufspec, collocate buf, pic alloc fail
- bit[7] reset buffmgr if dpb error
-
- bit[8] check total mbx/mby of decoded frame
- bit[9] check ERROR_STATUS_REG
- bit[10] check reference list
- bit[11] mark error if dpb error
- bit[12] i_only when error happen
- bit[13] 0: mark error according to last pic, 1: ignore mark error
- bit[14] 0: result done when timeout from ucode. 1: reset bufmgr when timeout.
- bit[15] 1: dpb_frame_count If the dpb_frame_count difference is large, it moves out of the DPB buffer.
- bit[16] 1: check slice header number.
- bit[17] 1: If the decoded Mb count is insufficient but greater than the threshold, it is considered the correct frame.
- bit[18] 1: time out status, store pic to dpb buffer.
- bit[19] 1: If a lot b frames are wrong consecutively, the DPB queue reset.
- bit[20] 1: fixed some error stream will lead to the diffusion of the error, resulting playback stuck.
- bit[21] 1: fixed DVB loop playback cause jetter issue.
- bit[22] 1: In streaming mode, support for discarding data.
- bit[23] 0: set error flag on frame number gap error and drop it, 1: ignore error.
-*/
-static unsigned int error_proc_policy = 0x3fCfb6; /*0x1f14*/
-
-static unsigned int v4l_error_policy = 0x8017C3B5; //default
-
-/*
- error_skip_count:
- bit[11:0] error skip frame count
- bit[15:12] error skip i picture count
-*/
-static unsigned int error_skip_count = (0x2 << 12) | 0x40;
-
-static unsigned int force_sliding_margin;
-/*
- bit[1:0]:
- 0, start playing from any frame
- 1, start playing from I frame
- bit[15:8]: the count of skip frames after first I
- 2, start playing from second I frame (decode from the first I)
- bit[15:8]: the max count of skip frames after first I
- 3, start playing from IDR
-*/
-static unsigned int first_i_policy = 1;
-
-/*
- fast_output_enable:
- bit [0], output frame if there is IDR in list
- bit [1], output frame if the current poc is 1 big than the previous poc
- bit [2], if even poc only, output frame ifthe cuurent poc
- is 2 big than the previous poc
- bit [3], ip only
-*/
-static unsigned int fast_output_enable = H264_OUTPUT_MODE_NORMAL;
-
-static unsigned int enable_itu_t35 = 1;
-
-static unsigned int frmbase_cont_bitlevel = 0x40;
-
-static unsigned int frmbase_cont_bitlevel2 = 0x1;
-
-static unsigned int check_slice_num = 30;
-
-static unsigned int mb_count_threshold = 5; /*percentage*/
-
-#define MH264_USERDATA_ENABLE
-
-/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
-/* hevc->double_write_mode:
- 0, no double write
- 1, 1:1 ratio
- 2, (1/4):(1/4) ratio
- 3, (1/4):(1/4) ratio, with both compressed frame included
- 4, (1/2):(1/2) ratio
- 0x10, double write only
- 0x10000: vdec dw horizotal 1/2
- 0x20000: vdec dw horizotal/vertical 1/2
-*/
-static u32 double_write_mode;
-static u32 without_display_mode;
-
-static int loop_playback_poc_threshold = 400;
-static int poc_threshold = 50;
-
-static u32 lookup_check_conut = 30;
-
-
-/*
- *[3:0] 0: default use config from omx.
- * 1: force enable fence.
- * 2: disable fence.
- *[7:4] 0: fence use for driver.
- * 1: fence fd use for app.
- */
-static u32 force_config_fence;
-
-static u32 adjust_dpb_size = 13;
-
-#define IS_VDEC_DW(hw) (hw->double_write_mode >> 16 & 0xf)
-
-static void vmh264_dump_state(struct vdec_s *vdec);
-
-#define is_in_parsing_state(status) \
- ((status == H264_ACTION_SEARCH_HEAD) || \
- ((status & 0xf0) == 0x80))
-
-#define is_interlace(frame) \
- ((frame->frame &&\
- frame->top_field &&\
- frame->bottom_field &&\
- (!frame->frame->coded_frame)) || \
- (frame->frame && \
- frame->frame->coded_frame && \
- (!frame->frame->frame_mbs_only_flag) && \
- frame->frame->structure == FRAME))
-
-static inline bool close_to(int a, int b, int m)
-{
- return (abs(a - b) < m) ? true : false;
-}
-
-#if 0
-#define h264_alloc_hw_stru(dev, size, opt) devm_kzalloc(dev, size, opt)
-#define h264_free_hw_stru(dev, hw) devm_kfree(dev, hw)
-#else
-#define h264_alloc_hw_stru(dev, size, opt) vzalloc(size)
-#define h264_free_hw_stru(dev, hw) vfree(hw)
-#endif
-
-/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
-#define NV21
-/* #endif */
-
-/* 12M for L41 */
-#define MAX_DPB_BUFF_SIZE (12*1024*1024)
-#define DEFAULT_MEM_SIZE (32*1024*1024)
-#define AVIL_DPB_BUFF_SIZE 0x01ec2000
-
-#define DEF_BUF_START_ADDR 0x00000000
-#define mem_sps_base 0x01c3c00
-#define mem_pps_base 0x01cbc00
-/*#define V_BUF_ADDR_OFFSET (0x13e000)*/
-u32 V_BUF_ADDR_OFFSET = 0x200000;
-#define DCAC_READ_MARGIN (64 * 1024)
-
-
-#define EXTEND_SAR 0xff
-#define BUFSPEC_POOL_SIZE 64
-#define VF_POOL_SIZE 64
-#define VF_POOL_NUM 2
-#define MAX_VF_BUF_NUM 27
-#define BMMU_MAX_BUFFERS (BUFSPEC_POOL_SIZE + 3)
-#define BMMU_REF_IDX (BUFSPEC_POOL_SIZE)
-#define BMMU_DPB_IDX (BUFSPEC_POOL_SIZE + 1)
-#define BMMU_EXTIF_IDX (BUFSPEC_POOL_SIZE + 2)
-#define EXTIF_BUF_SIZE (0x10000 * 2)
-
-#define HEADER_BUFFER_IDX(n) (n)
-#define VF_BUFFER_IDX(n) (n)
-
-
-#define PUT_INTERVAL (HZ/100)
-#define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL)
-
-#define MMU_MAX_BUFFERS BUFSPEC_POOL_SIZE
-#define SWITCHING_STATE_OFF 0
-#define SWITCHING_STATE_ON_CMD3 1
-#define SWITCHING_STATE_ON_CMD1 2
-
-
-
-#define INCPTR(p) ptr_atomic_wrap_inc(&p)
-
-#define SLICE_TYPE_I 2
-#define SLICE_TYPE_P 5
-#define SLICE_TYPE_B 6
-
-struct buffer_spec_s {
- /*
- used:
- -1, none allocated
- 0, allocated, free
- 1, used by dpb
- 2, in disp queue;
- 3, in disp queue, isolated,
- do not use for dpb when vf_put;
- 4, to release
- 5, in disp queue, isolated (but not to release)
- do not use for dpb when vf_put;
- */
- unsigned int used;
- unsigned int info0;
- unsigned int info1;
- unsigned int info2;
- unsigned int y_addr;
- unsigned int u_addr;
- unsigned int v_addr;
-
- int y_canvas_index;
- int u_canvas_index;
- int v_canvas_index;
-
-#ifdef VDEC_DW
- unsigned int vdec_dw_y_addr;
- unsigned int vdec_dw_u_addr;
- unsigned int vdec_dw_v_addr;
-
- int vdec_dw_y_canvas_index;
- int vdec_dw_u_canvas_index;
- int vdec_dw_v_canvas_index;
-#ifdef NV21
- struct canvas_config_s vdec_dw_canvas_config[2];
-#else
- struct canvas_config_s vdec_dw_canvas_config[3];
-#endif
-#endif
-
-#ifdef NV21
- struct canvas_config_s canvas_config[2];
-#else
- struct canvas_config_s canvas_config[3];
-#endif
- unsigned long cma_alloc_addr;
- unsigned int buf_adr;
-#ifdef H264_MMU
- unsigned long alloc_header_addr;
-#endif
- char *aux_data_buf;
- int aux_data_size;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- unsigned char dv_enhance_exist;
-#endif
- int canvas_pos;
- int vf_ref;
- /*unsigned int comp_body_size;*/
- unsigned int dw_y_adr;
- unsigned int dw_u_v_adr;
- int fs_idx;
- int ctx_buf_idx;
-};
-
-#define AUX_DATA_SIZE(pic) (hw->buffer_spec[pic->buf_spec_num].aux_data_size)
-#define AUX_DATA_BUF(pic) (hw->buffer_spec[pic->buf_spec_num].aux_data_buf)
-#define DEL_EXIST(h, p) (h->buffer_spec[p->buf_spec_num].dv_enhance_exist)
-
-
-#define vdec_dw_spec2canvas(x) \
- (((x)->vdec_dw_v_canvas_index << 16) | \
- ((x)->vdec_dw_u_canvas_index << 8) | \
- ((x)->vdec_dw_y_canvas_index << 0))
-
-
-#define spec2canvas(x) \
- (((x)->v_canvas_index << 16) | \
- ((x)->u_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-#define FRAME_INDEX(vf_index) (vf_index & 0xff)
-#define BUFSPEC_INDEX(vf_index) ((vf_index >> 8) & 0xff)
-#define VF_INDEX(frm_idx, bufspec_idx) (frm_idx | (bufspec_idx << 8))
-
-static struct vframe_s *vh264_vf_peek(void *);
-static struct vframe_s *vh264_vf_get(void *);
-static void vh264_vf_put(struct vframe_s *, void *);
-static int vh264_vf_states(struct vframe_states *states, void *);
-static int vh264_event_cb(int type, void *data, void *private_data);
-static void vh264_work(struct work_struct *work);
-static void vh264_timeout_work(struct work_struct *work);
-static void vh264_notify_work(struct work_struct *work);
-#ifdef MH264_USERDATA_ENABLE
-static void user_data_ready_notify_work(struct work_struct *work);
-static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec);
-#endif
-
-static const char vh264_dec_id[] = "vh264-dev";
-
-#define PROVIDER_NAME "vdec.h264"
-
-static const struct vframe_operations_s vf_provider_ops = {
- .peek = vh264_vf_peek,
- .get = vh264_vf_get,
- .put = vh264_vf_put,
- .event_cb = vh264_event_cb,
- .vf_states = vh264_vf_states,
-};
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_CONFIG_PARAM 3
-#define DEC_RESULT_GET_DATA 4
-#define DEC_RESULT_GET_DATA_RETRY 5
-#define DEC_RESULT_ERROR 6
-#define DEC_RESULT_EOS 7
-#define DEC_RESULT_FORCE_EXIT 8
-#define DEC_RESULT_TIMEOUT 9
-#define DEC_RESULT_NEED_MORE_BUFFER 10
-
-
-/*
- *static const char *dec_result_str[] = {
- * "DEC_RESULT_NONE ",
- * "DEC_RESULT_DONE ",
- * "DEC_RESULT_AGAIN ",
- * "DEC_RESULT_CONFIG_PARAM",
- * "DEC_RESULT_GET_DATA ",
- * "DEC_RESULT_GET_DA_RETRY",
- * "DEC_RESULT_ERROR ",
- *};
- */
-
-#define UCODE_IP_ONLY 2
-#define UCODE_IP_ONLY_PARAM 1
-
-#define MC_OFFSET_HEADER 0x0000
-#define MC_OFFSET_DATA 0x1000
-#define MC_OFFSET_MMCO 0x2000
-#define MC_OFFSET_LIST 0x3000
-#define MC_OFFSET_SLICE 0x4000
-#define MC_OFFSET_MAIN 0x5000
-
-#define MC_TOTAL_SIZE ((20+16)*SZ_1K)
-#define MC_SWAP_SIZE (4*SZ_1K)
-#define MODE_ERROR 0
-#define MODE_FULL 1
-
-#define DFS_HIGH_THEASHOLD 3
-
-#define INIT_FLAG_REG AV_SCRATCH_2
-#define HEAD_PADING_REG AV_SCRATCH_3
-#define UCODE_WATCHDOG_REG AV_SCRATCH_7
-#define LMEM_DUMP_ADR AV_SCRATCH_L
-#define DEBUG_REG1 AV_SCRATCH_M
-#define DEBUG_REG2 AV_SCRATCH_N
-#define FRAME_COUNTER_REG AV_SCRATCH_I
-#define RPM_CMD_REG AV_SCRATCH_A
-#define H264_DECODE_SIZE AV_SCRATCH_E
-#define H264_DECODE_MODE AV_SCRATCH_4
-#define H264_DECODE_SEQINFO AV_SCRATCH_5
-#define H264_AUX_ADR AV_SCRATCH_C
-#define H264_AUX_DATA_SIZE AV_SCRATCH_H
-
-#define H264_DECODE_INFO M4_CONTROL_REG /* 0xc29 */
-#define DPB_STATUS_REG AV_SCRATCH_J
-#define ERROR_STATUS_REG AV_SCRATCH_9
- /*
- NAL_SEARCH_CTL: bit 0, enable itu_t35
- NAL_SEARCH_CTL: bit 1, enable mmu
- NAL_SEARCH_CTL: bit 2, detect frame_mbs_only_flag whether switch resolution
- NAL_SEARCH_CTL: bit 15,bitstream_restriction_flag
- */
-#define NAL_SEARCH_CTL AV_SCRATCH_9
-#define MBY_MBX MB_MOTION_MODE /*0xc07*/
-
-#define DECODE_MODE_SINGLE 0x0
-#define DECODE_MODE_MULTI_FRAMEBASE 0x1
-#define DECODE_MODE_MULTI_STREAMBASE 0x2
-#define DECODE_MODE_MULTI_DVBAL 0x3
-#define DECODE_MODE_MULTI_DVENL 0x4
-static DEFINE_MUTEX(vmh264_mutex);
-static DEFINE_MUTEX(reset_mutex);
-
-
-
-#ifdef MH264_USERDATA_ENABLE
-
-struct mh264_userdata_record_t {
- struct userdata_meta_info_t meta_info;
- u32 rec_start;
- u32 rec_len;
-};
-
-struct mh264_ud_record_wait_node_t {
- struct list_head list;
- struct mh264_userdata_record_t ud_record;
-};
-#define USERDATA_FIFO_NUM 256
-#define MAX_FREE_USERDATA_NODES 5
-
-struct mh264_userdata_info_t {
- struct mh264_userdata_record_t records[USERDATA_FIFO_NUM];
- u8 *data_buf;
- u8 *data_buf_end;
- u32 buf_len;
- u32 read_index;
- u32 write_index;
- u32 last_wp;
-};
-
-
-#endif
-
-struct mh264_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
-
-struct vdec_h264_hw_s {
- spinlock_t lock;
- spinlock_t bufspec_lock;
- int id;
- struct platform_device *platform_dev;
- unsigned long cma_alloc_addr;
- /* struct page *collocate_cma_alloc_pages; */
- unsigned long collocate_cma_alloc_addr;
-
- u32 prefix_aux_size;
- u32 suffix_aux_size;
- void *aux_addr;
- dma_addr_t aux_phy_addr;
-
- /* buffer for store all sei data */
- void *sei_data_buf;
- u32 sei_data_len;
-
- /* buffer for storing one itu35 recored */
- void *sei_itu_data_buf;
- u32 sei_itu_data_len;
-
- /* recycle buffer for user data storing all itu35 records */
- void *sei_user_data_buffer;
- u32 sei_user_data_wp;
-#ifdef MH264_USERDATA_ENABLE
- struct work_struct user_data_ready_work;
-#endif
- struct StorablePicture *last_dec_picture;
-
- ulong lmem_phy_addr;
- dma_addr_t lmem_addr;
-
- void *bmmu_box;
-#ifdef H264_MMU
- void *mmu_box;
- void *frame_mmu_map_addr;
- dma_addr_t frame_mmu_map_phy_addr;
- u32 hevc_cur_buf_idx;
- u32 losless_comp_body_size;
- u32 losless_comp_body_size_sao;
- u32 losless_comp_header_size;
- u32 mc_buffer_size_u_v;
- u32 mc_buffer_size_u_v_h;
- u32 is_idr_frame;
- u32 is_new_pic;
- u32 frame_done;
- u32 frame_busy;
- unsigned long extif_addr;
- int double_write_mode;
- int mmu_enable;
-#endif
-
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-
- int cur_pool;
- struct vframe_s vfpool[VF_POOL_NUM][VF_POOL_SIZE];
- struct buffer_spec_s buffer_spec[BUFSPEC_POOL_SIZE];
- struct vframe_s switching_fense_vf;
- struct h264_dpb_stru dpb;
- u8 init_flag;
- u8 first_sc_checked;
- u8 has_i_frame;
- u8 config_bufmgr_done;
- u32 max_reference_size;
- u32 decode_pic_count;
- u32 reflist_error_count;
- int start_search_pos;
- u32 reg_iqidct_control;
- bool reg_iqidct_control_init_flag;
- u32 reg_vcop_ctrl_reg;
- u32 reg_rv_ai_mb_count;
- u32 vld_dec_control;
- struct vframe_s vframe_dummy;
-
- unsigned char buffer_empty_flag;
-
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 frame_prog;
- u32 frame_packing_type;
-
- struct vframe_chunk_s *chunk;
-
- u32 stat;
- unsigned long buf_start;
- u32 buf_offset;
- u32 buf_size;
- /* u32 ucode_map_start; */
- u32 pts_outside;
- u32 sync_outside;
- u32 vh264_ratio;
- u32 vh264_rotation;
- u32 use_idr_framerate;
-
- u32 seq_info;
- u32 seq_info2;
- u32 video_signal_from_vui; /*to do .. */
- u32 timing_info_present_flag;
- u32 fixed_frame_rate_flag;
- u32 bitstream_restriction_flag;
- u32 num_reorder_frames;
- u32 max_dec_frame_buffering;
- u32 iframe_count;
- u32 aspect_ratio_info;
- u32 num_units_in_tick;
- u32 time_scale;
- u32 h264_ar;
- bool h264_first_valid_pts_ready;
- u32 h264pts1;
- u32 h264pts2;
- u32 pts_duration;
- u32 h264_pts_count;
- u32 duration_from_pts_done;
- u32 pts_unstable;
- u32 unstable_pts;
- u32 last_checkout_pts;
- u32 max_refer_buf;
-
- s32 vh264_stream_switching_state;
- struct vframe_s *p_last_vf;
- u32 last_pts;
- u32 last_pts_remainder;
- u32 last_duration;
- u32 last_mb_width, last_mb_height;
- bool check_pts_discontinue;
- bool pts_discontinue;
- u32 wait_buffer_counter;
- u32 first_offset;
- u32 first_pts;
- u64 first_pts64;
- bool first_pts_cached;
- u64 last_pts64;
-#if 0
- void *sei_data_buffer;
- dma_addr_t sei_data_buffer_phys;
-#endif
-
- uint error_recovery_mode;
- uint mb_total;
- uint mb_width;
- uint mb_height;
-
- uint i_only;
- int skip_frame_count;
- bool no_poc_reorder_flag;
- bool send_error_frame_flag;
- dma_addr_t mc_dma_handle;
- void *mc_cpu_addr;
- int vh264_reset;
-
- atomic_t vh264_active;
-
- struct dec_sysinfo vh264_amstream_dec_info;
-
- int dec_result;
- u32 timeout_processing;
- struct work_struct work;
- struct work_struct notify_work;
- struct work_struct timeout_work;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
-
- struct timer_list check_timer;
-
- /**/
- unsigned int last_frame_time;
- atomic_t vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
-
- /* timeout handle */
- unsigned long int start_process_time;
- unsigned int last_mby_mbx;
- unsigned int last_vld_level;
- unsigned int decode_timeout_count;
- unsigned int timeout_num;
- unsigned int search_dataempty_num;
- unsigned int decode_timeout_num;
- unsigned int decode_dataempty_num;
- unsigned int buffer_empty_recover_num;
-
- unsigned get_data_count;
- unsigned get_data_start_time;
- /**/
-
- /*log*/
- unsigned int packet_write_success_count;
- unsigned int packet_write_EAGAIN_count;
- unsigned int packet_write_ENOMEM_count;
- unsigned int packet_write_EFAULT_count;
- unsigned int total_read_size_pre;
- unsigned int total_read_size;
- unsigned int frame_count_pre;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- u8 switch_dvlayer_flag;
- u8 got_valid_nal;
-#endif
- u8 eos;
- u8 data_flag;
- u32 no_error_count;
- u32 no_error_i_count;
- /*
- NODISP_FLAG
- */
- u8 dec_flag;
-
- u32 ucode_pause_pos;
-
- u8 reset_bufmgr_flag;
- u32 reset_bufmgr_count;
- ulong timeout;
- u32 timeout_flag;
- u32 cfg_param1;
- u32 cfg_param2;
- u32 cfg_param3;
- u32 cfg_param4;
- u32 cfg_bitstream_restriction_flag;
- int valve_count;
- u8 next_again_flag;
- u32 pre_parser_wr_ptr;
- struct firmware_s *fw;
- struct firmware_s *fw_mmu;
-#ifdef MH264_USERDATA_ENABLE
- /*user data*/
- struct mutex userdata_mutex;
- struct mh264_userdata_info_t userdata_info;
- struct mh264_userdata_record_t ud_record;
- int wait_for_udr_send;
-#endif
- u32 no_mem_count;
- u32 canvas_mode;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- wait_queue_head_t wait_q;
- u32 reg_g_status;
- struct mutex chunks_mutex;
- int need_cache_size;
- u64 sc_start_time;
- u8 frmbase_cont_flag;
- struct vframe_qos_s vframe_qos;
- int frameinfo_enable;
- bool first_head_check_flag;
- unsigned int height_aspect_ratio;
- unsigned int width_aspect_ratio;
- unsigned int first_i_policy;
- u32 reorder_dpb_size_margin;
- bool wait_reset_done_flag;
-#ifdef DETECT_WRONG_MULTI_SLICE
- unsigned int multi_slice_pic_check_count;
- /* multi_slice_pic_flag:
- 0, unknown;
- 1, single slice;
- 2, multi slice
- */
- unsigned int multi_slice_pic_flag;
- unsigned int picture_slice_count;
- unsigned int cur_picture_slice_count;
- unsigned char force_slice_as_picture_flag;
- unsigned int last_picture_slice_count;
- unsigned int first_pre_frame_num;
-#endif
- u32 res_ch_flag;
- u32 b_frame_error_count;
- struct vdec_info gvs;
- u32 kpi_first_i_comming;
- u32 kpi_first_i_decoded;
- int sidebind_type;
- int sidebind_channel_id;
- u32 low_latency_mode;
- int ip_field_error_count;
- int buffer_wrap[BUFSPEC_POOL_SIZE];
- int loop_flag;
- int loop_last_poc;
- bool enable_fence;
- int fence_usage;
- bool discard_dv_data;
- u32 metadata_config_flag;
- int vdec_pg_enable_flag;
- u32 save_reg_f;
- u32 start_bit_cnt;
- u32 right_frame_count;
- u32 wrong_frame_count;
- u32 error_frame_width;
- u32 error_frame_height;
- ulong fb_token;
- struct mh264_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- u32 no_decoder_buffer_flag;
- u32 video_signal_type;
- bool need_free_aux_data;
- u32 error_proc_policy;
- struct trace_decoder_name trace;
- int csd_change_flag;
-};
-
-static u32 again_threshold;
-
-static void timeout_process(struct vdec_h264_hw_s *hw);
-static void dump_bufspec(struct vdec_h264_hw_s *hw,
- const char *caller);
-static void h264_reconfig(struct vdec_h264_hw_s *hw);
-static void h264_reset_bufmgr_v4l(struct vdec_s *vdec, int flush_flag);
-static void vh264_local_init(struct vdec_h264_hw_s *hw, bool is_reset);
-static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw);
-static int vh264_stop(struct vdec_h264_hw_s *hw);
-static s32 vh264_init(struct vdec_h264_hw_s *hw);
-static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf,
- u32 index);
-static void release_aux_data(struct vdec_h264_hw_s *hw,
- int buf_spec_num);
-#ifdef ERROR_HANDLE_TEST
-static void h264_clear_dpb(struct vdec_h264_hw_s *hw);
-#endif
-
-#define H265_PUT_SAO_4K_SET 0x03
-#define H265_ABORT_SAO_4K_SET 0x04
-#define H265_ABORT_SAO_4K_SET_DONE 0x05
-
-#define SYS_COMMAND HEVC_ASSIST_SCRATCH_0
-#define H265_CHECK_AXI_INFO_BASE HEVC_ASSIST_SCRATCH_8
-#define H265_SAO_4K_SET_BASE HEVC_ASSIST_SCRATCH_9
-#define H265_SAO_4K_SET_COUNT HEVC_ASSIST_SCRATCH_A
-#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
-
-
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_CM_BODY_START_ADDR 0x3626
-#define HEVC_CM_BODY_LENGTH 0x3627
-#define HEVC_CM_HEADER_LENGTH 0x3629
-#define HEVC_CM_HEADER_OFFSET 0x362b
-#define HEVC_SAO_CTRL9 0x362d
-#define HEVCD_MPP_DECOMP_CTL3 0x34c4
-#define HEVCD_MPP_VDEC_MCR_CTL 0x34c8
-#define HEVC_DBLK_CFGB 0x350b
-#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-
-#define H265_DW_NO_SCALE
-#define H265_MEM_MAP_MODE 0 /*0:linear 1:32x32 2:64x32*/
-#define H265_LOSLESS_COMPRESS_MODE
-#define MAX_FRAME_4K_NUM 0x1200
-#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)
-
-/* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
-static u32 mem_map_mode = H265_MEM_MAP_MODE;
-
-#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
-
-
-
-static int is_oversize(int w, int h)
-{
- int max = MAX_SIZE_4K;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
- if (w < 0 || h < 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-static void vmh264_udc_fill_vpts(struct vdec_h264_hw_s *hw,
- int frame_type,
- u32 vpts,
- u32 vpts_valid);
-static int compute_losless_comp_body_size(int width,
- int height, int bit_depth_10);
-static int compute_losless_comp_header_size(int width, int height);
-
-static int hevc_alloc_mmu(struct vdec_h264_hw_s *hw, int pic_idx,
- int pic_width, int pic_height, u16 bit_depth,
- unsigned int *mmu_index_adr) {
- int cur_buf_idx;
- int bit_depth_10 = (bit_depth != 0x00);
- int picture_size;
- u32 cur_mmu_4k_number;
-
- WRITE_VREG(CURR_CANVAS_CTRL, pic_idx<<24);
- cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL)&0xff;
- picture_size = compute_losless_comp_body_size(pic_width,
- pic_height, bit_depth_10);
- cur_mmu_4k_number = ((picture_size+(1<<12)-1) >> 12);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL,
- "alloc_mmu new_fb_idx %d picture_size %d cur_mmu_4k_number %d\n",
- cur_buf_idx, picture_size, cur_mmu_4k_number);
-
- if (cur_mmu_4k_number > MAX_FRAME_4K_NUM) {
- pr_err("hevc_alloc_mmu cur_mmu_4k_number %d unsupport\n",
- cur_mmu_4k_number);
- return -1;
- }
-
- return decoder_mmu_box_alloc_idx(
- hw->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
-}
-
-static int compute_losless_comp_body_size(int width,
- int height, int bit_depth_10)
-{
- int width_x64;
- int height_x32;
- int bsize;
-
- width_x64 = width + 63;
- width_x64 >>= 6;
-
- height_x32 = height + 31;
- height_x32 >>= 5;
-
-#ifdef H264_MMU
- bsize = (bit_depth_10 ? 4096 : 3264) * width_x64*height_x32;
-#else
- bsize = (bit_depth_10 ? 4096 : 3072) * width_x64*height_x32;
-#endif
- return bsize;
-}
-
-static int compute_losless_comp_header_size(int width, int height)
-{
- int width_x64;
- int width_x128;
- int height_x64;
- int hsize;
-
- width_x64 = width + 63;
- width_x64 >>= 6;
-
- width_x128 = width + 127;
- width_x128 >>= 7;
-
- height_x64 = height + 63;
- height_x64 >>= 6;
-
-#ifdef H264_MMU
- hsize = 128*width_x64*height_x64;
-#else
- hsize = 32*width_x128*height_x64;
-#endif
- return hsize;
-}
-
-static int get_dw_size(struct vdec_h264_hw_s *hw, u32 *pdw_buffer_size_u_v_h)
-{
- int pic_width, pic_height;
- int lcu_size = 16;
- int dw_buf_size;
- u32 dw_buffer_size_u_v;
- u32 dw_buffer_size_u_v_h;
- int dw_mode = hw->double_write_mode;
-
- pic_width = hw->frame_width;
- pic_height = hw->frame_height;
-
- if (dw_mode) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(hw->double_write_mode);
- int pic_height_dw = pic_height /
- get_double_write_ratio(hw->double_write_mode);
-
- int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
- pic_width_dw / lcu_size + 1 :
- pic_width_dw / lcu_size;
- int pic_height_lcu_dw = (pic_height_dw % lcu_size) ?
- pic_height_dw / lcu_size + 1 :
- pic_height_dw / lcu_size;
- int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
-
-
- dw_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2;
- dw_buffer_size_u_v_h = (dw_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- dw_buf_size = ((dw_buffer_size_u_v_h << 16) * 3);
- *pdw_buffer_size_u_v_h = dw_buffer_size_u_v_h;
- } else {
- *pdw_buffer_size_u_v_h = 0;
- dw_buf_size = 0;
- }
-
- return dw_buf_size;
-}
-
-
-static void hevc_mcr_config_canv2axitbl(struct vdec_h264_hw_s *hw, int restore)
-{
- int i, size;
- u32 canvas_addr;
- unsigned long maddr;
- int num_buff = hw->dpb.mDPB.size;
- int dw_size = 0;
- u32 dw_buffer_size_u_v_h;
- u32 blkmode = hw->canvas_mode;
- int dw_mode = hw->double_write_mode;
-
- canvas_addr = ANC0_CANVAS_ADDR;
- for (i = 0; i < num_buff; i++)
- WRITE_VREG((canvas_addr + i), i | (i << 8) | (i << 16));
-
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
- size = hw->losless_comp_body_size + hw->losless_comp_header_size;
-
-
- dw_size = get_dw_size(hw, &dw_buffer_size_u_v_h);
- size += dw_size;
- if (size > 0)
- size += 0x10000;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL,
- "dw_buffer_size_u_v_h = %d, dw_size = 0x%x, size = 0x%x\n",
- dw_buffer_size_u_v_h, dw_size, size);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL,
- "body_size = %d, header_size = %d, body_size_sao = %d\n",
- hw->losless_comp_body_size,
- hw->losless_comp_header_size,
- hw->losless_comp_body_size_sao);
-
- for (i = 0; i < num_buff; i++) {
- if (!restore) {
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box,
- HEADER_BUFFER_IDX(i), size,
- DRIVER_HEADER_NAME, &maddr) < 0) {
- dpb_print(DECODE_ID(hw), 0,
- "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, i);
- return;
- }
- } else
- maddr = hw->buffer_spec[i].alloc_header_addr;
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA, maddr >> 5);
- hw->buffer_spec[i].alloc_header_addr = maddr;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL,
- "%s : canvas: %d axiaddr:%x size 0x%x\n",
- __func__, i, (u32)maddr, size);
-
- if (dw_mode) {
- u32 addr;
- int canvas_w;
- int canvas_h;
-
- canvas_w = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
- canvas_h = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
-
- if (hw->canvas_mode == 0)
- canvas_w = ALIGN(canvas_w, 32);
- else
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- hw->buffer_spec[i].dw_y_adr =
- maddr + hw->losless_comp_header_size;
-
- hw->buffer_spec[i].dw_y_adr =
- ((hw->buffer_spec[i].dw_y_adr + 0xffff) >> 16)
- << 16;
- hw->buffer_spec[i].dw_u_v_adr =
- hw->buffer_spec[i].dw_y_adr
- + (dw_buffer_size_u_v_h << 16) * 2;
-
-
- hw->buffer_spec[i].buf_adr
- = hw->buffer_spec[i].dw_y_adr;
- addr = hw->buffer_spec[i].buf_adr;
-
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL,
- "dw_y_adr = 0x%x, dw_u_v_adr = 0x%x, y_addr = 0x%x, u_addr = 0x%x, v_addr = 0x%x, width = %d, height = %d\n",
- hw->buffer_spec[i].dw_y_adr,
- hw->buffer_spec[i].dw_u_v_adr,
- hw->buffer_spec[i].y_addr,
- hw->buffer_spec[i].u_addr,
- hw->buffer_spec[i].v_addr,
- canvas_w,
- canvas_h);
-
- hw->buffer_spec[i].canvas_config[0].phy_addr =
- hw->buffer_spec[i].dw_y_adr;
- hw->buffer_spec[i].canvas_config[0].width = canvas_w;
- hw->buffer_spec[i].canvas_config[0].height = canvas_h;
- hw->buffer_spec[i].canvas_config[0].block_mode =
- blkmode;
- hw->buffer_spec[i].canvas_config[0].endian = 7;
-
- hw->buffer_spec[i].canvas_config[1].phy_addr =
- hw->buffer_spec[i].dw_u_v_adr;
- hw->buffer_spec[i].canvas_config[1].width = canvas_w;
- hw->buffer_spec[i].canvas_config[1].height = canvas_h;
- hw->buffer_spec[i].canvas_config[1].block_mode =
- blkmode;
- hw->buffer_spec[i].canvas_config[1].endian = 7;
- }
- }
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
- for (i = 0; i < 32; i++)
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
- return;
-}
-static void hevc_mcr_config_mc_ref(struct vdec_h264_hw_s *hw)
-{
- u32 i;
- u32 ref_canv;
- struct Slice *pSlice = &(hw->dpb.mSlice);
- /*REFLIST[0]*/
- for (i = 0; i < (unsigned int)(pSlice->listXsize[0]); i++) {
- struct StorablePicture *ref = pSlice->listX[0][i];
- if (ref == NULL)
- return;
- WRITE_VREG(CURR_CANVAS_CTRL, ref->buf_spec_num<<24);
- ref_canv = READ_VREG(CURR_CANVAS_CTRL)&0xffffff;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (ref->buf_spec_num & 0x3f) << 8);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, ref_canv);
- }
- /*REFLIST[1]*/
- for (i = 0; i < (unsigned int)(pSlice->listXsize[1]); i++) {
- struct StorablePicture *ref = pSlice->listX[1][i];
- if (ref == NULL)
- return;
- WRITE_VREG(CURR_CANVAS_CTRL, ref->buf_spec_num<<24);
- ref_canv = READ_VREG(CURR_CANVAS_CTRL)&0xffffff;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (ref->buf_spec_num & 0x3f) << 8);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, ref_canv);
- }
- return;
-}
-
-static void hevc_mcr_config_mcrcc(struct vdec_h264_hw_s *hw)
-{
- u32 rdata32;
- u32 rdata32_2;
- u32 slice_type;
- struct StorablePicture *ref;
- struct Slice *pSlice;
- slice_type = hw->dpb.mSlice.slice_type;
- pSlice = &(hw->dpb.mSlice);
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2);
- if (slice_type == I_SLICE) {
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
- return;
- }
- if (slice_type == B_SLICE) {
- ref = pSlice->listX[0][0];
- if (ref == NULL)
- return;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- ((ref->buf_spec_num & 0x3f) << 8));
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- ref = pSlice->listX[1][0];
- if (ref == NULL)
- return;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- ((ref->buf_spec_num & 0x3f) << 8));
- rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- if (rdata32 == rdata32_2) {
- ref = pSlice->listX[1][1];
- if (ref == NULL)
- return;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- ((ref->buf_spec_num & 0x3f) << 8));
- rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- }
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32_2);
- } else { /*P-PIC*/
- ref = pSlice->listX[0][0];
- if (ref == NULL)
- return;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- ((ref->buf_spec_num & 0x3f) << 8));
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- ref = pSlice->listX[0][1];
- if (ref == NULL)
- return;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- ((ref->buf_spec_num & 0x3f) << 8));
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- }
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);
- return;
-}
-
-
-static void hevc_mcr_sao_global_hw_init(struct vdec_h264_hw_s *hw,
- u32 width, u32 height) {
- u32 data32;
- u32 lcu_x_num, lcu_y_num;
- u32 lcu_total;
- u32 mc_buffer_size_u_v;
- u32 mc_buffer_size_u_v_h;
- int dw_mode = hw->double_write_mode;
-
- /*lcu_x_num = (width + 15) >> 4;*/
- // width need to be round to 64 pixel -- case0260 1/10/2020
- lcu_x_num = (((width + 63) >> 6) << 2);
- lcu_y_num = (height + 15) >> 4;
- lcu_total = lcu_x_num * lcu_y_num;
-
- hw->mc_buffer_size_u_v = mc_buffer_size_u_v = lcu_total*16*16/2;
- hw->mc_buffer_size_u_v_h =
- mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16;
-
- hw->losless_comp_body_size = 0;
-
- hw->losless_comp_body_size_sao =
- compute_losless_comp_body_size(width, height, 0);
- hw->losless_comp_header_size =
- compute_losless_comp_header_size(width, height);
-
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1); /*sw reset ipp10b_top*/
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x0); /*sw reset ipp10b_top*/
-
- /* setup lcu_size = 16*/
- WRITE_VREG(HEVCD_IPP_TOP_LCUCONFIG, 16); /*set lcu size = 16*/
- /*pic_width/pic_height*/
- WRITE_VREG(HEVCD_IPP_TOP_FRMCONFIG,
- (height & 0xffff) << 16 | (width & 0xffff));
- /* bitdepth_luma = 8*/
- /* bitdepth_chroma = 8*/
- WRITE_VREG(HEVCD_IPP_BITDEPTH_CONFIG, 0x0);/*set bit-depth 8 */
-
-#ifdef H265_LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- data32 |= (hw->canvas_mode << 4);
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,
- (0x80 << 20) | (0x80 << 10) | (0xff));
-
- WRITE_VREG(HEVCD_MPP_VDEC_MCR_CTL, 0x1 | (0x1 << 4));
-
- /*comfig vdec:h264:mdec to use hevc mcr/mcrcc/decomp*/
- WRITE_VREG(MDEC_PIC_DC_MUX_CTRL,
- READ_VREG(MDEC_PIC_DC_MUX_CTRL) | 0x1 << 31);
- /* ipp_enable*/
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, 0x1 << 1);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(HEVC_DBLK_CFG1, 0x2); // set ctusize==16
- WRITE_VREG(HEVC_DBLK_CFG2, ((height & 0xffff)<<16) | (width & 0xffff));
- if (dw_mode & 0x10)
- WRITE_VREG(HEVC_DBLK_CFGB, 0x40405603);
- else if (dw_mode)
- WRITE_VREG(HEVC_DBLK_CFGB, 0x40405703);
- else
- WRITE_VREG(HEVC_DBLK_CFGB, 0x40405503);
- }
-
- data32 = READ_VREG(HEVC_SAO_CTRL0);
- data32 &= (~0xf);
- data32 |= 0x4;
- WRITE_VREG(HEVC_SAO_CTRL0, data32);
- WRITE_VREG(HEVC_SAO_PIC_SIZE, (height & 0xffff) << 16 |
- (width & 0xffff));
- data32 = ((lcu_x_num-1) | (lcu_y_num-1) << 16);
-
- WRITE_VREG(HEVC_SAO_PIC_SIZE_LCU, data32);
- data32 = (lcu_x_num | lcu_y_num << 16);
- WRITE_VREG(HEVC_SAO_TILE_SIZE_LCU, data32);
- data32 = (mc_buffer_size_u_v_h << 16) << 1;
- WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
- data32 = (mc_buffer_size_u_v_h << 16);
- WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
-
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- data32 &= (~0xff0);
- data32 |= endian; /* Big-Endian per 64-bit */
-
- if (hw->mmu_enable && (dw_mode & 0x10))
- data32 |= ((hw->canvas_mode << 12) |1);
- else if (hw->mmu_enable && dw_mode)
- data32 |= ((hw->canvas_mode << 12));
- else
- data32 |= ((hw->canvas_mode << 12)|2);
-
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
-#ifdef H265_DW_NO_SCALE
- WRITE_VREG(HEVC_SAO_CTRL5, READ_VREG(HEVC_SAO_CTRL5) & ~(0xff << 16));
- if (hw->mmu_enable && dw_mode) {
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 &= (~(0xff << 16));
- if (dw_mode == 2 ||
- dw_mode == 3)
- data32 |= (0xff<<16);
- else if (dw_mode == 4)
- data32 |= (0x33<<16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
-
-#endif
-
-
-#ifdef H265_LOSLESS_COMPRESS_MODE
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<9); /*8-bit smem-mode*/
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- WRITE_VREG(HEVC_CM_BODY_LENGTH, hw->losless_comp_body_size_sao);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, hw->losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, hw->losless_comp_header_size);
-#endif
-
-#ifdef H265_LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC_SAO_CTRL9, READ_VREG(HEVC_SAO_CTRL9) | (0x1 << 1));
- WRITE_VREG(HEVC_SAO_CTRL5, READ_VREG(HEVC_SAO_CTRL5) | (0x1 << 10));
-#endif
-
- WRITE_VREG(HEVC_SAO_CTRL9, READ_VREG(HEVC_SAO_CTRL9) | 0x1 << 7);
-
- memset(hw->frame_mmu_map_addr, 0, FRAME_MMU_MAP_SIZE);
-
- WRITE_VREG(MDEC_EXTIF_CFG0, hw->extif_addr);
- WRITE_VREG(MDEC_EXTIF_CFG1, 0x80000000);
- return;
-}
-
-static void hevc_sao_set_slice_type(struct vdec_h264_hw_s *hw,
- u32 is_new_pic, u32 is_idr)
-{
- hw->is_new_pic = is_new_pic;
- hw->is_idr_frame = is_idr;
- return;
-}
-
-static void hevc_sao_set_pic_buffer(struct vdec_h264_hw_s *hw,
- struct StorablePicture *pic) {
- u32 mc_y_adr;
- u32 mc_u_v_adr;
- u32 dw_y_adr;
- u32 dw_u_v_adr;
- u32 canvas_addr;
- int ret;
- int dw_mode = hw->double_write_mode;
- if (hw->is_new_pic != 1)
- return;
-
- if (hw->is_idr_frame) {
- /* William TBD */
- memset(hw->frame_mmu_map_addr, 0, FRAME_MMU_MAP_SIZE);
- }
-
- WRITE_VREG(CURR_CANVAS_CTRL, pic->buf_spec_num << 24);
- canvas_addr = READ_VREG(CURR_CANVAS_CTRL)&0xffffff;
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x0 << 1) |
- (0x0 << 2) | ((canvas_addr & 0xff) << 8));
- mc_y_adr = READ_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA) << 5;
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x0 << 1) |
- (0x0 << 2) | (((canvas_addr >> 8) & 0xff) << 8));
- mc_u_v_adr = READ_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA) << 5;
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-
-
- if (dw_mode) {
- dw_y_adr = hw->buffer_spec[pic->buf_spec_num].dw_y_adr;
- dw_u_v_adr = hw->buffer_spec[pic->buf_spec_num].dw_u_v_adr;
- } else {
- dw_y_adr = 0;
- dw_u_v_adr = 0;
- }
-#ifdef H265_LOSLESS_COMPRESS_MODE
- if (dw_mode)
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, dw_y_adr);
- WRITE_VREG(HEVC_CM_BODY_START_ADDR, mc_y_adr);
-#ifdef H264_MMU
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR, mc_y_adr);
-#else
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR,
- (mc_y_adr + hw->losless_comp_body_size));
-#endif
-#else
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, mc_y_adr);
-#endif
-
-#ifndef H265_LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC_SAO_C_START_ADDR, mc_u_v_adr);
-#else
- if (dw_mode)
- WRITE_VREG(HEVC_SAO_C_START_ADDR, dw_u_v_adr);
-#endif
-
-#ifndef LOSLESS_COMPRESS_MODE
- if (dw_mode) {
- WRITE_VREG(HEVC_SAO_Y_WPTR, mc_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, mc_u_v_adr);
- }
-#else
- WRITE_VREG(HEVC_SAO_Y_WPTR, dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, dw_u_v_adr);
-#endif
-
- ret = hevc_alloc_mmu(hw, pic->buf_spec_num,
- (hw->mb_width << 4), (hw->mb_height << 4), 0x0,
- hw->frame_mmu_map_addr);
- if (ret != 0) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, "can't alloc need mmu1,idx %d ret =%d\n",
- pic->buf_spec_num,
- ret);
- return;
- }
-
- /*Reset SAO + Enable SAO slice_start*/
- if (hw->mmu_enable && get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- WRITE_VREG(HEVC_DBLK_CFG0, 0x1); // reset buffer32x4 in lpf for every picture
- WRITE_VREG(HEVC_SAO_INT_STATUS,
- READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 28);
- WRITE_VREG(HEVC_SAO_INT_STATUS,
- READ_VREG(HEVC_SAO_INT_STATUS) | 0x1 << 31);
- /*pr_info("hevc_sao_set_pic_buffer:mc_y_adr: %x\n", mc_y_adr);*/
- /*Send coommand to hevc-code to supply 4k buffers to sao*/
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(H265_SAO_4K_SET_BASE, (u32)hw->frame_mmu_map_phy_addr);
- WRITE_VREG(H265_SAO_4K_SET_COUNT, MAX_FRAME_4K_NUM);
- } else
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, (u32)hw->frame_mmu_map_phy_addr);
- WRITE_VREG(SYS_COMMAND, H265_PUT_SAO_4K_SET);
- hw->frame_busy = 1;
- return;
-}
-
-
-static void hevc_set_unused_4k_buff_idx(struct vdec_h264_hw_s *hw,
- u32 buf_spec_num) {
- WRITE_VREG(CURR_CANVAS_CTRL, buf_spec_num<<24);
- hw->hevc_cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL)&0xff;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, " %s cur_buf_idx %d buf_spec_num %d\n",
- __func__, hw->hevc_cur_buf_idx, buf_spec_num);
- return;
-}
-
-
-static void hevc_set_frame_done(struct vdec_h264_hw_s *hw)
-{
- ulong timeout = jiffies + HZ;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, "hevc_frame_done...set\n");
- while ((READ_VREG(HEVC_SAO_INT_STATUS) & 0x1) == 0) {
- if (time_after(jiffies, timeout)) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, " %s..timeout!\n", __func__);
- break;
- }
- }
- timeout = jiffies + HZ;
- while (READ_VREG(HEVC_CM_CORE_STATUS) & 0x1) {
- if (time_after(jiffies, timeout)) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, " %s cm_core..timeout!\n", __func__);
- break;
- }
- }
- WRITE_VREG(HEVC_SAO_INT_STATUS, 0x1);
- hw->frame_done = 1;
- return;
-}
-
-static void release_cur_decoding_buf(struct vdec_h264_hw_s *hw)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- if (p_H264_Dpb->mVideo.dec_picture) {
- release_picture(p_H264_Dpb,
- p_H264_Dpb->mVideo.dec_picture);
- p_H264_Dpb->mVideo.dec_picture->data_flag &= ~ERROR_FLAG;
- p_H264_Dpb->mVideo.dec_picture = NULL;
- if (hw->mmu_enable)
- hevc_set_frame_done(hw);
- }
-}
-
-static void hevc_sao_wait_done(struct vdec_h264_hw_s *hw)
-{
- ulong timeout = jiffies + HZ;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL, "hevc_sao_wait_done...start\n");
- while ((READ_VREG(HEVC_SAO_INT_STATUS) >> 31)) {
- if (time_after(jiffies, timeout)) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL,
- "hevc_sao_wait_done...wait timeout!\n");
- break;
- }
- }
- timeout = jiffies + HZ;
- if ((hw->frame_busy == 1) && (hw->frame_done == 1) ) {
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(SYS_COMMAND, H265_ABORT_SAO_4K_SET);
- while ((READ_VREG(SYS_COMMAND) & 0xff) !=
- H265_ABORT_SAO_4K_SET_DONE) {
- if (time_after(jiffies, timeout)) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL,
- "wait h265_abort_sao_4k_set_done timeout!\n");
- break;
- }
- }
- }
- amhevc_stop();
- hw->frame_busy = 0;
- hw->frame_done = 0;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL,
- "sao wait done ,hevc stop!\n");
- }
- return;
-}
-static void buf_spec_init(struct vdec_h264_hw_s *hw, bool buffer_reset_flag)
-{
- int i;
- unsigned long flags;
- spin_lock_irqsave(&hw->bufspec_lock, flags);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i];
- u32 ref_idx = BUFSPEC_INDEX(vf->index);
- if ((vf->index != -1) &&
- (hw->buffer_spec[ref_idx].vf_ref == 0) &&
- (hw->buffer_spec[ref_idx].used != -1)) {
- vf->index = -1;
- }
- }
-
- hw->cur_pool++;
- if (hw->cur_pool >= VF_POOL_NUM)
- hw->cur_pool = 0;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- struct vframe_s *vf = &hw->vfpool[hw->cur_pool][i];
- u32 ref_idx = BUFSPEC_INDEX(vf->index);
- if ((vf->index != -1) &&
- (hw->buffer_spec[ref_idx].vf_ref == 0) &&
- (hw->buffer_spec[ref_idx].used != -1)) {
- vf->index = -1;
- }
- }
- /* buffers are alloced when error reset, v4l must find buffer by buffer_wrap[] */
- if (hw->reset_bufmgr_flag && buffer_reset_flag) {
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_spec[i].used == 1 || hw->buffer_spec[i].used == 2)
- hw->buffer_spec[i].used = 0;
- }
- } else {
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- hw->buffer_spec[i].used = -1;
- hw->buffer_spec[i].canvas_pos = -1;
- hw->buffer_wrap[i] = -1;
- }
- }
-
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
-}
-
-
-/*is active in buf management */
-static unsigned char is_buf_spec_in_use(struct vdec_h264_hw_s *hw,
- int buf_spec_num)
-{
- unsigned char ret = 0;
- if (hw->buffer_spec[buf_spec_num].used == 1 ||
- hw->buffer_spec[buf_spec_num].used == 2 ||
- hw->buffer_spec[buf_spec_num].used == 3 ||
- hw->buffer_spec[buf_spec_num].used == 5)
- ret = 1;
- return ret;
-}
-
-static unsigned char is_buf_spec_in_disp_q(struct vdec_h264_hw_s *hw,
- int buf_spec_num)
-{
- unsigned char ret = 0;
- if (hw->buffer_spec[buf_spec_num].used == 2 ||
- hw->buffer_spec[buf_spec_num].used == 3 ||
- hw->buffer_spec[buf_spec_num].used == 5)
- ret = 1;
- return ret;
-}
-
-static int alloc_one_buf_spec(struct vdec_h264_hw_s *hw, int i)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
- if (hw->mmu_enable) {
- if (hw->buffer_spec[i].alloc_header_addr)
- return 0;
- else
- return -1;
- } else {
-
- int buf_size = (hw->mb_total << 8) + (hw->mb_total << 7);
- int addr;
-#ifdef VDEC_DW
- int orig_buf_size;
- orig_buf_size = buf_size;
- if (IS_VDEC_DW(hw) == 1)
- buf_size += (hw->mb_total << 7) + (hw->mb_total << 6);
- else if (IS_VDEC_DW(hw) == 2)
- buf_size += (hw->mb_total << 6) + (hw->mb_total << 5);
- else if (IS_VDEC_DW(hw) == 4)
- buf_size += (hw->mb_total << 4) + (hw->mb_total << 3);
- else if (IS_VDEC_DW(hw) == 8)
- buf_size += (hw->mb_total << 2) + (hw->mb_total << 1);
- if (IS_VDEC_DW(hw)) {
- u32 align_size;
- /* add align padding size for blk64x32: (mb_w<<4)*32, (mb_h<<4)*64 */
- align_size = ((hw->mb_width << 9) + (hw->mb_height << 10)) / IS_VDEC_DW(hw);
- /* double align padding size for uv*/
- align_size <<= 1;
- buf_size += align_size + PAGE_SIZE;
- }
-#endif
- if (hw->buffer_spec[i].cma_alloc_addr)
- return 0;
-
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, i,
- PAGE_ALIGN(buf_size), DRIVER_NAME,
- &hw->buffer_spec[i].cma_alloc_addr) < 0) {
- hw->buffer_spec[i].cma_alloc_addr = 0;
- if (hw->no_mem_count++ > 3) {
- hw->stat |= DECODER_FATAL_ERROR_NO_MEM;
- hw->reset_bufmgr_flag = 1;
- }
- dpb_print(DECODE_ID(hw), 0,
- "%s, fail to alloc buf for bufspec%d, try later\n",
- __func__, i
- );
- return -1;
- } else {
- hw->no_mem_count = 0;
- hw->stat &= ~DECODER_FATAL_ERROR_NO_MEM;
- }
- if (!vdec_secure(vdec)) {
- /*init internal buf*/
- char *tmpbuf = (char *)codec_mm_phys_to_virt(hw->buffer_spec[i].cma_alloc_addr);
- if (tmpbuf) {
- memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
- codec_mm_dma_flush(tmpbuf,
- PAGE_ALIGN(buf_size),
- DMA_TO_DEVICE);
- } else {
- tmpbuf = codec_mm_vmap(hw->buffer_spec[i].cma_alloc_addr, PAGE_ALIGN(buf_size));
- if (tmpbuf) {
- memset(tmpbuf, 0, PAGE_ALIGN(buf_size));
- codec_mm_dma_flush(tmpbuf,
- PAGE_ALIGN(buf_size),
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(tmpbuf);
- }
- }
- }
- hw->buffer_spec[i].buf_adr =
- hw->buffer_spec[i].cma_alloc_addr;
- addr = hw->buffer_spec[i].buf_adr;
-
-
- hw->buffer_spec[i].y_addr = addr;
- addr += hw->mb_total << 8;
- hw->buffer_spec[i].u_addr = addr;
- hw->buffer_spec[i].v_addr = addr;
- addr += hw->mb_total << 7;
-
- hw->buffer_spec[i].canvas_config[0].phy_addr =
- hw->buffer_spec[i].y_addr;
- hw->buffer_spec[i].canvas_config[0].width =
- hw->mb_width << 4;
- hw->buffer_spec[i].canvas_config[0].height =
- hw->mb_height << 4;
- hw->buffer_spec[i].canvas_config[0].block_mode =
- hw->canvas_mode;
-
- hw->buffer_spec[i].canvas_config[1].phy_addr =
- hw->buffer_spec[i].u_addr;
- hw->buffer_spec[i].canvas_config[1].width =
- hw->mb_width << 4;
- hw->buffer_spec[i].canvas_config[1].height =
- hw->mb_height << 3;
- hw->buffer_spec[i].canvas_config[1].block_mode =
- hw->canvas_mode;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, alloc buf for bufspec%d\n",
- __func__, i);
-#ifdef VDEC_DW
- if (!IS_VDEC_DW(hw))
- return 0;
- else {
- int w_shift = 3, h_shift = 3;
-
- if (IS_VDEC_DW(hw) == 1) {
- w_shift = 3;
- h_shift = 4;
- } else if (IS_VDEC_DW(hw) == 2) {
- w_shift = 3;
- h_shift = 3;
- } else if (IS_VDEC_DW(hw) == 4) {
- w_shift = 2;
- h_shift = 2;
- } else if (IS_VDEC_DW(hw) == 8) {
- w_shift = 1;
- h_shift = 1;
- }
-
- addr = hw->buffer_spec[i].cma_alloc_addr + PAGE_ALIGN(orig_buf_size);
- hw->buffer_spec[i].vdec_dw_y_addr = addr;
- addr += ALIGN_WIDTH(hw->mb_width << w_shift) * ALIGN_HEIGHT(hw->mb_height << h_shift);
- hw->buffer_spec[i].vdec_dw_u_addr = addr;
- hw->buffer_spec[i].vdec_dw_v_addr = addr;
- addr += hw->mb_total << (w_shift + h_shift - 1);
-
- hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr =
- hw->buffer_spec[i].vdec_dw_y_addr;
- hw->buffer_spec[i].vdec_dw_canvas_config[0].width =
- ALIGN_WIDTH(hw->mb_width << w_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[0].height =
- ALIGN_HEIGHT(hw->mb_height << h_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[0].block_mode =
- hw->canvas_mode;
-
- hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr =
- hw->buffer_spec[i].vdec_dw_u_addr;
- hw->buffer_spec[i].vdec_dw_canvas_config[1].width =
- ALIGN_WIDTH(hw->mb_width << w_shift);
- hw->buffer_spec[i].vdec_dw_canvas_config[1].height =
- ALIGN_HEIGHT(hw->mb_height << (h_shift - 1));
- hw->buffer_spec[i].vdec_dw_canvas_config[1].block_mode =
- hw->canvas_mode;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, vdec_dw: alloc buf for bufspec%d blkmod %d\n",
- __func__, i, hw->canvas_mode);
- }
-#endif
- }
- return 0;
-}
-
-static void vh264_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vh264_vf_put(vf, vdec_ctx);
-}
-
-static void vh264_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vh264_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = vh264_get_video_frame,
- .put_vframe = vh264_put_video_frame,
-};
-
-static int alloc_one_buf_spec_from_queue(struct vdec_h264_hw_s *hw, int idx)
-{
- int ret = 0;
- struct aml_vcodec_ctx *ctx = NULL;
- struct buffer_spec_s *bs = &hw->buffer_spec[idx];
- struct canvas_config_s *y_canvas_cfg = NULL;
- struct canvas_config_s *c_canvas_cfg = NULL;
- struct vdec_v4l2_buffer *fb = NULL;
- unsigned int y_addr = 0, c_addr = 0;
-
- if (IS_ERR_OR_NULL(hw->v4l2_ctx)) {
- pr_err("the v4l context has err.\n");
- return -1;
- }
-
- if (bs->cma_alloc_addr)
- return 0;
-
- ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), try alloc from v4l queue buf size: %d\n",
- ctx->id, __func__,
- (hw->mb_total << 8) + (hw->mb_total << 7));
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] get fb fail.\n", ctx->id);
- return ret;
- }
-
- bs->cma_alloc_addr = (unsigned long)fb;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), cma alloc addr: 0x%x, out %d dec %d\n",
- ctx->id, __func__, bs->cma_alloc_addr,
- ctx->cap_pool.out, ctx->cap_pool.dec);
-
- if (fb->num_planes == 1) {
- y_addr = fb->m.mem[0].addr;
- c_addr = fb->m.mem[0].addr + fb->m.mem[0].offset;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- } else if (fb->num_planes == 2) {
- y_addr = fb->m.mem[0].addr;
- c_addr = fb->m.mem[1].addr;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hw));
- fb->status = FB_ST_DECODER;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), y_addr: %x, size: %u\n",
- ctx->id, __func__, y_addr, fb->m.mem[0].size);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), c_addr: %x, size: %u\n",
- ctx->id, __func__, c_addr, fb->m.mem[1].size);
-
- bs->y_addr = y_addr;
- bs->u_addr = c_addr;
- bs->v_addr = c_addr;
-
- y_canvas_cfg = &bs->canvas_config[0];
- c_canvas_cfg = &bs->canvas_config[1];
-
- y_canvas_cfg->phy_addr = y_addr;
- y_canvas_cfg->width = hw->mb_width << 4;
- y_canvas_cfg->height = hw->mb_height << 4;
- y_canvas_cfg->block_mode = hw->canvas_mode;
- //fb->m.mem[0].bytes_used = y_canvas_cfg->width * y_canvas_cfg->height;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), y_w: %d, y_h: %d\n", ctx->id, __func__,
- y_canvas_cfg->width,y_canvas_cfg->height);
-
- c_canvas_cfg->phy_addr = c_addr;
- c_canvas_cfg->width = hw->mb_width << 4;
- c_canvas_cfg->height = hw->mb_height << 3;
- c_canvas_cfg->block_mode = hw->canvas_mode;
- //fb->m.mem[1].bytes_used = c_canvas_cfg->width * c_canvas_cfg->height;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), c_w: %d, c_h: %d\n", ctx->id, __func__,
- c_canvas_cfg->width, c_canvas_cfg->height);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), alloc buf for bufspec%d\n", ctx->id, __func__, idx);
-
- return ret;
-}
-
-static void config_decode_canvas(struct vdec_h264_hw_s *hw, int i)
-{
- int blkmode = hw->canvas_mode;
- int endian = 0;
-
- if (blkmode == CANVAS_BLKMODE_LINEAR) {
- if ((h264_debug_flag & IGNORE_PARAM_FROM_CONFIG) == 0)
- endian = 7;
- else
- endian = 0;
- }
-
- if (hw->is_used_v4l)
- endian = 7;
-
- config_cav_lut_ex(hw->buffer_spec[i].
- y_canvas_index,
- hw->buffer_spec[i].y_addr,
- hw->mb_width << 4,
- hw->mb_height << 4,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- endian,
- VDEC_1);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
- (1 << 11) | /* canvas_blk32_wr */
- (blkmode << 10) | /* canvas_blk32*/
- (1 << 8) | /* canvas_index_wr*/
- (hw->buffer_spec[i].y_canvas_index << 0) /* canvas index*/
- );
- }
-
- config_cav_lut_ex(hw->buffer_spec[i].
- u_canvas_index,
- hw->buffer_spec[i].u_addr,
- hw->mb_width << 4,
- hw->mb_height << 3,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- endian,
- VDEC_1);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
- (1 << 11) |
- (blkmode << 10) |
- (1 << 8) |
- (hw->buffer_spec[i].u_canvas_index << 0));
- }
-
- WRITE_VREG(ANC0_CANVAS_ADDR + hw->buffer_spec[i].canvas_pos,
- spec2canvas(&hw->buffer_spec[i]));
-
-
-#ifdef VDEC_DW
- if (!IS_VDEC_DW(hw))
- return;
- else {
- config_cav_lut_ex(hw->buffer_spec[i].
- vdec_dw_y_canvas_index,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].phy_addr,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].width,
- hw->buffer_spec[i].vdec_dw_canvas_config[0].height,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- endian,
- VDEC_1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
- (1 << 11) |
- (blkmode << 10) |
- (1 << 8) |
- (hw->buffer_spec[i].vdec_dw_y_canvas_index << 0));
- }
-
- config_cav_lut_ex(hw->buffer_spec[i].
- vdec_dw_u_canvas_index,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].phy_addr,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].width,
- hw->buffer_spec[i].vdec_dw_canvas_config[1].height,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- endian,
- VDEC_1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(VDEC_ASSIST_CANVAS_BLK32,
- (1 << 11) |
- (blkmode << 10) |
- (1 << 8) |
- (hw->buffer_spec[i].vdec_dw_u_canvas_index << 0));
- }
- }
-#endif
-}
-
-static void config_decode_canvas_ex(struct vdec_h264_hw_s *hw, int i)
-{
- u32 blkmode = hw->canvas_mode;
- int canvas_w;
- int canvas_h;
-
- canvas_w = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
- canvas_h = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
-
- if (hw->canvas_mode == 0)
- canvas_w = ALIGN(canvas_w, 32);
- else
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- config_cav_lut_ex(hw->buffer_spec[i].
- y_canvas_index,
- hw->buffer_spec[i].dw_y_adr,
- canvas_w,
- canvas_h,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- 7,
- VDEC_HEVC);
-
- config_cav_lut_ex(hw->buffer_spec[i].
- u_canvas_index,
- hw->buffer_spec[i].dw_u_v_adr,
- canvas_w,
- canvas_h,
- CANVAS_ADDR_NOWRAP,
- blkmode,
- 7,
- VDEC_HEVC);
-}
-
-static int v4l_get_free_buffer_spec(struct vdec_h264_hw_s *hw)
-{
- int i;
-
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_spec[i].cma_alloc_addr == 0)
- return i;
- }
-
- return -1;
-}
-
-static int v4l_find_buffer_spec_idx(struct vdec_h264_hw_s *hw, unsigned int v4l_indx)
-{
- int i;
-
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_wrap[i] == v4l_indx)
- return i;
- }
- return -1;
-}
-
-static int v4l_get_free_buf_idx(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx * v4l = hw->v4l2_ctx;
- struct v4l_buff_pool *pool = &v4l->cap_pool;
- struct buffer_spec_s *pic = NULL;
- int i, rt, idx = INVALID_IDX;
- ulong flags;
- u32 state = 0, index;
-
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0; i < pool->in; ++i) {
- state = (pool->seq[i] >> 16);
- index = (pool->seq[i] & 0xffff);
-
- switch (state) {
- case V4L_CAP_BUFF_IN_DEC:
- rt = v4l_find_buffer_spec_idx(hw, index);
- if (rt >= 0) {
- pic = &hw->buffer_spec[rt];
- if ((pic->vf_ref == 0) &&
- (pic->used == 0) &&
- pic->cma_alloc_addr) {
- idx = rt;
- }
- }
- break;
- case V4L_CAP_BUFF_IN_M2M:
- rt = v4l_get_free_buffer_spec(hw);
- if (rt >= 0) {
- pic = &hw->buffer_spec[rt];
- if (!alloc_one_buf_spec_from_queue(hw, rt)) {
- struct vdec_v4l2_buffer *fb;
- config_decode_canvas(hw, rt);
- fb = (struct vdec_v4l2_buffer *)pic->cma_alloc_addr;
- hw->buffer_wrap[rt] = fb->buf_idx;
- idx = rt;
- }
- }
- break;
- default:
- break;
- }
-
- if (idx != INVALID_IDX) {
- pic->used = 1;
- break;
- }
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
-
- if (idx < 0) {
- dpb_print(DECODE_ID(hw), 0, "%s fail, state %d\n", __func__, state);
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- dpb_print(DECODE_ID(hw), 0, "%s, %d\n",
- __func__, hw->buffer_wrap[i]);
- }
- vmh264_dump_state(vdec);
- } else {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)pic->cma_alloc_addr;
-
- fb->status = FB_ST_DECODER;
-
- v4l->aux_infos.bind_sei_buffer(v4l, &pic->aux_data_buf,
- &pic->aux_data_size, &pic->ctx_buf_idx);
- }
-
- return idx;
-}
-
-int get_free_buf_idx(struct vdec_s *vdec)
-{
- int i;
- unsigned long addr, flags;
- int index = -1;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- int buf_total = BUFSPEC_POOL_SIZE;
-
- if (hw->is_used_v4l)
- return v4l_get_free_buf_idx(vdec);
-
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- /*hw->start_search_pos = 0;*/
- for (i = hw->start_search_pos; i < buf_total; i++) {
- if (hw->mmu_enable)
- addr = hw->buffer_spec[i].alloc_header_addr;
- else
- addr = hw->buffer_spec[i].cma_alloc_addr;
-
- if (hw->buffer_spec[i].vf_ref == 0 &&
- hw->buffer_spec[i].used == 0 && addr) {
- hw->buffer_spec[i].used = 1;
- hw->start_search_pos = i+1;
- index = i;
- hw->buffer_wrap[i] = index;
- break;
- }
- }
- if (index < 0) {
- for (i = 0; i < hw->start_search_pos; i++) {
- if (hw->mmu_enable)
- addr = hw->buffer_spec[i].alloc_header_addr;
- else
- addr = hw->buffer_spec[i].cma_alloc_addr;
-
- if (hw->buffer_spec[i].vf_ref == 0 &&
- hw->buffer_spec[i].used == 0 && addr) {
- hw->buffer_spec[i].used = 1;
- hw->start_search_pos = i+1;
- index = i;
- hw->buffer_wrap[i] = index;
- break;
- }
- }
- }
-
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- if (hw->start_search_pos >= buf_total)
- hw->start_search_pos = 0;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s, buf_spec_num %d\n", __func__, index);
-
- if (index < 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s fail\n", __func__);
- vmh264_dump_state(vdec);
- }
-
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
- return index;
-}
-
-int release_buf_spec_num(struct vdec_s *vdec, int buf_spec_num)
-{
- /*u32 cur_buf_idx;*/
- unsigned long flags;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_MMU_DETAIL,
- "%s buf_spec_num %d used %d\n",
- __func__, buf_spec_num,
- buf_spec_num > 0 ? hw->buffer_spec[buf_spec_num].used : 0);
- if (buf_spec_num >= 0 &&
- buf_spec_num < BUFSPEC_POOL_SIZE
- ) {
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- hw->buffer_spec[buf_spec_num].used = 0;
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- if (hw->mmu_enable) {
- /*WRITE_VREG(CURR_CANVAS_CTRL, buf_spec_num<<24);
- cur_buf_idx = READ_VREG(CURR_CANVAS_CTRL);
- cur_buf_idx = cur_buf_idx&0xff;*/
- decoder_mmu_box_free_idx(hw->mmu_box, buf_spec_num);
- }
- release_aux_data(hw, buf_spec_num);
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
- return 0;
-}
-
-static void config_buf_specs(struct vdec_s *vdec)
-{
- int i, j;
- unsigned long flags;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- int mode = IS_VDEC_DW(hw) ? 2 : 1;
-
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0, j = 0;
- j < hw->dpb.mDPB.size
- && i < BUFSPEC_POOL_SIZE;
- i++) {
- int canvas;
- if (hw->buffer_spec[i].used != -1)
- continue;
- if (vdec->parallel_dec == 1) {
- if (hw->buffer_spec[i].y_canvas_index == -1)
- hw->buffer_spec[i].y_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].u_canvas_index == -1) {
- hw->buffer_spec[i].u_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->buffer_spec[i].v_canvas_index = hw->buffer_spec[i].u_canvas_index;
- }
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- if (hw->buffer_spec[i].vdec_dw_y_canvas_index == -1)
- hw->buffer_spec[i].vdec_dw_y_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].vdec_dw_u_canvas_index == -1) {
- hw->buffer_spec[i].vdec_dw_u_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->buffer_spec[i].vdec_dw_v_canvas_index =
- hw->buffer_spec[i].vdec_dw_u_canvas_index;
- }
- }
-#endif
- } else {
- canvas = vdec->get_canvas(j * mode, 2);
- hw->buffer_spec[i].y_canvas_index = canvas_y(canvas);
- hw->buffer_spec[i].u_canvas_index = canvas_u(canvas);
- hw->buffer_spec[i].v_canvas_index = canvas_v(canvas);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DPB_DETAIL,
- "config canvas (%d) %x for bufspec %d\r\n",
- j, canvas, i);
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- canvas = vdec->get_canvas(j * mode + 1, 2);
- hw->buffer_spec[i].vdec_dw_y_canvas_index = canvas_y(canvas);
- hw->buffer_spec[i].vdec_dw_u_canvas_index = canvas_u(canvas);
- hw->buffer_spec[i].vdec_dw_v_canvas_index = canvas_v(canvas);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DPB_DETAIL,
- "vdec_dw: config canvas (%d) %x for bufspec %d\r\n",
- j, canvas, i);
- }
-#endif
- }
-
- hw->buffer_spec[i].used = 0;
- hw->buffer_spec[i].canvas_pos = j;
-
-
- j++;
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
-}
-
-static void config_buf_specs_ex(struct vdec_s *vdec)
-{
- int i, j;
- unsigned long flags;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- int mode = IS_VDEC_DW(hw) ? 2 : 1;
-
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0, j = 0;
- j < hw->dpb.mDPB.size
- && i < BUFSPEC_POOL_SIZE;
- i++) {
- int canvas = 0;
- if (hw->buffer_spec[i].used != -1)
- continue;
- if (vdec->parallel_dec == 1) {
- if (hw->buffer_spec[i].y_canvas_index == -1)
- hw->buffer_spec[i].y_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].u_canvas_index == -1) {
- hw->buffer_spec[i].u_canvas_index = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->buffer_spec[i].v_canvas_index = hw->buffer_spec[i].u_canvas_index;
- }
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- if (hw->buffer_spec[i].vdec_dw_y_canvas_index == -1)
- hw->buffer_spec[i].vdec_dw_y_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].vdec_dw_u_canvas_index == -1) {
- hw->buffer_spec[i].vdec_dw_u_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->buffer_spec[i].vdec_dw_v_canvas_index =
- hw->buffer_spec[i].vdec_dw_u_canvas_index;
- }
- }
-#endif
- } else {
- canvas = vdec->get_canvas(j* mode, 2);
- hw->buffer_spec[i].y_canvas_index = canvas_y(canvas);
- hw->buffer_spec[i].u_canvas_index = canvas_u(canvas);
- hw->buffer_spec[i].v_canvas_index = canvas_v(canvas);
-
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DPB_DETAIL,
- "config canvas (%d) %x for bufspec %d\r\n",
- j, canvas, i);
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- canvas = vdec->get_canvas(j*mode + 1, 2);
- hw->buffer_spec[i].vdec_dw_y_canvas_index = canvas_y(canvas);
- hw->buffer_spec[i].vdec_dw_u_canvas_index = canvas_u(canvas);
- hw->buffer_spec[i].vdec_dw_v_canvas_index = canvas_v(canvas);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DPB_DETAIL,
- "vdec_dw: config canvas (%d) %x for bufspec %d\r\n",
- j, canvas, i);
- }
-#endif
- }
-
- hw->buffer_spec[i].used = 0;
- hw->buffer_spec[i].alloc_header_addr = 0;
- hw->buffer_spec[i].canvas_pos = j;
-
- j++;
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
-}
-
-
-static void dealloc_buf_specs(struct vdec_h264_hw_s *hw,
- unsigned char release_all)
-{
- int i;
- unsigned long flags;
- unsigned char dealloc_flag = 0;
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_spec[i].used == 4 ||
- release_all) {
- dealloc_flag = 1;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DPB_DETAIL,
- "%s buf_spec_num %d\n",
- __func__, i
- );
- spin_lock_irqsave
- (&hw->bufspec_lock, flags);
- hw->buffer_spec[i].used = -1;
- spin_unlock_irqrestore
- (&hw->bufspec_lock, flags);
- release_aux_data(hw, i);
-
- if (!hw->mmu_enable) {
- if (hw->buffer_spec[i].cma_alloc_addr) {
- if (!hw->is_used_v4l) {
- decoder_bmmu_box_free_idx(
- hw->bmmu_box,
- i);
- }
- spin_lock_irqsave
- (&hw->bufspec_lock, flags);
- hw->buffer_spec[i].cma_alloc_addr = 0;
- hw->buffer_spec[i].buf_adr = 0;
- spin_unlock_irqrestore
- (&hw->bufspec_lock, flags);
- }
- } else {
- if (hw->buffer_spec[i].alloc_header_addr) {
- decoder_mmu_box_free_idx(
- hw->mmu_box,
- i);
- spin_lock_irqsave
- (&hw->bufspec_lock, flags);
- hw->buffer_spec[i].
- alloc_header_addr = 0;
- hw->buffer_spec[i].buf_adr = 0;
- spin_unlock_irqrestore
- (&hw->bufspec_lock, flags);
- }
- }
- }
- }
- if (dealloc_flag &&
- dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
- return;
-}
-
-unsigned char have_free_buf_spec(struct vdec_s *vdec)
-{
- int i;
- unsigned long addr;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx * ctx = hw->v4l2_ctx;
- int canvas_pos_min = BUFSPEC_POOL_SIZE;
- int index = -1;
- int ret = 0;
- int allocated_count = 0;
-
- if (hw->is_used_v4l) {
- struct h264_dpb_stru *dpb = &hw->dpb;
- int free_count = 0;
- int used_count = 0;
-
- /* trigger to parse head data. */
- if (!hw->v4l_params_parsed)
- return 1;
-
- if (dpb->mDPB.used_size >= dpb->mDPB.size - 1)
- return 0;
-
- if (ctx->cap_pool.dec < hw->dpb.mDPB.size) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hw->dpb.mDPB.size; i++) {
- if (hw->buffer_spec[i].used == 0 &&
- hw->buffer_spec[i].vf_ref == 0 &&
- hw->buffer_spec[i].cma_alloc_addr) {
- free_count++;
- } else if (hw->buffer_spec[i].cma_alloc_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= run_ready_min_buf_num ? 1 : 0;
- }
-
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->mmu_enable)
- addr = hw->buffer_spec[i].alloc_header_addr;
- else
- addr = hw->buffer_spec[i].cma_alloc_addr;
- if (hw->buffer_spec[i].used == 0 &&
- hw->buffer_spec[i].vf_ref == 0) {
-
- if (addr)
- return 1;
- if (hw->buffer_spec[i].canvas_pos < canvas_pos_min) {
- canvas_pos_min = hw->buffer_spec[i].canvas_pos;
- index = i;
- }
- }
- if (addr)
- allocated_count++;
- }
- if (index >= 0) {
- mutex_lock(&vmh264_mutex);
- dealloc_buf_specs(hw, 0);
- if (max_alloc_buf_count == 0 ||
- allocated_count < max_alloc_buf_count) {
- if (alloc_one_buf_spec(hw, index) >= 0)
- ret = 1;
- }
- mutex_unlock(&vmh264_mutex);
- }
-
- return ret;
-}
-
-static int get_buf_spec_by_canvas_pos(struct vdec_h264_hw_s *hw,
- int canvas_pos)
-{
- int i;
- int j = 0;
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_spec[i].canvas_pos >= 0) {
- if (j == canvas_pos)
- return i;
- j++;
- }
- }
- return -1;
-}
-static void update_vf_memhandle(struct vdec_h264_hw_s *hw,
- struct vframe_s *vf, int index)
-{
- if (index < 0) {
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
- } else if (vf->type & VIDTYPE_SCATTER) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hw->mmu_box, index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, HEADER_BUFFER_IDX(index));
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, VF_BUFFER_IDX(index));
- /* vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, HEADER_BUFFER_IDX(index));*/
- }
- return;
-}
-static int check_force_interlace(struct vdec_h264_hw_s *hw,
- struct FrameStore *frame)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int bForceInterlace = 0;
- /* no di in secure mode, disable force di */
- if (vdec_secure(hw_to_vdec(hw)))
- return 0;
-
- if (hw->is_used_v4l)
- return 0;
-
- if ((dec_control & DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE)
- && hw->bitstream_restriction_flag
- && (hw->frame_width == 1920)
- && (hw->frame_height >= 1080) /* For being compatible with a fake progressive stream which is interlaced actually*/
- && (hw->frame_dur == 3203 || (hw->frame_dur == 3840 && p_H264_Dpb->mSPS.profile_idc == 100 &&
- p_H264_Dpb->mSPS.level_idc == 40))) {
- bForceInterlace = 1;
- } else if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE)
- && (hw->frame_width == 720)
- && (hw->frame_height == 576)
- && (hw->frame_dur == 3840)) {
- bForceInterlace = 1;
- }
- if (hw->is_used_v4l && (bForceInterlace == 0) && frame->frame) {
- bForceInterlace = (frame->frame->mb_aff_frame_flag)?1:0;
- }
- return bForceInterlace;
-}
-
-static void fill_frame_info(struct vdec_h264_hw_s *hw, struct FrameStore *frame)
-{
- struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
-
- if (frame->slice_type == I_SLICE)
- vframe_qos->type = 1;
- else if (frame->slice_type == P_SLICE)
- vframe_qos->type = 2;
- else if (frame->slice_type == B_SLICE)
- vframe_qos->type = 3;
-
- if (input_frame_based(hw_to_vdec(hw)))
- vframe_qos->size = frame->frame_size2;
- else
- vframe_qos->size = frame->frame_size;
- vframe_qos->pts = frame->pts64;
-
- vframe_qos->max_mv = frame->max_mv;
- vframe_qos->avg_mv = frame->avg_mv;
- vframe_qos->min_mv = frame->min_mv;
-/*
- pr_info("mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
-*/
-
- vframe_qos->max_qp = frame->max_qp;
- vframe_qos->avg_qp = frame->avg_qp;
- vframe_qos->min_qp = frame->min_qp;
-/*
- pr_info("qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
-*/
-
- vframe_qos->max_skip = frame->max_skip;
- vframe_qos->avg_skip = frame->avg_skip;
- vframe_qos->min_skip = frame->min_skip;
-/*
- pr_info("skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
-*/
- vframe_qos->num++;
-}
-
-static int is_iframe(struct FrameStore *frame) {
-
- if (frame->frame && frame->frame->slice_type == I_SLICE) {
- return 1;
- }
- return 0;
-}
-
-static int post_prepare_process(struct vdec_s *vdec, struct FrameStore *frame)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- int buffer_index = frame->buf_spec_num;
-
- if (buffer_index < 0 || buffer_index >= BUFSPEC_POOL_SIZE) {
- dpb_print(DECODE_ID(hw), 0,
- "%s, buffer_index 0x%x is beyond range\n",
- __func__, buffer_index);
- return -1;
- }
-
- if (force_disp_bufspec_num & 0x100) {
- /*recycle directly*/
- if (hw->buffer_spec[frame->buf_spec_num].used != 3 &&
- hw->buffer_spec[frame->buf_spec_num].used != 5)
- set_frame_output_flag(&hw->dpb, frame->index);
-
- /*make pre_output not set*/
- return -1;
- }
- if (hw->error_proc_policy & 0x1000) {
- int error_skip_i_count = (error_skip_count >> 12) & 0xf;
- int error_skip_frame_count = error_skip_count & 0xfff;
- if (((hw->no_error_count < error_skip_frame_count)
- && (error_skip_i_count == 0 ||
- hw->no_error_i_count < error_skip_i_count))
- && (!(frame->data_flag & I_FLAG)))
- frame->data_flag |= ERROR_FLAG;
- }
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "%s, buffer_index 0x%x frame_error %x poc %d hw error %x hw error_proc_policy %x\n",
- __func__, buffer_index,
- frame->data_flag & ERROR_FLAG,
- frame->poc, hw->data_flag & ERROR_FLAG,
- hw->error_proc_policy);
-
- if (frame->frame == NULL &&
- ((frame->is_used == 1 && frame->top_field)
- || (frame->is_used == 2 && frame->bottom_field))) {
- if (hw->i_only) {
- if (frame->is_used == 1)
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s No bottom_field !! frame_num %d used %d\n",
- __func__, frame->frame_num, frame->is_used);
- if (frame->is_used == 2)
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s No top_field !! frame_num %d used %d\n",
- __func__, frame->frame_num, frame->is_used);
- }
- else {
- frame->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "%s Error frame_num %d used %d\n",
- __func__, frame->frame_num, frame->is_used);
- }
- }
- if (vdec_stream_based(vdec) && !(frame->data_flag & NODISP_FLAG)) {
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if ((pts_lookup_offset_us64(PTS_TYPE_VIDEO,
- frame->offset_delimiter, &frame->pts, &frame->frame_size,
- 0, &frame->pts64) == 0)) {
- if ((lookup_check_conut && (atomic_read(&hw->vf_pre_count) > lookup_check_conut) &&
- (hw->wrong_frame_count > hw->right_frame_count)) &&
- ((frame->decoded_frame_size * 2 < frame->frame_size))) {
- /*resolve many frame only one check in pts, cause playback unsmooth issue*/
- frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ;
- frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
- }
- hw->right_frame_count++;
- } else {
- frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ;
- frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
- hw->wrong_frame_count++;
- }
- }
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s error= 0x%x poc = %d offset= 0x%x pts= 0x%x last_pts =0x%x pts64 = %lld last_pts64= %lld duration = %d\n",
- __func__, (frame->data_flag & ERROR_FLAG), frame->poc,
- frame->offset_delimiter, frame->pts,hw->last_pts,
- frame->pts64, hw->last_pts64, hw->frame_dur);
- hw->last_pts64 = frame->pts64;
- hw->last_pts = frame->pts;
- }
-
- /* SWPL-18973 96000/15=6400, less than 15fps check */
- if ((!hw->duration_from_pts_done) && (hw->frame_dur > 6400ULL)) {
- if ((check_force_interlace(hw, frame)) &&
- (frame->slice_type == I_SLICE) &&
- (hw->pts_outside)) {
- if ((!hw->h264_pts_count) || (!hw->h264pts1)) {
- hw->h264pts1 = frame->pts;
- hw->h264_pts_count = 0;
- } else if (frame->pts > hw->h264pts1) {
- u32 calc_dur =
- PTS2DUR(frame->pts - hw->h264pts1);
- calc_dur = ((calc_dur/hw->h264_pts_count) << 1);
- if (hw->frame_dur < (calc_dur + 200) &&
- hw->frame_dur > (calc_dur - 200)) {
- hw->frame_dur >>= 1;
- vdec_schedule_work(&hw->notify_work);
- dpb_print(DECODE_ID(hw), 0,
- "correct frame_dur %d, calc_dur %d, count %d\n",
- hw->frame_dur, (calc_dur >> 1), hw->h264_pts_count);
- hw->duration_from_pts_done = 1;
- hw->h264_pts_count = 0;
- }
- }
- }
- hw->h264_pts_count++;
- }
-
- if (frame->data_flag & ERROR_FLAG) {
- vdec_count_info(&hw->gvs, 1, 0);
- if (frame->slice_type == I_SLICE) {
- hw->gvs.i_concealed_frames++;
- } else if (frame->slice_type == P_SLICE) {
- hw->gvs.p_concealed_frames++;
- } else if (frame->slice_type == B_SLICE) {
- hw->gvs.b_concealed_frames++;
- }
- if (!hw->send_error_frame_flag) {
- hw->gvs.drop_frame_count++;
- if (frame->slice_type == I_SLICE) {
- hw->gvs.i_lost_frames++;
- } else if (frame->slice_type == P_SLICE) {
- hw->gvs.p_lost_frames++;
- } else if (frame->slice_type == B_SLICE) {
- hw->gvs.b_lost_frames++;
- }
- }
-
- }
-
- if ((!hw->enable_fence) &&
- ((frame->data_flag & NODISP_FLAG) ||
- (frame->data_flag & NULL_FLAG) ||
- ((!hw->send_error_frame_flag) &&
- (frame->data_flag & ERROR_FLAG)) ||
- ((hw->i_only & 0x1) &&
- (!(frame->data_flag & I_FLAG))))) {
- frame->show_frame = false;
- return 0;
- }
-
- if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL)) {
- dpb_print(DECODE_ID(hw), 0,
- "%s, fs[%d] poc %d, buf_spec_num %d\n",
- __func__, frame->index, frame->poc,
- frame->buf_spec_num);
- print_pic_info(DECODE_ID(hw), "predis_frm",
- frame->frame, -1);
- print_pic_info(DECODE_ID(hw), "predis_top",
- frame->top_field, -1);
- print_pic_info(DECODE_ID(hw), "predis_bot",
- frame->bottom_field, -1);
- }
-
- frame->show_frame = true;
-
- return 0;
-}
-
-static int post_video_frame(struct vdec_s *vdec, struct FrameStore *frame)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct vframe_s *vf = NULL;
- int buffer_index = frame->buf_spec_num;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- ulong nv_order = VIDTYPE_VIU_NV21;
- int bForceInterlace = 0;
- int vf_count = 1;
- int i;
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
- if (!is_interlace(frame))
- vf_count = 1;
- else
- vf_count = 2;
-
- bForceInterlace = check_force_interlace(hw, frame);
- if (bForceInterlace)
- vf_count = 2;
-
- if (!hw->enable_fence)
- hw->buffer_spec[buffer_index].vf_ref = 0;
- fill_frame_info(hw, frame);
-
- if ((hw->is_used_v4l) &&
- ((vdec->prog_only) || (!v4l2_ctx->vpp_is_need)))
- vf_count = 1;
-
- for (i = 0; i < vf_count; i++) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0 ||
- vf == NULL) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s fatal error, no available buffer slot.\n",
- __func__);
- return -1;
- }
- vf->duration_pulldown = 0;
- if (!(is_iframe(frame)) && hw->unstable_pts) {
- vf->pts = 0;
- vf->pts_us64 = 0;
- vf->timestamp = 0;
- vf->index = VF_INDEX(frame->index, buffer_index);
- } else {
- if ((i == 0) && (vf_count == 2))
- vf->timestamp = frame->last_field_timestamp;
- else
- vf->timestamp = frame->timestamp;
- vf->pts = frame->pts;
- vf->pts_us64 = frame->pts64;
- if ((i > 0) && v4l2_ctx->second_field_pts_mode) {
- vf->timestamp = 0;
- }
- vf->index = VF_INDEX(frame->index, buffer_index);
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->buffer_spec[buffer_index].cma_alloc_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- }
-
- if (hw->enable_fence) {
- /* fill fence information. */
- if (hw->fence_usage == FENCE_USE_FOR_DRIVER)
- vf->fence = frame->fence;
- }
-
- if (hw->mmu_enable) {
- if (hw->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
- } else {
- /*head adr*/
- vf->compHeadAddr =
- hw->buffer_spec[buffer_index].alloc_header_addr;
- /*body adr*/
- vf->compBodyAddr = 0;
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
-
- vf->type = VIDTYPE_SCATTER;
-
- if (hw->double_write_mode) {
- vf->type |= VIDTYPE_PROGRESSIVE
- | VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
- if (hw->double_write_mode == 3)
- vf->type |= VIDTYPE_COMPRESS;
-
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- hw->buffer_spec[buffer_index].
- canvas_config[0];
- vf->canvas0_config[1] =
- hw->buffer_spec[buffer_index].
- canvas_config[1];
-
- vf->canvas1_config[0] =
- hw->buffer_spec[buffer_index].
- canvas_config[0];
- vf->canvas1_config[1] =
- hw->buffer_spec[buffer_index].
- canvas_config[1];
-
- } else {
- vf->type |=
- VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
-
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
-
- vf->compWidth = hw->frame_width;
- vf->compHeight = hw->frame_height;
- } else {
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
- nv_order;
-
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(&hw->buffer_spec[buffer_index]);
-#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw))
- vf->canvas0Addr = vf->canvas1Addr =
- vdec_dw_spec2canvas(&hw->buffer_spec[buffer_index]);
- } else {
- if (IS_VDEC_DW(hw))
- vf->canvas0Addr = vf->canvas1Addr = -1;
- }
-#endif
-
- }
- if (frame->data_flag & ERROR_FLAG) {
- vf->frame_type |= V4L2_BUF_FLAG_ERROR;
- }
-
- set_frame_info(hw, vf, buffer_index);
- if (hw->discard_dv_data) {
- vf->discard_dv_data = true;
- }
-
- if (hw->mmu_enable && hw->double_write_mode) {
- vf->width = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
- vf->height = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
- }
-
- if (frame->slice_type == I_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME;
- } else if (frame->slice_type == P_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_PFRAME;
- } else if (frame->slice_type == B_SLICE) {
- vf->frame_type |= V4L2_BUF_FLAG_BFRAME;
- }
-
- vf->flag = 0;
- if (frame->data_flag & I_FLAG)
- vf->flag |= VFRAME_FLAG_SYNCFRAME;
- if (frame->data_flag & ERROR_FLAG)
- vf->flag |= VFRAME_FLAG_ERROR_RECOVERY;
- update_vf_memhandle(hw, vf, buffer_index);
-
- if (!hw->enable_fence) {
- hw->buffer_spec[buffer_index].used = 2;
- hw->buffer_spec[buffer_index].vf_ref++;
- }
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s %d frame = %p top_field = %p bottom_field = %p\n", __func__, __LINE__, frame->frame,
- frame->top_field, frame->bottom_field);
-
- if (frame->frame != NULL) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s %d coded_frame = %d frame_mbs_only_flag = %d structure = %d\n", __func__, __LINE__,
- frame->frame->coded_frame, frame->frame->frame_mbs_only_flag, frame->frame->structure);
- }
-
- if (bForceInterlace || is_interlace(frame)) {
- vf->type =
- VIDTYPE_INTERLACE_FIRST |
- nv_order;
-
- if (frame->frame != NULL &&
- (frame->frame->pic_struct == PIC_TOP_BOT ||
- frame->frame->pic_struct == PIC_BOT_TOP) &&
- frame->frame->coded_frame) {
- if (frame->frame != NULL && frame->frame->pic_struct == PIC_TOP_BOT) {
- vf->type |= (i == 0 ?
- VIDTYPE_INTERLACE_TOP :
- VIDTYPE_INTERLACE_BOTTOM);
- } else if (frame->frame != NULL && frame->frame->pic_struct == PIC_BOT_TOP) {
- vf->type |= (i == 0 ?
- VIDTYPE_INTERLACE_BOTTOM :
- VIDTYPE_INTERLACE_TOP);
- }
- } else if (frame->top_field != NULL && frame->bottom_field != NULL) {/*top first*/
- if (frame->top_field->poc <= frame->bottom_field->poc)
- vf->type |= (i == 0 ?
- VIDTYPE_INTERLACE_TOP :
- VIDTYPE_INTERLACE_BOTTOM);
- else
- vf->type |= (i == 0 ?
- VIDTYPE_INTERLACE_BOTTOM :
- VIDTYPE_INTERLACE_TOP);
- } else {
- vf->type |= (i == 0 ?
- VIDTYPE_INTERLACE_TOP :
- VIDTYPE_INTERLACE_BOTTOM);
- }
- vf->duration = vf->duration/2;
- if (i == 1) {
- vf->pts = 0;
- vf->pts_us64 = 0;
- }
-
- if (frame->frame) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s %d type = 0x%x pic_struct = %d pts = 0x%x pts_us64 = 0x%llx bForceInterlace = %d\n",
- __func__, __LINE__, vf->type, frame->frame->pic_struct,
- vf->pts, vf->pts_us64, bForceInterlace);
- }
- }
-
- if (hw->i_only) {
- if (vf_count == 1 && frame->is_used == 1 && frame->top_field
- && frame->bottom_field == NULL && frame->frame == NULL) {
- vf->type =
- VIDTYPE_INTERLACE_FIRST |
- nv_order;
- vf->type |= VIDTYPE_INTERLACE_TOP;
- vf->duration = vf->duration/2;
- }
-
- if (vf_count == 1 && frame->is_used == 2 && frame->bottom_field
- && frame->top_field == NULL && frame->frame == NULL) {
- vf->type =
- VIDTYPE_INTERLACE_FIRST |
- nv_order;
- vf->type |= VIDTYPE_INTERLACE_BOTTOM;
- vf->duration = vf->duration/2;
- }
- }
-
- /*vf->ratio_control |= (0x3FF << DISP_RATIO_ASPECT_RATIO_BIT);*/
- vf->sar_width = hw->width_aspect_ratio;
- vf->sar_height = hw->height_aspect_ratio;
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- /* offset for tsplayer pts lookup */
- if (i == 0) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) &
- 0xffffffff00000000) | frame->offset_delimiter;
- vf->pts = 0;
- } else {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- }
- atomic_add(1, &hw->vf_pre_count);
- vdec_vframe_ready(hw_to_vdec(hw), vf);
- if (!frame->show_frame) {
- vh264_vf_put(vf, vdec);
- atomic_add(1, &hw->vf_get_count);
- continue;
- }
-
- if (i == 0) {
- struct vdec_s *pvdec;
- struct vdec_info vs;
-
- pvdec = hw_to_vdec(hw);
- memset(&vs, 0, sizeof(struct vdec_info));
- pvdec->dec_status(pvdec, &vs);
- decoder_do_frame_check(pvdec, vf);
- vdec_fill_vdec_frame(pvdec, &hw->vframe_qos, &vs, vf, frame->hw_decode_time);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "[%s:%d] i_decoded_frame = %d p_decoded_frame = %d b_decoded_frame = %d\n",
- __func__, __LINE__,vs.i_decoded_frames,vs.p_decoded_frames,vs.b_decoded_frames);
- }
-
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
- vdec->vdec_fps_detec(vdec->id);
-#ifdef AUX_DATA_CRC
- decoder_do_aux_data_check(vdec, hw->buffer_spec[buffer_index].aux_data_buf,
- hw->buffer_spec[buffer_index].aux_data_size);
-#endif
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL, "aux_data_size: %d, signal_type: 0x%x\n",
- hw->buffer_spec[buffer_index].aux_data_size, hw->video_signal_type);
-
- if (dpb_is_debug(DECODE_ID(hw), PRINT_FLAG_SEI_DETAIL)) {
- int i = 0;
- PR_INIT(128);
-
- for (i = 0; i < hw->buffer_spec[buffer_index].aux_data_size; i++) {
- PR_FILL("%02x ", hw->buffer_spec[buffer_index].aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hw->id);
- }
- PR_INFO(hw->id);
- }
-
- if (hw->is_used_v4l) {
- if ((hw->buffer_spec[buffer_index].aux_data_size == 0) &&
- (frame->slice_type == I_SLICE) &&
- (atomic_read(&hw->vf_pre_count) == 1)) {
- hw->need_free_aux_data = true;
- }
-
- if (hw->need_free_aux_data) {
- v4l2_ctx->aux_infos.free_one_sei_buffer(v4l2_ctx,
- &hw->buffer_spec[buffer_index].aux_data_buf,
- &hw->buffer_spec[buffer_index].aux_data_size,
- hw->buffer_spec[buffer_index].ctx_buf_idx);
- } else {
- if (!hw->discard_dv_data)
- v4l2_ctx->aux_infos.bind_dv_buffer(v4l2_ctx,
- &vf->src_fmt.comp_buf,
- &vf->src_fmt.md_buf);
- update_vframe_src_fmt(vf,
- hw->buffer_spec[buffer_index].aux_data_buf,
- hw->buffer_spec[buffer_index].aux_data_size,
- false, vdec->vf_provider_name, NULL);
- }
- }
-
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vh264_vf_put(vh264_vf_get(vdec), vdec);
- } else {
- set_meta_data_to_vf(vf, UVM_META_DATA_VF_BASE_INFOS, hw->v4l2_ctx);
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- } else
- vh264_vf_put(vh264_vf_get(vdec), vdec);
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
-
- return 0;
-}
-
-int post_picture_early(struct vdec_s *vdec, int index)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct h264_dpb_stru *dpb_stru = &hw->dpb;
- struct FrameStore fs;
- u32 offset_lo, offset_hi;
-
- if (!hw->enable_fence)
- return 0;
-
- /* create fence for each buffers. */
- if (vdec_timeline_create_fence(vdec->sync))
- return -1;
-
- memset(&fs, 0, sizeof(fs));
-
- fs.buf_spec_num = index;
- fs.fence = vdec->sync->fence;
- fs.slice_type = dpb_stru->mSlice.slice_type;
- fs.dpb_frame_count = dpb_stru->dpb_frame_count;
-
- offset_lo = dpb_stru->dpb_param.l.data[OFFSET_DELIMITER_LO];
- offset_hi = dpb_stru->dpb_param.l.data[OFFSET_DELIMITER_HI];
- fs.offset_delimiter = (offset_lo | offset_hi << 16);
-
- if (hw->chunk) {
- fs.pts = hw->chunk->pts;
- fs.pts64 = hw->chunk->pts64;
- fs.timestamp = hw->chunk->timestamp;
- }
- fs.show_frame = true;
- post_video_frame(vdec, &fs);
-
- display_frame_count[DECODE_ID(hw)]++;
- return 0;
-}
-
-int prepare_display_buf(struct vdec_s *vdec, struct FrameStore *frame)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)vdec->private;
-
- if (hw->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
-
- post_prepare_process(vdec, frame);
-
- if (!frame->show_frame)
- pr_info("do not display.\n");
-
- hw->buffer_spec[frame->buf_spec_num].used = 2;
- hw->buffer_spec[frame->buf_spec_num].vf_ref = 1;
- hw->buffer_spec[frame->buf_spec_num].fs_idx = frame->index;
-
- /* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
-
- mutex_lock(&hw->fence_mutex);
- used_size = hw->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (hw->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(hw->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = hw->fence_vf_s.fence_vf[i];
- hw->fence_vf_s.fence_vf[i] = NULL;
- hw->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&hw->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vh264_vf_put(signed_fence[i], vdec);
- }
-
- return 0;
- }
-
- if (post_prepare_process(vdec, frame))
- return -1;
-
- if (post_video_frame(vdec, frame))
- return -1;
-
- display_frame_count[DECODE_ID(hw)]++;
- return 0;
-}
-
-int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!have_free_buf_spec(vdec)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] H264 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = v4l_get_free_buf_idx(vdec);
- if (INVALID_IDX == index) {
- pr_err("[%d] H264 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->buffer_spec[index].cma_alloc_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- vf->v4l_mem_handle = (ulong)fb;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER(hw->trace.pts_name, vf->timestamp);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- pr_info("[%d] H264 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-/******************
- * Hardware config
- */
-char *slice_type_name[] = {
- "P_SLICE ",
- "B_SLICE ",
- "I_SLICE ",
- "SP_SLICE",
- "SI_SLICE",
-};
-
-char *picture_structure_name[] = {
- "FRAME",
- "TOP_FIELD",
- "BOTTOM_FIELD"
-};
-
-void print_pic_info(int decindex, const char *info,
- struct StorablePicture *pic,
- int slice_type)
-{
- if (pic)
- dpb_print(decindex, PRINT_FLAG_DEC_DETAIL,
- "%s: %s (original %s), %s, mb_aff_frame_flag %d poc %d, pic_num %d, buf_spec_num %d data_flag 0x%x\n",
- info,
- picture_structure_name[pic->structure],
- pic->coded_frame ? "Frame" : "Field",
- (slice_type < 0 ||
- slice_type >= (sizeof(slice_type_name) / sizeof(slice_type_name[0]))) ? "" : slice_type_name[slice_type],
- pic->mb_aff_frame_flag,
- pic->poc,
- pic->pic_num,
- pic->buf_spec_num,
- pic->data_flag);
-}
-
-static void reset_process_time(struct vdec_h264_hw_s *hw)
-{
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[DECODE_ID(hw)])
- max_process_time[DECODE_ID(hw)] = process_time;
- }
-}
-
-static void start_process_time(struct vdec_h264_hw_s *hw)
-{
- hw->decode_timeout_count = 10;
- hw->start_process_time = jiffies;
-}
-
-static void config_aux_buf(struct vdec_h264_hw_s *hw)
-{
- WRITE_VREG(H264_AUX_ADR, hw->aux_phy_addr);
- WRITE_VREG(H264_AUX_DATA_SIZE,
- ((hw->prefix_aux_size >> 4) << 16) |
- (hw->suffix_aux_size >> 4)
- );
-}
-
-/*
-* dv_meta_flag: 1, dolby meta only; 2, not include dolby meta
-*/
-static void set_aux_data(struct vdec_h264_hw_s *hw,
- struct StorablePicture *pic, unsigned char suffix_flag,
- unsigned char dv_meta_flag, struct vdec_h264_hw_s *hw_b)
-{
- int i;
- unsigned short *aux_adr;
- unsigned size_reg_val =
- READ_VREG(H264_AUX_DATA_SIZE);
- unsigned aux_count = 0;
- int aux_size = 0;
- struct vdec_h264_hw_s *hw_buf = hw_b ? hw_b : hw;
- if (pic == NULL || pic->buf_spec_num < 0 || pic->buf_spec_num >= BUFSPEC_POOL_SIZE
- || (!is_buf_spec_in_use(hw, pic->buf_spec_num)))
- return;
-
- if (suffix_flag) {
- aux_adr = (unsigned short *)
- (hw_buf->aux_addr +
- hw_buf->prefix_aux_size);
- aux_count =
- ((size_reg_val & 0xffff) << 4)
- >> 1;
- aux_size =
- hw_buf->suffix_aux_size;
- } else {
- aux_adr =
- (unsigned short *)hw_buf->aux_addr;
- aux_count =
- ((size_reg_val >> 16) << 4)
- >> 1;
- aux_size =
- hw_buf->prefix_aux_size;
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL)) {
- dpb_print(DECODE_ID(hw), 0,
- "%s:poc %d old size %d count %d,suf %d dv_flag %d\r\n",
- __func__, pic->poc, AUX_DATA_SIZE(pic),
- aux_count, suffix_flag, dv_meta_flag);
- }
- if (aux_size > 0 && aux_count > 0) {
- int heads_size = 0;
-
- for (i = 0; i < aux_count; i++) {
- unsigned char tag = aux_adr[i] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- heads_size += 8;
- else if (dv_meta_flag == 1 && tag == 0x1)
- heads_size += 8;
- else if (dv_meta_flag == 2 && tag != 0x1)
- heads_size += 8;
- }
- }
-
- if (AUX_DATA_BUF(pic)) {
- unsigned char valid_tag = 0;
- unsigned char *h =
- AUX_DATA_BUF(pic) +
- AUX_DATA_SIZE(pic);
- unsigned char *p = h + 8;
- int len = 0;
- int padding_len = 0;
- for (i = 0; i < aux_count; i += 4) {
- int ii;
- unsigned char tag = aux_adr[i + 3] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- valid_tag = 1;
- else if (dv_meta_flag == 1
- && tag == 0x1)
- valid_tag = 1;
- else if (dv_meta_flag == 2
- && tag != 0x1)
- valid_tag = 1;
- else
- valid_tag = 0;
- if (valid_tag && len > 0) {
- AUX_DATA_SIZE(pic) +=
- (len + 8);
- h[0] =
- (len >> 24) & 0xff;
- h[1] =
- (len >> 16) & 0xff;
- h[2] =
- (len >> 8) & 0xff;
- h[3] =
- (len >> 0) & 0xff;
- h[6] =
- (padding_len >> 8)
- & 0xff;
- h[7] =
- (padding_len) & 0xff;
- h += (len + 8);
- p += 8;
- len = 0;
- padding_len = 0;
- }
- if (valid_tag) {
- h[4] = tag;
- h[5] = 0;
- h[6] = 0;
- h[7] = 0;
- }
- }
- if (valid_tag) {
- for (ii = 0; ii < 4; ii++) {
- unsigned short aa =
- aux_adr[i + 3
- - ii];
- *p = aa & 0xff;
- p++;
- len++;
- /*if ((aa >> 8) == 0xff)
- padding_len++;*/
- }
- }
- }
- if (len > 0) {
- AUX_DATA_SIZE(pic) += (len + 8);
- h[0] = (len >> 24) & 0xff;
- h[1] = (len >> 16) & 0xff;
- h[2] = (len >> 8) & 0xff;
- h[3] = (len >> 0) & 0xff;
- h[6] = (padding_len >> 8) & 0xff;
- h[7] = (padding_len) & 0xff;
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL)) {
- dpb_print(DECODE_ID(hw), 0,
- "aux: (size %d) suffix_flag %d\n",
- AUX_DATA_SIZE(pic), suffix_flag);
- for (i = 0; i < AUX_DATA_SIZE(pic); i++) {
- dpb_print_cont(DECODE_ID(hw), 0,
- "%02x ", AUX_DATA_BUF(pic)[i]);
- if (((i + 1) & 0xf) == 0)
- dpb_print_cont(
- DECODE_ID(hw),
- 0, "\n");
- }
- dpb_print_cont(DECODE_ID(hw),
- 0, "\n");
- }
- }
- }
-
-}
-
-static void release_aux_data(struct vdec_h264_hw_s *hw,
- int buf_spec_num)
-{
-#if 0
- kfree(hw->buffer_spec[buf_spec_num].aux_data_buf);
- hw->buffer_spec[buf_spec_num].aux_data_buf = NULL;
- hw->buffer_spec[buf_spec_num].aux_data_size = 0;
-#endif
-}
-
-static void dump_aux_buf(struct vdec_h264_hw_s *hw)
-{
- int i;
- unsigned short *aux_adr =
- (unsigned short *)
- hw->aux_addr;
- unsigned aux_size =
- (READ_VREG(H264_AUX_DATA_SIZE)
- >> 16) << 4;
-
- if (hw->prefix_aux_size > 0) {
- dpb_print(DECODE_ID(hw),
- 0,
- "prefix aux: (size %d)\n",
- aux_size);
- for (i = 0; i <
- (aux_size >> 1); i++) {
- dpb_print_cont(DECODE_ID(hw),
- 0,
- "%04x ",
- *(aux_adr + i));
- if (((i + 1) & 0xf)
- == 0)
- dpb_print_cont(
- DECODE_ID(hw),
- 0, "\n");
- }
- }
- if (hw->suffix_aux_size > 0) {
- aux_adr = (unsigned short *)
- (hw->aux_addr +
- hw->prefix_aux_size);
- aux_size =
- (READ_VREG(H264_AUX_DATA_SIZE) & 0xffff)
- << 4;
- dpb_print(DECODE_ID(hw),
- 0,
- "suffix aux: (size %d)\n",
- aux_size);
- for (i = 0; i <
- (aux_size >> 1); i++) {
- dpb_print_cont(DECODE_ID(hw),
- 0,
- "%04x ", *(aux_adr + i));
- if (((i + 1) & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw),
- 0, "\n");
- }
- }
-}
-
-#ifdef VDEC_DW
-
-struct vdec_dw_param_set{
- char dw_x_shrink_1st;
- char dw_x_shrink_2nd;
- char dw_x_shrink_3rd;
- char dw_y_shrink_1st;
- char dw_y_shrink_2nd;
- char dw_y_shrink_3rd;
- char dw_merge_8to16;
- char dw_merge_16to32;
- char dw_dma_blk_mode;
- char dw_bwsave_mode;
-};
-//#define FOR_LPDDR4_EFFICIENCY
-
-static void h264_vdec_dw_cfg(struct vdec_h264_hw_s *hw, int canvas_pos)
-{
- u32 data32 = 0, stride = 0;
- struct vdec_dw_param_set *p = NULL;
- struct vdec_dw_param_set dw_param_set_pool[] = {
- /*x1, x2, x3, y1, y2, y3, m8t6, m16to32 */
- //{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/1, 1/1 */
- {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/1 */
- {1, 0, 0, 1, 0, 0, 0, 0, 0, 1}, /* 1/2, 1/2 */
- //{1, 0, 0, 1, 1, 0, 0, 0, 0, 1}, /* 1/4, 1/2 */
- {2, 0, 1, 1, 3, 0, 0, 1, 0, 1}, /* 1/4, 1/4 */
- //{1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/4 */
- {1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /*> 1080p 1/8, 1/8 */
- };
-
- if (IS_VDEC_DW(hw))
- p = &dw_param_set_pool[__ffs(IS_VDEC_DW(hw))];
- else
- return;
-
- WRITE_VREG(MDEC_DOUBLEW_CFG3,
- hw->buffer_spec[canvas_pos].vdec_dw_y_addr); // luma start address
- WRITE_VREG(MDEC_DOUBLEW_CFG4,
- hw->buffer_spec[canvas_pos].vdec_dw_u_addr); // chroma start address
-
- stride = ALIGN_WIDTH((hw->mb_width << 4) / (IS_VDEC_DW(hw)));
- if ((IS_VDEC_DW(hw)) == 1) //width 1/2
- stride >>= 1;
- data32 = (stride << 16) | stride;
- WRITE_VREG(MDEC_DOUBLEW_CFG5, data32); // chroma stride | luma stride
-
- data32 = 0;
- p->dw_dma_blk_mode = hw->canvas_mode;
- data32 |= ((p->dw_x_shrink_1st << 0 ) | // 1st down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_1st << 2 ) | // 1st down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_x_shrink_2nd << 4 ) | // 2nd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_2nd << 6 ) | // 2nd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_x_shrink_3rd << 8 ) | // 3rd down-scale horizontal, 00:no-scale 01:1/2avg 10:left 11:right
- (p->dw_y_shrink_3rd << 10) | // 3rd down-scale vertical, 00:no-scale 01:1/2avg 10:up 11:down
- (p->dw_merge_8to16 << 12 ) | // 8->16 horizontal block merge for better ddr efficiency
- (p->dw_merge_16to32 << 13) | // 16->32 horizontal block merge for better ddr efficiency
- (p->dw_dma_blk_mode << 14) | // DMA block mode, 0:linear 1:32x32 2:64x32
-#ifdef FOR_LPDDR4_EFFICIENCY
- (1 << 19) |
-#endif
- (p->dw_bwsave_mode << 22)); // Save line buffers to save band width
- WRITE_VREG(MDEC_DOUBLEW_CFG1, data32); // add some special tests here
-
- data32 = 0;
- data32 |= (1 << 0) | (0 << 27);
- WRITE_VREG(MDEC_DOUBLEW_CFG0, data32); // Double Write Enable | source from dblk
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "vdec_double_write mode %d\n",
- IS_VDEC_DW(hw));
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "param {%d, %d, %d, %d, %d, %d, %d, %d, %d}\n",
- p->dw_x_shrink_1st,
- p->dw_y_shrink_1st,
- p->dw_x_shrink_2nd,
- p->dw_y_shrink_2nd,
- p->dw_x_shrink_3rd,
- p->dw_y_shrink_3rd,
- p->dw_merge_8to16,
- p->dw_merge_16to32,
- p->dw_dma_blk_mode);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "cfg0,1,3,4,5 = {%x, %x, %x, %x, %x}\n",
- READ_VREG(MDEC_DOUBLEW_CFG0),
- READ_VREG(MDEC_DOUBLEW_CFG1),
- READ_VREG(MDEC_DOUBLEW_CFG3),
- READ_VREG(MDEC_DOUBLEW_CFG4),
- READ_VREG(MDEC_DOUBLEW_CFG5));
-}
-#endif
-
-static void config_decode_mode(struct vdec_h264_hw_s *hw)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hw);
-#endif
- if (input_frame_based(hw_to_vdec(hw)))
- WRITE_VREG(H264_DECODE_MODE,
- DECODE_MODE_MULTI_FRAMEBASE);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec->slave)
- WRITE_VREG(H264_DECODE_MODE,
- (hw->got_valid_nal << 8) |
- DECODE_MODE_MULTI_DVBAL);
- else if (vdec->master)
- WRITE_VREG(H264_DECODE_MODE,
- (hw->got_valid_nal << 8) |
- DECODE_MODE_MULTI_DVENL);
-#endif
- else
- WRITE_VREG(H264_DECODE_MODE,
- DECODE_MODE_MULTI_STREAMBASE);
- WRITE_VREG(H264_DECODE_SEQINFO,
- hw->seq_info2);
- WRITE_VREG(HEAD_PADING_REG, 0);
-
- if (hw->init_flag == 0)
- WRITE_VREG(INIT_FLAG_REG, 0);
- else
- WRITE_VREG(INIT_FLAG_REG, 1);
-}
-
-int config_decode_buf(struct vdec_h264_hw_s *hw, struct StorablePicture *pic)
-{
- /* static int count = 0; */
- int ret = 0;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- struct Slice *pSlice = &(p_H264_Dpb->mSlice);
- unsigned int colocate_adr_offset;
- unsigned int val;
- struct StorablePicture *last_pic = hw->last_dec_picture;
-
-#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF
- int colocate_buf_index;
-#endif
-#define H264_BUFFER_INFO_INDEX PMV3_X /* 0xc24 */
-#define H264_BUFFER_INFO_DATA PMV2_X /* 0xc22 */
-#define H264_CURRENT_POC_IDX_RESET LAST_SLICE_MV_ADDR /* 0xc30 */
-#define H264_CURRENT_POC LAST_MVY /* 0xc32 shared with conceal MV */
-
-#define H264_CO_MB_WR_ADDR VLD_C38 /* 0xc38 */
-/* bit 31:30 -- L1[0] picture coding structure,
- * 00 - top field, 01 - bottom field,
- * 10 - frame, 11 - mbaff frame
- * bit 29 - L1[0] top/bot for B field pciture , 0 - top, 1 - bot
- * bit 28:0 h264_co_mb_mem_rd_addr[31:3]
- * -- only used for B Picture Direct mode [2:0] will set to 3'b000
- */
-#define H264_CO_MB_RD_ADDR VLD_C39 /* 0xc39 */
-
-/* bit 15 -- flush co_mb_data to DDR -- W-Only
- * bit 14 -- h264_co_mb_mem_wr_addr write Enable -- W-Only
- * bit 13 -- h264_co_mb_info_wr_ptr write Enable -- W-Only
- * bit 9 -- soft_reset -- W-Only
- * bit 8 -- upgent
- * bit 7:2 -- h264_co_mb_mem_wr_addr
- * bit 1:0 -- h264_co_mb_info_wr_ptr
- */
-#define H264_CO_MB_RW_CTL VLD_C3D /* 0xc3d */
-#define DCAC_DDR_BYTE64_CTL 0x0e1d
- unsigned long canvas_adr;
- unsigned int ref_reg_val;
- unsigned int one_ref_cfg = 0;
- int h264_buffer_info_data_write_count;
- int i, j;
- unsigned int colocate_wr_adr;
- unsigned int colocate_rd_adr;
- unsigned char use_direct_8x8;
- int canvas_pos;
- canvas_pos = hw->buffer_spec[pic->buf_spec_num].canvas_pos;
- WRITE_VREG(H264_CURRENT_POC_IDX_RESET, 0);
- WRITE_VREG(H264_CURRENT_POC, pic->frame_poc);
- WRITE_VREG(H264_CURRENT_POC, pic->top_poc);
- WRITE_VREG(H264_CURRENT_POC, pic->bottom_poc);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "%s: pic_num is %d, poc is %d (%d, %d, %d), buf_spec_num %d canvas_pos %d\n",
- __func__, pic->pic_num, pic->poc, pic->frame_poc,
- pic->top_poc, pic->bottom_poc, pic->buf_spec_num,
- canvas_pos);
- print_pic_info(DECODE_ID(hw), "cur", pic, pSlice->slice_type);
-
-#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw) && pic->mb_aff_frame_flag)
- WRITE_VREG(MDEC_DOUBLEW_CFG0,
- (READ_VREG(MDEC_DOUBLEW_CFG0) & (~(1 << 30))));
- }
-#endif
- WRITE_VREG(CURR_CANVAS_CTRL, canvas_pos << 24);
- canvas_adr = READ_VREG(CURR_CANVAS_CTRL) & 0xffffff;
-
- if (!hw->mmu_enable) {
- WRITE_VREG(REC_CANVAS_ADDR, canvas_adr);
- WRITE_VREG(DBKR_CANVAS_ADDR, canvas_adr);
- WRITE_VREG(DBKW_CANVAS_ADDR, canvas_adr);
-#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- WRITE_VREG(MDEC_DOUBLEW_CFG1,
- (hw->buffer_spec[canvas_pos].vdec_dw_y_canvas_index |
- (hw->buffer_spec[canvas_pos].vdec_dw_u_canvas_index << 8)));
- } else {
- h264_vdec_dw_cfg(hw, canvas_pos);
- }
-#endif
- } else
- hevc_sao_set_pic_buffer(hw, pic);
-
- if (pic->mb_aff_frame_flag)
- hw->buffer_spec[pic->buf_spec_num].info0 = 0xf4c0;
- else if (pic->structure == TOP_FIELD)
- hw->buffer_spec[pic->buf_spec_num].info0 = 0xf400;
- else if (pic->structure == BOTTOM_FIELD)
- hw->buffer_spec[pic->buf_spec_num].info0 = 0xf440;
- else
- hw->buffer_spec[pic->buf_spec_num].info0 = 0xf480;
-
- if (pic->bottom_poc < pic->top_poc)
- hw->buffer_spec[pic->buf_spec_num].info0 |= 0x100;
-
- hw->buffer_spec[pic->buf_spec_num].info1 = pic->top_poc;
- hw->buffer_spec[pic->buf_spec_num].info2 = pic->bottom_poc;
- WRITE_VREG(H264_BUFFER_INFO_INDEX, 16);
-
- for (j = 0; j < hw->dpb.mDPB.size; j++) {
- int long_term_flag;
- i = get_buf_spec_by_canvas_pos(hw, j);
- if (i < 0)
- break;
- long_term_flag =
- get_long_term_flag_by_buf_spec_num(p_H264_Dpb, i);
- if (long_term_flag > 0) {
- if (long_term_flag & 0x1)
- hw->buffer_spec[i].info0 |= (1 << 4);
- else
- hw->buffer_spec[i].info0 &= ~(1 << 4);
-
- if (long_term_flag & 0x2)
- hw->buffer_spec[i].info0 |= (1 << 5);
- else
- hw->buffer_spec[i].info0 &= ~(1 << 5);
- }
-
- if (i == pic->buf_spec_num)
- WRITE_VREG(H264_BUFFER_INFO_DATA,
- hw->buffer_spec[i].info0 | 0xf);
- else
- WRITE_VREG(H264_BUFFER_INFO_DATA,
- hw->buffer_spec[i].info0);
- WRITE_VREG(H264_BUFFER_INFO_DATA, hw->buffer_spec[i].info1);
- WRITE_VREG(H264_BUFFER_INFO_DATA, hw->buffer_spec[i].info2);
- }
-
- /* config reference buffer */
- if (hw->mmu_enable) {
- hevc_mcr_config_mc_ref(hw);
- hevc_mcr_config_mcrcc(hw);
- }
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "list0 size %d\n", pSlice->listXsize[0]);
- WRITE_VREG(H264_BUFFER_INFO_INDEX, 0);
- ref_reg_val = 0;
- j = 0;
- h264_buffer_info_data_write_count = 0;
-
- //disable this read cache when frame width <= 64 (4MBs)
- //IQIDCT_CONTROL, bit[16] dcac_dma_read_cache_disable
- if (hw->frame_width <= 64) {
- SET_VREG_MASK(IQIDCT_CONTROL,(1 << 16));
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A))
- // Disable DDR_BYTE64_CACHE
- WRITE_VREG(DCAC_DDR_BYTE64_CTL,
- (READ_VREG(DCAC_DDR_BYTE64_CTL) & (~0xf)) | 0xa);
- }
- else
- CLEAR_VREG_MASK(IQIDCT_CONTROL,(1 << 16));
-
- if (last_pic)
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "last_pic->data_flag %x slice_type %x last_pic->slice_type %x\n",
- last_pic->data_flag, pSlice->slice_type, last_pic->slice_type);
- if (!hw->i_only && !(hw->error_proc_policy & 0x2000) &&
- last_pic && (last_pic->data_flag & ERROR_FLAG)
- && (!(last_pic->slice_type == B_SLICE))
- && (!(pSlice->slice_type == I_SLICE))) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "no i/idr error mark\n");
- hw->data_flag |= ERROR_FLAG;
- pic->data_flag |= ERROR_FLAG;
- }
-
- for (i = 0; i < (unsigned int)(pSlice->listXsize[0]); i++) {
- /*ref list 0 */
- struct StorablePicture *ref = pSlice->listX[0][i];
- unsigned int cfg;
- /* bit[6:5] - frame/field info,
- * 01 - top, 10 - bottom, 11 - frame
- */
- #ifdef ERROR_CHECK
- if (ref == NULL) {
- hw->data_flag |= ERROR_FLAG;
- pic->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref list0 NULL\n");
- return -1;
- }
- if ((ref->data_flag & ERROR_FLAG) && ref_frame_mark_flag[DECODE_ID(hw)]) {
- hw->data_flag |= ERROR_FLAG;
- pic->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark1 \n");
- }
-
- if (hw->error_proc_policy & 0x80000) {
- if (ref_b_frame_error_max_count &&
- ref->slice_type == B_SLICE) {
- if (ref->data_flag & ERROR_FLAG)
- hw->b_frame_error_count++;
- else
- hw->b_frame_error_count = 0;
- if (hw->b_frame_error_count > ref_b_frame_error_max_count) {
- hw->b_frame_error_count = 0;
- dpb_print(DECODE_ID(hw), 0,
- "error %d B frame, reset dpb buffer\n",
- ref_b_frame_error_max_count);
- return -1;
- }
- }
- }
-
- if (ref->data_flag & NULL_FLAG)
- hw->data_flag |= NULL_FLAG;
-#endif
- canvas_pos = hw->buffer_spec[ref->buf_spec_num].canvas_pos;
-
- if (ref->structure == TOP_FIELD)
- cfg = 0x1;
- else if (ref->structure == BOTTOM_FIELD)
- cfg = 0x2;
- else /* FRAME */
- cfg = 0x3;
-
- one_ref_cfg = (canvas_pos & 0x1f) | (cfg << 5);
- ref_reg_val <<= 8;
- ref_reg_val |= one_ref_cfg;
- j++;
-
- if (j == 4) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "H264_BUFFER_INFO_DATA: %x\n", ref_reg_val);
- WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val);
- h264_buffer_info_data_write_count++;
- j = 0;
- }
- print_pic_info(DECODE_ID(hw), "list0",
- pSlice->listX[0][i], -1);
- }
- if (j != 0) {
- while (j != 4) {
- ref_reg_val <<= 8;
- ref_reg_val |= one_ref_cfg;
- j++;
- }
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "H264_BUFFER_INFO_DATA: %x\n",
- ref_reg_val);
- WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val);
- h264_buffer_info_data_write_count++;
- }
- ref_reg_val = (one_ref_cfg << 24) | (one_ref_cfg<<16) |
- (one_ref_cfg << 8) | one_ref_cfg;
- for (i = h264_buffer_info_data_write_count; i < 8; i++)
- WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "list1 size %d\n", pSlice->listXsize[1]);
- WRITE_VREG(H264_BUFFER_INFO_INDEX, 8);
- ref_reg_val = 0;
- j = 0;
-
- for (i = 0; i < (unsigned int)(pSlice->listXsize[1]); i++) {
- /* ref list 0 */
- struct StorablePicture *ref = pSlice->listX[1][i];
- unsigned int cfg;
- /* bit[6:5] - frame/field info,
- * 01 - top, 10 - bottom, 11 - frame
- */
-
- #ifdef ERROR_CHECK
- if (ref == NULL) {
- hw->data_flag |= ERROR_FLAG;
- pic->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error list1 NULL\n");
- return -2;
- }
- if ((ref->data_flag & ERROR_FLAG) && (ref_frame_mark_flag[DECODE_ID(hw)])) {
- pic->data_flag |= ERROR_FLAG;
- hw->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " ref error mark2\n");
- }
- if (ref->data_flag & NULL_FLAG)
- hw->data_flag |= NULL_FLAG;
-#endif
- canvas_pos = hw->buffer_spec[ref->buf_spec_num].canvas_pos;
- if (ref->structure == TOP_FIELD)
- cfg = 0x1;
- else if (ref->structure == BOTTOM_FIELD)
- cfg = 0x2;
- else /* FRAME */
- cfg = 0x3;
- one_ref_cfg = (canvas_pos & 0x1f) | (cfg << 5);
- ref_reg_val <<= 8;
- ref_reg_val |= one_ref_cfg;
- j++;
-
- if (j == 4) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "H264_BUFFER_INFO_DATA: %x\n",
- ref_reg_val);
- WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val);
- j = 0;
- }
- print_pic_info(DECODE_ID(hw), "list1",
- pSlice->listX[1][i], -1);
- }
- if (j != 0) {
- while (j != 4) {
- ref_reg_val <<= 8;
- ref_reg_val |= one_ref_cfg;
- j++;
- }
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "H264_BUFFER_INFO_DATA: %x\n", ref_reg_val);
- WRITE_VREG(H264_BUFFER_INFO_DATA, ref_reg_val);
- }
-
- /* configure co-locate buffer */
- while ((READ_VREG(H264_CO_MB_RW_CTL) >> 11) & 0x1)
- ;
- if ((pSlice->mode_8x8_flags & 0x4) &&
- (pSlice->mode_8x8_flags & 0x2))
- use_direct_8x8 = 1;
- else
- use_direct_8x8 = 0;
-
-#ifndef ONE_COLOCATE_BUF_PER_DECODE_BUF
- colocate_adr_offset =
- ((pic->structure == FRAME && pic->mb_aff_frame_flag == 0)
- ? 1 : 2) * 96;
- if (use_direct_8x8)
- colocate_adr_offset >>= 2;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "colocate buf size of each mb 0x%x first_mb_in_slice 0x%x colocate_adr_offset 0x%x\r\n",
- colocate_adr_offset, pSlice->first_mb_in_slice,
- colocate_adr_offset * pSlice->first_mb_in_slice);
-
- colocate_adr_offset *= pSlice->first_mb_in_slice;
-
- if ((pic->colocated_buf_index >= 0) &&
- (pic->colocated_buf_index < p_H264_Dpb->colocated_buf_count)) {
- colocate_wr_adr = p_H264_Dpb->colocated_mv_addr_start +
- ((p_H264_Dpb->colocated_buf_size *
- pic->colocated_buf_index)
- >> (use_direct_8x8 ? 2 : 0));
- if ((colocate_wr_adr + p_H264_Dpb->colocated_buf_size) >
- p_H264_Dpb->colocated_mv_addr_end) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "Error, colocate buf is not enough, index is %d\n",
- pic->colocated_buf_index);
- ret = -3;
- }
- val = colocate_wr_adr + colocate_adr_offset;
- WRITE_VREG(H264_CO_MB_WR_ADDR, val);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "WRITE_VREG(H264_CO_MB_WR_ADDR) = %x, first_mb_in_slice %x pic_structure %x colocate_adr_offset %x mode_8x8_flags %x colocated_buf_size %x\n",
- val, pSlice->first_mb_in_slice, pic->structure,
- colocate_adr_offset, pSlice->mode_8x8_flags,
- p_H264_Dpb->colocated_buf_size);
- } else {
- WRITE_VREG(H264_CO_MB_WR_ADDR, 0xffffffff);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "WRITE_VREG(H264_CO_MB_WR_ADDR) = 0xffffffff\n");
- }
-#else
- colocate_buf_index = hw->buffer_spec[pic->buf_spec_num].canvas_pos;
- colocate_adr_offset =
- ((pic->structure == FRAME && pic->mb_aff_frame_flag == 0) ? 1 : 2) * 96;
- if (use_direct_8x8)
- colocate_adr_offset >>= 2;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "colocate buf size of each mb 0x%x first_mb_in_slice 0x%x colocate_adr_offset 0x%x\r\n",
- colocate_adr_offset, pSlice->first_mb_in_slice,
- colocate_adr_offset * pSlice->first_mb_in_slice);
-
- colocate_adr_offset *= pSlice->first_mb_in_slice;
-
- colocate_wr_adr = p_H264_Dpb->colocated_mv_addr_start +
- ((p_H264_Dpb->colocated_buf_size * colocate_buf_index) >>
- (use_direct_8x8 ? 2 : 0));
-
- if ((colocate_wr_adr + p_H264_Dpb->colocated_buf_size) >
- p_H264_Dpb->colocated_mv_addr_end) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "Error, colocate buf is not enough, col buf index is %d\n",
- colocate_buf_index);
- ret = -4;
- }
- val = colocate_wr_adr + colocate_adr_offset;
- WRITE_VREG(H264_CO_MB_WR_ADDR, val);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "WRITE_VREG(H264_CO_MB_WR_ADDR) = %x, first_mb_in_slice %x pic_structure %x colocate_adr_offset %x mode_8x8_flags %x colocated_buf_size %x\n",
- val, pSlice->first_mb_in_slice, pic->structure,
- colocate_adr_offset, pSlice->mode_8x8_flags,
- p_H264_Dpb->colocated_buf_size);
-#endif
- if (pSlice->listXsize[1] > 0) {
- struct StorablePicture *colocate_pic = pSlice->listX[1][0];
- /* H264_CO_MB_RD_ADDR[bit 31:30],
- * original picture structure of L1[0],
- * 00 - top field, 01 - bottom field,
- * 10 - frame, 11 - mbaff frame
- */
- int l10_structure, cur_structure;
- int cur_colocate_ref_type;
- /* H264_CO_MB_RD_ADDR[bit 29], top/bot for B field pciture,
- * 0 - top, 1 - bot
- */
- unsigned int val;
- unsigned int colocate_rd_adr_offset;
- unsigned int mby_mbx;
- unsigned int mby, mbx;
-#ifdef ERROR_CHECK
- if (colocate_pic == NULL) {
- hw->data_flag |= ERROR_FLAG;
- pic->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocate error pic NULL\n");
- return -5;
- }
- if (colocate_pic->data_flag & ERROR_FLAG) {
- pic->data_flag |= ERROR_FLAG;
- hw->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG, " colocare ref error mark\n");
- }
- if (colocate_pic->data_flag & NULL_FLAG)
- hw->data_flag |= NULL_FLAG;
-#endif
-
- if (colocate_pic->mb_aff_frame_flag)
- l10_structure = 3;
- else {
- if (colocate_pic->coded_frame)
- l10_structure = 2;
- else
- l10_structure = (colocate_pic->structure ==
- BOTTOM_FIELD) ? 1 : 0;
- }
-
- //ALLEGRO_FIX, ported from single mode ucode
- mby_mbx = READ_VREG(MBY_MBX);
- mby = pSlice->first_mb_in_slice / hw->mb_width;
- mbx = pSlice->first_mb_in_slice % hw->mb_width;
- if (pic->mb_aff_frame_flag)
- cur_structure = 3;
- else {
- if (pic->coded_frame)
- cur_structure = 2;
- else
- cur_structure = (pic->structure ==
- BOTTOM_FIELD) ? 1 : 0;
- }
- if (cur_structure < 2) {
- //current_field_structure
- if (l10_structure != 2) {
- colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2;
- } else {
- // field_ref_from_frame co_mv_rd_addr :
- // mby*2*mb_width + mbx
- colocate_rd_adr_offset = mby * 2 * hw->mb_width + mbx;
- }
-
- } else {
- //current_frame_structure
- if (l10_structure < 2) {
- //calculate_co_mv_offset_frame_ref_field:
- // frame_ref_from_field co_mv_rd_addr :
- // (mby/2*mb_width+mbx)*2
- colocate_rd_adr_offset = ((mby / 2) * hw->mb_width + mbx) * 2;
- } else if (cur_structure == 2) {
- colocate_rd_adr_offset = pSlice->first_mb_in_slice;
- } else {
- //mbaff frame case1196
- colocate_rd_adr_offset = pSlice->first_mb_in_slice * 2;
- }
-
- }
-
- colocate_rd_adr_offset *= 96;
- if (use_direct_8x8)
- colocate_rd_adr_offset >>= 2;
-
- if (colocate_old_cal)
- colocate_rd_adr_offset = colocate_adr_offset;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "first_mb_in_slice 0x%x 0x%x 0x%x (MBY_MBX reg 0x%x) use_direct_8x8 %d cur %d (mb_aff_frame_flag %d, coded_frame %d structure %d) col %d (mb_aff_frame_flag %d, coded_frame %d structure %d) offset 0x%x rdoffset 0x%x\n",
- pSlice->first_mb_in_slice, mby, mbx, mby_mbx, use_direct_8x8,
- cur_structure, pic->mb_aff_frame_flag, pic->coded_frame, pic->structure,
- l10_structure, colocate_pic->mb_aff_frame_flag, colocate_pic->coded_frame, colocate_pic->structure,
- colocate_adr_offset,
- colocate_rd_adr_offset);
-
-#if 0
- /*case0016, p16,
- *cur_colocate_ref_type should be configured base on current pic
- */
- if (pic->structure == FRAME &&
- pic->mb_aff_frame_flag)
- cur_colocate_ref_type = 0;
- else if (pic->structure == BOTTOM_FIELD)
- cur_colocate_ref_type = 1;
- else
- cur_colocate_ref_type = 0;
-#else
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- " CUR TMP DEBUG : mb_aff_frame_flag : %d, structure : %d coded_frame %d\n",
- pic->mb_aff_frame_flag,
- pic->structure,
- pic->coded_frame);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- " COL TMP DEBUG : mb_aff_frame_flag : %d, structure : %d coded_frame %d\n",
- colocate_pic->mb_aff_frame_flag,
- colocate_pic->structure,
- colocate_pic->coded_frame);
- if (pic->structure == FRAME || pic->mb_aff_frame_flag) {
- cur_colocate_ref_type =
- (abs(pic->poc - colocate_pic->top_poc)
- < abs(pic->poc -
- colocate_pic->bottom_poc)) ? 0 : 1;
- } else
- cur_colocate_ref_type =
- (colocate_pic->structure
- == BOTTOM_FIELD) ? 1 : 0;
-#endif
-
-#ifndef ONE_COLOCATE_BUF_PER_DECODE_BUF
- if ((colocate_pic->colocated_buf_index >= 0) &&
- (colocate_pic->colocated_buf_index <
- p_H264_Dpb->colocated_buf_count)) {
- colocate_rd_adr = p_H264_Dpb->colocated_mv_addr_start +
- ((p_H264_Dpb->colocated_buf_size *
- colocate_pic->colocated_buf_index)
- >> (use_direct_8x8 ? 2 : 0));
- if ((colocate_rd_adr + p_H264_Dpb->colocated_buf_size) >
- p_H264_Dpb->colocated_mv_addr_end) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR,
- "Error, colocate buf is not enough, index is %d\n",
- colocate_pic->colocated_buf_index);
- ret = -6;
- }
- /* bit 31:30 -- L1[0] picture coding structure,
- * 00 - top field, 01 - bottom field,
- * 10 - frame, 11 - mbaff frame
- * bit 29 - L1[0] top/bot for B field pciture,
- * 0 - top, 1 - bot
- * bit 28:0 h264_co_mb_mem_rd_addr[31:3]
- * -- only used for B Picture Direct mode
- * [2:0] will set to 3'b000
- */
- /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */
- val = ((colocate_rd_adr+colocate_rd_adr_offset) >> 3) |
- (l10_structure << 30) |
- (cur_colocate_ref_type << 29);
- WRITE_VREG(H264_CO_MB_RD_ADDR, val);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "co idx %d, WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, addr %x L1(0) pic_structure %d mbaff %d\n",
- colocate_pic->colocated_buf_index,
- val, colocate_rd_adr + colocate_rd_adr_offset,
- colocate_pic->structure,
- colocate_pic->mb_aff_frame_flag);
- } else {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "Error, reference pic has no colocated buf\n");
- ret = -7;
- }
-#else
- colocate_buf_index =
- hw->buffer_spec[colocate_pic->buf_spec_num].canvas_pos;
- colocate_rd_adr = p_H264_Dpb->colocated_mv_addr_start +
- ((p_H264_Dpb->colocated_buf_size *
- colocate_buf_index)
- >> (use_direct_8x8 ? 2 : 0));
- if ((colocate_rd_adr + p_H264_Dpb->colocated_buf_size) >
- p_H264_Dpb->colocated_mv_addr_end) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "Error, colocate buf is not enough, col buf index is %d\n",
- colocate_buf_index);
- ret = -8;
- }
- /* bit 31:30 -- L1[0] picture coding structure,
- * 00 - top field, 01 - bottom field,
- * 10 - frame, 11 - mbaff frame
- * bit 29 - L1[0] top/bot for B field pciture,
- * 0 - top, 1 - bot
- * bit 28:0 h264_co_mb_mem_rd_addr[31:3]
- * -- only used for B Picture Direct mode
- * [2:0] will set to 3'b000
- */
- /* #define H264_CO_MB_RD_ADDR VLD_C39 0xc39 */
- val = ((colocate_rd_adr+colocate_rd_adr_offset)>>3) |
- (l10_structure << 30) | (cur_colocate_ref_type << 29);
- WRITE_VREG(H264_CO_MB_RD_ADDR, val);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "WRITE_VREG(H264_CO_MB_RD_ADDR) = %x, L1(0) pic_structure %d mbaff %d\n",
- val, colocate_pic->structure,
- colocate_pic->mb_aff_frame_flag);
-#endif
- }
- return ret;
-}
-
-static int vh264_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
- struct vdec_s *vdec = op_arg;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
-
- spin_lock_irqsave(&hw->lock, flags);
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
-
- spin_unlock_irqrestore(&hw->lock, flags);
-
- return 0;
-}
-
-static struct vframe_s *vh264_vf_peek(void *op_arg)
-{
- struct vframe_s *vf[2] = {0, 0};
- struct vdec_s *vdec = op_arg;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
-
- if (!hw)
- return NULL;
-
- if (force_disp_bufspec_num & 0x100) {
- if (force_disp_bufspec_num & 0x200)
- return NULL;
- return &hw->vframe_dummy;
- }
-
- if (kfifo_out_peek(&hw->display_q, (void *)&vf, 2)) {
- if (vf[1]) {
- vf[0]->next_vf_pts_valid = true;
- vf[0]->next_vf_pts = vf[1]->pts;
- } else
- vf[0]->next_vf_pts_valid = false;
- return vf[0];
- }
-
- return NULL;
-}
-
-static struct vframe_s *vh264_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- ulong nv_order = VIDTYPE_VIU_NV21;
-
- if (!hw)
- return NULL;
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
- if (force_disp_bufspec_num & 0x100) {
- int buffer_index = force_disp_bufspec_num & 0xff;
- if (force_disp_bufspec_num & 0x200)
- return NULL;
-
- vf = &hw->vframe_dummy;
- vf->duration_pulldown = 0;
- vf->pts = 0;
- vf->pts_us64 = 0;
- set_frame_info(hw, vf, buffer_index);
- vf->flag = 0;
- if (hw->mmu_enable) {
- if (hw->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
- } else {
- /*head adr*/
- vf->compHeadAddr =
- hw->buffer_spec[buffer_index].alloc_header_addr;
- /*body adr*/
- vf->compBodyAddr = 0;
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
-
- vf->type = VIDTYPE_SCATTER;
-
- if (hw->double_write_mode) {
- vf->type |= VIDTYPE_PROGRESSIVE
- | VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
- if (hw->double_write_mode == 3)
- vf->type |= VIDTYPE_COMPRESS;
-
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- hw->buffer_spec[buffer_index].
- canvas_config[0];
- vf->canvas0_config[1] =
- hw->buffer_spec[buffer_index].
- canvas_config[1];
-
- vf->canvas1_config[0] =
- hw->buffer_spec[buffer_index].
- canvas_config[0];
- vf->canvas1_config[1] =
- hw->buffer_spec[buffer_index].
- canvas_config[1];
- } else {
- vf->type |=
- VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
-
- vf->compWidth = hw->frame_width;
- vf->compHeight = hw->frame_height;
-
- if (hw->double_write_mode) {
- vf->width = hw->frame_width /
- get_double_write_ratio(hw->double_write_mode);
- vf->height = hw->frame_height /
- get_double_write_ratio(hw->double_write_mode);
- }
- } else {
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
- nv_order;
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(&hw->buffer_spec[buffer_index]);
- }
-
- /*vf->mem_handle = decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, buffer_index);*/
- update_vf_memhandle(hw, vf, buffer_index);
- force_disp_bufspec_num |= 0x200;
- return vf;
- }
-
- if (kfifo_get(&hw->display_q, &vf)) {
- int time = jiffies;
- unsigned int frame_interval =
- 1000*(time - hw->last_frame_time)/HZ;
- struct vframe_s *next_vf = NULL;
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_VDEC_DETAIL)) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int frame_index = FRAME_INDEX(vf->index);
- if (frame_index < 0 ||
- frame_index >= DPB_SIZE_MAX) {
- dpb_print(DECODE_ID(hw), 0,
- "%s vf index 0x%x error\r\n",
- __func__, vf->index);
- } else {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s buf_spec_num %d vf %p poc %d dur %d pts %d interval %dms, ts: %lld\n",
- __func__, BUFSPEC_INDEX(vf->index), vf,
- p_H264_Dpb->mFrameStore[frame_index].poc,
- vf->duration, vf->pts, frame_interval, vf->timestamp);
- }
- }
- if (hw->last_frame_time > 0) {
- if (frame_interval >
- max_get_frame_interval[DECODE_ID(hw)])
- max_get_frame_interval[DECODE_ID(hw)]
- = frame_interval;
- }
- hw->last_frame_time = time;
- vf->index_disp = atomic_read(&hw->vf_get_count);
- atomic_add(1, &hw->vf_get_count);
- if (kfifo_peek(&hw->display_q, &next_vf) && next_vf) {
- vf->next_vf_pts_valid = true;
- vf->next_vf_pts = next_vf->pts;
- } else
- vf->next_vf_pts_valid = false;
-
- return vf;
- }
-
- return NULL;
-}
-
-static bool vf_valid_check(struct vframe_s *vf, struct vdec_h264_hw_s *hw) {
- int i,j;
- if (hw->is_used_v4l)
- return true;
- for (i = 0; i < VF_POOL_SIZE; i++) {
- for (j = 0; j < VF_POOL_NUM; j ++) {
- if (vf == &(hw->vfpool[j][i]) || vf == &hw->vframe_dummy)
- return true;
- }
- }
- dpb_print(DECODE_ID(hw), 0, " invalid vf been put, vf = %p\n", vf);
- for (i = 0; i < VF_POOL_SIZE; i++) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "dump vf [%d]= %p\n", i, &(hw->vfpool[hw->cur_pool][i]));
- }
- return false;
-}
-
-static void vh264_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- unsigned long flags;
- int buf_spec_num;
- int frame_index;
-
- if (vf == (&hw->vframe_dummy))
- return;
-
- if (!vf)
- return;
-
- if (vf->index == -1) {
- dpb_print(DECODE_ID(hw), 0,
- "Warning: %s vf %p invalid index\r\n",
- __func__, vf);
- return;
- }
-
- if (hw->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&hw->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (hw->fence_vf_s.fence_vf[i] == NULL) {
- hw->fence_vf_s.fence_vf[i] = vf;
- hw->fence_vf_s.used_size++;
- mutex_unlock(&hw->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&hw->fence_mutex);
- }
-
- buf_spec_num = BUFSPEC_INDEX(vf->index);
- if (hw->enable_fence)
- frame_index = hw->buffer_spec[buf_spec_num].fs_idx;
- else
- frame_index = FRAME_INDEX(vf->index);
-
- if (frame_index < 0 ||
- frame_index >= DPB_SIZE_MAX ||
- buf_spec_num < 0 ||
- buf_spec_num >= BUFSPEC_POOL_SIZE) {
- dpb_print(DECODE_ID(hw), 0,
- "%s vf index 0x%x error\r\n",
- __func__, vf->index);
- return;
- }
- /*get_buf_spec_idx_by_canvas_config(hw,
- &vf->canvas0_config[0]);*/
-
- if (hw->enable_fence && vf->fence) {
- vdec_fence_put(vf->fence);
- vf->fence = NULL;
- }
-
- if (vf->meta_data_buf) {
- vf->meta_data_buf = NULL;
- vf->meta_data_size = 0;
- }
-
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- if (hw->buffer_spec[buf_spec_num].used == 2) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s %p to fs[%d], poc %d buf_spec_num %d used %d vf_ref %d\n",
- __func__, vf, frame_index,
- p_H264_Dpb->mFrameStore[frame_index].poc,
- buf_spec_num,
- hw->buffer_spec[buf_spec_num].used,
- hw->buffer_spec[buf_spec_num].vf_ref);
- hw->buffer_spec[buf_spec_num].vf_ref--;
- if (hw->buffer_spec[buf_spec_num].vf_ref <= 0)
- set_frame_output_flag(&hw->dpb, frame_index);
- } else {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s %p isolated vf, buf_spec_num %d used %d vf_ref %d\n",
- __func__, vf, buf_spec_num,
- hw->buffer_spec[buf_spec_num].used,
- hw->buffer_spec[buf_spec_num].vf_ref);
- hw->buffer_spec[buf_spec_num].vf_ref--;
- if (hw->buffer_spec[buf_spec_num].vf_ref <= 0) {
- if (hw->buffer_spec[buf_spec_num].used == 3)
- hw->buffer_spec[buf_spec_num].used = 4;
- else if (hw->buffer_spec[buf_spec_num].used == 5)
- hw->buffer_spec[buf_spec_num].used = 0;
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
-
- }
-
- if (hw->is_used_v4l) {
- struct buffer_spec_s *pic = &hw->buffer_spec[buf_spec_num];
-
- if (vf->v4l_mem_handle != pic->cma_alloc_addr) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "H264 update fb handle, old:%llx, new:%llx\n",
- pic->cma_alloc_addr, vf->v4l_mem_handle);
-
- pic->cma_alloc_addr = vf->v4l_mem_handle;
- }
- }
-
- if (vf && (vf_valid_check(vf, hw) == true)) {
- atomic_add(1, &hw->vf_put_count);
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
- }
-#define ASSIST_MBOX1_IRQ_REG VDEC_ASSIST_MBOX1_IRQ_REG
- if (hw->buffer_empty_flag)
- WRITE_VREG(ASSIST_MBOX1_IRQ_REG, 0x1);
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
-}
-
-
-void * vh264_get_bufspec_lock(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- if (hw)
- return (&hw->bufspec_lock);
- else
- return NULL;
-}
-static int vh264_event_cb(int type, void *data, void *op_arg)
-{
- unsigned long flags;
- struct vdec_s *vdec = op_arg;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
-
- if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
- struct provider_aux_req_s *req =
- (struct provider_aux_req_s *)data;
- int buf_spec_num;
-
- if (!req->vf) {
- req->aux_size = atomic_read(&hw->vf_put_count);
- return 0;
- }
- buf_spec_num = BUFSPEC_INDEX(req->vf->index);
- spin_lock_irqsave(&hw->lock, flags);
- req->aux_buf = NULL;
- req->aux_size = 0;
- if (buf_spec_num >= 0 &&
- buf_spec_num < BUFSPEC_POOL_SIZE &&
- is_buf_spec_in_disp_q(hw, buf_spec_num)
- ) {
- req->aux_buf =
- hw->buffer_spec[buf_spec_num].aux_data_buf;
- req->aux_size =
- hw->buffer_spec[buf_spec_num].aux_data_size;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- req->dv_enhance_exist =
- hw->buffer_spec[buf_spec_num].dv_enhance_exist;
-#else
- req->dv_enhance_exist = 0;
-#endif
- }
- spin_unlock_irqrestore(&hw->lock, flags);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s(type 0x%x vf buf_spec_num 0x%x)=>size 0x%x\n",
- __func__, type, buf_spec_num, req->aux_size);
- } else if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf,
- u32 index)
-{
- int endian_tmp;
- struct canvas_config_s *p_canvas_config;
- int force_rate = input_frame_based(hw_to_vdec(hw)) ?
- force_rate_framebase : force_rate_streambase;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s (%d,%d) dur %d, vf %p, index %d\n", __func__,
- hw->frame_width, hw->frame_height, hw->frame_dur, vf, index);
-
- /* signal_type */
- if (hw->video_signal_from_vui & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) {
- vf->signal_type = hw->video_signal_from_vui;
- if (hw->is_used_v4l) {
- struct aml_vdec_hdr_infos hdr;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.signal_type = hw->video_signal_from_vui;
- vdec_v4l_set_hdr_infos(ctx, &hdr);
- }
- } else
- vf->signal_type = 0;
- hw->video_signal_type = vf->signal_type;
-
- vf->width = hw->frame_width;
- vf->height = hw->frame_height;
- if (force_rate) {
- if (force_rate == -1)
- vf->duration = 0;
- else
- vf->duration = 96000/force_rate;
- } else
- vf->duration = hw->frame_dur;
- vf->ratio_control =
- (min(hw->h264_ar, (u32) DISP_RATIO_ASPECT_RATIO_MAX)) <<
- DISP_RATIO_ASPECT_RATIO_BIT;
- vf->orientation = hw->vh264_rotation;
-
- vf->sidebind_type = hw->sidebind_type;
- vf->sidebind_channel_id = hw->sidebind_channel_id;
-
- if (hw->mmu_enable)
- return;
-
- vf->canvas0Addr = vf->canvas1Addr = -1;
-#ifdef NV21
- vf->plane_num = 2;
-#else
- vf->plane_num = 3;
-#endif
-
- if (IS_VDEC_DW(hw)) {
- if (IS_VDEC_DW(hw) == 1)
- vf->width = hw->frame_width / 2;
- else
- vf->width = (hw->frame_width / IS_VDEC_DW(hw));
- vf->height = (hw->frame_height / IS_VDEC_DW(hw));
- p_canvas_config = &hw->buffer_spec[index].vdec_dw_canvas_config[0];
- } else
- p_canvas_config = &hw->buffer_spec[index].canvas_config[0];
-
- vf->canvas0_config[0] = p_canvas_config[0];
- vf->canvas0_config[1] = p_canvas_config[1];
- vf->canvas1_config[0] = p_canvas_config[0];
- vf->canvas1_config[1] = p_canvas_config[1];
-#ifndef NV21
- vf->canvas0_config[2] = p_canvas_config[2];
- vf->canvas1_config[2] = p_canvas_config[2];
-#endif
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- } else {
- endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 0 : 7;
- }
- vf->canvas0_config[0].endian = endian_tmp;
- vf->canvas0_config[1].endian = endian_tmp;
- vf->canvas1_config[0].endian = endian_tmp;
- vf->canvas1_config[1].endian = endian_tmp;
-#ifndef NV21
- vf->canvas0_config[2].endian = endian_tmp;
- vf->canvas1_config[2].endian = endian_tmp;
-#endif
-}
-
-static void get_picture_qos_info(struct StorablePicture *picture)
-{
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
-
- get_random_bytes(&data, sizeof(unsigned long));
- if (picture->slice_type == I_SLICE)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_mv = a[2];
- picture->avg_mv = a[1];
- picture->min_mv = a[0];
- /*
- pr_info("mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
- */
-
- get_random_bytes(&data, sizeof(unsigned long));
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_qp = a[2];
- picture->avg_qp = a[1];
- picture->min_qp = a[0];
- /*
- pr_info("qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
- */
-
- get_random_bytes(&data, sizeof(unsigned long));
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_skip = a[2];
- picture->avg_skip = a[1];
- picture->min_skip = a[0];
-
-
- /*
- pr_info("skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data,a[0], a[1], a[2]);
- */
- } else {
- uint32_t blk88_y_count;
- uint32_t blk88_c_count;
- uint32_t blk22_mv_count;
- uint32_t rdata32;
- int32_t mv_hi;
- int32_t mv_lo;
- uint32_t rdata32_l;
- uint32_t mvx_L0_hi;
- uint32_t mvy_L0_hi;
- uint32_t mvx_L1_hi;
- uint32_t mvy_L1_hi;
- int64_t value;
- uint64_t temp_value;
-/*
-#define DEBUG_QOS
-*/
-#ifdef DEBUG_QOS
- int pic_number = picture->poc;
-#endif
-
- picture->max_mv = 0;
- picture->avg_mv = 0;
- picture->min_mv = 0;
-
- picture->max_skip = 0;
- picture->avg_skip = 0;
- picture->min_skip = 0;
-
- picture->max_qp = 0;
- picture->avg_qp = 0;
- picture->min_qp = 0;
-
-
-
-
-
- /* set rd_idx to 0 */
- WRITE_VREG(VDEC_PIC_QUALITY_CTRL, 0);
- blk88_y_count = READ_VREG(VDEC_PIC_QUALITY_DATA);
- if (blk88_y_count == 0) {
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_y_sum */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_y_count,
- rdata32, blk88_y_count);
-#endif
- picture->avg_qp = rdata32/blk88_y_count;
- /* intra_y_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- /* skipped_y_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- picture->avg_skip = rdata32*100/blk88_y_count;
- /* coeff_non_zero_y_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_y_count*1)),
- '%', rdata32);
-#endif
- /* blk66_c_count */
- blk88_c_count = READ_VREG(VDEC_PIC_QUALITY_DATA);
- if (blk88_c_count == 0) {
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_c_sum */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] C QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_c_count,
- rdata32, blk88_c_count);
-#endif
- /* intra_c_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] C intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* skipped_cu_c_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] C skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* coeff_non_zero_c_count */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_c_count*1)),
- '%', rdata32);
-#endif
-
- /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
- 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
-#endif
- picture->min_qp = (rdata32>>0)&0xff;
-
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
-#endif
- picture->max_qp = (rdata32>>8)&0xff;
-
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
- pr_info(" [Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
-#endif
-
- /* blk22_mv_count */
- blk22_mv_count = READ_VREG(VDEC_PIC_QUALITY_DATA);
- if (blk22_mv_count == 0) {
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] NO MV Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* mvy_L1_count[39:32], mvx_L1_count[39:32],
- mvy_L0_count[39:32], mvx_L0_count[39:32] */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
- /* should all be 0x00 or 0xff */
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MV AVG High Bits: 0x%X\n",
- pic_number, rdata32);
-#endif
- mvx_L0_hi = ((rdata32>>0)&0xff);
- mvy_L0_hi = ((rdata32>>8)&0xff);
- mvx_L1_hi = ((rdata32>>16)&0xff);
- mvy_L1_hi = ((rdata32>>24)&0xff);
-
- /* mvx_L0_count[31:0] */
- rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA);
- temp_value = mvx_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvx_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
- value = div_s64(value, blk22_mv_count);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
- pic_number, (int)(value),
- value, blk22_mv_count);
-#endif
- picture->avg_mv = value;
-
- /* mvy_L0_count[31:0] */
- rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA);
- temp_value = mvy_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvy_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvx_L1_count[31:0] */
- rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA);
- temp_value = mvx_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvx_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvy_L1_count[31:0] */
- rdata32_l = READ_VREG(VDEC_PIC_QUALITY_DATA);
- temp_value = mvy_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvy_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVX_L0 MAX : %d\n",
- pic_number, mv_hi);
-#endif
- picture->max_mv = mv_hi;
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] MVX_L0 MIN : %d\n",
- pic_number, mv_lo);
-#endif
- picture->min_mv = mv_lo;
-
-#ifdef DEBUG_QOS
- /* {mvy_L0_max, mvy_L0_min} */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
- pr_info(" [Picture %d Quality] MVY_L0 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- pr_info(" [Picture %d Quality] MVY_L0 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvx_L1_max, mvx_L1_min} */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- pr_info(" [Picture %d Quality] MVX_L1 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- pr_info(" [Picture %d Quality] MVX_L1 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvy_L1_max, mvy_L1_min} */
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- pr_info(" [Picture %d Quality] MVY_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- pr_info(" [Picture %d Quality] MVY_L1 MIN : %d\n",
- pic_number, mv_lo);
-#endif
-
- rdata32 = READ_VREG(VDEC_PIC_QUALITY_CTRL);
-#ifdef DEBUG_QOS
- pr_info(" [Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
- pic_number, rdata32);
-#endif
- /* reset all counts */
- WRITE_VREG(VDEC_PIC_QUALITY_CTRL, (1<<8));
- }
-}
-
-static int get_dec_dpb_size(struct vdec_h264_hw_s *hw, int mb_width,
- int mb_height, int level_idc)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int pic_size = mb_width * mb_height * 384;
- int size = 0, size_vui;
-
- switch (level_idc) {
- case 9:
- size = 152064;
- break;
- case 10:
- size = 152064;
- break;
- case 11:
- size = 345600;
- break;
- case 12:
- size = 912384;
- break;
- case 13:
- size = 912384;
- break;
- case 20:
- size = 912384;
- break;
- case 21:
- size = 1824768;
- break;
- case 22:
- size = 3110400;
- break;
- case 30:
- size = 3110400;
- break;
- case 31:
- size = 6912000;
- break;
- case 32:
- size = 7864320;
- break;
- case 40:
- size = 12582912;
- break;
- case 41:
- size = 12582912;
- break;
- case 42:
- size = 13369344;
- break;
- case 50:
- size = 42393600;
- break;
- case 51:
- case 52:
- default:
- size = 70778880;
- break;
- }
-
- size /= pic_size;
- size = imin(size, 16);
- dpb_print(DECODE_ID(hw), 0,
- "level_idc = %d pic_size = %d size = %d\n",
- level_idc, pic_size, size);
- if (p_H264_Dpb->bitstream_restriction_flag) {
- if ((int)p_H264_Dpb->max_dec_frame_buffering > size) {
- dpb_print(DECODE_ID(hw), 0,
- "max_dec_frame_buffering larger than MaxDpbSize.\n");
- }
- size_vui = imax (1, p_H264_Dpb->max_dec_frame_buffering);
- if (size_vui < size) {
- dpb_print(DECODE_ID(hw), 0,
- "Warning: max_dec_frame_buffering(%d) is less than DPB size(%d) calculated from Profile/Level.\n",
- size_vui, size);
- }
- size = size_vui;
- }
-
- size += 2; /* need two more buffer */
-
- if (!hw->discard_dv_data) {
- size += 1;
- dpb_print(DECODE_ID(hw), 0, "dv stream need one more buffer.\n");
- }
-
- return size;
-}
-
-static int get_dec_dpb_size_active(struct vdec_h264_hw_s *hw, u32 param1, u32 param4)
-{
- int mb_width, mb_total;
- int mb_height = 0;
- int dec_dpb_size;
- int level_idc = param4 & 0xff;
-
- mb_width = param1 & 0xff;
- mb_total = (param1 >> 8) & 0xffff;
- if (!mb_width && mb_total) /*for 4k2k*/
- mb_width = 256;
- if (mb_width)
- mb_height = mb_total/mb_width;
- if (mb_width <= 0 || mb_height <= 0 ||
- is_oversize(mb_width << 4, mb_height << 4)) {
- dpb_print(DECODE_ID(hw), 0,
- "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
- param1,
- mb_width,
- mb_height);
- hw->error_frame_width = mb_width << 4;
- hw->error_frame_height = mb_height << 4;
- return -1;
- }
- hw->error_frame_width = 0;
- hw->error_frame_height = 0;
-
- dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height, level_idc);
-
- if (hw->no_poc_reorder_flag)
- dec_dpb_size = 1;
-
- return dec_dpb_size;
-}
-
-static void vh264_config_canvs_for_mmu(struct vdec_h264_hw_s *hw)
-{
- int i, j;
-
- if (hw->double_write_mode) {
- mutex_lock(&vmh264_mutex);
- if (hw->decode_pic_count == 0) {
- for (j = 0; j < hw->dpb.mDPB.size; j++) {
- i = get_buf_spec_by_canvas_pos(hw, j);
- if (i >= 0)
- config_decode_canvas_ex(hw, i);
- }
- }
- mutex_unlock(&vmh264_mutex);
- }
-}
-
-static int vh264_set_params(struct vdec_h264_hw_s *hw,
- u32 param1, u32 param2, u32 param3, u32 param4, bool buffer_reset_flag)
-{
- int i, j;
- int mb_width, mb_total;
- int max_reference_size, level_idc;
- int mb_height = 0;
- unsigned long flags;
- /*int mb_mv_byte;*/
- struct vdec_s *vdec = hw_to_vdec(hw);
- u32 seq_info2;
- int ret = 0;
- int active_buffer_spec_num;
- unsigned int buf_size;
- unsigned int frame_mbs_only_flag;
- unsigned int chroma_format_idc;
- unsigned int crop_bottom, crop_right;
- unsigned int used_reorder_dpb_size_margin
- = hw->reorder_dpb_size_margin;
- u8 *colocate_vaddr = NULL;
- int dec_dpb_size_change = 0;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master || vdec->slave)
- used_reorder_dpb_size_margin =
- reorder_dpb_size_margin_dv;
-#endif
- seq_info2 = param1;
- hw->seq_info = param2;
-
- mb_width = seq_info2 & 0xff;
- mb_total = (seq_info2 >> 8) & 0xffff;
- if (!mb_width && mb_total) /*for 4k2k*/
- mb_width = 256;
- if (mb_width)
- mb_height = mb_total/mb_width;
- if (mb_width <= 0 || mb_height <= 0 ||
- is_oversize(mb_width << 4, mb_height << 4)) {
- dpb_print(DECODE_ID(hw), 0,
- "!!!wrong seq_info2 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
- seq_info2,
- mb_width,
- mb_height);
- hw->error_frame_width = mb_width << 4;
- hw->error_frame_height = mb_height << 4;
- return -1;
- }
- hw->error_frame_width = 0;
- hw->error_frame_height = 0;
-
- dec_dpb_size_change = hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1, param4);
-
- if (((seq_info2 != 0 &&
- hw->seq_info2 != seq_info2) || hw->csd_change_flag) &&
- hw->seq_info2 != 0
- ) {
- if (((hw->seq_info2 & 0x80ffffff) != (param1 & 0x80ffffff)) || dec_dpb_size_change) { /*picture size changed*/
- h264_reconfig(hw);
- } else {
- /*someting changes and not including dpb_size, width, height, ...*/
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- u32 reg_val = param4;
- max_reference_size = (reg_val >> 8) & 0xff;
- hw->dpb.reorder_output = max_reference_size;
-
- hw->cfg_param1 = param1;
- hw->cfg_bitstream_restriction_flag = hw->bitstream_restriction_flag;
-
- hw->seq_info2 = seq_info2;
-
- if (p_H264_Dpb->bitstream_restriction_flag &&
- p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering &&
- p_H264_Dpb->num_reorder_frames >= 0) {
- hw->dpb.reorder_output = hw->num_reorder_frames + 1;
- }
-
- hw->max_reference_size =
- max_reference_size + reference_buf_margin;
-
- if (hw->max_reference_size > MAX_VF_BUF_NUM)
- hw->max_reference_size = MAX_VF_BUF_NUM;
- hw->dpb.max_reference_size = hw->max_reference_size;
- }
- }
-
- if (hw->config_bufmgr_done == 0) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- u32 reg_val;
- int sub_width_c = 0, sub_height_c = 0;
-
- hw->cfg_param1 = param1;
- hw->cfg_param2 = param2;
- hw->cfg_param3 = param3;
- hw->cfg_param4 = param4;
- hw->cfg_bitstream_restriction_flag = hw->bitstream_restriction_flag;
-
- hw->seq_info2 = seq_info2;
- dpb_print(DECODE_ID(hw), 0,
- "AV_SCRATCH_1 = %x, AV_SCRATCH_2 %x\r\n",
- seq_info2, hw->seq_info);
-
- dpb_init_global(&hw->dpb,
- DECODE_ID(hw), 0, 0);
-
- p_H264_Dpb->fast_output_enable = fast_output_enable;
- /*mb_mv_byte = (seq_info2 & 0x80000000) ? 24 : 96;*/
-
- if (hw->enable_fence)
- p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST;
-
-#if 1
- /*crop*/
- /* AV_SCRATCH_2
- bit 15: frame_mbs_only_flag
- bit 13-14: chroma_format_idc */
- frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01;
- if (p_H264_Dpb->mSPS.profile_idc != 100 &&
- p_H264_Dpb->mSPS.profile_idc != 110 &&
- p_H264_Dpb->mSPS.profile_idc != 122 &&
- p_H264_Dpb->mSPS.profile_idc != 144) {
- p_H264_Dpb->chroma_format_idc = 1;
- }
- chroma_format_idc = p_H264_Dpb->chroma_format_idc;
-
- /* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1
- @AV_SCRATCH_6.15-0 = (top << 8 | bottom ) <<
- (2 - frame_mbs_only_flag) */
-
- switch (chroma_format_idc) {
- case 1:
- sub_width_c = 2;
- sub_height_c = 2;
- break;
-
- case 2:
- sub_width_c = 2;
- sub_height_c = 1;
- break;
-
- case 3:
- sub_width_c = 1;
- sub_height_c = 1;
- break;
-
- default:
- break;
- }
-
- if (chroma_format_idc == 0) {
- crop_right = p_H264_Dpb->frame_crop_right_offset;
- crop_bottom = p_H264_Dpb->frame_crop_bottom_offset *
- (2 - frame_mbs_only_flag);
- } else {
- crop_right = sub_width_c * p_H264_Dpb->frame_crop_right_offset;
- crop_bottom = sub_height_c * p_H264_Dpb->frame_crop_bottom_offset *
- (2 - frame_mbs_only_flag);
- }
-
- p_H264_Dpb->mSPS.frame_mbs_only_flag = frame_mbs_only_flag;
- hw->frame_width = mb_width << 4;
- hw->frame_height = mb_height << 4;
-
- hw->frame_width = hw->frame_width - crop_right;
- hw->frame_height = hw->frame_height - crop_bottom;
-
- dpb_print(DECODE_ID(hw), 0,
- "chroma_format_idc = %d frame_mbs_only_flag %d, crop_bottom %d, frame_height %d,\n",
- chroma_format_idc, frame_mbs_only_flag, crop_bottom, hw->frame_height);
- dpb_print(DECODE_ID(hw), 0,
- "mb_height %d,crop_right %d, frame_width %d, mb_width %d\n",
- mb_height, crop_right,
- hw->frame_width, mb_width);
-
- if (hw->frame_height == 1088 && (crop_right != 0 || crop_bottom != 0))
- hw->frame_height = 1080;
-#endif
- reg_val = param4;
- level_idc = reg_val & 0xff;
- p_H264_Dpb->mSPS.level_idc = level_idc;
- max_reference_size = (reg_val >> 8) & 0xff;
- hw->dpb.reorder_output = max_reference_size;
- hw->dpb.dec_dpb_size =
- get_dec_dpb_size(hw , mb_width, mb_height, level_idc);
- if (!hw->mmu_enable) {
- mb_width = (mb_width+3) & 0xfffffffc;
- mb_height = (mb_height+3) & 0xfffffffc;
- }
- mb_total = mb_width * mb_height;
- hw->mb_width = mb_width;
- hw->mb_height = mb_height;
- hw->mb_total = mb_total;
- if (hw->mmu_enable)
- hevc_mcr_sao_global_hw_init(hw,
- (hw->mb_width << 4), (hw->mb_height << 4));
-
- dpb_print(DECODE_ID(hw), 0,
- "mb height/widht/total: %x/%x/%x level_idc %x max_ref_num %x\n",
- mb_height, mb_width, mb_total,
- level_idc, max_reference_size);
-
- p_H264_Dpb->colocated_buf_size = mb_total * 96;
-
- dpb_print(DECODE_ID(hw), 0,
- "restriction_flag=%d, max_dec_frame_buffering=%d, dec_dpb_size=%d num_reorder_frames %d used_reorder_dpb_size_margin %d\n",
- hw->bitstream_restriction_flag,
- hw->max_dec_frame_buffering,
- hw->dpb.dec_dpb_size,
- hw->num_reorder_frames,
- used_reorder_dpb_size_margin);
-
- if (p_H264_Dpb->bitstream_restriction_flag &&
- p_H264_Dpb->num_reorder_frames <= p_H264_Dpb->max_dec_frame_buffering &&
- p_H264_Dpb->num_reorder_frames >= 0) {
- hw->dpb.reorder_output = hw->num_reorder_frames + 1;
- }
-
- active_buffer_spec_num =
- hw->dpb.dec_dpb_size
- + used_reorder_dpb_size_margin;
- hw->max_reference_size =
- max_reference_size + reference_buf_margin;
-
- if (active_buffer_spec_num > MAX_VF_BUF_NUM) {
- active_buffer_spec_num = MAX_VF_BUF_NUM;
- hw->dpb.dec_dpb_size = active_buffer_spec_num
- - used_reorder_dpb_size_margin;
- dpb_print(DECODE_ID(hw), 0,
- "active_buffer_spec_num is larger than MAX %d, set dec_dpb_size to %d\n",
- MAX_VF_BUF_NUM, hw->dpb.dec_dpb_size);
- }
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vdec_pic_info pic;
-
- vdec_v4l_get_pic_info(ctx, &pic);
-
- active_buffer_spec_num = pic.dpb_frames +
- pic.dpb_margin;
- }
-
- hw->dpb.mDPB.size = active_buffer_spec_num;
- if (hw->max_reference_size > MAX_VF_BUF_NUM)
- hw->max_reference_size = MAX_VF_BUF_NUM;
- hw->dpb.max_reference_size = hw->max_reference_size;
-
- if (hw->no_poc_reorder_flag)
- hw->dpb.dec_dpb_size = 1;
- dpb_print(DECODE_ID(hw), 0,
- "%s active_buf_spec_num %d dec_dpb_size %d collocate_buf_num %d\r\n",
- __func__, active_buffer_spec_num,
- hw->dpb.dec_dpb_size,
- hw->max_reference_size);
-
- if (hw->kpi_first_i_comming == 0) {
- hw->kpi_first_i_comming = 1;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "[vdec_kpi][%s] First I frame comming.\n", __func__);
- }
-
- buf_size = (hw->mb_total << 8) + (hw->mb_total << 7);
-
- mutex_lock(&vmh264_mutex);
- if (!hw->mmu_enable) {
- if (!buffer_reset_flag)
- config_buf_specs(vdec);
- i = get_buf_spec_by_canvas_pos(hw, 0);
-
- if (hw->is_used_v4l) {
- if (i != -1) {
- pr_info("v4l: delay alloc the buffer.\n");
- }
- } else {
- if ((i != -1) && alloc_one_buf_spec(hw, i) >= 0)
- config_decode_canvas(hw, i);
- else
- ret = -1;
- }
- } else {
- if (hw->double_write_mode) {
- config_buf_specs_ex(vdec);
- } else {
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0, j = 0;
- j < active_buffer_spec_num
- && i < BUFSPEC_POOL_SIZE;
- i++) {
- if (hw->buffer_spec[i].used != -1)
- continue;
- hw->buffer_spec[i].used = 0;
- hw->buffer_spec[i].
- alloc_header_addr = 0;
- hw->buffer_spec[i].canvas_pos = j;
- j++;
- }
- spin_unlock_irqrestore(&hw->bufspec_lock,
- flags);
- }
- hevc_mcr_config_canv2axitbl(hw, 0);
- }
- mutex_unlock(&vmh264_mutex);
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, __func__);
-
-#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF
- buf_size = PAGE_ALIGN(
- p_H264_Dpb->colocated_buf_size *
- active_buffer_spec_num);
-#else
- buf_size = PAGE_ALIGN(
- p_H264_Dpb->colocated_buf_size *
- hw->max_reference_size);
-#endif
-
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_REF_IDX,
- buf_size, DRIVER_NAME,
- &hw->collocate_cma_alloc_addr) < 0)
- return -1;
- if (!vdec_secure(vdec)) {
- /* clear for some mosaic problem after reset bufmgr */
- colocate_vaddr = codec_mm_vmap(hw->collocate_cma_alloc_addr, buf_size);
- if (colocate_vaddr != NULL) {
- memset(colocate_vaddr, 0, buf_size);
- codec_mm_dma_flush(colocate_vaddr, buf_size, DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(colocate_vaddr);
- }
- }
-
- hw->dpb.colocated_mv_addr_start =
- hw->collocate_cma_alloc_addr;
-#ifdef ONE_COLOCATE_BUF_PER_DECODE_BUF
- hw->dpb.colocated_mv_addr_end =
- hw->dpb.colocated_mv_addr_start +
- (p_H264_Dpb->colocated_buf_size *
- active_buffer_spec_num);
-#else
- hw->dpb.colocated_mv_addr_end =
- hw->dpb.colocated_mv_addr_start +
- (p_H264_Dpb->colocated_buf_size *
- hw->max_reference_size);
-#endif
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "callocate cma, %lx, %x\n",
- hw->collocate_cma_alloc_addr,
- hw->dpb.colocated_mv_addr_start);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "colocated_mv_addr_start %x colocated_mv_addr_end %x\n",
- hw->dpb.colocated_mv_addr_start,
- hw->dpb.colocated_mv_addr_end);
- if (!hw->mmu_enable) {
- mutex_lock(&vmh264_mutex);
- if (ret >= 0 && hw->decode_pic_count == 0) {
- int buf_cnt;
- /* h264_reconfig: alloc later*/
- buf_cnt = hw->dpb.mDPB.size;
-
- for (j = 1; j < buf_cnt; j++) {
- i = get_buf_spec_by_canvas_pos(hw, j);
-
- if (hw->is_used_v4l) {
- pr_info("v4l: delay alloc the buffer.\n");
- break;
- } else if (alloc_one_buf_spec(hw, i) < 0)
- break;
-
- config_decode_canvas(hw, i);
- }
- }
- mutex_unlock(&vmh264_mutex);
- } else {
- vh264_config_canvs_for_mmu(hw);
- }
-
- hw->config_bufmgr_done = 1;
-
- /*end of config_bufmgr_done */
- }
-
- return ret;
-}
-
-static void vui_config(struct vdec_h264_hw_s *hw)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int aspect_ratio_info_present_flag, aspect_ratio_idc;
- /*time*/
- hw->num_units_in_tick = p_H264_Dpb->num_units_in_tick;
- hw->time_scale = p_H264_Dpb->time_scale;
- hw->timing_info_present_flag = p_H264_Dpb->vui_status & 0x2;
-
- hw->bitstream_restriction_flag =
- p_H264_Dpb->bitstream_restriction_flag;
- hw->num_reorder_frames =
- p_H264_Dpb->num_reorder_frames;
- hw->max_dec_frame_buffering =
- p_H264_Dpb->max_dec_frame_buffering;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "vui_config: pdb %d, %d, %d\n",
- p_H264_Dpb->bitstream_restriction_flag,
- p_H264_Dpb->num_reorder_frames,
- p_H264_Dpb->max_dec_frame_buffering);
-
- hw->fixed_frame_rate_flag = 0;
- if (hw->timing_info_present_flag) {
- hw->fixed_frame_rate_flag =
- p_H264_Dpb->fixed_frame_rate_flag;
-
- if (hw->is_used_v4l && (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] == I_Slice) &&
- (hw->num_units_in_tick != 0)) {
- if (hw->num_units_in_tick % 1001 == 0) {
- int multiple = hw->num_units_in_tick / 1001;
-
- if (hw->time_scale / multiple == 120000) {
- hw->frame_dur = RATE_11990_FPS;
- if (hw->fixed_frame_rate_flag == 1)
- hw->frame_dur = RATE_5994_FPS;
- } else if (hw->time_scale / multiple == 60000) {
- hw->frame_dur = RATE_5994_FPS;
- if (hw->fixed_frame_rate_flag == 1)
- hw->frame_dur = RATE_2997_FPS;
- } else if ((hw->time_scale / multiple == 48000) &&
- (hw->fixed_frame_rate_flag == 1)) {
- hw->frame_dur = RATE_2397_FPS;
- } else if (hw->time_scale / multiple == 30000) {
- hw->frame_dur = RATE_2997_FPS;
- } else if (hw->time_scale / multiple == 24000) {
- hw->frame_dur = RATE_2397_FPS;
- }
- } else {
- u32 frame_rate = hw->time_scale / hw->num_units_in_tick;
-
- if (hw->fixed_frame_rate_flag == 1) {
- frame_rate = frame_rate / 2;
- }
- hw->frame_dur = 96000 / frame_rate;
- }
- }
-
- if (((hw->num_units_in_tick * 120) >= hw->time_scale &&
- ((!hw->sync_outside) ||
- (!hw->frame_dur)))
- && hw->num_units_in_tick && hw->time_scale) {
- if (hw->use_idr_framerate ||
- hw->fixed_frame_rate_flag ||
- !hw->frame_dur ||
- !hw->duration_from_pts_done
- /*|| vh264_running*/) {
- u32 frame_dur_es =
- div_u64(96000ULL * 2 * hw->num_units_in_tick,
- hw->time_scale);
- if (hw->frame_dur != frame_dur_es) {
- hw->h264_first_valid_pts_ready = false;
- hw->h264pts1 = 0;
- hw->h264pts2 = 0;
- hw->h264_pts_count = 0;
- hw->duration_from_pts_done = 0;
- fixed_frame_rate_mode =
- FIX_FRAME_RATE_OFF;
- hw->pts_duration = 0;
- hw->frame_dur = frame_dur_es;
- if (!hw->fixed_frame_rate_flag && (p_H264_Dpb->mSPS.profile_idc != BASELINE)) {
- if (frame_dur_es == 7680)
- hw->frame_dur = frame_dur_es /2;
- }
- vdec_schedule_work(&hw->notify_work);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DEC_DETAIL,
- "frame_dur %d from timing_info\n",
- hw->frame_dur);
- }
-
- /*hack to avoid use ES frame duration when
- *it's half of the rate from system info
- * sometimes the encoder is given a wrong
- * frame rate but the system side information
- * is more reliable
- *if ((frame_dur * 2) != frame_dur_es) {
- * frame_dur = frame_dur_es;
- *}
- */
- }
- }
- } else {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "H.264: timing_info not present\n");
- }
-
- /*aspect ratio*/
- aspect_ratio_info_present_flag =
- p_H264_Dpb->vui_status & 0x1;
- aspect_ratio_idc = p_H264_Dpb->aspect_ratio_idc;
-
- if (aspect_ratio_info_present_flag) {
- if (aspect_ratio_idc == EXTEND_SAR) {
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio =
- p_H264_Dpb->aspect_ratio_sar_height;
- hw->width_aspect_ratio =
- p_H264_Dpb->aspect_ratio_sar_width;
- } else {
- /* pr_info("v264dec: aspect_ratio_idc = %d\n",
- aspect_ratio_idc); */
-
- switch (aspect_ratio_idc) {
- case 1:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 1;
- break;
- case 2:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 12;
- break;
- case 3:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 10;
- break;
- case 4:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 16;
- break;
- case 5:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 33;
- hw->width_aspect_ratio = 40;
- break;
- case 6:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 24;
- break;
- case 7:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 20;
- break;
- case 8:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 32;
- break;
- case 9:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 33;
- hw->width_aspect_ratio = 80;
- break;
- case 10:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 18;
- break;
- case 11:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 11;
- hw->width_aspect_ratio = 15;
- break;
- case 12:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 33;
- hw->width_aspect_ratio = 64;
- break;
- case 13:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 99;
- hw->width_aspect_ratio = 160;
- break;
- case 14:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 3;
- hw->width_aspect_ratio = 4;
- break;
- case 15:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 2;
- hw->width_aspect_ratio = 3;
- break;
- case 16:
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 2;
- break;
- default:
- if (hw->vh264_ratio >> 16) {
- hw->h264_ar = (hw->frame_height *
- (hw->vh264_ratio & 0xffff) *
- 0x100 +
- ((hw->vh264_ratio >> 16) *
- hw->frame_width / 2)) /
- ((hw->vh264_ratio >> 16) *
- hw->frame_width);
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 1;
- } else {
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 1;
- }
- break;
- }
- }
- } else {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "v264dec: aspect_ratio not available from source\n");
- if (hw->vh264_ratio >> 16) {
- /* high 16 bit is width, low 16 bit is height */
- hw->h264_ar =
- ((hw->vh264_ratio & 0xffff) *
- hw->frame_height * 0x100 +
- (hw->vh264_ratio >> 16) *
- hw->frame_width / 2) /
- ((hw->vh264_ratio >> 16) *
- hw->frame_width);
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 1;
- } else {
- hw->h264_ar = 0x3ff;
- hw->height_aspect_ratio = 1;
- hw->width_aspect_ratio = 1;
- }
- }
-
- if (hw->pts_unstable && (hw->fixed_frame_rate_flag == 0)) {
- if (((hw->frame_dur == RATE_2397_FPS)
- && (dec_control
- & DEC_CONTROL_FLAG_FORCE_RATE_2397_FPS_FIX_FRAME_RATE))
- || ((RATE_2997_FPS ==
- hw->frame_dur) &&
- (dec_control &
- DEC_CONTROL_FLAG_FORCE_RATE_2997_FPS_FIX_FRAME_RATE))) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "force fix frame rate\n");
- hw->fixed_frame_rate_flag = 0x40;
- }
- }
-
- /*video_signal_from_vui: to do .. */
-}
-
-static void bufmgr_recover(struct vdec_h264_hw_s *hw)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 2);
- if (hw->error_proc_policy & 0x20) {
- if (!hw->is_used_v4l)
- hw->reset_bufmgr_flag = 1;
- }
-}
-
-void bufmgr_force_recover(struct h264_dpb_stru *p_H264_Dpb)
-{
- struct vdec_h264_hw_s *hw =
- container_of(p_H264_Dpb, struct vdec_h264_hw_s, dpb);
-
- dpb_print(DECODE_ID(hw), 0, "call %s\n", __func__);
-
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 2);
- hw->reset_bufmgr_flag = 1;
-}
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static int get_vf_ref_only_buf_count(struct vdec_h264_hw_s *hw)
-{
- int i;
- int count = 0;
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (is_buf_spec_in_disp_q(hw, i) &&
- hw->buffer_spec[i].vf_ref > 0)
- count++;
- }
- return count;
-}
-
-static int get_used_buf_count(struct vdec_h264_hw_s *hw)
-{
- int i;
- int count = 0;
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (is_buf_spec_in_use(hw, i))
- count++;
- }
- return count;
-}
-#endif
-
-
-static bool is_buffer_available(struct vdec_s *vdec)
-{
- bool buffer_available = 1;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- int i, frame_outside_count = 0, inner_size = 0;
- if ((kfifo_len(&hw->newframe_q) <= 0) ||
- ((hw->config_bufmgr_done) && (!have_free_buf_spec(vdec))) ||
- ((p_H264_Dpb->mDPB.init_done) &&
- (p_H264_Dpb->mDPB.used_size >= (p_H264_Dpb->mDPB.size - 1)) &&
- (is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB) == 0))) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s, empty, newq(%d), free_spec(%d), initdon(%d), used_size(%d/%d), unused_fr_dpb(%d)\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- have_free_buf_spec(vdec),
- p_H264_Dpb->mDPB.init_done,
- p_H264_Dpb->mDPB.used_size, p_H264_Dpb->mDPB.size,
- is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB)
- );
- buffer_available = 0;
- if (dpb_is_debug(DECODE_ID(hw),
- DEBUG_DISABLE_RUNREADY_RMBUF))
- return buffer_available;
-
- if ((hw->error_proc_policy & 0x4) &&
- (hw->error_proc_policy & 0x8)) {
- if ((kfifo_len(&hw->display_q) <= 0) &&
- (p_H264_Dpb->mDPB.used_size >=
- (p_H264_Dpb->mDPB.size - 1)) &&
- (p_Dpb->ref_frames_in_buffer >
- (imax(
- 1, p_Dpb->num_ref_frames)
- - p_Dpb->ltref_frames_in_buffer +
- force_sliding_margin))){
- bufmgr_recover(hw);
- } else {
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 1);
- }
- } else if ((hw->error_proc_policy & 0x4) &&
- (kfifo_len(&hw->display_q) <= 0) &&
- ((p_H264_Dpb->mDPB.used_size >=
- (p_H264_Dpb->mDPB.size - 1)) ||
- (!have_free_buf_spec(vdec))) &&
- (hw->discard_dv_data)) {
- unsigned long flags;
- spin_lock_irqsave(&hw->bufspec_lock, flags);
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- if (p_Dpb->fs[i]->pre_output)
- frame_outside_count++;
- else if (p_Dpb->fs[i]->is_output && !is_used_for_reference(p_Dpb->fs[i])) {
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
- return 0;
- }
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- inner_size = p_Dpb->size - frame_outside_count;
-
- if (inner_size >= p_H264_Dpb->dec_dpb_size) {
- if (p_H264_Dpb->mDPB.used_size >=
- p_H264_Dpb->mDPB.size) {
- bufmgr_recover(hw);
- } else if (p_H264_Dpb->mDPB.used_size >=
- (p_H264_Dpb->mDPB.size - 1)) {
- if (inner_size > p_H264_Dpb->dec_dpb_size) {
- bufmgr_recover(hw);
- }
- }
- }
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
- } else if ((hw->error_proc_policy & 0x8) &&
- (p_Dpb->ref_frames_in_buffer >
- (imax(
- 1, p_Dpb->num_ref_frames)
- - p_Dpb->ltref_frames_in_buffer +
- force_sliding_margin)))
- bufmgr_recover(hw);
- else
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 1);
-
- if (hw->reset_bufmgr_flag == 1)
- buffer_available = 1;
- }
-
- if (hw->is_used_v4l)
- buffer_available = have_free_buf_spec(vdec);
-
- return buffer_available;
-}
-
-#define AUX_TAG_SEI 0x2
-
-#define SEI_BUFFERING_PERIOD 0
-#define SEI_PicTiming 1
-#define SEI_USER_DATA 4
-#define SEI_RECOVERY_POINT 6
-
-/*
- *************************************************************************
- * Function:Reads bits from the bitstream buffer
- * Input:
- byte buffer[]
- containing sei message data bits
- int totbitoffset
- bit offset from start of partition
- int bytecount
- total bytes in bitstream
- int numbits
- number of bits to read
- * Output:
- int *info
- * Return:
- -1: failed
- > 0: the count of bit read
- * Attention:
- *************************************************************************
- */
-
-static int get_bits(unsigned char buffer[],
- int totbitoffset,
- int *info,
- int bytecount,
- int numbits)
-{
- register int inf;
- long byteoffset;
- int bitoffset;
-
- int bitcounter = numbits;
-
- byteoffset = totbitoffset / 8;
- bitoffset = 7 - (totbitoffset % 8);
-
- inf = 0;
- while (numbits) {
- inf <<= 1;
- inf |= (buffer[byteoffset] & (0x01 << bitoffset)) >> bitoffset;
- numbits--;
- bitoffset--;
- if (bitoffset < 0) {
- byteoffset++;
- bitoffset += 8;
- if (byteoffset > bytecount)
- return -1;
- }
- }
-
- *info = inf;
-
-
- return bitcounter;
-}
-
-static int parse_one_sei_record(struct vdec_h264_hw_s *hw,
- u8 *sei_data_buf,
- u8 *sei_data_buf_end)
-{
- int payload_type;
- int payload_size;
- u8 *p_sei;
- int temp = 0;
- int bit_offset;
- int read_size;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
- p_sei = sei_data_buf;
- read_size = 0;
- payload_type = 0;
- do {
- if (p_sei >= sei_data_buf_end)
- return read_size;
-
- payload_type += *p_sei;
- read_size++;
- } while (*p_sei++ == 255);
-
-
- payload_size = 0;
- do {
- if (p_sei >= sei_data_buf_end)
- return read_size;
-
- payload_size += *p_sei;
- read_size++;
- } while (*p_sei++ == 255);
-
-
- if (p_sei + payload_size > sei_data_buf_end) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s: payload_type = %d, payload_size = %d is over\n",
- __func__, payload_type, payload_size);
- return read_size;
- }
- bit_offset = 0;
-
- if (payload_size <= 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "%s warning: this is a null sei message for payload_type = %d\n",
- __func__, payload_type);
- return read_size;
- }
- p_H264_Dpb->vui_status = p_H264_Dpb->dpb_param.l.data[VUI_STATUS];
- switch (payload_type) {
- case SEI_BUFFERING_PERIOD:
- break;
- case SEI_PicTiming:
- if (p_H264_Dpb->vui_status & 0xc) {
- int cpb_removal_delay;
- int dpb_output_delay;
- u32 delay_len;
-
- delay_len = p_H264_Dpb->dpb_param.l.data[DELAY_LENGTH];
- cpb_removal_delay
- = (delay_len & 0x1F) + 1;
- dpb_output_delay
- = ((delay_len >> 5) & 0x1F) + 1;
-
- get_bits(p_sei, bit_offset,
- &temp, payload_size,
- dpb_output_delay+cpb_removal_delay);
- bit_offset += dpb_output_delay+cpb_removal_delay;
- }
- if (p_H264_Dpb->vui_status & 0x10) {
- get_bits(p_sei, bit_offset, &temp, payload_size, 4);
- bit_offset += 4;
- p_H264_Dpb->dpb_param.l.data[PICTURE_STRUCT] = temp;
- }
- break;
- case SEI_USER_DATA:
- if (enable_itu_t35) {
- int i;
- int j;
- int data_len;
- u8 *user_data_buf;
-
- user_data_buf
- = hw->sei_itu_data_buf + hw->sei_itu_data_len;
- /* user data length should be align with 8 bytes,
- if not, then padding with zero*/
- for (i = 0; i < payload_size; i += 8) {
- if (hw->sei_itu_data_len + i >= SEI_ITU_DATA_SIZE)
- break; // Avoid out-of-bound writing
- for (j = 0; j < 8; j++) {
- int index;
-
- index = i+7-j;
- if (index >= payload_size)
- user_data_buf[i+j] = 0;
- else
- user_data_buf[i+j]
- = p_sei[i+7-j];
- }
- }
-
- data_len = payload_size;
- if (payload_size % 8)
- data_len = ((payload_size + 8) >> 3) << 3;
-
- hw->sei_itu_data_len += data_len;
- if (hw->sei_itu_data_len >= SEI_ITU_DATA_SIZE)
- hw->sei_itu_data_len = SEI_ITU_DATA_SIZE;
- /*
- dpb_print(DECODE_ID(hw), 0,
- "%s: user data, and len = %d:\n",
- __func__, hw->sei_itu_data_len);
- */
- }
- break;
- case SEI_RECOVERY_POINT:
- p_H264_Dpb->dpb_param.l.data[RECOVERY_POINT] = 1;
- break;
- }
-
- return read_size + payload_size;
-}
-
-static void parse_sei_data(struct vdec_h264_hw_s *hw,
- u8 *sei_data_buf,
- int len)
-{
- char *p_sei;
- char *p_sei_end;
- int parsed_size;
- int read_size;
-
-
- p_sei = sei_data_buf;
- p_sei_end = p_sei + len;
- parsed_size = 0;
- while (parsed_size < len) {
- read_size = parse_one_sei_record(hw, p_sei, p_sei_end);
- p_sei += read_size;
- parsed_size += read_size;
- if (*p_sei == 0x80) {
- p_sei++;
- parsed_size++;
- }
- }
-}
-
-static void check_decoded_pic_error(struct vdec_h264_hw_s *hw)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- struct StorablePicture *p = p_H264_Dpb->mVideo.dec_picture;
- unsigned mby_mbx = READ_VREG(MBY_MBX);
- unsigned mb_total = (hw->seq_info2 >> 8) & 0xffff;
- unsigned mb_width = hw->seq_info2 & 0xff;
- unsigned decode_mb_count;
- if (!mb_width && mb_total) /*for 4k2k*/
- mb_width = 256;
- decode_mb_count = ((mby_mbx & 0xff) * mb_width +
- (((mby_mbx >> 8) & 0xff) + 1));
- if ((mby_mbx == 0) && (p_H264_Dpb->dec_dpb_status != H264_SLICE_HEAD_DONE)) {
- dpb_print(DECODE_ID(hw), 0,
- "mby_mbx is zero\n");
- return;
- }
- if (get_cur_slice_picture_struct(p_H264_Dpb) != FRAME)
- mb_total /= 2;
-
- if ((hw->error_proc_policy & 0x200) &&
- READ_VREG(ERROR_STATUS_REG) != 0) {
- p->data_flag |= ERROR_FLAG;
- }
-
- if (error_proc_policy & 0x100 && !(p->data_flag & ERROR_FLAG)) {
- if (decode_mb_count < mb_total) {
- p->data_flag |= ERROR_FLAG;
- if (((error_proc_policy & 0x20000) &&
- decode_mb_count >= mb_total * (100 - mb_count_threshold) / 100)) {
- p->data_flag &= ~ERROR_FLAG;
- }
- }
- }
-
- if ((hw->error_proc_policy & 0x100000) &&
- hw->last_dec_picture &&
- (hw->last_dec_picture->slice_type == I_SLICE) &&
- (hw->dpb.mSlice.slice_type == P_SLICE)) {
- if ((p->data_flag & ERROR_FLAG) &&
- (decode_mb_count >= mb_total)) {
- hw->ip_field_error_count++;
- if (hw->ip_field_error_count == 4) {
- unsigned int i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
- for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
- if (p_Dpb->fs_ref[i]->top_field)
- p_Dpb->fs_ref[i]->top_field->data_flag &= ~ERROR_FLAG;
- if (p_Dpb->fs_ref[i]->bottom_field)
- p_Dpb->fs_ref[i]->bottom_field->data_flag &= ~ERROR_FLAG;
- if (p_Dpb->fs_ref[i]->frame)
- p_Dpb->fs_ref[i]->frame->data_flag &= ~ERROR_FLAG;
- }
- hw->ip_field_error_count = 0;
- p->data_flag &= ~ERROR_FLAG;
- hw->data_flag &= ~ERROR_FLAG;
- dpb_print(DECODE_ID(hw), 0,
- "clear all ref frame error flag\n");
- }
- } else {
- if (hw->ip_field_error_count > 0)
- dpb_print(DECODE_ID(hw), 0,
- "clear error count %d\n", hw->ip_field_error_count);
- hw->ip_field_error_count = 0;
- }
- }
-
- if (p->data_flag & ERROR_FLAG) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERRORFLAG_DBG,
- "%s: decode error, seq_info2 0x%x, mby_mbx 0x%x, mb_total %d decoded mb_count %d ERROR_STATUS_REG 0x%x\n",
- __func__,
- hw->seq_info2,
- mby_mbx,
- mb_total,
- decode_mb_count,
- READ_VREG(ERROR_STATUS_REG)
- );
-
- }
-}
-
-static int vh264_pic_done_proc(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int ret;
- int i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
-
- if (input_frame_based(vdec) &&
- (!(hw->i_only & 0x2)) &&
- frmbase_cont_bitlevel != 0 &&
- READ_VREG(VIFF_BIT_CNT) >
- frmbase_cont_bitlevel) {
- /*handle the case: multi pictures in one packet*/
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s H264_PIC_DATA_DONE decode slice count %d, continue (bitcnt 0x%x)\n",
- __func__,
- hw->decode_pic_count,
- READ_VREG(VIFF_BIT_CNT));
- hw->frmbase_cont_flag = 1;
- } else
- hw->frmbase_cont_flag = 0;
-
- if (p_H264_Dpb->mVideo.dec_picture) {
- get_picture_qos_info(p_H264_Dpb->mVideo.dec_picture);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- DEL_EXIST(hw,
- p_H264_Dpb->mVideo.dec_picture) = 0;
- if (vdec->master) {
- struct vdec_h264_hw_s *hw_ba =
- (struct vdec_h264_hw_s *)
- vdec->master->private;
- if (hw_ba->last_dec_picture)
- DEL_EXIST(hw_ba,
- hw_ba->last_dec_picture)
- = 1;
- }
-#endif
- mutex_lock(&hw->chunks_mutex);
- if (hw->chunk) {
- p_H264_Dpb->mVideo.dec_picture->pts =
- hw->chunk->pts;
- p_H264_Dpb->mVideo.dec_picture->pts64 =
- hw->chunk->pts64;
- p_H264_Dpb->mVideo.dec_picture->timestamp =
- hw->chunk->timestamp;
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- hw->chunk->pts, 1);
-#endif
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- } else if (vdec->master) {
- /*dv enhance layer,
- do not checkout pts*/
- struct StorablePicture *pic =
- p_H264_Dpb->mVideo.dec_picture;
- pic->pts = 0;
- pic->pts64 = 0;
-#endif
- } else {
- struct StorablePicture *pic =
- p_H264_Dpb->mVideo.dec_picture;
- u32 offset = pic->offset_delimiter;
- pic->pic_size = (hw->start_bit_cnt - READ_VREG(VIFF_BIT_CNT)) >> 3;
- if (pts_pickout_offset_us64(PTS_TYPE_VIDEO,
- offset, &pic->pts, 0, &pic->pts64)) {
- pic->pts = 0;
- pic->pts64 = 0;
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- pic->pts, 0);
-#endif
- } else {
-#ifdef MH264_USERDATA_ENABLE
- vmh264_udc_fill_vpts(hw,
- p_H264_Dpb->mSlice.slice_type,
- pic->pts, 1);
-#endif
- }
-
- }
- mutex_unlock(&hw->chunks_mutex);
-
- check_decoded_pic_error(hw);
-#ifdef ERROR_HANDLE_TEST
- if ((hw->data_flag & ERROR_FLAG)
- && (hw->error_proc_policy & 0x80)) {
- release_cur_decoding_buf(hw);
- h264_clear_dpb(hw);
- hw->dec_flag = 0;
- hw->data_flag = 0;
- hw->skip_frame_count = 0;
- hw->has_i_frame = 0;
- hw->no_error_count = 0xfff;
- hw->no_error_i_count = 0xf;
- } else
-#endif
- if (hw->error_proc_policy & 0x200000) {
- if (!hw->loop_flag) {
- for (i = 0; i < p_Dpb->used_size; i++) {
- if ((p_H264_Dpb->mVideo.dec_picture->poc + loop_playback_poc_threshold < p_Dpb->fs[i]->poc) &&
- !p_Dpb->fs[i]->is_output &&
- !p_Dpb->fs[i]->pre_output) {
- hw->loop_flag = 1;
- hw->loop_last_poc = p_H264_Dpb->mVideo.dec_picture->poc;
- break;
- }
- }
- } else {
- if ((p_H264_Dpb->mVideo.dec_picture->poc >= hw->loop_last_poc - poc_threshold) &&
- (p_H264_Dpb->mVideo.dec_picture->poc <= hw->loop_last_poc + poc_threshold)) {
- if (hw->loop_flag >= 5) {
- for (i = 0; i < p_Dpb->used_size; i++) {
- if ((hw->loop_last_poc + loop_playback_poc_threshold < p_Dpb->fs[i]->poc) &&
- !p_Dpb->fs[i]->is_output &&
- !p_Dpb->fs[i]->pre_output) {
- p_Dpb->fs[i]->is_output = 1;
- }
- }
- hw->loop_flag = 0;
- } else
- hw->loop_flag++;
- } else
- hw->loop_flag = 0;
- }
- }
- p_H264_Dpb->wait_aux_data_flag = ((!hw->discard_dv_data) && (hw->frmbase_cont_flag));
- ret = store_picture_in_dpb(p_H264_Dpb,
- p_H264_Dpb->mVideo.dec_picture,
- hw->data_flag | hw->dec_flag |
- p_H264_Dpb->mVideo.dec_picture->data_flag);
-
-
-
- if (ret == -1) {
- release_cur_decoding_buf(hw);
- bufmgr_force_recover(p_H264_Dpb);
- } else if (ret == -2) {
- release_cur_decoding_buf(hw);
- } else {
- if (hw->data_flag & ERROR_FLAG) {
- hw->no_error_count = 0;
- hw->no_error_i_count = 0;
- } else {
- hw->no_error_count++;
- if (hw->data_flag & I_FLAG)
- hw->no_error_i_count++;
- }
- if (hw->mmu_enable)
- hevc_set_unused_4k_buff_idx(hw,
- p_H264_Dpb->mVideo.
- dec_picture->buf_spec_num);
- bufmgr_post(p_H264_Dpb);
- hw->last_dec_picture =
- p_H264_Dpb->mVideo.dec_picture;
- p_H264_Dpb->mVideo.dec_picture = NULL;
- /* dump_dpb(&p_H264_Dpb->mDPB); */
- hw->has_i_frame = 1;
- if (hw->mmu_enable)
- hevc_set_frame_done(hw);
- hw->decode_pic_count++;
- p_H264_Dpb->decode_pic_count = hw->decode_pic_count;
- if (hw->skip_frame_count > 0) {
- /*skip n frame after first I */
- hw->skip_frame_count--;
- if (hw->skip_frame_count == 0)
- hw->dec_flag &= (~NODISP_FLAG);
- } else if (hw->skip_frame_count < -1) {
- /*skip n frame after first I until second I */
- hw->skip_frame_count++;
- if (hw->skip_frame_count == -1)
- hw->dec_flag &= (~NODISP_FLAG);
- }
- }
- }
- return 0;
-}
-
-static irqreturn_t vh264_isr_thread_fn(struct vdec_s *vdec, int irq)
-{
- int i;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- unsigned int dec_dpb_status = p_H264_Dpb->dec_dpb_status;
- u32 debug_tag;
-
- if (dec_dpb_status == H264_SLICE_HEAD_DONE ||
- p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_dpb_status == H264_PIC_DATA_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
- else if (dec_dpb_status == H264_SEI_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_SEI_START);
- else if (dec_dpb_status == H264_AUX_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_AUX_START);
-
- if (dec_dpb_status == H264_CONFIG_REQUEST) {
-#if 1
- unsigned short *p = (unsigned short *)hw->lmem_addr;
- for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++) {
- p_H264_Dpb->dpb_param.l.data[i+ii] =
- p[i+3-ii];
- if (dpb_is_debug(DECODE_ID(hw),
- RRINT_FLAG_RPM)) {
- if (((i + ii) & 0xf) == 0)
- dpb_print(DECODE_ID(hw),
- 0, "%04x:",
- i);
- dpb_print_cont(DECODE_ID(hw),
- 0, "%04x ",
- p[i+3-ii]);
- if (((i + ii + 1) & 0xf) == 0)
- dpb_print_cont(
- DECODE_ID(hw),
- 0, "\r\n");
- }
- }
- }
-
- if (p_H264_Dpb->bitstream_restriction_flag !=
- ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1)) {
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "p_H264_Dpb->bitstream_restriction_flag 0x%x, new 0x%x\n",
- p_H264_Dpb->bitstream_restriction_flag, ((p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1));
- hw->csd_change_flag = 1;
- }
- p_H264_Dpb->bitstream_restriction_flag =
- (p_H264_Dpb->dpb_param.l.data[SPS_FLAGS2] >> 3) & 0x1;
- p_H264_Dpb->num_reorder_frames =
- p_H264_Dpb->dpb_param.l.data[NUM_REORDER_FRAMES];
- p_H264_Dpb->max_dec_frame_buffering =
- p_H264_Dpb->dpb_param.l.data[MAX_BUFFER_FRAME];
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DPB_DETAIL,
- "H264_CONFIG_REQUEST: pdb %d, %d, %d\n",
- p_H264_Dpb->bitstream_restriction_flag,
- p_H264_Dpb->num_reorder_frames,
- p_H264_Dpb->max_dec_frame_buffering);
- hw->bitstream_restriction_flag =
- p_H264_Dpb->bitstream_restriction_flag;
- hw->num_reorder_frames =
- p_H264_Dpb->num_reorder_frames;
- hw->max_dec_frame_buffering =
- p_H264_Dpb->max_dec_frame_buffering;
-
- /*crop*/
- p_H264_Dpb->chroma_format_idc = p_H264_Dpb->dpb_param.dpb.chroma_format_idc;
- p_H264_Dpb->frame_crop_left_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_left_offset;
- p_H264_Dpb->frame_crop_right_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_right_offset;
- p_H264_Dpb->frame_crop_top_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_top_offset;
- p_H264_Dpb->frame_crop_bottom_offset = p_H264_Dpb->dpb_param.dpb.frame_crop_bottom_offset;
-
- dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
- "%s chroma_format_idc %d crop offset: left %d right %d top %d bottom %d\n",
- __func__, p_H264_Dpb->chroma_format_idc,
- p_H264_Dpb->frame_crop_left_offset,
- p_H264_Dpb->frame_crop_right_offset,
- p_H264_Dpb->frame_crop_top_offset,
- p_H264_Dpb->frame_crop_bottom_offset);
-#endif
-
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_CONFIG_DONE);
- reset_process_time(hw);
- hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
- hw->reg_iqidct_control_init_flag = 1;
- hw->dec_result = DEC_RESULT_CONFIG_PARAM;
-#ifdef DETECT_WRONG_MULTI_SLICE
- /*restart check count and set 'unknown'*/
- dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_CONFIG_REQUEST => restart check\n",
- __func__,
- hw->multi_slice_pic_check_count,
- hw->picture_slice_count,
- hw->cur_picture_slice_count,
- hw->multi_slice_pic_flag);
-
- hw->multi_slice_pic_check_count = 0;
- hw->multi_slice_pic_flag = 0;
- hw->picture_slice_count = 0;
-#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- vdec_schedule_work(&hw->work);
- } else if (dec_dpb_status == H264_SLICE_HEAD_DONE) {
- u16 data_hight;
- u16 data_low;
- u32 video_signal;
-
- int slice_header_process_status = 0;
- int I_flag;
- int frame_num_gap = 0;
- union param dpb_param_bak;
- /*unsigned char is_idr;*/
- unsigned short *p = (unsigned short *)hw->lmem_addr;
- unsigned mb_width = hw->seq_info2 & 0xff;
- unsigned short first_mb_in_slice;
- unsigned int decode_mb_count, mby_mbx;
- struct StorablePicture *pic = p_H264_Dpb->mVideo.dec_picture;
- reset_process_time(hw);
- hw->frmbase_cont_flag = 0;
-
- if ((pic != NULL) && (pic->mb_aff_frame_flag == 1))
- first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3] * 2;
- else
- first_mb_in_slice = p[FIRST_MB_IN_SLICE + 3];
-
-#ifdef DETECT_WRONG_MULTI_SLICE
- hw->cur_picture_slice_count++;
-
- if ((hw->error_proc_policy & 0x10000) &&
- (hw->cur_picture_slice_count > 1) &&
- (first_mb_in_slice == 0) &&
- (hw->multi_slice_pic_flag == 0))
- hw->multi_slice_pic_check_count = 0;
-
- if ((hw->error_proc_policy & 0x10000) &&
- (hw->cur_picture_slice_count > 1) &&
- (hw->multi_slice_pic_flag == 1)) {
- dpb_print(DECODE_ID(hw), 0,
- "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), WRONG_MULTI_SLICE detected, insert picture\n",
- __func__,
- hw->multi_slice_pic_check_count,
- hw->picture_slice_count,
- hw->cur_picture_slice_count,
- hw->multi_slice_pic_flag);
-
- mby_mbx = READ_VREG(MBY_MBX);
- decode_mb_count = ((mby_mbx & 0xff) * mb_width +
- (((mby_mbx >> 8) & 0xff) + 1));
-
- if (first_mb_in_slice == decode_mb_count &&
- first_mb_in_slice != 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s first_mb_in_slice = %d \n",
- __func__, first_mb_in_slice);
-
- hw->multi_slice_pic_flag = 0;
- hw->multi_slice_pic_check_count = 0;
- } else if (hw->cur_picture_slice_count > hw->last_picture_slice_count) {
- vh264_pic_done_proc(vdec);
- //if (p_H264_Dpb->mDPB.used_size == p_H264_Dpb->mDPB.size) {
- if (!have_free_buf_spec(vdec)) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, "dpb full, wait buffer\n");
- p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num;
- hw->last_picture_slice_count = hw->cur_picture_slice_count;
- hw->no_decoder_buffer_flag = 1;
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
- else {
- if (p_H264_Dpb->mVideo.dec_picture) {
- if (p_H264_Dpb->mVideo.dec_picture->colocated_buf_index >= 0) {
- release_colocate_buf(p_H264_Dpb,
- p_H264_Dpb->mVideo.dec_picture->colocated_buf_index);
- p_H264_Dpb->mVideo.dec_picture->colocated_buf_index = -1;
- }
- }
- release_cur_decoding_buf(hw);
- }
- }
-#endif
-
- hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
- hw->reg_iqidct_control_init_flag = 1;
- hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
- hw->reg_rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT);
- hw->vld_dec_control = READ_VREG(VLD_DECODE_CONTROL);
- if (input_frame_based(vdec) &&
- frmbase_cont_bitlevel2 != 0 &&
- READ_VREG(VIFF_BIT_CNT) <
- frmbase_cont_bitlevel2 &&
- hw->get_data_count >= 0x70000000) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s H264_SLICE_HEAD_DONE with small bitcnt %d, goto empty_proc\n",
- __func__,
- READ_VREG(VIFF_BIT_CNT));
-
- goto empty_proc;
- }
-
-#if 0
- if (p_H264_Dpb->mVideo.dec_picture == NULL) {
- if (!is_buffer_available(vdec)) {
- hw->buffer_empty_flag = 1;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_UCODE_EVT,
- "%s, buffer_empty, newframe_q(%d), have_free_buf_spec(%d), init_done(%d), used_size(%d/%d), is_there_unused_frame_from_dpb(%d)\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- have_free_buf_spec(vdec),
- p_H264_Dpb->mDPB.init_done,
- p_H264_Dpb->mDPB.used_size,
- p_H264_Dpb->mDPB.size,
- is_there_unused_frame_from_dpb(
- &p_H264_Dpb->mDPB));
- return IRQ_HANDLED;
- }
- }
-
- hw->buffer_empty_flag = 0;
-#endif
-#ifdef SEND_PARAM_WITH_REG
- for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
- unsigned int data32;
-
- do {
- data32 = READ_VREG(RPM_CMD_REG);
- /* printk("%x\n", data32); */
- } while ((data32&0x10000) == 0);
- p_H264_Dpb->dpb_param.l.data[i] = data32 & 0xffff;
- WRITE_VREG(RPM_CMD_REG, 0);
- /* printk("%x:%x\n", i,data32); */
- }
-#else
- dpb_param_bak = p_H264_Dpb->dpb_param;
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_START);
- for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
- int ii;
-
- for (ii = 0; ii < 4; ii++) {
- p_H264_Dpb->dpb_param.l.data[i+ii] =
- p[i+3-ii];
- if (dpb_is_debug(DECODE_ID(hw),
- RRINT_FLAG_RPM)) {
- if (((i + ii) & 0xf) == 0)
- dpb_print(DECODE_ID(hw),
- 0, "%04x:",
- i);
- dpb_print_cont(DECODE_ID(hw),
- 0, "%04x ",
- p[i+3-ii]);
- if (((i + ii + 1) & 0xf) == 0)
- dpb_print_cont(
- DECODE_ID(hw),
- 0, "\r\n");
- }
- }
- }
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_RPM_END);
-#endif
-#ifdef DETECT_WRONG_MULTI_SLICE
-
- if (p_H264_Dpb->mVideo.dec_picture &&
- hw->multi_slice_pic_flag == 2 &&
- (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] != dpb_param_bak.l.data[SLICE_TYPE] ||
- dpb_param_bak.l.data[FIRST_MB_IN_SLICE] > p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE])) {
- dpb_print(DECODE_ID(hw), 0,
- "decode next pic, save before, SLICE_TYPE BAK %d, SLICE_TYPE %d, FIRST_MB_IN_SLICE BAK %d, FIRST_MB_IN_SLICE %d\n",
- dpb_param_bak.l.data[SLICE_TYPE], p_H264_Dpb->dpb_param.l.data[SLICE_TYPE],
- dpb_param_bak.l.data[FIRST_MB_IN_SLICE], p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]);
- vh264_pic_done_proc(vdec);
- }
-#endif
- data_low = p_H264_Dpb->dpb_param.l.data[VIDEO_SIGNAL_LOW];
- data_hight = p_H264_Dpb->dpb_param.l.data[VIDEO_SIGNAL_HIGHT];
-
- video_signal = (data_hight << 16) | data_low;
- hw->video_signal_from_vui =
- ((video_signal & 0xffff) << 8) |
- ((video_signal & 0xff0000) >> 16) |
- ((video_signal & 0x3f000000));
-
-
- /*dpb_print(DECODE_ID(hw),
- 0,
- "video_signal_from_vui:0x%x, "
- "data_low:0x%x, data_hight:0x%x\n",
- hw->video_signal_from_vui,
- data_low,
- data_hight);*/
-
- parse_sei_data(hw, hw->sei_data_buf, hw->sei_data_len);
-
- if (hw->config_bufmgr_done == 0) {
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_UCODE_EVT,
- "config_bufmgr not done, discard frame\n");
- return IRQ_HANDLED;
- } else if ((hw->first_i_policy & 0x3) != 0) {
- unsigned char is_i_slice =
- (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE]
- == I_Slice)
- ? 1 : 0;
- unsigned char is_idr =
- ((p_H264_Dpb->dpb_param.dpb.NAL_info_mmco & 0x1f)
- == 5);
- if ((hw->first_i_policy & 0x3) == 0x3)
- is_i_slice = is_idr;
- if (!is_i_slice) {
- if (hw->has_i_frame == 0) {
- amvdec_stop();
- vdec->mc_loaded = 0;
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_UCODE_EVT,
- "has_i_frame is 0, discard none I(DR) frame silce_type %d is_idr %d\n", p_H264_Dpb->dpb_param.l.data[SLICE_TYPE], is_idr);
- return IRQ_HANDLED;
- }
- } else {
- if (hw->skip_frame_count < 0 || is_idr) {
- /* second I */
- hw->dec_flag &= (~NODISP_FLAG);
- hw->skip_frame_count = 0;
- }
- if (hw->has_i_frame == 0 &&
- (!is_idr)) {
- int skip_count =
- (hw->first_i_policy >> 8) & 0xff;
- /* first I (not IDR) */
- if ((hw->first_i_policy & 0x3) == 2)
- hw->skip_frame_count =
- -1 - skip_count;
- else
- hw->skip_frame_count =
- skip_count;
- if (hw->skip_frame_count != 0)
- hw->dec_flag |= NODISP_FLAG;
- }
- }
- }
- dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "current dpb index %d, poc %d, top/bot poc (%d,%d)\n",
- p_H264_Dpb->dpb_param.dpb.current_dpb_index,
- val(p_H264_Dpb->dpb_param.dpb.frame_pic_order_cnt),
- val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt),
- val(p_H264_Dpb->dpb_param.dpb.top_field_pic_order_cnt));
- I_flag = (p_H264_Dpb->dpb_param.l.data[SLICE_TYPE] == I_Slice)
- ? I_FLAG : 0;
-
- if ((hw->i_only & 0x2) && (I_flag & I_FLAG))
- flush_dpb(p_H264_Dpb);
-
- if ((hw->i_only & 0x2) && (!(I_flag & I_FLAG)) &&
- (p_H264_Dpb->mSlice.structure == FRAME)) {
- hw->data_flag = NULL_FLAG;
- goto pic_done_proc;
- }
-
- slice_header_process_status =
- h264_slice_header_process(p_H264_Dpb, &frame_num_gap);
- if (hw->mmu_enable)
- hevc_sao_set_slice_type(hw,
- slice_header_process_status,
- hw->dpb.mSlice.idr_flag);
- vui_config(hw);
-
- if (slice_header_process_status == -1) {
- amvdec_stop();
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
-
- if (p_H264_Dpb->mVideo.dec_picture) {
- int cfg_ret = 0;
- bool field_pic_flag = false;
- unsigned mby_mbx = READ_VREG(MBY_MBX);
- struct StorablePicture *p =
- p_H264_Dpb->mVideo.dec_picture;
-
- if (slice_header_process_status == 1) {
- if (!p_H264_Dpb->mSPS.frame_mbs_only_flag) {
- field_pic_flag =
- (p_H264_Dpb->mSlice.structure == TOP_FIELD ||
- p_H264_Dpb->mSlice.structure == BOTTOM_FIELD) ?
- true : false;
- }
-
- vdec_set_profile_level(vdec, p_H264_Dpb->mSPS.profile_idc,
- p_H264_Dpb->mSPS.level_idc);
-
- if (!field_pic_flag && (((p_H264_Dpb->mSPS.profile_idc == BASELINE) &&
- (p_H264_Dpb->dec_dpb_size < 2)) ||
- (((unsigned long)(hw->vh264_amstream_dec_info
- .param)) & 0x8) || hw->low_latency_mode & 0x8)) {
- p_H264_Dpb->fast_output_enable =
- H264_OUTPUT_MODE_FAST;
- }
- else
- p_H264_Dpb->fast_output_enable
- = fast_output_enable;
- if (hw->enable_fence)
- p_H264_Dpb->fast_output_enable = H264_OUTPUT_MODE_FAST;
-
- hw->data_flag = I_flag;
- if ((p_H264_Dpb->
- dpb_param.dpb.NAL_info_mmco & 0x1f)
- == 5)
- hw->data_flag |= IDR_FLAG;
- if ((p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]) && !mby_mbx) {
- p->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_VDEC_STATUS,
- "one slice error in muulti-slice first_mb 0x%x mby_mbx 0x%x slice_type %d\n",
- p_H264_Dpb->dpb_param.l.
- data[FIRST_MB_IN_SLICE],
- READ_VREG(MBY_MBX),
- p->slice_type);
- }
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_VDEC_STATUS,
- "==================> frame count %d to skip %d\n",
- hw->decode_pic_count+1,
- hw->skip_frame_count);
- } else if (hw->error_proc_policy & 0x100){
- unsigned decode_mb_count =
- ((mby_mbx & 0xff) * hw->mb_width +
- (((mby_mbx >> 8) & 0xff) + 1));
- if (decode_mb_count <
- ((p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE]) *
- (1 + p->mb_aff_frame_flag)) && decode_mb_count) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_VDEC_STATUS,
- "Error detect! first_mb 0x%x mby_mbx 0x%x decode_mb 0x%x\n",
- p_H264_Dpb->dpb_param.l.
- data[FIRST_MB_IN_SLICE],
- READ_VREG(MBY_MBX),
- decode_mb_count);
- p->data_flag |= ERROR_FLAG;
- }/* else if (!p_H264_Dpb->dpb_param.l.data[FIRST_MB_IN_SLICE] && decode_mb_count) {
- p->data_flag |= ERROR_FLAG;
- goto pic_done_proc;
- }*/
- }
-
- if (!I_flag && frame_num_gap && !p_H264_Dpb->long_term_reference_flag) {
- if (!(hw->error_proc_policy & 0x800000)) {
- hw->data_flag |= ERROR_FLAG;
- p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), 0, "frame number gap error\n");
- }
- }
-
- if (hw->error_proc_policy & 0x400) {
- int ret = dpb_check_ref_list_error(p_H264_Dpb);
- if (ret != 0) {
- hw->reflist_error_count ++;
- dpb_print(DECODE_ID(hw), 0,
- "reference list error %d frame count %d to skip %d reflist_error_count %d\n",
- ret,
- hw->decode_pic_count+1,
- hw->skip_frame_count,
- hw->reflist_error_count);
-
- p_H264_Dpb->mVideo.dec_picture->data_flag = NODISP_FLAG;
- if (((hw->error_proc_policy & 0x80)
- && ((hw->dec_flag &
- NODISP_FLAG) == 0)) ||(hw->reflist_error_count > 50)) {
- hw->reset_bufmgr_flag = 1;
- hw->reflist_error_count =0;
- amvdec_stop();
- vdec->mc_loaded = 0;
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- } else
- hw->reflist_error_count = 0;
- }
- if ((hw->error_proc_policy & 0x800) && (!(hw->i_only & 0x2))
- && p_H264_Dpb->dpb_error_flag != 0) {
- dpb_print(DECODE_ID(hw), 0,
- "dpb error %d\n",
- p_H264_Dpb->dpb_error_flag);
- hw->data_flag |= ERROR_FLAG;
- p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
- if ((hw->error_proc_policy & 0x80) &&
- ((hw->dec_flag & NODISP_FLAG) == 0)) {
- hw->reset_bufmgr_flag = 1;
- amvdec_stop();
- vdec->mc_loaded = 0;
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_START);
- cfg_ret = config_decode_buf(hw,
- p_H264_Dpb->mVideo.dec_picture);
- ATRACE_COUNTER(hw->trace.decode_header_time_name, TRACE_HEADER_REGISTER_END);
- if (cfg_ret < 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "config_decode_buf fail (%d)\n",
- cfg_ret);
- if (hw->error_proc_policy & 0x2) {
- release_cur_decoding_buf(hw);
- /*hw->data_flag |= ERROR_FLAG;*/
- hw->reset_bufmgr_flag = 1;
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- } else
- hw->data_flag |= ERROR_FLAG;
- p_H264_Dpb->mVideo.dec_picture->data_flag |= ERROR_FLAG;
- }
- }
-
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
-
- if (slice_header_process_status == 1)
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_NEWPIC);
- else
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_SLICE);
- hw->last_mby_mbx = 0;
- hw->last_vld_level = 0;
- start_process_time(hw);
- } else if (dec_dpb_status == H264_PIC_DATA_DONE
- ||((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) {
-#ifdef DETECT_WRONG_MULTI_SLICE
- dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "%s MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d), H264_PIC_DATA_DONE\n",
- __func__,
- hw->multi_slice_pic_check_count,
- hw->picture_slice_count,
- hw->cur_picture_slice_count,
- hw->multi_slice_pic_flag);
-
- if (hw->multi_slice_pic_check_count < check_slice_num) {
- hw->multi_slice_pic_check_count++;
- if (hw->cur_picture_slice_count !=
- hw->picture_slice_count) {
- /*restart check count and set 'unknown'*/
- hw->multi_slice_pic_check_count = 0;
- hw->multi_slice_pic_flag = 0;
- }
- hw->picture_slice_count =
- hw->cur_picture_slice_count;
- } else if (hw->multi_slice_pic_check_count >= check_slice_num) {
- if (hw->picture_slice_count > 1)
- hw->multi_slice_pic_flag = 2;
- else
- hw->multi_slice_pic_flag = 1;
- }
-#endif
-
-pic_done_proc:
- reset_process_time(hw);
- if ((dec_dpb_status == H264_SEARCH_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_TIMEOUT) ||
- ((dec_dpb_status == H264_DATA_REQUEST) && input_frame_based(vdec))) {
- hw->data_flag |= ERROR_FLAG;
- if (hw->dpb.mVideo.dec_picture)
- hw->dpb.mVideo.dec_picture->data_flag |= ERROR_FLAG;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s, mark err_frame\n", __func__);
- }
- vh264_pic_done_proc(vdec);
-
- if (hw->frmbase_cont_flag) {
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
- if (!have_free_buf_spec(vdec)) {
- hw->dec_result = DEC_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- /*do not DEC_RESULT_GET_DATA*/
- hw->get_data_count = 0x7fffffff;
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
- decode_frame_count[DECODE_ID(hw)]++;
- if (p_H264_Dpb->mSlice.slice_type == I_SLICE) {
- hw->gvs.i_decoded_frames++;
- } else if (p_H264_Dpb->mSlice.slice_type == P_SLICE) {
- hw->gvs.p_decoded_frames++;
- } else if (p_H264_Dpb->mSlice.slice_type == B_SLICE) {
- hw->gvs.b_decoded_frames++;
- }
- start_process_time(hw);
- return IRQ_HANDLED;
- }
- amvdec_stop();
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s %s decode slice count %d\n",
- __func__,
- (dec_dpb_status == H264_PIC_DATA_DONE) ?
- "H264_PIC_DATA_DONE" :
- (dec_dpb_status == H264_FIND_NEXT_PIC_NAL) ?
- "H264_FIND_NEXT_PIC_NAL" : "H264_FIND_NEXT_DVEL_NAL",
- hw->decode_pic_count);
- if (hw->kpi_first_i_decoded == 0) {
- hw->kpi_first_i_decoded = 1;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "[vdec_kpi][%s] First I frame decoded.\n", __func__);
- }
- /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD); */
- hw->dec_result = DEC_RESULT_DONE;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->slave &&
- dec_dpb_status == H264_FIND_NEXT_DVEL_NAL) {
- struct vdec_h264_hw_s *hw_el =
- (struct vdec_h264_hw_s *)(vdec->slave->private);
- hw_el->got_valid_nal = 0;
- hw->switch_dvlayer_flag = 1;
- } else if (vdec->master &&
- dec_dpb_status == H264_FIND_NEXT_PIC_NAL) {
- struct vdec_h264_hw_s *hw_bl =
- (struct vdec_h264_hw_s *)(vdec->master->private);
- hw_bl->got_valid_nal = 0;
- hw->switch_dvlayer_flag = 1;
- } else {
- hw->switch_dvlayer_flag = 0;
- hw->got_valid_nal = 1;
- }
-#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
-
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- } else if (
- (dec_dpb_status == H264_FIND_NEXT_PIC_NAL) ||
- (dec_dpb_status == H264_FIND_NEXT_DVEL_NAL)) {
- goto pic_done_proc;
-#endif
- } else if (dec_dpb_status == H264_AUX_DATA_READY) {
- reset_process_time(hw);
- if (READ_VREG(H264_AUX_DATA_SIZE) != 0) {
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_SEI_DETAIL))
- dump_aux_buf(hw);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec_frame_based(vdec)) {
- if (hw->last_dec_picture)
- set_aux_data(hw,
- hw->last_dec_picture, 0, 0, NULL);
- } else if (vdec->dolby_meta_with_el || vdec->slave) {
- if (hw->last_dec_picture)
- set_aux_data(hw, hw->last_dec_picture,
- 0, 0, NULL);
- } else {
- if (vdec->master) {
- struct vdec_h264_hw_s *hw_bl =
- (struct vdec_h264_hw_s *)
- (vdec->master->private);
- if (hw_bl->last_dec_picture != NULL) {
- set_aux_data(hw_bl,
- hw_bl->last_dec_picture,
- 0, 1, hw);
- }
- set_aux_data(hw,
- hw->last_dec_picture,
- 0, 2, NULL);
- }
- }
-#else
- if (hw->last_dec_picture)
- set_aux_data(hw,
- hw->last_dec_picture, 0, 0, NULL);
-#endif
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hw->switch_dvlayer_flag = 0;
- hw->got_valid_nal = 1;
-#endif
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s H264_AUX_DATA_READY\n", __func__);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- } else if (/*(dec_dpb_status == H264_DATA_REQUEST) ||*/
- (dec_dpb_status == H264_SEARCH_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_BUFEMPTY) ||
- (dec_dpb_status == H264_DECODE_TIMEOUT)) {
-empty_proc:
- reset_process_time(hw);
- if ((hw->error_proc_policy & 0x40000) &&
- ((dec_dpb_status == H264_DECODE_TIMEOUT) ||
- (!hw->frmbase_cont_flag && (dec_dpb_status == H264_SEARCH_BUFEMPTY || dec_dpb_status == H264_DECODE_BUFEMPTY) && input_frame_based(vdec))))
- goto pic_done_proc;
- if (!hw->frmbase_cont_flag)
- release_cur_decoding_buf(hw);
-
- if (input_frame_based(vdec) ||
- (READ_VREG(VLD_MEM_VIFIFO_LEVEL) > 0x200)) {
- if (h264_debug_flag &
- DISABLE_ERROR_HANDLE) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR,
- "%s decoding error, level 0x%x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- goto send_again;
- }
- amvdec_stop();
- vdec->mc_loaded = 0;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s %s\n", __func__,
- (dec_dpb_status == H264_SEARCH_BUFEMPTY) ?
- "H264_SEARCH_BUFEMPTY" :
- (dec_dpb_status == H264_DECODE_BUFEMPTY) ?
- "H264_DECODE_BUFEMPTY" :
- (dec_dpb_status == H264_DECODE_TIMEOUT) ?
- "H264_DECODE_TIMEOUT" :
- "OTHER");
- hw->dec_result = DEC_RESULT_DONE;
-
- if (dec_dpb_status == H264_SEARCH_BUFEMPTY)
- hw->search_dataempty_num++;
- else if (dec_dpb_status == H264_DECODE_TIMEOUT) {
- hw->decode_timeout_num++;
- if (hw->error_proc_policy & 0x4000) {
- hw->data_flag |= ERROR_FLAG;
- if ((p_H264_Dpb->last_dpb_status == H264_DECODE_TIMEOUT) ||
- (p_H264_Dpb->last_dpb_status == H264_PIC_DATA_DONE) ||
- ((p_H264_Dpb->last_dpb_status == H264_SLICE_HEAD_DONE) &&
- (p_H264_Dpb->mSlice.slice_type != B_SLICE))) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR, "%s last dpb status 0x%x need bugmgr reset \n",
- p_H264_Dpb->last_dpb_status, __func__);
- hw->reset_bufmgr_flag = 1;
- }
- }
- } else if (dec_dpb_status == H264_DECODE_BUFEMPTY)
- hw->decode_dataempty_num++;
- if (!hw->frmbase_cont_flag)
- hw->data_flag |= ERROR_FLAG;
-
- vdec_schedule_work(&hw->work);
- } else {
- /* WRITE_VREG(DPB_STATUS_REG, H264_ACTION_INIT); */
-#ifdef DETECT_WRONG_MULTI_SLICE
- if (hw->error_proc_policy & 0x10000) {
- p_H264_Dpb->mVideo.pre_frame_num = hw->first_pre_frame_num;
- }
- hw->last_picture_slice_count = hw->cur_picture_slice_count;
-#endif
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_AGAIN\n", __func__);
-send_again:
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- }
- } else if (dec_dpb_status == H264_DATA_REQUEST) {
- reset_process_time(hw);
- if (input_frame_based(vdec)) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_VDEC_STATUS,
- "%s H264_DATA_REQUEST (%d)\n",
- __func__, hw->get_data_count);
- hw->dec_result = DEC_RESULT_GET_DATA;
- hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
- hw->reg_iqidct_control_init_flag = 1;
- hw->get_data_start_time = jiffies;
- hw->get_data_count++;
- if (hw->get_data_count >= frame_max_data_packet)
- goto empty_proc;
- vdec_schedule_work(&hw->work);
- } else
- goto empty_proc;
- } else if (dec_dpb_status == H264_DECODE_OVER_SIZE) {
- dpb_print(DECODE_ID(hw), 0,
- "vmh264 decode oversize !!\n");
- release_cur_decoding_buf(hw);
- hw->data_flag |= ERROR_FLAG;
- hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- } else if (dec_dpb_status == H264_SEI_DATA_READY) {
- int aux_data_len;
- aux_data_len =
- (READ_VREG(H264_AUX_DATA_SIZE) >> 16) << 4;
-
- if (aux_data_len > SEI_DATA_SIZE) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "sei data size more than 4K: %d, discarded it\n",
- hw->sei_itu_data_len);
- hw->sei_itu_data_len = 0;
- }
-
- if (aux_data_len != 0) {
- u8 *trans_data_buf;
- u8 *sei_data_buf;
- u8 swap_byte;
-
-#if 0
- dump_aux_buf(hw);
-#endif
- trans_data_buf = (u8 *)hw->aux_addr;
-
- if (trans_data_buf[7] == AUX_TAG_SEI) {
- int left_len;
-
- sei_data_buf = (u8 *)hw->sei_data_buf
- + hw->sei_data_len;
- left_len = SEI_DATA_SIZE - hw->sei_data_len;
- if (aux_data_len/2 <= left_len) {
- for (i = 0; i < aux_data_len/2; i++)
- sei_data_buf[i]
- = trans_data_buf[i*2];
-
- aux_data_len = aux_data_len / 2;
- for (i = 0; i < aux_data_len; i = i+4) {
- swap_byte = sei_data_buf[i];
- sei_data_buf[i]
- = sei_data_buf[i+3];
- sei_data_buf[i+3] = swap_byte;
-
- swap_byte = sei_data_buf[i+1];
- sei_data_buf[i+1]
- = sei_data_buf[i+2];
- sei_data_buf[i+2] = swap_byte;
- }
-
- for (i = aux_data_len-1; i >= 0; i--)
- if (sei_data_buf[i] != 0)
- break;
-
- hw->sei_data_len += i+1;
- } else
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR,
- "sei data size %d and more than left space: %d, discarded it\n",
- hw->sei_itu_data_len,
- left_len);
- }
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- WRITE_VREG(DPB_STATUS_REG, H264_SEI_DATA_DONE);
-
- return IRQ_HANDLED;
- }
-
-
- /* ucode debug */
- debug_tag = READ_VREG(DEBUG_REG1);
- if (debug_tag & 0x10000) {
- unsigned short *p = (unsigned short *)hw->lmem_addr;
-
- dpb_print(DECODE_ID(hw), 0,
- "LMEM<tag %x>:\n", debug_tag);
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw), 0,
- "%03x: ", i);
- for (ii = 0; ii < 4; ii++)
- dpb_print_cont(DECODE_ID(hw), 0,
- "%04x ", p[i+3-ii]);
- if (((i+ii) & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw), 0,
- "\n");
- }
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx ==
- hw->decode_pic_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_VREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- else if (debug_tag & 0x20000)
- hw->ucode_pause_pos = 0xffffffff;
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_VREG(DEBUG_REG1, 0);
- } else if (debug_tag != 0) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "dbg%x: %x\n", debug_tag,
- READ_VREG(DEBUG_REG2));
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx ==
- hw->decode_pic_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_VREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_VREG(DEBUG_REG1, 0);
- }
- /**/
- return IRQ_HANDLED;
-}
-
-static irqreturn_t vh264_isr(struct vdec_s *vdec, int irq)
-{
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)(vdec->private);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
-
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- if (!hw)
- return IRQ_HANDLED;
-
- if (hw->eos)
- return IRQ_HANDLED;
-
- p_H264_Dpb->vdec = vdec;
- p_H264_Dpb->dec_dpb_status = READ_VREG(DPB_STATUS_REG);
-
- if (p_H264_Dpb->dec_dpb_status == H264_SLICE_HEAD_DONE ||
- p_H264_Dpb->dec_dpb_status == H264_CONFIG_REQUEST) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (p_H264_Dpb->dec_dpb_status == H264_PIC_DATA_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
- else if (p_H264_Dpb->dec_dpb_status == H264_SEI_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_SEI_DONE);
- else if (p_H264_Dpb->dec_dpb_status == H264_AUX_DATA_READY)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_AUX_DONE);
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_UCODE_EVT,
- "%s DPB_STATUS_REG: 0x%x, run(%d) last_state (%x) ERROR_STATUS_REG 0x%x, sb (0x%x 0x%x 0x%x) bitcnt 0x%x mby_mbx 0x%x\n",
- __func__,
- p_H264_Dpb->dec_dpb_status,
- run_count[DECODE_ID(hw)],
- hw->dec_result,
- READ_VREG(ERROR_STATUS_REG),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VIFF_BIT_CNT),
- READ_VREG(MBY_MBX));
-
- ATRACE_COUNTER("V_ST_DEC-decode_state", p_H264_Dpb->dec_dpb_status);
-
- if (p_H264_Dpb->dec_dpb_status == H264_WRRSP_REQUEST) {
- if (hw->mmu_enable)
- hevc_sao_wait_done(hw);
- WRITE_VREG(DPB_STATUS_REG, H264_WRRSP_DONE);
- return IRQ_HANDLED;
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END);
- return IRQ_WAKE_THREAD;
-
-}
-
-static void timeout_process(struct vdec_h264_hw_s *hw)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- /*
- * In this very timeout point,the vh264_work arrives,
- * or in some cases the system become slow, then come
- * this second timeout. In both cases we return.
- */
- if (work_pending(&hw->work) ||
- work_busy(&hw->work) ||
- work_busy(&hw->timeout_work) ||
- work_pending(&hw->timeout_work)) {
- pr_err("%s h264[%d] work pending, do nothing.\n",__func__, vdec->id);
- return;
- }
-
- hw->timeout_num++;
- amvdec_stop();
- vdec->mc_loaded = 0;
- if (hw->mmu_enable) {
- hevc_set_frame_done(hw);
- hevc_sao_wait_done(hw);
- }
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR, "%s decoder timeout, DPB_STATUS_REG 0x%x\n", __func__, READ_VREG(DPB_STATUS_REG));
- release_cur_decoding_buf(hw);
- hw->dec_result = DEC_RESULT_TIMEOUT;
- hw->data_flag |= ERROR_FLAG;
-
- if (work_pending(&hw->work))
- return;
- vdec_schedule_work(&hw->timeout_work);
-}
-
-static void dump_bufspec(struct vdec_h264_hw_s *hw,
- const char *caller)
-{
- int i;
- dpb_print(DECODE_ID(hw), 0,
- "%s in %s:\n", __func__, caller);
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (hw->buffer_spec[i].used == -1)
- continue;
- dpb_print(DECODE_ID(hw), 0,
- "bufspec (%d): used %d adr 0x%x(%lx) canvas(%d) vf_ref(%d) ",
- i, hw->buffer_spec[i].used,
- hw->buffer_spec[i].buf_adr,
- hw->buffer_spec[i].cma_alloc_addr,
- hw->buffer_spec[i].canvas_pos,
- hw->buffer_spec[i].vf_ref
- );
-#ifdef CONFIG_AM_VDEC_DV
- dpb_print_cont(DECODE_ID(hw), 0,
- "dv_el_exist %d",
- hw->buffer_spec[i].dv_enhance_exist
- );
-#endif
- dpb_print_cont(DECODE_ID(hw), 0, "\n");
- }
-
-}
-
-static void vmh264_dump_state(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)(vdec->private);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- dpb_print(DECODE_ID(hw), 0,
- "====== %s\n", __func__);
- dpb_print(DECODE_ID(hw), 0,
- "width/height (%d/%d), num_reorder_frames %d dec_dpb_size %d dpb size(bufspec count) %d max_reference_size(collocate count) %d i_only %d signal_type 0x%x send_err %d\n",
- hw->frame_width,
- hw->frame_height,
- hw->num_reorder_frames,
- hw->dpb.dec_dpb_size,
- hw->dpb.mDPB.size,
- hw->max_reference_size,
- hw->i_only,
- hw->video_signal_type,
- hw->send_error_frame_flag
- );
-
- dpb_print(DECODE_ID(hw), 0,
- "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d bufmgr_reset_cnt %d error_frame_count = %d, drop_frame_count = %d\n",
- input_frame_based(vdec),
- hw->eos,
- hw->stat,
- hw->dec_result,
- decode_frame_count[DECODE_ID(hw)],
- display_frame_count[DECODE_ID(hw)],
- run_count[DECODE_ID(hw)],
- not_run_ready[DECODE_ID(hw)],
- input_empty[DECODE_ID(hw)],
- hw->reset_bufmgr_count,
- hw->gvs.error_frame_count,
- hw->gvs.drop_frame_count
- );
-
-#ifdef DETECT_WRONG_MULTI_SLICE
- dpb_print(DECODE_ID(hw), 0,
- "MULTI_SLICE_DETECT (check_count %d slice_count %d cur_slice_count %d flag %d)\n",
- hw->multi_slice_pic_check_count,
- hw->picture_slice_count,
- hw->cur_picture_slice_count,
- hw->multi_slice_pic_flag);
-#endif
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- dpb_print(DECODE_ID(hw), 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- dpb_print(DECODE_ID(hw), 0,
- "%s, newq(%d/%d), dispq(%d/%d) vf prepare/get/put (%d/%d/%d), free_spec(%d), initdon(%d), used_size(%d/%d), unused_fr_dpb(%d) fast_output_enable %x \n",
- __func__,
- kfifo_len(&hw->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->display_q),
- VF_POOL_SIZE,
- hw->vf_pre_count,
- hw->vf_get_count,
- hw->vf_put_count,
- have_free_buf_spec(vdec),
- p_H264_Dpb->mDPB.init_done,
- p_H264_Dpb->mDPB.used_size, p_H264_Dpb->mDPB.size,
- is_there_unused_frame_from_dpb(&p_H264_Dpb->mDPB),
- p_H264_Dpb->fast_output_enable
- );
-
- dump_dpb(&p_H264_Dpb->mDPB, 1);
- dump_pic(p_H264_Dpb);
- dump_bufspec(hw, __func__);
-
- dpb_print(DECODE_ID(hw), 0,
- "DPB_STATUS_REG=0x%x\n",
- READ_VREG(DPB_STATUS_REG));
- dpb_print(DECODE_ID(hw), 0,
- "MPC_E=0x%x\n",
- READ_VREG(MPC_E));
- dpb_print(DECODE_ID(hw), 0,
- "H264_DECODE_MODE=0x%x\n",
- READ_VREG(H264_DECODE_MODE));
- dpb_print(DECODE_ID(hw), 0,
- "MBY_MBX=0x%x\n",
- READ_VREG(MBY_MBX));
- dpb_print(DECODE_ID(hw), 0,
- "H264_DECODE_SIZE=0x%x\n",
- READ_VREG(H264_DECODE_SIZE));
- dpb_print(DECODE_ID(hw), 0,
- "VIFF_BIT_CNT=0x%x\n",
- READ_VREG(VIFF_BIT_CNT));
- dpb_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- dpb_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_WP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- dpb_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_RP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- dpb_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- dpb_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (input_frame_based(vdec) &&
- dpb_is_debug(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA)
- ) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, hw->chunk->size);
- else
- data = ((u8 *)hw->chunk->block->start_virt)
- + hw->chunk->offset;
-
- dpb_print(DECODE_ID(hw), 0,
- "frame data size 0x%x\n",
- hw->chunk->size);
- for (jj = 0; jj < hw->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- dpb_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-}
-
-
-static void check_timer_func(struct timer_list *timer)
-{
- struct vdec_h264_hw_s *hw = container_of(timer,
- struct vdec_h264_hw_s, check_timer);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int error_skip_frame_count = error_skip_count & 0xfff;
- unsigned int timeout_val = decode_timeout_val;
- if (timeout_val != 0 &&
- hw->no_error_count < error_skip_frame_count)
- timeout_val = errordata_timeout_val;
- if ((h264_debug_cmd & 0x100) != 0 &&
- DECODE_ID(hw) == (h264_debug_cmd & 0xff)) {
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- pr_info("vdec %d is forced to be disconnected\n",
- h264_debug_cmd & 0xff);
- h264_debug_cmd = 0;
- return;
- }
- if ((h264_debug_cmd & 0x200) != 0 &&
- DECODE_ID(hw) == (h264_debug_cmd & 0xff)) {
- pr_debug("vdec %d is forced to reset bufmgr\n",
- h264_debug_cmd & 0xff);
- hw->reset_bufmgr_flag = 1;
- h264_debug_cmd = 0;
- return;
- }
-
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED &&
- !hw->is_used_v4l) {
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- pr_debug("vdec requested to be disconnected\n");
- return;
- }
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (((h264_debug_flag & DISABLE_ERROR_HANDLE) == 0) &&
- (timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > timeout_val)
- ) {
- u32 dpb_status = READ_VREG(DPB_STATUS_REG);
- u32 mby_mbx = READ_VREG(MBY_MBX);
- if ((dpb_status == H264_ACTION_DECODE_NEWPIC) ||
- (dpb_status == H264_ACTION_DECODE_SLICE) ||
- (dpb_status == H264_SEI_DATA_DONE) ||
- (dpb_status == H264_STATE_SEARCH_HEAD) ||
- (dpb_status == H264_SLICE_HEAD_DONE) ||
- (dpb_status == H264_SEI_DATA_READY)) {
- if (h264_debug_flag & DEBUG_TIMEOUT_DEC_STAT)
- pr_debug("%s dpb_status = 0x%x last_mby_mbx = %u mby_mbx = %u\n",
- __func__, dpb_status, hw->last_mby_mbx, mby_mbx);
-
- if (hw->last_mby_mbx == mby_mbx) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- {
- reset_process_time(hw);
- timeout_process(hw);
- }
- } else
- start_process_time(hw);
- } else if (is_in_parsing_state(dpb_status)) {
- if (hw->last_vld_level ==
- READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- {
- reset_process_time(hw);
- timeout_process(hw);
- }
- }
- }
- hw->last_vld_level =
- READ_VREG(VLD_MEM_VIFIFO_LEVEL);
- hw->last_mby_mbx = mby_mbx;
- }
-
- if ((hw->ucode_pause_pos != 0) &&
- (hw->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != hw->ucode_pause_pos) {
- hw->ucode_pause_pos = 0;
- WRITE_VREG(DEBUG_REG1, 0);
- }
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- u32 ar, ar_tmp;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
-
- if (!hw)
- return -1;
-
- vstatus->frame_width = hw->frame_width;
- vstatus->frame_height = hw->frame_height;
- if (hw->error_frame_width &&
- hw->error_frame_height) {
- vstatus->frame_width = hw->error_frame_width;
- vstatus->frame_height = hw->error_frame_height;
- }
- if (hw->frame_dur != 0) {
- vstatus->frame_dur = hw->frame_dur;
- vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- }
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = hw->gvs.error_frame_count;
- vstatus->status = hw->stat;
- if (hw->h264_ar == 0x3ff)
- ar_tmp = (0x100 *
- hw->frame_height * hw->height_aspect_ratio) /
- (hw->frame_width * hw->width_aspect_ratio);
- else
- ar_tmp = hw->h264_ar;
- ar = min_t(u32,
- ar_tmp,
- DISP_RATIO_ASPECT_RATIO_MAX);
- vstatus->ratio_control =
- ar << DISP_RATIO_ASPECT_RATIO_BIT;
-
- vstatus->error_frame_count = hw->gvs.error_frame_count;
- vstatus->drop_frame_count = hw->gvs.drop_frame_count;
- vstatus->frame_count = decode_frame_count[DECODE_ID(hw)];
- vstatus->i_decoded_frames = hw->gvs.i_decoded_frames;
- vstatus->i_lost_frames = hw->gvs.i_lost_frames;
- vstatus->i_concealed_frames = hw->gvs.i_concealed_frames;
- vstatus->p_decoded_frames = hw->gvs.p_decoded_frames;
- vstatus->p_lost_frames = hw->gvs.p_lost_frames;
- vstatus->p_concealed_frames = hw->gvs.p_concealed_frames;
- vstatus->b_decoded_frames = hw->gvs.b_decoded_frames;
- vstatus->b_lost_frames = hw->gvs.b_lost_frames;
- vstatus->b_concealed_frames = hw->gvs.b_concealed_frames;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s-%02d", DRIVER_NAME, hw->id);
-
- return 0;
-}
-
-static int vh264_hw_ctx_restore(struct vdec_h264_hw_s *hw)
-{
- int i, j;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- hw->frmbase_cont_flag = 0;
-
- /* if (hw->init_flag == 0) { */
- if (h264_debug_flag & 0x40000000) {
- /* if (1) */
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, reset register\n", __func__);
-
- while (READ_VREG(DCAC_DMA_CTRL) & 0x8000)
- ;
- while (READ_VREG(LMEM_DMA_CTRL) & 0x8000)
- ; /* reg address is 0x350 */
-
-#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
- WRITE_VREG(DOS_SW_RESET0, (1<<7) | (1<<6) | (1<<4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
- READ_VREG(DOS_SW_RESET0);
- READ_VREG(DOS_SW_RESET0);
-
- WRITE_VREG(DOS_SW_RESET0, (1<<7) | (1<<6) | (1<<4));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(DOS_SW_RESET0, (1<<9) | (1<<8));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- READ_VREG(DOS_SW_RESET0);
- READ_VREG(DOS_SW_RESET0);
- READ_VREG(DOS_SW_RESET0);
-
-#else
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
- READ_RESET_REG(RESET0_REGISTER);
- WRITE_RESET_REG(RESET0_REGISTER,
- RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
-
- WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
-#endif
- WRITE_VREG(POWER_CTL_VLD,
- READ_VREG(POWER_CTL_VLD) | (0 << 10) |
- (1 << 9) | (1 << 6));
- } else {
- /* WRITE_VREG(POWER_CTL_VLD,
- * READ_VREG(POWER_CTL_VLD) | (0 << 10) | (1 << 9) );
- */
- WRITE_VREG(POWER_CTL_VLD,
- READ_VREG(POWER_CTL_VLD) |
- (0 << 10) | (1 << 9) | (1 << 6));
- }
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17);
-#endif
-
- /* cbcr_merge_swap_en */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- } else {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- }
-
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24);
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 0xbf << 24);
-
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31);
- if (hw->mmu_enable) {
- SET_VREG_MASK(MDEC_PIC_DC_MUX_CTRL, 1<<31);
- /* sw reset to extif hardware */
- SET_VREG_MASK(MDEC_EXTIF_CFG1, 1<<30);
- CLEAR_VREG_MASK(MDEC_EXTIF_CFG1, 1<<30);
- } else {
- CLEAR_VREG_MASK(MDEC_PIC_DC_MUX_CTRL, 1 << 31);
- WRITE_VREG(MDEC_EXTIF_CFG1, 0);
- }
-
-
-#if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
- /* pr_info("vh264 meson8 prot init\n"); */
- WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
-#endif
-
-#ifdef VDEC_DW
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T7) {
- if (IS_VDEC_DW(hw)) {
- u32 data = ((1 << 30) |(1 << 0) |(1 << 8));
-
- if (IS_VDEC_DW(hw) == 2)
- data |= (1 << 9);
- WRITE_VREG(MDEC_DOUBLEW_CFG0, data); /* Double Write Enable*/
- }
- }
-#endif
- if (hw->dpb.mDPB.size > 0) {
- WRITE_VREG(AV_SCRATCH_7, (hw->max_reference_size << 24) |
- (hw->dpb.mDPB.size << 16) |
- (hw->dpb.mDPB.size << 8));
-
- for (j = 0; j < hw->dpb.mDPB.size; j++) {
- i = get_buf_spec_by_canvas_pos(hw, j);
- if (i < 0)
- break;
-
- if (!hw->mmu_enable &&
- hw->buffer_spec[i].cma_alloc_addr)
- config_decode_canvas(hw, i);
- if (hw->mmu_enable && hw->double_write_mode)
- config_decode_canvas_ex(hw, i);
- }
- } else {
- WRITE_VREG(AV_SCRATCH_0, 0);
- WRITE_VREG(AV_SCRATCH_9, 0);
- }
-
- if (hw->init_flag == 0)
- WRITE_VREG(DPB_STATUS_REG, 0);
- else
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_DECODE_START);
-
- WRITE_VREG(FRAME_COUNTER_REG, hw->decode_pic_count);
- WRITE_VREG(AV_SCRATCH_8, hw->buf_offset);
- if (!tee_enabled())
- WRITE_VREG(AV_SCRATCH_G, hw->mc_dma_handle);
-
- /* hw->error_recovery_mode = (error_recovery_mode != 0) ?
- * error_recovery_mode : error_recovery_mode_in;
- */
- /* WRITE_VREG(AV_SCRATCH_F,
- * (READ_VREG(AV_SCRATCH_F) & 0xffffffc3) );
- */
- WRITE_VREG(AV_SCRATCH_F, (hw->save_reg_f & 0xffffffc3) |
- ((error_recovery_mode_in & 0x1) << 4));
- /*if (hw->ucode_type == UCODE_IP_ONLY_PARAM)
- SET_VREG_MASK(AV_SCRATCH_F, 1 << 6);
- else*/
- CLEAR_VREG_MASK(AV_SCRATCH_F, 1 << 6);
-
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr);
-#if 1 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
- WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
-#endif
-
- WRITE_VREG(DEBUG_REG1, 0);
- WRITE_VREG(DEBUG_REG2, 0);
-
- /*Because CSD data is not found at playback start,
- the IQIDCT_CONTROL register is not saved,
- the initialized value 0x200 of IQIDCT_CONTROL is set*/
- if (hw->init_flag && (hw->reg_iqidct_control_init_flag == 0))
- WRITE_VREG(IQIDCT_CONTROL, 0x200);
-
- if (hw->reg_iqidct_control)
- WRITE_VREG(IQIDCT_CONTROL, hw->reg_iqidct_control);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "IQIDCT_CONTROL = 0x%x\n", READ_VREG(IQIDCT_CONTROL));
-
- if (hw->reg_vcop_ctrl_reg)
- WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg);
- if (hw->vld_dec_control)
- WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_dec_control);
- return 0;
-}
-
-static int vmh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)vdec->private;
- if (i_only_flag & 0x100)
- return 0;
- if (trickmode == TRICKMODE_I)
- hw->i_only = 0x3;
- else if (trickmode == TRICKMODE_NONE)
- hw->i_only = 0x0;
- return 0;
-}
-
-static unsigned char amvdec_enable_flag;
-static void vh264_local_init(struct vdec_h264_hw_s *hw, bool is_reset)
-{
- int i;
- hw->init_flag = 0;
- hw->first_sc_checked= 0;
- hw->eos = 0;
- hw->valve_count = 0;
- hw->config_bufmgr_done = 0;
- hw->start_process_time = 0;
- hw->has_i_frame = 0;
- hw->no_error_count = 0xfff;
- hw->no_error_i_count = 0xf;
-
- hw->dec_flag = 0;
- hw->data_flag = 0;
- hw->skip_frame_count = 0;
- hw->reg_iqidct_control = 0;
- hw->reg_iqidct_control_init_flag = 0;
- hw->reg_vcop_ctrl_reg = 0;
- hw->reg_rv_ai_mb_count = 0;
- hw->vld_dec_control = 0;
- hw->decode_timeout_count = 0;
- hw->no_mem_count = 0;
- hw->vh264_ratio = hw->vh264_amstream_dec_info.ratio;
- /* vh264_ratio = 0x100; */
-
- hw->vh264_rotation = (((unsigned long)
- hw->vh264_amstream_dec_info.param) >> 16) & 0xffff;
-
- hw->frame_prog = 0;
- hw->frame_width = hw->vh264_amstream_dec_info.width;
- hw->frame_height = hw->vh264_amstream_dec_info.height;
- hw->frame_dur = hw->vh264_amstream_dec_info.rate;
- hw->pts_outside = ((unsigned long)
- hw->vh264_amstream_dec_info.param) & 0x01;
- hw->sync_outside = ((unsigned long)
- hw->vh264_amstream_dec_info.param & 0x02) >> 1;
- hw->use_idr_framerate = ((unsigned long)
- hw->vh264_amstream_dec_info.param & 0x04) >> 2;
- hw->max_refer_buf = !(((unsigned long)
- hw->vh264_amstream_dec_info.param & 0x10) >> 4);
- if (hw->frame_dur < 96000/960) {
- /*more than 960fps,it should not be a correct value,
- *give default 30fps
- */
- hw->frame_dur = 96000/30;
- }
-
- hw->unstable_pts = (((unsigned long) hw->vh264_amstream_dec_info.param & 0x40) >> 6);
-
- hw->first_i_policy = first_i_policy;
-
- pr_info("H264 sysinfo: %dx%d duration=%d, pts_outside=%d\n",
- hw->frame_width, hw->frame_height, hw->frame_dur, hw->pts_outside);
- pr_debug("sync_outside=%d, use_idr_framerate=%d, is_used_v4l: %d\n",
- hw->sync_outside, hw->use_idr_framerate, hw->is_used_v4l);
-
- if (i_only_flag & 0x100)
- hw->i_only = i_only_flag & 0xff;
- if (hw->i_only)
- hw->dpb.first_insert_frame = FirstInsertFrm_SKIPDONE;
-
- if ((unsigned long) hw->vh264_amstream_dec_info.param
- & 0x08)
- hw->no_poc_reorder_flag = 1;
-
- error_recovery_mode_in = 1; /*ucode control?*/
- if (hw->error_proc_policy & 0x80000000)
- hw->send_error_frame_flag = hw->error_proc_policy & 0x1;
- else if ((unsigned long) hw->vh264_amstream_dec_info.param & 0x20)
- hw->send_error_frame_flag = 0; /*Don't display mark err frames*/
-
- if (!is_reset) {
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]);
- hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
- hw->vfpool[hw->cur_pool][i].bufWidth = 1920;
- kfifo_put(&hw->newframe_q, vf);
- }
- }
-
- hw->duration_from_pts_done = 0;
-
- hw->p_last_vf = NULL;
- hw->vh264_stream_switching_state = SWITCHING_STATE_OFF;
- hw->hevc_cur_buf_idx = 0xffff;
-
- init_waitqueue_head(&hw->wait_q);
-
- return;
-}
-
-static s32 vh264_init(struct vdec_h264_hw_s *hw)
-{
- int size = -1;
- int fw_size = 0x1000 * 16;
- int fw_mmu_size = 0x1000 * 16;
- struct firmware_s *fw = NULL, *fw_mmu = NULL;
-
- /* int trickmode_fffb = 0; */
-
- /* pr_info("\nvh264_init\n"); */
- /* init_timer(&hw->recycle_timer); */
-
- /* timer init */
- timer_setup(&hw->check_timer, check_timer_func, 0);
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
-
- /* add_timer(&hw->check_timer); */
- hw->stat |= STAT_TIMER_ARM;
- hw->stat |= STAT_ISR_REG;
-
- mutex_init(&hw->chunks_mutex);
- vh264_local_init(hw, false);
- INIT_WORK(&hw->work, vh264_work);
- INIT_WORK(&hw->notify_work, vh264_notify_work);
- INIT_WORK(&hw->timeout_work, vh264_timeout_work);
-#ifdef MH264_USERDATA_ENABLE
- INIT_WORK(&hw->user_data_ready_work, user_data_ready_notify_work);
-#endif
-
- /*if (!amvdec_enable_flag) {
- amvdec_enable_flag = true;
- amvdec_enable();
- if (hw->mmu_enable)
- amhevc_enable();
- }*/
- if (hw->mmu_enable) {
-
- hw->frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- FRAME_MMU_MAP_SIZE,
- &hw->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hw->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -ENOMEM;
- }
- }
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- size = get_firmware_data(VIDEO_DEC_H264_MULTI, fw->data);
- if (size < 0) {
- pr_err("get firmware fail.\n");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
-
- if (hw->mmu_enable) {
- fw_mmu = vmalloc(sizeof(struct firmware_s) + fw_mmu_size);
- if (IS_ERR_OR_NULL(fw_mmu))
- return -ENOMEM;
-
- size = get_firmware_data(VIDEO_DEC_H264_MULTI_MMU, fw_mmu->data);
- if (size < 0) {
- pr_err("get mmu fw fail.\n");
- vfree(fw_mmu);
- return -1;
- }
-
- fw_mmu->len = size;
- hw->fw_mmu = fw_mmu;
- }
-
- if (!tee_enabled()) {
- /* -- ucode loading (amrisc and swap code) */
- hw->mc_cpu_addr =
- dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE,
- &hw->mc_dma_handle, GFP_KERNEL);
- if (!hw->mc_cpu_addr) {
- amvdec_enable_flag = false;
- amvdec_disable();
- hw->vdec_pg_enable_flag = 0;
- if (hw->mmu_enable)
- amhevc_disable();
- pr_info("vh264_init: Can not allocate mc memory.\n");
- return -ENOMEM;
- }
-
- /*pr_info("264 ucode swap area: phyaddr %p, cpu vaddr %p\n",
- (void *)hw->mc_dma_handle, hw->mc_cpu_addr);
- */
-
- /*ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf);*/
-
- /*header*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_HEADER,
- fw->data + 0x4000, MC_SWAP_SIZE);
- /*data*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_DATA,
- fw->data + 0x2000, MC_SWAP_SIZE);
- /*mmco*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MMCO,
- fw->data + 0x6000, MC_SWAP_SIZE);
- /*list*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_LIST,
- fw->data + 0x3000, MC_SWAP_SIZE);
- /*slice*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_SLICE,
- fw->data + 0x5000, MC_SWAP_SIZE);
- /*main*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN,
- fw->data, 0x2000);
- /*data*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x2000,
- fw->data + 0x2000, 0x1000);
- /*slice*/
- memcpy((u8 *) hw->mc_cpu_addr + MC_OFFSET_MAIN + 0x3000,
- fw->data + 0x5000, 0x1000);
- }
-
-#if 1 /* #ifdef BUFFER_MGR_IN_C */
- hw->lmem_addr = (dma_addr_t)dma_alloc_coherent(amports_get_dma_device(),
- PAGE_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, GFP_KERNEL);
-
- if (hw->lmem_addr == 0) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- }
- pr_debug("%s, phy_addr=%lx vaddr=%p\n",
- __func__, hw->lmem_phy_addr, (void *)hw->lmem_addr);
-
- if (prefix_aux_buf_size > 0 ||
- suffix_aux_buf_size > 0) {
- u32 aux_buf_size;
- hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size);
- hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size);
- aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size;
- hw->aux_addr = dma_alloc_coherent(amports_get_dma_device(),
- aux_buf_size, &hw->aux_phy_addr,
- GFP_KERNEL);
- if (hw->aux_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
-
- hw->sei_data_buf = kmalloc(SEI_DATA_SIZE, GFP_KERNEL);
- if (hw->sei_data_buf == NULL) {
- pr_err("%s: failed to alloc sei itu data buffer\n",
- __func__);
- return -1;
- }
- hw->sei_itu_data_buf = kmalloc(SEI_ITU_DATA_SIZE, GFP_KERNEL);
- if (hw->sei_itu_data_buf == NULL) {
- pr_err("%s: failed to alloc sei itu data buffer\n",
- __func__);
- dma_free_coherent(amports_get_dma_device(),
- hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
- hw->aux_phy_addr);
- hw->aux_addr = NULL;
- kfree(hw->sei_data_buf);
- hw->sei_data_buf = NULL;
-
- return -1;
- }
-
- if (NULL == hw->sei_user_data_buffer) {
- hw->sei_user_data_buffer = kmalloc(USER_DATA_SIZE,
- GFP_KERNEL);
- if (!hw->sei_user_data_buffer) {
- pr_info("%s: Can not allocate sei_data_buffer\n",
- __func__);
- dma_free_coherent(amports_get_dma_device(),
- hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
- hw->aux_phy_addr);
- hw->aux_addr = NULL;
- kfree(hw->sei_data_buf);
- hw->sei_data_buf = NULL;
- kfree(hw->sei_itu_data_buf);
- hw->sei_itu_data_buf = NULL;
-
- return -1;
- }
- hw->sei_user_data_wp = 0;
- }
- }
-/* BUFFER_MGR_IN_C */
-#endif
- hw->stat |= STAT_MC_LOAD;
-
- /* add memory barrier */
- wmb();
-
- return 0;
-}
-
-static int vh264_stop(struct vdec_h264_hw_s *hw)
-{
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-#ifdef VDEC_DW
- WRITE_VREG(MDEC_DOUBLEW_CFG0, 0);
- WRITE_VREG(MDEC_DOUBLEW_CFG1, 0);
-#endif
-#ifdef MH264_USERDATA_ENABLE
- cancel_work_sync(&hw->user_data_ready_work);
-#endif
- cancel_work_sync(&hw->notify_work);
- cancel_work_sync(&hw->timeout_work);
- cancel_work_sync(&hw->work);
-
- if (hw->stat & STAT_MC_LOAD) {
- if (hw->mc_cpu_addr != NULL) {
- dma_free_coherent(amports_get_dma_device(),
- MC_TOTAL_SIZE, hw->mc_cpu_addr,
- hw->mc_dma_handle);
- hw->mc_cpu_addr = NULL;
- }
- if (hw->frame_mmu_map_addr != NULL) {
- dma_free_coherent(amports_get_dma_device(),
- FRAME_MMU_MAP_SIZE, hw->frame_mmu_map_addr,
- hw->frame_mmu_map_phy_addr);
- hw->frame_mmu_map_addr = NULL;
- }
-
- }
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- if (hw->lmem_addr) {
- dma_free_coherent(amports_get_dma_device(),
- PAGE_SIZE, (void *)hw->lmem_addr,
- hw->lmem_phy_addr);
- hw->lmem_addr = 0;
- }
-
- if (hw->aux_addr) {
- dma_free_coherent(amports_get_dma_device(),
- hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
- hw->aux_phy_addr);
- hw->aux_addr = NULL;
- }
- if (hw->sei_data_buf != NULL) {
- kfree(hw->sei_data_buf);
- hw->sei_data_buf = NULL;
- }
- if (hw->sei_itu_data_buf != NULL) {
- kfree(hw->sei_itu_data_buf);
- hw->sei_itu_data_buf = NULL;
- }
- if (hw->sei_user_data_buffer != NULL) {
- kfree(hw->sei_user_data_buffer);
- hw->sei_user_data_buffer = NULL;
- }
- /* amvdec_disable(); */
-
- vfree(hw->fw);
- hw->fw = NULL;
-
- if (hw->mmu_enable) {
- vfree(hw->fw_mmu);
- hw->fw_mmu = NULL;
- }
-
- dpb_print(DECODE_ID(hw), 0,
- "%s\n",
- __func__);
- return 0;
-}
-
-static void wait_vmh264_search_done(struct vdec_h264_hw_s *hw)
-{
- u32 vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- int count = 0;
- do {
- usleep_range(100, 500);
- if (vld_rp == READ_VREG(VLD_MEM_VIFIFO_RP))
- break;
- if (count > 2000) {
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_ERROR, "%s timeout count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n",
- __func__, count, vld_rp, READ_VREG(VLD_MEM_VIFIFO_RP));
- break;
- } else
- vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- count++;
- } while (1);
-}
-
-static void vh264_notify_work(struct work_struct *work)
-{
- struct vdec_h264_hw_s *hw = container_of(work,
- struct vdec_h264_hw_s, notify_work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (hw->is_used_v4l)
- return;
-
- if (vdec->fr_hint_state == VDEC_NEED_HINT) {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)hw->frame_dur));
- vdec->fr_hint_state = VDEC_HINTED;
- }
-
- return;
-}
-
-#ifdef MH264_USERDATA_ENABLE
-static void vmh264_reset_udr_mgr(struct vdec_h264_hw_s *hw)
-{
- hw->wait_for_udr_send = 0;
- hw->sei_itu_data_len = 0;
- memset(&hw->ud_record, 0, sizeof(hw->ud_record));
-}
-
-static void vmh264_crate_userdata_manager(
- struct vdec_h264_hw_s *hw,
- u8 *userdata_buf,
- int buf_len)
-{
- if (hw) {
-
-
- mutex_init(&hw->userdata_mutex);
-
- memset(&hw->userdata_info, 0,
- sizeof(struct mh264_userdata_info_t));
- hw->userdata_info.data_buf = userdata_buf;
- hw->userdata_info.buf_len = buf_len;
- hw->userdata_info.data_buf_end = userdata_buf + buf_len;
-
- vmh264_reset_udr_mgr(hw);
-
- }
-}
-
-static void vmh264_destroy_userdata_manager(struct vdec_h264_hw_s *hw)
-{
- if (hw)
- memset(&hw->userdata_info,
- 0,
- sizeof(struct mh264_userdata_info_t));
-}
-
-/*
-#define DUMP_USERDATA_RECORD
-*/
-#ifdef DUMP_USERDATA_RECORD
-
-#define MAX_USER_DATA_SIZE 3145728
-static void *user_data_buf;
-static unsigned char *pbuf_start;
-static int total_len;
-static int bskip;
-static int n_userdata_id;
-
-static void print_data(unsigned char *pdata,
- int len,
- unsigned int poc_number,
- unsigned int flag,
- unsigned int duration,
- unsigned int vpts,
- unsigned int vpts_valid,
- int rec_id)
-{
- int nLeft;
-
- nLeft = len;
-#if 0
- pr_info("%d len:%d, flag:%d, dur:%d, vpts:0x%x, valid:%d, poc:%d\n",
- rec_id, len, flag,
- duration, vpts, vpts_valid, poc_number);
-#endif
- pr_info("%d len = %d, flag = %d, vpts = 0x%x\n",
- rec_id, len, flag, vpts);
-
- if (len == 96) {
- int i;
- nLeft = 72;
- while (nLeft >= 16) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7],
- pdata[8], pdata[9], pdata[10], pdata[11],
- pdata[12], pdata[13], pdata[14], pdata[15]);
- nLeft -= 16;
- pdata += 16;
- }
-
-
- while (nLeft > 0) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
-
- i = 0;
- nLeft = 96-72;
- while (i < nLeft) {
- if (pdata[0] != 0) {
- pr_info("some data error\n");
- break;
- }
- pdata++;
- i++;
- }
- } else {
- while (nLeft >= 16) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7],
- pdata[8], pdata[9], pdata[10], pdata[11],
- pdata[12], pdata[13], pdata[14], pdata[15]);
- nLeft -= 16;
- pdata += 16;
- }
-
-
- while (nLeft > 0) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
-
- }
-}
-
-static void push_to_buf(struct vdec_h264_hw_s *hw,
- u8 *pdata,
- int len,
- struct userdata_meta_info_t *pmeta);
-
-static void dump_userdata_record(struct vdec_h264_hw_s *hw,
- struct mh264_userdata_record_t *record)
-{
- if (record && hw) {
- u8 *pdata;
-
- pdata = hw->userdata_info.data_buf + record->rec_start;
-/*
- print_data(pdata,
- record->rec_len,
- record->meta_info.flags,
- record->meta_info.duration,
- record->meta_info.vpts,
- record->meta_info.vpts_valid,
- n_record_id);
-*/
- push_to_buf(hw, pdata, record->rec_len, &record->meta_info);
- n_userdata_id++;
- }
-}
-
-
-static void push_to_buf(struct vdec_h264_hw_s *hw,
- u8 *pdata, int len,
- struct userdata_meta_info_t *pmeta)
-{
- u32 *pLen;
- int info_cnt;
- u8 *pbuf_end;
-
- if (!user_data_buf)
- return;
-
- if (bskip) {
- pr_info("over size, skip\n");
- return;
- }
- info_cnt = 0;
- pLen = (u32 *)pbuf_start;
-
- *pLen = len;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->poc_number;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->duration;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->flags;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->vpts;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->vpts_valid;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
-
- *pLen = n_userdata_id;
- pbuf_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
-
-
- pbuf_end = (u8 *)hw->sei_user_data_buffer + USER_DATA_SIZE;
- if (pdata + len > pbuf_end) {
- int first_section_len;
-
- first_section_len = pbuf_end - pdata;
- memcpy(pbuf_start, pdata, first_section_len);
- pdata = (u8 *)hw->sei_user_data_buffer;
- pbuf_start += first_section_len;
- memcpy(pbuf_start, pdata, len - first_section_len);
- pbuf_start += len - first_section_len;
- } else {
- memcpy(pbuf_start, pdata, len);
- pbuf_start += len;
- }
-
- total_len += len + info_cnt * sizeof(u32);
- if (total_len >= MAX_USER_DATA_SIZE-4096)
- bskip = 1;
-}
-
-static void show_user_data_buf(void)
-{
- u8 *pbuf;
- int len;
- unsigned int flag;
- unsigned int duration;
- unsigned int vpts;
- unsigned int vpts_valid;
- unsigned int poc_number;
- int rec_id;
-
- pr_info("show user data buf\n");
- pbuf = user_data_buf;
-
- while (pbuf < pbuf_start) {
- u32 *pLen;
-
- pLen = (u32 *)pbuf;
-
- len = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- poc_number = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- duration = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- flag = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- vpts = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- vpts_valid = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- rec_id = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- print_data(pbuf, len, poc_number, flag,
- duration, vpts,
- vpts_valid, rec_id);
- pbuf += len;
- msleep(30);
- }
-}
-
-static int vmh264_init_userdata_dump(void)
-{
- user_data_buf = kmalloc(MAX_USER_DATA_SIZE, GFP_KERNEL);
- if (user_data_buf)
- return 1;
- else
- return 0;
-}
-
-static void vmh264_dump_userdata(void)
-{
- if (user_data_buf) {
- show_user_data_buf();
- kfree(user_data_buf);
- user_data_buf = NULL;
- }
-}
-
-static void vmh264_reset_user_data_buf(void)
-{
- total_len = 0;
- pbuf_start = user_data_buf;
- bskip = 0;
- n_userdata_id = 0;
-}
-#endif
-
-
-static void vmh264_udc_fill_vpts(struct vdec_h264_hw_s *hw,
- int frame_type,
- u32 vpts,
- u32 vpts_valid)
-{
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
- unsigned char *pdata;
- u8 *pmax_sei_data_buffer;
- u8 *sei_data_buf;
- int i;
- int wp;
- int data_length;
- struct mh264_userdata_record_t *p_userdata_rec;
-
-
-#ifdef MH264_USERDATA_ENABLE
- struct userdata_meta_info_t meta_info;
- memset(&meta_info, 0, sizeof(meta_info));
-#endif
-
- if (hw->sei_itu_data_len <= 0)
- return;
-
- pdata = (u8 *)hw->sei_user_data_buffer + hw->sei_user_data_wp;
- pmax_sei_data_buffer = (u8 *)hw->sei_user_data_buffer + USER_DATA_SIZE;
- sei_data_buf = (u8 *)hw->sei_itu_data_buf;
- for (i = 0; i < hw->sei_itu_data_len; i++) {
- *pdata++ = sei_data_buf[i];
- if (pdata >= pmax_sei_data_buffer)
- pdata = (u8 *)hw->sei_user_data_buffer;
- }
-
- hw->sei_user_data_wp = (hw->sei_user_data_wp
- + hw->sei_itu_data_len) % USER_DATA_SIZE;
- hw->sei_itu_data_len = 0;
-
-#ifdef MH264_USERDATA_ENABLE
- meta_info.duration = hw->frame_dur;
- meta_info.flags |= (VFORMAT_H264 << 3);
-
- meta_info.vpts = vpts;
- meta_info.vpts_valid = vpts_valid;
- meta_info.poc_number =
- p_H264_Dpb->mVideo.dec_picture->poc;
-
-
- wp = hw->sei_user_data_wp;
-
- if (hw->sei_user_data_wp > hw->userdata_info.last_wp)
- data_length = wp - hw->userdata_info.last_wp;
- else
- data_length = wp + hw->userdata_info.buf_len
- - hw->userdata_info.last_wp;
-
- if (data_length & 0x7)
- data_length = (((data_length + 8) >> 3) << 3);
-
- p_userdata_rec = &hw->ud_record;
- p_userdata_rec->meta_info = meta_info;
- p_userdata_rec->rec_start = hw->userdata_info.last_wp;
- p_userdata_rec->rec_len = data_length;
- hw->userdata_info.last_wp = wp;
-
- p_userdata_rec->meta_info.flags |=
- p_H264_Dpb->mVideo.dec_picture->pic_struct << 12;
-
- hw->wait_for_udr_send = 1;
- vdec_schedule_work(&hw->user_data_ready_work);
-#endif
-}
-
-
-static void user_data_ready_notify_work(struct work_struct *work)
-{
- struct vdec_h264_hw_s *hw = container_of(work,
- struct vdec_h264_hw_s, user_data_ready_work);
-
-
- mutex_lock(&hw->userdata_mutex);
-
- hw->userdata_info.records[hw->userdata_info.write_index]
- = hw->ud_record;
- hw->userdata_info.write_index++;
- if (hw->userdata_info.write_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.write_index = 0;
-
- mutex_unlock(&hw->userdata_mutex);
-
-#ifdef DUMP_USERDATA_RECORD
- dump_userdata_record(hw, &hw->ud_record);
-#endif
- vdec_wakeup_userdata_poll(hw_to_vdec(hw));
-
- hw->wait_for_udr_send = 0;
-}
-
-static int vmh264_user_data_read(struct vdec_s *vdec,
- struct userdata_param_t *puserdata_para)
-{
- struct vdec_h264_hw_s *hw = NULL;
- int rec_ri, rec_wi;
- int rec_len;
- u8 *rec_data_start;
- u8 *pdest_buf;
- struct mh264_userdata_record_t *p_userdata_rec;
- u32 data_size;
- u32 res;
- int copy_ok = 1;
-
- hw = (struct vdec_h264_hw_s *)vdec->private;
-
- pdest_buf = puserdata_para->pbuf_addr;
-
- mutex_lock(&hw->userdata_mutex);
-
-/*
- pr_info("ri = %d, wi = %d\n",
- lg_p_mpeg12_userdata_info->read_index,
- lg_p_mpeg12_userdata_info->write_index);
-*/
- rec_ri = hw->userdata_info.read_index;
- rec_wi = hw->userdata_info.write_index;
-
- if (rec_ri == rec_wi) {
- mutex_unlock(&hw->userdata_mutex);
- return 0;
- }
-
- p_userdata_rec = hw->userdata_info.records + rec_ri;
-
- rec_len = p_userdata_rec->rec_len;
- rec_data_start = p_userdata_rec->rec_start + hw->userdata_info.data_buf;
-/*
- pr_info("rec_len:%d, rec_start:%d, buf_len:%d\n",
- p_userdata_rec->rec_len,
- p_userdata_rec->rec_start,
- puserdata_para->buf_len);
-*/
- if (rec_len <= puserdata_para->buf_len) {
- /* dvb user data buffer is enought to
- copy the whole recored. */
- data_size = rec_len;
- if (rec_data_start + data_size
- > hw->userdata_info.data_buf_end) {
- int first_section_len;
-
- first_section_len = hw->userdata_info.buf_len -
- p_userdata_rec->rec_start;
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- first_section_len);
- if (res) {
- pr_info("p1 read not end res=%d, request=%d\n",
- res, first_section_len);
- copy_ok = 0;
-
- p_userdata_rec->rec_len -=
- first_section_len - res;
- p_userdata_rec->rec_start +=
- first_section_len - res;
- puserdata_para->data_size =
- first_section_len - res;
- } else {
- res = (u32)copy_to_user(
- (void *)(pdest_buf+first_section_len),
- (void *)hw->userdata_info.data_buf,
- data_size - first_section_len);
- if (res) {
- pr_info("p2 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
- p_userdata_rec->rec_len -=
- data_size - res;
- p_userdata_rec->rec_start =
- data_size - first_section_len - res;
- puserdata_para->data_size =
- data_size - res;
- }
- } else {
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- data_size);
- if (res) {
- pr_info("p3 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
- p_userdata_rec->rec_len -= data_size - res;
- p_userdata_rec->rec_start += data_size - res;
- puserdata_para->data_size = data_size - res;
- }
-
- if (copy_ok) {
- hw->userdata_info.read_index++;
- if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.read_index = 0;
- }
- } else {
- /* dvb user data buffer is not enought
- to copy the whole recored. */
- data_size = puserdata_para->buf_len;
- if (rec_data_start + data_size
- > hw->userdata_info.data_buf_end) {
- int first_section_len;
-
- first_section_len = hw->userdata_info.buf_len -
- p_userdata_rec->rec_start;
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- first_section_len);
- if (res) {
- pr_info("p4 read not end res=%d, request=%d\n",
- res, first_section_len);
- copy_ok = 0;
- p_userdata_rec->rec_len -=
- first_section_len - res;
- p_userdata_rec->rec_start +=
- first_section_len - res;
- puserdata_para->data_size =
- first_section_len - res;
- } else {
- /* first secton copy is ok*/
- res = (u32)copy_to_user(
- (void *)(pdest_buf+first_section_len),
- (void *)hw->userdata_info.data_buf,
- data_size - first_section_len);
- if (res) {
- pr_info("p5 read not end res=%d, request=%d\n",
- res,
- data_size - first_section_len);
- copy_ok = 0;
- }
-
- p_userdata_rec->rec_len -=
- data_size - res;
- p_userdata_rec->rec_start =
- data_size - first_section_len - res;
- puserdata_para->data_size =
- data_size - res;
- }
- } else {
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- data_size);
- if (res) {
- pr_info("p6 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
-
- p_userdata_rec->rec_len -= data_size - res;
- p_userdata_rec->rec_start += data_size - res;
- puserdata_para->data_size = data_size - res;
- }
-
- if (copy_ok) {
- hw->userdata_info.read_index++;
- if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.read_index = 0;
- }
-
- }
- puserdata_para->meta_info = p_userdata_rec->meta_info;
-
- if (hw->userdata_info.read_index <= hw->userdata_info.write_index)
- puserdata_para->meta_info.records_in_que =
- hw->userdata_info.write_index -
- hw->userdata_info.read_index;
- else
- puserdata_para->meta_info.records_in_que =
- hw->userdata_info.write_index +
- USERDATA_FIFO_NUM -
- hw->userdata_info.read_index;
-
- puserdata_para->version = (0<<24|0<<16|0<<8|1);
-
- mutex_unlock(&hw->userdata_mutex);
-
- return 1;
-}
-
-static void vmh264_reset_userdata_fifo(struct vdec_s *vdec, int bInit)
-{
- struct vdec_h264_hw_s *hw = NULL;
-
- hw = (struct vdec_h264_hw_s *)vdec->private;
-
- if (hw) {
- mutex_lock(&hw->userdata_mutex);
- pr_info("vmh264_reset_userdata_fifo: bInit: %d, ri: %d, wi: %d\n",
- bInit,
- hw->userdata_info.read_index,
- hw->userdata_info.write_index);
- hw->userdata_info.read_index = 0;
- hw->userdata_info.write_index = 0;
-
- if (bInit)
- hw->userdata_info.last_wp = 0;
- mutex_unlock(&hw->userdata_mutex);
- }
-}
-
-static void vmh264_wakeup_userdata_poll(struct vdec_s *vdec)
-{
- amstream_wakeup_userdata_poll(vdec);
-}
-
-#endif
-
-static int vmh264_get_ps_info(struct vdec_h264_hw_s *hw,
- u32 param1, u32 param2, u32 param3, u32 param4,
- struct aml_vdec_ps_infos *ps)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hw);
-#endif
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vdec_pic_info pic;
- int mb_width, mb_total;
- int mb_height = 0;
- int active_buffer_spec_num, dec_dpb_size;
- int max_reference_size ,level_idc;
- u32 frame_mbs_only_flag;
- u32 chroma_format_idc;
- u32 crop_bottom, crop_right;
- int sub_width_c = 0, sub_height_c = 0;
- u32 frame_width, frame_height;
- u32 used_reorder_dpb_size_margin
- = hw->reorder_dpb_size_margin;
-
- level_idc = param4 & 0xff;
- max_reference_size = (param4 >> 8) & 0xff;
- hw->dpb.mSPS.level_idc = level_idc;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master || vdec->slave)
- used_reorder_dpb_size_margin =
- reorder_dpb_size_margin_dv;
-#endif
- mb_width = param1 & 0xff;
- mb_total = (param1 >> 8) & 0xffff;
- if (!mb_width && mb_total) /*for 4k2k*/
- mb_width = 256;
- if (mb_width)
- mb_height = mb_total/mb_width;
- if (mb_width <= 0 || mb_height <= 0 ||
- is_oversize(mb_width << 4, mb_height << 4)) {
- dpb_print(DECODE_ID(hw), 0,
- "!!!wrong param1 0x%x mb_width/mb_height (0x%x/0x%x) %x\r\n",
- param1,
- mb_width,
- mb_height);
- hw->error_frame_width = mb_width << 4;
- hw->error_frame_height = mb_height << 4;
- return -1;
- }
- hw->error_frame_width = 0;
- hw->error_frame_height = 0;
-
- dec_dpb_size = get_dec_dpb_size(hw , mb_width, mb_height, level_idc);
-
- dpb_print(DECODE_ID(hw), 0,
- "v4l restriction:%d, max buffering:%d, DPB size:%d, reorder frames:%d, margin:%d\n",
- hw->bitstream_restriction_flag,
- hw->max_dec_frame_buffering,
- dec_dpb_size,
- hw->num_reorder_frames,
- used_reorder_dpb_size_margin);
-
- active_buffer_spec_num =
- dec_dpb_size
- + used_reorder_dpb_size_margin;
-
- if (active_buffer_spec_num > MAX_VF_BUF_NUM) {
- active_buffer_spec_num = MAX_VF_BUF_NUM;
- dec_dpb_size = active_buffer_spec_num
- - used_reorder_dpb_size_margin;
- }
-
- hw->dpb.mDPB.size = active_buffer_spec_num;
-
- if (hw->no_poc_reorder_flag)
- dec_dpb_size = 1;
-
- /*
- * crop
- * AV_SCRATCH_2
- * bit 15: frame_mbs_only_flag
- * bit 13-14: chroma_format_idc
- */
- hw->seq_info = param2;
- frame_mbs_only_flag = (hw->seq_info >> 15) & 0x01;
- if (hw->dpb.mSPS.profile_idc != 100 &&
- hw->dpb.mSPS.profile_idc != 110 &&
- hw->dpb.mSPS.profile_idc != 122 &&
- hw->dpb.mSPS.profile_idc != 144) {
- hw->dpb.chroma_format_idc = 1;
- }
- chroma_format_idc = hw->dpb.chroma_format_idc;
-
- /*
- * AV_SCRATCH_6 bit 31-16 = (left << 8 | right ) << 1
- * AV_SCRATCH_6 bit 15-0 = (top << 8 | bottom ) <<
- * (2 - frame_mbs_only_flag)
- */
- switch (chroma_format_idc) {
- case 1:
- sub_width_c = 2;
- sub_height_c = 2;
- break;
-
- case 2:
- sub_width_c = 2;
- sub_height_c = 1;
- break;
-
- case 3:
- sub_width_c = 1;
- sub_height_c = 1;
- break;
-
- default:
- break;
- }
-
- if (chroma_format_idc == 0) {
- crop_right = hw->dpb.frame_crop_right_offset;
- crop_bottom = hw->dpb.frame_crop_bottom_offset *
- (2 - frame_mbs_only_flag);
- } else {
- crop_right = sub_width_c * hw->dpb.frame_crop_right_offset;
- crop_bottom = sub_height_c * hw->dpb.frame_crop_bottom_offset *
- (2 - frame_mbs_only_flag);
- }
-
- frame_width = mb_width << 4;
- frame_height = mb_height << 4;
-
- frame_width = frame_width - crop_right;
- frame_height = frame_height - crop_bottom;
-
- ps->profile = level_idc;
- ps->ref_frames = max_reference_size;
- ps->mb_width = mb_width;
- ps->mb_height = mb_height;
- ps->visible_width = frame_width;
- ps->visible_height = frame_height;
- ps->coded_width = ALIGN(mb_width << 4, 64);
- ps->coded_height = ALIGN(mb_height << 4, 64);
- ps->dpb_frames = dec_dpb_size + 1; /* +1 for two frames in one packet */
- ps->dpb_margin = used_reorder_dpb_size_margin;
- ps->dpb_size = active_buffer_spec_num;
- ps->field = frame_mbs_only_flag ?
- V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
-
- /* update reoder and margin num. */
- if (hw->res_ch_flag) {
- vdec_v4l_get_pic_info(ctx, &pic);
- ps->dpb_frames = pic.dpb_frames;
- ps->dpb_margin = pic.dpb_margin;
- }
-
- if ((ps->dpb_frames >= 16) && (ps->coded_width > 1280) &&
- (ps->coded_height > 768)) {
- if (ps->field == V4L2_FIELD_NONE) {
- ps->dpb_frames = adjust_dpb_size;
- } else {
- ps->dpb_frames = adjust_dpb_size - 2;
- }
- }
-
- dpb_print(DECODE_ID(hw), 0,
- "Res:%dx%d, DPB size:%d, margin:%d, scan:%s\n",
- ps->visible_width, ps->visible_height,
- ps->dpb_frames, ps->dpb_margin,
- (ps->field == V4L2_FIELD_NONE) ? "P" : "I");
-
- return 0;
-}
-
-static int v4l_res_change(struct vdec_h264_hw_s *hw,
- u32 param1, u32 param2,
- u32 param3, u32 param4)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int ret = 0;
- int dec_dpb_size_change = hw->dpb.dec_dpb_size != get_dec_dpb_size_active(hw, param1, param4);
-
- if (ctx->param_sets_from_ucode &&
- hw->res_ch_flag == 0) {
- if (((param1 != 0 &&
- hw->seq_info2 != param1) || hw->csd_change_flag) &&
- hw->seq_info2 != 0) {
- if (((hw->seq_info2 & 0x80ffffff) != (param1 & 0x80ffffff)) || dec_dpb_size_change) { /*picture size changed*/
- struct aml_vdec_ps_infos ps;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "h264 res_change\n");
- if (vmh264_get_ps_info(hw, param1,
- param2, param3, param4, &ps) < 0) {
- dpb_print(DECODE_ID(hw), 0,
- "set parameters error\n");
- }
- hw->v4l_params_parsed = false;
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- hw->bitstream_restriction_flag = hw->cfg_bitstream_restriction_flag; // restore the old value when v4l res change
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- hw->eos = 1;
- flush_dpb(p_H264_Dpb);
- //del_timer_sync(&hw->check_timer);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- ret = 1;
- }
- }
- }
-
- return ret;
-
-}
-
-static void vh264_work_implement(struct vdec_h264_hw_s *hw,
- struct vdec_s *vdec, int from)
-{
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-
- if (hw->dec_result == DEC_RESULT_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START);
- } else if (hw->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s dec_result %d %x %x %x\n",
- __func__,
- hw->dec_result,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));
-
- ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result);
-
- if (!hw->mmu_enable) {
- mutex_lock(&vmh264_mutex);
- dealloc_buf_specs(hw, 0);
- mutex_unlock(&vmh264_mutex);
- }
- hw->save_reg_f = READ_VREG(AV_SCRATCH_F);
- hw->dpb.last_dpb_status = hw->dpb.dec_dpb_status;
- if (hw->dec_result == DEC_RESULT_CONFIG_PARAM) {
- u32 param1 = READ_VREG(AV_SCRATCH_1);
- u32 param2 = READ_VREG(AV_SCRATCH_2);
- u32 param3 = READ_VREG(AV_SCRATCH_6);
- u32 param4 = READ_VREG(AV_SCRATCH_B);
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (hw->is_used_v4l &&
- ctx->param_sets_from_ucode) {
- if (!v4l_res_change(hw, param1, param2, param3, param4)) {
- if (!hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_DEC_DETAIL,
- "h264 parsered csd data\n");
- if (vmh264_get_ps_info(hw,
- param1, param2,
- param3, param4, &ps) < 0) {
- dpb_print(DECODE_ID(hw), 0,
- "set parameters error\n");
- }
- hw->v4l_params_parsed = true;
- vdec_v4l_set_ps_infos(ctx, &ps);
-
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START);
- } else {
- if (vh264_set_params(hw, param1,
- param2, param3, param4, false) < 0) {
- hw->init_flag = 0;
- dpb_print(DECODE_ID(hw), 0, "set parameters error, init_flag: %u\n",
- hw->init_flag);
- }
-
- WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
- (hw->dpb.mDPB.size<<16) |
- (hw->dpb.mDPB.size<<8));
- hw->res_ch_flag = 0;
- start_process_time(hw);
- return;
- }
- }
- } else {
- if (vh264_set_params(hw, param1,
- param2, param3, param4, false) < 0) {
- hw->init_flag = 0;
- dpb_print(DECODE_ID(hw), 0, "set parameters error, init_flag: %u\n",
- hw->init_flag);
- }
-
- WRITE_VREG(AV_SCRATCH_0, (hw->max_reference_size<<24) |
- (hw->dpb.mDPB.size<<16) |
- (hw->dpb.mDPB.size<<8));
- start_process_time(hw);
- return;
- }
- } else
- if (((hw->dec_result == DEC_RESULT_GET_DATA) ||
- (hw->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
-
- if (hw->dec_result == DEC_RESULT_GET_DATA) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));
- mutex_lock(&hw->chunks_mutex);
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk = NULL;
- mutex_unlock(&hw->chunks_mutex);
- vdec_clean_input(vdec);
- }
- if ((hw->dec_result == DEC_RESULT_GET_DATA_RETRY) &&
- ((1000 * (jiffies - hw->get_data_start_time) / HZ)
- > get_data_timeout_val)) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA_RETRY timeout\n",
- __func__);
- goto result_done;
- }
- if (is_buffer_available(vdec)) {
- int r;
- int decode_size;
- r = vdec_prepare_input(vdec, &hw->chunk);
- if (r < 0 && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- hw->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_VDEC_DETAIL,
- "vdec_prepare_input: Insufficient data\n");
- vdec_schedule_work(&hw->work);
- return;
- }
- hw->dec_result = DEC_RESULT_NONE;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: chunk size 0x%x\n",
- __func__, hw->chunk->size);
-
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA)) {
- int jj;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(
- hw->chunk->block->start +
- hw->chunk->offset, r);
- else
- data = ((u8 *)
- hw->chunk->block->start_virt)
- + hw->chunk->offset;
-
- for (jj = 0; jj < r; jj++) {
- if ((jj & 0xf) == 0)
- dpb_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- WRITE_VREG(POWER_CTL_VLD,
- READ_VREG(POWER_CTL_VLD) |
- (0 << 10) | (1 << 9) | (1 << 6));
- WRITE_VREG(H264_DECODE_INFO, (1<<13));
- decode_size = hw->chunk->size +
- (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(H264_DECODE_SIZE, decode_size);
- WRITE_VREG(VIFF_BIT_CNT, decode_size * 8);
- vdec_enable_input(vdec);
-
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
- start_process_time(hw);
- } else{
- if (hw_to_vdec(hw)->next_status
- != VDEC_STATUS_DISCONNECTED) {
- hw->dec_result = DEC_RESULT_GET_DATA_RETRY;
- vdec_schedule_work(&hw->work);
- }
- }
- return;
- } else if (hw->dec_result == DEC_RESULT_DONE ||
- hw->dec_result == DEC_RESULT_TIMEOUT) {
- /* if (!hw->ctx_valid)
- hw->ctx_valid = 1; */
- if ((hw->dec_result == DEC_RESULT_TIMEOUT) &&
- !hw->i_only && (hw->error_proc_policy & 0x2)) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- dpb_print(DECODE_ID(hw), 0,
- "%s, decode timeout flush dpb\n",
- __func__);
- flush_dpb(p_H264_Dpb);
- }
-result_done:
- {
- if (hw->error_proc_policy & 0x8000) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int i;
- struct DecodedPictureBuffer *p_Dpb = &p_H264_Dpb->mDPB;
-
- for (i = 0; i < p_Dpb->used_size; i++) {
- int i_flag = p_Dpb->fs[i]->bottom_field || p_Dpb->fs[i]->top_field;
- int threshold = (i_flag || (hw->max_reference_size >= 12)) ? ((50 + p_Dpb->used_size) * 2) : 50 + p_Dpb->used_size;
- if ((p_Dpb->fs[i]->dpb_frame_count + threshold
- < p_H264_Dpb->dpb_frame_count) &&
- p_Dpb->fs[i]->is_reference &&
- !p_Dpb->fs[i]->is_long_term &&
- p_Dpb->fs[i]->is_output) {
- dpb_print(DECODE_ID(hw),
- 0,
- "unmark reference dpb_frame_count diffrence large in dpb\n");
- unmark_for_reference(p_Dpb, p_Dpb->fs[i]);
- update_ref_list(p_Dpb);
- }
- }
- }
- }
- if (hw->mmu_enable
- && hw->frame_busy && hw->frame_done) {
- long used_4k_num;
- hevc_sao_wait_done(hw);
- if (hw->hevc_cur_buf_idx != 0xffff) {
- used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- if (used_4k_num >= 0)
- dpb_print(DECODE_ID(hw),
- PRINT_FLAG_MMU_DETAIL,
- "release unused buf , used_4k_num %ld index %d\n",
- used_4k_num, hw->hevc_cur_buf_idx);
- hevc_mmu_dma_check(hw_to_vdec(hw));
- decoder_mmu_box_free_idx_tail(
- hw->mmu_box,
- hw->hevc_cur_buf_idx,
- used_4k_num);
- hw->hevc_cur_buf_idx = 0xffff;
- }
- }
- decode_frame_count[DECODE_ID(hw)]++;
- if (hw->dpb.mSlice.slice_type == I_SLICE) {
- hw->gvs.i_decoded_frames++;
- } else if (hw->dpb.mSlice.slice_type == P_SLICE) {
- hw->gvs.p_decoded_frames++;
- } else if (hw->dpb.mSlice.slice_type == B_SLICE) {
- hw->gvs.b_decoded_frames++;
- }
- amvdec_stop();
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s dec_result %d %x %x %x\n",
- __func__,
- hw->dec_result,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));
- mutex_lock(&hw->chunks_mutex);
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- hw->chunk = NULL;
- mutex_unlock(&hw->chunks_mutex);
- } else if (hw->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec) && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED) && (hw->no_decoder_buffer_flag == 0)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- hw->no_decoder_buffer_flag = 0;
- hw->next_again_flag = 1;
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: end of stream\n",
- __func__);
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- hw->eos = 1;
- flush_dpb(p_H264_Dpb);
- if (hw->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
- mutex_lock(&hw->chunks_mutex);
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- hw->chunk = NULL;
- mutex_unlock(&hw->chunks_mutex);
- vdec_clean_input(vdec);
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_NEED_MORE_BUFFER) {
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
- if (!have_free_buf_spec(vdec)) {
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED)
- hw->dec_result = DEC_RESULT_AGAIN;
- else
- hw->dec_result = DEC_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- } else {
- hw->get_data_count = 0x7fffffff;
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
- decode_frame_count[DECODE_ID(hw)]++;
- if (p_H264_Dpb->mSlice.slice_type == I_SLICE) {
- hw->gvs.i_decoded_frames++;
- } else if (p_H264_Dpb->mSlice.slice_type == P_SLICE) {
- hw->gvs.p_decoded_frames++;
- } else if (p_H264_Dpb->mSlice.slice_type == B_SLICE) {
- hw->gvs.b_decoded_frames++;
- }
- start_process_time(hw);
- }
- return;
- }
-
- if (p_H264_Dpb->mVideo.dec_picture) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s, release decoded picture\n", __func__);
- release_cur_decoding_buf(hw);
- }
-
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
-#ifdef DETECT_WRONG_MULTI_SLICE
- if (hw->dec_result != DEC_RESULT_AGAIN)
- hw->last_picture_slice_count = 0;
-#endif
- ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START);
- wait_vmh264_search_done(hw);
- ATRACE_COUNTER(hw->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END);
- /* mark itself has all HW resource released and input released */
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (hw->switch_dvlayer_flag) {
- if (vdec->slave)
- vdec_set_next_sched(vdec, vdec->slave);
- else if (vdec->master)
- vdec_set_next_sched(vdec, vdec->master);
- } else if (vdec->slave || vdec->master)
- vdec_set_next_sched(vdec, vdec);
-#endif
-
- if (from == 1) {
- /* This is a timeout work */
- if (work_pending(&hw->work)) {
- /*
- * The vh264_work arrives at the last second,
- * give it a chance to handle the scenario.
- */
- return;
- }
- }
-
- if (hw->dec_result == DEC_RESULT_DONE || hw->dec_result == DEC_RESULT_CONFIG_PARAM) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END);
- }
-
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec == 1) {
- if (hw->mmu_enable == 0)
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1);
- else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- } else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- wake_up_interruptible(&hw->wait_q);
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hw->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- if (hw->vdec_cb)
- hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
-}
-
-
-static void vh264_work(struct work_struct *work)
-{
- struct vdec_h264_hw_s *hw = container_of(work,
- struct vdec_h264_hw_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- vh264_work_implement(hw, vdec, 0);
-}
-
-
-static void vh264_timeout_work(struct work_struct *work)
-{
- struct vdec_h264_hw_s *hw = container_of(work,
- struct vdec_h264_hw_s, timeout_work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (work_pending(&hw->work))
- return;
-
- hw->timeout_processing = 1;
- vh264_work_implement(hw, vdec, 1);
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- bool ret = 0;
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)vdec->private;
- int tvp = vdec_secure(hw_to_vdec(hw)) ?
- CODEC_MM_FLAGS_TVP : 0;
-
- if (hw->timeout_processing &&
- (work_pending(&hw->work) || work_busy(&hw->work) ||
- work_pending(&hw->timeout_work) || work_busy(&hw->timeout_work))) {
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "h264 work pending, not ready for run.\n");
- return 0;
- }
- hw->timeout_processing = 0;
- if (!hw->first_sc_checked && hw->mmu_enable) {
- int size = decoder_mmu_box_sc_check(hw->mmu_box, tvp);
- hw->first_sc_checked =1;
- dpb_print(DECODE_ID(hw), 0,
- "vmh264 cached=%d need_size=%d speed= %d ms\n",
- size, (hw->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - hw->sc_start_time) * 1000/HZ);
- }
-
- if (vdec_stream_based(vdec) && (hw->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level)
- return 0;
- }
-
-#ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master)
- return 0;
-#endif
- if (hw->eos)
- return 0;
-
- if (hw->stat & DECODER_FATAL_ERROR_NO_MEM)
- return 0;
-
- if (disp_vframe_valve_level &&
- kfifo_len(&hw->display_q) >=
- disp_vframe_valve_level) {
- hw->valve_count--;
- if (hw->valve_count <= 0)
- hw->valve_count = 2;
- else
- return 0;
- }
- if (hw->next_again_flag &&
- (!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr = STBUF_READ(&vdec->vbuf, get_wp);
- if (parser_wr_ptr >= hw->pre_parser_wr_ptr &&
- (parser_wr_ptr - hw->pre_parser_wr_ptr) <
- again_threshold) {
- int r = vdec_sync_input(vdec);
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "%s buf lelvel:%x\n", __func__, r);
- return 0;
- }
- }
-
- if (h264_debug_flag & 0x20000000) {
- /* pr_info("%s, a\n", __func__); */
- ret = 1;
- } else
- ret = is_buffer_available(vdec);
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
- if (ret && (hw->dpb.mDPB.size > 0)) { /*make sure initilized*/
- if (run_ready_max_vf_only_num > 0 &&
- get_vf_ref_only_buf_count(hw) >=
- run_ready_max_vf_only_num
- )
- ret = 0;
- if (run_ready_display_q_num > 0 &&
- kfifo_len(&hw->display_q) >=
- run_ready_display_q_num)
- ret = 0;
- /*avoid more buffers consumed when
- switching resolution*/
- if (run_ready_max_buf_num == 0xff &&
- get_used_buf_count(hw) >
- hw->dpb.mDPB.size)
- ret = 0;
- else if (run_ready_max_buf_num &&
- get_used_buf_count(hw) >=
- run_ready_max_buf_num)
- ret = 0;
- if (ret == 0)
- bufmgr_h264_remove_unused_frame(&hw->dpb, 0);
- }
-#endif
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode) {
- if (hw->v4l_params_parsed) {
- if (ctx->cap_pool.dec < hw->dpb.mDPB.size) {
- if (is_buffer_available(vdec))
- ret = 1;
- else
- ret = 0;
- }
- } else {
- if (ctx->v4l_resolution_change)
- ret = 0;
- }
- } else if (!ctx->v4l_codec_dpb_ready) {
- if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
- run_ready_min_buf_num)
- ret = 0;
- }
- }
-
- if (ret)
- not_run_ready[DECODE_ID(hw)] = 0;
- else
- not_run_ready[DECODE_ID(hw)]++;
- if (vdec->parallel_dec == 1) {
- if (hw->mmu_enable == 0)
- return ret ? (CORE_MASK_VDEC_1) : 0;
- else
- return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
- } else
- return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
-}
-
-static unsigned char get_data_check_sum
- (struct vdec_h264_hw_s *hw, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt)
- + hw->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)vdec->private;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int size, ret = -1;
- if (!hw->vdec_pg_enable_flag) {
- hw->vdec_pg_enable_flag = 1;
- amvdec_enable();
- if (hw->mmu_enable)
- amhevc_enable();
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START);
-
- run_count[DECODE_ID(hw)]++;
- vdec_reset_core(vdec);
- if (hw->mmu_enable)
- hevc_reset_core(vdec);
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
-
-#ifdef DETECT_WRONG_MULTI_SLICE
- hw->cur_picture_slice_count = 0;
-#endif
-
- if (kfifo_len(&hw->display_q) > VF_POOL_SIZE) {
- hw->reset_bufmgr_flag = 1;
- dpb_print(DECODE_ID(hw), 0,
- "kfifo len:%d invaild, need bufmgr reset\n",
- kfifo_len(&hw->display_q));
- }
-
- if (vdec_stream_based(vdec)) {
- hw->pre_parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- hw->next_again_flag = 0;
- }
-
- if (hw->reset_bufmgr_flag ||
- ((hw->error_proc_policy & 0x40) &&
- p_H264_Dpb->buf_alloc_fail)) {
- h264_reset_bufmgr_v4l(vdec, 1);
- //flag must clear after reset for v4l buf_spec_init use
- hw->reset_bufmgr_flag = 0;
- }
-
- if (h264_debug_cmd & 0xf000) {
- if (((h264_debug_cmd >> 12) & 0xf)
- == (DECODE_ID(hw) + 1)) {
- h264_reconfig(hw);
- h264_debug_cmd &= (~0xf000);
- }
- }
- /* hw->chunk = vdec_prepare_input(vdec); */
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->slave || vdec->master)
- vdec_set_flag(vdec, VDEC_FLAG_SELF_INPUT_CONTEXT);
-#endif
- size = vdec_prepare_input(vdec, &hw->chunk);
- if ((size < 0) ||
- (input_frame_based(vdec) && hw->chunk == NULL)) {
- input_empty[DECODE_ID(hw)]++;
- hw->dec_result = DEC_RESULT_AGAIN;
-
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_DETAIL,
- "vdec_prepare_input: Insufficient data\n");
-
- vdec_schedule_work(&hw->work);
- return;
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", size);
-
- input_empty[DECODE_ID(hw)] = 0;
-
- hw->dec_result = DEC_RESULT_NONE;
- hw->get_data_count = 0;
- hw->csd_change_flag = 0;
-#if 0
- pr_info("VLD_MEM_VIFIFO_LEVEL = 0x%x, rp = 0x%x, wp = 0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_MEM_VIFIFO_WP));
-#endif
-
- if (input_frame_based(vdec) && !vdec_secure(vdec)) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt)
- + hw->chunk->offset;
-
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_VDEC_STATUS)
- ) {
- dpb_print(DECODE_ID(hw), 0,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, get_data_check_sum(hw, size),
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
- }
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA)
- ) {
- int jj;
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- dpb_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- dpb_print_cont(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- } else
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: %x %x %x %x %x size 0x%x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp),
- size);
-
- start_process_time(hw);
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- WRITE_VREG(AV_SCRATCH_G, hw->reg_g_status);
- } else {
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
- ret = amvdec_vdec_loadmc_ex(VFORMAT_H264, "mh264", vdec, hw->fw->data);
- if (ret < 0) {
- amvdec_enable_flag = false;
- amvdec_disable();
- hw->vdec_pg_enable_flag = 0;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "MH264 the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_type = VFORMAT_H264;
- hw->reg_g_status = READ_VREG(AV_SCRATCH_G);
- if (hw->mmu_enable) {
- ret = amhevc_loadmc_ex(VFORMAT_H264, "mh264_mmu",
- hw->fw_mmu->data);
- if (ret < 0) {
- amvdec_enable_flag = false;
- amhevc_disable();
- dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "MH264_MMU the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_type = ((1 << 16) | VFORMAT_H264);
- }
- vdec->mc_loaded = 0;
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
- }
- vmh264_reset_udr_mgr(hw);
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
- if (vh264_hw_ctx_restore(hw) < 0) {
- vdec_schedule_work(&hw->work);
- return;
- }
- if (error_proc_policy & 0x10000) {
- hw->first_pre_frame_num = p_H264_Dpb->mVideo.pre_frame_num;
- }
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
- if (input_frame_based(vdec)) {
- int decode_size = 0;
-
- decode_size = hw->chunk->size +
- (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(H264_DECODE_INFO, (1<<13));
- WRITE_VREG(H264_DECODE_SIZE, decode_size);
- WRITE_VREG(VIFF_BIT_CNT, decode_size * 8);
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hw->chunk->size;
- } else {
- if (size <= 0)
- size = 0x7fffffff; /*error happen*/
- WRITE_VREG(H264_DECODE_INFO, (1<<13));
- WRITE_VREG(H264_DECODE_SIZE, size);
- WRITE_VREG(VIFF_BIT_CNT, size * 8);
- hw->start_bit_cnt = size * 8;
- }
- config_aux_buf(hw);
- config_decode_mode(hw);
- vdec_enable_input(vdec);
- WRITE_VREG(NAL_SEARCH_CTL, 0);
- hw->sei_data_len = 0;
- if (enable_itu_t35)
- WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x1);
- if (!hw->init_flag) {
- if (hw->mmu_enable)
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) | 0x2);
- else
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) & (~0x2));
- }
- WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | (1 << 2) | (hw->bitstream_restriction_flag << 15));
-
- if (udebug_flag)
- WRITE_VREG(AV_SCRATCH_K, udebug_flag);
- hw->stat |= STAT_TIMER_ARM;
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
-
- if (hw->mmu_enable)
- SET_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3);
- else
- CLEAR_VREG_MASK(VDEC_ASSIST_MMC_CTRL1, 1 << 3);
- }
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- amvdec_start();
- if (hw->mmu_enable /*&& !hw->frame_busy && !hw->frame_done*/) {
- WRITE_VREG(HEVC_ASSIST_SCRATCH_0, 0x0);
- amhevc_start();
- if (hw->config_bufmgr_done) {
- hevc_mcr_sao_global_hw_init(hw,
- (hw->mb_width << 4), (hw->mb_height << 4));
- hevc_mcr_config_canv2axitbl(hw, 1);
- }
- }
-
- /* if (hw->init_flag) { */
- WRITE_VREG(DPB_STATUS_REG, H264_ACTION_SEARCH_HEAD);
- /* } */
-
- hw->init_flag = 1;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END);
-}
-
-static void clear_refer_bufs(struct vdec_h264_hw_s *hw)
-{
- int i;
- ulong flags;
-
- if (hw->is_used_v4l) {
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- hw->buffer_spec[i].used = -1;
- hw->buffer_spec[i].cma_alloc_addr = 0;
- hw->buffer_spec[i].buf_adr = 0;
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- }
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]);
- hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
- hw->vfpool[hw->cur_pool][i].bufWidth = 1920;
- kfifo_put(&hw->newframe_q, vf);
- }
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)vdec->private;
-
- pr_info("vmh264 reset\n");
-
- cancel_work_sync(&hw->work);
- cancel_work_sync(&hw->notify_work);
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- if (hw->mmu_enable)
- amhevc_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
- hw->eos = 0;
- hw->decode_pic_count = 0;
-
- reset_process_time(hw);
- h264_reset_bufmgr_v4l(vdec, 0);
- clear_refer_bufs(hw);
-
- atomic_set(&hw->vf_pre_count, 0);
- atomic_set(&hw->vf_get_count, 0);
- atomic_set(&hw->vf_put_count, 0);
-
- dpb_print(DECODE_ID(hw), 0, "%s\n", __func__);
-}
-
-static void h264_reconfig(struct vdec_h264_hw_s *hw)
-{
- int i;
- unsigned long flags;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- struct vdec_s *vdec = hw_to_vdec(hw);
- dpb_print(DECODE_ID(hw), 0,
- "%s\n", __func__);
- /* after calling flush_dpb() and bufmgr_h264_remove_unused_frame(),
- all buffers are in display queue (used == 2),
- or free (used == 0)
- */
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, "pre h264_reconfig");
-
- flush_dpb(p_H264_Dpb);
- bufmgr_h264_remove_unused_frame(p_H264_Dpb, 0);
-
- if (hw->collocate_cma_alloc_addr) {
- decoder_bmmu_box_free_idx(
- hw->bmmu_box,
- BMMU_REF_IDX);
- hw->collocate_cma_alloc_addr = 0;
- hw->dpb.colocated_mv_addr_start = 0;
- hw->dpb.colocated_mv_addr_end = 0;
- }
- spin_lock_irqsave(&hw->bufspec_lock, flags);
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- if (vdec->parallel_dec == 1) {
- vdec->free_canvas_ex(hw->buffer_spec[i].y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id);
- hw->buffer_spec[i].y_canvas_index = -1;
- hw->buffer_spec[i].u_canvas_index = -1;
- hw->buffer_spec[i].v_canvas_index = -1;
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_v_canvas_index, vdec->id);
- hw->buffer_spec[i].vdec_dw_y_canvas_index = -1;
- hw->buffer_spec[i].vdec_dw_u_canvas_index = -1;
- hw->buffer_spec[i].vdec_dw_v_canvas_index = -1;
-#endif
- }
- }
- /*make sure buffers not put back to bufmgr when
- vf_put is called*/
- if (hw->buffer_spec[i].used == 2)
- hw->buffer_spec[i].used = 3;
-
- /* ready to release "free buffers"
- */
- if (hw->buffer_spec[i].used == 0)
- hw->buffer_spec[i].used = 4;
-
- hw->buffer_spec[i].canvas_pos = -1;
-
- if (hw->buffer_spec[i].used == 4 &&
- hw->buffer_spec[i].vf_ref != 0 &&
- hw->buffer_spec[i].cma_alloc_addr) {
- hw->buffer_spec[i].used = 3;
- }
- }
- spin_unlock_irqrestore(&hw->bufspec_lock, flags);
- hw->has_i_frame = 0;
- hw->config_bufmgr_done = 0;
-
- if (hw->is_used_v4l) {
- mutex_lock(&vmh264_mutex);
- dealloc_buf_specs(hw, 1);
- mutex_unlock(&vmh264_mutex);
- }
-
- if (dpb_is_debug(DECODE_ID(hw),
- PRINT_FLAG_DUMP_BUFSPEC))
- dump_bufspec(hw, "after h264_reconfig");
-}
-
-#ifdef ERROR_HANDLE_TEST
-static void h264_clear_dpb(struct vdec_h264_hw_s *hw)
-{
- int i;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s\n", __func__);
- remove_dpb_pictures(p_H264_Dpb);
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- /*make sure buffers not put back to bufmgr when
- vf_put is called*/
- if (hw->buffer_spec[i].used == 2)
- hw->buffer_spec[i].used = 5;
- }
-
-}
-#endif
-
-static void h264_reset_bufmgr_v4l(struct vdec_s *vdec, int flush_flag)
-{
- ulong timeout;
- struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
-#if 0
- struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
- int actual_dpb_size, max_reference_size;
- int reorder_pic_num;
- unsigned int colocated_buf_size;
- unsigned int colocated_mv_addr_start;
- unsigned int colocated_mv_addr_end;
- dpb_print(DECODE_ID(hw), 0,
- "%s\n", __func__);
-
- for (i = 0; i < VF_POOL_SIZE; i++)
- hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
-
- actual_dpb_size = p_H264_Dpb->mDPB.size;
- max_reference_size = p_H264_Dpb->max_reference_size;
- reorder_pic_num = p_H264_Dpb->reorder_pic_num;
-
- colocated_buf_size = p_H264_Dpb->colocated_buf_size;
- colocated_mv_addr_start = p_H264_Dpb->colocated_mv_addr_start;
- colocated_mv_addr_end = p_H264_Dpb->colocated_mv_addr_end;
-
- hw->cur_pool++;
- if (hw->cur_pool >= VF_POOL_NUM)
- hw->cur_pool = 0;
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &(hw->vfpool[hw->cur_pool][i]);
- hw->vfpool[hw->cur_pool][i].index = -1; /* VF_BUF_NUM; */
- hw->vfpool[hw->cur_pool][i].bufWidth = 1920;
- kfifo_put(&hw->newframe_q, vf);
- }
-
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++)
- hw->buffer_spec[i].used = 0;
-
- dpb_init_global(&hw->dpb,
- DECODE_ID(hw), 0, 0);
- p_H264_Dpb->mDPB.size = actual_dpb_size;
- p_H264_Dpb->max_reference_size = max_reference_size;
- p_H264_Dpb->reorder_pic_num = reorder_pic_num;
-
- p_H264_Dpb->colocated_buf_size = colocated_buf_size;
- p_H264_Dpb->colocated_mv_addr_start = colocated_mv_addr_start;
- p_H264_Dpb->colocated_mv_addr_end = colocated_mv_addr_end;
-
- p_H264_Dpb->fast_output_enable = fast_output_enable;
- hw->has_i_frame = 0;
-#else
- mutex_lock(&reset_mutex);
- dpb_print(DECODE_ID(hw), 0,
- "%s frame count %d to skip %d\n\n",
- __func__, hw->decode_pic_count+1,
- hw->skip_frame_count);
-
- /* If the caller is from reset, then we don't call flush_dbp */
- if (flush_flag)
- flush_dpb(&hw->dpb);
-
- if (!hw->is_used_v4l) {
- timeout = jiffies + HZ;
- while (kfifo_len(&hw->display_q) > 0) {
- if (time_after(jiffies, timeout))
- break;
- schedule();
- }
- }
-
- buf_spec_init(hw, true);
-
- vh264_local_init(hw, true);
- /*hw->decode_pic_count = 0;
- hw->seq_info2 = 0;*/
-
- if (vh264_set_params(hw,
- hw->cfg_param1,
- hw->cfg_param2,
- hw->cfg_param3,
- hw->cfg_param4, hw->reset_bufmgr_flag) < 0)
- hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- else
- hw->stat &= (~DECODER_FATAL_ERROR_SIZE_OVERFLOW);
-
- /*drop 3 frames after reset bufmgr if bit0 is set 1 */
- if (first_i_policy & 0x01)
- hw->first_i_policy = (3 << 8) | first_i_policy;
-
- p_H264_Dpb->first_insert_frame = FirstInsertFrm_RESET;
-
- if (hw->stat & DECODER_FATAL_ERROR_SIZE_OVERFLOW)
- hw->init_flag = 0;
- else
- hw->init_flag = 1;
-
- hw->reset_bufmgr_count++;
- mutex_unlock(&reset_mutex);
-#endif
-}
-
-int ammvdec_h264_mmu_init(struct vdec_h264_hw_s *hw)
-{
- int ret = -1;
- int tvp_flag = vdec_secure(hw_to_vdec(hw)) ?
- CODEC_MM_FLAGS_TVP : 0;
- int buf_size = 64;
-
- pr_debug("ammvdec_h264_mmu_init tvp = 0x%x mmu_enable %d\n",
- tvp_flag, hw->mmu_enable);
- hw->need_cache_size = buf_size * SZ_1M;
- hw->sc_start_time = get_jiffies_64();
- if (hw->mmu_enable && !hw->mmu_box) {
- hw->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- hw->id,
- MMU_MAX_BUFFERS,
- hw->need_cache_size,
- tvp_flag);
- if (!hw->mmu_box) {
- pr_err("h264 4k alloc mmu box failed!!\n");
- return -1;
- }
- ret = 0;
- }
- if (!hw->bmmu_box) {
- hw->bmmu_box = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- hw->id,
- BMMU_MAX_BUFFERS,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
- if (hw->bmmu_box)
- ret = 0;
- }
- return ret;
-}
-int ammvdec_h264_mmu_release(struct vdec_h264_hw_s *hw)
-{
- if (hw->mmu_box) {
- decoder_mmu_box_free(hw->mmu_box);
- hw->mmu_box = NULL;
- }
- if (hw->bmmu_box) {
- decoder_bmmu_box_free(hw->bmmu_box);
- hw->bmmu_box = NULL;
- }
- return 0;
-}
-
-static int ammvdec_h264_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_h264_hw_s *hw = NULL;
- char *tmpbuf;
- int config_val;
-
- if (pdata == NULL) {
- pr_info("\nammvdec_h264 memory resource undefined.\n");
- return -EFAULT;
- }
-
- hw = (struct vdec_h264_hw_s *)h264_alloc_hw_stru(&pdev->dev,
- sizeof(struct vdec_h264_hw_s), GFP_KERNEL);
- if (hw == NULL) {
- pr_info("\nammvdec_h264 device data allocation failed\n");
- return -ENOMEM;
- }
- hw->id = pdev->id;
- hw->platform_dev = pdev;
-
- snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name),
- "h264-%d", hw->id);
- snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name),
- "%s-timestamp", hw->trace.vdec_name);
- snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name),
- "%s-newframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name),
- "%s-dispframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hw->trace.decode_header_time_name, sizeof(hw->trace.decode_header_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
-
- /* the ctx from v4l2 driver. */
- hw->v4l2_ctx = pdata->private;
-
- platform_set_drvdata(pdev, pdata);
-
- hw->mmu_enable = 0;
- hw->first_head_check_flag = 0;
-
- if (pdata->sys_info)
- hw->vh264_amstream_dec_info = *pdata->sys_info;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5)
- force_enable_mmu = 1;
-
- if (force_enable_mmu && pdata->sys_info &&
- (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_GXLX) &&
- (pdata->sys_info->height * pdata->sys_info->width
- > 1920 * 1088))
- hw->mmu_enable = 1;
-
- if (hw->mmu_enable &&
- (pdata->frame_base_video_path == FRAME_BASE_PATH_IONVIDEO)) {
- hw->mmu_enable = 0;
- pr_info("ionvideo needs disable mmu, path= %d \n",
- pdata->frame_base_video_path);
- }
-
- if (ammvdec_h264_mmu_init(hw)) {
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pr_info("\nammvdec_h264 mmu alloc failed!\n");
- return -ENOMEM;
- }
-
- if (pdata->config_len) {
- dpb_print(DECODE_ID(hw), 0, "pdata->config=%s\n", pdata->config);
- /*use ptr config for doubel_write_mode, etc*/
- if (get_config_int(pdata->config,
- "mh264_double_write_mode", &config_val) == 0)
- hw->double_write_mode = config_val;
- else
- hw->double_write_mode = double_write_mode;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hw->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->reorder_dpb_size_margin = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hw->canvas_mode = config_val;
- if (get_config_int(pdata->config,
- "parm_v4l_low_latency_mode",
- &config_val) == 0) {
- hw->low_latency_mode = (config_val & 1) ? 0x8:0;
- hw->enable_fence = (config_val & 2) ? 1 : 0;
- }
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hw->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hw->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_enable_fence",
- &config_val) == 0)
- hw->enable_fence = config_val;
-
- if (get_config_int(pdata->config,
- "parm_fence_usage",
- &config_val) == 0)
- hw->fence_usage = config_val;
-
- if (hw->is_used_v4l) {
- if (get_config_int(pdata->config,
- "parm_v4l_metadata_config_flag",
- &config_val) == 0) {
- hw->metadata_config_flag = config_val;
- hw->discard_dv_data = hw->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE;
- if (config_val & VDEC_CFG_FLAG_DIS_ERR_POLICY) {
- hw->error_proc_policy = v4l_error_policy; //default
- } else {
- hw->error_proc_policy = error_proc_policy;
- }
- } else {
- hw->discard_dv_data = 1; //default
- hw->error_proc_policy = error_proc_policy;
- }
- } else {
- if (get_config_int(pdata->config,
- "negative_dv",
- &config_val) == 0) {
- hw->discard_dv_data = config_val;
- } else {
- hw->discard_dv_data = 1; //default
- }
- }
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
- if (hw->discard_dv_data)
- dpb_print(DECODE_ID(hw), 0, "discard dv data\n");
- } else
- hw->double_write_mode = double_write_mode;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5)
- hw->double_write_mode = 3;
-
- if (force_config_fence) {
- hw->enable_fence = true;
- hw->fence_usage = (force_config_fence >> 4) & 0xf;
- if (force_config_fence & 0x2)
- hw->enable_fence = false;
- dpb_print(DECODE_ID(hw), 0,
- "enable fence: %d, fence usage: %d\n",
- hw->enable_fence, hw->fence_usage);
- }
-
- if (!hw->is_used_v4l) {
- hw->reorder_dpb_size_margin = reorder_dpb_size_margin;
- hw->canvas_mode = mem_map_mode;
-
- if ((h264_debug_flag & IGNORE_PARAM_FROM_CONFIG) == 0)
- hw->canvas_mode = pdata->canvas_mode;
- }
-
- if (hw->is_used_v4l && (hw->v4l2_ctx != NULL)) {
- struct aml_vcodec_ctx *ctx = hw->v4l2_ctx;
-
- ctx->aux_infos.alloc_buffer(ctx, SEI_TYPE);
-
- if (!hw->discard_dv_data)
- ctx->aux_infos.alloc_buffer(ctx, DV_TYPE);
- }
-
- if (hw->mmu_enable) {
- hw->canvas_mode = CANVAS_BLKMODE_LINEAR;
- hw->double_write_mode &= 0xffff;
- }
-
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) && hw->enable_fence) {
- hw->canvas_mode = 1;
- }
-
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- hw->buffer_spec[i].y_canvas_index = -1;
- hw->buffer_spec[i].u_canvas_index = -1;
- hw->buffer_spec[i].v_canvas_index = -1;
-#ifdef VDEC_DW
- if (IS_VDEC_DW(hw)) {
- hw->buffer_spec[i].vdec_dw_y_canvas_index = -1;
- hw->buffer_spec[i].vdec_dw_u_canvas_index = -1;
- hw->buffer_spec[i].vdec_dw_v_canvas_index = -1;
- }
-#endif
- }
- }
-
- dpb_print(DECODE_ID(hw), 0,
- "%s mmu_enable %d double_write_mode 0x%x\n",
- __func__, hw->mmu_enable, hw->double_write_mode);
-
- pdata->private = hw;
- pdata->dec_status = dec_status;
- pdata->set_trickmode = vmh264_set_trickmode;
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vh264_isr;
- pdata->threaded_irq_handler = vh264_isr_thread_fn;
- pdata->dump_state = vmh264_dump_state;
-
-#ifdef MH264_USERDATA_ENABLE
- pdata->wakeup_userdata_poll = vmh264_wakeup_userdata_poll;
- pdata->user_data_read = vmh264_user_data_read;
- pdata->reset_userdata_fifo = vmh264_reset_userdata_fifo;
-#else
- pdata->wakeup_userdata_poll = NULL;
- pdata->user_data_read = NULL;
- pdata->reset_userdata_fifo = NULL;
-#endif
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- hw->frameinfo_enable = 1;
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec_dual(pdata)) {
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
- VFM_DEC_DVEL_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
- VFM_DEC_DVBL_PROVIDER_NAME);
- }
-#endif
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- if (!hw->is_used_v4l)
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vf_provider_ops, pdata);
-
- platform_set_drvdata(pdev, pdata);
-
- buf_spec_init(hw, false);
-
- hw->platform_dev = pdev;
-
-#ifdef DUMP_USERDATA_RECORD
- vmh264_init_userdata_dump();
- vmh264_reset_user_data_buf();
-#endif
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_DPB_IDX,
- V_BUF_ADDR_OFFSET, DRIVER_NAME, &hw->cma_alloc_addr) < 0) {
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pdata->dec_status = NULL;
- return -ENOMEM;
- }
-
- hw->buf_offset = hw->cma_alloc_addr - DEF_BUF_START_ADDR +
- DCAC_READ_MARGIN;
- if (hw->mmu_enable) {
- u32 extif_size = EXTIF_BUF_SIZE;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- extif_size <<= 1;
- if (decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, BMMU_EXTIF_IDX,
- extif_size, DRIVER_NAME, &hw->extif_addr) < 0) {
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pdata->dec_status = NULL;
- return -ENOMEM;
- }
- }
- if (!vdec_secure(pdata)) {
-#if 1
- /*init internal buf*/
- tmpbuf = (char *)codec_mm_phys_to_virt(hw->cma_alloc_addr);
- if (tmpbuf) {
- memset(tmpbuf, 0, V_BUF_ADDR_OFFSET);
- codec_mm_dma_flush(tmpbuf,
- V_BUF_ADDR_OFFSET,
- DMA_TO_DEVICE);
- } else {
- tmpbuf = codec_mm_vmap(hw->cma_alloc_addr,
- V_BUF_ADDR_OFFSET);
- if (tmpbuf) {
- memset(tmpbuf, 0, V_BUF_ADDR_OFFSET);
- codec_mm_dma_flush(tmpbuf,
- V_BUF_ADDR_OFFSET,
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(tmpbuf);
- }
- }
-#else
- /*init sps/pps internal buf 64k*/
- tmpbuf = (char *)codec_mm_phys_to_virt(hw->cma_alloc_addr
- + (mem_sps_base - DEF_BUF_START_ADDR));
- memset(tmpbuf, 0, 0x10000);
- dma_sync_single_for_device(amports_get_dma_device(),
- hw->cma_alloc_addr +
- (mem_sps_base - DEF_BUF_START_ADDR),
- 0x10000, DMA_TO_DEVICE);
-#endif
- }
- /**/
-
-#if 0
- if (NULL == hw->sei_data_buffer) {
- hw->sei_data_buffer =
- dma_alloc_coherent(amports_get_dma_device(),
- USER_DATA_SIZE,
- &hw->sei_data_buffer_phys, GFP_KERNEL);
- if (!hw->sei_data_buffer) {
- pr_info("%s: Can not allocate sei_data_buffer\n",
- __func__);
- ammvdec_h264_mmu_release(hw);
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- return -ENOMEM;
- }
- /* pr_info("buffer 0x%x, phys 0x%x, remap 0x%x\n",
- sei_data_buffer, sei_data_buffer_phys,
- (u32)sei_data_buffer_remap); */
- }
-#endif
- dpb_print(DECODE_ID(hw), 0, "ammvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx\n",
- pdata->mem_start, hw->buf_offset, hw->cma_alloc_addr);
-
- vdec_source_changed(VFORMAT_H264, 3840, 2160, 60);
-
- if (hw->mmu_enable)
- hevc_source_changed(VFORMAT_HEVC, 3840, 2160, 60);
-
- if (vh264_init(hw) < 0) {
- pr_info("\nammvdec_h264 init failed.\n");
- ammvdec_h264_mmu_release(hw);
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
-#ifdef MH264_USERDATA_ENABLE
- vmh264_crate_userdata_manager(hw,
- hw->sei_user_data_buffer,
- USER_DATA_SIZE);
-#endif
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_init(pdata);
-#endif
-
- vdec_set_prepare_level(pdata, start_decode_buf_level);
- if (pdata->parallel_dec == 1) {
- if (hw->mmu_enable == 0)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
- } else
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
-
- atomic_set(&hw->vh264_active, 1);
- vdec_set_vframe_comm(pdata, DRIVER_NAME);
- display_frame_count[DECODE_ID(hw)] = 0;
- decode_frame_count[DECODE_ID(hw)] = 0;
- hw->dpb.without_display_mode = without_display_mode;
- mutex_init(&hw->fence_mutex);
- if (hw->enable_fence) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- dpb_print(DECODE_ID(hw), 0, "alloc fence timeline error\n");
- ammvdec_h264_mmu_release(hw);
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- ctx->sync = pdata->sync;
- pdata->sync->usage = hw->fence_usage;
- /* creat timeline. */
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
- vdec_timeline_get(pdata->sync);
- }
-
- return 0;
-}
-
-static void vdec_fence_release(struct vdec_h264_hw_s *hw,
- struct vdec_sync *sync)
-{
- ulong expires;
-
- /* clear display pool. */
- clear_refer_bufs(hw);
-
- /* notify signal to wake up all fences. */
- vdec_timeline_increase(sync, VF_POOL_SIZE);
-
- expires = jiffies + msecs_to_jiffies(2000);
- while (!check_objs_all_signaled(sync)) {
- if (time_after(jiffies, expires)) {
- pr_err("wait fence signaled timeout.\n");
- break;
- }
- }
-
- pr_info("fence start release\n");
-
- /* decreases refcnt of timeline. */
- vdec_timeline_put(sync);
-}
-
-static int ammvdec_h264_remove(struct platform_device *pdev)
-{
- struct vdec_h264_hw_s *hw =
- (struct vdec_h264_hw_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- int i;
-
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED
- && (vdec->status == VDEC_STATUS_ACTIVE)) {
- dpb_print(DECODE_ID(hw), 0,
- "%s force exit %d\n", __func__, __LINE__);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- wait_event_interruptible_timeout(hw->wait_q,
- (vdec->status == VDEC_STATUS_CONNECTED),
- msecs_to_jiffies(1000)); /* wait for work done */
- }
-
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++)
- release_aux_data(hw, i);
-
- atomic_set(&hw->vh264_active, 0);
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-
- vh264_stop(hw);
-#ifdef MH264_USERDATA_ENABLE
-#ifdef DUMP_USERDATA_RECORD
- vmh264_dump_userdata();
-#endif
- vmh264_destroy_userdata_manager(hw);
-#endif
- /* vdec_source_changed(VFORMAT_H264, 0, 0, 0); */
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_exit(vdec);
-#endif
-
- atomic_set(&hw->vh264_active, 0);
- if (vdec->parallel_dec == 1) {
- if (hw->mmu_enable == 0)
- vdec_core_release(vdec, CORE_MASK_VDEC_1);
- else
- vdec_core_release(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC |
- CORE_MASK_COMBINE);
- } else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
- vdec->free_canvas_ex(hw->buffer_spec[i].y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id);
- if (IS_VDEC_DW(hw)) {
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].vdec_dw_v_canvas_index, vdec->id);
- }
- }
- }
-
- if (hw->enable_fence)
- vdec_fence_release(hw, vdec->sync);
-
- ammvdec_h264_mmu_release(hw);
- h264_free_hw_stru(&pdev->dev, (void *)hw);
- clk_adj_frame_count = 0;
-
- return 0;
-}
-
-/****************************************/
-
-static struct platform_driver ammvdec_h264_driver = {
- .probe = ammvdec_h264_probe,
- .remove = ammvdec_h264_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = DRIVER_NAME,
- }
-};
-
-static struct codec_profile_t ammvdec_h264_profile = {
- .name = "H.264-V4L",
- .profile = ""
-};
-
-static struct mconfig hm264_configs[] = {
- MC_PU32("h264_debug_flag", &h264_debug_flag),
- MC_PI32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("fixed_frame_rate_mode", &fixed_frame_rate_mode),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
- MC_PU32("reorder_dpb_size_margin", &reorder_dpb_size_margin),
- MC_PU32("reference_buf_margin", &reference_buf_margin),
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("h264_debug_mask", &h264_debug_mask),
- MC_PU32("h264_debug_cmd", &h264_debug_cmd),
- MC_PI32("force_rate_streambase", &force_rate_streambase),
- MC_PI32("dec_control", &dec_control),
- MC_PI32("force_rate_framebase", &force_rate_framebase),
- MC_PI32("force_disp_bufspec_num", &force_disp_bufspec_num),
- MC_PU32("prefix_aux_buf_size", &prefix_aux_buf_size),
- MC_PU32("suffix_aux_buf_size", &suffix_aux_buf_size),
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- MC_PU32("reorder_dpb_size_margin_dv", &reorder_dpb_size_margin_dv),
- MC_PU32("dv_toggle_prov_name", &dv_toggle_prov_name),
- MC_PU32("dolby_meta_with_el", &dolby_meta_with_el),
-#endif
- MC_PU32("i_only_flag", &i_only_flag),
- MC_PU32("force_rate_streambase", &force_rate_streambase),
-};
-static struct mconfig_node hm264_node;
-
-
-static int __init ammvdec_h264_driver_init_module(void)
-{
- pr_info("ammvdec_h264 module init\n");
- if (platform_driver_register(&ammvdec_h264_driver)) {
- pr_info("failed to register ammvdec_h264 driver\n");
- return -ENODEV;
- }
-
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX) {
- ammvdec_h264_profile.profile =
- "4k, dwrite, compressed, frame_dv, fence";
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB) {
- ammvdec_h264_profile.profile = "4k, frame_dv, fence";
- }
- } else {
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) {
- ammvdec_h264_profile.profile =
- "dwrite, compressed, frame_dv, v4l";
- } else {
- ammvdec_h264_profile.profile =
- "dwrite, compressed, v4l";
- }
- }
-
- vcodec_profile_register(&ammvdec_h264_profile);
-
- INIT_REG_NODE_CONFIGS("media.decoder", &hm264_node,
- "mh264-v4l", hm264_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_H264, 1);
- return 0;
-}
-
-static void __exit ammvdec_h264_driver_remove_module(void)
-{
- pr_info("ammvdec_h264 module remove.\n");
-
- platform_driver_unregister(&ammvdec_h264_driver);
-}
-
-/****************************************/
-module_param(h264_debug_flag, uint, 0664);
-MODULE_PARM_DESC(h264_debug_flag, "\n ammvdec_h264 h264_debug_flag\n");
-
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n ammvdec_h264 start_decode_buf_level\n");
-
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level, "\n ammvdec_h264 pre_decode_buf_level\n");
-
-module_param(fixed_frame_rate_mode, uint, 0664);
-MODULE_PARM_DESC(fixed_frame_rate_mode, "\namvdec_h264 fixed_frame_rate_mode\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val, "\n amvdec_h264 decode_timeout_val\n");
-
-module_param(errordata_timeout_val, uint, 0664);
-MODULE_PARM_DESC(errordata_timeout_val, "\n amvdec_h264 errordata_timeout_val\n");
-
-module_param(get_data_timeout_val, uint, 0664);
-MODULE_PARM_DESC(get_data_timeout_val, "\n amvdec_h264 get_data_timeout_val\n");
-
-module_param(frame_max_data_packet, uint, 0664);
-MODULE_PARM_DESC(frame_max_data_packet, "\n amvdec_h264 frame_max_data_packet\n");
-
-module_param(reorder_dpb_size_margin, uint, 0664);
-MODULE_PARM_DESC(reorder_dpb_size_margin, "\n ammvdec_h264 reorder_dpb_size_margin\n");
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(reorder_dpb_size_margin_dv, uint, 0664);
-MODULE_PARM_DESC(reorder_dpb_size_margin_dv,
- "\n ammvdec_h264 reorder_dpb_size_margin_dv\n");
-#endif
-
-module_param(reference_buf_margin, uint, 0664);
-MODULE_PARM_DESC(reference_buf_margin, "\n ammvdec_h264 reference_buf_margin\n");
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-module_param(run_ready_max_vf_only_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_vf_only_num, "\n run_ready_max_vf_only_num\n");
-
-module_param(run_ready_display_q_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_display_q_num, "\n run_ready_display_q_num\n");
-
-module_param(run_ready_max_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_buf_num, "\n run_ready_max_buf_num\n");
-#endif
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(h264_debug_mask, uint, 0664);
-MODULE_PARM_DESC(h264_debug_mask, "\n amvdec_h264 h264_debug_mask\n");
-
-module_param(h264_debug_cmd, uint, 0664);
-MODULE_PARM_DESC(h264_debug_cmd, "\n amvdec_h264 h264_debug_cmd\n");
-
-module_param(force_rate_streambase, int, 0664);
-MODULE_PARM_DESC(force_rate_streambase, "\n amvdec_h264 force_rate_streambase\n");
-
-module_param(dec_control, int, 0664);
-MODULE_PARM_DESC(dec_control, "\n amvdec_h264 dec_control\n");
-
-module_param(force_rate_framebase, int, 0664);
-MODULE_PARM_DESC(force_rate_framebase, "\n amvdec_h264 force_rate_framebase\n");
-
-module_param(force_disp_bufspec_num, int, 0664);
-MODULE_PARM_DESC(force_disp_bufspec_num, "\n amvdec_h264 force_disp_bufspec_num\n");
-
-module_param(V_BUF_ADDR_OFFSET, int, 0664);
-MODULE_PARM_DESC(V_BUF_ADDR_OFFSET, "\n amvdec_h264 V_BUF_ADDR_OFFSET\n");
-
-module_param(prefix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(prefix_aux_buf_size, "\n prefix_aux_buf_size\n");
-
-module_param(suffix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(suffix_aux_buf_size, "\n suffix_aux_buf_size\n");
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(dv_toggle_prov_name, uint, 0664);
-MODULE_PARM_DESC(dv_toggle_prov_name, "\n dv_toggle_prov_name\n");
-
-module_param(dolby_meta_with_el, uint, 0664);
-MODULE_PARM_DESC(dolby_meta_with_el, "\n dolby_meta_with_el\n");
-
-#endif
-
-module_param(fast_output_enable, uint, 0664);
-MODULE_PARM_DESC(fast_output_enable, "\n amvdec_h264 fast_output_enable\n");
-
-module_param(error_proc_policy, uint, 0664);
-MODULE_PARM_DESC(error_proc_policy, "\n amvdec_h264 error_proc_policy\n");
-
-module_param(v4l_error_policy, uint, 0664);
-MODULE_PARM_DESC(v4l_error_policy, "\n amvdec_h264 v4l_error_policy\n");
-
-
-module_param(error_skip_count, uint, 0664);
-MODULE_PARM_DESC(error_skip_count, "\n amvdec_h264 error_skip_count\n");
-
-module_param(force_sliding_margin, uint, 0664);
-MODULE_PARM_DESC(force_sliding_margin, "\n amvdec_h264 force_sliding_margin\n");
-
-module_param(i_only_flag, uint, 0664);
-MODULE_PARM_DESC(i_only_flag, "\n amvdec_h264 i_only_flag\n");
-
-module_param(first_i_policy, uint, 0664);
-MODULE_PARM_DESC(first_i_policy, "\n amvdec_h264 first_i_policy\n");
-
-module_param(frmbase_cont_bitlevel, uint, 0664);
-MODULE_PARM_DESC(frmbase_cont_bitlevel,
- "\n amvdec_h264 frmbase_cont_bitlevel\n");
-
-module_param(frmbase_cont_bitlevel2, uint, 0664);
-MODULE_PARM_DESC(frmbase_cont_bitlevel2,
- "\n amvdec_h264 frmbase_cont_bitlevel\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_mh264 udebug_flag\n");
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-module_param(max_alloc_buf_count, uint, 0664);
-MODULE_PARM_DESC(max_alloc_buf_count, "\n amvdec_h264 max_alloc_buf_count\n");
-
-module_param(enable_itu_t35, uint, 0664);
-MODULE_PARM_DESC(enable_itu_t35, "\n amvdec_h264 enable_itu_t35\n");
-
-module_param(endian, uint, 0664);
-MODULE_PARM_DESC(endian, "\nrval\n");
-
-module_param(mmu_enable, uint, 0664);
-MODULE_PARM_DESC(mmu_enable, "\n mmu_enable\n");
-
-module_param(force_enable_mmu, uint, 0664);
-MODULE_PARM_DESC(force_enable_mmu, "\n force_enable_mmu\n");
-
-module_param(again_threshold, uint, 0664);
-MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-
-module_param(stream_mode_start_num, uint, 0664);
-MODULE_PARM_DESC(stream_mode_start_num, "\n stream_mode_start_num\n");
-
-module_param(colocate_old_cal, uint, 0664);
-MODULE_PARM_DESC(colocate_old_cal, "\n amvdec_mh264 colocate_old_cal\n");
-
-/*
-module_param(trigger_task, uint, 0664);
-MODULE_PARM_DESC(trigger_task, "\n amvdec_h264 trigger_task\n");
-*/
-module_param_array(decode_frame_count, uint, &max_decode_instance_num, 0664);
-
-module_param_array(display_frame_count, uint, &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint, &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(not_run_ready, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(input_empty, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_get_frame_interval, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(step, uint, &max_decode_instance_num, 0664);
-
-module_param_array(ref_frame_mark_flag, uint, &max_decode_instance_num, 0664);
-
-module_param(disp_vframe_valve_level, uint, 0664);
-MODULE_PARM_DESC(disp_vframe_valve_level, "\n disp_vframe_valve_level\n");
-
-module_param(double_write_mode, uint, 0664);
-MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
-
-module_param(mem_map_mode, uint, 0664);
-MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-
-module_param(check_slice_num, uint, 0664);
-MODULE_PARM_DESC(check_slice_num, "\n check_slice_num\n");
-
-module_param(mb_count_threshold, uint, 0664);
-MODULE_PARM_DESC(mb_count_threshold, "\n mb_count_threshold\n");
-
-module_param(loop_playback_poc_threshold, int, 0664);
-MODULE_PARM_DESC(loop_playback_poc_threshold, "\n loop_playback_poc_threshold\n");
-
-module_param(poc_threshold, int, 0664);
-MODULE_PARM_DESC(poc_threshold, "\n poc_threshold\n");
-
-module_param(force_config_fence, uint, 0664);
-MODULE_PARM_DESC(force_config_fence, "\n force enable fence\n");
-
-module_param(adjust_dpb_size, uint, 0664);
-MODULE_PARM_DESC(adjust_dpb_size, "\n adjust dpb size\n");
-
-module_init(ammvdec_h264_driver_init_module);
-module_exit(ammvdec_h264_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC H264 Video Decoder Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/frame_provider/decoder_v4l/h265/Makefile b/drivers/frame_provider/decoder_v4l/h265/Makefile
deleted file mode 100644
index 51a37f5..0000000
--- a/drivers/frame_provider/decoder_v4l/h265/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H265) += amvdec_h265_v4l.o
-amvdec_h265_v4l-objs += vh265.o
diff --git a/drivers/frame_provider/decoder_v4l/h265/vh265.c b/drivers/frame_provider/decoder_v4l/h265/vh265.c
deleted file mode 100644
index cc36fab..0000000
--- a/drivers/frame_provider/decoder_v4l/h265/vh265.c
+++ /dev/null
@@ -1,15687 +0,0 @@
-/*
- * drivers/amlogic/amports/vh265.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include "../../decoder/utils/config_parser.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include <media/v4l2-mem2mem.h>
-#include <linux/crc32.h>
-
-/*
-to enable DV of frame mode
-#define DOLBY_META_SUPPORT in ucode
-*/
-
-#define HEVC_8K_LFTOFFSET_FIX
-#define SUPPORT_LONG_TERM_RPS
-
-//#define CO_MV_COMPRESS
-
-#define CONSTRAIN_MAX_BUF_NUM
-
-#define SWAP_HEVC_UCODE
-#define DETREFILL_ENABLE
-
-#define AGAIN_HAS_THRESHOLD
-/*#define TEST_NO_BUF*/
-#define HEVC_PIC_STRUCT_SUPPORT
-#define MULTI_INSTANCE_SUPPORT
-#define USE_UNINIT_SEMA
-
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
-#define MPRED_8K_MV_BUF_SIZE (0x120000*4)
-#define MPRED_4K_MV_BUF_SIZE (0x120000)
-#define MPRED_MV_BUF_SIZE (0x3fc00)
-
-#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
-#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
-#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
-#define DB_NUM 20
-
-#define MAX_FRAME_4K_NUM 0x1200
-#define MAX_FRAME_8K_NUM ((MAX_FRAME_4K_NUM) * 4)
-
-//#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)
-#define H265_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_7
-
-#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_SAO_MMU_VH1_ADDR 0x363b
-#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-
-#define HEVC_DBLK_CFGB 0x350b
-#define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7
-#define SWAP_HEVC_OFFSET (3 * 0x1000)
-
-#define MEM_NAME "codec_265"
-/* #include <mach/am_regs.h> */
-#include <linux/amlogic/media/utils/vdec_reg.h>
-
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#include <linux/amlogic/media/video_sink/video.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define SEND_LMEM_WITH_RPM
-#define SUPPORT_10BIT
-/* #define ERROR_HANDLE_DEBUG */
-
-#ifndef STAT_KTHREAD
-#define STAT_KTHREAD 0x40
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define MAX_DECODE_INSTANCE_NUM 9
-#define MULTI_DRIVER_NAME "ammvdec_h265_v4l"
-#endif
-#define DRIVER_NAME "amvdec_h265_v4l"
-#define DRIVER_HEADER_NAME "amvdec_h265_header"
-
-#define PUT_INTERVAL (HZ/100)
-#define ERROR_SYSTEM_RESET_COUNT 200
-
-#define PTS_NORMAL 0
-#define PTS_NONE_REF_USE_DURATION 1
-
-#define PTS_MODE_SWITCHING_THRESHOLD 3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
-
-#define DUR2PTS(x) ((x)*90/96)
-
-#define MAX_SIZE_8K (8192 * 4608)
-#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
-
-#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
-#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
-
-#define SEI_UserDataITU_T_T35 4
-#define INVALID_IDX -1 /* Invalid buffer index.*/
-
-static struct semaphore h265_sema;
-
-struct hevc_state_s;
-static int hevc_print(struct hevc_state_s *hevc,
- int debug_flag, const char *fmt, ...);
-static int hevc_print_cont(struct hevc_state_s *hevc,
- int debug_flag, const char *fmt, ...);
-static int vh265_vf_states(struct vframe_states *states, void *);
-static struct vframe_s *vh265_vf_peek(void *);
-static struct vframe_s *vh265_vf_get(void *);
-static void vh265_vf_put(struct vframe_s *, void *);
-static int vh265_event_cb(int type, void *data, void *private_data);
-#ifdef MULTI_INSTANCE_SUPPORT
-static int vmh265_stop(struct hevc_state_s *hevc);
-static s32 vh265_init(struct vdec_s *vdec);
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask);
-static void reset_process_time(struct hevc_state_s *hevc);
-static void start_process_time(struct hevc_state_s *hevc);
-static void restart_process_time(struct hevc_state_s *hevc);
-static void timeout_process(struct hevc_state_s *hevc);
-#else
-static s32 vh265_init(struct hevc_state_s *hevc);
-#endif
-static void vh265_prot_init(struct hevc_state_s *hevc);
-static int vh265_local_init(struct hevc_state_s *hevc);
-static void vh265_check_timer_func(struct timer_list *timer);
-static void config_decode_mode(struct hevc_state_s *hevc);
-
-static const char vh265_dec_id[] = "vh265-dev";
-
-#define PROVIDER_NAME "decoder.h265"
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.h265"
-
-static const struct vframe_operations_s vh265_vf_provider = {
- .peek = vh265_vf_peek,
- .get = vh265_vf_get,
- .put = vh265_vf_put,
- .event_cb = vh265_event_cb,
- .vf_states = vh265_vf_states,
-};
-
-static struct vframe_provider_s vh265_vf_prov;
-
-static u32 bit_depth_luma;
-static u32 bit_depth_chroma;
-static u32 video_signal_type;
-static int start_decode_buf_level = 0x8000;
-static unsigned int decode_timeout_val = 200;
-
-static u32 run_ready_min_buf_num = 1;
-static u32 disable_ip_mode;
-static u32 print_lcu_error = 1;
-/*data_resend_policy:
- bit 0, stream base resend data when decoding buf empty
-*/
-static u32 data_resend_policy = 1;
-static int poc_num_margin = 1000;
-static int poc_error_limit = 30;
-
-static u32 dirty_time_threshold = 2000;
-static u32 dirty_count_threshold = 200;
-static u32 dirty_buffersize_threshold = 0x800000;
-
-
-#define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK 0x20000000
-/*
-static const char * const video_format_names[] = {
- "component", "PAL", "NTSC", "SECAM",
- "MAC", "unspecified", "unspecified", "unspecified"
-};
-
-static const char * const color_primaries_names[] = {
- "unknown", "bt709", "undef", "unknown",
- "bt470m", "bt470bg", "smpte170m", "smpte240m",
- "film", "bt2020"
-};
-
-static const char * const transfer_characteristics_names[] = {
- "unknown", "bt709", "undef", "unknown",
- "bt470m", "bt470bg", "smpte170m", "smpte240m",
- "linear", "log100", "log316", "iec61966-2-4",
- "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12",
- "smpte-st-2084", "smpte-st-428"
-};
-
-static const char * const matrix_coeffs_names[] = {
- "GBR", "bt709", "undef", "unknown",
- "fcc", "bt470bg", "smpte170m", "smpte240m",
- "YCgCo", "bt2020nc", "bt2020c"
-};
-*/
-#ifdef SUPPORT_10BIT
-#define HEVC_CM_BODY_START_ADDR 0x3626
-#define HEVC_CM_BODY_LENGTH 0x3627
-#define HEVC_CM_HEADER_LENGTH 0x3629
-#define HEVC_CM_HEADER_OFFSET 0x362b
-#define HEVC_SAO_CTRL9 0x362d
-#define LOSLESS_COMPRESS_MODE
-/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
-/* double_write_mode:
- * 0, no double write;
- * 1, 1:1 ratio;
- * 2, (1/4):(1/4) ratio;
- * 3, (1/4):(1/4) ratio, with both compressed frame included
- * 4, (1/2):(1/2) ratio;
- * 5, (1/2):(1/2) ratio, with both compressed frame included
- * 8, (1/8):(1/8) ratio, from t7
- * 0x10, double write only
- * 0x100, if > 1080p,use mode 4,else use mode 1;
- * 0x200, if > 1080p,use mode 2,else use mode 1;
- * 0x300, if > 720p, use mode 4, else use mode 1;
- * 0x1000,if > 1080p,use mode 3, else if > 960*540, use mode 4, else use mode 1;
- */
-static u32 double_write_mode;
-
-/*#define DECOMP_HEADR_SURGENT*/
-
-static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
-static u32 enable_mem_saving = 1;
-static u32 workaround_enable;
-static u32 force_w_h;
-#endif
-static u32 force_fps;
-static u32 pts_unstable;
-#define H265_DEBUG_BUFMGR 0x01
-#define H265_DEBUG_BUFMGR_MORE 0x02
-#define H265_DEBUG_DETAIL 0x04
-#define H265_DEBUG_REG 0x08
-#define H265_DEBUG_MAN_SEARCH_NAL 0x10
-#define H265_DEBUG_MAN_SKIP_NAL 0x20
-#define H265_DEBUG_DISPLAY_CUR_FRAME 0x40
-#define H265_DEBUG_FORCE_CLK 0x80
-#define H265_DEBUG_SEND_PARAM_WITH_REG 0x100
-#define H265_DEBUG_NO_DISPLAY 0x200
-#define H265_DEBUG_DISCARD_NAL 0x400
-#define H265_DEBUG_OUT_PTS 0x800
-#define H265_DEBUG_DUMP_PIC_LIST 0x1000
-#define H265_DEBUG_PRINT_SEI 0x2000
-#define H265_DEBUG_PIC_STRUCT 0x4000
-#define H265_DEBUG_HAS_AUX_IN_SLICE 0x8000
-#define H265_DEBUG_DIS_LOC_ERROR_PROC 0x10000
-#define H265_DEBUG_DIS_SYS_ERROR_PROC 0x20000
-#define H265_NO_CHANG_DEBUG_FLAG_IN_CODE 0x40000
-#define H265_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000
-#define H265_DEBUG_HW_RESET 0x100000
-#define H265_CFG_CANVAS_IN_DECODE 0x200000
-#define H265_DEBUG_DV 0x400000
-#define H265_DEBUG_NO_EOS_SEARCH_DONE 0x800000
-#define H265_DEBUG_NOT_USE_LAST_DISPBUF 0x1000000
-#define H265_DEBUG_IGNORE_CONFORMANCE_WINDOW 0x2000000
-#define H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x4000000
-#ifdef MULTI_INSTANCE_SUPPORT
-#define PRINT_FLAG_ERROR 0x0
-#define IGNORE_PARAM_FROM_CONFIG 0x08000000
-#define PRINT_FRAMEBASE_DATA 0x10000000
-#define PRINT_FLAG_VDEC_STATUS 0x20000000
-#define PRINT_FLAG_VDEC_DETAIL 0x40000000
-#define PRINT_FLAG_V4L_DETAIL 0x80000000
-#endif
-
-#define BUF_POOL_SIZE 32
-#define MAX_BUF_NUM 24
-#define MAX_REF_PIC_NUM 24
-#define MAX_REF_ACTIVE 16
-
-#ifdef MV_USE_FIXED_BUF
-#define BMMU_MAX_BUFFERS (BUF_POOL_SIZE + 1)
-#define VF_BUFFER_IDX(n) (n)
-#define BMMU_WORKSPACE_ID (BUF_POOL_SIZE)
-#else
-#define BMMU_MAX_BUFFERS (BUF_POOL_SIZE + 1 + MAX_REF_PIC_NUM)
-#define VF_BUFFER_IDX(n) (n)
-#define BMMU_WORKSPACE_ID (BUF_POOL_SIZE)
-#define MV_BUFFER_IDX(n) (BUF_POOL_SIZE + 1 + n)
-#endif
-
-#define HEVC_MV_INFO 0x310d
-#define HEVC_QP_INFO 0x3137
-#define HEVC_SKIP_INFO 0x3136
-
-const u32 h265_version = 201602101;
-static u32 debug_mask = 0xffffffff;
-static u32 log_mask;
-static u32 debug;
-static u32 radr;
-static u32 rval;
-static u32 dbg_cmd;
-static u32 dump_nal;
-static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
-#ifdef ERROR_HANDLE_DEBUG
-static u32 dbg_nal_skip_flag;
- /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
-static u32 dbg_nal_skip_count;
-#endif
-/*for debug*/
-static u32 force_bufspec;
-
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode detail print
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-static u32 decode_pic_begin;
-static uint slice_parse_begin;
-static u32 step;
-static bool is_reset;
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static u32 run_ready_max_vf_only_num;
-static u32 run_ready_display_q_num;
- /*0: not check
- 0xff: work_pic_num
- */
-static u32 run_ready_max_buf_num = 0xff;
-#endif
-
-static u32 dynamic_buf_num_margin = 7;
-static u32 buf_alloc_width;
-static u32 buf_alloc_height;
-
-static u32 max_buf_num = 16;
-static u32 buf_alloc_size;
-/*static u32 re_config_pic_flag;*/
-/*
- *bit[0]: 0,
- *bit[1]: 0, always release cma buffer when stop
- *bit[1]: 1, never release cma buffer when stop
- *bit[0]: 1, when stop, release cma buffer if blackout is 1;
- *do not release cma buffer is blackout is not 1
- *
- *bit[2]: 0, when start decoding, check current displayed buffer
- * (only for buffer decoded by h265) if blackout is 0
- * 1, do not check current displayed buffer
- *
- *bit[3]: 1, if blackout is not 1, do not release current
- * displayed cma buffer always.
- */
-/* set to 1 for fast play;
- * set to 8 for other case of "keep last frame"
- */
-static u32 buffer_mode = 1;
-
-/* buffer_mode_dbg: debug only*/
-static u32 buffer_mode_dbg = 0xffff0000;
-/**/
-/*
- *bit[1:0]PB_skip_mode: 0, start decoding at begin;
- *1, start decoding after first I;
- *2, only decode and display none error picture;
- *3, start decoding and display after IDR,etc
- *bit[31:16] PB_skip_count_after_decoding (decoding but not display),
- *only for mode 0 and 1.
- */
-static u32 nal_skip_policy = 2;
-
-/*
- *bit 0, 1: only display I picture;
- *bit 1, 1: only decode I picture;
- */
-static u32 i_only_flag;
-static u32 skip_nal_count = 500;
-/*
-bit 0, fast output first I picture
-*/
-static u32 fast_output_enable = 1;
-
-static u32 frmbase_cont_bitlevel = 0x60;
-
-/*
-use_cma: 1, use both reserver memory and cma for buffers
-2, only use cma for buffers
-*/
-static u32 use_cma = 2;
-
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-/*
-static u32 prefix_aux_buf_size = (16 * 1024);
-static u32 suffix_aux_buf_size;
-*/
-static u32 prefix_aux_buf_size = (12 * 1024);
-static u32 suffix_aux_buf_size = (12 * 1024);
-
-static u32 max_decoding_time;
-/*
- *error handling
- */
-/*error_handle_policy:
- *bit 0: 0, auto skip error_skip_nal_count nals before error recovery;
- *1, skip error_skip_nal_count nals before error recovery;
- *bit 1 (valid only when bit0 == 1):
- *1, wait vps/sps/pps after error recovery;
- *bit 2 (valid only when bit0 == 0):
- *0, auto search after error recovery (hevc_recover() called);
- *1, manual search after error recovery
- *(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2))
- *
- *bit 4: 0, set error_mark after reset/recover
- * 1, do not set error_mark after reset/recover
- *
- *bit 5: 0, check total lcu for every picture
- * 1, do not check total lcu
- *
- *bit 6: 0, do not check head error
- * 1, check head error
- *
- *bit 7: 0, allow to print over decode
- * 1, NOT allow to print over decode
- *
- *bit 8: 0, use interlace policy
- * 1, NOT use interlace policy
- *bit 9: 0, discard dirty data on playback start
- * 1, do not discard dirty data on playback start
- *
- */
-
-static u32 error_handle_policy;
-static u32 error_skip_nal_count = 6;
-static u32 error_handle_threshold = 30;
-static u32 error_handle_nal_skip_threshold = 10;
-static u32 error_handle_system_threshold = 30;
-static u32 interlace_enable = 1;
-static u32 fr_hint_status;
-
- /*
- *parser_sei_enable:
- * bit 0, sei;
- * bit 1, sei_suffix (fill aux buf)
- * bit 2, fill sei to aux buf (when bit 0 is 1)
- * bit 8, debug flag
- */
-static u32 parser_sei_enable;
-static u32 parser_dolby_vision_enable = 1;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static u32 dolby_meta_with_el;
-static u32 dolby_el_flush_th = 2;
-#endif
-/* this is only for h265 mmu enable */
-
-static u32 mmu_enable = 1;
-static u32 mmu_enable_force;
-static u32 work_buf_size;
-static unsigned int force_disp_pic_index;
-static unsigned int disp_vframe_valve_level;
-static int pre_decode_buf_level = 0x1000;
-static unsigned int pic_list_debug;
-#ifdef HEVC_8K_LFTOFFSET_FIX
- /* performance_profile: bit 0, multi slice in ucode
- */
-static unsigned int performance_profile = 1;
-#endif
-#ifdef MULTI_INSTANCE_SUPPORT
-static unsigned int max_decode_instance_num
- = MAX_DECODE_INSTANCE_NUM;
-static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
-static unsigned int max_get_frame_interval[MAX_DECODE_INSTANCE_NUM];
-static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
-static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
-static unsigned int ref_frame_mark_flag[MAX_DECODE_INSTANCE_NUM] =
-{1, 1, 1, 1, 1, 1, 1, 1, 1};
-
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-static unsigned char get_idx(struct hevc_state_s *hevc);
-#endif
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static u32 dv_toggle_prov_name;
-
-static u32 dv_debug;
-
-static u32 force_bypass_dvenl;
-#endif
-#endif
-
-/*
- *[3:0] 0: default use config from omx.
- * 1: force enable fence.
- * 2: disable fence.
- *[7:4] 0: fence use for driver.
- * 1: fence fd use for app.
- */
-static u32 force_config_fence;
-
-/*
- *The parameter sps_max_dec_pic_buffering_minus1_0+1
- *in SPS is the minimum DPB size required for stream
- *(note: this parameter does not include the frame
- *currently being decoded) +1 (decoding the current
- *frame) +1 (decoding the current frame will only
- *update refrence frame information, such as reference
- *relation, when the next frame is decoded)
- */
-static u32 detect_stuck_buffer_margin = 3;
-
-
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-#define get_dbg_flag(hevc) ((debug_mask & (1 << hevc->index)) ? debug : 0)
-#define get_dbg_flag2(hevc) ((debug_mask & (1 << get_idx(hevc))) ? debug : 0)
-#define is_log_enable(hevc) ((log_mask & (1 << hevc->index)) ? 1 : 0)
-#else
-#define get_dbg_flag(hevc) debug
-#define get_dbg_flag2(hevc) debug
-#define is_log_enable(hevc) (log_mask ? 1 : 0)
-#define get_valid_double_write_mode(hevc) double_write_mode
-#define get_buf_alloc_width(hevc) buf_alloc_width
-#define get_buf_alloc_height(hevc) buf_alloc_height
-#define get_dynamic_buf_num_margin(hevc) dynamic_buf_num_margin
-#endif
-#define get_buffer_mode(hevc) buffer_mode
-
-
-static DEFINE_SPINLOCK(lock);
-struct task_struct *h265_task = NULL;
-#undef DEBUG_REG
-#ifdef DEBUG_REG
-void WRITE_VREG_DBG(unsigned adr, unsigned val)
-{
- if (debug & H265_DEBUG_REG)
- pr_info("%s(%x, %x)\n", __func__, adr, val);
- WRITE_VREG(adr, val);
-}
-
-#undef WRITE_VREG
-#define WRITE_VREG WRITE_VREG_DBG
-#endif
-extern u32 trickmode_i;
-
-static DEFINE_MUTEX(vh265_mutex);
-
-static DEFINE_MUTEX(vh265_log_mutex);
-
-//static struct vdec_info *gvs;
-
-static u32 without_display_mode;
-
-static u32 mv_buf_dynamic_alloc;
-
-/**************************************************
- *
- *h265 buffer management include
- *
- ***************************************************
- */
-enum NalUnitType {
- NAL_UNIT_CODED_SLICE_TRAIL_N = 0, /* 0 */
- NAL_UNIT_CODED_SLICE_TRAIL_R, /* 1 */
-
- NAL_UNIT_CODED_SLICE_TSA_N, /* 2 */
- /* Current name in the spec: TSA_R */
- NAL_UNIT_CODED_SLICE_TLA, /* 3 */
-
- NAL_UNIT_CODED_SLICE_STSA_N, /* 4 */
- NAL_UNIT_CODED_SLICE_STSA_R, /* 5 */
-
- NAL_UNIT_CODED_SLICE_RADL_N, /* 6 */
- /* Current name in the spec: RADL_R */
- NAL_UNIT_CODED_SLICE_DLP, /* 7 */
-
- NAL_UNIT_CODED_SLICE_RASL_N, /* 8 */
- /* Current name in the spec: RASL_R */
- NAL_UNIT_CODED_SLICE_TFD, /* 9 */
-
- NAL_UNIT_RESERVED_10,
- NAL_UNIT_RESERVED_11,
- NAL_UNIT_RESERVED_12,
- NAL_UNIT_RESERVED_13,
- NAL_UNIT_RESERVED_14,
- NAL_UNIT_RESERVED_15,
-
- /* Current name in the spec: BLA_W_LP */
- NAL_UNIT_CODED_SLICE_BLA, /* 16 */
- /* Current name in the spec: BLA_W_DLP */
- NAL_UNIT_CODED_SLICE_BLANT, /* 17 */
- NAL_UNIT_CODED_SLICE_BLA_N_LP, /* 18 */
- /* Current name in the spec: IDR_W_DLP */
- NAL_UNIT_CODED_SLICE_IDR, /* 19 */
- NAL_UNIT_CODED_SLICE_IDR_N_LP, /* 20 */
- NAL_UNIT_CODED_SLICE_CRA, /* 21 */
- NAL_UNIT_RESERVED_22,
- NAL_UNIT_RESERVED_23,
-
- NAL_UNIT_RESERVED_24,
- NAL_UNIT_RESERVED_25,
- NAL_UNIT_RESERVED_26,
- NAL_UNIT_RESERVED_27,
- NAL_UNIT_RESERVED_28,
- NAL_UNIT_RESERVED_29,
- NAL_UNIT_RESERVED_30,
- NAL_UNIT_RESERVED_31,
-
- NAL_UNIT_VPS, /* 32 */
- NAL_UNIT_SPS, /* 33 */
- NAL_UNIT_PPS, /* 34 */
- NAL_UNIT_ACCESS_UNIT_DELIMITER, /* 35 */
- NAL_UNIT_EOS, /* 36 */
- NAL_UNIT_EOB, /* 37 */
- NAL_UNIT_FILLER_DATA, /* 38 */
- NAL_UNIT_SEI, /* 39 Prefix SEI */
- NAL_UNIT_SEI_SUFFIX, /* 40 Suffix SEI */
- NAL_UNIT_RESERVED_41,
- NAL_UNIT_RESERVED_42,
- NAL_UNIT_RESERVED_43,
- NAL_UNIT_RESERVED_44,
- NAL_UNIT_RESERVED_45,
- NAL_UNIT_RESERVED_46,
- NAL_UNIT_RESERVED_47,
- NAL_UNIT_UNSPECIFIED_48,
- NAL_UNIT_UNSPECIFIED_49,
- NAL_UNIT_UNSPECIFIED_50,
- NAL_UNIT_UNSPECIFIED_51,
- NAL_UNIT_UNSPECIFIED_52,
- NAL_UNIT_UNSPECIFIED_53,
- NAL_UNIT_UNSPECIFIED_54,
- NAL_UNIT_UNSPECIFIED_55,
- NAL_UNIT_UNSPECIFIED_56,
- NAL_UNIT_UNSPECIFIED_57,
- NAL_UNIT_UNSPECIFIED_58,
- NAL_UNIT_UNSPECIFIED_59,
- NAL_UNIT_UNSPECIFIED_60,
- NAL_UNIT_UNSPECIFIED_61,
- NAL_UNIT_UNSPECIFIED_62,
- NAL_UNIT_UNSPECIFIED_63,
- NAL_UNIT_INVALID,
-};
-
-/* --------------------------------------------------- */
-/* Amrisc Software Interrupt */
-/* --------------------------------------------------- */
-#define AMRISC_STREAM_EMPTY_REQ 0x01
-#define AMRISC_PARSER_REQ 0x02
-#define AMRISC_MAIN_REQ 0x04
-
-/* --------------------------------------------------- */
-/* HEVC_DEC_STATUS define */
-/* --------------------------------------------------- */
-#define HEVC_DEC_IDLE 0x0
-#define HEVC_NAL_UNIT_VPS 0x1
-#define HEVC_NAL_UNIT_SPS 0x2
-#define HEVC_NAL_UNIT_PPS 0x3
-#define HEVC_NAL_UNIT_CODED_SLICE_SEGMENT 0x4
-#define HEVC_CODED_SLICE_SEGMENT_DAT 0x5
-#define HEVC_SLICE_DECODING 0x6
-#define HEVC_NAL_UNIT_SEI 0x7
-#define HEVC_SLICE_SEGMENT_DONE 0x8
-#define HEVC_NAL_SEARCH_DONE 0x9
-#define HEVC_DECPIC_DATA_DONE 0xa
-#define HEVC_DECPIC_DATA_ERROR 0xb
-#define HEVC_SEI_DAT 0xc
-#define HEVC_SEI_DAT_DONE 0xd
-#define HEVC_NAL_DECODE_DONE 0xe
-#define HEVC_OVER_DECODE 0xf
-
-#define HEVC_DATA_REQUEST 0x12
-
-#define HEVC_DECODE_BUFEMPTY 0x20
-#define HEVC_DECODE_TIMEOUT 0x21
-#define HEVC_SEARCH_BUFEMPTY 0x22
-#define HEVC_DECODE_OVER_SIZE 0x23
-#define HEVC_DECODE_BUFEMPTY2 0x24
-#define HEVC_FIND_NEXT_PIC_NAL 0x50
-#define HEVC_FIND_NEXT_DVEL_NAL 0x51
-
-#define HEVC_DUMP_LMEM 0x30
-
-#define HEVC_4k2k_60HZ_NOT_SUPPORT 0x80
-#define HEVC_DISCARD_NAL 0xf0
-#define HEVC_ACTION_DEC_CONT 0xfd
-#define HEVC_ACTION_ERROR 0xfe
-#define HEVC_ACTION_DONE 0xff
-
-/* --------------------------------------------------- */
-/* Include "parser_cmd.h" */
-/* --------------------------------------------------- */
-#define PARSER_CMD_SKIP_CFG_0 0x0000090b
-
-#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
-
-#define PARSER_CMD_SKIP_CFG_2 0x001b1910
-
-#define PARSER_CMD_NUMBER 37
-
-/**************************************************
- *
- *h265 buffer management
- *
- ***************************************************
- */
-/* #define BUFFER_MGR_ONLY */
-/* #define CONFIG_HEVC_CLK_FORCED_ON */
-/* #define ENABLE_SWAP_TEST */
-#define MCRCC_ENABLE
-#define INVALID_POC 0x80000000
-
-#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
-#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
-#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2
-#define HEVC_VPS_BUFFER HEVC_ASSIST_SCRATCH_3
-#define HEVC_SPS_BUFFER HEVC_ASSIST_SCRATCH_4
-#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
-#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
-#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
-#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
-#define HEVC_sao_mem_unit HEVC_ASSIST_SCRATCH_9
-#define HEVC_SAO_ABV HEVC_ASSIST_SCRATCH_A
-#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B
-#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C
-#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
-#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
-#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
-#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F
-#ifdef ENABLE_SWAP_TEST
-#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
-#endif
-
-/*#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M*/
-/*#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N*/
-#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
- /*do not define ENABLE_SWAP_TEST*/
-#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L
-#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_M
-
-#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
-#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
-/*
- *ucode parser/search control
- *bit 0: 0, header auto parse; 1, header manual parse
- *bit 1: 0, auto skip for noneseamless stream; 1, no skip
- *bit [3:2]: valid when bit1==0;
- *0, auto skip nal before first vps/sps/pps/idr;
- *1, auto skip nal before first vps/sps/pps
- *2, auto skip nal before first vps/sps/pps,
- * and not decode until the first I slice (with slice address of 0)
- *
- *3, auto skip before first I slice (nal_type >=16 && nal_type<=21)
- *bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
- *bit [16]: for NAL_UNIT_EOS when bit0 is 0:
- * 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
- *bit [17]: for NAL_SEI when bit0 is 0:
- * 0, do not parse/fetch SEI in ucode;
- * 1, parse/fetch SEI in ucode
- *bit [18]: for NAL_SEI_SUFFIX when bit0 is 0:
- * 0, do not fetch NAL_SEI_SUFFIX to aux buf;
- * 1, fetch NAL_SEL_SUFFIX data to aux buf
- *bit [19]:
- * 0, parse NAL_SEI in ucode
- * 1, fetch NAL_SEI to aux buf
- *bit [20]: for DOLBY_VISION_META
- * 0, do not fetch DOLBY_VISION_META to aux buf
- * 1, fetch DOLBY_VISION_META to aux buf
- */
-#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
- /*read only*/
-#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J
- /*
- [15 : 8] rps_set_id
- [7 : 0] start_decoding_flag
- */
-#define HEVC_DECODE_INFO HEVC_ASSIST_SCRATCH_1
- /*set before start decoder*/
-#define HEVC_DECODE_MODE HEVC_ASSIST_SCRATCH_J
-#define HEVC_DECODE_MODE2 HEVC_ASSIST_SCRATCH_H
-#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
-
-#define DECODE_MODE_SINGLE 0x0
-#define DECODE_MODE_MULTI_FRAMEBASE 0x1
-#define DECODE_MODE_MULTI_STREAMBASE 0x2
-#define DECODE_MODE_MULTI_DVBAL 0x3
-#define DECODE_MODE_MULTI_DVENL 0x4
-
-#define MAX_INT 0x7FFFFFFF
-
-#define RPM_BEGIN 0x100
-#define modification_list_cur 0x148
-#define RPM_END 0x180
-#ifdef SUPPORT_LONG_TERM_RPS
-/*
- */
-#define RPS_END 0x8000
-#define RPS_LT_BIT 14
-#define RPS_USED_BIT 13
-#define RPS_SIGN_BIT 12
-
-
-#else
-#define RPS_END 0x8000
-#define RPS_USED_BIT 14
-#define RPS_SIGN_BIT 13
-#endif
-/* MISC_FLAG0 */
-#define PCM_LOOP_FILTER_DISABLED_FLAG_BIT 0
-#define PCM_ENABLE_FLAG_BIT 1
-#define LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT 2
-#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 3
-#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT 4
-#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 5
-#define DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT 6
-#define SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT 7
-#define SLICE_SAO_LUMA_FLAG_BIT 8
-#define SLICE_SAO_CHROMA_FLAG_BIT 9
-#define SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT 10
-
-union param_u {
- struct {
- unsigned short data[RPM_END - RPM_BEGIN];
- } l;
- struct {
- /* from ucode lmem, do not change this struct */
- unsigned short CUR_RPS[0x10];
- unsigned short num_ref_idx_l0_active;
- unsigned short num_ref_idx_l1_active;
- unsigned short slice_type;
- unsigned short slice_temporal_mvp_enable_flag;
- unsigned short dependent_slice_segment_flag;
- unsigned short slice_segment_address;
- unsigned short num_title_rows_minus1;
- unsigned short pic_width_in_luma_samples;
- unsigned short pic_height_in_luma_samples;
- unsigned short log2_min_coding_block_size_minus3;
- unsigned short log2_diff_max_min_coding_block_size;
- unsigned short log2_max_pic_order_cnt_lsb_minus4;
- unsigned short POClsb;
- unsigned short collocated_from_l0_flag;
- unsigned short collocated_ref_idx;
- unsigned short log2_parallel_merge_level;
- unsigned short five_minus_max_num_merge_cand;
- unsigned short sps_num_reorder_pics_0;
- unsigned short modification_flag;
- unsigned short tiles_enabled_flag;
- unsigned short num_tile_columns_minus1;
- unsigned short num_tile_rows_minus1;
- unsigned short tile_width[12];
- unsigned short tile_height[8];
- unsigned short misc_flag0;
- unsigned short pps_beta_offset_div2;
- unsigned short pps_tc_offset_div2;
- unsigned short slice_beta_offset_div2;
- unsigned short slice_tc_offset_div2;
- unsigned short pps_cb_qp_offset;
- unsigned short pps_cr_qp_offset;
- unsigned short first_slice_segment_in_pic_flag;
- unsigned short m_temporalId;
- unsigned short m_nalUnitType;
-
- unsigned short vui_num_units_in_tick_hi;
- unsigned short vui_num_units_in_tick_lo;
- unsigned short vui_time_scale_hi;
- unsigned short vui_time_scale_lo;
- unsigned short bit_depth;
- unsigned short profile_etc;
- unsigned short sei_frame_field_info;
- unsigned short video_signal_type;
- unsigned short modification_list[0x20];
- unsigned short conformance_window_flag;
- unsigned short conf_win_left_offset;
- unsigned short conf_win_right_offset;
- unsigned short conf_win_top_offset;
- unsigned short conf_win_bottom_offset;
- unsigned short chroma_format_idc;
- unsigned short color_description;
- unsigned short aspect_ratio_idc;
- unsigned short sar_width;
- unsigned short sar_height;
- unsigned short sps_max_dec_pic_buffering_minus1_0;
- } p;
-};
-
-#define RPM_BUF_SIZE (0x80*2)
-/* non mmu mode lmem size : 0x400, mmu mode : 0x500*/
-#define LMEM_BUF_SIZE (0x500 * 2)
-
-struct buff_s {
- u32 buf_start;
- u32 buf_size;
- u32 buf_end;
-};
-
-struct BuffInfo_s {
- u32 max_width;
- u32 max_height;
- unsigned int start_adr;
- unsigned int end_adr;
- struct buff_s ipp;
- struct buff_s sao_abv;
- struct buff_s sao_vb;
- struct buff_s short_term_rps;
- struct buff_s vps;
- struct buff_s sps;
- struct buff_s pps;
- struct buff_s sao_up;
- struct buff_s swap_buf;
- struct buff_s swap_buf2;
- struct buff_s scalelut;
- struct buff_s dblk_para;
- struct buff_s dblk_data;
- struct buff_s dblk_data2;
- struct buff_s mmu_vbh;
- struct buff_s cm_header;
- struct buff_s mpred_above;
-#ifdef MV_USE_FIXED_BUF
- struct buff_s mpred_mv;
-#endif
- struct buff_s rpm;
- struct buff_s lmem;
-};
-
-//#define VBH_BUF_SIZE (2 * 16 * 2304)
-//#define VBH_BUF_COUNT 4
-
- /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
-#define VBH_BUF_SIZE_1080P 0x3000
-#define VBH_BUF_SIZE_4K 0x5000
-#define VBH_BUF_SIZE_8K 0xa000
-#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
- /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
- HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
-#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
-#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
-#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
-#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
-static struct BuffInfo_s amvh265_workbuff_spec[WORK_BUF_SPEC_NUM] = {
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
-#ifdef SUPPORT_10BIT
- .buf_size = 0x40000,
-#else
- /* DBLK -> Max 256(4096/16) LCU, each para
- *512bytes(total:0x20000), data 1024bytes(total:0x40000)
- */
- .buf_size = 0x20000,
-#endif
- },
- .dblk_data = {
- .buf_size = 0x40000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000 * 2,
- }, /*dblk data for adapter*/
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2048,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU, each para
- * 512bytes(total:0x20000),
- * data 1024bytes(total:0x40000)
- */
- .buf_size = 0x20000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .dblk_data2 = {
- .buf_size = 0x80000,
- }, /*dblk data for adapter*/
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- }
- },
-
- {
- .max_width = 4096*2,
- .max_height = 2048*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0x30000*2,
- },
- .sao_vb = {
- .buf_size = 0x30000*2,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x2800*2,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x8000*2,
- },
- .dblk_para = {.buf_size = 0x40000*2, }, // dblk parameter
- .dblk_data = {.buf_size = 0x80000*2, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x80000*2, }, // dblk data for adapter
- .mmu_vbh = {
- .buf_size = 0x5000*2, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header = {
- .buf_size = MMU_COMPRESS_8K_HEADER_SIZE *
- MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000*2,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- },
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {/*checked*/
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x1e00,
- },
- .sao_abv = {
- .buf_size = 0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0, //0x30000,
- },
- .short_term_rps = {/*checked*/
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {/*checked*/
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {/*checked*/
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {/*checked*/
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0, //0x2800,
- },
- .swap_buf = {/*checked*/
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {/*checked*/
- .buf_size = 0x800,
- },
- .scalelut = {/*checked*/
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {.buf_size = 0x14500, }, // dblk parameter
- .dblk_data = {.buf_size = 0x62800, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x22800, }, // dblk data for adapter
- .mmu_vbh = {/*checked*/
- .buf_size = VBH_BUF_SIZE_1080P, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/*checked*//* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {/*checked*/
- .buf_size = 0x1e00,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/*checked*//* 1080p, 0x40000 per buffer */
- .buf_size = MPRED_MV_BUF_SIZE * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {/*checked*/
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {/*checked*/
- .buf_size = 0x500 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2048,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0, //0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0, //0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {.buf_size = 0x19100, }, // dblk parameter
- .dblk_data = {.buf_size = 0x88800, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x48800, }, // dblk data for adapter
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_4K, /*2*16*2304/4, 4K*/
- },
-#if 0
- .cm_header = {/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE_4K *
- (MAX_REF_PIC_NUM + 1),
- },
-#endif
- .mpred_above = {
- .buf_size = 0x4000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = MPRED_4K_MV_BUF_SIZE * MAX_REF_PIC_NUM,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- }
- },
-
- {
- .max_width = 4096*2,
- .max_height = 2048*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0, //0x30000*2,
- },
- .sao_vb = {
- .buf_size = 0, //0x30000*2,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0, //0x2800*2,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x8000, //0x8000*2,
- },
- .dblk_para = {.buf_size = 0x32100, }, // dblk parameter
- .dblk_data = {.buf_size = 0x110800, }, // dblk data for left/top
- .dblk_data2 = {.buf_size = 0x90800, }, // dblk data for adapter
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_8K, //2*16*2304/4, 4K
- },
-#if 0
- .cm_header = {
- .buf_size = MMU_COMPRESS_HEADER_SIZE_8K *
- MAX_REF_PIC_NUM, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x8000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- .buf_size = MPRED_8K_MV_BUF_SIZE * MAX_REF_PIC_NUM, //4k2k , 0x120000 per buffer
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x500 * 2,
- },
- }
-};
-
-static void init_buff_spec(struct hevc_state_s *hevc,
- struct BuffInfo_s *buf_spec)
-{
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
- buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
- buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
- buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
- buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
- buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
- buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
- buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
- buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
- buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
- buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
- buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
- buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
- buf_spec->dblk_data2.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
- buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-#ifdef MV_USE_FIXED_BUF
- buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
-#else
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
-#endif
- buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
- buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
-
- if (hevc && get_dbg_flag2(hevc)) {
- hevc_print(hevc, 0,
- "%s workspace (%x %x) size = %x\n", __func__,
- buf_spec->start_adr, buf_spec->end_adr,
- buf_spec->end_adr - buf_spec->start_adr);
-
- hevc_print(hevc, 0,
- "ipp.buf_start :%x\n",
- buf_spec->ipp.buf_start);
- hevc_print(hevc, 0,
- "sao_abv.buf_start :%x\n",
- buf_spec->sao_abv.buf_start);
- hevc_print(hevc, 0,
- "sao_vb.buf_start :%x\n",
- buf_spec->sao_vb.buf_start);
- hevc_print(hevc, 0,
- "short_term_rps.buf_start :%x\n",
- buf_spec->short_term_rps.buf_start);
- hevc_print(hevc, 0,
- "vps.buf_start :%x\n",
- buf_spec->vps.buf_start);
- hevc_print(hevc, 0,
- "sps.buf_start :%x\n",
- buf_spec->sps.buf_start);
- hevc_print(hevc, 0,
- "pps.buf_start :%x\n",
- buf_spec->pps.buf_start);
- hevc_print(hevc, 0,
- "sao_up.buf_start :%x\n",
- buf_spec->sao_up.buf_start);
- hevc_print(hevc, 0,
- "swap_buf.buf_start :%x\n",
- buf_spec->swap_buf.buf_start);
- hevc_print(hevc, 0,
- "swap_buf2.buf_start :%x\n",
- buf_spec->swap_buf2.buf_start);
- hevc_print(hevc, 0,
- "scalelut.buf_start :%x\n",
- buf_spec->scalelut.buf_start);
- hevc_print(hevc, 0,
- "dblk_para.buf_start :%x\n",
- buf_spec->dblk_para.buf_start);
- hevc_print(hevc, 0,
- "dblk_data.buf_start :%x\n",
- buf_spec->dblk_data.buf_start);
- hevc_print(hevc, 0,
- "dblk_data2.buf_start :%x\n",
- buf_spec->dblk_data2.buf_start);
- hevc_print(hevc, 0,
- "mpred_above.buf_start :%x\n",
- buf_spec->mpred_above.buf_start);
-#ifdef MV_USE_FIXED_BUF
- hevc_print(hevc, 0,
- "mpred_mv.buf_start :%x\n",
- buf_spec->mpred_mv.buf_start);
-#endif
- if ((get_dbg_flag2(hevc)
- &
- H265_DEBUG_SEND_PARAM_WITH_REG)
- == 0) {
- hevc_print(hevc, 0,
- "rpm.buf_start :%x\n",
- buf_spec->rpm.buf_start);
- }
- }
-
-}
-
-enum SliceType {
- B_SLICE,
- P_SLICE,
- I_SLICE
-};
-
-/*USE_BUF_BLOCK*/
-struct BUF_s {
- ulong start_adr;
- u32 size;
- u32 luma_size;
- ulong header_addr;
- u32 header_size;
- int used_flag;
- ulong v4l_ref_buf_addr;
- ulong chroma_addr;
- u32 chroma_size;
-} /*BUF_t */;
-
-/* level 6, 6.1 maximum slice number is 800; other is 200 */
-#define MAX_SLICE_NUM 800
-struct PIC_s {
- int index;
- int scatter_alloc;
- int BUF_index;
- int mv_buf_index;
- int POC;
- int decode_idx;
- int slice_type;
- int RefNum_L0;
- int RefNum_L1;
- int num_reorder_pic;
- int stream_offset;
- unsigned char referenced;
- unsigned char output_mark;
- unsigned char recon_mark;
- unsigned char output_ready;
- unsigned char error_mark;
- //dis_mark = 0:discard mark,dis_mark = 1:no discard mark
- unsigned char dis_mark;
- /**/ int slice_idx;
- int m_aiRefPOCList0[MAX_SLICE_NUM][16];
- int m_aiRefPOCList1[MAX_SLICE_NUM][16];
-#ifdef SUPPORT_LONG_TERM_RPS
- unsigned char long_term_ref;
- unsigned char m_aiRefLTflgList0[MAX_SLICE_NUM][16];
- unsigned char m_aiRefLTflgList1[MAX_SLICE_NUM][16];
-#endif
- /*buffer */
- unsigned int header_adr;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- unsigned char dv_enhance_exist;
-#endif
- char *aux_data_buf;
- int aux_data_size;
- unsigned long cma_alloc_addr;
- struct page *alloc_pages;
- unsigned int mpred_mv_wr_start_addr;
- int mv_size;
- unsigned int mc_y_adr;
- unsigned int mc_u_v_adr;
-#ifdef SUPPORT_10BIT
- /*unsigned int comp_body_size;*/
- unsigned int dw_y_adr;
- unsigned int dw_u_v_adr;
-#endif
- u32 luma_size;
- u32 chroma_size;
-
- int mc_canvas_y;
- int mc_canvas_u_v;
- int width;
- int height;
-
- int y_canvas_index;
- int uv_canvas_index;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct canvas_config_s canvas_config[2];
-#endif
-#ifdef SUPPORT_10BIT
- int mem_saving_mode;
- u32 bit_depth_luma;
- u32 bit_depth_chroma;
-#endif
-#ifdef LOSLESS_COMPRESS_MODE
- unsigned int losless_comp_body_size;
-#endif
- unsigned char pic_struct;
- int vf_ref;
-
- u32 pts;
- u64 pts64;
- u64 timestamp;
-
- u32 aspect_ratio_idc;
- u32 sar_width;
- u32 sar_height;
- u32 double_write_mode;
- u32 video_signal_type;
- unsigned short conformance_window_flag;
- unsigned short conf_win_left_offset;
- unsigned short conf_win_right_offset;
- unsigned short conf_win_top_offset;
- unsigned short conf_win_bottom_offset;
- unsigned short chroma_format_idc;
-
- /* picture qos infomation*/
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
-
- u32 hw_decode_time;
- u32 frame_size; // For frame base mode
- bool ip_mode;
- u32 hdr10p_data_size;
- char *hdr10p_data_buf;
- struct dma_fence *fence;
- bool show_frame;
- int ctx_buf_idx;
-} /*PIC_t */;
-
-#define MAX_TILE_COL_NUM 10
-#define MAX_TILE_ROW_NUM 20
-struct tile_s {
- int width;
- int height;
- int start_cu_x;
- int start_cu_y;
-
- unsigned int sao_vb_start_addr;
- unsigned int sao_abv_start_addr;
-};
-
-#define SEI_MASTER_DISPLAY_COLOR_MASK 0x00000001
-#define SEI_CONTENT_LIGHT_LEVEL_MASK 0x00000002
-#define SEI_HDR10PLUS_MASK 0x00000004
-#define SEI_HDR_CUVA_MASK 0x00000008
-
-
-#define VF_POOL_SIZE 32
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_CONFIG_PARAM 3
-#define DEC_RESULT_ERROR 4
-#define DEC_INIT_PICLIST 5
-#define DEC_UNINIT_PICLIST 6
-#define DEC_RESULT_GET_DATA 7
-#define DEC_RESULT_GET_DATA_RETRY 8
-#define DEC_RESULT_EOS 9
-#define DEC_RESULT_FORCE_EXIT 10
-#define DEC_RESULT_FREE_CANVAS 11
-
-
-static void vh265_work(struct work_struct *work);
-static void vh265_timeout_work(struct work_struct *work);
-static void vh265_notify_work(struct work_struct *work);
-
-#endif
-
-struct debug_log_s {
- struct list_head list;
- uint8_t data; /*will alloc more size*/
-};
-
-struct mh265_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
-struct hevc_state_s {
-#ifdef MULTI_INSTANCE_SUPPORT
- struct platform_device *platform_dev;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- struct vframe_chunk_s *chunk;
- int dec_result;
- u32 timeout_processing;
- struct work_struct work;
- struct work_struct timeout_work;
- struct work_struct notify_work;
- struct work_struct set_clk_work;
- /* timeout handle */
- unsigned long int start_process_time;
- unsigned int last_lcu_idx;
- unsigned int decode_timeout_count;
- unsigned int timeout_num;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- unsigned char switch_dvlayer_flag;
- unsigned char no_switch_dvlayer_count;
- unsigned char bypass_dvenl_enable;
- unsigned char bypass_dvenl;
-#endif
- unsigned char start_parser_type;
- /*start_decoding_flag:
- vps/pps/sps/idr info from ucode*/
- unsigned char start_decoding_flag;
- unsigned char rps_set_id;
- unsigned char eos;
- int pic_decoded_lcu_idx;
- u8 over_decode;
- u8 empty_flag;
-#endif
- struct vframe_s vframe_dummy;
- char *provider_name;
- int index;
- struct device *cma_dev;
- unsigned char m_ins_flag;
- unsigned char dolby_enhance_flag;
- unsigned long buf_start;
- u32 buf_size;
- u32 mv_buf_size;
-
- struct BuffInfo_s work_space_buf_store;
- struct BuffInfo_s *work_space_buf;
-
- u8 aux_data_dirty;
- u32 prefix_aux_size;
- u32 suffix_aux_size;
- void *aux_addr;
- void *rpm_addr;
- void *lmem_addr;
- dma_addr_t aux_phy_addr;
- dma_addr_t rpm_phy_addr;
- dma_addr_t lmem_phy_addr;
-
- unsigned int pic_list_init_flag;
- unsigned int use_cma_flag;
-
- unsigned short *rpm_ptr;
- unsigned short *lmem_ptr;
- unsigned short *debug_ptr;
- int debug_ptr_size;
- int pic_w;
- int pic_h;
- int lcu_x_num;
- int lcu_y_num;
- int lcu_total;
- int lcu_size;
- int lcu_size_log2;
- int lcu_x_num_pre;
- int lcu_y_num_pre;
- int first_pic_after_recover;
-
- int num_tile_col;
- int num_tile_row;
- int tile_enabled;
- int tile_x;
- int tile_y;
- int tile_y_x;
- int tile_start_lcu_x;
- int tile_start_lcu_y;
- int tile_width_lcu;
- int tile_height_lcu;
-
- int slice_type;
- unsigned int slice_addr;
- unsigned int slice_segment_addr;
-
- unsigned char interlace_flag;
- unsigned char curr_pic_struct;
- unsigned char frame_field_info_present_flag;
-
- unsigned short sps_num_reorder_pics_0;
- unsigned short misc_flag0;
- int m_temporalId;
- int m_nalUnitType;
- int TMVPFlag;
- int isNextSliceSegment;
- int LDCFlag;
- int m_pocRandomAccess;
- int plevel;
- int MaxNumMergeCand;
-
- int new_pic;
- int new_tile;
- int curr_POC;
- int iPrevPOC;
-#ifdef MULTI_INSTANCE_SUPPORT
- int decoded_poc;
- struct PIC_s *decoding_pic;
-#endif
- int iPrevTid0POC;
- int list_no;
- int RefNum_L0;
- int RefNum_L1;
- int ColFromL0Flag;
- int LongTerm_Curr;
- int LongTerm_Col;
- int Col_POC;
- int LongTerm_Ref;
-#ifdef MULTI_INSTANCE_SUPPORT
- int m_pocRandomAccess_bak;
- int curr_POC_bak;
- int iPrevPOC_bak;
- int iPrevTid0POC_bak;
- unsigned char start_parser_type_bak;
- unsigned char start_decoding_flag_bak;
- unsigned char rps_set_id_bak;
- int pic_decoded_lcu_idx_bak;
- int decode_idx_bak;
-#endif
- struct PIC_s *cur_pic;
- struct PIC_s *col_pic;
- int skip_flag;
- int decode_idx;
- int slice_idx;
- unsigned char have_vps;
- unsigned char have_sps;
- unsigned char have_pps;
- unsigned char have_valid_start_slice;
- unsigned char wait_buf;
- unsigned char error_flag;
- unsigned int error_skip_nal_count;
- long used_4k_num;
-
- unsigned char
- ignore_bufmgr_error; /* bit 0, for decoding;
- bit 1, for displaying
- bit 1 must be set if bit 0 is 1*/
- int PB_skip_mode;
- int PB_skip_count_after_decoding;
-#ifdef SUPPORT_10BIT
- int mem_saving_mode;
-#endif
-#ifdef LOSLESS_COMPRESS_MODE
- unsigned int losless_comp_body_size;
-#endif
- int pts_mode;
- int last_lookup_pts;
- int last_pts;
- u64 last_lookup_pts_us64;
- u64 last_pts_us64;
- u32 shift_byte_count_lo;
- u32 shift_byte_count_hi;
- int pts_mode_switching_count;
- int pts_mode_recovery_count;
-
- int pic_num;
-
- /**/
- union param_u param;
-
- struct tile_s m_tile[MAX_TILE_ROW_NUM][MAX_TILE_COL_NUM];
-
- struct timer_list timer;
- struct BUF_s m_BUF[BUF_POOL_SIZE];
- struct BUF_s m_mv_BUF[MAX_REF_PIC_NUM];
- struct PIC_s *m_PIC[MAX_REF_PIC_NUM];
-
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
-
- u32 stat;
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 frame_ar;
- u32 bit_depth_luma;
- u32 bit_depth_chroma;
- u32 video_signal_type;
- u32 video_signal_type_debug;
- u32 saved_resolution;
- bool get_frame_dur;
- u32 error_watchdog_count;
- u32 error_skip_nal_wt_cnt;
- u32 error_system_watchdog_count;
-
-#ifdef DEBUG_PTS
- unsigned long pts_missed;
- unsigned long pts_hit;
-#endif
- struct dec_sysinfo vh265_amstream_dec_info;
- unsigned char init_flag;
- unsigned char first_sc_checked;
- unsigned char uninit_list;
- u32 start_decoding_time;
-
- int show_frame_num;
-#ifdef USE_UNINIT_SEMA
- struct semaphore h265_uninit_done_sema;
-#endif
- int fatal_error;
-
-
- u32 sei_present_flag;
- void *frame_mmu_map_addr;
- dma_addr_t frame_mmu_map_phy_addr;
- unsigned int mmu_mc_buf_start;
- unsigned int mmu_mc_buf_end;
- unsigned int mmu_mc_start_4k_adr;
- void *mmu_box;
- void *bmmu_box;
- int mmu_enable;
-
- unsigned int dec_status;
-
- /* data for SEI_MASTER_DISPLAY_COLOR */
- unsigned int primaries[3][2];
- unsigned int white_point[2];
- unsigned int luminance[2];
- /* data for SEI_CONTENT_LIGHT_LEVEL */
- unsigned int content_light_level[2];
-
- struct PIC_s *pre_top_pic;
- struct PIC_s *pre_bot_pic;
-
-#ifdef MULTI_INSTANCE_SUPPORT
- int double_write_mode;
- int dynamic_buf_num_margin;
- int start_action;
- int save_buffer_mode;
-#endif
- u32 i_only;
- struct list_head log_list;
- u32 ucode_pause_pos;
- u32 start_shift_bytes;
-
- atomic_t vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
-#ifdef SWAP_HEVC_UCODE
- dma_addr_t mc_dma_handle;
- void *mc_cpu_addr;
- int swap_size;
- ulong swap_addr;
-#endif
-#ifdef DETREFILL_ENABLE
- dma_addr_t detbuf_adr;
- u16 *detbuf_adr_virt;
- u8 delrefill_check;
-#endif
- u8 head_error_flag;
- int valve_count;
- struct firmware_s *fw;
- int max_pic_w;
- int max_pic_h;
-#ifdef AGAIN_HAS_THRESHOLD
- u8 next_again_flag;
- u32 pre_parser_wr_ptr;
-#endif
- u32 ratio_control;
- u32 first_pic_flag;
- u32 decode_size;
- struct mutex chunks_mutex;
- int need_cache_size;
- u64 sc_start_time;
- u32 skip_nal_count;
- bool is_swap;
- bool is_4k;
-
- int frameinfo_enable;
- struct vframe_qos_s vframe_qos;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- u32 mem_map_mode;
- u32 performance_profile;
- struct vdec_info *gvs;
- bool ip_mode;
- u32 kpi_first_i_comming;
- u32 kpi_first_i_decoded;
- int sidebind_type;
- int sidebind_channel_id;
- u32 again_count;
- u64 again_timeout_jiffies;
- u32 pre_parser_video_rp;
- u32 pre_parser_video_wp;
- bool dv_duallayer;
- u32 poc_error_count;
- u32 timeout_flag;
- ulong timeout;
- bool discard_dv_data;
- bool enable_fence;
- int fence_usage;
- int buffer_wrap[MAX_REF_PIC_NUM];
- int low_latency_flag;
- u32 metadata_config_flag;
- int last_width;
- int last_height;
- int used_buf_num;
- u32 dirty_shift_flag;
- u32 endian;
- ulong fb_token;
- int send_frame_flag;
- struct vdec_v4l2_buffer *pair_fb[2];
- struct mh265_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- bool resolution_change;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- bool no_need_aux_data;
- struct trace_decoder_name trace;
-} /*hevc_stru_t */;
-
-#ifdef AGAIN_HAS_THRESHOLD
-static u32 again_threshold;
-#endif
-#ifdef SEND_LMEM_WITH_RPM
-#define get_lmem_params(hevc, ladr) \
- hevc->lmem_ptr[ladr - (ladr & 0x3) + 3 - (ladr & 0x3)]
-
-
-static int get_frame_mmu_map_size(void)
-{
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- return (MAX_FRAME_8K_NUM * 4);
-
- return (MAX_FRAME_4K_NUM * 4);
-}
-
-static int is_oversize(int w, int h)
-{
- int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
- MAX_SIZE_8K : MAX_SIZE_4K;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
- if (w < 0 || h < 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-int is_oversize_ex(int w, int h)
-{
- int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) ?
- MAX_SIZE_8K : MAX_SIZE_4K;
-
- if (w == 0 || h == 0)
- return true;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- if (w > 8192 || h > 4608)
- return true;
- } else {
- if (w > 4096 || h > 2304)
- return true;
- }
-
- if (w < 0 || h < 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-
-void check_head_error(struct hevc_state_s *hevc)
-{
-#define pcm_enabled_flag 0x040
-#define pcm_sample_bit_depth_luma 0x041
-#define pcm_sample_bit_depth_chroma 0x042
- hevc->head_error_flag = 0;
- if ((error_handle_policy & 0x40) == 0)
- return;
- if (get_lmem_params(hevc, pcm_enabled_flag)) {
- uint16_t pcm_depth_luma = get_lmem_params(
- hevc, pcm_sample_bit_depth_luma);
- uint16_t pcm_sample_chroma = get_lmem_params(
- hevc, pcm_sample_bit_depth_chroma);
- if (pcm_depth_luma >
- hevc->bit_depth_luma ||
- pcm_sample_chroma >
- hevc->bit_depth_chroma) {
- hevc_print(hevc, 0,
- "error, pcm bit depth %d, %d is greater than normal bit depth %d, %d\n",
- pcm_depth_luma,
- pcm_sample_chroma,
- hevc->bit_depth_luma,
- hevc->bit_depth_chroma);
- hevc->head_error_flag = 1;
- }
- }
-}
-#endif
-
-#ifdef SUPPORT_10BIT
-/* Losless compression body buffer size 4K per 64x32 (jt) */
-static int compute_losless_comp_body_size(struct hevc_state_s *hevc,
- int width, int height, int mem_saving_mode)
-{
- int width_x64;
- int height_x32;
- int bsize;
-
- width_x64 = width + 63;
- width_x64 >>= 6;
-
- height_x32 = height + 31;
- height_x32 >>= 5;
- if (mem_saving_mode == 1 && hevc->mmu_enable)
- bsize = 3200 * width_x64 * height_x32;
- else if (mem_saving_mode == 1)
- bsize = 3072 * width_x64 * height_x32;
- else
- bsize = 4096 * width_x64 * height_x32;
-
- return bsize;
-}
-
-/* Losless compression header buffer size 32bytes per 128x64 (jt) */
-static int compute_losless_comp_header_size(int width, int height)
-{
- int width_x128;
- int height_x64;
- int hsize;
-
- width_x128 = width + 127;
- width_x128 >>= 7;
-
- height_x64 = height + 63;
- height_x64 >>= 6;
-
- hsize = 32*width_x128*height_x64;
-
- return hsize;
-}
-#endif
-
-static int add_log(struct hevc_state_s *hevc,
- const char *fmt, ...)
-{
-#define HEVC_LOG_BUF 196
- struct debug_log_s *log_item;
- unsigned char buf[HEVC_LOG_BUF];
- int len = 0;
- va_list args;
- mutex_lock(&vh265_log_mutex);
- va_start(args, fmt);
- len = sprintf(buf, "<%ld> <%05d> ",
- jiffies, hevc->decode_idx);
- len += vsnprintf(buf + len,
- HEVC_LOG_BUF - len, fmt, args);
- va_end(args);
- log_item = kmalloc(
- sizeof(struct debug_log_s) + len,
- GFP_KERNEL);
- if (log_item) {
- INIT_LIST_HEAD(&log_item->list);
- strcpy(&log_item->data, buf);
- list_add_tail(&log_item->list,
- &hevc->log_list);
- }
- mutex_unlock(&vh265_log_mutex);
- return 0;
-}
-
-static void dump_log(struct hevc_state_s *hevc)
-{
- int i = 0;
- struct debug_log_s *log_item, *tmp;
- mutex_lock(&vh265_log_mutex);
- list_for_each_entry_safe(log_item, tmp, &hevc->log_list, list) {
- hevc_print(hevc, 0,
- "[LOG%04d]%s\n",
- i++,
- &log_item->data);
- list_del(&log_item->list);
- kfree(log_item);
- }
- mutex_unlock(&vh265_log_mutex);
-}
-
-static unsigned char is_skip_decoding(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
- if (pic->error_mark
- && ((hevc->ignore_bufmgr_error & 0x1) == 0))
- return 1;
- return 0;
-}
-
-static int get_pic_poc(struct hevc_state_s *hevc,
- unsigned int idx)
-{
- if (idx != 0xff
- && idx < MAX_REF_PIC_NUM
- && hevc->m_PIC[idx])
- return hevc->m_PIC[idx]->POC;
- return INVALID_POC;
-}
-
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-static int get_valid_double_write_mode(struct hevc_state_s *hevc)
-{
- return (hevc->m_ins_flag &&
- ((double_write_mode & 0x80000000) == 0)) ?
- hevc->double_write_mode :
- (double_write_mode & 0x7fffffff);
-}
-
-static int get_dynamic_buf_num_margin(struct hevc_state_s *hevc)
-{
- return (hevc->m_ins_flag &&
- ((dynamic_buf_num_margin & 0x80000000) == 0)) ?
- hevc->dynamic_buf_num_margin :
- (dynamic_buf_num_margin & 0x7fffffff);
-}
-#endif
-
-static int get_double_write_mode(struct hevc_state_s *hevc)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(hevc);
- int w = hevc->pic_w;
- int h = hevc->pic_h;
- u32 dw = 0x1; /*1:1*/
-
- if (hevc->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(hevc->v4l2_ctx, &out);
- dw = out;
- return dw;
- }
-
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- case 0x1000:
- if (w * h > 1920 * 1080)
- dw = 3;
- else if (w * h > 960 * 540)
- dw = 5;
- else
- dw = 1;
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-static unsigned char get_idx(struct hevc_state_s *hevc)
-{
- return hevc->index;
-}
-#endif
-
-#undef pr_info
-#define pr_info printk
-static int hevc_print(struct hevc_state_s *hevc,
- int flag, const char *fmt, ...)
-{
-#define HEVC_PRINT_BUF 512
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- if (hevc == NULL ||
- (flag == 0) ||
- ((debug_mask &
- (1 << hevc->index))
- && (debug & flag))) {
-#endif
- va_list args;
-
- va_start(args, fmt);
- if (hevc)
- len = sprintf(buf, "[%d]", hevc->index);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_debug("%s", buf);
- va_end(args);
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- }
-#endif
- return 0;
-}
-
-static int hevc_print_cont(struct hevc_state_s *hevc,
- int flag, const char *fmt, ...)
-{
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- if (hevc == NULL ||
- (flag == 0) ||
- ((debug_mask &
- (1 << hevc->index))
- && (debug & flag))) {
-#endif
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- }
-#endif
- return 0;
-}
-
-static void put_mv_buf(struct hevc_state_s *hevc,
- struct PIC_s *pic);
-
-static void update_vf_memhandle(struct hevc_state_s *hevc,
- struct vframe_s *vf, struct PIC_s *pic);
-
-static void set_canvas(struct hevc_state_s *hevc, struct PIC_s *pic);
-
-static void release_aux_data(struct hevc_state_s *hevc,
- struct PIC_s *pic);
-static void release_pic_mmu_buf(struct hevc_state_s *hevc, struct PIC_s *pic);
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static void backup_decode_state(struct hevc_state_s *hevc)
-{
- hevc->m_pocRandomAccess_bak = hevc->m_pocRandomAccess;
- hevc->curr_POC_bak = hevc->curr_POC;
- hevc->iPrevPOC_bak = hevc->iPrevPOC;
- hevc->iPrevTid0POC_bak = hevc->iPrevTid0POC;
- hevc->start_parser_type_bak = hevc->start_parser_type;
- hevc->start_decoding_flag_bak = hevc->start_decoding_flag;
- hevc->rps_set_id_bak = hevc->rps_set_id;
- hevc->pic_decoded_lcu_idx_bak = hevc->pic_decoded_lcu_idx;
- hevc->decode_idx_bak = hevc->decode_idx;
-
-}
-
-static void restore_decode_state(struct hevc_state_s *hevc)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
- if (!vdec_has_more_input(vdec)) {
- hevc->pic_decoded_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- return;
- }
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: discard pic index 0x%x\n",
- __func__, hevc->decoding_pic ?
- hevc->decoding_pic->index : 0xff);
- if (hevc->decoding_pic) {
- hevc->decoding_pic->error_mark = 0;
- hevc->decoding_pic->output_ready = 0;
- hevc->decoding_pic->show_frame = false;
- hevc->decoding_pic->output_mark = 0;
- hevc->decoding_pic->referenced = 0;
- hevc->decoding_pic->POC = INVALID_POC;
- put_mv_buf(hevc, hevc->decoding_pic);
- release_aux_data(hevc, hevc->decoding_pic);
- hevc->decoding_pic = NULL;
- }
- /*if (vdec_stream_based(vdec) &&
- (hevc->decode_idx - hevc->decode_idx_bak > 1)) {
- int i;
- hevc_print(hevc, 0, "decode_idx %d, decode_idx_bak %d\n",
- hevc->decode_idx, hevc->decode_idx_bak);
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic;
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- (pic->index == -1) ||
- (pic->BUF_index == -1) ||
- (pic->POC == INVALID_POC))
- continue;
- if ((pic->decode_idx >= hevc->decode_idx_bak) &&
- pic->decode_idx != (hevc->decode_idx - 1)) {
- hevc_print(hevc, 0, "release error buffer\n");
- pic->error_mark = 0;
- pic->output_ready = 0;
- pic->show_frame = false;
- pic->output_mark = 0;
- pic->referenced = 0;
- pic->POC = INVALID_POC;
- put_mv_buf(hevc, pic);
- release_aux_data(hevc, pic);
- }
- }
- }*/
- hevc->decode_idx = hevc->decode_idx_bak;
- hevc->m_pocRandomAccess = hevc->m_pocRandomAccess_bak;
- hevc->curr_POC = hevc->curr_POC_bak;
- hevc->iPrevPOC = hevc->iPrevPOC_bak;
- hevc->iPrevTid0POC = hevc->iPrevTid0POC_bak;
- hevc->start_parser_type = hevc->start_parser_type_bak;
- hevc->start_decoding_flag = hevc->start_decoding_flag_bak;
- hevc->rps_set_id = hevc->rps_set_id_bak;
- hevc->pic_decoded_lcu_idx = hevc->pic_decoded_lcu_idx_bak;
-
- if (hevc->pic_list_init_flag == 1)
- hevc->pic_list_init_flag = 0;
- /*if (hevc->decode_idx == 0)
- hevc->start_decoding_flag = 0;*/
-
- hevc->slice_idx = 0;
- hevc->used_4k_num = -1;
-}
-#endif
-
-static void hevc_init_stru(struct hevc_state_s *hevc,
- struct BuffInfo_s *buf_spec_i)
-{
- int i;
- INIT_LIST_HEAD(&hevc->log_list);
- hevc->work_space_buf = buf_spec_i;
- hevc->prefix_aux_size = 0;
- hevc->suffix_aux_size = 0;
- hevc->aux_addr = NULL;
- hevc->rpm_addr = NULL;
- hevc->lmem_addr = NULL;
-
- hevc->curr_POC = INVALID_POC;
-
- hevc->pic_list_init_flag = 0;
- hevc->use_cma_flag = 0;
- hevc->decode_idx = 0;
- hevc->slice_idx = 0;
- hevc->new_pic = 0;
- hevc->new_tile = 0;
- hevc->iPrevPOC = 0;
- hevc->list_no = 0;
- /* int m_uiMaxCUWidth = 1<<7; */
- /* int m_uiMaxCUHeight = 1<<7; */
- hevc->m_pocRandomAccess = MAX_INT;
- hevc->tile_enabled = 0;
- hevc->tile_x = 0;
- hevc->tile_y = 0;
- hevc->iPrevTid0POC = 0;
- hevc->slice_addr = 0;
- hevc->slice_segment_addr = 0;
- hevc->skip_flag = 0;
- hevc->misc_flag0 = 0;
-
- hevc->cur_pic = NULL;
- hevc->col_pic = NULL;
- hevc->wait_buf = 0;
- hevc->error_flag = 0;
- hevc->head_error_flag = 0;
- hevc->error_skip_nal_count = 0;
- hevc->have_vps = 0;
- hevc->have_sps = 0;
- hevc->have_pps = 0;
- hevc->have_valid_start_slice = 0;
-
- hevc->pts_mode = PTS_NORMAL;
- hevc->last_pts = 0;
- hevc->last_lookup_pts = 0;
- hevc->last_pts_us64 = 0;
- hevc->last_lookup_pts_us64 = 0;
- hevc->pts_mode_switching_count = 0;
- hevc->pts_mode_recovery_count = 0;
-
- hevc->PB_skip_mode = nal_skip_policy & 0x3;
- hevc->PB_skip_count_after_decoding = (nal_skip_policy >> 16) & 0xffff;
- if (hevc->PB_skip_mode == 0)
- hevc->ignore_bufmgr_error = 0x1;
- else
- hevc->ignore_bufmgr_error = 0x0;
-
- if (hevc->is_used_v4l) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_PIC[i] != NULL) {
- char *addr = NULL;
- int size;
- unsigned long flags;
-
- spin_lock_irqsave(&lock, flags);
- addr = hevc->m_PIC[i]->aux_data_buf;
- size = hevc->m_PIC[i]->aux_data_size;
-
- memset(hevc->m_PIC[i], 0 ,sizeof(struct PIC_s));
- hevc->m_PIC[i]->index = i;
- hevc->m_PIC[i]->aux_data_buf = addr;
- hevc->m_PIC[i]->aux_data_size = size;
- spin_unlock_irqrestore(&lock, flags);
- }
- }
- }
-
- hevc->pic_num = 0;
- hevc->lcu_x_num_pre = 0;
- hevc->lcu_y_num_pre = 0;
- hevc->first_pic_after_recover = 0;
-
- hevc->pre_top_pic = NULL;
- hevc->pre_bot_pic = NULL;
-
- hevc->sei_present_flag = 0;
- hevc->valve_count = 0;
- hevc->first_pic_flag = 0;
-#ifdef MULTI_INSTANCE_SUPPORT
- hevc->decoded_poc = INVALID_POC;
- hevc->start_process_time = 0;
- hevc->last_lcu_idx = 0;
- hevc->decode_timeout_count = 0;
- hevc->timeout_num = 0;
- hevc->eos = 0;
- hevc->pic_decoded_lcu_idx = -1;
- hevc->over_decode = 0;
- hevc->used_4k_num = -1;
- hevc->start_decoding_flag = 0;
- hevc->rps_set_id = 0;
- backup_decode_state(hevc);
-#endif
-#ifdef DETREFILL_ENABLE
- hevc->detbuf_adr = 0;
- hevc->detbuf_adr_virt = NULL;
-#endif
-}
-
-static int post_picture_early(struct vdec_s *vdec, int index);
-static int prepare_display_buf(struct vdec_s *vdec, struct PIC_s *pic);
-static int H265_alloc_mmu(struct hevc_state_s *hevc,
- struct PIC_s *new_pic, unsigned short bit_depth,
- unsigned int *mmu_index_adr);
-
-#ifdef DETREFILL_ENABLE
-#define DETREFILL_BUF_SIZE (4 * 0x4000)
-#define HEVC_SAO_DBG_MODE0 0x361e
-#define HEVC_SAO_DBG_MODE1 0x361f
-#define HEVC_SAO_CTRL10 0x362e
-#define HEVC_SAO_CTRL11 0x362f
-static int init_detrefill_buf(struct hevc_state_s *hevc)
-{
- if (hevc->detbuf_adr_virt)
- return 0;
-
- hevc->detbuf_adr_virt =
- (void *)dma_alloc_coherent(amports_get_dma_device(),
- DETREFILL_BUF_SIZE, &hevc->detbuf_adr,
- GFP_KERNEL);
-
- if (hevc->detbuf_adr_virt == NULL) {
- pr_err("%s: failed to alloc ETREFILL_BUF\n", __func__);
- return -1;
- }
- return 0;
-}
-
-static void uninit_detrefill_buf(struct hevc_state_s *hevc)
-{
- if (hevc->detbuf_adr_virt) {
- dma_free_coherent(amports_get_dma_device(),
- DETREFILL_BUF_SIZE, hevc->detbuf_adr_virt,
- hevc->detbuf_adr);
-
- hevc->detbuf_adr_virt = NULL;
- hevc->detbuf_adr = 0;
- }
-}
-
-/*
- * convert uncompressed frame buffer data from/to ddr
- */
-static void convUnc8x4blk(uint16_t* blk8x4Luma,
- uint16_t* blk8x4Cb, uint16_t* blk8x4Cr, uint16_t* cmBodyBuf, int32_t direction)
-{
- if (direction == 0) {
- blk8x4Luma[3 + 0 * 8] = ((cmBodyBuf[0] >> 0)) & 0x3ff;
- blk8x4Luma[3 + 1 * 8] = ((cmBodyBuf[1] << 6)
- | (cmBodyBuf[0] >> 10)) & 0x3ff;
- blk8x4Luma[3 + 2 * 8] = ((cmBodyBuf[1] >> 4)) & 0x3ff;
- blk8x4Luma[3 + 3 * 8] = ((cmBodyBuf[2] << 2)
- | (cmBodyBuf[1] >> 14)) & 0x3ff;
- blk8x4Luma[7 + 0 * 8] = ((cmBodyBuf[3] << 8)
- | (cmBodyBuf[2] >> 8)) & 0x3ff;
- blk8x4Luma[7 + 1 * 8] = ((cmBodyBuf[3] >> 2)) & 0x3ff;
- blk8x4Luma[7 + 2 * 8] = ((cmBodyBuf[4] << 4)
- | (cmBodyBuf[3] >> 12)) & 0x3ff;
- blk8x4Luma[7 + 3 * 8] = ((cmBodyBuf[4] >> 6)) & 0x3ff;
- blk8x4Cb [0 + 0 * 4] = ((cmBodyBuf[5] >> 0)) & 0x3ff;
- blk8x4Cr [0 + 0 * 4] = ((cmBodyBuf[6] << 6)
- | (cmBodyBuf[5] >> 10)) & 0x3ff;
- blk8x4Cb [0 + 1 * 4] = ((cmBodyBuf[6] >> 4)) & 0x3ff;
- blk8x4Cr [0 + 1 * 4] = ((cmBodyBuf[7] << 2)
- | (cmBodyBuf[6] >> 14)) & 0x3ff;
-
- blk8x4Luma[0 + 0 * 8] = ((cmBodyBuf[0 + 8] >> 0)) & 0x3ff;
- blk8x4Luma[1 + 0 * 8] = ((cmBodyBuf[1 + 8] << 6) |
- (cmBodyBuf[0 + 8] >> 10)) & 0x3ff;
- blk8x4Luma[2 + 0 * 8] = ((cmBodyBuf[1 + 8] >> 4)) & 0x3ff;
- blk8x4Luma[0 + 1 * 8] = ((cmBodyBuf[2 + 8] << 2) |
- (cmBodyBuf[1 + 8] >> 14)) & 0x3ff;
- blk8x4Luma[1 + 1 * 8] = ((cmBodyBuf[3 + 8] << 8) |
- (cmBodyBuf[2 + 8] >> 8)) & 0x3ff;
- blk8x4Luma[2 + 1 * 8] = ((cmBodyBuf[3 + 8] >> 2)) & 0x3ff;
- blk8x4Luma[0 + 2 * 8] = ((cmBodyBuf[4 + 8] << 4) |
- (cmBodyBuf[3 + 8] >> 12)) & 0x3ff;
- blk8x4Luma[1 + 2 * 8] = ((cmBodyBuf[4 + 8] >> 6)) & 0x3ff;
- blk8x4Luma[2 + 2 * 8] = ((cmBodyBuf[5 + 8] >> 0)) & 0x3ff;
- blk8x4Luma[0 + 3 * 8] = ((cmBodyBuf[6 + 8] << 6) |
- (cmBodyBuf[5 + 8] >> 10)) & 0x3ff;
- blk8x4Luma[1 + 3 * 8] = ((cmBodyBuf[6 + 8] >> 4)) & 0x3ff;
- blk8x4Luma[2 + 3 * 8] = ((cmBodyBuf[7 + 8] << 2) |
- (cmBodyBuf[6 + 8] >> 14)) & 0x3ff;
-
- blk8x4Luma[4 + 0 * 8] = ((cmBodyBuf[0 + 16] >> 0)) & 0x3ff;
- blk8x4Luma[5 + 0 * 8] = ((cmBodyBuf[1 + 16] << 6) |
- (cmBodyBuf[0 + 16] >> 10)) & 0x3ff;
- blk8x4Luma[6 + 0 * 8] = ((cmBodyBuf[1 + 16] >> 4)) & 0x3ff;
- blk8x4Luma[4 + 1 * 8] = ((cmBodyBuf[2 + 16] << 2) |
- (cmBodyBuf[1 + 16] >> 14)) & 0x3ff;
- blk8x4Luma[5 + 1 * 8] = ((cmBodyBuf[3 + 16] << 8) |
- (cmBodyBuf[2 + 16] >> 8)) & 0x3ff;
- blk8x4Luma[6 + 1 * 8] = ((cmBodyBuf[3 + 16] >> 2)) & 0x3ff;
- blk8x4Luma[4 + 2 * 8] = ((cmBodyBuf[4 + 16] << 4) |
- (cmBodyBuf[3 + 16] >> 12)) & 0x3ff;
- blk8x4Luma[5 + 2 * 8] = ((cmBodyBuf[4 + 16] >> 6)) & 0x3ff;
- blk8x4Luma[6 + 2 * 8] = ((cmBodyBuf[5 + 16] >> 0)) & 0x3ff;
- blk8x4Luma[4 + 3 * 8] = ((cmBodyBuf[6 + 16] << 6) |
- (cmBodyBuf[5 + 16] >> 10)) & 0x3ff;
- blk8x4Luma[5 + 3 * 8] = ((cmBodyBuf[6 + 16] >> 4)) & 0x3ff;
- blk8x4Luma[6 + 3 * 8] = ((cmBodyBuf[7 + 16] << 2) |
- (cmBodyBuf[6 + 16] >> 14)) & 0x3ff;
-
- blk8x4Cb[1 + 0 * 4] = ((cmBodyBuf[0 + 24] >> 0)) & 0x3ff;
- blk8x4Cr[1 + 0 * 4] = ((cmBodyBuf[1 + 24] << 6) |
- (cmBodyBuf[0 + 24] >> 10)) & 0x3ff;
- blk8x4Cb[2 + 0 * 4] = ((cmBodyBuf[1 + 24] >> 4)) & 0x3ff;
- blk8x4Cr[2 + 0 * 4] = ((cmBodyBuf[2 + 24] << 2) |
- (cmBodyBuf[1 + 24] >> 14)) & 0x3ff;
- blk8x4Cb[3 + 0 * 4] = ((cmBodyBuf[3 + 24] << 8) |
- (cmBodyBuf[2 + 24] >> 8)) & 0x3ff;
- blk8x4Cr[3 + 0 * 4] = ((cmBodyBuf[3 + 24] >> 2)) & 0x3ff;
- blk8x4Cb[1 + 1 * 4] = ((cmBodyBuf[4 + 24] << 4) |
- (cmBodyBuf[3 + 24] >> 12)) & 0x3ff;
- blk8x4Cr[1 + 1 * 4] = ((cmBodyBuf[4 + 24] >> 6)) & 0x3ff;
- blk8x4Cb[2 + 1 * 4] = ((cmBodyBuf[5 + 24] >> 0)) & 0x3ff;
- blk8x4Cr[2 + 1 * 4] = ((cmBodyBuf[6 + 24] << 6) |
- (cmBodyBuf[5 + 24] >> 10)) & 0x3ff;
- blk8x4Cb[3 + 1 * 4] = ((cmBodyBuf[6 + 24] >> 4)) & 0x3ff;
- blk8x4Cr[3 + 1 * 4] = ((cmBodyBuf[7 + 24] << 2) |
- (cmBodyBuf[6 + 24] >> 14)) & 0x3ff;
- } else {
- cmBodyBuf[0 + 8 * 0] = (blk8x4Luma[3 + 1 * 8] << 10) |
- blk8x4Luma[3 + 0 * 8];
- cmBodyBuf[1 + 8 * 0] = (blk8x4Luma[3 + 3 * 8] << 14) |
- (blk8x4Luma[3 + 2 * 8] << 4) | (blk8x4Luma[3 + 1 * 8] >> 6);
- cmBodyBuf[2 + 8 * 0] = (blk8x4Luma[7 + 0 * 8] << 8) |
- (blk8x4Luma[3 + 3 * 8] >> 2);
- cmBodyBuf[3 + 8 * 0] = (blk8x4Luma[7 + 2 * 8] << 12) |
- (blk8x4Luma[7 + 1 * 8] << 2) | (blk8x4Luma[7 + 0 * 8] >>8);
- cmBodyBuf[4 + 8 * 0] = (blk8x4Luma[7 + 3 * 8] << 6) |
- (blk8x4Luma[7 + 2 * 8] >>4);
- cmBodyBuf[5 + 8 * 0] = (blk8x4Cr[0 + 0 * 4] << 10) |
- blk8x4Cb[0 + 0 * 4];
- cmBodyBuf[6 + 8 * 0] = (blk8x4Cr[0 + 1 * 4] << 14) |
- (blk8x4Cb[0 + 1 * 4] << 4) | (blk8x4Cr[0 + 0 * 4] >> 6);
- cmBodyBuf[7 + 8 * 0] = (0<< 8) | (blk8x4Cr[0 + 1 * 4] >> 2);
-
- cmBodyBuf[0 + 8 * 1] = (blk8x4Luma[1 + 0 * 8] << 10) |
- blk8x4Luma[0 + 0 * 8];
- cmBodyBuf[1 + 8 * 1] = (blk8x4Luma[0 + 1 * 8] << 14) |
- (blk8x4Luma[2 + 0 * 8] << 4) | (blk8x4Luma[1 + 0 * 8] >> 6);
- cmBodyBuf[2 + 8 * 1] = (blk8x4Luma[1 + 1 * 8] << 8) |
- (blk8x4Luma[0 + 1 * 8] >> 2);
- cmBodyBuf[3 + 8 * 1] = (blk8x4Luma[0 + 2 * 8] << 12) |
- (blk8x4Luma[2 + 1 * 8] << 2) | (blk8x4Luma[1 + 1 * 8] >>8);
- cmBodyBuf[4 + 8 * 1] = (blk8x4Luma[1 + 2 * 8] << 6) |
- (blk8x4Luma[0 + 2 * 8] >>4);
- cmBodyBuf[5 + 8 * 1] = (blk8x4Luma[0 + 3 * 8] << 10) |
- blk8x4Luma[2 + 2 * 8];
- cmBodyBuf[6 + 8 * 1] = (blk8x4Luma[2 + 3 * 8] << 14) |
- (blk8x4Luma[1 + 3 * 8] << 4) | (blk8x4Luma[0 + 3 * 8] >> 6);
- cmBodyBuf[7 + 8 * 1] = (0<< 8) | (blk8x4Luma[2 + 3 * 8] >> 2);
-
- cmBodyBuf[0 + 8 * 2] = (blk8x4Luma[5 + 0 * 8] << 10) |
- blk8x4Luma[4 + 0 * 8];
- cmBodyBuf[1 + 8 * 2] = (blk8x4Luma[4 + 1 * 8] << 14) |
- (blk8x4Luma[6 + 0 * 8] << 4) | (blk8x4Luma[5 + 0 * 8] >> 6);
- cmBodyBuf[2 + 8 * 2] = (blk8x4Luma[5 + 1 * 8] << 8) |
- (blk8x4Luma[4 + 1 * 8] >> 2);
- cmBodyBuf[3 + 8 * 2] = (blk8x4Luma[4 + 2 * 8] << 12) |
- (blk8x4Luma[6 + 1 * 8] << 2) | (blk8x4Luma[5 + 1 * 8] >>8);
- cmBodyBuf[4 + 8 * 2] = (blk8x4Luma[5 + 2 * 8] << 6) |
- (blk8x4Luma[4 + 2 * 8] >>4);
- cmBodyBuf[5 + 8 * 2] = (blk8x4Luma[4 + 3 * 8] << 10) |
- blk8x4Luma[6 + 2 * 8];
- cmBodyBuf[6 + 8 * 2] = (blk8x4Luma[6 + 3 * 8] << 14) |
- (blk8x4Luma[5 + 3 * 8] << 4) | (blk8x4Luma[4 + 3 * 8] >> 6);
- cmBodyBuf[7 + 8 * 2] = (0<< 8) | (blk8x4Luma[6 + 3 * 8] >> 2);
-
- cmBodyBuf[0 + 8 * 3] = (blk8x4Cr[1 + 0 * 4] << 10) |
- blk8x4Cb[1 + 0 * 4];
- cmBodyBuf[1 + 8 * 3] = (blk8x4Cr[2 + 0 * 4] << 14) |
- (blk8x4Cb[2 + 0 * 4] << 4) | (blk8x4Cr[1 + 0 * 4] >> 6);
- cmBodyBuf[2 + 8 * 3] = (blk8x4Cb[3 + 0 * 4] << 8) |
- (blk8x4Cr[2 + 0 * 4] >> 2);
- cmBodyBuf[3 + 8 * 3] = (blk8x4Cb[1 + 1 * 4] << 12) |
- (blk8x4Cr[3 + 0 * 4] << 2) | (blk8x4Cb[3 + 0 * 4] >>8);
- cmBodyBuf[4 + 8 * 3] = (blk8x4Cr[1 + 1 * 4] << 6) |
- (blk8x4Cb[1 + 1 * 4] >>4);
- cmBodyBuf[5 + 8 * 3] = (blk8x4Cr[2 + 1 * 4] << 10) |
- blk8x4Cb[2 + 1 * 4];
- cmBodyBuf[6 + 8 * 3] = (blk8x4Cr[3 + 1 * 4] << 14) |
- (blk8x4Cb[3 + 1 * 4] << 4) | (blk8x4Cr[2 + 1 * 4] >> 6);
- cmBodyBuf[7 + 8 * 3] = (0 << 8) | (blk8x4Cr[3 + 1 * 4] >> 2);
- }
-}
-
-static void corrRefillWithAmrisc (
- struct hevc_state_s *hevc,
- uint32_t cmHeaderBaseAddr,
- uint32_t picWidth,
- uint32_t ctuPosition)
-{
- int32_t i;
- uint16_t ctux = (ctuPosition>>16) & 0xffff;
- uint16_t ctuy = (ctuPosition>> 0) & 0xffff;
- int32_t aboveCtuAvailable = (ctuy) ? 1 : 0;
-
- uint16_t *cmBodyBuf = NULL;
-
- uint32_t pic_width_x64_pre = picWidth + 0x3f;
- uint32_t pic_width_x64 = pic_width_x64_pre >> 6;
- uint32_t stride64x64 = pic_width_x64 * 128;
- uint32_t addr_offset64x64_abv = stride64x64 *
- (aboveCtuAvailable ? ctuy - 1 : ctuy) + 128 * ctux;
- uint32_t addr_offset64x64_cur = stride64x64*ctuy + 128 * ctux;
- uint32_t cmHeaderAddrAbv = cmHeaderBaseAddr + addr_offset64x64_abv;
- uint32_t cmHeaderAddrCur = cmHeaderBaseAddr + addr_offset64x64_cur;
- unsigned int tmpData32;
-
- uint16_t blkBuf0Y[32];
- uint16_t blkBuf0Cb[8];
- uint16_t blkBuf0Cr[8];
- uint16_t blkBuf1Y[32];
- uint16_t blkBuf1Cb[8];
- uint16_t blkBuf1Cr[8];
- int32_t blkBufCnt = 0;
-
- int32_t blkIdx;
- PR_INIT(128);
-
- cmBodyBuf = vzalloc(sizeof(uint16_t) * 32 * 18);
- if (!cmBodyBuf)
- return;
-
- WRITE_VREG(HEVC_SAO_CTRL10, cmHeaderAddrAbv);
- WRITE_VREG(HEVC_SAO_CTRL11, cmHeaderAddrCur);
- WRITE_VREG(HEVC_SAO_DBG_MODE0, hevc->detbuf_adr);
- WRITE_VREG(HEVC_SAO_DBG_MODE1, 2);
-
- for (i = 0; i < 32 * 18; i++)
- cmBodyBuf[i] = 0;
-
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s, %d\n", __func__, __LINE__);
- do {
- tmpData32 = READ_VREG(HEVC_SAO_DBG_MODE1);
- } while (tmpData32);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s, %d\n", __func__, __LINE__);
-
- hevc_print(hevc, H265_DEBUG_DETAIL,
- "cmBodyBuf from detbuf:\n");
- for (i = 0; i < 32 * 18; i++) {
- cmBodyBuf[i] = hevc->detbuf_adr_virt[i];
- if (get_dbg_flag(hevc) &
- H265_DEBUG_DETAIL) {
- if ((i & 0xf) == 0)
- PR_INFO(hevc->index);
- PR_FILL("%02x ", cmBodyBuf[i]);
- }
- }
- PR_INFO(hevc->index);
-
- for (i = 0; i < 32; i++)
- blkBuf0Y[i] = 0;
- for (i = 0; i < 8; i++)
- blkBuf0Cb[i] = 0;
- for (i = 0; i < 8; i++)
- blkBuf0Cr[i] = 0;
- for (i = 0; i < 32; i++)
- blkBuf1Y[i] = 0;
- for (i = 0; i < 8; i++)
- blkBuf1Cb[i] = 0;
- for (i = 0; i < 8; i++)
- blkBuf1Cr[i] = 0;
-
- for (blkIdx = 0; blkIdx < 18; blkIdx++) {
- int32_t inAboveCtu = (blkIdx<2) ? 1 : 0;
- int32_t restoreEnable = (blkIdx>0) ? 1 : 0;
- uint16_t* blkY = (blkBufCnt==0) ? blkBuf0Y : blkBuf1Y ;
- uint16_t* blkCb = (blkBufCnt==0) ? blkBuf0Cb : blkBuf1Cb;
- uint16_t* blkCr = (blkBufCnt==0) ? blkBuf0Cr : blkBuf1Cr;
- uint16_t* cmBodyBufNow = cmBodyBuf + (blkIdx * 32);
-
- if (!aboveCtuAvailable && inAboveCtu)
- continue;
-
- /* detRefillBuf --> 8x4block*/
- convUnc8x4blk(blkY, blkCb, blkCr, cmBodyBufNow, 0);
-
- if (restoreEnable) {
- blkY[3 + 0 * 8] = blkY[2 + 0 * 8] + 2;
- blkY[4 + 0 * 8] = blkY[1 + 0 * 8] + 3;
- blkY[5 + 0 * 8] = blkY[0 + 0 * 8] + 1;
- blkY[6 + 0 * 8] = blkY[0 + 0 * 8] + 2;
- blkY[7 + 0 * 8] = blkY[1 + 0 * 8] + 2;
- blkY[3 + 1 * 8] = blkY[2 + 1 * 8] + 1;
- blkY[4 + 1 * 8] = blkY[1 + 1 * 8] + 2;
- blkY[5 + 1 * 8] = blkY[0 + 1 * 8] + 2;
- blkY[6 + 1 * 8] = blkY[0 + 1 * 8] + 2;
- blkY[7 + 1 * 8] = blkY[1 + 1 * 8] + 3;
- blkY[3 + 2 * 8] = blkY[2 + 2 * 8] + 3;
- blkY[4 + 2 * 8] = blkY[1 + 2 * 8] + 1;
- blkY[5 + 2 * 8] = blkY[0 + 2 * 8] + 3;
- blkY[6 + 2 * 8] = blkY[0 + 2 * 8] + 3;
- blkY[7 + 2 * 8] = blkY[1 + 2 * 8] + 3;
- blkY[3 + 3 * 8] = blkY[2 + 3 * 8] + 0;
- blkY[4 + 3 * 8] = blkY[1 + 3 * 8] + 0;
- blkY[5 + 3 * 8] = blkY[0 + 3 * 8] + 1;
- blkY[6 + 3 * 8] = blkY[0 + 3 * 8] + 2;
- blkY[7 + 3 * 8] = blkY[1 + 3 * 8] + 1;
- blkCb[1 + 0 * 4] = blkCb[0 + 0 * 4];
- blkCb[2 + 0 * 4] = blkCb[0 + 0 * 4];
- blkCb[3 + 0 * 4] = blkCb[0 + 0 * 4];
- blkCb[1 + 1 * 4] = blkCb[0 + 1 * 4];
- blkCb[2 + 1 * 4] = blkCb[0 + 1 * 4];
- blkCb[3 + 1 * 4] = blkCb[0 + 1 * 4];
- blkCr[1 + 0 * 4] = blkCr[0 + 0 * 4];
- blkCr[2 + 0 * 4] = blkCr[0 + 0 * 4];
- blkCr[3 + 0 * 4] = blkCr[0 + 0 * 4];
- blkCr[1 + 1 * 4] = blkCr[0 + 1 * 4];
- blkCr[2 + 1 * 4] = blkCr[0 + 1 * 4];
- blkCr[3 + 1 * 4] = blkCr[0 + 1 * 4];
-
- /*Store data back to DDR*/
- convUnc8x4blk(blkY, blkCb, blkCr, cmBodyBufNow, 1);
- }
-
- blkBufCnt = (blkBufCnt==1) ? 0 : blkBufCnt + 1;
- }
-
- hevc_print(hevc, H265_DEBUG_DETAIL,
- "cmBodyBuf to detbuf:\n");
- for (i = 0; i < 32 * 18; i++) {
- hevc->detbuf_adr_virt[i] = cmBodyBuf[i];
- if (get_dbg_flag(hevc) &
- H265_DEBUG_DETAIL) {
- if ((i & 0xf) == 0)
- PR_INFO(hevc->index);
- PR_FILL("%02x ", cmBodyBuf[i]);
- }
- }
-
- PR_INFO(hevc->index);
-
- WRITE_VREG(HEVC_SAO_DBG_MODE1, 3);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s, %d\n", __func__, __LINE__);
- do {
- tmpData32 = READ_VREG(HEVC_SAO_DBG_MODE1);
- } while (tmpData32);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s, %d\n", __func__, __LINE__);
- vfree(cmBodyBuf);
-}
-
-static void delrefill(struct hevc_state_s *hevc)
-{
- /*
- * corrRefill
- */
- /*HEVC_SAO_DBG_MODE0: picGlobalVariable
- [31:30]error number
- [29:20]error2([9:7]tilex[6:0]ctuy)
- [19:10]error1 [9:0]error0*/
- uint32_t detResult = READ_VREG(HEVC_ASSIST_SCRATCH_3);
- uint32_t errorIdx;
- uint32_t errorNum = (detResult>>30);
-
- if (detResult) {
- hevc_print(hevc, H265_DEBUG_BUFMGR,
- "[corrRefillWithAmrisc] detResult=%08x\n", detResult);
- for (errorIdx = 0; errorIdx < errorNum; errorIdx++) {
- uint32_t errorPos = errorIdx * 10;
- uint32_t errorResult = (detResult >> errorPos) & 0x3ff;
- uint32_t tilex = (errorResult >> 7) - 1;
- uint16_t ctux = hevc->m_tile[0][tilex].start_cu_x
- + hevc->m_tile[0][tilex].width - 1;
- uint16_t ctuy = (uint16_t)(errorResult & 0x7f);
- uint32_t ctuPosition = (ctux<< 16) + ctuy;
- hevc_print(hevc, H265_DEBUG_BUFMGR,
- "Idx:%d tilex:%d ctu(%d(0x%x), %d(0x%x))\n",
- errorIdx,tilex,ctux,ctux, ctuy,ctuy);
- corrRefillWithAmrisc(
- hevc,
- (uint32_t)hevc->cur_pic->header_adr,
- hevc->pic_w,
- ctuPosition);
- }
-
- WRITE_VREG(HEVC_ASSIST_SCRATCH_3, 0); /*clear status*/
- WRITE_VREG(HEVC_SAO_DBG_MODE0, 0);
- WRITE_VREG(HEVC_SAO_DBG_MODE1, 1);
- }
-}
-#endif
-
-static void get_rpm_param(union param_u *params)
-{
- int i;
- unsigned int data32;
-
- for (i = 0; i < 128; i++) {
- do {
- data32 = READ_VREG(RPM_CMD_REG);
- /* hevc_print(hevc, 0, "%x\n", data32); */
- } while ((data32 & 0x10000) == 0);
- params->l.data[i] = data32 & 0xffff;
- /* hevc_print(hevc, 0, "%x\n", data32); */
- WRITE_VREG(RPM_CMD_REG, 0);
- }
-}
-
-static struct PIC_s *get_pic_by_POC(struct hevc_state_s *hevc, int POC)
-{
- int i;
- struct PIC_s *pic;
- struct PIC_s *ret_pic = NULL;
- if (POC == INVALID_POC)
- return NULL;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1 ||
- pic->BUF_index == -1)
- continue;
- if (pic->POC == POC) {
- if (ret_pic == NULL)
- ret_pic = pic;
- else {
- if (pic->decode_idx > ret_pic->decode_idx)
- ret_pic = pic;
- }
- }
- }
- return ret_pic;
-}
-
-static struct PIC_s *get_ref_pic_by_POC(struct hevc_state_s *hevc, int POC)
-{
- int i;
- struct PIC_s *pic;
- struct PIC_s *ret_pic = NULL;
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1 ||
- pic->BUF_index == -1)
- continue;
- /*Add width and height of ref picture detection,
- resolved incorrectly referenced frame.*/
- if ((pic->POC == POC) && (pic->referenced) &&
- (hevc->pic_w == pic->width) &&
- (hevc->pic_h == pic->height)) {
- if (ret_pic == NULL)
- ret_pic = pic;
- else {
- if (pic->decode_idx > ret_pic->decode_idx)
- ret_pic = pic;
- }
- }
- }
-
- return ret_pic;
-}
-
-static unsigned int log2i(unsigned int val)
-{
- unsigned int ret = -1;
-
- while (val != 0) {
- val >>= 1;
- ret++;
- }
- return ret;
-}
-
-static int init_buf_spec(struct hevc_state_s *hevc);
-
-
-static void uninit_mmu_buffers(struct hevc_state_s *hevc)
-{
- if (hevc->mmu_box) {
- decoder_mmu_box_free(hevc->mmu_box);
- hevc->mmu_box = NULL;
- }
-
- if (hevc->bmmu_box) {
- /* release workspace */
- decoder_bmmu_box_free_idx(hevc->bmmu_box,
- BMMU_WORKSPACE_ID);
- decoder_bmmu_box_free(hevc->bmmu_box);
- hevc->bmmu_box = NULL;
- }
-}
-
-/* return in MB */
-static int hevc_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 64;
-
- if ((max_w * max_h) > 0 &&
- (max_w * max_h) <= 1920*1088) {
- buf_size = 24;
- }
- return buf_size;
-}
-
-static int init_mmu_buffers(struct hevc_state_s *hevc, bool bmmu_flag)
-{
- int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ?
- CODEC_MM_FLAGS_TVP : 0;
- int buf_size = hevc_max_mmu_buf_size(hevc->max_pic_w,
- hevc->max_pic_h);
-
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0, "%s max_w %d max_h %d\n",
- __func__, hevc->max_pic_w, hevc->max_pic_h);
- }
-
- hevc->need_cache_size = buf_size * SZ_1M;
- hevc->sc_start_time = get_jiffies_64();
- if (hevc->mmu_enable && !hevc->is_used_v4l) {
- hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- hevc->index,
- MAX_REF_PIC_NUM,
- buf_size * SZ_1M,
- tvp_flag
- );
- if (!hevc->mmu_box) {
- pr_err("h265 alloc mmu box failed!!\n");
- return -1;
- }
- }
-
- if (!bmmu_flag)
- return 0;
-
- hevc->bmmu_box = decoder_bmmu_box_alloc_box(DRIVER_NAME,
- hevc->index,
- BMMU_MAX_BUFFERS,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
- if (!hevc->bmmu_box) {
- if (hevc->mmu_box)
- decoder_mmu_box_free(hevc->mmu_box);
- hevc->mmu_box = NULL;
- pr_err("h265 alloc mmu box failed!!\n");
- return -1;
- }
- return 0;
-}
-
-struct buf_stru_s
-{
- int lcu_total;
- int mc_buffer_size_h;
- int mc_buffer_size_u_v_h;
-};
-
-#ifndef MV_USE_FIXED_BUF
-static void dealloc_mv_bufs(struct hevc_state_s *hevc)
-{
- int i;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_mv_BUF[i].start_adr) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "dealloc mv buf(%d) adr 0x%p size 0x%x used_flag %d\n",
- i, hevc->m_mv_BUF[i].start_adr,
- hevc->m_mv_BUF[i].size,
- hevc->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- hevc->bmmu_box,
- MV_BUFFER_IDX(i));
- hevc->m_mv_BUF[i].start_adr = 0;
- hevc->m_mv_BUF[i].size = 0;
- hevc->m_mv_BUF[i].used_flag = 0;
- }
- }
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_PIC[i] != NULL)
- hevc->m_PIC[i]->mv_buf_index = -1;
- }
-}
-
-static int alloc_mv_buf(struct hevc_state_s *hevc, int i)
-{
- int ret = 0;
- /*get_cma_alloc_ref();*/ /*DEBUG_TMP*/
- if (decoder_bmmu_box_alloc_buf_phy
- (hevc->bmmu_box,
- MV_BUFFER_IDX(i), hevc->mv_buf_size,
- DRIVER_NAME,
- &hevc->m_mv_BUF[i].start_adr) < 0) {
- hevc->m_mv_BUF[i].start_adr = 0;
- ret = -1;
- } else {
- hevc->m_mv_BUF[i].size = hevc->mv_buf_size;
- hevc->m_mv_BUF[i].used_flag = 0;
- ret = 0;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "MV Buffer %d: start_adr %p size %x\n",
- i,
- (void *)hevc->m_mv_BUF[i].start_adr,
- hevc->m_mv_BUF[i].size);
- }
- if (!vdec_secure(hw_to_vdec(hevc)) && (hevc->m_mv_BUF[i].start_adr)) {
- void *mem_start_virt;
- mem_start_virt =
- codec_mm_phys_to_virt(hevc->m_mv_BUF[i].start_adr);
- if (mem_start_virt) {
- memset(mem_start_virt, 0, hevc->m_mv_BUF[i].size);
- codec_mm_dma_flush(mem_start_virt,
- hevc->m_mv_BUF[i].size, DMA_TO_DEVICE);
- } else {
- mem_start_virt = codec_mm_vmap(
- hevc->m_mv_BUF[i].start_adr,
- hevc->m_mv_BUF[i].size);
- if (mem_start_virt) {
- memset(mem_start_virt, 0, hevc->m_mv_BUF[i].size);
- codec_mm_dma_flush(mem_start_virt,
- hevc->m_mv_BUF[i].size,
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(mem_start_virt);
- } else {
- /*not virt for tvp playing,
- may need clear on ucode.*/
- pr_err("ref %s mem_start_virt failed\n", __func__);
- }
- }
- }
- }
- /*put_cma_alloc_ref();*/ /*DEBUG_TMP*/
- return ret;
-}
-#endif
-
-static int get_mv_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
-#ifdef MV_USE_FIXED_BUF
- if (pic && pic->index >= 0) {
- int mv_size;
- if (IS_8K_SIZE(pic->width, pic->height))
- mv_size = MPRED_8K_MV_BUF_SIZE;
- else if (IS_4K_SIZE(pic->width, pic->height))
- mv_size = MPRED_4K_MV_BUF_SIZE; /*0x120000*/
- else
- mv_size = MPRED_MV_BUF_SIZE;
-
- pic->mpred_mv_wr_start_addr =
- hevc->work_space_buf->mpred_mv.buf_start
- + (pic->index * mv_size);
- pic->mv_size = mv_size;
- }
- return 0;
-#else
- int i;
- int ret = -1;
- int new_size;
- if (mv_buf_dynamic_alloc) {
- int MV_MEM_UNIT =
- hevc->lcu_size_log2 == 6 ? 0x200 : hevc->lcu_size_log2 ==
- 5 ? 0x80 : 0x20;
- int extended_pic_width = (pic->width + hevc->lcu_size -1)
- & (~(hevc->lcu_size - 1));
- int extended_pic_height = (pic->height + hevc->lcu_size -1)
- & (~(hevc->lcu_size - 1));
- int lcu_x_num = extended_pic_width / hevc->lcu_size;
- int lcu_y_num = extended_pic_height / hevc->lcu_size;
- new_size = lcu_x_num * lcu_y_num * MV_MEM_UNIT;
- hevc->mv_buf_size = (new_size + 0xffff) & (~0xffff);
- } else {
- if (IS_8K_SIZE(pic->width, pic->height))
- new_size = MPRED_8K_MV_BUF_SIZE;
- else if (IS_4K_SIZE(pic->width, pic->height))
- new_size = MPRED_4K_MV_BUF_SIZE; /*0x120000*/
- else
- new_size = MPRED_MV_BUF_SIZE;
-
- if (new_size != hevc->mv_buf_size) {
- dealloc_mv_bufs(hevc);
- hevc->mv_buf_size = new_size;
- }
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_mv_BUF[i].start_adr &&
- hevc->m_mv_BUF[i].used_flag == 0) {
- hevc->m_mv_BUF[i].used_flag = 1;
- ret = i;
- break;
- }
- }
- }
- if (ret < 0) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_mv_BUF[i].start_adr == 0) {
- if (alloc_mv_buf(hevc, i) >= 0) {
- hevc->m_mv_BUF[i].used_flag = 1;
- ret = i;
- }
- break;
- }
- }
- }
-
- if (ret >= 0) {
- pic->mv_buf_index = ret;
- pic->mv_size = hevc->m_mv_BUF[ret].size;
- pic->mpred_mv_wr_start_addr =
- (hevc->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s => %d (0x%x) size 0x%x\n",
- __func__, ret,
- pic->mpred_mv_wr_start_addr,
- pic->mv_size);
-
- } else {
- hevc_print(hevc, 0,
- "%s: Error, mv buf is not enough\n",
- __func__);
- }
- return ret;
-
-#endif
-}
-
-static void put_mv_buf(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
-#ifndef MV_USE_FIXED_BUF
- int i = pic->mv_buf_index;
- if (i < 0 || i >= MAX_REF_PIC_NUM) {
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s: index %d beyond range\n",
- __func__, i);
- return;
- }
- if (mv_buf_dynamic_alloc) {
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s(%d)\n",
- __func__, i);
-
- decoder_bmmu_box_free_idx(
- hevc->bmmu_box,
- MV_BUFFER_IDX(i));
- hevc->m_mv_BUF[i].start_adr = 0;
- hevc->m_mv_BUF[i].size = 0;
- hevc->m_mv_BUF[i].used_flag = 0;
- pic->mv_buf_index = -1;
- return;
- }
-
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s(%d): used_flag(%d)\n",
- __func__, i,
- hevc->m_mv_BUF[i].used_flag);
-
- if (hevc->m_mv_BUF[i].start_adr &&
- hevc->m_mv_BUF[i].used_flag)
- hevc->m_mv_BUF[i].used_flag = 0;
- pic->mv_buf_index = -1;
-#endif
-}
-
-static int cal_current_buf_size(struct hevc_state_s *hevc,
- struct buf_stru_s *buf_stru)
-{
-
- int buf_size;
- int pic_width = hevc->pic_w;
- int pic_height = hevc->pic_h;
- int lcu_size = hevc->lcu_size;
- int pic_width_lcu = (pic_width % lcu_size) ? pic_width / lcu_size +
- 1 : pic_width / lcu_size;
- int pic_height_lcu = (pic_height % lcu_size) ? pic_height / lcu_size +
- 1 : pic_height / lcu_size;
- /*SUPPORT_10BIT*/
- int losless_comp_header_size = compute_losless_comp_header_size
- (pic_width, pic_height);
- /*always alloc buf for 10bit*/
- int losless_comp_body_size = compute_losless_comp_body_size
- (hevc, pic_width, pic_height, 0);
- int mc_buffer_size = losless_comp_header_size
- + losless_comp_body_size;
- int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16;
- int mc_buffer_size_u_v_h = 0;
-
- int dw_mode = get_double_write_mode(hevc);
-
- if (hevc->mmu_enable) {
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
- buf_size = ((MMU_COMPRESS_HEADER_SIZE_8K + 0xffff) >> 16)
- << 16;
- else
- buf_size = ((MMU_COMPRESS_HEADER_SIZE_4K + 0xffff) >> 16)
- << 16;
- } else
- buf_size = 0;
-
- if (dw_mode) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
- int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
-
- int pic_width_lcu_dw = (pic_width_dw % lcu_size) ?
- pic_width_dw / lcu_size + 1 :
- pic_width_dw / lcu_size;
- int pic_height_lcu_dw = (pic_height_dw % lcu_size) ?
- pic_height_dw / lcu_size + 1 :
- pic_height_dw / lcu_size;
- int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
-
- int mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2;
- mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
- }
-
- if ((!hevc->mmu_enable) &&
- ((dw_mode & 0x10) == 0)) {
- /* use compress mode without mmu,
- need buf for compress decoding*/
- buf_size += (mc_buffer_size_h << 16);
- }
-
- /*in case start adr is not 64k alignment*/
- if (buf_size > 0)
- buf_size += 0x10000;
-
- if (buf_stru) {
- buf_stru->lcu_total = pic_width_lcu * pic_height_lcu;
- buf_stru->mc_buffer_size_h = mc_buffer_size_h;
- buf_stru->mc_buffer_size_u_v_h = mc_buffer_size_u_v_h;
- }
-
- hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,"pic width: %d, pic height: %d, headr: %d, body: %d, size h: %d, size uvh: %d, buf size: %x\n",
- pic_width, pic_height, losless_comp_header_size,
- losless_comp_body_size, mc_buffer_size_h,
- mc_buffer_size_u_v_h, buf_size);
-
- return buf_size;
-}
-
-static int hevc_get_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(w, h)))
- return ALIGN(MMU_COMPRESS_HEADER_SIZE_8K, 0x10000);
- else
- return ALIGN(MMU_COMPRESS_HEADER_SIZE_4K, 0x10000);
-}
-
-static void hevc_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vh265_vf_put(vf, vdec_ctx);
-}
-
-static void hevc_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vh265_vf_get(vdec_ctx);
-}
-
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct hevc_state_s *hevc,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct hevc_state_s *hevc, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- hevc->m_PIC[index]->cma_alloc_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = hevc_get_video_frame,
- .put_vframe = hevc_put_video_frame,
-};
-
-static int v4l_alloc_buf(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
- int ret = -1;
- int i = pic->index;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hevc->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hevc->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- hevc_print(hevc, 0, "[%d] H265 get buffer fail.\n", ctx->id);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hevc));
- fb->status = FB_ST_DECODER;
-
- if (hevc->mmu_enable) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hevc, fb);
- hevc->m_BUF[i].header_addr = ibuf->header_addr;
- }
-
- hevc->m_BUF[i].used_flag = 1;
- hevc->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
- pic->cma_alloc_addr = hevc->m_BUF[i].v4l_ref_buf_addr;
- if (fb->num_planes == 1) {
- hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
- hevc->m_BUF[i].luma_size = fb->m.mem[0].offset;
- hevc->m_BUF[i].size = fb->m.mem[0].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- pic->dw_y_adr = hevc->m_BUF[i].start_adr;
- pic->dw_u_v_adr = pic->dw_y_adr + hevc->m_BUF[i].luma_size;
- pic->luma_size = fb->m.mem[0].offset;
- pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset;
- } else if (fb->num_planes == 2) {
- hevc->m_BUF[i].start_adr = fb->m.mem[0].addr;
- hevc->m_BUF[i].luma_size = fb->m.mem[0].size;
- hevc->m_BUF[i].chroma_addr = fb->m.mem[1].addr;
- hevc->m_BUF[i].chroma_size = fb->m.mem[1].size;
- hevc->m_BUF[i].size = fb->m.mem[0].size + fb->m.mem[1].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- pic->dw_y_adr = hevc->m_BUF[i].start_adr;
- pic->dw_u_v_adr = hevc->m_BUF[i].chroma_addr;
- pic->luma_size = fb->m.mem[0].size;
- pic->chroma_size = fb->m.mem[1].size;
- }
-
- return ret;
-}
-
-static int alloc_buf(struct hevc_state_s *hevc)
-{
- int i;
- int ret = -1;
- int buf_size = cal_current_buf_size(hevc, NULL);
-
- if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
- return ret;
-
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- if (hevc->m_BUF[i].start_adr == 0)
- break;
- }
- if (i < BUF_POOL_SIZE) {
- if (buf_size > 0) {
- ret = decoder_bmmu_box_alloc_buf_phy
- (hevc->bmmu_box,
- VF_BUFFER_IDX(i), buf_size,
- DRIVER_NAME,
- &hevc->m_BUF[i].start_adr);
- if (ret < 0) {
- hevc->m_BUF[i].start_adr = 0;
- if (i <= 8) {
- hevc->fatal_error |=
- DECODER_FATAL_ERROR_NO_MEM;
- hevc_print(hevc, PRINT_FLAG_ERROR,
- "%s[%d], size: %d, no mem fatal err\n",
- __func__, i, buf_size);
- }
- }
-
- if (ret >= 0) {
- hevc->m_BUF[i].size = buf_size;
- hevc->m_BUF[i].used_flag = 0;
- ret = 0;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "Buffer %d: start_adr %p size %x\n",
- i,
- (void *)hevc->m_BUF[i].start_adr,
- hevc->m_BUF[i].size);
- }
- /*flush the buffer make sure no cache dirty*/
- if (!vdec_secure(hw_to_vdec(hevc)) && (hevc->m_BUF[i].start_adr)) {
- void *mem_start_virt;
- mem_start_virt =
- codec_mm_phys_to_virt(hevc->m_BUF[i].start_adr);
- if (mem_start_virt) {
- memset(mem_start_virt, 0, hevc->m_BUF[i].size);
- codec_mm_dma_flush(mem_start_virt,
- hevc->m_BUF[i].size, DMA_TO_DEVICE);
- } else {
- codec_mm_memset(hevc->m_BUF[i].start_adr,
- 0, hevc->m_BUF[i].size);
- }
- }
- }
- /*put_cma_alloc_ref();*/ /*DEBUG_TMP*/
- } else
- ret = 0;
- }
-
- if (ret >= 0) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "alloc buf(%d) for %d/%d size 0x%x) => %p\n",
- i, hevc->pic_w, hevc->pic_h,
- buf_size,
- hevc->m_BUF[i].start_adr);
- }
- } else {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "alloc buf(%d) for %d/%d size 0x%x) => Fail!!!\n",
- i, hevc->pic_w, hevc->pic_h,
- buf_size);
- }
- }
- return ret;
-}
-
-static void set_buf_unused(struct hevc_state_s *hevc, int i)
-{
- if (i >= 0 && i < BUF_POOL_SIZE)
- hevc->m_BUF[i].used_flag = 0;
-}
-
-static void dealloc_unused_buf(struct hevc_state_s *hevc)
-{
- int i;
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- if (hevc->m_BUF[i].start_adr &&
- hevc->m_BUF[i].used_flag == 0) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "dealloc buf(%d) adr 0x%p size 0x%x\n",
- i, hevc->m_BUF[i].start_adr,
- hevc->m_BUF[i].size);
- }
- if (!hevc->is_used_v4l)
- decoder_bmmu_box_free_idx(
- hevc->bmmu_box,
- VF_BUFFER_IDX(i));
- hevc->m_BUF[i].start_adr = 0;
- hevc->m_BUF[i].header_addr = 0;
- hevc->m_BUF[i].size = 0;
- }
- }
-}
-
-static void dealloc_pic_buf(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
- int i = pic->BUF_index;
- pic->BUF_index = -1;
- if (i >= 0 &&
- i < BUF_POOL_SIZE &&
- hevc->m_BUF[i].start_adr) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "dealloc buf(%d) adr 0x%p size 0x%x\n",
- i, hevc->m_BUF[i].start_adr,
- hevc->m_BUF[i].size);
- }
-
- if (!hevc->is_used_v4l)
- decoder_bmmu_box_free_idx(
- hevc->bmmu_box,
- VF_BUFFER_IDX(i));
- hevc->m_BUF[i].used_flag = 0;
- hevc->m_BUF[i].start_adr = 0;
- hevc->m_BUF[i].header_addr = 0;
- hevc->m_BUF[i].size = 0;
- }
-}
-
-static int v4l_parser_work_pic_num(struct hevc_state_s *hevc)
-{
- int used_buf_num = 0;
-
- pr_debug("margin = %d, sps_max_dec_pic_buffering_minus1_0 = %d\n",
- get_dynamic_buf_num_margin(hevc),
- hevc->param.p.sps_max_dec_pic_buffering_minus1_0);
-
- used_buf_num = hevc->param.p.sps_max_dec_pic_buffering_minus1_0 + 1;
- /*
- 1. need one more for multi instance, as apply_ref_pic_set()
- has no chanch to run to clear referenced flag in some case
- 2. for eos add more buffer to flush.
- */
- used_buf_num += 2;
-
- if (hevc->save_buffer_mode)
- hevc_print(hevc, 0,
- "save buf _mode : dynamic_buf_num_margin %d ----> %d \n",
- dynamic_buf_num_margin, hevc->dynamic_buf_num_margin);
-
- if (used_buf_num > max_buf_num)
- used_buf_num = max_buf_num;
- return used_buf_num;
-}
-
-static int get_alloc_pic_count(struct hevc_state_s *hevc)
-{
- int alloc_pic_count = 0;
- int i;
- struct PIC_s *pic;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic && pic->index >= 0)
- alloc_pic_count++;
- }
- return alloc_pic_count;
-}
-
-static int v4l_config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
- int i = pic->index;
- int dw_mode = get_double_write_mode(hevc);
-
- if (hevc->mmu_enable)
- pic->header_adr = hevc->m_BUF[i].header_addr;
-
- pic->BUF_index = i;
- pic->POC = INVALID_POC;
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
-
- if (dw_mode & 0x10) {
- pic->mc_canvas_y = (pic->index << 1);
- pic->mc_canvas_u_v = (pic->index << 1) + 1;
- pic->mc_y_adr = pic->dw_y_adr;
- pic->mc_u_v_adr = pic->dw_u_v_adr;
- }
-
- return 0;
-}
-
-static int config_pic(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
- int ret = -1;
- int i;
- /*int lcu_size_log2 = hevc->lcu_size_log2;
- int MV_MEM_UNIT=lcu_size_log2==
- 6 ? 0x100 : lcu_size_log2==5 ? 0x40 : 0x10;*/
- /*int MV_MEM_UNIT = lcu_size_log2 == 6 ? 0x200 : lcu_size_log2 ==
- 5 ? 0x80 : 0x20;
- int mpred_mv_end = hevc->work_space_buf->mpred_mv.buf_start +
- hevc->work_space_buf->mpred_mv.buf_size;*/
- unsigned int y_adr = 0;
- struct buf_stru_s buf_stru;
- int buf_size = cal_current_buf_size(hevc, &buf_stru);
- int dw_mode = get_double_write_mode(hevc);
-
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- if (hevc->m_BUF[i].start_adr != 0 &&
- hevc->m_BUF[i].used_flag == 0 &&
- buf_size <= hevc->m_BUF[i].size) {
- hevc->m_BUF[i].used_flag = 1;
- break;
- }
- }
-
- if (i >= BUF_POOL_SIZE)
- return -1;
-
- if (hevc->mmu_enable) {
- pic->header_adr = hevc->m_BUF[i].start_adr;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (IS_8K_SIZE(hevc->pic_w, hevc->pic_h)))
- y_adr = hevc->m_BUF[i].start_adr +
- MMU_COMPRESS_HEADER_SIZE_8K;
- else
- y_adr = hevc->m_BUF[i].start_adr +
- MMU_COMPRESS_HEADER_SIZE_4K;
- } else
- y_adr = hevc->m_BUF[i].start_adr;
-
- y_adr = ((y_adr + 0xffff) >> 16) << 16; /*64k alignment*/
-
- pic->POC = INVALID_POC;
- /*ensure get_pic_by_POC()
- not get the buffer not decoded*/
- pic->BUF_index = i;
-
- if ((!hevc->mmu_enable) &&
- ((dw_mode & 0x10) == 0)
- ) {
- pic->mc_y_adr = y_adr;
- y_adr += (buf_stru.mc_buffer_size_h << 16);
- }
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
- if (dw_mode & 0x10) {
- pic->mc_y_adr = y_adr;
- pic->mc_u_v_adr = y_adr +
- ((buf_stru.mc_buffer_size_u_v_h << 16) << 1);
- pic->mc_canvas_y = (pic->index << 1);
- pic->mc_canvas_u_v = (pic->index << 1) + 1;
-
- pic->dw_y_adr = pic->mc_y_adr;
- pic->dw_u_v_adr = pic->mc_u_v_adr;
- } else if (dw_mode) {
- pic->dw_y_adr = y_adr;
- pic->dw_u_v_adr = pic->dw_y_adr +
- ((buf_stru.mc_buffer_size_u_v_h << 16) << 1);
- }
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "%s index %d BUF_index %d mc_y_adr %x\n",
- __func__, pic->index,
- pic->BUF_index, pic->mc_y_adr);
- if (hevc->mmu_enable &&
- dw_mode)
- hevc_print(hevc, 0,
- "mmu double write adr %ld\n",
- pic->cma_alloc_addr);
- }
- ret = 0;
-
- return ret;
-}
-
-static void init_pic_list(struct hevc_state_s *hevc)
-{
- int i;
- int init_buf_num = hevc->used_buf_num;
- int dw_mode = get_double_write_mode(hevc);
- struct vdec_s *vdec = hw_to_vdec(hevc);
- /*alloc decoder buf will be delay if work on v4l. */
- if (!hevc->is_used_v4l) {
- for (i = 0; i < init_buf_num; i++) {
- if (alloc_buf(hevc) < 0) {
- if (i <= 8) {
- /*if alloced (i+1)>=9
- don't send errors.*/
- hevc->fatal_error |=
- DECODER_FATAL_ERROR_NO_MEM;
- }
- break;
- }
- }
- }
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic = hevc->m_PIC[i];
-
- if (!pic) {
- pic = vzalloc(sizeof(struct PIC_s));
- if (pic == NULL) {
- hevc_print(hevc, 0,
- "%s: alloc pic %d fail!!!\n",
- __func__, i);
- break;
- }
- hevc->m_PIC[i] = pic;
- } else {
- char *aux_data_tmp;
- u32 aux_data_size;
-
- aux_data_tmp = pic->aux_data_buf;
- aux_data_size = pic->aux_data_size;
- memset(pic, 0, sizeof(struct PIC_s));
- pic->aux_data_buf = aux_data_tmp;
- pic->aux_data_size = aux_data_size;
- }
-
- pic->index = i;
- pic->BUF_index = -1;
- pic->mv_buf_index = -1;
- if (vdec->parallel_dec == 1) {
- pic->y_canvas_index = -1;
- pic->uv_canvas_index = -1;
- }
-
- pic->width = hevc->pic_w;
- pic->height = hevc->pic_h;
- pic->double_write_mode = dw_mode;
- pic->POC = INVALID_POC;
-
- /*config canvas will be delay if work on v4l. */
- if (!hevc->is_used_v4l) {
- if (config_pic(hevc, pic) < 0) {
- if (get_dbg_flag(hevc))
- hevc_print(hevc, 0,
- "Config_pic %d fail\n", pic->index);
- pic->index = -1;
- i++;
- break;
- }
-
- if (pic->double_write_mode)
- set_canvas(hevc, pic);
- }
- }
-}
-
-static void uninit_pic_list(struct hevc_state_s *hevc)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
- int i;
-#ifndef MV_USE_FIXED_BUF
- dealloc_mv_bufs(hevc);
-#endif
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic = hevc->m_PIC[i];
-
- if (pic) {
- if (vdec->parallel_dec == 1) {
- vdec->free_canvas_ex(pic->y_canvas_index, vdec->id);
- vdec->free_canvas_ex(pic->uv_canvas_index, vdec->id);
- }
- release_aux_data(hevc, pic);
- vfree(pic);
- hevc->m_PIC[i] = NULL;
- }
- }
-}
-
-#ifdef LOSLESS_COMPRESS_MODE
-static void init_decode_head_hw(struct hevc_state_s *hevc)
-{
-
- struct BuffInfo_s *buf_spec = hevc->work_space_buf;
- unsigned int data32;
-
- int losless_comp_header_size =
- compute_losless_comp_header_size(hevc->pic_w,
- hevc->pic_h);
- int losless_comp_body_size = compute_losless_comp_body_size(hevc,
- hevc->pic_w, hevc->pic_h, hevc->mem_saving_mode);
-
- hevc->losless_comp_body_size = losless_comp_body_size;
-
-
- if (hevc->mmu_enable) {
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0x0);
- } else {
- if (hevc->mem_saving_mode == 1)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
- (1 << 3) | ((workaround_enable & 2) ? 1 : 0));
- else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
- ((workaround_enable & 2) ? 1 : 0));
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
- /*
- *WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);
- * //8-bit mode
- */
- }
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
-
- if (hevc->mmu_enable) {
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR,
- buf_spec->mmu_vbh.buf_start +
- buf_spec->mmu_vbh.buf_size/2);
- data32 = READ_VREG(HEVC_SAO_CTRL9);
- data32 |= 0x1;
- WRITE_VREG(HEVC_SAO_CTRL9, data32);
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- if (!hevc->m_ins_flag)
- hevc_print(hevc, 0,
- "%s: (%d, %d) body_size 0x%x header_size 0x%x\n",
- __func__, hevc->pic_w, hevc->pic_h,
- losless_comp_body_size, losless_comp_header_size);
-
-}
-#endif
-#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
-
-static void init_pic_list_hw(struct hevc_state_s *hevc)
-{
- int i;
- int cur_pic_num = MAX_REF_PIC_NUM;
- int dw_mode = get_double_write_mode(hevc);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL)
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
- else
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- if (hevc->m_PIC[i] == NULL ||
- hevc->m_PIC[i]->index == -1) {
- cur_pic_num = i;
- break;
- }
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
- if (hevc->mmu_enable && ((dw_mode & 0x10) == 0))
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- hevc->m_PIC[i]->header_adr>>5);
- else
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- hevc->m_PIC[i]->mc_y_adr >> 5);
- } else
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- hevc->m_PIC[i]->mc_y_adr |
- (hevc->m_PIC[i]->mc_canvas_y << 8) | 0x1);
- if (dw_mode & 0x10) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- hevc->m_PIC[i]->mc_u_v_adr >> 5);
- }
- else
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- hevc->m_PIC[i]->mc_u_v_adr |
- (hevc->m_PIC[i]->mc_canvas_u_v << 8)
- | 0x1);
- }
- }
- if (cur_pic_num == 0)
- return;
-
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-
- /* Zero out canvas registers in IPP -- avoid simulation X */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
- for (i = 0; i < 32; i++)
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
-
-#ifdef LOSLESS_COMPRESS_MODE
- if ((dw_mode & 0x10) == 0)
- init_decode_head_hw(hevc);
-#endif
-
-}
-
-
-static void dump_pic_list(struct hevc_state_s *hevc)
-{
- int i;
- struct PIC_s *pic;
- PR_INIT(256);
-
- hevc_print(hevc, 0,
- "pic_list_init_flag is %d\r\n", hevc->pic_list_init_flag);
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- PR_FILL("index %d buf_idx %d mv_idx %d decode_idx:%d, POC:%d, referenced:%d (LT %d), ",
- pic->index, pic->BUF_index,
-#ifndef MV_USE_FIXED_BUF
- pic->mv_buf_index,
-#else
- -1,
-#endif
- pic->decode_idx, pic->POC, pic->referenced
-#ifdef SUPPORT_LONG_TERM_RPS
- , pic->long_term_ref
-#else
- , 0
-#endif
- );
- PR_FILL("num_reorder_pic:%d, output_mark:%d, error_mark:%d w/h %d,%d",
- pic->num_reorder_pic, pic->output_mark, pic->error_mark,
- pic->width, pic->height);
- PR_FILL("output_ready:%d, mv_wr_start %x vf_ref %d",
- pic->output_ready, pic->mpred_mv_wr_start_addr,
- pic->vf_ref);
- PR_INFO(hevc->index);
- }
-}
-
-static void clear_referenced_flag(struct hevc_state_s *hevc)
-{
- int i;
- struct PIC_s *pic;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if (pic->referenced) {
- pic->referenced = 0;
- put_mv_buf(hevc, pic);
- }
- }
-}
-
-static void clear_poc_flag(struct hevc_state_s *hevc)
-{
- int i;
- struct PIC_s *pic;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- pic->POC = INVALID_POC;
- }
-}
-
-static struct PIC_s *output_pic(struct hevc_state_s *hevc,
- unsigned char flush_flag)
-{
- int num_pic_not_yet_display = 0;
- int i, fisrt_pic_flag = 0;
- struct PIC_s *pic;
- struct PIC_s *pic_display = NULL;
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (hevc->i_only & 0x4) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- (pic->index == -1) ||
- (pic->BUF_index == -1) ||
- (pic->POC == INVALID_POC))
- continue;
- if (pic->output_mark) {
- if (pic_display) {
- if (pic->decode_idx <
- pic_display->decode_idx)
- pic_display = pic;
-
- } else
- pic_display = pic;
-
- }
- }
- if (pic_display) {
- pic_display->output_mark = 0;
- pic_display->recon_mark = 0;
- pic_display->output_ready = 1;
- pic_display->referenced = 0;
- put_mv_buf(hevc, pic_display);
- }
- } else {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- (pic->index == -1) ||
- (pic->BUF_index == -1) ||
- (pic->POC == INVALID_POC))
- continue;
- if (pic->output_mark)
- num_pic_not_yet_display++;
- if (pic->slice_type == 2 &&
- atomic_read(&hevc->vf_pre_count) == 0 &&
- fast_output_enable & 0x1) {
- /*fast output for first I picture*/
- pic->num_reorder_pic = 0;
- if (vdec->master || vdec->slave)
- pic_display = pic;
- fisrt_pic_flag = 1;
- hevc_print(hevc, 0, "VH265: output first frame\n");
- }
- }
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- (pic->index == -1) ||
- (pic->BUF_index == -1) ||
- (pic->POC == INVALID_POC))
- continue;
- if (pic->output_mark) {
- if (pic_display) {
- if (pic->POC < pic_display->POC)
- pic_display = pic;
- else if ((pic->POC == pic_display->POC)
- && (pic->decode_idx <
- pic_display->
- decode_idx))
- pic_display
- = pic;
- } else
- pic_display = pic;
- }
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- /* dv wait cur_pic all data get,
- some data may get after picture output */
- if ((vdec->master || vdec->slave)
- && (pic_display == hevc->cur_pic) &&
- (!flush_flag) &&
- (hevc->bypass_dvenl && !dolby_meta_with_el)
- && (!fisrt_pic_flag))
- pic_display = NULL;
-#endif
- if (pic_display) {
- if ((num_pic_not_yet_display >
- pic_display->num_reorder_pic)
- || flush_flag) {
- pic_display->output_mark = 0;
- pic_display->recon_mark = 0;
- pic_display->output_ready = 1;
- } else if (num_pic_not_yet_display >=
- (MAX_REF_PIC_NUM - 1)) {
- pic_display->output_mark = 0;
- pic_display->recon_mark = 0;
- pic_display->output_ready = 1;
- hevc_print(hevc, 0,
- "Warning, num_reorder_pic %d is byeond buf num\n",
- pic_display->num_reorder_pic);
- } else
- pic_display = NULL;
- }
- }
-
- if (pic_display && hevc->sps_num_reorder_pics_0 &&
- (atomic_read(&hevc->vf_pre_count) == 1) && (hevc->first_pic_flag == 1)) {
- pic_display = NULL;
- hevc->first_pic_flag = 2;
- }
- return pic_display;
-}
-
-static int config_mc_buffer(struct hevc_state_s *hevc, struct PIC_s *cur_pic)
-{
- int i;
- struct PIC_s *pic;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "config_mc_buffer entered .....\n");
- if (cur_pic->slice_type != 2) { /* P and B pic */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
- for (i = 0; i < cur_pic->RefNum_L0; i++) {
- pic =
- get_ref_pic_by_POC(hevc,
- cur_pic->
- m_aiRefPOCList0[cur_pic->
- slice_idx][i]);
- if (pic) {
- if ((pic->width != hevc->pic_w) ||
- (pic->height != hevc->pic_h)) {
- hevc_print(hevc, 0,
- "%s: Wrong reference pic (poc %d) width/height %d/%d\n",
- __func__, pic->POC,
- pic->width, pic->height);
- cur_pic->error_mark = 1;
- }
- if (pic->error_mark && (ref_frame_mark_flag[hevc->index]))
- cur_pic->error_mark = 1;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16)
- | (pic->mc_canvas_u_v
- << 8) |
- pic->mc_canvas_y);
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print_cont(hevc, 0,
- "refid %x mc_canvas_u_v %x",
- i, pic->mc_canvas_u_v);
- hevc_print_cont(hevc, 0,
- " mc_canvas_y %x\n",
- pic->mc_canvas_y);
- }
- } else
- cur_pic->error_mark = 1;
-
- if (pic == NULL || pic->error_mark) {
- hevc_print(hevc, 0,
- "Error %s, %dth poc (%d) %s",
- __func__, i,
- cur_pic->m_aiRefPOCList0[cur_pic->
- slice_idx][i],
- pic ? "has error" :
- "not in list0");
- }
- }
- }
- if (cur_pic->slice_type == 0) { /* B pic */
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "config_mc_buffer RefNum_L1\n");
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (0 << 1) | 1);
-
- for (i = 0; i < cur_pic->RefNum_L1; i++) {
- pic =
- get_ref_pic_by_POC(hevc,
- cur_pic->
- m_aiRefPOCList1[cur_pic->
- slice_idx][i]);
- if (pic) {
- if ((pic->width != hevc->pic_w) ||
- (pic->height != hevc->pic_h)) {
- hevc_print(hevc, 0,
- "%s: Wrong reference pic (poc %d) width/height %d/%d\n",
- __func__, pic->POC,
- pic->width, pic->height);
- cur_pic->error_mark = 1;
- }
-
- if (pic->error_mark && (ref_frame_mark_flag[hevc->index]))
- cur_pic->error_mark = 1;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic->mc_canvas_u_v << 16)
- | (pic->mc_canvas_u_v
- << 8) |
- pic->mc_canvas_y);
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print_cont(hevc, 0,
- "refid %x mc_canvas_u_v %x",
- i, pic->mc_canvas_u_v);
- hevc_print_cont(hevc, 0,
- " mc_canvas_y %x\n",
- pic->mc_canvas_y);
- }
- } else
- cur_pic->error_mark = 1;
-
- if (pic == NULL || pic->error_mark) {
- hevc_print(hevc, 0,
- "Error %s, %dth poc (%d) %s",
- __func__, i,
- cur_pic->m_aiRefPOCList1[cur_pic->
- slice_idx][i],
- pic ? "has error" :
- "not in list1");
- }
- }
- }
- return 0;
-}
-
-#ifdef SUPPORT_LONG_TERM_RPS
-static unsigned char is_ref_long_term(struct hevc_state_s *hevc, int poc)
-{
- int ii;
- struct PIC_s *pic;
- for (ii = 0; ii < MAX_REF_PIC_NUM; ii++) {
- pic = hevc->m_PIC[ii];
- if (pic == NULL ||
- pic->index == -1 ||
- pic->BUF_index == -1
- )
- continue;
-
- if (pic->referenced && pic->POC == poc
- && pic->long_term_ref)
- return 1;
- }
- return 0;
-}
-
-#endif
-
-static void apply_ref_pic_set(struct hevc_state_s *hevc, int cur_poc,
- union param_u *params)
-{
- int ii, i;
- int poc_tmp;
- struct PIC_s *pic;
- unsigned char is_referenced;
- /* hevc_print(hevc, 0,
- "%s cur_poc %d\n", __func__, cur_poc); */
- if (pic_list_debug & 0x2) {
- pr_err("cur poc %d\n", cur_poc);
- }
- for (ii = 0; ii < MAX_REF_PIC_NUM; ii++) {
- pic = hevc->m_PIC[ii];
- if (pic == NULL ||
- pic->index == -1 ||
- pic->BUF_index == -1
- )
- continue;
-
-#ifdef SUPPORT_LONG_TERM_RPS
- pic->long_term_ref = 0;
-#endif
- if ((pic->referenced == 0 || pic->POC == cur_poc))
- continue;
- is_referenced = 0;
-
- for (i = 0; i < 16; i++) {
- int delt;
-#ifdef SUPPORT_LONG_TERM_RPS
- if (params->p.CUR_RPS[i] == RPS_END)
- break;
-#else
- if (params->p.CUR_RPS[i] & 0x8000)
- break;
-#endif
- delt =
- params->p.CUR_RPS[i] &
- ((1 << (RPS_USED_BIT - 1)) - 1);
- if (params->p.CUR_RPS[i] & (1 << (RPS_USED_BIT - 1))) {
- poc_tmp =
- cur_poc - ((1 << (RPS_USED_BIT - 1)) -
- delt);
- } else
- poc_tmp = cur_poc + delt;
- if (poc_tmp == pic->POC) {
-#ifdef SUPPORT_LONG_TERM_RPS
- if (params->p.CUR_RPS[i] & (1 << (RPS_LT_BIT)))
- pic->long_term_ref = 1;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- hevc_print(hevc, 0, "%d: CUR_RPS 0x%x, LT %d\n",
- i, params->p.CUR_RPS[i],
- pic->long_term_ref);
-#endif
- is_referenced = 1;
- break;
- }
- }
- if (is_referenced == 0) {
- pic->referenced = 0;
- put_mv_buf(hevc, pic);
- /* hevc_print(hevc, 0,
- "set poc %d reference to 0\n", pic->POC); */
- if (pic_list_debug & 0x2) {
- pr_err("set poc %d reference to 0\n", pic->POC);
- }
- }
- }
-
-}
-
-static void set_ref_pic_list(struct hevc_state_s *hevc, union param_u *params)
-{
- struct PIC_s *pic = hevc->cur_pic;
- int i, rIdx;
- int num_neg = 0;
- int num_pos = 0;
- int total_num;
- int num_ref_idx_l0_active =
- (params->p.num_ref_idx_l0_active >
- MAX_REF_ACTIVE) ? MAX_REF_ACTIVE :
- params->p.num_ref_idx_l0_active;
- int num_ref_idx_l1_active =
- (params->p.num_ref_idx_l1_active >
- MAX_REF_ACTIVE) ? MAX_REF_ACTIVE :
- params->p.num_ref_idx_l1_active;
-
- int RefPicSetStCurr0[16];
- int RefPicSetStCurr1[16];
-#ifdef SUPPORT_LONG_TERM_RPS
- int num_lt = 0;
- int RefPicSetLtCurr[16];
-#endif
- PR_INIT(128);
-
- for (i = 0; i < 16; i++) {
- RefPicSetStCurr0[i] = 0;
- RefPicSetStCurr1[i] = 0;
- pic->m_aiRefPOCList0[pic->slice_idx][i] = 0;
- pic->m_aiRefPOCList1[pic->slice_idx][i] = 0;
- }
- for (i = 0; i < 16; i++) {
-#ifdef SUPPORT_LONG_TERM_RPS
- if (params->p.CUR_RPS[i] == RPS_END)
- break;
-#else
- if (params->p.CUR_RPS[i] & 0x8000)
- break;
-#endif
- if ((params->p.CUR_RPS[i] >> RPS_USED_BIT) & 1) {
- int delt =
- params->p.CUR_RPS[i] &
- ((1 << (RPS_USED_BIT - 1)) - 1);
-
- if ((params->p.CUR_RPS[i] >> (RPS_USED_BIT - 1)) & 1) {
-#ifdef SUPPORT_LONG_TERM_RPS
- if ((params->p.CUR_RPS[i] >> RPS_LT_BIT) & 1) {
- RefPicSetLtCurr[num_lt] =
- pic->POC - ((1 << (RPS_USED_BIT - 1)) -
- delt);
- num_lt++;
- continue;
- }
-#endif
-
- RefPicSetStCurr0[num_neg] =
- pic->POC - ((1 << (RPS_USED_BIT - 1)) -
- delt);
- /* hevc_print(hevc, 0,
- * "RefPicSetStCurr0 %x %x %x\n",
- * RefPicSetStCurr0[num_neg], pic->POC,
- * (0x800-(params[i]&0x7ff)));
- */
- num_neg++;
- } else {
-#ifdef SUPPORT_LONG_TERM_RPS
- if ((params->p.CUR_RPS[i] >> RPS_LT_BIT) & 1) {
- RefPicSetLtCurr[num_lt] = pic->POC + delt;
- num_lt++;
- continue;
- }
-#endif
- RefPicSetStCurr1[num_pos] = pic->POC + delt;
- /* hevc_print(hevc, 0,
- * "RefPicSetStCurr1 %d\n",
- * RefPicSetStCurr1[num_pos]);
- */
- num_pos++;
- }
- }
- }
-#ifdef SUPPORT_LONG_TERM_RPS
- total_num = num_neg + num_pos + num_lt;
-#else
- total_num = num_neg + num_pos;
-#endif
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "%s: curpoc %d slice_type %d, total %d ",
- __func__, pic->POC, params->p.slice_type, total_num);
-#ifdef SUPPORT_LONG_TERM_RPS
- hevc_print_cont(hevc, 0,
- "num_neg %d num_lt %d num_list0 %d num_list1 %d\n",
- num_neg, num_lt, num_ref_idx_l0_active, num_ref_idx_l1_active);
-#else
- hevc_print_cont(hevc, 0,
- "num_neg %d num_list0 %d num_list1 %d\n",
- num_neg, num_ref_idx_l0_active, num_ref_idx_l1_active);
-#endif
-
- }
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "HEVC Stream buf start ");
- hevc_print_cont(hevc, 0,
- "%x end %x wr %x rd %x lev %x ctl %x intctl %x\n",
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_FIFO_CTL),
- READ_VREG(HEVC_PARSER_INT_CONTROL));
- }
-
- if (total_num > 0) {
- if (params->p.modification_flag & 0x1) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0, "ref0 POC (modification):");
- for (rIdx = 0; rIdx < num_ref_idx_l0_active; rIdx++) {
- int cIdx = params->p.modification_list[rIdx];
-
- pic->m_aiRefPOCList0[pic->slice_idx][rIdx] =
-#ifdef SUPPORT_LONG_TERM_RPS
- cIdx >= (num_neg + num_pos) ?
- RefPicSetLtCurr[cIdx - num_neg - num_pos] :
-#endif
- (cIdx >=
- num_neg ? RefPicSetStCurr1[cIdx -
- num_neg] :
- RefPicSetStCurr0[cIdx]);
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- PR_FILL("%d ",
- pic->m_aiRefPOCList0[pic->
- slice_idx]
- [rIdx]);
- }
- }
- } else {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0, "ref0 POC:");
- for (rIdx = 0; rIdx < num_ref_idx_l0_active; rIdx++) {
- int cIdx = rIdx % total_num;
-
- pic->m_aiRefPOCList0[pic->slice_idx][rIdx] =
-#ifdef SUPPORT_LONG_TERM_RPS
- cIdx >= (num_neg + num_pos) ?
- RefPicSetLtCurr[cIdx - num_neg - num_pos] :
-#endif
- (cIdx >=
- num_neg ? RefPicSetStCurr1[cIdx -
- num_neg] :
- RefPicSetStCurr0[cIdx]);
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- PR_FILL("%d ",
- pic->m_aiRefPOCList0[pic->
- slice_idx]
- [rIdx]);
- }
- }
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_INFO(hevc->index);
- if (params->p.slice_type == B_SLICE) {
- if (params->p.modification_flag & 0x2) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "ref1 POC (modification):");
- for (rIdx = 0; rIdx < num_ref_idx_l1_active;
- rIdx++) {
- int cIdx;
-
- if (params->p.modification_flag & 0x1) {
- cIdx =
- params->p.
- modification_list
- [num_ref_idx_l0_active +
- rIdx];
- } else {
- cIdx =
- params->p.
- modification_list[rIdx];
- }
- pic->m_aiRefPOCList1[pic->
- slice_idx][rIdx] =
-#ifdef SUPPORT_LONG_TERM_RPS
- cIdx >= (num_neg + num_pos) ?
- RefPicSetLtCurr[cIdx - num_neg - num_pos] :
-#endif
- (cIdx >=
- num_pos ?
- RefPicSetStCurr0[cIdx - num_pos]
- : RefPicSetStCurr1[cIdx]);
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- PR_FILL("%d ",
- pic->
- m_aiRefPOCList1[pic->
- slice_idx]
- [rIdx]);
- }
- }
- } else {
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0, "ref1 POC:");
- for (rIdx = 0; rIdx < num_ref_idx_l1_active;
- rIdx++) {
- int cIdx = rIdx % total_num;
-
- pic->m_aiRefPOCList1[pic->
- slice_idx][rIdx] =
-#ifdef SUPPORT_LONG_TERM_RPS
- cIdx >= (num_neg + num_pos) ?
- RefPicSetLtCurr[cIdx - num_neg - num_pos] :
-#endif
- (cIdx >=
- num_pos ?
- RefPicSetStCurr0[cIdx -
- num_pos]
- : RefPicSetStCurr1[cIdx]);
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- PR_FILL("%d ",
- pic->
- m_aiRefPOCList1[pic->
- slice_idx]
- [rIdx]);
- }
- }
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_INFO(hevc->index);
- }
- }
- /*set m_PIC */
- pic->slice_type = (params->p.slice_type == I_SLICE) ? 2 :
- (params->p.slice_type == P_SLICE) ? 1 :
- (params->p.slice_type == B_SLICE) ? 0 : 3;
- pic->RefNum_L0 = num_ref_idx_l0_active;
- pic->RefNum_L1 = num_ref_idx_l1_active;
-}
-
-static void update_tile_info(struct hevc_state_s *hevc, int pic_width_cu,
- int pic_height_cu, int sao_mem_unit,
- union param_u *params)
-{
- int i, j;
- int start_cu_x, start_cu_y;
- int sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu;
- int sao_abv_size = sao_mem_unit * pic_width_cu;
- PR_INIT(128);
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap && get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- int tmpRefillLcuSize = 1 <<
- (params->p.log2_min_coding_block_size_minus3 +
- 3 + params->p.log2_diff_max_min_coding_block_size);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%x, %x, %x, %x\n",
- params->p.slice_segment_address,
- params->p.bit_depth,
- params->p.tiles_enabled_flag,
- tmpRefillLcuSize);
- if (params->p.slice_segment_address == 0 &&
- params->p.bit_depth != 0 &&
- (params->p.tiles_enabled_flag & 1) &&
- tmpRefillLcuSize == 64)
- hevc->delrefill_check = 1;
- else
- hevc->delrefill_check = 0;
- }
-#endif
-
- hevc->tile_enabled = params->p.tiles_enabled_flag & 1;
- if (params->p.tiles_enabled_flag & 1) {
- hevc->num_tile_col = params->p.num_tile_columns_minus1 + 1;
- hevc->num_tile_row = params->p.num_tile_rows_minus1 + 1;
-
- if (hevc->num_tile_row > MAX_TILE_ROW_NUM
- || hevc->num_tile_row <= 0) {
- hevc->num_tile_row = 1;
- hevc_print(hevc, 0,
- "%s: num_tile_rows_minus1 (%d) error!!\n",
- __func__, params->p.num_tile_rows_minus1);
- }
- if (hevc->num_tile_col > MAX_TILE_COL_NUM
- || hevc->num_tile_col <= 0) {
- hevc->num_tile_col = 1;
- hevc_print(hevc, 0,
- "%s: num_tile_columns_minus1 (%d) error!!\n",
- __func__, params->p.num_tile_columns_minus1);
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "%s pic_w_cu %d pic_h_cu %d tile_enabled ",
- __func__, pic_width_cu, pic_height_cu);
- hevc_print_cont(hevc, 0,
- "num_tile_col %d num_tile_row %d:\n",
- hevc->num_tile_col, hevc->num_tile_row);
- }
-
- if (params->p.tiles_enabled_flag & 2) { /* uniform flag */
- int w = pic_width_cu / hevc->num_tile_col;
- int h = pic_height_cu / hevc->num_tile_row;
-
- start_cu_y = 0;
- for (i = 0; i < hevc->num_tile_row; i++) {
- start_cu_x = 0;
- for (j = 0; j < hevc->num_tile_col; j++) {
- if (j == (hevc->num_tile_col - 1)) {
- hevc->m_tile[i][j].width =
- pic_width_cu -
- start_cu_x;
- } else
- hevc->m_tile[i][j].width = w;
- if (i == (hevc->num_tile_row - 1)) {
- hevc->m_tile[i][j].height =
- pic_height_cu -
- start_cu_y;
- } else
- hevc->m_tile[i][j].height = h;
- hevc->m_tile[i][j].start_cu_x
- = start_cu_x;
- hevc->m_tile[i][j].start_cu_y
- = start_cu_y;
- hevc->m_tile[i][j].sao_vb_start_addr =
- hevc->work_space_buf->sao_vb.
- buf_start + j * sao_vb_size;
- hevc->m_tile[i][j].sao_abv_start_addr =
- hevc->work_space_buf->sao_abv.
- buf_start + i * sao_abv_size;
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- PR_FILL(
- "{y=%d, x=%d w %d h %d ",
- i, j, hevc->m_tile[i][j].width,
- hevc->m_tile[i][j].height);
- PR_FILL(
- "start_x %d start_y %d ",
- hevc->m_tile[i][j].start_cu_x,
- hevc->m_tile[i][j].start_cu_y);
- PR_FILL(
- "sao_vb_start 0x%x ",
- hevc->m_tile[i][j].
- sao_vb_start_addr);
- PR_FILL(
- "sao_abv_start 0x%x}\n",
- hevc->m_tile[i][j].
- sao_abv_start_addr);
- PR_INFO(hevc->index);
- }
- start_cu_x += hevc->m_tile[i][j].width;
-
- }
- start_cu_y += hevc->m_tile[i][0].height;
- }
- } else {
- start_cu_y = 0;
- for (i = 0; i < hevc->num_tile_row; i++) {
- start_cu_x = 0;
- for (j = 0; j < hevc->num_tile_col; j++) {
- if (j == (hevc->num_tile_col - 1)) {
- hevc->m_tile[i][j].width =
- pic_width_cu -
- start_cu_x;
- } else {
- hevc->m_tile[i][j].width =
- params->p.tile_width[j];
- }
- if (i == (hevc->num_tile_row - 1)) {
- hevc->m_tile[i][j].height =
- pic_height_cu -
- start_cu_y;
- } else {
- hevc->m_tile[i][j].height =
- params->
- p.tile_height[i];
- }
- hevc->m_tile[i][j].start_cu_x
- = start_cu_x;
- hevc->m_tile[i][j].start_cu_y
- = start_cu_y;
- hevc->m_tile[i][j].sao_vb_start_addr =
- hevc->work_space_buf->sao_vb.
- buf_start + j * sao_vb_size;
- hevc->m_tile[i][j].sao_abv_start_addr =
- hevc->work_space_buf->sao_abv.
- buf_start + i * sao_abv_size;
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- PR_FILL(
- "{y=%d, x=%d w %d h %d ",
- i, j, hevc->m_tile[i][j].width,
- hevc->m_tile[i][j].height);
- PR_FILL(
- "start_x %d start_y %d ",
- hevc->m_tile[i][j].start_cu_x,
- hevc->m_tile[i][j].start_cu_y);
- PR_FILL(
- "sao_vb_start 0x%x ",
- hevc->m_tile[i][j].
- sao_vb_start_addr);
- PR_FILL(
- "sao_abv_start 0x%x}\n",
- hevc->m_tile[i][j].
- sao_abv_start_addr);
- PR_INFO(hevc->index);
- }
- start_cu_x += hevc->m_tile[i][j].width;
- }
- start_cu_y += hevc->m_tile[i][0].height;
- }
- }
- } else {
- hevc->num_tile_col = 1;
- hevc->num_tile_row = 1;
- hevc->m_tile[0][0].width = pic_width_cu;
- hevc->m_tile[0][0].height = pic_height_cu;
- hevc->m_tile[0][0].start_cu_x = 0;
- hevc->m_tile[0][0].start_cu_y = 0;
- hevc->m_tile[0][0].sao_vb_start_addr =
- hevc->work_space_buf->sao_vb.buf_start;
- hevc->m_tile[0][0].sao_abv_start_addr =
- hevc->work_space_buf->sao_abv.buf_start;
- }
-}
-
-static int get_tile_index(struct hevc_state_s *hevc, int cu_adr,
- int pic_width_lcu)
-{
- int cu_x;
- int cu_y;
- int tile_x = 0;
- int tile_y = 0;
- int i;
-
- if (pic_width_lcu == 0) {
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "%s Error, pic_width_lcu is 0, pic_w %d, pic_h %d\n",
- __func__, hevc->pic_w, hevc->pic_h);
- }
- return -1;
- }
- cu_x = cu_adr % pic_width_lcu;
- cu_y = cu_adr / pic_width_lcu;
- if (hevc->tile_enabled) {
- for (i = 0; i < hevc->num_tile_col; i++) {
- if (cu_x >= hevc->m_tile[0][i].start_cu_x)
- tile_x = i;
- else
- break;
- }
- for (i = 0; i < hevc->num_tile_row; i++) {
- if (cu_y >= hevc->m_tile[i][0].start_cu_y)
- tile_y = i;
- else
- break;
- }
- }
- return (tile_x) | (tile_y << 8);
-}
-
-static void print_scratch_error(int error_num)
-{
-#if 0
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- " ERROR : HEVC_ASSIST_SCRATCH_TEST Error : %d\n",
- error_num);
- }
-#endif
-}
-
-static void hevc_config_work_space_hw(struct hevc_state_s *hevc)
-{
- struct BuffInfo_s *buf_spec = hevc->work_space_buf;
-
- if (get_dbg_flag(hevc))
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
- __func__,
- buf_spec->ipp.buf_start,
- buf_spec->start_adr,
- buf_spec->short_term_rps.buf_start,
- buf_spec->vps.buf_start,
- buf_spec->sps.buf_start,
- buf_spec->pps.buf_start,
- buf_spec->sao_up.buf_start,
- buf_spec->swap_buf.buf_start,
- buf_spec->swap_buf2.buf_start,
- buf_spec->scalelut.buf_start,
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_data.buf_start,
- buf_spec->dblk_data2.buf_start);
- WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE, buf_spec->ipp.buf_start);
- if ((get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) == 0)
- WRITE_VREG(HEVC_RPM_BUFFER, (u32)hevc->rpm_phy_addr);
- WRITE_VREG(HEVC_SHORT_TERM_RPS, buf_spec->short_term_rps.buf_start);
- WRITE_VREG(HEVC_VPS_BUFFER, buf_spec->vps.buf_start);
- WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);
- WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
- WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
- if (hevc->mmu_enable) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, hevc->frame_mmu_map_phy_addr);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "write HEVC_ASSIST_MMU_MAP_ADDR\n");
- } else
- WRITE_VREG(H265_MMU_MAP_BUFFER, hevc->frame_mmu_map_phy_addr);
- } /*else
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER,
- buf_spec->swap_buf.buf_start);
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);*/
- WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
-#ifdef HEVC_8K_LFTOFFSET_FIX
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
- WRITE_VREG(HEVC_DBLK_CFG3, 0x4010);
- else
- WRITE_VREG(HEVC_DBLK_CFG3, 0x8020);
- //WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); /*offset should x2 if 8k*/
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "write HEVC_DBLK_CFG3 to %x\n", READ_VREG(HEVC_DBLK_CFG3));
- }
-#endif
- /* cfg_p_addr */
- WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
- /* cfg_d_addr */
- WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
-
- WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
-
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hevc->lmem_phy_addr);
-}
-
-static void parser_cmd_write(void)
-{
- u32 i;
- const unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
- 0x0401, 0x8401, 0x0800, 0x0402, 0x9002, 0x1423,
- 0x8CC3, 0x1423, 0x8804, 0x9825, 0x0800, 0x04FE,
- 0x8406, 0x8411, 0x1800, 0x8408, 0x8409, 0x8C2A,
- 0x9C2B, 0x1C00, 0x840F, 0x8407, 0x8000, 0x8408,
- 0x2000, 0xA800, 0x8410, 0x04DE, 0x840C, 0x840D,
- 0xAC00, 0xA000, 0x08C0, 0x08E0, 0xA40E, 0xFC00,
- 0x7C00
- };
- for (i = 0; i < PARSER_CMD_NUMBER; i++)
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
-}
-
-static void hevc_init_decoder_hw(struct hevc_state_s *hevc,
- int decode_pic_begin, int decode_pic_num)
-{
- unsigned int data32;
- int i;
-#if 0
- if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) {
- /* Set MCR fetch priorities*/
- data32 = 0x1 | (0x1 << 2) | (0x1 <<3) |
- (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
- WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
- }
-#endif
-#if 1
- /* m8baby test1902 */
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "%s\n", __func__);
- data32 = READ_VREG(HEVC_PARSER_VERSION);
- if (data32 != 0x00010001) {
- print_scratch_error(25);
- return;
- }
- WRITE_VREG(HEVC_PARSER_VERSION, 0x5a5a55aa);
- data32 = READ_VREG(HEVC_PARSER_VERSION);
- if (data32 != 0x5a5a55aa) {
- print_scratch_error(26);
- return;
- }
-#if 0
- /* test Parser Reset */
- /* reset iqit to start mem init again */
- WRITE_VREG(DOS_SW_RESET3, (1 << 14) |
- (1 << 3) /* reset_whole parser */
- );
- WRITE_VREG(DOS_SW_RESET3, 0); /* clear reset_whole parser */
- data32 = READ_VREG(HEVC_PARSER_VERSION);
- if (data32 != 0x00010001)
- hevc_print(hevc, 0,
- "Test Parser Fatal Error\n");
-#endif
- /* reset iqit to start mem init again */
- WRITE_VREG(DOS_SW_RESET3, (1 << 14)
- );
- CLEAR_VREG_MASK(HEVC_CABAC_CONTROL, 1);
- CLEAR_VREG_MASK(HEVC_PARSER_CORE_CONTROL, 1);
-
-#endif
- if (!hevc->m_ins_flag) {
- data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 | (1 << 0); /* stream_fetch_enable */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- data32 |= (0xf << 25); /*arwlen_axi_max*/
- WRITE_VREG(HEVC_STREAM_CONTROL, data32);
- }
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- print_scratch_error(29);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- print_scratch_error(30);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- print_scratch_error(31);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- print_scratch_error(32);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
-
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- data32 &= 0x03ffffff;
- data32 = data32 | (3 << 29) | (2 << 26) | (1 << 24)
- | /* stream_buffer_empty_int_amrisc_enable */
- (1 << 22) | /* stream_fifo_empty_int_amrisc_enable*/
- (1 << 7) | /* dec_done_int_cpu_enable */
- (1 << 4) | /* startcode_found_int_cpu_enable */
- (0 << 3) | /* startcode_found_int_amrisc_enable */
- (1 << 0) /* parser_int_enable */
- ;
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STATUS);
- data32 = data32 | (1 << 1) | /* emulation_check_on */
- (1 << 0) /* startcode_check_on */
- ;
- WRITE_VREG(HEVC_SHIFT_STATUS, data32);
-
- WRITE_VREG(HEVC_SHIFT_CONTROL, (3 << 6) |/* sft_valid_wr_position */
- (2 << 4) | /* emulate_code_length_sub_1 */
- (2 << 1) | /* start_code_length_sub_1 */
- (1 << 0) /* stream_shift_enable */
- );
-
- WRITE_VREG(HEVC_CABAC_CONTROL, (1 << 0) /* cabac_enable */
- );
- /* hevc_parser_core_clk_en */
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0)
- );
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
-
- /* Initial IQIT_SCALELUT memory -- just to avoid X in simulation */
- if (is_rdma_enable())
- rdma_back_end_work(hevc->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
-
-#ifdef ENABLE_SWAP_TEST
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
-#endif
-
- /*WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);*/
- /*WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0xffffffff);*/
- WRITE_VREG(HEVC_DECODE_SIZE, 0);
- /*WRITE_VREG(HEVC_DECODE_COUNT, 0);*/
- /* Send parser_cmd */
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
-
- parser_cmd_write();
-
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
-
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- /* (1 << 8) | // sao_sw_pred_enable */
- (1 << 5) | /* parser_sao_if_en */
- (1 << 2) | /* parser_mpred_if_en */
- (1 << 0) /* parser_scaler_if_en */
- );
-
- /* Changed to Start MPRED in microcode */
- /*
- * hevc_print(hevc, 0, "[test.c] Start MPRED\n");
- * WRITE_VREG(HEVC_MPRED_INT_STATUS,
- * (1<<31)
- * );
- */
-
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, (0 << 1) | /* enable ipp */
- (1 << 0) /* software reset ipp and mpp */
- );
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, (1 << 1) | /* enable ipp */
- (0 << 0) /* software reset ipp and mpp */
- );
-
- if (get_double_write_mode(hevc) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
- 0x1 << 31 /*/Enable NV21 reference read mode for MC*/
- );
-
-}
-
-static void decoder_hw_reset(void)
-{
- int i;
- unsigned int data32;
-
- /* reset iqit to start mem init again */
- WRITE_VREG(DOS_SW_RESET3, (1 << 14)
- );
- CLEAR_VREG_MASK(HEVC_CABAC_CONTROL, 1);
- CLEAR_VREG_MASK(HEVC_PARSER_CORE_CONTROL, 1);
-
- data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 | (1 << 0) /* stream_fetch_enable */
- ;
- WRITE_VREG(HEVC_STREAM_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- print_scratch_error(29);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- print_scratch_error(30);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- print_scratch_error(31);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- print_scratch_error(32);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
-
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- data32 &= 0x03ffffff;
- data32 = data32 | (3 << 29) | (2 << 26) | (1 << 24)
- | /* stream_buffer_empty_int_amrisc_enable */
- (1 << 22) | /*stream_fifo_empty_int_amrisc_enable */
- (1 << 7) | /* dec_done_int_cpu_enable */
- (1 << 4) | /* startcode_found_int_cpu_enable */
- (0 << 3) | /* startcode_found_int_amrisc_enable */
- (1 << 0) /* parser_int_enable */
- ;
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STATUS);
- data32 = data32 | (1 << 1) | /* emulation_check_on */
- (1 << 0) /* startcode_check_on */
- ;
- WRITE_VREG(HEVC_SHIFT_STATUS, data32);
-
- WRITE_VREG(HEVC_SHIFT_CONTROL, (3 << 6) |/* sft_valid_wr_position */
- (2 << 4) | /* emulate_code_length_sub_1 */
- (2 << 1) | /* start_code_length_sub_1 */
- (1 << 0) /* stream_shift_enable */
- );
-
- WRITE_VREG(HEVC_CABAC_CONTROL, (1 << 0) /* cabac_enable */
- );
- /* hevc_parser_core_clk_en */
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, (1 << 0)
- );
-
- /* Initial IQIT_SCALELUT memory -- just to avoid X in simulation */
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); /* cfg_p_addr */
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
-
- /* Send parser_cmd */
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
-
- parser_cmd_write();
-
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
-
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- /* (1 << 8) | // sao_sw_pred_enable */
- (1 << 5) | /* parser_sao_if_en */
- (1 << 2) | /* parser_mpred_if_en */
- (1 << 0) /* parser_scaler_if_en */
- );
-
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, (0 << 1) | /* enable ipp */
- (1 << 0) /* software reset ipp and mpp */
- );
- WRITE_VREG(HEVCD_IPP_TOP_CNTL, (1 << 1) | /* enable ipp */
- (0 << 0) /* software reset ipp and mpp */
- );
-}
-
-#ifdef CONFIG_HEVC_CLK_FORCED_ON
-static void config_hevc_clk_forced_on(void)
-{
- unsigned int rdata32;
- /* IQIT */
- rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
- WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
-
- /* DBLK */
- rdata32 = READ_VREG(HEVC_DBLK_CFG0);
- WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
-
- /* SAO */
- rdata32 = READ_VREG(HEVC_SAO_CTRL1);
- WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
-
- /* MPRED */
- rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
- WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
-
- /* PARSER */
- rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
- WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
- WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
- WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
- rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- rdata32 | (0x3 << 5) | (0x3 << 2) | (0x3 << 0));
-
- /* IPP */
- rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
- WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
-
- /* MCRCC */
- rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
- WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
-}
-#endif
-
-#ifdef MCRCC_ENABLE
-static void config_mcrcc_axi_hw(struct hevc_state_s *hevc, int slice_type)
-{
- unsigned int rdata32;
- unsigned int rdata32_2;
- int l0_cnt = 0;
- int l1_cnt = 0x7fff;
-
- if (get_double_write_mode(hevc) & 0x10) {
- l0_cnt = hevc->cur_pic->RefNum_L0;
- l1_cnt = hevc->cur_pic->RefNum_L1;
- }
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); /* reset mcrcc */
-
- if (slice_type == 2) { /* I-PIC */
- /* remove reset -- disables clock */
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
- return;
- }
-
- if (slice_type == 0) { /* B-PIC */
- /* Programme canvas0 */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- /* Programme canvas1 */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (1 << 1) | 0);
- rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- if (rdata32 == rdata32_2 && l1_cnt > 1) {
- rdata32_2 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32_2 = rdata32_2 & 0xffff;
- rdata32_2 = rdata32_2 | (rdata32_2 << 16);
- }
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32_2);
- } else { /* P-PIC */
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (1 << 1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- if (l0_cnt == 1) {
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- } else {
- /* Programme canvas1 */
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- }
- }
- /* enable mcrcc progressive-mode */
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);
-}
-#endif
-
-static void config_title_hw(struct hevc_state_s *hevc, int sao_vb_size,
- int sao_mem_unit)
-{
- WRITE_VREG(HEVC_sao_mem_unit, sao_mem_unit);
- WRITE_VREG(HEVC_SAO_ABV, hevc->work_space_buf->sao_abv.buf_start);
- WRITE_VREG(HEVC_sao_vb_size, sao_vb_size);
- WRITE_VREG(HEVC_SAO_VB, hevc->work_space_buf->sao_vb.buf_start);
-}
-
-static u32 init_aux_size;
-static int aux_data_is_avaible(struct hevc_state_s *hevc)
-{
- u32 reg_val;
-
- reg_val = READ_VREG(HEVC_AUX_DATA_SIZE);
- if (reg_val != 0 && reg_val != init_aux_size)
- return 1;
- else
- return 0;
-}
-
-static void config_aux_buf(struct hevc_state_s *hevc)
-{
- WRITE_VREG(HEVC_AUX_ADR, hevc->aux_phy_addr);
- init_aux_size = ((hevc->prefix_aux_size >> 4) << 16) |
- (hevc->suffix_aux_size >> 4);
- WRITE_VREG(HEVC_AUX_DATA_SIZE, init_aux_size);
-}
-
-static void config_mpred_hw(struct hevc_state_s *hevc)
-{
- int i;
- unsigned int data32;
- struct PIC_s *cur_pic = hevc->cur_pic;
- struct PIC_s *col_pic = hevc->col_pic;
- int AMVP_MAX_NUM_CANDS_MEM = 3;
- int AMVP_MAX_NUM_CANDS = 2;
- int NUM_CHROMA_MODE = 5;
- int DM_CHROMA_IDX = 36;
- int above_ptr_ctrl = 0;
- int buffer_linear = 1;
- int cu_size_log2 = 3;
-
- int mpred_mv_rd_start_addr;
- int mpred_curr_lcu_x;
- int mpred_curr_lcu_y;
- int mpred_above_buf_start;
- int mpred_mv_rd_ptr;
- int mpred_mv_rd_ptr_p1;
- int mpred_mv_rd_end_addr;
- int MV_MEM_UNIT;
- int mpred_mv_wr_ptr;
- int *ref_poc_L0, *ref_poc_L1;
-
- int above_en;
- int mv_wr_en;
- int mv_rd_en;
- int col_isIntra;
-
- if (hevc->slice_type != 2) {
- above_en = 1;
- mv_wr_en = 1;
- mv_rd_en = 1;
- col_isIntra = 0;
- } else {
- above_en = 1;
- mv_wr_en = 1;
- mv_rd_en = 0;
- col_isIntra = 0;
- }
-
- mpred_mv_rd_start_addr = col_pic->mpred_mv_wr_start_addr;
- data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
- mpred_curr_lcu_x = data32 & 0xffff;
- mpred_curr_lcu_y = (data32 >> 16) & 0xffff;
-
- MV_MEM_UNIT =
- hevc->lcu_size_log2 == 6 ? 0x200 : hevc->lcu_size_log2 ==
- 5 ? 0x80 : 0x20;
- mpred_mv_rd_ptr =
- mpred_mv_rd_start_addr + (hevc->slice_addr * MV_MEM_UNIT);
-
- mpred_mv_rd_ptr_p1 = mpred_mv_rd_ptr + MV_MEM_UNIT;
- mpred_mv_rd_end_addr =
- mpred_mv_rd_start_addr +
- col_pic->mv_size;
- //((hevc->lcu_x_num * hevc->lcu_y_num) * MV_MEM_UNIT);
-
- mpred_above_buf_start = hevc->work_space_buf->mpred_above.buf_start;
-
- mpred_mv_wr_ptr =
- cur_pic->mpred_mv_wr_start_addr +
- (hevc->slice_addr * MV_MEM_UNIT);
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "cur pic index %d col pic index %d\n", cur_pic->index,
- col_pic->index);
- }
-
- WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
- cur_pic->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR, mpred_mv_rd_start_addr);
-
- data32 = ((hevc->lcu_x_num - hevc->tile_width_lcu) * MV_MEM_UNIT);
- WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP, data32);
- WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP, data32);
-
- data32 = READ_VREG(HEVC_MPRED_CTRL0);
- data32 = ((hevc->slice_type & 3) |
- (hevc->new_pic & 1) << 2 |
- (hevc->new_tile & 1) << 3 |
- (hevc->isNextSliceSegment & 1)<< 4 |
- (hevc->TMVPFlag & 1)<< 5 |
- (hevc->LDCFlag & 1) << 6 |
- (hevc->ColFromL0Flag & 1)<< 7 |
- (above_ptr_ctrl & 1)<< 8 |
- (above_en & 1) << 9 |
- (mv_wr_en & 1) << 10 |
- (mv_rd_en & 1)<< 11 |
- (col_isIntra & 1)<< 12 |
- (buffer_linear & 1)<< 13 |
- (hevc->LongTerm_Curr & 1) << 14 |
- (hevc->LongTerm_Col & 1) << 15 |
- (hevc->lcu_size_log2 & 0xf) << 16 |
- (cu_size_log2 & 0xf) << 20 | (hevc->plevel & 0x7) << 24);
- data32 &= ~(1<< 28);
- WRITE_VREG(HEVC_MPRED_CTRL0, data32);
-
- data32 = READ_VREG(HEVC_MPRED_CTRL1);
- data32 = (
-#if 0
- /* no set in m8baby test1902 */
- /* Don't override clk_forced_on , */
- (data32 & (0x1 << 24)) |
-#endif
- hevc->MaxNumMergeCand |
- AMVP_MAX_NUM_CANDS << 4 |
- AMVP_MAX_NUM_CANDS_MEM << 8 |
- NUM_CHROMA_MODE << 12 | DM_CHROMA_IDX << 16);
- WRITE_VREG(HEVC_MPRED_CTRL1, data32);
-
- data32 = (hevc->pic_w | hevc->pic_h << 16);
- WRITE_VREG(HEVC_MPRED_PIC_SIZE, data32);
-
- data32 = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16);
- WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU, data32);
-
- data32 = (hevc->tile_start_lcu_x | hevc->tile_start_lcu_y << 16);
- WRITE_VREG(HEVC_MPRED_TILE_START, data32);
-
- data32 = (hevc->tile_width_lcu | hevc->tile_height_lcu << 16);
- WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU, data32);
-
- data32 = (hevc->RefNum_L0 | hevc->RefNum_L1 << 8 | 0
- /* col_RefNum_L0<<16| */
- /* col_RefNum_L1<<24 */
- );
- WRITE_VREG(HEVC_MPRED_REF_NUM, data32);
-
-#ifdef SUPPORT_LONG_TERM_RPS
- data32 = 0;
- for (i = 0; i < hevc->RefNum_L0; i++) {
- if (is_ref_long_term(hevc,
- cur_pic->m_aiRefPOCList0
- [cur_pic->slice_idx][i]))
- data32 = data32 | (1 << i);
- }
- for (i = 0; i < hevc->RefNum_L1; i++) {
- if (is_ref_long_term(hevc,
- cur_pic->m_aiRefPOCList1
- [cur_pic->slice_idx][i]))
- data32 = data32 | (1 << (i + 16));
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "LongTerm_Ref 0x%x\n", data32);
- }
-#else
- data32 = hevc->LongTerm_Ref;
-#endif
- WRITE_VREG(HEVC_MPRED_LT_REF, data32);
-
- data32 = 0;
- for (i = 0; i < hevc->RefNum_L0; i++)
- data32 = data32 | (1 << i);
- WRITE_VREG(HEVC_MPRED_REF_EN_L0, data32);
-
- data32 = 0;
- for (i = 0; i < hevc->RefNum_L1; i++)
- data32 = data32 | (1 << i);
- WRITE_VREG(HEVC_MPRED_REF_EN_L1, data32);
-
- WRITE_VREG(HEVC_MPRED_CUR_POC, hevc->curr_POC);
- WRITE_VREG(HEVC_MPRED_COL_POC, hevc->Col_POC);
-
- /* below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 ->
- * Ref_POC_xx_L1 in pair write order!!!
- */
- ref_poc_L0 = &(cur_pic->m_aiRefPOCList0[cur_pic->slice_idx][0]);
- ref_poc_L1 = &(cur_pic->m_aiRefPOCList1[cur_pic->slice_idx][0]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF00_POC, ref_poc_L0[0]);
- WRITE_VREG(HEVC_MPRED_L1_REF00_POC, ref_poc_L1[0]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF01_POC, ref_poc_L0[1]);
- WRITE_VREG(HEVC_MPRED_L1_REF01_POC, ref_poc_L1[1]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF02_POC, ref_poc_L0[2]);
- WRITE_VREG(HEVC_MPRED_L1_REF02_POC, ref_poc_L1[2]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF03_POC, ref_poc_L0[3]);
- WRITE_VREG(HEVC_MPRED_L1_REF03_POC, ref_poc_L1[3]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF04_POC, ref_poc_L0[4]);
- WRITE_VREG(HEVC_MPRED_L1_REF04_POC, ref_poc_L1[4]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF05_POC, ref_poc_L0[5]);
- WRITE_VREG(HEVC_MPRED_L1_REF05_POC, ref_poc_L1[5]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF06_POC, ref_poc_L0[6]);
- WRITE_VREG(HEVC_MPRED_L1_REF06_POC, ref_poc_L1[6]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF07_POC, ref_poc_L0[7]);
- WRITE_VREG(HEVC_MPRED_L1_REF07_POC, ref_poc_L1[7]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF08_POC, ref_poc_L0[8]);
- WRITE_VREG(HEVC_MPRED_L1_REF08_POC, ref_poc_L1[8]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF09_POC, ref_poc_L0[9]);
- WRITE_VREG(HEVC_MPRED_L1_REF09_POC, ref_poc_L1[9]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF10_POC, ref_poc_L0[10]);
- WRITE_VREG(HEVC_MPRED_L1_REF10_POC, ref_poc_L1[10]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF11_POC, ref_poc_L0[11]);
- WRITE_VREG(HEVC_MPRED_L1_REF11_POC, ref_poc_L1[11]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF12_POC, ref_poc_L0[12]);
- WRITE_VREG(HEVC_MPRED_L1_REF12_POC, ref_poc_L1[12]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF13_POC, ref_poc_L0[13]);
- WRITE_VREG(HEVC_MPRED_L1_REF13_POC, ref_poc_L1[13]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF14_POC, ref_poc_L0[14]);
- WRITE_VREG(HEVC_MPRED_L1_REF14_POC, ref_poc_L1[14]);
-
- WRITE_VREG(HEVC_MPRED_L0_REF15_POC, ref_poc_L0[15]);
- WRITE_VREG(HEVC_MPRED_L1_REF15_POC, ref_poc_L1[15]);
-
- if (hevc->new_pic) {
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, mpred_above_buf_start);
- WRITE_VREG(HEVC_MPRED_MV_WPTR, mpred_mv_wr_ptr);
- /* WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr); */
- WRITE_VREG(HEVC_MPRED_MV_RPTR, mpred_mv_rd_start_addr);
- } else if (!hevc->isNextSliceSegment) {
- /* WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1); */
- WRITE_VREG(HEVC_MPRED_MV_RPTR, mpred_mv_rd_ptr);
- }
-
- WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr);
-}
-
-static void config_sao_hw(struct hevc_state_s *hevc, union param_u *params)
-{
- unsigned int data32, data32_2;
- int misc_flag0 = hevc->misc_flag0;
- int slice_deblocking_filter_disabled_flag = 0;
-
- int mc_buffer_size_u_v =
- hevc->lcu_total * hevc->lcu_size * hevc->lcu_size / 2;
- int mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- struct PIC_s *cur_pic = hevc->cur_pic;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- PR_INIT(128);
-
- data32 = READ_VREG(HEVC_SAO_CTRL0);
- data32 &= (~0xf);
- data32 |= hevc->lcu_size_log2;
- WRITE_VREG(HEVC_SAO_CTRL0, data32);
-
- data32 = (hevc->pic_w | hevc->pic_h << 16);
- WRITE_VREG(HEVC_SAO_PIC_SIZE, data32);
-
- data32 = ((hevc->lcu_x_num - 1) | (hevc->lcu_y_num - 1) << 16);
- WRITE_VREG(HEVC_SAO_PIC_SIZE_LCU, data32);
-
- if (hevc->new_pic)
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
-#ifdef LOSLESS_COMPRESS_MODE
-/*SUPPORT_10BIT*/
- if ((get_double_write_mode(hevc) & 0x10) == 0) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 &= (~(0xff << 16));
- if ((get_double_write_mode(hevc) == 8) ||
- (get_double_write_mode(hevc) == 9)) {
- data32 |= (0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else {
- if (get_double_write_mode(hevc) == 2 ||
- get_double_write_mode(hevc) == 3)
- data32 |= (0xff<<16);
- else if (get_double_write_mode(hevc) == 4 ||
- get_double_write_mode(hevc) == 5)
- data32 |= (0x33<<16);
-
- if (hevc->mem_saving_mode == 1)
- data32 |= (1 << 9);
- else
- data32 &= ~(1 << 9);
- if (workaround_enable & 1)
- data32 |= (1 << 7);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
- }
- data32 = cur_pic->mc_y_adr;
- if (get_double_write_mode(hevc))
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
-
- if ((get_double_write_mode(hevc) & 0x10) == 0)
- WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32);
-
- if (hevc->mmu_enable)
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
-#else
- data32 = cur_pic->mc_y_adr;
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, data32);
-#endif
- data32 = (mc_buffer_size_u_v_h << 16) << 1;
- WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
-
-#ifdef LOSLESS_COMPRESS_MODE
-/*SUPPORT_10BIT*/
- if (get_double_write_mode(hevc))
- WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
-#else
- data32 = cur_pic->mc_u_v_adr;
- WRITE_VREG(HEVC_SAO_C_START_ADDR, data32);
-#endif
- data32 = (mc_buffer_size_u_v_h << 16);
- WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
-
- if (hevc->is_used_v4l) {
- WRITE_VREG(HEVC_SAO_Y_LENGTH, cur_pic->luma_size);
- WRITE_VREG(HEVC_SAO_C_LENGTH, cur_pic->chroma_size);
- if (debug & PRINT_FLAG_V4L_DETAIL) {
- pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n",
- v4l2_ctx->id, cur_pic->index,
- cur_pic->dw_y_adr, cur_pic->luma_size,
- cur_pic->dw_u_v_adr, cur_pic->chroma_size);
- }
- }
-
-#ifdef LOSLESS_COMPRESS_MODE
-/*SUPPORT_10BIT*/
- if (get_double_write_mode(hevc)) {
- WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, cur_pic->dw_u_v_adr);
- }
-#else
- /* multi tile to do... */
- data32 = cur_pic->mc_y_adr;
- WRITE_VREG(HEVC_SAO_Y_WPTR, data32);
-
- data32 = cur_pic->mc_u_v_adr;
- WRITE_VREG(HEVC_SAO_C_WPTR, data32);
-#endif
- /* DBLK CONFIG HERE */
- if (hevc->new_pic) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- data32 = (0xff << 8) | (0x0 << 0);
- else
- data32 = (0x57 << 8) | /* 1st/2nd write both enable*/
- (0x0 << 0); /* h265 video format*/
-
- if (hevc->pic_w >= 1280)
- data32 |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
- data32 &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (get_double_write_mode(hevc) == 0)
- data32 |= (0x1 << 8); /*enable first write*/
- else if (get_double_write_mode(hevc) == 0x10)
- data32 |= (0x1 << 9); /*double write only*/
- else
- data32 |= ((0x1 << 8) |(0x1 << 9));
-
- WRITE_VREG(HEVC_DBLK_CFGB, data32);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "[DBLK DEBUG] HEVC1 CFGB : 0x%x\n", data32);
- }
- data32 = (hevc->pic_w | hevc->pic_h << 16);
- WRITE_VREG(HEVC_DBLK_CFG2, data32);
-
- if ((misc_flag0 >> PCM_ENABLE_FLAG_BIT) & 0x1) {
- data32 =
- ((misc_flag0 >>
- PCM_LOOP_FILTER_DISABLED_FLAG_BIT) &
- 0x1) << 3;
- } else
- data32 = 0;
- data32 |=
- (((params->p.pps_cb_qp_offset & 0x1f) << 4) |
- ((params->p.pps_cr_qp_offset
- & 0x1f) <<
- 9));
- data32 |=
- (hevc->lcu_size ==
- 64) ? 0 : ((hevc->lcu_size == 32) ? 1 : 2);
- data32 |= (hevc->pic_w <= 64) ? (1 << 20) : 0;
- WRITE_VREG(HEVC_DBLK_CFG1, data32);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- /*if (debug & 0x80) {*/
- data32 = 1 << 28; /* Debug only: sts1 chooses dblk_main*/
- WRITE_VREG(HEVC_DBLK_STS1 + 4, data32); /* 0x3510 */
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "[DBLK DEBUG] HEVC1 STS1 : 0x%x\n",
- data32);
- /*}*/
- }
- }
-#if 0
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- data32 |= (hevc->mem_map_mode <<
- 12);
-
-/* [13:12] axi_aformat,
- * 0-Linear, 1-32x32, 2-64x32
- */
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- data32 |= (hevc->mem_map_mode <<
- 4);
-
-/* [5:4] -- address_format
- * 00:linear 01:32x32 10:64x32
- */
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#else
- /* m8baby test1902 */
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
- data32 |= (hevc->mem_map_mode << 12);
- data32 &= (~0xff0);
- data32 |= ((hevc->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
- data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
- if (get_double_write_mode(hevc) == 0)
- data32 |= 0x2; /*disable double write*/
- else if (get_double_write_mode(hevc) & 0x10)
- data32 |= 0x1; /*disable cm*/
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned int data;
- data = (0x57 << 8) | /* 1st/2nd write both enable*/
- (0x0 << 0); /* h265 video format*/
- if (hevc->pic_w >= 1280)
- data |= (0x1 << 4); /*dblk pipeline mode=1 for performance*/
- data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (get_double_write_mode(hevc) == 0)
- data |= (0x1 << 8); /*enable first write*/
- else if (get_double_write_mode(hevc) & 0x10)
- data |= (0x1 << 9); /*double write only*/
- else
- data |= ((0x1 << 8) |(0x1 << 9));
-
- WRITE_VREG(HEVC_DBLK_CFGB, data);
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "[DBLK DEBUG] HEVC1 CFGB : 0x%x\n", data);
- }
-
- /* swap uv */
- if (hevc->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
- data32 &= ~(1 << 8); /* NV21 */
- else
- data32 |= (1 << 8); /* NV12 */
- }
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
- if (get_double_write_mode(hevc) & 0x10) {
- /* [23:22] dw_v1_ctrl
- *[21:20] dw_v0_ctrl
- *[19:18] dw_h1_ctrl
- *[17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (hevc->mem_map_mode << 4);
- data32 &= (~0xF);
- data32 |= (hevc->endian & 0xf); /* valid only when double write only */
-
- /* swap uv */
- if (hevc->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
- data32 |= (1 << 12); /* NV21 */
- else
- data32 &= ~(1 << 12); /* NV12 */
- }
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
- data32 = 0;
- data32_2 = READ_VREG(HEVC_SAO_CTRL0);
- data32_2 &= (~0x300);
- /* slice_deblocking_filter_disabled_flag = 0;
- * ucode has handle it , so read it from ucode directly
- */
- if (hevc->tile_enabled) {
- data32 |=
- ((misc_flag0 >>
- LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT) &
- 0x1) << 0;
- data32_2 |=
- ((misc_flag0 >>
- LOOP_FILER_ACROSS_TILES_ENABLED_FLAG_BIT) &
- 0x1) << 8;
- }
- slice_deblocking_filter_disabled_flag = (misc_flag0 >>
- SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) &
- 0x1; /* ucode has handle it,so read it from ucode directly */
- if ((misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_BIT))
- && (misc_flag0 & (1 << DEBLOCKING_FILTER_OVERRIDE_FLAG_BIT))) {
- /* slice_deblocking_filter_disabled_flag =
- * (misc_flag0>>SLICE_DEBLOCKING_FILTER_DISABLED_FLAG_BIT)&0x1;
- * //ucode has handle it , so read it from ucode directly
- */
- data32 |= slice_deblocking_filter_disabled_flag << 2;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(1,%x)", data32);
- if (!slice_deblocking_filter_disabled_flag) {
- data32 |= (params->p.slice_beta_offset_div2 & 0xf) << 3;
- data32 |= (params->p.slice_tc_offset_div2 & 0xf) << 7;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(2,%x)", data32);
- }
- } else {
- data32 |=
- ((misc_flag0 >>
- PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) &
- 0x1) << 2;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(3,%x)", data32);
- if (((misc_flag0 >> PPS_DEBLOCKING_FILTER_DISABLED_FLAG_BIT) &
- 0x1) == 0) {
- data32 |= (params->p.pps_beta_offset_div2 & 0xf) << 3;
- data32 |= (params->p.pps_tc_offset_div2 & 0xf) << 7;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(4,%x)", data32);
- }
- }
- if ((misc_flag0 & (1 << PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT))
- && ((misc_flag0 & (1 << SLICE_SAO_LUMA_FLAG_BIT))
- || (misc_flag0 & (1 << SLICE_SAO_CHROMA_FLAG_BIT))
- || (!slice_deblocking_filter_disabled_flag))) {
- data32 |=
- ((misc_flag0 >>
- SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
- & 0x1) << 1;
- data32_2 |=
- ((misc_flag0 >>
- SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
- & 0x1) << 9;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(5,%x)\n", data32);
- } else {
- data32 |=
- ((misc_flag0 >>
- PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
- & 0x1) << 1;
- data32_2 |=
- ((misc_flag0 >>
- PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG_BIT)
- & 0x1) << 9;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_FILL("(6,%x)\n", data32);
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- PR_INFO(hevc->index);
-
- WRITE_VREG(HEVC_DBLK_CFG9, data32);
- WRITE_VREG(HEVC_SAO_CTRL0, data32_2);
-}
-
-#ifdef TEST_NO_BUF
-static unsigned char test_flag = 1;
-#endif
-
-static void pic_list_process(struct hevc_state_s *hevc)
-{
- int work_pic_num = hevc->used_buf_num;
- int alloc_pic_count = 0;
- int i;
- struct PIC_s *pic;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- alloc_pic_count++;
- if (pic->output_mark == 0 && pic->referenced == 0
- && pic->output_ready == 0
- && (pic->width != hevc->pic_w ||
- pic->height != hevc->pic_h)
- ) {
- set_buf_unused(hevc, pic->BUF_index);
- pic->BUF_index = -1;
- if (alloc_pic_count > work_pic_num) {
- pic->width = 0;
- pic->height = 0;
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- release_pic_mmu_buf(hevc, pic);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- pic->index = -1;
- } else {
- pic->width = hevc->pic_w;
- pic->height = hevc->pic_h;
- }
- }
- }
- if (alloc_pic_count < work_pic_num) {
- int new_count = alloc_pic_count;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic && pic->index == -1) {
- pic->index = i;
- pic->BUF_index = -1;
- pic->width = hevc->pic_w;
- pic->height = hevc->pic_h;
- new_count++;
- if (new_count >=
- work_pic_num)
- break;
- }
- }
-
- }
- dealloc_unused_buf(hevc);
- if (get_alloc_pic_count(hevc)
- != alloc_pic_count) {
- hevc_print_cont(hevc, 0,
- "%s: work_pic_num is %d, Change alloc_pic_count from %d to %d\n",
- __func__,
- work_pic_num,
- alloc_pic_count,
- get_alloc_pic_count(hevc));
- }
-}
-
-static struct PIC_s *get_new_pic(struct hevc_state_s *hevc,
- union param_u *rpm_param)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
- struct PIC_s *new_pic = NULL;
- struct PIC_s *pic;
- int i;
- int ret;
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
-
- if (pic->output_mark == 0 && pic->referenced == 0
- && pic->output_ready == 0
- && pic->width == hevc->pic_w
- && pic->height == hevc->pic_h
- && pic->vf_ref == 0
- ) {
- if (new_pic) {
- if (new_pic->POC != INVALID_POC) {
- if (pic->POC == INVALID_POC ||
- pic->POC < new_pic->POC)
- new_pic = pic;
- }
- } else
- new_pic = pic;
- }
- }
-
- if (new_pic == NULL)
- return NULL;
-
- if (new_pic->BUF_index < 0) {
- if (alloc_buf(hevc) < 0)
- return NULL;
- else {
- if (config_pic(hevc, new_pic) < 0) {
- dealloc_pic_buf(hevc, new_pic);
- return NULL;
- }
- }
- new_pic->width = hevc->pic_w;
- new_pic->height = hevc->pic_h;
- set_canvas(hevc, new_pic);
-
- init_pic_list_hw(hevc);
- }
-
- if (new_pic) {
- new_pic->double_write_mode =
- get_double_write_mode(hevc);
- if (new_pic->double_write_mode)
- set_canvas(hevc, new_pic);
-
-#ifdef TEST_NO_BUF
- if (test_flag) {
- test_flag = 0;
- return NULL;
- } else
- test_flag = 1;
-#endif
- if (get_mv_buf(hevc, new_pic) < 0)
- return NULL;
-
- if (hevc->mmu_enable) {
- ret = H265_alloc_mmu(hevc, new_pic,
- rpm_param->p.bit_depth,
- hevc->frame_mmu_map_addr);
- if (ret != 0) {
- put_mv_buf(hevc, new_pic);
- hevc_print(hevc, 0,
- "can't alloc need mmu1,idx %d ret =%d\n",
- new_pic->decode_idx,
- ret);
- return NULL;
- }
- }
- new_pic->referenced = 1;
- new_pic->decode_idx = hevc->decode_idx;
- new_pic->slice_idx = 0;
- new_pic->referenced = 1;
- new_pic->output_mark = 0;
- new_pic->recon_mark = 0;
- new_pic->error_mark = 0;
- new_pic->dis_mark = 0;
- /* new_pic->output_ready = 0; */
- new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0;
- new_pic->ip_mode = (!new_pic->num_reorder_pic &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
- new_pic->losless_comp_body_size = hevc->losless_comp_body_size;
- new_pic->POC = hevc->curr_POC;
- new_pic->pic_struct = hevc->curr_pic_struct;
- if (new_pic->aux_data_buf)
- release_aux_data(hevc, new_pic);
- new_pic->mem_saving_mode =
- hevc->mem_saving_mode;
- new_pic->bit_depth_luma =
- hevc->bit_depth_luma;
- new_pic->bit_depth_chroma =
- hevc->bit_depth_chroma;
- new_pic->video_signal_type =
- hevc->video_signal_type;
-
- new_pic->conformance_window_flag =
- hevc->param.p.conformance_window_flag;
- new_pic->conf_win_left_offset =
- hevc->param.p.conf_win_left_offset;
- new_pic->conf_win_right_offset =
- hevc->param.p.conf_win_right_offset;
- new_pic->conf_win_top_offset =
- hevc->param.p.conf_win_top_offset;
- new_pic->conf_win_bottom_offset =
- hevc->param.p.conf_win_bottom_offset;
- new_pic->chroma_format_idc =
- hevc->param.p.chroma_format_idc;
-
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s: index %d, buf_idx %d, decode_idx %d, POC %d\n",
- __func__, new_pic->index,
- new_pic->BUF_index, new_pic->decode_idx,
- new_pic->POC);
-
- }
- if (pic_list_debug & 0x1) {
- dump_pic_list(hevc);
- pr_err("\n*******************************************\n");
- }
-
- return new_pic;
-}
-
-static int get_free_fb_idx(struct hevc_state_s *hevc)
-{
- int i;
-
- for (i = 0; i < hevc->used_buf_num; ++i) {
- if (hevc->m_PIC[i] == NULL)
- continue;
-
- if ((hevc->m_PIC[i]->referenced == 0) &&
- (hevc->m_PIC[i]->vf_ref == 0) &&
- (!hevc->m_PIC[i]->cma_alloc_addr))
- break;
- }
-
- return (hevc->m_PIC[i] &&
- (i != hevc->used_buf_num)) ? i : -1;
-}
-
-static struct PIC_s *v4l_get_new_pic(struct hevc_state_s *hevc,
- union param_u *rpm_param)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
- int ret;
- struct aml_vcodec_ctx * v4l = hevc->v4l2_ctx;
- struct v4l_buff_pool *pool = &v4l->cap_pool;
- struct PIC_s *new_pic = NULL;
- struct PIC_s *pic = NULL;
- int i, j, idx;
-
- for (i = 0; i < pool->in; ++i) {
- u32 state = (pool->seq[i] >> 16);
- u32 index = (pool->seq[i] & 0xffff);
-
- switch (state) {
- case V4L_CAP_BUFF_IN_DEC:
- for (j = 0; j < hevc->used_buf_num; j++) {
- pic = hevc->m_PIC[j];
- if (pic == NULL || pic->index == -1)
- continue;
-
- if (pic->output_mark == 0 &&
- pic->referenced == 0 &&
- pic->output_ready == 0 &&
- pic->width == hevc->pic_w &&
- pic->height == hevc->pic_h &&
- pic->vf_ref == 0 &&
- pic->cma_alloc_addr) {
- if (new_pic) {
- if (new_pic->POC != INVALID_POC) {
- if (pic->POC == INVALID_POC ||
- pic->POC < new_pic->POC)
- new_pic = pic;
- }
- } else
- new_pic = pic;
- }
- }
- break;
- case V4L_CAP_BUFF_IN_M2M:
- idx = get_free_fb_idx(hevc);
- if (idx < 0)
- break;
- pic = hevc->m_PIC[idx];
- pic->width = hevc->pic_w;
- pic->height = hevc->pic_h;
- hevc->buffer_wrap[idx] = index;
- if ((pic->index != -1) &&
- !v4l_alloc_buf(hevc, pic)) {
- v4l_config_pic(hevc, pic);
- init_pic_list_hw(hevc);
- new_pic = pic;
- }
- break;
- default:
- break;
- }
-
- if (new_pic)
- break;
- }
-
- if (new_pic == NULL)
- return NULL;
-
- /* for notify eos. */
- if (!rpm_param)
- return new_pic;
-
- new_pic->double_write_mode = get_double_write_mode(hevc);
- if (new_pic->double_write_mode)
- set_canvas(hevc, new_pic);
-
- if (get_mv_buf(hevc, new_pic) < 0)
- return NULL;
-
- if (hevc->mmu_enable) {
- ret = H265_alloc_mmu(hevc, new_pic,
- rpm_param->p.bit_depth,
- hevc->frame_mmu_map_addr);
- if (ret != 0) {
- put_mv_buf(hevc, new_pic);
- hevc_print(hevc, 0,
- "can't alloc need mmu1,idx %d ret =%d\n",
- new_pic->decode_idx, ret);
- return NULL;
- }
- }
-
- new_pic->referenced = 1;
- new_pic->decode_idx = hevc->decode_idx;
- new_pic->slice_idx = 0;
- new_pic->referenced = 1;
- new_pic->output_mark = 0;
- new_pic->recon_mark = 0;
- new_pic->error_mark = 0;
- new_pic->dis_mark = 0;
- /* new_pic->output_ready = 0; */
- new_pic->num_reorder_pic = rpm_param->p.sps_num_reorder_pics_0;
- new_pic->ip_mode = hevc->low_latency_flag ? true :
- (!new_pic->num_reorder_pic &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
- new_pic->losless_comp_body_size = hevc->losless_comp_body_size;
- new_pic->POC = hevc->curr_POC;
- new_pic->pic_struct = hevc->curr_pic_struct;
-
- v4l->aux_infos.bind_sei_buffer(v4l, &new_pic->aux_data_buf,
- &new_pic->aux_data_size, &new_pic->ctx_buf_idx);
-
- new_pic->mem_saving_mode =
- hevc->mem_saving_mode;
- new_pic->bit_depth_luma =
- hevc->bit_depth_luma;
- new_pic->bit_depth_chroma =
- hevc->bit_depth_chroma;
- new_pic->video_signal_type =
- hevc->video_signal_type;
-
- new_pic->conformance_window_flag =
- hevc->param.p.conformance_window_flag;
- new_pic->conf_win_left_offset =
- hevc->param.p.conf_win_left_offset;
- new_pic->conf_win_right_offset =
- hevc->param.p.conf_win_right_offset;
- new_pic->conf_win_top_offset =
- hevc->param.p.conf_win_top_offset;
- new_pic->conf_win_bottom_offset =
- hevc->param.p.conf_win_bottom_offset;
- new_pic->chroma_format_idc =
- hevc->param.p.chroma_format_idc;
-
- if (new_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)new_pic->cma_alloc_addr;
-
- fb->status = FB_ST_DECODER;
- }
-
- hevc_print(hevc, H265_DEBUG_BUFMGR,
- "%s: index %d, buf_idx %d, decode_idx %d, POC %d\n",
- __func__, new_pic->index,
- new_pic->BUF_index, new_pic->decode_idx,
- new_pic->POC);
-
- return new_pic;
-}
-
-static int get_display_pic_num(struct hevc_state_s *hevc)
-{
- int i;
- struct PIC_s *pic;
- int num = 0;
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- pic->index == -1)
- continue;
-
- if (pic->output_ready == 1)
- num++;
- }
- return num;
-}
-
-static void flush_output(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
- struct PIC_s *pic_display;
-
- if (pic) {
- /*PB skip control */
- if (pic->error_mark == 0 && hevc->PB_skip_mode == 1) {
- /* start decoding after first I */
- hevc->ignore_bufmgr_error |= 0x1;
- }
- if (hevc->ignore_bufmgr_error & 1) {
- if (hevc->PB_skip_count_after_decoding > 0)
- hevc->PB_skip_count_after_decoding--;
- else {
- /* start displaying */
- hevc->ignore_bufmgr_error |= 0x2;
- }
- }
- if (pic->POC != INVALID_POC && !pic->ip_mode)
- pic->output_mark = 1;
- pic->recon_mark = 1;
- }
- do {
- pic_display = output_pic(hevc, 1);
-
- if (pic_display) {
- pic_display->referenced = 0;
- put_mv_buf(hevc, pic_display);
- if ((pic_display->error_mark
- && ((hevc->ignore_bufmgr_error & 0x2) == 0))
- || (get_dbg_flag(hevc) &
- H265_DEBUG_DISPLAY_CUR_FRAME)
- || (get_dbg_flag(hevc) &
- H265_DEBUG_NO_DISPLAY)) {
- pic_display->output_ready = 0;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] Display: POC %d, ",
- pic_display->POC);
- hevc_print_cont(hevc, 0,
- "decoding index %d ==> ",
- pic_display->decode_idx);
- hevc_print_cont(hevc, 0,
- "Debug mode or error, recycle it\n");
- }
- /*
- * Here the pic/frame error_mark is 1,
- * and it won't be displayed, so increase
- * the drop count
- */
- hevc->gvs->drop_frame_count++;
- if (pic_display->slice_type == I_SLICE) {
- hevc->gvs->i_lost_frames++;
- } else if (pic_display->slice_type == P_SLICE) {
- hevc->gvs->p_lost_frames++;
- } else if (pic_display->slice_type == B_SLICE) {
- hevc->gvs->b_lost_frames++;
- }
- /* error frame count also need increase */
- hevc->gvs->error_frame_count++;
- if (pic_display->slice_type == I_SLICE) {
- hevc->gvs->i_concealed_frames++;
- } else if (pic_display->slice_type == P_SLICE) {
- hevc->gvs->p_concealed_frames++;
- } else if (pic_display->slice_type == B_SLICE) {
- hevc->gvs->b_concealed_frames++;
- }
- } else {
- if (hevc->i_only & 0x1
- && pic_display->slice_type != 2) {
- pic_display->output_ready = 0;
- } else {
- prepare_display_buf(hw_to_vdec(hevc), pic_display);
- if (get_dbg_flag(hevc)
- & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] flush Display: POC %d, ",
- pic_display->POC);
- hevc_print_cont(hevc, 0,
- "decoding index %d\n",
- pic_display->decode_idx);
- }
- }
- }
- }
- } while (pic_display);
- clear_referenced_flag(hevc);
-}
-
-/*
-* dv_meta_flag: 1, dolby meta only; 2, not include dolby meta
-*/
-static void set_aux_data(struct hevc_state_s *hevc,
- struct PIC_s *pic, unsigned char suffix_flag,
- unsigned char dv_meta_flag)
-{
- int i;
- unsigned short *aux_adr;
- unsigned int size_reg_val =
- READ_VREG(HEVC_AUX_DATA_SIZE);
- unsigned int aux_count = 0;
- int aux_size = 0;
- if (pic == NULL || 0 == aux_data_is_avaible(hevc))
- return;
-
- if (hevc->aux_data_dirty ||
- hevc->m_ins_flag == 0) {
-
- hevc->aux_data_dirty = 0;
- }
-
- if (suffix_flag) {
- aux_adr = (unsigned short *)
- (hevc->aux_addr +
- hevc->prefix_aux_size);
- aux_count =
- ((size_reg_val & 0xffff) << 4)
- >> 1;
- aux_size =
- hevc->suffix_aux_size;
- } else {
- aux_adr =
- (unsigned short *)hevc->aux_addr;
- aux_count =
- ((size_reg_val >> 16) << 4)
- >> 1;
- aux_size =
- hevc->prefix_aux_size;
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- hevc_print(hevc, 0,
- "%s:pic 0x%p old size %d count %d,suf %d dv_flag %d\r\n",
- __func__, pic, pic->aux_data_size,
- aux_count, suffix_flag, dv_meta_flag);
- }
-
- if (aux_count > aux_size) {
- hevc_print(hevc, 0,
- "%s:aux_count(%d) is over size\n", __func__, aux_count);
- aux_count = 0;
- }
- if (aux_size > 0 && aux_count > 0) {
- int heads_size = 0;
-
- for (i = 0; i < aux_count; i++) {
- unsigned char tag = aux_adr[i] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- heads_size += 8;
- else if (dv_meta_flag == 1 && tag == 0x1)
- heads_size += 8;
- else if (dv_meta_flag == 2 && tag != 0x1)
- heads_size += 8;
- }
- }
-
- if (pic->aux_data_buf) {
- unsigned char valid_tag = 0;
- unsigned char *h =
- pic->aux_data_buf +
- pic->aux_data_size;
- unsigned char *p = h + 8;
- int len = 0;
- int padding_len = 0;
-
- for (i = 0; i < aux_count; i += 4) {
- int ii;
- unsigned char tag = aux_adr[i + 3] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- valid_tag = 1;
- else if (dv_meta_flag == 1
- && tag == 0x1)
- valid_tag = 1;
- else if (dv_meta_flag == 2
- && tag != 0x1)
- valid_tag = 1;
- else
- valid_tag = 0;
- if (valid_tag && len > 0) {
- pic->aux_data_size +=
- (len + 8);
- h[0] = (len >> 24)
- & 0xff;
- h[1] = (len >> 16)
- & 0xff;
- h[2] = (len >> 8)
- & 0xff;
- h[3] = (len >> 0)
- & 0xff;
- h[6] =
- (padding_len >> 8)
- & 0xff;
- h[7] = (padding_len)
- & 0xff;
- h += (len + 8);
- p += 8;
- len = 0;
- padding_len = 0;
- }
- if (valid_tag) {
- h[4] = tag;
- h[5] = 0;
- h[6] = 0;
- h[7] = 0;
- }
- }
- if (valid_tag) {
- for (ii = 0; ii < 4; ii++) {
- unsigned short aa =
- aux_adr[i + 3
- - ii];
- *p = aa & 0xff;
- p++;
- len++;
- /*if ((aa >> 8) == 0xff)
- padding_len++;*/
- }
- }
- }
- if (len > 0) {
- pic->aux_data_size += (len + 8);
- h[0] = (len >> 24) & 0xff;
- h[1] = (len >> 16) & 0xff;
- h[2] = (len >> 8) & 0xff;
- h[3] = (len >> 0) & 0xff;
- h[6] = (padding_len >> 8) & 0xff;
- h[7] = (padding_len) & 0xff;
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- PR_INIT(128);
- hevc_print(hevc, 0,
- "aux: (size %d) suffix_flag %d\n",
- pic->aux_data_size, suffix_flag);
- for (i = 0; i < pic->aux_data_size; i++) {
- PR_FILL("%02x ", pic->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
- }
- }
-
-}
-
-static void release_aux_data(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
-#if 0
- if (pic->aux_data_buf) {
- vfree(pic->aux_data_buf);
- if ((run_count[hevc->index] & 63) == 0)
- vm_unmap_aliases();
- }
- pic->aux_data_buf = NULL;
- pic->aux_data_size = 0;
-#endif
-}
-
-static int recycle_mmu_buf_tail(struct hevc_state_s *hevc,
- bool check_dma)
-{
- hevc_print(hevc,
- H265_DEBUG_BUFMGR_MORE,
- "%s pic index %d scatter_alloc %d page_start %d\n",
- "decoder_mmu_box_free_idx_tail",
- hevc->cur_pic->index,
- hevc->cur_pic->scatter_alloc,
- hevc->used_4k_num);
- if (check_dma)
- hevc_mmu_dma_check(hw_to_vdec(hevc));
-
- if (hevc->is_used_v4l) {
- int index = hevc->cur_pic->BUF_index;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hevc, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- hevc->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- hevc->mmu_box,
- hevc->cur_pic->index,
- hevc->used_4k_num);
- }
- hevc->cur_pic->scatter_alloc = 2;
- hevc->used_4k_num = -1;
- return 0;
-}
-
-static inline void hevc_pre_pic(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
-
- /* prev pic */
- /*if (hevc->curr_POC != 0) {*/
- int decoded_poc = hevc->iPrevPOC;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- decoded_poc = hevc->decoded_poc;
- hevc->decoded_poc = INVALID_POC;
- }
-#endif
- if (hevc->m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR
- && hevc->m_nalUnitType !=
- NAL_UNIT_CODED_SLICE_IDR_N_LP) {
- struct PIC_s *pic_display;
-
- pic = get_pic_by_POC(hevc, decoded_poc);
- if (pic && (pic->POC != INVALID_POC)) {
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- /*PB skip control */
- if (pic->error_mark == 0
- && hevc->PB_skip_mode == 1) {
- /* start decoding after
- * first I
- */
- hevc->ignore_bufmgr_error |= 0x1;
- }
- if (hevc->ignore_bufmgr_error & 1) {
- if (hevc->PB_skip_count_after_decoding > 0) {
- hevc->PB_skip_count_after_decoding--;
- } else {
- /* start displaying */
- hevc->ignore_bufmgr_error |= 0x2;
- }
- }
- if (hevc->mmu_enable
- && ((hevc->double_write_mode & 0x10) == 0)) {
- if (!hevc->m_ins_flag) {
- hevc->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
-
- if ((!is_skip_decoding(hevc, pic)) &&
- (hevc->used_4k_num >= 0) &&
- (hevc->cur_pic->scatter_alloc
- == 1)) {
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- recycle_mmu_buf_tail(hevc, true);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
- }
- }
- if (!pic->ip_mode)
- pic->output_mark = 1;
- pic->recon_mark = 1;
- pic->dis_mark = 1;
- if (vdec->mvfrm) {
- pic->frame_size = vdec->mvfrm->frame_size;
- pic->hw_decode_time = (u32)vdec->mvfrm->hw_decode_time;
- }
- }
- do {
- pic_display = output_pic(hevc, 0);
-
- if (pic_display) {
- if ((pic_display->error_mark &&
- ((hevc->ignore_bufmgr_error &
- 0x2) == 0))
- || (get_dbg_flag(hevc) &
- H265_DEBUG_DISPLAY_CUR_FRAME)
- || (get_dbg_flag(hevc) &
- H265_DEBUG_NO_DISPLAY)) {
- pic_display->output_ready = 0;
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] Display: POC %d, ",
- pic_display->POC);
- hevc_print_cont(hevc, 0,
- "decoding index %d ==> ",
- pic_display->
- decode_idx);
- hevc_print_cont(hevc, 0,
- "Debug or err,recycle it\n");
- }
- /*
- * Here the pic/frame error_mark is 1,
- * and it won't be displayed, so increase
- * the drop count
- */
- hevc->gvs->drop_frame_count++;
- if (pic_display->slice_type == I_SLICE) {
- hevc->gvs->i_lost_frames++;
- }else if (pic_display->slice_type == P_SLICE) {
- hevc->gvs->p_lost_frames++;
- } else if (pic_display->slice_type == B_SLICE) {
- hevc->gvs->b_lost_frames++;
- }
- /* error frame count also need increase */
- hevc->gvs->error_frame_count++;
- if (pic_display->slice_type == I_SLICE) {
- hevc->gvs->i_concealed_frames++;
- } else if (pic_display->slice_type == P_SLICE) {
- hevc->gvs->p_concealed_frames++;
- } else if (pic_display->slice_type == B_SLICE) {
- hevc->gvs->b_concealed_frames++;
- }
- } else {
- if (hevc->i_only & 0x1
- && pic_display->
- slice_type != 2) {
- pic_display->output_ready = 0;
- } else {
- prepare_display_buf
- (hw_to_vdec(hevc),
- pic_display);
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] Display: POC %d, ",
- pic_display->POC);
- hevc_print_cont(hevc, 0,
- "decoding index %d\n",
- pic_display->
- decode_idx);
- }
- }
- }
- }
- } while (pic_display);
- } else {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] current pic is IDR, ");
- hevc_print(hevc, 0,
- "clear referenced flag of all buffers\n");
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- dump_pic_list(hevc);
- if (atomic_read(&hevc->vf_pre_count) == 1 &&
- hevc->first_pic_flag == 1) {
- hevc->first_pic_flag = 2;
- pic = NULL;
- }
- else
- pic = get_pic_by_POC(hevc, decoded_poc);
-
- flush_output(hevc, pic);
- }
-
-}
-
-static void check_pic_decoded_error_pre(struct hevc_state_s *hevc,
- int decoded_lcu)
-{
- int current_lcu_idx = decoded_lcu;
- if (decoded_lcu < 0)
- return;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "cur lcu idx = %d, (total %d)\n",
- current_lcu_idx, hevc->lcu_total);
- }
- if ((error_handle_policy & 0x20) == 0 && hevc->cur_pic != NULL) {
- if (hevc->first_pic_after_recover) {
- if (current_lcu_idx !=
- ((hevc->lcu_x_num_pre*hevc->lcu_y_num_pre) - 1))
- hevc->cur_pic->error_mark = 1;
- } else {
- if (hevc->lcu_x_num_pre != 0
- && hevc->lcu_y_num_pre != 0
- && current_lcu_idx != 0
- && current_lcu_idx <
- ((hevc->lcu_x_num_pre*hevc->lcu_y_num_pre) - 1))
- hevc->cur_pic->error_mark = 1;
- }
- if (hevc->cur_pic->error_mark) {
- if (print_lcu_error)
- hevc_print(hevc, 0,
- "cur lcu idx = %d, (total %d), set error_mark\n",
- current_lcu_idx,
- hevc->lcu_x_num_pre*hevc->lcu_y_num_pre);
- if (is_log_enable(hevc))
- add_log(hevc,
- "cur lcu idx = %d, (total %d), set error_mark",
- current_lcu_idx,
- hevc->lcu_x_num_pre *
- hevc->lcu_y_num_pre);
-
- }
-
- }
- if (hevc->cur_pic && hevc->head_error_flag) {
- hevc->cur_pic->error_mark = 1;
- hevc_print(hevc, 0,
- "head has error, set error_mark\n");
- }
-
- if ((error_handle_policy & 0x80) == 0) {
- if (hevc->over_decode && hevc->cur_pic) {
- hevc_print(hevc, 0,
- "over decode, set error_mark\n");
- hevc->cur_pic->error_mark = 1;
- }
- }
-
- hevc->lcu_x_num_pre = hevc->lcu_x_num;
- hevc->lcu_y_num_pre = hevc->lcu_y_num;
-}
-
-static void check_pic_decoded_error(struct hevc_state_s *hevc,
- int decoded_lcu)
-{
- int current_lcu_idx = decoded_lcu;
- if (decoded_lcu < 0)
- return;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "cur lcu idx = %d, (total %d)\n",
- current_lcu_idx, hevc->lcu_total);
- }
- if ((error_handle_policy & 0x20) == 0 && hevc->cur_pic != NULL) {
- if (hevc->lcu_x_num != 0
- && hevc->lcu_y_num != 0
- && current_lcu_idx != 0
- && current_lcu_idx <
- ((hevc->lcu_x_num*hevc->lcu_y_num) - 1))
- hevc->cur_pic->error_mark = 1;
-
- if (hevc->cur_pic->error_mark) {
- if (print_lcu_error)
- hevc_print(hevc, 0,
- "cur lcu idx = %d, (total %d), set error_mark\n",
- current_lcu_idx,
- hevc->lcu_x_num*hevc->lcu_y_num);
- if (((hevc->i_only & 0x4) == 0) && hevc->cur_pic->POC && ( hevc->cur_pic->slice_type == 0)
- && ((hevc->cur_pic->POC + MAX_BUF_NUM) < hevc->iPrevPOC)) {
- hevc_print(hevc, 0,
- "Flush.. num_reorder_pic %d pic->POC %d hevc->iPrevPOC %d\n",
- hevc->sps_num_reorder_pics_0,hevc->cur_pic->POC ,hevc->iPrevPOC);
- flush_output(hevc, get_pic_by_POC(hevc, hevc->cur_pic->POC ));
- }
- if (is_log_enable(hevc))
- add_log(hevc,
- "cur lcu idx = %d, (total %d), set error_mark",
- current_lcu_idx,
- hevc->lcu_x_num *
- hevc->lcu_y_num);
-
- }
-
- }
- if (hevc->cur_pic && hevc->head_error_flag) {
- hevc->cur_pic->error_mark = 1;
- hevc_print(hevc, 0,
- "head has error, set error_mark\n");
- }
-
- if ((error_handle_policy & 0x80) == 0) {
- if (hevc->over_decode && hevc->cur_pic) {
- hevc_print(hevc, 0,
- "over decode, set error_mark\n");
- hevc->cur_pic->error_mark = 1;
- }
- }
-}
-
-/* only when we decoded one field or one frame,
-we can call this function to get qos info*/
-static void get_picture_qos_info(struct hevc_state_s *hevc)
-{
- struct PIC_s *picture = hevc->cur_pic;
-
-/*
-#define DEBUG_QOS
-*/
-
- if (!hevc->cur_pic)
- return;
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
-
- data = READ_VREG(HEVC_MV_INFO);
- if (picture->slice_type == I_SLICE)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_mv = a[2];
- picture->avg_mv = a[1];
- picture->min_mv = a[0];
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
-
- data = READ_VREG(HEVC_QP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_qp = a[2];
- picture->avg_qp = a[1];
- picture->min_qp = a[0];
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
-
- data = READ_VREG(HEVC_SKIP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++)
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- picture->max_skip = a[2];
- picture->avg_skip = a[1];
- picture->min_skip = a[0];
-
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-#endif
- } else {
- uint32_t blk88_y_count;
- uint32_t blk88_c_count;
- uint32_t blk22_mv_count;
- uint32_t rdata32;
- int32_t mv_hi;
- int32_t mv_lo;
- uint32_t rdata32_l;
- uint32_t mvx_L0_hi;
- uint32_t mvy_L0_hi;
- uint32_t mvx_L1_hi;
- uint32_t mvy_L1_hi;
- int64_t value;
- uint64_t temp_value;
-#ifdef DEBUG_QOS
- int pic_number = picture->POC;
-#endif
-
- picture->max_mv = 0;
- picture->avg_mv = 0;
- picture->min_mv = 0;
-
- picture->max_skip = 0;
- picture->avg_skip = 0;
- picture->min_skip = 0;
-
- picture->max_qp = 0;
- picture->avg_qp = 0;
- picture->min_qp = 0;
-
-
-
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "slice_type:%d, poc:%d\n",
- picture->slice_type,
- picture->POC);
-#endif
- /* set rd_idx to 0 */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0);
-
- blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_y_count == 0) {
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_y_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_y_count,
- rdata32, blk88_y_count);
-#endif
- picture->avg_qp = rdata32/blk88_y_count;
- /* intra_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] Y intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- /* skipped_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-#endif
- picture->avg_skip = rdata32*100/blk88_y_count;
- /* coeff_non_zero_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_y_count*1)),
- '%', rdata32);
-#endif
- /* blk66_c_count */
- blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_c_count == 0) {
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_c_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] C QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_c_count,
- rdata32, blk88_c_count);
-#endif
- /* intra_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] C intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* skipped_cu_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] C skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-#endif
- /* coeff_non_zero_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_c_count*1)),
- '%', rdata32);
-#endif
-
- /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
- 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "[Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
-#endif
- picture->min_qp = (rdata32>>0)&0xff;
-
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "[Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
-#endif
- picture->max_qp = (rdata32>>8)&0xff;
-
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "[Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
- hevc_print(hevc, 0, "[Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
-#endif
-
- /* blk22_mv_count */
- blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk22_mv_count == 0) {
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] NO MV Data yet.\n",
- pic_number);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* mvy_L1_count[39:32], mvx_L1_count[39:32],
- mvy_L0_count[39:32], mvx_L0_count[39:32] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- /* should all be 0x00 or 0xff */
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] MV AVG High Bits: 0x%X\n",
- pic_number, rdata32);
-#endif
- mvx_L0_hi = ((rdata32>>0)&0xff);
- mvy_L0_hi = ((rdata32>>8)&0xff);
- mvx_L1_hi = ((rdata32>>16)&0xff);
- mvy_L1_hi = ((rdata32>>24)&0xff);
-
- /* mvx_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvx_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
- value = div_s64(value, blk22_mv_count);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
- pic_number, (int)value,
- value, blk22_mv_count);
-#endif
- picture->avg_mv = value;
-
- /* mvy_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvy_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvx_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvx_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* mvy_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvy_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-#endif
-
- /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "[Picture %d Quality] MVX_L0 MAX : %d\n",
- pic_number, mv_hi);
-#endif
- picture->max_mv = mv_hi;
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0, "[Picture %d Quality] MVX_L0 MIN : %d\n",
- pic_number, mv_lo);
-#endif
- picture->min_mv = mv_lo;
-
-#ifdef DEBUG_QOS
- /* {mvy_L0_max, mvy_L0_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
- hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- hevc_print(hevc, 0, "[Picture %d Quality] MVY_L0 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvx_L1_max, mvx_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MAX : %d\n",
- pic_number, mv_hi);
-
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- hevc_print(hevc, 0, "[Picture %d Quality] MVX_L1 MIN : %d\n",
- pic_number, mv_lo);
-
-
- /* {mvy_L1_max, mvy_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- hevc_print(hevc, 0, "[Picture %d Quality] MVY_L1 MIN : %d\n",
- pic_number, mv_lo);
-#endif
-
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL);
-#ifdef DEBUG_QOS
- hevc_print(hevc, 0,
- "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
- pic_number, rdata32);
-#endif
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- }
-}
-
-static int hevc_slice_segment_header_process(struct hevc_state_s *hevc,
- union param_u *rpm_param,
- int decode_pic_begin)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hevc);
-#endif
- int i;
- int lcu_x_num_div;
- int lcu_y_num_div;
- int Col_ref;
- int dbg_skip_flag = 0;
-
- if (hevc->wait_buf == 0) {
- hevc->sps_num_reorder_pics_0 =
- rpm_param->p.sps_num_reorder_pics_0;
- hevc->ip_mode = (!hevc->sps_num_reorder_pics_0 &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
- hevc->m_temporalId = rpm_param->p.m_temporalId;
- hevc->m_nalUnitType = rpm_param->p.m_nalUnitType;
- hevc->interlace_flag =
- (rpm_param->p.profile_etc >> 2) & 0x1;
- hevc->curr_pic_struct =
- (rpm_param->p.sei_frame_field_info >> 3) & 0xf;
-
- hevc->frame_field_info_present_flag =
- (rpm_param->p.sei_frame_field_info >> 8) & 0x1;
-
- if (hevc->frame_field_info_present_flag) {
- if (hevc->curr_pic_struct == 0
- || hevc->curr_pic_struct == 7
- || hevc->curr_pic_struct == 8)
- hevc->interlace_flag = 0;
- }
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "frame_field_info_present_flag = %d curr_pic_struct = %d interlace_flag = %d\n",
- hevc->frame_field_info_present_flag,
- hevc->curr_pic_struct,
- hevc->interlace_flag);
-
- /* if (interlace_enable == 0 || hevc->m_ins_flag) */
- if (interlace_enable == 0)
- hevc->interlace_flag = 0;
- if (interlace_enable & 0x100)
- hevc->interlace_flag = interlace_enable & 0x1;
- if (hevc->interlace_flag == 0)
- hevc->curr_pic_struct = 0;
- /* if(hevc->m_nalUnitType == NAL_UNIT_EOS){ */
- /*
- *hevc->m_pocRandomAccess = MAX_INT;
- * //add to fix RAP_B_Bossen_1
- */
- /* } */
- hevc->misc_flag0 = rpm_param->p.misc_flag0;
- if (rpm_param->p.first_slice_segment_in_pic_flag == 0) {
- hevc->slice_segment_addr =
- rpm_param->p.slice_segment_address;
- if (!rpm_param->p.dependent_slice_segment_flag)
- hevc->slice_addr = hevc->slice_segment_addr;
- } else {
- hevc->slice_segment_addr = 0;
- hevc->slice_addr = 0;
- }
-
- hevc->iPrevPOC = hevc->curr_POC;
- hevc->slice_type = (rpm_param->p.slice_type == I_SLICE) ? 2 :
- (rpm_param->p.slice_type == P_SLICE) ? 1 :
- (rpm_param->p.slice_type == B_SLICE) ? 0 : 3;
- /* hevc->curr_predFlag_L0=(hevc->slice_type==2) ? 0:1; */
- /* hevc->curr_predFlag_L1=(hevc->slice_type==0) ? 1:0; */
- hevc->TMVPFlag = rpm_param->p.slice_temporal_mvp_enable_flag;
- hevc->isNextSliceSegment =
- rpm_param->p.dependent_slice_segment_flag ? 1 : 0;
- if (is_oversize_ex(rpm_param->p.pic_width_in_luma_samples,
- rpm_param->p.pic_height_in_luma_samples)) {
- hevc_print(hevc, 0, "over size : %u x %u.\n",
- rpm_param->p.pic_width_in_luma_samples, rpm_param->p.pic_height_in_luma_samples);
- if ((!hevc->m_ins_flag) &&
- ((debug &
- H265_NO_CHANG_DEBUG_FLAG_IN_CODE) == 0))
- debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC |
- H265_DEBUG_DIS_SYS_ERROR_PROC);
- return 3;
- }
-
- if (hevc->pic_w != rpm_param->p.pic_width_in_luma_samples
- || hevc->pic_h !=
- rpm_param->p.pic_height_in_luma_samples) {
- hevc_print(hevc, 0,
- "Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n",
- hevc->pic_w, hevc->pic_h,
- rpm_param->p.pic_width_in_luma_samples,
- rpm_param->p.pic_height_in_luma_samples,
- hevc->interlace_flag);
-
- hevc->pic_w = rpm_param->p.pic_width_in_luma_samples;
- hevc->pic_h = rpm_param->p.pic_height_in_luma_samples;
- hevc->frame_width = hevc->pic_w;
- hevc->frame_height = hevc->pic_h;
-#ifdef LOSLESS_COMPRESS_MODE
- if (/*re_config_pic_flag == 0 &&*/
- (get_double_write_mode(hevc) & 0x10) == 0)
- init_decode_head_hw(hevc);
-#endif
- }
-
- if (hevc->bit_depth_chroma > 10 ||
- hevc->bit_depth_luma > 10) {
- hevc_print(hevc, 0, "unsupport bitdepth : %u,%u\n",
- hevc->bit_depth_chroma,
- hevc->bit_depth_luma);
- if (!hevc->m_ins_flag)
- debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC |
- H265_DEBUG_DIS_SYS_ERROR_PROC);
- hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- return 4;
- }
-
- /* it will cause divide 0 error */
- if (hevc->pic_w == 0 || hevc->pic_h == 0) {
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "Fatal Error, pic_w = %d, pic_h = %d\n",
- hevc->pic_w, hevc->pic_h);
- }
- return 3;
- }
- pic_list_process(hevc);
-
- hevc->lcu_size =
- 1 << (rpm_param->p.log2_min_coding_block_size_minus3 +
- 3 + rpm_param->
- p.log2_diff_max_min_coding_block_size);
- if (hevc->lcu_size == 0) {
- hevc_print(hevc, 0,
- "Error, lcu_size = 0 (%d,%d)\n",
- rpm_param->p.
- log2_min_coding_block_size_minus3,
- rpm_param->p.
- log2_diff_max_min_coding_block_size);
- return 3;
- }
- hevc->lcu_size_log2 = log2i(hevc->lcu_size);
- lcu_x_num_div = (hevc->pic_w / hevc->lcu_size);
- lcu_y_num_div = (hevc->pic_h / hevc->lcu_size);
- hevc->lcu_x_num =
- ((hevc->pic_w % hevc->lcu_size) ==
- 0) ? lcu_x_num_div : lcu_x_num_div + 1;
- hevc->lcu_y_num =
- ((hevc->pic_h % hevc->lcu_size) ==
- 0) ? lcu_y_num_div : lcu_y_num_div + 1;
- hevc->lcu_total = hevc->lcu_x_num * hevc->lcu_y_num;
-
- if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_IDR_N_LP) {
- hevc->curr_POC = 0;
- if ((hevc->m_temporalId - 1) == 0)
- hevc->iPrevTid0POC = hevc->curr_POC;
- } else {
- int iMaxPOClsb =
- 1 << (rpm_param->p.
- log2_max_pic_order_cnt_lsb_minus4 + 4);
- int iPrevPOClsb;
- int iPrevPOCmsb;
- int iPOCmsb;
- int iPOClsb = rpm_param->p.POClsb;
-
- if (iMaxPOClsb == 0) {
- hevc_print(hevc, 0,
- "error iMaxPOClsb is 0\n");
- return 3;
- }
-
- iPrevPOClsb = hevc->iPrevTid0POC % iMaxPOClsb;
- iPrevPOCmsb = hevc->iPrevTid0POC - iPrevPOClsb;
-
- if ((iPOClsb < iPrevPOClsb)
- && ((iPrevPOClsb - iPOClsb) >=
- (iMaxPOClsb / 2)))
- iPOCmsb = iPrevPOCmsb + iMaxPOClsb;
- else if ((iPOClsb > iPrevPOClsb)
- && ((iPOClsb - iPrevPOClsb) >
- (iMaxPOClsb / 2)))
- iPOCmsb = iPrevPOCmsb - iMaxPOClsb;
- else
- iPOCmsb = iPrevPOCmsb;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "iPrePOC%d iMaxPOClsb%d iPOCmsb%d iPOClsb%d\n",
- hevc->iPrevTid0POC, iMaxPOClsb, iPOCmsb,
- iPOClsb);
- }
- if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLANT
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLA_N_LP) {
- /* For BLA picture types, POCmsb is set to 0. */
- iPOCmsb = 0;
- }
- hevc->curr_POC = (iPOCmsb + iPOClsb);
- if ((hevc->m_temporalId - 1) == 0)
- hevc->iPrevTid0POC = hevc->curr_POC;
- else {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "m_temporalID is %d\n",
- hevc->m_temporalId);
- }
- }
- }
- hevc->RefNum_L0 =
- (rpm_param->p.num_ref_idx_l0_active >
- MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : rpm_param->p.
- num_ref_idx_l0_active;
- hevc->RefNum_L1 =
- (rpm_param->p.num_ref_idx_l1_active >
- MAX_REF_ACTIVE) ? MAX_REF_ACTIVE : rpm_param->p.
- num_ref_idx_l1_active;
-
- /* if(curr_POC==0x10) dump_lmem(); */
-
- /* skip RASL pictures after CRA/BLA pictures */
- if (hevc->m_pocRandomAccess == MAX_INT) {/* first picture */
- if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_CRA ||
- hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLANT
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLA_N_LP)
- hevc->m_pocRandomAccess = hevc->curr_POC;
- else
- hevc->m_pocRandomAccess = -MAX_INT;
- } else if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLANT
- || hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_BLA_N_LP)
- hevc->m_pocRandomAccess = hevc->curr_POC;
- else if ((hevc->curr_POC < hevc->m_pocRandomAccess) &&
- (nal_skip_policy >= 3) &&
- (hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_RASL_N ||
- hevc->m_nalUnitType ==
- NAL_UNIT_CODED_SLICE_TFD)) { /* skip */
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "RASL picture with POC %d < %d ",
- hevc->curr_POC, hevc->m_pocRandomAccess);
- hevc_print(hevc, 0,
- "RandomAccess point POC), skip it\n");
- }
- return 1;
- }
-
- WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) | 0x2);
- hevc->skip_flag = 0;
- /**/
- /* if((iPrevPOC != curr_POC)){ */
- if (rpm_param->p.slice_segment_address == 0) {
- struct PIC_s *pic = NULL;
-
- hevc->new_pic = 1;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hevc->m_ins_flag)
-#endif
- check_pic_decoded_error_pre(hevc,
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff);
- if (vdec_stream_based(vdec) && ((READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff) != 0)) {
- if (hevc->cur_pic)
- hevc->cur_pic->error_mark = 1;
- }
- /**/ if (use_cma == 0) {
- if (hevc->pic_list_init_flag == 0) {
- init_pic_list(hevc);
- init_pic_list_hw(hevc);
- init_buf_spec(hevc);
- hevc->pic_list_init_flag = 3;
- }
- }
- if (!hevc->m_ins_flag) {
- if (hevc->cur_pic)
- get_picture_qos_info(hevc);
- }
- hevc->first_pic_after_recover = 0;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- dump_pic_list(hevc);
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master) {
- struct hevc_state_s *hevc_ba =
- (struct hevc_state_s *)
- vdec->master->private;
- if (hevc_ba->cur_pic != NULL) {
- hevc_ba->cur_pic->dv_enhance_exist = 1;
- hevc_print(hevc, H265_DEBUG_DV,
- "To decode el (poc %d) => set bl (poc %d) dv_enhance_exist flag\n",
- hevc->curr_POC, hevc_ba->cur_pic->POC);
- }
- }
- if (vdec->master == NULL &&
- vdec->slave == NULL)
- set_aux_data(hevc,
- hevc->cur_pic, 1, 0); /*suffix*/
- if (hevc->bypass_dvenl && !dolby_meta_with_el)
- set_aux_data(hevc,
- hevc->cur_pic, 0, 1); /*dv meta only*/
-#else
- set_aux_data(hevc, hevc->cur_pic, 1, 0);
-#endif
-
- /* prev pic */
- hevc_pre_pic(hevc, pic);
- /*
- *update referenced of old pictures
- *(cur_pic->referenced is 1 and not updated)
- */
- apply_ref_pic_set(hevc, hevc->curr_POC,
- rpm_param);
-
- /*if (hevc->mmu_enable)
- recycle_mmu_bufs(hevc);*/
-
- /* new pic */
- hevc->cur_pic = hevc->is_used_v4l ?
- v4l_get_new_pic(hevc, rpm_param) :
- get_new_pic(hevc, rpm_param);
- if (hevc->cur_pic == NULL) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- dump_pic_list(hevc);
- hevc->wait_buf = 1;
- return -1;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- hevc->decoding_pic = hevc->cur_pic;
- if (!hevc->m_ins_flag)
- hevc->over_decode = 0;
-#endif
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hevc->cur_pic->dv_enhance_exist = 0;
- if (vdec->slave)
- hevc_print(hevc, H265_DEBUG_DV,
- "Clear bl (poc %d) dv_enhance_exist flag\n",
- hevc->curr_POC);
- if (vdec->master == NULL &&
- vdec->slave == NULL)
- set_aux_data(hevc,
- hevc->cur_pic, 0, 0); /*prefix*/
-
- if (hevc->bypass_dvenl && !dolby_meta_with_el)
- set_aux_data(hevc,
- hevc->cur_pic, 0, 2); /*pre sei only*/
-#else
- set_aux_data(hevc, hevc->cur_pic, 0, 0);
-#endif
- if (get_dbg_flag(hevc) & H265_DEBUG_DISPLAY_CUR_FRAME) {
- hevc->cur_pic->output_ready = 1;
- hevc->cur_pic->stream_offset =
- READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- prepare_display_buf(vdec, hevc->cur_pic);
- hevc->wait_buf = 2;
- return -1;
- }
- } else {
- if (get_dbg_flag(hevc) & H265_DEBUG_HAS_AUX_IN_SLICE) {
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (vdec->master == NULL &&
- vdec->slave == NULL) {
- set_aux_data(hevc, hevc->cur_pic, 1, 0);
- set_aux_data(hevc, hevc->cur_pic, 0, 0);
- }
-#else
- set_aux_data(hevc, hevc->cur_pic, 1, 0);
- set_aux_data(hevc, hevc->cur_pic, 0, 0);
-#endif
- }
- if (hevc->pic_list_init_flag != 3
- || hevc->cur_pic == NULL) {
- /* make it dec from the first slice segment */
- return 3;
- }
- hevc->cur_pic->slice_idx++;
- hevc->new_pic = 0;
- }
- } else {
- if (hevc->wait_buf == 1) {
- pic_list_process(hevc);
-
- hevc->cur_pic = hevc->is_used_v4l ?
- v4l_get_new_pic(hevc, rpm_param) :
- get_new_pic(hevc, rpm_param);
- if (hevc->cur_pic == NULL)
- return -1;
-
- if (!hevc->m_ins_flag)
- hevc->over_decode = 0;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hevc->cur_pic->dv_enhance_exist = 0;
- if (vdec->master == NULL &&
- vdec->slave == NULL)
- set_aux_data(hevc, hevc->cur_pic, 0, 0);
-#else
- set_aux_data(hevc, hevc->cur_pic, 0, 0);
-#endif
- hevc->wait_buf = 0;
- } else if (hevc->wait_buf ==
- 2) {
- if (get_display_pic_num(hevc) >
- 1)
- return -1;
- hevc->wait_buf = 0;
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- dump_pic_list(hevc);
- }
-
- if (hevc->new_pic) {
-#if 1
- /*SUPPORT_10BIT*/
- int sao_mem_unit =
- (hevc->lcu_size == 16 ? 9 :
- hevc->lcu_size ==
- 32 ? 14 : 24) << 4;
-#else
- int sao_mem_unit = ((hevc->lcu_size / 8) * 2 + 4) << 4;
-#endif
- int pic_height_cu =
- (hevc->pic_h + hevc->lcu_size - 1) / hevc->lcu_size;
- int pic_width_cu =
- (hevc->pic_w + hevc->lcu_size - 1) / hevc->lcu_size;
- int sao_vb_size = (sao_mem_unit + (2 << 4)) * pic_height_cu;
-
- /* int sao_abv_size = sao_mem_unit*pic_width_cu; */
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "==>%s dec idx %d, struct %d interlace %d pic idx %d\n",
- __func__,
- hevc->decode_idx,
- hevc->curr_pic_struct,
- hevc->interlace_flag,
- hevc->cur_pic->index);
- }
- if (dbg_skip_decode_index != 0 &&
- hevc->decode_idx == dbg_skip_decode_index)
- dbg_skip_flag = 1;
-
- hevc->decode_idx++;
- update_tile_info(hevc, pic_width_cu, pic_height_cu,
- sao_mem_unit, rpm_param);
-
- config_title_hw(hevc, sao_vb_size, sao_mem_unit);
- }
-
- if (hevc->iPrevPOC != hevc->curr_POC) {
- hevc->new_tile = 1;
- hevc->tile_x = 0;
- hevc->tile_y = 0;
- hevc->tile_y_x = 0;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "new_tile (new_pic) tile_x=%d, tile_y=%d\n",
- hevc->tile_x, hevc->tile_y);
- }
- } else if (hevc->tile_enabled) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "slice_segment_address is %d\n",
- rpm_param->p.slice_segment_address);
- }
- hevc->tile_y_x =
- get_tile_index(hevc, rpm_param->p.slice_segment_address,
- (hevc->pic_w +
- hevc->lcu_size -
- 1) / hevc->lcu_size);
- if ((hevc->tile_y_x != (hevc->tile_x | (hevc->tile_y << 8)))
- && (hevc->tile_y_x != -1)) {
- hevc->new_tile = 1;
- hevc->tile_x = hevc->tile_y_x & 0xff;
- hevc->tile_y = (hevc->tile_y_x >> 8) & 0xff;
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "new_tile seg adr %d tile_x=%d, tile_y=%d\n",
- rpm_param->p.slice_segment_address,
- hevc->tile_x, hevc->tile_y);
- }
- } else
- hevc->new_tile = 0;
- } else
- hevc->new_tile = 0;
-
- if ((hevc->tile_x > (MAX_TILE_COL_NUM - 1))
- || (hevc->tile_y > (MAX_TILE_ROW_NUM - 1)))
- hevc->new_tile = 0;
-
- if (hevc->new_tile) {
- hevc->tile_start_lcu_x =
- hevc->m_tile[hevc->tile_y][hevc->tile_x].start_cu_x;
- hevc->tile_start_lcu_y =
- hevc->m_tile[hevc->tile_y][hevc->tile_x].start_cu_y;
- hevc->tile_width_lcu =
- hevc->m_tile[hevc->tile_y][hevc->tile_x].width;
- hevc->tile_height_lcu =
- hevc->m_tile[hevc->tile_y][hevc->tile_x].height;
- }
-
- set_ref_pic_list(hevc, rpm_param);
-
- Col_ref = rpm_param->p.collocated_ref_idx;
-
- hevc->LDCFlag = 0;
- if (rpm_param->p.slice_type != I_SLICE) {
- hevc->LDCFlag = 1;
- for (i = 0; (i < hevc->RefNum_L0) && hevc->LDCFlag; i++) {
- if (hevc->cur_pic->
- m_aiRefPOCList0[hevc->cur_pic->slice_idx][i] >
- hevc->curr_POC)
- hevc->LDCFlag = 0;
- }
- if (rpm_param->p.slice_type == B_SLICE) {
- for (i = 0; (i < hevc->RefNum_L1)
- && hevc->LDCFlag; i++) {
- if (hevc->cur_pic->
- m_aiRefPOCList1[hevc->cur_pic->
- slice_idx][i] >
- hevc->curr_POC)
- hevc->LDCFlag = 0;
- }
- }
- }
-
- hevc->ColFromL0Flag = rpm_param->p.collocated_from_l0_flag;
-
- hevc->plevel =
- rpm_param->p.log2_parallel_merge_level;
- hevc->MaxNumMergeCand = 5 - rpm_param->p.five_minus_max_num_merge_cand;
-
- hevc->LongTerm_Curr = 0; /* to do ... */
- hevc->LongTerm_Col = 0; /* to do ... */
-
- hevc->list_no = 0;
- if (rpm_param->p.slice_type == B_SLICE)
- hevc->list_no = 1 - hevc->ColFromL0Flag;
- if (hevc->list_no == 0) {
- if (Col_ref < hevc->RefNum_L0) {
- hevc->Col_POC =
- hevc->cur_pic->m_aiRefPOCList0[hevc->cur_pic->
- slice_idx][Col_ref];
- } else
- hevc->Col_POC = INVALID_POC;
- } else {
- if (Col_ref < hevc->RefNum_L1) {
- hevc->Col_POC =
- hevc->cur_pic->m_aiRefPOCList1[hevc->cur_pic->
- slice_idx][Col_ref];
- } else
- hevc->Col_POC = INVALID_POC;
- }
-
- hevc->LongTerm_Ref = 0; /* to do ... */
-
- if (hevc->slice_type != 2) {
- /* if(hevc->i_only==1){ */
- /* return 0xf; */
- /* } */
-
- if (hevc->Col_POC != INVALID_POC) {
- hevc->col_pic = get_ref_pic_by_POC(hevc, hevc->Col_POC);
- if (hevc->col_pic == NULL) {
- hevc->cur_pic->error_mark = 1;
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "WRONG,fail to get the pic Col_POC\n");
- }
- if (is_log_enable(hevc))
- add_log(hevc,
- "WRONG,fail to get the pic Col_POC");
- } else if (hevc->col_pic->error_mark || hevc->col_pic->dis_mark == 0) {
- hevc->col_pic->error_mark = 1;
- hevc->cur_pic->error_mark = 1;
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "WRONG, Col_POC error_mark is 1\n");
- }
- if (is_log_enable(hevc))
- add_log(hevc,
- "WRONG, Col_POC error_mark is 1");
- } else {
- if ((hevc->col_pic->width
- != hevc->pic_w) ||
- (hevc->col_pic->height
- != hevc->pic_h)) {
- hevc_print(hevc, 0,
- "Wrong reference pic (poc %d) width/height %d/%d\n",
- hevc->col_pic->POC,
- hevc->col_pic->width,
- hevc->col_pic->height);
- hevc->cur_pic->error_mark = 1;
- }
-
- }
-
- if (hevc->cur_pic->error_mark
- && ((hevc->ignore_bufmgr_error & 0x1) == 0)) {
- /*count info*/
- vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
- hevc->cur_pic->stream_offset);
- if (hevc->cur_pic->slice_type == I_SLICE) {
- hevc->gvs->i_decoded_frames++;
- } else if (hevc->cur_pic->slice_type == P_SLICE) {
- hevc->gvs->p_decoded_frames++;
- } else if (hevc->cur_pic->slice_type == B_SLICE) {
- hevc->gvs->b_decoded_frames++;
- }
- if (hevc->cur_pic->error_mark) {
- if (hevc->cur_pic->slice_type == I_SLICE) {
- hevc->gvs->i_concealed_frames++;
- } else if (hevc->cur_pic->slice_type == P_SLICE) {
- hevc->gvs->p_concealed_frames++;
- } else if (hevc->cur_pic->slice_type == B_SLICE) {
- hevc->gvs->b_concealed_frames++;
- }
- }
- if (hevc->PB_skip_mode == 2) {
- hevc->gvs->drop_frame_count++;
- if (rpm_param->p.slice_type == I_SLICE) {
- hevc->gvs->i_lost_frames++;
- } else if (rpm_param->p.slice_type == P_SLICE) {
- hevc->gvs->p_lost_frames++;
- } else if (rpm_param->p.slice_type == B_SLICE) {
- hevc->gvs->b_lost_frames++;
- }
- }
- }
-
- if (is_skip_decoding(hevc,
- hevc->cur_pic)) {
- return 2;
- }
- } else
- hevc->col_pic = hevc->cur_pic;
- } /* */
- if (hevc->col_pic == NULL)
- hevc->col_pic = hevc->cur_pic;
-#ifdef BUFFER_MGR_ONLY
- return 0xf;
-#else
- if ((decode_pic_begin > 0 && hevc->decode_idx <= decode_pic_begin)
- || (dbg_skip_flag))
- return 0xf;
-#endif
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
- config_mc_buffer(hevc, hevc->cur_pic);
-
- if (is_skip_decoding(hevc,
- hevc->cur_pic)) {
- if (get_dbg_flag(hevc))
- hevc_print(hevc, 0,
- "Discard this picture index %d\n",
- hevc->cur_pic->index);
- /*count info*/
- vdec_count_info(hevc->gvs, hevc->cur_pic->error_mark,
- hevc->cur_pic->stream_offset);
- if (hevc->cur_pic->slice_type == I_SLICE) {
- hevc->gvs->i_decoded_frames++;
- } else if (hevc->cur_pic->slice_type == P_SLICE) {
- hevc->gvs->p_decoded_frames++;
- } else if (hevc->cur_pic->slice_type == B_SLICE) {
- hevc->gvs->b_decoded_frames++;
- }
- if (hevc->cur_pic->error_mark) {
- if (hevc->cur_pic->slice_type == I_SLICE) {
- hevc->gvs->i_concealed_frames++;
- } else if (hevc->cur_pic->slice_type == P_SLICE) {
- hevc->gvs->p_concealed_frames++;
- } else if (hevc->cur_pic->slice_type == B_SLICE) {
- hevc->gvs->b_concealed_frames++;
- }
- }
- if (hevc->PB_skip_mode == 2) {
- hevc->gvs->drop_frame_count++;
- if (rpm_param->p.slice_type == I_SLICE) {
- hevc->gvs->i_lost_frames++;
- } else if (rpm_param->p.slice_type == P_SLICE) {
- hevc->gvs->p_lost_frames++;
- } else if (rpm_param->p.slice_type == B_SLICE) {
- hevc->gvs->b_lost_frames++;
- }
- }
- return 2;
- }
-#ifdef MCRCC_ENABLE
- config_mcrcc_axi_hw(hevc, hevc->cur_pic->slice_type);
-#endif
- if (!hevc->tile_width_lcu || !hevc->tile_height_lcu)
- return -1;
- config_mpred_hw(hevc);
-
- config_sao_hw(hevc, rpm_param);
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
- if ((hevc->slice_type != 2) && (hevc->i_only & 0x2))
- return 0xf;
-
- if (post_picture_early(vdec, hevc->cur_pic->index))
- return -1;
-
- return 0;
-}
-
-/* return page number */
-static int hevc_mmu_page_num(struct hevc_state_s *hevc,
- int w, int h, int save_mode)
-{
- int picture_size;
- int page_num;
- int max_frame_num;
-
- picture_size = compute_losless_comp_body_size(hevc, w,
- h, save_mode);
- page_num = ((picture_size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- max_frame_num = MAX_FRAME_8K_NUM;
- else
- max_frame_num = MAX_FRAME_4K_NUM;
-
- if (page_num > max_frame_num) {
- hevc_print(hevc, 0, "over max !! 0x%x width %d height %d\n",
- page_num, w, h);
- return -1;
- }
- return page_num;
-}
-
-static int H265_alloc_mmu(struct hevc_state_s *hevc, struct PIC_s *new_pic,
- unsigned short bit_depth, unsigned int *mmu_index_adr) {
- int bit_depth_10 = (bit_depth != 0x00);
- int cur_mmu_4k_number;
- int ret;
-
- if (get_double_write_mode(hevc) == 0x10)
- return 0;
-
- cur_mmu_4k_number = hevc_mmu_page_num(hevc, new_pic->width,
- new_pic->height, !bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- if (hevc->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hevc, new_pic->BUF_index);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ret = decoder_mmu_box_alloc_idx(
- hevc->mmu_box,
- new_pic->index,
- cur_mmu_4k_number,
- mmu_index_adr);
- }
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- new_pic->scatter_alloc = 1;
-
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s pic index %d page count(%d) ret =%d\n",
- __func__, new_pic->index,
- cur_mmu_4k_number, ret);
- return ret;
-}
-
-
-static void release_pic_mmu_buf(struct hevc_state_s *hevc,
- struct PIC_s *pic)
-{
- hevc_print(hevc, H265_DEBUG_BUFMGR_MORE,
- "%s pic index %d scatter_alloc %d\n",
- __func__, pic->index,
- pic->scatter_alloc);
-
- if (hevc->mmu_enable
- && !(hevc->double_write_mode & 0x10)
- && pic->scatter_alloc) {
- if (!hevc->is_used_v4l)
- decoder_mmu_box_free_idx(hevc->mmu_box, pic->index);
- else {
- struct internal_comp_buf *ibuf =
- ibuf = index_to_icomp_buf(hevc, pic->BUF_index);
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- }
- }
- pic->scatter_alloc = 0;
-}
-
-/*
- *************************************************
- *
- *h265 buffer management end
- *
- **************************************************
- */
-static struct hevc_state_s *gHevc;
-
-static void hevc_local_uninit(struct hevc_state_s *hevc)
-{
- hevc->rpm_ptr = NULL;
- hevc->lmem_ptr = NULL;
-
-#ifdef SWAP_HEVC_UCODE
- if (hevc->is_swap && get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- if (hevc->mc_cpu_addr != NULL) {
- dma_free_coherent(amports_get_dma_device(),
- hevc->swap_size, hevc->mc_cpu_addr,
- hevc->mc_dma_handle);
- hevc->mc_cpu_addr = NULL;
- }
-
- }
-#endif
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap && get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- uninit_detrefill_buf(hevc);
-#endif
- if (hevc->aux_addr) {
- dma_free_coherent(amports_get_dma_device(),
- hevc->prefix_aux_size + hevc->suffix_aux_size, hevc->aux_addr,
- hevc->aux_phy_addr);
- hevc->aux_addr = NULL;
- }
- if (hevc->rpm_addr) {
- dma_free_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE, hevc->rpm_addr,
- hevc->rpm_phy_addr);
- hevc->rpm_addr = NULL;
- }
- if (hevc->lmem_addr) {
- dma_free_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE, hevc->lmem_addr,
- hevc->lmem_phy_addr);
- hevc->lmem_addr = NULL;
- }
-
- if (hevc->mmu_enable && hevc->frame_mmu_map_addr) {
- if (hevc->frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(), hevc->frame_mmu_map_addr,
- hevc->frame_mmu_map_phy_addr);
-
- hevc->frame_mmu_map_addr = NULL;
- }
-
- //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
-}
-
-static int hevc_local_init(struct hevc_state_s *hevc)
-{
- int ret = -1;
- struct BuffInfo_s *cur_buf_info = NULL;
-
- memset(&hevc->param, 0, sizeof(union param_u));
-
- cur_buf_info = &hevc->work_space_buf_store;
- if (force_bufspec) {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[force_bufspec & 0xf],
- sizeof(struct BuffInfo_s));
- pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- memcpy(cur_buf_info, &amvh265_workbuff_spec[2], /* 4k */
- sizeof(struct BuffInfo_s));
- else
- memcpy(cur_buf_info, &amvh265_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[0], /* 1080p */
- sizeof(struct BuffInfo_s));
- }
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[5], /* 4k */
- sizeof(struct BuffInfo_s));
- } else {
- memcpy(cur_buf_info, &amvh265_workbuff_spec[3], /* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
- }
-
- cur_buf_info->start_adr = hevc->buf_start;
- init_buff_spec(hevc, cur_buf_info);
-
- hevc_init_stru(hevc, cur_buf_info);
-
- hevc->bit_depth_luma = 8;
- hevc->bit_depth_chroma = 8;
- hevc->video_signal_type = 0;
- hevc->video_signal_type_debug = 0;
- bit_depth_luma = hevc->bit_depth_luma;
- bit_depth_chroma = hevc->bit_depth_chroma;
- video_signal_type = hevc->video_signal_type;
-
- if ((get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG) == 0) {
- hevc->rpm_addr = dma_alloc_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE, &hevc->rpm_phy_addr, GFP_KERNEL);
- if (hevc->rpm_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
- hevc->rpm_ptr = hevc->rpm_addr;
- }
-
- if (prefix_aux_buf_size > 0 ||
- suffix_aux_buf_size > 0) {
- u32 aux_buf_size;
-
- hevc->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size);
- hevc->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size);
- aux_buf_size = hevc->prefix_aux_size + hevc->suffix_aux_size;
- hevc->aux_addr =dma_alloc_coherent(amports_get_dma_device(),
- aux_buf_size, &hevc->aux_phy_addr, GFP_KERNEL);
- if (hevc->aux_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
- }
-
- hevc->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, &hevc->lmem_phy_addr, GFP_KERNEL);
- if (hevc->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- }
- hevc->lmem_ptr = hevc->lmem_addr;
-
- if (hevc->mmu_enable) {
- hevc->frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- get_frame_mmu_map_size(),
- &hevc->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hevc->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(hevc->frame_mmu_map_addr, 0, get_frame_mmu_map_size());
- }
- ret = 0;
- return ret;
-}
-
-/*
- *******************************************
- * Mailbox command
- *******************************************
- */
-#define CMD_FINISHED 0
-#define CMD_ALLOC_VIEW 1
-#define CMD_FRAME_DISPLAY 3
-#define CMD_DEBUG 10
-
-
-#define DECODE_BUFFER_NUM_MAX 32
-#define DISPLAY_BUFFER_NUM 6
-
-#define video_domain_addr(adr) (adr&0x7fffffff)
-#define DECODER_WORK_SPACE_SIZE 0x800000
-
-#define spec2canvas(x) \
- (((x)->uv_canvas_index << 16) | \
- ((x)->uv_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-
-static void set_canvas(struct hevc_state_s *hevc, struct PIC_s *pic)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
- int canvas_w = ALIGN(pic->width, 64)/4;
- int canvas_h = ALIGN(pic->height, 32)/4;
- int blkmode = hevc->mem_map_mode;
-
- /*CANVAS_BLKMODE_64X32*/
-#ifdef SUPPORT_10BIT
- if (pic->double_write_mode) {
- canvas_w = pic->width /
- get_double_write_ratio(pic->double_write_mode);
- canvas_h = pic->height /
- get_double_write_ratio(pic->double_write_mode);
-
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- if (vdec->parallel_dec == 1) {
- if (pic->y_canvas_index == -1)
- pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic->uv_canvas_index == -1)
- pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic->y_canvas_index = 128 + pic->index * 2;
- pic->uv_canvas_index = 128 + pic->index * 2 + 1;
- }
-
- config_cav_lut_ex(pic->y_canvas_index,
- pic->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
- canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
-#ifdef MULTI_INSTANCE_SUPPORT
- pic->canvas_config[0].phy_addr =
- pic->dw_y_adr;
- pic->canvas_config[0].width =
- canvas_w;
- pic->canvas_config[0].height =
- canvas_h;
- pic->canvas_config[0].block_mode =
- blkmode;
- pic->canvas_config[0].endian = hevc->is_used_v4l ? 0 : 7;
-
- pic->canvas_config[1].phy_addr =
- pic->dw_u_v_adr;
- pic->canvas_config[1].width =
- canvas_w;
- pic->canvas_config[1].height =
- canvas_h;
- pic->canvas_config[1].block_mode =
- blkmode;
- pic->canvas_config[1].endian = hevc->is_used_v4l ? 0 : 7;
-
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr);
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
- __func__, pic->canvas_config[0].phy_addr);
-#else
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
- __func__, spec2canvas(pic));
-#endif
- } else {
- if (!hevc->mmu_enable) {
- /* to change after 10bit VPU is ready ... */
- if (vdec->parallel_dec == 1) {
- if (pic->y_canvas_index == -1)
- pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- pic->uv_canvas_index = pic->y_canvas_index;
- } else {
- pic->y_canvas_index = 128 + pic->index;
- pic->uv_canvas_index = 128 + pic->index;
- }
-
- config_cav_lut_ex(pic->y_canvas_index,
- pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
- canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- }
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
- __func__, spec2canvas(pic));
- }
-#else
- if (vdec->parallel_dec == 1) {
- if (pic->y_canvas_index == -1)
- pic->y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic->uv_canvas_index == -1)
- pic->uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic->y_canvas_index = 128 + pic->index * 2;
- pic->uv_canvas_index = 128 + pic->index * 2 + 1;
- }
-
-
- config_cav_lut_ex(pic->y_canvas_index, pic->mc_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic->uv_canvas_index, pic->mc_u_v_adr,
- canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hevc->is_used_v4l ? 0 : 7, VDEC_HEVC);
-
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, spec2canvas(pic));
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,"%s(canvas0 addr:0x%x)\n",
- __func__, spec2canvas(pic));
-#endif
-}
-
-static int init_buf_spec(struct hevc_state_s *hevc)
-{
- int pic_width = hevc->pic_w;
- int pic_height = hevc->pic_h;
-
- /* hevc_print(hevc, 0,
- *"%s1: %d %d\n", __func__, hevc->pic_w, hevc->pic_h);
- */
- hevc_print(hevc, 0,
- "%s2 %d %d\n", __func__, pic_width, pic_height);
- /* pic_width = hevc->pic_w; */
- /* pic_height = hevc->pic_h; */
-
- if (hevc->frame_width == 0 || hevc->frame_height == 0) {
- hevc->frame_width = pic_width;
- hevc->frame_height = pic_height;
-
- }
-
- return 0;
-}
-
-static int parse_sei(struct hevc_state_s *hevc,
- struct PIC_s *pic, char *sei_buf, uint32_t size)
-{
- char *p = sei_buf;
- char *p_sei;
- uint16_t header;
- uint16_t nal_unit_type;
- uint16_t payload_type, payload_size;
- int i, j;
-
- if (size < 2)
- return 0;
- header = *p++;
- header <<= 8;
- header += *p++;
- nal_unit_type = header >> 9;
- if ((nal_unit_type != NAL_UNIT_SEI)
- && (nal_unit_type != NAL_UNIT_SEI_SUFFIX))
- return 0;
- while (p+4 <= sei_buf+size) {
- payload_type = *p++;
- if (payload_type == 0xff) {
- payload_type += *p++;
- }
- payload_size = *p++;
- if (payload_size == 0xff) {
- payload_size += *p++;
- }
-
- if (p+payload_size <= sei_buf+size) {
- switch (payload_type) {
- case SEI_PicTiming:
- if ((parser_sei_enable & 0x4) &&
- hevc->frame_field_info_present_flag) {
- p_sei = p;
- hevc->curr_pic_struct = (*p_sei >> 4)&0x0f;
- pic->pic_struct = hevc->curr_pic_struct;
- if (get_dbg_flag(hevc) &
- H265_DEBUG_PIC_STRUCT) {
- hevc_print(hevc, 0,
- "parse result pic_struct = %d\n",
- hevc->curr_pic_struct);
- }
- }
- break;
- case SEI_UserDataITU_T_T35:
- p_sei = p;
- if (p_sei[0] == 0xB5
- && p_sei[1] == 0x00
- && p_sei[2] == 0x3C
- && p_sei[3] == 0x00
- && p_sei[4] == 0x01
- && p_sei[5] == 0x04) {
- char *new_buf;
- hevc->sei_present_flag |= SEI_HDR10PLUS_MASK;
- new_buf = vzalloc(payload_size);
- if (new_buf) {
- memcpy(new_buf, p_sei, payload_size);
- pic->hdr10p_data_buf = new_buf;
- pic->hdr10p_data_size = payload_size;
- } else {
- hevc_print(hevc, 0,
- "%s:hdr10p data vzalloc size(%d) fail\n",
- __func__, payload_size);
- pic->hdr10p_data_buf = NULL;
- pic->hdr10p_data_size = 0;
- }
- } else if (p_sei[0] == 0x26
- && p_sei[1] == 0x00
- && p_sei[2] == 0x04
- && p_sei[3] == 0x00
- && p_sei[4] == 0x05) {
- hevc->sei_present_flag |= SEI_HDR_CUVA_MASK;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- PR_INIT(128);
- hevc_print(hevc, 0,
- "hdr cuva data: (size %d)\n",
- payload_size);
- for (i = 0; i < payload_size; i++) {
- PR_FILL("%02x ", p_sei[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
- }
-
- break;
- case SEI_MasteringDisplayColorVolume:
- /*hevc_print(hevc, 0,
- "sei type: primary display color volume %d, size %d\n",
- payload_type,
- payload_size);*/
- /* master_display_colour */
- p_sei = p;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 2; j++) {
- hevc->primaries[i][j]
- = (*p_sei<<8)
- | *(p_sei+1);
- p_sei += 2;
- }
- }
- for (i = 0; i < 2; i++) {
- hevc->white_point[i]
- = (*p_sei<<8)
- | *(p_sei+1);
- p_sei += 2;
- }
- for (i = 0; i < 2; i++) {
- hevc->luminance[i]
- = (*p_sei<<24)
- | (*(p_sei+1)<<16)
- | (*(p_sei+2)<<8)
- | *(p_sei+3);
- p_sei += 4;
- }
- hevc->sei_present_flag |=
- SEI_MASTER_DISPLAY_COLOR_MASK;
- /*for (i = 0; i < 3; i++)
- for (j = 0; j < 2; j++)
- hevc_print(hevc, 0,
- "\tprimaries[%1d][%1d] = %04x\n",
- i, j,
- hevc->primaries[i][j]);
- hevc_print(hevc, 0,
- "\twhite_point = (%04x, %04x)\n",
- hevc->white_point[0],
- hevc->white_point[1]);
- hevc_print(hevc, 0,
- "\tmax,min luminance = %08x, %08x\n",
- hevc->luminance[0],
- hevc->luminance[1]);*/
- break;
- case SEI_ContentLightLevel:
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "sei type: max content light level %d, size %d\n",
- payload_type, payload_size);
- /* content_light_level */
- p_sei = p;
- hevc->content_light_level[0]
- = (*p_sei<<8) | *(p_sei+1);
- p_sei += 2;
- hevc->content_light_level[1]
- = (*p_sei<<8) | *(p_sei+1);
- p_sei += 2;
- hevc->sei_present_flag |=
- SEI_CONTENT_LIGHT_LEVEL_MASK;
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\tmax cll = %04x, max_pa_cll = %04x\n",
- hevc->content_light_level[0],
- hevc->content_light_level[1]);
- break;
- default:
- break;
- }
- }
- p += payload_size;
- }
- return 0;
-}
-
-static unsigned calc_ar(unsigned idc, unsigned sar_w, unsigned sar_h,
- unsigned w, unsigned h)
-{
- unsigned ar;
-
- if (idc == 255) {
- ar = div_u64(256ULL * sar_h * h,
- sar_w * w);
- } else {
- switch (idc) {
- case 1:
- ar = 0x100 * h / w;
- break;
- case 2:
- ar = 0x100 * h * 11 / (w * 12);
- break;
- case 3:
- ar = 0x100 * h * 11 / (w * 10);
- break;
- case 4:
- ar = 0x100 * h * 11 / (w * 16);
- break;
- case 5:
- ar = 0x100 * h * 33 / (w * 40);
- break;
- case 6:
- ar = 0x100 * h * 11 / (w * 24);
- break;
- case 7:
- ar = 0x100 * h * 11 / (w * 20);
- break;
- case 8:
- ar = 0x100 * h * 11 / (w * 32);
- break;
- case 9:
- ar = 0x100 * h * 33 / (w * 80);
- break;
- case 10:
- ar = 0x100 * h * 11 / (w * 18);
- break;
- case 11:
- ar = 0x100 * h * 11 / (w * 15);
- break;
- case 12:
- ar = 0x100 * h * 33 / (w * 64);
- break;
- case 13:
- ar = 0x100 * h * 99 / (w * 160);
- break;
- case 14:
- ar = 0x100 * h * 3 / (w * 4);
- break;
- case 15:
- ar = 0x100 * h * 2 / (w * 3);
- break;
- case 16:
- ar = 0x100 * h * 1 / (w * 2);
- break;
- default:
- ar = h * 0x100 / w;
- break;
- }
- }
-
- return ar;
-}
-
-static void set_frame_info(struct hevc_state_s *hevc, struct vframe_s *vf,
- struct PIC_s *pic)
-{
- unsigned int ar;
- int i, j;
- char *p;
- unsigned size = 0;
- unsigned type = 0;
- struct vframe_master_display_colour_s *vf_dp
- = &vf->prop.master_display_colour;
-
- vf->width = pic->width /
- get_double_write_ratio(pic->double_write_mode);
- vf->height = pic->height /
- get_double_write_ratio(pic->double_write_mode);
-
- vf->duration = hevc->frame_dur;
- vf->duration_pulldown = 0;
- vf->flag = 0;
-
- ar = min_t(u32, hevc->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
-
-
- if (((pic->aspect_ratio_idc == 255) &&
- pic->sar_width &&
- pic->sar_height) ||
- ((pic->aspect_ratio_idc != 255) &&
- (pic->width))) {
- ar = min_t(u32,
- calc_ar(pic->aspect_ratio_idc,
- pic->sar_width,
- pic->sar_height,
- pic->width,
- pic->height),
- DISP_RATIO_ASPECT_RATIO_MAX);
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
- vf->ratio_control <<= hevc->interlace_flag;
- }
- hevc->ratio_control = vf->ratio_control;
- if (pic->aux_data_buf
- && pic->aux_data_size) {
- /* parser sei */
- p = pic->aux_data_buf;
- while (p < pic->aux_data_buf
- + pic->aux_data_size - 8) {
- size = *p++;
- size = (size << 8) | *p++;
- size = (size << 8) | *p++;
- size = (size << 8) | *p++;
- type = *p++;
- type = (type << 8) | *p++;
- type = (type << 8) | *p++;
- type = (type << 8) | *p++;
- if (type == 0x02000000) {
- /* hevc_print(hevc, 0,
- "sei(%d)\n", size); */
- parse_sei(hevc, pic, p, size);
- }
- p += size;
- }
- }
- if (hevc->video_signal_type & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) {
- vf->signal_type = pic->video_signal_type;
- if (hevc->sei_present_flag & SEI_HDR10PLUS_MASK) {
- u32 data;
- data = vf->signal_type;
- data = data & 0xFFFF00FF;
- data = data | (0x30<<8);
- vf->signal_type = data;
- }
-
- if (hevc->sei_present_flag & SEI_HDR_CUVA_MASK) {
- u32 data;
- data = vf->signal_type;
- data = data & 0x7FFFFFFF;
- data = data | (1<<31);
- vf->signal_type = data;
- }
- }
- else
- vf->signal_type = 0;
- hevc->video_signal_type_debug = vf->signal_type;
-
- /* master_display_colour */
- if (hevc->sei_present_flag & SEI_MASTER_DISPLAY_COLOR_MASK) {
- for (i = 0; i < 3; i++)
- for (j = 0; j < 2; j++)
- vf_dp->primaries[i][j] = hevc->primaries[i][j];
- for (i = 0; i < 2; i++) {
- vf_dp->white_point[i] = hevc->white_point[i];
- vf_dp->luminance[i]
- = hevc->luminance[i];
- }
- vf_dp->present_flag = 1;
- } else
- vf_dp->present_flag = 0;
-
- /* content_light_level */
- if (hevc->sei_present_flag & SEI_CONTENT_LIGHT_LEVEL_MASK) {
- vf_dp->content_light_level.max_content
- = hevc->content_light_level[0];
- vf_dp->content_light_level.max_pic_average
- = hevc->content_light_level[1];
- vf_dp->content_light_level.present_flag = 1;
- } else
- vf_dp->content_light_level.present_flag = 0;
-
- if (hevc->is_used_v4l &&
- ((hevc->video_signal_type & VIDEO_SIGNAL_TYPE_AVAILABLE_MASK) ||
- (hevc->sei_present_flag & SEI_HDR10PLUS_MASK) ||
- (vf_dp->present_flag) ||
- (vf_dp->content_light_level.present_flag))) {
- struct aml_vdec_hdr_infos hdr;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.signal_type = vf->signal_type;
- hdr.color_parms = *vf_dp;
- vdec_v4l_set_hdr_infos(ctx, &hdr);
- }
-
- if ((hevc->sei_present_flag & SEI_HDR10PLUS_MASK) && (pic->hdr10p_data_buf != NULL)
- && (pic->hdr10p_data_size != 0)) {
- if (pic->hdr10p_data_size <= 128) {
- char *new_buf;
- new_buf = kzalloc(pic->hdr10p_data_size, GFP_ATOMIC);
-
- if (new_buf) {
- memcpy(new_buf, pic->hdr10p_data_buf, pic->hdr10p_data_size);
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- PR_INIT(128);
- hevc_print(hevc, 0,
- "hdr10p data: (size %d)\n",
- pic->hdr10p_data_size);
- for (i = 0; i < pic->hdr10p_data_size; i++) {
- PR_FILL("%02x ", pic->hdr10p_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
-
- vf->hdr10p_data_size = pic->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
- set_meta_data_to_vf(vf, UVM_META_DATA_HDR10P_DATA, hevc->v4l2_ctx);
- } else {
- hevc_print(hevc, 0,
- "%s:hdr10p data vzalloc size(%d) fail\n",
- __func__, pic->hdr10p_data_size);
- vf->hdr10p_data_buf = NULL;
- vf->hdr10p_data_size = 0;
- }
- }
-
- vfree(pic->hdr10p_data_buf);
- pic->hdr10p_data_buf = NULL;
- pic->hdr10p_data_size = 0;
- }
-
- vf->sidebind_type = hevc->sidebind_type;
- vf->sidebind_channel_id = hevc->sidebind_channel_id;
-}
-
-static int vh265_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct vdec_s *vdec = op_arg;
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg;
-#endif
-
- spin_lock_irqsave(&lock, flags);
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hevc->newframe_q);
- states->buf_avail_num = kfifo_len(&hevc->display_q);
-
- if (step == 2)
- states->buf_avail_num = 0;
- spin_unlock_irqrestore(&lock, flags);
- return 0;
-}
-
-static struct vframe_s *vh265_vf_peek(void *op_arg)
-{
- struct vframe_s *vf[2] = {0, 0};
-#ifdef MULTI_INSTANCE_SUPPORT
- struct vdec_s *vdec = op_arg;
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg;
-#endif
-
- if (step == 2)
- return NULL;
-
- if (force_disp_pic_index & 0x100) {
- if (force_disp_pic_index & 0x200)
- return NULL;
- return &hevc->vframe_dummy;
- }
-
-
- if (kfifo_out_peek(&hevc->display_q, (void *)&vf, 2)) {
- if (vf[1]) {
- vf[0]->next_vf_pts_valid = true;
- vf[0]->next_vf_pts = vf[1]->pts;
- } else
- vf[0]->next_vf_pts_valid = false;
- return vf[0];
- }
-
- return NULL;
-}
-
-static struct vframe_s *vh265_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct vdec_s *vdec = op_arg;
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg;
-#endif
-
- if (step == 2)
- return NULL;
- else if (step == 1)
- step = 2;
-
-#if 0
- if (force_disp_pic_index & 0x100) {
- int buffer_index = force_disp_pic_index & 0xff;
- struct PIC_s *pic = NULL;
- if (buffer_index >= 0
- && buffer_index < MAX_REF_PIC_NUM)
- pic = hevc->m_PIC[buffer_index];
- if (pic == NULL)
- return NULL;
- if (force_disp_pic_index & 0x200)
- return NULL;
-
- vf = &hevc->vframe_dummy;
- if (get_double_write_mode(hevc)) {
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD |
- VIDTYPE_VIU_NV21;
- if (hevc->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic->canvas_config[0];
- vf->canvas0_config[1] =
- pic->canvas_config[1];
-
- vf->canvas1_config[0] =
- pic->canvas_config[0];
- vf->canvas1_config[1] =
- pic->canvas_config[1];
- } else {
- vf->canvas0Addr = vf->canvas1Addr
- = spec2canvas(pic);
- }
- } else {
- vf->canvas0Addr = vf->canvas1Addr = 0;
- vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
- vf->compWidth = pic->width;
- vf->compHeight = pic->height;
- update_vf_memhandle(hevc, vf, pic);
- switch (hevc->bit_depth_luma) {
- case 9:
- vf->bitdepth = BITDEPTH_Y9 | BITDEPTH_U9 | BITDEPTH_V9;
- break;
- case 10:
- vf->bitdepth = BITDEPTH_Y10 | BITDEPTH_U10
- | BITDEPTH_V10;
- break;
- default:
- vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- break;
- }
- if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- if (hevc->mem_saving_mode == 1)
- vf->bitdepth |= BITDEPTH_SAVING_MODE;
- vf->duration_pulldown = 0;
- vf->pts = 0;
- vf->pts_us64 = 0;
- set_frame_info(hevc, vf);
-
- vf->width = pic->width /
- get_double_write_ratio(pic->double_write_mode);
- vf->height = pic->height /
- get_double_write_ratio(pic->double_write_mode);
-
- force_disp_pic_index |= 0x200;
- return vf;
- }
-#endif
-
- if (kfifo_get(&hevc->display_q, &vf)) {
- struct vframe_s *next_vf = NULL;
-
- ATRACE_COUNTER(hevc->trace.vf_get_name, (long)vf);
- ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q));
-#ifdef MULTI_INSTANCE_SUPPORT
- ATRACE_COUNTER(hevc->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr);
-#else
- ATRACE_COUNTER(hevc->trace.get_canvas0_addr, vf->canvas0Addr);
-#endif
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT) {
- hevc_print(hevc, 0,
- "%s(vf 0x%p type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n",
- __func__, vf, vf->type, vf->index,
- get_pic_poc(hevc, vf->index & 0xff),
- get_pic_poc(hevc, (vf->index >> 8) & 0xff),
- vf->pts, vf->pts_us64,
- vf->duration);
-#ifdef MULTI_INSTANCE_SUPPORT
- hevc_print(hevc, 0, "get canvas0 addr:0x%x\n", vf->canvas0_config[0].phy_addr);
-#else
- hevc_print(hevc, 0, "get canvas0 addr:0x%x\n", vf->canvas0Addr);
-#endif
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (get_dbg_flag(hevc) & H265_DEBUG_DV) {
- struct PIC_s *pic = hevc->m_PIC[vf->index & 0xff];
- hevc_print(hevc, 0, "pic 0x%p aux size %d:\n",
- pic, pic->aux_data_size);
- if (pic->aux_data_buf && pic->aux_data_size > 0) {
- PR_INIT(128);
- int i;
- for (i = 0; i < pic->aux_data_size; i++) {
- PR_FILL("%02x ", pic->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
- }
-#endif
- hevc->show_frame_num++;
- vf->index_disp = atomic_read(&hevc->vf_get_count);
- atomic_add(1, &hevc->vf_get_count);
-
- if (kfifo_peek(&hevc->display_q, &next_vf) && next_vf) {
- vf->next_vf_pts_valid = true;
- vf->next_vf_pts = next_vf->pts;
- } else
- vf->next_vf_pts_valid = false;
-
- return vf;
- }
-
- return NULL;
-}
-static bool vf_valid_check(struct vframe_s *vf, struct hevc_state_s *hevc) {
- int i;
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &hevc->vfpool[i] || vf == &hevc->vframe_dummy)
- return true;
- }
- hevc_print(hevc, 0," h265 invalid vf been put, vf = %p\n", vf);
- for (i = 0; i < VF_POOL_SIZE; i++) {
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,"valid vf[%d]= %p \n", i, &hevc->vfpool[i]);
- }
- return false;
-}
-
-static void vh265_vf_put(struct vframe_s *vf, void *op_arg)
-{
- unsigned long flags;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct vdec_s *vdec = op_arg;
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg;
-#endif
- unsigned char index_top;
- unsigned char index_bot;
-
- if (!vf)
- return;
- if (vf == (&hevc->vframe_dummy))
- return;
- if (vf && (vf_valid_check(vf, hevc) == false))
- return;
-
- if (hevc->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&hevc->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (hevc->fence_vf_s.fence_vf[i] == NULL) {
- hevc->fence_vf_s.fence_vf[i] = vf;
- hevc->fence_vf_s.used_size++;
- mutex_unlock(&hevc->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&hevc->fence_mutex);
- }
-
- ATRACE_COUNTER(hevc->trace.vf_put_name, (long)vf);
-#ifdef MULTI_INSTANCE_SUPPORT
- ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr);
-#else
- ATRACE_COUNTER(hevc->trace.put_canvas0_addr, vf->canvas0Addr);
-#endif
- index_top = vf->index & 0xff;
- index_bot = (vf->index >> 8) & 0xff;
- if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
- hevc_print(hevc, 0,
- "%s(vf 0x%p type %d index 0x%x put canvas0 addr:0x%x)\n",
- __func__, vf, vf->type, vf->index
-#ifdef MULTI_INSTANCE_SUPPORT
- , vf->canvas0_config[0].phy_addr
-#else
- , vf->canvas0Addr
-#endif
- );
- atomic_add(1, &hevc->vf_put_count);
- spin_lock_irqsave(&lock, flags);
- kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q));
- if (hevc->enable_fence && vf->fence) {
- vdec_fence_put(vf->fence);
- vf->fence = NULL;
- }
-
- if (vf->hdr10p_data_buf) {
- kfree(vf->hdr10p_data_buf);
- vf->hdr10p_data_buf = NULL;
- vf->hdr10p_data_size = 0;
- }
-
- if (vf->meta_data_buf) {
- vf->meta_data_buf = NULL;
- vf->meta_data_size = 0;
- }
-
- if (!hevc->interlace_flag &&
- (vf->v4l_mem_handle !=
- hevc->m_PIC[index_top]->cma_alloc_addr)) {
- hevc_print(hevc, PRINT_FLAG_V4L_DETAIL,
- "H265 update fb handle, old:%llx, new:%llx\n",
- hevc->m_PIC[index_top]->cma_alloc_addr,
- vf->v4l_mem_handle);
-
- hevc->m_PIC[index_top]->cma_alloc_addr
- = vf->v4l_mem_handle;
- }
-
- if (index_top != 0xff
- && index_top < MAX_REF_PIC_NUM
- && hevc->m_PIC[index_top]) {
- if (hevc->m_PIC[index_top]->vf_ref > 0) {
- hevc->m_PIC[index_top]->vf_ref--;
-
- if (hevc->m_PIC[index_top]->vf_ref == 0) {
- hevc->m_PIC[index_top]->output_ready = 0;
- hevc->m_PIC[index_top]->show_frame = false;
-
- if (hevc->wait_buf != 0)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
- }
-
- if (index_bot != 0xff
- && index_bot < MAX_REF_PIC_NUM
- && hevc->m_PIC[index_bot]) {
- if (hevc->m_PIC[index_bot]->vf_ref > 0) {
- hevc->m_PIC[index_bot]->vf_ref--;
-
- if (hevc->m_PIC[index_bot]->vf_ref == 0) {
- hevc->m_PIC[index_bot]->output_ready = 0;
- hevc->m_PIC[index_bot]->show_frame = false;
-
- if (hevc->wait_buf != 0)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
- }
-
- spin_unlock_irqrestore(&lock, flags);
-}
-
-
-static int vh265_event_cb(int type, void *data, void *op_arg)
-{
- unsigned long flags;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct vdec_s *vdec = op_arg;
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = (struct hevc_state_s *)op_arg;
-#endif
- if (type & VFRAME_EVENT_RECEIVER_RESET) {
-#if 0
- amhevc_stop();
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_light_unreg_provider(&vh265_vf_prov);
-#endif
- spin_lock_irqsave(&hevc->lock, flags);
- vh265_local_init();
- vh265_prot_init();
- spin_unlock_irqrestore(&hevc->lock, flags);
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_reg_provider(&vh265_vf_prov);
-#endif
- amhevc_start();
-#endif
- } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
- struct provider_aux_req_s *req =
- (struct provider_aux_req_s *)data;
- unsigned char index;
-
- if (!req->vf) {
- req->aux_size = atomic_read(&hevc->vf_put_count);
- return 0;
- }
- spin_lock_irqsave(&lock, flags);
- index = req->vf->index & 0xff;
- req->aux_buf = NULL;
- req->aux_size = 0;
- req->format = VFORMAT_HEVC;
- if (req->bot_flag)
- index = (req->vf->index >> 8) & 0xff;
- if (index != 0xff
- && index < MAX_REF_PIC_NUM
- && hevc->m_PIC[index]) {
- req->aux_buf = hevc->m_PIC[index]->aux_data_buf;
- req->aux_size = hevc->m_PIC[index]->aux_data_size;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (hevc->bypass_dvenl && !dolby_meta_with_el)
- req->dv_enhance_exist = false;
- else
- req->dv_enhance_exist =
- hevc->m_PIC[index]->dv_enhance_exist;
- if (vdec_frame_based(vdec) && (hevc->dv_duallayer == true))
- req->dv_enhance_exist = 1;
- hevc_print(hevc, H265_DEBUG_DV,
- "query dv_enhance_exist for (pic 0x%p, vf 0x%p, poc %d index %d) flag => %d, aux sizd 0x%x\n",
- hevc->m_PIC[index],
- req->vf,
- hevc->m_PIC[index]->POC, index,
- req->dv_enhance_exist, req->aux_size);
-#else
- req->dv_enhance_exist = 0;
-#endif
- }
- spin_unlock_irqrestore(&lock, flags);
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
- hevc_print(hevc, 0,
- "%s(type 0x%x vf index 0x%x)=>size 0x%x\n",
- __func__, type, index, req->aux_size);
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (type & VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL) {
- if ((force_bypass_dvenl & 0x80000000) == 0) {
- hevc_print(hevc, 0,
- "%s: VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL\n",
- __func__);
- hevc->bypass_dvenl_enable = 1;
- }
- }
-#endif
- else if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static void get_pair_fb(struct hevc_state_s *hevc, struct vframe_s *vf)
-{
- int i;
- for (i = 0; i < 2; i ++) {
- if (hevc->pair_fb[i] == NULL) {
- hevc->pair_fb[i] = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- break;
- }
- }
-
- if (i >= 2) {
- hevc->pair_fb[0] = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- hevc->pair_fb[1] = NULL;
- }
-}
-
-static void clear_pair_fb(struct hevc_state_s *hevc)
-{
- int i;
- for (i = 0; i < 2; i ++)
- hevc->pair_fb[i] = NULL;
-}
-
-static bool v4l_output_dw_with_compress(struct hevc_state_s *hevc, int dw)
-{
- if ((!hevc->is_used_v4l) || (dw == 0x10) ||
- IS_8K_SIZE(hevc->frame_width, hevc->frame_height) ||
- hevc->interlace_flag)
- return false;
-
- return true;
-}
-
-#ifdef HEVC_PIC_STRUCT_SUPPORT
-static int process_pending_vframe(struct hevc_state_s *hevc,
- struct PIC_s *pair_pic, unsigned char pair_frame_top_flag)
-{
- struct vframe_s *vf;
-
- if (!pair_pic)
- return -1;
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "%s: pair_pic index 0x%x %s\n", __func__, pair_pic->index,
- pair_frame_top_flag ? "top" : "bot");
-
- if (kfifo_len(&hevc->pending_q) > 1) {
- unsigned long flags;
- int index1;
- int index2;
- /* do not pending more than 1 frame */
- if (kfifo_get(&hevc->pending_q, &vf) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_PIC_STRUCT)
- hevc_print(hevc, 0,
- "%s warning(1), vf=>display_q: (index 0x%x), vf 0x%px\n",
- __func__, vf->index, vf);
-
- if (v4l_output_dw_with_compress(hevc, pair_pic->double_write_mode)) {
- vf->type |= VIDTYPE_COMPRESS;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
-
- /* recycle vframe */
- atomic_add(1, &hevc->vf_pre_count);
- spin_lock_irqsave(&lock, flags);
- kfifo_put(&hevc->newframe_q, (const struct vframe_s *)vf);
- index1 = vf->index & 0xff;
- index2 = (vf->index >> 8) & 0xff;
- if (index1 >= MAX_REF_PIC_NUM &&
- index2 >= MAX_REF_PIC_NUM) {
- spin_unlock_irqrestore(&lock, flags);
- return -1;
- }
-
- if (index1 < MAX_REF_PIC_NUM) {
- hevc->m_PIC[index1]->vf_ref = 0;
- hevc->m_PIC[index1]->output_ready = 0;
- }
- if (index2 < MAX_REF_PIC_NUM) {
- hevc->m_PIC[index2]->vf_ref = 0;
- hevc->m_PIC[index2]->output_ready = 0;
- }
- if (hevc->wait_buf != 0)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- spin_unlock_irqrestore(&lock, flags);
-
- ATRACE_COUNTER(hevc->trace.pts_name, vf->timestamp);
- }
-
- if (kfifo_peek(&hevc->pending_q, &vf)) {
- if (kfifo_get(&hevc->pending_q, &vf) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
- if (vf == NULL)
- return -1;
-
- if (pair_pic == NULL || pair_pic->vf_ref <= 0) {
- /*
- *if pair_pic is recycled (pair_pic->vf_ref <= 0),
- *do not use it
- */
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "%s warning(2), vf=>display_q: (index 0x%x)\n",
- __func__, vf->index);
-
- if (v4l_output_dw_with_compress(hevc, pair_pic->double_write_mode)) {
- vf->type |= VIDTYPE_COMPRESS;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
- atomic_add(1, &hevc->vf_pre_count);
- vdec_vframe_ready(hw_to_vdec(hevc), vf);
- hevc->send_frame_flag = 1;
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->timestamp);
- } else if ((!pair_frame_top_flag) && (((vf->index >> 8) & 0xff) == 0xff)) {
- if (v4l_output_dw_with_compress(hevc, pair_pic->double_write_mode)) {
- vf->type |= VIDTYPE_COMPRESS;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
-
- vf->index &= 0xff;
- vf->index |= (pair_pic->index << 8);
- pair_pic->vf_ref++;
- vdec_vframe_ready(hw_to_vdec(hevc), vf);
- hevc->send_frame_flag = 1;
- get_pair_fb(hevc, vf);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->timestamp);
- atomic_add(1, &hevc->vf_pre_count);
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "%s vf => display_q: (index 0x%x), w %d, h %d, type 0x%x\n",
- __func__, vf->index, vf->width, vf->height, vf->type);
- } else if (pair_frame_top_flag && ((vf->index & 0xff) == 0xff)) {
- if (v4l_output_dw_with_compress(hevc, pair_pic->double_write_mode)) {
- vf->type |= VIDTYPE_COMPRESS;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
-
- vf->index &= 0xff00;
- vf->index |= pair_pic->index;
- pair_pic->vf_ref++;
- vdec_vframe_ready(hw_to_vdec(hevc), vf);
- hevc->send_frame_flag = 1;
- get_pair_fb(hevc, vf);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->timestamp);
- atomic_add(1, &hevc->vf_pre_count);
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "%s vf => display_q: (index 0x%x), w %d, h %d, type 0x%x\n",
- __func__, vf->index, vf->width, vf->height, vf->type);
- }
- }
- return 0;
-}
-#endif
-static void update_vf_memhandle(struct hevc_state_s *hevc,
- struct vframe_s *vf, struct PIC_s *pic)
-{
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
-
- /* keeper not needed for v4l solution */
- if (hevc->is_used_v4l)
- return;
-
- if (vf->type & VIDTYPE_SCATTER) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hevc->mmu_box, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hevc->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- vf->mem_head_handle = NULL;
- /*vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hevc->bmmu_box, VF_BUFFER_IDX(BUF_index));*/
- }
- return;
-}
-
-static void fill_frame_info(struct hevc_state_s *hevc,
- struct PIC_s *pic, unsigned int framesize, unsigned int pts)
-{
- struct vframe_qos_s *vframe_qos = &hevc->vframe_qos;
- if (hevc->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR)
- vframe_qos->type = 4;
- else if (pic->slice_type == I_SLICE)
- vframe_qos->type = 1;
- else if (pic->slice_type == P_SLICE)
- vframe_qos->type = 2;
- else if (pic->slice_type == B_SLICE)
- vframe_qos->type = 3;
-/*
-#define SHOW_QOS_INFO
-*/
- if (input_frame_based(hw_to_vdec(hevc)))
- vframe_qos->size = pic->frame_size;
- else
- vframe_qos->size = framesize;
- vframe_qos->pts = pts;
-#ifdef SHOW_QOS_INFO
- hevc_print(hevc, 0, "slice:%d, poc:%d\n", pic->slice_type, pic->POC);
-#endif
-
-
- vframe_qos->max_mv = pic->max_mv;
- vframe_qos->avg_mv = pic->avg_mv;
- vframe_qos->min_mv = pic->min_mv;
-#ifdef SHOW_QOS_INFO
- hevc_print(hevc, 0, "mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
-#endif
-
- vframe_qos->max_qp = pic->max_qp;
- vframe_qos->avg_qp = pic->avg_qp;
- vframe_qos->min_qp = pic->min_qp;
-#ifdef SHOW_QOS_INFO
- hevc_print(hevc, 0, "qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
-#endif
-
- vframe_qos->max_skip = pic->max_skip;
- vframe_qos->avg_skip = pic->avg_skip;
- vframe_qos->min_skip = pic->min_skip;
-#ifdef SHOW_QOS_INFO
- hevc_print(hevc, 0, "skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
-#endif
-
- vframe_qos->num++;
-
-}
-
-static inline void hevc_update_gvs(struct hevc_state_s *hevc)
-{
- if (hevc->gvs->frame_height != hevc->frame_height) {
- hevc->gvs->frame_width = hevc->frame_width;
- hevc->gvs->frame_height = hevc->frame_height;
- }
- if (hevc->gvs->frame_dur != hevc->frame_dur) {
- hevc->gvs->frame_dur = hevc->frame_dur;
- if (hevc->frame_dur != 0)
- hevc->gvs->frame_rate = ((96000 * 10 / hevc->frame_dur) % 10) < 5 ?
- 96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1);
- else
- hevc->gvs->frame_rate = -1;
- }
- hevc->gvs->error_count = hevc->gvs->error_frame_count;
- hevc->gvs->status = hevc->stat | hevc->fatal_error;
- if (hevc->gvs->ratio_control != hevc->ratio_control)
- hevc->gvs->ratio_control = hevc->ratio_control;
-}
-
-static void put_vf_to_display_q(struct hevc_state_s *hevc, struct vframe_s *vf)
-{
- atomic_add(1, &hevc->vf_pre_count);
- decoder_do_frame_check(hw_to_vdec(hevc), vf);
- vdec_vframe_ready(hw_to_vdec(hevc), vf);
- hevc->send_frame_flag = 1;
- kfifo_put(&hevc->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hevc->trace.pts_name, vf->timestamp);
-}
-
-static int post_prepare_process(struct vdec_s *vdec, struct PIC_s *frame)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-
- if (force_disp_pic_index & 0x100) {
- /*recycle directly*/
- frame->output_ready = 0;
- frame->show_frame = false;
- hevc_print(hevc, 0, "discard show frame.\n");
- return 0;
- }
-
- frame->show_frame = true;
-
- return 0;
-}
-
-static int post_video_frame(struct vdec_s *vdec, struct PIC_s *pic)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
- struct vframe_s *vf = NULL;
- int stream_offset = pic->stream_offset;
- unsigned short slice_type = pic->slice_type;
- ulong nv_order = VIDTYPE_VIU_NV21;
- u32 frame_size = 0;
- struct vdec_info tmp4x;
- struct aml_vcodec_ctx * v4l2_ctx = hevc->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- int index;
-
- hevc->send_frame_flag = 0;
- /* swap uv */
- if (hevc->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
- if (kfifo_get(&hevc->newframe_q, &vf) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
-
- if (vf) {
- /*hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: pic index 0x%x\n",
- __func__, pic->index);*/
-
- if (hevc->is_used_v4l) {
- vf->v4l_mem_handle = pic->cma_alloc_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- if (hevc->mmu_enable) {
- vf->mm_box.bmmu_box = hevc->bmmu_box;
- vf->mm_box.bmmu_idx = VF_BUFFER_IDX(hevc->buffer_wrap[pic->BUF_index]);
- vf->mm_box.mmu_box = hevc->mmu_box;
- vf->mm_box.mmu_idx = hevc->buffer_wrap[pic->BUF_index];
- }
- }
-
- if (hevc->enable_fence) {
- /* fill fence information. */
- if (hevc->fence_usage == FENCE_USE_FOR_DRIVER)
- vf->fence = pic->fence;
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(vdec)) {
- vf->pts = pic->pts;
- vf->pts_us64 = pic->pts64;
- vf->timestamp = pic->timestamp;
- }
- /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
- stream_offset, &vf->pts, 0) != 0) { */
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec->master == NULL) {
-#else
- else {
-#endif
-#endif
- hevc_print(hevc, H265_DEBUG_OUT_PTS,
- "call pts_lookup_offset_us64(0x%x)\n",
- stream_offset);
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64
- (PTS_TYPE_VIDEO, stream_offset, &vf->pts,
- &frame_size, 0, &vf->pts_us64) != 0) {
-#ifdef DEBUG_PTS
- hevc->pts_missed++;
-#endif
- vf->pts = 0;
- vf->pts_us64 = 0;
- } else {
-#ifdef DEBUG_PTS
- hevc->pts_hit++;
-#endif
- }
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- } else {
- vf->pts = 0;
- vf->pts_us64 = 0;
- }
-#else
- }
-#endif
-#endif
-
- if (pts_unstable && (hevc->frame_dur > 0))
- hevc->pts_mode = PTS_NONE_REF_USE_DURATION;
-
- fill_frame_info(hevc, pic, frame_size, vf->pts);
-
- if (vf->pts != 0)
- hevc->last_lookup_pts = vf->pts;
-
- if ((hevc->pts_mode == PTS_NONE_REF_USE_DURATION)
- && (slice_type != 2))
- vf->pts = hevc->last_pts + DUR2PTS(hevc->frame_dur);
- hevc->last_pts = vf->pts;
-
- if (vf->pts_us64 != 0)
- hevc->last_lookup_pts_us64 = vf->pts_us64;
-
- if ((hevc->pts_mode == PTS_NONE_REF_USE_DURATION)
- && (slice_type != 2)) {
- vf->pts_us64 =
- hevc->last_pts_us64 +
- (DUR2PTS(hevc->frame_dur) * 100 / 9);
- }
- hevc->last_pts_us64 = vf->pts_us64;
- if ((get_dbg_flag(hevc) & H265_DEBUG_OUT_PTS) != 0) {
- hevc_print(hevc, 0,
- "H265 dec out pts: vf->pts=%d, vf->pts_us64 = %lld, ts: %llu\n",
- vf->pts, vf->pts_us64, vf->timestamp);
- }
-
- /*
- *vf->index:
- *(1) vf->type is VIDTYPE_INTERLACE
- * and vf->canvas0Addr != vf->canvas1Addr,
- * vf->index[7:0] is the index of top pic
- * vf->index[15:8] is the index of bot pic
- *(2) other cases,
- * only vf->index[7:0] is used
- * vf->index[15:8] == 0xff
- */
- vf->index = 0xff00 | pic->index;
-#if 1
-/*SUPPORT_10BIT*/
- if (pic->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
- } else {
-
- if (hevc->mmu_enable) {
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic->header_adr;
- } else {
- vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
- vf->compHeadAddr = pic->mc_y_adr +
- pic->losless_comp_body_size;
- vf->mem_head_handle = NULL;
- }
-
- /*head adr*/
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
- if (pic->double_write_mode) {
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
-
- if (v4l_output_dw_with_compress(hevc, pic->double_write_mode)) {
- vf->type |= VIDTYPE_COMPRESS;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag &&
- (get_dbg_flag(hevc)
- & H265_CFG_CANVAS_IN_DECODE) == 0) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic->canvas_config[0];
- vf->canvas0_config[1] =
- pic->canvas_config[1];
-
- vf->canvas1_config[0] =
- pic->canvas_config[0];
- vf->canvas1_config[1] =
- pic->canvas_config[1];
-
- } else
-#endif
- vf->canvas0Addr = vf->canvas1Addr
- = spec2canvas(pic);
- } else {
- vf->canvas0Addr = vf->canvas1Addr = 0;
- vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- if (hevc->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
- vf->compWidth = pic->width;
- vf->compHeight = pic->height;
- update_vf_memhandle(hevc, vf, pic);
- switch (pic->bit_depth_luma) {
- case 9:
- vf->bitdepth = BITDEPTH_Y9;
- break;
- case 10:
- vf->bitdepth = BITDEPTH_Y10;
- break;
- default:
- vf->bitdepth = BITDEPTH_Y8;
- break;
- }
- switch (pic->bit_depth_chroma) {
- case 9:
- vf->bitdepth |= (BITDEPTH_U9 | BITDEPTH_V9);
- break;
- case 10:
- vf->bitdepth |= (BITDEPTH_U10 | BITDEPTH_V10);
- break;
- default:
- vf->bitdepth |= (BITDEPTH_U8 | BITDEPTH_V8);
- break;
- }
- if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- if (pic->mem_saving_mode == 1)
- vf->bitdepth |= BITDEPTH_SAVING_MODE;
-#else
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
- vf->canvas0Addr = vf->canvas1Addr = spec2canvas(pic);
-#endif
- set_frame_info(hevc, vf, pic);
- if (hevc->discard_dv_data) {
- vf->discard_dv_data = true;
- }
-
- vf->width = pic->width;
- vf->height = pic->height;
-
- if (force_w_h != 0) {
- vf->width = (force_w_h >> 16) & 0xffff;
- vf->height = force_w_h & 0xffff;
- }
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
-
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
- if (force_fps & 0x200) {
- vf->pts = 0;
- vf->pts_us64 = 0;
- }
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- vf->pts_us64 = stream_offset;
- vf->pts = 0;
- }
- /*
- * !!! to do ...
- * need move below code to get_new_pic(),
- * hevc->xxx can only be used by current decoded pic
- */
- if (pic->conformance_window_flag &&
- (get_dbg_flag(hevc) &
- H265_DEBUG_IGNORE_CONFORMANCE_WINDOW) == 0) {
- unsigned int SubWidthC, SubHeightC;
-
- switch (pic->chroma_format_idc) {
- case 1:
- SubWidthC = 2;
- SubHeightC = 2;
- break;
- case 2:
- SubWidthC = 2;
- SubHeightC = 1;
- break;
- default:
- SubWidthC = 1;
- SubHeightC = 1;
- break;
- }
- vf->width -= SubWidthC *
- (pic->conf_win_left_offset +
- pic->conf_win_right_offset);
- vf->height -= SubHeightC *
- (pic->conf_win_top_offset +
- pic->conf_win_bottom_offset);
-
- vf->compWidth -= SubWidthC *
- (pic->conf_win_left_offset +
- pic->conf_win_right_offset);
- vf->compHeight -= SubHeightC *
- (pic->conf_win_top_offset +
- pic->conf_win_bottom_offset);
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "conformance_window %d, %d, %d, %d, %d => cropped width %d, height %d com_w %d com_h %d\n",
- pic->chroma_format_idc,
- pic->conf_win_left_offset,
- pic->conf_win_right_offset,
- pic->conf_win_top_offset,
- pic->conf_win_bottom_offset,
- vf->width, vf->height, vf->compWidth, vf->compHeight);
- }
-
- vf->width = vf->width /
- get_double_write_ratio(pic->double_write_mode);
- vf->height = vf->height /
- get_double_write_ratio(pic->double_write_mode);
-
- if (hevc->is_used_v4l && (vdec->prog_only || (!v4l2_ctx->vpp_is_need)))
- pic->pic_struct = 0;
-
- vf->height <<= hevc->interlace_flag;
- /* vf->compHeight <<= hevc->interlace_flag; */
- vf->canvas0_config[0].height <<= hevc->interlace_flag;
- vf->canvas0_config[1].height <<= hevc->interlace_flag;
-
-#ifdef HEVC_PIC_STRUCT_SUPPORT
- if (pic->pic_struct == 3 || pic->pic_struct == 4) {
- struct vframe_s *vf2;
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "pic_struct = %d index 0x%x\n",
- pic->pic_struct, pic->index);
-
- if (kfifo_get(&hevc->newframe_q, &vf2) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
-
- pic->vf_ref = 2;
- vf->duration = vf->duration>>1;
- memcpy(vf2, vf, sizeof(struct vframe_s));
-
- if (v4l2_ctx->second_field_pts_mode) {
- vf2->timestamp = 0;
- }
- if (pic->pic_struct == 3) {
- vf->type = VIDTYPE_INTERLACE_TOP
- | nv_order;
- vf2->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order;
- } else {
- vf->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order;
- vf2->type = VIDTYPE_INTERLACE_TOP
- | nv_order;
- }
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- atomic_add(1, &hevc->vf_pre_count);
- vdec_vframe_ready(hw_to_vdec(hevc), vf2);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf2);
- ATRACE_COUNTER(hevc->trace.pts_name, vf2->timestamp);
- } else {
- vh265_vf_put(vf, vdec);
- vh265_vf_put(vf2, vdec);
- atomic_add(2, &hevc->vf_get_count);
- atomic_add(2, &hevc->vf_pre_count);
- return 0;
- }
- } else if (pic->pic_struct == 5
- || pic->pic_struct == 6) {
- struct vframe_s *vf2, *vf3;
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "pic_struct = %d index 0x%x\n",
- pic->pic_struct, pic->index);
-
- if (kfifo_get(&hevc->newframe_q, &vf2) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
- if (kfifo_get(&hevc->newframe_q, &vf3) == 0) {
- hevc_print(hevc, 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
- pic->vf_ref = 3;
- vf->duration = vf->duration/3;
- memcpy(vf2, vf, sizeof(struct vframe_s));
- memcpy(vf3, vf, sizeof(struct vframe_s));
-
- if (v4l2_ctx->second_field_pts_mode) {
- vf2->timestamp = 0;
- vf3->timestamp = 0;
- }
-
- if (pic->pic_struct == 5) {
- vf->type = VIDTYPE_INTERLACE_TOP
- | nv_order;
- vf2->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order;
- vf3->type = VIDTYPE_INTERLACE_TOP
- | nv_order;
- } else {
- vf->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order;
- vf2->type = VIDTYPE_INTERLACE_TOP
- | nv_order;
- vf3->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order;
- }
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- atomic_add(1, &hevc->vf_pre_count);
- vdec_vframe_ready(hw_to_vdec(hevc), vf2);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf2);
- ATRACE_COUNTER(hevc->trace.pts_name, vf2->timestamp);
- atomic_add(1, &hevc->vf_pre_count);
- vdec_vframe_ready(hw_to_vdec(hevc), vf3);
- kfifo_put(&hevc->display_q,
- (const struct vframe_s *)vf3);
- ATRACE_COUNTER(hevc->trace.pts_name, vf3->timestamp);
- } else {
- vh265_vf_put(vf, vdec);
- vh265_vf_put(vf2, vdec);
- vh265_vf_put(vf3, vdec);
- atomic_add(3, &hevc->vf_get_count);
- atomic_add(3, &hevc->vf_pre_count);
- return 0;
- }
- } else if (pic->pic_struct == 9
- || pic->pic_struct == 10) {
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "pic_struct = %d index 0x%x\n",
- pic->pic_struct, pic->index);
-
- pic->vf_ref = 1;
- /* process previous pending vf*/
- process_pending_vframe(hevc,
- pic, (pic->pic_struct == 9));
-
- if (pic->show_frame) {
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- /* process current vf */
- kfifo_put(&hevc->pending_q,
- (const struct vframe_s *)vf);
- if (pic->pic_struct == 9) {
- vf->type = VIDTYPE_INTERLACE_TOP
- | nv_order | VIDTYPE_VIU_FIELD;
- process_pending_vframe(hevc,
- hevc->pre_bot_pic, 0);
- } else {
- vf->type = VIDTYPE_INTERLACE_BOTTOM |
- nv_order | VIDTYPE_VIU_FIELD;
- vf->index = (pic->index << 8) | 0xff;
- process_pending_vframe(hevc,
- hevc->pre_top_pic, 1);
- }
-
- if (atomic_read(&hevc->vf_pre_count) == 0)
- atomic_add(1, &hevc->vf_pre_count);
-
- /**/
- if (pic->pic_struct == 9)
- hevc->pre_top_pic = pic;
- else
- hevc->pre_bot_pic = pic;
- } else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
- atomic_add(1, &hevc->vf_pre_count);
- return 0;
- }
- } else if (pic->pic_struct == 11
- || pic->pic_struct == 12) {
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "pic_struct = %d index 0x%x\n",
- pic->pic_struct, pic->index);
- pic->vf_ref = 1;
-
- /* process previous pending vf*/
- process_pending_vframe(hevc, pic,
- (pic->pic_struct == 11));
-
- /* put current into pending q */
- if (pic->pic_struct == 11)
- vf->type = VIDTYPE_INTERLACE_TOP |
- nv_order | VIDTYPE_VIU_FIELD;
- else {
- vf->type = VIDTYPE_INTERLACE_BOTTOM |
- nv_order | VIDTYPE_VIU_FIELD;
- vf->index = (pic->index << 8) | 0xff;
- }
- if (pic->show_frame) {
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hevc->pending_q,
- (const struct vframe_s *)vf);
- if (atomic_read(&hevc->vf_pre_count) == 0)
- atomic_add(1, &hevc->vf_pre_count);
-
- /**/
- if (pic->pic_struct == 11)
- hevc->pre_top_pic = pic;
- else
- hevc->pre_bot_pic = pic;
- } else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
- atomic_add(1, &hevc->vf_pre_count);
- return 0;
- }
- } else {
- pic->vf_ref = 1;
-
- hevc_print(hevc, H265_DEBUG_PIC_STRUCT,
- "pic_struct = %d index 0x%x\n",
- pic->pic_struct, pic->index);
-
- switch (pic->pic_struct) {
- case 7:
- vf->duration <<= 1;
- break;
- case 8:
- vf->duration = vf->duration * 3;
- break;
- case 1:
- vf->type = VIDTYPE_INTERLACE_TOP |
- nv_order | VIDTYPE_VIU_FIELD;
- process_pending_vframe(hevc, pic, 1);
- hevc->pre_top_pic = pic;
- break;
- case 2:
- vf->type = VIDTYPE_INTERLACE_BOTTOM
- | nv_order
- | VIDTYPE_VIU_FIELD;
- process_pending_vframe(hevc, pic, 0);
- hevc->pre_bot_pic = pic;
- break;
- }
-
- if (pic->show_frame) {
- put_vf_to_display_q(hevc, vf);
- } else {
- vh265_vf_put(vf, vdec);
- atomic_add(1, &hevc->vf_get_count);
- atomic_add(1, &hevc->vf_pre_count);
- return 0;
- }
- }
-#else
- vf->type_original = vf->type;
- pic->vf_ref = 1;
- put_vf_to_display_q(hevc, vf);
-#endif
- ATRACE_COUNTER(hevc->trace.new_q_name, kfifo_len(&hevc->newframe_q));
- ATRACE_COUNTER(hevc->trace.disp_q_name, kfifo_len(&hevc->display_q));
- /*count info*/
- vdec_count_info(hevc->gvs, 0, stream_offset);
- if (pic->slice_type == I_SLICE) {
- hevc->gvs->i_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_KEYFRAME;
- } else if (pic->slice_type == P_SLICE) {
- hevc->gvs->p_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_PFRAME;
- } else if (pic->slice_type == B_SLICE) {
- hevc->gvs->b_decoded_frames++;
- vf->frame_type |= V4L2_BUF_FLAG_BFRAME;
- }
- hevc_update_gvs(hevc);
- memcpy(&tmp4x, hevc->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = pic->bit_depth_luma;
- tmp4x.bit_depth_chroma = pic->bit_depth_chroma;
- tmp4x.double_write_mode = pic->double_write_mode;
- vdec_fill_vdec_frame(vdec, &hevc->vframe_qos, &tmp4x, vf, pic->hw_decode_time);
- vdec->vdec_fps_detec(vdec->id);
- hevc_print(hevc, H265_DEBUG_BUFMGR,
- "%s(type %d index 0x%x poc %d/%d) pts(%d,%d) dur %d\n",
- __func__, vf->type, vf->index,
- get_pic_poc(hevc, vf->index & 0xff),
- get_pic_poc(hevc, (vf->index >> 8) & 0xff),
- vf->pts, vf->pts_us64,
- vf->duration);
- if (pic->pic_struct == 10 || pic->pic_struct == 12) {
- index = (vf->index >> 8) & 0xff;
- } else {
- index = vf->index & 0xff;
- }
-#ifdef AUX_DATA_CRC
- if (index <= MAX_REF_PIC_NUM)
- decoder_do_aux_data_check(vdec, hevc->m_PIC[index]->aux_data_buf,
- hevc->m_PIC[index]->aux_data_size);
-#endif
-
- hevc_print(hevc, H265_DEBUG_PRINT_SEI,
- "aux_data_size:%d, signal_type: %d, sei_present_flag: %d\n",
- hevc->m_PIC[index]->aux_data_size, hevc->video_signal_type, hevc->sei_present_flag);
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI) {
- int i = 0;
- PR_INIT(128);
- for (i = 0; i < hevc->m_PIC[index]->aux_data_size; i++) {
- PR_FILL("%02x ", hevc->m_PIC[index]->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
-
- if (hevc->is_used_v4l) {
- if ((hevc->m_PIC[index]->aux_data_size == 0) &&
- (pic->slice_type == I_SLICE) &&
- (atomic_read(&hevc->vf_pre_count) == 1)) {
- hevc->no_need_aux_data = true;
- }
-
- if (hevc->no_need_aux_data) {
- v4l2_ctx->aux_infos.free_one_sei_buffer(v4l2_ctx,
- &hevc->m_PIC[index]->aux_data_buf,
- &hevc->m_PIC[index]->aux_data_size,
- hevc->m_PIC[index]->ctx_buf_idx);
- } else {
- if (!hevc->discard_dv_data)
- v4l2_ctx->aux_infos.bind_dv_buffer(v4l2_ctx, &vf->src_fmt.comp_buf,
- &vf->src_fmt.md_buf);
-
- update_vframe_src_fmt(vf,
- hevc->m_PIC[index]->aux_data_buf,
- hevc->m_PIC[index]->aux_data_size,
- hevc->dv_duallayer, hevc->provider_name, NULL);
- }
- }
-
- /*if (pic->vf_ref == hevc->vf_pre_count) {*/
- if (hevc->kpi_first_i_decoded == 0) {
- hevc->kpi_first_i_decoded = 1;
- pr_debug("[vdec_kpi][%s] First I frame decoded.\n",
- __func__);
- }
-
- if (without_display_mode == 0) {
- if (hevc->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vh265_vf_put(vh265_vf_get(vdec), vdec);
- } else {
- if (hevc->send_frame_flag == 1) {
- while (kfifo_len(&hevc->display_q)) {
- if (hevc->pair_fb[0] != NULL && hevc->pair_fb[1] != NULL) {
- set_meta_data_to_vf(vf, UVM_META_DATA_VF_BASE_INFOS, hevc->v4l2_ctx);
- ATRACE_COUNTER("VC_OUT_DEC-submit", hevc->pair_fb[0]->buf_idx);
- hevc->pair_fb[0]->task->submit(hevc->pair_fb[0]->task, TASK_TYPE_DEC);
- ATRACE_COUNTER("VC_OUT_DEC-submit", hevc->pair_fb[1]->buf_idx);
- hevc->pair_fb[1]->task->submit(hevc->pair_fb[1]->task, TASK_TYPE_DEC);
- clear_pair_fb(hevc);
- } else {
- set_meta_data_to_vf(vf, UVM_META_DATA_VF_BASE_INFOS, hevc->v4l2_ctx);
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- }
- }
- }
- } else {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- }
- else
- vh265_vf_put(vh265_vf_get(vdec), vdec);
- }
-
- return 0;
-}
-
-static int post_picture_early(struct vdec_s *vdec, int index)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
- struct PIC_s *pic = hevc->m_PIC[index];
-
- if (!hevc->enable_fence)
- return 0;
-
- /* create fence for each buffers. */
- if (vdec_timeline_create_fence(vdec->sync))
- return -1;
-
- pic->fence = vdec->sync->fence;
- pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-
- if (hevc->chunk) {
- pic->pts = hevc->chunk->pts;
- pic->pts64 = hevc->chunk->pts64;
- pic->timestamp = hevc->chunk->timestamp;
- }
- pic->show_frame = true;
- post_video_frame(vdec, pic);
-
- display_frame_count[hevc->index]++;
-
- return 0;
-}
-
-static int prepare_display_buf(struct vdec_s *vdec, struct PIC_s *frame)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
-
- if (hevc->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
-
- post_prepare_process(vdec, frame);
-
- if (!frame->show_frame)
- pr_info("do not display.\n");
-
- hevc->m_PIC[frame->index]->vf_ref = 1;
-
- /* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
- mutex_lock(&hevc->fence_mutex);
- used_size = hevc->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (hevc->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(hevc->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = hevc->fence_vf_s.fence_vf[i];
- hevc->fence_vf_s.fence_vf[i] = NULL;
- hevc->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&hevc->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vh265_vf_put(signed_fence[i], vdec);
- }
- return 0;
- }
-
- if (post_prepare_process(vdec, frame))
- return -1;
-
- if (post_video_frame(vdec, frame))
- return -1;
-
- display_frame_count[hevc->index]++;
- return 0;
-}
-
-static bool is_avaliable_buffer(struct hevc_state_s *hevc);
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct hevc_state_s *hw = (struct hevc_state_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- static struct PIC_s *pic = NULL;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] H265 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- pic = v4l_get_new_pic(hw, NULL);
- if (NULL == pic) {
- pr_err("[%d] H265 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- pic->cma_alloc_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- vf->v4l_mem_handle = (ulong)fb;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- pr_info("[%d] H265 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void process_nal_sei(struct hevc_state_s *hevc,
- int payload_type, int payload_size)
-{
- unsigned short data;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\tsei message: payload_type = 0x%02x, payload_size = 0x%02x\n",
- payload_type, payload_size);
-
- if (payload_type == 137) {
- int i, j;
- /* MASTERING_DISPLAY_COLOUR_VOLUME */
- if (payload_size >= 24) {
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\tsei MASTERING_DISPLAY_COLOUR_VOLUME available\n");
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 2; j++) {
- data =
- (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- hevc->primaries[i][j] = data;
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\t\tprimaries[%1d][%1d] = %04x\n",
- i, j, hevc->primaries[i][j]);
- }
- }
- for (i = 0; i < 2; i++) {
- data = (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- hevc->white_point[i] = data;
- WRITE_HREG(HEVC_SHIFT_COMMAND, (1<<7)|16);
- if (get_dbg_flag(hevc) & H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\t\twhite_point[%1d] = %04x\n",
- i, hevc->white_point[i]);
- }
- for (i = 0; i < 2; i++) {
- data = (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- hevc->luminance[i] = data << 16;
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- data =
- (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- hevc->luminance[i] |= data;
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
- hevc_print(hevc, 0,
- "\t\tluminance[%1d] = %08x\n",
- i, hevc->luminance[i]);
- }
- hevc->sei_present_flag |= SEI_MASTER_DISPLAY_COLOR_MASK;
- }
- payload_size -= 24;
- while (payload_size > 0) {
- data = (READ_HREG(HEVC_SHIFTED_DATA) >> 24);
- payload_size--;
- WRITE_HREG(HEVC_SHIFT_COMMAND, (1<<7)|8);
- hevc_print(hevc, 0, "\t\tskip byte %02x\n", data);
- }
- }
-}
-
-static int hevc_recover(struct hevc_state_s *hevc)
-{
- int ret = -1;
- u32 rem;
- u64 shift_byte_count64;
- unsigned int hevc_shift_byte_count;
- unsigned int hevc_stream_start_addr;
- unsigned int hevc_stream_end_addr;
- unsigned int hevc_stream_rd_ptr;
- unsigned int hevc_stream_wr_ptr;
- unsigned int hevc_stream_control;
- unsigned int hevc_stream_fifo_ctl;
- unsigned int hevc_stream_buf_size;
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- mutex_lock(&vh265_mutex);
-#if 0
- for (i = 0; i < (hevc->debug_ptr_size / 2); i += 4) {
- int ii;
-
- for (ii = 0; ii < 4; ii++)
- hevc_print(hevc, 0,
- "%04x ", hevc->debug_ptr[i + 3 - ii]);
- if (((i + ii) & 0xf) == 0)
- hevc_print(hevc, 0, "\n");
- }
-#endif
-#define ES_VID_MAN_RD_PTR (1<<0)
- if (!hevc->init_flag) {
- hevc_print(hevc, 0, "h265 has stopped, recover return!\n");
- mutex_unlock(&vh265_mutex);
- return ret;
- }
- amhevc_stop();
- msleep(20);
- ret = 0;
- /* reset */
- if (vdec_stream_based(vdec)) {
- STBUF_WRITE(&vdec->vbuf, set_rp,
- READ_VREG(HEVC_STREAM_RD_PTR));
-
- if (!vdec->vbuf.no_parser)
- SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
- ES_VID_MAN_RD_PTR);
- }
-
- hevc_stream_start_addr = READ_VREG(HEVC_STREAM_START_ADDR);
- hevc_stream_end_addr = READ_VREG(HEVC_STREAM_END_ADDR);
- hevc_stream_rd_ptr = READ_VREG(HEVC_STREAM_RD_PTR);
- hevc_stream_wr_ptr = READ_VREG(HEVC_STREAM_WR_PTR);
- hevc_stream_control = READ_VREG(HEVC_STREAM_CONTROL);
- hevc_stream_fifo_ctl = READ_VREG(HEVC_STREAM_FIFO_CTL);
- hevc_stream_buf_size = hevc_stream_end_addr - hevc_stream_start_addr;
-
- /* HEVC streaming buffer will reset and restart
- * from current hevc_stream_rd_ptr position
- */
- /* calculate HEVC_SHIFT_BYTE_COUNT value with the new position. */
- hevc_shift_byte_count = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- if ((hevc->shift_byte_count_lo & (1 << 31))
- && ((hevc_shift_byte_count & (1 << 31)) == 0))
- hevc->shift_byte_count_hi++;
-
- hevc->shift_byte_count_lo = hevc_shift_byte_count;
- shift_byte_count64 = ((u64)(hevc->shift_byte_count_hi) << 32) |
- hevc->shift_byte_count_lo;
- div_u64_rem(shift_byte_count64, hevc_stream_buf_size, &rem);
- shift_byte_count64 -= rem;
- shift_byte_count64 += hevc_stream_rd_ptr - hevc_stream_start_addr;
-
- if (rem > (hevc_stream_rd_ptr - hevc_stream_start_addr))
- shift_byte_count64 += hevc_stream_buf_size;
-
- hevc->shift_byte_count_lo = (u32)shift_byte_count64;
- hevc->shift_byte_count_hi = (u32)(shift_byte_count64 >> 32);
-
- WRITE_VREG(DOS_SW_RESET3,
- /* (1<<2)| */
- (1 << 3) | (1 << 4) | (1 << 8) |
- (1 << 11) | (1 << 12) | (1 << 14)
- | (1 << 15) | (1 << 17) | (1 << 18) | (1 << 19));
- WRITE_VREG(DOS_SW_RESET3, 0);
-
- WRITE_VREG(HEVC_STREAM_START_ADDR, hevc_stream_start_addr);
- WRITE_VREG(HEVC_STREAM_END_ADDR, hevc_stream_end_addr);
- WRITE_VREG(HEVC_STREAM_RD_PTR, hevc_stream_rd_ptr);
- WRITE_VREG(HEVC_STREAM_WR_PTR, hevc_stream_wr_ptr);
- WRITE_VREG(HEVC_STREAM_CONTROL, hevc_stream_control);
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, hevc->shift_byte_count_lo);
- WRITE_VREG(HEVC_STREAM_FIFO_CTL, hevc_stream_fifo_ctl);
-
- hevc_config_work_space_hw(hevc);
- decoder_hw_reset();
-
- hevc->have_vps = 0;
- hevc->have_sps = 0;
- hevc->have_pps = 0;
-
- hevc->have_valid_start_slice = 0;
-
- if (get_double_write_mode(hevc) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
- 0x1 << 31 /*/Enable NV21 reference read mode for MC*/
- );
-
- WRITE_VREG(HEVC_WAIT_FLAG, 1);
- /* clear mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
- /* enable mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1);
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(HEVC_PSCALE_CTRL, 0);
-
- CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);
-
- WRITE_VREG(DEBUG_REG1, 0x0);
-
- if ((error_handle_policy & 1) == 0) {
- if ((error_handle_policy & 4) == 0) {
- /* ucode auto mode, and do not check vps/sps/pps/idr */
- WRITE_VREG(NAL_SEARCH_CTL,
- 0xc);
- } else {
- WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */
- }
- } else {
- WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */
- }
-
- if (get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE)
- WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x10000);
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL)
- | ((parser_sei_enable & 0x7) << 17));
-/*#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION*/
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) |
- ((parser_dolby_vision_enable & 0x1) << 20));
-/*#endif*/
- config_decode_mode(hevc);
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-
- /* if (amhevc_loadmc(vh265_mc) < 0) { */
- /* amhevc_disable(); */
- /* return -EBUSY; */
- /* } */
-#if 0
- for (i = 0; i < (hevc->debug_ptr_size / 2); i += 4) {
- int ii;
-
- for (ii = 0; ii < 4; ii++) {
- /* hevc->debug_ptr[i+3-ii]=ttt++; */
- hevc_print(hevc, 0,
- "%04x ", hevc->debug_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- hevc_print(hevc, 0, "\n");
- }
-#endif
- init_pic_list_hw(hevc);
-
- hevc_print(hevc, 0, "%s HEVC_SHIFT_BYTE_COUNT=0x%x\n", __func__,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
-
-#ifdef SWAP_HEVC_UCODE
- if (!tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->mc_dma_handle);
- /*pr_info("write swap buffer %x\n", (u32)(hevc->mc_dma_handle));*/
- }
-#endif
- amhevc_start();
-
- /* skip, search next start code */
- WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2));
- hevc->skip_flag = 1;
-#ifdef ERROR_HANDLE_DEBUG
- if (dbg_nal_skip_count & 0x20000) {
- dbg_nal_skip_count &= ~0x20000;
- mutex_unlock(&vh265_mutex);
- return ret;
- }
-#endif
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hevc->m_ins_flag)
-#endif
- hevc->first_pic_after_recover = 1;
- mutex_unlock(&vh265_mutex);
- return ret;
-}
-
-static void dump_aux_buf(struct hevc_state_s *hevc)
-{
- int i;
- unsigned short *aux_adr =
- (unsigned short *)
- hevc->aux_addr;
- unsigned int aux_size =
- (READ_VREG(HEVC_AUX_DATA_SIZE)
- >> 16) << 4;
- PR_INIT(128);
-
- if (hevc->prefix_aux_size > 0) {
- hevc_print(hevc, 0,
- "prefix aux: (size %d)\n",
- aux_size);
- if (aux_size > hevc->prefix_aux_size) {
- hevc_print(hevc, 0,
- "%s:aux_size(%d) is over size\n", __func__, aux_size);
- return ;
- }
- for (i = 0; i < (aux_size >> 1); i++) {
- PR_FILL("%04x ", *(aux_adr + i));
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);;
- }
- PR_INFO(hevc->index);;
- }
- if (hevc->suffix_aux_size > 0) {
- aux_adr = (unsigned short *)
- (hevc->aux_addr +
- hevc->prefix_aux_size);
- aux_size =
- (READ_VREG(HEVC_AUX_DATA_SIZE) & 0xffff)
- << 4;
- hevc_print(hevc, 0,
- "suffix aux: (size %d)\n",
- aux_size);
- if (aux_size > hevc->suffix_aux_size) {
- hevc_print(hevc, 0,
- "%s:aux_size(%d) is over size\n", __func__, aux_size);
- return ;
- }
- for (i = 0; i <
- (aux_size >> 1); i++) {
- PR_FILL("%04x ", *(aux_adr + i));
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
- }
-}
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static void dolby_get_meta(struct hevc_state_s *hevc)
-{
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
- dump_aux_buf(hevc);
- if (vdec->dolby_meta_with_el || vdec->slave) {
- set_aux_data(hevc,
- hevc->cur_pic, 0, 0);
- } else if (vdec->master) {
- struct hevc_state_s *hevc_ba =
- (struct hevc_state_s *)
- vdec->master->private;
- /*do not use hevc_ba*/
- set_aux_data(hevc,
- hevc_ba->cur_pic,
- 0, 1);
- set_aux_data(hevc,
- hevc->cur_pic, 0, 2);
- } else if (vdec_frame_based(vdec)) {
- set_aux_data(hevc,
- hevc->cur_pic, 1, 0);
- }
-}
-#endif
-
-static void read_decode_info(struct hevc_state_s *hevc)
-{
- uint32_t decode_info =
- READ_HREG(HEVC_DECODE_INFO);
- hevc->start_decoding_flag |=
- (decode_info & 0xff);
- hevc->rps_set_id = (decode_info >> 8) & 0xff;
-}
-
-static int vh265_get_ps_info(struct hevc_state_s *hevc,
- union param_u *rpm_param,
- struct aml_vdec_ps_infos *ps)
-{
- u32 SubWidthC, SubHeightC;
- u32 width = rpm_param->p.pic_width_in_luma_samples;
- u32 height = rpm_param->p.pic_height_in_luma_samples;
-
- switch (rpm_param->p.chroma_format_idc) {
- case 1:
- SubWidthC = 2;
- SubHeightC = 2;
- break;
- case 2:
- SubWidthC = 2;
- SubHeightC = 1;
- break;
- default:
- SubWidthC = 1;
- SubHeightC = 1;
- break;
- }
-
- width -= SubWidthC *
- (rpm_param->p.conf_win_left_offset +
- rpm_param->p.conf_win_right_offset);
- height -= SubHeightC *
- (rpm_param->p.conf_win_top_offset +
- rpm_param->p.conf_win_bottom_offset);
-
- hevc->last_width = rpm_param->p.pic_width_in_luma_samples;
- hevc->last_height = rpm_param->p.pic_height_in_luma_samples;
- hevc->sps_num_reorder_pics_0 =
- rpm_param->p.sps_num_reorder_pics_0;
-
- height <<= hevc->interlace_flag;
- ps->visible_width = width;
- ps->visible_height = height;
- ps->coded_width = ALIGN(width, 64);
- ps->coded_height = ALIGN(height, 64);
- ps->field = hevc->interlace_flag ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
- ps->dpb_frames = v4l_parser_work_pic_num(hevc);
- ps->dpb_margin = get_dynamic_buf_num_margin(hevc);
-
- return 0;
-}
-
-static int vh265_get_cfg_info(struct hevc_state_s *hevc,
- union param_u *rpm_param,
- struct aml_vdec_cfg_infos *cfg)
-{
- /* force h265 interlace video to double write 1*/
- if (hevc->interlace_flag) {
- cfg->double_write_mode = 1;
- hevc->double_write_mode = 1;
- hevc_print(hevc, 0,
- "hevc interlace force dw 1\n");
- }
- cfg->init_width = rpm_param->p.pic_width_in_luma_samples;
- cfg->init_height = rpm_param->p.pic_height_in_luma_samples
- << hevc->interlace_flag;
-
- return 0;
-}
-
-static void get_comp_buf_info(struct hevc_state_s *hevc,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = hevc->param.p.bit_depth;
- int w = hevc->param.p.pic_width_in_luma_samples;
- int h = hevc->param.p.pic_height_in_luma_samples;
-
- info->max_size = hevc_max_mmu_buf_size(
- hevc->max_pic_w,
- hevc->max_pic_h);
- info->header_size = hevc_get_header_size(w,h);
- info->frame_buffer_size = hevc_mmu_page_num(
- hevc, w, h, bit_depth == 0);
-
- pr_info("hevc get comp info: %d %d %d\n",
- info->max_size, info->header_size,
- info->frame_buffer_size);
-}
-
-static int is_interlace(struct hevc_state_s *hevc)
-{
- int pic_struct = (hevc->param.p.sei_frame_field_info >> 3) & 0xf;
- int frame_field_info_present_flag =
- (hevc->param.p.sei_frame_field_info >> 8) & 0x1;
-
- if ((hevc->param.p.profile_etc & 0xc) == 0x4
- && (frame_field_info_present_flag
- && (pic_struct == 0
- || pic_struct == 7
- || pic_struct == 8)))
- return 0;
- else if ((hevc->param.p.profile_etc & 0xc) == 0x4)
- return 1;
-
- return 0;
-}
-
-static void hevc_interlace_check(struct hevc_state_s *hevc,
- union param_u *rpm_param)
-{
- int w, h;
-
- w = hevc->param.p.pic_width_in_luma_samples;
- h = hevc->param.p.pic_height_in_luma_samples;
- /* interlace check, 4k force no interlace */
- if ((interlace_enable != 0) &&
- (!IS_4K_SIZE(w, h)) &&
- (is_interlace(hevc))) {
- hevc->interlace_flag = 1;
- hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2;
- hevc_print(hevc, 0,
- "interlace (%d, %d), profile_etc %x, ar 0x%x, dw %d\n",
- hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar,
- get_double_write_mode(hevc));
- }
-}
-
-static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- int i, ret = 0;
-
- if (ctx->param_sets_from_ucode) {
- struct aml_vdec_ps_infos ps;
- int width = rpm_param->p.pic_width_in_luma_samples;
- int height = rpm_param->p.pic_height_in_luma_samples;
-
- if ((hevc->last_width != 0 &&
- hevc->last_height != 0) &&
- (hevc->last_width != width ||
- hevc->last_height != height)) {
- hevc_print(hevc, 0,
- "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d), interlace %d\n",
- hevc->last_width, hevc->last_height,
- width,
- height,
- hevc->interlace_flag);
-
- if (get_valid_double_write_mode(hevc) != 16) {
- struct vdec_comp_buf_info info;
-
- get_comp_buf_info(hevc, &info);
- vdec_v4l_set_comp_buf_info(ctx, &info);
- }
- vh265_get_ps_info(hevc, &hevc->param, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hevc->v4l_params_parsed = false;
- ctx->v4l_resolution_change = 1;
- hevc->eos = 1;
- hevc->resolution_change = true;
-
- /*
- * marks frame valid on the dpb is the ouput state,
- * then via flush_output all frames can be flushed out.
- */
- for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
- if ((hevc->m_PIC[i] == NULL) ||
- (hevc->m_PIC[i]->index == -1) ||
- (hevc->m_PIC[i]->BUF_index == -1))
- continue;
-
- if ((hevc->m_PIC[i]->POC != INVALID_POC) &&
- (hevc->m_PIC[i]->output_ready == 0) &&
- hevc->m_PIC[i]->referenced &&
- (hevc->m_PIC[i]->POC >= hevc->decoded_poc)) {
- hevc->m_PIC[i]->output_mark = 1;
- }
- }
-
- flush_output(hevc, NULL);
- //del_timer_sync(&hevc->timer);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hevc));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
-
- ret = 1;
- }
- }
-
- return ret;
-}
-
-static int hevc_skip_nal(struct hevc_state_s *hevc)
-{
- if ((hevc->pic_h == 96) && (hevc->pic_w == 160) &&
- (get_double_write_mode(hevc) == 0x10)) {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TXLX) {
- if (hevc->skip_nal_count < skip_nal_count)
- return 1;
- } else {
- if (hevc->skip_nal_count < 1)
- return 1;
- }
- }
- return 0;
-}
-
-static irqreturn_t vh265_isr_thread_fn(int irq, void *data)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *) data;
- unsigned int dec_status = hevc->dec_status;
- int i, ret;
-
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (dec_status == HEVC_SLICE_SEGMENT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
- if (hevc->eos)
- return IRQ_HANDLED;
- if (
-#ifdef MULTI_INSTANCE_SUPPORT
- (!hevc->m_ins_flag) &&
-#endif
- hevc->error_flag == 1) {
- if ((error_handle_policy & 0x10) == 0) {
- if (hevc->cur_pic) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- if (current_lcu_idx <
- ((hevc->lcu_x_num*hevc->lcu_y_num)-1))
- hevc->cur_pic->error_mark = 1;
-
- }
- }
- if ((error_handle_policy & 1) == 0) {
- hevc->error_skip_nal_count = 1;
- /* manual search nal, skip error_skip_nal_count
- * of nal and trigger the HEVC_NAL_SEARCH_DONE irq
- */
- WRITE_VREG(NAL_SEARCH_CTL,
- (error_skip_nal_count << 4) | 0x1);
- } else {
- hevc->error_skip_nal_count = error_skip_nal_count;
- WRITE_VREG(NAL_SEARCH_CTL, 0x1);/* manual parser NAL */
- }
- if ((get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE)
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- || vdec->master
- || vdec->slave
-#endif
- ) {
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) | 0x10000);
- }
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL)
- | ((parser_sei_enable & 0x7) << 17));
-/*#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION*/
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) |
- ((parser_dolby_vision_enable & 0x1) << 20));
-/*#endif*/
- config_decode_mode(hevc);
- /* search new nal */
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-
- /* hevc_print(hevc, 0,
- *"%s: error handle\n", __func__);
- */
- hevc->error_flag = 2;
- return IRQ_HANDLED;
- } else if (
-#ifdef MULTI_INSTANCE_SUPPORT
- (!hevc->m_ins_flag) &&
-#endif
- hevc->error_flag == 3) {
- hevc_print(hevc, 0, "error_flag=3, hevc_recover\n");
- hevc_recover(hevc);
- hevc->error_flag = 0;
-
- if ((error_handle_policy & 0x10) == 0) {
- if (hevc->cur_pic) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- if (current_lcu_idx <
- ((hevc->lcu_x_num*hevc->lcu_y_num)-1))
- hevc->cur_pic->error_mark = 1;
-
- }
- }
- if ((error_handle_policy & 1) == 0) {
- /* need skip some data when
- * error_flag of 3 is triggered,
- */
- /* to avoid hevc_recover() being called
- * for many times at the same bitstream position
- */
- hevc->error_skip_nal_count = 1;
- /* manual search nal, skip error_skip_nal_count
- * of nal and trigger the HEVC_NAL_SEARCH_DONE irq
- */
- WRITE_VREG(NAL_SEARCH_CTL,
- (error_skip_nal_count << 4) | 0x1);
- }
-
- if ((error_handle_policy & 0x2) == 0) {
- hevc->have_vps = 1;
- hevc->have_sps = 1;
- hevc->have_pps = 1;
- }
- return IRQ_HANDLED;
- }
- if (!hevc->m_ins_flag) {
- i = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- if ((hevc->shift_byte_count_lo & (1 << 31))
- && ((i & (1 << 31)) == 0))
- hevc->shift_byte_count_hi++;
- hevc->shift_byte_count_lo = i;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- mutex_lock(&hevc->chunks_mutex);
- if ((dec_status == HEVC_DECPIC_DATA_DONE ||
- dec_status == HEVC_FIND_NEXT_PIC_NAL ||
- dec_status == HEVC_FIND_NEXT_DVEL_NAL)
- && (hevc->chunk)) {
- hevc->cur_pic->pts = hevc->chunk->pts;
- hevc->cur_pic->pts64 = hevc->chunk->pts64;
- hevc->cur_pic->timestamp = hevc->chunk->timestamp;
- }
- mutex_unlock(&hevc->chunks_mutex);
-
- if (dec_status == HEVC_DECODE_BUFEMPTY ||
- dec_status == HEVC_DECODE_BUFEMPTY2) {
- if (hevc->m_ins_flag) {
- read_decode_info(hevc);
- if (vdec_frame_based(hw_to_vdec(hevc))) {
- hevc->empty_flag = 1;
- /*suffix sei or dv meta*/
- set_aux_data(hevc, hevc->cur_pic, 1, 0);
- goto pic_done;
- } else {
- if (
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- vdec->master ||
- vdec->slave ||
-#endif
- (data_resend_policy & 0x1)) {
- hevc->dec_result = DEC_RESULT_AGAIN;
- amhevc_stop();
- restore_decode_state(hevc);
- } else
- hevc->dec_result = DEC_RESULT_GET_DATA;
- }
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
- }
- return IRQ_HANDLED;
- } else if ((dec_status == HEVC_SEARCH_BUFEMPTY) ||
- (dec_status == HEVC_NAL_DECODE_DONE)
- ) {
- if (hevc->m_ins_flag) {
- read_decode_info(hevc);
- if (vdec_frame_based(hw_to_vdec(hevc))) {
- /*hevc->dec_result = DEC_RESULT_GET_DATA;*/
- hevc->empty_flag = 1;
- /*suffix sei or dv meta*/
- set_aux_data(hevc, hevc->cur_pic, 1, 0);
- goto pic_done;
- } else {
- hevc->dec_result = DEC_RESULT_AGAIN;
- amhevc_stop();
- restore_decode_state(hevc);
- }
-
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
- }
-
- return IRQ_HANDLED;
- } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- if (hevc->m_ins_flag) {
- struct PIC_s *pic;
- struct PIC_s *pic_display;
- int decoded_poc;
-
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- if (hevc->detbuf_adr_virt && hevc->delrefill_check
- && READ_VREG(HEVC_SAO_DBG_MODE0))
- hevc->delrefill_check = 2;
- }
-#endif
- hevc->empty_flag = 0;
-pic_done:
- if (vdec->master == NULL && vdec->slave == NULL &&
- hevc->empty_flag == 0) {
- hevc->over_decode =
- (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
- if (hevc->over_decode)
- hevc_print(hevc, 0,
- "!!!Over decode %d\n", __LINE__);
- }
- if (input_frame_based(hw_to_vdec(hevc)) &&
- frmbase_cont_bitlevel != 0 &&
- (hevc->decode_size > READ_VREG(HEVC_SHIFT_BYTE_COUNT)) &&
- (hevc->decode_size - (READ_VREG(HEVC_SHIFT_BYTE_COUNT))
- > frmbase_cont_bitlevel)) {
- check_pic_decoded_error(hevc, READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff);
- /*handle the case: multi pictures in one packet*/
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s has more data index= %d, size=0x%x shiftcnt=0x%x)\n",
- __func__,
- hevc->decode_idx, hevc->decode_size,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- start_process_time(hevc);
- return IRQ_HANDLED;
- }
-
- read_decode_info(hevc);
- get_picture_qos_info(hevc);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hevc->start_parser_type = 0;
- hevc->switch_dvlayer_flag = 0;
-#endif
- hevc->decoded_poc = hevc->curr_POC;
- hevc->decoding_pic = NULL;
- hevc->dec_result = DEC_RESULT_DONE;
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- if (hevc->delrefill_check != 2)
-#endif
-
- amhevc_stop();
-
- reset_process_time(hevc);
-
- if ((!input_stream_based(vdec) &&
- atomic_read(&hevc->vf_pre_count) == 0) || hevc->ip_mode) {
- decoded_poc = hevc->curr_POC;
- pic = get_pic_by_POC(hevc, decoded_poc);
- if (pic && (pic->POC != INVALID_POC)) {
- /*PB skip control */
- if (pic->error_mark == 0
- && hevc->PB_skip_mode == 1) {
- /* start decoding after
- * first I
- */
- hevc->ignore_bufmgr_error |= 0x1;
- }
- if (hevc->ignore_bufmgr_error & 1) {
- if (hevc->PB_skip_count_after_decoding > 0) {
- hevc->PB_skip_count_after_decoding--;
- } else {
- /* start displaying */
- hevc->ignore_bufmgr_error |= 0x2;
- }
- }
- if (hevc->mmu_enable
- && ((hevc->double_write_mode & 0x10) == 0)) {
- if (!hevc->m_ins_flag) {
- hevc->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
-
- if ((!is_skip_decoding(hevc, pic)) &&
- (hevc->used_4k_num >= 0) &&
- (hevc->cur_pic->scatter_alloc
- == 1))
- recycle_mmu_buf_tail(hevc, false);
- }
- }
-
- pic->output_mark = 1;
- pic->recon_mark = 1;
- if (vdec->mvfrm) {
- pic->frame_size =
- vdec->mvfrm->frame_size;
- pic->hw_decode_time =
- (u32)vdec->mvfrm->hw_decode_time;
- }
- }
- /*Detects the first frame whether has an over decode error*/
- if (vdec->master == NULL && vdec->slave == NULL &&
- hevc->empty_flag == 0) {
- hevc->over_decode =
- (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
- if (hevc->over_decode)
- hevc_print(hevc, 0,
- "!!!Over decode %d\n", __LINE__);
- }
- check_pic_decoded_error(hevc,
- READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff);
- if (hevc->cur_pic != NULL &&
- (READ_VREG(HEVC_PARSER_LCU_START) & 0xffffff) == 0
- && (hevc->lcu_x_num * hevc->lcu_y_num != 1))
- hevc->cur_pic->error_mark = 1;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-force_output:
-#endif
- pic_display = output_pic(hevc, 1);
-
- if (pic_display) {
- if ((pic_display->error_mark &&
- ((hevc->ignore_bufmgr_error &
- 0x2) == 0))
- || (get_dbg_flag(hevc) &
- H265_DEBUG_DISPLAY_CUR_FRAME)
- || (get_dbg_flag(hevc) &
- H265_DEBUG_NO_DISPLAY)) {
- pic_display->output_ready = 0;
- if (get_dbg_flag(hevc) &
- H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "[BM] Display: POC %d, ",
- pic_display->POC);
- hevc_print_cont(hevc, 0,
- "decoding index %d ==> ",
- pic_display->
- decode_idx);
- hevc_print_cont(hevc, 0,
- "Debug or err,recycle it\n");
- }
- } else {
- if ((pic_display->
- slice_type != 2) && !pic_display->ip_mode) {
- pic_display->output_ready = 0;
- } else {
- prepare_display_buf
- (hw_to_vdec(hevc),
- pic_display);
- hevc->first_pic_flag = 1;
- }
- }
- }
- }
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- vdec_schedule_work(&hevc->work);
- }
-
- return IRQ_HANDLED;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- } else if (dec_status == HEVC_FIND_NEXT_PIC_NAL ||
- dec_status == HEVC_FIND_NEXT_DVEL_NAL) {
- if (hevc->m_ins_flag) {
- unsigned char next_parser_type =
- READ_HREG(CUR_NAL_UNIT_TYPE) & 0xff;
- read_decode_info(hevc);
-
- if (vdec->slave &&
- dec_status == HEVC_FIND_NEXT_DVEL_NAL) {
- /*cur is base, found enhance*/
- struct hevc_state_s *hevc_el =
- (struct hevc_state_s *)
- vdec->slave->private;
- hevc->switch_dvlayer_flag = 1;
- hevc->no_switch_dvlayer_count = 0;
- hevc_el->start_parser_type =
- next_parser_type;
- hevc_print(hevc, H265_DEBUG_DV,
- "switch (poc %d) to el\n",
- hevc->cur_pic ?
- hevc->cur_pic->POC :
- INVALID_POC);
- } else if (vdec->master &&
- dec_status == HEVC_FIND_NEXT_PIC_NAL) {
- /*cur is enhance, found base*/
- struct hevc_state_s *hevc_ba =
- (struct hevc_state_s *)
- vdec->master->private;
- hevc->switch_dvlayer_flag = 1;
- hevc->no_switch_dvlayer_count = 0;
- hevc_ba->start_parser_type =
- next_parser_type;
- hevc_print(hevc, H265_DEBUG_DV,
- "switch (poc %d) to bl\n",
- hevc->cur_pic ?
- hevc->cur_pic->POC :
- INVALID_POC);
- } else {
- hevc->switch_dvlayer_flag = 0;
- hevc->start_parser_type =
- next_parser_type;
- hevc->no_switch_dvlayer_count++;
- hevc_print(hevc, H265_DEBUG_DV,
- "%s: no_switch_dvlayer_count = %d\n",
- vdec->master ? "el" : "bl",
- hevc->no_switch_dvlayer_count);
- if (vdec->slave &&
- dolby_el_flush_th != 0 &&
- hevc->no_switch_dvlayer_count >
- dolby_el_flush_th) {
- struct hevc_state_s *hevc_el =
- (struct hevc_state_s *)
- vdec->slave->private;
- struct PIC_s *el_pic;
- check_pic_decoded_error(hevc_el,
- hevc_el->pic_decoded_lcu_idx);
- el_pic = get_pic_by_POC(hevc_el,
- hevc_el->curr_POC);
- hevc_el->curr_POC = INVALID_POC;
- hevc_el->m_pocRandomAccess = MAX_INT;
- flush_output(hevc_el, el_pic);
- hevc_el->decoded_poc = INVALID_POC; /*
- already call flush_output*/
- hevc_el->decoding_pic = NULL;
- hevc->no_switch_dvlayer_count = 0;
- if (get_dbg_flag(hevc) & H265_DEBUG_DV)
- hevc_print(hevc, 0,
- "no el anymore, flush_output el\n");
- }
- }
- hevc->decoded_poc = hevc->curr_POC;
- hevc->decoding_pic = NULL;
- hevc->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- reset_process_time(hevc);
- if (aux_data_is_avaible(hevc))
- dolby_get_meta(hevc);
- if(hevc->cur_pic && hevc->cur_pic->slice_type == 2 &&
- atomic_read(&hevc->vf_pre_count) == 0) {
- hevc_print(hevc, 0,
- "first slice_type %x no_switch_dvlayer_count %x\n",
- hevc->cur_pic->slice_type,
- hevc->no_switch_dvlayer_count);
- goto force_output;
- }
- vdec_schedule_work(&hevc->work);
- }
-
- return IRQ_HANDLED;
-#endif
- }
-
-#endif
-
- if (dec_status == HEVC_SEI_DAT) {
- if (!hevc->m_ins_flag) {
- int payload_type =
- READ_HREG(CUR_NAL_UNIT_TYPE) & 0xffff;
- int payload_size =
- (READ_HREG(CUR_NAL_UNIT_TYPE) >> 16) & 0xffff;
- process_nal_sei(hevc,
- payload_type, payload_size);
- }
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_SEI_DAT_DONE);
- } else if (dec_status == HEVC_NAL_SEARCH_DONE) {
- int naltype = READ_HREG(CUR_NAL_UNIT_TYPE);
- int parse_type = HEVC_DISCARD_NAL;
-
- hevc->error_watchdog_count = 0;
- hevc->error_skip_nal_wt_cnt = 0;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag)
- reset_process_time(hevc);
-#endif
- if (slice_parse_begin > 0 &&
- get_dbg_flag(hevc) & H265_DEBUG_DISCARD_NAL) {
- hevc_print(hevc, 0,
- "nal type %d, discard %d\n", naltype,
- slice_parse_begin);
- if (naltype <= NAL_UNIT_CODED_SLICE_CRA)
- slice_parse_begin--;
- }
- if (naltype == NAL_UNIT_EOS) {
- struct PIC_s *pic;
- bool eos_in_head = false;
-
- hevc_print(hevc, 0, "get NAL_UNIT_EOS, flush output\n");
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if ((!hevc->discard_dv_data) && aux_data_is_avaible(hevc)) {
- if (hevc->decoding_pic)
- dolby_get_meta(hevc);
- }
-#endif
- /*Detects frame whether has an over decode error*/
- if (vdec->master == NULL && vdec->slave == NULL &&
- hevc->empty_flag == 0 && input_stream_based(vdec)) {
- hevc->over_decode =
- (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
- if (hevc->over_decode)
- hevc_print(hevc, 0,
- "!!!Over decode %d\n", __LINE__);
- }
- check_pic_decoded_error(hevc,
- hevc->pic_decoded_lcu_idx);
- pic = get_pic_by_POC(hevc, hevc->curr_POC);
- hevc->curr_POC = INVALID_POC;
- /* add to fix RAP_B_Bossen_1 */
- hevc->m_pocRandomAccess = MAX_INT;
- flush_output(hevc, pic);
- clear_poc_flag(hevc);
- if (input_frame_based(vdec)) {
- u32 shiftbyte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- if (shiftbyte < 0x8 && (hevc->decode_size - shiftbyte) > 0x100) {
- hevc_print(hevc, 0," shiftbytes 0x%x decode_size 0x%x\n", shiftbyte, hevc->decode_size);
- eos_in_head = true;
- }
- }
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_DISCARD_NAL);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-
- /* eos is in the head of the chunk and followed by sps/pps/IDR
- * so need to go on decoding
- */
- if (eos_in_head)
- return IRQ_HANDLED;
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- hevc->decoded_poc = INVALID_POC; /*
- already call flush_output*/
- hevc->decoding_pic = NULL;
- hevc->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
-
- vdec_schedule_work(&hevc->work);
- }
-#endif
- return IRQ_HANDLED;
- }
-
- if (
-#ifdef MULTI_INSTANCE_SUPPORT
- (!hevc->m_ins_flag) &&
-#endif
- hevc->error_skip_nal_count > 0) {
- hevc_print(hevc, 0,
- "nal type %d, discard %d\n", naltype,
- hevc->error_skip_nal_count);
- hevc->error_skip_nal_count--;
- if (hevc->error_skip_nal_count == 0) {
- hevc_recover(hevc);
- hevc->error_flag = 0;
- if ((error_handle_policy & 0x2) == 0) {
- hevc->have_vps = 1;
- hevc->have_sps = 1;
- hevc->have_pps = 1;
- }
- return IRQ_HANDLED;
- }
- } else if (naltype == NAL_UNIT_VPS) {
- parse_type = HEVC_NAL_UNIT_VPS;
- hevc->have_vps = 1;
-#ifdef ERROR_HANDLE_DEBUG
- if (dbg_nal_skip_flag & 1)
- parse_type = HEVC_DISCARD_NAL;
-#endif
- } else if (hevc->have_vps) {
- if (naltype == NAL_UNIT_SPS) {
- parse_type = HEVC_NAL_UNIT_SPS;
- hevc->have_sps = 1;
-#ifdef ERROR_HANDLE_DEBUG
- if (dbg_nal_skip_flag & 2)
- parse_type = HEVC_DISCARD_NAL;
-#endif
- } else if (naltype == NAL_UNIT_PPS) {
- parse_type = HEVC_NAL_UNIT_PPS;
- hevc->have_pps = 1;
-#ifdef ERROR_HANDLE_DEBUG
- if (dbg_nal_skip_flag & 4)
- parse_type = HEVC_DISCARD_NAL;
-#endif
- } else if (hevc->have_sps && hevc->have_pps) {
- int seg = HEVC_NAL_UNIT_CODED_SLICE_SEGMENT;
-
- if ((naltype == NAL_UNIT_CODED_SLICE_IDR) ||
- (naltype ==
- NAL_UNIT_CODED_SLICE_IDR_N_LP)
- || (naltype ==
- NAL_UNIT_CODED_SLICE_CRA)
- || (naltype ==
- NAL_UNIT_CODED_SLICE_BLA)
- || (naltype ==
- NAL_UNIT_CODED_SLICE_BLANT)
- || (naltype ==
- NAL_UNIT_CODED_SLICE_BLA_N_LP)
- ) {
- if (slice_parse_begin > 0) {
- hevc_print(hevc, 0,
- "discard %d, for debugging\n",
- slice_parse_begin);
- slice_parse_begin--;
- } else {
- parse_type = seg;
- }
- hevc->have_valid_start_slice = 1;
- } else if (naltype <=
- NAL_UNIT_CODED_SLICE_CRA
- && (hevc->have_valid_start_slice
- || (hevc->PB_skip_mode != 3))) {
- if (slice_parse_begin > 0) {
- hevc_print(hevc, 0,
- "discard %d, dd\n",
- slice_parse_begin);
- slice_parse_begin--;
- } else
- parse_type = seg;
-
- }
- }
- }
- if (hevc->have_vps && hevc->have_sps && hevc->have_pps
- && hevc->have_valid_start_slice &&
- hevc->error_flag == 0) {
- if ((get_dbg_flag(hevc) &
- H265_DEBUG_MAN_SEARCH_NAL) == 0
- /* && (!hevc->m_ins_flag)*/) {
- /* auot parser NAL; do not check
- *vps/sps/pps/idr
- */
- WRITE_VREG(NAL_SEARCH_CTL, 0x2);
- }
-
- if ((get_dbg_flag(hevc) &
- H265_DEBUG_NO_EOS_SEARCH_DONE)
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- || vdec->master
- || vdec->slave
-#endif
- ) {
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) |
- 0x10000);
- }
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL)
- | ((parser_sei_enable & 0x7) << 17));
-/*#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION*/
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) |
- ((parser_dolby_vision_enable & 0x1) << 20));
-/*#endif*/
- config_decode_mode(hevc);
- }
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR) {
- hevc_print(hevc, 0,
- "naltype = %d parse_type %d\n %d %d %d %d\n",
- naltype, parse_type, hevc->have_vps,
- hevc->have_sps, hevc->have_pps,
- hevc->have_valid_start_slice);
- }
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, parse_type);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag)
- start_process_time(hevc);
-#endif
- } else if (dec_status == HEVC_SLICE_SEGMENT_DONE) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- reset_process_time(hevc);
- read_decode_info(hevc);
-
- }
-#endif
- if (hevc->start_decoding_time > 0) {
- u32 process_time = 1000*
- (jiffies - hevc->start_decoding_time)/HZ;
- if (process_time > max_decoding_time)
- max_decoding_time = process_time;
- }
-
- hevc->error_watchdog_count = 0;
- if (hevc->pic_list_init_flag == 2) {
- hevc->pic_list_init_flag = 3;
- hevc_print(hevc, 0, "set pic_list_init_flag to 3\n");
- if (hevc->kpi_first_i_comming == 0) {
- hevc->kpi_first_i_comming = 1;
- pr_debug("[vdec_kpi][%s] First I frame coming.\n",
- __func__);
- }
- } else if (hevc->wait_buf == 0) {
- u32 vui_time_scale;
- u32 vui_num_units_in_tick;
- unsigned char reconfig_flag = 0;
-
- if (get_dbg_flag(hevc) & H265_DEBUG_SEND_PARAM_WITH_REG)
- get_rpm_param(&hevc->param);
- else {
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
-
- for (ii = 0; ii < 4; ii++) {
- hevc->param.l.data[i + ii] =
- hevc->rpm_ptr[i + 3
- - ii];
- }
- }
- ATRACE_COUNTER(hevc->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
-#ifdef SEND_LMEM_WITH_RPM
- check_head_error(hevc);
-#endif
- }
-
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE) {
- PR_INIT(128);
-
- hevc_print(hevc, 0,
- "rpm_param: (%d)\n", hevc->slice_idx);
- hevc->slice_idx++;
-
- for (i = 0; i < (RPM_END - RPM_BEGIN); i++) {
- PR_FILL("%04x ", hevc->param.l.data[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
-
- hevc_print(hevc, 0,
- "vui_timing_info: %x, %x, %x, %x\n",
- hevc->param.p.vui_num_units_in_tick_hi,
- hevc->param.p.vui_num_units_in_tick_lo,
- hevc->param.p.vui_time_scale_hi,
- hevc->param.p.vui_time_scale_lo);
- }
-
- if (aux_data_is_avaible(hevc)) {
- static struct PIC_s pic;
- u32 size = 0, type = 0;
- char *p;
-
- memset(&pic, 0, sizeof(pic));
-
- pic.aux_data_buf = vzalloc(hevc->prefix_aux_size);
-
- set_aux_data(hevc, &pic, 0, 0);
-
- if (pic.aux_data_buf
- && pic.aux_data_size) {
- hevc->frame_field_info_present_flag =
- (hevc->param.p.sei_frame_field_info >> 8) & 0x1;
-
- /* parser sei */
- p = pic.aux_data_buf;
- while (p < pic.aux_data_buf
- + pic.aux_data_size - 8) {
- size = *p++;
- size = (size << 8) | *p++;
- size = (size << 8) | *p++;
- size = (size << 8) | *p++;
- type = *p++;
- type = (type << 8) | *p++;
- type = (type << 8) | *p++;
- type = (type << 8) | *p++;
- if (type == 0x02000000) {
- /* hevc_print(hevc, 0, "sei(%d)\n", size);*/
- parse_sei(hevc, &pic, p, size);
- }
- p += size;
- }
-
- hevc->param.p.sei_frame_field_info &=
- ~(0xf << 3);
- hevc->param.p.sei_frame_field_info |=
- (pic.pic_struct << 3);
- }
-
- if (pic.hdr10p_data_buf)
- vfree(pic.hdr10p_data_buf);
- if (pic.aux_data_buf)
- vfree(pic.aux_data_buf);
- }
-
- if (hevc->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- if (!v4l_res_change(hevc, &hevc->param)) {
- if (ctx->param_sets_from_ucode && !hevc->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
- struct aml_vdec_cfg_infos cfg;
- int log = hevc->param.p.log2_min_coding_block_size_minus3;
- int log_s = hevc->param.p.log2_diff_max_min_coding_block_size;
-
- hevc->pic_w = hevc->param.p.pic_width_in_luma_samples;
- hevc->pic_h = hevc->param.p.pic_height_in_luma_samples;
- hevc->lcu_size = 1 << (log + 3 + log_s);
-
- pr_debug("set ucode parse\n");
- hevc_interlace_check(hevc, &hevc->param);
- if (hevc->interlace_flag) {
- vh265_get_cfg_info(hevc, &hevc->param, &cfg);
- vdec_v4l_set_cfg_infos(ctx, &cfg);
- }
- if (get_valid_double_write_mode(hevc) != 16) {
- struct vdec_comp_buf_info info;
-
- get_comp_buf_info(hevc, &info);
- vdec_v4l_set_comp_buf_info(ctx, &info);
- }
- vh265_get_ps_info(hevc, &hevc->param, &ps);
- /*notice the v4l2 codec.*/
- vdec_v4l_set_ps_infos(ctx, &ps);
- hevc->v4l_params_parsed = true;
- hevc->dec_result = DEC_RESULT_AGAIN;
- amhevc_stop();
- restore_decode_state(hevc);
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
- } else {
- struct vdec_pic_info pic;
-
- vdec_v4l_get_pic_info(ctx, &pic);
- hevc->used_buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hevc->used_buf_num > MAX_BUF_NUM)
- hevc->used_buf_num = MAX_BUF_NUM;
- }
- } else {
- pr_debug("resolution change\n");
- hevc->dec_result = DEC_RESULT_AGAIN;
- amhevc_stop();
- restore_decode_state(hevc);
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
- return IRQ_HANDLED;
- }
- }
-
- if (
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- vdec->master == NULL &&
- vdec->slave == NULL &&
-#endif
- aux_data_is_avaible(hevc)
- ) {
-
- if (get_dbg_flag(hevc) &
- H265_DEBUG_PRINT_SEI)
- dump_aux_buf(hevc);
- }
-
- vui_time_scale =
- (u32)(hevc->param.p.vui_time_scale_hi << 16) |
- hevc->param.p.vui_time_scale_lo;
- vui_num_units_in_tick =
- (u32)(hevc->param.
- p.vui_num_units_in_tick_hi << 16) |
- hevc->param.
- p.vui_num_units_in_tick_lo;
- if (hevc->bit_depth_luma !=
- ((hevc->param.p.bit_depth & 0xf) + 8)) {
- reconfig_flag = 1;
- hevc_print(hevc, 0, "Bit depth luma = %d\n",
- (hevc->param.p.bit_depth & 0xf) + 8);
- }
- if (hevc->bit_depth_chroma !=
- (((hevc->param.p.bit_depth >> 4) & 0xf) + 8)) {
- reconfig_flag = 1;
- hevc_print(hevc, 0, "Bit depth chroma = %d\n",
- ((hevc->param.p.bit_depth >> 4) &
- 0xf) + 8);
- }
- hevc->bit_depth_luma =
- (hevc->param.p.bit_depth & 0xf) + 8;
- hevc->bit_depth_chroma =
- ((hevc->param.p.bit_depth >> 4) & 0xf) + 8;
- bit_depth_luma = hevc->bit_depth_luma;
- bit_depth_chroma = hevc->bit_depth_chroma;
-#ifdef SUPPORT_10BIT
- if (hevc->bit_depth_luma == 8 &&
- hevc->bit_depth_chroma == 8 &&
- enable_mem_saving)
- hevc->mem_saving_mode = 1;
- else
- hevc->mem_saving_mode = 0;
-#endif
- if (reconfig_flag &&
- (get_double_write_mode(hevc) & 0x10) == 0)
- init_decode_head_hw(hevc);
-
- if ((vui_time_scale != 0)
- && (vui_num_units_in_tick != 0)) {
- hevc->frame_dur =
- div_u64(96000ULL *
- vui_num_units_in_tick,
- vui_time_scale);
- if (hevc->get_frame_dur != true)
- vdec_schedule_work(
- &hevc->notify_work);
-
- hevc->get_frame_dur = true;
- //hevc->gvs->frame_dur = hevc->frame_dur;
- }
-
- if (hevc->video_signal_type !=
- ((hevc->param.p.video_signal_type << 16)
- | hevc->param.p.color_description)) {
- u32 v = hevc->param.p.video_signal_type;
- u32 c = hevc->param.p.color_description;
-#if 0
- if (v & 0x2000) {
- hevc_print(hevc, 0,
- "video_signal_type present:\n");
- hevc_print(hevc, 0, " %s %s\n",
- video_format_names[(v >> 10) & 7],
- ((v >> 9) & 1) ?
- "full_range" : "limited");
- if (v & 0x100) {
- hevc_print(hevc, 0,
- " color_description present:\n");
- hevc_print(hevc, 0,
- " color_primarie = %s\n",
- color_primaries_names
- [v & 0xff]);
- hevc_print(hevc, 0,
- " transfer_characteristic = %s\n",
- transfer_characteristics_names
- [(c >> 8) & 0xff]);
- hevc_print(hevc, 0,
- " matrix_coefficient = %s\n",
- matrix_coeffs_names[c & 0xff]);
- }
- }
-#endif
- hevc->video_signal_type = (v << 16) | c;
- video_signal_type = hevc->video_signal_type;
- }
-
- if (use_cma &&
- (hevc->param.p.slice_segment_address == 0)
- && (hevc->pic_list_init_flag == 0)) {
- int log = hevc->param.p.log2_min_coding_block_size_minus3;
- int log_s = hevc->param.p.log2_diff_max_min_coding_block_size;
-
- hevc->pic_w = hevc->param.p.pic_width_in_luma_samples;
- hevc->pic_h = hevc->param.p.pic_height_in_luma_samples;
- hevc->lcu_size = 1 << (log + 3 + log_s);
- hevc->lcu_size_log2 = log2i(hevc->lcu_size);
- if (performance_profile &&( (!is_oversize(hevc->pic_w, hevc->pic_h)) && IS_8K_SIZE(hevc->pic_w,hevc->pic_h)))
- hevc->performance_profile = 1;
- else
- hevc->performance_profile = 0;
- hevc_print(hevc, 0, "hevc->performance_profile %d\n", hevc->performance_profile);
- if (hevc->pic_w == 0 || hevc->pic_h == 0
- || hevc->lcu_size == 0
- || is_oversize(hevc->pic_w, hevc->pic_h)
- || hevc_skip_nal(hevc)) {
- /* skip search next start code */
- WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG)
- & (~0x2));
- if ((hevc->pic_h == 96) && (hevc->pic_w == 160))
- hevc->skip_nal_count++;
- hevc->skip_flag = 1;
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag)
- start_process_time(hevc);
-#endif
- } else {
- hevc->sps_num_reorder_pics_0 =
- hevc->param.p.sps_num_reorder_pics_0;
- hevc->ip_mode = hevc->low_latency_flag ? true :
- (!hevc->sps_num_reorder_pics_0 &&
- !(vdec->slave || vdec->master) &&
- !disable_ip_mode) ? true : false;
- hevc->pic_list_init_flag = 1;
- #if 0
- if ((!IS_4K_SIZE(hevc->pic_w, hevc->pic_h)) &&
- ((hevc->param.p.profile_etc & 0xc) == 0x4)
- && (interlace_enable != 0)) {
- hevc->double_write_mode = 1;
- hevc->interlace_flag = 1;
- hevc->frame_ar = (hevc->pic_h * 0x100 / hevc->pic_w) * 2;
- hevc_print(hevc, 0,
- "interlace (%d, %d), profile_etc %x, ar 0x%x, dw %d\n",
- hevc->pic_w, hevc->pic_h, hevc->param.p.profile_etc, hevc->frame_ar,
- get_double_write_mode(hevc));
- /* When dw changed from 0x10 to 1, the mmu_box is NULL */
- if (!hevc->mmu_box && init_mmu_buffers(hevc, 0) != 0) {
- hevc->dec_result = DEC_RESULT_FORCE_EXIT;
- hevc->fatal_error |=
- DECODER_FATAL_ERROR_NO_MEM;
- vdec_schedule_work(&hevc->work);
- hevc_print(hevc,
- 0, "can not alloc mmu box, force exit\n");
- return IRQ_HANDLED;
- }
- }
- #endif
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- vdec_schedule_work(&hevc->work);
- } else
-#endif
- up(&h265_sema);
- hevc_print(hevc, 0, "set pic_list_init_flag 1\n");
- }
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
- }
-
-}
- ret =
- hevc_slice_segment_header_process(hevc,
- &hevc->param, decode_pic_begin);
- if (ret < 0) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- hevc->wait_buf = 0;
- hevc->dec_result = DEC_RESULT_AGAIN;
- amhevc_stop();
- restore_decode_state(hevc);
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
- return IRQ_HANDLED;
- }
-#else
- ;
-#endif
- } else if (ret == 0) {
- if ((hevc->new_pic) && (hevc->cur_pic)) {
- hevc->cur_pic->stream_offset =
- READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- hevc_print(hevc, H265_DEBUG_OUT_PTS,
- "read stream_offset = 0x%x\n",
- hevc->cur_pic->stream_offset);
- hevc->cur_pic->aspect_ratio_idc =
- hevc->param.p.aspect_ratio_idc;
- hevc->cur_pic->sar_width =
- hevc->param.p.sar_width;
- hevc->cur_pic->sar_height =
- hevc->param.p.sar_height;
- }
-
- WRITE_VREG(HEVC_DEC_STATUS_REG,
- HEVC_CODED_SLICE_SEGMENT_DAT);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
-
- hevc->start_decoding_time = jiffies;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag)
- start_process_time(hevc);
-#endif
-#if 1
- /*to do..., copy aux data to hevc->cur_pic*/
-#endif
-#ifdef MULTI_INSTANCE_SUPPORT
- } else if (hevc->m_ins_flag) {
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s, bufmgr ret %d skip, DEC_RESULT_DONE\n",
- __func__, ret);
- hevc->decoded_poc = INVALID_POC;
- hevc->decoding_pic = NULL;
- hevc->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- reset_process_time(hevc);
- vdec_schedule_work(&hevc->work);
-#endif
- } else {
- /* skip, search next start code */
- hevc->gvs->drop_frame_count++;
- if (hevc->cur_pic->slice_type == I_SLICE) {
- hevc->gvs->i_lost_frames++;
- } else if (hevc->cur_pic->slice_type == P_SLICE) {
- hevc->gvs->i_lost_frames++;
- } else if (hevc->cur_pic->slice_type == B_SLICE) {
- hevc->gvs->i_lost_frames++;
- }
- WRITE_VREG(HEVC_WAIT_FLAG, READ_VREG(HEVC_WAIT_FLAG) & (~0x2));
- hevc->skip_flag = 1;
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- /* Interrupt Amrisc to excute */
- WRITE_VREG(HEVC_MCPU_INTR_REQ, AMRISC_MAIN_REQ);
- }
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
-
- } else if (dec_status == HEVC_DECODE_OVER_SIZE) {
- hevc_print(hevc, 0 , "hevc decode oversize !!\n");
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hevc->m_ins_flag)
- debug |= (H265_DEBUG_DIS_LOC_ERROR_PROC |
- H265_DEBUG_DIS_SYS_ERROR_PROC);
-#endif
- hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- }
- return IRQ_HANDLED;
-}
-
-static void wait_hevc_search_done(struct hevc_state_s *hevc)
-{
- int count = 0;
- WRITE_VREG(HEVC_SHIFT_STATUS, 0);
- while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
- msleep(20);
- count++;
- if (count > 100) {
- hevc_print(hevc, 0, "%s timeout\n", __func__);
- break;
- }
- }
-}
-static irqreturn_t vh265_isr(int irq, void *data)
-{
- int i, temp;
- unsigned int dec_status;
- struct hevc_state_s *hevc = (struct hevc_state_s *)data;
- u32 debug_tag;
- dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
-
- if (dec_status == HEVC_SLICE_SEGMENT_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
-
- if (hevc->init_flag == 0)
- return IRQ_HANDLED;
-
- ATRACE_COUNTER("V_ST_DEC-decode_state", dec_status);
-
- hevc->dec_status = dec_status;
- if (is_log_enable(hevc))
- add_log(hevc,
- "isr: status = 0x%x dec info 0x%x lcu 0x%x shiftbyte 0x%x shiftstatus 0x%x",
- dec_status, READ_HREG(HEVC_DECODE_INFO),
- READ_VREG(HEVC_MPRED_CURR_LCU),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_STATUS));
-
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR)
- hevc_print(hevc, 0,
- "265 isr dec status = 0x%x dec info 0x%x shiftbyte 0x%x shiftstatus 0x%x\n",
- dec_status, READ_HREG(HEVC_DECODE_INFO),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_STATUS));
-
- debug_tag = READ_HREG(DEBUG_REG1);
- if (debug_tag & 0x10000) {
- PR_INIT(128);
- hevc_print(hevc, 0,
- "LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
-
- if (hevc->mmu_enable)
- temp = 0x500;
- else
- temp = 0x400;
- for (i = 0; i < temp; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- PR_FILL("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- PR_FILL("%04x ",
- hevc->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
-
- PR_INFO(hevc->index);
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hevc->decode_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hevc->ucode_pause_pos = udebug_pause_pos;
- }
- else if (debug_tag & 0x20000)
- hevc->ucode_pause_pos = 0xffffffff;
- if (hevc->ucode_pause_pos)
- reset_process_time(hevc);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- } else if (debug_tag != 0) {
- hevc_print(hevc, 0,
- "dbg%x: %x l/w/r %x %x %x\n", READ_HREG(DEBUG_REG1),
- READ_HREG(DEBUG_REG2),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hevc->decode_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hevc->ucode_pause_pos = udebug_pause_pos;
- }
- if (hevc->ucode_pause_pos)
- reset_process_time(hevc);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- return IRQ_HANDLED;
- }
-
-
- if (hevc->pic_list_init_flag == 1)
- return IRQ_HANDLED;
-
- if (!hevc->m_ins_flag) {
- if (dec_status == HEVC_OVER_DECODE) {
- hevc->over_decode = 1;
- hevc_print(hevc, 0,
- "isr: over decode\n"),
- WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
- return IRQ_HANDLED;
- }
- }
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_ISR_END);
- return IRQ_WAKE_THREAD;
-
-}
-
-static void vh265_set_clk(struct work_struct *work)
-{
- struct hevc_state_s *hevc = container_of(work,
- struct hevc_state_s, set_clk_work);
-
- int fps = 96000 / hevc->frame_dur;
-
- if (hevc_source_changed(VFORMAT_HEVC,
- hevc->frame_width, hevc->frame_height, fps) > 0)
- hevc->saved_resolution = hevc->frame_width *
- hevc->frame_height * fps;
-}
-
-static void vh265_check_timer_func(struct timer_list *timer)
-{
- struct hevc_state_s *hevc = container_of(timer,
- struct hevc_state_s, timer);
- unsigned char empty_flag;
- unsigned int buf_level;
-
- enum receviver_start_e state = RECEIVER_INACTIVE;
-
- if (hevc->init_flag == 0) {
- if (hevc->stat & STAT_TIMER_ARM) {
- mod_timer(&hevc->timer, jiffies + PUT_INTERVAL);
- }
- return;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag &&
- (get_dbg_flag(hevc) &
- H265_DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 &&
- hw_to_vdec(hevc)->next_status ==
- VDEC_STATUS_DISCONNECTED &&
- !hevc->is_used_v4l) {
- hevc->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hevc->work);
- hevc_print(hevc,
- 0, "vdec requested to be disconnected\n");
- return;
- }
-
- if (hevc->m_ins_flag) {
- if (((get_dbg_flag(hevc) &
- H265_DEBUG_DIS_LOC_ERROR_PROC) == 0) &&
- (decode_timeout_val > 0) &&
- (hevc->start_process_time > 0) &&
- ((1000 * (jiffies - hevc->start_process_time) / HZ)
- > decode_timeout_val)
- ) {
- u32 dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)&0xffffff;
- if (dec_status == HEVC_CODED_SLICE_SEGMENT_DAT) {
- if (hevc->last_lcu_idx == current_lcu_idx) {
- if (hevc->decode_timeout_count > 0)
- hevc->decode_timeout_count--;
- if (hevc->decode_timeout_count == 0)
- timeout_process(hevc);
- } else
- restart_process_time(hevc);
- hevc->last_lcu_idx = current_lcu_idx;
- } else {
- hevc->pic_decoded_lcu_idx = current_lcu_idx;
- timeout_process(hevc);
- }
- }
- } else {
-#endif
- if (hevc->m_ins_flag == 0 &&
- vf_get_receiver(hevc->provider_name)) {
- state =
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- } else
- state = RECEIVER_INACTIVE;
-
- empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
- /* error watchdog */
- if (hevc->m_ins_flag == 0 &&
- (empty_flag == 0)
- && (hevc->pic_list_init_flag == 0
- || hevc->pic_list_init_flag
- == 3)) {
- /* decoder has input */
- if ((get_dbg_flag(hevc) &
- H265_DEBUG_DIS_LOC_ERROR_PROC) == 0) {
-
- buf_level = READ_VREG(HEVC_STREAM_LEVEL);
- /* receiver has no buffer to recycle */
- if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&hevc->display_q) &&
- buf_level > 0x200)
- ) {
- if (hevc->error_flag == 0) {
- hevc->error_watchdog_count++;
- if (hevc->error_watchdog_count ==
- error_handle_threshold) {
- hevc_print(hevc, 0,
- "H265 dec err local reset.\n");
- hevc->error_flag = 1;
- hevc->error_watchdog_count = 0;
- hevc->error_skip_nal_wt_cnt = 0;
- hevc->
- error_system_watchdog_count++;
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- } else if (hevc->error_flag == 2) {
- int th =
- error_handle_nal_skip_threshold;
- hevc->error_skip_nal_wt_cnt++;
- if (hevc->error_skip_nal_wt_cnt
- == th) {
- hevc->error_flag = 3;
- hevc->error_watchdog_count = 0;
- hevc->
- error_skip_nal_wt_cnt = 0;
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
- }
- }
-
- if ((get_dbg_flag(hevc)
- & H265_DEBUG_DIS_SYS_ERROR_PROC) == 0)
- /* receiver has no buffer to recycle */
- if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&hevc->display_q))
- ) { /* no buffer to recycle */
- if ((get_dbg_flag(hevc) &
- H265_DEBUG_DIS_LOC_ERROR_PROC) !=
- 0)
- hevc->error_system_watchdog_count++;
- if (hevc->error_system_watchdog_count ==
- error_handle_system_threshold) {
- /* and it lasts for a while */
- hevc_print(hevc, 0,
- "H265 dec fatal error watchdog.\n");
- hevc->
- error_system_watchdog_count = 0;
- hevc->fatal_error |= DECODER_FATAL_ERROR_UNKNOWN;
- }
- }
- } else {
- hevc->error_watchdog_count = 0;
- hevc->error_system_watchdog_count = 0;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- }
-#endif
- if ((hevc->ucode_pause_pos != 0) &&
- (hevc->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != hevc->ucode_pause_pos) {
- hevc->ucode_pause_pos = 0;
- WRITE_HREG(DEBUG_REG1, 0);
- }
-
- if (get_dbg_flag(hevc) & H265_DEBUG_DUMP_PIC_LIST) {
- dump_pic_list(hevc);
- debug &= ~H265_DEBUG_DUMP_PIC_LIST;
- }
- if (get_dbg_flag(hevc) & H265_DEBUG_TRIG_SLICE_SEGMENT_PROC) {
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- debug &= ~H265_DEBUG_TRIG_SLICE_SEGMENT_PROC;
- }
-#ifdef TEST_NO_BUF
- if (hevc->wait_buf)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
-#endif
- if (get_dbg_flag(hevc) & H265_DEBUG_HW_RESET) {
- hevc->error_skip_nal_count = error_skip_nal_count;
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- debug &= ~H265_DEBUG_HW_RESET;
- }
-
-#ifdef ERROR_HANDLE_DEBUG
- if ((dbg_nal_skip_count > 0) && ((dbg_nal_skip_count & 0x10000) != 0)) {
- hevc->error_skip_nal_count = dbg_nal_skip_count & 0xffff;
- dbg_nal_skip_count &= ~0x10000;
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- }
-#endif
-
- if (radr != 0) {
-#ifdef SUPPORT_LONG_TERM_RPS
- if ((radr >> 24) != 0) {
- int count = radr >> 24;
- int adr = radr & 0xffffff;
- int i;
- for (i = 0; i < count; i++)
- pr_info("READ_VREG(%x)=%x\n", adr+i, READ_VREG(adr+i));
- } else
-#endif
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
- if (dbg_cmd != 0) {
- if (dbg_cmd == 1) {
- u32 disp_laddr;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
- get_double_write_mode(hevc) == 0) {
- disp_laddr =
- READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
- } else {
- struct canvas_s cur_canvas;
-
- canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
- & 0xff), &cur_canvas);
- disp_laddr = cur_canvas.addr;
- }
- hevc_print(hevc, 0,
- "current displayed buffer address %x\r\n",
- disp_laddr);
- }
- dbg_cmd = 0;
- }
- /*don't changed at start.*/
- if (hevc->m_ins_flag == 0 &&
- hevc->get_frame_dur && hevc->show_frame_num > 60 &&
- hevc->frame_dur > 0 && hevc->saved_resolution !=
- hevc->frame_width * hevc->frame_height *
- (96000 / hevc->frame_dur))
- vdec_schedule_work(&hevc->set_clk_work);
-
- mod_timer(timer, jiffies + PUT_INTERVAL);
-}
-
-static int h265_task_handle(void *data)
-{
- int ret = 0;
- struct hevc_state_s *hevc = (struct hevc_state_s *)data;
-
- set_user_nice(current, -10);
- while (1) {
- if (use_cma == 0) {
- hevc_print(hevc, 0,
- "ERROR: use_cma can not be changed dynamically\n");
- }
- ret = down_interruptible(&h265_sema);
- if ((hevc->init_flag != 0) && (hevc->pic_list_init_flag == 1)) {
- init_pic_list(hevc);
- init_pic_list_hw(hevc);
- init_buf_spec(hevc);
- hevc->pic_list_init_flag = 2;
- hevc_print(hevc, 0, "set pic_list_init_flag to 2\n");
-
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
-
- }
-
- if (hevc->uninit_list) {
- /*USE_BUF_BLOCK*/
- uninit_pic_list(hevc);
- hevc_print(hevc, 0, "uninit list\n");
- hevc->uninit_list = 0;
-#ifdef USE_UNINIT_SEMA
- if (use_cma) {
- up(&hevc->h265_uninit_done_sema);
- while (!kthread_should_stop())
- msleep(1);
- break;
- }
-#endif
- }
- }
-
- return 0;
-}
-
-void vh265_free_cmabuf(void)
-{
- struct hevc_state_s *hevc = gHevc;
-
- mutex_lock(&vh265_mutex);
-
- if (hevc->init_flag) {
- mutex_unlock(&vh265_mutex);
- return;
- }
-
- mutex_unlock(&vh265_mutex);
-}
-
-#ifdef MULTI_INSTANCE_SUPPORT
-int vh265_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-#else
-int vh265_dec_status(struct vdec_info *vstatus)
-#endif
-{
-#ifdef MULTI_INSTANCE_SUPPORT
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
-#else
- struct hevc_state_s *hevc = gHevc;
-#endif
- if (!hevc)
- return -1;
-
- vstatus->frame_width = hevc->pic_w;
- /* for hevc interlace for disp height x2 */
- vstatus->frame_height =
- (hevc->pic_h << hevc->interlace_flag);
- if (hevc->frame_dur != 0)
- vstatus->frame_rate = ((96000 * 10 / hevc->frame_dur) % 10) < 5 ?
- 96000 / hevc->frame_dur : (96000 / hevc->frame_dur +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = hevc->gvs->error_frame_count;
- vstatus->status = hevc->stat | hevc->fatal_error;
- vstatus->bit_rate = hevc->gvs->bit_rate;
- vstatus->frame_dur = hevc->frame_dur;
- if (hevc->gvs) {
- vstatus->bit_rate = hevc->gvs->bit_rate;
- vstatus->frame_data = hevc->gvs->frame_data;
- vstatus->total_data = hevc->gvs->total_data;
- vstatus->frame_count = hevc->gvs->frame_count;
- vstatus->error_frame_count = hevc->gvs->error_frame_count;
- vstatus->drop_frame_count = hevc->gvs->drop_frame_count;
- vstatus->i_decoded_frames = hevc->gvs->i_decoded_frames;
- vstatus->i_lost_frames = hevc->gvs->i_lost_frames;
- vstatus->i_concealed_frames = hevc->gvs->i_concealed_frames;
- vstatus->p_decoded_frames = hevc->gvs->p_decoded_frames;
- vstatus->p_lost_frames = hevc->gvs->p_lost_frames;
- vstatus->p_concealed_frames = hevc->gvs->p_concealed_frames;
- vstatus->b_decoded_frames = hevc->gvs->b_decoded_frames;
- vstatus->b_lost_frames = hevc->gvs->b_lost_frames;
- vstatus->b_concealed_frames = hevc->gvs->b_concealed_frames;
- vstatus->samp_cnt = hevc->gvs->samp_cnt;
- vstatus->offset = hevc->gvs->offset;
- }
-
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
- vstatus->ratio_control = hevc->ratio_control;
- return 0;
-}
-
-int vh265_set_isreset(struct vdec_s *vdec, int isreset)
-{
- is_reset = isreset;
- return 0;
-}
-
-static int vh265_vdec_info_init(struct hevc_state_s *hevc)
-{
- hevc->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
- //pr_err("[%s line %d] hevc->gvs=0x%p operation\n",__func__, __LINE__, hevc->gvs);
- if (NULL == hevc->gvs) {
- pr_info("the struct of vdec status malloc failed.\n");
- return -ENOMEM;
- }
- vdec_set_vframe_comm(hw_to_vdec(hevc), DRIVER_NAME);
- return 0;
-}
-
-#if 0
-static void H265_DECODE_INIT(void)
-{
- /* enable hevc clocks */
- WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
- /* *************************************************************** */
- /* Power ON HEVC */
- /* *************************************************************** */
- /* Powerup HEVC */
- WRITE_VREG(P_AO_RTI_GEN_PWR_SLEEP0,
- READ_VREG(P_AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6)));
- WRITE_VREG(DOS_MEM_PD_HEVC, 0x0);
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2));
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2)));
- /* remove isolations */
- WRITE_VREG(AO_RTI_GEN_PWR_ISO0,
- READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10)));
-
-}
-#endif
-
-int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
- hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode);
-
- if (trickmode == TRICKMODE_I) {
- trickmode_i = 1;
- i_only_flag = 0x1;
- } else if (trickmode == TRICKMODE_NONE) {
- trickmode_i = 0;
- i_only_flag = 0x0;
- } else if (trickmode == 0x02) {
- trickmode_i = 0;
- i_only_flag = 0x02;
- } else if (trickmode == 0x03) {
- trickmode_i = 1;
- i_only_flag = 0x03;
- } else if (trickmode == 0x07) {
- trickmode_i = 1;
- i_only_flag = 0x07;
- }
- //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i);
-
- return 0;
-}
-
-static void config_decode_mode(struct hevc_state_s *hevc)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hevc);
-#endif
- unsigned decode_mode;
-#ifdef HEVC_8K_LFTOFFSET_FIX
- if (hevc->performance_profile)
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) | (1 << 21));
-#endif
- if (!hevc->m_ins_flag)
- decode_mode = DECODE_MODE_SINGLE;
- else if (vdec_frame_based(hw_to_vdec(hevc)))
- decode_mode =
- DECODE_MODE_MULTI_FRAMEBASE;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec->slave) {
- if (force_bypass_dvenl & 0x80000000)
- hevc->bypass_dvenl = force_bypass_dvenl & 0x1;
- else
- hevc->bypass_dvenl = hevc->bypass_dvenl_enable;
- if (dolby_meta_with_el && hevc->bypass_dvenl) {
- hevc->bypass_dvenl = 0;
- hevc_print(hevc, 0,
- "NOT support bypass_dvenl when meta_with_el\n");
- }
- if (hevc->bypass_dvenl)
- decode_mode =
- (hevc->start_parser_type << 8)
- | DECODE_MODE_MULTI_STREAMBASE;
- else
- decode_mode =
- (hevc->start_parser_type << 8)
- | DECODE_MODE_MULTI_DVBAL;
- } else if (vdec->master)
- decode_mode =
- (hevc->start_parser_type << 8)
- | DECODE_MODE_MULTI_DVENL;
-#endif
- else
- decode_mode =
- DECODE_MODE_MULTI_STREAMBASE;
-
- if (hevc->m_ins_flag)
- decode_mode |=
- (hevc->start_decoding_flag << 16);
- /* set MBX0 interrupt flag */
- decode_mode |= (0x80 << 24);
- WRITE_VREG(HEVC_DECODE_MODE, decode_mode);
- WRITE_VREG(HEVC_DECODE_MODE2,
- hevc->rps_set_id);
-}
-
-static void vh265_prot_init(struct hevc_state_s *hevc)
-{
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- struct vdec_s *vdec = hw_to_vdec(hevc);
-#endif
- /* H265_DECODE_INIT(); */
-
- hevc_config_work_space_hw(hevc);
-
- hevc_init_decoder_hw(hevc, 0, 0xffffffff);
-
- WRITE_VREG(HEVC_WAIT_FLAG, 1);
-
- /* WRITE_VREG(P_HEVC_MPSR, 1); */
-
- /* clear mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(HEVC_PSCALE_CTRL, 0);
-
- WRITE_VREG(DEBUG_REG1, 0x0 | (dump_nal << 8));
-
- if ((get_dbg_flag(hevc) &
- (H265_DEBUG_MAN_SKIP_NAL |
- H265_DEBUG_MAN_SEARCH_NAL))
- /*||hevc->m_ins_flag*/
- ) {
- WRITE_VREG(NAL_SEARCH_CTL, 0x1); /* manual parser NAL */
- } else {
- /* check vps/sps/pps/i-slice in ucode */
- unsigned ctl_val = 0x8;
- if (hevc->PB_skip_mode == 0)
- ctl_val = 0x4; /* check vps/sps/pps only in ucode */
- else if (hevc->PB_skip_mode == 3)
- ctl_val = 0x0; /* check vps/sps/pps/idr in ucode */
- /*if (((error_handle_policy & 0x200) == 0) &&
- input_stream_based(vdec))
- ctl_val = 0x1;*/
- WRITE_VREG(NAL_SEARCH_CTL, ctl_val);
- }
- if ((get_dbg_flag(hevc) & H265_DEBUG_NO_EOS_SEARCH_DONE)
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- || vdec->master
- || vdec->slave
-#endif
- )
- WRITE_VREG(NAL_SEARCH_CTL, READ_VREG(NAL_SEARCH_CTL) | 0x10000);
-
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL)
- | ((parser_sei_enable & 0x7) << 17));
-/*#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION*/
- WRITE_VREG(NAL_SEARCH_CTL,
- READ_VREG(NAL_SEARCH_CTL) |
- ((parser_dolby_vision_enable & 0x1) << 20));
-/*#endif*/
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-
- config_decode_mode(hevc);
- config_aux_buf(hevc);
-#ifdef SWAP_HEVC_UCODE
- if (!tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->mc_dma_handle);
- /*pr_info("write swap buffer %x\n", (u32)(hevc->mc_dma_handle));*/
- }
-#endif
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- WRITE_VREG(HEVC_SAO_DBG_MODE0, 0);
- WRITE_VREG(HEVC_SAO_DBG_MODE1, 0);
- }
-#endif
-}
-
-static int vh265_local_init(struct hevc_state_s *hevc)
-{
- int i;
- int ret = -1;
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
-#ifdef DEBUG_PTS
- hevc->pts_missed = 0;
- hevc->pts_hit = 0;
-#endif
- hevc->saved_resolution = 0;
- hevc->get_frame_dur = false;
- hevc->frame_width = hevc->vh265_amstream_dec_info.width;
- hevc->frame_height = hevc->vh265_amstream_dec_info.height;
- if (is_oversize(hevc->frame_width, hevc->frame_height)) {
- pr_info("over size : %u x %u.\n",
- hevc->frame_width, hevc->frame_height);
- hevc->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- return ret;
- }
-
- if (hevc->max_pic_w && hevc->max_pic_h) {
- hevc->is_4k = !(hevc->max_pic_w && hevc->max_pic_h) ||
- ((hevc->max_pic_w * hevc->max_pic_h) >
- 1920 * 1088) ? true : false;
- } else {
- hevc->is_4k = !(hevc->frame_width && hevc->frame_height) ||
- ((hevc->frame_width * hevc->frame_height) >
- 1920 * 1088) ? true : false;
- }
-
- hevc->frame_dur =
- (hevc->vh265_amstream_dec_info.rate ==
- 0) ? 3600 : hevc->vh265_amstream_dec_info.rate;
- //hevc->gvs->frame_dur = hevc->frame_dur;
- if (hevc->frame_width && hevc->frame_height)
- hevc->frame_ar = hevc->frame_height * 0x100 / hevc->frame_width;
-
- if (i_only_flag)
- hevc->i_only = i_only_flag & 0xff;
- else if ((unsigned long) hevc->vh265_amstream_dec_info.param
- & 0x08)
- hevc->i_only = 0x7;
- else
- hevc->i_only = 0x0;
- hevc->error_watchdog_count = 0;
- hevc->sei_present_flag = 0;
- if (vdec->sys_info)
- pts_unstable = ((unsigned long)vdec->sys_info->param
- & 0x40) >> 6;
- hevc_print(hevc, 0,
- "h265:pts_unstable=%d\n", pts_unstable);
-/*
- *TODO:FOR VERSION
- */
- hevc_print(hevc, 0,
- "h265: ver (%d,%d) decinfo: %dx%d rate=%d\n", h265_version,
- 0, hevc->frame_width, hevc->frame_height, hevc->frame_dur);
-
- if (hevc->frame_dur == 0)
- hevc->frame_dur = 96000 / 24;
-
- INIT_KFIFO(hevc->display_q);
- INIT_KFIFO(hevc->newframe_q);
- INIT_KFIFO(hevc->pending_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hevc->vfpool[i];
-
- hevc->vfpool[i].index = -1;
- kfifo_put(&hevc->newframe_q, vf);
- }
-
- if (!hevc->resolution_change)
- ret = hevc_local_init(hevc);
- else
- ret = 0;
-
- return ret;
-}
-#ifdef MULTI_INSTANCE_SUPPORT
-static s32 vh265_init(struct vdec_s *vdec)
-{
- struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private;
-#else
-static s32 vh265_init(struct hevc_state_s *hevc)
-{
-
-#endif
- int ret, size = -1;
- int fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
-
- timer_setup(&hevc->timer, vh265_check_timer_func, 0);
-
- hevc->stat |= STAT_TIMER_INIT;
-
- if (hevc->m_ins_flag) {
-#ifdef USE_UNINIT_SEMA
- sema_init(&hevc->h265_uninit_done_sema, 0);
-#endif
- INIT_WORK(&hevc->work, vh265_work);
- INIT_WORK(&hevc->timeout_work, vh265_timeout_work);
- }
-
- if (vh265_local_init(hevc) < 0)
- return -EBUSY;
-
- mutex_init(&hevc->chunks_mutex);
- INIT_WORK(&hevc->notify_work, vh265_notify_work);
- INIT_WORK(&hevc->set_clk_work, vh265_set_clk);
-
- fw = vzalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- if (hevc->mmu_enable)
- if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM)
- size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data);
- else {
- if (!hevc->is_4k) {
- /* if an older version of the fw was loaded, */
- /* needs try to load noswap fw because the */
- /* old fw package dose not contain the swap fw.*/
- size = get_firmware_data(
- VIDEO_DEC_HEVC_MMU_SWAP, fw->data);
- if (size < 0)
- size = get_firmware_data(
- VIDEO_DEC_HEVC_MMU, fw->data);
- else if (size)
- hevc->is_swap = true;
- } else
- size = get_firmware_data(VIDEO_DEC_HEVC_MMU,
- fw->data);
- }
- else
- size = get_firmware_data(VIDEO_DEC_HEVC, fw->data);
-
- if (size < 0) {
- pr_err("get firmware fail.\n");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
-
-#ifdef SWAP_HEVC_UCODE
- if (!tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- if (hevc->mmu_enable) {
- hevc->swap_size = (4 * (4 * SZ_1K)); /*max 4 swap code, each 0x400*/
- hevc->mc_cpu_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- hevc->swap_size,
- &hevc->mc_dma_handle, GFP_KERNEL);
- if (!hevc->mc_cpu_addr) {
- amhevc_disable();
- pr_info("vh265 mmu swap ucode loaded fail.\n");
- return -ENOMEM;
- }
-
- memcpy((u8 *) hevc->mc_cpu_addr, fw->data + SWAP_HEVC_OFFSET,
- hevc->swap_size);
-
- hevc_print(hevc, 0,
- "vh265 mmu ucode swap loaded %x\n",
- hevc->mc_dma_handle);
- }
- }
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hevc->m_ins_flag) {
- //hevc->timer.data = (ulong) hevc;
- //hevc->timer.function = vh265_check_timer_func;
- hevc->timer.expires = jiffies + PUT_INTERVAL;
-
- hevc->fw = fw;
- hevc->init_flag = 1;
-
- return 0;
- }
-#endif
- amhevc_enable();
-
- if (hevc->mmu_enable)
- if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM)
- ret = amhevc_loadmc_ex(VFORMAT_HEVC, "h265_mmu", fw->data);
- else {
- if (!hevc->is_4k) {
- /* if an older version of the fw was loaded, */
- /* needs try to load noswap fw because the */
- /* old fw package dose not contain the swap fw. */
- ret = amhevc_loadmc_ex(VFORMAT_HEVC,
- "hevc_mmu_swap", fw->data);
- if (ret < 0)
- ret = amhevc_loadmc_ex(VFORMAT_HEVC,
- "h265_mmu", fw->data);
- else
- hevc->is_swap = true;
- } else
- ret = amhevc_loadmc_ex(VFORMAT_HEVC,
- "h265_mmu", fw->data);
- }
- else
- ret = amhevc_loadmc_ex(VFORMAT_HEVC, NULL, fw->data);
-
- if (ret < 0) {
- amhevc_disable();
- vfree(fw);
- pr_err("H265: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- vfree(fw);
-
- hevc->stat |= STAT_MC_LOAD;
-
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- init_detrefill_buf(hevc);
-#endif
- /* enable AMRISC side protocol */
- vh265_prot_init(hevc);
-
- if (vdec_request_threaded_irq(VDEC_IRQ_0, vh265_isr,
- vh265_isr_thread_fn,
- IRQF_ONESHOT,/*run thread on this irq disabled*/
- "vh265-irq", (void *)hevc)) {
- hevc_print(hevc, 0, "vh265 irq register error.\n");
- amhevc_disable();
- return -ENOENT;
- }
-
- hevc->stat |= STAT_ISR_REG;
- hevc->provider_name = PROVIDER_NAME;
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hevc->is_used_v4l) {
- vf_provider_init(&vh265_vf_prov, hevc->provider_name,
- &vh265_vf_provider, vdec);
- vf_reg_provider(&vh265_vf_prov);
- vf_notify_receiver(hevc->provider_name, VFRAME_EVENT_PROVIDER_START,
- NULL);
- if (hevc->frame_dur != 0) {
- if (!is_reset) {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- fr_hint_status = VDEC_HINTED;
- }
- } else
- fr_hint_status = VDEC_NEED_HINT;
- }
-#else
- vf_provider_init(&vh265_vf_prov, PROVIDER_NAME, &vh265_vf_provider,
- hevc);
- vf_reg_provider(&vh265_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
- if (hevc->frame_dur != 0) {
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- fr_hint_status = VDEC_HINTED;
- } else
- fr_hint_status = VDEC_NEED_HINT;
-#endif
- hevc->stat |= STAT_VF_HOOK;
-
- //hevc->timer.data = (ulong) hevc;
- //hevc->timer.function = vh265_check_timer_func;
- hevc->timer.expires = jiffies + PUT_INTERVAL;
-
- add_timer(&hevc->timer);
-
- hevc->stat |= STAT_TIMER_ARM;
-
- if (use_cma) {
-#ifdef USE_UNINIT_SEMA
- sema_init(&hevc->h265_uninit_done_sema, 0);
-#endif
- if (h265_task == NULL) {
- sema_init(&h265_sema, 1);
- h265_task =
- kthread_run(h265_task_handle, hevc,
- "kthread_h265");
- }
- }
- /* hevc->stat |= STAT_KTHREAD; */
-#if 0
- if (get_dbg_flag(hevc) & H265_DEBUG_FORCE_CLK) {
- hevc_print(hevc, 0, "%s force clk\n", __func__);
- WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL,
- READ_VREG(HEVC_IQIT_CLK_RST_CTRL) |
- ((1 << 2) | (1 << 1)));
- WRITE_VREG(HEVC_DBLK_CFG0,
- READ_VREG(HEVC_DBLK_CFG0) | ((1 << 2) |
- (1 << 1) | 0x3fff0000));/* 2,29:16 */
- WRITE_VREG(HEVC_SAO_CTRL1, READ_VREG(HEVC_SAO_CTRL1) |
- (1 << 2)); /* 2 */
- WRITE_VREG(HEVC_MPRED_CTRL1, READ_VREG(HEVC_MPRED_CTRL1) |
- (1 << 24)); /* 24 */
- WRITE_VREG(HEVC_STREAM_CONTROL,
- READ_VREG(HEVC_STREAM_CONTROL) |
- (1 << 15)); /* 15 */
- WRITE_VREG(HEVC_CABAC_CONTROL, READ_VREG(HEVC_CABAC_CONTROL) |
- (1 << 13)); /* 13 */
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
- READ_VREG(HEVC_PARSER_CORE_CONTROL) |
- (1 << 15)); /* 15 */
- WRITE_VREG(HEVC_PARSER_INT_CONTROL,
- READ_VREG(HEVC_PARSER_INT_CONTROL) |
- (1 << 15)); /* 15 */
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- READ_VREG(HEVC_PARSER_IF_CONTROL) | ((1 << 6) |
- (1 << 3) | (1 << 1))); /* 6, 3, 1 */
- WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, 0xffffffff); /* 31:0 */
- WRITE_VREG(HEVCD_MCRCC_CTL1, READ_VREG(HEVCD_MCRCC_CTL1) |
- (1 << 3)); /* 3 */
- }
-#endif
-#ifdef SWAP_HEVC_UCODE
- if (!tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->mc_dma_handle);
- /*pr_info("write swap buffer %x\n", (u32)(hevc->mc_dma_handle));*/
- }
-#endif
-
-#ifndef MULTI_INSTANCE_SUPPORT
- set_vdec_func(&vh265_dec_status);
-#endif
- amhevc_start();
-
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
-
- hevc->stat |= STAT_VDEC_RUN;
- hevc->init_flag = 1;
- error_handle_threshold = 30;
- /* pr_info("%d, vh265_init, RP=0x%x\n",
- * __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
- */
-
- return 0;
-}
-
-static int check_dirty_data(struct vdec_s *vdec)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)(vdec->private);
- struct vdec_input_s *input = &vdec->input;
- u32 wp, rp, level;
- u32 rp_set;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = hevc->pre_parser_wr_ptr;
-
- if (wp > rp)
- level = wp - rp;
- else
- level = wp + vdec->input.size - rp;
-
- if (level > 0x100000) {
- u32 skip_size = ((level >> 1) >> 19) << 19;
- if (!vdec->input.swap_valid) {
- hevc_print(hevc , 0, "h265 start data discard level 0x%x, buffer level 0x%x, RP 0x%x, WP 0x%x\n",
- ((level >> 1) >> 19) << 19, level, rp, wp);
- if (wp >= rp) {
- rp_set = rp + skip_size;
- }
- else if ((rp + skip_size) < (input->start + input->size)) {
- rp_set = rp + skip_size;
- } else {
- rp_set = rp + skip_size - input->size;
- }
- STBUF_WRITE(&vdec->vbuf, set_rp, rp_set);
- vdec->discard_start_data_flag = 1;
- vdec->input.stream_cookie += skip_size;
- hevc->dirty_shift_flag = 1;
- }
- return 1;
- }
- return 0;
-}
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static void reset_process_time(struct hevc_state_s *hevc)
-{
- if (hevc->start_process_time) {
- unsigned int process_time =
- 1000 * (jiffies - hevc->start_process_time) / HZ;
- hevc->start_process_time = 0;
- if (process_time > max_process_time[hevc->index])
- max_process_time[hevc->index] = process_time;
- }
-}
-
-static void start_process_time(struct hevc_state_s *hevc)
-{
- hevc->start_process_time = jiffies;
- hevc->decode_timeout_count = 2;
- hevc->last_lcu_idx = 0;
-}
-
-static void restart_process_time(struct hevc_state_s *hevc)
-{
- hevc->start_process_time = jiffies;
- hevc->decode_timeout_count = 2;
-}
-
-static void timeout_process(struct hevc_state_s *hevc)
-{
- /*
- * In this very timeout point,the vh265_work arrives,
- * or in some cases the system become slow, then come
- * this second timeout. In both cases we return.
- */
- if (work_pending(&hevc->work) ||
- work_busy(&hevc->work) ||
- work_busy(&hevc->timeout_work) ||
- work_pending(&hevc->timeout_work)) {
- pr_err("%s h265[%d] work pending, do nothing.\n",__func__, hevc->index);
- return;
- }
-
- hevc->timeout_num++;
- amhevc_stop();
- read_decode_info(hevc);
-
- hevc_print(hevc,
- 0, "%s decoder timeout\n", __func__);
- check_pic_decoded_error(hevc,
- hevc->pic_decoded_lcu_idx);
- /*The current decoded frame is marked
- error when the decode timeout*/
- if (hevc->cur_pic != NULL)
- hevc->cur_pic->error_mark = 1;
- hevc->decoded_poc = hevc->curr_POC;
- hevc->decoding_pic = NULL;
- hevc->dec_result = DEC_RESULT_DONE;
- reset_process_time(hevc);
-
- if (work_pending(&hevc->work))
- return;
- vdec_schedule_work(&hevc->timeout_work);
-}
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-static int get_vf_ref_only_buf_count(struct hevc_state_s *hevc)
-{
- struct PIC_s *pic;
- int i;
- int count = 0;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if (pic->output_mark == 0 && pic->referenced == 0
- && pic->output_ready == 1)
- count++;
- }
-
- return count;
-}
-
-static int get_used_buf_count(struct hevc_state_s *hevc)
-{
- struct PIC_s *pic;
- int i;
- int count = 0;
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if (pic->output_mark != 0 || pic->referenced != 0
- || pic->output_ready != 0)
- count++;
- }
-
- return count;
-}
-#endif
-
-static bool is_avaliable_buffer(struct hevc_state_s *hevc)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- struct PIC_s *pic = NULL;
- int i, free_count = 0;
- int used_count = 0;
-
- if ((hevc->used_buf_num == 0) ||
- (ctx->cap_pool.dec < hevc->used_buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hevc->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hevc->used_buf_num; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL ||
- pic->index == -1 ||
- pic->BUF_index == -1)
- continue;
-
- if ((pic->output_mark == 0) &&
- (pic->referenced == 0) &&
- (pic->output_ready == 0) &&
- (pic->vf_ref == 0) &&
- pic->cma_alloc_addr) {
- free_count++;
- } else if (pic->cma_alloc_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned char is_new_pic_available(struct hevc_state_s *hevc)
-{
- struct PIC_s *new_pic = NULL;
- struct PIC_s *pic;
- /* recycle un-used pic */
- int i;
- int ref_pic = 0;
- struct vdec_s *vdec = hw_to_vdec(hevc);
- unsigned long flags;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- /*return 1 if pic_list is not initialized yet*/
- if (hevc->pic_list_init_flag != 3)
- return 1;
-
- spin_lock_irqsave(&lock, flags);
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1 || pic->BUF_index == -1)
- continue;
- if (pic->referenced == 1)
- ref_pic++;
- if (pic->output_mark == 0 && pic->referenced == 0
- && pic->output_ready == 0
- && pic->vf_ref == 0
- ) {
- if (new_pic) {
- if (pic->POC < new_pic->POC)
- new_pic = pic;
- } else
- new_pic = pic;
- }
- }
- if (!hevc->is_used_v4l && new_pic == NULL) {
- enum receviver_start_e state = RECEIVER_INACTIVE;
- if (vf_get_receiver(vdec->vf_provider_name)) {
- state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- }
- if (state == RECEIVER_INACTIVE) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- int poc = INVALID_POC;
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if ((pic->referenced == 0) &&
- (pic->error_mark == 1) &&
- (pic->output_mark == 1)) {
- if (poc == INVALID_POC || (pic->POC < poc)) {
- new_pic = pic;
- poc = pic->POC;
- }
- }
- }
- if (new_pic) {
- new_pic->referenced = 0;
- new_pic->output_mark = 0;
- put_mv_buf(hevc, new_pic);
- hevc_print(hevc, 0, "force release error pic %d recieve_state %d \n", new_pic->POC, state);
- } else {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if ((pic->referenced == 1) && (pic->error_mark == 1)) {
- spin_unlock_irqrestore(&lock, flags);
- flush_output(hevc, pic);
- hevc_print(hevc, 0, "DPB error, neeed fornce flush recieve_state %d \n", state);
- return 0;
- }
- }
- }
- }
- }
-
- if ((new_pic == NULL) ||
- (hevc->is_used_v4l &&
- (ctx->param_sets_from_ucode) &&
- (hevc->v4l_params_parsed) &&
- (ctx->cap_pool.dec < hevc->used_buf_num) && !is_avaliable_buffer(hevc))) {
- int decode_count = 0;
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1 || pic->BUF_index == -1)
- continue;
- if ((pic->output_ready == 0) && (pic->output_mark != 0 ||
- pic->referenced != 0 ||
- pic->vf_ref != 0))
- decode_count++;
- }
-
- if (decode_count >=
- hevc->param.p.sps_max_dec_pic_buffering_minus1_0 + detect_stuck_buffer_margin) {
- if (get_dbg_flag(hevc) & H265_DEBUG_BUFMGR_MORE)
- dump_pic_list(hevc);
- if (!(error_handle_policy & 0x400)) {
- spin_unlock_irqrestore(&lock, flags);
- flush_output(hevc, NULL);
- hevc_print(hevc, H265_DEBUG_BUFMGR, "flush dpb, ref_error_count %d, sps_max_dec_pic_buffering_minus1_0 %d\n",
- decode_count, hevc->param.p.sps_max_dec_pic_buffering_minus1_0);
- return 0;
- }
- }
- }
-
- spin_unlock_irqrestore(&lock, flags);
-
- return (new_pic != NULL) ? 1 : 0;
-}
-
-static void check_buffer_status(struct hevc_state_s *hevc)
-{
- int i;
- struct PIC_s *new_pic = NULL;
- struct PIC_s *pic;
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- enum receviver_start_e state = RECEIVER_INACTIVE;
-
- if (hevc->is_used_v4l)
- return;
-
- if (vf_get_receiver(vdec->vf_provider_name)) {
- state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- }
- if (hevc->timeout_flag == false)
- hevc->timeout = jiffies + HZ / 2;
-
- if (state == RECEIVER_INACTIVE)
- hevc->timeout_flag = true;
- else
- hevc->timeout_flag = false;
-
- if (state == RECEIVER_INACTIVE && hevc->timeout_flag &&
- time_after(jiffies, hevc->timeout)) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- int poc = INVALID_POC;
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if ((pic->referenced == 0) &&
- (pic->error_mark == 1) &&
- (pic->output_mark == 1)) {
- if (poc == INVALID_POC || (pic->POC < poc)) {
- new_pic = pic;
- poc = pic->POC;
- }
- }
- }
- if (new_pic) {
- new_pic->referenced = 0;
- new_pic->output_mark = 0;
- put_mv_buf(hevc, new_pic);
- hevc_print(hevc, 0, "check_buffer_status force release error pic %d recieve_state %d \n", new_pic->POC, state);
- } else {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- pic = hevc->m_PIC[i];
- if (pic == NULL || pic->index == -1)
- continue;
- if ((pic->referenced == 1) && (pic->error_mark == 1)) {
- flush_output(hevc, pic);
- hevc_print(hevc, 0, "check_buffer_status DPB error, neeed fornce flush recieve_state %d \n", state);
- break;
- }
- }
- }
- }
-}
-
-
-static int vmh265_stop(struct hevc_state_s *hevc)
-{
- if (hevc->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hevc->timer);
- hevc->stat &= ~STAT_TIMER_ARM;
- }
- if (hevc->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hevc->stat &= ~STAT_VDEC_RUN;
- }
- if (hevc->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_0, (void *)hevc);
- hevc->stat &= ~STAT_ISR_REG;
- }
-
- if (!hevc->is_used_v4l && hevc->stat & STAT_VF_HOOK) {
- if (fr_hint_status == VDEC_HINTED)
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_FR_END_HINT,
- NULL);
- fr_hint_status = VDEC_NO_NEED_HINT;
- vf_unreg_provider(&vh265_vf_prov);
- hevc->stat &= ~STAT_VF_HOOK;
- }
-
- hevc_local_uninit(hevc);
-
- if (hevc->gvs)
- kfree(hevc->gvs);
- hevc->gvs = NULL;
-
- if (use_cma) {
- hevc->uninit_list = 1;
- reset_process_time(hevc);
- hevc->dec_result = DEC_RESULT_FREE_CANVAS;
- vdec_schedule_work(&hevc->work);
- flush_work(&hevc->work);
-#ifdef USE_UNINIT_SEMA
- if (hevc->init_flag) {
- down(&hevc->h265_uninit_done_sema);
- }
-#else
- while (hevc->uninit_list) /* wait uninit complete */
- msleep(20);
-#endif
- }
- hevc->init_flag = 0;
- hevc->first_sc_checked = 0;
- cancel_work_sync(&hevc->notify_work);
- cancel_work_sync(&hevc->set_clk_work);
- cancel_work_sync(&hevc->timeout_work);
- cancel_work_sync(&hevc->work);
- uninit_mmu_buffers(hevc);
-
- vfree(hevc->fw);
- hevc->fw = NULL;
-
- dump_log(hevc);
- return 0;
-}
-
-static unsigned char get_data_check_sum
- (struct hevc_state_s *hevc, int size)
-{
- int sum = 0;
- u8 *data = NULL;
-
- if (!hevc->chunk->block->is_mapped)
- data = codec_mm_vmap(hevc->chunk->block->start +
- hevc->chunk->offset, size);
- else
- data = ((u8 *)hevc->chunk->block->start_virt) +
- hevc->chunk->offset;
-
- sum = crc32_le(0, data, size);
-
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, sum,
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
-
- if (!hevc->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void vh265_notify_work(struct work_struct *work)
-{
- struct hevc_state_s *hevc =
- container_of(work,
- struct hevc_state_s,
- notify_work);
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (hevc->is_used_v4l)
- return;
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec->fr_hint_state == VDEC_NEED_HINT) {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- vdec->fr_hint_state = VDEC_HINTED;
- } else if (fr_hint_status == VDEC_NEED_HINT) {
- vf_notify_receiver(hevc->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- fr_hint_status = VDEC_HINTED;
- }
-#else
- if (fr_hint_status == VDEC_NEED_HINT)
- vf_notify_receiver(PROVIDER_NAME,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hevc->frame_dur));
- fr_hint_status = VDEC_HINTED;
- }
-#endif
-
- return;
-}
-
-static void vh265_work_implement(struct hevc_state_s *hevc,
- struct vdec_s *vdec,int from)
-{
- ATRACE_COUNTER("V_ST_DEC-work_state", hevc->dec_result);
-
- if (hevc->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_AGAIN);
- if (hevc->dec_result != DEC_RESULT_NONE)
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_START);
- if (hevc->dec_result == DEC_RESULT_FREE_CANVAS) {
- /*USE_BUF_BLOCK*/
- uninit_pic_list(hevc);
- hevc->uninit_list = 0;
-#ifdef USE_UNINIT_SEMA
- up(&hevc->h265_uninit_done_sema);
-#endif
- return;
- }
-
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- if (hevc->pic_list_init_flag == 1
- && (hevc->dec_result != DEC_RESULT_FORCE_EXIT)) {
- hevc->pic_list_init_flag = 2;
- init_pic_list(hevc);
- init_pic_list_hw(hevc);
- init_buf_spec(hevc);
- hevc_print(hevc, 0,
- "set pic_list_init_flag to 2\n");
-
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- return;
- }
-
- hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
- "%s dec_result %d %x %x %x\n",
- __func__,
- hevc->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
-
- if (((hevc->dec_result == DEC_RESULT_GET_DATA) ||
- (hevc->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(hevc)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(vdec)) {
- hevc->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hevc->work);
- return;
- }
- if (!input_frame_based(vdec)) {
- int r = vdec_sync_input(vdec);
- if (r >= 0x200) {
- WRITE_VREG(HEVC_DECODE_SIZE,
- READ_VREG(HEVC_DECODE_SIZE) + r);
-
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x mpc %x size 0x%x\n",
- __func__,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_MPC_E), r);
-
- start_process_time(hevc);
- if (READ_VREG(HEVC_DEC_STATUS_REG)
- == HEVC_DECODE_BUFEMPTY2)
- WRITE_VREG(HEVC_DEC_STATUS_REG,
- HEVC_ACTION_DONE);
- else
- WRITE_VREG(HEVC_DEC_STATUS_REG,
- HEVC_ACTION_DEC_CONT);
- } else {
- hevc->dec_result = DEC_RESULT_GET_DATA_RETRY;
- vdec_schedule_work(&hevc->work);
- }
- return;
- }
-
- /*below for frame_base*/
- if (hevc->dec_result == DEC_RESULT_GET_DATA) {
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x mpc %x\n",
- __func__,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_MPC_E));
- mutex_lock(&hevc->chunks_mutex);
- vdec_vframe_dirty(vdec, hevc->chunk);
- hevc->chunk = NULL;
- mutex_unlock(&hevc->chunks_mutex);
- vdec_clean_input(vdec);
- }
-
- /*if (is_new_pic_available(hevc)) {*/
- if (run_ready(vdec, VDEC_HEVC)) {
- int r;
- int decode_size;
-
- r = vdec_prepare_input(vdec, &hevc->chunk);
- if (r < 0) {
- hevc->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- hevc_print(hevc,
- PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&hevc->work);
- return;
- }
- hevc->dec_result = DEC_RESULT_NONE;
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: chunk size 0x%x sum 0x%x mpc %x\n",
- __func__, r,
- (get_dbg_flag(hevc) & PRINT_FLAG_VDEC_STATUS) ?
- get_data_check_sum(hevc, r) : 0,
- READ_VREG(HEVC_MPC_E));
-
- if (get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) {
- int jj;
- u8 *data = NULL;
- PR_INIT(128);
-
- if (!hevc->chunk->block->is_mapped)
- data = codec_mm_vmap(
- hevc->chunk->block->start +
- hevc->chunk->offset, r);
- else
- data = ((u8 *)
- hevc->chunk->block->start_virt)
- + hevc->chunk->offset;
-
- for (jj = 0; jj < r; jj++) {
- if ((jj & 0xf) == 0)
- PR_FILL("%06x:", jj);
- PR_FILL("%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
-
- if (!hevc->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
-
- decode_size = hevc->chunk->size +
- (hevc->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(HEVC_DECODE_SIZE,
- READ_VREG(HEVC_DECODE_SIZE) + decode_size);
-
- vdec_enable_input(vdec);
-
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: mpc %x\n",
- __func__, READ_VREG(HEVC_MPC_E));
-
- start_process_time(hevc);
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
- } else{
- hevc->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- /*hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
- * "amvdec_vh265: Insufficient data\n");
- */
-
- vdec_schedule_work(&hevc->work);
- }
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_END);
- return;
- } else if (hevc->dec_result == DEC_RESULT_DONE) {
- /* if (!hevc->ctx_valid)
- hevc->ctx_valid = 1; */
- int i;
- decode_frame_count[hevc->index]++;
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM) {
- if (hevc->delrefill_check == 2) {
- delrefill(hevc);
- amhevc_stop();
- }
- }
-#endif
- if (hevc->mmu_enable && ((hevc->double_write_mode & 0x10) == 0)) {
- hevc->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
- if (hevc->used_4k_num >= 0 &&
- hevc->cur_pic &&
- hevc->cur_pic->scatter_alloc
- == 1)
- recycle_mmu_buf_tail(hevc, hevc->m_ins_flag);
- }
- hevc->pic_decoded_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
-
- if (vdec->master == NULL && vdec->slave == NULL &&
- hevc->empty_flag == 0) {
- hevc->over_decode =
- (READ_VREG(HEVC_SHIFT_STATUS) >> 15) & 0x1;
- if (hevc->over_decode)
- hevc_print(hevc, 0,
- "!!!Over decode\n");
- }
-
- if (is_log_enable(hevc))
- add_log(hevc,
- "%s dec_result %d lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x",
- __func__,
- hevc->dec_result,
- hevc->pic_decoded_lcu_idx,
- hevc->used_4k_num,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- hevc->start_shift_bytes
- );
-
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s dec_result %d (%x %x %x) lcu %d used_mmu %d shiftbyte 0x%x decbytes 0x%x\n",
- __func__,
- hevc->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- hevc->pic_decoded_lcu_idx,
- hevc->used_4k_num,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- hevc->start_shift_bytes
- );
-
- hevc->used_4k_num = -1;
-
- check_pic_decoded_error(hevc,
- hevc->pic_decoded_lcu_idx);
- if ((error_handle_policy & 0x100) == 0 && hevc->cur_pic) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic;
- pic = hevc->m_PIC[i];
- if (!pic || pic->index == -1)
- continue;
- if ((hevc->cur_pic->POC + poc_num_margin < pic->POC) && (pic->referenced == 0) &&
- (pic->output_mark == 1) && (pic->output_ready == 0)) {
- hevc->poc_error_count++;
- break;
- }
- }
- if (i == MAX_REF_PIC_NUM)
- hevc->poc_error_count = 0;
- if (hevc->poc_error_count >= poc_error_limit) {
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic;
- pic = hevc->m_PIC[i];
- if (!pic || pic->index == -1)
- continue;
- if ((hevc->cur_pic->POC + poc_num_margin < pic->POC) && (pic->referenced == 0) &&
- (pic->output_mark == 1) && (pic->output_ready == 0)) {
- pic->output_mark = 0;
- hevc_print(hevc, 0, "DPB poc error, remove error frame\n");
- }
- }
- }
- }
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-#if 1
- if (vdec->slave) {
- if (dv_debug & 0x1)
- vdec_set_flag(vdec->slave,
- VDEC_FLAG_SELF_INPUT_CONTEXT);
- else
- vdec_set_flag(vdec->slave,
- VDEC_FLAG_OTHER_INPUT_CONTEXT);
- }
-#else
- if (vdec->slave) {
- if (no_interleaved_el_slice)
- vdec_set_flag(vdec->slave,
- VDEC_FLAG_INPUT_KEEP_CONTEXT);
- /* this will move real HW pointer for input */
- else
- vdec_set_flag(vdec->slave, 0);
- /* this will not move real HW pointer
- *and SL layer decoding
- *will start from same stream position
- *as current BL decoder
- */
- }
-#endif
-#endif
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hevc->shift_byte_count_lo
- = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- if (vdec->slave) {
- /*cur is base, found enhance*/
- struct hevc_state_s *hevc_el =
- (struct hevc_state_s *)
- vdec->slave->private;
- if (hevc_el)
- hevc_el->shift_byte_count_lo =
- hevc->shift_byte_count_lo;
- } else if (vdec->master) {
- /*cur is enhance, found base*/
- struct hevc_state_s *hevc_ba =
- (struct hevc_state_s *)
- vdec->master->private;
- if (hevc_ba)
- hevc_ba->shift_byte_count_lo =
- hevc->shift_byte_count_lo;
- }
-#endif
- mutex_lock(&hevc->chunks_mutex);
- vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk);
- hevc->chunk = NULL;
- mutex_unlock(&hevc->chunks_mutex);
- } else if (hevc->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- hevc->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hevc->work);
- return;
- }
-#ifdef AGAIN_HAS_THRESHOLD
- hevc->next_again_flag = 1;
-#endif
- if (input_stream_based(vdec)) {
- u32 rp, wp, level;
- struct vdec_input_s *input = &vdec->input;
- rp = STBUF_READ(&vdec->vbuf, get_rp);;
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = input->size + wp - rp;
- else
- level = wp - rp;
- if ((level >= dirty_buffersize_threshold) &&
- (hevc->pre_parser_video_rp ==
- STBUF_READ(&vdec->vbuf, get_rp)) &&
- (hevc->pre_parser_video_wp ==
- STBUF_READ(&vdec->vbuf, get_wp))) {
- if (hevc->again_count == 0) {
- hevc->again_timeout_jiffies =
- get_jiffies_64() + dirty_time_threshold * HZ/1000;
- }
- hevc->again_count++;
- }
- else
- hevc->again_count = 0;
-
- hevc->pre_parser_video_rp = STBUF_READ(&vdec->vbuf, get_rp);
- hevc->pre_parser_video_wp = STBUF_READ(&vdec->vbuf, get_wp);
-
- if (((hevc->again_count > dirty_count_threshold) &&
- time_after64(get_jiffies_64(), hevc->again_timeout_jiffies))) {
- mutex_lock(&hevc->chunks_mutex);
- hevc->again_count = 0;
- vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk);
- hevc->chunk = NULL;
- hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
- "Discard dirty data\n");
- mutex_unlock(&hevc->chunks_mutex);
- } else if ((((error_handle_policy & 0x200) == 0) &&
- (hevc->pic_list_init_flag == 0))) {
- check_dirty_data(vdec);
- }
- }
- } else if (hevc->dec_result == DEC_RESULT_EOS) {
- struct PIC_s *pic;
- hevc->eos = 1;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if ((!hevc->discard_dv_data) && aux_data_is_avaible(hevc))
- if (hevc->decoding_pic)
- dolby_get_meta(hevc);
-#endif
- check_pic_decoded_error(hevc,
- hevc->pic_decoded_lcu_idx);
- pic = get_pic_by_POC(hevc, hevc->curr_POC);
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: end of stream, last dec poc %d => 0x%pf\n",
- __func__, hevc->curr_POC, pic);
- flush_output(hevc, pic);
- /* dummy vf with eos flag to backend */
- if (hevc->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hevc));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- hevc->shift_byte_count_lo
- = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- if (vdec->slave) {
- /*cur is base, found enhance*/
- struct hevc_state_s *hevc_el =
- (struct hevc_state_s *)
- vdec->slave->private;
- if (hevc_el)
- hevc_el->shift_byte_count_lo =
- hevc->shift_byte_count_lo;
- } else if (vdec->master) {
- /*cur is enhance, found base*/
- struct hevc_state_s *hevc_ba =
- (struct hevc_state_s *)
- vdec->master->private;
- if (hevc_ba)
- hevc_ba->shift_byte_count_lo =
- hevc->shift_byte_count_lo;
- }
-#endif
- mutex_lock(&hevc->chunks_mutex);
- vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk);
- hevc->chunk = NULL;
- mutex_unlock(&hevc->chunks_mutex);
- } else if (hevc->dec_result == DEC_RESULT_FORCE_EXIT) {
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
- if (hevc->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hevc->stat &= ~STAT_VDEC_RUN;
- }
- if (hevc->stat & STAT_ISR_REG) {
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0);
- vdec_free_irq(VDEC_IRQ_0, (void *)hevc);
- hevc->stat &= ~STAT_ISR_REG;
- }
- hevc_print(hevc, 0, "%s: force exit end\n",
- __func__);
- }
-
- if (hevc->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hevc->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hevc->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hevc->timer);
- hevc->stat &= ~STAT_TIMER_ARM;
- }
-
- ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_START);
- wait_hevc_search_done(hevc);
- ATRACE_COUNTER(hevc->trace.decode_work_time_name, TRACE_WORK_WAIT_SEARCH_DONE_END);
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (hevc->switch_dvlayer_flag) {
- if (vdec->slave)
- vdec_set_next_sched(vdec, vdec->slave);
- else if (vdec->master)
- vdec_set_next_sched(vdec, vdec->master);
- } else if (vdec->slave || vdec->master)
- vdec_set_next_sched(vdec, vdec);
-#endif
-
- if (from == 1) {
- /* This is a timeout work */
- if (work_pending(&hevc->work)) {
- /*
- * The vh265_work arrives at the last second,
- * give it a chance to handle the scenario.
- */
- return;
- //cancel_work_sync(&hevc->work);//reserved for future considraion
- }
- }
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_WORKER_END);
-
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(vdec, CORE_MASK_HEVC);
- else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- if (hevc->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hevc->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- if (hevc->vdec_cb)
- hevc->vdec_cb(hw_to_vdec(hevc), hevc->vdec_cb_arg);
-}
-
-static void vh265_work(struct work_struct *work)
-{
- struct hevc_state_s *hevc = container_of(work,
- struct hevc_state_s, work);
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- vh265_work_implement(hevc, vdec, 0);
-}
-
-static void vh265_timeout_work(struct work_struct *work)
-{
- struct hevc_state_s *hevc = container_of(work,
- struct hevc_state_s, timeout_work);
- struct vdec_s *vdec = hw_to_vdec(hevc);
-
- if (work_pending(&hevc->work))
- return;
- hevc->timeout_processing = 1;
- vh265_work_implement(hevc, vdec, 1);
-}
-
-
-static int vh265_hw_ctx_restore(struct hevc_state_s *hevc)
-{
- /* new to do ... */
- vh265_prot_init(hevc);
- return 0;
-}
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
- int tvp = vdec_secure(hw_to_vdec(hevc)) ?
- CODEC_MM_FLAGS_TVP : 0;
- bool ret = 0;
- if (step == 0x12)
- return 0;
- else if (step == 0x11)
- step = 0x12;
-
- if (hevc->fatal_error & DECODER_FATAL_ERROR_NO_MEM)
- return 0;
-
- if (hevc->eos)
- return 0;
- if (hevc->timeout_processing &&
- (work_pending(&hevc->work) ||
- work_busy(&hevc->work) ||
- work_busy(&hevc->timeout_work) ||
- work_pending(&hevc->timeout_work))) {
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "h265 work pending,not ready for run.\n");
- return 0;
- }
- hevc->timeout_processing = 0;
- if (!hevc->first_sc_checked && hevc->mmu_enable) {
- int size;
- void * mmu_box;
-
- if (hevc->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = hevc->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
- hevc->first_sc_checked =1;
- hevc_print(hevc, 0,
- "vh265 cached=%d need_size=%d speed= %d ms\n",
- size, (hevc->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - hevc->sc_start_time) * 1000/HZ);
- }
- if (vdec_stream_based(vdec) && (hevc->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level)
- return 0;
- }
-
-#ifdef AGAIN_HAS_THRESHOLD
- if (hevc->next_again_flag &&
- (!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- if (parser_wr_ptr >= hevc->pre_parser_wr_ptr &&
- (parser_wr_ptr - hevc->pre_parser_wr_ptr) <
- again_threshold) {
- int r = vdec_sync_input(vdec);
- hevc_print(hevc,
- PRINT_FLAG_VDEC_DETAIL, "%s buf lelvel:%x\n", __func__, r);
- return 0;
- }
- }
-#endif
-
- if (disp_vframe_valve_level &&
- kfifo_len(&hevc->display_q) >=
- disp_vframe_valve_level) {
- hevc->valve_count--;
- if (hevc->valve_count <= 0)
- hevc->valve_count = 2;
- else
- return 0;
- }
-
- ret = is_new_pic_available(hevc);
- if (!ret) {
- hevc_print(hevc,
- PRINT_FLAG_VDEC_DETAIL, "%s=>%d\r\n",
- __func__, ret);
- }
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
- if (hevc->pic_list_init_flag == 3 && !hevc->is_used_v4l) {
- if (run_ready_max_vf_only_num > 0 &&
- get_vf_ref_only_buf_count(hevc) >=
- run_ready_max_vf_only_num
- )
- ret = 0;
- if (run_ready_display_q_num > 0 &&
- kfifo_len(&hevc->display_q) >=
- run_ready_display_q_num)
- ret = 0;
-
- /*avoid more buffers consumed when
- switching resolution*/
- if (run_ready_max_buf_num == 0xff &&
- (get_used_buf_count(hevc) >=
- v4l_parser_work_pic_num(hevc) +
- get_dynamic_buf_num_margin(hevc))) {
- check_buffer_status(hevc);
- ret = 0;
- }
- else if (run_ready_max_buf_num &&
- get_used_buf_count(hevc) >=
- run_ready_max_buf_num)
- ret = 0;
- }
-#endif
-
- if (hevc->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode) {
- if (hevc->v4l_params_parsed) {
- ret = is_avaliable_buffer(hevc) ? 1 : 0;
- } else {
- ret = ctx->v4l_resolution_change ? 0 : 1;
- }
- } else if (!ctx->v4l_codec_dpb_ready) {
- if (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) <
- run_ready_min_buf_num)
- ret = 0;
- }
- }
-
- if (ret)
- not_run_ready[hevc->index] = 0;
- else
- not_run_ready[hevc->index]++;
- if (vdec->parallel_dec == 1)
- return ret ? (CORE_MASK_HEVC) : 0;
- else
- return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
- int r, loadr = 0;
- unsigned char check_sum = 0;
-
- run_count[hevc->index]++;
- hevc->vdec_cb_arg = arg;
- hevc->vdec_cb = callback;
- hevc->aux_data_dirty = 1;
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_START);
- hevc_reset_core(vdec);
-
-#ifdef AGAIN_HAS_THRESHOLD
- if (vdec_stream_based(vdec)) {
- hevc->pre_parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- hevc->next_again_flag = 0;
- }
-#endif
- r = vdec_prepare_input(vdec, &hevc->chunk);
- if (r < 0) {
- input_empty[hevc->index]++;
- hevc->dec_result = DEC_RESULT_AGAIN;
- hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL,
- "ammvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&hevc->work);
- return;
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", r);
-
- input_empty[hevc->index] = 0;
- hevc->dec_result = DEC_RESULT_NONE;
- if (vdec_frame_based(vdec) &&
- ((get_dbg_flag(hevc) & PRINT_FLAG_VDEC_STATUS)
- || is_log_enable(hevc)) &&
- !vdec_secure(vdec))
- check_sum = get_data_check_sum(hevc, r);
-
- if (is_log_enable(hevc))
- add_log(hevc,
- "%s: size 0x%x sum 0x%x shiftbyte 0x%x",
- __func__, r,
- check_sum,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT)
- );
- if ((hevc->dirty_shift_flag == 1) && !(vdec->input.swap_valid)) {
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, vdec->input.stream_cookie);
- }
- hevc->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-
- hevc_print(hevc, PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x (%x %x %x %x %x) byte count %x\n",
- __func__, r,
- check_sum,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp),
- hevc->start_shift_bytes
- );
- if ((get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) &&
- input_frame_based(vdec) &&
- !vdec_secure(vdec)) {
- int jj;
- u8 *data = NULL;
- PR_INIT(128);
-
- if (!hevc->chunk->block->is_mapped)
- data = codec_mm_vmap(hevc->chunk->block->start +
- hevc->chunk->offset, r);
- else
- data = ((u8 *)hevc->chunk->block->start_virt)
- + hevc->chunk->offset;
-
- for (jj = 0; jj < r; jj++) {
- if ((jj & 0xf) == 0)
- PR_FILL("%06x:", jj);
- PR_FILL("%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
-
- if (!hevc->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- if (tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, hevc->swap_addr);
- } else {
- if (hevc->mmu_enable)
- if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_GXM)
- loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
- "h265_mmu", hevc->fw->data);
- else {
- if (!hevc->is_4k) {
- /* if an older version of the fw was loaded, */
- /* needs try to load noswap fw because the */
- /* old fw package dose not contain the swap fw.*/
- loadr = amhevc_vdec_loadmc_ex(
- VFORMAT_HEVC, vdec,
- "hevc_mmu_swap",
- hevc->fw->data);
- if (loadr < 0)
- loadr = amhevc_vdec_loadmc_ex(
- VFORMAT_HEVC, vdec,
- "h265_mmu",
- hevc->fw->data);
- else
- hevc->is_swap = true;
- } else
- loadr = amhevc_vdec_loadmc_ex(
- VFORMAT_HEVC, vdec,
- "h265_mmu", hevc->fw->data);
- }
- else
- loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
- NULL, hevc->fw->data);
-
- if (loadr < 0) {
- amhevc_disable();
- hevc_print(hevc, 0, "H265: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", loadr);
- hevc->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hevc->work);
- return;
- }
-
- if (tee_enabled() && hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- hevc->swap_addr = READ_VREG(HEVC_STREAM_SWAP_BUFFER2);
-#ifdef DETREFILL_ENABLE
- if (hevc->is_swap &&
- get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_GXM)
- init_detrefill_buf(hevc);
-#endif
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_HEVC;
- }
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
-
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
- if (vh265_hw_ctx_restore(hevc) < 0) {
- vdec_schedule_work(&hevc->work);
- return;
- }
- ATRACE_COUNTER(hevc->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- if (vdec_frame_based(vdec)) {
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
- r = hevc->chunk->size +
- (hevc->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- hevc->decode_size = r;
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hevc->chunk->size;
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else {
- if (vdec->master || vdec->slave)
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT,
- hevc->shift_byte_count_lo);
- }
-#endif
- WRITE_VREG(HEVC_DECODE_SIZE, r);
- /*WRITE_VREG(HEVC_DECODE_COUNT, hevc->decode_idx);*/
- hevc->init_flag = 1;
-
- if (hevc->pic_list_init_flag == 3)
- init_pic_list_hw(hevc);
-
- backup_decode_state(hevc);
-
- start_process_time(hevc);
- mod_timer(&hevc->timer, jiffies);
- hevc->stat |= STAT_TIMER_ARM;
- hevc->stat |= STAT_ISR_REG;
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- amhevc_start();
- hevc->stat |= STAT_VDEC_RUN;
-
- ATRACE_COUNTER(hevc->trace.decode_time_name, DECODER_RUN_END);
-}
-
-static void aml_free_canvas(struct vdec_s *vdec)
-{
- int i;
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- struct PIC_s *pic = hevc->m_PIC[i];
-
- if (pic) {
- if (vdec->parallel_dec == 1) {
- vdec->free_canvas_ex(pic->y_canvas_index, vdec->id);
- vdec->free_canvas_ex(pic->uv_canvas_index, vdec->id);
- }
- pic->cma_alloc_addr = 0;
- }
- hevc->buffer_wrap[i] = i;
- }
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
- int i;
-
- cancel_work_sync(&hevc->work);
- cancel_work_sync(&hevc->notify_work);
- if (hevc->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hevc->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hevc->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hevc->timer);
- hevc->stat &= ~STAT_TIMER_ARM;
- }
- hevc->dec_result = DEC_RESULT_NONE;
- reset_process_time(hevc);
- hevc->pic_list_init_flag = 0;
- dealloc_mv_bufs(hevc);
- aml_free_canvas(vdec);
- if (!hevc->resolution_change)
- hevc_local_uninit(hevc);
- if (vh265_local_init(hevc) < 0)
- pr_debug(" %s local init fail\n", __func__);
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- hevc->m_BUF[i].start_adr = 0;
- }
-
- atomic_set(&hevc->vf_pre_count, 0);
- atomic_set(&hevc->vf_get_count, 0);
- atomic_set(&hevc->vf_put_count, 0);
- hevc->eos = 0;
- hevc->resolution_change = false;
-
- hevc_print(hevc, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
-}
-
-static irqreturn_t vh265_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
-
- return vh265_isr(0, hevc);
-}
-
-static irqreturn_t vh265_threaded_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
-
- return vh265_isr_thread_fn(0, hevc);
-}
-#endif
-
-/****************************************/
-#ifdef CONFIG_PM
-static int h265_suspend(struct device *dev)
-{
- amhevc_suspend(to_platform_device(dev), dev->power.power_state);
- return 0;
-}
-
-static int h265_resume(struct device *dev)
-{
- amhevc_resume(to_platform_device(dev));
- return 0;
-}
-
-static const struct dev_pm_ops h265_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(h265_suspend, h265_resume)
-};
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static void vh265_dump_state(struct vdec_s *vdec)
-{
- int i;
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)vdec->private;
- hevc_print(hevc, 0,
- "====== %s\n", __func__);
-
- hevc_print(hevc, 0,
- "width/height (%d/%d), reorder_pic_num %d ip_mode %d buf count(bufspec size) %d, video_signal_type 0x%x, is_swap %d i_only 0x%x\n",
- hevc->frame_width,
- hevc->frame_height,
- hevc->sps_num_reorder_pics_0,
- hevc->ip_mode,
- hevc->used_buf_num,
- hevc->video_signal_type_debug,
- hevc->is_swap,
- hevc->i_only
- );
-
- hevc_print(hevc, 0,
- "is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n",
- input_frame_based(vdec),
- hevc->eos,
- hevc->dec_result,
- decode_frame_count[hevc->index],
- display_frame_count[hevc->index],
- run_count[hevc->index],
- not_run_ready[hevc->index],
- input_empty[hevc->index]
- );
-
- if (hevc->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- hevc_print(hevc, 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- hevc_print(hevc, 0,
- "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), pic_list_init_flag(%d), is_new_pic_available(%d)\n",
- __func__,
- kfifo_len(&hevc->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hevc->display_q),
- VF_POOL_SIZE,
- hevc->vf_pre_count,
- hevc->vf_get_count,
- hevc->vf_put_count,
- hevc->pic_list_init_flag,
- is_new_pic_available(hevc)
- );
-
- dump_pic_list(hevc);
-
- for (i = 0; i < BUF_POOL_SIZE; i++) {
- hevc_print(hevc, 0,
- "Buf(%d) start_adr 0x%x header_addr 0x%x size 0x%x used %d\n",
- i,
- hevc->m_BUF[i].start_adr,
- hevc->m_BUF[i].header_addr,
- hevc->m_BUF[i].size,
- hevc->m_BUF[i].used_flag);
- }
-
- for (i = 0; i < MAX_REF_PIC_NUM; i++) {
- hevc_print(hevc, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
- i,
- hevc->m_mv_BUF[i].start_adr,
- hevc->m_mv_BUF[i].size,
- hevc->m_mv_BUF[i].used_flag);
- }
-
- hevc_print(hevc, 0,
- "HEVC_DEC_STATUS_REG=0x%x\n",
- READ_VREG(HEVC_DEC_STATUS_REG));
- hevc_print(hevc, 0,
- "HEVC_MPC_E=0x%x\n",
- READ_VREG(HEVC_MPC_E));
- hevc_print(hevc, 0,
- "HEVC_DECODE_MODE=0x%x\n",
- READ_VREG(HEVC_DECODE_MODE));
- hevc_print(hevc, 0,
- "HEVC_DECODE_MODE2=0x%x\n",
- READ_VREG(HEVC_DECODE_MODE2));
- hevc_print(hevc, 0,
- "NAL_SEARCH_CTL=0x%x\n",
- READ_VREG(NAL_SEARCH_CTL));
- hevc_print(hevc, 0,
- "HEVC_PARSER_LCU_START=0x%x\n",
- READ_VREG(HEVC_PARSER_LCU_START));
- hevc_print(hevc, 0,
- "HEVC_DECODE_SIZE=0x%x\n",
- READ_VREG(HEVC_DECODE_SIZE));
- hevc_print(hevc, 0,
- "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- hevc_print(hevc, 0,
- "HEVC_STREAM_START_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_START_ADDR));
- hevc_print(hevc, 0,
- "HEVC_STREAM_END_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_END_ADDR));
- hevc_print(hevc, 0,
- "HEVC_STREAM_LEVEL=0x%x\n",
- READ_VREG(HEVC_STREAM_LEVEL));
- hevc_print(hevc, 0,
- "HEVC_STREAM_WR_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_WR_PTR));
- hevc_print(hevc, 0,
- "HEVC_STREAM_RD_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_RD_PTR));
- hevc_print(hevc, 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- hevc_print(hevc, 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (input_frame_based(vdec) &&
- (get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA)
- ) {
- int jj;
- PR_INIT(128);
-
- if (hevc->chunk && hevc->chunk->block &&
- hevc->chunk->size > 0) {
- u8 *data = NULL;
- if (!hevc->chunk->block->is_mapped)
- data = codec_mm_vmap(hevc->chunk->block->start +
- hevc->chunk->offset, hevc->chunk->size);
- else
- data = ((u8 *)hevc->chunk->block->start_virt)
- + hevc->chunk->offset;
- hevc_print(hevc, 0,
- "frame data size 0x%x\n",
- hevc->chunk->size);
- for (jj = 0; jj < hevc->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- PR_FILL("%06x:", jj);
- PR_FILL("%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- PR_INFO(hevc->index);
- }
- PR_INFO(hevc->index);
-
- if (!hevc->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-
-}
-
-
-static int ammvdec_h265_probe(struct platform_device *pdev)
-{
-
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct hevc_state_s *hevc = NULL;
- int ret;
- int i;
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- int config_val;
-#endif
-
- if (pdata == NULL) {
- pr_info("\nammvdec_h265 memory resource undefined.\n");
- return -EFAULT;
- }
-
- /* hevc = (struct hevc_state_s *)devm_kzalloc(&pdev->dev,
- sizeof(struct hevc_state_s), GFP_KERNEL); */
- hevc = vmalloc(sizeof(struct hevc_state_s));
- if (hevc == NULL) {
- pr_info("\nammvdec_h265 device data allocation failed\n");
- return -ENOMEM;
- }
- memset(hevc, 0, sizeof(struct hevc_state_s));
-
- /* the ctx from v4l2 driver. */
- hevc->v4l2_ctx = pdata->private;
-
- pdata->private = hevc;
- pdata->dec_status = vh265_dec_status;
- pdata->set_trickmode = vh265_set_trickmode;
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vh265_irq_cb;
- pdata->threaded_irq_handler = vh265_threaded_irq_cb;
- pdata->dump_state = vh265_dump_state;
-
- hevc->index = pdev->id;
- hevc->m_ins_flag = 1;
-
-
- if (is_rdma_enable()) {
- hevc->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hevc->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- hevc->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- hevc->rdma_adr[i * 4 + 1] = i;
- hevc->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- hevc->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- hevc->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
- snprintf(hevc->trace.vdec_name, sizeof(hevc->trace.vdec_name),
- "h265-%d", hevc->index);
- snprintf(hevc->trace.pts_name, sizeof(hevc->trace.pts_name),
- "%s-timestamp", hevc->trace.vdec_name);
- snprintf(hevc->trace.vf_get_name, sizeof(hevc->trace.vf_get_name),
- "%s-vf_get", hevc->trace.vdec_name);
- snprintf(hevc->trace.vf_put_name, sizeof(hevc->trace.vf_put_name),
- "%s-vf_put", hevc->trace.vdec_name);
- snprintf(hevc->trace.set_canvas0_addr, sizeof(hevc->trace.set_canvas0_addr),
- "%s-set_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.get_canvas0_addr, sizeof(hevc->trace.get_canvas0_addr),
- "%s-get_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.put_canvas0_addr, sizeof(hevc->trace.put_canvas0_addr),
- "%s-put_canvas0_addr", hevc->trace.vdec_name);
- snprintf(hevc->trace.new_q_name, sizeof(hevc->trace.new_q_name),
- "%s-newframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.disp_q_name, sizeof(hevc->trace.disp_q_name),
- "%s-dispframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.new_q_name, sizeof(hevc->trace.new_q_name),
- "%s-newframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.disp_q_name, sizeof(hevc->trace.disp_q_name),
- "%s-dispframe_q", hevc->trace.vdec_name);
- snprintf(hevc->trace.decode_time_name, sizeof(hevc->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hevc->trace.decode_run_time_name, sizeof(hevc->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hevc->trace.decode_header_memory_time_name, sizeof(hevc->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hevc->trace.decode_work_time_name, sizeof(hevc->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
-
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- hevc->frameinfo_enable = 1;
- }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec_dual(pdata)) {
- struct hevc_state_s *hevc_pair = NULL;
-
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
- VFM_DEC_DVEL_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
- VFM_DEC_DVBL_PROVIDER_NAME);
- hevc->dolby_enhance_flag = pdata->master ? 1 : 0;
- if (pdata->master)
- hevc_pair = (struct hevc_state_s *)
- pdata->master->private;
- else if (pdata->slave)
- hevc_pair = (struct hevc_state_s *)
- pdata->slave->private;
- if (hevc_pair)
- hevc->shift_byte_count_lo =
- hevc_pair->shift_byte_count_lo;
- }
-#endif
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- hevc->provider_name = pdata->vf_provider_name;
- platform_set_drvdata(pdev, pdata);
-
- hevc->platform_dev = pdev;
-
- if (((get_dbg_flag(hevc) & IGNORE_PARAM_FROM_CONFIG) == 0) &&
- pdata->config_len) {
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- /*use ptr config for doubel_write_mode, etc*/
- hevc_print(hevc, 0, "pdata->config=%s\n", pdata->config);
-
- if (get_config_int(pdata->config, "hevc_double_write_mode",
- &config_val) == 0)
- hevc->double_write_mode = config_val;
- else
- hevc->double_write_mode = double_write_mode;
-
- if (get_config_int(pdata->config, "save_buffer_mode",
- &config_val) == 0)
- hevc->save_buffer_mode = config_val;
- else
- hevc->save_buffer_mode = 0;
-
- /*use ptr config for max_pic_w, etc*/
- if (get_config_int(pdata->config, "hevc_buf_width",
- &config_val) == 0) {
- hevc->max_pic_w = config_val;
- }
- if (get_config_int(pdata->config, "hevc_buf_height",
- &config_val) == 0) {
- hevc->max_pic_h = config_val;
- }
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hevc->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hevc->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hevc->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_buffer_margin",
- &config_val) == 0)
- hevc->dynamic_buf_num_margin = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hevc->mem_map_mode = config_val;
-
- if (get_config_int(pdata->config, "negative_dv",
- &config_val) == 0) {
- hevc->discard_dv_data = config_val;
- hevc_print(hevc, 0, "discard dv data\n");
- }
-
- if (get_config_int(pdata->config,
- "parm_enable_fence",
- &config_val) == 0)
- hevc->enable_fence = config_val;
-
- if (get_config_int(pdata->config,
- "parm_fence_usage",
- &config_val) == 0)
- hevc->fence_usage = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_low_latency_mode",
- &config_val) == 0) {
- hevc->low_latency_flag = (config_val & 1) ? 1 : 0;
- hevc->enable_fence = (config_val & 2) ? 1 : 0;
- }
-
- if (get_config_int(pdata->config,
- "parm_v4l_metadata_config_flag",
- &config_val) == 0) {
- hevc->metadata_config_flag = config_val;
- hevc->discard_dv_data = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_NEGATIVE;
- hevc->dv_duallayer = hevc->metadata_config_flag & VDEC_CFG_FLAG_DV_TWOLARYER;
- if (hevc->discard_dv_data)
- hevc_print(hevc, 0, "discard dv data\n");
- if (hevc->dv_duallayer)
- hevc_print(hevc, 0, "dv_duallayer\n");
- }
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
-#endif
- } else {
- if (pdata->sys_info)
- hevc->vh265_amstream_dec_info = *pdata->sys_info;
- else {
- hevc->vh265_amstream_dec_info.width = 0;
- hevc->vh265_amstream_dec_info.height = 0;
- hevc->vh265_amstream_dec_info.rate = 30;
- }
- hevc->double_write_mode = double_write_mode;
- }
-
- if (!hevc->is_used_v4l)
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vh265_vf_provider, pdata);
-
- if (force_config_fence) {
- hevc->enable_fence = true;
- hevc->fence_usage = (force_config_fence >> 4) & 0xf;
- if (force_config_fence & 0x2)
- hevc->enable_fence = false;
- hevc_print(hevc, 0,
- "enable fence: %d, fence usage: %d\n",
- hevc->enable_fence, hevc->fence_usage);
- }
-
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) &&
- (hevc->double_write_mode == 3))
- hevc->double_write_mode = 0x1000;
-
- hevc->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (!hevc->is_used_v4l) {
- /* get valid double write from configure or node */
- //hevc->double_write_mode = get_double_write_mode(hevc);
- if (hevc->save_buffer_mode && dynamic_buf_num_margin > 2)
- hevc->dynamic_buf_num_margin = dynamic_buf_num_margin -2;
- else
- hevc->dynamic_buf_num_margin = dynamic_buf_num_margin;
-
- hevc->mem_map_mode = mem_map_mode;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
- hevc->endian = HEVC_CONFIG_BIG_ENDIAN;
- }
- if (endian)
- hevc->endian = endian;
-
- if (mmu_enable_force == 0) {
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL
- || hevc->double_write_mode == 0x10)
- hevc->mmu_enable = 0;
- else
- hevc->mmu_enable = 1;
- }
-
- if (hevc->is_used_v4l) {
- if (hevc->double_write_mode & 0x10)
- hevc->mmu_enable = 0;
- else
- hevc->mmu_enable = 1;
- }
-
- if (hevc->is_used_v4l && (hevc->v4l2_ctx != NULL)) {
- struct aml_vcodec_ctx *ctx = hevc->v4l2_ctx;
-
- ctx->aux_infos.alloc_buffer(ctx, SEI_TYPE);
-
- if (!hevc->discard_dv_data)
- ctx->aux_infos.alloc_buffer(ctx, DV_TYPE);
- }
-
- if (init_mmu_buffers(hevc, 1) < 0) {
- hevc_print(hevc, 0,
- "\n 265 mmu init failed!\n");
- mutex_unlock(&vh265_mutex);
- /* devm_kfree(&pdev->dev, (void *)hevc);*/
- if (hevc)
- vfree((void *)hevc);
- pdata->dec_status = NULL;
- return -EFAULT;
- }
-#if 0
- hevc->buf_start = pdata->mem_start;
- hevc->buf_size = pdata->mem_end - pdata->mem_start + 1;
-#else
-
- ret = decoder_bmmu_box_alloc_buf_phy(hevc->bmmu_box,
- BMMU_WORKSPACE_ID, work_buf_size,
- DRIVER_NAME, &hevc->buf_start);
- if (ret < 0) {
- uninit_mmu_buffers(hevc);
- /* devm_kfree(&pdev->dev, (void *)hevc); */
- if (hevc)
- vfree((void *)hevc);
- pdata->dec_status = NULL;
- mutex_unlock(&vh265_mutex);
- return ret;
- }
- hevc->buf_size = work_buf_size;
-#endif
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXTVBB) &&
- (parser_sei_enable & 0x100) == 0)
- parser_sei_enable = 7;
- hevc->init_flag = 0;
- hevc->first_sc_checked = 0;
- hevc->uninit_list = 0;
- hevc->fatal_error = 0;
- hevc->show_frame_num = 0;
-
- /*
- *hevc->mc_buf_spec.buf_end = pdata->mem_end + 1;
- *for (i = 0; i < WORK_BUF_SPEC_NUM; i++)
- * amvh265_workbuff_spec[i].start_adr = pdata->mem_start;
- */
- if (get_dbg_flag(hevc)) {
- hevc_print(hevc, 0,
- "===H.265 decoder mem resource 0x%lx size 0x%x\n",
- hevc->buf_start, hevc->buf_size);
- }
-
- hevc_print(hevc, 0,
- "dynamic_buf_num_margin=%d\n",
- hevc->dynamic_buf_num_margin);
- hevc_print(hevc, 0,
- "double_write_mode=%d\n",
- hevc->double_write_mode);
-
- hevc->cma_dev = pdata->cma_dev;
- vh265_vdec_info_init(hevc);
-
- if (vh265_init(pdata) < 0) {
- hevc_print(hevc, 0,
- "\namvdec_h265 init failed.\n");
- hevc_local_uninit(hevc);
- if (hevc->gvs)
- kfree(hevc->gvs);
- hevc->gvs = NULL;
- uninit_mmu_buffers(hevc);
- /* devm_kfree(&pdev->dev, (void *)hevc); */
- if (hevc)
- vfree((void *)hevc);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_init(pdata);
-#endif
-
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- /*set the max clk for smooth playing...*/
- hevc_source_changed(VFORMAT_HEVC,
- 3840, 2160, 60);
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_HEVC);
- else
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- mutex_init(&hevc->fence_mutex);
- if (hevc->enable_fence) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hevc->v4l2_ctx);
-
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- hevc_print(hevc, 0, "alloc fence timeline error\n");
- hevc_local_uninit(hevc);
- if (hevc->gvs)
- kfree(hevc->gvs);
- hevc->gvs = NULL;
- uninit_mmu_buffers(hevc);
- /* devm_kfree(&pdev->dev, (void *)hevc); */
- if (hevc)
- vfree((void *)hevc);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- ctx->sync = pdata->sync;
- pdata->sync->usage = hevc->fence_usage;
- /* creat timeline. */
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
- vdec_timeline_get(pdata->sync);
- }
-
- return 0;
-}
-
-static void vdec_fence_release(struct hevc_state_s *hw,
- struct vdec_sync *sync)
-{
- ulong expires;
-
- /* notify signal to wake up all fences. */
- vdec_timeline_increase(sync, VF_POOL_SIZE);
-
- expires = jiffies + msecs_to_jiffies(2000);
- while (!check_objs_all_signaled(sync)) {
- if (time_after(jiffies, expires)) {
- pr_err("wait fence signaled timeout.\n");
- break;
- }
- }
-
- /* decreases refcnt of timeline. */
- vdec_timeline_put(sync);
-}
-
-static int ammvdec_h265_remove(struct platform_device *pdev)
-{
- struct hevc_state_s *hevc =
- (struct hevc_state_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec;
-
- if (hevc == NULL)
- return 0;
- vdec = hw_to_vdec(hevc);
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_exit(vdec);
-#endif
-
- //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
- if (get_dbg_flag(hevc))
- hevc_print(hevc, 0, "%s\r\n", __func__);
-
- vmh265_stop(hevc);
-
- /* vdec_source_changed(VFORMAT_H264, 0, 0, 0); */
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hevc), CORE_MASK_HEVC);
- else
- vdec_core_release(hw_to_vdec(hevc), CORE_MASK_HEVC);
-
- vdec_set_status(hw_to_vdec(hevc), VDEC_STATUS_DISCONNECTED);
-
- if (hevc->enable_fence)
- vdec_fence_release(hevc, vdec->sync);
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hevc->rdma_adr, hevc->rdma_phy_adr);
- vfree((void *)hevc);
-
- return 0;
-}
-
-static struct platform_driver ammvdec_h265_driver = {
- .probe = ammvdec_h265_probe,
- .remove = ammvdec_h265_remove,
- .driver = {
- .name = MULTI_DRIVER_NAME,
-#ifdef CONFIG_PM
- .pm = &h265_pm_ops,
-#endif
- }
-};
-#endif
-
-static struct codec_profile_t amvdec_h265_profile = {
- .name = "H.265-V4L",
- .profile = ""
-};
-
-static struct mconfig h265_configs[] = {
- MC_PU32("use_cma", &use_cma),
- MC_PU32("bit_depth_luma", &bit_depth_luma),
- MC_PU32("bit_depth_chroma", &bit_depth_chroma),
- MC_PU32("video_signal_type", &video_signal_type),
-#ifdef ERROR_HANDLE_DEBUG
- MC_PU32("dbg_nal_skip_flag", &dbg_nal_skip_flag),
- MC_PU32("dbg_nal_skip_count", &dbg_nal_skip_count),
-#endif
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("dbg_cmd", &dbg_cmd),
- MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
- MC_PU32("endian", &endian),
- MC_PU32("step", &step),
- MC_PU32("udebug_flag", &udebug_flag),
- MC_PU32("decode_pic_begin", &decode_pic_begin),
- MC_PU32("slice_parse_begin", &slice_parse_begin),
- MC_PU32("nal_skip_policy", &nal_skip_policy),
- MC_PU32("i_only_flag", &i_only_flag),
- MC_PU32("error_handle_policy", &error_handle_policy),
- MC_PU32("error_handle_threshold", &error_handle_threshold),
- MC_PU32("error_handle_nal_skip_threshold",
- &error_handle_nal_skip_threshold),
- MC_PU32("error_handle_system_threshold",
- &error_handle_system_threshold),
- MC_PU32("error_skip_nal_count", &error_skip_nal_count),
- MC_PU32("debug", &debug),
- MC_PU32("debug_mask", &debug_mask),
- MC_PU32("buffer_mode", &buffer_mode),
- MC_PU32("double_write_mode", &double_write_mode),
- MC_PU32("buf_alloc_width", &buf_alloc_width),
- MC_PU32("buf_alloc_height", &buf_alloc_height),
- MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
- MC_PU32("max_buf_num", &max_buf_num),
- MC_PU32("buf_alloc_size", &buf_alloc_size),
- MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
- MC_PU32("mem_map_mode", &mem_map_mode),
- MC_PU32("enable_mem_saving", &enable_mem_saving),
- MC_PU32("force_w_h", &force_w_h),
- MC_PU32("force_fps", &force_fps),
- MC_PU32("max_decoding_time", &max_decoding_time),
- MC_PU32("prefix_aux_buf_size", &prefix_aux_buf_size),
- MC_PU32("suffix_aux_buf_size", &suffix_aux_buf_size),
- MC_PU32("interlace_enable", &interlace_enable),
- MC_PU32("pts_unstable", &pts_unstable),
- MC_PU32("parser_sei_enable", &parser_sei_enable),
- MC_PU32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
- MC_PU32("parser_dolby_vision_enable", &parser_dolby_vision_enable),
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- MC_PU32("dv_toggle_prov_name", &dv_toggle_prov_name),
- MC_PU32("dv_debug", &dv_debug),
-#endif
-};
-static struct mconfig_node decoder_265_node;
-
-static int __init amvdec_h265_driver_init_module(void)
-{
- struct BuffInfo_s *p_buf_info;
-
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvh265_workbuff_spec[2];
- else
- p_buf_info = &amvh265_workbuff_spec[1];
- } else
- p_buf_info = &amvh265_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k())
- p_buf_info = &amvh265_workbuff_spec[5];
- else
- p_buf_info = &amvh265_workbuff_spec[3];
- }
-
- init_buff_spec(NULL, p_buf_info);
- work_buf_size =
- (p_buf_info->end_adr - p_buf_info->start_adr
- + 0xffff) & (~0xffff);
-
- pr_debug("amvdec_h265 module init\n");
- error_handle_policy = 0;
-
-#ifdef ERROR_HANDLE_DEBUG
- dbg_nal_skip_flag = 0;
- dbg_nal_skip_count = 0;
-#endif
- udebug_flag = 0;
- decode_pic_begin = 0;
- slice_parse_begin = 0;
- step = 0;
- buf_alloc_size = 0;
-
- if (platform_driver_register(&ammvdec_h265_driver)) {
- pr_err("failed to register ammvdec_h265 driver\n");
- return -ENODEV;
- }
-
-#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/
- if (!has_hevc_vdec()) {
- /* not support hevc */
- amvdec_h265_profile.name = "hevc_unsupport";
- }
- if ((vdec_is_support_4k())) {
- if (is_meson_m8m2_cpu()) {
- /* m8m2 support 4k */
- amvdec_h265_profile.profile = "4k";
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- amvdec_h265_profile.profile =
- "8k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, uvm";
- }else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) {
- amvdec_h265_profile.profile =
- "4k, 8bit, 10bit, dwrite, compressed, frame_dv, fence, uvm";
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_MG9TV)
- amvdec_h265_profile.profile = "4k";
- } else {
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D || is_cpu_s4_s805x2()) {
- amvdec_h265_profile.profile =
- "8bit, 10bit, dwrite, compressed, frame_dv, uvm, v4l";
- } else {
- amvdec_h265_profile.profile =
- "8bit, 10bit, dwrite, compressed, v4l";
- }
- }
-#endif
- if (codec_mm_get_total_size() < 80 * SZ_1M) {
- pr_info("amvdec_h265 default mmu enabled.\n");
- mmu_enable = 1;
- }
-
- vcodec_profile_register(&amvdec_h265_profile);
- INIT_REG_NODE_CONFIGS("media.decoder", &decoder_265_node,
- "h265-v4l", h265_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_HEVC, 1);
- return 0;
-}
-
-static void __exit amvdec_h265_driver_remove_module(void)
-{
- pr_debug("amvdec_h265 module remove.\n");
-
- platform_driver_unregister(&ammvdec_h265_driver);
-
-}
-
-/****************************************/
-/*
- *module_param(stat, uint, 0664);
- *MODULE_PARM_DESC(stat, "\n amvdec_h265 stat\n");
- */
-module_param(use_cma, uint, 0664);
-MODULE_PARM_DESC(use_cma, "\n amvdec_h265 use_cma\n");
-
-module_param(bit_depth_luma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_h265 bit_depth_luma\n");
-
-module_param(bit_depth_chroma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_h265 bit_depth_chroma\n");
-
-module_param(video_signal_type, uint, 0664);
-MODULE_PARM_DESC(video_signal_type, "\n amvdec_h265 video_signal_type\n");
-
-#ifdef ERROR_HANDLE_DEBUG
-module_param(dbg_nal_skip_flag, uint, 0664);
-MODULE_PARM_DESC(dbg_nal_skip_flag, "\n amvdec_h265 dbg_nal_skip_flag\n");
-
-module_param(dbg_nal_skip_count, uint, 0664);
-MODULE_PARM_DESC(dbg_nal_skip_count, "\n amvdec_h265 dbg_nal_skip_count\n");
-#endif
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\n radr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\n rval\n");
-
-module_param(dbg_cmd, uint, 0664);
-MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n");
-
-module_param(dump_nal, uint, 0664);
-MODULE_PARM_DESC(dump_nal, "\n dump_nal\n");
-
-module_param(dbg_skip_decode_index, uint, 0664);
-MODULE_PARM_DESC(dbg_skip_decode_index, "\n dbg_skip_decode_index\n");
-
-module_param(endian, uint, 0664);
-MODULE_PARM_DESC(endian, "\n rval\n");
-
-module_param(step, uint, 0664);
-MODULE_PARM_DESC(step, "\n amvdec_h265 step\n");
-
-module_param(decode_pic_begin, uint, 0664);
-MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_h265 decode_pic_begin\n");
-
-module_param(slice_parse_begin, uint, 0664);
-MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_h265 slice_parse_begin\n");
-
-module_param(nal_skip_policy, uint, 0664);
-MODULE_PARM_DESC(nal_skip_policy, "\n amvdec_h265 nal_skip_policy\n");
-
-module_param(i_only_flag, uint, 0664);
-MODULE_PARM_DESC(i_only_flag, "\n amvdec_h265 i_only_flag\n");
-
-module_param(fast_output_enable, uint, 0664);
-MODULE_PARM_DESC(fast_output_enable, "\n amvdec_h265 fast_output_enable\n");
-
-module_param(error_handle_policy, uint, 0664);
-MODULE_PARM_DESC(error_handle_policy, "\n amvdec_h265 error_handle_policy\n");
-
-module_param(error_handle_threshold, uint, 0664);
-MODULE_PARM_DESC(error_handle_threshold,
- "\n amvdec_h265 error_handle_threshold\n");
-
-module_param(error_handle_nal_skip_threshold, uint, 0664);
-MODULE_PARM_DESC(error_handle_nal_skip_threshold,
- "\n amvdec_h265 error_handle_nal_skip_threshold\n");
-
-module_param(error_handle_system_threshold, uint, 0664);
-MODULE_PARM_DESC(error_handle_system_threshold,
- "\n amvdec_h265 error_handle_system_threshold\n");
-
-module_param(error_skip_nal_count, uint, 0664);
-MODULE_PARM_DESC(error_skip_nal_count,
- "\n amvdec_h265 error_skip_nal_count\n");
-
-module_param(skip_nal_count, uint, 0664);
-MODULE_PARM_DESC(skip_nal_count, "\n skip_nal_count\n");
-
-module_param(debug, uint, 0664);
-MODULE_PARM_DESC(debug, "\n amvdec_h265 debug\n");
-
-module_param(debug_mask, uint, 0664);
-MODULE_PARM_DESC(debug_mask, "\n amvdec_h265 debug mask\n");
-
-module_param(log_mask, uint, 0664);
-MODULE_PARM_DESC(log_mask, "\n amvdec_h265 log_mask\n");
-
-module_param(buffer_mode, uint, 0664);
-MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
-
-module_param(double_write_mode, uint, 0664);
-MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
-
-module_param(buf_alloc_width, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
-
-module_param(buf_alloc_height, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-module_param(max_buf_num, uint, 0664);
-MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
-
-module_param(buf_alloc_size, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
-
-#ifdef CONSTRAIN_MAX_BUF_NUM
-module_param(run_ready_max_vf_only_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_vf_only_num, "\n run_ready_max_vf_only_num\n");
-
-module_param(run_ready_display_q_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_display_q_num, "\n run_ready_display_q_num\n");
-
-module_param(run_ready_max_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_max_buf_num, "\n run_ready_max_buf_num\n");
-
-module_param(run_ready_min_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
-#endif
-
-#if 0
-module_param(re_config_pic_flag, uint, 0664);
-MODULE_PARM_DESC(re_config_pic_flag, "\n re_config_pic_flag\n");
-#endif
-
-module_param(buffer_mode_dbg, uint, 0664);
-MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
-
-module_param(mem_map_mode, uint, 0664);
-MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
-
-module_param(enable_mem_saving, uint, 0664);
-MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
-
-module_param(force_w_h, uint, 0664);
-MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
-
-module_param(force_fps, uint, 0664);
-MODULE_PARM_DESC(force_fps, "\n force_fps\n");
-
-module_param(max_decoding_time, uint, 0664);
-MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
-
-module_param(prefix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(prefix_aux_buf_size, "\n prefix_aux_buf_size\n");
-
-module_param(suffix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(suffix_aux_buf_size, "\n suffix_aux_buf_size\n");
-
-module_param(interlace_enable, uint, 0664);
-MODULE_PARM_DESC(interlace_enable, "\n interlace_enable\n");
-module_param(pts_unstable, uint, 0664);
-MODULE_PARM_DESC(pts_unstable, "\n amvdec_h265 pts_unstable\n");
-module_param(parser_sei_enable, uint, 0664);
-MODULE_PARM_DESC(parser_sei_enable, "\n parser_sei_enable\n");
-
-module_param(parser_dolby_vision_enable, uint, 0664);
-MODULE_PARM_DESC(parser_dolby_vision_enable,
- "\n parser_dolby_vision_enable\n");
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(dolby_meta_with_el, uint, 0664);
-MODULE_PARM_DESC(dolby_meta_with_el,
- "\n dolby_meta_with_el\n");
-
-module_param(dolby_el_flush_th, uint, 0664);
-MODULE_PARM_DESC(dolby_el_flush_th,
- "\n dolby_el_flush_th\n");
-#endif
-module_param(mmu_enable, uint, 0664);
-MODULE_PARM_DESC(mmu_enable, "\n mmu_enable\n");
-
-module_param(mmu_enable_force, uint, 0664);
-MODULE_PARM_DESC(mmu_enable_force, "\n mmu_enable_force\n");
-
-#ifdef MULTI_INSTANCE_SUPPORT
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n h265 start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val,
- "\n h265 decode_timeout_val\n");
-
-module_param(print_lcu_error, uint, 0664);
-MODULE_PARM_DESC(print_lcu_error,
- "\n h265 print_lcu_error\n");
-
-module_param(data_resend_policy, uint, 0664);
-MODULE_PARM_DESC(data_resend_policy,
- "\n h265 data_resend_policy\n");
-
-module_param(poc_num_margin, int, 0664);
-MODULE_PARM_DESC(poc_num_margin,
- "\n h265 poc_num_margin\n");
-
-module_param(poc_error_limit, int, 0664);
-MODULE_PARM_DESC(poc_error_limit,
- "\n h265 poc_error_limit\n");
-
-module_param_array(decode_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(display_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_get_frame_interval,
- uint, &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(input_empty, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(not_run_ready, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(ref_frame_mark_flag, uint,
- &max_decode_instance_num, 0664);
-
-#endif
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(dv_toggle_prov_name, uint, 0664);
-MODULE_PARM_DESC(dv_toggle_prov_name, "\n dv_toggle_prov_name\n");
-
-module_param(dv_debug, uint, 0664);
-MODULE_PARM_DESC(dv_debug, "\n dv_debug\n");
-
-module_param(force_bypass_dvenl, uint, 0664);
-MODULE_PARM_DESC(force_bypass_dvenl, "\n force_bypass_dvenl\n");
-#endif
-
-#ifdef AGAIN_HAS_THRESHOLD
-module_param(again_threshold, uint, 0664);
-MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-#endif
-
-module_param(force_disp_pic_index, int, 0664);
-MODULE_PARM_DESC(force_disp_pic_index,
- "\n amvdec_h265 force_disp_pic_index\n");
-
-module_param(frmbase_cont_bitlevel, uint, 0664);
-MODULE_PARM_DESC(frmbase_cont_bitlevel, "\n frmbase_cont_bitlevel\n");
-
-module_param(force_bufspec, uint, 0664);
-MODULE_PARM_DESC(force_bufspec, "\n amvdec_h265 force_bufspec\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level, "\n ammvdec_h264 pre_decode_buf_level\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-module_param(disp_vframe_valve_level, uint, 0664);
-MODULE_PARM_DESC(disp_vframe_valve_level, "\n disp_vframe_valve_level\n");
-
-module_param(pic_list_debug, uint, 0664);
-MODULE_PARM_DESC(pic_list_debug, "\n pic_list_debug\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n amvdec_h265 without_display_mode\n");
-
-#ifdef HEVC_8K_LFTOFFSET_FIX
-module_param(performance_profile, uint, 0664);
-MODULE_PARM_DESC(performance_profile, "\n amvdec_h265 performance_profile\n");
-#endif
-module_param(disable_ip_mode, uint, 0664);
-MODULE_PARM_DESC(disable_ip_mode, "\n amvdec_h265 disable ip_mode\n");
-
-module_param(dirty_time_threshold, uint, 0664);
-MODULE_PARM_DESC(dirty_time_threshold, "\n dirty_time_threshold\n");
-
-module_param(dirty_count_threshold, uint, 0664);
-MODULE_PARM_DESC(dirty_count_threshold, "\n dirty_count_threshold\n");
-
-module_param(dirty_buffersize_threshold, uint, 0664);
-MODULE_PARM_DESC(dirty_buffersize_threshold, "\n dirty_buffersize_threshold\n");
-
-module_param(force_config_fence, uint, 0664);
-MODULE_PARM_DESC(force_config_fence, "\n force enable fence\n");
-
-module_param(mv_buf_dynamic_alloc, uint, 0664);
-MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
-
-module_param(detect_stuck_buffer_margin, uint, 0664);
-MODULE_PARM_DESC(detect_stuck_buffer_margin, "\n detect_stuck_buffer_margin\n");
-
-module_init(amvdec_h265_driver_init_module);
-module_exit(amvdec_h265_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC h265 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder_v4l/h265/vh265.h b/drivers/frame_provider/decoder_v4l/h265/vh265.h
deleted file mode 100644
index 11de11a..0000000
--- a/drivers/frame_provider/decoder_v4l/h265/vh265.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * drivers/amlogic/amports/vh265.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef VH265_H
-#define VH265_H
-
-extern u32 get_blackout_policy(void);
-
-extern s32 vh265_init(void);
-
-extern s32 vh265_release(void);
-
-#endif /* VMPEG4_H */
diff --git a/drivers/frame_provider/decoder_v4l/mjpeg/Makefile b/drivers/frame_provider/decoder_v4l/mjpeg/Makefile
deleted file mode 100644
index 23819c6..0000000
--- a/drivers/frame_provider/decoder_v4l/mjpeg/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI) += amvdec_mmjpeg_v4l.o
-amvdec_mmjpeg_v4l-objs += vmjpeg_multi.o
diff --git a/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c
deleted file mode 100644
index 2f0bb96..0000000
--- a/drivers/frame_provider/decoder_v4l/mjpeg/vmjpeg_multi.c
+++ /dev/null
@@ -1,1877 +0,0 @@
-/*
- * drivers/amlogic/amports/vmjpeg.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-
-#include "../../decoder/utils/vdec_input.h"
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/firmware.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include "../../decoder/utils/config_parser.h"
-#include <media/v4l2-mem2mem.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define MEM_NAME "codec_mmjpeg"
-
-#define DRIVER_NAME "ammvdec_mjpeg_v4l"
-#define CHECK_INTERVAL (HZ/100)
-
-/* protocol register usage
- * AV_SCRATCH_4 : decode buffer spec
- * AV_SCRATCH_5 : decode buffer index
- */
-
-#define MREG_DECODE_PARAM AV_SCRATCH_2 /* bit 0-3: pico_addr_mode */
-/* bit 15-4: reference height */
-#define MREG_TO_AMRISC AV_SCRATCH_8
-#define MREG_FROM_AMRISC AV_SCRATCH_9
-#define MREG_FRAME_OFFSET AV_SCRATCH_A
-#define DEC_STATUS_REG AV_SCRATCH_F
-#define MREG_PIC_WIDTH AV_SCRATCH_B
-#define MREG_PIC_HEIGHT AV_SCRATCH_C
-#define DECODE_STOP_POS AV_SCRATCH_K
-
-#define PICINFO_BUF_IDX_MASK 0x0007
-#define PICINFO_AVI1 0x0080
-#define PICINFO_INTERLACE 0x0020
-#define PICINFO_INTERLACE_AVI1_BOT 0x0010
-#define PICINFO_INTERLACE_FIRST 0x0010
-
-#define VF_POOL_SIZE 64
-#define DECODE_BUFFER_NUM_MAX 16
-#define DECODE_BUFFER_NUM_DEF 4
-#define MAX_BMMU_BUFFER_NUM DECODE_BUFFER_NUM_MAX
-
-#define DEFAULT_MEM_SIZE (32*SZ_1M)
-
-#define INVALID_IDX (-1) /* Invalid buffer index.*/
-
-static int debug_enable;
-static u32 udebug_flag;
-#define DECODE_ID(hw) (hw_to_vdec(hw)->id)
-
-static unsigned int radr;
-static unsigned int rval;
-#define VMJPEG_DEV_NUM 9
-static unsigned int max_decode_instance_num = VMJPEG_DEV_NUM;
-static unsigned int max_process_time[VMJPEG_DEV_NUM];
-static unsigned int decode_timeout_val = 200;
-static struct vframe_s *vmjpeg_vf_peek(void *);
-static struct vframe_s *vmjpeg_vf_get(void *);
-static void vmjpeg_vf_put(struct vframe_s *, void *);
-static int vmjpeg_vf_states(struct vframe_states *states, void *);
-static int vmjpeg_event_cb(int type, void *data, void *private_data);
-static void vmjpeg_work(struct work_struct *work);
-static int notify_v4l_eos(struct vdec_s *vdec);
-static int pre_decode_buf_level = 0x800;
-static int start_decode_buf_level = 0x2000;
-static u32 without_display_mode;
-static u32 dynamic_buf_num_margin;
-static u32 run_ready_min_buf_num = 2;
-#undef pr_info
-#define pr_info printk
-unsigned int mmjpeg_debug_mask = 0xff;
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_RUN_FLOW 0X0001
-#define PRINT_FLAG_TIMEINFO 0x0002
-#define PRINT_FLAG_UCODE_DETAIL 0x0004
-#define PRINT_FLAG_VLD_DETAIL 0x0008
-#define PRINT_FLAG_DEC_DETAIL 0x0010
-#define PRINT_FLAG_BUFFER_DETAIL 0x0020
-#define PRINT_FLAG_RESTORE 0x0040
-#define PRINT_FRAME_NUM 0x0080
-#define PRINT_FLAG_FORCE_DONE 0x0100
-#define PRINT_FRAMEBASE_DATA 0x0400
-#define PRINT_FLAG_TIMEOUT_STATUS 0x1000
-#define PRINT_FLAG_V4L_DETAIL 0x8000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-
-int mmjpeg_debug_print(int index, int debug_flag, const char *fmt, ...)
-{
- if (((debug_enable & debug_flag) &&
- ((1 << index) & mmjpeg_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
- int len = 0;
- va_list args;
-
- if (!buf)
- return 0;
-
- va_start(args, fmt);
- len = sprintf(buf, "%d: ", index);
- vsnprintf(buf + len, 512-len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- kfree(buf);
- }
- return 0;
-}
-
-static const char vmjpeg_dec_id[] = "vmmjpeg-dev";
-
-#define PROVIDER_NAME "vdec.mjpeg"
-static const struct vframe_operations_s vf_provider_ops = {
- .peek = vmjpeg_vf_peek,
- .get = vmjpeg_vf_get,
- .put = vmjpeg_vf_put,
- .event_cb = vmjpeg_event_cb,
- .vf_states = vmjpeg_vf_states,
-};
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_ERROR 3
-#define DEC_RESULT_FORCE_EXIT 4
-#define DEC_RESULT_EOS 5
-#define DEC_DECODE_TIMEOUT 0x21
-
-
-struct buffer_spec_s {
- unsigned int y_addr;
- unsigned int u_addr;
- unsigned int v_addr;
-
- int y_canvas_index;
- int u_canvas_index;
- int v_canvas_index;
-
- struct canvas_config_s canvas_config[3];
- unsigned long cma_alloc_addr;
- int cma_alloc_count;
- unsigned int buf_adr;
- ulong v4l_ref_buf_addr;
-};
-
-#define spec2canvas(x) \
- (((x)->v_canvas_index << 16) | \
- ((x)->u_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-struct vdec_mjpeg_hw_s {
- spinlock_t lock;
- struct mutex vmjpeg_mutex;
-
- struct platform_device *platform_dev;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
-
- struct vframe_s vfpool[VF_POOL_SIZE];
- struct vframe_s vframe_dummy;
-
- struct buffer_spec_s buffer_spec[DECODE_BUFFER_NUM_MAX];
- s32 vfbuf_use[DECODE_BUFFER_NUM_MAX];
-
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 saved_resolution;
- u8 init_flag;
- u32 stat;
- u32 dec_result;
- unsigned long buf_start;
- u32 buf_size;
- void *mm_blk_handle;
- struct dec_sysinfo vmjpeg_amstream_dec_info;
-
- struct vframe_chunk_s *chunk;
- struct work_struct work;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- struct firmware_s *fw;
- struct timer_list check_timer;
- u32 decode_timeout_count;
- u32 start_process_time;
- u32 last_vld_level;
- u8 eos;
- u32 frame_num;
- u32 run_count;
- u32 not_run_ready;
- u32 buffer_not_ready;
- u32 input_empty;
- atomic_t peek_num;
- atomic_t get_num;
- atomic_t put_num;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- int buf_num;
- int dynamic_buf_num_margin;
- int sidebind_type;
- int sidebind_channel_id;
- u32 res_ch_flag;
- u32 canvas_mode;
- u32 canvas_endian;
- ulong fb_token;
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
-};
-
-static void reset_process_time(struct vdec_mjpeg_hw_s *hw);
-
-static void set_frame_info(struct vdec_mjpeg_hw_s *hw, struct vframe_s *vf)
-{
- u32 temp;
- u32 temp_endian;
-
- temp = READ_VREG(MREG_PIC_WIDTH);
- if (temp > 1920)
- vf->width = hw->frame_width = 1920;
- else if (temp > 0)
- vf->width = hw->frame_width = temp;
- temp = READ_VREG(MREG_PIC_HEIGHT);
- if (temp > 1088)
- vf->height = hw->frame_height = 1088;
- else if (temp > 0)
- vf->height = hw->frame_height = temp;
- vf->duration = hw->frame_dur;
- vf->ratio_control = DISP_RATIO_ASPECT_RATIO_MAX << DISP_RATIO_ASPECT_RATIO_BIT;
- vf->sar_width = 1;
- vf->sar_height = 1;
- vf->duration_pulldown = 0;
- vf->flag = 0;
-
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 3;
-
- vf->canvas0_config[0] = hw->buffer_spec[vf->index].canvas_config[0];
- vf->canvas0_config[1] = hw->buffer_spec[vf->index].canvas_config[1];
- vf->canvas0_config[2] = hw->buffer_spec[vf->index].canvas_config[2];
-
- vf->canvas1_config[0] = hw->buffer_spec[vf->index].canvas_config[0];
- vf->canvas1_config[1] = hw->buffer_spec[vf->index].canvas_config[1];
- vf->canvas1_config[2] = hw->buffer_spec[vf->index].canvas_config[2];
-
- /* mjpeg convert endian to match display. */
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5W)) {
- temp_endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- } else {
- temp_endian = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 0 : 7;
- }
-
- vf->canvas0_config[0].endian = temp_endian;
- vf->canvas0_config[1].endian = temp_endian;
- vf->canvas0_config[2].endian = temp_endian;
- vf->canvas1_config[0].endian = temp_endian;
- vf->canvas1_config[1].endian = temp_endian;
- vf->canvas1_config[2].endian = temp_endian;
-
- vf->sidebind_type = hw->sidebind_type;
- vf->sidebind_channel_id = hw->sidebind_channel_id;
-}
-
-static irqreturn_t vmjpeg_isr(struct vdec_s *vdec, int irq)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)(vdec->private);
-
- if (!hw)
- return IRQ_HANDLED;
-
- if (hw->eos)
- return IRQ_HANDLED;
-
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- return IRQ_WAKE_THREAD;
-}
-
-static int vmjpeg_get_ps_info(struct vdec_mjpeg_hw_s *hw, int width, int height, struct aml_vdec_ps_infos *ps)
-{
- ps->visible_width = width;
- ps->visible_height = height;
- ps->coded_width = ALIGN(width, 64);
- ps->coded_height = ALIGN(height, 64);
- ps->dpb_size = hw->buf_num;
- ps->dpb_frames = DECODE_BUFFER_NUM_DEF;
- ps->dpb_margin = hw->dynamic_buf_num_margin;
- ps->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int v4l_res_change(struct vdec_mjpeg_hw_s *hw, int width, int height)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- if (ctx->param_sets_from_ucode &&
- hw->res_ch_flag == 0) {
- struct aml_vdec_ps_infos ps;
-
- if ((hw->frame_width != 0 &&
- hw->frame_height != 0) &&
- (hw->frame_width != width ||
- hw->frame_height != height)) {
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d)\n",
- hw->frame_width, hw->frame_height,
- width,
- height);
- vmjpeg_get_ps_info(hw, width, height, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->v4l_params_parsed = false;
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- hw->eos = 1;
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
-
- ret = 1;
- }
- }
-
- return ret;
-}
-
-static irqreturn_t vmjpeg_isr_thread_fn(struct vdec_s *vdec, int irq)
-{
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)(vdec->private);
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- u32 reg;
- struct vframe_s *vf = NULL;
- u32 index, offset = 0, pts;
- u64 pts_us64;
- u32 frame_size;
-
- if (READ_VREG(AV_SCRATCH_D) != 0 &&
- (debug_enable & PRINT_FLAG_UCODE_DETAIL)) {
- pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_D),
- READ_VREG(AV_SCRATCH_E));
- WRITE_VREG(AV_SCRATCH_D, 0);
- return IRQ_HANDLED;
- }
-
- if (READ_VREG(DEC_STATUS_REG) == 1) {
- if (hw->is_used_v4l) {
- int frame_width = READ_VREG(MREG_PIC_WIDTH);
- int frame_height = READ_VREG(MREG_PIC_HEIGHT);
-
- if (!v4l_res_change(hw, frame_width, frame_height)) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
-
- vmjpeg_get_ps_info(hw, frame_width, frame_height, &ps);
- hw->v4l_params_parsed = true;
- vdec_v4l_set_ps_infos(ctx, &ps);
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- } else {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- WRITE_VREG(DEC_STATUS_REG, 0);
-
- hw->res_ch_flag = 1;
- }
- } else {
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- }
- } else
- WRITE_VREG(DEC_STATUS_REG, 0);
- return IRQ_HANDLED;
- }
- reset_process_time(hw);
-
- reg = READ_VREG(MREG_FROM_AMRISC);
- index = READ_VREG(AV_SCRATCH_5) & 0xffffff;
-
- if (index >= hw->buf_num) {
- pr_err("fatal error, invalid buffer index.");
- return IRQ_HANDLED;
- }
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- pr_info(
- "fatal error, no available buffer slot.");
- return IRQ_HANDLED;
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->buffer_spec[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l mem handle: 0x%lx\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
- __func__, vf->v4l_mem_handle);
- }
-
- vf->index = index;
- set_frame_info(hw, vf);
-
- vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
- /* vf->pts = (pts_valid) ? pts : 0; */
- /* vf->pts_us64 = (pts_valid) ? pts_us64 : 0; */
-
- if (hw->chunk) {
- vf->pts = hw->chunk->pts;
- vf->pts_us64 = hw->chunk->pts64;
- vf->timestamp = hw->chunk->timestamp;
- } else {
- offset = READ_VREG(MREG_FRAME_OFFSET);
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64
- (PTS_TYPE_VIDEO, offset, &pts,
- &frame_size, 3000,
- &pts_us64) == 0) {
- vf->pts = pts;
- vf->pts_us64 = pts_us64;
- } else {
- vf->pts = 0;
- vf->pts_us64 = 0;
- }
- }
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- vf->pts_us64 = offset;
- vf->pts = 0;
- }
- }
- vf->orientation = 0;
- hw->vfbuf_use[index]++;
-
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle, index);
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- hw->frame_num++;
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FRAME_NUM,
- "%s:frame num:%d,pts=%d,pts64=%lld. dur=%d\n",
- __func__, hw->frame_num,
- vf->pts, vf->pts_us64, vf->duration);
- vdec->vdec_fps_detec(vdec->id);
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec);
- } else {
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- }
- } else
- vmjpeg_vf_put(vmjpeg_vf_get(vdec), vdec);
-
- hw->dec_result = DEC_RESULT_DONE;
-
- vdec_schedule_work(&hw->work);
-
- return IRQ_HANDLED;
-}
-
-static int valid_vf_check(struct vframe_s *vf, struct vdec_mjpeg_hw_s *hw)
-{
- int i;
-
- if (!vf || (vf->index == -1))
- return 0;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &hw->vfpool[i])
- return 1;
- }
-
- return 0;
-}
-
-static struct vframe_s *vmjpeg_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
-
- if (!hw)
- return NULL;
- atomic_add(1, &hw->peek_num);
- if (kfifo_peek(&hw->display_q, &vf))
- return vf;
-
- return NULL;
-}
-
-static struct vframe_s *vmjpeg_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
-
- if (!hw)
- return NULL;
-
- if (kfifo_get(&hw->display_q, &vf)) {
- vf->index_disp = atomic_read(&hw->get_num);
- atomic_add(1, &hw->get_num);
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- return vf;
- }
- return NULL;
-}
-
-static void vmjpeg_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
-
- if (!valid_vf_check(vf, hw)) {
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "invalid vf: %lx\n", (ulong)vf);
- return ;
- }
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FRAME_NUM,
- "%s:put_num:%d\n", __func__, hw->put_num);
-
- if (vf->v4l_mem_handle !=
- hw->buffer_spec[vf->index].v4l_ref_buf_addr) {
- hw->buffer_spec[vf->index].v4l_ref_buf_addr
- = vf->v4l_mem_handle;
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "MJPEG update fb handle, old:%llx, new:%llx\n",
- hw->buffer_spec[vf->index].v4l_ref_buf_addr,
- vf->v4l_mem_handle);
- }
-
- hw->vfbuf_use[vf->index]--;
-
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- atomic_add(1, &hw->put_num);
-}
-
-static int vmjpeg_event_cb(int type, void *data, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
-
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static int vmjpeg_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
- struct vdec_s *vdec = op_arg;
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
-
- spin_lock_irqsave(&hw->lock, flags);
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
- states->buf_recycle_num = 0;
-
- spin_unlock_irqrestore(&hw->lock, flags);
-
- return 0;
-}
-
-static int vmjpeg_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
-
- if (!hw)
- return -1;
-
- vstatus->frame_width = hw->frame_width;
- vstatus->frame_height = hw->frame_height;
- if (0 != hw->frame_dur)
- vstatus->frame_rate = 96000 / hw->frame_dur;
- else
- vstatus->frame_rate = 96000;
- vstatus->error_count = 0;
- vstatus->status = hw->stat;
-
- return 0;
-}
-
-static void init_scaler(void)
-{
- /* 4 point triangle */
- const unsigned int filt_coef[] = {
- 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
- 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
- 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
- 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
- 0x18382808, 0x18382808, 0x17372909, 0x17372909,
- 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
- 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
- 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
- 0x10303010
- };
- int i;
-
- /* pscale enable, PSCALE cbus bmem enable */
- WRITE_VREG(PSCALE_CTRL, 0xc000);
-
- /* write filter coefs */
- WRITE_VREG(PSCALE_BMEM_ADDR, 0);
- for (i = 0; i < 33; i++) {
- WRITE_VREG(PSCALE_BMEM_DAT, 0);
- WRITE_VREG(PSCALE_BMEM_DAT, filt_coef[i]);
- }
-
- /* Y horizontal initial info */
- WRITE_VREG(PSCALE_BMEM_ADDR, 37 * 2);
- /* [35]: buf repeat pix0,
- * [34:29] => buf receive num,
- * [28:16] => buf blk x,
- * [15:0] => buf phase
- */
- WRITE_VREG(PSCALE_BMEM_DAT, 0x0008);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000);
-
- /* C horizontal initial info */
- WRITE_VREG(PSCALE_BMEM_ADDR, 41 * 2);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x0008);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000);
-
- /* Y vertical initial info */
- WRITE_VREG(PSCALE_BMEM_ADDR, 39 * 2);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x0008);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000);
-
- /* C vertical initial info */
- WRITE_VREG(PSCALE_BMEM_ADDR, 43 * 2);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x0008);
- WRITE_VREG(PSCALE_BMEM_DAT, 0x60000000);
-
- /* Y horizontal phase step */
- WRITE_VREG(PSCALE_BMEM_ADDR, 36 * 2 + 1);
- /* [19:0] => Y horizontal phase step */
- WRITE_VREG(PSCALE_BMEM_DAT, 0x10000);
- /* C horizontal phase step */
- WRITE_VREG(PSCALE_BMEM_ADDR, 40 * 2 + 1);
- /* [19:0] => C horizontal phase step */
- WRITE_VREG(PSCALE_BMEM_DAT, 0x10000);
-
- /* Y vertical phase step */
- WRITE_VREG(PSCALE_BMEM_ADDR, 38 * 2 + 1);
- /* [19:0] => Y vertical phase step */
- WRITE_VREG(PSCALE_BMEM_DAT, 0x10000);
- /* C vertical phase step */
- WRITE_VREG(PSCALE_BMEM_ADDR, 42 * 2 + 1);
- /* [19:0] => C horizontal phase step */
- WRITE_VREG(PSCALE_BMEM_DAT, 0x10000);
-
- /* reset pscaler */
-#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/
- WRITE_VREG(DOS_SW_RESET0, (1 << 10));
- WRITE_VREG(DOS_SW_RESET0, 0);
-#else
- WRITE_RESET_REG(RESET2_REGISTER, RESET_PSCALE);
-#endif
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) {
- READ_RESET_REG(RESET2_REGISTER);
- READ_RESET_REG(RESET2_REGISTER);
- READ_RESET_REG(RESET2_REGISTER);
- }
- WRITE_VREG(PSCALE_RST, 0x7);
- WRITE_VREG(PSCALE_RST, 0x0);
-}
-
-static void vmjpeg_dump_state(struct vdec_s *vdec)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)(vdec->private);
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "====== %s\n", __func__);
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "width/height (%d/%d) buf_num %d\n",
- hw->frame_width,
- hw->frame_height,
- hw->buf_num
- );
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d input_empty %d\n",
- input_frame_based(vdec),
- hw->eos,
- hw->stat,
- hw->dec_result,
- hw->frame_num,
- hw->put_num,
- hw->run_count,
- hw->not_run_ready,
- hw->input_empty
- );
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "%s, newq(%d/%d), dispq(%d/%d) vf peek/get/put (%d/%d/%d)\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->display_q),
- VF_POOL_SIZE,
- hw->peek_num,
- hw->get_num,
- hw->put_num
- );
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "VIFF_BIT_CNT=0x%x\n",
- READ_VREG(VIFF_BIT_CNT));
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_WP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_RP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
- if (input_frame_based(vdec) &&
- debug_enable & PRINT_FRAMEBASE_DATA
- ) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, hw->chunk->size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "frame data size 0x%x\n",
- hw->chunk->size);
- for (jj = 0; jj < hw->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- mmjpeg_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- mmjpeg_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- mmjpeg_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-}
-static void reset_process_time(struct vdec_mjpeg_hw_s *hw)
-{
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[DECODE_ID(hw)])
- max_process_time[DECODE_ID(hw)] = process_time;
- }
-}
-
-static void start_process_time(struct vdec_mjpeg_hw_s *hw)
-{
- hw->decode_timeout_count = 2;
- hw->start_process_time = jiffies;
-}
-
-static void timeout_process(struct vdec_mjpeg_hw_s *hw)
-{
- amvdec_stop();
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s decoder timeout\n", __func__);
- hw->dec_result = DEC_RESULT_DONE;
- reset_process_time(hw);
- vdec_schedule_work(&hw->work);
-}
-
-static void check_timer_func(struct timer_list *timer)
-{
- struct vdec_mjpeg_hw_s *hw = container_of(timer,
- struct vdec_mjpeg_hw_s, check_timer);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int timeout_val = decode_timeout_val;
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_VLD_DETAIL,
- "%s: status:nstatus=%d:%d\n",
- __func__, vdec->status, vdec->next_status);
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_VLD_DETAIL,
- "%s: %d,buftl=%x:%x:%x:%x\n",
- __func__, __LINE__,
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL),
- STBUF_READ(&vdec->vbuf, get_wp),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP));
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (((debug_enable & PRINT_FLAG_TIMEOUT_STATUS) == 0) &&
- (timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > timeout_val)) {
- if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- timeout_process(hw);
- }
- hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
- }
-
- if (READ_VREG(DEC_STATUS_REG) == DEC_DECODE_TIMEOUT) {
- pr_info("ucode DEC_DECODE_TIMEOUT\n");
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- timeout_process(hw);
- WRITE_VREG(DEC_STATUS_REG, 0);
- }
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static void mjpeg_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vmjpeg_vf_put(vf, vdec_ctx);
-}
-
-static void mjpeg_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vmjpeg_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = mjpeg_get_video_frame,
- .put_vframe = mjpeg_put_video_frame,
-};
-
-static int vmjpeg_v4l_alloc_buff_config_canvas(struct vdec_mjpeg_hw_s *hw, int i)
-{
- int ret;
- u32 canvas;
- ulong decbuf_start = 0, decbuf_u_start = 0, decbuf_v_start = 0;
- int decbuf_y_size = 0, decbuf_u_size = 0, decbuf_v_size = 0;
- u32 canvas_width = 0, canvas_height = 0;
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (hw->buffer_spec[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->buffer_spec[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- return 0;
- }
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "[%d] get fb fail.\n",
- ((struct aml_vcodec_ctx *)
- (hw->v4l2_ctx))->id);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hw));
- fb->status = FB_ST_DECODER;
-
- if (!hw->frame_width || !hw->frame_height) {
- struct vdec_pic_info pic;
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->frame_width = pic.visible_width;
- hw->frame_height = pic.visible_height;
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "[%d] set %d x %d from IF layer\n", ctx->id,
- hw->frame_width, hw->frame_height);
- }
-
- hw->buffer_spec[i].v4l_ref_buf_addr = (ulong)fb;
- if (fb->num_planes == 1) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].offset;
- decbuf_u_start = decbuf_start + decbuf_y_size;
- decbuf_u_size = decbuf_y_size / 4;
- decbuf_v_start = decbuf_u_start + decbuf_u_size;
- decbuf_v_size = decbuf_u_size;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- } else if (fb->num_planes == 2) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].size;
- decbuf_u_start = fb->m.mem[1].addr;
- decbuf_u_size = fb->m.mem[1].size >> 1;
- decbuf_v_start = decbuf_u_start + decbuf_u_size;
- decbuf_v_size = decbuf_u_size;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- } else if (fb->num_planes == 3) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].size;
- decbuf_u_start = fb->m.mem[1].addr;
- decbuf_u_size = fb->m.mem[1].size;
- decbuf_v_start = fb->m.mem[2].addr;
- decbuf_v_size = fb->m.mem[2].size;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- fb->m.mem[2].bytes_used = fb->m.mem[2].size;
- }
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] v4l ref buf addr: 0x%x\n", ctx->id, fb);
-
- if (vdec->parallel_dec == 1) {
- if (hw->buffer_spec[i].y_canvas_index == -1)
- hw->buffer_spec[i].y_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].u_canvas_index == -1)
- hw->buffer_spec[i].u_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- if (hw->buffer_spec[i].v_canvas_index == -1)
- hw->buffer_spec[i].v_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- } else {
- canvas = vdec->get_canvas(i, 3);
- hw->buffer_spec[i].y_canvas_index = canvas_y(canvas);
- hw->buffer_spec[i].u_canvas_index = canvas_u(canvas);
- hw->buffer_spec[i].v_canvas_index = canvas_v(canvas);
- }
-
- hw->buffer_spec[i].canvas_config[0].phy_addr =
- decbuf_start;
- hw->buffer_spec[i].canvas_config[0].width =
- canvas_width;
- hw->buffer_spec[i].canvas_config[0].height =
- canvas_height;
- hw->buffer_spec[i].canvas_config[0].block_mode =
- hw->canvas_mode;
- hw->buffer_spec[i].canvas_config[0].endian =
- (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
-
- config_cav_lut(hw->buffer_spec[i].y_canvas_index,
- &hw->buffer_spec[i].canvas_config[0], VDEC_1);
-
- hw->buffer_spec[i].canvas_config[1].phy_addr =
- decbuf_u_start;
- hw->buffer_spec[i].canvas_config[1].width =
- canvas_width / 2;
- hw->buffer_spec[i].canvas_config[1].height =
- canvas_height / 2;
- hw->buffer_spec[i].canvas_config[1].block_mode =
- hw->canvas_mode;
- hw->buffer_spec[i].canvas_config[1].endian =
- (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
-
- config_cav_lut(hw->buffer_spec[i].u_canvas_index,
- &hw->buffer_spec[i].canvas_config[1], VDEC_1);
-
- hw->buffer_spec[i].canvas_config[2].phy_addr =
- decbuf_v_start;
- hw->buffer_spec[i].canvas_config[2].width =
- canvas_width / 2;
- hw->buffer_spec[i].canvas_config[2].height =
- canvas_height / 2;
- hw->buffer_spec[i].canvas_config[2].block_mode =
- hw->canvas_mode;
- hw->buffer_spec[i].canvas_config[2].endian =
- (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
-
- config_cav_lut(hw->buffer_spec[i].v_canvas_index,
- &hw->buffer_spec[i].canvas_config[2], VDEC_1);
-
- return 0;
-}
-
-static int find_free_buffer(struct vdec_mjpeg_hw_s *hw)
-{
- int i;
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->vfbuf_use[i] == 0)
- break;
- }
-
- if ((i == hw->buf_num) &&
- (hw->buf_num != 0)) {
- return -1;
- }
-
- if (vmjpeg_v4l_alloc_buff_config_canvas(hw, i))
- return -1;
-
- return i;
-}
-
-static int vmjpeg_hw_ctx_restore(struct vdec_mjpeg_hw_s *hw)
-{
- int index = -1;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- int i = 0;
-
- if (hw->v4l_params_parsed) {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(v4l2_ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- index = find_free_buffer(hw);
- if ((index < 0) || (index >= hw->buf_num))
- return -1;
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->buffer_spec[i].v4l_ref_buf_addr) {
- config_cav_lut(hw->buffer_spec[i].y_canvas_index,
- &hw->buffer_spec[i].canvas_config[0], VDEC_1);
- config_cav_lut(hw->buffer_spec[i].u_canvas_index,
- &hw->buffer_spec[i].canvas_config[1], VDEC_1);
- config_cav_lut(hw->buffer_spec[i].v_canvas_index,
- &hw->buffer_spec[i].canvas_config[2], VDEC_1);
- }
- }
-
- /* find next decode buffer index */
- WRITE_VREG(AV_SCRATCH_4, spec2canvas(&hw->buffer_spec[index]));
- WRITE_VREG(AV_SCRATCH_5, index | 1 << 24);
-
- } else
- WRITE_VREG(AV_SCRATCH_5, 1 << 24);
-
- WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6));
- WRITE_VREG(DOS_SW_RESET0, 0);
- init_scaler();
-
- /* clear buffer IN/OUT registers */
- WRITE_VREG(MREG_TO_AMRISC, 0);
- WRITE_VREG(MREG_FROM_AMRISC, 0);
-
- WRITE_VREG(MCPU_INTR_MSK, 0xffff);
- WRITE_VREG(MREG_DECODE_PARAM, (hw->frame_height << 4) | 0x8000);
-
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
- /* set interrupt mapping for vld */
- WRITE_VREG(ASSIST_AMR1_INT8, 8);
-#if 1/*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6*/
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
- return 0;
-}
-
-static s32 vmjpeg_init(struct vdec_s *vdec)
-{
- int i;
- int size = -1, fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- size = get_firmware_data(VIDEO_DEC_MJPEG_MULTI, fw->data);
- if (size < 0) {
- pr_err("get firmware fail.");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
-
- if (hw->is_used_v4l) {
- hw->frame_width = 0;
- hw->frame_height = 0;
- } else {
- hw->frame_width = hw->vmjpeg_amstream_dec_info.width;
- hw->frame_height = hw->vmjpeg_amstream_dec_info.height;
- }
- hw->frame_dur = ((hw->vmjpeg_amstream_dec_info.rate) ?
- hw->vmjpeg_amstream_dec_info.rate : 3840);
- hw->saved_resolution = 0;
- hw->eos = 0;
- hw->init_flag = 0;
- hw->frame_num = 0;
- hw->run_count = 0;
- hw->not_run_ready = 0;
- hw->input_empty = 0;
- atomic_set(&hw->peek_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->put_num, 0);
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->vfbuf_use[i] = 0;
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- hw->vfpool[i].index = -1;
- kfifo_put(&hw->newframe_q, vf);
- }
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-
- hw->mm_blk_handle = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- 0,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER);
-
- timer_setup(&hw->check_timer, check_timer_func, 0);
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
- /*add_timer(&hw->check_timer);*/
- hw->stat |= STAT_TIMER_ARM;
- hw->stat |= STAT_ISR_REG;
-
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
- INIT_WORK(&hw->work, vmjpeg_work);
- pr_info("w:h=%d:%d\n", hw->frame_width, hw->frame_height);
- return 0;
-}
-
-static bool is_avaliable_buffer(struct vdec_mjpeg_hw_s *hw)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_count = 0;
- int used_count = 0;
-
- if ((hw->buf_num == 0) ||
- (ctx->cap_pool.dec < hw->buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hw->buf_num; ++i) {
- if ((hw->vfbuf_use[i] == 0) &&
- hw->buffer_spec[i].v4l_ref_buf_addr) {
- free_count++;
- } else if (hw->buffer_spec[i].v4l_ref_buf_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec,
- unsigned long mask)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- hw->not_run_ready++;
-
- if (hw->eos)
- return 0;
-
- if (vdec_stream_based(vdec) && (hw->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level)
- return 0;
- }
-
- if (hw->v4l_params_parsed) {
- ret = is_avaliable_buffer(hw) ? 1 : 0;
- } else {
- ret = ctx->v4l_resolution_change ? 0 : 1;
- }
-
- hw->not_run_ready = 0;
- hw->buffer_not_ready = 0;
-
- return ret ? CORE_MASK_VDEC_1 : 0;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
- int ret;
-
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
-
- hw->run_count++;
- vdec_reset_core(vdec);
-
- ret = vdec_prepare_input(vdec, &hw->chunk);
- if (ret <= 0) {
- hw->input_empty++;
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s: %d,r=%d,buftl=%x:%x:%x\n",
- __func__, __LINE__, ret,
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL),
- STBUF_READ(&vdec->vbuf, get_rp),
- READ_VREG(VLD_MEM_VIFIFO_WP));
-
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- return;
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", ret);
-
- hw->input_empty = 0;
- hw->dec_result = DEC_RESULT_NONE;
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
- ret = amvdec_vdec_loadmc_ex(VFORMAT_MJPEG, "mmjpeg", vdec, hw->fw->data);
- if (ret < 0) {
- pr_err("[%d] MMJPEG: the %s fw loading failed, err: %x\n",
- vdec->id, tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_MJPEG;
- }
-/* if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) {
- pr_err("%s: Error amvdec_loadmc fail\n", __func__);
- return;
- }*/
-
- if (vmjpeg_hw_ctx_restore(hw) < 0) {
- hw->dec_result = DEC_RESULT_ERROR;
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "amvdec_mmjpeg: error HW context restore\n");
- vdec_schedule_work(&hw->work);
- return;
- }
-#if 0
- vdec_enable_input(vdec);
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-#endif
- hw->stat |= STAT_MC_LOAD;
- start_process_time(hw);
- hw->last_vld_level = 0;
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
- amvdec_start();
- vdec_enable_input(vdec);
- hw->stat |= STAT_VDEC_RUN;
- hw->init_flag = 1;
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s (0x%x 0x%x 0x%x) vldcrl 0x%x bitcnt 0x%x powerctl 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VLD_DECODE_CONTROL),
- READ_VREG(VIFF_BIT_CNT),
- READ_VREG(POWER_CTL_VLD),
- READ_VREG(VLD_MEM_VIFIFO_START_PTR),
- READ_VREG(VLD_MEM_VIFIFO_CURR_PTR),
- READ_VREG(VLD_MEM_VIFIFO_CONTROL),
- READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL),
- READ_VREG(VLD_MEM_VIFIFO_END_PTR));
-}
-static void wait_vmjpeg_search_done(struct vdec_mjpeg_hw_s *hw)
-{
- u32 vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- int count = 0;
-
- do {
- usleep_range(100, 500);
- if (vld_rp == READ_VREG(VLD_MEM_VIFIFO_RP))
- break;
- if (count > 1000) {
- mmjpeg_debug_print(DECODE_ID(hw), 0,
- "%s, count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n",
- __func__, count, vld_rp, READ_VREG(VLD_MEM_VIFIFO_RP));
- break;
- } else
- vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- count++;
- } while (1);
-}
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct vdec_mjpeg_hw_s *hw = (struct vdec_mjpeg_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] MJPEG isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = find_free_buffer(hw);
- if (INVALID_IDX == index) {
- pr_err("[%d] MJPEG EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->buffer_spec[index].v4l_ref_buf_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = (ulong)fb;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- pr_info("[%d] mjpeg EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void vmjpeg_work(struct work_struct *work)
-{
- struct vdec_mjpeg_hw_s *hw = container_of(work,
- struct vdec_mjpeg_hw_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- mmjpeg_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "%s: result=%d,len=%d:%d\n",
- __func__, hw->dec_result,
- kfifo_len(&hw->newframe_q),
- kfifo_len(&hw->display_q));
-
- ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result);
-
- if (hw->dec_result == DEC_RESULT_DONE) {
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- hw->chunk = NULL;
- } else if (hw->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(hw_to_vdec(hw))) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- /*pr_info("%s: return\n",
- __func__);*/
- return;
- }
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- pr_info("%s: force exit\n", __func__);
- if (hw->stat & STAT_ISR_REG) {
- amvdec_stop();
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- pr_info("%s: end of stream\n", __func__);
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- hw->eos = 1;
- if (hw->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(vdec);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
-
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- hw->chunk = NULL;
- vdec_clean_input(hw_to_vdec(hw));
- }
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- /*disable mbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- wait_vmjpeg_search_done(hw);
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hw->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else {
- vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1
- | CORE_MASK_HEVC);
- }
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
-
- if (hw->vdec_cb)
- hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
-}
-
-static int vmjpeg_stop(struct vdec_mjpeg_hw_s *hw)
-{
- pr_info("%s ...count = %d\n", __func__, hw->frame_num);
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- pr_info("%s amvdec_stop\n", __func__);
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
- cancel_work_sync(&hw->work);
- hw->init_flag = 0;
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
-
- return 0;
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)vdec->private;
- int i;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- flush_work(&hw->work);
- reset_process_time(hw);
-
- for (i = 0; i < hw->buf_num; i++) {
- hw->buffer_spec[i].v4l_ref_buf_addr = 0;
- hw->vfbuf_use[i] = 0;
- }
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- memset((void *)vf, 0, sizeof(*vf));
- hw->vfpool[i].index = -1;
- kfifo_put(&hw->newframe_q, vf);
- }
- hw->eos = 0;
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(hw->buffer_spec[i].y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id);
- hw->buffer_spec[i].y_canvas_index = -1;
- hw->buffer_spec[i].u_canvas_index = -1;
- hw->buffer_spec[i].v_canvas_index = -1;
- }
-
- hw->eos = 0;
- hw->buf_num = 0;
- hw->frame_width = 0;
- hw->frame_height = 0;
-
- atomic_set(&hw->peek_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->put_num, 0);
-
- pr_info("mjpeg: reset.\n");
-}
-
-static int ammvdec_mjpeg_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_mjpeg_hw_s *hw = NULL;
- int config_val = 0;
-
- if (pdata == NULL) {
- pr_info("ammvdec_mjpeg memory resource undefined.\n");
- return -EFAULT;
- }
-
- hw = vzalloc(sizeof(struct vdec_mjpeg_hw_s));
- if (hw == NULL) {
- pr_info("\nammvdec_mjpeg device data allocation failed\n");
- return -ENOMEM;
- }
-
- /* the ctx from v4l2 driver. */
- hw->v4l2_ctx = pdata->private;
-
- pdata->private = hw;
- pdata->dec_status = vmjpeg_dec_status;
-
- pdata->run = run;
- pdata->run_ready = run_ready;
- pdata->reset = reset;
- pdata->irq_handler = vmjpeg_isr;
- pdata->threaded_irq_handler = vmjpeg_isr_thread_fn;
- pdata->dump_state = vmjpeg_dump_state;
-
- snprintf(hw->vdec_name, sizeof(hw->vdec_name),
- "vmjpeg-%d", pdev->id);
- snprintf(hw->pts_name, sizeof(hw->pts_name),
- "%s-timestamp", hw->vdec_name);
- snprintf(hw->new_q_name, sizeof(hw->new_q_name),
- "%s-newframe_q", hw->vdec_name);
- snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
- "%s-dispframe_q", hw->vdec_name);
-
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- hw->buffer_spec[i].y_canvas_index = -1;
- hw->buffer_spec[i].u_canvas_index = -1;
- hw->buffer_spec[i].v_canvas_index = -1;
- }
- }
-
- if (pdata->use_vfm_path)
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- platform_set_drvdata(pdev, pdata);
- hw->platform_dev = pdev;
-
- if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) {
- mmjpeg_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config);
- if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin = config_val;
- else
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hw->canvas_mode = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_endian",
- &config_val) == 0)
- hw->canvas_endian = config_val;
-
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hw->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hw->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hw->is_used_v4l = config_val;
-
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
- } else {
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- }
-
- if (!hw->is_used_v4l) {
- vf_provider_init(&pdata->vframe_provider,
- pdata->vf_provider_name, &vf_provider_ops, pdata);
- }
-
- platform_set_drvdata(pdev, pdata);
-
- hw->platform_dev = pdev;
-
- vdec_source_changed(VFORMAT_MJPEG,
- 1920, 1080, 60);
- if (vmjpeg_init(pdata) < 0) {
- pr_info("ammvdec_mjpeg init failed.\n");
- if (hw) {
- vfree(hw);
- hw = NULL;
- }
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
-
- return 0;
-}
-
-static int ammvdec_mjpeg_remove(struct platform_device *pdev)
-{
- struct vdec_mjpeg_hw_s *hw =
- (struct vdec_mjpeg_hw_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec;
- int i;
-
- if (!hw)
- return -1;
- vdec = hw_to_vdec(hw);
-
- vmjpeg_stop(hw);
-
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(hw->buffer_spec[i].y_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].u_canvas_index, vdec->id);
- vdec->free_canvas_ex(hw->buffer_spec[i].v_canvas_index, vdec->id);
- }
- }
-
- vfree(hw);
-
- pr_info("%s\n", __func__);
- return 0;
-}
-
-/****************************************/
-
-static struct platform_driver ammvdec_mjpeg_driver = {
- .probe = ammvdec_mjpeg_probe,
- .remove = ammvdec_mjpeg_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = DRIVER_NAME,
- }
-};
-
-static struct codec_profile_t ammvdec_mjpeg_profile = {
- .name = "MJPEG-V4L",
- .profile = ""
-};
-
-static int __init ammvdec_mjpeg_driver_init_module(void)
-{
- if (platform_driver_register(&ammvdec_mjpeg_driver)) {
- pr_err("failed to register ammvdec_mjpeg driver\n");
- return -ENODEV;
- }
- vcodec_profile_register(&ammvdec_mjpeg_profile);
- vcodec_feature_register(VFORMAT_MJPEG, 1);
- return 0;
-}
-
-static void __exit ammvdec_mjpeg_driver_remove_module(void)
-{
- platform_driver_unregister(&ammvdec_mjpeg_driver);
-}
-
-/****************************************/
-module_param(debug_enable, uint, 0664);
-MODULE_PARM_DESC(debug_enable, "\n debug enable\n");
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level,
- "\n ammvdec_h264 pre_decode_buf_level\n");
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_mmpeg12 udebug_flag\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val, "\n ammvdec_mjpeg decode_timeout_val\n");
-
-module_param_array(max_process_time, uint, &max_decode_instance_num, 0664);
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(start_decode_buf_level, uint, 0664);
-MODULE_PARM_DESC(start_decode_buf_level, "\nstart_decode_buf_level\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-
-module_init(ammvdec_mjpeg_driver_init_module);
-module_exit(ammvdec_mjpeg_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC MJMPEG Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder_v4l/mpeg12/Makefile b/drivers/frame_provider/decoder_v4l/mpeg12/Makefile
deleted file mode 100644
index 6419ed6..0000000
--- a/drivers/frame_provider/decoder_v4l/mpeg12/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI) += amvdec_mmpeg12_v4l.o
-amvdec_mmpeg12_v4l-objs += vmpeg12_multi.o
diff --git a/drivers/frame_provider/decoder_v4l/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder_v4l/mpeg12/vmpeg12_multi.c
deleted file mode 100644
index f67fd71..0000000
--- a/drivers/frame_provider/decoder_v4l/mpeg12/vmpeg12_multi.c
+++ /dev/null
@@ -1,3945 +0,0 @@
-/*
- * drivers/amlogic/amports/vmpeg12.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
-*/
-
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/platform_device.h>
-#include <linux/random.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/sched/clock.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/vdec_input.h"
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/config_parser.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include "../../decoder/utils/config_parser.h"
-#include <media/v4l2-mem2mem.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define MEM_NAME "codec_mmpeg12"
-#define CHECK_INTERVAL (HZ/100)
-
-#define DRIVER_NAME "ammvdec_mpeg12_v4l"
-#define MREG_REF0 AV_SCRATCH_2
-#define MREG_REF1 AV_SCRATCH_3
-/* protocol registers */
-#define MREG_SEQ_INFO AV_SCRATCH_4
-#define MREG_PIC_INFO AV_SCRATCH_5
-#define MREG_PIC_WIDTH AV_SCRATCH_6
-#define MREG_PIC_HEIGHT AV_SCRATCH_7
-#define MREG_INPUT AV_SCRATCH_8 /*input_type*/
-#define MREG_BUFFEROUT AV_SCRATCH_9 /*FROM_AMRISC_REG*/
-
-#define MREG_CMD AV_SCRATCH_A
-#define MREG_CO_MV_START AV_SCRATCH_B
-#define MREG_ERROR_COUNT AV_SCRATCH_C
-#define MREG_FRAME_OFFSET AV_SCRATCH_D
-#define MREG_WAIT_BUFFER AV_SCRATCH_E
-#define MREG_FATAL_ERROR AV_SCRATCH_F
-
-#define MREG_CC_ADDR AV_SCRATCH_0
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-
-#define GET_SLICE_TYPE(type) ("IPB##"[((type&PICINFO_TYPE_MASK)>>16)&0x3])
-#define PICINFO_ERROR 0x80000000
-#define PICINFO_TYPE_MASK 0x00030000
-#define PICINFO_TYPE_I 0x00000000
-#define PICINFO_TYPE_P 0x00010000
-#define PICINFO_TYPE_B 0x00020000
-#define PICINFO_PROG 0x8000
-#define PICINFO_RPT_FIRST 0x4000
-#define PICINFO_TOP_FIRST 0x2000
-#define PICINFO_FRAME 0x1000
-#define TOP_FIELD 0x1000
-#define BOTTOM_FIELD 0x2000
-#define FRAME_PICTURE 0x3000
-#define FRAME_PICTURE_MASK 0x3000
-
-#define SEQINFO_EXT_AVAILABLE 0x80000000
-#define SEQINFO_PROG 0x00010000
-#define CCBUF_SIZE (5*1024)
-
-#define VF_POOL_SIZE 64
-#define DECODE_BUFFER_NUM_MAX 16
-#define DECODE_BUFFER_NUM_DEF 8
-#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1)
-
-#define PUT_INTERVAL (HZ/100)
-#define WORKSPACE_SIZE (4*SZ_64K) /*swap&ccbuf&matirx&MV*/
-#define CTX_LMEM_SWAP_OFFSET 0
-#define CTX_CCBUF_OFFSET 0x800
-#define CTX_QUANT_MATRIX_OFFSET (CTX_CCBUF_OFFSET + 5*1024)
-#define CTX_CO_MV_OFFSET (CTX_QUANT_MATRIX_OFFSET + 1*1024)
-#define CTX_DECBUF_OFFSET (CTX_CO_MV_OFFSET + 0x11000)
-
-#define DEFAULT_MEM_SIZE (32*SZ_1M)
-
-#define INVALID_IDX (-1) /* Invalid buffer index.*/
-
-static int pre_decode_buf_level = 0x800;
-static int start_decode_buf_level = 0x4000;
-static u32 dec_control;
-static u32 error_frame_skip_level = 1;
-static u32 udebug_flag;
-static unsigned int radr;
-static unsigned int rval;
-
-static u32 without_display_mode;
-static u32 dynamic_buf_num_margin = 2;
-
-#define VMPEG12_DEV_NUM 9
-static unsigned int max_decode_instance_num = VMPEG12_DEV_NUM;
-static unsigned int max_process_time[VMPEG12_DEV_NUM];
-static unsigned int decode_timeout_val = 200;
-#define INCPTR(p) ptr_atomic_wrap_inc(&p)
-
-#define DEC_CONTROL_FLAG_FORCE_2500_720_576_INTERLACE 0x0002
-#define DEC_CONTROL_FLAG_FORCE_3000_704_480_INTERLACE 0x0004
-#define DEC_CONTROL_FLAG_FORCE_2500_704_576_INTERLACE 0x0008
-#define DEC_CONTROL_FLAG_FORCE_2500_544_576_INTERLACE 0x0010
-#define DEC_CONTROL_FLAG_FORCE_2500_480_576_INTERLACE 0x0020
-#define DEC_CONTROL_INTERNAL_MASK 0x0fff
-#define DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE 0x1000
-
-#define INTERLACE_SEQ_ALWAYS
-
-#if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
-#define NV21
-#endif
-
-#define AGAIN_HAS_THRESHOLD
-
-#ifdef AGAIN_HAS_THRESHOLD
-static u32 again_threshold;
-#endif
-
-/*
-#define DUMP_USER_DATA
-*/
-
-enum {
- FRAME_REPEAT_TOP,
- FRAME_REPEAT_BOT,
- FRAME_REPEAT_NONE
-};
-
-/*Send by AV_SCRATCH_9*/
-#define MPEG12_PIC_DONE 1
-#define MPEG12_DATA_EMPTY 2
-#define MPEG12_SEQ_END 3
-#define MPEG12_DATA_REQUEST 4
-
-/*Send by AV_SCRATCH_G*/
-#define MPEG12_V4L2_INFO_NOTIFY 1
-/*Send by AV_SCRATCH_J*/
-#define MPEG12_USERDATA_DONE 0x8000
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_ERROR 3
-#define DEC_RESULT_FORCE_EXIT 4
-#define DEC_RESULT_EOS 5
-#define DEC_RESULT_GET_DATA 6
-#define DEC_RESULT_GET_DATA_RETRY 7
-
-#define DEC_DECODE_TIMEOUT 0x21
-#define DECODE_ID(hw) (hw_to_vdec(hw)->id)
-#define DECODE_STOP_POS AV_SCRATCH_K
-
-struct mmpeg2_userdata_record_t {
- struct userdata_meta_info_t meta_info;
- u32 rec_start;
- u32 rec_len;
-};
-
-#define USERDATA_FIFO_NUM 256
-#define MAX_FREE_USERDATA_NODES 5
-
-struct mmpeg2_userdata_info_t {
- struct mmpeg2_userdata_record_t records[USERDATA_FIFO_NUM];
- u8 *data_buf;
- u8 *data_buf_end;
- u32 buf_len;
- u32 read_index;
- u32 write_index;
- u32 last_wp;
-};
-#define MAX_UD_RECORDS 5
-
-struct pic_info_t {
- u32 buffer_info;
- u32 index;
- u32 offset;
- u32 width;
- u32 height;
- u32 pts;
- u64 pts64;
- bool pts_valid;
- ulong v4l_ref_buf_addr;
- u32 hw_decode_time;
- u32 frame_size; // For frame base mode
- u64 timestamp;
- u64 last_timestamp;
-};
-
-struct vdec_mpeg12_hw_s {
- spinlock_t lock;
- struct platform_device *platform_dev;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
- struct vframe_s vframe_dummy;
- s32 vfbuf_use[DECODE_BUFFER_NUM_MAX];
- s32 ref_use[DECODE_BUFFER_NUM_MAX];
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 frame_prog;
- u32 seqinfo;
- u32 ctx_valid;
- u32 dec_control;
- void *mm_blk_handle;
- struct vframe_chunk_s *chunk;
- u32 stat;
- u8 init_flag;
- unsigned long buf_start;
- u32 buf_size;
- u32 reg_pic_width;
- u32 reg_pic_height;
- u32 reg_mpeg1_2_reg;
- u32 reg_pic_head_info;
- u32 reg_f_code_reg;
- u32 reg_slice_ver_pos_pic_type;
- u32 reg_vcop_ctrl_reg;
- u32 reg_mb_info;
- u32 reg_signal_type;
- u32 dec_num;
- struct timer_list check_timer;
- u32 decode_timeout_count;
- unsigned long int start_process_time;
- u32 last_vld_level;
- u32 eos;
-
- struct pic_info_t pics[DECODE_BUFFER_NUM_MAX];
- u32 canvas_spec[DECODE_BUFFER_NUM_MAX];
- u64 lastpts64;
- u32 last_chunk_pts;
- struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2];
- struct dec_sysinfo vmpeg12_amstream_dec_info;
-
- s32 refs[2];
- int dec_result;
- u32 timeout_processing;
- struct work_struct work;
- struct work_struct timeout_work;
- struct work_struct notify_work;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- dma_addr_t ccbuf_phyAddress;
- void *ccbuf_phyAddress_virt;
- u32 cc_buf_size;
- unsigned long ccbuf_phyAddress_is_remaped_nocache;
- u32 frame_rpt_state;
-/* for error handling */
- s32 frame_force_skip_flag;
- s32 error_frame_skip_level;
- s32 wait_buffer_counter;
- u32 first_i_frame_ready;
- u32 run_count;
- u32 not_run_ready;
- u32 input_empty;
- atomic_t disp_num;
- atomic_t put_num;
- atomic_t peek_num;
- atomic_t get_num;
- u32 drop_frame_count;
- u32 buffer_not_ready;
- u32 ratio_control;
- int frameinfo_enable;
- struct firmware_s *fw;
- u32 canvas_mode;
-#ifdef AGAIN_HAS_THRESHOLD
- u32 pre_parser_wr_ptr;
- u8 next_again_flag;
-#endif
-
- struct work_struct userdata_push_work;
- struct mutex userdata_mutex;
- struct mmpeg2_userdata_info_t userdata_info;
- struct mmpeg2_userdata_record_t ud_record[MAX_UD_RECORDS];
- int cur_ud_idx;
- u8 *user_data_buffer;
- int wait_for_udr_send;
- u32 ucode_cc_last_wp;
- u32 notify_ucode_cc_last_wp;
- u32 notify_data_cc_last_wp;
- u32 userdata_wp_ctx;
-#ifdef DUMP_USER_DATA
-#define MAX_USER_DATA_SIZE 1572864
- void *user_data_dump_buf;
- unsigned char *pdump_buf_cur_start;
- int total_len;
- int bskip;
- int n_userdata_id;
- u32 reference[MAX_UD_RECORDS];
-#endif
- int tvp_flag;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- u32 buf_num;
- u32 dynamic_buf_num_margin;
- struct vdec_info gvs;
- struct vframe_qos_s vframe_qos;
- u32 res_ch_flag;
- u32 i_only;
- u32 kpi_first_i_comming;
- u32 kpi_first_i_decoded;
- int sidebind_type;
- int sidebind_channel_id;
- u32 profile_idc;
- u32 level_idc;
- int dec_again_cnt;
- int vdec_pg_enable_flag;
- ulong fb_token;
- bool force_prog_only;
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
- u32 chunk_header_offset;
- u32 chunk_res_size;
- u64 first_field_timestamp;
- u64 first_field_timestamp_valid;
- u32 report_field;
-};
-static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw);
-static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw);
-static void reset_process_time(struct vdec_mpeg12_hw_s *hw);
-static void vmpeg12_workspace_init(struct vdec_mpeg12_hw_s *hw);
-static void flush_output(struct vdec_mpeg12_hw_s *hw);
-static struct vframe_s *vmpeg_vf_peek(void *);
-static struct vframe_s *vmpeg_vf_get(void *);
-static void vmpeg_vf_put(struct vframe_s *, void *);
-static int vmpeg_vf_states(struct vframe_states *states, void *);
-static int vmpeg_event_cb(int type, void *data, void *private_data);
-static int notify_v4l_eos(struct vdec_s *vdec);
-static void start_process_time_set(struct vdec_mpeg12_hw_s *hw);
-static int debug_enable;
-/*static struct work_struct userdata_push_work;*/
-#undef pr_info
-#define pr_info printk
-unsigned int mpeg12_debug_mask = 0xff;
-/*static int counter_max = 5;*/
-static u32 run_ready_min_buf_num = 2;
-static int dirty_again_threshold = 100;
-static int error_proc_policy = 0x1;
-
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_RUN_FLOW 0X0001
-#define PRINT_FLAG_TIMEINFO 0x0002
-#define PRINT_FLAG_UCODE_DETAIL 0x0004
-#define PRINT_FLAG_VLD_DETAIL 0x0008
-#define PRINT_FLAG_DEC_DETAIL 0x0010
-#define PRINT_FLAG_BUFFER_DETAIL 0x0020
-#define PRINT_FLAG_RESTORE 0x0040
-#define PRINT_FRAME_NUM 0x0080
-#define PRINT_FLAG_FORCE_DONE 0x0100
-#define PRINT_FLAG_COUNTER 0X0200
-#define PRINT_FRAMEBASE_DATA 0x0400
-#define PRINT_FLAG_VDEC_STATUS 0x0800
-#define PRINT_FLAG_PARA_DATA 0x1000
-#define PRINT_FLAG_USERDATA_DETAIL 0x2000
-#define PRINT_FLAG_TIMEOUT_STATUS 0x4000
-#define PRINT_FLAG_V4L_DETAIL 0x8000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-
-
-
-int debug_print(int index, int debug_flag, const char *fmt, ...)
-{
- if (((debug_enable & debug_flag) &&
- ((1 << index) & mpeg12_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
- int len = 0;
- va_list args;
-
- if (!buf)
- return 0;
-
- va_start(args, fmt);
- len = sprintf(buf, "%d: ", index);
- vsnprintf(buf + len, 512-len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- kfree(buf);
- }
- return 0;
-}
-
-
-/*static bool is_reset;*/
-#define PROVIDER_NAME "vdec.mpeg12"
-static const struct vframe_operations_s vf_provider_ops = {
- .peek = vmpeg_vf_peek,
- .get = vmpeg_vf_get,
- .put = vmpeg_vf_put,
- .event_cb = vmpeg_event_cb,
- .vf_states = vmpeg_vf_states,
-};
-
-
-static const u32 frame_rate_tab[16] = {
- 96000 / 30, 96000000 / 23976, 96000 / 24, 96000 / 25,
- 9600000 / 2997, 96000 / 30, 96000 / 50, 9600000 / 5994,
- 96000 / 60,
- /* > 8 reserved, use 24 */
- 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24,
- 96000 / 24, 96000 / 24, 96000 / 24
-};
-
-static void mpeg12_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vmpeg_vf_put(vf, vdec_ctx);
-}
-
-static void mpeg12_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vmpeg_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = mpeg12_get_video_frame,
- .put_vframe = mpeg12_put_video_frame,
-};
-
-static int vmpeg12_v4l_alloc_buff_config_canvas(struct vdec_mpeg12_hw_s *hw, int i)
-{
- int ret;
- u32 canvas;
- ulong decbuf_start = 0, decbuf_uv_start = 0;
- int decbuf_y_size = 0, decbuf_uv_size = 0;
- u32 canvas_width = 0, canvas_height = 0;
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (hw->pics[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->pics[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- return 0;
- }
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- debug_print(DECODE_ID(hw), 0,
- "[%d] get fb fail %d/%d.\n",
- ctx->id, i, hw->buf_num);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hw));
- fb->status = FB_ST_DECODER;
-
- if (!hw->frame_width || !hw->frame_height) {
- struct vdec_pic_info pic;
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->frame_width = pic.visible_width;
- hw->frame_height = pic.visible_height;
- debug_print(DECODE_ID(hw), 0,
- "[%d] set %d x %d from IF layer\n", ctx->id,
- hw->frame_width, hw->frame_height);
- }
-
- hw->pics[i].v4l_ref_buf_addr = (ulong)fb;
- if (fb->num_planes == 1) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].offset;
- decbuf_uv_start = decbuf_start + decbuf_y_size;
- decbuf_uv_size = decbuf_y_size / 2;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- } else if (fb->num_planes == 2) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].size;
- decbuf_uv_start = fb->m.mem[1].addr;
- decbuf_uv_size = fb->m.mem[1].size;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = decbuf_y_size;
- fb->m.mem[1].bytes_used = decbuf_uv_size;
- }
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l ref buf addr: 0x%x\n",
- ctx->id, __func__, fb);
-
- if (vdec->parallel_dec == 1) {
- u32 tmp;
- if (canvas_u(hw->canvas_spec[i]) == 0xff) {
- tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~(0xffff << 8);
- hw->canvas_spec[i] |= tmp << 8;
- hw->canvas_spec[i] |= tmp << 16;
- }
- if (canvas_y(hw->canvas_spec[i]) == 0xff) {
- tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~0xff;
- hw->canvas_spec[i] |= tmp;
- }
- canvas = hw->canvas_spec[i];
- } else {
- canvas = vdec->get_canvas(i, 2);
- hw->canvas_spec[i] = canvas;
- }
-
- hw->canvas_config[i][0].phy_addr = decbuf_start;
- hw->canvas_config[i][0].width = canvas_width;
- hw->canvas_config[i][0].height = canvas_height;
- hw->canvas_config[i][0].block_mode = hw->canvas_mode;
- hw->canvas_config[i][0].endian =
- (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- config_cav_lut(canvas_y(canvas), &hw->canvas_config[i][0], VDEC_1);
-
- hw->canvas_config[i][1].phy_addr = decbuf_uv_start;
- hw->canvas_config[i][1].width = canvas_width;
- hw->canvas_config[i][1].height = canvas_height / 2;
- hw->canvas_config[i][1].block_mode = hw->canvas_mode;
- hw->canvas_config[i][1].endian =
- (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- config_cav_lut(canvas_u(canvas), &hw->canvas_config[i][1], VDEC_1);
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "[%d] %s(), canvas: 0x%x mode: %d y: %x uv: %x w: %d h: %d\n",
- ctx->id, __func__, canvas, hw->canvas_mode,
- decbuf_start, decbuf_uv_start,
- canvas_width, canvas_height);
-
- return 0;
-}
-
-static int find_free_buffer(struct vdec_mpeg12_hw_s *hw)
-{
- int i;
-
- for (i = 0; i < hw->buf_num; i++) {
- if ((hw->vfbuf_use[i] == 0) &&
- (hw->ref_use[i] == 0))
- break;
- }
-
- if ((i == hw->buf_num) &&
- (hw->buf_num != 0)) {
- return -1;
- }
-
- if (vmpeg12_v4l_alloc_buff_config_canvas(hw, i))
- return -1;
-
- return i;
-}
-
-static u32 spec_to_index(struct vdec_mpeg12_hw_s *hw, u32 spec)
-{
- u32 i;
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->canvas_spec[i] == spec)
- return i;
- }
-
- return hw->buf_num;
-}
-
-/* +[SE][BUG-145343][huanghang] fixed:mpeg2 frame qos info notify */
-static void fill_frame_info(struct vdec_mpeg12_hw_s *hw, u32 slice_type,
- int frame_size, u32 pts)
-{
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
- struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
-
- vframe_qos->type = ((slice_type & PICINFO_TYPE_MASK) ==
- PICINFO_TYPE_I) ? 1 :
- ((slice_type &
- PICINFO_TYPE_MASK) ==
- PICINFO_TYPE_P) ? 2 : 3;
- vframe_qos->size = frame_size;
- vframe_qos->pts = pts;
-
- get_random_bytes(&data, sizeof(unsigned long));
- if (vframe_qos->type == 1)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- vframe_qos->max_mv = a[2];
- vframe_qos->avg_mv = a[1];
- vframe_qos->min_mv = a[0];
-
- get_random_bytes(&data, sizeof(unsigned long));
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- vframe_qos->max_qp = a[2];
- vframe_qos->avg_qp = a[1];
- vframe_qos->min_qp = a[0];
-
- get_random_bytes(&data, sizeof(unsigned long));
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i + 1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- vframe_qos->max_skip = a[2];
- vframe_qos->avg_skip = a[1];
- vframe_qos->min_skip = a[0];
-
- vframe_qos->num++;
-
- return;
-}
-
-static void set_frame_info(struct vdec_mpeg12_hw_s *hw, struct vframe_s *vf)
-{
- u32 ar_bits;
- u32 endian_tmp;
- u32 buffer_index = vf->index;
-
- vf->width = hw->pics[buffer_index].width;
- vf->height = hw->pics[buffer_index].height;
-
- if (hw->frame_dur > 0)
- vf->duration = hw->frame_dur;
- else {
- vf->duration = hw->frame_dur =
- frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf];
- vdec_schedule_work(&hw->notify_work);
- }
-
- vf->signal_type = hw->reg_signal_type;
-
- if (hw->is_used_v4l) {
- struct aml_vdec_hdr_infos hdr;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.signal_type = hw->reg_signal_type;
- vdec_v4l_set_hdr_infos(ctx, &hdr);
- }
-
- ar_bits = READ_VREG(MREG_SEQ_INFO) & 0xf;
-
- if (ar_bits == 0x2)
- vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT;
-
- else if (ar_bits == 0x3)
- vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT;
-
- else if (ar_bits == 0x4)
- vf->ratio_control = 0x74 << DISP_RATIO_ASPECT_RATIO_BIT;
- else
- vf->ratio_control = 0;
-
- hw->ratio_control = vf->ratio_control;
-
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
-
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- } else {
- endian_tmp = (hw->canvas_mode == CANVAS_BLKMODE_LINEAR) ? 0 : 7;
- }
-
- vf->canvas0_config[0].endian = endian_tmp;
- vf->canvas0_config[1].endian = endian_tmp;
- vf->canvas1_config[0].endian = endian_tmp;
- vf->canvas1_config[1].endian = endian_tmp;
-
- vf->sidebind_type = hw->sidebind_type;
- vf->sidebind_channel_id = hw->sidebind_channel_id;
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_PARA_DATA,
- "mpeg2dec: w(%d), h(%d), dur(%d), dur-ES(%d)\n",
- hw->frame_width, hw->frame_height, hw->frame_dur,
- frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf]);
-}
-
-static bool error_skip(struct vdec_mpeg12_hw_s *hw,
- u32 info, struct vframe_s *vf)
-{
- if (hw->error_frame_skip_level) {
- /* skip error frame */
- if ((info & PICINFO_ERROR) || (hw->frame_force_skip_flag)) {
- if ((info & PICINFO_ERROR) == 0) {
- if ((info & PICINFO_TYPE_MASK) ==
- PICINFO_TYPE_I)
- hw->frame_force_skip_flag = 0;
- } else {
- if (hw->error_frame_skip_level >= 2)
- hw->frame_force_skip_flag = 1;
- }
- if ((info & PICINFO_ERROR)
- || (hw->frame_force_skip_flag))
- return true;
- }
- }
- return false;
-}
-
-static inline void vmpeg12_save_hw_context(struct vdec_mpeg12_hw_s *hw, u32 reg)
-{
- if (reg == 3) {
- hw->ctx_valid = 0;
- //pr_info("%s, hw->userdata_wp_ctx %d\n", __func__, hw->userdata_wp_ctx);
- } else {
- hw->seqinfo = READ_VREG(MREG_SEQ_INFO);
- hw->reg_pic_width = READ_VREG(MREG_PIC_WIDTH);
- hw->reg_pic_height = READ_VREG(MREG_PIC_HEIGHT);
- hw->reg_mpeg1_2_reg = READ_VREG(MPEG1_2_REG);
- hw->reg_pic_head_info = READ_VREG(PIC_HEAD_INFO);
- hw->reg_f_code_reg = READ_VREG(F_CODE_REG);
- hw->reg_slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE);
- hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
- hw->reg_mb_info = READ_VREG(MB_INFO);
- hw->reg_signal_type = READ_VREG(AV_SCRATCH_H);
- debug_print(DECODE_ID(hw), PRINT_FLAG_PARA_DATA,
- "signal_type = %x", hw->reg_signal_type);
- hw->ctx_valid = 1;
- }
-}
-
-static void vmmpeg2_reset_udr_mgr(struct vdec_mpeg12_hw_s *hw)
-{
- hw->wait_for_udr_send = 0;
- hw->cur_ud_idx = 0;
- memset(&hw->ud_record, 0, sizeof(hw->ud_record));
-}
-
-static void vmmpeg2_crate_userdata_manager(
- struct vdec_mpeg12_hw_s *hw,
- u8 *userdata_buf,
- int buf_len)
-{
- if (hw) {
- mutex_init(&hw->userdata_mutex);
-
- memset(&hw->userdata_info, 0,
- sizeof(struct mmpeg2_userdata_info_t));
- hw->userdata_info.data_buf = userdata_buf;
- hw->userdata_info.buf_len = buf_len;
- hw->userdata_info.data_buf_end = userdata_buf + buf_len;
- hw->userdata_wp_ctx = 0;
-
- vmmpeg2_reset_udr_mgr(hw);
- }
-}
-
-static void vmmpeg2_destroy_userdata_manager(struct vdec_mpeg12_hw_s *hw)
-{
- if (hw)
- memset(&hw->userdata_info,
- 0,
- sizeof(struct mmpeg2_userdata_info_t));
-}
-
-static void aml_swap_data(uint8_t *user_data, int ud_size)
-{
- int swap_blocks, i, j, k, m;
- unsigned char c_temp;
-
- /* swap byte order */
- swap_blocks = ud_size / 8;
- for (i = 0; i < swap_blocks; i++) {
- j = i * 8;
- k = j + 7;
- for (m = 0; m < 4; m++) {
- c_temp = user_data[j];
- user_data[j++] = user_data[k];
- user_data[k--] = c_temp;
- }
- }
-}
-
-#ifdef DUMP_USER_DATA
-static void push_to_buf(struct vdec_mpeg12_hw_s *hw,
- u8 *pdata,
- int len,
- struct userdata_meta_info_t *pmeta,
- u32 reference)
-{
- u32 *pLen;
- int info_cnt;
- u8 *pbuf_end;
-
- if (!hw->user_data_dump_buf)
- return;
-
- if (hw->bskip) {
- pr_info("over size, skip\n");
- return;
- }
- info_cnt = 0;
- pLen = (u32 *)hw->pdump_buf_cur_start;
-
- *pLen = len;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->duration;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->flags;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->vpts;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = pmeta->vpts_valid;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
-
- *pLen = hw->n_userdata_id;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- *pLen = reference;
- hw->pdump_buf_cur_start += sizeof(u32);
- info_cnt++;
- pLen++;
-
- pbuf_end = hw->userdata_info.data_buf_end;
- if (pdata + len > pbuf_end) {
- int first_section_len;
-
- first_section_len = pbuf_end - pdata;
- memcpy(hw->pdump_buf_cur_start, pdata, first_section_len);
- pdata = (u8 *)hw->userdata_info.data_buf;
- hw->pdump_buf_cur_start += first_section_len;
- memcpy(hw->pdump_buf_cur_start, pdata, len - first_section_len);
- hw->pdump_buf_cur_start += len - first_section_len;
- } else {
- memcpy(hw->pdump_buf_cur_start, pdata, len);
- hw->pdump_buf_cur_start += len;
- }
-
- hw->total_len += len + info_cnt * sizeof(u32);
- if (hw->total_len >= MAX_USER_DATA_SIZE-4096)
- hw->bskip = 1;
-}
-
-static void dump_userdata_info(struct vdec_mpeg12_hw_s *hw,
- void *puser_data,
- int len,
- struct userdata_meta_info_t *pmeta,
- u32 reference)
-{
- u8 *pstart;
-
- pstart = (u8 *)puser_data;
-
-#ifdef DUMP_HEAD_INFO_DATA
- push_to_buf(hw, pstart, len, pmeta, reference);
-#else
- push_to_buf(hw, pstart+8, len - 8, pmeta, reference);
-#endif
-}
-
-
-static void print_data(unsigned char *pdata,
- int len,
- unsigned int flag,
- unsigned int duration,
- unsigned int vpts,
- unsigned int vpts_valid,
- int rec_id,
- u32 reference)
-{
- int nLeft;
-
- nLeft = len;
-
- pr_info("%d len:%d, flag:0x%x, dur:%d, vpts:0x%x, valid:%d, refer:%d\n",
- rec_id, len, flag,
- duration, vpts, vpts_valid,
- reference);
- while (nLeft >= 16) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7],
- pdata[8], pdata[9], pdata[10], pdata[11],
- pdata[12], pdata[13], pdata[14], pdata[15]);
- nLeft -= 16;
- pdata += 16;
- }
-
-
- while (nLeft > 0) {
- pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n",
- pdata[0], pdata[1], pdata[2], pdata[3],
- pdata[4], pdata[5], pdata[6], pdata[7]);
- nLeft -= 8;
- pdata += 8;
- }
-}
-
-static void dump_data(u8 *pdata,
- unsigned int user_data_length,
- unsigned int flag,
- unsigned int duration,
- unsigned int vpts,
- unsigned int vpts_valid,
- int rec_id,
- u32 reference)
-{
- unsigned char szBuf[256];
-
-
- memset(szBuf, 0, 256);
- memcpy(szBuf, pdata, user_data_length);
-
- aml_swap_data(szBuf, user_data_length);
-
- print_data(szBuf,
- user_data_length,
- flag,
- duration,
- vpts,
- vpts_valid,
- rec_id,
- reference);
-}
-
-
-static void show_user_data_buf(struct vdec_mpeg12_hw_s *hw)
-{
- u8 *pbuf;
- int len;
- unsigned int flag;
- unsigned int duration;
- unsigned int vpts;
- unsigned int vpts_valid;
- int rec_id;
- u32 reference;
-
- pr_info("show user data buf\n");
- pbuf = hw->user_data_dump_buf;
-
- while (pbuf < hw->pdump_buf_cur_start) {
- u32 *pLen;
-
- pLen = (u32 *)pbuf;
-
- len = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- duration = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- flag = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- vpts = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- vpts_valid = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- rec_id = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
- reference = *pLen;
- pLen++;
- pbuf += sizeof(u32);
-
-
- dump_data(pbuf, len, flag, duration,
- vpts, vpts_valid, rec_id, reference);
- pbuf += len;
- msleep(30);
- }
-}
-
-static int amvdec_mmpeg12_init_userdata_dump(struct vdec_mpeg12_hw_s *hw)
-{
- hw->user_data_dump_buf = kmalloc(MAX_USER_DATA_SIZE, GFP_KERNEL);
- if (hw->user_data_dump_buf)
- return 1;
- else
- return 0;
-}
-
-static void amvdec_mmpeg12_uninit_userdata_dump(struct vdec_mpeg12_hw_s *hw)
-{
- if (hw->user_data_dump_buf) {
- show_user_data_buf(hw);
- kfree(hw->user_data_dump_buf);
- hw->user_data_dump_buf = NULL;
- }
-}
-
-static void reset_user_data_buf(struct vdec_mpeg12_hw_s *hw)
-{
- hw->total_len = 0;
- hw->pdump_buf_cur_start = hw->user_data_dump_buf;
- hw->bskip = 0;
- hw->n_userdata_id = 0;
-}
-#endif
-
-static void user_data_ready_notify(struct vdec_mpeg12_hw_s *hw,
- u32 pts, u32 pts_valid)
-{
- struct mmpeg2_userdata_record_t *p_userdata_rec;
- int i;
-
- if (hw->wait_for_udr_send) {
- for (i = 0; i < hw->cur_ud_idx; i++) {
- mutex_lock(&hw->userdata_mutex);
-
-
- p_userdata_rec = hw->userdata_info.records
- + hw->userdata_info.write_index;
-
- hw->ud_record[i].meta_info.vpts_valid = pts_valid;
- hw->ud_record[i].meta_info.vpts = pts;
-
- *p_userdata_rec = hw->ud_record[i];
-#ifdef DUMP_USER_DATA
- dump_userdata_info(hw,
- hw->userdata_info.data_buf + p_userdata_rec->rec_start,
- p_userdata_rec->rec_len,
- &p_userdata_rec->meta_info,
- hw->reference[i]);
- hw->n_userdata_id++;
-#endif
-/*
- pr_info("notify: rec_start:%d, rec_len:%d, wi:%d, reference:%d\n",
- p_userdata_rec->rec_start,
- p_userdata_rec->rec_len,
- hw->userdata_info.write_index,
- hw->reference[i]);
-*/
- hw->userdata_info.write_index++;
- if (hw->userdata_info.write_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.write_index = 0;
-
- mutex_unlock(&hw->userdata_mutex);
-
-
- vdec_wakeup_userdata_poll(hw_to_vdec(hw));
- }
- hw->wait_for_udr_send = 0;
- hw->cur_ud_idx = 0;
- }
- hw->notify_ucode_cc_last_wp = hw->ucode_cc_last_wp;
- hw->notify_data_cc_last_wp = hw->userdata_info.last_wp;
-}
-
-static int vmmpeg2_user_data_read(struct vdec_s *vdec,
- struct userdata_param_t *puserdata_para)
-{
- struct vdec_mpeg12_hw_s *hw = NULL;
- int rec_ri, rec_wi;
- int rec_len;
- u8 *rec_data_start;
- u8 *pdest_buf;
- struct mmpeg2_userdata_record_t *p_userdata_rec;
- u32 data_size;
- u32 res;
- int copy_ok = 1;
-
- hw = (struct vdec_mpeg12_hw_s *)vdec->private;
-
- pdest_buf = puserdata_para->pbuf_addr;
-
- mutex_lock(&hw->userdata_mutex);
-
-/*
- pr_info("ri = %d, wi = %d\n",
- hw->userdata_info.read_index,
- hw->userdata_info.write_index);
-*/
- rec_ri = hw->userdata_info.read_index;
- rec_wi = hw->userdata_info.write_index;
-
- if (rec_ri == rec_wi) {
- mutex_unlock(&hw->userdata_mutex);
- return 0;
- }
-
- p_userdata_rec = hw->userdata_info.records + rec_ri;
-
- rec_len = p_userdata_rec->rec_len;
- rec_data_start = p_userdata_rec->rec_start + hw->userdata_info.data_buf;
-/*
- pr_info("ri:%d, wi:%d, rec_len:%d, rec_start:%d, buf_len:%d\n",
- rec_ri, rec_wi,
- p_userdata_rec->rec_len,
- p_userdata_rec->rec_start,
- puserdata_para->buf_len);
-*/
- if (rec_len <= puserdata_para->buf_len) {
- /* dvb user data buffer is enought to
- copy the whole recored. */
- data_size = rec_len;
- if (rec_data_start + data_size
- > hw->userdata_info.data_buf_end) {
- int first_section_len;
-
- first_section_len = hw->userdata_info.buf_len -
- p_userdata_rec->rec_start;
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- first_section_len);
- if (res) {
- pr_info("p1 read not end res=%d, request=%d\n",
- res, first_section_len);
- copy_ok = 0;
-
- p_userdata_rec->rec_len -=
- first_section_len - res;
- p_userdata_rec->rec_start +=
- first_section_len - res;
- puserdata_para->data_size =
- first_section_len - res;
- } else {
- res = (u32)copy_to_user(
- (void *)(pdest_buf+first_section_len),
- (void *)hw->userdata_info.data_buf,
- data_size - first_section_len);
- if (res) {
- pr_info("p2 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
- p_userdata_rec->rec_len -=
- data_size - res;
- p_userdata_rec->rec_start =
- data_size - first_section_len - res;
- puserdata_para->data_size =
- data_size - res;
- }
- } else {
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- data_size);
- if (res) {
- pr_info("p3 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
- p_userdata_rec->rec_len -= data_size - res;
- p_userdata_rec->rec_start += data_size - res;
- puserdata_para->data_size = data_size - res;
- }
-
- if (copy_ok) {
- hw->userdata_info.read_index++;
- if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.read_index = 0;
- }
- } else {
- /* dvb user data buffer is not enought
- to copy the whole recored. */
- data_size = puserdata_para->buf_len;
- if (rec_data_start + data_size
- > hw->userdata_info.data_buf_end) {
- int first_section_len;
-
- first_section_len = hw->userdata_info.buf_len -
- p_userdata_rec->rec_start;
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- first_section_len);
- if (res) {
- pr_info("p4 read not end res=%d, request=%d\n",
- res, first_section_len);
- copy_ok = 0;
- p_userdata_rec->rec_len -=
- first_section_len - res;
- p_userdata_rec->rec_start +=
- first_section_len - res;
- puserdata_para->data_size =
- first_section_len - res;
- } else {
- /* first secton copy is ok*/
- res = (u32)copy_to_user(
- (void *)(pdest_buf+first_section_len),
- (void *)hw->userdata_info.data_buf,
- data_size - first_section_len);
- if (res) {
- pr_info("p5 read not end res=%d, request=%d\n",
- res,
- data_size - first_section_len);
- copy_ok = 0;
- }
-
- p_userdata_rec->rec_len -=
- data_size - res;
- p_userdata_rec->rec_start =
- data_size - first_section_len - res;
- puserdata_para->data_size =
- data_size - res;
- }
- } else {
- res = (u32)copy_to_user((void *)pdest_buf,
- (void *)rec_data_start,
- data_size);
- if (res) {
- pr_info("p6 read not end res=%d, request=%d\n",
- res, data_size);
- copy_ok = 0;
- }
-
- p_userdata_rec->rec_len -= data_size - res;
- p_userdata_rec->rec_start += data_size - res;
- puserdata_para->data_size = data_size - res;
- }
-
- if (copy_ok) {
- hw->userdata_info.read_index++;
- if (hw->userdata_info.read_index >= USERDATA_FIFO_NUM)
- hw->userdata_info.read_index = 0;
- }
-
- }
- puserdata_para->meta_info = p_userdata_rec->meta_info;
-
- if (hw->userdata_info.read_index <= hw->userdata_info.write_index)
- puserdata_para->meta_info.records_in_que =
- hw->userdata_info.write_index -
- hw->userdata_info.read_index;
- else
- puserdata_para->meta_info.records_in_que =
- hw->userdata_info.write_index +
- USERDATA_FIFO_NUM -
- hw->userdata_info.read_index;
-
- puserdata_para->version = (0<<24|0<<16|0<<8|1);
-
- mutex_unlock(&hw->userdata_mutex);
-
-
- return 1;
-}
-
-static void vmmpeg2_reset_userdata_fifo(struct vdec_s *vdec, int bInit)
-{
- struct vdec_mpeg12_hw_s *hw = NULL;
-
- hw = (struct vdec_mpeg12_hw_s *)vdec->private;
-
- if (hw) {
- mutex_lock(&hw->userdata_mutex);
- pr_info("mpeg2_reset_userdata_fifo: bInit: %d, ri: %d, wi: %d\n",
- bInit,
- hw->userdata_info.read_index,
- hw->userdata_info.write_index);
- hw->userdata_info.read_index = 0;
- hw->userdata_info.write_index = 0;
-
- if (bInit)
- hw->userdata_info.last_wp = 0;
- mutex_unlock(&hw->userdata_mutex);
- }
-}
-
-static void vmmpeg2_wakeup_userdata_poll(struct vdec_s *vdec)
-{
- amstream_wakeup_userdata_poll(vdec);
-}
-
-/*
-#define PRINT_HEAD_INFO
-*/
-static void userdata_push_do_work(struct work_struct *work)
-{
- u32 reg;
- u8 *pdata;
- u8 *psrc_data;
- u8 head_info[8];
- struct userdata_meta_info_t meta_info;
- u32 wp;
- u32 index;
- u32 picture_struct;
- u32 reference;
- u32 picture_type;
- u32 temp;
- u32 data_length;
- u32 data_start;
- int i;
- u32 offset;
- u32 cur_wp;
-#ifdef PRINT_HEAD_INFO
- u8 *ptype_str;
-#endif
- struct mmpeg2_userdata_record_t *pcur_ud_rec;
-
- struct vdec_mpeg12_hw_s *hw = container_of(work,
- struct vdec_mpeg12_hw_s, userdata_push_work);
-
- memset(&meta_info, 0, sizeof(meta_info));
-
- meta_info.duration = hw->frame_dur;
-
-
- reg = READ_VREG(AV_SCRATCH_J);
- hw->userdata_wp_ctx = reg & (~(1<<16));
- meta_info.flags = ((reg >> 30) << 1);
- meta_info.flags |= (VFORMAT_MPEG12 << 3);
- /* check top_field_first flag */
- if ((reg >> 28) & 0x1) {
- meta_info.flags |= (1 << 10);
- meta_info.flags |= (((reg >> 29) & 0x1) << 11);
- }
-
- cur_wp = reg & 0x7fff;
- if (cur_wp == hw->ucode_cc_last_wp || (cur_wp >= AUX_BUF_ALIGN(CCBUF_SIZE))) {
- debug_print(DECODE_ID(hw), 0,
- "Null or Over size user data package: wp = %d\n", cur_wp);
- WRITE_VREG(AV_SCRATCH_J, 0);
- return;
- }
-
- if (hw->cur_ud_idx >= MAX_UD_RECORDS) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "UD Records over: %d, skip it\n", MAX_UD_RECORDS);
- WRITE_VREG(AV_SCRATCH_J, 0);
- hw->cur_ud_idx = 0;
- return;
- }
-
- if (cur_wp < hw->ucode_cc_last_wp)
- hw->ucode_cc_last_wp = 0;
-
- offset = READ_VREG(AV_SCRATCH_I);
-
- codec_mm_dma_flush(
- hw->ccbuf_phyAddress_virt,
- CCBUF_SIZE,
- DMA_FROM_DEVICE);
-
- mutex_lock(&hw->userdata_mutex);
- if (hw->ccbuf_phyAddress_virt) {
- pdata = (u8 *)hw->ccbuf_phyAddress_virt + hw->ucode_cc_last_wp;
- memcpy(head_info, pdata, 8);
- } else
- memset(head_info, 0, 8);
- mutex_unlock(&hw->userdata_mutex);
- aml_swap_data(head_info, 8);
-
- wp = (head_info[0] << 8 | head_info[1]);
- index = (head_info[2] << 8 | head_info[3]);
-
- picture_struct = (head_info[6] << 8 | head_info[7]);
- temp = (head_info[4] << 8 | head_info[5]);
- reference = temp & 0x3FF;
- picture_type = (temp >> 10) & 0x7;
-
- if (debug_enable & PRINT_FLAG_USERDATA_DETAIL)
- pr_info("index:%d, wp:%d, ref:%d, type:%d, struct:0x%x, u_last_wp:0x%x\n",
- index, wp, reference,
- picture_type, picture_struct,
- hw->ucode_cc_last_wp);
-
- switch (picture_type) {
- case 1:
- /* pr_info("I type, pos:%d\n",
- (meta_info.flags>>1)&0x3); */
- meta_info.flags |= (1<<7);
-#ifdef PRINT_HEAD_INFO
- ptype_str = " I";
-#endif
- break;
- case 2:
- /* pr_info("P type, pos:%d\n",
- (meta_info.flags>>1)&0x3); */
- meta_info.flags |= (2<<7);
-#ifdef PRINT_HEAD_INFO
- ptype_str = " P";
-#endif
- break;
- case 3:
- /* pr_info("B type, pos:%d\n",
- (meta_info.flags>>1)&0x3); */
- meta_info.flags |= (3<<7);
-#ifdef PRINT_HEAD_INFO
- ptype_str = " B";
-#endif
- break;
- case 4:
- /* pr_info("D type, pos:%d\n",
- (meta_info.flags>>1)&0x3); */
- meta_info.flags |= (4<<7);
-#ifdef PRINT_HEAD_INFO
- ptype_str = " D";
-#endif
- break;
- default:
- /* pr_info("Unknown type:0x%x, pos:%d\n",
- pheader->picture_coding_type,
- (meta_info.flags>>1)&0x3); */
-#ifdef PRINT_HEAD_INFO
- ptype_str = " U";
-#endif
- break;
- }
-#ifdef PRINT_HEAD_INFO
- pr_info("ref:%d, type:%s, ext:%d, first:%d, data_length:%d\n",
- reference, ptype_str,
- (reg >> 30),
- (reg >> 28)&0x3,
- reg & 0xffff);
-#endif
- data_length = cur_wp - hw->ucode_cc_last_wp;
- data_start = reg & 0xffff;
- psrc_data = (u8 *)hw->ccbuf_phyAddress_virt + hw->ucode_cc_last_wp;
-
- pdata = hw->userdata_info.data_buf + hw->userdata_info.last_wp;
- for (i = 0; i < data_length && hw->ccbuf_phyAddress_virt != NULL && psrc_data; i++) {
- *pdata++ = *psrc_data++;
- if (pdata >= hw->userdata_info.data_buf_end)
- pdata = hw->userdata_info.data_buf;
- }
-
- pcur_ud_rec = hw->ud_record + hw->cur_ud_idx;
-
- pcur_ud_rec->meta_info = meta_info;
- pcur_ud_rec->rec_start = hw->userdata_info.last_wp;
- pcur_ud_rec->rec_len = data_length;
-
- hw->userdata_info.last_wp += data_length;
- if (hw->userdata_info.last_wp >= USER_DATA_SIZE)
- hw->userdata_info.last_wp %= USER_DATA_SIZE;
-
- hw->wait_for_udr_send = 1;
-
- hw->ucode_cc_last_wp = cur_wp;
-
- if (debug_enable & PRINT_FLAG_USERDATA_DETAIL)
- pr_info("cur_wp:%d, rec_start:%d, rec_len:%d\n",
- cur_wp,
- pcur_ud_rec->rec_start,
- pcur_ud_rec->rec_len);
-
-#ifdef DUMP_USER_DATA
- hw->reference[hw->cur_ud_idx] = reference;
-#endif
-
- hw->cur_ud_idx++;
- WRITE_VREG(AV_SCRATCH_J, 0);
-}
-
-
-void userdata_pushed_drop(struct vdec_mpeg12_hw_s *hw)
-{
- hw->userdata_info.last_wp = hw->notify_data_cc_last_wp;
- hw->ucode_cc_last_wp = hw->notify_ucode_cc_last_wp;
- hw->cur_ud_idx = 0;
- hw->wait_for_udr_send = 0;
-
-}
-
-
-static inline void hw_update_gvs(struct vdec_mpeg12_hw_s *hw)
-{
- if (hw->gvs.frame_height != hw->frame_height) {
- hw->gvs.frame_width = hw->frame_width;
- hw->gvs.frame_height = hw->frame_height;
- }
- if (hw->gvs.frame_dur != hw->frame_dur) {
- hw->gvs.frame_dur = hw->frame_dur;
- if (hw->frame_dur != 0)
- hw->gvs.frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- hw->gvs.frame_rate = -1;
- }
- if (hw->gvs.ratio_control != hw->ratio_control)
- hw->gvs.ratio_control = hw->ratio_control;
-
- hw->gvs.status = hw->stat;
- hw->gvs.error_count = hw->gvs.error_frame_count;
- hw->gvs.drop_frame_count = hw->drop_frame_count;
-
-}
-
-static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw,
- struct pic_info_t *pic)
-{
- u32 field_num = 0, i;
- u32 first_field_type = 0, type = 0;
- struct vframe_s *vf = NULL;
- u32 index = pic->index;
- u32 info = pic->buffer_info;
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- ulong nv_order = VIDTYPE_VIU_NV21;
- bool pb_skip = false;
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
-#ifdef NV21
- type = nv_order;
-#endif
- if (hw->i_only) {
- pb_skip = 1;
- }
-
- user_data_ready_notify(hw, pic->pts, pic->pts_valid);
-
- if (hw->frame_prog & PICINFO_PROG) {
- field_num = 1;
- type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | nv_order;
- } else {
-#ifdef INTERLACE_SEQ_ALWAYS
- /* once an interlace seq, force interlace, to make di easy. */
- hw->dec_control |= DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE;
-#endif
- hw->frame_rpt_state = FRAME_REPEAT_NONE;
-
- first_field_type = (info & PICINFO_TOP_FIRST) ?
- VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
- field_num = (info & PICINFO_RPT_FIRST) ? 3 : 2;
- }
-
- if ((hw->is_used_v4l) &&
- ((vdec->prog_only) || (hw->report_field & V4L2_FIELD_NONE) ||
- (!v4l2_ctx->vpp_is_need))) {
- field_num = 1;
- type |= VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | nv_order;
- }
-
- for (i = 0; i < field_num; i++) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "fatal error, no available buffer slot.");
- hw->dec_result = DEC_RESULT_ERROR;
- vdec_schedule_work(&hw->work);
- return -1;
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->pics[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l mem handle: 0x%lx\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
- __func__, vf->v4l_mem_handle);
- }
-
- hw->vfbuf_use[index]++;
- vf->index = index;
- set_frame_info(hw, vf);
- if (field_num > 1) {
- vf->duration = vf->duration / field_num;
- vf->duration_pulldown = (field_num == 3) ?
- (vf->duration >> 1):0;
- type = nv_order;
- if (i == 1) /* second field*/
- type |= (first_field_type == VIDTYPE_INTERLACE_TOP) ?
- VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP;
- else
- type |= (first_field_type == VIDTYPE_INTERLACE_TOP) ?
- VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
- } else {
- if ((hw->seqinfo & SEQINFO_EXT_AVAILABLE) &&
- (hw->seqinfo & SEQINFO_PROG)) {
- if (info & PICINFO_RPT_FIRST) {
- if (info & PICINFO_TOP_FIRST)
- vf->duration *= 3;
- else
- vf->duration *= 2;
- }
- vf->duration_pulldown = 0;
- } else {
- vf->duration_pulldown =
- (info & PICINFO_RPT_FIRST) ?
- vf->duration >> 1 : 0;
- }
- }
- vf->duration += vf->duration_pulldown;
- vf->type = type;
- vf->orientation = 0;
- if (i > 0) {
- vf->pts = 0;
- vf->pts_us64 = 0;
- vf->timestamp = pic->timestamp;
- if (v4l2_ctx->second_field_pts_mode) {
- vf->timestamp = 0;
- }
- } else {
- vf->pts = (pic->pts_valid) ? pic->pts : 0;
- vf->pts_us64 = (pic->pts_valid) ? pic->pts64 : 0;
- if (field_num == 1)
- vf->timestamp = pic->timestamp;
- else
- vf->timestamp = pic->last_timestamp;
- }
- vf->type_original = vf->type;
-
- if ((error_skip(hw, pic->buffer_info, vf)) ||
- (((hw->first_i_frame_ready == 0) || pb_skip) &&
- ((PICINFO_TYPE_MASK & pic->buffer_info) !=
- PICINFO_TYPE_I))) {
- unsigned long flags;
- hw->drop_frame_count++;
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_lost_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_lost_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_lost_frames++;
- }
- /* Though we drop it, it is still an error frame, count it.
- * Becase we've counted the error frame in vdec_count_info
- * function, avoid count it twice.
- */
- if (!(info & PICINFO_ERROR)) {
- hw->gvs.error_frame_count++;
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_concealed_frames++;
- }
- }
- hw->vfbuf_use[index]--;
- spin_lock_irqsave(&hw->lock, flags);
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- spin_unlock_irqrestore(&hw->lock, flags);
- } else {
- debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "%s, vf: %lx, num[%d]: %d(%c), dur: %d, type: %x, pts: %d(%lld), ts(%lld)\n",
- __func__, (ulong)vf, i, hw->disp_num, GET_SLICE_TYPE(info),
- vf->duration, vf->type, vf->pts, vf->pts_us64, vf->timestamp);
- atomic_add(1, &hw->disp_num);
- if (i == 0) {
- decoder_do_frame_check(vdec, vf);
- hw_update_gvs(hw);
- vdec_fill_vdec_frame(vdec, &hw->vframe_qos,
- &hw->gvs, vf, pic->hw_decode_time);
- }
- vdec->vdec_fps_detec(vdec->id);
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle, index);
- if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
- /* offset for tsplayer pts lookup */
- if (i == 0) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) &
- 0xffffffff00000000) | pic->offset;
- vf->pts = 0;
- } else {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- }
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- /* if (hw->disp_num == 1) { */
- if (hw->kpi_first_i_decoded == 0) {
- hw->kpi_first_i_decoded = 1;
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "[vdec_kpi][%s] First I frame decoded.\n",
- __func__);
- }
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- set_meta_data_to_vf(vf, UVM_META_DATA_VF_BASE_INFOS, hw->v4l2_ctx);
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY,
- NULL);
- }
- } else
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
-
-
- }
- }
- return 0;
-}
-
-static void force_interlace_check(struct vdec_mpeg12_hw_s *hw)
-{
- if ((hw->dec_control &
- DEC_CONTROL_FLAG_FORCE_2500_720_576_INTERLACE) &&
- (hw->frame_width == 720) &&
- (hw->frame_height == 576) &&
- (hw->frame_dur == 3840)) {
- hw->frame_prog = 0;
- } else if ((hw->dec_control
- & DEC_CONTROL_FLAG_FORCE_3000_704_480_INTERLACE) &&
- (hw->frame_width == 704) &&
- (hw->frame_height == 480) &&
- (hw->frame_dur == 3200)) {
- hw->frame_prog = 0;
- } else if ((hw->dec_control
- & DEC_CONTROL_FLAG_FORCE_2500_704_576_INTERLACE) &&
- (hw->frame_width == 704) &&
- (hw->frame_height == 576) &&
- (hw->frame_dur == 3840)) {
- hw->frame_prog = 0;
- } else if ((hw->dec_control
- & DEC_CONTROL_FLAG_FORCE_2500_544_576_INTERLACE) &&
- (hw->frame_width == 544) &&
- (hw->frame_height == 576) &&
- (hw->frame_dur == 3840)) {
- hw->frame_prog = 0;
- } else if ((hw->dec_control
- & DEC_CONTROL_FLAG_FORCE_2500_480_576_INTERLACE) &&
- (hw->frame_width == 480) &&
- (hw->frame_height == 576) &&
- (hw->frame_dur == 3840)) {
- hw->frame_prog = 0;
- } else if (hw->dec_control
- & DEC_CONTROL_FLAG_FORCE_SEQ_INTERLACE) {
- hw->frame_prog = 0;
- }
-
-}
-
-static int update_reference(struct vdec_mpeg12_hw_s *hw,
- int index)
-{
- hw->ref_use[index]++;
- if (hw->refs[1] == -1) {
- hw->refs[1] = index;
- /*
- * first pic need output to show
- * usecnt do not decrease.
- */
- } else if (hw->refs[0] == -1) {
- hw->refs[0] = hw->refs[1];
- hw->refs[1] = index;
- /* second pic do not output */
- index = hw->buf_num;
- } else {
- hw->ref_use[hw->refs[0]]--; //old ref0 ununsed
- hw->refs[0] = hw->refs[1];
- hw->refs[1] = index;
- index = hw->refs[0];
- }
- return index;
-}
-
-static bool is_ref_error(struct vdec_mpeg12_hw_s *hw)
-{
- if ((hw->pics[hw->refs[0]].buffer_info & PICINFO_ERROR) ||
- (hw->pics[hw->refs[1]].buffer_info & PICINFO_ERROR))
- return 1;
- return 0;
-}
-
-static int vmpeg2_get_ps_info(struct vdec_mpeg12_hw_s *hw, int width, int height,
- bool frame_prog, struct aml_vdec_ps_infos *ps)
-{
- ps->visible_width = width;
- ps->visible_height = height;
- ps->coded_width = ALIGN(width, 64);
- ps->coded_height = ALIGN(height, 64);
- ps->dpb_size = hw->buf_num;
- ps->dpb_frames = DECODE_BUFFER_NUM_DEF;
- ps->dpb_margin = hw->dynamic_buf_num_margin;
- ps->field = frame_prog ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
- ps->field = hw->force_prog_only ? V4L2_FIELD_NONE : ps->field;
-
- return 0;
-}
-
-static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height, bool frame_prog)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- if (ctx->param_sets_from_ucode &&
- hw->res_ch_flag == 0) {
- struct aml_vdec_ps_infos ps;
-
- if ((hw->frame_width != 0 &&
- hw->frame_height != 0) &&
- (hw->frame_width != width ||
- hw->frame_height != height)) {
- debug_print(DECODE_ID(hw), 0,
- "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d)\n",
- hw->frame_width, hw->frame_height,
- width,
- height);
- vmpeg2_get_ps_info(hw, width, height, frame_prog, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->v4l_params_parsed = false;
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- hw->eos = 1;
- flush_output(hw);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
-
- ret = 1;
- }
- }
-
- return ret;
-}
-
-void cal_chunk_offset_and_size(struct vdec_mpeg12_hw_s *hw)
-{
- u32 consume_byte, res_byte;
-
- res_byte = READ_VREG(VIFF_BIT_CNT) >> 3;
-
- if (hw->chunk->size > res_byte) {
- consume_byte = hw->chunk->size - res_byte;
-
- if (consume_byte > VDEC_FIFO_ALIGN) {
- consume_byte -= VDEC_FIFO_ALIGN;
- res_byte += VDEC_FIFO_ALIGN;
- }
- hw->chunk_header_offset = hw->chunk->offset + consume_byte;
- hw->chunk_res_size = res_byte;
- }
-}
-
-static irqreturn_t vmpeg12_isr_thread_fn(struct vdec_s *vdec, int irq)
-{
- u32 reg, index, info, seqinfo, offset, pts, frame_size=0, tmp_h, tmp_w;
- u64 pts_us64 = 0;
- struct pic_info_t *new_pic, *disp_pic;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)(vdec->private);
-
- if (READ_VREG(AV_SCRATCH_M) != 0 &&
- (debug_enable & PRINT_FLAG_UCODE_DETAIL)) {
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "dbg %x: %x, level %x, wp %x, rp %x, cnt %x\n",
- READ_VREG(AV_SCRATCH_M), READ_VREG(AV_SCRATCH_N),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VIFF_BIT_CNT));
- WRITE_VREG(AV_SCRATCH_M, 0);
- return IRQ_HANDLED;
- }
-
- reg = READ_VREG(AV_SCRATCH_G);
- if (reg == 1) {
- if (hw->kpi_first_i_comming == 0) {
- hw->kpi_first_i_comming = 1;
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "[vdec_kpi][%s] First I frame coming.\n",
- __func__);
- }
- if (hw->is_used_v4l) {
- int frame_width = READ_VREG(MREG_PIC_WIDTH);
- int frame_height = READ_VREG(MREG_PIC_HEIGHT);
- int info = READ_VREG(MREG_SEQ_INFO);
- bool frame_prog = info & 0x10000;
-
- if (!v4l_res_change(hw, frame_width, frame_height, frame_prog)) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
-
- vmpeg2_get_ps_info(hw, frame_width, frame_height, frame_prog, &ps);
- hw->v4l_params_parsed = true;
- hw->report_field = frame_prog ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
- vdec_v4l_set_ps_infos(ctx, &ps);
- cal_chunk_offset_and_size(hw);
- userdata_pushed_drop(hw);
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- } else {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- WRITE_VREG(AV_SCRATCH_G, 0);
-
- hw->res_ch_flag = 0;
- }
- } else {
- userdata_pushed_drop(hw);
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- }
- } else
- WRITE_VREG(AV_SCRATCH_G, 0);
- return IRQ_HANDLED;
- }
-
- reg = READ_VREG(AV_SCRATCH_J);
- if (reg & (1<<16)) {
- vdec_schedule_work(&hw->userdata_push_work);
- return IRQ_HANDLED;
- }
-
- reg = READ_VREG(MREG_BUFFEROUT);
-
- ATRACE_COUNTER("V_ST_DEC-decode_state", reg);
-
- if (reg == MPEG12_DATA_REQUEST) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s: data request, bcnt=%x\n",
- __func__, READ_VREG(VIFF_BIT_CNT));
- if (vdec_frame_based(vdec)) {
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_GET_DATA;
- vdec_schedule_work(&hw->work);
- }
- } else if (reg == MPEG12_DATA_EMPTY) {
- /*timeout when decoding next frame*/
- debug_print(DECODE_ID(hw), PRINT_FLAG_VLD_DETAIL,
- "%s: Insufficient data, lvl=%x ctrl=%x bcnt=%x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_CONTROL),
- READ_VREG(VIFF_BIT_CNT));
-
- if (vdec_frame_based(vdec)) {
- userdata_pushed_drop(hw);
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- } else {
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- userdata_pushed_drop(hw);
- reset_process_time(hw);
- }
- return IRQ_HANDLED;
- } else { /* MPEG12_PIC_DONE, MPEG12_SEQ_END */
- reset_process_time(hw);
-
- info = READ_VREG(MREG_PIC_INFO);
- offset = READ_VREG(MREG_FRAME_OFFSET);
- index = spec_to_index(hw, READ_VREG(REC_CANVAS_ADDR));
- seqinfo = READ_VREG(MREG_SEQ_INFO);
-
- if (((seqinfo >> 8) & 0xff) &&
- ((seqinfo >> 12 & 0x7) != hw->profile_idc ||
- (seqinfo >> 8 & 0xf) != hw->level_idc)) {
- hw->profile_idc = seqinfo >> 12 & 0x7;
- hw->level_idc = seqinfo >> 8 & 0xf;
- vdec_set_profile_level(vdec, hw->profile_idc, hw->level_idc);
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "profile_idc: %d level_idc: %d\n",
- hw->profile_idc, hw->level_idc);
- }
-
- if ((info & PICINFO_PROG) == 0 &&
- (info & FRAME_PICTURE_MASK) != FRAME_PICTURE) {
- hw->first_i_frame_ready = 1; /* for field struct case*/
- }
- if (index >= hw->buf_num) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "mmpeg12: invalid buf index: %d\n", index);
- hw->dec_result = DEC_RESULT_ERROR;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- hw->dec_num++;
- hw->dec_result = DEC_RESULT_DONE;
- new_pic = &hw->pics[index];
- if (vdec->mvfrm) {
- new_pic->frame_size = vdec->mvfrm->frame_size;
- new_pic->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- }
-
- tmp_w = READ_VREG(MREG_PIC_WIDTH);
- tmp_h = READ_VREG(MREG_PIC_HEIGHT);
-
- new_pic->width = tmp_w;
- hw->frame_width = tmp_w;
- new_pic->height = tmp_h;
- hw->frame_height = tmp_h;
-
- new_pic->buffer_info = info;
- new_pic->offset = offset;
- new_pic->index = index;
- if (((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) ||
- ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P)) {
- if (hw->chunk) {
- new_pic->pts_valid = hw->chunk->pts_valid;
- new_pic->pts = hw->chunk->pts;
- new_pic->pts64 = hw->chunk->pts64;
- if (hw->first_field_timestamp_valid)
- new_pic->last_timestamp = hw->first_field_timestamp;
- else
- new_pic->last_timestamp = hw->chunk->timestamp;
- hw->first_field_timestamp_valid = false;
- new_pic->timestamp = hw->chunk->timestamp;
- if (hw->last_chunk_pts == hw->chunk->pts) {
- new_pic->pts_valid = 0;
- debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "pts invalid\n");
- }
- } else {
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset,
- &pts, &frame_size, 0, &pts_us64) == 0) {
- new_pic->pts_valid = true;
- new_pic->pts = pts;
- new_pic->pts64 = pts_us64;
- } else
- new_pic->pts_valid = false;
- }
- }
- } else {
- if (hw->chunk) {
- hw->last_chunk_pts = hw->chunk->pts;
- if (hw->first_field_timestamp_valid)
- new_pic->last_timestamp = hw->first_field_timestamp;
- else
- new_pic->last_timestamp = hw->chunk->timestamp;
- hw->first_field_timestamp_valid = false;
- new_pic->timestamp = hw->chunk->timestamp;
- }
- new_pic->pts_valid = false;
- }
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "mmpeg12: new_pic=%d, ind=%d, info=%x, seq=%x, offset=%d\n",
- hw->dec_num, index, info, seqinfo, offset);
-
- hw->frame_prog = info & PICINFO_PROG;
-#if 1
- if ((seqinfo & SEQINFO_EXT_AVAILABLE) &&
- ((seqinfo & SEQINFO_PROG) == 0))
- hw->frame_prog = 0;
-#endif
- force_interlace_check(hw);
-
- if (is_ref_error(hw)) {
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B)
- new_pic->buffer_info |= PICINFO_ERROR;
- }
-
- if (((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) ||
- ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P)) {
- index = update_reference(hw, index);
- } else {
- /* drop b frame before reference pic ready */
- if (hw->refs[0] == -1)
- index = hw->buf_num;
- }
- vmpeg12_save_hw_context(hw, reg);
-
- if (index >= hw->buf_num) {
- if (hw->dec_num != 2) {
- debug_print(DECODE_ID(hw), 0,
- "mmpeg12: drop pic num %d, type %c, index %d, offset %x\n",
- hw->dec_num, GET_SLICE_TYPE(info), index, offset);
- hw->dec_result = DEC_RESULT_ERROR;
- }
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
-
- disp_pic = &hw->pics[index];
- info = hw->pics[index].buffer_info;
- if (disp_pic->pts_valid && hw->lastpts64 == disp_pic->pts64)
- disp_pic->pts_valid = false;
- if (disp_pic->pts_valid)
- hw->lastpts64 = disp_pic->pts64;
-
- if (input_frame_based(hw_to_vdec(hw)))
- frame_size = new_pic->frame_size;
-
- fill_frame_info(hw, info, frame_size, new_pic->pts);
-
- if ((hw->first_i_frame_ready == 0) &&
- ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) &&
- ((info & PICINFO_ERROR) == 0)) {
- hw->first_i_frame_ready = 1;
- }
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "mmpeg12: disp_pic=%d(%c), ind=%d, offst=%x, pts=(%d,%lld,%lld)(%d)\n",
- hw->disp_num, GET_SLICE_TYPE(info), index, disp_pic->offset,
- disp_pic->pts, disp_pic->pts64,
- disp_pic->timestamp, disp_pic->pts_valid);
-
- prepare_display_buf(hw, disp_pic);
- vdec_schedule_work(&hw->work);
- }
-
- return IRQ_HANDLED;
-}
-static irqreturn_t vmpeg12_isr(struct vdec_s *vdec, int irq)
-{
- u32 info, offset;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)(vdec->private);
- if (hw->eos)
- return IRQ_HANDLED;
- info = READ_VREG(MREG_PIC_INFO);
- offset = READ_VREG(MREG_FRAME_OFFSET);
-
- vdec_count_info(&hw->gvs, info & PICINFO_ERROR, offset);
- if (info &PICINFO_ERROR) {
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_concealed_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_concealed_frames++;
- }
- }
- if (offset) {
- if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
- hw->gvs.i_decoded_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_P) {
- hw->gvs.p_decoded_frames++;
- } else if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_B) {
- hw->gvs.b_decoded_frames++;
- }
- }
-
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- return IRQ_WAKE_THREAD;
-}
-
-static void vmpeg12_notify_work(struct work_struct *work)
-{
- struct vdec_mpeg12_hw_s *hw = container_of(work,
- struct vdec_mpeg12_hw_s, notify_work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (!hw->is_used_v4l && vdec->fr_hint_state == VDEC_NEED_HINT) {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)hw->frame_dur));
- vdec->fr_hint_state = VDEC_HINTED;
- }
-}
-
-static void wait_vmmpeg12_search_done(struct vdec_mpeg12_hw_s *hw)
-{
- u32 vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- int count = 0;
-
- do {
- usleep_range(100, 500);
- if (vld_rp == READ_VREG(VLD_MEM_VIFIFO_RP))
- break;
- if (count > 1000) {
- debug_print(DECODE_ID(hw), 0,
- "%s, count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n",
- __func__, count, vld_rp, READ_VREG(VLD_MEM_VIFIFO_RP));
- break;
- } else
- vld_rp = READ_VREG(VLD_MEM_VIFIFO_RP);
- count++;
- } while (1);
-}
-
-static void flush_output(struct vdec_mpeg12_hw_s *hw)
-{
- int index = hw->refs[1];
-
- /* video only one frame need not flush. */
- if (hw->dec_num < 2)
- return;
-
- if ((hw->refs[0] >= 0) &&
- (hw->refs[0] < hw->buf_num))
- hw->ref_use[hw->refs[0]] = 0;
-
- if (index >= 0 && index < hw->buf_num) {
- hw->ref_use[index] = 0;
- prepare_display_buf(hw, &hw->pics[index]);
- }
-}
-
-static bool is_avaliable_buffer(struct vdec_mpeg12_hw_s *hw);
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] MPEG2 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = find_free_buffer(hw);
- if (INVALID_IDX == index) {
- pr_err("[%d] MPEG2 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->pics[index].v4l_ref_buf_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = (ulong)fb;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- pr_info("[%d] mpeg12 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void vmpeg12_work_implement(struct vdec_mpeg12_hw_s *hw,
- struct vdec_s *vdec, int from)
-{
- int r;
-
- if (hw->dec_result != DEC_RESULT_DONE)
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s, result=%d, status=%d\n", __func__,
- hw->dec_result, vdec->next_status);
-
- ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result);
-
- if (hw->dec_result == DEC_RESULT_DONE) {
- if (vdec->input.swap_valid)
- hw->dec_again_cnt = 0;
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk = NULL;
- hw->chunk_header_offset = 0;
- hw->chunk_res_size = 0;
- } else if (hw->dec_result == DEC_RESULT_AGAIN &&
- (vdec->next_status != VDEC_STATUS_DISCONNECTED)) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
-#ifdef AGAIN_HAS_THRESHOLD
- hw->next_again_flag = 1;
-#endif
- //hw->dec_again_cnt++;
- } else if (hw->dec_result == DEC_RESULT_GET_DATA &&
- vdec->next_status != VDEC_STATUS_DISCONNECTED) {
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- debug_print(DECODE_ID(hw), PRINT_FLAG_VLD_DETAIL,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP));
- if (hw->chunk != NULL) {
- hw->first_field_timestamp = hw->chunk->timestamp;
- hw->first_field_timestamp_valid = true;
- }
-
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk_header_offset = 0;
- hw->chunk_res_size = 0;
- hw->chunk = NULL;
- vdec_clean_input(vdec);
-
- r = vdec_prepare_input(vdec, &hw->chunk);
- if (r < 0) {
- hw->input_empty++;
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_GET_DATA;
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "%s: Insufficient data, get data retry\n", __func__);
- vdec_schedule_work(&hw->work);
- return;
- }
-
- hw->input_empty = 0;
- if (vdec_frame_based(vdec) && (hw->chunk != NULL)) {
- r = hw->chunk->size +
- (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(VIFF_BIT_CNT, r * 8);
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size += hw->chunk->size;
- }
- debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: %x %x %x size %d, bitcnt %d\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- r, READ_VREG(VIFF_BIT_CNT));
- vdec_enable_input(vdec);
- hw->dec_result = DEC_RESULT_NONE;
- hw->last_vld_level = 0;
- start_process_time_set(hw);
- hw->init_flag = 1;
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
- WRITE_VREG(MREG_BUFFEROUT, 0);
- return;
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s: force exit\n", __func__);
- if (hw->stat & STAT_ISR_REG) {
- amvdec_stop();
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- hw->eos = 1;
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk_header_offset = 0;
- hw->chunk_res_size = 0;
- hw->chunk = NULL;
- vdec_clean_input(vdec);
- flush_output(hw);
- if (hw->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(vdec);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
-
- debug_print(DECODE_ID(hw), 0,
- "%s: end of stream, num %d(%d)\n",
- __func__, hw->disp_num, hw->dec_num);
- }
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- /*disable mbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- wait_vmmpeg12_search_done(hw);
-
- if (from == 1) {
- /*This is a timeout work*/
- if (work_pending(&hw->work)) {
- pr_err("timeout work return befor finishing.");
- /*
- * The vmpeg12_work arrives at the last second,
- * give it a chance to handle the scenario.
- */
- return;
- }
- }
-
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1);
- else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hw->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- if (hw->vdec_cb)
- hw->vdec_cb(vdec, hw->vdec_cb_arg);
-}
-
-static void vmpeg12_work(struct work_struct *work)
-{
- struct vdec_mpeg12_hw_s *hw =
- container_of(work, struct vdec_mpeg12_hw_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- vmpeg12_work_implement(hw, vdec, 0);
-}
-static void vmpeg12_timeout_work(struct work_struct *work)
-{
- struct vdec_mpeg12_hw_s *hw =
- container_of(work, struct vdec_mpeg12_hw_s, timeout_work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (work_pending(&hw->work)) {
- pr_err("timeout work return befor executing.");
- return;
- }
-
- hw->timeout_processing = 1;
- vmpeg12_work_implement(hw, vdec, 1);
-}
-
-static struct vframe_s *vmpeg_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- atomic_add(1, &hw->peek_num);
- if (kfifo_peek(&hw->display_q, &vf))
- return vf;
-
- return NULL;
-}
-
-static struct vframe_s *vmpeg_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
-
- if (kfifo_get(&hw->display_q, &vf)) {
- vf->index_disp = atomic_read(&hw->get_num);
- atomic_add(1, &hw->get_num);
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- return vf;
- }
- return NULL;
-}
-
-static int mpeg12_valid_vf_check(struct vframe_s *vf, struct vdec_mpeg12_hw_s *hw)
-{
- int i;
-
- if (vf == NULL || (vf->index == -1))
- return 0;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &hw->vfpool[i])
- return 1;
- }
-
- return 0;
-}
-
-static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- unsigned long flags;
-
- if (!mpeg12_valid_vf_check(vf, hw)) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "invalid vf: %lx\n", (ulong)vf);
- return ;
- }
-
- if (vf->meta_data_buf) {
- vf->meta_data_buf = NULL;
- vf->meta_data_size = 0;
- }
-
- if (vf->v4l_mem_handle !=
- hw->pics[vf->index].v4l_ref_buf_addr) {
- hw->pics[vf->index].v4l_ref_buf_addr
- = vf->v4l_mem_handle;
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "MPEG12 update fb handle, old:%llx, new:%llx\n",
- hw->pics[vf->index].v4l_ref_buf_addr,
- vf->v4l_mem_handle);
- }
- spin_lock_irqsave(&hw->lock, flags);
- hw->vfbuf_use[vf->index]--;
- if (hw->vfbuf_use[vf->index] < 0) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "warn: vf %lx, index %d putback repetitive, set use to 0\n", (ulong)vf, vf->index);
- hw->vfbuf_use[vf->index] = 0;
- }
- atomic_add(1, &hw->put_num);
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s: vf: %lx, index: %d, use: %d\n", __func__, (ulong)vf,
- vf->index, hw->vfbuf_use[vf->index]);
-
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static int vmpeg_event_cb(int type, void *data, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
-
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static int vmpeg_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
-
- spin_lock_irqsave(&hw->lock, flags);
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
- states->buf_recycle_num = 0;
-
- spin_unlock_irqrestore(&hw->lock, flags);
- return 0;
-}
-static int vmmpeg12_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
-
- if (!hw)
- return -1;
-
- vstatus->frame_width = hw->frame_width;
- vstatus->frame_height = hw->frame_height;
- if (hw->frame_dur != 0)
- vstatus->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = READ_VREG(AV_SCRATCH_C);
- vstatus->status = hw->stat;
- vstatus->bit_rate = hw->gvs.bit_rate;
- vstatus->frame_dur = hw->frame_dur;
- vstatus->frame_data = hw->gvs.frame_data;
- vstatus->total_data = hw->gvs.total_data;
- vstatus->frame_count = hw->gvs.frame_count;
- vstatus->error_frame_count = hw->gvs.error_frame_count;
- vstatus->drop_frame_count = hw->drop_frame_count;
- vstatus->i_decoded_frames = hw->gvs.i_decoded_frames;
- vstatus->i_lost_frames = hw->gvs.i_lost_frames;
- vstatus->i_concealed_frames = hw->gvs.i_concealed_frames;
- vstatus->p_decoded_frames = hw->gvs.p_decoded_frames;
- vstatus->p_lost_frames = hw->gvs.p_lost_frames;
- vstatus->p_concealed_frames = hw->gvs.p_concealed_frames;
- vstatus->b_decoded_frames = hw->gvs.b_decoded_frames;
- vstatus->b_lost_frames = hw->gvs.b_lost_frames;
- vstatus->b_concealed_frames = hw->gvs.b_concealed_frames;
- vstatus->total_data = hw->gvs.total_data;
- vstatus->samp_cnt = hw->gvs.samp_cnt;
- vstatus->offset = hw->gvs.offset;
- vstatus->ratio_control = hw->ratio_control;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
-
- return 0;
-}
-
-/****************************************/
-static void vmpeg12_workspace_init(struct vdec_mpeg12_hw_s *hw)
-{
- int ret;
-
- ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle,
- DECODE_BUFFER_NUM_MAX,
- WORKSPACE_SIZE,
- DRIVER_NAME,
- &hw->buf_start);
- if (ret < 0) {
- pr_err("mpeg2 workspace alloc size %d failed.\n",
- WORKSPACE_SIZE);
- return;
- }
-
- if (!hw->ccbuf_phyAddress_virt) {
- hw->cc_buf_size = AUX_BUF_ALIGN(CCBUF_SIZE);
- hw->ccbuf_phyAddress_virt =
- dma_alloc_coherent(amports_get_dma_device(),
- hw->cc_buf_size, &hw->ccbuf_phyAddress,
- GFP_KERNEL);
- if (hw->ccbuf_phyAddress_virt == NULL) {
- pr_err("%s: failed to alloc cc buffer\n", __func__);
- return;
- }
- }
-
- WRITE_VREG(MREG_CO_MV_START, hw->buf_start);
- WRITE_VREG(MREG_CC_ADDR, hw->ccbuf_phyAddress);
-
- return;
-}
-
-static void vmpeg2_dump_state(struct vdec_s *vdec)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)(vdec->private);
- u32 i;
- debug_print(DECODE_ID(hw), 0,
- "====== %s\n", __func__);
- debug_print(DECODE_ID(hw), 0,
- "width/height (%d/%d),i_first %d, buf_num %d\n",
- hw->frame_width,
- hw->frame_height,
- hw->first_i_frame_ready,
- hw->buf_num
- );
- debug_print(DECODE_ID(hw), 0,
- "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d put_frm %d run %d not_run_ready %d,input_empty %d\n",
- vdec_frame_based(vdec),
- hw->eos,
- hw->stat,
- hw->dec_result,
- hw->dec_num,
- hw->put_num,
- hw->run_count,
- hw->not_run_ready,
- hw->input_empty
- );
-
- for (i = 0; i < hw->buf_num; i++) {
- debug_print(DECODE_ID(hw), 0,
- "index %d, used %d, ref %d\n", i,
- hw->vfbuf_use[i], hw->ref_use[i]);
- }
-
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- debug_print(DECODE_ID(hw), 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
- debug_print(DECODE_ID(hw), 0,
- "%s, newq(%d/%d), dispq(%d/%d) vf pre/get/put (%d/%d/%d),drop=%d, buffer_not_ready %d\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->display_q),
- VF_POOL_SIZE,
- hw->disp_num,
- hw->get_num,
- hw->put_num,
- hw->drop_frame_count,
- hw->buffer_not_ready
- );
- debug_print(DECODE_ID(hw), 0,
- "VIFF_BIT_CNT=0x%x\n",
- READ_VREG(VIFF_BIT_CNT));
- debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_WP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_RP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (vdec_frame_based(vdec) &&
- debug_enable & PRINT_FRAMEBASE_DATA
- ) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, hw->chunk->size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- debug_print(DECODE_ID(hw), 0,
- "frame data size 0x%x\n",
- hw->chunk->size);
- for (jj = 0; jj < hw->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA, "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-}
-
-static void reset_process_time(struct vdec_mpeg12_hw_s *hw)
-{
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[DECODE_ID(hw)])
- max_process_time[DECODE_ID(hw)] = process_time;
- }
-}
-
-static void start_process_time_set(struct vdec_mpeg12_hw_s *hw)
-{
- if ((hw->refs[1] != -1) && (hw->refs[0] == -1))
- hw->decode_timeout_count = 1;
- else
- hw->decode_timeout_count = 10;
- hw->start_process_time = jiffies;
-}
-static void timeout_process(struct vdec_mpeg12_hw_s *hw)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- if (work_pending(&hw->work) ||
- work_busy(&hw->work) ||
- work_busy(&hw->timeout_work) ||
- work_pending(&hw->timeout_work)) {
- pr_err("%s mpeg12[%d] timeout_process return befor do anything.\n",__func__, vdec->id);
- return;
- }
- reset_process_time(hw);
- amvdec_stop();
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s decoder timeout, status=%d, level=%d\n",
- __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- hw->dec_result = DEC_RESULT_DONE;
- if ((hw->refs[1] != -1) && (hw->refs[0] != -1))
- hw->first_i_frame_ready = 0;
-
- /*
- * In this very timeout point,the vmpeg12_work arrives,
- * let it to handle the scenario.
- */
- if (work_pending(&hw->work)) {
- pr_err("%s mpeg12[%d] return befor schedule.", __func__, vdec->id);
- return;
- }
- vdec_schedule_work(&hw->timeout_work);
-}
-
-static void check_timer_func(struct timer_list *timer)
-{
- struct vdec_mpeg12_hw_s *hw = container_of(timer,
- struct vdec_mpeg12_hw_s, check_timer);
- unsigned int timeout_val = decode_timeout_val;
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (((debug_enable & PRINT_FLAG_TIMEOUT_STATUS) == 0) &&
- (timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > timeout_val)) {
- if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- timeout_process(hw);
- }
- hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
- }
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw)
-{
- u32 index = -1;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- int i;
-
- if (!hw->init_flag)
- vmpeg12_workspace_init(hw);
-
- if (hw->v4l_params_parsed) {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(v4l2_ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- index = find_free_buffer(hw);
- if ((index < 0) || (index >= hw->buf_num))
- return -1;
-
- WRITE_VREG(MREG_CO_MV_START, hw->buf_start);
- WRITE_VREG(MREG_CC_ADDR, hw->ccbuf_phyAddress);
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->pics[i].v4l_ref_buf_addr) {
- config_cav_lut(canvas_y(hw->canvas_spec[i]),
- &hw->canvas_config[i][0], VDEC_1);
- config_cav_lut(canvas_u(hw->canvas_spec[i]),
- &hw->canvas_config[i][1], VDEC_1);
- }
- }
-
- /* prepare REF0 & REF1
- points to the past two IP buffers
- prepare REC_CANVAS_ADDR and ANC2_CANVAS_ADDR
- points to the output buffer*/
- WRITE_VREG(MREG_REF0,
- (hw->refs[0] == -1) ? 0xffffffff :
- hw->canvas_spec[hw->refs[0]]);
- WRITE_VREG(MREG_REF1,
- (hw->refs[1] == -1) ? 0xffffffff :
- hw->canvas_spec[hw->refs[1]]);
- WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]);
- WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]);
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE,
- "%s,ref0=0x%x, ref1=0x%x,rec=0x%x, ctx_valid=%d,index=%d\n",
- __func__,
- READ_VREG(MREG_REF0),
- READ_VREG(MREG_REF1),
- READ_VREG(REC_CANVAS_ADDR),
- hw->ctx_valid, index);
- }
-
- /* set to mpeg1 default */
- WRITE_VREG(MPEG1_2_REG,
- (hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 0);
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
- /* for Mpeg1 default value */
- WRITE_VREG(PIC_HEAD_INFO,
- (hw->ctx_valid) ? hw->reg_pic_head_info : 0x380);
- /* disable mpeg4 */
- WRITE_VREG(M4_CONTROL_REG, 0);
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
- /* clear buffer IN/OUT registers */
- WRITE_VREG(MREG_BUFFEROUT, 0);
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
- /* set reference width and height */
- if ((hw->frame_width != 0) && (hw->frame_height != 0))
- WRITE_VREG(MREG_CMD,
- (hw->frame_width << 16) | hw->frame_height);
- else
- WRITE_VREG(MREG_CMD, 0);
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE,
- "0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
- hw->frame_width, hw->frame_height, hw->seqinfo,
- hw->reg_f_code_reg, hw->reg_slice_ver_pos_pic_type,
- hw->reg_mb_info);
-
- WRITE_VREG(MREG_PIC_WIDTH, hw->reg_pic_width);
- WRITE_VREG(MREG_PIC_HEIGHT, hw->reg_pic_height);
- WRITE_VREG(MREG_SEQ_INFO, hw->seqinfo);
- WRITE_VREG(F_CODE_REG, hw->reg_f_code_reg);
- WRITE_VREG(SLICE_VER_POS_PIC_TYPE,
- hw->reg_slice_ver_pos_pic_type);
- WRITE_VREG(MB_INFO, hw->reg_mb_info);
- WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg);
- WRITE_VREG(AV_SCRATCH_H, hw->reg_signal_type);
-
- if (READ_VREG(MREG_ERROR_COUNT) != 0 ||
- READ_VREG(MREG_FATAL_ERROR) == 1)
- debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE,
- "err_cnt:%d fa_err:%d\n",
- READ_VREG(MREG_ERROR_COUNT),
- READ_VREG(MREG_FATAL_ERROR));
-
- /* clear error count */
- WRITE_VREG(MREG_ERROR_COUNT, 0);
- /*Use MREG_FATAL_ERROR bit1, the ucode determine
- whether to report the interruption of width and
- height information,in order to be compatible
- with the old version of ucode.
- 1: Report the width and height information
- 0: No Report
- bit0:
- 1: Use cma cc buffer for new driver
- 0: use codec mm cc buffer for old driver
- */
- WRITE_VREG(MREG_FATAL_ERROR, 3);
- /* clear wait buffer status */
- WRITE_VREG(MREG_WAIT_BUFFER, 0);
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17);
-#endif
-
- /* cbcr_merge_swap_en */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- } else {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- }
-
- if (!hw->ctx_valid)
- WRITE_VREG(AV_SCRATCH_J, hw->userdata_wp_ctx);
-
- if (hw->chunk) {
- /*frame based input*/
- WRITE_VREG(MREG_INPUT,
- (hw->chunk->offset & 7) | (1<<7) | (hw->ctx_valid<<6));
- } else {
- /*stream based input*/
- WRITE_VREG(MREG_INPUT, (hw->ctx_valid<<6));
- }
- return 0;
-}
-
-static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw)
-{
- int i;
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf;
- vf = &hw->vfpool[i];
- hw->vfpool[i].index = DECODE_BUFFER_NUM_MAX;
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- }
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- hw->vfbuf_use[i] = 0;
- hw->ref_use[i] = 0;
- }
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-
- hw->mm_blk_handle = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- 0,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- hw->tvp_flag);
-
- hw->eos = 0;
- hw->frame_width = hw->frame_height = 0;
- hw->frame_dur = hw->frame_prog = 0;
- hw->frame_force_skip_flag = 0;
- hw->wait_buffer_counter = 0;
- hw->first_i_frame_ready = 0;
- hw->dec_control &= DEC_CONTROL_INTERNAL_MASK;
- hw->refs[0] = -1;
- hw->refs[1] = -1;
- hw->dec_num = 0;
- hw->run_count = 0;
- hw->not_run_ready = 0;
- hw->input_empty = 0;
- hw->drop_frame_count = 0;
- hw->buffer_not_ready = 0;
- hw->start_process_time = 0;
- hw->init_flag = 0;
- hw->dec_again_cnt = 0;
- hw->error_frame_skip_level = error_frame_skip_level;
- atomic_set(&hw->disp_num, 0);
- atomic_set(&hw->put_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->peek_num, 0);
-
- if (dec_control)
- hw->dec_control = dec_control;
-}
-
-static s32 vmpeg12_init(struct vdec_mpeg12_hw_s *hw)
-{
- int size;
- u32 fw_size = 16*0x1000;
- struct firmware_s *fw;
-
- vmpeg12_local_init(hw);
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- pr_debug("get firmware ...\n");
- size = get_firmware_data(VIDEO_DEC_MPEG12_MULTI, fw->data);
- if (size < 0) {
- pr_err("get firmware fail.\n");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
-
- INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);
- INIT_WORK(&hw->work, vmpeg12_work);
- INIT_WORK(&hw->timeout_work, vmpeg12_timeout_work);
- INIT_WORK(&hw->notify_work, vmpeg12_notify_work);
-
- if (NULL == hw->user_data_buffer) {
- hw->user_data_buffer = kmalloc(USER_DATA_SIZE,
- GFP_KERNEL);
- if (!hw->user_data_buffer) {
- pr_info("%s: Can not allocate user_data_buffer\n",
- __func__);
- return -1;
- }
- }
-
- vmmpeg2_crate_userdata_manager(hw,
- hw->user_data_buffer,
- USER_DATA_SIZE);
-
- //amvdec_enable();
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (unsigned long)hw;
- //hw->check_timer.function = check_timer_func;
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
-
- hw->stat |= STAT_TIMER_ARM;
- hw->stat |= STAT_ISR_REG;
-
- hw->buf_start = 0;
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-
- return 0;
-}
-
-static bool is_avaliable_buffer(struct vdec_mpeg12_hw_s *hw)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_count = 0;
- int used_count = 0;
-
- if ((hw->buf_num == 0) ||
- (ctx->cap_pool.dec < hw->buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hw->buf_num; ++i) {
- if ((hw->vfbuf_use[i] == 0) &&
- (hw->ref_use[i] == 0) &&
- hw->pics[i].v4l_ref_buf_addr) {
- free_count++;
- } else if (hw->pics[i].v4l_ref_buf_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- if (hw->eos)
- return 0;
-
- if (hw->timeout_processing &&
- (work_pending(&hw->work) || work_busy(&hw->work) ||
- work_pending(&hw->timeout_work) || work_busy(&hw->timeout_work))) {
- debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "mpeg12 work pending,not ready for run.\n");
- return 0;
- }
- hw->timeout_processing = 0;
- if (vdec_stream_based(vdec) && (hw->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
-
- if (level < pre_decode_buf_level) {
- hw->not_run_ready++;
- return 0;
- }
- }
-
-#ifdef AGAIN_HAS_THRESHOLD
- if (hw->next_again_flag&&
- (!vdec_frame_based(vdec))) {
- u32 parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- if (parser_wr_ptr >= hw->pre_parser_wr_ptr &&
- (parser_wr_ptr - hw->pre_parser_wr_ptr) <
- again_threshold) {
- int r = vdec_sync_input(vdec);
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s buf level%x\n",
- __func__, r);
- return 0;
- }
- }
-#endif
-
- if (hw->v4l_params_parsed) {
- ret = is_avaliable_buffer(hw) ? 1 : 0;
- } else {
- ret = ctx->v4l_resolution_change ? 0 : 1;
- }
-
- hw->not_run_ready = 0;
- hw->buffer_not_ready = 0;
-
- return ret ? CORE_MASK_VDEC_1 : 0;
-}
-
-static unsigned char get_data_check_sum
- (struct vdec_mpeg12_hw_s *hw, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static int check_dirty_data(struct vdec_s *vdec)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)(vdec->private);
- u32 wp, rp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
-
- if (wp > rp)
- level = wp - rp;
- else
- level = wp + vdec->input.size - rp ;
-
- if (hw->next_again_flag &&
- hw->pre_parser_wr_ptr !=
- STBUF_READ(&vdec->vbuf, get_wp))
- hw->dec_again_cnt++;
- if ((level > (vdec->input.size * 2 / 3) ) &&
- (hw->dec_again_cnt > dirty_again_threshold)) {
- debug_print(DECODE_ID(hw), 0, "mpeg12 data skipped %x, level %x\n", ((level / 2) >> 20) << 20, level);
- if (vdec->input.swap_valid) {
- vdec_stream_skip_data(vdec, ((level / 2) >> 20) << 20);
- hw->dec_again_cnt = 0;
- }
- return 1;
- }
- return 0;
-}
-
-
-static void run(struct vdec_s *vdec, unsigned long mask,
-void (*callback)(struct vdec_s *, void *),
- void *arg)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- int save_reg;
- int size, ret;
- if (!hw->vdec_pg_enable_flag) {
- hw->vdec_pg_enable_flag = 1;
- amvdec_enable();
- }
- save_reg = READ_VREG(POWER_CTL_VLD);
- /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/
- WRITE_VREG(DOS_SW_RESET0, 0xfffffff0);
- WRITE_VREG(DOS_SW_RESET0, 0);
- WRITE_VREG(POWER_CTL_VLD, save_reg);
- hw->run_count++;
- vdec_reset_core(vdec);
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
-
- if ((vdec_stream_based(vdec)) &&
- (error_proc_policy & 0x1) &&
- check_dirty_data(vdec)) {
- hw->dec_result = DEC_RESULT_AGAIN;
- if (!vdec->input.swap_valid) {
- debug_print(DECODE_ID(hw), 0, "mpeg12 start dirty data skipped\n");
- vdec_prepare_input(vdec, &hw->chunk);
- hw->dec_result = DEC_RESULT_DONE;
- }
- vdec_schedule_work(&hw->work);
- return;
- }
-
-#ifdef AGAIN_HAS_THRESHOLD
- if (vdec_stream_based(vdec)) {
- hw->pre_parser_wr_ptr =
- STBUF_READ(&vdec->vbuf, get_wp);
- hw->next_again_flag = 0;
- }
-#endif
-
- if ((vdec_frame_based(vdec)) && (hw->chunk_header_offset != 0) &&
- (!hw->v4l_params_parsed) && (hw->chunk != NULL) &&
- (hw->chunk_res_size != 0)) {
- hw->chunk->offset = hw->chunk_header_offset;
- hw->chunk->size = hw->chunk_res_size;
- hw->chunk_header_offset = 0;
- hw->chunk_res_size = 0;
- debug_print(DECODE_ID(hw), 0, "Multiple heads are parsed in a chunk and resolution changed.\n");
- }
-
- size = vdec_prepare_input(vdec, &hw->chunk);
- if (size < 0) {
- hw->input_empty++;
- hw->dec_result = DEC_RESULT_AGAIN;
-
- debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "vdec_prepare_input: Insufficient data\n");
- vdec_schedule_work(&hw->work);
- return;
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", size);
-
- hw->input_empty = 0;
- if ((vdec_frame_based(vdec)) &&
- (hw->chunk != NULL)) {
- size = hw->chunk->size +
- (hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(VIFF_BIT_CNT, size * 8);
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hw->chunk->size;
- }
- if (vdec_frame_based(vdec) && !vdec_secure(vdec)) {
- /* HW needs padding (NAL start) for frame ending */
- char* tail = (char *)hw->chunk->block->start_virt;
-
- tail += hw->chunk->offset + hw->chunk->size;
- tail[0] = 0;
- tail[1] = 0;
- tail[2] = 1;
- tail[3] = 0;
- codec_mm_dma_flush(tail, 4, DMA_TO_DEVICE);
- }
-
- if (vdec_frame_based(vdec) && debug_enable && !vdec_secure(vdec)) {
- u8 *data = NULL;
- if (hw->chunk)
- debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "run: chunk offset 0x%x, size %d\n",
- hw->chunk->offset, hw->chunk->size);
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- if (debug_enable & PRINT_FLAG_VDEC_STATUS
- ) {
- debug_print(DECODE_ID(hw), 0,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, get_data_check_sum(hw, size),
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
- }
- if (debug_enable & PRINT_FRAMEBASE_DATA
- ) {
- int jj;
- debug_print(DECODE_ID(hw), PRINT_FRAMEBASE_DATA,
- "frame data:\n");
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- pr_info("%06x:", jj);
- pr_info("%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- pr_info("\n");
- }
- pr_info("\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- } else {
- debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: %x %x %x %x %x size 0x%x, bitcnt %d\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp),
- size, READ_VREG(VIFF_BIT_CNT));
- }
-
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
- ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG12, "mmpeg12", vdec,
- hw->fw->data, hw->fw->len);
- if (ret < 0) {
- pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
- hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_MPEG12;
- }
-
- if (vmpeg12_hw_ctx_restore(hw) < 0) {
- hw->dec_result = DEC_RESULT_ERROR;
- debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "ammvdec_mpeg12: error HW context restore\n");
- vdec_schedule_work(&hw->work);
- return;
- }
- /*wmb();*/
- hw->dec_result = DEC_RESULT_NONE;
- hw->stat |= STAT_MC_LOAD;
- vdec_enable_input(vdec);
- hw->last_vld_level = 0;
- start_process_time_set(hw);
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- amvdec_start();
- hw->stat |= STAT_VDEC_RUN;
- hw->stat |= STAT_TIMER_ARM;
- hw->init_flag = 1;
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- int i;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- flush_work(&hw->work);
- flush_work(&hw->timeout_work);
- flush_work(&hw->notify_work);
- flush_work(&hw->userdata_push_work);
- reset_process_time(hw);
-
- for (i = 0; i < hw->buf_num; i++) {
- hw->pics[i].v4l_ref_buf_addr = 0;
- hw->vfbuf_use[i] = 0;
- hw->ref_use[i] = 0;
- }
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- memset((void *)vf, 0, sizeof(*vf));
- hw->vfpool[i].index = -1;
- kfifo_put(&hw->newframe_q, vf);
- }
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
- vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
- hw->canvas_spec[i] = 0xffffff;
- }
-
- hw->refs[0] = -1;
- hw->refs[1] = -1;
- hw->ctx_valid = 0;
- hw->dec_num = 0;
- hw->eos = 0;
- hw->buf_num = 0;
- hw->frame_width = 0;
- hw->frame_height = 0;
- hw->first_i_frame_ready = 0;
- hw->first_field_timestamp = 0;
- hw->first_field_timestamp_valid = false;
-
- atomic_set(&hw->disp_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->put_num, 0);
-
- pr_info("mpeg12: reset.\n");
-}
-
-static int vmpeg12_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)vdec->private;
- if (!hw)
- return 0;
-
- if (trickmode == TRICKMODE_I) {
- hw->i_only = 0x3;
- //trickmode_i = 1;
- } else if (trickmode == TRICKMODE_NONE) {
- hw->i_only = 0x0;
- //trickmode_i = 0;
- }
- return 0;
-}
-
-static int ammvdec_mpeg12_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_mpeg12_hw_s *hw = NULL;
- int config_val = 0;
-
- pr_info("ammvdec_mpeg12 probe start.\n");
-
- if (pdata == NULL) {
- pr_info("ammvdec_mpeg12 platform data undefined.\n");
- return -EFAULT;
- }
-
- hw = vzalloc(sizeof(struct vdec_mpeg12_hw_s));
- if (hw == NULL) {
- pr_info("\nammvdec_mpeg12 decoder driver alloc failed\n");
- return -ENOMEM;
- }
-
- /* the ctx from v4l2 driver. */
- hw->v4l2_ctx = pdata->private;
-
- pdata->private = hw;
- pdata->dec_status = vmmpeg12_dec_status;
- pdata->set_trickmode = vmpeg12_set_trickmode;
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vmpeg12_isr;
- pdata->threaded_irq_handler = vmpeg12_isr_thread_fn;
- pdata->dump_state = vmpeg2_dump_state;
-
- pdata->user_data_read = vmmpeg2_user_data_read;
- pdata->reset_userdata_fifo = vmmpeg2_reset_userdata_fifo;
- pdata->wakeup_userdata_poll = vmmpeg2_wakeup_userdata_poll;
-
- snprintf(hw->vdec_name, sizeof(hw->vdec_name),
- "mpeg12-%d", pdev->id);
- snprintf(hw->pts_name, sizeof(hw->pts_name),
- "%s-timestamp", hw->vdec_name);
- snprintf(hw->new_q_name, sizeof(hw->new_q_name),
- "%s-newframe_q", hw->vdec_name);
- snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
- "%s-dispframe_q", hw->vdec_name);
-
- if (pdata->use_vfm_path) {
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- hw->frameinfo_enable = 1;
- }
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vf_provider_ops, pdata);
-
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->canvas_spec[i] = 0xffffff;
- }
- platform_set_drvdata(pdev, pdata);
-
- hw->canvas_mode = pdata->canvas_mode;
- if (pdata->config_len) {
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hw->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hw->canvas_mode = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_metadata_config_flag",
- &config_val) == 0)
- hw->force_prog_only = (config_val & VDEC_CFG_FLAG_PROG_ONLY) ? 1 : 0;
-
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
-
- if ((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0 &&
- get_config_int(pdata->config,
- "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin= config_val;
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hw->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hw->sidebind_channel_id = config_val;
- }
- hw->platform_dev = pdev;
- hw->chunk_header_offset = 0;
- hw->chunk_res_size = 0;
- hw->first_field_timestamp = 0;
- hw->first_field_timestamp_valid = false;
-
- if (hw->force_prog_only) {
- pdata->prog_only = 1;
- debug_print(DECODE_ID(hw), 0,
- "forced progressive output\n");
- }
-
- hw->tvp_flag = vdec_secure(pdata) ? CODEC_MM_FLAGS_TVP : 0;
- if (pdata->sys_info)
- hw->vmpeg12_amstream_dec_info = *pdata->sys_info;
-
- debug_print(DECODE_ID(hw), 0,
- "%s, sysinfo: %dx%d, tvp_flag = 0x%x\n",
- __func__,
- hw->vmpeg12_amstream_dec_info.width,
- hw->vmpeg12_amstream_dec_info.height,
- hw->tvp_flag);
-
- if (vmpeg12_init(hw) < 0) {
- pr_info("ammvdec_mpeg12 init failed.\n");
- if (hw) {
- vfree(hw);
- hw = NULL;
- }
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- vdec_set_vframe_comm(pdata, DRIVER_NAME);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
-#ifdef DUMP_USER_DATA
- amvdec_mmpeg12_init_userdata_dump(hw);
- reset_user_data_buf(hw);
-#endif
-
- /*INIT_WORK(&userdata_push_work, userdata_push_do_work);*/
- return 0;
-}
-
-static int ammvdec_mpeg12_remove(struct platform_device *pdev)
-
-{
- struct vdec_mpeg12_hw_s *hw =
- (struct vdec_mpeg12_hw_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int i;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
- cancel_work_sync(&hw->userdata_push_work);
- cancel_work_sync(&hw->notify_work);
- cancel_work_sync(&hw->work);
- cancel_work_sync(&hw->timeout_work);
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
- vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
- }
- }
-
- if (hw->ccbuf_phyAddress_virt) {
- dma_free_coherent(amports_get_dma_device(),hw->cc_buf_size,
- hw->ccbuf_phyAddress_virt, hw->ccbuf_phyAddress);
- hw->ccbuf_phyAddress_virt = NULL;
- hw->ccbuf_phyAddress = 0;
- }
-
- if (hw->user_data_buffer != NULL) {
- kfree(hw->user_data_buffer);
- hw->user_data_buffer = NULL;
- }
- vmmpeg2_destroy_userdata_manager(hw);
-
-#ifdef DUMP_USER_DATA
- amvdec_mmpeg12_uninit_userdata_dump(hw);
-#endif
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
-
- vfree(hw);
-
- pr_info("ammvdec_mpeg12 removed.\n");
-
- return 0;
-}
-
-/****************************************/
-
-static struct platform_driver ammvdec_mpeg12_driver = {
- .probe = ammvdec_mpeg12_probe,
- .remove = ammvdec_mpeg12_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = DRIVER_NAME,
- }
-};
-
-static struct codec_profile_t ammvdec_mpeg12_profile = {
- .name = "MPEG12-V4L",
- .profile = ""
-};
-
-static struct mconfig mmpeg12_configs[] = {
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("dec_control", &dec_control),
- MC_PU32("error_frame_skip_level", &error_frame_skip_level),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
- MC_PU32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("pre_decode_buf_level", &pre_decode_buf_level),
- MC_PU32("debug_enable", &debug_enable),
- MC_PU32("udebug_flag", &udebug_flag),
- MC_PU32("without_display_mode", &without_display_mode),
- MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
-#ifdef AGAIN_HAS_THRESHOLD
- MC_PU32("again_threshold", &again_threshold),
-#endif
-};
-static struct mconfig_node mmpeg12_node;
-
-static int __init ammvdec_mpeg12_driver_init_module(void)
-{
- pr_info("ammvdec_mpeg12 module init\n");
-
- if (platform_driver_register(&ammvdec_mpeg12_driver)) {
- pr_info("failed to register ammvdec_mpeg12 driver\n");
- return -ENODEV;
- }
- vcodec_profile_register(&ammvdec_mpeg12_profile);
- INIT_REG_NODE_CONFIGS("media.decoder", &mmpeg12_node,
- "mmpeg12-v4l", mmpeg12_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_MPEG12, 1);
- return 0;
-}
-
-static void __exit ammvdec_mpeg12_driver_remove_module(void)
-{
- pr_info("ammvdec_mpeg12 module exit.\n");
- platform_driver_unregister(&ammvdec_mpeg12_driver);
-}
-
-/****************************************/
-module_param(dec_control, uint, 0664);
-MODULE_PARM_DESC(dec_control, "\n ammvdec_mpeg12 decoder control\n");
-module_param(error_frame_skip_level, uint, 0664);
-MODULE_PARM_DESC(error_frame_skip_level,
- "\n ammvdec_mpeg12 error_frame_skip_level\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(debug_enable, uint, 0664);
-MODULE_PARM_DESC(debug_enable,
- "\n ammvdec_mpeg12 debug enable\n");
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level,
- "\n ammvdec_mpeg12 pre_decode_buf_level\n");
-
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n ammvdec_mpeg12 start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val, "\n ammvdec_mpeg12 decode_timeout_val\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n ammvdec_mpeg12 dynamic_buf_num_margin\n");
-
-module_param_array(max_process_time, uint, &max_decode_instance_num, 0664);
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n ammvdec_mpeg12 udebug_flag\n");
-
-module_param(dirty_again_threshold, int, 0664);
-MODULE_PARM_DESC(dirty_again_threshold, "\n ammvdec_mpeg12 dirty_again_threshold\n");
-
-
-#ifdef AGAIN_HAS_THRESHOLD
-module_param(again_threshold, uint, 0664);
-MODULE_PARM_DESC(again_threshold, "\n again_threshold\n");
-#endif
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n ammvdec_mpeg12 without_display_mode\n");
-
-module_param(error_proc_policy, uint, 0664);
-MODULE_PARM_DESC(error_proc_policy, "\n ammvdec_mpeg12 error_proc_policy\n");
-
-module_init(ammvdec_mpeg12_driver_init_module);
-module_exit(ammvdec_mpeg12_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC MULTI MPEG1/2 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-
-
diff --git a/drivers/frame_provider/decoder_v4l/mpeg4/Makefile b/drivers/frame_provider/decoder_v4l/mpeg4/Makefile
deleted file mode 100644
index 7164940..0000000
--- a/drivers/frame_provider/decoder_v4l/mpeg4/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4_MULTI) += amvdec_mmpeg4_v4l.o
-amvdec_mmpeg4_v4l-objs += vmpeg4_multi.o
diff --git a/drivers/frame_provider/decoder_v4l/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder_v4l/mpeg4/vmpeg4_multi.c
deleted file mode 100644
index 1cd8f44..0000000
--- a/drivers/frame_provider/decoder_v4l/mpeg4/vmpeg4_multi.c
+++ /dev/null
@@ -1,3003 +0,0 @@
-/*
- * drivers/amlogic/amports/vmpeg4.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/amvdec.h"
-#include "../../decoder/utils/vdec_input.h"
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/firmware.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include "../../decoder/utils/config_parser.h"
-#include <media/v4l2-mem2mem.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define DRIVER_NAME "ammvdec_mpeg4_v4l"
-
-#define MEM_NAME "codec_mmpeg4"
-
-#define DEBUG_PTS
-
-#define NV21
-#define I_PICTURE 0
-#define P_PICTURE 1
-#define B_PICTURE 2
-#define GET_PIC_TYPE(type) ("IPB####"[type&0x3])
-
-#define ORI_BUFFER_START_ADDR 0x01000000
-#define DEFAULT_MEM_SIZE (32*SZ_1M)
-
-#define INTERLACE_FLAG 0x80
-#define TOP_FIELD_FIRST_FLAG 0x40
-
-/* protocol registers */
-#define MREG_REF0 AV_SCRATCH_1
-#define MREG_REF1 AV_SCRATCH_2
-#define MP4_PIC_RATIO AV_SCRATCH_5
-#define MP4_RATE AV_SCRATCH_3
-#define MP4_ERR_COUNT AV_SCRATCH_6
-#define MP4_PIC_WH AV_SCRATCH_7
-#define MREG_INPUT AV_SCRATCH_8
-#define MREG_BUFFEROUT AV_SCRATCH_9
-#define MP4_NOT_CODED_CNT AV_SCRATCH_A
-#define MP4_VOP_TIME_INC AV_SCRATCH_B
-#define MP4_OFFSET_REG AV_SCRATCH_C
-#define MP4_VOS_INFO AV_SCRATCH_D
-#define MP4_SYS_RATE AV_SCRATCH_E
-#define MEM_OFFSET_REG AV_SCRATCH_F
-#define MP4_PIC_INFO AV_SCRATCH_H
-
-#define PARC_FORBIDDEN 0
-#define PARC_SQUARE 1
-#define PARC_CIF 2
-#define PARC_10_11 3
-#define PARC_16_11 4
-#define PARC_40_33 5
-#define PARC_RESERVED 6
-/* values between 6 and 14 are reserved */
-#define PARC_EXTENDED 15
-
-#define VF_POOL_SIZE 64
-#define DECODE_BUFFER_NUM_MAX 16
-#define DECODE_BUFFER_NUM_DEF 8
-#define PUT_INTERVAL (HZ/100)
-#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + 1)
-#define WORKSPACE_SIZE (12*SZ_64K)
-
-#define CTX_LMEM_SWAP_OFFSET 0
-#define CTX_QUANT_MATRIX_OFFSET 0x800
-/* dcac buffer must align at 4k boundary */
-#define CTX_DCAC_BUF_OFFSET 0x1000
-#define CTX_DECBUF_OFFSET (0x0c0000 + 0x1000)
-
-#define RATE_DETECT_COUNT 5
-#define DURATION_UNIT 96000
-#define PTS_UNIT 90000
-#define CHECK_INTERVAL (HZ/100)
-
-#define DUR2PTS(x) ((x) - ((x) >> 4))
-
-/* 96000/(60fps* 2field) = 800, 96000/10fps = 9600 */
-#define MPEG4_VALID_DUR(x) ((x < 9600) && (x > 799))
-
-#define MAX_MPEG4_SUPPORT_SIZE (1920*1088)
-
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_ERROR 3
-#define DEC_RESULT_FORCE_EXIT 4
-#define DEC_RESULT_EOS 5
-#define DEC_RESULT_UNFINISH 6
-#define DEC_RESULT_ERROR_SZIE 7
-
-#define DEC_DECODE_TIMEOUT 0x21
-#define DECODE_ID(hw) (hw_to_vdec(hw)->id)
-#define DECODE_STOP_POS AV_SCRATCH_K
-
-#define INVALID_IDX (-1) /* Invalid buffer index.*/
-
-static u32 udebug_flag;
-
-static struct vframe_s *vmpeg_vf_peek(void *);
-static struct vframe_s *vmpeg_vf_get(void *);
-static void vmpeg_vf_put(struct vframe_s *, void *);
-static int vmpeg_vf_states(struct vframe_states *states, void *);
-static int vmpeg_event_cb(int type, void *data, void *private_data);
-static int notify_v4l_eos(struct vdec_s *vdec);
-
-static int pre_decode_buf_level = 0x800;
-static int start_decode_buf_level = 0x4000;
-static int debug_enable;
-static unsigned int radr;
-static unsigned int rval;
-/* 0x40bit = 8byte */
-static unsigned int frmbase_cont_bitlevel = 0x40;
-static unsigned int dynamic_buf_num_margin;
-
-#define VMPEG4_DEV_NUM 9
-static unsigned int max_decode_instance_num = VMPEG4_DEV_NUM;
-static unsigned int max_process_time[VMPEG4_DEV_NUM];
-static unsigned int decode_timeout_val = 200;
-
-static u32 without_display_mode;
-
-#undef pr_info
-#define pr_info printk
-unsigned int mpeg4_debug_mask = 0xff;
-static u32 run_ready_min_buf_num = 2;
-
-
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_RUN_FLOW 0X0001
-#define PRINT_FLAG_TIMEINFO 0x0002
-#define PRINT_FLAG_UCODE_DETAIL 0x0004
-#define PRINT_FLAG_VLD_DETAIL 0x0008
-#define PRINT_FLAG_DEC_DETAIL 0x0010
-#define PRINT_FLAG_BUFFER_DETAIL 0x0020
-#define PRINT_FLAG_RESTORE 0x0040
-#define PRINT_FRAME_NUM 0x0080
-#define PRINT_FLAG_FORCE_DONE 0x0100
-#define PRINT_FLAG_COUNTER 0X0200
-#define PRINT_FRAMEBASE_DATA 0x0400
-#define PRINT_FLAG_VDEC_STATUS 0x0800
-#define PRINT_FLAG_TIMEOUT_STATUS 0x1000
-#define PRINT_FLAG_V4L_DETAIL 0x8000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-
-int mmpeg4_debug_print(int index, int debug_flag, const char *fmt, ...)
-{
- if (((debug_enable & debug_flag) &&
- ((1 << index) & mpeg4_debug_mask))
- || (debug_flag == PRINT_FLAG_ERROR)) {
- unsigned char *buf = kzalloc(512, GFP_ATOMIC);
- int len = 0;
- va_list args;
-
- if (!buf)
- return 0;
-
- va_start(args, fmt);
- len = sprintf(buf, "%d: ", index);
- vsnprintf(buf + len, 512-len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- kfree(buf);
- }
- return 0;
-}
-
-struct pic_info_t {
- int index;
- u32 pic_type;
- u32 pic_info;
- u32 pts;
- u64 pts64;
- bool pts_valid;
- u32 duration;
- u32 repeat_cnt;
- ulong v4l_ref_buf_addr;
- u32 hw_decode_time;
- u32 frame_size; // For frame base mode;
- u64 timestamp;
- u32 offset;
- u32 height;
- u32 width;
-};
-
-struct vdec_mpeg4_hw_s {
- spinlock_t lock;
- struct platform_device *platform_dev;
- /* struct device *cma_dev; */
-
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
- struct vframe_s vframe_dummy;
- s32 vfbuf_use[DECODE_BUFFER_NUM_MAX];
- u32 frame_width;
- u32 frame_height;
- u32 frame_dur;
- u32 frame_prog;
-
- u32 ctx_valid;
- u32 reg_vcop_ctrl_reg;
- u32 reg_pic_head_info;
- u32 reg_mpeg1_2_reg;
- u32 reg_slice_qp;
- u32 reg_mp4_pic_wh;
- u32 reg_mp4_rate;
- u32 reg_mb_info;
- u32 reg_dc_ac_ctrl;
- u32 reg_iqidct_control;
- u32 reg_resync_marker_length;
- u32 reg_rv_ai_mb_count;
- struct timer_list check_timer;
- u32 decode_timeout_count;
- u32 timeout_cnt;
- unsigned long int start_process_time;
-
- u32 last_vld_level;
- u8 init_flag;
- u32 eos;
- void *mm_blk_handle;
-
- struct vframe_chunk_s *chunk;
- u32 chunk_offset;
- u32 chunk_size;
- u32 chunk_frame_count;
- u32 stat;
- unsigned long buf_start;
- u32 buf_size;
- /*
- unsigned long cma_alloc_addr;
- int cma_alloc_count;
- */
- u32 vmpeg4_ratio;
- u64 vmpeg4_ratio64;
- u32 rate_detect;
- u32 vmpeg4_rotation;
- u32 total_frame;
- u32 last_vop_time_inc;
- u32 last_duration;
- u32 last_anch_pts;
- u32 vop_time_inc_since_last_anch;
- u32 frame_num_since_last_anch;
- u64 last_anch_pts_us64;
-
- u32 last_pts;
- u64 last_pts64;
- u32 pts_hit;
- u32 pts_missed;
- u32 pts_i_hit;
- u32 pts_i_missed;
- struct pic_info_t pic[DECODE_BUFFER_NUM_MAX];
- u32 canvas_spec[DECODE_BUFFER_NUM_MAX];
-#ifdef NV21
- struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2];
-#else
- struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][3];
-#endif
- struct dec_sysinfo vmpeg4_amstream_dec_info;
-
- s32 refs[2];
- int dec_result;
- struct work_struct work;
-
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- u32 frame_num;
- u32 sys_mp4_rate;
- u32 run_count;
- u32 not_run_ready;
- u32 buffer_not_ready;
- u32 input_empty;
- atomic_t peek_num;
- atomic_t get_num;
- atomic_t put_num;
- u32 first_i_frame_ready;
- u32 drop_frame_count;
- u32 unstable_pts;
- u32 last_dec_pts;
-
- struct firmware_s *fw;
- u32 blkmode;
- wait_queue_head_t wait_q;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- u32 buf_num;
- u32 dynamic_buf_num_margin;
- u32 i_only;
- int sidebind_type;
- int sidebind_channel_id;
- u32 res_ch_flag;
- u32 profile_idc;
- u32 level_idc;
- unsigned int i_decoded_frames;
- unsigned int i_lost_frames;
- unsigned int i_concealed_frames;
- unsigned int p_decoded_frames;
- unsigned int p_lost_frames;
- unsigned int p_concealed_frames;
- unsigned int b_decoded_frames;
- unsigned int b_lost_frames;
- unsigned int b_concealed_frames;
- int vdec_pg_enable_flag;
- ulong fb_token;
- char vdec_name[32];
- char pts_name[32];
- char new_q_name[32];
- char disp_q_name[32];
-};
-static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw);
-static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw);
-static unsigned char
- get_data_check_sum(struct vdec_mpeg4_hw_s *hw, int size);
-static void flush_output(struct vdec_mpeg4_hw_s * hw);
-
-#define PROVIDER_NAME "vdec.mpeg4"
-
-/*
- *int query_video_status(int type, int *value);
- */
-static const struct vframe_operations_s vf_provider_ops = {
- .peek = vmpeg_vf_peek,
- .get = vmpeg_vf_get,
- .put = vmpeg_vf_put,
- .event_cb = vmpeg_event_cb,
- .vf_states = vmpeg_vf_states,
-};
-
-static unsigned char aspect_ratio_table[16] = {
- PARC_FORBIDDEN,
- PARC_SQUARE,
- PARC_CIF,
- PARC_10_11,
- PARC_16_11,
- PARC_40_33,
- PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
- PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
- PARC_RESERVED, PARC_EXTENDED
-};
-
-static void reset_process_time(struct vdec_mpeg4_hw_s *hw);
-
-static void mpeg4_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vmpeg_vf_put(vf, vdec_ctx);
-}
-
-static void mpeg4_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vmpeg_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = mpeg4_get_video_frame,
- .put_vframe = mpeg4_put_video_frame,
-};
-
-static int vmpeg4_v4l_alloc_buff_config_canvas(struct vdec_mpeg4_hw_s *hw, int i)
-{
- int ret;
- u32 canvas;
- ulong decbuf_start = 0, decbuf_uv_start = 0;
- int decbuf_y_size = 0, decbuf_uv_size = 0;
- u32 canvas_width = 0, canvas_height = 0;
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct vdec_v4l2_buffer *fb = NULL;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (hw->pic[i].v4l_ref_buf_addr) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->pic[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- return 0;
- }
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "[%d] get fb fail.\n",
- ((struct aml_vcodec_ctx *)
- (hw->v4l2_ctx))->id);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw_to_vdec(hw));
- fb->status = FB_ST_DECODER;
-
- if (!hw->frame_width || !hw->frame_height) {
- struct vdec_pic_info pic;
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->frame_width = pic.visible_width;
- hw->frame_height = pic.visible_height;
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "[%d] set %d x %d from IF layer\n", ctx->id,
- hw->frame_width, hw->frame_height);
- }
-
- hw->pic[i].v4l_ref_buf_addr = (ulong)fb;
- if (fb->num_planes == 1) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].offset;
- decbuf_uv_start = decbuf_start + decbuf_y_size;
- decbuf_uv_size = decbuf_y_size / 2;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- } else if (fb->num_planes == 2) {
- decbuf_start = fb->m.mem[0].addr;
- decbuf_y_size = fb->m.mem[0].size;
- decbuf_uv_start = fb->m.mem[1].addr;
- decbuf_uv_size = fb->m.mem[1].size;
- canvas_width = ALIGN(hw->frame_width, 64);
- canvas_height = ALIGN(hw->frame_height, 64);
- fb->m.mem[0].bytes_used = decbuf_y_size;
- fb->m.mem[1].bytes_used = decbuf_uv_size;
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l ref buf addr: 0x%x\n",
- ctx->id, __func__, fb);
-
- if (vdec->parallel_dec == 1) {
- u32 tmp;
- if (canvas_y(hw->canvas_spec[i]) == 0xff) {
- tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~0xff;
- hw->canvas_spec[i] |= tmp;
- }
- if (canvas_u(hw->canvas_spec[i]) == 0xff) {
- tmp = vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id);
- hw->canvas_spec[i] &= ~(0xffff << 8);
- hw->canvas_spec[i] |= tmp << 8;
- hw->canvas_spec[i] |= tmp << 16;
- }
- canvas = hw->canvas_spec[i];
- } else {
- canvas = vdec->get_canvas(i, 2);
- hw->canvas_spec[i] = canvas;
- }
-
- hw->canvas_config[i][0].phy_addr = decbuf_start;
- hw->canvas_config[i][0].width = canvas_width;
- hw->canvas_config[i][0].height = canvas_height;
- hw->canvas_config[i][0].block_mode = hw->blkmode;
- if (hw->blkmode == CANVAS_BLKMODE_LINEAR)
- hw->canvas_config[i][0].endian = 7;
- else
- hw->canvas_config[i][0].endian = 0;
- config_cav_lut(canvas_y(canvas),
- &hw->canvas_config[i][0], VDEC_1);
-
- hw->canvas_config[i][1].phy_addr =
- decbuf_uv_start;
- hw->canvas_config[i][1].width = canvas_width;
- hw->canvas_config[i][1].height = (canvas_height >> 1);
- hw->canvas_config[i][1].block_mode = hw->blkmode;
- if (hw->blkmode == CANVAS_BLKMODE_LINEAR)
- hw->canvas_config[i][1].endian = 7;
- else
- hw->canvas_config[i][1].endian = 0;
- config_cav_lut(canvas_u(canvas),
- &hw->canvas_config[i][1], VDEC_1);
-
- return 0;
-}
-
-static int find_free_buffer(struct vdec_mpeg4_hw_s *hw)
-{
- int i;
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->vfbuf_use[i] == 0)
- break;
- }
-
- if ((i == hw->buf_num) &&
- (hw->buf_num != 0)) {
- return -1;
- }
-
- if (vmpeg4_v4l_alloc_buff_config_canvas(hw, i))
- return -1;
-
- return i;
-}
-
-static int spec_to_index(struct vdec_mpeg4_hw_s *hw, u32 spec)
-{
- int i;
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->canvas_spec[i] == spec)
- return i;
- }
-
- return -1;
-}
-
-static void set_frame_info(struct vdec_mpeg4_hw_s *hw, struct vframe_s *vf,
- int buffer_index)
-{
- int ar = 0;
- int endian_tmp;
- unsigned int num = 0;
- unsigned int den = 0;
- unsigned int pixel_ratio = READ_VREG(MP4_PIC_RATIO);
-
- if (hw->vmpeg4_ratio64 != 0) {
- num = hw->vmpeg4_ratio64>>32;
- den = hw->vmpeg4_ratio64 & 0xffffffff;
- } else {
- num = hw->vmpeg4_ratio>>16;
- den = hw->vmpeg4_ratio & 0xffff;
-
- }
- if ((num == 0) || (den == 0)) {
- num = 1;
- den = 1;
- }
-
- if (hw->vmpeg4_ratio == 0) {
- vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT);
- /* always stretch to 16:9 */
- } else if (pixel_ratio > 0x0f) {
- num = (pixel_ratio >> 8) *
- hw->frame_width * num;
- ar = div_u64((pixel_ratio & 0xff) *
- hw->frame_height * den * 0x100ULL +
- (num >> 1), num);
- } else {
- switch (aspect_ratio_table[pixel_ratio]) {
- case 0:
- num = hw->frame_width * num;
- ar = (hw->frame_height * den *
- 0x100 + (num >> 1)) / num;
- break;
- case 1:
- num = vf->width * num;
- ar = (vf->height * den * 0x100 + (num >> 1)) / num;
- break;
- case 2:
- num = (vf->width * 12) * num;
- ar = (vf->height * den * 0x100 * 11 +
- ((num) >> 1)) / num;
- break;
- case 3:
- num = (vf->width * 10) * num;
- ar = (vf->height * den * 0x100 * 11 + (num >> 1)) /
- num;
- break;
- case 4:
- num = (vf->width * 16) * num;
- ar = (vf->height * den * 0x100 * 11 + (num >> 1)) /
- num;
- break;
- case 5:
- num = (vf->width * 40) * num;
- ar = (vf->height * den * 0x100 * 33 + (num >> 1)) /
- num;
- break;
- default:
- num = vf->width * num;
- ar = (vf->height * den * 0x100 + (num >> 1)) / num;
- break;
- }
- }
-
- vf->sidebind_type = hw->sidebind_type;
- vf->sidebind_channel_id = hw->sidebind_channel_id;
-
- ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
-
- vf->signal_type = 0;
- vf->type_original = vf->type;
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
- vf->canvas0Addr = vf->canvas1Addr = -1;
-#ifdef NV21
- vf->plane_num = 2;
-#else
- vf->plane_num = 3;
-#endif
- vf->canvas0_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas0_config[1] = hw->canvas_config[buffer_index][1];
-#ifndef NV21
- vf->canvas0_config[2] = hw->canvas_config[buffer_index][2];
-#endif
- vf->canvas1_config[0] = hw->canvas_config[buffer_index][0];
- vf->canvas1_config[1] = hw->canvas_config[buffer_index][1];
-#ifndef NV21
- vf->canvas1_config[2] = hw->canvas_config[buffer_index][2];
-#endif
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- endian_tmp = (hw->blkmode == CANVAS_BLKMODE_LINEAR) ? 7 : 0;
- } else {
- endian_tmp = (hw->blkmode == CANVAS_BLKMODE_LINEAR) ? 0 : 7;
- }
- /* mpeg4 convert endian to match display */
- vf->canvas0_config[0].endian = endian_tmp;
- vf->canvas0_config[1].endian = endian_tmp;
- vf->canvas1_config[0].endian = endian_tmp;
- vf->canvas1_config[1].endian = endian_tmp;
-#ifndef NV21
- vf->canvas0_config[2].endian = endian_tmp;
- vf->canvas1_config[2].endian = endian_tmp;
-#endif
-}
-
-static inline void vmpeg4_save_hw_context(struct vdec_mpeg4_hw_s *hw)
-{
- hw->reg_mpeg1_2_reg = READ_VREG(MPEG1_2_REG);
- hw->reg_vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG);
- hw->reg_pic_head_info = READ_VREG(PIC_HEAD_INFO);
- hw->reg_slice_qp = READ_VREG(SLICE_QP);
- hw->reg_mp4_pic_wh = READ_VREG(MP4_PIC_WH);
- hw->reg_mp4_rate = READ_VREG(MP4_RATE);
- hw->reg_mb_info = READ_VREG(MB_INFO);
- hw->reg_dc_ac_ctrl = READ_VREG(DC_AC_CTRL);
- hw->reg_iqidct_control = READ_VREG(IQIDCT_CONTROL);
- hw->reg_resync_marker_length = READ_VREG(RESYNC_MARKER_LENGTH);
- hw->reg_rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT);
-}
-
-static int update_ref(struct vdec_mpeg4_hw_s *hw, int index)
-{
- hw->vfbuf_use[index]++;
-
- if (hw->refs[1] == -1) {
- hw->refs[1] = index;
- index = -1;
- } else if (hw->refs[0] == -1) {
- hw->refs[0] = hw->refs[1];
- hw->refs[1] = index;
- index = hw->refs[0];
- } else {
- hw->vfbuf_use[hw->refs[0]]--;
- hw->refs[0] = hw->refs[1];
- hw->refs[1] = index;
- index = hw->refs[0];
- }
-
- return index;
-}
-
-static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw,
- struct pic_info_t *pic)
-{
- struct vframe_s *vf = NULL;
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- ulong nv_order = VIDTYPE_VIU_NV21;
- int index = pic->index;
- bool pb_skip = false;
- unsigned long flags;
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- if (vdec->prog_only || (!v4l2_ctx->vpp_is_need))
- pic->pic_info &= ~INTERLACE_FLAG;
- }
-
- if (hw->i_only)
- pb_skip = 1;
-
- if (pic->pic_info & INTERLACE_FLAG) {
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "fatal error, no available buffer slot.");
- return -1;
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->pic[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l mem handle: 0x%lx\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
- __func__, vf->v4l_mem_handle);
- }
-
- vf->index = pic->index;
- vf->width = pic->width;
- vf->height = pic->height;
- vf->bufWidth = 1920;
- vf->flag = 0;
- vf->orientation = hw->vmpeg4_rotation;
- vf->pts = pic->pts;
- vf->pts_us64 = pic->pts64;
- vf->timestamp = pic->timestamp;
- vf->duration = pic->duration >> 1;
- vf->duration_pulldown = 0;
- vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ?
- VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
-#ifdef NV21
- vf->type |= nv_order;
-#endif
- set_frame_info(hw, vf, pic->index);
-
- hw->vfbuf_use[pic->index]++;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n",
- vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) &
- 0xffffffff00000000) | pic->offset;
- vf->pts = 0;
- }
- if (((hw->first_i_frame_ready == 0) || pb_skip)
- && (pic->pic_type != I_PICTURE)) {
- hw->drop_frame_count++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_lost_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_lost_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_lost_frames++;
- }
- hw->vfbuf_use[index]--;
- spin_lock_irqsave(&hw->lock, flags);
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- spin_unlock_irqrestore(&hw->lock, flags);
- return 0;
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle, index);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- hw->frame_num++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_decoded_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_decoded_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_decoded_frames++;
- }
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- } else
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- }
-
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "error, no available buf.\n");
- hw->dec_result = DEC_RESULT_ERROR;
- return -1;
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->pic[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l mem handle: 0x%lx\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
- __func__, vf->v4l_mem_handle);
- }
-
- vf->index = pic->index;
- vf->width = pic->width;
- vf->height = pic->height;
- vf->bufWidth = 1920;
- vf->flag = 0;
- vf->orientation = hw->vmpeg4_rotation;
- vf->pts = 0;
- vf->pts_us64 = 0;
- vf->timestamp = pic->timestamp;
- if (v4l2_ctx->second_field_pts_mode) {
- vf->timestamp = 0;
- }
-
- vf->duration = pic->duration >> 1;
- vf->duration_pulldown = 0;
- vf->type = (pic->pic_info & TOP_FIELD_FIRST_FLAG) ?
- VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP;
-#ifdef NV21
- vf->type |= nv_order;
-#endif
- set_frame_info(hw, vf, pic->index);
-
- hw->vfbuf_use[pic->index]++;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "filed1: pts %d, pts64 %lld, w %d, h %d, dur: %d\n",
- vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 = (u64)-1;
- vf->pts = 0;
- }
- if (((hw->first_i_frame_ready == 0) || pb_skip)
- && (pic->pic_type != I_PICTURE)) {
- hw->drop_frame_count++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_lost_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_lost_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_lost_frames++;
- }
- hw->vfbuf_use[index]--;
- spin_lock_irqsave(&hw->lock, flags);
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- spin_unlock_irqrestore(&hw->lock, flags);
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle, index);
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q,
- (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- vdec->vdec_fps_detec(vdec->id);
- hw->frame_num++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_decoded_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_decoded_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_decoded_frames++;
- }
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- } else
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- }
- } else {
- /* progressive */
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "error, no available buf\n");
- hw->dec_result = DEC_RESULT_ERROR;
- return -1;
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->pic[index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "[%d] %s(), v4l mem handle: 0x%lx\n",
- ((struct aml_vcodec_ctx *)(hw->v4l2_ctx))->id,
- __func__, vf->v4l_mem_handle);
- }
-
- vf->index = index;
- vf->width = hw->frame_width;
- vf->height = hw->frame_height;
- vf->bufWidth = 1920;
- vf->flag = 0;
- vf->orientation = hw->vmpeg4_rotation;
- vf->pts = pic->pts;
- vf->pts_us64 = pic->pts64;
- vf->timestamp = pic->timestamp;
- vf->duration = pic->duration;
- vf->duration_pulldown = pic->repeat_cnt *
- pic->duration;
-#ifdef NV21
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD | nv_order;
-#else
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD;
-#endif
- set_frame_info(hw, vf, index);
-
- hw->vfbuf_use[index]++;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n",
- vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration);
-
- if (vdec_stream_based(vdec) && (!vdec->vbuf.use_ptsserv)) {
- vf->pts_us64 =
- (((u64)vf->duration << 32) &
- 0xffffffff00000000) | pic->offset;
- vf->pts = 0;
- }
- if (((hw->first_i_frame_ready == 0) || pb_skip)
- && (pic->pic_type != I_PICTURE)) {
- hw->drop_frame_count++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_lost_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_lost_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_lost_frames++;
- }
- hw->vfbuf_use[index]--;
- spin_lock_irqsave(&hw->lock, flags);
- kfifo_put(&hw->newframe_q,
- (const struct vframe_s *)vf);
- spin_unlock_irqrestore(&hw->lock, flags);
- } else {
- struct vdec_info vinfo;
-
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->mm_blk_handle, index);
- decoder_do_frame_check(vdec, vf);
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- vdec->vdec_fps_detec(vdec->id);
- hw->frame_num++;
- if (pic->pic_type == I_PICTURE) {
- hw->i_decoded_frames++;
- } else if (pic->pic_type == P_PICTURE) {
- hw->p_decoded_frames++;
- } else if (pic->pic_type == B_PICTURE) {
- hw->b_decoded_frames++;
- }
- vdec->dec_status(vdec, &vinfo);
- vdec_fill_vdec_frame(vdec, NULL,
- &vinfo, vf, pic->hw_decode_time);
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- } else {
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- } else
- vmpeg_vf_put(vmpeg_vf_get(vdec), vdec);
- }
-
- }
- return 0;
-}
-
-static void vmpeg4_prepare_input(struct vdec_mpeg4_hw_s *hw)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
- struct vdec_input_s *input = &vdec->input;
- struct vframe_block_list_s *block = NULL;
- struct vframe_chunk_s *chunk = hw->chunk;
- int dummy;
-
- if (chunk == NULL)
- return;
-
- /* full reset to HW input */
- WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
-
- /* reset VLD fifo for all vdec */
- WRITE_VREG(DOS_SW_RESET0, (1<<5) | (1<<4) | (1<<3));
- WRITE_VREG(DOS_SW_RESET0, 0);
-
- WRITE_VREG(POWER_CTL_VLD, 1 << 4);
-
- /*
- *setup HW decoder input buffer (VLD context)
- * based on input->type and input->target
- */
- if (input_frame_based(input)) {
- block = chunk->block;
-
- WRITE_VREG(VLD_MEM_VIFIFO_START_PTR, block->start);
- WRITE_VREG(VLD_MEM_VIFIFO_END_PTR, block->start +
- block->size - 8);
- WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR,
- round_down(block->start + hw->chunk_offset,
- VDEC_FIFO_ALIGN));
-
- WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1);
- WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
-
- /* set to manual mode */
- WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2);
- WRITE_VREG(VLD_MEM_VIFIFO_RP,
- round_down(block->start + hw->chunk_offset,
- VDEC_FIFO_ALIGN));
- dummy = hw->chunk_offset + hw->chunk_size +
- VLD_PADDING_SIZE;
- if (dummy >= block->size)
- dummy -= block->size;
- WRITE_VREG(VLD_MEM_VIFIFO_WP,
- round_down(block->start + dummy,
- VDEC_FIFO_ALIGN));
-
- WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 3);
- WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2);
-
- WRITE_VREG(VLD_MEM_VIFIFO_CONTROL,
- (0x11 << 16) | (1<<10) | (7<<3));
-
- }
-}
-
-static int vmpeg4_get_ps_info(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace, struct aml_vdec_ps_infos *ps)
-{
- ps->visible_width = width;
- ps->visible_height = height;
- ps->coded_width = ALIGN(width, 64);
- ps->coded_height = ALIGN(height, 64);
- ps->dpb_size = hw->buf_num;
- ps->dpb_frames = DECODE_BUFFER_NUM_DEF;
- ps->dpb_margin = hw->dynamic_buf_num_margin;
- ps->field = interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height, int interlace)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- if (ctx->param_sets_from_ucode &&
- hw->res_ch_flag == 0) {
- struct aml_vdec_ps_infos ps;
-
- if ((hw->frame_width != 0 &&
- hw->frame_height != 0) &&
- (hw->frame_width != width ||
- hw->frame_height != height)) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "v4l_res_change Pic Width/Height Change (%d,%d)=>(%d,%d)\n",
- hw->frame_width, hw->frame_height,
- width,
- height);
- vmpeg4_get_ps_info(hw, width, height, interlace, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->v4l_params_parsed = false;
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- hw->eos = 1;
- flush_output(hw);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
-
- ret = 1;
- }
- }
-
- return ret;
-}
-
-static irqreturn_t vmpeg4_isr_thread_fn(struct vdec_s *vdec, int irq)
-{
- u32 reg;
- u32 picture_type;
- int index;
- u32 pts, offset = 0;
- u64 pts_us64 = 0;
- u32 frame_size, dec_w, dec_h;
- u32 time_increment_resolution, fixed_vop_rate, vop_time_inc, vos_info;
- u32 repeat_cnt, duration = 3200;
- struct pic_info_t *dec_pic, *disp_pic;
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)(vdec->private);
- if (hw->eos)
- return IRQ_HANDLED;
-
- if (READ_VREG(MP4_PIC_INFO) == 1) {
- if (hw->is_used_v4l) {
- int frame_width = READ_VREG(MP4_PIC_WH)>> 16;
- int frame_height = READ_VREG(MP4_PIC_WH) & 0xffff;
- int interlace = (READ_VREG(MP4_PIC_RATIO) & 0x80000000) >> 31;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "interlace = %d\n", interlace);
- if (!v4l_res_change(hw, frame_width, frame_height, interlace)) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
-
- vmpeg4_get_ps_info(hw, frame_width, frame_height, interlace, &ps);
- hw->v4l_params_parsed = true;
- vdec_v4l_set_ps_infos(ctx, &ps);
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- } else {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- WRITE_VREG(MP4_PIC_INFO, 0);
-
- hw->res_ch_flag = 0;
- }
- } else {
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- }
- } else
- WRITE_VREG(MP4_PIC_INFO, 0);
- return IRQ_HANDLED;
- }
-
- if ((hw->is_used_v4l) && !hw->v4l_params_parsed) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "The head was not found, can not to decode\n");
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
-
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
- if (READ_VREG(AV_SCRATCH_M) != 0 &&
- (debug_enable & PRINT_FLAG_UCODE_DETAIL)) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_UCODE_DETAIL,
- "dbg %x: %x, level %x, wp %x, rp %x, cnt %x\n",
- READ_VREG(AV_SCRATCH_M), READ_VREG(AV_SCRATCH_N),
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- READ_VREG(VIFF_BIT_CNT));
- WRITE_VREG(AV_SCRATCH_M, 0);
- return IRQ_HANDLED;
- }
- reg = READ_VREG(MREG_BUFFEROUT);
-
- ATRACE_COUNTER("V_ST_DEC-decode_state", reg);
-
- time_increment_resolution = READ_VREG(MP4_RATE);
- fixed_vop_rate = time_increment_resolution >> 16;
- time_increment_resolution &= 0xffff;
- if (time_increment_resolution > 0 &&
- fixed_vop_rate == 0)
- hw->sys_mp4_rate = time_increment_resolution;
-
- if (hw->vmpeg4_amstream_dec_info.rate == 0) {
- if ((fixed_vop_rate != 0) &&
- (time_increment_resolution != 0)) {
- hw->vmpeg4_amstream_dec_info.rate = fixed_vop_rate *
- DURATION_UNIT / time_increment_resolution;
- } else if (time_increment_resolution == 0
- && hw->sys_mp4_rate > 0)
- time_increment_resolution = hw->sys_mp4_rate;
- }
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "time_inc_res = %d, fixed_vop_rate = %d, rate = %d\n",
- time_increment_resolution, fixed_vop_rate,
- hw->vmpeg4_amstream_dec_info.rate);
-
- if (reg == 2) {
- /* timeout when decoding next frame */
-
- /* for frame based case, insufficient result may happen
- * at the beginning when only VOL head is available save
- * HW context also, such as for the QTable from VCOP register
- */
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FLAG_VLD_DETAIL,
- "%s, level = %x, vfifo_ctrl = %x, bitcnt = %d\n",
- __func__,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_CONTROL),
- READ_VREG(VIFF_BIT_CNT));
-
- if (vdec_frame_based(vdec)) {
- vmpeg4_save_hw_context(hw);
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
- } else {
- reset_process_time(hw);
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- }
- return IRQ_HANDLED;
- } else {
- reset_process_time(hw);
- picture_type = (reg >> 3) & 7;
- repeat_cnt = READ_VREG(MP4_NOT_CODED_CNT);
- vop_time_inc = READ_VREG(MP4_VOP_TIME_INC);
- vos_info = READ_VREG(MP4_VOS_INFO);
- if ((vos_info & 0xff) &&
- (((vos_info >> 4) & 0xf) != hw->profile_idc ||
- (vos_info & 0xf) != hw->level_idc)) {
- hw->profile_idc = vos_info >> 4 & 0xf;
- hw->level_idc = vos_info & 0xf;
- vdec_set_profile_level(vdec, hw->profile_idc, hw->level_idc);
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_DEC_DETAIL,
- "profile_idc: %d level_idc: %d\n",
- hw->profile_idc, hw->level_idc);
- }
-
- index = spec_to_index(hw, READ_VREG(REC_CANVAS_ADDR));
- if (index < 0) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "invalid buffer index %d. rec = %x\n",
- index, READ_VREG(REC_CANVAS_ADDR));
- hw->dec_result = DEC_RESULT_ERROR;
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- hw->dec_result = DEC_RESULT_DONE;
- dec_pic = &hw->pic[index];
- if (vdec->mvfrm) {
- dec_pic->frame_size = vdec->mvfrm->frame_size;
- dec_pic->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- }
- dec_pic->pts_valid = false;
- dec_pic->pts = 0;
- dec_pic->pts64 = 0;
- dec_pic->timestamp = 0;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "new pic: index=%d, used=%d, repeat=%d, time_inc=%d\n",
- index, hw->vfbuf_use[index], repeat_cnt, vop_time_inc);
-
- dec_w = READ_VREG(MP4_PIC_WH)>> 16;
- dec_h = READ_VREG(MP4_PIC_WH) & 0xffff;
- if (dec_w != 0) {
- hw->frame_width = dec_w;
- dec_pic->width = dec_w;
- }
- if (dec_h != 0) {
- hw->frame_height = dec_h;
- dec_pic->height = dec_h;
- }
- hw->res_ch_flag = 0;
-
- if (hw->vmpeg4_amstream_dec_info.rate == 0) {
- if (vop_time_inc < hw->last_vop_time_inc) {
- duration = vop_time_inc +
- time_increment_resolution -
- hw->last_vop_time_inc;
- } else {
- duration = vop_time_inc -
- hw->last_vop_time_inc;
- }
-
- if (duration == hw->last_duration) {
- hw->rate_detect++;
- if ((hw->rate_detect >= RATE_DETECT_COUNT) &&
- (time_increment_resolution != 0)) {
- hw->vmpeg4_amstream_dec_info.rate =
- duration * DURATION_UNIT /
- time_increment_resolution;
- duration =
- hw->vmpeg4_amstream_dec_info.rate;
- }
- } else {
- hw->rate_detect = 0;
- hw->last_duration = duration;
- }
- if (MPEG4_VALID_DUR(duration)) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "warn: duration %x, set 0\n", duration);
- duration = 0;
- }
- } else {
- duration = hw->vmpeg4_amstream_dec_info.rate;
-#if 0
- pr_info("info rate = %d, ucode rate = 0x%x:0x%x\n",
- hw->vmpeg4_amstream_dec_info.rate,
- READ_VREG(MP4_RATE), vop_time_inc);
-#endif
- }
-
- /* frame mode with unstable pts */
- if (hw->unstable_pts && hw->chunk) {
- dec_pic->pts_valid = hw->chunk->pts_valid;
- dec_pic->pts = hw->chunk->pts;
- dec_pic->pts64 = hw->chunk->pts64;
- dec_pic->timestamp = hw->chunk->timestamp;
- if ((B_PICTURE == picture_type) ||
- (hw->last_dec_pts == dec_pic->pts))
- dec_pic->pts_valid = 0;
-
- hw->last_dec_pts = dec_pic->pts;
- } else if ((I_PICTURE == picture_type) ||
- (P_PICTURE == picture_type)) {
- offset = READ_VREG(MP4_OFFSET_REG);
- if (hw->chunk) {
- dec_pic->pts_valid = hw->chunk->pts_valid;
- dec_pic->pts = hw->chunk->pts;
- dec_pic->pts64 = hw->chunk->pts64;
- dec_pic->timestamp = hw->chunk->timestamp;
- } else {
- dec_pic->offset = offset;
- if ((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset,
- &pts, &frame_size, 3000, &pts_us64) == 0) {
- dec_pic->pts_valid = true;
- dec_pic->pts = pts;
- dec_pic->pts64 = pts_us64;
- hw->pts_hit++;
- } else {
- dec_pic->pts_valid = false;
- hw->pts_missed++;
- }
- }
- }
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "%c, offset=0x%x, pts=0x%x(%d), index=%d, used=%d\n",
- GET_PIC_TYPE(picture_type), offset, dec_pic->pts,
- dec_pic->pts_valid, index, hw->vfbuf_use[index]);
- } else if (B_PICTURE == picture_type) {
- if (hw->chunk) {
- dec_pic->pts_valid = hw->chunk->pts_valid;
- dec_pic->pts = hw->chunk->pts;
- dec_pic->pts64 = hw->chunk->pts64;
- dec_pic->timestamp = hw->chunk->timestamp;
- }
- }
-
- dec_pic->index = index;
- dec_pic->pic_info = reg;
- dec_pic->pic_type = picture_type;
- dec_pic->duration = duration;
- hw->vfbuf_use[index] = 0;
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "mmpeg4: pic_num: %d, index %d, type %c, pts %x\n",
- hw->frame_num, index,
- GET_PIC_TYPE(picture_type),
- dec_pic->pts);
-
- /* buffer management */
- if ((picture_type == I_PICTURE) ||
- (picture_type == P_PICTURE)) {
- index = update_ref(hw, index);
- } else {
- /* drop B frame or disp immediately.
- * depend on if there are two ref frames
- */
- if (hw->refs[1] == -1)
- index = -1;
- }
- vmpeg4_save_hw_context(hw);
- if (index < 0) {
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- disp_pic = &hw->pic[index];
- if ((hw->first_i_frame_ready == 0) &&
- (I_PICTURE == disp_pic->pic_type))
- hw->first_i_frame_ready = 1;
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "disp: index=%d, pts=%x(%d), used=%d, picout=%c(dec=%c)\n",
- index, disp_pic->pts, disp_pic->pts_valid,
- hw->vfbuf_use[index],
- GET_PIC_TYPE(disp_pic->pic_type),
- GET_PIC_TYPE(picture_type));
-
- if (disp_pic->pts_valid) {
- hw->last_anch_pts = disp_pic->pts;
- hw->last_anch_pts_us64 = disp_pic->pts64;
- hw->frame_num_since_last_anch = 0;
- hw->vop_time_inc_since_last_anch = 0;
- } else if (vdec_stream_based(vdec)) {
- disp_pic->pts = hw->last_anch_pts;
- disp_pic->pts64 = hw->last_anch_pts_us64;
-
- if ((time_increment_resolution != 0) &&
- (fixed_vop_rate == 0) &&
- (hw->vmpeg4_amstream_dec_info.rate == 0)) {
- /* variable PTS rate */
- /*bug on variable pts calc,
- *do as dixed vop first if we
- *have rate setting before.
- */
- if (vop_time_inc > hw->last_vop_time_inc) {
- duration = vop_time_inc -
- hw->last_vop_time_inc;
- } else {
- duration = vop_time_inc +
- time_increment_resolution -
- hw->last_vop_time_inc;
- }
-
- hw->vop_time_inc_since_last_anch += duration;
-
- disp_pic->pts += hw->vop_time_inc_since_last_anch *
- PTS_UNIT / time_increment_resolution;
- disp_pic->pts64 += (hw->vop_time_inc_since_last_anch *
- PTS_UNIT / time_increment_resolution) *
- 100 / 9;
-
- if (hw->vop_time_inc_since_last_anch >
- (1 << 14)) {
- /* avoid overflow */
- hw->last_anch_pts = disp_pic->pts;
- hw->last_anch_pts_us64 = disp_pic->pts64;
- hw->vop_time_inc_since_last_anch = 0;
- }
- } else {
- /* fixed VOP rate */
- hw->frame_num_since_last_anch++;
- disp_pic->pts += DUR2PTS(hw->frame_num_since_last_anch *
- hw->vmpeg4_amstream_dec_info.rate);
- disp_pic->pts64 += DUR2PTS(
- hw->frame_num_since_last_anch *
- hw->vmpeg4_amstream_dec_info.rate) * 100 / 9;
-
- if (hw->frame_num_since_last_anch > (1 << 15)) {
- /* avoid overflow */
- hw->last_anch_pts = disp_pic->pts;
- hw->last_anch_pts_us64 = disp_pic->pts64;
- hw->frame_num_since_last_anch = 0;
- }
- }
- } else if (hw->unstable_pts && hw->chunk &&
- MPEG4_VALID_DUR(duration)) {
- /* invalid pts calc */
- hw->frame_num_since_last_anch = hw->chunk_frame_count;
- disp_pic->pts = hw->last_anch_pts +
- DUR2PTS(hw->frame_num_since_last_anch *
- duration);
- disp_pic->pts64 = hw->last_anch_pts_us64 +
- DUR2PTS(hw->frame_num_since_last_anch *
- duration) * 100 / 9;
-
- if (hw->frame_num_since_last_anch > (1 << 15)) {
- /* avoid overflow */
- hw->last_anch_pts = disp_pic->pts;
- hw->last_anch_pts_us64 = disp_pic->pts64;
- hw->frame_num_since_last_anch = 0;
- } else
- disp_pic->pts_valid = 1;
- }
-
- if (vdec_frame_based(vdec) &&
- (hw->unstable_pts) &&
- MPEG4_VALID_DUR(duration)) {
-
- u32 threshold = DUR2PTS(duration) >> 3;
-
- if (disp_pic->pts <= (hw->last_pts + threshold)) {
- disp_pic->pts = hw->last_pts + DUR2PTS(duration);
- disp_pic->pts64 = hw->last_pts64 +
- (DUR2PTS(duration)*100/9);
- }
- if (!disp_pic->pts_valid) {
- disp_pic->pts = 0;
- disp_pic->pts64 = 0;
- disp_pic->timestamp = 0;
- }
- }
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO,
- "disp: pic_type %c, pts %d(%lld), diff %d, cnt %d, disp_pic->timestamp %llu\n",
- GET_PIC_TYPE(disp_pic->pic_type),
- disp_pic->pts,
- disp_pic->pts64,
- disp_pic->pts - hw->last_pts,
- hw->chunk_frame_count,
- disp_pic->timestamp);
- hw->last_pts = disp_pic->pts;
- hw->last_pts64 = disp_pic->pts64;
- hw->frame_dur = duration;
- disp_pic->duration = duration;
- disp_pic->repeat_cnt = repeat_cnt;
-
- prepare_display_buf(hw, disp_pic);
-
- hw->total_frame += repeat_cnt + 1;
- hw->last_vop_time_inc = vop_time_inc;
-
- if (vdec_frame_based(vdec) &&
- (frmbase_cont_bitlevel != 0) &&
- (hw->first_i_frame_ready)) {
- u32 consume_byte, res_byte, bitcnt;
-
- bitcnt = READ_VREG(VIFF_BIT_CNT);
- res_byte = bitcnt >> 3;
-
- if (hw->chunk_size > res_byte) {
- if (bitcnt > frmbase_cont_bitlevel) {
- consume_byte = hw->chunk_size - res_byte;
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s, size %d, consume %d, res %d\n", __func__,
- hw->chunk_size, consume_byte, res_byte);
-
- if (consume_byte > VDEC_FIFO_ALIGN) {
- consume_byte -= VDEC_FIFO_ALIGN;
- res_byte += VDEC_FIFO_ALIGN;
- }
- hw->chunk_offset += consume_byte;
- hw->chunk_size = res_byte;
- hw->dec_result = DEC_RESULT_UNFINISH;
- hw->chunk_frame_count++;
- hw->unstable_pts = 1;
- } else {
- hw->chunk_size = 0;
- hw->chunk_offset = 0;
- }
- } else {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "error: bitbyte %d hw->chunk_size %d\n", res_byte, hw->chunk_size);
- hw->chunk_size = 0;
- hw->chunk_offset = 0;
- }
- }
- vdec_schedule_work(&hw->work);
- }
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FRAME_NUM,
- "%s: frame num:%d\n", __func__, hw->frame_num);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t vmpeg4_isr(struct vdec_s *vdec, int irq)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)(vdec->private);
-
- if (hw->eos)
- return IRQ_HANDLED;
-
- return IRQ_WAKE_THREAD;
-}
-
-static void flush_output(struct vdec_mpeg4_hw_s * hw)
-{
- struct pic_info_t *pic;
-
- if (hw->vfbuf_use[hw->refs[1]] > 0) {
- pic = &hw->pic[hw->refs[1]];
- prepare_display_buf(hw, pic);
- }
-}
-
-static bool is_avaliable_buffer(struct vdec_mpeg4_hw_s *hw);
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] MPEG4 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = find_free_buffer(hw);
- if (INVALID_IDX == index) {
- pr_err("[%d] MPEG4 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->pic[index].v4l_ref_buf_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->v4l_mem_handle = (ulong)fb;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- ATRACE_COUNTER(hw->pts_name, vf->timestamp);
-
- pr_info("[%d] mpeg4 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void vmpeg4_work(struct work_struct *work)
-{
- struct vdec_mpeg4_hw_s *hw =
- container_of(work, struct vdec_mpeg4_hw_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
-
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- if (hw->dec_result != DEC_RESULT_DONE)
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "vmpeg4_work: result=%d,status=%d\n",
- hw->dec_result, hw_to_vdec(hw)->next_status);
-
- ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result);
-
- if (hw->dec_result == DEC_RESULT_UNFINISH) {
- if (!hw->ctx_valid)
- hw->ctx_valid = 1;
-
- } else if ((hw->dec_result == DEC_RESULT_DONE) ||
- ((!hw->is_used_v4l) && (input_frame_based(&vdec->input)) && hw->chunk)) {
- if (!hw->ctx_valid)
- hw->ctx_valid = 1;
-
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk = NULL;
- } else if (hw->dec_result == DEC_RESULT_AGAIN
- && (vdec->next_status != VDEC_STATUS_DISCONNECTED)) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "%s: force exit\n", __func__);
- if (hw->stat & STAT_ISR_REG) {
- amvdec_stop();
- vdec_free_irq(VDEC_IRQ_1, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- hw->eos = 1;
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk = NULL;
- vdec_clean_input(vdec);
- flush_output(hw);
-
- if (hw->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(vdec);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s: eos flushed, frame_num %d\n",
- __func__, hw->frame_num);
- } else if (hw->dec_result == DEC_RESULT_ERROR_SZIE) {
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- } else {
- vdec_vframe_dirty(vdec, hw->chunk);
- hw->chunk = NULL;
- }
- }
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- /*disable mbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 0);
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hw->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1);
- else
- vdec_core_finish_run(vdec, CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- wake_up_interruptible(&hw->wait_q);
- if (hw->vdec_cb)
- hw->vdec_cb(vdec, hw->vdec_cb_arg);
-}
-
-static struct vframe_s *vmpeg_vf_peek(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
-
- if (!hw)
- return NULL;
- atomic_add(1, &hw->peek_num);
- if (kfifo_peek(&hw->display_q, &vf))
- return vf;
-
- return NULL;
-}
-
-static struct vframe_s *vmpeg_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
-
- if (kfifo_get(&hw->display_q, &vf)) {
- vf->index_disp = atomic_read(&hw->get_num);
- atomic_add(1, &hw->get_num);
- ATRACE_COUNTER(hw->disp_q_name, kfifo_len(&hw->display_q));
- return vf;
- }
- return NULL;
-}
-
-static int valid_vf_check(struct vframe_s *vf, struct vdec_mpeg4_hw_s *hw)
-{
- int i;
-
- if (!vf || (vf->index == -1))
- return 0;
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (vf == &hw->vfpool[i])
- return 1;
- }
-
- return 0;
-}
-
-
-static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
- unsigned long flags;
-
- if (!valid_vf_check(vf, hw)) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
- "invalid vf: %lx\n", (ulong)vf);
- return ;
- }
-
- if (vf->v4l_mem_handle !=
- hw->pic[vf->index].v4l_ref_buf_addr) {
- hw->pic[vf->index].v4l_ref_buf_addr
- = vf->v4l_mem_handle;
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
- "MPEG4 update fb handle, old:%llx, new:%llx\n",
- hw->pic[vf->index].v4l_ref_buf_addr,
- vf->v4l_mem_handle);
- }
-
- hw->vfbuf_use[vf->index]--;
- atomic_add(1, &hw->put_num);
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FRAME_NUM,
- "%s: put num:%d\n",__func__, hw->put_num);
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_BUFFER_DETAIL,
- "index=%d, used=%d\n", vf->index, hw->vfbuf_use[vf->index]);
- spin_lock_irqsave(&hw->lock, flags);
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- spin_unlock_irqrestore(&hw->lock, flags);
- ATRACE_COUNTER(hw->new_q_name, kfifo_len(&hw->newframe_q));
-}
-
-static int vmpeg_event_cb(int type, void *data, void *op_arg)
-{
- struct vdec_s *vdec = op_arg;
-
- if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(vdec);
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-static int vmpeg_vf_states(struct vframe_states *states, void *op_arg)
-{
- unsigned long flags;
- struct vdec_s *vdec = op_arg;
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
-
- spin_lock_irqsave(&hw->lock, flags);
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
- states->buf_recycle_num = 0;
-
- spin_unlock_irqrestore(&hw->lock, flags);
-
- return 0;
-}
-
-
-static int dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)vdec->private;
-
- if (!hw)
- return -1;
-
- vstatus->frame_width = hw->frame_width;
- vstatus->frame_height = hw->frame_height;
- if (0 != hw->vmpeg4_amstream_dec_info.rate)
- vstatus->frame_rate = ((DURATION_UNIT * 10 / hw->vmpeg4_amstream_dec_info.rate) % 10) < 5 ?
- DURATION_UNIT / hw->vmpeg4_amstream_dec_info.rate : (DURATION_UNIT / hw->vmpeg4_amstream_dec_info.rate +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = READ_VREG(MP4_ERR_COUNT);
- vstatus->status = hw->stat;
- vstatus->frame_dur = hw->frame_dur;
- vstatus->error_frame_count = READ_VREG(MP4_ERR_COUNT);
- vstatus->drop_frame_count = hw->drop_frame_count;
- vstatus->frame_count =hw->frame_num;
- vstatus->i_decoded_frames = hw->i_decoded_frames;
- vstatus->i_lost_frames = hw->i_lost_frames;
- vstatus->i_concealed_frames = hw->i_concealed_frames;
- vstatus->p_decoded_frames = hw->p_decoded_frames;
- vstatus->p_lost_frames = hw->p_lost_frames;
- vstatus->p_concealed_frames = hw->p_concealed_frames;
- vstatus->b_decoded_frames = hw->b_decoded_frames;
- vstatus->b_lost_frames = hw->b_lost_frames;
- vstatus->b_concealed_frames = hw->b_concealed_frames;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
-
- return 0;
-}
-
-/****************************************/
-static int vmpeg4_workspace_init(struct vdec_mpeg4_hw_s *hw)
-{
- int ret;
- void *buf = NULL;
-
- ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle,
- DECODE_BUFFER_NUM_MAX,
- WORKSPACE_SIZE,
- DRIVER_NAME,
- &hw->buf_start);
- if (ret < 0) {
- pr_err("mpeg4 workspace alloc size %d failed.\n",
- WORKSPACE_SIZE);
- return ret;
- }
-
- /* notify ucode the buffer start address */
- buf = codec_mm_vmap(hw->buf_start, WORKSPACE_SIZE);
- if (buf) {
- memset(buf, 0, WORKSPACE_SIZE);
- codec_mm_dma_flush(buf,
- WORKSPACE_SIZE, DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(buf);
- }
-
- WRITE_VREG(MEM_OFFSET_REG, hw->buf_start);
-
- return 0;
-}
-
-static void vmpeg4_dump_state(struct vdec_s *vdec)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)(vdec->private);
- u32 i;
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "====== %s\n", __func__);
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "width/height (%d/%d), i_fram:%d, buffer_not_ready %d, buf_num %d\n",
- hw->frame_width,
- hw->frame_height,
- hw->first_i_frame_ready,
- hw->buffer_not_ready,
- hw->buf_num
- );
- for (i = 0; i < hw->buf_num; i++) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "index %d, used %d\n", i, hw->vfbuf_use[i]);
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "is_framebase(%d), eos %d, state 0x%x, dec_result 0x%x dec_frm %d\n",
- vdec_frame_based(vdec),
- hw->eos,
- hw->stat,
- hw->dec_result,
- hw->frame_num
- );
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "is_framebase(%d), put_frm %d run %d not_run_ready %d input_empty %d,drop %d\n",
- vdec_frame_based(vdec),
- hw->put_num,
- hw->run_count,
- hw->not_run_ready,
- hw->input_empty,
- hw->drop_frame_count
- );
-
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s, newq(%d/%d), dispq(%d/%d) vf peek/get/put (%d/%d/%d)\n",
- __func__,
- kfifo_len(&hw->newframe_q), VF_POOL_SIZE,
- kfifo_len(&hw->display_q), VF_POOL_SIZE,
- hw->peek_num, hw->get_num, hw->put_num
- );
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "VIFF_BIT_CNT=0x%x\n",
- READ_VREG(VIFF_BIT_CNT));
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_LEVEL=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_LEVEL));
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_WP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_WP));
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "VLD_MEM_VIFIFO_RP=0x%x\n",
- READ_VREG(VLD_MEM_VIFIFO_RP));
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (vdec_frame_based(vdec) &&
- debug_enable & PRINT_FRAMEBASE_DATA) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, hw->chunk->size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "frame data size 0x%x\n",
- hw->chunk->size);
- for (jj = 0; jj < hw->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-}
-
-static void reset_process_time(struct vdec_mpeg4_hw_s *hw)
-{
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[DECODE_ID(hw)])
- max_process_time[DECODE_ID(hw)] = process_time;
- }
-}
-static void start_process_time(struct vdec_mpeg4_hw_s *hw)
-{
- hw->decode_timeout_count = 2;
- hw->start_process_time = jiffies;
-}
-
-static void timeout_process(struct vdec_mpeg4_hw_s *hw)
-{
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s decoder timeout %d\n", __func__, hw->timeout_cnt);
- if (vdec_frame_based((hw_to_vdec(hw)))) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s frame_num %d, chunk size 0x%x, chksum 0x%x\n",
- __func__,
- hw->frame_num,
- hw->chunk->size,
- get_data_check_sum(hw, hw->chunk->size));
- }
- hw->timeout_cnt++;
- /* timeout: data droped, frame_num inaccurate*/
- hw->frame_num++;
- reset_process_time(hw);
- hw->first_i_frame_ready = 0;
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
-}
-
-
-static void check_timer_func(struct timer_list *timer)
-{
- struct vdec_mpeg4_hw_s *hw = container_of(timer,
- struct vdec_mpeg4_hw_s, check_timer);
- unsigned int timeout_val = decode_timeout_val;
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
-
- if (((debug_enable & PRINT_FLAG_TIMEOUT_STATUS) == 0) &&
- (timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > timeout_val)) {
- if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0)
- timeout_process(hw);
- }
- hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
- }
-
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw)
-{
- int index;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- int i;
-
- if (!hw->init_flag)
- vmpeg4_workspace_init(hw);
-
- if (hw->v4l_params_parsed) {
- struct vdec_pic_info pic;
-
- if (!hw->buf_num) {
- vdec_v4l_get_pic_info(v4l2_ctx, &pic);
- hw->buf_num = pic.dpb_frames +
- pic.dpb_margin;
- if (hw->buf_num > DECODE_BUFFER_NUM_MAX)
- hw->buf_num = DECODE_BUFFER_NUM_MAX;
- }
-
- index = find_free_buffer(hw);
- if ((index < 0) || (index >= hw->buf_num))
- return -1;
-
- WRITE_VREG(MEM_OFFSET_REG, hw->buf_start);
-
- for (i = 0; i < hw->buf_num; i++) {
- if (hw->pic[i].v4l_ref_buf_addr) {
- config_cav_lut(canvas_y(hw->canvas_spec[i]),
- &hw->canvas_config[i][0], VDEC_1);
- config_cav_lut(canvas_u(hw->canvas_spec[i]),
- &hw->canvas_config[i][1], VDEC_1);
- }
- }
-
- /* prepare REF0 & REF1
- * points to the past two IP buffers
- * prepare REC_CANVAS_ADDR and ANC2_CANVAS_ADDR
- * points to the output buffer
- */
- if (hw->refs[0] == -1) {
- WRITE_VREG(MREG_REF0, (hw->refs[1] == -1) ? 0xffffffff :
- hw->canvas_spec[hw->refs[1]]);
- } else {
- WRITE_VREG(MREG_REF0, hw->canvas_spec[hw->refs[0]]);
- }
- WRITE_VREG(MREG_REF1, (hw->refs[1] == -1) ? 0xffffffff :
- hw->canvas_spec[hw->refs[1]]);
- if ((hw->is_used_v4l) && (index == 0xffffff)) {
- WRITE_VREG(REC_CANVAS_ADDR, 0xffffff);
- WRITE_VREG(ANC2_CANVAS_ADDR, 0xffffff);
- } else {
- WRITE_VREG(REC_CANVAS_ADDR, hw->canvas_spec[index]);
- WRITE_VREG(ANC2_CANVAS_ADDR, hw->canvas_spec[index]);
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RESTORE,
- "restore ref0=0x%x, ref1=0x%x, rec=0x%x, ctx_valid=%d,index=%d\n",
- READ_VREG(MREG_REF0),
- READ_VREG(MREG_REF1),
- READ_VREG(REC_CANVAS_ADDR),
- hw->ctx_valid, index);
- }
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(PSCALE_CTRL, 0);
-
- WRITE_VREG(MREG_BUFFEROUT, 0x10000);
-
- /* clear mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(ASSIST_MBOX1_MASK, 1);
-
- /* clear repeat count */
- WRITE_VREG(MP4_NOT_CODED_CNT, 0);
-
-#ifdef NV21
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
-
- /* cbcr_merge_swap_en */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- } else {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- else
- CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 16);
- }
-
-#if 1/* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
- WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
-#endif
-
- WRITE_VREG(MP4_PIC_WH, (hw->ctx_valid) ?
- hw->reg_mp4_pic_wh :
- ((hw->frame_width << 16) | hw->frame_height));
- WRITE_VREG(MP4_SYS_RATE, hw->vmpeg4_amstream_dec_info.rate);
-
- if (hw->ctx_valid) {
- WRITE_VREG(DC_AC_CTRL, hw->reg_dc_ac_ctrl);
- WRITE_VREG(IQIDCT_CONTROL, hw->reg_iqidct_control);
- WRITE_VREG(RESYNC_MARKER_LENGTH, hw->reg_resync_marker_length);
- WRITE_VREG(RV_AI_MB_COUNT, hw->reg_rv_ai_mb_count);
- }
- WRITE_VREG(MPEG1_2_REG, (hw->ctx_valid) ? hw->reg_mpeg1_2_reg : 1);
- WRITE_VREG(VCOP_CTRL_REG, hw->reg_vcop_ctrl_reg);
- WRITE_VREG(PIC_HEAD_INFO, hw->reg_pic_head_info);
- WRITE_VREG(SLICE_QP, hw->reg_slice_qp);
- WRITE_VREG(MB_INFO, hw->reg_mb_info);
-
- if (vdec_frame_based(hw_to_vdec(hw)) && hw->chunk) {
- /* frame based input */
- WRITE_VREG(MREG_INPUT, (hw->chunk->offset & 7) | (1<<7) |
- (hw->ctx_valid<<6));
- } else {
- /* stream based input */
- WRITE_VREG(MREG_INPUT, (hw->ctx_valid<<6));
- }
-
- return 0;
-}
-
-static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw)
-{
- int i;
-
- hw->vmpeg4_ratio = hw->vmpeg4_amstream_dec_info.ratio;
-
- hw->vmpeg4_ratio64 = hw->vmpeg4_amstream_dec_info.ratio64;
-
- hw->vmpeg4_rotation =
- (((unsigned long)hw->vmpeg4_amstream_dec_info.param) >> 16) & 0xffff;
- hw->sys_mp4_rate = hw->vmpeg4_amstream_dec_info.rate;
- if (hw->is_used_v4l) {
- hw->frame_width = 0;
- hw->frame_height = 0;
- } else {
- hw->frame_width = hw->vmpeg4_amstream_dec_info.width;
- hw->frame_height = hw->vmpeg4_amstream_dec_info.height;
- }
-
- hw->frame_dur = 0;
- hw->frame_prog = 0;
- hw->unstable_pts =
- (((unsigned long) hw->vmpeg4_amstream_dec_info.param & 0x40) >> 6);
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "param = 0x%x unstable_pts = %d\n",
- hw->vmpeg4_amstream_dec_info.param,
- hw->unstable_pts);
- hw->last_dec_pts = -1;
-
- hw->total_frame = 0;
-
- hw->last_anch_pts = 0;
-
- hw->last_anch_pts_us64 = 0;
-
- hw->last_vop_time_inc = hw->last_duration = 0;
-
- hw->vop_time_inc_since_last_anch = 0;
- hw->last_pts = 0;
- hw->last_pts64 = 0;
- hw->frame_num_since_last_anch = 0;
- hw->frame_num = 0;
- hw->run_count = 0;
- hw->not_run_ready = 0;
- hw->input_empty = 0;
- atomic_set(&hw->peek_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->put_num, 0);
-
- hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0;
- hw->refs[0] = -1;
- hw->refs[1] = -1;
- hw->first_i_frame_ready = 0;
- hw->drop_frame_count = 0;
- hw->buffer_not_ready = 0;
- hw->init_flag = 0;
- hw->dec_result = DEC_RESULT_NONE;
- hw->timeout_cnt = 0;
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->vfbuf_use[i] = 0;
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- hw->vfpool[i].index = DECODE_BUFFER_NUM_MAX;
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- }
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
- hw->mm_blk_handle = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- 0,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER);
-
- INIT_WORK(&hw->work, vmpeg4_work);
-
- init_waitqueue_head(&hw->wait_q);
-}
-
-static s32 vmmpeg4_init(struct vdec_mpeg4_hw_s *hw)
-{
- int trickmode_fffb = 0;
- int size = -1, fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- if (hw->vmpeg4_amstream_dec_info.format ==
- VIDEO_DEC_FORMAT_MPEG4_5) {
- size = get_firmware_data(VIDEO_DEC_MPEG4_5_MULTI, fw->data);
- strncpy(fw->name, "mmpeg4_mc_5", sizeof(fw->name));
- } else if (hw->vmpeg4_amstream_dec_info.format ==
- VIDEO_DEC_FORMAT_H263) {
- size = get_firmware_data(VIDEO_DEC_H263_MULTI, fw->data);
- strncpy(fw->name, "mh263_mc", sizeof(fw->name));
- } else
- pr_err("unsupport mpeg4 sub format %d\n",
- hw->vmpeg4_amstream_dec_info.format);
- pr_info("mmpeg4 get fw %s, size %x\n", fw->name, size);
- if (size < 0) {
- pr_err("get firmware failed.");
- vfree(fw);
- return -1;
- }
-
- fw->len = size;
- hw->fw = fw;
-
- query_video_status(0, &trickmode_fffb);
-
- pr_info("%s\n", __func__);
-
- //amvdec_enable();
-
- timer_setup(&hw->check_timer, check_timer_func, 0);
- //init_timer(&hw->check_timer);
- //hw->check_timer.data = (unsigned long)hw;
- //hw->check_timer.function = check_timer_func;
- hw->check_timer.expires = jiffies + CHECK_INTERVAL;
- hw->stat |= STAT_TIMER_ARM;
- hw->eos = 0;
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-
- vmpeg4_local_init(hw);
- wmb();
-
- return 0;
-}
-
-static bool is_avaliable_buffer(struct vdec_mpeg4_hw_s *hw)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_count = 0;
- int used_count = 0;
-
- if ((hw->buf_num == 0) ||
- (ctx->cap_pool.dec < hw->buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hw->buf_num; ++i) {
- if ((hw->vfbuf_use[i] == 0) &&
- hw->pic[i].v4l_ref_buf_addr) {
- free_count++;
- } else if (hw->pic[i].v4l_ref_buf_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)vdec->private;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int ret = 0;
-
- if (hw->eos)
- return 0;
-
- if (vdec_stream_based(vdec) && (hw->init_flag == 0)
- && pre_decode_buf_level != 0) {
- u32 rp, wp, level;
-
- rp = STBUF_READ(&vdec->vbuf, get_rp);
- wp = STBUF_READ(&vdec->vbuf, get_wp);
- if (wp < rp)
- level = vdec->input.size + wp - rp;
- else
- level = wp - rp;
- if (level < pre_decode_buf_level) {
- hw->not_run_ready++;
- return 0;
- }
- }
-
- if (hw->v4l_params_parsed) {
- ret = is_avaliable_buffer(hw) ? 1 : 0;
- } else {
- ret = ctx->v4l_resolution_change ? 0 : 1;
- }
-
- hw->not_run_ready = 0;
- hw->buffer_not_ready = 0;
-
- return ret ? CORE_MASK_VDEC_1 : 0;
-}
-
-static unsigned char get_data_check_sum
- (struct vdec_mpeg4_hw_s *hw, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk->offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct vdec_mpeg4_hw_s *hw = (struct vdec_mpeg4_hw_s *)vdec->private;
- int size = 0, ret = 0;
- if (!hw->vdec_pg_enable_flag) {
- hw->vdec_pg_enable_flag = 1;
- amvdec_enable();
- }
- hw->run_count++;
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
- vdec_reset_core(vdec);
-
- if ((vdec_frame_based(vdec)) &&
- (hw->dec_result == DEC_RESULT_UNFINISH)) {
- vmpeg4_prepare_input(hw);
- size = hw->chunk_size;
- } else {
- size = vdec_prepare_input(vdec, &hw->chunk);
- if (size < 4) { /*less than start code size 00 00 01 xx*/
- hw->input_empty++;
- hw->dec_result = DEC_RESULT_ERROR_SZIE;
- vdec_schedule_work(&hw->work);
- return;
- }
- if ((vdec_frame_based(vdec)) &&
- (hw->chunk != NULL)) {
- hw->chunk_offset = hw->chunk->offset;
- hw->chunk_size = hw->chunk->size;
- hw->chunk_frame_count = 0;
- }
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", size);
-
- if (vdec_frame_based(vdec) && !vdec_secure(vdec)) {
- /* HW needs padding (NAL start) for frame ending */
- char* tail = (char *)hw->chunk->block->start_virt;
-
- tail += hw->chunk->offset + hw->chunk->size;
- tail[0] = 0;
- tail[1] = 0;
- tail[2] = 1;
- tail[3] = 0xb6;
- codec_mm_dma_flush(tail, 4, DMA_TO_DEVICE);
- }
- if (vdec_frame_based(vdec) &&
- (debug_enable & 0xc00)) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->chunk_offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->chunk_offset;
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, get_data_check_sum(hw, size),
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
-
- if (debug_enable & PRINT_FRAMEBASE_DATA) {
- int jj;
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%06x:", jj);
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- mmpeg4_debug_print(DECODE_ID(hw),
- PRINT_FRAMEBASE_DATA,
- "\n");
- }
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "%s, size=%d, %x %x %x %x %x\n",
- __func__, size,
- READ_VREG(VLD_MEM_VIFIFO_LEVEL),
- READ_VREG(VLD_MEM_VIFIFO_WP),
- READ_VREG(VLD_MEM_VIFIFO_RP),
- STBUF_READ(&vdec->vbuf, get_rp),
- STBUF_READ(&vdec->vbuf, get_wp));
-
- hw->dec_result = DEC_RESULT_NONE;
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
- ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG4,hw->fw->name, vdec,
- hw->fw->data, hw->fw->len);
- if (ret < 0) {
- pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
- hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_MPEG4;
- }
- if (vmpeg4_hw_ctx_restore(hw) < 0) {
- hw->dec_result = DEC_RESULT_ERROR;
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "amvdec_mpeg4: error HW context restore\n");
- vdec_schedule_work(&hw->work);
- return;
- }
- if (vdec_frame_based(vdec)) {
- size = hw->chunk_size +
- (hw->chunk_offset & (VDEC_FIFO_ALIGN - 1));
- WRITE_VREG(VIFF_BIT_CNT, size * 8);
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hw->chunk->size;
- }
- hw->input_empty = 0;
- hw->last_vld_level = 0;
- start_process_time(hw);
- vdec_enable_input(vdec);
- /* wmb before ISR is handled */
- wmb();
-
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- amvdec_start();
- hw->stat |= STAT_VDEC_RUN;
- hw->stat |= STAT_TIMER_ARM;
- hw->init_flag = 1;
- mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
-}
-
-static int vmpeg4_stop(struct vdec_mpeg4_hw_s *hw)
-{
- cancel_work_sync(&hw->work);
-
- if (hw->mm_blk_handle) {
- decoder_bmmu_box_free(hw->mm_blk_handle);
- hw->mm_blk_handle = NULL;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->check_timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-
- if (hw->fw) {
- vfree(hw->fw);
- hw->fw = NULL;
- }
- return 0;
-}
-static void reset(struct vdec_s *vdec)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)vdec->private;
- int i;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amvdec_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- hw->dec_result = DEC_RESULT_NONE;
- flush_work(&hw->work);
- reset_process_time(hw);
-
- for (i = 0; i < hw->buf_num; i++) {
- hw->pic[i].v4l_ref_buf_addr = 0;
- hw->vfbuf_use[i] = 0;
- }
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- memset((void *)vf, 0, sizeof(*vf));
- hw->vfpool[i].index = -1;
- kfifo_put(&hw->newframe_q, vf);
- }
-
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
- vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
- hw->canvas_spec[i] = 0xffffff;
- }
-
- hw->refs[0] = -1;
- hw->refs[1] = -1;
- hw->ctx_valid = 0;
- hw->eos = 0;
- hw->buf_num = 0;
- hw->frame_width = 0;
- hw->frame_height = 0;
- hw->first_i_frame_ready = 0;
-
- atomic_set(&hw->peek_num, 0);
- atomic_set(&hw->get_num, 0);
- atomic_set(&hw->put_num, 0);
-
- pr_info("mpeg4: reset.\n");
-}
-
-static int vmpeg4_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)vdec->private;
- if (!hw)
- return 0;
-
- if (trickmode == TRICKMODE_I) {
- hw->i_only = 0x3;
- trickmode_i = 1;
- } else if (trickmode == TRICKMODE_NONE) {
- hw->i_only = 0x0;
- trickmode_i = 0;
- }
- return 0;
-}
-
-static int ammvdec_mpeg4_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- struct vdec_mpeg4_hw_s *hw = NULL;
- int config_val = 0;
-
- if (pdata == NULL) {
- pr_err("%s memory resource undefined.\n", __func__);
- return -EFAULT;
- }
-
- hw = vmalloc(sizeof(struct vdec_mpeg4_hw_s));
- if (hw == NULL) {
- pr_err("\namvdec_mpeg4 decoder driver alloc failed\n");
- return -ENOMEM;
- }
- memset(hw, 0, sizeof(struct vdec_mpeg4_hw_s));
-
- /* the ctx from v4l2 driver. */
- hw->v4l2_ctx = pdata->private;
-
- pdata->private = hw;
- pdata->dec_status = dec_status;
- /* pdata->set_trickmode = set_trickmode; */
- pdata->set_trickmode = vmpeg4_set_trickmode;
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vmpeg4_isr;
- pdata->threaded_irq_handler = vmpeg4_isr_thread_fn;
- pdata->dump_state = vmpeg4_dump_state;
-
- snprintf(hw->vdec_name, sizeof(hw->vdec_name),
- "mpeg4-%d", pdev->id);
- snprintf(hw->pts_name, sizeof(hw->pts_name),
- "%s-timestamp", hw->vdec_name);
- snprintf(hw->new_q_name, sizeof(hw->new_q_name),
- "%s-newframe_q", hw->vdec_name);
- snprintf(hw->disp_q_name, sizeof(hw->disp_q_name),
- "%s-dispframe_q", hw->vdec_name);
-
- if (pdata->use_vfm_path)
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- platform_set_drvdata(pdev, pdata);
- hw->platform_dev = pdev;
-
- if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) {
- mmpeg4_debug_print(DECODE_ID(hw), 0, "pdata->config: %s\n", pdata->config);
- if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin = config_val;
- else
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- } else {
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
- }
-
- if (pdata->parallel_dec == 1) {
- int i;
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++)
- hw->canvas_spec[i] = 0xffffff;
- }
-
- hw->blkmode = pdata->canvas_mode;
-
- if (pdata->sys_info) {
- hw->vmpeg4_amstream_dec_info = *pdata->sys_info;
- if ((hw->vmpeg4_amstream_dec_info.height != 0) &&
- (hw->vmpeg4_amstream_dec_info.width >
- (MAX_MPEG4_SUPPORT_SIZE/hw->vmpeg4_amstream_dec_info.height))) {
- pr_info("ammvdec_mpeg4: oversize, unsupport: %d*%d\n",
- hw->vmpeg4_amstream_dec_info.width,
- hw->vmpeg4_amstream_dec_info.height);
- pdata->dec_status = NULL;
- vfree((void *)hw);
- hw = NULL;
- return -EFAULT;
- }
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "sysinfo: %d x %d, rate: %d\n",
- hw->vmpeg4_amstream_dec_info.width,
- hw->vmpeg4_amstream_dec_info.height,
- hw->vmpeg4_amstream_dec_info.rate);
- }
- if (((debug_enable & IGNORE_PARAM_FROM_CONFIG) == 0) && pdata->config_len) {
- mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW,
- "pdata->config: %s\n", pdata->config);
- if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin = config_val;
- else
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
-
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hw->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hw->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hw->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hw->blkmode = config_val;
-
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
- } else
- hw->dynamic_buf_num_margin = dynamic_buf_num_margin;
-
- if (hw->is_used_v4l) {
- vf_provider_init(&pdata->vframe_provider,
- pdata->vf_provider_name, &vf_provider_ops, pdata);
- }
-
- if (vmmpeg4_init(hw) < 0) {
- pr_err("%s init failed.\n", __func__);
-
- if (hw) {
- vfree((void *)hw);
- hw = NULL;
- }
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- vdec_set_prepare_level(pdata, start_decode_buf_level);
-
- vdec_set_vframe_comm(pdata, DRIVER_NAME);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_VDEC_1);
- else {
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s end.\n", __func__);
- return 0;
-}
-
-static int ammvdec_mpeg4_remove(struct platform_device *pdev)
-{
- struct vdec_mpeg4_hw_s *hw =
- (struct vdec_mpeg4_hw_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int i;
-
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED
- && (vdec->status == VDEC_STATUS_ACTIVE)) {
- mmpeg4_debug_print(DECODE_ID(hw), 0,
- "%s force exit %d\n", __func__, __LINE__);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- wait_event_interruptible_timeout(hw->wait_q,
- (vdec->status == VDEC_STATUS_CONNECTED),
- msecs_to_jiffies(1000)); /* wait for work done */
- }
-
- vmpeg4_stop(hw);
-
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1);
- else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
- vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id);
- vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id);
- }
- }
-
- mmpeg4_debug_print(DECODE_ID(hw), 0, "%s\n", __func__);
- vfree((void *)hw);
- hw = NULL;
-
- return 0;
-}
-
-/****************************************/
-
-static struct platform_driver ammvdec_mpeg4_driver = {
- .probe = ammvdec_mpeg4_probe,
- .remove = ammvdec_mpeg4_remove,
-#ifdef CONFIG_PM
- .suspend = amvdec_suspend,
- .resume = amvdec_resume,
-#endif
- .driver = {
- .name = DRIVER_NAME,
- }
-};
-
-static struct codec_profile_t amvdec_mpeg4_profile = {
- .name = "MPEG4-V4L",
- .profile = ""
-};
-
-static int __init ammvdec_mpeg4_driver_init_module(void)
-{
- pr_info("%s \n", __func__);
-
- if (platform_driver_register(&ammvdec_mpeg4_driver)) {
- pr_err("failed to register ammvdec_mpeg4 driver\n");
- return -ENODEV;
- }
- vcodec_profile_register(&amvdec_mpeg4_profile);
- vcodec_feature_register(VFORMAT_MPEG4, 1);
- return 0;
-}
-
-static void __exit ammvdec_mpeg4_driver_remove_module(void)
-{
- pr_info("ammvdec_mpeg4 module remove.\n");
-
- platform_driver_unregister(&ammvdec_mpeg4_driver);
-}
-
-/****************************************/
-module_param(debug_enable, uint, 0664);
-MODULE_PARM_DESC(debug_enable,
- "\n ammvdec_mpeg4 debug enable\n");
-
-module_param(frmbase_cont_bitlevel, uint, 0664);
-MODULE_PARM_DESC(frmbase_cont_bitlevel, "\nfrmbase_cont_bitlevel\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\nradr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\nrval\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val, "\n ammvdec_mpeg4 decode_timeout_val\n");
-
-module_param_array(max_process_time, uint, &max_decode_instance_num, 0664);
-
-module_param(pre_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(pre_decode_buf_level,
- "\n ammvdec_mpeg4 pre_decode_buf_level\n");
-
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n ammvdec_mpeg4 start_decode_buf_level\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n ammvdec_mpeg4 udebug_flag\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n ammvdec_mpeg4 without_display_mode\n");
-
-module_init(ammvdec_mpeg4_driver_init_module);
-module_exit(ammvdec_mpeg4_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC MPEG4 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
-
diff --git a/drivers/frame_provider/decoder_v4l/vav1/Makefile b/drivers/frame_provider/decoder_v4l/vav1/Makefile
deleted file mode 100644
index 7d9a267..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AV1) += amvdec_av1_v4l.o
-amvdec_av1_v4l-objs += vav1.o av1_bufmgr.o av1_film_grain.o
diff --git a/drivers/frame_provider/decoder_v4l/vav1/aom_av1_define.h b/drivers/frame_provider/decoder_v4l/vav1/aom_av1_define.h
deleted file mode 100644
index 69e63f1..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/aom_av1_define.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-enum NalUnitType
-{
- NAL_UNIT_CODED_SLICE_TRAIL_N = 0, // 0
- NAL_UNIT_CODED_SLICE_TRAIL_R, // 1
-
- NAL_UNIT_CODED_SLICE_TSA_N, // 2
- NAL_UNIT_CODED_SLICE_TLA, // 3 // Current name in the spec: TSA_R
-
- NAL_UNIT_CODED_SLICE_STSA_N, // 4
- NAL_UNIT_CODED_SLICE_STSA_R, // 5
-
- NAL_UNIT_CODED_SLICE_RADL_N, // 6
- NAL_UNIT_CODED_SLICE_DLP, // 7 // Current name in the spec: RADL_R
-
- NAL_UNIT_CODED_SLICE_RASL_N, // 8
- NAL_UNIT_CODED_SLICE_TFD, // 9 // Current name in the spec: RASL_R
-
- NAL_UNIT_RESERVED_10,
- NAL_UNIT_RESERVED_11,
- NAL_UNIT_RESERVED_12,
- NAL_UNIT_RESERVED_13,
- NAL_UNIT_RESERVED_14,
- NAL_UNIT_RESERVED_15,
-
- NAL_UNIT_CODED_SLICE_BLA, // 16 // Current name in the spec: BLA_W_LP
- NAL_UNIT_CODED_SLICE_BLANT, // 17 // Current name in the spec: BLA_W_DLP
- NAL_UNIT_CODED_SLICE_BLA_N_LP, // 18
- NAL_UNIT_CODED_SLICE_IDR, // 19 // Current name in the spec: IDR_W_DLP
- NAL_UNIT_CODED_SLICE_IDR_N_LP, // 20
- NAL_UNIT_CODED_SLICE_CRA, // 21
- NAL_UNIT_RESERVED_22,
- NAL_UNIT_RESERVED_23,
-
- NAL_UNIT_RESERVED_24,
- NAL_UNIT_RESERVED_25,
- NAL_UNIT_RESERVED_26,
- NAL_UNIT_RESERVED_27,
- NAL_UNIT_RESERVED_28,
- NAL_UNIT_RESERVED_29,
- NAL_UNIT_RESERVED_30,
- NAL_UNIT_RESERVED_31,
-
- NAL_UNIT_VPS, // 32
- NAL_UNIT_SPS, // 33
- NAL_UNIT_PPS, // 34
- NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35
- NAL_UNIT_EOS, // 36
- NAL_UNIT_EOB, // 37
- NAL_UNIT_FILLER_DATA, // 38
- NAL_UNIT_SEI, // 39 Prefix SEI
- NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI
- NAL_UNIT_RESERVED_41,
- NAL_UNIT_RESERVED_42,
- NAL_UNIT_RESERVED_43,
- NAL_UNIT_RESERVED_44,
- NAL_UNIT_RESERVED_45,
- NAL_UNIT_RESERVED_46,
- NAL_UNIT_RESERVED_47,
- NAL_UNIT_UNSPECIFIED_48,
- NAL_UNIT_UNSPECIFIED_49,
- NAL_UNIT_UNSPECIFIED_50,
- NAL_UNIT_UNSPECIFIED_51,
- NAL_UNIT_UNSPECIFIED_52,
- NAL_UNIT_UNSPECIFIED_53,
- NAL_UNIT_UNSPECIFIED_54,
- NAL_UNIT_UNSPECIFIED_55,
- NAL_UNIT_UNSPECIFIED_56,
- NAL_UNIT_UNSPECIFIED_57,
- NAL_UNIT_UNSPECIFIED_58,
- NAL_UNIT_UNSPECIFIED_59,
- NAL_UNIT_UNSPECIFIED_60,
- NAL_UNIT_UNSPECIFIED_61,
- NAL_UNIT_UNSPECIFIED_62,
- NAL_UNIT_UNSPECIFIED_63,
- NAL_UNIT_INVALID,
-};
-
-int forbidden_zero_bit;
-int m_nalUnitType;
-int m_reservedZero6Bits;
-int m_temporalId;
-
-//---------------------------------------------------
-// Amrisc Software Interrupt
-//---------------------------------------------------
-#define AMRISC_STREAM_EMPTY_REQ 0x01
-#define AMRISC_PARSER_REQ 0x02
-#define AMRISC_MAIN_REQ 0x04
-
-//---------------------------------------------------
-// AOM_AV1_DEC_STATUS (HEVC_DEC_STATUS) define
-//---------------------------------------------------
- /*command*/
-#define AOM_AV1_DEC_IDLE 0
-#define AOM_AV1_DEC_FRAME_HEADER 1
-#define AOM_AV1_DEC_TILE_END 2
-#define AOM_AV1_DEC_TG_END 3
-#define AOM_AV1_DEC_LCU_END 4
-#define AOM_AV1_DECODE_SLICE 5
-#define AOM_AV1_SEARCH_HEAD 6
-#define AOM_AV1_DUMP_LMEM 7
-#define AOM_AV1_FGS_PARAM_CONT 8
-#define AOM_AV1_FGS_PARAM_CONT 8
-#define AOM_AV1_PIC_END_CONT 9
- /*status*/
-#define AOM_AV1_DEC_PIC_END 0xe0
- /*AOM_AV1_FGS_PARA:
- Bit[11] - 0 Read, 1 - Write
- Bit[10:8] - film_grain_params_ref_idx, For Write request
- */
-#define AOM_AV1_FGS_PARAM 0xe1
-#define AOM_AV1_DEC_PIC_END_PRE 0xe2
-#define AOM_AV1_HEAD_PARSER_DONE 0xf0
-#define AOM_AV1_HEAD_SEARCH_DONE 0xf1
-#define AOM_AV1_SEQ_HEAD_PARSER_DONE 0xf2
-#define AOM_AV1_FRAME_HEAD_PARSER_DONE 0xf3
-#define AOM_AV1_FRAME_PARSER_DONE 0xf4
-#define AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE 0xf5
-#define HEVC_ACTION_DONE 0xff
-
-
-//---------------------------------------------------
-// Include "parser_cmd.h"
-//---------------------------------------------------
-#define PARSER_CMD_SKIP_CFG_0 0x0000090b
-
-#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
-
-#define PARSER_CMD_SKIP_CFG_2 0x001b1910
-
-#define PARSER_CMD_NUMBER 37
-
-unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
-0x0401,
-0x8401,
-0x0800,
-0x0402,
-0x9002,
-0x1423,
-0x8CC3,
-0x1423,
-0x8804,
-0x9825,
-0x0800,
-0x04FE,
-0x8406,
-0x8411,
-0x1800,
-0x8408,
-0x8409,
-0x8C2A,
-0x9C2B,
-0x1C00,
-0x840F,
-0x8407,
-0x8000,
-0x8408,
-0x2000,
-0xA800,
-0x8410,
-0x04DE,
-0x840C,
-0x840D,
-0xAC00,
-0xA000,
-0x08C0,
-0x08E0,
-0xA40E,
-0xFC00,
-0x7C00
-};
diff --git a/drivers/frame_provider/decoder_v4l/vav1/av1_bufmgr.c b/drivers/frame_provider/decoder_v4l/vav1/av1_bufmgr.c
deleted file mode 100755
index a863654..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/av1_bufmgr.c
+++ /dev/null
@@ -1,3426 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#else
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-
-#undef pr_info
-#define pr_info printk
-
-#define __COMPARE(context, p1, p2) comp(p1, p2)
-#define __SHORTSORT(lo, hi, width, comp, context) \
- shortsort(lo, hi, width, comp)
-#define CUTOFF 8 /* testing shows that this is good value */
-#define STKSIZ (8*sizeof(void *) - 2)
-
-#undef swap
-static void swap(char *a, char *b, size_t width)
-{
- char tmp;
-
- if (a != b)
- /* Do the swap one character at a time to avoid potential
- * alignment problems.
- */
- while (width--) {
- tmp = *a;
- *a++ = *b;
- *b++ = tmp;
- }
-}
-
-static void shortsort(char *lo, char *hi, size_t width,
- int (*comp)(const void *, const void *))
-{
- char *p, *max;
-
- /* Note: in assertions below, i and j are alway inside original
- * bound of array to sort.
- */
- while (hi > lo) {
- /* A[i] <= A[j] for i <= j, j > hi */
- max = lo;
- for (p = lo + width; p <= hi; p += width) {
- /* A[i] <= A[max] for lo <= i < p */
- if (__COMPARE(context, p, max) > 0)
- max = p;
- /* A[i] <= A[max] for lo <= i <= p */
- }
- /* A[i] <= A[max] for lo <= i <= hi */
- swap(max, hi, width);
-
- /* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j,
- * j >= hi
- */
- hi -= width;
-
- /* A[i] <= A[j] for i <= j, j > hi, loop top condition
- * established
- */
- }
-}
-
-static void qsort(void *base, size_t num, size_t width,
- int (*comp)(const void *, const void *))
-{
- char *lo, *hi; /* ends of sub-array currently sorting */
- char *mid; /* points to middle of subarray */
- char *loguy, *higuy; /* traveling pointers for partition step */
- size_t size; /* size of the sub-array */
- char *lostk[STKSIZ], *histk[STKSIZ];
- int stkptr;
-
-/* stack for saving sub-array to be
- * processed
- */
-#if 0
- /* validation section */
- _VALIDATE_RETURN_VOID(base != NULL || num == 0, EINVAL);
- _VALIDATE_RETURN_VOID(width > 0, EINVAL);
- _VALIDATE_RETURN_VOID(comp != NULL, EINVAL);
-#endif
- if (num < 2)
- return; /* nothing to do */
-
- stkptr = 0; /* initialize stack */
- lo = (char *)base;
- hi = (char *)base + width * (num - 1); /* initialize limits */
-
- /* this entry point is for pseudo-recursion calling: setting
- * lo and hi and jumping to here is like recursion, but stkptr is
- * preserved, locals aren't, so we preserve stuff on the stack
- */
-recurse:
-
- size = (hi - lo) / width + 1; /* number of el's to sort */
-
- /* below a certain size, it is faster to use a O(n^2) sorting method */
- if (size <= CUTOFF) {
- __SHORTSORT(lo, hi, width, comp, context);
- } else {
- /* First we pick a partitioning element. The efficiency of
- * the algorithm demands that we find one that is approximately
- * the median of the values, but also that we select one fast.
- * We choose the median of the first, middle, and last
- * elements, to avoid bad performance in the face of already
- * sorted data, or data that is made up of multiple sorted
- * runs appended together. Testing shows that a
- * median-of-three algorithm provides better performance than
- * simply picking the middle element for the latter case.
- */
-
- mid = lo + (size / 2) * width; /* find middle element */
-
- /* Sort the first, middle, last elements into order */
- if (__COMPARE(context, lo, mid) > 0)
- swap(lo, mid, width);
- if (__COMPARE(context, lo, hi) > 0)
- swap(lo, hi, width);
- if (__COMPARE(context, mid, hi) > 0)
- swap(mid, hi, width);
-
- /* We now wish to partition the array into three pieces, one
- * consisting of elements <= partition element, one of elements
- * equal to the partition element, and one of elements > than
- * it. This is done below; comments indicate conditions
- * established at every step.
- */
-
- loguy = lo;
- higuy = hi;
-
- /* Note that higuy decreases and loguy increases on every
- * iteration, so loop must terminate.
- */
- for (;;) {
- /* lo <= loguy < hi, lo < higuy <= hi,
- * A[i] <= A[mid] for lo <= i <= loguy,
- * A[i] > A[mid] for higuy <= i < hi,
- * A[hi] >= A[mid]
- */
-
- /* The doubled loop is to avoid calling comp(mid,mid),
- * since some existing comparison funcs don't work
- * when passed the same value for both pointers.
- */
-
- if (mid > loguy) {
- do {
- loguy += width;
- } while (loguy < mid &&
- __COMPARE(context, loguy, mid) <= 0);
- }
- if (mid <= loguy) {
- do {
- loguy += width;
- } while (loguy <= hi &&
- __COMPARE(context, loguy, mid) <= 0);
- }
-
- /* lo < loguy <= hi+1, A[i] <= A[mid] for
- * lo <= i < loguy,
- * either loguy > hi or A[loguy] > A[mid]
- */
-
- do {
- higuy -= width;
- } while (higuy > mid &&
- __COMPARE(context, higuy, mid) > 0);
-
- /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi,
- * either higuy == lo or A[higuy] <= A[mid]
- */
-
- if (higuy < loguy)
- break;
-
- /* if loguy > hi or higuy == lo, then we would have
- * exited, so A[loguy] > A[mid], A[higuy] <= A[mid],
- * loguy <= hi, higuy > lo
- */
-
- swap(loguy, higuy, width);
-
- /* If the partition element was moved, follow it.
- * Only need to check for mid == higuy, since before
- * the swap, A[loguy] > A[mid] implies loguy != mid.
- */
-
- if (mid == higuy)
- mid = loguy;
-
- /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition
- * at top of loop is re-established
- */
- }
-
- /* A[i] <= A[mid] for lo <= i < loguy,
- * A[i] > A[mid] for higuy < i < hi,
- * A[hi] >= A[mid]
- * higuy < loguy
- * implying:
- * higuy == loguy-1
- * or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid]
- */
-
- /* Find adjacent elements equal to the partition element. The
- * doubled loop is to avoid calling comp(mid,mid), since some
- * existing comparison funcs don't work when passed the same
- * value for both pointers.
- */
-
- higuy += width;
- if (mid < higuy) {
- do {
- higuy -= width;
- } while (higuy > mid &&
- __COMPARE(context, higuy, mid) == 0);
- }
- if (mid >= higuy) {
- do {
- higuy -= width;
- } while (higuy > lo &&
- __COMPARE(context, higuy, mid) == 0);
- }
-
- /* OK, now we have the following:
- * higuy < loguy
- * lo <= higuy <= hi
- * A[i] <= A[mid] for lo <= i <= higuy
- * A[i] == A[mid] for higuy < i < loguy
- * A[i] > A[mid] for loguy <= i < hi
- * A[hi] >= A[mid]
- */
-
- /* We've finished the partition, now we want to sort the
- * subarrays [lo, higuy] and [loguy, hi].
- * We do the smaller one first to minimize stack usage.
- * We only sort arrays of length 2 or more.
- */
-
- if (higuy - lo >= hi - loguy) {
- if (lo < higuy) {
- lostk[stkptr] = lo;
- histk[stkptr] = higuy;
- ++stkptr;
- } /* save big recursion for later */
-
- if (loguy < hi) {
- lo = loguy;
- goto recurse; /* do small recursion */
- }
- } else {
- if (loguy < hi) {
- lostk[stkptr] = loguy;
- histk[stkptr] = hi;
- ++stkptr; /* save big recursion for later */
- }
-
- if (lo < higuy) {
- hi = higuy;
- goto recurse; /* do small recursion */
- }
- }
- }
-
- /* We have sorted the array, except for any pending sorts on the stack.
- * Check if there are any, and do them.
- */
-
- --stkptr;
- if (stkptr >= 0) {
- lo = lostk[stkptr];
- hi = histk[stkptr];
- goto recurse; /* pop subarray from stack */
- } else
- return; /* all subarrays done */
-}
-
-#endif
-
-#include "av1_global.h"
-int aom_realloc_frame_buffer(AV1_COMMON *cm, PIC_BUFFER_CONFIG *pic,
- int width, int height, unsigned int order_hint);
-void dump_params(AV1Decoder *pbi, union param_u *params);
-
-#define assert(a)
-#define IMPLIES(a)
-
-int new_compressed_data_count = 0;
-
-static int valid_ref_frame_size(int ref_width, int ref_height,
- int this_width, int this_height) {
- return 2 * this_width >= ref_width && 2 * this_height >= ref_height &&
- this_width <= 16 * ref_width && this_height <= 16 * ref_height;
-}
-
-#ifdef SUPPORT_SCALE_FACTOR
-// Note: Expect val to be in q4 precision
-static inline int scaled_x(int val, const struct scale_factors *sf) {
- const int off =
- (sf->x_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
- const int64_t tval = (int64_t)val * sf->x_scale_fp + off;
- return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
- REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
-}
-
-// Note: Expect val to be in q4 precision
-static inline int scaled_y(int val, const struct scale_factors *sf) {
- const int off =
- (sf->y_scale_fp - (1 << REF_SCALE_SHIFT)) * (1 << (SUBPEL_BITS - 1));
- const int64_t tval = (int64_t)val * sf->y_scale_fp + off;
- return (int)ROUND_POWER_OF_TWO_SIGNED_64(tval,
- REF_SCALE_SHIFT - SCALE_EXTRA_BITS);
-}
-
-// Note: Expect val to be in q4 precision
-static int unscaled_value(int val, const struct scale_factors *sf) {
- (void)sf;
- return val << SCALE_EXTRA_BITS;
-}
-
-static int get_fixed_point_scale_factor(int other_size, int this_size) {
- // Calculate scaling factor once for each reference frame
- // and use fixed point scaling factors in decoding and encoding routines.
- // Hardware implementations can calculate scale factor in device driver
- // and use multiplication and shifting on hardware instead of division.
- return ((other_size << REF_SCALE_SHIFT) + this_size / 2) / this_size;
-}
-
-// Given the fixed point scale, calculate coarse point scale.
-static int fixed_point_scale_to_coarse_point_scale(int scale_fp) {
- return ROUND_POWER_OF_TWO(scale_fp, REF_SCALE_SHIFT - SCALE_SUBPEL_BITS);
-}
-
-
-void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
- int other_h, int this_w, int this_h) {
- if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) {
- sf->x_scale_fp = REF_INVALID_SCALE;
- sf->y_scale_fp = REF_INVALID_SCALE;
- return;
- }
-
- sf->x_scale_fp = get_fixed_point_scale_factor(other_w, this_w);
- sf->y_scale_fp = get_fixed_point_scale_factor(other_h, this_h);
-
- sf->x_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->x_scale_fp);
- sf->y_step_q4 = fixed_point_scale_to_coarse_point_scale(sf->y_scale_fp);
-
- if (av1_is_scaled(sf)) {
- sf->scale_value_x = scaled_x;
- sf->scale_value_y = scaled_y;
- } else {
- sf->scale_value_x = unscaled_value;
- sf->scale_value_y = unscaled_value;
- }
-#ifdef ORI_CODE
- // AV1 convolve functions
- // Special case convolve functions should produce the same result as
- // av1_convolve_2d.
- // subpel_x_qn == 0 && subpel_y_qn == 0
- sf->convolve[0][0][0] = av1_convolve_2d_copy_sr;
- // subpel_x_qn == 0
- sf->convolve[0][1][0] = av1_convolve_y_sr;
- // subpel_y_qn == 0
- sf->convolve[1][0][0] = av1_convolve_x_sr;
- // subpel_x_qn != 0 && subpel_y_qn != 0
- sf->convolve[1][1][0] = av1_convolve_2d_sr;
- // subpel_x_qn == 0 && subpel_y_qn == 0
- sf->convolve[0][0][1] = av1_dist_wtd_convolve_2d_copy;
- // subpel_x_qn == 0
- sf->convolve[0][1][1] = av1_dist_wtd_convolve_y;
- // subpel_y_qn == 0
- sf->convolve[1][0][1] = av1_dist_wtd_convolve_x;
- // subpel_x_qn != 0 && subpel_y_qn != 0
- sf->convolve[1][1][1] = av1_dist_wtd_convolve_2d;
- // AV1 High BD convolve functions
- // Special case convolve functions should produce the same result as
- // av1_highbd_convolve_2d.
- // subpel_x_qn == 0 && subpel_y_qn == 0
- sf->highbd_convolve[0][0][0] = av1_highbd_convolve_2d_copy_sr;
- // subpel_x_qn == 0
- sf->highbd_convolve[0][1][0] = av1_highbd_convolve_y_sr;
- // subpel_y_qn == 0
- sf->highbd_convolve[1][0][0] = av1_highbd_convolve_x_sr;
- // subpel_x_qn != 0 && subpel_y_qn != 0
- sf->highbd_convolve[1][1][0] = av1_highbd_convolve_2d_sr;
- // subpel_x_qn == 0 && subpel_y_qn == 0
- sf->highbd_convolve[0][0][1] = av1_highbd_dist_wtd_convolve_2d_copy;
- // subpel_x_qn == 0
- sf->highbd_convolve[0][1][1] = av1_highbd_dist_wtd_convolve_y;
- // subpel_y_qn == 0
- sf->highbd_convolve[1][0][1] = av1_highbd_dist_wtd_convolve_x;
- // subpel_x_qn != 0 && subpel_y_qn != 0
- sf->highbd_convolve[1][1][1] = av1_highbd_dist_wtd_convolve_2d;
-#endif
-}
-#endif
-
-static RefCntBuffer *assign_cur_frame_new_fb(AV1_COMMON *const cm) {
- // Release the previously-used frame-buffer
- int new_fb_idx;
- if (cm->cur_frame != NULL) {
- --cm->cur_frame->ref_count;
- cm->cur_frame = NULL;
- }
-
- // Assign a new framebuffer
- new_fb_idx = get_free_frame_buffer(cm);
- if (new_fb_idx == INVALID_IDX) return NULL;
-
- cm->buffer_pool->frame_bufs[new_fb_idx].buf.v4l_buf_index = new_fb_idx;
- cm->cur_frame = &cm->buffer_pool->frame_bufs[new_fb_idx];
- cm->cur_frame->buf.buf_8bit_valid = 0;
-#ifdef AML
- cm->cur_frame->buf.index = new_fb_idx;
-#endif
-#ifdef ORI_CODE
- av1_zero(cm->cur_frame->interp_filter_selected);
-#endif
- return cm->cur_frame;
-}
-
-// Modify 'lhs_ptr' to reference the buffer at 'rhs_ptr', and update the ref
-// counts accordingly.
-static void assign_frame_buffer_p(RefCntBuffer **lhs_ptr,
- RefCntBuffer *rhs_ptr) {
- RefCntBuffer *const old_ptr = *lhs_ptr;
- if (old_ptr != NULL) {
- assert(old_ptr->ref_count > 0);
- // One less reference to the buffer at 'old_ptr', so decrease ref count.
- --old_ptr->ref_count;
- }
-
- *lhs_ptr = rhs_ptr;
- // One more reference to the buffer at 'rhs_ptr', so increase ref count.
- ++rhs_ptr->ref_count;
-}
-
-AV1Decoder *av1_decoder_create(BufferPool *const pool, AV1_COMMON *cm) {
- int i;
-
-#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- AV1Decoder *pbi = (AV1Decoder *)malloc(sizeof(*pbi));
-#else
- AV1Decoder *pbi = (AV1Decoder *)vmalloc(sizeof(AV1Decoder));
-#endif
- if (!pbi) return NULL;
- memset(pbi, 0, sizeof(*pbi));
-
- // The jmp_buf is valid only for the duration of the function that calls
- // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
- // before it returns.
-
- pbi->common = cm;
- cm->error.setjmp = 1;
-
-#ifdef ORI_CODE
- memset(cm->fc, 0, sizeof(*cm->fc));
- memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context));
-#endif
- pbi->need_resync = 1;
-
- // Initialize the references to not point to any frame buffers.
- for (i = 0; i < REF_FRAMES; i++) {
- cm->ref_frame_map[i] = NULL;
- cm->next_ref_frame_map[i] = NULL;
-#ifdef AML
- cm->next_used_ref_frame_map[i] = NULL;
-#endif
- }
-
- cm->current_frame.frame_number = 0;
- pbi->decoding_first_frame = 1;
- pbi->common->buffer_pool = pool;
-
- cm->seq_params.bit_depth = AOM_BITS_8;
-
-#ifdef ORI_CODE
- cm->alloc_mi = dec_alloc_mi;
- cm->free_mi = dec_free_mi;
- cm->setup_mi = dec_setup_mi;
-
- av1_loop_filter_init(cm);
-
- av1_qm_init(cm);
- av1_loop_restoration_precal();
-#if CONFIG_ACCOUNTING
- pbi->acct_enabled = 1;
- aom_accounting_init(&pbi->accounting);
-#endif
-#endif
- cm->error.setjmp = 0;
-
-#ifdef ORI_CODE
- aom_get_worker_interface()->init(&pbi->lf_worker);
- pbi->lf_worker.thread_name = "aom lf worker";
-#endif
-
- return pbi;
-}
-
-static void reset_frame_buffers(AV1Decoder *const pbi);
-
-void av1_bufmgr_ctx_reset(AV1Decoder *pbi, BufferPool *const pool, AV1_COMMON *cm)
-{
- u32 save_w, save_h;
-
- if (!pbi || !pool || !cm)
- return;
-
- reset_frame_buffers(pbi);
- memset(pbi, 0, sizeof(*pbi));
- /*save w,h for resolution change after seek */
- save_w = cm->width;
- save_h = cm->height;
- memset(cm, 0, sizeof(*cm));
-
- cm->current_frame.frame_number = 0;
- cm->seq_params.bit_depth = AOM_BITS_8;
- cm->error.setjmp = 0;
- cm->width = save_w;
- cm->height = save_h;
-
- pbi->bufmgr_proc_count = 0;
- pbi->need_resync = 1;
- pbi->decoding_first_frame = 1;
- pbi->num_output_frames = 0;
- pbi->common = cm;
- pbi->common->buffer_pool = pool;
-}
-
-int release_fb_cb(void *cb_priv, aom_codec_frame_buffer_t *fb) {
-#if 0
- InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv;
- (void)cb_priv;
- if (int_fb) int_fb->in_use = 0;
-#endif
- return 0;
-}
-
-static void decrease_ref_count(AV1Decoder *pbi, RefCntBuffer *const buf,
- BufferPool *const pool) {
- if (buf != NULL) {
- --buf->ref_count;
- // Reference counts should never become negative. If this assertion fails,
- // there is a bug in our reference count management.
- assert(buf->ref_count >= 0);
- // A worker may only get a free framebuffer index when calling get_free_fb.
- // But the raw frame buffer is not set up until we finish decoding header.
- // So if any error happens during decoding header, frame_bufs[idx] will not
- // have a valid raw frame buffer.
- if (buf->ref_count == 0
-#ifdef ORI_CODE
- && buf->raw_frame_buffer.data
-#endif
- ) {
-#ifdef AML
- av1_release_buf(pbi, buf);
-#endif
- release_fb_cb(pool->cb_priv, &buf->raw_frame_buffer);
- buf->raw_frame_buffer.data = NULL;
- buf->raw_frame_buffer.size = 0;
- buf->raw_frame_buffer.priv = NULL;
- }
- }
-}
-
-void clear_frame_buf_ref_count(AV1Decoder *pbi)
-{
- int i;
-
- for (i = 0; i < pbi->num_output_frames; i++) {
- decrease_ref_count(pbi, pbi->output_frames[i],
- pbi->common->buffer_pool);
- }
- pbi->num_output_frames = 0;
-}
-
-static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) {
- int ref_index = 0, mask;
- AV1_COMMON *const cm = pbi->common;
- BufferPool *const pool = cm->buffer_pool;
- unsigned long flags;
-
- if (frame_decoded) {
- int check_on_show_existing_frame;
- lock_buffer_pool(pool, flags);
-
- // In ext-tile decoding, the camera frame header is only decoded once. So,
- // we don't release the references here.
- if (!pbi->camera_frame_header_ready) {
- // If we are not holding reference buffers in cm->next_ref_frame_map,
- // assert that the following two for loops are no-ops.
- assert(IMPLIES(!pbi->hold_ref_buf,
- cm->current_frame.refresh_frame_flags == 0));
- assert(IMPLIES(!pbi->hold_ref_buf,
- cm->show_existing_frame && !pbi->reset_decoder_state));
-
- // The following two for loops need to release the reference stored in
- // cm->ref_frame_map[ref_index] before transferring the reference stored
- // in cm->next_ref_frame_map[ref_index] to cm->ref_frame_map[ref_index].
- for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
- decrease_ref_count(pbi, cm->ref_frame_map[ref_index], pool);
- cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- cm->next_ref_frame_map[ref_index] = NULL;
- ++ref_index;
- }
-
- check_on_show_existing_frame =
- !cm->show_existing_frame || pbi->reset_decoder_state;
- for (; ref_index < REF_FRAMES && check_on_show_existing_frame;
- ++ref_index) {
- decrease_ref_count(pbi, cm->ref_frame_map[ref_index], pool);
- cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- cm->next_ref_frame_map[ref_index] = NULL;
- }
- }
-
- if (cm->show_existing_frame || cm->show_frame) {
- if (pbi->output_all_layers) {
- // Append this frame to the output queue
- if (pbi->num_output_frames >= MAX_NUM_SPATIAL_LAYERS) {
- // We can't store the new frame anywhere, so drop it and return an
- // error
- cm->cur_frame->buf.corrupted = 1;
- decrease_ref_count(pbi, cm->cur_frame, pool);
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- } else {
- pbi->output_frames[pbi->num_output_frames] = cm->cur_frame;
- pbi->num_output_frames++;
- }
- } else {
- // Replace any existing output frame
- assert(pbi->num_output_frames == 0 || pbi->num_output_frames == 1);
- if (pbi->num_output_frames > 0) {
- decrease_ref_count(pbi, pbi->output_frames[0], pool);
- }
- if (cm->cur_frame) {
- pbi->output_frames[0] = cm->cur_frame;
- pbi->num_output_frames = 1;
- }
- }
- } else {
- decrease_ref_count(pbi, cm->cur_frame, pool);
- }
-
- unlock_buffer_pool(pool, flags);
- } else {
- // The code here assumes we are not holding reference buffers in
- // cm->next_ref_frame_map. If this assertion fails, we are leaking the
- // frame buffer references in cm->next_ref_frame_map.
- assert(IMPLIES(!pbi->camera_frame_header_ready, !pbi->hold_ref_buf));
- // Nothing was decoded, so just drop this frame buffer
- lock_buffer_pool(pool, flags);
- decrease_ref_count(pbi, cm->cur_frame, pool);
- unlock_buffer_pool(pool, flags);
- }
- cm->cur_frame = NULL;
-
- if (!pbi->camera_frame_header_ready) {
- pbi->hold_ref_buf = 0;
-
- // Invalidate these references until the next frame starts.
- for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) {
- cm->remapped_ref_idx[ref_index] = INVALID_IDX;
- }
- }
-}
-
-void aom_internal_error(struct aom_internal_error_info *info,
- aom_codec_err_t error, const char *fmt, ...) {
- va_list ap;
-
- info->error_code = error;
- info->has_detail = 0;
-
- if (fmt) {
- size_t sz = sizeof(info->detail);
-
- info->has_detail = 1;
- va_start(ap, fmt);
- vsnprintf(info->detail, sz - 1, fmt, ap);
- va_end(ap);
- info->detail[sz - 1] = '\0';
- }
-#ifdef ORI_CODE
- if (info->setjmp) longjmp(info->jmp, info->error_code);
-#endif
-}
-
-#ifdef ORI_CODE
-void av1_zero_unused_internal_frame_buffers(InternalFrameBufferList *list) {
- int i;
-
- assert(list != NULL);
-
- for (i = 0; i < list->num_internal_frame_buffers; ++i) {
- if (list->int_fb[i].data && !list->int_fb[i].in_use)
- memset(list->int_fb[i].data, 0, list->int_fb[i].size);
- }
-}
-#endif
-
-// Release the references to the frame buffers in cm->ref_frame_map and reset
-// all elements of cm->ref_frame_map to NULL.
-static void reset_ref_frame_map(AV1Decoder *const pbi) {
- AV1_COMMON *const cm = pbi->common;
- BufferPool *const pool = cm->buffer_pool;
- int i;
-
- for (i = 0; i < REF_FRAMES; i++) {
- decrease_ref_count(pbi, cm->ref_frame_map[i], pool);
- cm->ref_frame_map[i] = NULL;
-#ifdef AML
- cm->next_used_ref_frame_map[i] = NULL;
-#endif
- }
-}
-
-// Generate next_ref_frame_map.
-static void generate_next_ref_frame_map(AV1Decoder *const pbi) {
- AV1_COMMON *const cm = pbi->common;
- BufferPool *const pool = cm->buffer_pool;
- unsigned long flags;
- int ref_index = 0;
- int mask;
-
- lock_buffer_pool(pool, flags);
- // cm->next_ref_frame_map holds references to frame buffers. After storing a
- // frame buffer index in cm->next_ref_frame_map, we need to increase the
- // frame buffer's ref_count.
- for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
- if (mask & 1) {
- cm->next_ref_frame_map[ref_index] = cm->cur_frame;
- } else {
- cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
- }
- if (cm->next_ref_frame_map[ref_index] != NULL)
- ++cm->next_ref_frame_map[ref_index]->ref_count;
- ++ref_index;
- }
-
- for (; ref_index < REF_FRAMES; ++ref_index) {
- cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
- if (cm->next_ref_frame_map[ref_index] != NULL)
- ++cm->next_ref_frame_map[ref_index]->ref_count;
- }
- unlock_buffer_pool(pool, flags);
- pbi->hold_ref_buf = 1;
-}
-
-// If the refresh_frame_flags bitmask is set, update reference frame id values
-// and mark frames as valid for reference.
-static void update_ref_frame_id(AV1_COMMON *const cm, int frame_id) {
- int i;
- int refresh_frame_flags = cm->current_frame.refresh_frame_flags;
- assert(cm->seq_params.frame_id_numbers_present_flag);
- for (i = 0; i < REF_FRAMES; i++) {
- if ((refresh_frame_flags >> i) & 1) {
- cm->ref_frame_id[i] = frame_id;
- cm->valid_for_referencing[i] = 1;
- }
- }
-}
-
-static void show_existing_frame_reset(AV1Decoder *const pbi,
- int existing_frame_idx) {
- AV1_COMMON *const cm = pbi->common;
- int i;
- assert(cm->show_existing_frame);
-
- cm->current_frame.frame_type = KEY_FRAME;
-
- cm->current_frame.refresh_frame_flags = (1 << REF_FRAMES) - 1;
-
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- cm->remapped_ref_idx[i] = INVALID_IDX;
- }
-
- if (pbi->need_resync) {
- reset_ref_frame_map(pbi);
- pbi->need_resync = 0;
- }
-
- // Note that the displayed frame must be valid for referencing in order to
- // have been selected.
- if (cm->seq_params.frame_id_numbers_present_flag) {
- cm->current_frame_id = cm->ref_frame_id[existing_frame_idx];
- update_ref_frame_id(cm, cm->current_frame_id);
- }
-
- cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
-
- generate_next_ref_frame_map(pbi);
-
-#ifdef ORI_CODE
- // Reload the adapted CDFs from when we originally coded this keyframe
- *cm->fc = cm->next_ref_frame_map[existing_frame_idx]->frame_context;
-#endif
-}
-
-static void reset_frame_buffers(AV1Decoder *const pbi) {
- AV1_COMMON *const cm = pbi->common;
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
- unsigned long flags;
-
- // We have not stored any references to frame buffers in
- // cm->next_ref_frame_map, so we can directly reset it to all NULL.
- for (i = 0; i < REF_FRAMES; ++i) {
- cm->next_ref_frame_map[i] = NULL;
- }
-
- lock_buffer_pool(cm->buffer_pool, flags);
- reset_ref_frame_map(pbi);
- assert(cm->cur_frame->ref_count == 1);
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- // Reset all unreferenced frame buffers. We can also reset cm->cur_frame
- // because we are the sole owner of cm->cur_frame.
- if (frame_bufs[i].ref_count > 0 && &frame_bufs[i] != cm->cur_frame) {
- continue;
- }
- frame_bufs[i].order_hint = 0;
- av1_zero(frame_bufs[i].ref_order_hints);
- }
-#ifdef ORI_CODE
- av1_zero_unused_internal_frame_buffers(&cm->buffer_pool->int_frame_buffers);
-#endif
- unlock_buffer_pool(cm->buffer_pool, flags);
-}
-
-static int frame_is_intra_only(const AV1_COMMON *const cm) {
- return cm->current_frame.frame_type == KEY_FRAME ||
- cm->current_frame.frame_type == INTRA_ONLY_FRAME;
-}
-
-static int frame_is_sframe(const AV1_COMMON *cm) {
- return cm->current_frame.frame_type == S_FRAME;
-}
-
-// These functions take a reference frame label between LAST_FRAME and
-// EXTREF_FRAME inclusive. Note that this is different to the indexing
-// previously used by the frame_refs[] array.
-static int get_ref_frame_map_idx(const AV1_COMMON *const cm,
- const MV_REFERENCE_FRAME ref_frame) {
- return (ref_frame >= LAST_FRAME && ref_frame <= EXTREF_FRAME)
- ? cm->remapped_ref_idx[ref_frame - LAST_FRAME]
- : INVALID_IDX;
-}
-
-static RefCntBuffer *get_ref_frame_buf(
- const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) {
- const int map_idx = get_ref_frame_map_idx(cm, ref_frame);
- return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : NULL;
-}
-#ifdef SUPPORT_SCALE_FACTOR
-static struct scale_factors *get_ref_scale_factors(
- AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) {
- const int map_idx = get_ref_frame_map_idx(cm, ref_frame);
- return (map_idx != INVALID_IDX) ? &cm->ref_scale_factors[map_idx] : NULL;
-}
-#endif
-static RefCntBuffer *get_primary_ref_frame_buf(
- const AV1_COMMON *const cm) {
- int map_idx;
- if (cm->primary_ref_frame == PRIMARY_REF_NONE) return NULL;
- map_idx = get_ref_frame_map_idx(cm, cm->primary_ref_frame + 1);
- return (map_idx != INVALID_IDX) ? cm->ref_frame_map[map_idx] : NULL;
-}
-
-static int get_relative_dist(const OrderHintInfo *oh, int a, int b) {
- int bits;
- int m;
- int diff;
- if (!oh->enable_order_hint) return 0;
-
- bits = oh->order_hint_bits_minus_1 + 1;
-
- assert(bits >= 1);
- assert(a >= 0 && a < (1 << bits));
- assert(b >= 0 && b < (1 << bits));
-
- diff = a - b;
- m = 1 << (bits - 1);
- diff = (diff & (m - 1)) - (diff & m);
- return diff;
-}
-
-
-void av1_read_frame_size(union param_u *params, int num_bits_width,
- int num_bits_height, int *width, int *height, int* dec_width) {
- *width = params->p.frame_width;
- *height = params->p.frame_height;//aom_rb_read_literal(rb, num_bits_height) + 1;
-#ifdef AML
- *dec_width = params->p.dec_frame_width;
-#endif
-}
-
-static REFERENCE_MODE read_frame_reference_mode(
- const AV1_COMMON *cm, union param_u *params) {
- if (frame_is_intra_only(cm)) {
- return SINGLE_REFERENCE;
- } else {
- return params->p.reference_mode ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
- }
-}
-
-static inline int calc_mi_size(int len) {
- // len is in mi units. Align to a multiple of SBs.
- return ALIGN_POWER_OF_TWO(len, MAX_MIB_SIZE_LOG2);
-}
-
-void av1_set_mb_mi(AV1_COMMON *cm, int width, int height) {
- // Ensure that the decoded width and height are both multiples of
- // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
- // subsampling is used).
- // This simplifies the implementation of various experiments,
- // eg. cdef, which operates on units of 8x8 luma pixels.
- const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
- const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, " [PICTURE] av1_set_mb_mi (%d X %d)\n", width, height);
-
- cm->mi_cols = aligned_width >> MI_SIZE_LOG2;
- cm->mi_rows = aligned_height >> MI_SIZE_LOG2;
- cm->mi_stride = calc_mi_size(cm->mi_cols);
-
- cm->mb_cols = (cm->mi_cols + 2) >> 2;
- cm->mb_rows = (cm->mi_rows + 2) >> 2;
- cm->MBs = cm->mb_rows * cm->mb_cols;
-
-#if CONFIG_LPF_MASK
- alloc_loop_filter_mask(cm);
-#endif
-}
-
-int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) {
-#ifdef ORI_CODE
- int new_mi_size;
-#endif
- av1_set_mb_mi(cm, width, height);
-#ifdef ORI_CODE
- new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
- if (cm->mi_alloc_size < new_mi_size) {
- cm->free_mi(cm);
- if (cm->alloc_mi(cm, new_mi_size)) goto fail;
- }
-#endif
- return 0;
-
-#ifdef ORI_CODE
-fail:
-#endif
- // clear the mi_* values to force a realloc on resync
- av1_set_mb_mi(cm, 0, 0);
-#ifdef ORI_CODE
- av1_free_context_buffers(cm);
-#endif
- return 1;
-}
-
-#ifndef USE_SCALED_WIDTH_FROM_UCODE
-static void calculate_scaled_size_helper(int *dim, int denom) {
- if (denom != SCALE_NUMERATOR) {
- // We need to ensure the constraint in "Appendix A" of the spec:
- // * FrameWidth is greater than or equal to 16
- // * FrameHeight is greater than or equal to 16
- // For this, we clamp the downscaled dimension to at least 16. One
- // exception: if original dimension itself was < 16, then we keep the
- // downscaled dimension to be same as the original, to ensure that resizing
- // is valid.
- const int min_dim = AOMMIN(16, *dim);
- // Use this version if we need *dim to be even
- // *width = (*width * SCALE_NUMERATOR + denom) / (2 * denom);
- // *width <<= 1;
- *dim = (*dim * SCALE_NUMERATOR + denom / 2) / (denom);
- *dim = AOMMAX(*dim, min_dim);
- }
-}
-#ifdef ORI_CODE
-void av1_calculate_scaled_size(int *width, int *height, int resize_denom) {
- calculate_scaled_size_helper(width, resize_denom);
- calculate_scaled_size_helper(height, resize_denom);
-}
-#endif
-void av1_calculate_scaled_superres_size(int *width, int *height,
- int superres_denom) {
- (void)height;
- calculate_scaled_size_helper(width, superres_denom);
-}
-#endif
-
-static void setup_superres(AV1_COMMON *const cm, union param_u *params,
- int *width, int *height) {
-#ifdef USE_SCALED_WIDTH_FROM_UCODE
- cm->superres_upscaled_width = params->p.frame_width_scaled;
- cm->superres_upscaled_height = params->p.frame_height;
-
-
- *width = params->p.dec_frame_width;
- *height = params->p.frame_height;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, " [PICTURE] set decoding size to (%d X %d) scaled size to (%d X %d)\n",
- *width, *height,
- cm->superres_upscaled_width,
- cm->superres_upscaled_height);
-#else
- cm->superres_upscaled_width = *width;
- cm->superres_upscaled_height = *height;
-
- const SequenceHeader *const seq_params = &cm->seq_params;
- if (!seq_params->enable_superres) return;
-
- //if (aom_rb_read_bit(-1, defmark, rb)) {
- if (params->p.superres_scale_denominator != SCALE_NUMERATOR) {
-#ifdef ORI_CODE
- cm->superres_scale_denominator =
- (uint8_t)aom_rb_read_literal(-1, defmark, rb, SUPERRES_SCALE_BITS);
- cm->superres_scale_denominator += SUPERRES_SCALE_DENOMINATOR_MIN;
-#else
- cm->superres_scale_denominator = params->p.superres_scale_denominator;
-#endif
- // Don't edit cm->width or cm->height directly, or the buffers won't get
- // resized correctly
- av1_calculate_scaled_superres_size(width, height,
- cm->superres_scale_denominator);
- } else {
- // 1:1 scaling - ie. no scaling, scale not provided
- cm->superres_scale_denominator = SCALE_NUMERATOR;
- }
-/*!USE_SCALED_WIDTH_FROM_UCODE*/
-#endif
-}
-
-static void resize_context_buffers(AV1_COMMON *cm, int width, int height) {
-#if CONFIG_SIZE_LIMIT
- if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Dimensions of %dx%d beyond allowed size of %dx%d.",
- width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);
-#endif
- if (cm->width != width || cm->height != height) {
- const int new_mi_rows =
- ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
- const int new_mi_cols =
- ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
-
- // Allocations in av1_alloc_context_buffers() depend on individual
- // dimensions as well as the overall size.
- if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) {
- if (av1_alloc_context_buffers(cm, width, height)) {
- // The cm->mi_* values have been cleared and any existing context
- // buffers have been freed. Clear cm->width and cm->height to be
- // consistent and to force a realloc next time.
- cm->width = 0;
- cm->height = 0;
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate context buffers");
- }
- } else {
- av1_set_mb_mi(cm, width, height);
- }
-#ifdef ORI_CODE
- av1_init_context_buffers(cm);
-#endif
- cm->width = width;
- cm->height = height;
- }
-
-#ifdef ORI_CODE
- ensure_mv_buffer(cm->cur_frame, cm);
-#endif
- cm->cur_frame->width = cm->width;
- cm->cur_frame->height = cm->height;
-}
-
-static void setup_buffer_pool(AV1_COMMON *cm) {
- BufferPool *const pool = cm->buffer_pool;
- const SequenceHeader *const seq_params = &cm->seq_params;
- unsigned long flags;
-
- lock_buffer_pool(pool, flags);
- if (aom_realloc_frame_buffer(cm, &cm->cur_frame->buf,
- cm->width, cm->height, cm->cur_frame->order_hint)) {
- unlock_buffer_pool(pool, flags);
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate frame buffer");
- }
- unlock_buffer_pool(pool, flags);
-
- cm->cur_frame->buf.bit_depth = (unsigned int)seq_params->bit_depth;
- cm->cur_frame->buf.color_primaries = seq_params->color_primaries;
- cm->cur_frame->buf.transfer_characteristics =
- seq_params->transfer_characteristics;
- cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients;
- cm->cur_frame->buf.monochrome = seq_params->monochrome;
- cm->cur_frame->buf.chroma_sample_position =
- seq_params->chroma_sample_position;
- cm->cur_frame->buf.color_range = seq_params->color_range;
- cm->cur_frame->buf.render_width = cm->render_width;
- cm->cur_frame->buf.render_height = cm->render_height;
-}
-
-static void setup_frame_size(AV1_COMMON *cm, int frame_size_override_flag, union param_u *params) {
- const SequenceHeader *const seq_params = &cm->seq_params;
- int width, height, dec_width;
-
- if (frame_size_override_flag) {
- int num_bits_width = seq_params->num_bits_width;
- int num_bits_height = seq_params->num_bits_height;
- av1_read_frame_size(params, num_bits_width, num_bits_height, &width, &height, &dec_width);
-#ifdef AML
- cm->dec_width = dec_width;
-#endif
- if (width > seq_params->max_frame_width ||
- height > seq_params->max_frame_height) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Frame dimensions are larger than the maximum values");
- }
- } else {
- width = seq_params->max_frame_width;
- height = seq_params->max_frame_height;
-#ifdef AML
- cm->dec_width = dec_width = params->p.dec_frame_width;
-#endif
- }
- setup_superres(cm, params, &width, &height);
- resize_context_buffers(cm, width, height);
-#ifdef ORI_CODE
- setup_render_size(cm, params);
-#endif
- setup_buffer_pool(cm);
-}
-
-static int valid_ref_frame_img_fmt(aom_bit_depth_t ref_bit_depth,
- int ref_xss, int ref_yss,
- aom_bit_depth_t this_bit_depth,
- int this_xss, int this_yss) {
- return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
- ref_yss == this_yss;
-}
-
-static void setup_frame_size_with_refs(AV1_COMMON *cm, union param_u *params) {
- int width, height, dec_width;
- int found = 0;
- int has_valid_ref_frame = 0;
- int i;
- SequenceHeader *seq_params;
- for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
- /*if (aom_rb_read_bit(rb)) {*/
- if (params->p.valid_ref_frame_bits & (1<<i)) {
- const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, i);
- // This will never be NULL in a normal stream, as streams are required to
- // have a shown keyframe before any inter frames, which would refresh all
- // the reference buffers. However, it might be null if we're starting in
- // the middle of a stream, and static analysis will error if we don't do
- // a null check here.
- if (ref_buf == NULL) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Invalid condition: invalid reference buffer");
- } else {
- const PIC_BUFFER_CONFIG *const buf = &ref_buf->buf;
- width = buf->y_crop_width;
- height = buf->y_crop_height;
- cm->render_width = buf->render_width;
- cm->render_height = buf->render_height;
- setup_superres(cm, params, &width, &height);
- resize_context_buffers(cm, width, height);
- found = 1;
- break;
- }
- }
- }
-
- seq_params = &cm->seq_params;
- if (!found) {
- int num_bits_width = seq_params->num_bits_width;
- int num_bits_height = seq_params->num_bits_height;
-
- av1_read_frame_size(params, num_bits_width, num_bits_height, &width, &height, &dec_width);
-#ifdef AML
- cm->dec_width = dec_width;
-#endif
- setup_superres(cm, params, &width, &height);
- resize_context_buffers(cm, width, height);
-#ifdef ORI_CODE
- setup_render_size(cm, rb);
-#endif
- }
-
- if (width <= 0 || height <= 0)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Invalid frame size");
-
- // Check to make sure at least one of frames that this frame references
- // has valid dimensions.
- for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
- const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i);
- if (ref_frame != NULL) {
- has_valid_ref_frame |=
- valid_ref_frame_size(ref_frame->buf.y_crop_width,
- ref_frame->buf.y_crop_height, width, height);
- }
- }
- if (!has_valid_ref_frame)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Referenced frame has invalid size");
- for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
- const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i);
- if (ref_frame != NULL) {
- if (!valid_ref_frame_img_fmt(
- ref_frame->buf.bit_depth, ref_frame->buf.subsampling_x,
- ref_frame->buf.subsampling_y, seq_params->bit_depth,
- seq_params->subsampling_x, seq_params->subsampling_y))
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Referenced frame has incompatible color format");
- }
- }
- setup_buffer_pool(cm);
-}
-
-typedef struct {
- int map_idx; // frame map index
- RefCntBuffer *buf; // frame buffer
- int sort_idx; // index based on the offset to be used for sorting
-} REF_FRAME_INFO;
-
-// Compares the sort_idx fields. If they are equal, then compares the map_idx
-// fields to break the tie. This ensures a stable sort.
-static int compare_ref_frame_info(const void *arg_a, const void *arg_b) {
- const REF_FRAME_INFO *info_a = (REF_FRAME_INFO *)arg_a;
- const REF_FRAME_INFO *info_b = (REF_FRAME_INFO *)arg_b;
-
- const int sort_idx_diff = info_a->sort_idx - info_b->sort_idx;
- if (sort_idx_diff != 0) return sort_idx_diff;
- return info_a->map_idx - info_b->map_idx;
-}
-
-
-/*
-for av1_setup_motion_field()
-*/
-static int motion_field_projection(AV1_COMMON *cm,
- MV_REFERENCE_FRAME start_frame, int dir) {
-#ifdef ORI_CODE
- TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
- int ref_offset[REF_FRAMES] = { 0 };
-#endif
- MV_REFERENCE_FRAME rf;
- const RefCntBuffer *const start_frame_buf =
- get_ref_frame_buf(cm, start_frame);
- int start_frame_order_hint;
- unsigned int const *ref_order_hints;
- int cur_order_hint;
- int start_to_current_frame_offset;
-
-#ifdef AML
- int i;
- //av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "$$$$$$$$$$$%s:cm->mv_ref_id_index = %d, start_frame=%d\n", __func__, cm->mv_ref_id_index, start_frame);
- cm->mv_ref_id[cm->mv_ref_id_index] = start_frame;
- for (i = 0; i < REF_FRAMES; i++) {
- cm->mv_ref_offset[cm->mv_ref_id_index][i]=0;
- }
- cm->mv_cal_tpl_mvs[cm->mv_ref_id_index]=0;
- cm->mv_ref_id_index++;
-#endif
- if (start_frame_buf == NULL) return 0;
-
- if (start_frame_buf->frame_type == KEY_FRAME ||
- start_frame_buf->frame_type == INTRA_ONLY_FRAME)
- return 0;
-
- if (start_frame_buf->mi_rows != cm->mi_rows ||
- start_frame_buf->mi_cols != cm->mi_cols)
- return 0;
-
- start_frame_order_hint = start_frame_buf->order_hint;
- ref_order_hints =
- &start_frame_buf->ref_order_hints[0];
- cur_order_hint = cm->cur_frame->order_hint;
- start_to_current_frame_offset = get_relative_dist(
- &cm->seq_params.order_hint_info, start_frame_order_hint, cur_order_hint);
-
- for (rf = LAST_FRAME; rf <= INTER_REFS_PER_FRAME; ++rf) {
- cm->mv_ref_offset[cm->mv_ref_id_index-1][rf] = get_relative_dist(&cm->seq_params.order_hint_info,
- start_frame_order_hint,
- ref_order_hints[rf - LAST_FRAME]);
- }
-#ifdef AML
- cm->mv_cal_tpl_mvs[cm->mv_ref_id_index-1]=1;
-#endif
- if (dir == 2) start_to_current_frame_offset = -start_to_current_frame_offset;
-#ifdef ORI_CODE
- MV_REF *mv_ref_base = start_frame_buf->mvs;
- const int mvs_rows = (cm->mi_rows + 1) >> 1;
- const int mvs_cols = (cm->mi_cols + 1) >> 1;
-
- for (int blk_row = 0; blk_row < mvs_rows; ++blk_row) {
- for (int blk_col = 0; blk_col < mvs_cols; ++blk_col) {
- MV_REF *mv_ref = &mv_ref_base[blk_row * mvs_cols + blk_col];
- MV fwd_mv = mv_ref->mv.as_mv;
-
- if (mv_ref->ref_frame > INTRA_FRAME) {
- int_mv this_mv;
- int mi_r, mi_c;
- const int ref_frame_offset = ref_offset[mv_ref->ref_frame];
-
- int pos_valid =
- abs(ref_frame_offset) <= MAX_FRAME_DISTANCE &&
- ref_frame_offset > 0 &&
- abs(start_to_current_frame_offset) <= MAX_FRAME_DISTANCE;
-
- if (pos_valid) {
- get_mv_projection(&this_mv.as_mv, fwd_mv,
- start_to_current_frame_offset, ref_frame_offset);
- pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
- this_mv.as_mv, dir >> 1);
- }
-
- if (pos_valid) {
- const int mi_offset = mi_r * (cm->mi_stride >> 1) + mi_c;
-
- tpl_mvs_base[mi_offset].mfmv0.as_mv.row = fwd_mv.row;
- tpl_mvs_base[mi_offset].mfmv0.as_mv.col = fwd_mv.col;
- tpl_mvs_base[mi_offset].ref_frame_offset = ref_frame_offset;
- }
- }
- }
- }
-#endif
- return 1;
-}
-
-#ifdef AML
-static int setup_motion_field_debug_count = 0;
-#endif
-void av1_setup_motion_field(AV1_COMMON *cm) {
- const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info;
- int ref_frame;
- int size;
- int cur_order_hint;
- const RefCntBuffer *ref_buf[INTER_REFS_PER_FRAME];
- int ref_order_hint[INTER_REFS_PER_FRAME];
- int ref_stamp;
- memset(cm->ref_frame_side, 0, sizeof(cm->ref_frame_side));
- if (!order_hint_info->enable_order_hint) return;
-#ifdef ORI_CODE
- TPL_MV_REF *tpl_mvs_base = cm->tpl_mvs;
-#endif
- size = ((cm->mi_rows + MAX_MIB_SIZE) >> 1) * (cm->mi_stride >> 1);
-#ifdef ORI_CODE
- for (int idx = 0; idx < size; ++idx) {
- tpl_mvs_base[idx].mfmv0.as_int = INVALID_MV;
- tpl_mvs_base[idx].ref_frame_offset = 0;
- }
-#endif
- cur_order_hint = cm->cur_frame->order_hint;
-
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
- const int ref_idx = ref_frame - LAST_FRAME;
- const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
- int order_hint = 0;
-
- if (buf != NULL) order_hint = buf->order_hint;
-
- ref_buf[ref_idx] = buf;
- ref_order_hint[ref_idx] = order_hint;
-
- if (get_relative_dist(order_hint_info, order_hint, cur_order_hint) > 0)
- cm->ref_frame_side[ref_frame] = 1;
- else if (order_hint == cur_order_hint)
- cm->ref_frame_side[ref_frame] = -1;
- }
- ref_stamp = MFMV_STACK_SIZE - 1;
-#ifdef AML
- cm->mv_ref_id_index = 0;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s(%d) mi_cols %d mi_rows %d\n",
- __func__, setup_motion_field_debug_count++,
- cm->mi_cols,
- cm->mi_rows
- );
-#endif
- if (ref_buf[LAST_FRAME - LAST_FRAME] != NULL) {
- const int alt_of_lst_order_hint =
- ref_buf[LAST_FRAME - LAST_FRAME]
- ->ref_order_hints[ALTREF_FRAME - LAST_FRAME];
-
- const int is_lst_overlay =
- (alt_of_lst_order_hint == ref_order_hint[GOLDEN_FRAME - LAST_FRAME]);
- if (!is_lst_overlay) motion_field_projection(cm, LAST_FRAME, 2);
- --ref_stamp;
- }
-
- if (get_relative_dist(order_hint_info,
- ref_order_hint[BWDREF_FRAME - LAST_FRAME],
- cur_order_hint) > 0) {
- if (motion_field_projection(cm, BWDREF_FRAME, 0)) --ref_stamp;
- }
-
- if (get_relative_dist(order_hint_info,
- ref_order_hint[ALTREF2_FRAME - LAST_FRAME],
- cur_order_hint) > 0) {
- if (motion_field_projection(cm, ALTREF2_FRAME, 0)) --ref_stamp;
- }
-
- if (get_relative_dist(order_hint_info,
- ref_order_hint[ALTREF_FRAME - LAST_FRAME],
- cur_order_hint) > 0 &&
- ref_stamp >= 0)
- if (motion_field_projection(cm, ALTREF_FRAME, 0)) --ref_stamp;
-
- if (ref_stamp >= 0) motion_field_projection(cm, LAST2_FRAME, 2);
-}
-
-
-static void set_ref_frame_info(int *remapped_ref_idx, int frame_idx,
- REF_FRAME_INFO *ref_info) {
- assert(frame_idx >= 0 && frame_idx < INTER_REFS_PER_FRAME);
-
- remapped_ref_idx[frame_idx] = ref_info->map_idx;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "+++++++++++++%s:remapped_ref_idx[%d]=0x%x\n", __func__, frame_idx, ref_info->map_idx);
-}
-
-
-void av1_set_frame_refs(AV1_COMMON *const cm, int *remapped_ref_idx,
- int lst_map_idx, int gld_map_idx) {
- int lst_frame_sort_idx = -1;
- int gld_frame_sort_idx = -1;
- int i;
- //assert(cm->seq_params.order_hint_info.enable_order_hint);
- //assert(cm->seq_params.order_hint_info.order_hint_bits_minus_1 >= 0);
- const int cur_order_hint = (int)cm->current_frame.order_hint;
- const int cur_frame_sort_idx =
- 1 << cm->seq_params.order_hint_info.order_hint_bits_minus_1;
-
- REF_FRAME_INFO ref_frame_info[REF_FRAMES];
- int ref_flag_list[INTER_REFS_PER_FRAME] = { 0, 0, 0, 0, 0, 0, 0 };
- int bwd_start_idx;
- int bwd_end_idx;
- int fwd_start_idx, fwd_end_idx;
- int ref_idx;
- static const MV_REFERENCE_FRAME ref_frame_list[INTER_REFS_PER_FRAME - 2] = {
- LAST2_FRAME, LAST3_FRAME, BWDREF_FRAME, ALTREF2_FRAME, ALTREF_FRAME
- };
-
- for (i = 0; i < REF_FRAMES; ++i) {
- const int map_idx = i;
- RefCntBuffer *buf;
- int offset;
-
- ref_frame_info[i].map_idx = map_idx;
- ref_frame_info[i].sort_idx = -1;
-
- buf = cm->ref_frame_map[map_idx];
- ref_frame_info[i].buf = buf;
-
- if (buf == NULL) continue;
- // If this assertion fails, there is a reference leak.
- assert(buf->ref_count > 0);
-
- offset = (int)buf->order_hint;
- ref_frame_info[i].sort_idx =
- (offset == -1) ? -1
- : cur_frame_sort_idx +
- get_relative_dist(&cm->seq_params.order_hint_info,
- offset, cur_order_hint);
- assert(ref_frame_info[i].sort_idx >= -1);
-
- if (map_idx == lst_map_idx) lst_frame_sort_idx = ref_frame_info[i].sort_idx;
- if (map_idx == gld_map_idx) gld_frame_sort_idx = ref_frame_info[i].sort_idx;
- }
-
- // Confirm both LAST_FRAME and GOLDEN_FRAME are valid forward reference
- // frames.
- if (lst_frame_sort_idx == -1 || lst_frame_sort_idx >= cur_frame_sort_idx) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Inter frame requests a look-ahead frame as LAST");
- }
- if (gld_frame_sort_idx == -1 || gld_frame_sort_idx >= cur_frame_sort_idx) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Inter frame requests a look-ahead frame as GOLDEN");
- }
-
- // Sort ref frames based on their frame_offset values.
- qsort(ref_frame_info, REF_FRAMES, sizeof(REF_FRAME_INFO),
- compare_ref_frame_info);
-
- // Identify forward and backward reference frames.
- // Forward reference: offset < order_hint
- // Backward reference: offset >= order_hint
- fwd_start_idx = 0;
- fwd_end_idx = REF_FRAMES - 1;
-
- for (i = 0; i < REF_FRAMES; i++) {
- if (ref_frame_info[i].sort_idx == -1) {
- fwd_start_idx++;
- continue;
- }
-
- if (ref_frame_info[i].sort_idx >= cur_frame_sort_idx) {
- fwd_end_idx = i - 1;
- break;
- }
- }
-
- bwd_start_idx = fwd_end_idx + 1;
- bwd_end_idx = REF_FRAMES - 1;
-
- // === Backward Reference Frames ===
-
- // == ALTREF_FRAME ==
- if (bwd_start_idx <= bwd_end_idx) {
- set_ref_frame_info(remapped_ref_idx, ALTREF_FRAME - LAST_FRAME,
- &ref_frame_info[bwd_end_idx]);
- ref_flag_list[ALTREF_FRAME - LAST_FRAME] = 1;
- bwd_end_idx--;
- }
-
- // == BWDREF_FRAME ==
- if (bwd_start_idx <= bwd_end_idx) {
- set_ref_frame_info(remapped_ref_idx, BWDREF_FRAME - LAST_FRAME,
- &ref_frame_info[bwd_start_idx]);
- ref_flag_list[BWDREF_FRAME - LAST_FRAME] = 1;
- bwd_start_idx++;
- }
-
- // == ALTREF2_FRAME ==
- if (bwd_start_idx <= bwd_end_idx) {
- set_ref_frame_info(remapped_ref_idx, ALTREF2_FRAME - LAST_FRAME,
- &ref_frame_info[bwd_start_idx]);
- ref_flag_list[ALTREF2_FRAME - LAST_FRAME] = 1;
- }
-
- // === Forward Reference Frames ===
-
- for (i = fwd_start_idx; i <= fwd_end_idx; ++i) {
- // == LAST_FRAME ==
- if (ref_frame_info[i].map_idx == lst_map_idx) {
- set_ref_frame_info(remapped_ref_idx, LAST_FRAME - LAST_FRAME,
- &ref_frame_info[i]);
- ref_flag_list[LAST_FRAME - LAST_FRAME] = 1;
- }
-
- // == GOLDEN_FRAME ==
- if (ref_frame_info[i].map_idx == gld_map_idx) {
- set_ref_frame_info(remapped_ref_idx, GOLDEN_FRAME - LAST_FRAME,
- &ref_frame_info[i]);
- ref_flag_list[GOLDEN_FRAME - LAST_FRAME] = 1;
- }
- }
-
- assert(ref_flag_list[LAST_FRAME - LAST_FRAME] == 1 &&
- ref_flag_list[GOLDEN_FRAME - LAST_FRAME] == 1);
-
- // == LAST2_FRAME ==
- // == LAST3_FRAME ==
- // == BWDREF_FRAME ==
- // == ALTREF2_FRAME ==
- // == ALTREF_FRAME ==
-
- // Set up the reference frames in the anti-chronological order.
- for (ref_idx = 0; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) {
- const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx];
-
- if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue;
-
- while (fwd_start_idx <= fwd_end_idx &&
- (ref_frame_info[fwd_end_idx].map_idx == lst_map_idx ||
- ref_frame_info[fwd_end_idx].map_idx == gld_map_idx)) {
- fwd_end_idx--;
- }
- if (fwd_start_idx > fwd_end_idx) break;
-
- set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME,
- &ref_frame_info[fwd_end_idx]);
- ref_flag_list[ref_frame - LAST_FRAME] = 1;
-
- fwd_end_idx--;
- }
-
- // Assign all the remaining frame(s), if any, to the earliest reference frame.
- for (; ref_idx < (INTER_REFS_PER_FRAME - 2); ref_idx++) {
- const MV_REFERENCE_FRAME ref_frame = ref_frame_list[ref_idx];
- if (ref_flag_list[ref_frame - LAST_FRAME] == 1) continue;
- set_ref_frame_info(remapped_ref_idx, ref_frame - LAST_FRAME,
- &ref_frame_info[fwd_start_idx]);
- ref_flag_list[ref_frame - LAST_FRAME] = 1;
- }
-
- for (i = 0; i < INTER_REFS_PER_FRAME; i++) {
- assert(ref_flag_list[i] == 1);
- }
-}
-
-void av1_setup_frame_buf_refs(AV1_COMMON *cm) {
- MV_REFERENCE_FRAME ref_frame;
- cm->cur_frame->order_hint = cm->current_frame.order_hint;
-
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
- if (buf != NULL)
- cm->cur_frame->ref_order_hints[ref_frame - LAST_FRAME] = buf->order_hint;
- }
-}
-
-void av1_setup_frame_sign_bias(AV1_COMMON *cm) {
- MV_REFERENCE_FRAME ref_frame;
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
- if (cm->seq_params.order_hint_info.enable_order_hint && buf != NULL) {
- const int ref_order_hint = buf->order_hint;
- cm->ref_frame_sign_bias[ref_frame] =
- (get_relative_dist(&cm->seq_params.order_hint_info, ref_order_hint,
- (int)cm->current_frame.order_hint) <= 0)
- ? 0
- : 1;
- } else {
- cm->ref_frame_sign_bias[ref_frame] = 0;
- }
- }
-}
-
-
-void av1_setup_skip_mode_allowed(AV1_COMMON *cm)
-{
- const OrderHintInfo *const order_hint_info = &cm->seq_params.order_hint_info;
- SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
- int i;
- int cur_order_hint;
- int ref_order_hints[2] = { -1, INT_MAX };
- int ref_idx[2] = { INVALID_IDX, INVALID_IDX };
-
- skip_mode_info->skip_mode_allowed = 0;
- skip_mode_info->ref_frame_idx_0 = INVALID_IDX;
- skip_mode_info->ref_frame_idx_1 = INVALID_IDX;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "av1_setup_skip_mode_allowed %d %d %d\n", order_hint_info->enable_order_hint,
- frame_is_intra_only(cm),
- cm->current_frame.reference_mode);
- if (!order_hint_info->enable_order_hint || frame_is_intra_only(cm) ||
- cm->current_frame.reference_mode == SINGLE_REFERENCE)
- return;
-
- cur_order_hint = cm->current_frame.order_hint;
-
- // Identify the nearest forward and backward references.
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- const RefCntBuffer *const buf = get_ref_frame_buf(cm, LAST_FRAME + i);
- int ref_order_hint;
- if (buf == NULL) continue;
-
- ref_order_hint = buf->order_hint;
- if (get_relative_dist(order_hint_info, ref_order_hint, cur_order_hint) < 0) {
- // Forward reference
- if (ref_order_hints[0] == -1 ||
- get_relative_dist(order_hint_info, ref_order_hint,
- ref_order_hints[0]) > 0) {
- ref_order_hints[0] = ref_order_hint;
- ref_idx[0] = i;
- }
- } else if (get_relative_dist(order_hint_info, ref_order_hint,
- cur_order_hint) > 0) {
- // Backward reference
- if (ref_order_hints[1] == INT_MAX ||
- get_relative_dist(order_hint_info, ref_order_hint,
- ref_order_hints[1]) < 0) {
- ref_order_hints[1] = ref_order_hint;
- ref_idx[1] = i;
- }
- }
- }
-
- if (ref_idx[0] != INVALID_IDX && ref_idx[1] != INVALID_IDX) {
- // == Bi-directional prediction ==
- skip_mode_info->skip_mode_allowed = 1;
- skip_mode_info->ref_frame_idx_0 = AOMMIN(ref_idx[0], ref_idx[1]);
- skip_mode_info->ref_frame_idx_1 = AOMMAX(ref_idx[0], ref_idx[1]);
- } else if (ref_idx[0] != INVALID_IDX && ref_idx[1] == INVALID_IDX) {
- // == Forward prediction only ==
- // Identify the second nearest forward reference.
- ref_order_hints[1] = -1;
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- const RefCntBuffer *const buf = get_ref_frame_buf(cm, LAST_FRAME + i);
- int ref_order_hint;
- if (buf == NULL) continue;
-
- ref_order_hint = buf->order_hint;
- if ((ref_order_hints[0] != -1 &&
- get_relative_dist(order_hint_info, ref_order_hint, ref_order_hints[0]) < 0) &&
- (ref_order_hints[1] == -1 ||
- get_relative_dist(order_hint_info, ref_order_hint, ref_order_hints[1]) > 0)) {
- // Second closest forward reference
- ref_order_hints[1] = ref_order_hint;
- ref_idx[1] = i;
- }
- }
- if (ref_order_hints[1] != -1) {
- skip_mode_info->skip_mode_allowed = 1;
- skip_mode_info->ref_frame_idx_0 = AOMMIN(ref_idx[0], ref_idx[1]);
- skip_mode_info->ref_frame_idx_1 = AOMMAX(ref_idx[0], ref_idx[1]);
- }
- }
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL,
- "skip_mode_info: skip_mode_allowed 0x%x 0x%x 0x%x\n",
- cm->current_frame.skip_mode_info.skip_mode_allowed,
- cm->current_frame.skip_mode_info.ref_frame_idx_0,
- cm->current_frame.skip_mode_info.ref_frame_idx_1);
-}
-
-static inline int frame_might_allow_ref_frame_mvs(const AV1_COMMON *cm) {
- return !cm->error_resilient_mode &&
- cm->seq_params.order_hint_info.enable_ref_frame_mvs &&
- cm->seq_params.order_hint_info.enable_order_hint &&
- !frame_is_intra_only(cm);
-}
-
-#ifdef ORI_CODE
-/*
-* segmentation
-*/
-static const int seg_feature_data_signed[SEG_LVL_MAX] = {
- 1, 1, 1, 1, 1, 0, 0, 0
-};
-
-static const int seg_feature_data_max[SEG_LVL_MAX] = { MAXQ,
- MAX_LOOP_FILTER,
- MAX_LOOP_FILTER,
- MAX_LOOP_FILTER,
- MAX_LOOP_FILTER,
- 7,
- 0,
- 0 };
-
-
-static inline void segfeatures_copy(struct segmentation *dst,
- const struct segmentation *src) {
- int i, j;
- for (i = 0; i < MAX_SEGMENTS; i++) {
- dst->feature_mask[i] = src->feature_mask[i];
- for (j = 0; j < SEG_LVL_MAX; j++) {
- dst->feature_data[i][j] = src->feature_data[i][j];
- }
- }
- dst->segid_preskip = src->segid_preskip;
- dst->last_active_segid = src->last_active_segid;
-}
-
-static void av1_clearall_segfeatures(struct segmentation *seg) {
- av1_zero(seg->feature_data);
- av1_zero(seg->feature_mask);
-}
-
-static void av1_enable_segfeature(struct segmentation *seg, int segment_id,
- int feature_id) {
- seg->feature_mask[segment_id] |= 1 << feature_id;
-}
-
-void av1_calculate_segdata(struct segmentation *seg) {
- seg->segid_preskip = 0;
- seg->last_active_segid = 0;
- for (int i = 0; i < MAX_SEGMENTS; i++) {
- for (int j = 0; j < SEG_LVL_MAX; j++) {
- if (seg->feature_mask[i] & (1 << j)) {
- seg->segid_preskip |= (j >= SEG_LVL_REF_FRAME);
- seg->last_active_segid = i;
- }
- }
- }
-}
-
-static int av1_seg_feature_data_max(int feature_id) {
- return seg_feature_data_max[feature_id];
-}
-
-static int av1_is_segfeature_signed(int feature_id) {
- return seg_feature_data_signed[feature_id];
-}
-
-static void av1_set_segdata(struct segmentation *seg, int segment_id,
- int feature_id, int seg_data) {
- if (seg_data < 0) {
- assert(seg_feature_data_signed[feature_id]);
- assert(-seg_data <= seg_feature_data_max[feature_id]);
- } else {
- assert(seg_data <= seg_feature_data_max[feature_id]);
- }
-
- seg->feature_data[segment_id][feature_id] = seg_data;
-}
-
-static inline int clamp(int value, int low, int high) {
- return value < low ? low : (value > high ? high : value);
-}
-
-static void setup_segmentation(AV1_COMMON *const cm,
- union param_u *params) {
- struct segmentation *const seg = &cm->seg;
-
- seg->update_map = 0;
- seg->update_data = 0;
- seg->temporal_update = 0;
-
- seg->enabled = params->p.seg_enabled; //aom_rb_read_bit(-1, defmark, rb);
- if (!seg->enabled) {
- if (cm->cur_frame->seg_map)
- memset(cm->cur_frame->seg_map, 0, (cm->mi_rows * cm->mi_cols));
-
- memset(seg, 0, sizeof(*seg));
- segfeatures_copy(&cm->cur_frame->seg, seg);
- return;
- }
- if (cm->seg.enabled && cm->prev_frame &&
- (cm->mi_rows == cm->prev_frame->mi_rows) &&
- (cm->mi_cols == cm->prev_frame->mi_cols)) {
- cm->last_frame_seg_map = cm->prev_frame->seg_map;
- } else {
- cm->last_frame_seg_map = NULL;
- }
- // Read update flags
- if (cm->primary_ref_frame == PRIMARY_REF_NONE) {
- // These frames can't use previous frames, so must signal map + features
- seg->update_map = 1;
- seg->temporal_update = 0;
- seg->update_data = 1;
- } else {
- seg->update_map = params->p.seg_update_map; // aom_rb_read_bit(-1, defmark, rb);
- if (seg->update_map) {
- seg->temporal_update = params->p.seg_temporal_update; //aom_rb_read_bit(-1, defmark, rb);
- } else {
- seg->temporal_update = 0;
- }
- seg->update_data = params->p.seg_update_data; //aom_rb_read_bit(-1, defmark, rb);
- }
-
- // Segmentation data update
- if (seg->update_data) {
- av1_clearall_segfeatures(seg);
-
- for (int i = 0; i < MAX_SEGMENTS; i++) {
- for (int j = 0; j < SEG_LVL_MAX; j++) {
- int data = 0;
- const int feature_enabled = params->p.seg_feature_enabled ;//aom_rb_read_bit(-1, defmark, rb);
- if (feature_enabled) {
- av1_enable_segfeature(seg, i, j);
-
- const int data_max = av1_seg_feature_data_max(j);
- const int data_min = -data_max;
- /*
- const int ubits = get_unsigned_bits(data_max);
-
- if (av1_is_segfeature_signed(j)) {
- data = aom_rb_read_inv_signed_literal(-1, defmark, rb, ubits);
- } else {
- data = aom_rb_read_literal(-1, defmark, rb, ubits);
- }*/
- data = params->p.seg_data;
- data = clamp(data, data_min, data_max);
- }
- av1_set_segdata(seg, i, j, data);
- }
- }
- av1_calculate_segdata(seg);
- } else if (cm->prev_frame) {
- segfeatures_copy(seg, &cm->prev_frame->seg);
- }
- segfeatures_copy(&cm->cur_frame->seg, seg);
-}
-#endif
-
-/**/
-
-
-int av1_decode_frame_headers_and_setup(AV1Decoder *pbi, int trailing_bits_present, union param_u *params)
-{
- AV1_COMMON *const cm = pbi->common;
- /*
- read_uncompressed_header()
- */
- const SequenceHeader *const seq_params = &cm->seq_params;
- CurrentFrame *const current_frame = &cm->current_frame;
- //MACROBLOCKD *const xd = &pbi->mb;
- BufferPool *const pool = cm->buffer_pool;
- RefCntBuffer *const frame_bufs = pool->frame_bufs;
- int i;
- int frame_size_override_flag;
- unsigned long flags;
-
- if (!pbi->sequence_header_ready) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "No sequence header");
- }
- cm->last_frame_type = current_frame->frame_type;
-
- if (seq_params->reduced_still_picture_hdr) {
- cm->show_existing_frame = 0;
- cm->show_frame = 1;
- current_frame->frame_type = KEY_FRAME;
- if (pbi->sequence_header_changed) {
- // This is the start of a new coded video sequence.
- pbi->sequence_header_changed = 0;
- pbi->decoding_first_frame = 1;
- reset_frame_buffers(pbi);
- }
- cm->error_resilient_mode = 1;
- } else {
- cm->show_existing_frame = params->p.show_existing_frame;
- pbi->reset_decoder_state = 0;
- if (cm->show_existing_frame) {
- int existing_frame_idx;
- RefCntBuffer *frame_to_show;
- if (pbi->sequence_header_changed) {
- aom_internal_error(
- &cm->error, AOM_CODEC_CORRUPT_FRAME,
- "New sequence header starts with a show_existing_frame.");
- }
- // Show an existing frame directly.
- existing_frame_idx = params->p.existing_frame_idx; //aom_rb_read_literal(rb, 3);
- frame_to_show = cm->ref_frame_map[existing_frame_idx];
- if (frame_to_show == NULL) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Buffer does not contain a decoded frame");
- return 0;
- }
- if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0) {
- cm->frame_presentation_time = params->p.frame_presentation_time;
- //read_temporal_point_info(cm);
- }
- if (seq_params->frame_id_numbers_present_flag) {
- //int frame_id_length = seq_params->frame_id_length;
- int display_frame_id = params->p.display_frame_id; //aom_rb_read_literal(rb, frame_id_length);
- /* Compare display_frame_id with ref_frame_id and check valid for
- * referencing */
- if (display_frame_id != cm->ref_frame_id[existing_frame_idx] ||
- cm->valid_for_referencing[existing_frame_idx] == 0)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Reference buffer frame ID mismatch");
- }
- lock_buffer_pool(pool, flags);
- assert(frame_to_show->ref_count > 0);
- // cm->cur_frame should be the buffer referenced by the return value
- // of the get_free_fb() call in av1_receive_compressed_data(), and
- // generate_next_ref_frame_map() has not been called, so ref_count
- // should still be 1.
- assert(cm->cur_frame->ref_count == 1);
- // assign_frame_buffer_p() decrements ref_count directly rather than
- // call decrease_ref_count(). If cm->cur_frame->raw_frame_buffer has
- // already been allocated, it will not be released by
- // assign_frame_buffer_p()!
- assert(!cm->cur_frame->raw_frame_buffer.data);
-
- if (check_buff_has_show(frame_to_show)) {
- frame_to_show->buf.v4l_buf_index = cm->cur_frame->buf.index;
- frame_to_show->buf.repeat_count ++;
- cm->cur_frame->buf.repeat_pic = &frame_to_show->buf;
- }
-
- frame_to_show->buf.timestamp = cm->cur_frame->buf.timestamp;
-
- assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
- pbi->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME;
- unlock_buffer_pool(pool, flags);
-
-#ifdef ORI_CODE
- cm->lf.filter_level[0] = 0;
- cm->lf.filter_level[1] = 0;
-#endif
- cm->show_frame = 1;
-
- // Section 6.8.2: It is a requirement of bitstream conformance that when
- // show_existing_frame is used to show a previous frame, that the value
- // of showable_frame for the previous frame was equal to 1.
- if (!frame_to_show->showable_frame) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Buffer does not contain a showable frame");
- }
- // Section 6.8.2: It is a requirement of bitstream conformance that when
- // show_existing_frame is used to show a previous frame with
- // RefFrameType[ frame_to_show_map_idx ] equal to KEY_FRAME, that the
- // frame is output via the show_existing_frame mechanism at most once.
- if (pbi->reset_decoder_state) frame_to_show->showable_frame = 0;
-
-#ifdef ORI_CODE
- cm->film_grain_params = frame_to_show->film_grain_params;
-#endif
- if (pbi->reset_decoder_state) {
- show_existing_frame_reset(pbi, existing_frame_idx);
- } else {
- current_frame->refresh_frame_flags = 0;
- }
-
- return 0;
- }
-
- current_frame->frame_type = (FRAME_TYPE)params->p.frame_type; //aom_rb_read_literal(rb, 2);
- if (pbi->sequence_header_changed) {
- if (current_frame->frame_type == KEY_FRAME) {
- // This is the start of a new coded video sequence.
- pbi->sequence_header_changed = 0;
- pbi->decoding_first_frame = 1;
- reset_frame_buffers(pbi);
- } else {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Sequence header has changed without a keyframe.");
- }
- }
- cm->show_frame = params->p.show_frame; //aom_rb_read_bit(rb);
- if (seq_params->still_picture &&
- (current_frame->frame_type != KEY_FRAME || !cm->show_frame)) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Still pictures must be coded as shown keyframes");
- }
- cm->showable_frame = current_frame->frame_type != KEY_FRAME;
- if (cm->show_frame) {
- if (seq_params->decoder_model_info_present_flag &&
- cm->timing_info.equal_picture_interval == 0)
- cm->frame_presentation_time = params->p.frame_presentation_time;
- //read_temporal_point_info(cm);
- } else {
- // See if this frame can be used as show_existing_frame in future
- cm->showable_frame = params->p.showable_frame;//aom_rb_read_bit(rb);
- }
- cm->cur_frame->show_frame = cm->show_frame;
- cm->cur_frame->showable_frame = cm->showable_frame;
- cm->error_resilient_mode =
- frame_is_sframe(cm) ||
- (current_frame->frame_type == KEY_FRAME && cm->show_frame)
- ? 1
- : params->p.error_resilient_mode; //aom_rb_read_bit(rb);
- }
-
-#ifdef ORI_CODE
- cm->disable_cdf_update = aom_rb_read_bit(rb);
- if (seq_params->force_screen_content_tools == 2) {
- cm->allow_screen_content_tools = aom_rb_read_bit(rb);
- } else {
- cm->allow_screen_content_tools = seq_params->force_screen_content_tools;
- }
-
- if (cm->allow_screen_content_tools) {
- if (seq_params->force_integer_mv == 2) {
- cm->cur_frame_force_integer_mv = aom_rb_read_bit(rb);
- } else {
- cm->cur_frame_force_integer_mv = seq_params->force_integer_mv;
- }
- } else {
- cm->cur_frame_force_integer_mv = 0;
- }
-#endif
-
- frame_size_override_flag = 0;
- cm->allow_intrabc = 0;
- cm->primary_ref_frame = PRIMARY_REF_NONE;
-
- if (!seq_params->reduced_still_picture_hdr) {
- if (seq_params->frame_id_numbers_present_flag) {
- int frame_id_length = seq_params->frame_id_length;
- int diff_len = seq_params->delta_frame_id_length;
- int prev_frame_id = 0;
- int have_prev_frame_id =
- !pbi->decoding_first_frame &&
- !(current_frame->frame_type == KEY_FRAME && cm->show_frame);
- if (have_prev_frame_id) {
- prev_frame_id = cm->current_frame_id;
- }
- cm->current_frame_id = params->p.current_frame_id; //aom_rb_read_literal(rb, frame_id_length);
-
- if (have_prev_frame_id) {
- int diff_frame_id;
- if (cm->current_frame_id > prev_frame_id) {
- diff_frame_id = cm->current_frame_id - prev_frame_id;
- } else {
- diff_frame_id =
- (1 << frame_id_length) + cm->current_frame_id - prev_frame_id;
- }
- /* Check current_frame_id for conformance */
- if (prev_frame_id == cm->current_frame_id ||
- diff_frame_id >= (1 << (frame_id_length - 1))) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Invalid value of current_frame_id");
- }
- }
- /* Check if some frames need to be marked as not valid for referencing */
- for (i = 0; i < REF_FRAMES; i++) {
- if (current_frame->frame_type == KEY_FRAME && cm->show_frame) {
- cm->valid_for_referencing[i] = 0;
- } else if (cm->current_frame_id - (1 << diff_len) > 0) {
- if (cm->ref_frame_id[i] > cm->current_frame_id ||
- cm->ref_frame_id[i] < cm->current_frame_id - (1 << diff_len))
- cm->valid_for_referencing[i] = 0;
- } else {
- if (cm->ref_frame_id[i] > cm->current_frame_id &&
- cm->ref_frame_id[i] < (1 << frame_id_length) +
- cm->current_frame_id - (1 << diff_len))
- cm->valid_for_referencing[i] = 0;
- }
- }
- }
-
- frame_size_override_flag = frame_is_sframe(cm) ? 1 : params->p.frame_size_override_flag; //aom_rb_read_bit(rb);
-
- current_frame->order_hint = params->p.order_hint; /*aom_rb_read_literal(
- rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);*/
- current_frame->frame_number = current_frame->order_hint;
-
- if (!cm->error_resilient_mode && !frame_is_intra_only(cm)) {
- cm->primary_ref_frame = params->p.primary_ref_frame;//aom_rb_read_literal(rb, PRIMARY_REF_BITS);
- }
- }
-
- if (seq_params->decoder_model_info_present_flag) {
- cm->buffer_removal_time_present = params->p.buffer_removal_time_present; //aom_rb_read_bit(rb);
- if (cm->buffer_removal_time_present) {
- int op_num;
- for (op_num = 0;
- op_num < seq_params->operating_points_cnt_minus_1 + 1; op_num++) {
- if (cm->op_params[op_num].decoder_model_param_present_flag) {
- if ((((seq_params->operating_point_idc[op_num] >>
- cm->temporal_layer_id) &
- 0x1) &&
- ((seq_params->operating_point_idc[op_num] >>
- (cm->spatial_layer_id + 8)) &
- 0x1)) ||
- seq_params->operating_point_idc[op_num] == 0) {
- cm->op_frame_timing[op_num].buffer_removal_time =
- params->p.op_frame_timing[op_num];
- /*aom_rb_read_unsigned_literal(
- rb, cm->buffer_model.buffer_removal_time_length);*/
- } else {
- cm->op_frame_timing[op_num].buffer_removal_time = 0;
- }
- } else {
- cm->op_frame_timing[op_num].buffer_removal_time = 0;
- }
- }
- }
- }
- if (current_frame->frame_type == KEY_FRAME) {
- if (!cm->show_frame) { // unshown keyframe (forward keyframe)
- current_frame->refresh_frame_flags = params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES);
- } else { // shown keyframe
- current_frame->refresh_frame_flags = (1 << REF_FRAMES) - 1;
- }
-
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- cm->remapped_ref_idx[i] = INVALID_IDX;
- }
- if (pbi->need_resync) {
- reset_ref_frame_map(pbi);
- pbi->need_resync = 0;
- }
- } else {
- if (current_frame->frame_type == INTRA_ONLY_FRAME) {
- current_frame->refresh_frame_flags = params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES);
- if (current_frame->refresh_frame_flags == 0xFF) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Intra only frames cannot have refresh flags 0xFF");
- }
- if (pbi->need_resync) {
- reset_ref_frame_map(pbi);
- pbi->need_resync = 0;
- }
- } else if (pbi->need_resync != 1) { /* Skip if need resync */
- current_frame->refresh_frame_flags =
- frame_is_sframe(cm) ? 0xFF : params->p.refresh_frame_flags; //aom_rb_read_literal(rb, REF_FRAMES);
- }
- }
-
- if (!frame_is_intra_only(cm) || current_frame->refresh_frame_flags != 0xFF) {
- // Read all ref frame order hints if error_resilient_mode == 1
- if (cm->error_resilient_mode &&
- seq_params->order_hint_info.enable_order_hint) {
- int ref_idx;
- for (ref_idx = 0; ref_idx < REF_FRAMES; ref_idx++) {
- // Read order hint from bit stream
- unsigned int order_hint = params->p.ref_order_hint[ref_idx];/*aom_rb_read_literal(
- rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);*/
- // Get buffer
- RefCntBuffer *buf = cm->ref_frame_map[ref_idx];
- int buf_idx;
- if (buf == NULL || order_hint != buf->order_hint) {
- if (buf != NULL) {
- lock_buffer_pool(pool, flags);
- decrease_ref_count(pbi, buf, pool);
- unlock_buffer_pool(pool, flags);
- }
- // If no corresponding buffer exists, allocate a new buffer with all
- // pixels set to neutral grey.
- buf_idx = get_free_frame_buffer(cm);
- if (buf_idx == INVALID_IDX) {
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Unable to find free frame buffer");
- }
- buf = &frame_bufs[buf_idx];
- lock_buffer_pool(pool, flags);
- if (aom_realloc_frame_buffer(cm, &buf->buf, seq_params->max_frame_width,
- seq_params->max_frame_height, buf->order_hint)) {
- decrease_ref_count(pbi, buf, pool);
- unlock_buffer_pool(pool, flags);
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate frame buffer");
- }
- unlock_buffer_pool(pool, flags);
-#ifdef ORI_CODE
- set_planes_to_neutral_grey(seq_params, &buf->buf, 0);
-#endif
- cm->ref_frame_map[ref_idx] = buf;
- buf->order_hint = order_hint;
- }
- }
- }
- }
-
- if (current_frame->frame_type == KEY_FRAME) {
- setup_frame_size(cm, frame_size_override_flag, params);
-#ifdef ORI_CODE
- if (cm->allow_screen_content_tools && !av1_superres_scaled(cm))
- cm->allow_intrabc = aom_rb_read_bit(rb);
-#endif
- cm->allow_ref_frame_mvs = 0;
- cm->prev_frame = NULL;
- } else {
- cm->allow_ref_frame_mvs = 0;
-
- if (current_frame->frame_type == INTRA_ONLY_FRAME) {
-#ifdef ORI_CODE
- cm->cur_frame->film_grain_params_present =
- seq_params->film_grain_params_present;
-#endif
- setup_frame_size(cm, frame_size_override_flag, params);
-#ifdef ORI_CODE
- if (cm->allow_screen_content_tools && !av1_superres_scaled(cm))
- cm->allow_intrabc = aom_rb_read_bit(rb);
-#endif
- } else if (pbi->need_resync != 1) { /* Skip if need resync */
- int frame_refs_short_signaling = 0;
- // Frame refs short signaling is off when error resilient mode is on.
- if (seq_params->order_hint_info.enable_order_hint)
- frame_refs_short_signaling = params->p.frame_refs_short_signaling;//aom_rb_read_bit(rb);
-
- if (frame_refs_short_signaling) {
- // == LAST_FRAME ==
- const int lst_ref = params->p.lst_ref; //aom_rb_read_literal(rb, REF_FRAMES_LOG2);
- const RefCntBuffer *const lst_buf = cm->ref_frame_map[lst_ref];
-
- // == GOLDEN_FRAME ==
- const int gld_ref = params->p.gld_ref; //aom_rb_read_literal(rb, REF_FRAMES_LOG2);
- const RefCntBuffer *const gld_buf = cm->ref_frame_map[gld_ref];
-
- // Most of the time, streams start with a keyframe. In that case,
- // ref_frame_map will have been filled in at that point and will not
- // contain any NULLs. However, streams are explicitly allowed to start
- // with an intra-only frame, so long as they don't then signal a
- // reference to a slot that hasn't been set yet. That's what we are
- // checking here.
- if (lst_buf == NULL)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Inter frame requests nonexistent reference");
- if (gld_buf == NULL)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Inter frame requests nonexistent reference");
-
- av1_set_frame_refs(cm, cm->remapped_ref_idx, lst_ref, gld_ref);
- }
-
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- int ref = 0;
- if (!frame_refs_short_signaling) {
- ref = params->p.remapped_ref_idx[i];//aom_rb_read_literal(rb, REF_FRAMES_LOG2);
-
- // Most of the time, streams start with a keyframe. In that case,
- // ref_frame_map will have been filled in at that point and will not
- // contain any NULLs. However, streams are explicitly allowed to start
- // with an intra-only frame, so long as they don't then signal a
- // reference to a slot that hasn't been set yet. That's what we are
- // checking here.
- if (cm->ref_frame_map[ref] == NULL)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Inter frame requests nonexistent reference");
- cm->remapped_ref_idx[i] = ref;
- } else {
- ref = cm->remapped_ref_idx[i];
- }
-
- cm->ref_frame_sign_bias[LAST_FRAME + i] = 0;
-
- if (seq_params->frame_id_numbers_present_flag) {
- int frame_id_length = seq_params->frame_id_length;
- //int diff_len = seq_params->delta_frame_id_length;
- int delta_frame_id_minus_1 = params->p.delta_frame_id_minus_1[i];//aom_rb_read_literal(rb, diff_len);
- int ref_frame_id =
- ((cm->current_frame_id - (delta_frame_id_minus_1 + 1) +
- (1 << frame_id_length)) %
- (1 << frame_id_length));
- // Compare values derived from delta_frame_id_minus_1 and
- // refresh_frame_flags. Also, check valid for referencing
- if (ref_frame_id != cm->ref_frame_id[ref] ||
- cm->valid_for_referencing[ref] == 0)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Reference buffer frame ID mismatch");
- }
- }
-
- if (!cm->error_resilient_mode && frame_size_override_flag) {
- setup_frame_size_with_refs(cm, params);
- } else {
- setup_frame_size(cm, frame_size_override_flag, params);
- }
-#ifdef ORI_CODE
- if (cm->cur_frame_force_integer_mv) {
- cm->allow_high_precision_mv = 0;
- } else {
- cm->allow_high_precision_mv = aom_rb_read_bit(rb);
- }
- cm->interp_filter = read_frame_interp_filter(rb);
- cm->switchable_motion_mode = aom_rb_read_bit(rb);
-#endif
- }
-
- cm->prev_frame = get_primary_ref_frame_buf(cm);
- if (cm->primary_ref_frame != PRIMARY_REF_NONE &&
- get_primary_ref_frame_buf(cm) == NULL) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Reference frame containing this frame's initial "
- "frame context is unavailable.");
- }
-#if 0
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%d,%d,%d,%d\n",cm->error_resilient_mode,
- cm->seq_params.order_hint_info.enable_ref_frame_mvs,
- cm->seq_params.order_hint_info.enable_order_hint,frame_is_intra_only(cm));
-
- printf("frame_might_allow_ref_frame_mvs()=>%d, current_frame->frame_type=%d, pbi->need_resync=%d, params->p.allow_ref_frame_mvs=%d\n",
- frame_might_allow_ref_frame_mvs(cm), current_frame->frame_type, pbi->need_resync,
- params->p.allow_ref_frame_mvs);
-#endif
- if (!(current_frame->frame_type == INTRA_ONLY_FRAME) &&
- pbi->need_resync != 1) {
- if (frame_might_allow_ref_frame_mvs(cm))
- cm->allow_ref_frame_mvs = params->p.allow_ref_frame_mvs; //aom_rb_read_bit(-1, "<allow_ref_frame_mvs>", rb);
- else
- cm->allow_ref_frame_mvs = 0;
-
-#ifdef SUPPORT_SCALE_FACTOR
- for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
- const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, i);
- struct scale_factors *const ref_scale_factors =
- get_ref_scale_factors(cm, i);
- if (ref_buf != NULL) {
-#ifdef AML
- av1_setup_scale_factors_for_frame(
- ref_scale_factors, ref_buf->buf.y_crop_width,
- ref_buf->buf.y_crop_height, cm->dec_width, cm->height);
-#else
- av1_setup_scale_factors_for_frame(
- ref_scale_factors, ref_buf->buf.y_crop_width,
- ref_buf->buf.y_crop_height, cm->width, cm->height);
-#endif
- }
- if (ref_scale_factors) {
- if ((!av1_is_valid_scale(ref_scale_factors)))
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Reference frame has invalid dimensions");
- }
- }
-#endif
- }
- }
-
- av1_setup_frame_buf_refs(cm);
-
- av1_setup_frame_sign_bias(cm);
-
- cm->cur_frame->frame_type = current_frame->frame_type;
-
- if (seq_params->frame_id_numbers_present_flag) {
- update_ref_frame_id(cm, cm->current_frame_id);
- }
-#ifdef ORI_CODE
- const int might_bwd_adapt =
- !(seq_params->reduced_still_picture_hdr) && !(cm->disable_cdf_update);
- if (might_bwd_adapt) {
- cm->refresh_frame_context = aom_rb_read_bit(rb)
- ? REFRESH_FRAME_CONTEXT_DISABLED
- : REFRESH_FRAME_CONTEXT_BACKWARD;
- } else {
- cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
- }
-#endif
-
- cm->cur_frame->buf.bit_depth = seq_params->bit_depth;
- cm->cur_frame->buf.color_primaries = seq_params->color_primaries;
- cm->cur_frame->buf.transfer_characteristics =
- seq_params->transfer_characteristics;
- cm->cur_frame->buf.matrix_coefficients = seq_params->matrix_coefficients;
- cm->cur_frame->buf.monochrome = seq_params->monochrome;
- cm->cur_frame->buf.chroma_sample_position =
- seq_params->chroma_sample_position;
- cm->cur_frame->buf.color_range = seq_params->color_range;
- cm->cur_frame->buf.render_width = cm->render_width;
- cm->cur_frame->buf.render_height = cm->render_height;
-
- if (pbi->need_resync) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Keyframe / intra-only frame required to reset decoder"
- " state");
- }
-
- generate_next_ref_frame_map(pbi);
-
-#ifdef ORI_CODE
- if (cm->allow_intrabc) {
- // Set parameters corresponding to no filtering.
- struct loopfilter *lf = &cm->lf;
- lf->filter_level[0] = 0;
- lf->filter_level[1] = 0;
- cm->cdef_info.cdef_bits = 0;
- cm->cdef_info.cdef_strengths[0] = 0;
- cm->cdef_info.nb_cdef_strengths = 1;
- cm->cdef_info.cdef_uv_strengths[0] = 0;
- cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
- cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
- cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
- }
-
- read_tile_info(pbi, rb);
- if (!av1_is_min_tile_width_satisfied(cm)) {
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Minimum tile width requirement not satisfied");
- }
-
- setup_quantization(cm, rb);
- xd->bd = (int)seq_params->bit_depth;
-
- if (cm->num_allocated_above_context_planes < av1_num_planes(cm) ||
- cm->num_allocated_above_context_mi_col < cm->mi_cols ||
- cm->num_allocated_above_contexts < cm->tile_rows) {
- av1_free_above_context_buffers(cm, cm->num_allocated_above_contexts);
- if (av1_alloc_above_context_buffers(cm, cm->tile_rows))
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate context buffers");
- }
-
- if (cm->primary_ref_frame == PRIMARY_REF_NONE) {
- av1_setup_past_independence(cm);
- }
-
- setup_segmentation(cm, params);
-
- cm->delta_q_info.delta_q_res = 1;
- cm->delta_q_info.delta_lf_res = 1;
- cm->delta_q_info.delta_lf_present_flag = 0;
- cm->delta_q_info.delta_lf_multi = 0;
- cm->delta_q_info.delta_q_present_flag =
- cm->base_qindex > 0 ? aom_rb_read_bit(-1, defmark, rb) : 0;
- if (cm->delta_q_info.delta_q_present_flag) {
- xd->current_qindex = cm->base_qindex;
- cm->delta_q_info.delta_q_res = 1 << aom_rb_read_literal(-1, defmark, rb, 2);
- if (!cm->allow_intrabc)
- cm->delta_q_info.delta_lf_present_flag = aom_rb_read_bit(-1, defmark, rb);
- if (cm->delta_q_info.delta_lf_present_flag) {
- cm->delta_q_info.delta_lf_res = 1 << aom_rb_read_literal(-1, defmark, rb, 2);
- cm->delta_q_info.delta_lf_multi = aom_rb_read_bit(-1, defmark, rb);
- av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
- }
- }
-
- xd->cur_frame_force_integer_mv = cm->cur_frame_force_integer_mv;
-
- for (int i = 0; i < MAX_SEGMENTS; ++i) {
- const int qindex = av1_get_qindex(&cm->seg, i, cm->base_qindex);
- xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
- cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 &&
- cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0;
- xd->qindex[i] = qindex;
- }
- cm->coded_lossless = is_coded_lossless(cm, xd);
- cm->all_lossless = cm->coded_lossless && !av1_superres_scaled(cm);
- setup_segmentation_dequant(cm, xd);
- if (cm->coded_lossless) {
- cm->lf.filter_level[0] = 0;
- cm->lf.filter_level[1] = 0;
- }
- if (cm->coded_lossless || !seq_params->enable_cdef) {
- cm->cdef_info.cdef_bits = 0;
- cm->cdef_info.cdef_strengths[0] = 0;
- cm->cdef_info.cdef_uv_strengths[0] = 0;
- }
- if (cm->all_lossless || !seq_params->enable_restoration) {
- cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
- cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
- cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
- }
- setup_loopfilter(cm, rb);
-
- if (!cm->coded_lossless && seq_params->enable_cdef) {
- setup_cdef(cm, rb);
- }
- if (!cm->all_lossless && seq_params->enable_restoration) {
- decode_restoration_mode(cm, rb);
- }
-
- cm->tx_mode = read_tx_mode(cm, rb);
-#endif
-
- current_frame->reference_mode = read_frame_reference_mode(cm, params);
-
-#ifdef ORI_CODE
- if (current_frame->reference_mode != SINGLE_REFERENCE)
- setup_compound_reference_mode(cm);
-
-
-#endif
-
- av1_setup_skip_mode_allowed(cm);
-
- /*
- the point that ucode send send_bufmgr_info
- and wait bufmgr code to return is_skip_mode_allowed
- */
-
- /*
- read_uncompressed_header() end
- */
-
- av1_setup_motion_field(cm);
-#ifdef AML
- cm->cur_frame->mi_cols = cm->mi_cols;
- cm->cur_frame->mi_rows = cm->mi_rows;
- cm->cur_frame->dec_width = cm->dec_width;
-
- /*
- superres_post_decode(AV1Decoder *pbi) =>
- av1_superres_upscale(cm, pool); =>
- aom_realloc_frame_buffer(
- frame_to_show, cm->superres_upscaled_width,
- cm->superres_upscaled_height, seq_params->subsampling_x,
- seq_params->subsampling_y, seq_params->use_highbitdepth,
- AOM_BORDER_IN_PIXELS, cm->byte_alignment, fb, cb, cb_priv)
- */
- aom_realloc_frame_buffer(cm, &cm->cur_frame->buf,
- cm->superres_upscaled_width, cm->superres_upscaled_height,
- cm->cur_frame->order_hint);
-#endif
- return 0;
-}
-
-static int are_seq_headers_consistent(const SequenceHeader *seq_params_old,
- const SequenceHeader *seq_params_new) {
- return !memcmp(seq_params_old, seq_params_new, sizeof(SequenceHeader));
-}
-
-aom_codec_err_t aom_get_num_layers_from_operating_point_idc(
- int operating_point_idc, unsigned int *number_spatial_layers,
- unsigned int *number_temporal_layers) {
- // derive number of spatial/temporal layers from operating_point_idc
-
- if (!number_spatial_layers || !number_temporal_layers)
- return AOM_CODEC_INVALID_PARAM;
-
- if (operating_point_idc == 0) {
- *number_temporal_layers = 1;
- *number_spatial_layers = 1;
- } else {
- int j;
- *number_spatial_layers = 0;
- *number_temporal_layers = 0;
- for (j = 0; j < MAX_NUM_SPATIAL_LAYERS; j++) {
- *number_spatial_layers +=
- (operating_point_idc >> (j + MAX_NUM_TEMPORAL_LAYERS)) & 0x1;
- }
- for (j = 0; j < MAX_NUM_TEMPORAL_LAYERS; j++) {
- *number_temporal_layers += (operating_point_idc >> j) & 0x1;
- }
- }
-
- return AOM_CODEC_OK;
-}
-
-void av1_read_sequence_header(AV1_COMMON *cm, union param_u *params,
- SequenceHeader *seq_params) {
-#ifdef ORI_CODE
- const int num_bits_width = aom_rb_read_literal(-1, "<num_bits_width>", rb, 4) + 1;
- const int num_bits_height = aom_rb_read_literal(-1, "<num_bits_height>", rb, 4) + 1;
- const int max_frame_width = aom_rb_read_literal(-1, "<max_frame_width>", rb, num_bits_width) + 1;
- const int max_frame_height = aom_rb_read_literal(-1, "<max_frame_height>", rb, num_bits_height) + 1;
-
- seq_params->num_bits_width = num_bits_width;
- seq_params->num_bits_height = num_bits_height;
-#endif
- seq_params->max_frame_width = params->p.max_frame_width; //max_frame_width;
- seq_params->max_frame_height = params->p.max_frame_height; //max_frame_height;
-
- if (seq_params->reduced_still_picture_hdr) {
- seq_params->frame_id_numbers_present_flag = 0;
- } else {
- seq_params->frame_id_numbers_present_flag = params->p.frame_id_numbers_present_flag; //aom_rb_read_bit(-1, "<frame_id_numbers_present_flag>", rb);
- }
- if (seq_params->frame_id_numbers_present_flag) {
- // We must always have delta_frame_id_length < frame_id_length,
- // in order for a frame to be referenced with a unique delta.
- // Avoid wasting bits by using a coding that enforces this restriction.
-#ifdef ORI_CODE
- seq_params->delta_frame_id_length = aom_rb_read_literal(-1, "<delta_frame_id_length>", rb, 4) + 2;
- seq_params->frame_id_length = params->p.frame_id_length + aom_rb_read_literal(-1, "<frame_id_length>", rb, 3) + seq_params->delta_frame_id_length + 1;
-#else
- seq_params->delta_frame_id_length = params->p.delta_frame_id_length;
- seq_params->frame_id_length = params->p.frame_id_length + seq_params->delta_frame_id_length + 1;
-#endif
- if (seq_params->frame_id_length > 16)
- aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
- "Invalid frame_id_length");
- }
-#ifdef ORI_CODE
- setup_sb_size(seq_params, rb);
- seq_params->enable_filter_intra = aom_rb_read_bit(-1, "<enable_filter_intra>", rb);
- seq_params->enable_intra_edge_filter = aom_rb_read_bit(-1, "<enable_intra_edge_filter>", rb);
-#endif
-
- if (seq_params->reduced_still_picture_hdr) {
- seq_params->enable_interintra_compound = 0;
- seq_params->enable_masked_compound = 0;
- seq_params->enable_warped_motion = 0;
- seq_params->enable_dual_filter = 0;
- seq_params->order_hint_info.enable_order_hint = 0;
- seq_params->order_hint_info.enable_dist_wtd_comp = 0;
- seq_params->order_hint_info.enable_ref_frame_mvs = 0;
- seq_params->force_screen_content_tools = 2; // SELECT_SCREEN_CONTENT_TOOLS
- seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV
- seq_params->order_hint_info.order_hint_bits_minus_1 = -1;
- } else {
-#ifdef ORI_CODE
- seq_params->enable_interintra_compound = aom_rb_read_bit(-1, "<enable_interintra_compound>", rb);
- seq_params->enable_masked_compound = aom_rb_read_bit(-1, "<enable_masked_compound>", rb);
- seq_params->enable_warped_motion = aom_rb_read_bit(-1, "<enable_warped_motion>", rb);
- seq_params->enable_dual_filter = aom_rb_read_bit(-1, "<enable_dual_filter>", rb);
-#endif
- seq_params->order_hint_info.enable_order_hint = params->p.enable_order_hint; //aom_rb_read_bit(-1, "<order_hint_info.enable_order_hint>", rb);
- seq_params->order_hint_info.enable_dist_wtd_comp =
- seq_params->order_hint_info.enable_order_hint ? params->p.enable_dist_wtd_comp : 0; //aom_rb_read_bit(-1, "<order_hint_info.enable_dist_wtd_comp>", rb) : 0;
- seq_params->order_hint_info.enable_ref_frame_mvs =
- seq_params->order_hint_info.enable_order_hint ? params->p.enable_ref_frame_mvs : 0; //aom_rb_read_bit(-1, "<order_hint_info.enable_ref_frame_mvs>", rb) : 0;
-
-#ifdef ORI_CODE
- if (aom_rb_read_bit(-1, defmark, rb)) {
- seq_params->force_screen_content_tools =
- 2; // SELECT_SCREEN_CONTENT_TOOLS
- } else {
- seq_params->force_screen_content_tools = aom_rb_read_bit(-1, defmark, rb);
- }
-
- if (seq_params->force_screen_content_tools > 0) {
- if (aom_rb_read_bit(-1, defmark, rb)) {
- seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV
- } else {
- seq_params->force_integer_mv = aom_rb_read_bit(-1, defmark, rb);
- }
- } else {
- seq_params->force_integer_mv = 2; // SELECT_INTEGER_MV
- }
-#endif
- seq_params->order_hint_info.order_hint_bits_minus_1 =
- seq_params->order_hint_info.enable_order_hint
- ? params->p.order_hint_bits_minus_1 /*aom_rb_read_literal(-1, "<order_hint_info.order_hint_bits_minus_1>", rb, 3)*/
- : -1;
- }
- seq_params->enable_superres = params->p.enable_superres; //aom_rb_read_bit(-1, defmark, rb);
-
-#ifdef ORI_CODE
- seq_params->enable_cdef = aom_rb_read_bit(-1, defmark, rb);
- seq_params->enable_restoration = aom_rb_read_bit(-1, defmark, rb);
-#endif
-}
-
-#ifdef ORI_CODE
-void av1_read_op_parameters_info(AV1_COMMON *const cm,
- struct aom_read_bit_buffer *rb, int op_num) {
- // The cm->op_params array has MAX_NUM_OPERATING_POINTS + 1 elements.
- if (op_num > MAX_NUM_OPERATING_POINTS) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "AV1 does not support %d decoder model operating points",
- op_num + 1);
- }
-
- cm->op_params[op_num].decoder_buffer_delay = aom_rb_read_unsigned_literal(-1, defmark,
- rb, cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- cm->op_params[op_num].encoder_buffer_delay = aom_rb_read_unsigned_literal(-1, defmark,
- rb, cm->buffer_model.encoder_decoder_buffer_delay_length);
-
- cm->op_params[op_num].low_delay_mode_flag = aom_rb_read_bit(-1, defmark, rb);
-}
-#endif
-
-static int is_valid_seq_level_idx(AV1_LEVEL seq_level_idx) {
- return seq_level_idx < SEQ_LEVELS || seq_level_idx == SEQ_LEVEL_MAX;
-}
-
-static uint32_t read_sequence_header_obu(AV1Decoder *pbi,
- union param_u *params) {
- AV1_COMMON *const cm = pbi->common;
- int i;
- int operating_point;
- // Verify rb has been configured to report errors.
- //assert(rb->error_handler);
-
- // Use a local variable to store the information as we decode. At the end,
- // if no errors have occurred, cm->seq_params is updated.
- SequenceHeader sh = cm->seq_params;
- SequenceHeader *const seq_params = &sh;
-
- seq_params->profile = params->p.profile; //av1_read_profile(rb);
- if (seq_params->profile > CONFIG_MAX_DECODE_PROFILE) {
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- return 0;
- }
-
- // Still picture or not
- seq_params->still_picture = params->p.still_picture; //aom_rb_read_bit(-1, "<still_picture>", rb);
- seq_params->reduced_still_picture_hdr = params->p.reduced_still_picture_hdr; //aom_rb_read_bit(-1, "<reduced_still_picture_hdr>", rb);
- // Video must have reduced_still_picture_hdr = 0
- if (!seq_params->still_picture && seq_params->reduced_still_picture_hdr) {
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- return 0;
- }
-
- if (seq_params->reduced_still_picture_hdr) {
- cm->timing_info_present = 0;
- seq_params->decoder_model_info_present_flag = 0;
- seq_params->display_model_info_present_flag = 0;
- seq_params->operating_points_cnt_minus_1 = 0;
- seq_params->operating_point_idc[0] = 0;
- //if (!read_bitstream_level(0, "<seq_level_idx>", &seq_params->seq_level_idx[0], rb)) {
- if (!is_valid_seq_level_idx(params->p.seq_level_idx[0])) {
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- return 0;
- }
- seq_params->tier[0] = 0;
- cm->op_params[0].decoder_model_param_present_flag = 0;
- cm->op_params[0].display_model_param_present_flag = 0;
- } else {
- cm->timing_info_present = params->p.timing_info_present; //aom_rb_read_bit(-1, "<timing_info_present>", rb); // timing_info_present_flag
- if (cm->timing_info_present) {
-#ifdef ORI_CODE
- av1_read_timing_info_header(cm, rb);
-#endif
- seq_params->decoder_model_info_present_flag = params->p.decoder_model_info_present_flag; //aom_rb_read_bit(-1, "<decoder_model_info_present_flag>", rb);
-#ifdef ORI_CODE
- if (seq_params->decoder_model_info_present_flag)
- av1_read_decoder_model_info(cm, rb);
-#endif
- } else {
- seq_params->decoder_model_info_present_flag = 0;
- }
-#ifdef ORI_CODE
- seq_params->display_model_info_present_flag = aom_rb_read_bit(-1, "<display_model_info_present_flag>", rb);
-#endif
- seq_params->operating_points_cnt_minus_1 = params->p.operating_points_cnt_minus_1;
- //aom_rb_read_literal(-1, "<operating_points_cnt_minus_1>", rb, OP_POINTS_CNT_MINUS_1_BITS);
- for (i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) {
- seq_params->operating_point_idc[i] = params->p.operating_point_idc[i];
- //aom_rb_read_literal(i, "<operating_point_idc>", rb, OP_POINTS_IDC_BITS);
- //if (!read_bitstream_level(i, "<seq_level_idx>", &seq_params->seq_level_idx[i], rb)) {
- if (!is_valid_seq_level_idx(params->p.seq_level_idx[i])) {
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- return 0;
- }
- // This is the seq_level_idx[i] > 7 check in the spec. seq_level_idx 7
- // is equivalent to level 3.3.
-#ifdef ORI_CODE
- if (seq_params->seq_level_idx[i] >= SEQ_LEVEL_4_0)
- seq_params->tier[i] = aom_rb_read_bit(i, "<tier>", rb);
- else
- seq_params->tier[i] = 0;
-#endif
- if (seq_params->decoder_model_info_present_flag) {
- cm->op_params[i].decoder_model_param_present_flag = params->p.decoder_model_param_present_flag[i]; //aom_rb_read_bit(-1, defmark, rb);
-#ifdef ORI_CODE
- if (cm->op_params[i].decoder_model_param_present_flag)
- av1_read_op_parameters_info(cm, rb, i);
-#endif
- } else {
- cm->op_params[i].decoder_model_param_present_flag = 0;
- }
-#ifdef ORI_CODE
- if (cm->timing_info_present &&
- (cm->timing_info.equal_picture_interval ||
- cm->op_params[i].decoder_model_param_present_flag)) {
- cm->op_params[i].bitrate = av1_max_level_bitrate(
- seq_params->profile, seq_params->seq_level_idx[i],
- seq_params->tier[i]);
- // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass
- // the check
- if (cm->op_params[i].bitrate == 0)
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "AV1 does not support this combination of "
- "profile, level, and tier.");
- // Buffer size in bits/s is bitrate in bits/s * 1 s
- cm->op_params[i].buffer_size = cm->op_params[i].bitrate;
- }
-#endif
- if (cm->timing_info_present && cm->timing_info.equal_picture_interval &&
- !cm->op_params[i].decoder_model_param_present_flag) {
- // When the decoder_model_parameters are not sent for this op, set
- // the default ones that can be used with the resource availability mode
- cm->op_params[i].decoder_buffer_delay = 70000;
- cm->op_params[i].encoder_buffer_delay = 20000;
- cm->op_params[i].low_delay_mode_flag = 0;
- }
-
-#ifdef ORI_CODE
- if (seq_params->display_model_info_present_flag) {
- cm->op_params[i].display_model_param_present_flag = aom_rb_read_bit(-1, defmark, rb);
- if (cm->op_params[i].display_model_param_present_flag) {
- cm->op_params[i].initial_display_delay =
- aom_rb_read_literal(-1, defmark, rb, 4) + 1;
- if (cm->op_params[i].initial_display_delay > 10)
- aom_internal_error(
- &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "AV1 does not support more than 10 decoded frames delay");
- } else {
- cm->op_params[i].initial_display_delay = 10;
- }
- } else {
- cm->op_params[i].display_model_param_present_flag = 0;
- cm->op_params[i].initial_display_delay = 10;
- }
-#endif
- }
- }
- // This decoder supports all levels. Choose operating point provided by
- // external means
- operating_point = pbi->operating_point;
- if (operating_point < 0 ||
- operating_point > seq_params->operating_points_cnt_minus_1)
- operating_point = 0;
- pbi->current_operating_point =
- seq_params->operating_point_idc[operating_point];
- if (aom_get_num_layers_from_operating_point_idc(
- pbi->current_operating_point, &cm->number_spatial_layers,
- &cm->number_temporal_layers) != AOM_CODEC_OK) {
- cm->error.error_code = AOM_CODEC_ERROR;
- return 0;
- }
-
- av1_read_sequence_header(cm, params, seq_params);
-#ifdef ORI_CODE
- av1_read_color_config(rb, pbi->allow_lowbitdepth, seq_params, &cm->error);
- if (!(seq_params->subsampling_x == 0 && seq_params->subsampling_y == 0) &&
- !(seq_params->subsampling_x == 1 && seq_params->subsampling_y == 1) &&
- !(seq_params->subsampling_x == 1 && seq_params->subsampling_y == 0)) {
- aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
- "Only 4:4:4, 4:2:2 and 4:2:0 are currently supported, "
- "%d %d subsampling is not supported.\n",
- seq_params->subsampling_x, seq_params->subsampling_y);
- }
- seq_params->film_grain_params_present = aom_rb_read_bit(-1, "<film_grain_params_present>", rb);
-
- if (av1_check_trailing_bits(pbi, rb) != 0) {
- // cm->error.error_code is already set.
- return 0;
- }
-#endif
-
- // If a sequence header has been decoded before, we check if the new
- // one is consistent with the old one.
- if (pbi->sequence_header_ready) {
- if (!are_seq_headers_consistent(&cm->seq_params, seq_params))
- pbi->sequence_header_changed = 1;
- }
-
- cm->seq_params = *seq_params;
- pbi->sequence_header_ready = 1;
- return 0;
-
-}
-
-int aom_decode_frame_from_obus(AV1Decoder *pbi, union param_u *params, int obu_type)
-{
- AV1_COMMON *const cm = pbi->common;
- ObuHeader obu_header;
- int frame_decoding_finished = 0;
- uint32_t frame_header_size = 0;
-
- //struct aom_read_bit_buffer rb;
- size_t payload_size = 0;
- size_t decoded_payload_size = 0;
- size_t obu_payload_offset = 0;
- //size_t bytes_read = 0;
-
- memset(&obu_header, 0, sizeof(obu_header));
-#ifdef ORI_CODE
- pbi->seen_frame_header = 0;
-#else
- /* set in the test.c*/
-#endif
-
- obu_header.type = obu_type;
- pbi->cur_obu_type = obu_header.type;
- if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO))
- dump_params(pbi, params);
- switch (obu_header.type) {
- case OBU_SEQUENCE_HEADER:
- decoded_payload_size = read_sequence_header_obu(pbi, params);
- if (cm->error.error_code != AOM_CODEC_OK) return -1;
- break;
-
- case OBU_FRAME_HEADER:
- case OBU_REDUNDANT_FRAME_HEADER:
- case OBU_FRAME:
- if (obu_header.type == OBU_REDUNDANT_FRAME_HEADER) {
- if (!pbi->seen_frame_header) {
- cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
- return -1;
- }
- } else {
- // OBU_FRAME_HEADER or OBU_FRAME.
- if (pbi->seen_frame_header) {
- cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
- return -1;
- }
- }
- // Only decode first frame header received
- if (!pbi->seen_frame_header ||
- (cm->large_scale_tile && !pbi->camera_frame_header_ready)) {
- frame_header_size = av1_decode_frame_headers_and_setup(
- pbi, /*&rb, data, p_data_end,*/obu_header.type != OBU_FRAME, params);
- pbi->seen_frame_header = 1;
- if (!pbi->ext_tile_debug && cm->large_scale_tile)
- pbi->camera_frame_header_ready = 1;
- } else {
- // TODO(wtc): Verify that the frame_header_obu is identical to the
- // original frame_header_obu. For now just skip frame_header_size
- // bytes in the bit buffer.
- if (frame_header_size > payload_size) {
- cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
- return -1;
- }
- assert(rb.bit_offset == 0);
-#ifdef ORI_CODE
- rb.bit_offset = 8 * frame_header_size;
-#endif
- }
-
- decoded_payload_size = frame_header_size;
- pbi->frame_header_size = frame_header_size;
-
- if (cm->show_existing_frame) {
- if (obu_header.type == OBU_FRAME) {
- cm->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
- return -1;
- }
- frame_decoding_finished = 1;
- pbi->seen_frame_header = 0;
- break;
- }
-
- // In large scale tile coding, decode the common camera frame header
- // before any tile list OBU.
- if (!pbi->ext_tile_debug && pbi->camera_frame_header_ready) {
- frame_decoding_finished = 1;
- // Skip the rest of the frame data.
- decoded_payload_size = payload_size;
- // Update data_end.
-#ifdef ORI_CODE
- *p_data_end = data_end;
-#endif
- break;
- }
-#if 0 //def AML
- frame_decoding_finished = 1;
-#endif
- if (obu_header.type != OBU_FRAME) break;
- obu_payload_offset = frame_header_size;
- // Byte align the reader before reading the tile group.
- // byte_alignment() has set cm->error.error_code if it returns -1.
-#ifdef ORI_CODE
- if (byte_alignment(cm, &rb)) return -1;
- AOM_FALLTHROUGH_INTENDED; // fall through to read tile group.
-#endif
- default:
- break;
- }
- return frame_decoding_finished;
-}
-
-int get_buffer_index(AV1Decoder *pbi, RefCntBuffer *buffer)
-{
- AV1_COMMON *const cm = pbi->common;
- int i = -1;
-
- if (buffer) {
- for (i = 0; i < FRAME_BUFFERS; i++) {
- RefCntBuffer *buf =
- &cm->buffer_pool->frame_bufs[i];
- if (buf == buffer) {
- break;
- }
- }
- }
- return i;
-}
-
-void dump_buffer(RefCntBuffer *buf)
-{
- int i;
- pr_info("ref_count %d, vf_ref %d, order_hint %d, w/h(%d,%d) showable_frame %d frame_type %d canvas(%d,%d) w/h(%d,%d) mi_c/r(%d,%d) header 0x%x ref_deltas(",
- buf->ref_count, buf->buf.vf_ref, buf->order_hint, buf->width, buf->height, buf->showable_frame, buf->frame_type,
- buf->buf.mc_canvas_y, buf->buf.mc_canvas_u_v,
- buf->buf.y_crop_width, buf->buf.y_crop_height,
- buf->mi_cols, buf->mi_rows,
- buf->buf.header_adr);
- for (i = 0; i < REF_FRAMES; i++)
- pr_info("%d,", buf->ref_deltas[i]);
- pr_info("), ref_order_hints(");
-
- for (i = 0; i < INTER_REFS_PER_FRAME; i++)
- pr_info("%d ", buf->ref_order_hints[i]);
- pr_info(")");
-}
-
-void dump_ref_buffer_info(AV1Decoder *pbi, int i)
-{
- AV1_COMMON *const cm = pbi->common;
- pr_info("remapped_ref_idx %d, ref_frame_sign_bias %d, ref_frame_id %d, valid_for_referencing %d ref_frame_side %d ref_frame_map idx %d, next_ref_frame_map idx %d",
- cm->remapped_ref_idx[i],
- cm->ref_frame_sign_bias[i],
- cm->ref_frame_id[i],
- cm->valid_for_referencing[i],
- cm->ref_frame_side[i],
- get_buffer_index(pbi, cm->ref_frame_map[i]),
- get_buffer_index(pbi, cm->next_ref_frame_map[i]));
-}
-
-void dump_mv_refs(AV1Decoder *pbi)
-{
- int i, j;
- AV1_COMMON *const cm = pbi->common;
- for (i = 0; i < cm->mv_ref_id_index; i++) {
- pr_info("%d: ref_id %d cal_tpl_mvs %d mv_ref_offset: ",
- i, cm->mv_ref_id[i], cm->mv_cal_tpl_mvs[i]);
- for (j = 0; j < REF_FRAMES; j++)
- pr_info("%d ", cm->mv_ref_offset[i][j]);
- pr_info("\n");
- }
-}
-
-void dump_ref_spec_bufs(AV1Decoder *pbi)
-{
- int i;
- AV1_COMMON *const cm = pbi->common;
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- PIC_BUFFER_CONFIG *pic_config = av1_get_ref_frame_spec_buf(cm, LAST_FRAME + i);
- if (pic_config == NULL) continue;
- pr_info("%d: index %d order_hint %d header 0x%x dw_header 0x%x canvas(%d,%d) mv_wr_start 0x%x lcu_total %d\n",
- i, pic_config->index,
- pic_config->order_hint,
- pic_config->header_adr,
-#ifdef AOM_AV1_MMU_DW
- pic_config->header_dw_adr,
-#else
- 0,
-#endif
- pic_config->mc_canvas_y,
- pic_config->mc_canvas_u_v,
- pic_config->mpred_mv_wr_start_addr,
- pic_config->lcu_total
- );
- }
-}
-
-#ifdef SUPPORT_SCALE_FACTOR
-void dump_scale_factors(AV1Decoder *pbi)
-{
- int i;
- AV1_COMMON *const cm = pbi->common;
- for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
- struct scale_factors *const sf =
- get_ref_scale_factors(cm, i);
- if (sf)
- pr_info("%d: is_scaled %d x_scale_fp %d, y_scale_fp %d\n",
- i, av1_is_scaled(sf),
- sf->x_scale_fp, sf->y_scale_fp);
- else
- pr_info("%d: sf null\n", i);
- }
-}
-
-#endif
-
-void dump_buffer_status(AV1Decoder *pbi)
-{
- int i;
- AV1_COMMON *const cm = pbi->common;
- BufferPool *const pool = cm->buffer_pool;
- unsigned long flags;
-
- lock_buffer_pool(pool, flags);
-
- pr_info("%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame);
-
- pr_info("Buffer Pool:\n");
- for (i = 0; i < FRAME_BUFFERS; i++) {
- RefCntBuffer *buf =
- &cm->buffer_pool->frame_bufs[i];
- pr_info("%d: ", i);
- if (buf)
- dump_buffer(buf);
- pr_info("\n");
- }
-
- if (cm->prev_frame) {
- pr_info("prev_frame (%d): ",
- get_buffer_index(pbi, cm->prev_frame));
- dump_buffer(cm->prev_frame);
- pr_info("\n");
- }
- if (cm->cur_frame) {
- pr_info("cur_frame (%d): ",
- get_buffer_index(pbi, cm->cur_frame));
- dump_buffer(cm->cur_frame);
- pr_info("\n");
- }
- pr_info("REF_FRAMES Info(ref buf is ref_frame_map[remapped_ref_idx[i-1]], i=1~7):\n");
- for (i = 0; i < REF_FRAMES; i++) {
- pr_info("%d: ", i);
- dump_ref_buffer_info(pbi, i);
- pr_info("\n");
- }
- pr_info("Ref Spec Buffers:\n");
- dump_ref_spec_bufs(pbi);
-
- pr_info("MV refs:\n");
- dump_mv_refs(pbi);
-
-#ifdef SUPPORT_SCALE_FACTOR
- pr_info("Scale factors:\n");
- dump_scale_factors(pbi);
-#endif
- unlock_buffer_pool(pool, flags);
-}
-
-
-struct param_dump_item_s {
- unsigned int size;
- char* name;
- unsigned int adr_off;
-} param_dump_items[] = {
- {1, "profile", (unsigned long)&(((union param_u *)0)->p.profile )},
- {1, "still_picture", (unsigned long)&(((union param_u *)0)->p.still_picture )},
- {1, "reduced_still_picture_hdr", (unsigned long)&(((union param_u *)0)->p.reduced_still_picture_hdr )},
- {1, "decoder_model_info_present_flag", (unsigned long)&(((union param_u *)0)->p.decoder_model_info_present_flag)},
- {1, "max_frame_width", (unsigned long)&(((union param_u *)0)->p.max_frame_width )},
- {1, "max_frame_height", (unsigned long)&(((union param_u *)0)->p.max_frame_height )},
- {1, "frame_id_numbers_present_flag", (unsigned long)&(((union param_u *)0)->p.frame_id_numbers_present_flag )},
- {1, "delta_frame_id_length", (unsigned long)&(((union param_u *)0)->p.delta_frame_id_length )},
- {1, "frame_id_length", (unsigned long)&(((union param_u *)0)->p.frame_id_length )},
- {1, "order_hint_bits_minus_1", (unsigned long)&(((union param_u *)0)->p.order_hint_bits_minus_1 )},
- {1, "enable_order_hint", (unsigned long)&(((union param_u *)0)->p.enable_order_hint )},
- {1, "enable_dist_wtd_comp", (unsigned long)&(((union param_u *)0)->p.enable_dist_wtd_comp )},
- {1, "enable_ref_frame_mvs", (unsigned long)&(((union param_u *)0)->p.enable_ref_frame_mvs )},
- {1, "enable_superres", (unsigned long)&(((union param_u *)0)->p.enable_superres )},
- {1, "superres_scale_denominator", (unsigned long)&(((union param_u *)0)->p.superres_scale_denominator )},
- {1, "show_existing_frame", (unsigned long)&(((union param_u *)0)->p.show_existing_frame )},
- {1, "frame_type", (unsigned long)&(((union param_u *)0)->p.frame_type )},
- {1, "show_frame", (unsigned long)&(((union param_u *)0)->p.show_frame )},
- {1, "e.r.r.o.r_resilient_mode", (unsigned long)&(((union param_u *)0)->p.error_resilient_mode )},
- {1, "refresh_frame_flags", (unsigned long)&(((union param_u *)0)->p.refresh_frame_flags )},
- {1, "showable_frame", (unsigned long)&(((union param_u *)0)->p.showable_frame )},
- {1, "current_frame_id", (unsigned long)&(((union param_u *)0)->p.current_frame_id )},
- {1, "frame_size_override_flag", (unsigned long)&(((union param_u *)0)->p.frame_size_override_flag )},
- {1, "order_hint", (unsigned long)&(((union param_u *)0)->p.order_hint )},
- {1, "primary_ref_frame", (unsigned long)&(((union param_u *)0)->p.primary_ref_frame )},
- {1, "frame_refs_short_signaling", (unsigned long)&(((union param_u *)0)->p.frame_refs_short_signaling )},
- {1, "frame_width", (unsigned long)&(((union param_u *)0)->p.frame_width )},
- {1, "dec_frame_width", (unsigned long)&(((union param_u *)0)->p.dec_frame_width )},
- {1, "frame_width_scaled", (unsigned long)&(((union param_u *)0)->p.frame_width_scaled )},
- {1, "frame_height", (unsigned long)&(((union param_u *)0)->p.frame_height )},
- {1, "reference_mode", (unsigned long)&(((union param_u *)0)->p.reference_mode )},
- {1, "update_parameters", (unsigned long)&(((union param_u *)0)->p.update_parameters )},
- {1, "film_grain_params_ref_idx", (unsigned long)&(((union param_u *)0)->p.film_grain_params_ref_idx )},
- {1, "allow_ref_frame_mvs", (unsigned long)&(((union param_u *)0)->p.allow_ref_frame_mvs )},
- {1, "lst_ref", (unsigned long)&(((union param_u *)0)->p.lst_ref )},
- {1, "gld_ref", (unsigned long)&(((union param_u *)0)->p.gld_ref )},
- {INTER_REFS_PER_FRAME, "remapped_ref_idx", (unsigned long)&(((union param_u *)0)->p.remapped_ref_idx[0] )},
- {INTER_REFS_PER_FRAME, "delta_frame_id_minus_1", (unsigned long)&(((union param_u *)0)->p.delta_frame_id_minus_1[0] )},
- {REF_FRAMES, "ref_order_hint", (unsigned long)&(((union param_u *)0)->p.ref_order_hint[0] )},
-};
-
-void dump_params(AV1Decoder *pbi, union param_u *params)
-{
- int i, j;
- unsigned char *start_adr = (unsigned char*)params;
-
- pr_info("============ params:\n");
- for (i = 0; i < sizeof(param_dump_items) / sizeof(param_dump_items[0]); i++) {
- for (j = 0; j < param_dump_items[i].size; j++) {
- if (param_dump_items[i].size > 1)
- pr_info("%s(%d): 0x%x\n",
- param_dump_items[i].name, j,
- *((unsigned short*)(start_adr + param_dump_items[i].adr_off + j * 2)));
- else
- pr_info("%s: 0x%x\n", param_dump_items[i].name,
- *((unsigned short*)(start_adr + param_dump_items[i].adr_off + j * 2)));
- }
- }
-}
-
-/*static void raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd)
-{
- printf("$$$$$$$ output image\n");
-}*/
-
-/*
- return 0, need decoding data
- 1, decoding done
- -1, decoding error
-
-*/
-int av1_bufmgr_process(AV1Decoder *pbi, union param_u *params,
- unsigned char new_compressed_data, int obu_type)
-{
- AV1_COMMON *const cm = pbi->common;
- int j;
- // Release any pending output frames from the previous decoder_decode call.
- // We need to do this even if the decoder is being flushed or the input
- // arguments are invalid.
- BufferPool *const pool = cm->buffer_pool;
- int frame_decoded;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame);
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: new_compressed_data= %d\n", __func__, new_compressed_data);
- for (j = 0; j < pbi->num_output_frames; j++) {
- decrease_ref_count(pbi, pbi->output_frames[j], pool);
- }
- pbi->num_output_frames = 0;
- //
- if (new_compressed_data) {
- if (assign_cur_frame_new_fb(cm) == NULL) {
- cm->error.error_code = AOM_CODEC_MEM_ERROR;
- return -1;
- }
- pbi->seen_frame_header = 0;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "New_compressed_data (%d)\n", new_compressed_data_count++);
-
- }
-
- frame_decoded =
- aom_decode_frame_from_obus(pbi, params, obu_type);
-
- if (pbi->cur_obu_type == OBU_FRAME_HEADER ||
- pbi->cur_obu_type == OBU_REDUNDANT_FRAME_HEADER ||
- pbi->cur_obu_type == OBU_FRAME) {
- if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO)) {
- pr_info("after bufmgr (frame_decoded %d seen_frame_header %d): ",
- frame_decoded, pbi->seen_frame_header);
- dump_buffer_status(pbi);
- }
- }
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s: pbi %p cm %p cur_frame %p\n", __func__, pbi, cm, cm->cur_frame);
-
- return frame_decoded;
-
-}
-
-int av1_get_raw_frame(AV1Decoder *pbi, size_t index, PIC_BUFFER_CONFIG **sd) {
- if (index >= pbi->num_output_frames) return -1;
- *sd = &pbi->output_frames[index]->buf;
- //*grain_params = &pbi->output_frames[index]->film_grain_params;
- //aom_clear_system_state();
- return 0;
-}
-
-int av1_bufmgr_postproc(AV1Decoder *pbi, unsigned char frame_decoded)
-{
- PIC_BUFFER_CONFIG *sd = NULL;
- int index;
-#if 0
- if (frame_decoded) {
- printf("before swap_frame_buffers: ");
- dump_buffer_status(pbi);
- }
-#endif
- swap_frame_buffers(pbi, frame_decoded);
- if (frame_decoded) {
- if (av1_is_debug(AOM_DEBUG_PRINT_LIST_INFO)) {
- pr_info("after swap_frame_buffers: ");
- dump_buffer_status(pbi);
- }
- }
- if (frame_decoded) {
- pbi->decoding_first_frame = 0;
- }
-
-
- for (index = 0;;index++) {
- if (av1_get_raw_frame(pbi, index, &sd) < 0)
- break;
- if (sd)
- av1_raw_write_image(pbi, sd);
- }
- return 0;
-}
-
-int aom_realloc_frame_buffer(AV1_COMMON *cm, PIC_BUFFER_CONFIG *pic,
- int width, int height, unsigned int order_hint)
-{
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s, index 0x%x, width 0x%x, height 0x%x order_hint 0x%x\n",
- __func__, pic->index, width, height, order_hint);
- pic->y_crop_width = width;
- pic->y_crop_height = height;
- pic->order_hint = order_hint;
- return 0;
-}
-
-
-unsigned char av1_frame_is_inter(const AV1_COMMON *const cm) {
- unsigned char is_inter = cm->cur_frame && (cm->cur_frame->frame_type != KEY_FRAME)
- && (cm->current_frame.frame_type != INTRA_ONLY_FRAME);
- return is_inter;
-}
-
-PIC_BUFFER_CONFIG *av1_get_ref_frame_spec_buf(
- const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame) {
- RefCntBuffer *buf = get_ref_frame_buf(cm, ref_frame);
- if (buf) {
- buf->buf.order_hint = buf->order_hint;
- return &(buf->buf);
- }
- return NULL;
-}
-
-struct scale_factors *av1_get_ref_scale_factors(
- AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame)
-{
- return get_ref_scale_factors(cm, ref_frame);
-}
-
-void av1_set_next_ref_frame_map(AV1Decoder *pbi) {
- int ref_index = 0;
- int mask;
- AV1_COMMON *const cm = pbi->common;
- int check_on_show_existing_frame;
- av1_print2(AV1_DEBUG_BUFMGR_DETAIL, "%s, %d, mask 0x%x, show_existing_frame %d, reset_decoder_state %d\n",
- __func__, pbi->camera_frame_header_ready,
- cm->current_frame.refresh_frame_flags,
- cm->show_existing_frame,
- pbi->reset_decoder_state
- );
- if (!pbi->camera_frame_header_ready) {
- for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
- cm->next_used_ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- ++ref_index;
- }
-
- check_on_show_existing_frame =
- !cm->show_existing_frame || pbi->reset_decoder_state;
- for (; ref_index < REF_FRAMES && check_on_show_existing_frame;
- ++ref_index) {
- cm->next_used_ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
- }
- }
-}
-
-unsigned int av1_get_next_used_ref_info(
- const AV1_COMMON *const cm, int i) {
- /*
- i = 0~1 orde_hint map
- i = 2~10 size map[i-2]
- */
- unsigned int info = 0;
- int j;
- if (i < 2) {
- /*next_used_ref_frame_map has 8 items*/
- for (j = 0; j < 4; j++) {
- RefCntBuffer *buf =
- cm->next_used_ref_frame_map[(i * 4) + j];
- if (buf)
- info |= ((buf->buf.order_hint & 0xff)
- << (j * 8));
- }
- } else if (i < 10) {
- RefCntBuffer *buf =
- cm->next_used_ref_frame_map[i-2];
- if (buf)
- info = (buf->buf.y_crop_width << 16) | (buf->buf.y_crop_height & 0xffff);
- } else {
- for (j = 0; j < 4; j++) {
- RefCntBuffer *buf =
- cm->next_used_ref_frame_map[((i - 10) * 4) + j];
- if (buf)
- info |= ((buf->buf.index & 0xff)
- << (j * 8));
- }
- }
- return info;
-}
-
-RefCntBuffer *av1_get_primary_ref_frame_buf(
- const AV1_COMMON *const cm)
-{
- return get_primary_ref_frame_buf(cm);
-}
diff --git a/drivers/frame_provider/decoder_v4l/vav1/av1_film_grain.c b/drivers/frame_provider/decoder_v4l/vav1/av1_film_grain.c
deleted file mode 100644
index a19762c..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/av1_film_grain.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-/*
- * Copyright (c) 2016, Alliance for Open Media. All rights reserved
- *
- * This source code is subject to the terms of the BSD 2 Clause License and
- * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
- * was not distributed with this source code in the LICENSE file, you can
- * obtain it at www.aomedia.org/license/software. If the Alliance for Open
- * Media Patent License 1.0 was not distributed with this source code in the
- * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
- */
-
-/*!\file
- * \brief Describes film grain parameters and film grain synthesis
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/kthread.h>
-#include <linux/sched/clock.h>
-#include "vav1.h"
-
-#define FILM_GRAIN_REG_SIZE 39
-
-#define MID(a, min, max) ((a > max) ? max : ((a > min) ? a : min))
-
-#define gauss_bits 11
-
-#define luma_subblock_size_y 32
-#define luma_subblock_size_x 32
-
-#define left_pad 3
-#define right_pad 3 // padding to offset for AR coefficients
-#define top_pad 3
-#define bottom_pad 0
-#define ar_padding 3 // maximum lag used for stabilization of AR coefficients
-
-#define luma_grain_block_offt 0x120 //18 * 16
-#define cb_grain_block_offt 0x1520 //(18 + 320) * 16
-
-struct aom_film_grain_t {
- u8 apply_grain;
-
- u8 update_parameters;
-
- // 8 bit values
- s32 scaling_points_y[14][2];
- u8 num_y_points; // value: 0..14
-
- // 8 bit values
- s32 scaling_points_cb[10][2];
- u8 num_cb_points; // value: 0..10
-
- // 8 bit values
- s32 scaling_points_cr[10][2];
- u8 num_cr_points; // value: 0..10
-
- u8 scaling_shift; // values : 8..11
-
- s32 ar_coeff_lag; // values: 0..3
-
- // 8 bit values
- s32 ar_coeffs_y[24];
- s32 ar_coeffs_cb[25];
- s32 ar_coeffs_cr[25];
-
- // Shift value: AR coeffs range
- // 6: [-2, 2)
- // 7: [-1, 1)
- // 8: [-0.5, 0.5)
- // 9: [-0.25, 0.25)
- u8 ar_coeff_shift; // values : 6..9
-
- s8 cb_mult; // 8 bits
- s8 cb_luma_mult; // 8 bits
- s16 cb_offset; // 9 bits
-
- s8 cr_mult; // 8 bits
- s8 cr_luma_mult; // 8 bits
- s16 cr_offset; // 9 bits
-
- u8 overlap_flag;
-
- u8 clip_to_restricted_range;
-
- u8 bit_depth; // video bit depth
-
- u8 mc_identity;
-
- u8 chroma_scaling_from_luma;
-
- u8 grain_scale_shift;
-
- u16 random_seed;
-
- u16 random_register_y;
- u16 random_register_cb;
- u16 random_register_cr;
-
- s32 scaling_delta_y[14];
- s32 scaling_delta_cb[10];
- s32 scaling_delta_cr[10];
-};
-
-
-static u32 debug_fgs;
-module_param(debug_fgs, uint, 0664);
-
-// Samples with Gaussian distribution in the range of [-2048, 2047] (12 bits)
-// with zero mean and standard deviation of about 512.
-// should be divided by 4 for 10-bit range and 16 for 8-bit range.
-static const s32 gaussian_seq[2048] = {
- 56, 568, -180, 172, 124, -84, 172, -64, -900, 24, 820,
- 224, 1248, 996, 272, -8, -916, -388, -732, -104, -188, 800,
- 112, -652, -320, -376, 140, -252, 492, -168, 44, -788, 588,
- -584, 500, -228, 12, 680, 272, -476, 972, -100, 652, 368,
- 432, -196, -720, -192, 1000, -332, 652, -136, -552, -604, -4,
- 192, -220, -136, 1000, -52, 372, -96, -624, 124, -24, 396,
- 540, -12, -104, 640, 464, 244, -208, -84, 368, -528, -740,
- 248, -968, -848, 608, 376, -60, -292, -40, -156, 252, -292,
- 248, 224, -280, 400, -244, 244, -60, 76, -80, 212, 532,
- 340, 128, -36, 824, -352, -60, -264, -96, -612, 416, -704,
- 220, -204, 640, -160, 1220, -408, 900, 336, 20, -336, -96,
- -792, 304, 48, -28, -1232, -1172, -448, 104, -292, -520, 244,
- 60, -948, 0, -708, 268, 108, 356, -548, 488, -344, -136,
- 488, -196, -224, 656, -236, -1128, 60, 4, 140, 276, -676,
- -376, 168, -108, 464, 8, 564, 64, 240, 308, -300, -400,
- -456, -136, 56, 120, -408, -116, 436, 504, -232, 328, 844,
- -164, -84, 784, -168, 232, -224, 348, -376, 128, 568, 96,
- -1244, -288, 276, 848, 832, -360, 656, 464, -384, -332, -356,
- 728, -388, 160, -192, 468, 296, 224, 140, -776, -100, 280,
- 4, 196, 44, -36, -648, 932, 16, 1428, 28, 528, 808,
- 772, 20, 268, 88, -332, -284, 124, -384, -448, 208, -228,
- -1044, -328, 660, 380, -148, -300, 588, 240, 540, 28, 136,
- -88, -436, 256, 296, -1000, 1400, 0, -48, 1056, -136, 264,
- -528, -1108, 632, -484, -592, -344, 796, 124, -668, -768, 388,
- 1296, -232, -188, -200, -288, -4, 308, 100, -168, 256, -500,
- 204, -508, 648, -136, 372, -272, -120, -1004, -552, -548, -384,
- 548, -296, 428, -108, -8, -912, -324, -224, -88, -112, -220,
- -100, 996, -796, 548, 360, -216, 180, 428, -200, -212, 148,
- 96, 148, 284, 216, -412, -320, 120, -300, -384, -604, -572,
- -332, -8, -180, -176, 696, 116, -88, 628, 76, 44, -516,
- 240, -208, -40, 100, -592, 344, -308, -452, -228, 20, 916,
- -1752, -136, -340, -804, 140, 40, 512, 340, 248, 184, -492,
- 896, -156, 932, -628, 328, -688, -448, -616, -752, -100, 560,
- -1020, 180, -800, -64, 76, 576, 1068, 396, 660, 552, -108,
- -28, 320, -628, 312, -92, -92, -472, 268, 16, 560, 516,
- -672, -52, 492, -100, 260, 384, 284, 292, 304, -148, 88,
- -152, 1012, 1064, -228, 164, -376, -684, 592, -392, 156, 196,
- -524, -64, -884, 160, -176, 636, 648, 404, -396, -436, 864,
- 424, -728, 988, -604, 904, -592, 296, -224, 536, -176, -920,
- 436, -48, 1176, -884, 416, -776, -824, -884, 524, -548, -564,
- -68, -164, -96, 692, 364, -692, -1012, -68, 260, -480, 876,
- -1116, 452, -332, -352, 892, -1088, 1220, -676, 12, -292, 244,
- 496, 372, -32, 280, 200, 112, -440, -96, 24, -644, -184,
- 56, -432, 224, -980, 272, -260, 144, -436, 420, 356, 364,
- -528, 76, 172, -744, -368, 404, -752, -416, 684, -688, 72,
- 540, 416, 92, 444, 480, -72, -1416, 164, -1172, -68, 24,
- 424, 264, 1040, 128, -912, -524, -356, 64, 876, -12, 4,
- -88, 532, 272, -524, 320, 276, -508, 940, 24, -400, -120,
- 756, 60, 236, -412, 100, 376, -484, 400, -100, -740, -108,
- -260, 328, -268, 224, -200, -416, 184, -604, -564, -20, 296,
- 60, 892, -888, 60, 164, 68, -760, 216, -296, 904, -336,
- -28, 404, -356, -568, -208, -1480, -512, 296, 328, -360, -164,
- -1560, -776, 1156, -428, 164, -504, -112, 120, -216, -148, -264,
- 308, 32, 64, -72, 72, 116, 176, -64, -272, 460, -536,
- -784, -280, 348, 108, -752, -132, 524, -540, -776, 116, -296,
- -1196, -288, -560, 1040, -472, 116, -848, -1116, 116, 636, 696,
- 284, -176, 1016, 204, -864, -648, -248, 356, 972, -584, -204,
- 264, 880, 528, -24, -184, 116, 448, -144, 828, 524, 212,
- -212, 52, 12, 200, 268, -488, -404, -880, 824, -672, -40,
- 908, -248, 500, 716, -576, 492, -576, 16, 720, -108, 384,
- 124, 344, 280, 576, -500, 252, 104, -308, 196, -188, -8,
- 1268, 296, 1032, -1196, 436, 316, 372, -432, -200, -660, 704,
- -224, 596, -132, 268, 32, -452, 884, 104, -1008, 424, -1348,
- -280, 4, -1168, 368, 476, 696, 300, -8, 24, 180, -592,
- -196, 388, 304, 500, 724, -160, 244, -84, 272, -256, -420,
- 320, 208, -144, -156, 156, 364, 452, 28, 540, 316, 220,
- -644, -248, 464, 72, 360, 32, -388, 496, -680, -48, 208,
- -116, -408, 60, -604, -392, 548, -840, 784, -460, 656, -544,
- -388, -264, 908, -800, -628, -612, -568, 572, -220, 164, 288,
- -16, -308, 308, -112, -636, -760, 280, -668, 432, 364, 240,
- -196, 604, 340, 384, 196, 592, -44, -500, 432, -580, -132,
- 636, -76, 392, 4, -412, 540, 508, 328, -356, -36, 16,
- -220, -64, -248, -60, 24, -192, 368, 1040, 92, -24, -1044,
- -32, 40, 104, 148, 192, -136, -520, 56, -816, -224, 732,
- 392, 356, 212, -80, -424, -1008, -324, 588, -1496, 576, 460,
- -816, -848, 56, -580, -92, -1372, -112, -496, 200, 364, 52,
- -140, 48, -48, -60, 84, 72, 40, 132, -356, -268, -104,
- -284, -404, 732, -520, 164, -304, -540, 120, 328, -76, -460,
- 756, 388, 588, 236, -436, -72, -176, -404, -316, -148, 716,
- -604, 404, -72, -88, -888, -68, 944, 88, -220, -344, 960,
- 472, 460, -232, 704, 120, 832, -228, 692, -508, 132, -476,
- 844, -748, -364, -44, 1116, -1104, -1056, 76, 428, 552, -692,
- 60, 356, 96, -384, -188, -612, -576, 736, 508, 892, 352,
- -1132, 504, -24, -352, 324, 332, -600, -312, 292, 508, -144,
- -8, 484, 48, 284, -260, -240, 256, -100, -292, -204, -44,
- 472, -204, 908, -188, -1000, -256, 92, 1164, -392, 564, 356,
- 652, -28, -884, 256, 484, -192, 760, -176, 376, -524, -452,
- -436, 860, -736, 212, 124, 504, -476, 468, 76, -472, 552,
- -692, -944, -620, 740, -240, 400, 132, 20, 192, -196, 264,
- -668, -1012, -60, 296, -316, -828, 76, -156, 284, -768, -448,
- -832, 148, 248, 652, 616, 1236, 288, -328, -400, -124, 588,
- 220, 520, -696, 1032, 768, -740, -92, -272, 296, 448, -464,
- 412, -200, 392, 440, -200, 264, -152, -260, 320, 1032, 216,
- 320, -8, -64, 156, -1016, 1084, 1172, 536, 484, -432, 132,
- 372, -52, -256, 84, 116, -352, 48, 116, 304, -384, 412,
- 924, -300, 528, 628, 180, 648, 44, -980, -220, 1320, 48,
- 332, 748, 524, -268, -720, 540, -276, 564, -344, -208, -196,
- 436, 896, 88, -392, 132, 80, -964, -288, 568, 56, -48,
- -456, 888, 8, 552, -156, -292, 948, 288, 128, -716, -292,
- 1192, -152, 876, 352, -600, -260, -812, -468, -28, -120, -32,
- -44, 1284, 496, 192, 464, 312, -76, -516, -380, -456, -1012,
- -48, 308, -156, 36, 492, -156, -808, 188, 1652, 68, -120,
- -116, 316, 160, -140, 352, 808, -416, 592, 316, -480, 56,
- 528, -204, -568, 372, -232, 752, -344, 744, -4, 324, -416,
- -600, 768, 268, -248, -88, -132, -420, -432, 80, -288, 404,
- -316, -1216, -588, 520, -108, 92, -320, 368, -480, -216, -92,
- 1688, -300, 180, 1020, -176, 820, -68, -228, -260, 436, -904,
- 20, 40, -508, 440, -736, 312, 332, 204, 760, -372, 728,
- 96, -20, -632, -520, -560, 336, 1076, -64, -532, 776, 584,
- 192, 396, -728, -520, 276, -188, 80, -52, -612, -252, -48,
- 648, 212, -688, 228, -52, -260, 428, -412, -272, -404, 180,
- 816, -796, 48, 152, 484, -88, -216, 988, 696, 188, -528,
- 648, -116, -180, 316, 476, 12, -564, 96, 476, -252, -364,
- -376, -392, 556, -256, -576, 260, -352, 120, -16, -136, -260,
- -492, 72, 556, 660, 580, 616, 772, 436, 424, -32, -324,
- -1268, 416, -324, -80, 920, 160, 228, 724, 32, -516, 64,
- 384, 68, -128, 136, 240, 248, -204, -68, 252, -932, -120,
- -480, -628, -84, 192, 852, -404, -288, -132, 204, 100, 168,
- -68, -196, -868, 460, 1080, 380, -80, 244, 0, 484, -888,
- 64, 184, 352, 600, 460, 164, 604, -196, 320, -64, 588,
- -184, 228, 12, 372, 48, -848, -344, 224, 208, -200, 484,
- 128, -20, 272, -468, -840, 384, 256, -720, -520, -464, -580,
- 112, -120, 644, -356, -208, -608, -528, 704, 560, -424, 392,
- 828, 40, 84, 200, -152, 0, -144, 584, 280, -120, 80,
- -556, -972, -196, -472, 724, 80, 168, -32, 88, 160, -688,
- 0, 160, 356, 372, -776, 740, -128, 676, -248, -480, 4,
- -364, 96, 544, 232, -1032, 956, 236, 356, 20, -40, 300,
- 24, -676, -596, 132, 1120, -104, 532, -1096, 568, 648, 444,
- 508, 380, 188, -376, -604, 1488, 424, 24, 756, -220, -192,
- 716, 120, 920, 688, 168, 44, -460, 568, 284, 1144, 1160,
- 600, 424, 888, 656, -356, -320, 220, 316, -176, -724, -188,
- -816, -628, -348, -228, -380, 1012, -452, -660, 736, 928, 404,
- -696, -72, -268, -892, 128, 184, -344, -780, 360, 336, 400,
- 344, 428, 548, -112, 136, -228, -216, -820, -516, 340, 92,
- -136, 116, -300, 376, -244, 100, -316, -520, -284, -12, 824,
- 164, -548, -180, -128, 116, -924, -828, 268, -368, -580, 620,
- 192, 160, 0, -1676, 1068, 424, -56, -360, 468, -156, 720,
- 288, -528, 556, -364, 548, -148, 504, 316, 152, -648, -620,
- -684, -24, -376, -384, -108, -920, -1032, 768, 180, -264, -508,
- -1268, -260, -60, 300, -240, 988, 724, -376, -576, -212, -736,
- 556, 192, 1092, -620, -880, 376, -56, -4, -216, -32, 836,
- 268, 396, 1332, 864, -600, 100, 56, -412, -92, 356, 180,
- 884, -468, -436, 292, -388, -804, -704, -840, 368, -348, 140,
- -724, 1536, 940, 372, 112, -372, 436, -480, 1136, 296, -32,
- -228, 132, -48, -220, 868, -1016, -60, -1044, -464, 328, 916,
- 244, 12, -736, -296, 360, 468, -376, -108, -92, 788, 368,
- -56, 544, 400, -672, -420, 728, 16, 320, 44, -284, -380,
- -796, 488, 132, 204, -596, -372, 88, -152, -908, -636, -572,
- -624, -116, -692, -200, -56, 276, -88, 484, -324, 948, 864,
- 1000, -456, -184, -276, 292, -296, 156, 676, 320, 160, 908,
- -84, -1236, -288, -116, 260, -372, -644, 732, -756, -96, 84,
- 344, -520, 348, -688, 240, -84, 216, -1044, -136, -676, -396,
- -1500, 960, -40, 176, 168, 1516, 420, -504, -344, -364, -360,
- 1216, -940, -380, -212, 252, -660, -708, 484, -444, -152, 928,
- -120, 1112, 476, -260, 560, -148, -344, 108, -196, 228, -288,
- 504, 560, -328, -88, 288, -1008, 460, -228, 468, -836, -196,
- 76, 388, 232, 412, -1168, -716, -644, 756, -172, -356, -504,
- 116, 432, 528, 48, 476, -168, -608, 448, 160, -532, -272,
- 28, -676, -12, 828, 980, 456, 520, 104, -104, 256, -344,
- -4, -28, -368, -52, -524, -572, -556, -200, 768, 1124, -208,
- -512, 176, 232, 248, -148, -888, 604, -600, -304, 804, -156,
- -212, 488, -192, -804, -256, 368, -360, -916, -328, 228, -240,
- -448, -472, 856, -556, -364, 572, -12, -156, -368, -340, 432,
- 252, -752, -152, 288, 268, -580, -848, -592, 108, -76, 244,
- 312, -716, 592, -80, 436, 360, 4, -248, 160, 516, 584,
- 732, 44, -468, -280, -292, -156, -588, 28, 308, 912, 24,
- 124, 156, 180, -252, 944, -924, -772, -520, -428, -624, 300,
- -212, -1144, 32, -724, 800, -1128, -212, -1288, -848, 180, -416,
- 440, 192, -576, -792, -76, -1080, 80, -532, -352, -132, 380,
- -820, 148, 1112, 128, 164, 456, 700, -924, 144, -668, -384,
- 648, -832, 508, 552, -52, -100, -656, 208, -568, 748, -88,
- 680, 232, 300, 192, -408, -1012, -152, -252, -268, 272, -876,
- -664, -648, -332, -136, 16, 12, 1152, -28, 332, -536, 320,
- -672, -460, -316, 532, -260, 228, -40, 1052, -816, 180, 88,
- -496, -556, -672, -368, 428, 92, 356, 404, -408, 252, 196,
- -176, -556, 792, 268, 32, 372, 40, 96, -332, 328, 120,
- 372, -900, -40, 472, -264, -592, 952, 128, 656, 112, 664,
- -232, 420, 4, -344, -464, 556, 244, -416, -32, 252, 0,
- -412, 188, -696, 508, -476, 324, -1096, 656, -312, 560, 264,
- -136, 304, 160, -64, -580, 248, 336, -720, 560, -348, -288,
- -276, -196, -500, 852, -544, -236, -1128, -992, -776, 116, 56,
- 52, 860, 884, 212, -12, 168, 1020, 512, -552, 924, -148,
- 716, 188, 164, -340, -520, -184, 880, -152, -680, -208, -1156,
- -300, -528, -472, 364, 100, -744, -1056, -32, 540, 280, 144,
- -676, -32, -232, -280, -224, 96, 568, -76, 172, 148, 148,
- 104, 32, -296, -32, 788, -80, 32, -16, 280, 288, 944,
- 428, -484
-};
-
-static inline void fg_data_copy_unsigned(
- s32 *to, u8 *from, s32 size, u8 endian_swap, s32 offt)
-{
- s32 i;
-
- if (endian_swap) {
- for (i = 0; i < size; i += 4) {
- to[i] = from[i + 3] - offt;
- to[i + 1] = from[i + 2] - offt;
- to[i + 2] = from[i + 1] - offt;
- to[i + 3] = from[i] - offt;
- }
- } else {
- for (i = 0; i < size; i++) {
- to[i] = from[i];
- }
- }
-}
-
-static inline void fg_data_copy_signed(
- s32 *to, s8 *from, s32 size, u8 endian_swap, s32 offt)
-{
- s32 i;
-
- if (endian_swap) {
- for (i = 0; i < size; i += 4) {
- to[i] = (s32)(from[i + 3] - offt);
- to[i + 1] = (s32)(from[i + 2] - offt);
- to[i + 2] = (s32)(from[i + 1] - offt);
- to[i + 3] = (s32)(from[i] - offt);
- }
- } else {
- for (i = 0; i < size; i++) {
- to[i] = from[i];
- }
- }
-}
-
-
-static void fg_info_print(struct aom_film_grain_t *p)
-{
- s32 i;
-
- pr_info("apply_grain: %d\n", p->apply_grain);
- pr_info("update_parameters: %d\n", p->update_parameters);
-
- if (p->num_y_points > 0) {
- for (i = 0; i < 14; i++) {
- pr_info("scaling_points_y[%d][0]: %x, [1]: %x\n", i, p->scaling_points_y[i][0], p->scaling_points_y[i][1]);
- }
- }
- pr_info("num_y_points: %d\n", p->num_y_points);
-
- if (p->num_cb_points > 0) {
- for (i = 0; i < 10; i++) {
- pr_info("scaling_points_cb[%d][0]: %x, [1]: %x\n", i, p->scaling_points_cb[i][0], p->scaling_points_cb[i][1]);
- }
- }
- pr_info("num_cb_points: %d\n", p->num_cb_points);
-
- if (p->num_cb_points > 0) {
- for (i = 0; i < 10; i++) {
- pr_info("scaling_points_cr[%d][0]: %x, [1]: %x\n", i, p->scaling_points_cr[i][0], p->scaling_points_cr[i][1]);
- }
- }
- pr_info("num_cr_points: %d\n", p->num_cr_points);
- pr_info("scaling_shift: %d\n", p->scaling_shift);
- pr_info("ar_coeff_lag: 0x%x\n", p->ar_coeff_lag);
-
- for (i = 0; i < 24; i++) {
- pr_info("ar_coeffs_y[%d]: %x\n", i, p->ar_coeffs_y[i]);
- }
- for (i = 0; i < 25; i++) {
- pr_info("ar_coeffs_cb[%d]: %x\n", i, p->ar_coeffs_cb[i]);
- }
- for (i = 0; i < 25; i++) {
- pr_info("ar_coeffs_cr[%d]: %x\n", i, p->ar_coeffs_cr[i]);
- }
- pr_info("ar_coeff_shift: %d\n", p->ar_coeff_shift);
- pr_info("cb_mult: 0x%x\n", p->cb_mult);
- pr_info("cb_luma_mult: 0x%x\n", p->cb_luma_mult);
- pr_info("cb_offset: 0x%x\n", p->cb_offset);
-
- pr_info("cr_mult: 0x%x\n", p->cr_mult);
- pr_info("cr_luma_mult: 0x%x\n", p->cr_luma_mult);
- pr_info("cr_offset: 0x%x\n", p->cr_offset);
-
- pr_info("overlap_flag: %d\n", p->overlap_flag);
- pr_info("clip_to_restricted_range: %d\n", p->clip_to_restricted_range);
- pr_info("bit_depth: %d\n", p->bit_depth);
- pr_info("mc_identity: %d\n", p->mc_identity);
- pr_info("chroma_scaling_from_luma: %d\n", p->chroma_scaling_from_luma);
- pr_info("grain_scale_shift: %d\n", p->grain_scale_shift);
- pr_info("random_seed: 0x%x\n", p->random_seed);
-}
-
-static void film_grain_data_parse(struct aom_film_grain_t *para, u32 fgs_ctrl, u32 *fgs_data)
-{
- /* index 0
- bit[30] - bit_depth_10
- bit[29] - mc_identity
- bit[28] - num_pos_chroma_one_more
- bit[27:24] - ar_coeff_shift
- bit[23:20] - scaling_shift
- bit[19] - overlap_flag
- bit[18] - clip_to_restricted_range
- bit[17] - chroma_scaling_from_luma
- */
- para->bit_depth = (fgs_data[0] & (1 << 30)) ? 10 : 8; // video bit depth
- para->mc_identity = (fgs_data[0] & (1 << 29)) ? 1 : 0;
- para->ar_coeff_shift = (fgs_data[0] >> 24) & 0xf;; // values : 6..9
- para->scaling_shift = (fgs_data[0] >> 20) & 0xf; // values : 8..11
- para->overlap_flag = (fgs_data[0] >> 19) & 0x1;
- para->clip_to_restricted_range = (fgs_data[0] >> 18) & 0x1;
- para->chroma_scaling_from_luma = (fgs_data[0] >> 17) & 0x1;
-
- /* index 1
- bit[31:30] - grain_scale_shift
- bit[29:28] - ar_coeff_lag
- bit[27:20] - ar_coeffs_cr[24]
- bit[19:12] - ar_coeffs_cb[24]
- bit[11:8] - num_cr_points
- bit[7:4] - num_cb_points
- bit[3:0] - num_y_points
- */
- para->grain_scale_shift = (fgs_data[1] >> 30) & 0x3;
- para->ar_coeff_lag = (fgs_data[1] >> 28) & 0x3; // values: 0..3
- para->ar_coeffs_cr[24] = (fgs_data[1] >> 20) & 0xff;
- para->ar_coeffs_cr[24] -= 128;
- para->ar_coeffs_cb[24] = (fgs_data[1] >> 12) & 0xff;
- para->ar_coeffs_cb[24] -= 128;
- para->num_cr_points = (fgs_data[1] >> 8) & 0xf; // value: 0..10
- para->num_cb_points = (fgs_data[1] >> 4) & 0xf; // value: 0..10
- para->num_y_points = (fgs_data[1] >> 0) & 0xf; // value: 0..14
-
- /* index 2~8 scaling_points_y[14][2] */
- fg_data_copy_unsigned(¶->scaling_points_y[0][0], (u8 *)&fgs_data[2], para->num_y_points * 2, 1, 0); // 8 bit values // brian swap ?
-
- /* index 9-13 scaling_points_cb[10][2] */
- fg_data_copy_unsigned(¶->scaling_points_cb[0][0], (u8 *)&fgs_data[9], para->num_cb_points * 2, 1, 0); // 8 bit values // brian chroma_scaling_from_luma and swap ?
-
- // 14-18 -- scaling_points_cr[10][2]
- fg_data_copy_unsigned(¶->scaling_points_cr[0][0], (u8 *)&fgs_data[14], para->num_cr_points * 2, 1, 0); // 8 bit values // brian chroma_scaling_from_luma and swap ?
-
- // 19-24 -- ar_coeffs_y[0-23]
- fg_data_copy_unsigned(para->ar_coeffs_y, (u8 *)&fgs_data[19], 24, 1, 128); // brian chroma_scaling_from_luma and swap ?
-
- // 25-30 -- ar_coeffs_cb[0-23]
- fg_data_copy_unsigned(para->ar_coeffs_cb, (u8 *)&fgs_data[25], 24, 1, 128); // brian chroma_scaling_from_luma ?
-
- // 31-36 -- ar_coeffs_cr[0-23]
- fg_data_copy_unsigned(para->ar_coeffs_cr, (u8 *)&fgs_data[31], 24, 1, 128); // brian chroma_scaling_from_luma ?
-
- /* index 37
- bit[31:24] - cb_mult
- bit[23:16] - cb_luma_mult
- bit[15:7] - cb_offset
- */
- if (para->num_cb_points > 0) { // brian chroma_scaling_from_luma ?
- para->cb_mult = (fgs_data[37] >> 24) & 0xff; // 8 bits
- para->cb_luma_mult = (fgs_data[37] >> 16) & 0xff; // 8 bits
- para->cb_offset = (fgs_data[37] >> 7) & 0x1ff; // 9 bits
- } else {
- para->cb_mult = 0; // 8 bits
- para->cb_luma_mult = 0; // 8 bits
- para->cb_offset = 0; // 9 bits
- }
-
- /* index 38
- bit[31:24] - cr_mult
- bit[23:16] - cr_luma_mult
- bit[15:7] - cr_offset
- */
- if (para->num_cr_points > 0) { // brian chroma_scaling_from_luma ?
- para->cr_mult = (fgs_data[38] >> 24) & 0xff; // 8 bits
- para->cr_luma_mult = (fgs_data[38] >> 16) & 0xff; // 8 bits
- para->cr_offset = (fgs_data[38] >> 7) & 0x1ff; // 9 bits
- } else {
- para->cr_mult = 0; // 8 bits
- para->cr_luma_mult = 0; // 8 bits
- para->cr_offset = 0; // 9 bits
- }
- /*
- bit[31:16] - random_seed
- bit[06] - apply_cr (RO) //assign apply_cr = num_cr_points>0 | chroma_scaling_from_luma;
- bit[05] - apply_cb (RO) //assign apply_cb = num_cb_points>0 | chroma_scaling_from_luma;
- bit[04] - apply_lu (RO) //assign apply_lu = num_y_points>0;
- bit[03] - fgs_not_bypass : 0=fgs bypass 1:=fgs not bypass (default=0)
- bit[02] - update_parameters
- bit[01] - apply_grain
- bit[00] - film gran start
- */
- para->apply_grain = (fgs_ctrl >> 1) & 0x1;
- para->update_parameters = (fgs_ctrl >> 2) & 0x1;
- para->random_seed = (fgs_ctrl >> 16) & 0xffff;
-}
-
-#define DEFAULT_ALIGNMENT (2 * sizeof(void *))
-
-static inline void *fgs_alloc(u32 size)
-{
- void *addr;
- size = size + DEFAULT_ALIGNMENT - 1 + sizeof(size_t);
- addr = vzalloc(size);
- if (addr == NULL)
- addr = vzalloc(size);
-
- return addr;
-}
-
-static void init_arrays(struct aom_film_grain_t *params,
- s32 ***pred_pos_luma_p, s32 ***pred_pos_chroma_p,
- s32 **luma_grain_block, s32 **cb_grain_block, s32 **cr_grain_block,
- s32 luma_grain_samples, s32 luma_grain_stride,
- s32 chroma_grain_samples, s32 chroma_grain_stride)
-{
- s32 num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
- s32 num_pos_chroma = num_pos_luma;
- s32 row, col;
- s32 pos_ar_index = 0;
- s32 **pred_pos_luma;
- s32 **pred_pos_chroma;
-
- if (params->num_y_points > 0)
- ++num_pos_chroma;
-
- if (debug_fgs & DEBUG_FGS_DETAIL) {
- pr_info("num_pos_luma %d, sizeof(*pred_pos_luma):%ld\n", num_pos_luma, sizeof(*pred_pos_luma));
- pr_info("num_pos_chroma %d, sizeof(*pred_pos_chroma):%ld\n", num_pos_chroma, sizeof(*pred_pos_chroma));
- }
- pred_pos_luma = (s32 **)fgs_alloc(sizeof(*pred_pos_luma) * num_pos_luma);
-
- for (row = 0; row < num_pos_luma; row++) {
- pred_pos_luma[row] = (s32 *)fgs_alloc(sizeof(**pred_pos_luma) * 3);
- }
-
- pred_pos_chroma = (s32 **)fgs_alloc(sizeof(*pred_pos_chroma) * num_pos_chroma);
-
- for (row = 0; row < num_pos_chroma; row++) {
- pred_pos_chroma[row] = (s32 *)fgs_alloc(sizeof(**pred_pos_chroma) * 3);
- }
-
- for (row = -params->ar_coeff_lag; row < 0; row++) {
- for (col = -params->ar_coeff_lag;
- col < params->ar_coeff_lag + 1; col++) {
- pred_pos_luma[pos_ar_index][0] = row * luma_grain_stride;
- pred_pos_luma[pos_ar_index][1] = col;
- pred_pos_luma[pos_ar_index][2] = 0;
-
- pred_pos_chroma[pos_ar_index][0] = row * chroma_grain_stride;
- pred_pos_chroma[pos_ar_index][1] = col;
- pred_pos_chroma[pos_ar_index][2] = 0;
- ++pos_ar_index;
- }
- }
-
- for (col = -params->ar_coeff_lag; col < 0; col++) {
- pred_pos_luma[pos_ar_index][0] = 0;
- pred_pos_luma[pos_ar_index][1] = col;
- pred_pos_luma[pos_ar_index][2] = 0;
-
- pred_pos_chroma[pos_ar_index][0] = 0;
- pred_pos_chroma[pos_ar_index][1] = col;
- pred_pos_chroma[pos_ar_index][2] = 0;
-
- ++pos_ar_index;
- }
-
- if (params->num_y_points > 0) {
- pred_pos_chroma[pos_ar_index][0] = 0;
- pred_pos_chroma[pos_ar_index][1] = 0;
- pred_pos_chroma[pos_ar_index][2] = 1;
- }
-
- *pred_pos_luma_p = pred_pos_luma;
- *pred_pos_chroma_p = pred_pos_chroma;
- *luma_grain_block =
- (s32 *)fgs_alloc(sizeof(**luma_grain_block) * luma_grain_samples);
- if (debug_fgs & DEBUG_FGS_DETAIL) {
- pr_info("luma block size %ld, luma_grain_samples:%d\n", sizeof(**luma_grain_block) * luma_grain_samples, luma_grain_samples);
- }
- *cb_grain_block =
- (s32 *)fgs_alloc(sizeof(**cb_grain_block) * chroma_grain_samples);
- *cr_grain_block =
- (s32*)fgs_alloc(sizeof(**cr_grain_block) * chroma_grain_samples);
- if (debug_fgs & DEBUG_FGS_DETAIL) {
- pr_info("chroma block size %ld, chroma_grain_samples:%d\n", sizeof(**cb_grain_block) * chroma_grain_samples, chroma_grain_samples);
- }
-}
-
-static void dealloc_arrays(struct aom_film_grain_t *params,
- s32 ***pred_pos_luma, s32 ***pred_pos_chroma,
- s32 **luma_grain_block, s32 **cb_grain_block, s32 **cr_grain_block)
-{
- s32 num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
- s32 num_pos_chroma = num_pos_luma;
- s32 row;
-
- if (params->num_y_points > 0)
- ++num_pos_chroma;
-
- for (row = 0; row < num_pos_luma; row++) {
- vfree((*pred_pos_luma)[row]);
- }
- vfree(*pred_pos_luma);
-
- for (row = 0; row < num_pos_chroma; row++) {
- vfree((*pred_pos_chroma)[row]);
- }
- vfree((*pred_pos_chroma));
-
- vfree(*luma_grain_block);
-
- vfree(*cb_grain_block);
-
- vfree(*cr_grain_block);
-}
-
-// get a number between 0 and 2^bits - 1
-static inline s32 get_random_number(u16 *random_register, s32 bits)
-{
- u16 bit;
-
- bit = ((*random_register >> 0) ^ (*random_register >> 1) ^
- (*random_register >> 3) ^ (*random_register >> 12)) & 1;
- *random_register = (*random_register >> 1) | (bit << 15);
- return (*random_register >> (16 - bits)) & ((1 << bits) - 1);
-}
-
-static inline void init_random_generator(u16 *random_register, u16 seed, s32 luma_line)
-{
- // same for the picture
- u16 msb = (seed >> 8) & 0xff;
- u16 lsb = seed & 0xff;
- s32 luma_num = luma_line >> 5;
-
- *random_register = (msb << 8) + lsb;
- *random_register ^= ((luma_num * 37 + 178) & 255) << 8;
- *random_register ^= ((luma_num * 173 + 105) & 255);
-}
-
-static void generate_luma_grain_block(struct aom_film_grain_t *params,
- s32 **pred_pos_luma, s32 *luma_grain_block,
- s32 luma_block_size_y, s32 luma_block_size_x, s32 luma_grain_stride,
- s8 *table_ptr)
-{
- s32 x_start = left_pad + ar_padding * 2;
- s32 x_end = luma_block_size_x - right_pad - (ar_padding * 2) - 1;
- s32 y_start = top_pad + ar_padding * 2;
- s32 y_end = luma_block_size_y - bottom_pad - 1;
- s32 x_pad_start = left_pad;
- s32 x_pad_end = luma_block_size_x - right_pad - 1;
- s32 y_pad_start = top_pad;
- s32 y_pad_end = luma_block_size_y - bottom_pad - 1;
- u8 cnt = 0;
- s32 grain_block[4], grain_val;
- u32 bit_mask = (1 << params->bit_depth) - 1;
- s8 gauss_sec_shift = 12 - params->bit_depth + params->grain_scale_shift;
- s32 gauss_sec_val = (1 << gauss_sec_shift) >> 1;
- u32 num_pos_luma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
- s32 rounding_offset = (1 << (params->ar_coeff_shift - 1));
- u32 i, j, pos, block_id = 0;
- s32 random_num;
- s32 grain_center = 128 << (params->bit_depth - 8);
- s32 grain_min = 0 - grain_center;
- s32 grain_max = (256 << (params->bit_depth - 8)) - 1 - grain_center;
- s32 pred[30];
-
- table_ptr += luma_grain_block_offt;
- params->random_register_y = params->random_seed;
-
- if (params->num_y_points == 0)
- return;
-
- if (debug_fgs & DEBUG_FGS_DETAIL) {
- pr_info("-->gauss_sec_shift = %d \n",gauss_sec_shift);
- pr_info("-->ar_coeff_shift = %x \n",params->ar_coeff_shift);
- pr_info("-->rounding_offset = %x \n",rounding_offset);
- }
-
- for (pos = 0; pos < num_pos_luma; pos++)
- pred[pos] = pred_pos_luma[pos][0] + pred_pos_luma[pos][1];
-
- for (i = 0; i < luma_block_size_y; i++) {
- for (j = 0; j < luma_block_size_x; j++) {
- random_num =
- get_random_number(¶ms->random_register_y, gauss_bits);
- grain_val = (gaussian_seq[random_num] + gauss_sec_val) >> gauss_sec_shift;
- luma_grain_block[block_id] = grain_val;
- if (i >= y_pad_start && i <= y_pad_end &&
- j >= x_pad_start && j <= x_pad_end) {
- s32 wsum = 0;
-
- for (pos = 0; pos < num_pos_luma; pos++)
- wsum += params->ar_coeffs_y[pos] *
- luma_grain_block[block_id + pred[pos]];
- wsum += rounding_offset;
- wsum = wsum >> params->ar_coeff_shift;
- grain_val = MID(grain_val + wsum, grain_min, grain_max);
- luma_grain_block[block_id] = grain_val;
- if (i >= y_start && i <= y_end &&
- j >= x_start && j <= x_end) {
- grain_block[cnt++] = grain_val & bit_mask;
- if (cnt == 4) {
- table_ptr[0] = grain_block[0] & 0xff;
- table_ptr[1] = (grain_block[1] & 0x3f) << 2;
- table_ptr[1] |= (grain_block[0] >> 8) & 3;
- table_ptr[2] = (grain_block[2] & 0xf) << 4;
- table_ptr[2] |= (grain_block[1] >> 6) & 0xf;
- table_ptr[3] = (grain_block[3] & 3) << 6;
- table_ptr[3] |= (grain_block[2] >> 4) & 0x3f;
- table_ptr[4] = (grain_block[3] >> 2) & 0xff;
- table_ptr += 5;
- cnt = 0;
- }
- }
- }
- block_id++;
- }
- }
-}
-
-static s32 generate_chroma_grain_blocks(struct aom_film_grain_t *params,
- s32 **pred_pos_chroma, s32 *luma_grain_block, s32 *cb_grain_block,
- s32 *cr_grain_block, s32 luma_grain_stride, s32 chroma_block_size_y,
- s32 chroma_block_size_x, s32 chroma_grain_stride,
- s32 chroma_subsamp_y, s32 chroma_subsamp_x,
- s8 *table_ptr)
-{
- s8 gauss_sec_shift = 12 - params->bit_depth + params->grain_scale_shift;
- s32 gauss_sec_val = (1 << gauss_sec_shift) >> 1;
- s32 i, j, k, l, pos;
- u32 num_pos_chroma = 2 * params->ar_coeff_lag * (params->ar_coeff_lag + 1);
- s32 rounding_offset = (1 << (params->ar_coeff_shift - 1));
- s32 chroma_grain_samples = chroma_block_size_y * chroma_block_size_x;
- s32 cb_block[2], cr_block[2], cb_grain_val, cr_grain_val;
- u32 bit_mask = (1 << params->bit_depth) - 1;
- s32 x_start = left_pad + ar_padding * (2 >> chroma_subsamp_x);
- s32 x_end = chroma_block_size_x - right_pad - (ar_padding * (2 >> chroma_subsamp_x)) - 1;
- s32 y_start = top_pad + ar_padding * (2 >> chroma_subsamp_x);
- s32 y_end = chroma_block_size_y - bottom_pad - 1;
- s32 x_pad_start = left_pad;
- s32 x_pad_end = chroma_block_size_x - right_pad - 1;
- s32 y_pad_start = top_pad;
- s32 y_pad_end = chroma_block_size_y - bottom_pad - 1;
- u8 cnt;
- s32 random_num_cb, random_num_cr;
- u32 block_id;
- u8 do_cb = 1, do_cr = 1;
- s32 grain_center = 128 << (params->bit_depth - 8);
- s32 grain_min = 0 - grain_center;
- s32 grain_max = (256 << (params->bit_depth - 8)) - 1 - grain_center;
- s32 pred[30];
- u8 subsamp = chroma_subsamp_y + chroma_subsamp_x;
- u8 subsamp_val = (1 << (chroma_subsamp_y + chroma_subsamp_x)) >> 1;
-
- table_ptr += cb_grain_block_offt;
-
- if (params->num_y_points > 0)
- ++num_pos_chroma;
-
- for (pos = 0; pos < num_pos_chroma; pos++)
- pred[pos] = pred_pos_chroma[pos][0] + pred_pos_chroma[pos][1];
-
- if (!params->num_cb_points && !params->chroma_scaling_from_luma) {
- memset(cb_grain_block, 0, sizeof(*cb_grain_block) * chroma_grain_samples);
- do_cb = 0;
- } else {
- init_random_generator(
- ¶ms->random_register_cb,
- params->random_seed, 7 << 5);
- }
- if (!params->num_cr_points && !params->chroma_scaling_from_luma) {
- memset(cr_grain_block, 0, sizeof(*cr_grain_block) * chroma_grain_samples);
- do_cr = 0;
- } else {
- init_random_generator(
- ¶ms->random_register_cr,
- params->random_seed, 11 << 5);
-
- }
-
- block_id = 0;
- for (i = 0; i < chroma_block_size_y; i++) {
- for (j = 0; j < chroma_block_size_x; j++) {
- if (do_cb) {
- random_num_cb = get_random_number(
- ¶ms->random_register_cb, gauss_bits);
- cb_grain_val =
- (gaussian_seq[random_num_cb] + gauss_sec_val)
- >> gauss_sec_shift;
- cb_grain_block[block_id] = cb_grain_val;
- }
- if (do_cr) {
- random_num_cr = get_random_number(
- ¶ms->random_register_cr, gauss_bits);
- cr_grain_val =
- (gaussian_seq[random_num_cr] + gauss_sec_val)
- >> gauss_sec_shift;
- cr_grain_block[block_id] = cr_grain_val;
- }
- if (i >= y_pad_start && i <= y_pad_end &&
- j >= x_pad_start && j <= x_pad_end) {
- s32 wsum_cb = 0;
- s32 wsum_cr = 0;
-
- for (pos = 0; pos < num_pos_chroma; pos++) {
- if (pred_pos_chroma[pos][2] == 0) {
- wsum_cb += params->ar_coeffs_cb[pos] *
- cb_grain_block[block_id + pred[pos]];
- wsum_cr += params->ar_coeffs_cr[pos] *
- cr_grain_block[block_id + pred[pos]];
- } else if (pred_pos_chroma[pos][2] == 1) {
- s32 av_luma = 0;
- s32 luma_coord_y = ((i - top_pad) << chroma_subsamp_y) + top_pad;
- s32 luma_coord_x = ((j - left_pad) << chroma_subsamp_x) + left_pad;
-
- for (k = luma_coord_y;
- k < luma_coord_y + chroma_subsamp_y + 1; k++)
- for (l = luma_coord_x;
- l < luma_coord_x + chroma_subsamp_x + 1; l++) {
- av_luma += luma_grain_block[k * luma_grain_stride + l];
- }
- av_luma = (av_luma + subsamp_val) >> subsamp;
- wsum_cb += params->ar_coeffs_cb[pos] * av_luma;
- wsum_cr += params->ar_coeffs_cr[pos] * av_luma;
- } else {
- pr_info(
- "Grain synthesis: prediction between two chroma components is "
- "not supported!");
- return -1;
- }
- }
- if (do_cb) {
- wsum_cb += rounding_offset;
- wsum_cb = wsum_cb >> params->ar_coeff_shift;
- cb_grain_val =
- MID(cb_grain_val + wsum_cb, grain_min, grain_max);
- cb_grain_block[block_id] = cb_grain_val;
- }
- if (do_cr) {
- wsum_cr += rounding_offset;
- wsum_cr = wsum_cr >> params->ar_coeff_shift;
- cr_grain_val =
- MID(cr_grain_val + wsum_cr, grain_min, grain_max);
- cr_grain_block[block_id] = cr_grain_val;
- }
- if (i >= y_start && i <= y_end && j >= x_start && j <= x_end) {
- cb_block[cnt] = cb_grain_val & bit_mask;
- cr_block[cnt++] = cr_grain_val & bit_mask;
- if (cnt == 2) {
- table_ptr[0] = cb_block[0] & 0xff;
- table_ptr[1] = (cr_block[0] & 0x3f) << 2;
- table_ptr[1] |= (cb_block[0] >> 8) & 3;
- table_ptr[2] = (cb_block[1] & 0xf) << 4;
- table_ptr[2] |= (cr_block[0] >> 6) & 0xf;
- table_ptr[3] = (cr_block[1] & 3) << 6;
- table_ptr[3] |= (cb_block[1] >> 4) & 0x3f;
- table_ptr[4] = (cr_block[1] >> 2) & 0xff;
- table_ptr += 5;
- cnt = 0;
- }
- }
- }
- block_id++;
- }
- }
- return 0;
-}
-
-static void init_scaling_function(
- s32 scaling_points[][2], u8 num_points, s32 scaling_delta[])
-{
- s64 delta;
- s32 delta_y, delta_x, point;
-
- if (num_points == 0) return;
-
- for (point = 0; point < num_points - 1; point++) {
- delta_y = scaling_points[point + 1][1] - scaling_points[point][1];
- delta_x = scaling_points[point + 1][0] - scaling_points[point][0];
-
- delta = delta_y * ((65536 + (delta_x >> 1)) / delta_x);
- scaling_delta[point]=delta;
- }
-}
-
-void convert_to_fg_table(struct aom_film_grain_t *params, u8 *table_ptr)
-{
- s32 i, j;
- u32 total = 0;
-
- if (params->num_y_points > 0 ||
- params->num_cb_points > 0 ||
- params->num_cr_points > 0) {
- table_ptr[0] =
- ((params->apply_grain & 0x1) << 0) | //1bit [0]
- ((params->overlap_flag & 0x1) << 1) | //1bit [1]
- ((params->chroma_scaling_from_luma & 0x1) << 2) | //1bit [2]
- ((params->clip_to_restricted_range & 0x1) << 3) | //1bit [3]
- ((params->mc_identity & 0x1) << 4); //1bit [4]
- table_ptr[1] = (params->random_seed >> 0) & 0xff; //random_seed: 16bits
- table_ptr[2] = (params->random_seed >> 8) & 0xff;
- table_ptr[3] =
- ((params->num_y_points & 0xf) << 0) | //4bit 0...14
- ((params->num_cb_points & 0xf) << 4); //4bit 0...10
- table_ptr[4] =
- ((params->num_cr_points & 0xf) << 0) | //4bit 0...10
- ((params->scaling_shift & 0xf) << 4); //4bit: 8...11
- table_ptr[5] = params->cb_luma_mult; //8bit
- table_ptr[6] = params->cb_mult; //8bit
- table_ptr[7] = ((params->cb_offset >> 0) & 0xff); //cb_offset:9bit
- table_ptr[8] = ((params->cb_offset >> 8) & 0x1);
- table_ptr[9] = params->cr_luma_mult; //8bit
- table_ptr[10] = params->cr_mult; //8bit
- table_ptr[11] = ((params->cr_offset >> 0) & 0xff); //cr_offset:9bit
- table_ptr[12] = ((params->cr_offset >> 8) & 0x1);
- table_ptr[13] = 0;
- table_ptr[14] = 0;
- table_ptr[15] = 0;
- } else {
- memset(table_ptr, 0, 16 * sizeof(char));
- }
- total = 1;
- table_ptr += 16;
- //y_scale (7x128bit)
- if (params->num_y_points > 0) {
- for (i = 0; i < 14; i += 2) {
- j = i + 1;
- table_ptr[0] = params->scaling_points_y[i][0]; //x
- table_ptr[1] = params->scaling_points_y[i][1]; //y
- //delta, it be signed, so 25bit
- table_ptr[2] = (params->scaling_delta_y[i] >> 0) & 0xff;
- table_ptr[3] = (params->scaling_delta_y[i] >> 8) & 0xff;
- table_ptr[4] = (params->scaling_delta_y[i] >> 16) & 0xff;
- table_ptr[5] = (params->scaling_delta_y[i] >> 24) & 0xff;
- table_ptr[6] = params->scaling_points_y[j][0];
- table_ptr[7] = params->scaling_points_y[j][1];
- table_ptr[8] =
- (j == 13) ? 0 : ((params->scaling_delta_y[j] >> 0) & 0xff);
- table_ptr[9] =
- (j == 13) ? 0 : ((params->scaling_delta_y[j] >> 8) & 0xff);
- table_ptr[10] =
- (j == 13) ? 0 : ((params->scaling_delta_y[j] >> 16) & 0xff);
- table_ptr[11] =
- (j == 13) ? 0 : ((params->scaling_delta_y[j] >> 24) & 0xff);
- table_ptr[12] = 0;
- table_ptr[13] = 0;
- table_ptr[14] = 0;
- table_ptr[15] = 0;
- table_ptr += 16;
- }
- } else {
- memset(table_ptr, 0, 16 * 7 * sizeof(char));
- table_ptr += 16 * 7;
- }
- total += 7;
- if (params->num_cb_points > 0) {
- for (i = 0; i < 10; i += 2) {
- j = i + 1;
- table_ptr[0] = params->scaling_points_cb[i][0];
- table_ptr[1] = params->scaling_points_cb[i][1];
- //delta, it be signed, so 25bit
- table_ptr[2] = (params->scaling_delta_cb[i] >> 0) & 0xff;
- table_ptr[3] = (params->scaling_delta_cb[i] >> 8) & 0xff;
- table_ptr[4] = (params->scaling_delta_cb[i] >> 16) & 0xff;
- table_ptr[5] = (params->scaling_delta_cb[i] >> 24) & 0xff;
- table_ptr[6] = params->scaling_points_cb[j][0];
- table_ptr[7] = params->scaling_points_cb[j][1];
- table_ptr[8] =
- (j == 9) ? 0 : ((params->scaling_delta_cb[j] >> 0) & 0xff);
- table_ptr[9] =
- (j == 9) ? 0 : ((params->scaling_delta_cb[j] >> 8) & 0xff);
- table_ptr[10] =
- (j == 9) ? 0 : ((params->scaling_delta_cb[j] >> 16) & 0xff);
- table_ptr[11] =
- (j == 9) ? 0 : ((params->scaling_delta_cb[j] >> 24) & 0xff);
- table_ptr[12] = 0;
- table_ptr[13] = 0;
- table_ptr[14] = 0;
- table_ptr[15] = 0;
- table_ptr += 16;
- }
- } else {
- memset(table_ptr, 0, 16 * 5 * sizeof(char));
- table_ptr += 16 * 5;
- }
- total += 5;
- if (params->num_cr_points > 0) {
- for (i = 0; i < 10; i += 2) {
- j = i + 1;
- table_ptr[0] = params->scaling_points_cr[i][0];
- table_ptr[1] = params->scaling_points_cr[i][1];
- //delta, it be signed, so 25bit
- table_ptr[2] = (params->scaling_delta_cr[i] >> 0) & 0xff;
- table_ptr[3] = (params->scaling_delta_cr[i] >> 8) & 0xff;
- table_ptr[4] = (params->scaling_delta_cr[i] >> 16) & 0xff;
- table_ptr[5] = (params->scaling_delta_cr[i] >> 24) & 0xff;
- table_ptr[6] = params->scaling_points_cr[j][0];
- table_ptr[7] = params->scaling_points_cr[j][1];
- table_ptr[8] =
- (j == 9) ? 0 : ((params->scaling_delta_cr[j] >> 0) & 0xff);
- table_ptr[9] =
- (j == 9) ? 0 : ((params->scaling_delta_cr[j] >> 8) & 0xff);
- table_ptr[10] =
- (j == 9) ? 0 : ((params->scaling_delta_cr[j] >> 16) & 0xff);
- table_ptr[11] =
- (j == 9) ? 0 : ((params->scaling_delta_cr[j] >> 24) & 0xff);
- table_ptr[12] = 0;
- table_ptr[13] = 0;
- table_ptr[14] = 0;
- table_ptr[15] = 0;
- table_ptr += 16;
- }
- } else {
- memset(table_ptr, 0, 16 * 5 * sizeof(char));
- table_ptr += 16 * 5;
- }
- //total += 5;
- //total += 480;//320;
-}
-
-void av1_add_film_grain_run(char *fg_table_buf, struct aom_film_grain_t *params)
-{
- s32 **pred_pos_luma;
- s32 **pred_pos_chroma;
- s32 *luma_grain_block;
- s32 *cb_grain_block;
- s32 *cr_grain_block;
- s32 luma_block_size_y, luma_block_size_x;
- s32 chroma_block_size_y, chroma_block_size_x;
- s32 chroma_subblock_size_y, chroma_subblock_size_x;
- s32 chroma_subsamp_x = 1;
- s32 chroma_subsamp_y = 1;
-
- ulong start_time, step_time;
- u32 time1, time2, time3, time4, time5, time6;
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME)
- start_time = step_time = local_clock();
-
- chroma_subblock_size_y = luma_subblock_size_y >> chroma_subsamp_y;
- chroma_subblock_size_x = luma_subblock_size_x >> chroma_subsamp_x;
-
- // Initial padding is only needed for generation of
- // film grain templates (to stabilize the AR process)
- // Only a 64x64 luma and 32x32 chroma part of a template
- // is used later for adding grain, padding can be discarded
-
- luma_block_size_y = top_pad + 2 * ar_padding +
- luma_subblock_size_y * 2 + bottom_pad;
- luma_block_size_x = left_pad + 2 * ar_padding +
- luma_subblock_size_x * 2 + 2 * ar_padding + right_pad;
-
- chroma_block_size_y = top_pad + (2 >> chroma_subsamp_y) * ar_padding +
- chroma_subblock_size_y * 2 + bottom_pad;
- chroma_block_size_x = left_pad + (2 >> chroma_subsamp_x) * ar_padding +
- chroma_subblock_size_x * 2 +
- (2 >> chroma_subsamp_x) * ar_padding + right_pad;
-
- init_arrays(params, &pred_pos_luma,
- &pred_pos_chroma, &luma_grain_block,
- &cb_grain_block, &cr_grain_block,
- luma_block_size_y * luma_block_size_x,
- luma_block_size_x,
- chroma_block_size_y * chroma_block_size_x,
- chroma_block_size_x);
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time1 = div64_u64(local_clock() - step_time, 1000);
- step_time = local_clock();
- }
-
- generate_luma_grain_block(params,
- pred_pos_luma, luma_grain_block,
- luma_block_size_y, luma_block_size_x,
- luma_block_size_x, fg_table_buf);
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time2 = div64_u64(local_clock() - step_time, 1000);
- step_time = local_clock();
- }
-
- generate_chroma_grain_blocks(params,
- pred_pos_chroma, luma_grain_block,
- cb_grain_block, cr_grain_block,
- luma_block_size_x,
- chroma_block_size_y, chroma_block_size_x,
- chroma_block_size_x,
- chroma_subsamp_y, chroma_subsamp_x,
- fg_table_buf);
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time3 = div64_u64(local_clock() - step_time, 1000);
- step_time = local_clock();
- }
-
- init_scaling_function(
- params->scaling_points_y,
- params->num_y_points,
- params->scaling_delta_y);
-
- if (!params->chroma_scaling_from_luma) {
- init_scaling_function(
- params->scaling_points_cb,
- params->num_cb_points,
- params->scaling_delta_cb);
- init_scaling_function(
- params->scaling_points_cr,
- params->num_cr_points,
- params->scaling_delta_cr);
- }
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time4 = div64_u64(local_clock() - step_time, 1000);
- step_time = local_clock();
- }
-
- convert_to_fg_table(params, fg_table_buf);
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time5 = div64_u64(local_clock() - step_time, 1000);
- step_time = local_clock();
- }
-
- dealloc_arrays(params,
- &pred_pos_luma, &pred_pos_chroma,
- &luma_grain_block,
- &cb_grain_block, &cr_grain_block);
-
- if (debug_fgs & DEBUG_FGS_CONSUME_TIME) {
- time6 = div64_u64(local_clock() - step_time, 1000);
- pr_info("fgs consume time %d (%d, %d, %d, %d, %d, %d)us\n",
- div64_u64(local_clock() - start_time, 1000), time1, time2, time3, time4, time5, time6);
- }
-}
-
-/* Film Grain Entry */
-#if 0
-int pic_film_grain_run(char *fg_table_addr, u32 fgs_ctrl, u32 *fgs_data)
-#endif
-int pic_film_grain_run(u32 frame_count, char *fg_table_addr, u32 fgs_ctrl, u32 *fgs_data)
-
-{
- struct aom_film_grain_t fg_params;
-
- if (debug_fgs & DEBUG_FGS_REGS) {
- int i;
- pr_info("film grain ctrl: 0x%08x\n", fgs_ctrl);
- for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) {
- pr_info("film grain reg[%02d]: 0x%08x\n", i, fgs_data[i]);
- }
- }
-
- film_grain_data_parse(&fg_params, fgs_ctrl, fgs_data);
-
- if (debug_fgs & DEBUG_FGS_REGS_PARSE) {
- fg_info_print(&fg_params);
- }
-
- av1_add_film_grain_run(fg_table_addr, &fg_params);
-
- if (debug_fgs & DEBUG_FGS_TABLE_DUMP) {
- #define FGS_TABLE_SIZE (512 * 128 / 8)
- struct file *fg_fp = NULL;
- char file[256] = {0};
-
- snprintf(file, sizeof(file), "/data/tmp/fgs_table_%d.bin", frame_count - 1);
- fg_fp = filp_open(file, O_CREAT | O_RDWR | O_TRUNC, 0666);
- if (IS_ERR(fg_fp)) {
- fg_fp = NULL;
- printk(KERN_ERR"open %s failed\n", file);
- } else {
- kernel_write(fg_fp, fg_table_addr, FGS_TABLE_SIZE, &fg_fp->f_pos);
- filp_close(fg_fp, current->files);
- fg_fp = NULL;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL(pic_film_grain_run);
-
-int get_debug_fgs(void)
-{
- return debug_fgs;
-}
-EXPORT_SYMBOL(get_debug_fgs);
-
diff --git a/drivers/frame_provider/decoder_v4l/vav1/av1_global.h b/drivers/frame_provider/decoder_v4l/vav1/av1_global.h
deleted file mode 100644
index 0c53ff8..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/av1_global.h
+++ /dev/null
@@ -1,2360 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef AV1_GLOBAL_H_
-#define AV1_GLOBAL_H_
-#define AOM_AV1_MMU_DW
-#ifndef HAVE_NEON
-#define HAVE_NEON 0
-#endif
-#ifndef CONFIG_ACCOUNTING
-#define CONFIG_ACCOUNTING 0
-#endif
-#ifndef CONFIG_INSPECTION
-#define CONFIG_INSPECTION 0
-#endif
-#ifndef CONFIG_LPF_MASK
-#define CONFIG_LPF_MASK 0
-#endif
-#ifndef CONFIG_SIZE_LIMIT
-#define CONFIG_SIZE_LIMIT 0
-#endif
-
-#define SUPPORT_SCALE_FACTOR
-#define USE_SCALED_WIDTH_FROM_UCODE
-#define AML
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-#define AML_DEVICE
-#endif
-#ifdef BUFMGR_FOR_SIM
-#define printf io_printf
-#endif
-
-#ifndef INT_MAX
-#define INT_MAX 0x7FFFFFFF
-#endif
-#define AOMMIN(x, y) (((x) < (y)) ? (x) : (y))
-#define AOMMAX(x, y) (((x) > (y)) ? (x) : (y))
-
-/*
- *typedef char int8_t;
- *#ifndef BUFMGR_FOR_SIM
- *typedef unsigned char uint8_t;
- *#endif
- *typedef unsigned int uint32_t;
- *typedef int int32_t;
- *typedef long long int64_t;
- */
-
-#ifdef AML
-#define AOM_AV1_MMU
-#define FILM_GRAIN_REG_SIZE 39
-typedef struct buff_s
-{
- uint32_t buf_start;
- uint32_t buf_size;
- uint32_t buf_end;
-} buff_t;
-
-typedef struct BuffInfo_s
-{
- uint32_t max_width;
- uint32_t max_height;
- uint32_t start_adr;
- uint32_t end_adr;
- buff_t ipp;
- buff_t sao_abv;
- buff_t sao_vb;
- buff_t short_term_rps;
- buff_t vps;
- buff_t seg_map;
- buff_t daala_top;
- buff_t sao_up;
- buff_t swap_buf;
- buff_t cdf_buf;
- buff_t gmc_buf;
- buff_t scalelut;
- buff_t dblk_para;
- buff_t dblk_data;
- buff_t cdef_data;
- buff_t ups_data;
-#ifdef AOM_AV1_MMU
- buff_t mmu_vbh;
- buff_t cm_header;
-#endif
-#ifdef AOM_AV1_MMU_DW
- buff_t mmu_vbh_dw;
- buff_t cm_header_dw;
-#endif
- buff_t fgs_table;
- buff_t mpred_above;
- buff_t mpred_mv;
- buff_t rpm;
- buff_t lmem;
-} BuffInfo_t;
-#endif
-
-#if 0
-#define va_start(v,l) __builtin_va_start(v,l)
-#define va_end(v) __builtin_va_end(v)
-#define va_arg(v,l) __builtin_va_arg(v,l)
-#endif
-
-/*
-mem.h
-*/
-#if (defined(__GNUC__) && __GNUC__) || defined(__SUNPRO_C)
-#define DECLARE_ALIGNED(n, typ, val) typ val __attribute__((aligned(n)))
-#elif defined(_MSC_VER)
-#define DECLARE_ALIGNED(n, typ, val) __declspec(align(n)) typ val
-#else
-#warning No alignment directives known for this compiler.
-#define DECLARE_ALIGNED(n, typ, val) typ val
-#endif
-
-/* Indicates that the usage of the specified variable has been audited to assure
- * that it's safe to use uninitialized. Silences 'may be used uninitialized'
- * warnings on gcc.
- */
-#if defined(__GNUC__) && __GNUC__
-#define UNINITIALIZED_IS_SAFE(x) x = x
-#else
-#define UNINITIALIZED_IS_SAFE(x) x
-#endif
-
-#if HAVE_NEON && defined(_MSC_VER)
-#define __builtin_prefetch(x)
-#endif
-
-/* Shift down with rounding for use when n >= 0, value >= 0 */
-#define ROUND_POWER_OF_TWO(value, n) (((value) + (((1 << (n)) >> 1))) >> (n))
-
-/* Shift down with rounding for signed integers, for use when n >= 0 */
-#define ROUND_POWER_OF_TWO_SIGNED(value, n) \
- (((value) < 0) ? -ROUND_POWER_OF_TWO(-(value), (n)) \
- : ROUND_POWER_OF_TWO((value), (n)))
-
-/* Shift down with rounding for use when n >= 0, value >= 0 for (64 bit) */
-#define ROUND_POWER_OF_TWO_64(value, n) \
- (((value) + ((((int64_t)1 << (n)) >> 1))) >> (n))
-/* Shift down with rounding for signed integers, for use when n >= 0 (64 bit) */
-#define ROUND_POWER_OF_TWO_SIGNED_64(value, n) \
- (((value) < 0) ? -ROUND_POWER_OF_TWO_64(-(value), (n)) \
- : ROUND_POWER_OF_TWO_64((value), (n)))
-
-/* shift right or left depending on sign of n */
-#define RIGHT_SIGNED_SHIFT(value, n) \
- ((n) < 0 ? ((value) << (-(n))) : ((value) >> (n)))
-
-#define ALIGN_POWER_OF_TWO(value, n) \
- (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1))
-
-#define DIVIDE_AND_ROUND(x, y) (((x) + ((y) >> 1)) / (y))
-
-#define CONVERT_TO_SHORTPTR(x) ((uint16_t *)(((uintptr_t)(x)) << 1))
-#define CONVERT_TO_BYTEPTR(x) ((uint8_t *)(((uintptr_t)(x)) >> 1))
-
-#ifdef AML
-#define TYPEDEF typedef
-#define UENUM1BYTE(enumvar) enumvar
-#define SENUM1BYTE(enumvar) enumvar
-#define UENUM2BYTE(enumvar) enumvar
-#define SENUM2BYTE(enumvar) enumvar
-#define UENUM4BYTE(enumvar) enumvar
-#define SENUM4BYTE(enumvar) enumvar
-
-#else
-#define TYPEDEF
-/*!\brief force enum to be unsigned 1 byte*/
-#define UENUM1BYTE(enumvar) \
- ; \
- typedef uint8_t enumvar
-
-/*!\brief force enum to be signed 1 byte*/
-#define SENUM1BYTE(enumvar) \
- ; \
- typedef int8_t enumvar
-
-/*!\brief force enum to be unsigned 2 byte*/
-#define UENUM2BYTE(enumvar) \
- ; \
- typedef uint16_t enumvar
-
-/*!\brief force enum to be signed 2 byte*/
-#define SENUM2BYTE(enumvar) \
- ; \
- typedef int16_t enumvar
-
-/*!\brief force enum to be unsigned 4 byte*/
-#define UENUM4BYTE(enumvar) \
- ; \
- typedef uint32_t enumvar
-
-/*!\brief force enum to be unsigned 4 byte*/
-#define SENUM4BYTE(enumvar) \
- ; \
- typedef int32_t enumvar
-#endif
-
-
-/*
-#include "enums.h"
-*/
-#undef MAX_SB_SIZE
-
-// Max superblock size
-#define MAX_SB_SIZE_LOG2 7
-#define MAX_SB_SIZE (1 << MAX_SB_SIZE_LOG2)
-#define MAX_SB_SQUARE (MAX_SB_SIZE * MAX_SB_SIZE)
-
-// Min superblock size
-#define MIN_SB_SIZE_LOG2 6
-
-// Pixels per Mode Info (MI) unit
-#define MI_SIZE_LOG2 2
-#define MI_SIZE (1 << MI_SIZE_LOG2)
-
-// MI-units per max superblock (MI Block - MIB)
-#define MAX_MIB_SIZE_LOG2 (MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2)
-#define MAX_MIB_SIZE (1 << MAX_MIB_SIZE_LOG2)
-
-// MI-units per min superblock
-#define MIN_MIB_SIZE_LOG2 (MIN_SB_SIZE_LOG2 - MI_SIZE_LOG2)
-
-// Mask to extract MI offset within max MIB
-#define MAX_MIB_MASK (MAX_MIB_SIZE - 1)
-
-// Maximum number of tile rows and tile columns
-#define MAX_TILE_ROWS 64
-#define MAX_TILE_COLS 64
-
-#define MAX_VARTX_DEPTH 2
-
-#define MI_SIZE_64X64 (64 >> MI_SIZE_LOG2)
-#define MI_SIZE_128X128 (128 >> MI_SIZE_LOG2)
-
-#define MAX_PALETTE_SQUARE (64 * 64)
-// Maximum number of colors in a palette.
-#define PALETTE_MAX_SIZE 8
-// Minimum number of colors in a palette.
-#define PALETTE_MIN_SIZE 2
-
-#define FRAME_OFFSET_BITS 5
-#define MAX_FRAME_DISTANCE ((1 << FRAME_OFFSET_BITS) - 1)
-
-// 4 frame filter levels: y plane vertical, y plane horizontal,
-// u plane, and v plane
-#define FRAME_LF_COUNT 4
-#define DEFAULT_DELTA_LF_MULTI 0
-#define MAX_MODE_LF_DELTAS 2
-
-#define DIST_PRECISION_BITS 4
-#define DIST_PRECISION (1 << DIST_PRECISION_BITS) // 16
-
-#define PROFILE_BITS 3
-// The following three profiles are currently defined.
-// Profile 0. 8-bit and 10-bit 4:2:0 and 4:0:0 only.
-// Profile 1. 8-bit and 10-bit 4:4:4
-// Profile 2. 8-bit and 10-bit 4:2:2
-// 12-bit 4:0:0, 4:2:2 and 4:4:4
-// Since we have three bits for the profiles, it can be extended later.
-TYPEDEF enum {
- PROFILE_0,
- PROFILE_1,
- PROFILE_2,
- MAX_PROFILES,
-} SENUM1BYTE(BITSTREAM_PROFILE);
-
-#define OP_POINTS_CNT_MINUS_1_BITS 5
-#define OP_POINTS_IDC_BITS 12
-
-// Note: Some enums use the attribute 'packed' to use smallest possible integer
-// type, so that we can save memory when they are used in structs/arrays.
-
-typedef enum ATTRIBUTE_PACKED {
- BLOCK_4X4,
- BLOCK_4X8,
- BLOCK_8X4,
- BLOCK_8X8,
- BLOCK_8X16,
- BLOCK_16X8,
- BLOCK_16X16,
- BLOCK_16X32,
- BLOCK_32X16,
- BLOCK_32X32,
- BLOCK_32X64,
- BLOCK_64X32,
- BLOCK_64X64,
- BLOCK_64X128,
- BLOCK_128X64,
- BLOCK_128X128,
- BLOCK_4X16,
- BLOCK_16X4,
- BLOCK_8X32,
- BLOCK_32X8,
- BLOCK_16X64,
- BLOCK_64X16,
- BLOCK_SIZES_ALL,
- BLOCK_SIZES = BLOCK_4X16,
- BLOCK_INVALID = 255,
- BLOCK_LARGEST = (BLOCK_SIZES - 1)
-} BLOCK_SIZE2;
-
-// 4X4, 8X8, 16X16, 32X32, 64X64, 128X128
-#define SQR_BLOCK_SIZES 6
-
-TYPEDEF enum {
- PARTITION_NONE,
- PARTITION_HORZ,
- PARTITION_VERT,
- PARTITION_SPLIT,
- PARTITION_HORZ_A, // HORZ split and the top partition is split again
- PARTITION_HORZ_B, // HORZ split and the bottom partition is split again
- PARTITION_VERT_A, // VERT split and the left partition is split again
- PARTITION_VERT_B, // VERT split and the right partition is split again
- PARTITION_HORZ_4, // 4:1 horizontal partition
- PARTITION_VERT_4, // 4:1 vertical partition
- EXT_PARTITION_TYPES,
- PARTITION_TYPES = PARTITION_SPLIT + 1,
- PARTITION_INVALID = 255
-} UENUM1BYTE(PARTITION_TYPE);
-
-typedef char PARTITION_CONTEXT;
-#define PARTITION_PLOFFSET 4 // number of probability models per block size
-#define PARTITION_BLOCK_SIZES 5
-#define PARTITION_CONTEXTS (PARTITION_BLOCK_SIZES * PARTITION_PLOFFSET)
-
-// block transform size
-TYPEDEF enum {
- TX_4X4, // 4x4 transform
- TX_8X8, // 8x8 transform
- TX_16X16, // 16x16 transform
- TX_32X32, // 32x32 transform
- TX_64X64, // 64x64 transform
- TX_4X8, // 4x8 transform
- TX_8X4, // 8x4 transform
- TX_8X16, // 8x16 transform
- TX_16X8, // 16x8 transform
- TX_16X32, // 16x32 transform
- TX_32X16, // 32x16 transform
- TX_32X64, // 32x64 transform
- TX_64X32, // 64x32 transform
- TX_4X16, // 4x16 transform
- TX_16X4, // 16x4 transform
- TX_8X32, // 8x32 transform
- TX_32X8, // 32x8 transform
- TX_16X64, // 16x64 transform
- TX_64X16, // 64x16 transform
- TX_SIZES_ALL, // Includes rectangular transforms
- TX_SIZES = TX_4X8, // Does NOT include rectangular transforms
- TX_SIZES_LARGEST = TX_64X64,
- TX_INVALID = 255 // Invalid transform size
-} UENUM1BYTE(TX_SIZE);
-
-#define TX_SIZE_LUMA_MIN (TX_4X4)
-/* We don't need to code a transform size unless the allowed size is at least
- one more than the minimum. */
-#define TX_SIZE_CTX_MIN (TX_SIZE_LUMA_MIN + 1)
-
-// Maximum tx_size categories
-#define MAX_TX_CATS (TX_SIZES - TX_SIZE_CTX_MIN)
-#define MAX_TX_DEPTH 2
-
-#define MAX_TX_SIZE_LOG2 (6)
-#define MAX_TX_SIZE (1 << MAX_TX_SIZE_LOG2)
-#define MIN_TX_SIZE_LOG2 2
-#define MIN_TX_SIZE (1 << MIN_TX_SIZE_LOG2)
-#define MAX_TX_SQUARE (MAX_TX_SIZE * MAX_TX_SIZE)
-
-// Pad 4 extra columns to remove horizontal availability check.
-#define TX_PAD_HOR_LOG2 2
-#define TX_PAD_HOR 4
-// Pad 6 extra rows (2 on top and 4 on bottom) to remove vertical availability
-// check.
-#define TX_PAD_TOP 0
-#define TX_PAD_BOTTOM 4
-#define TX_PAD_VER (TX_PAD_TOP + TX_PAD_BOTTOM)
-// Pad 16 extra bytes to avoid reading overflow in SIMD optimization.
-#define TX_PAD_END 16
-#define TX_PAD_2D ((32 + TX_PAD_HOR) * (32 + TX_PAD_VER) + TX_PAD_END)
-
-// Number of maxium size transform blocks in the maximum size superblock
-#define MAX_TX_BLOCKS_IN_MAX_SB_LOG2 ((MAX_SB_SIZE_LOG2 - MAX_TX_SIZE_LOG2) * 2)
-#define MAX_TX_BLOCKS_IN_MAX_SB (1 << MAX_TX_BLOCKS_IN_MAX_SB_LOG2)
-
-// frame transform mode
-TYPEDEF enum {
- ONLY_4X4, // use only 4x4 transform
- TX_MODE_LARGEST, // transform size is the largest possible for pu size
- TX_MODE_SELECT, // transform specified for each block
- TX_MODES,
-} UENUM1BYTE(TX_MODE);
-
-// 1D tx types
-TYPEDEF enum {
- DCT_1D,
- ADST_1D,
- FLIPADST_1D,
- IDTX_1D,
- TX_TYPES_1D,
-} UENUM1BYTE(TX_TYPE_1D);
-
-TYPEDEF enum {
- DCT_DCT, // DCT in both horizontal and vertical
- ADST_DCT, // ADST in vertical, DCT in horizontal
- DCT_ADST, // DCT in vertical, ADST in horizontal
- ADST_ADST, // ADST in both directions
- FLIPADST_DCT, // FLIPADST in vertical, DCT in horizontal
- DCT_FLIPADST, // DCT in vertical, FLIPADST in horizontal
- FLIPADST_FLIPADST, // FLIPADST in both directions
- ADST_FLIPADST, // ADST in vertical, FLIPADST in horizontal
- FLIPADST_ADST, // FLIPADST in vertical, ADST in horizontal
- IDTX, // Identity in both directions
- V_DCT, // DCT in vertical, identity in horizontal
- H_DCT, // Identity in vertical, DCT in horizontal
- V_ADST, // ADST in vertical, identity in horizontal
- H_ADST, // Identity in vertical, ADST in horizontal
- V_FLIPADST, // FLIPADST in vertical, identity in horizontal
- H_FLIPADST, // Identity in vertical, FLIPADST in horizontal
- TX_TYPES,
-} UENUM1BYTE(TX_TYPE);
-
-TYPEDEF enum {
- REG_REG,
- REG_SMOOTH,
- REG_SHARP,
- SMOOTH_REG,
- SMOOTH_SMOOTH,
- SMOOTH_SHARP,
- SHARP_REG,
- SHARP_SMOOTH,
- SHARP_SHARP,
-} UENUM1BYTE(DUAL_FILTER_TYPE);
-
-TYPEDEF enum {
- // DCT only
- EXT_TX_SET_DCTONLY,
- // DCT + Identity only
- EXT_TX_SET_DCT_IDTX,
- // Discrete Trig transforms w/o flip (4) + Identity (1)
- EXT_TX_SET_DTT4_IDTX,
- // Discrete Trig transforms w/o flip (4) + Identity (1) + 1D Hor/vert DCT (2)
- EXT_TX_SET_DTT4_IDTX_1DDCT,
- // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver DCT (2)
- EXT_TX_SET_DTT9_IDTX_1DDCT,
- // Discrete Trig transforms w/ flip (9) + Identity (1) + 1D Hor/Ver (6)
- EXT_TX_SET_ALL16,
- EXT_TX_SET_TYPES
-} UENUM1BYTE(TxSetType);
-
-#define IS_2D_TRANSFORM(tx_type) (tx_type < IDTX)
-
-#define EXT_TX_SIZES 4 // number of sizes that use extended transforms
-#define EXT_TX_SETS_INTER 4 // Sets of transform selections for INTER
-#define EXT_TX_SETS_INTRA 3 // Sets of transform selections for INTRA
-
-TYPEDEF enum {
- AOM_LAST_FLAG = 1 << 0,
- AOM_LAST2_FLAG = 1 << 1,
- AOM_LAST3_FLAG = 1 << 2,
- AOM_GOLD_FLAG = 1 << 3,
- AOM_BWD_FLAG = 1 << 4,
- AOM_ALT2_FLAG = 1 << 5,
- AOM_ALT_FLAG = 1 << 6,
- AOM_REFFRAME_ALL = (1 << 7) - 1
-} UENUM1BYTE(AOM_REFFRAME);
-
-TYPEDEF enum {
- UNIDIR_COMP_REFERENCE,
- BIDIR_COMP_REFERENCE,
- COMP_REFERENCE_TYPES,
-} UENUM1BYTE(COMP_REFERENCE_TYPE);
-
-/*enum { PLANE_TYPE_Y, PLANE_TYPE_UV, PLANE_TYPES } UENUM1BYTE(PLANE_TYPE);*/
-
-#define CFL_ALPHABET_SIZE_LOG2 4
-#define CFL_ALPHABET_SIZE (1 << CFL_ALPHABET_SIZE_LOG2)
-#define CFL_MAGS_SIZE ((2 << CFL_ALPHABET_SIZE_LOG2) + 1)
-#define CFL_IDX_U(idx) (idx >> CFL_ALPHABET_SIZE_LOG2)
-#define CFL_IDX_V(idx) (idx & (CFL_ALPHABET_SIZE - 1))
-
-/*enum { CFL_PRED_U, CFL_PRED_V, CFL_PRED_PLANES } UENUM1BYTE(CFL_PRED_TYPE);*/
-
-TYPEDEF enum {
- CFL_SIGN_ZERO,
- CFL_SIGN_NEG,
- CFL_SIGN_POS,
- CFL_SIGNS
-} UENUM1BYTE(CFL_SIGN_TYPE);
-
-TYPEDEF enum {
- CFL_DISALLOWED,
- CFL_ALLOWED,
- CFL_ALLOWED_TYPES
-} UENUM1BYTE(CFL_ALLOWED_TYPE);
-
-// CFL_SIGN_ZERO,CFL_SIGN_ZERO is invalid
-#define CFL_JOINT_SIGNS (CFL_SIGNS * CFL_SIGNS - 1)
-// CFL_SIGN_U is equivalent to (js + 1) / 3 for js in 0 to 8
-#define CFL_SIGN_U(js) (((js + 1) * 11) >> 5)
-// CFL_SIGN_V is equivalent to (js + 1) % 3 for js in 0 to 8
-#define CFL_SIGN_V(js) ((js + 1) - CFL_SIGNS * CFL_SIGN_U(js))
-
-// There is no context when the alpha for a given plane is zero.
-// So there are 2 fewer contexts than joint signs.
-#define CFL_ALPHA_CONTEXTS (CFL_JOINT_SIGNS + 1 - CFL_SIGNS)
-#define CFL_CONTEXT_U(js) (js + 1 - CFL_SIGNS)
-// Also, the contexts are symmetric under swapping the planes.
-#define CFL_CONTEXT_V(js) \
- (CFL_SIGN_V(js) * CFL_SIGNS + CFL_SIGN_U(js) - CFL_SIGNS)
-
-TYPEDEF enum {
- PALETTE_MAP,
- COLOR_MAP_TYPES,
-} UENUM1BYTE(COLOR_MAP_TYPE);
-
-TYPEDEF enum {
- TWO_COLORS,
- THREE_COLORS,
- FOUR_COLORS,
- FIVE_COLORS,
- SIX_COLORS,
- SEVEN_COLORS,
- EIGHT_COLORS,
- PALETTE_SIZES
-} UENUM1BYTE(PALETTE_SIZE);
-
-TYPEDEF enum {
- PALETTE_COLOR_ONE,
- PALETTE_COLOR_TWO,
- PALETTE_COLOR_THREE,
- PALETTE_COLOR_FOUR,
- PALETTE_COLOR_FIVE,
- PALETTE_COLOR_SIX,
- PALETTE_COLOR_SEVEN,
- PALETTE_COLOR_EIGHT,
- PALETTE_COLORS
-} UENUM1BYTE(PALETTE_COLOR);
-
-// Note: All directional predictors must be between V_PRED and D67_PRED (both
-// inclusive).
-TYPEDEF enum {
- DC_PRED, // Average of above and left pixels
- V_PRED, // Vertical
- H_PRED, // Horizontal
- D45_PRED, // Directional 45 degree
- D135_PRED, // Directional 135 degree
- D113_PRED, // Directional 113 degree
- D157_PRED, // Directional 157 degree
- D203_PRED, // Directional 203 degree
- D67_PRED, // Directional 67 degree
- SMOOTH_PRED, // Combination of horizontal and vertical interpolation
- SMOOTH_V_PRED, // Vertical interpolation
- SMOOTH_H_PRED, // Horizontal interpolation
- PAETH_PRED, // Predict from the direction of smallest gradient
- NEARESTMV,
- NEARMV,
- GLOBALMV,
- NEWMV,
- // Compound ref compound modes
- NEAREST_NEARESTMV,
- NEAR_NEARMV,
- NEAREST_NEWMV,
- NEW_NEARESTMV,
- NEAR_NEWMV,
- NEW_NEARMV,
- GLOBAL_GLOBALMV,
- NEW_NEWMV,
- MB_MODE_COUNT,
- INTRA_MODE_START = DC_PRED,
- INTRA_MODE_END = NEARESTMV,
- INTRA_MODE_NUM = INTRA_MODE_END - INTRA_MODE_START,
- SINGLE_INTER_MODE_START = NEARESTMV,
- SINGLE_INTER_MODE_END = NEAREST_NEARESTMV,
- SINGLE_INTER_MODE_NUM = SINGLE_INTER_MODE_END - SINGLE_INTER_MODE_START,
- COMP_INTER_MODE_START = NEAREST_NEARESTMV,
- COMP_INTER_MODE_END = MB_MODE_COUNT,
- COMP_INTER_MODE_NUM = COMP_INTER_MODE_END - COMP_INTER_MODE_START,
- INTER_MODE_START = NEARESTMV,
- INTER_MODE_END = MB_MODE_COUNT,
- INTRA_MODES = PAETH_PRED + 1, // PAETH_PRED has to be the last intra mode.
- INTRA_INVALID = MB_MODE_COUNT // For uv_mode in inter blocks
-} UENUM1BYTE(PREDICTION_MODE);
-
-// TODO(ltrudeau) Do we really want to pack this?
-// TODO(ltrudeau) Do we match with PREDICTION_MODE?
-TYPEDEF enum {
- UV_DC_PRED, // Average of above and left pixels
- UV_V_PRED, // Vertical
- UV_H_PRED, // Horizontal
- UV_D45_PRED, // Directional 45 degree
- UV_D135_PRED, // Directional 135 degree
- UV_D113_PRED, // Directional 113 degree
- UV_D157_PRED, // Directional 157 degree
- UV_D203_PRED, // Directional 203 degree
- UV_D67_PRED, // Directional 67 degree
- UV_SMOOTH_PRED, // Combination of horizontal and vertical interpolation
- UV_SMOOTH_V_PRED, // Vertical interpolation
- UV_SMOOTH_H_PRED, // Horizontal interpolation
- UV_PAETH_PRED, // Predict from the direction of smallest gradient
- UV_CFL_PRED, // Chroma-from-Luma
- UV_INTRA_MODES,
- UV_MODE_INVALID, // For uv_mode in inter blocks
-} UENUM1BYTE(UV_PREDICTION_MODE);
-
-TYPEDEF enum {
- SIMPLE_TRANSLATION,
- OBMC_CAUSAL, // 2-sided OBMC
- WARPED_CAUSAL, // 2-sided WARPED
- MOTION_MODES
-} UENUM1BYTE(MOTION_MODE);
-
-TYPEDEF enum {
- II_DC_PRED,
- II_V_PRED,
- II_H_PRED,
- II_SMOOTH_PRED,
- INTERINTRA_MODES
-} UENUM1BYTE(INTERINTRA_MODE);
-
-TYPEDEF enum {
- COMPOUND_AVERAGE,
- COMPOUND_DISTWTD,
- COMPOUND_WEDGE,
- COMPOUND_DIFFWTD,
- COMPOUND_TYPES,
- MASKED_COMPOUND_TYPES = 2,
-} UENUM1BYTE(COMPOUND_TYPE);
-
-TYPEDEF enum {
- FILTER_DC_PRED,
- FILTER_V_PRED,
- FILTER_H_PRED,
- FILTER_D157_PRED,
- FILTER_PAETH_PRED,
- FILTER_INTRA_MODES,
-} UENUM1BYTE(FILTER_INTRA_MODE);
-
-TYPEDEF enum {
- SEQ_LEVEL_2_0,
- SEQ_LEVEL_2_1,
- SEQ_LEVEL_2_2,
- SEQ_LEVEL_2_3,
- SEQ_LEVEL_3_0,
- SEQ_LEVEL_3_1,
- SEQ_LEVEL_3_2,
- SEQ_LEVEL_3_3,
- SEQ_LEVEL_4_0,
- SEQ_LEVEL_4_1,
- SEQ_LEVEL_4_2,
- SEQ_LEVEL_4_3,
- SEQ_LEVEL_5_0,
- SEQ_LEVEL_5_1,
- SEQ_LEVEL_5_2,
- SEQ_LEVEL_5_3,
- SEQ_LEVEL_6_0,
- SEQ_LEVEL_6_1,
- SEQ_LEVEL_6_2,
- SEQ_LEVEL_6_3,
- SEQ_LEVEL_7_0,
- SEQ_LEVEL_7_1,
- SEQ_LEVEL_7_2,
- SEQ_LEVEL_7_3,
- SEQ_LEVELS,
- SEQ_LEVEL_MAX = 31
-} UENUM1BYTE(AV1_LEVEL);
-
-#define LEVEL_BITS 5
-
-#define DIRECTIONAL_MODES 8
-#define MAX_ANGLE_DELTA 3
-#define ANGLE_STEP 3
-
-#define INTER_MODES (1 + NEWMV - NEARESTMV)
-
-#define INTER_COMPOUND_MODES (1 + NEW_NEWMV - NEAREST_NEARESTMV)
-
-#define SKIP_CONTEXTS 3
-#define SKIP_MODE_CONTEXTS 3
-
-#define COMP_INDEX_CONTEXTS 6
-#define COMP_GROUP_IDX_CONTEXTS 6
-
-#define NMV_CONTEXTS 3
-
-#define NEWMV_MODE_CONTEXTS 6
-#define GLOBALMV_MODE_CONTEXTS 2
-#define REFMV_MODE_CONTEXTS 6
-#define DRL_MODE_CONTEXTS 3
-
-#define GLOBALMV_OFFSET 3
-#define REFMV_OFFSET 4
-
-#define NEWMV_CTX_MASK ((1 << GLOBALMV_OFFSET) - 1)
-#define GLOBALMV_CTX_MASK ((1 << (REFMV_OFFSET - GLOBALMV_OFFSET)) - 1)
-#define REFMV_CTX_MASK ((1 << (8 - REFMV_OFFSET)) - 1)
-
-#define COMP_NEWMV_CTXS 5
-#define INTER_MODE_CONTEXTS 8
-
-#define DELTA_Q_SMALL 3
-#define DELTA_Q_PROBS (DELTA_Q_SMALL)
-#define DEFAULT_DELTA_Q_RES_PERCEPTUAL 4
-#define DEFAULT_DELTA_Q_RES_OBJECTIVE 4
-
-#define DELTA_LF_SMALL 3
-#define DELTA_LF_PROBS (DELTA_LF_SMALL)
-#define DEFAULT_DELTA_LF_RES 2
-
-/* Segment Feature Masks */
-#define MAX_MV_REF_CANDIDATES 2
-
-#define MAX_REF_MV_STACK_SIZE 8
-#define REF_CAT_LEVEL 640
-
-#define INTRA_INTER_CONTEXTS 4
-#define COMP_INTER_CONTEXTS 5
-#define REF_CONTEXTS 3
-
-#define COMP_REF_TYPE_CONTEXTS 5
-#define UNI_COMP_REF_CONTEXTS 3
-
-#define TXFM_PARTITION_CONTEXTS ((TX_SIZES - TX_8X8) * 6 - 3)
-#ifdef ORI_CODE
-typedef uint8_t TXFM_CONTEXT;
-#endif
-// An enum for single reference types (and some derived values).
-enum {
- NONE_FRAME = -1,
- INTRA_FRAME,
- LAST_FRAME,
- LAST2_FRAME,
- LAST3_FRAME,
- GOLDEN_FRAME,
- BWDREF_FRAME,
- ALTREF2_FRAME,
- ALTREF_FRAME,
- REF_FRAMES,
-
- // Extra/scratch reference frame. It may be:
- // - used to update the ALTREF2_FRAME ref (see lshift_bwd_ref_frames()), or
- // - updated from ALTREF2_FRAME ref (see rshift_bwd_ref_frames()).
- EXTREF_FRAME = REF_FRAMES,
-
- // Number of inter (non-intra) reference types.
- INTER_REFS_PER_FRAME = ALTREF_FRAME - LAST_FRAME + 1,
-
- // Number of forward (aka past) reference types.
- FWD_REFS = GOLDEN_FRAME - LAST_FRAME + 1,
-
- // Number of backward (aka future) reference types.
- BWD_REFS = ALTREF_FRAME - BWDREF_FRAME + 1,
-
- SINGLE_REFS = FWD_REFS + BWD_REFS,
-};
-
-#define REF_FRAMES_LOG2 3
-
-// REF_FRAMES for the cm->ref_frame_map array, 1 scratch frame for the new
-// frame in cm->cur_frame, INTER_REFS_PER_FRAME for scaled references on the
-// encoder in the cpi->scaled_ref_buf array.
-#define FRAME_BUFFERS (REF_FRAMES + 1 + INTER_REFS_PER_FRAME)
-
-#define FWD_RF_OFFSET(ref) (ref - LAST_FRAME)
-#define BWD_RF_OFFSET(ref) (ref - BWDREF_FRAME)
-
-TYPEDEF enum {
- LAST_LAST2_FRAMES, // { LAST_FRAME, LAST2_FRAME }
- LAST_LAST3_FRAMES, // { LAST_FRAME, LAST3_FRAME }
- LAST_GOLDEN_FRAMES, // { LAST_FRAME, GOLDEN_FRAME }
- BWDREF_ALTREF_FRAMES, // { BWDREF_FRAME, ALTREF_FRAME }
- LAST2_LAST3_FRAMES, // { LAST2_FRAME, LAST3_FRAME }
- LAST2_GOLDEN_FRAMES, // { LAST2_FRAME, GOLDEN_FRAME }
- LAST3_GOLDEN_FRAMES, // { LAST3_FRAME, GOLDEN_FRAME }
- BWDREF_ALTREF2_FRAMES, // { BWDREF_FRAME, ALTREF2_FRAME }
- ALTREF2_ALTREF_FRAMES, // { ALTREF2_FRAME, ALTREF_FRAME }
- TOTAL_UNIDIR_COMP_REFS,
- // NOTE: UNIDIR_COMP_REFS is the number of uni-directional reference pairs
- // that are explicitly signaled.
- UNIDIR_COMP_REFS = BWDREF_ALTREF_FRAMES + 1,
-} UENUM1BYTE(UNIDIR_COMP_REF);
-
-#define TOTAL_COMP_REFS (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)
-
-#define COMP_REFS (FWD_REFS * BWD_REFS + UNIDIR_COMP_REFS)
-
-// NOTE: A limited number of unidirectional reference pairs can be signalled for
-// compound prediction. The use of skip mode, on the other hand, makes it
-// possible to have a reference pair not listed for explicit signaling.
-#define MODE_CTX_REF_FRAMES (REF_FRAMES + TOTAL_COMP_REFS)
-
-// Note: It includes single and compound references. So, it can take values from
-// NONE_FRAME to (MODE_CTX_REF_FRAMES - 1). Hence, it is not defined as an enum.
-typedef int8_t MV_REFERENCE_FRAME;
-
-TYPEDEF enum {
- RESTORE_NONE,
- RESTORE_WIENER,
- RESTORE_SGRPROJ,
- RESTORE_SWITCHABLE,
- RESTORE_SWITCHABLE_TYPES = RESTORE_SWITCHABLE,
- RESTORE_TYPES = 4,
-} UENUM1BYTE(RestorationType);
-
-// Picture prediction structures (0-12 are predefined) in scalability metadata.
-TYPEDEF enum {
- SCALABILITY_L1T2 = 0,
- SCALABILITY_L1T3 = 1,
- SCALABILITY_L2T1 = 2,
- SCALABILITY_L2T2 = 3,
- SCALABILITY_L2T3 = 4,
- SCALABILITY_S2T1 = 5,
- SCALABILITY_S2T2 = 6,
- SCALABILITY_S2T3 = 7,
- SCALABILITY_L2T1h = 8,
- SCALABILITY_L2T2h = 9,
- SCALABILITY_L2T3h = 10,
- SCALABILITY_S2T1h = 11,
- SCALABILITY_S2T2h = 12,
- SCALABILITY_S2T3h = 13,
- SCALABILITY_SS = 14
-} UENUM1BYTE(SCALABILITY_STRUCTURES);
-
-#define SUPERRES_SCALE_BITS 3
-#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)
-
-// In large_scale_tile coding, external references are used.
-#define MAX_EXTERNAL_REFERENCES 128
-#define MAX_TILES 512
-
-
-#define CONFIG_MULTITHREAD 0
-#define CONFIG_ENTROPY_STATS 0
-
-#define CONFIG_MAX_DECODE_PROFILE 2
-
-/*
-from:
-seg_common.h
-*/
-#ifdef ORI_CODE
-
-#define MAX_SEGMENTS 8
-#define SEG_TREE_PROBS (MAX_SEGMENTS - 1)
-
-#define SEG_TEMPORAL_PRED_CTXS 3
-#define SPATIAL_PREDICTION_PROBS 3
-
-enum {
- SEG_LVL_ALT_Q, // Use alternate Quantizer ....
- SEG_LVL_ALT_LF_Y_V, // Use alternate loop filter value on y plane vertical
- SEG_LVL_ALT_LF_Y_H, // Use alternate loop filter value on y plane horizontal
- SEG_LVL_ALT_LF_U, // Use alternate loop filter value on u plane
- SEG_LVL_ALT_LF_V, // Use alternate loop filter value on v plane
- SEG_LVL_REF_FRAME, // Optional Segment reference frame
- SEG_LVL_SKIP, // Optional Segment (0,0) + skip mode
- SEG_LVL_GLOBALMV,
- SEG_LVL_MAX
-} UENUM1BYTE(SEG_LVL_FEATURES);
-
-struct segmentation {
- uint8_t enabled;
- uint8_t update_map;
- uint8_t update_data;
- uint8_t temporal_update;
-
- int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX];
- unsigned int feature_mask[MAX_SEGMENTS];
- int last_active_segid; // The highest numbered segment id that has some
- // enabled feature.
- uint8_t segid_preskip; // Whether the segment id will be read before the
- // skip syntax element.
- // 1: the segment id will be read first.
- // 0: the skip syntax element will be read first.
-};
-
-/*
-from av1_loopfilter.h
-*/
-#define MAX_LOOP_FILTER 63
-
-
-/* from
-quant_common.h:
-*/
-#define MAXQ 255
-
-#endif
-
-/*
-from:
-aom/av1/common/common.h
-*/
-#define av1_zero(dest) memset(&(dest), 0, sizeof(dest))
-#define av1_zero_array(dest, n) memset(dest, 0, n * sizeof(*(dest)))
-/*
-from:
-aom/av1/common/alloccommon.h
-*/
-#define INVALID_IDX -1 // Invalid buffer index.
-
-/*
-from:
-aom/av1/common/timing.h
-*/
-typedef struct aom_timing {
- uint32_t num_units_in_display_tick;
- uint32_t time_scale;
- int equal_picture_interval;
- uint32_t num_ticks_per_picture;
-} aom_timing_info_t;
-
-typedef struct aom_dec_model_info {
- uint32_t num_units_in_decoding_tick;
- int encoder_decoder_buffer_delay_length;
- int buffer_removal_time_length;
- int frame_presentation_time_length;
-} aom_dec_model_info_t;
-
-typedef struct aom_dec_model_op_parameters {
- int decoder_model_param_present_flag;
- int64_t bitrate;
- int64_t buffer_size;
- uint32_t decoder_buffer_delay;
- uint32_t encoder_buffer_delay;
- int low_delay_mode_flag;
- int display_model_param_present_flag;
- int initial_display_delay;
-} aom_dec_model_op_parameters_t;
-
-typedef struct aom_op_timing_info_t {
- uint32_t buffer_removal_time;
-} aom_op_timing_info_t;
-/*
-from:
-aom/aom_codec.h
-*/
-/*!\brief OBU types. */
-typedef enum {
- OBU_SEQUENCE_HEADER = 1,
- OBU_TEMPORAL_DELIMITER = 2,
- OBU_FRAME_HEADER = 3,
- OBU_TILE_GROUP = 4,
- OBU_METADATA = 5,
- OBU_FRAME = 6,
- OBU_REDUNDANT_FRAME_HEADER = 7,
- OBU_TILE_LIST = 8,
- OBU_PADDING = 15,
-} OBU_TYPE;
-
-typedef enum aom_bit_depth {
- AOM_BITS_8 = 8, /**< 8 bits */
- AOM_BITS_10 = 10, /**< 10 bits */
- AOM_BITS_12 = 12, /**< 12 bits */
-} aom_bit_depth_t;
-
-/*!\brief Algorithm return codes */
-typedef enum {
- /*!\brief Operation completed without error */
- AOM_CODEC_OK,
-
- /*!\brief Unspecified error */
- AOM_CODEC_ERROR,
-
- /*!\brief Memory operation failed */
- AOM_CODEC_MEM_ERROR,
-
- /*!\brief ABI version mismatch */
- AOM_CODEC_ABI_MISMATCH,
-
- /*!\brief Algorithm does not have required capability */
- AOM_CODEC_INCAPABLE,
-
- /*!\brief The given bitstream is not supported.
- *
- * The bitstream was unable to be parsed at the highest level. The decoder
- * is unable to proceed. This error \ref SHOULD be treated as fatal to the
- * stream. */
- AOM_CODEC_UNSUP_BITSTREAM,
-
- /*!\brief Encoded bitstream uses an unsupported feature
- *
- * The decoder does not implement a feature required by the encoder. This
- * return code should only be used for features that prevent future
- * pictures from being properly decoded. This error \ref MAY be treated as
- * fatal to the stream or \ref MAY be treated as fatal to the current GOP.
- */
- AOM_CODEC_UNSUP_FEATURE,
-
- /*!\brief The coded data for this stream is corrupt or incomplete
- *
- * There was a problem decoding the current frame. This return code
- * should only be used for failures that prevent future pictures from
- * being properly decoded. This error \ref MAY be treated as fatal to the
- * stream or \ref MAY be treated as fatal to the current GOP. If decoding
- * is continued for the current GOP, artifacts may be present.
- */
- AOM_CODEC_CORRUPT_FRAME,
-
- /*!\brief An application-supplied parameter is not valid.
- *
- */
- AOM_CODEC_INVALID_PARAM,
-
- /*!\brief An iterator reached the end of list.
- *
- */
- AOM_CODEC_LIST_END
-
-} aom_codec_err_t;
-
-typedef struct cfg_options {
- /*!\brief Reflects if ext_partition should be enabled
- *
- * If this value is non-zero it enabled the feature
- */
- unsigned int ext_partition;
-} cfg_options_t;
-
-/*
-from:
-aom/av1/common/obu_util.h
-*/
-typedef struct {
- size_t size; // Size (1 or 2 bytes) of the OBU header (including the
- // optional OBU extension header) in the bitstream.
- OBU_TYPE type;
- int has_size_field;
- int has_extension;
- // The following fields come from the OBU extension header and therefore are
- // only used if has_extension is true.
- int temporal_layer_id;
- int spatial_layer_id;
-} ObuHeader;
-
-
-/*
-from:
-aom/internal/aom_codec_internal.h
-*/
-
-struct aom_internal_error_info {
- aom_codec_err_t error_code;
- int has_detail;
- char detail[80];
- int setjmp; // Boolean: whether 'jmp' is valid.
-#ifdef ORI_CODE
- jmp_buf jmp;
-#endif
-};
-
-/*
-from:
-aom/aom_frame_buffer.h
-*/
-typedef struct aom_codec_frame_buffer {
- uint8_t *data; /**< Pointer to the data buffer */
- size_t size; /**< Size of data in bytes */
- void *priv; /**< Frame's private data */
-} aom_codec_frame_buffer_t;
-
-/*
-from:
-aom/aom_image.h
-*/
-#define AOM_IMAGE_ABI_VERSION (5) /**<\hideinitializer*/
-
-#define AOM_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
-#define AOM_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
-/** 0x400 used to signal alpha channel, skipping for backwards compatibility. */
-#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
-
-/*!\brief List of supported image formats */
-typedef enum aom_img_fmt {
- AOM_IMG_FMT_NONE,
- AOM_IMG_FMT_YV12 =
- AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
- AOM_IMG_FMT_I420 = AOM_IMG_FMT_PLANAR | 2,
- AOM_IMG_FMT_AOMYV12 = AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP |
- 3, /** < planar 4:2:0 format with aom color space */
- AOM_IMG_FMT_AOMI420 = AOM_IMG_FMT_PLANAR | 4,
- AOM_IMG_FMT_I422 = AOM_IMG_FMT_PLANAR | 5,
- AOM_IMG_FMT_I444 = AOM_IMG_FMT_PLANAR | 6,
- AOM_IMG_FMT_I42016 = AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH,
- AOM_IMG_FMT_YV1216 = AOM_IMG_FMT_YV12 | AOM_IMG_FMT_HIGHBITDEPTH,
- AOM_IMG_FMT_I42216 = AOM_IMG_FMT_I422 | AOM_IMG_FMT_HIGHBITDEPTH,
- AOM_IMG_FMT_I44416 = AOM_IMG_FMT_I444 | AOM_IMG_FMT_HIGHBITDEPTH,
-} aom_img_fmt_t; /**< alias for enum aom_img_fmt */
-
-/*!\brief List of supported color primaries */
-typedef enum aom_color_primaries {
- AOM_CICP_CP_RESERVED_0 = 0, /**< For future use */
- AOM_CICP_CP_BT_709 = 1, /**< BT.709 */
- AOM_CICP_CP_UNSPECIFIED = 2, /**< Unspecified */
- AOM_CICP_CP_RESERVED_3 = 3, /**< For future use */
- AOM_CICP_CP_BT_470_M = 4, /**< BT.470 System M (historical) */
- AOM_CICP_CP_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
- AOM_CICP_CP_BT_601 = 6, /**< BT.601 */
- AOM_CICP_CP_SMPTE_240 = 7, /**< SMPTE 240 */
- AOM_CICP_CP_GENERIC_FILM =
- 8, /**< Generic film (color filters using illuminant C) */
- AOM_CICP_CP_BT_2020 = 9, /**< BT.2020, BT.2100 */
- AOM_CICP_CP_XYZ = 10, /**< SMPTE 428 (CIE 1921 XYZ) */
- AOM_CICP_CP_SMPTE_431 = 11, /**< SMPTE RP 431-2 */
- AOM_CICP_CP_SMPTE_432 = 12, /**< SMPTE EG 432-1 */
- AOM_CICP_CP_RESERVED_13 = 13, /**< For future use (values 13 - 21) */
- AOM_CICP_CP_EBU_3213 = 22, /**< EBU Tech. 3213-E */
- AOM_CICP_CP_RESERVED_23 = 23 /**< For future use (values 23 - 255) */
-} aom_color_primaries_t; /**< alias for enum aom_color_primaries */
-
-/*!\brief List of supported transfer functions */
-typedef enum aom_transfer_characteristics {
- AOM_CICP_TC_RESERVED_0 = 0, /**< For future use */
- AOM_CICP_TC_BT_709 = 1, /**< BT.709 */
- AOM_CICP_TC_UNSPECIFIED = 2, /**< Unspecified */
- AOM_CICP_TC_RESERVED_3 = 3, /**< For future use */
- AOM_CICP_TC_BT_470_M = 4, /**< BT.470 System M (historical) */
- AOM_CICP_TC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
- AOM_CICP_TC_BT_601 = 6, /**< BT.601 */
- AOM_CICP_TC_SMPTE_240 = 7, /**< SMPTE 240 M */
- AOM_CICP_TC_LINEAR = 8, /**< Linear */
- AOM_CICP_TC_LOG_100 = 9, /**< Logarithmic (100 : 1 range) */
- AOM_CICP_TC_LOG_100_SQRT10 =
- 10, /**< Logarithmic (100 * Sqrt(10) : 1 range) */
- AOM_CICP_TC_IEC_61966 = 11, /**< IEC 61966-2-4 */
- AOM_CICP_TC_BT_1361 = 12, /**< BT.1361 */
- AOM_CICP_TC_SRGB = 13, /**< sRGB or sYCC*/
- AOM_CICP_TC_BT_2020_10_BIT = 14, /**< BT.2020 10-bit systems */
- AOM_CICP_TC_BT_2020_12_BIT = 15, /**< BT.2020 12-bit systems */
- AOM_CICP_TC_SMPTE_2084 = 16, /**< SMPTE ST 2084, ITU BT.2100 PQ */
- AOM_CICP_TC_SMPTE_428 = 17, /**< SMPTE ST 428 */
- AOM_CICP_TC_HLG = 18, /**< BT.2100 HLG, ARIB STD-B67 */
- AOM_CICP_TC_RESERVED_19 = 19 /**< For future use (values 19-255) */
-} aom_transfer_characteristics_t; /**< alias for enum aom_transfer_function */
-
-/*!\brief List of supported matrix coefficients */
-typedef enum aom_matrix_coefficients {
- AOM_CICP_MC_IDENTITY = 0, /**< Identity matrix */
- AOM_CICP_MC_BT_709 = 1, /**< BT.709 */
- AOM_CICP_MC_UNSPECIFIED = 2, /**< Unspecified */
- AOM_CICP_MC_RESERVED_3 = 3, /**< For future use */
- AOM_CICP_MC_FCC = 4, /**< US FCC 73.628 */
- AOM_CICP_MC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
- AOM_CICP_MC_BT_601 = 6, /**< BT.601 */
- AOM_CICP_MC_SMPTE_240 = 7, /**< SMPTE 240 M */
- AOM_CICP_MC_SMPTE_YCGCO = 8, /**< YCgCo */
- AOM_CICP_MC_BT_2020_NCL =
- 9, /**< BT.2020 non-constant luminance, BT.2100 YCbCr */
- AOM_CICP_MC_BT_2020_CL = 10, /**< BT.2020 constant luminance */
- AOM_CICP_MC_SMPTE_2085 = 11, /**< SMPTE ST 2085 YDzDx */
- AOM_CICP_MC_CHROMAT_NCL =
- 12, /**< Chromaticity-derived non-constant luminance */
- AOM_CICP_MC_CHROMAT_CL = 13, /**< Chromaticity-derived constant luminance */
- AOM_CICP_MC_ICTCP = 14, /**< BT.2100 ICtCp */
- AOM_CICP_MC_RESERVED_15 = 15 /**< For future use (values 15-255) */
-} aom_matrix_coefficients_t;
-
-/*!\brief List of supported color range */
-typedef enum aom_color_range {
- AOM_CR_STUDIO_RANGE = 0, /**< Y [16..235], UV [16..240] */
- AOM_CR_FULL_RANGE = 1 /**< YUV/RGB [0..255] */
-} aom_color_range_t; /**< alias for enum aom_color_range */
-
-/*!\brief List of chroma sample positions */
-typedef enum aom_chroma_sample_position {
- AOM_CSP_UNKNOWN = 0, /**< Unknown */
- AOM_CSP_VERTICAL = 1, /**< Horizontally co-located with luma(0, 0)*/
- /**< sample, between two vertical samples */
- AOM_CSP_COLOCATED = 2, /**< Co-located with luma(0, 0) sample */
- AOM_CSP_RESERVED = 3 /**< Reserved value */
-} aom_chroma_sample_position_t; /**< alias for enum aom_transfer_function */
-
-/*
-from:
-aom/aom_scale/yv12config.h
-*/
-typedef struct PIC_BUFFER_CONFIG_s {
- union {
- struct {
- int y_width;
- int uv_width;
- };
- int widths[2];
- };
- union {
- struct {
- int y_height;
- int uv_height;
- };
- int heights[2];
- };
- union {
- struct {
- int y_crop_width;
- int uv_crop_width;
- };
- int crop_widths[2];
- };
- union {
- struct {
- int y_crop_height;
- int uv_crop_height;
- };
- int crop_heights[2];
- };
- union {
- struct {
- int y_stride;
- int uv_stride;
- };
- int strides[2];
- };
- union {
- struct {
- uint8_t *y_buffer;
- uint8_t *u_buffer;
- uint8_t *v_buffer;
- };
- uint8_t *buffers[3];
- };
-
- // Indicate whether y_buffer, u_buffer, and v_buffer points to the internally
- // allocated memory or external buffers.
- int use_external_reference_buffers;
- // This is needed to store y_buffer, u_buffer, and v_buffer when set reference
- // uses an external refernece, and restore those buffer pointers after the
- // external reference frame is no longer used.
- uint8_t *store_buf_adr[3];
-
- // If the frame is stored in a 16-bit buffer, this stores an 8-bit version
- // for use in global motion detection. It is allocated on-demand.
- uint8_t *y_buffer_8bit;
- int buf_8bit_valid;
-
- uint8_t *buffer_alloc;
- size_t buffer_alloc_sz;
- int border;
- size_t frame_size;
- int subsampling_x;
- int subsampling_y;
- unsigned int bit_depth;
- aom_color_primaries_t color_primaries;
- aom_transfer_characteristics_t transfer_characteristics;
- aom_matrix_coefficients_t matrix_coefficients;
- uint8_t monochrome;
- aom_chroma_sample_position_t chroma_sample_position;
- aom_color_range_t color_range;
- int render_width;
- int render_height;
-
- int corrupted;
- int flags;
-
-#ifdef AML
- int32_t index;
- int32_t decode_idx;
- int32_t slice_type;
- int32_t RefNum_L0;
- int32_t RefNum_L1;
- int32_t num_reorder_pic;
- int32_t stream_offset;
- uint8_t referenced;
- uint8_t output_mark;
- uint8_t recon_mark;
- uint8_t output_ready;
- uint8_t error_mark;
- /**/
- int32_t slice_idx;
- /*buffer*/
- uint32_t fgs_table_adr;
- uint32_t sfgs_table_phy;
- char *sfgs_table_ptr;
-#ifdef AOM_AV1_MMU
- uint32_t header_adr;
-#endif
-#ifdef AOM_AV1_MMU_DW
- uint32_t header_dw_adr;
-#endif
- uint32_t mpred_mv_wr_start_addr;
- uint32_t mc_y_adr;
- uint32_t mc_u_v_adr;
- int32_t mc_canvas_y;
- int32_t mc_canvas_u_v;
-
- int32_t lcu_total;
- /**/
- unsigned int order_hint;
-#endif
-#ifdef AML_DEVICE
- int mv_buf_index;
- unsigned long cma_alloc_addr;
- int BUF_index;
- int buf_size;
- int comp_body_size;
- unsigned int dw_y_adr;
- unsigned int dw_u_v_adr;
- int double_write_mode;
- int y_canvas_index;
- int uv_canvas_index;
- int vf_ref;
- struct canvas_config_s canvas_config[2];
- char *aux_data_buf;
- int aux_data_size;
- u32 pts;
- u64 pts64;
- /* picture qos infomation*/
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
-#endif
- u64 timestamp;
- u32 hw_decode_time;
- u32 frame_size2; // For frame base mode
- int ctx_buf_idx;
- int v4l_buf_index;
- int repeat_count;
- struct PIC_BUFFER_CONFIG_s *repeat_pic;
-} PIC_BUFFER_CONFIG;
-
-/*
-from:
-common/blockd.h
-*/
-TYPEDEF enum {
- KEY_FRAME = 0,
- INTER_FRAME = 1,
- INTRA_ONLY_FRAME = 2, // replaces intra-only
- S_FRAME = 3,
- FRAME_TYPES,
-} UENUM1BYTE(FRAME_TYPE);
-
-/*from:
-mv.h
-*/
-#ifdef ORI_CODE
-typedef struct mv32 {
- int32_t row;
- int32_t col;
-} MV32;
-#endif
-/*from:
- aom_filter.h
-*/
-#define SUBPEL_BITS 4
-#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1)
-#define SUBPEL_SHIFTS (1 << SUBPEL_BITS)
-#define SUBPEL_TAPS 8
-
-#define SCALE_SUBPEL_BITS 10
-#define SCALE_SUBPEL_SHIFTS (1 << SCALE_SUBPEL_BITS)
-#define SCALE_SUBPEL_MASK (SCALE_SUBPEL_SHIFTS - 1)
-#define SCALE_EXTRA_BITS (SCALE_SUBPEL_BITS - SUBPEL_BITS)
-#define SCALE_EXTRA_OFF ((1 << SCALE_EXTRA_BITS) / 2)
-
-#define RS_SUBPEL_BITS 6
-#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1)
-#define RS_SCALE_SUBPEL_BITS 14
-#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1)
-#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS)
-#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1))
-
-/*from:
-scale.h
-*/
-#define SCALE_NUMERATOR 8
-
-#define REF_SCALE_SHIFT 14
-#define REF_NO_SCALE (1 << REF_SCALE_SHIFT)
-#define REF_INVALID_SCALE -1
-
-struct scale_factors {
- int x_scale_fp; // horizontal fixed point scale factor
- int y_scale_fp; // vertical fixed point scale factor
- int x_step_q4;
- int y_step_q4;
-
- int (*scale_value_x)(int val, const struct scale_factors *sf);
- int (*scale_value_y)(int val, const struct scale_factors *sf);
-#ifdef ORI_CODE
- // convolve_fn_ptr[subpel_x != 0][subpel_y != 0][is_compound]
- aom_convolve_fn_t convolve[2][2][2];
- aom_highbd_convolve_fn_t highbd_convolve[2][2][2];
-#endif
-};
-
-#ifdef ORI_CODE
-MV32 av1_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf);
-#endif
-void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
- int other_h, int this_w, int this_h);
-
-static inline int av1_is_valid_scale(const struct scale_factors *sf) {
-#ifdef ORI_CODE
- assert(sf != NULL);
-#endif
- return sf->x_scale_fp != REF_INVALID_SCALE &&
- sf->y_scale_fp != REF_INVALID_SCALE;
-}
-
-static inline int av1_is_scaled(const struct scale_factors *sf) {
-#ifdef ORI_CODE
- assert(sf != NULL);
-#endif
- return av1_is_valid_scale(sf) &&
- (sf->x_scale_fp != REF_NO_SCALE || sf->y_scale_fp != REF_NO_SCALE);
-}
-
-
-/*
-from:
-common/onyxc_int.h
-*/
-
-#define CDEF_MAX_STRENGTHS 16
-
-/* Constant values while waiting for the sequence header */
-#define FRAME_ID_LENGTH 15
-#define DELTA_FRAME_ID_LENGTH 14
-
-#define FRAME_CONTEXTS (FRAME_BUFFERS + 1)
-// Extra frame context which is always kept at default values
-#define FRAME_CONTEXT_DEFAULTS (FRAME_CONTEXTS - 1)
-#define PRIMARY_REF_BITS 3
-#define PRIMARY_REF_NONE 7
-
-#define NUM_PING_PONG_BUFFERS 2
-
-#define MAX_NUM_TEMPORAL_LAYERS 8
-#define MAX_NUM_SPATIAL_LAYERS 4
-/* clang-format off */
-// clang-format seems to think this is a pointer dereference and not a
-// multiplication.
-#define MAX_NUM_OPERATING_POINTS \
- MAX_NUM_TEMPORAL_LAYERS * MAX_NUM_SPATIAL_LAYERS
-/* clang-format on*/
-
-// TODO(jingning): Turning this on to set up transform coefficient
-// processing timer.
-#define TXCOEFF_TIMER 0
-#define TXCOEFF_COST_TIMER 0
-
-TYPEDEF enum {
- SINGLE_REFERENCE = 0,
- COMPOUND_REFERENCE = 1,
- REFERENCE_MODE_SELECT = 2,
- REFERENCE_MODES = 3,
-} UENUM1BYTE(REFERENCE_MODE);
-
-TYPEDEF enum {
- /**
- * Frame context updates are disabled
- */
- REFRESH_FRAME_CONTEXT_DISABLED,
- /**
- * Update frame context to values resulting from backward probability
- * updates based on entropy/counts in the decoded frame
- */
- REFRESH_FRAME_CONTEXT_BACKWARD,
-} UENUM1BYTE(REFRESH_FRAME_CONTEXT_MODE);
-
-#define MFMV_STACK_SIZE 3
-
-#ifdef AML
-#define MV_REF_SIZE 8
-#endif
-
-#ifdef ORI_CODE
-typedef struct {
- int_mv mfmv0;
- uint8_t ref_frame_offset;
-} TPL_MV_REF;
-typedef struct {
- int_mv mv;
- MV_REFERENCE_FRAME ref_frame;
-} MV_REF;
-#endif
-
-typedef struct RefCntBuffer_s {
- // For a RefCntBuffer, the following are reference-holding variables:
- // - cm->ref_frame_map[]
- // - cm->cur_frame
- // - cm->scaled_ref_buf[] (encoder only)
- // - cm->next_ref_frame_map[] (decoder only)
- // - pbi->output_frame_index[] (decoder only)
- // With that definition, 'ref_count' is the number of reference-holding
- // variables that are currently referencing this buffer.
- // For example:
- // - suppose this buffer is at index 'k' in the buffer pool, and
- // - Total 'n' of the variables / array elements above have value 'k' (that
- // is, they are pointing to buffer at index 'k').
- // Then, pool->frame_bufs[k].ref_count = n.
- int ref_count;
-
- unsigned int order_hint;
- unsigned int ref_order_hints[INTER_REFS_PER_FRAME];
-
- int intra_only;
- int segmentation_enabled;
- unsigned int segment_feature[8];
-#ifdef AML
- int segmentation_update_map;
- int prev_segmentation_enabled;
- int seg_mi_rows;
- int seg_mi_cols;
-
- unsigned int seg_lf_info_y[8];
- unsigned int seg_lf_info_c[8];
- int8_t ref_deltas[REF_FRAMES];
- int8_t mode_deltas[MAX_MODE_LF_DELTAS];
-#endif
- //MV_REF *mvs;
- uint8_t *seg_map;
-#ifdef ORI_CODE
- struct segmentation seg;
-#endif
-
- int mi_rows;
- int mi_cols;
- // Width and height give the size of the buffer (before any upscaling, unlike
- // the sizes that can be derived from the buf structure)
- int width;
- int height;
-#ifdef ORI_CODE
- WarpedMotionParams global_motion[REF_FRAMES];
-#endif
- int showable_frame; // frame can be used as show existing frame in future
- uint8_t film_grain_params_present;
-#ifdef ORI_CODE
- aom_film_grain_t film_grain_params;
-#endif
-#ifdef AML
- int dec_width;
- uint8_t film_grain_reg_valid;
- wait_queue_head_t wait_sfgs;
- atomic_t fgs_done;
- uint32_t film_grain_reg[FILM_GRAIN_REG_SIZE];
- uint32_t film_grain_ctrl;
-#endif
- aom_codec_frame_buffer_t raw_frame_buffer;
- PIC_BUFFER_CONFIG buf;
-#ifdef ORI_CODE
- hash_table hash_table;
-#endif
- FRAME_TYPE frame_type;
-
- // This is only used in the encoder but needs to be indexed per ref frame
- // so it's extremely convenient to keep it here.
-#ifdef ORI_CODE
- int interp_filter_selected[SWITCHABLE];
-#endif
- // Inter frame reference frame delta for loop filter
-#ifndef AML
- int8_t ref_deltas[REF_FRAMES];
-#endif
-#ifdef ORI_CODE
- // 0 = ZERO_MV, MV
- int8_t mode_deltas[MAX_MODE_LF_DELTAS];
-
- FRAME_CONTEXT frame_context;
-#endif
- int show_frame;
-} RefCntBuffer;
-
-typedef struct BufferPool_s {
-// Protect BufferPool from being accessed by several FrameWorkers at
-// the same time during frame parallel decode.
-// TODO(hkuang): Try to use atomic variable instead of locking the whole pool.
-// TODO(wtc): Remove this. See
-// https://chromium-review.googlesource.com/c/webm/libvpx/+/560630.
-#if CONFIG_MULTITHREAD
- pthread_mutex_t pool_mutex;
-#endif
-
- // Private data associated with the frame buffer callbacks.
- void *cb_priv;
-#ifdef ORI_CODE
- aom_get_frame_buffer_cb_fn_t get_fb_cb;
- aom_release_frame_buffer_cb_fn_t release_fb_cb;
-#endif
- RefCntBuffer frame_bufs[FRAME_BUFFERS];
-
-#ifdef ORI_CODE
- // Frame buffers allocated internally by the codec.
- InternalFrameBufferList int_frame_buffers;
-#endif
-#ifdef AML_DEVICE
- spinlock_t lock;
-#endif
-} BufferPool;
-
-typedef struct {
- int cdef_pri_damping;
- int cdef_sec_damping;
- int nb_cdef_strengths;
- int cdef_strengths[CDEF_MAX_STRENGTHS];
- int cdef_uv_strengths[CDEF_MAX_STRENGTHS];
- int cdef_bits;
-} CdefInfo;
-
-typedef struct {
- int delta_q_present_flag;
- // Resolution of delta quant
- int delta_q_res;
- int delta_lf_present_flag;
- // Resolution of delta lf level
- int delta_lf_res;
- // This is a flag for number of deltas of loop filter level
- // 0: use 1 delta, for y_vertical, y_horizontal, u, and v
- // 1: use separate deltas for each filter level
- int delta_lf_multi;
-} DeltaQInfo;
-
-typedef struct {
- int enable_order_hint; // 0 - disable order hint, and related tools
- int order_hint_bits_minus_1; // dist_wtd_comp, ref_frame_mvs,
- // frame_sign_bias
- // if 0, enable_dist_wtd_comp and
- // enable_ref_frame_mvs must be set as 0.
- int enable_dist_wtd_comp; // 0 - disable dist-wtd compound modes
- // 1 - enable it
- int enable_ref_frame_mvs; // 0 - disable ref frame mvs
- // 1 - enable it
-} OrderHintInfo;
-
-// Sequence header structure.
-// Note: All syntax elements of sequence_header_obu that need to be
-// bit-identical across multiple sequence headers must be part of this struct,
-// so that consistency is checked by are_seq_headers_consistent() function.
-typedef struct SequenceHeader {
- int num_bits_width;
- int num_bits_height;
- int max_frame_width;
- int max_frame_height;
- uint8_t frame_id_numbers_present_flag;
- int frame_id_length;
- int delta_frame_id_length;
- BLOCK_SIZE2 sb_size; // Size of the superblock used for this frame
- int mib_size; // Size of the superblock in units of MI blocks
- int mib_size_log2; // Log 2 of above.
-
- OrderHintInfo order_hint_info;
-
- uint8_t force_screen_content_tools; // 0 - force off
- // 1 - force on
- // 2 - adaptive
- uint8_t still_picture; // Video is a single frame still picture
- uint8_t reduced_still_picture_hdr; // Use reduced header for still picture
- uint8_t force_integer_mv; // 0 - Don't force. MV can use subpel
- // 1 - force to integer
- // 2 - adaptive
- uint8_t enable_filter_intra; // enables/disables filterintra
- uint8_t enable_intra_edge_filter; // enables/disables edge upsampling
- uint8_t enable_interintra_compound; // enables/disables interintra_compound
- uint8_t enable_masked_compound; // enables/disables masked compound
- uint8_t enable_dual_filter; // 0 - disable dual interpolation filter
- // 1 - enable vert/horz filter selection
- uint8_t enable_warped_motion; // 0 - disable warp for the sequence
- // 1 - enable warp for the sequence
- uint8_t enable_superres; // 0 - Disable superres for the sequence
- // and no frame level superres flag
- // 1 - Enable superres for the sequence
- // enable per-frame superres flag
- uint8_t enable_cdef; // To turn on/off CDEF
- uint8_t enable_restoration; // To turn on/off loop restoration
- BITSTREAM_PROFILE profile;
-
- // Operating point info.
- int operating_points_cnt_minus_1;
- int operating_point_idc[MAX_NUM_OPERATING_POINTS];
- uint8_t display_model_info_present_flag;
- uint8_t decoder_model_info_present_flag;
- AV1_LEVEL seq_level_idx[MAX_NUM_OPERATING_POINTS];
- uint8_t tier[MAX_NUM_OPERATING_POINTS]; // seq_tier in the spec. One bit: 0
- // or 1.
-
- // Color config.
- aom_bit_depth_t bit_depth; // AOM_BITS_8 in profile 0 or 1,
- // AOM_BITS_10 or AOM_BITS_12 in profile 2 or 3.
- uint8_t use_highbitdepth; // If true, we need to use 16bit frame buffers.
- uint8_t monochrome; // Monochorme video
- aom_color_primaries_t color_primaries;
- aom_transfer_characteristics_t transfer_characteristics;
- aom_matrix_coefficients_t matrix_coefficients;
- int color_range;
- int subsampling_x; // Chroma subsampling for x
- int subsampling_y; // Chroma subsampling for y
- aom_chroma_sample_position_t chroma_sample_position;
- uint8_t separate_uv_delta_q;
- uint8_t film_gry_dequant_QTXain_params_present;
-} SequenceHeader;
-
-typedef struct {
- int skip_mode_allowed;
- int skip_mode_flag;
- int ref_frame_idx_0;
- int ref_frame_idx_1;
-} SkipModeInfo;
-
-typedef struct {
- FRAME_TYPE frame_type;
- REFERENCE_MODE reference_mode;
-
- unsigned int order_hint;
- unsigned int frame_number;
- SkipModeInfo skip_mode_info;
- int refresh_frame_flags; // Which ref frames are overwritten by this frame
- int frame_refs_short_signaling;
-} CurrentFrame;
-
-typedef struct AV1_Common_s {
- CurrentFrame current_frame;
- struct aom_internal_error_info error;
- int width;
- int height;
- int render_width;
- int render_height;
- int timing_info_present;
- aom_timing_info_t timing_info;
- int buffer_removal_time_present;
- aom_dec_model_info_t buffer_model;
- aom_dec_model_op_parameters_t op_params[MAX_NUM_OPERATING_POINTS + 1];
- aom_op_timing_info_t op_frame_timing[MAX_NUM_OPERATING_POINTS + 1];
- uint32_t frame_presentation_time;
-
- int context_update_tile_id;
-#ifdef SUPPORT_SCALE_FACTOR
- // Scale of the current frame with respect to itself.
- struct scale_factors sf_identity;
-#endif
- RefCntBuffer *prev_frame;
-
- // TODO(hkuang): Combine this with cur_buf in macroblockd.
- RefCntBuffer *cur_frame;
-
- // For encoder, we have a two-level mapping from reference frame type to the
- // corresponding buffer in the buffer pool:
- // * 'remapped_ref_idx[i - 1]' maps reference type 'i' (range: LAST_FRAME ...
- // EXTREF_FRAME) to a remapped index 'j' (in range: 0 ... REF_FRAMES - 1)
- // * Later, 'cm->ref_frame_map[j]' maps the remapped index 'j' to a pointer to
- // the reference counted buffer structure RefCntBuffer, taken from the buffer
- // pool cm->buffer_pool->frame_bufs.
- //
- // LAST_FRAME, ..., EXTREF_FRAME
- // | |
- // v v
- // remapped_ref_idx[LAST_FRAME - 1], ..., remapped_ref_idx[EXTREF_FRAME - 1]
- // | |
- // v v
- // ref_frame_map[], ..., ref_frame_map[]
- //
- // Note: INTRA_FRAME always refers to the current frame, so there's no need to
- // have a remapped index for the same.
- int remapped_ref_idx[REF_FRAMES];
-
-#ifdef SUPPORT_SCALE_FACTOR
- struct scale_factors ref_scale_factors[REF_FRAMES];
-#endif
- // For decoder, ref_frame_map[i] maps reference type 'i' to a pointer to
- // the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'.
- // For encoder, ref_frame_map[j] (where j = remapped_ref_idx[i]) maps
- // remapped reference index 'j' (that is, original reference type 'i') to
- // a pointer to the buffer in the buffer pool 'cm->buffer_pool.frame_bufs'.
- RefCntBuffer *ref_frame_map[REF_FRAMES];
-
- // Prepare ref_frame_map for the next frame.
- // Only used in frame parallel decode.
- RefCntBuffer *next_ref_frame_map[REF_FRAMES];
-#ifdef AML
- RefCntBuffer *next_used_ref_frame_map[REF_FRAMES];
-#endif
- FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
-
- int show_frame;
- int showable_frame; // frame can be used as show existing frame in future
- int show_existing_frame;
-
- uint8_t disable_cdf_update;
- int allow_high_precision_mv;
- uint8_t cur_frame_force_integer_mv; // 0 the default in AOM, 1 only integer
-
- uint8_t allow_screen_content_tools;
- int allow_intrabc;
- int allow_warped_motion;
-
- // MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in
- // MB_MODE_INFO (8-pixel) units.
- int MBs;
- int mb_rows, mi_rows;
- int mb_cols, mi_cols;
- int mi_stride;
-
- /* profile settings */
- TX_MODE tx_mode;
-
-#if CONFIG_ENTROPY_STATS
- int coef_cdf_category;
-#endif
-
- int base_qindex;
- int y_dc_delta_q;
- int u_dc_delta_q;
- int v_dc_delta_q;
- int u_ac_delta_q;
- int v_ac_delta_q;
-
-#ifdef ORI_CODE
- // The dequantizers below are true dequantizers used only in the
- // dequantization process. They have the same coefficient
- // shift/scale as TX.
- int16_t y_dequant_QTX[MAX_SEGMENTS][2];
- int16_t u_dequant_QTX[MAX_SEGMENTS][2];
- int16_t v_dequant_QTX[MAX_SEGMENTS][2];
-
- // Global quant matrix tables
- const qm_val_t *giqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
- const qm_val_t *gqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
-
- // Local quant matrix tables for each frame
- const qm_val_t *y_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
- const qm_val_t *u_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
- const qm_val_t *v_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-#endif
- // Encoder
- int using_qmatrix;
- int qm_y;
- int qm_u;
- int qm_v;
- int min_qmlevel;
- int max_qmlevel;
- int use_quant_b_adapt;
-
- /* We allocate a MB_MODE_INFO struct for each macroblock, together with
- an extra row on top and column on the left to simplify prediction. */
- int mi_alloc_size;
-
-#ifdef ORI_CODE
- MB_MODE_INFO *mip; /* Base of allocated array */
- MB_MODE_INFO *mi; /* Corresponds to upper left visible macroblock */
-
- // TODO(agrange): Move prev_mi into encoder structure.
- // prev_mip and prev_mi will only be allocated in encoder.
- MB_MODE_INFO *prev_mip; /* MB_MODE_INFO array 'mip' from last decoded frame */
- MB_MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */
-
- // Separate mi functions between encoder and decoder.
- int (*alloc_mi)(struct AV1Common *cm, int mi_size);
- void (*free_mi)(struct AV1Common *cm);
- void (*setup_mi)(struct AV1Common *cm);
-
- // Grid of pointers to 8x8 MB_MODE_INFO structs. Any 8x8 not in the visible
- // area will be NULL.
- MB_MODE_INFO **mi_grid_base;
- MB_MODE_INFO **mi_grid_visible;
- MB_MODE_INFO **prev_mi_grid_base;
- MB_MODE_INFO **prev_mi_grid_visible;
-#endif
- // Whether to use previous frames' motion vectors for prediction.
- int allow_ref_frame_mvs;
-
- uint8_t *last_frame_seg_map;
-
-#ifdef ORI_CODE
- InterpFilter interp_filter;
-#endif
- int switchable_motion_mode;
-#ifdef ORI_CODE
- loop_filter_info_n lf_info;
-#endif
- // The denominator of the superres scale; the numerator is fixed.
- uint8_t superres_scale_denominator;
- int superres_upscaled_width;
- int superres_upscaled_height;
-
-#ifdef ORI_CODE
- RestorationInfo rst_info[MAX_MB_PLANE];
-#endif
- // Pointer to a scratch buffer used by self-guided restoration
- int32_t *rst_tmpbuf;
-#ifdef ORI_CODE
- RestorationLineBuffers *rlbs;
-#endif
- // Output of loop restoration
- PIC_BUFFER_CONFIG rst_frame;
-
- // Flag signaling how frame contexts should be updated at the end of
- // a frame decode
- REFRESH_FRAME_CONTEXT_MODE refresh_frame_context;
-
- int ref_frame_sign_bias[REF_FRAMES]; /* Two state 0, 1 */
-
-#ifdef ORI_CODE
- struct loopfilter lf;
- struct segmentation seg;
-#endif
-
- int coded_lossless; // frame is fully lossless at the coded resolution.
- int all_lossless; // frame is fully lossless at the upscaled resolution.
-
- int reduced_tx_set_used;
-
-#ifdef ORI_CODE
- // Context probabilities for reference frame prediction
- MV_REFERENCE_FRAME comp_fwd_ref[FWD_REFS];
- MV_REFERENCE_FRAME comp_bwd_ref[BWD_REFS];
-
- FRAME_CONTEXT *fc; /* this frame entropy */
- FRAME_CONTEXT *default_frame_context;
-#endif
- int primary_ref_frame;
-
- int error_resilient_mode;
-
- int tile_cols, tile_rows;
-
- int max_tile_width_sb;
- int min_log2_tile_cols;
- int max_log2_tile_cols;
- int max_log2_tile_rows;
- int min_log2_tile_rows;
- int min_log2_tiles;
- int max_tile_height_sb;
- int uniform_tile_spacing_flag;
- int log2_tile_cols; // only valid for uniform tiles
- int log2_tile_rows; // only valid for uniform tiles
- int tile_col_start_sb[MAX_TILE_COLS + 1]; // valid for 0 <= i <= tile_cols
- int tile_row_start_sb[MAX_TILE_ROWS + 1]; // valid for 0 <= i <= tile_rows
- int tile_width, tile_height; // In MI units
- int min_inner_tile_width; // min width of non-rightmost tile
-
- unsigned int large_scale_tile;
- unsigned int single_tile_decoding;
-
- int byte_alignment;
- int skip_loop_filter;
- int skip_film_grain;
-
- // External BufferPool passed from outside.
- BufferPool *buffer_pool;
-
-#ifdef ORI_CODE
- PARTITION_CONTEXT **above_seg_context;
- ENTROPY_CONTEXT **above_context[MAX_MB_PLANE];
- TXFM_CONTEXT **above_txfm_context;
- WarpedMotionParams global_motion[REF_FRAMES];
- aom_film_grain_t film_grain_params;
-
- CdefInfo cdef_info;
- DeltaQInfo delta_q_info; // Delta Q and Delta LF parameters
-#endif
- int num_tg;
- SequenceHeader seq_params;
- int current_frame_id;
- int ref_frame_id[REF_FRAMES];
- int valid_for_referencing[REF_FRAMES];
-#ifdef ORI_CODE
- TPL_MV_REF *tpl_mvs;
-#endif
- int tpl_mvs_mem_size;
- // TODO(jingning): This can be combined with sign_bias later.
- int8_t ref_frame_side[REF_FRAMES];
-
- int is_annexb;
-
- int temporal_layer_id;
- int spatial_layer_id;
- unsigned int number_temporal_layers;
- unsigned int number_spatial_layers;
- int num_allocated_above_context_mi_col;
- int num_allocated_above_contexts;
- int num_allocated_above_context_planes;
-
-#if TXCOEFF_TIMER
- int64_t cum_txcoeff_timer;
- int64_t txcoeff_timer;
- int txb_count;
-#endif
-
-#if TXCOEFF_COST_TIMER
- int64_t cum_txcoeff_cost_timer;
- int64_t txcoeff_cost_timer;
- int64_t txcoeff_cost_count;
-#endif
- const cfg_options_t *options;
- int is_decoding;
-#ifdef AML
- int mv_ref_offset[MV_REF_SIZE][REF_FRAMES];
- int mv_ref_id[MV_REF_SIZE];
- unsigned char mv_cal_tpl_mvs[MV_REF_SIZE];
- int mv_ref_id_index;
- int prev_fb_idx;
- int new_fb_idx;
- int32_t dec_width;
-#endif
-#ifdef AML_DEVICE
- int cur_fb_idx_mmu;
-#ifdef AOM_AV1_MMU_DW
- int cur_fb_idx_mmu_dw;
-#endif
- int current_video_frame;
- int use_prev_frame_mvs;
- int frame_type;
- int intra_only;
- struct RefCntBuffer_s frame_refs[INTER_REFS_PER_FRAME];
-
-#endif
-} AV1_COMMON;
-
-
-/*
-from:
- decoder/decoder.h
-*/
-
-typedef struct EXTERNAL_REFERENCES {
- PIC_BUFFER_CONFIG refs[MAX_EXTERNAL_REFERENCES];
- int num;
-} EXTERNAL_REFERENCES;
-
-typedef struct AV1Decoder {
- //DECLARE_ALIGNED(32, MACROBLOCKD, mb);
-
- //DECLARE_ALIGNED(32, AV1_COMMON, common);
- AV1_COMMON *common;
-
-#ifdef ORI_CODE
- AVxWorker lf_worker;
- AV1LfSync lf_row_sync;
- AV1LrSync lr_row_sync;
- AV1LrStruct lr_ctxt;
- AVxWorker *tile_workers;
- int num_workers;
- DecWorkerData *thread_data;
- ThreadData td;
- TileDataDec *tile_data;
- int allocated_tiles;
- TileBufferDec tile_buffers[MAX_TILE_ROWS][MAX_TILE_COLS];
- AV1DecTileMT tile_mt_info;
-#endif
-
- // Each time the decoder is called, we expect to receive a full temporal unit.
- // This can contain up to one shown frame per spatial layer in the current
- // operating point (note that some layers may be entirely omitted).
- // If the 'output_all_layers' option is true, we save all of these shown
- // frames so that they can be returned to the application. If the
- // 'output_all_layers' option is false, then we only output one image per
- // temporal unit.
- //
- // Note: The saved buffers are released at the start of the next time the
- // application calls aom_codec_decode().
- int output_all_layers;
- RefCntBuffer *output_frames[MAX_NUM_SPATIAL_LAYERS];
- size_t num_output_frames; // How many frames are queued up so far?
-
- // In order to properly support random-access decoding, we need
- // to behave slightly differently for the very first frame we decode.
- // So we track whether this is the first frame or not.
- int decoding_first_frame;
-
- int allow_lowbitdepth;
- int max_threads;
- int inv_tile_order;
- int need_resync; // wait for key/intra-only frame.
- int hold_ref_buf; // Boolean: whether we are holding reference buffers in
- // common.next_ref_frame_map.
- int reset_decoder_state;
-
- int tile_size_bytes;
- int tile_col_size_bytes;
- int dec_tile_row, dec_tile_col; // always -1 for non-VR tile encoding
-#if CONFIG_ACCOUNTING
- int acct_enabled;
- Accounting accounting;
-#endif
- int tg_size; // Number of tiles in the current tilegroup
- int tg_start; // First tile in the current tilegroup
- int tg_size_bit_offset;
- int sequence_header_ready;
- int sequence_header_changed;
-#if CONFIG_INSPECTION
- aom_inspect_cb inspect_cb;
- void *inspect_ctx;
-#endif
- int operating_point;
- int current_operating_point;
- int seen_frame_header;
-
- // State if the camera frame header is already decoded while
- // large_scale_tile = 1.
- int camera_frame_header_ready;
- size_t frame_header_size;
-#ifdef ORI_CODE
- DataBuffer obu_size_hdr;
-#endif
- int output_frame_width_in_tiles_minus_1;
- int output_frame_height_in_tiles_minus_1;
- int tile_count_minus_1;
- uint32_t coded_tile_data_size;
- unsigned int ext_tile_debug; // for ext-tile software debug & testing
- unsigned int row_mt;
- EXTERNAL_REFERENCES ext_refs;
- PIC_BUFFER_CONFIG tile_list_outbuf;
-
-#ifdef ORI_CODE
- CB_BUFFER *cb_buffer_base;
-#endif
- int cb_buffer_alloc_size;
-
- int allocated_row_mt_sync_rows;
-
-#if CONFIG_MULTITHREAD
- pthread_mutex_t *row_mt_mutex_;
- pthread_cond_t *row_mt_cond_;
-#endif
-
-#ifdef ORI_CODE
- AV1DecRowMTInfo frame_row_mt_info;
-#endif
-
-#ifdef AML
- unsigned char pred_inter_read_enable;
- int cur_obu_type;
- int decode_idx;
- int bufmgr_proc_count;
- int obu_frame_frame_head_come_after_tile;
- uint32_t frame_width;
- uint32_t frame_height;
- BuffInfo_t* work_space_buf;
- buff_t* mc_buf;
- //unsigned short *rpm_ptr;
- void *private_data;
- u32 pre_stream_offset;
-#endif
-} AV1Decoder;
-
-#define RPM_BEGIN 0x200
-#define RPM_END 0x280
-
-typedef union param_u {
- struct {
- unsigned short data[RPM_END - RPM_BEGIN];
- } l;
- struct {
- /*sequence head*/
- unsigned short profile;
- unsigned short still_picture;
- unsigned short reduced_still_picture_hdr;
- unsigned short decoder_model_info_present_flag;
- unsigned short max_frame_width;
- unsigned short max_frame_height;
- unsigned short frame_id_numbers_present_flag;
- unsigned short delta_frame_id_length;
- unsigned short frame_id_length;
- unsigned short order_hint_bits_minus_1;
- unsigned short enable_order_hint;
- unsigned short enable_dist_wtd_comp;
- unsigned short enable_ref_frame_mvs;
-
- /*frame head*/
- unsigned short show_existing_frame;
- unsigned short frame_type;
- unsigned short show_frame;
- unsigned short error_resilient_mode;
- unsigned short refresh_frame_flags;
- unsigned short showable_frame;
- unsigned short current_frame_id;
- unsigned short frame_size_override_flag;
- unsigned short order_hint;
- unsigned short primary_ref_frame;
- unsigned short frame_refs_short_signaling;
- unsigned short frame_width;
- unsigned short dec_frame_width;
- unsigned short frame_width_scaled;
- unsigned short frame_height;
- unsigned short reference_mode;
- unsigned short allow_ref_frame_mvs;
- unsigned short superres_scale_denominator;
- unsigned short lst_ref;
- unsigned short gld_ref;
- unsigned short existing_frame_idx;
-
- unsigned short remapped_ref_idx[INTER_REFS_PER_FRAME];
- unsigned short delta_frame_id_minus_1[INTER_REFS_PER_FRAME];
- unsigned short ref_order_hint[REF_FRAMES];
- /*other not in reference*/
- unsigned short bit_depth;
- unsigned short seq_flags;
- unsigned short update_parameters;
- unsigned short film_grain_params_ref_idx;
-
- /*loop_filter & segmentation*/
- unsigned short loop_filter_sharpness_level;
- unsigned short loop_filter_mode_ref_delta_enabled;
- unsigned short loop_filter_ref_deltas_0;
- unsigned short loop_filter_ref_deltas_1;
- unsigned short loop_filter_ref_deltas_2;
- unsigned short loop_filter_ref_deltas_3;
- unsigned short loop_filter_ref_deltas_4;
- unsigned short loop_filter_ref_deltas_5;
- unsigned short loop_filter_ref_deltas_6;
- unsigned short loop_filter_ref_deltas_7;
- unsigned short loop_filter_mode_deltas_0;
- unsigned short loop_filter_mode_deltas_1;
- unsigned short loop_filter_level_0;
- unsigned short loop_filter_level_1;
- unsigned short loop_filter_level_u;
- unsigned short loop_filter_level_v;
-
- unsigned short segmentation_enabled;
- /*
- SEG_LVL_ALT_LF_Y_V feature_enable: seg_lf_info_y[bit7]
- SEG_LVL_ALT_LF_Y_V data: seg_lf_info_y[bit0~6]
- SEG_LVL_ALT_LF_Y_H feature enable: seg_lf_info_y[bit15]
- SEG_LVL_ALT_LF_Y_H data: seg_lf_info_y[bit8~14]
- */
- unsigned short seg_lf_info_y[8];
- /*
- SEG_LVL_ALT_LF_U feature_enable: seg_lf_info_y[bit7]
- SEG_LVL_ALT_LF_U data: seg_lf_info_y[bit0~6]
- SEG_LVL_ALT_LF_V feature enable: seg_lf_info_y[bit15]
- SEG_LVL_ALT_LF_V data: seg_lf_info_y[bit8~14]
- */
- unsigned short seg_lf_info_c[8];
- unsigned short video_signal_type;
- unsigned short color_description;
-
- unsigned short mmu_used_num;
- unsigned short dw_mmu_used_num;
- unsigned short seq_flags_2;
- unsigned short film_grain_present_flag;
-
- /*ucode end*/
- /*other*/
- unsigned short enable_superres;
-
- /*seqence not use*/
- unsigned short operating_points_cnt_minus_1;
- unsigned short operating_point_idc[MAX_NUM_OPERATING_POINTS];
- unsigned short seq_level_idx[MAX_NUM_OPERATING_POINTS];
- unsigned short decoder_model_param_present_flag[MAX_NUM_OPERATING_POINTS];
- unsigned short timing_info_present;
- /*frame head not use*/
- unsigned short display_frame_id;
- unsigned short frame_presentation_time;
- unsigned short buffer_removal_time_present;
- unsigned short op_frame_timing[MAX_NUM_OPERATING_POINTS + 1];
- unsigned short valid_ref_frame_bits;
-
- } p;
-}param_t;
-
-PIC_BUFFER_CONFIG *av1_get_ref_frame_spec_buf(
- const AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame);
-
-int av1_bufmgr_process(AV1Decoder *pbi, union param_u *params,
- unsigned char new_compressed_data, int obu_type);
-
-struct scale_factors *av1_get_ref_scale_factors(
- AV1_COMMON *const cm, const MV_REFERENCE_FRAME ref_frame);
-
-void av1_set_next_ref_frame_map(AV1Decoder *pbi);
-
-unsigned int av1_get_next_used_ref_info(
- const AV1_COMMON *const cm, int i);
-
-void av1_release_buf(AV1Decoder *pbi, RefCntBuffer *const buf);
-
-int av1_bufmgr_postproc(AV1Decoder *pbi, unsigned char frame_decoded);
-
-AV1Decoder *av1_decoder_create(BufferPool *const pool, AV1_COMMON *cm);
-
-unsigned char av1_frame_is_inter(const AV1_COMMON *const cm);
-
-RefCntBuffer *av1_get_primary_ref_frame_buf(
- const AV1_COMMON *const cm);
-
-void av1_raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd);
-
-int get_free_frame_buffer(struct AV1_Common_s *cm);
-
-int check_buff_has_show(struct RefCntBuffer_s *frame_buf);
-
-void av1_bufmgr_ctx_reset(AV1Decoder *pbi, BufferPool *const pool, AV1_COMMON *cm);
-
-#if 1
-#define lock_buffer_pool(pool, flags) \
- spin_lock_irqsave(&pool->lock, flags)
-
-#define unlock_buffer_pool(pool, flags) \
- spin_unlock_irqrestore(&pool->lock, flags)
-#else
-#define lock_buffer_pool(pool, flags) flags=1;
-
-#define unlock_buffer_pool(pool, flags) flags=0;
-
-#endif
-
-#define AV1_DEBUG_BUFMGR 0x01
-#define AV1_DEBUG_BUFMGR_MORE 0x02
-#define AV1_DEBUG_BUFMGR_DETAIL 0x04
-#define AV1_DEBUG_TIMEOUT_INFO 0x08
-#define AV1_DEBUG_OUT_PTS 0x10
-#define AOM_DEBUG_HW_MORE 0x20
-#define AOM_DEBUG_VFRAME 0x40
-#define AOM_DEBUG_PRINT_LIST_INFO 0x80
-#define AOM_AV1_DEBUG_SEND_PARAM_WITH_REG 0x100
-#define AV1_DEBUG_IGNORE_VF_REF 0x200
-#define AV1_DEBUG_DBG_LF_PRINT 0x400
-#define AV1_DEBUG_REG 0x800
-#define AOM_DEBUG_BUFMGR_ONLY 0x1000
-#define AOM_DEBUG_AUX_DATA 0x2000
-#define AV1_DEBUG_QOS_INFO 0x4000
-#define AOM_DEBUG_DW_DISP_MAIN 0x8000
-#define AV1_DEBUG_DIS_LOC_ERROR_PROC 0x10000
-#define AOM_DEBUG_DIS_RECYCLE_MMU_TAIL 0x20000
-#define AV1_DEBUG_DUMP_PIC_LIST 0x40000
-#define AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000
-#define AOM_DEBUG_USE_FIXED_MV_BUF_SIZE 0x100000
-#define AV1_DEBUG_LOAD_UCODE_FROM_FILE 0x200000
-#define AV1_DEBUG_FORCE_SEND_AGAIN 0x400000
-#define AV1_DEBUG_DUMP_DATA 0x800000
-#define AV1_DEBUG_CACHE 0x1000000
-#define AV1_DEBUG_CACHE_HIT_RATE 0x2000000
-#define AV1_DEBUG_SEI_DETAIL 0x4000000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-#if 1
-/*def MULTI_INSTANCE_SUPPORT*/
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_V4L_DETAIL 0x10000000
-#define PRINT_FLAG_VDEC_STATUS 0x20000000
-#define PRINT_FLAG_VDEC_DETAIL 0x40000000
-#define PRINT_FLAG_VDEC_DATA 0x80000000
-#endif
-
-int av1_print2(int flag, const char *fmt, ...);
-
-unsigned char av1_is_debug(int flag);
-
-#endif
-
diff --git a/drivers/frame_provider/decoder_v4l/vav1/vav1.c b/drivers/frame_provider/decoder_v4l/vav1/vav1.c
deleted file mode 100755
index 132341b..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/vav1.c
+++ /dev/null
@@ -1,12061 +0,0 @@
- /*
- * drivers/amlogic/amports/vav1.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/sched/clock.h>
-#include <linux/sched.h>
-#include <linux/sched/rt.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/signal.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-#include <linux/amlogic/tee.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-#include <linux/crc32.h>
-
-#define MEM_NAME "codec_av1"
-/* #include <mach/am_regs.h> */
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-#include "../../decoder/utils/vdec_profile.h"
-#endif
-
-#include <linux/amlogic/media/video_sink/video.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/config_parser.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../../amvdec_ports/vdec_drv_base.h"
-
-//#define DEBUG_UCODE_LOG
-#define DEBUG_CMD
-#define DEBUG_CRC_ERROR
-
-#define SUPPORT_V4L2
-//#define DEBUG_USE_VP9_DEVICE_NAME
-//#define BUFMGR_ONLY_OLD_CHIP
-
-#ifdef SUPPORT_V4L2
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include <media/v4l2-mem2mem.h>
-#endif
-#include "../../../amvdec_ports/utils/common.h"
-#include "../../decoder/utils/vdec_feature.h"
-#include "../../decoder/utils/vdec_ge2d_utils.h"
-
-#define AML
-#include "aom_av1_define.h"
-#include "av1_global.h"
-
-#define DUMP_FILMGRAIN
-#define MIX_STREAM_SUPPORT
-//#define MV_USE_FIXED_BUF
-//#define USE_SPEC_BUF_FOR_MMU_HEAD
-
-#define AOM_AV1_DBLK_INIT
-#define AOM_AV1_UPSCALE_INIT
-
-#define USE_DEC_PIC_END
-
-#define SANITY_CHECK
-#define CO_MV_COMPRESS
-
-#include "vav1.h"
-
-#define FGS_TABLE_SIZE (512 * 128 / 8)
-
-#define AV1_GMC_PARAM_BUFF_ADDR 0x316d
-#define HEVCD_MPP_DECOMP_AXIURG_CTL 0x34c7
-#define HEVC_FGS_IDX 0x3660
-#define HEVC_FGS_DATA 0x3661
-#define HEVC_FGS_CTRL 0x3662
-#define AV1_SKIP_MODE_INFO 0x316c
-#define AV1_QUANT_WR 0x3146
-#define AV1_SEG_W_ADDR 0x3165
-#define AV1_SEG_R_ADDR 0x3166
-#define AV1_REF_SEG_INFO 0x3171
-#define HEVC_ASSIST_PIC_SIZE_FB_READ 0x300d
-#define PARSER_REF_SCALE_ENBL 0x316b
-#define HEVC_MPRED_MV_RPTR_1 0x3263
-#define HEVC_MPRED_MV_RPTR_2 0x3264
-#define HEVC_SAO_CTRL9 0x362d
-#define HEVC_FGS_TABLE_START 0x3666
-#define HEVC_FGS_TABLE_LENGTH 0x3667
-#define HEVC_DBLK_CDEF0 0x3515
-#define HEVC_DBLK_CDEF1 0x3516
-#define HEVC_DBLK_UPS1 0x351c
-#define HEVC_DBLK_UPS2 0x351d
-#define HEVC_DBLK_UPS3 0x351e
-#define HEVC_DBLK_UPS4 0x351f
-#define HEVC_DBLK_UPS5 0x3520
-#define AV1_UPSCALE_X0_QN 0x316e
-#define AV1_UPSCALE_STEP_QN 0x316f
-#define HEVC_DBLK_DBLK0 0x3523
-#define HEVC_DBLK_DBLK1 0x3524
-#define HEVC_DBLK_DBLK2 0x3525
-
-#define HW_MASK_FRONT 0x1
-#define HW_MASK_BACK 0x2
-
-#define AV1D_MPP_REFINFO_TBL_ACCCONFIG 0x3442
-#define AV1D_MPP_REFINFO_DATA 0x3443
-#define AV1D_MPP_REF_SCALE_ENBL 0x3441
-#define HEVC_MPRED_CTRL4 0x324c
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_DBLK_CFGB 0x350b
-#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
-#define HEVC_SAO_MMU_VH1_ADDR 0x363b
-#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-
-#define HEVC_MV_INFO 0x310d
-#define HEVC_QP_INFO 0x3137
-#define HEVC_SKIP_INFO 0x3136
-
-#define HEVC_CM_BODY_LENGTH2 0x3663
-#define HEVC_CM_HEADER_OFFSET2 0x3664
-#define HEVC_CM_HEADER_LENGTH2 0x3665
-
-#define HEVC_CM_HEADER_START_ADDR2 0x364a
-#define HEVC_SAO_MMU_DMA_CTRL2 0x364c
-#define HEVC_SAO_MMU_VH0_ADDR2 0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2 0x364e
-#define HEVC_SAO_MMU_STATUS2 0x3650
-#define HEVC_DW_VH0_ADDDR 0x365e
-#define HEVC_DW_VH1_ADDDR 0x365f
-
-#ifdef BUFMGR_ONLY_OLD_CHIP
-#undef AV1_SKIP_MODE_INFO
-#define AV1_SKIP_MODE_INFO HEVC_ASSIST_SCRATCH_B
-#endif
-
-
-#define AOM_AV1_DEC_IDLE 0
-#define AOM_AV1_DEC_FRAME_HEADER 1
-#define AOM_AV1_DEC_TILE_END 2
-#define AOM_AV1_DEC_TG_END 3
-#define AOM_AV1_DEC_LCU_END 4
-#define AOM_AV1_DECODE_SLICE 5
-#define AOM_AV1_SEARCH_HEAD 6
-#define AOM_AV1_DUMP_LMEM 7
-#define AOM_AV1_FGS_PARAM_CONT 8
-#define AOM_AV1_DISCARD_NAL 0x10
-#define AOM_AV1_RESULT_NEED_MORE_BUFFER 0x11
-#define DEC_RESULT_UNFINISH 0x12
-
-/*status*/
-#define AOM_AV1_DEC_PIC_END 0xe0
-/*AOM_AV1_FGS_PARA:
-Bit[11] - 0 Read, 1 - Write
-Bit[10:8] - film_grain_params_ref_idx, For Write request
-*/
-#define AOM_AV1_FGS_PARAM 0xe1
-#define AOM_AV1_DEC_PIC_END_PRE 0xe2
-#define AOM_AV1_HEAD_PARSER_DONE 0xf0
-#define AOM_AV1_HEAD_SEARCH_DONE 0xf1
-#define AOM_AV1_SEQ_HEAD_PARSER_DONE 0xf2
-#define AOM_AV1_FRAME_HEAD_PARSER_DONE 0xf3
-#define AOM_AV1_FRAME_PARSER_DONE 0xf4
-#define AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE 0xf5
-#define HEVC_ACTION_DONE 0xff
-
-#define AOM_DECODE_BUFEMPTY 0x20
-#define AOM_DECODE_TIMEOUT 0x21
-#define AOM_SEARCH_BUFEMPTY 0x22
-#define AOM_DECODE_OVER_SIZE 0x23
-#define AOM_EOS 0x24
-#define AOM_NAL_DECODE_DONE 0x25
-
-#define VF_POOL_SIZE 32
-
-#undef pr_info
-#define pr_info printk
-
-#define DECODE_MODE_SINGLE ((0x80 << 24) | 0)
-#define DECODE_MODE_MULTI_STREAMBASE ((0x80 << 24) | 1)
-#define DECODE_MODE_MULTI_FRAMEBASE ((0x80 << 24) | 2)
-#define DECODE_MODE_SINGLE_LOW_LATENCY ((0x80 << 24) | 3)
-#define DECODE_MODE_MULTI_FRAMEBASE_NOHEAD ((0x80 << 24) | 4)
-
-#define AV1_TRIGGER_FRAME_DONE 0x100
-#define AV1_TRIGGER_FRAME_ENABLE 0x200
-
-#define MV_MEM_UNIT 0x240
-/*---------------------------------------------------
- * Include "parser_cmd.h"
- *---------------------------------------------------
- */
-#define PARSER_CMD_SKIP_CFG_0 0x0000090b
-
-#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
-
-#define PARSER_CMD_SKIP_CFG_2 0x001b1910
-
-#define PARSER_CMD_NUMBER 37
-
-/*#define HEVC_PIC_STRUCT_SUPPORT*/
-/* to remove, fix build error */
-
-/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/
-
-#define MULTI_INSTANCE_SUPPORT
-#define SUPPORT_10BIT
-/* #define ERROR_HANDLE_DEBUG */
-
-#ifndef STAT_KTHREAD
-#define STAT_KTHREAD 0x40
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define MAX_DECODE_INSTANCE_NUM 9
-
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
-#define MULTI_DRIVER_NAME "ammvdec_vp9_v4l"
-#else
-#define MULTI_DRIVER_NAME "ammvdec_av1_v4l"
-#endif
-
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-#ifdef DEBUG_UCODE_LOG
-static u32 prefix_aux_buf_size;
-static u32 suffix_aux_buf_size;
-#else
-static u32 prefix_aux_buf_size = (16 * 1024);
-static u32 suffix_aux_buf_size;
-#endif
-#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
-//#define UCODE_LOG_BUF_SIZE (16 * 1024)
-#define UCODE_LOG_BUF_SIZE (1024 * 1024)
-#endif
-static unsigned int max_decode_instance_num
- = MAX_DECODE_INSTANCE_NUM;
-static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
-static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
-static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
-#ifdef AOM_AV1_MMU_DW
-static unsigned int dw_mmu_enable[MAX_DECODE_INSTANCE_NUM];
-#endif
-
-static u32 decode_timeout_val = 600;
-static u32 enable_single_slice = 1;
-static int start_decode_buf_level = 0x8000;
-//static u32 work_buf_size;
-static u32 force_pts_unstable;
-static u32 mv_buf_margin = REF_FRAMES;
-static u32 mv_buf_dynamic_alloc;
-static u32 force_max_one_mv_buffer_size;
-
-/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
-/* double_write_mode:
- * 0, no double write;
- * 1, 1:1 ratio;
- * 2, (1/4):(1/4) ratio;
- * 3, (1/4):(1/4) ratio, with both compressed frame included
- * 4, (1/2):(1/2) ratio;
- * 5, (1/2):(1/2) ratio, with both compressed frame included
- * 8, (1/8):(1/8) ratio;
- * 0x10, double write only
- * 0x20, mmu double write
- * 0x100, if > 1080p,use mode 4,else use mode 1;
- * 0x200, if > 1080p,use mode 2,else use mode 1;
- * 0x300, if > 720p, use mode 4, else use mode 1;
- */
-static u32 double_write_mode;
-
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
-#define DRIVER_NAME "amvdec_vp9_v4l"
-#define MODULE_NAME "amvdec_vp9_v4l"
-#define DRIVER_HEADER_NAME "amvdec_vp9_header"
-#else
-#define DRIVER_NAME "amvdec_av1_v4l"
-#define DRIVER_HEADER_NAME "amvdec_av1_header"
-#endif
-
-#define PUT_INTERVAL (HZ/100)
-#define ERROR_SYSTEM_RESET_COUNT 200
-
-#define PTS_NORMAL 0
-#define PTS_NONE_REF_USE_DURATION 1
-
-#define PTS_MODE_SWITCHING_THRESHOLD 3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
-
-#define DUR2PTS(x) ((x)*90/96)
-#define PTS2DUR(x) ((x)*96/90)
-#define PTS2DUR_u64(x) (div_u64((x)*96, 90))
-
-struct AV1HW_s;
-static int vav1_vf_states(struct vframe_states *states, void *);
-static struct vframe_s *vav1_vf_peek(void *);
-static struct vframe_s *vav1_vf_get(void *);
-static void vav1_vf_put(struct vframe_s *, void *);
-static int vav1_event_cb(int type, void *data, void *private_data);
-#ifdef MULTI_INSTANCE_SUPPORT
-static s32 vav1_init(struct vdec_s *vdec);
-#else
-static s32 vav1_init(struct AV1HW_s *hw);
-#endif
-static void vav1_prot_init(struct AV1HW_s *hw, u32 mask);
-static int vav1_local_init(struct AV1HW_s *hw, bool reset_flag);
-static void vav1_put_timer_func(struct timer_list *timer);
-static void dump_data(struct AV1HW_s *hw, int size);
-static unsigned int get_data_check_sum
- (struct AV1HW_s *hw, int size);
-static void dump_pic_list(struct AV1HW_s *hw);
-static int vav1_mmu_map_alloc(struct AV1HW_s *hw);
-static void vav1_mmu_map_free(struct AV1HW_s *hw);
-static int av1_alloc_mmu(
- struct AV1HW_s *hw,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr);
-
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
-static const char vav1_dec_id[] = "vvp9-dev";
-
-#define PROVIDER_NAME "decoder.vp9"
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.vp9"
-#else
-static const char vav1_dec_id[] = "vav1-dev";
-
-#define PROVIDER_NAME "decoder.av1"
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.av1"
-#endif
-#define DV_PROVIDER_NAME "dvbldec"
-
-static const struct vframe_operations_s vav1_vf_provider = {
- .peek = vav1_vf_peek,
- .get = vav1_vf_get,
- .put = vav1_vf_put,
- .event_cb = vav1_event_cb,
- .vf_states = vav1_vf_states,
-};
-
-static struct vframe_provider_s vav1_vf_prov;
-
-static u32 bit_depth_luma;
-static u32 bit_depth_chroma;
-static u32 frame_width;
-static u32 frame_height;
-static u32 video_signal_type;
-static u32 on_no_keyframe_skiped;
-static u32 without_display_mode;
-static u32 v4l_bitstream_id_enable = 1;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static u32 force_dv_enable;
-#endif
-
-#define PROB_SIZE (496 * 2 * 4)
-#define PROB_BUF_SIZE (0x5000)
-#define COUNT_BUF_SIZE (0x300 * 4 * 4)
-/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/
-#define MAX_FRAME_4K_NUM 0x1200
-#define MAX_FRAME_8K_NUM 0x4800
-
-#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-
-
-/*USE_BUF_BLOCK*/
-struct BUF_s {
- int index;
- unsigned int alloc_flag;
- /*buffer */
- unsigned int cma_page_count;
- unsigned long alloc_addr;
- unsigned long start_adr;
- unsigned int size;
-
- unsigned int free_start_adr;
- ulong v4l_ref_buf_addr;
- ulong header_addr;
- u32 header_size;
- u32 luma_size;
- ulong chroma_addr;
- u32 chroma_size;
- ulong header_dw_addr;
-} /*BUF_t */;
-
-struct MVBUF_s {
- unsigned long start_adr;
- unsigned int size;
- int used_flag;
-} /*MVBUF_t */;
-
-/*#define TEST_WR_PTR_INC*/
-/*#define WR_PTR_INC_NUM 128*/
-#define WR_PTR_INC_NUM 1
-
-//#define SIMULATION
-#define DOS_PROJECT
-#undef MEMORY_MAP_IN_REAL_CHIP
-
-/*#undef DOS_PROJECT*/
-/*#define MEMORY_MAP_IN_REAL_CHIP*/
-
-/*#define CONFIG_HEVC_CLK_FORCED_ON*/
-/*#define ENABLE_SWAP_TEST*/
-#ifndef BUFMGR_ONLY_OLD_CHIP
-#define MCRCC_ENABLE
-#endif
-
-#ifdef AV1_10B_NV21
-#else
-#define LOSLESS_COMPRESS_MODE
-#endif
-
-static u32 get_picture_qos;
-
-static u32 disable_repeat;
-
-static u32 debug;
-static u32 disable_fg;
-
-static bool is_reset;
-/*for debug*/
-static u32 force_bufspec;
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode detail print
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-static u32 dv_toggle_prov_name;
-#endif
-
-static u32 run_ready_min_buf_num = 2;
-#ifdef DEBUG_CRC_ERROR
-/*
- bit[4] fill zero in header before starting
- bit[5] dump mmu header always
-
- bit[6] dump mv buffer always
-
- bit[8] delay after decoding
- bit[31~16] delayed mseconds
-*/
-static u32 crc_debug_flag;
-#endif
-#ifdef DEBUG_CMD
-static u32 header_dump_size = 0x10000;
-static u32 debug_cmd_wait_count;
-static u32 debug_cmd_wait_type;
-#endif
-#define DEBUG_REG
-#ifdef DEBUG_REG
-void AV1_WRITE_VREG_DBG2(unsigned int adr, unsigned int val, int line)
-{
- if (debug & AV1_DEBUG_REG)
- pr_info("%d:%s(%x, %x)\n", line, __func__, adr, val);
- if (adr != 0)
- WRITE_VREG(adr, val);
-}
-
-#undef WRITE_VREG
-#define WRITE_VREG(a,v) AV1_WRITE_VREG_DBG2(a,v,__LINE__)
-#endif
-
-#define FRAME_CNT_WINDOW_SIZE 59
-#define RATE_CORRECTION_THRESHOLD 5
-/**************************************************
-
-AV1 buffer management start
-
-***************************************************/
-#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
-#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
-#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
-
-//#define MMU_COMPRESS_HEADER_SIZE 0x48000
-//#define MAX_ONE_MV_BUFFER_SIZE 0x260000
-//#define MAX_ONE_MV_BUFFER_SIZE 0x130000
-
-#define MAX_ONE_MV_BUFFER_SIZE_1080P 0x20400
-#define MAX_ONE_MV_BUFFER_SIZE_4K 0x91400
-#define MAX_ONE_MV_BUFFER_SIZE_8K 0x244800
-/*to support tm2revb and sc2*/
-#define MAX_ONE_MV_BUFFER_SIZE_1080P_TM2REVB 0x26400
-#define MAX_ONE_MV_BUFFER_SIZE_4K_TM2REVB 0xac400
-#define MAX_ONE_MV_BUFFER_SIZE_8K_TM2REVB 0x2b0800
-
-static int vav1_mmu_compress_header_size(struct AV1HW_s *hw);
-
-//#define MMU_COMPRESS_HEADER_SIZE 0x48000
-//#define MMU_COMPRESS_HEADER_SIZE_DW MMU_COMPRESS_HEADER_SIZE
-//#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4)
-#define MAX_SIZE_8K (8192 * 4608)
-#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
-#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
-#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
-
-#define INVALID_IDX -1 /* Invalid buffer index.*/
-
-
-/*4 scratch frames for the new frames to support a maximum of 4 cores decoding
- *in parallel, 3 for scaled references on the encoder.
- *TODO(hkuang): Add ondemand frame buffers instead of hardcoding the number
- * // of framebuffers.
- *TODO(jkoleszar): These 3 extra references could probably come from the
- *normal reference pool.
- */
-//#define FRAME_BUFFERS (REF_FRAMES + 16)
-//#define REF_FRAMES_4K (6)
-#define REF_FRAMES_4K REF_FRAMES
-
-#ifdef USE_SPEC_BUF_FOR_MMU_HEAD
-#define HEADER_FRAME_BUFFERS (0)
-#elif (defined AOM_AV1_MMU_DW)
-#define HEADER_FRAME_BUFFERS (2 * FRAME_BUFFERS)
-#else
-#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
-#endif
-#define MAX_BUF_NUM (FRAME_BUFFERS)
-#define MV_BUFFER_NUM FRAME_BUFFERS
-
-//#define FRAME_CONTEXTS_LOG2 2
-//#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
-/*buffer + header buffer + workspace*/
-#ifdef MV_USE_FIXED_BUF
-#define MAX_BMMU_BUFFER_NUM (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n)
-#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS)
-#else
-#define MAX_BMMU_BUFFER_NUM \
- (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM + 1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n)
-#define MV_BUFFER_IDX(n) (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + n)
-#define WORK_SPACE_BUF_ID \
- (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM)
-#endif
-#ifdef AOM_AV1_MMU_DW
-#define DW_HEADER_BUFFER_IDX(n) (HEADER_BUFFER_IDX(HEADER_FRAME_BUFFERS/2) + n)
-#endif
-
-
-static void set_canvas(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic_config);
-
-static void fill_frame_info(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *frame,
- unsigned int framesize,
- unsigned int pts);
-
-
-static int compute_losless_comp_body_size(int width, int height,
- uint8_t is_bit_depth_10);
-
-void clear_frame_buf_ref_count(AV1Decoder *pbi);
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_CONFIG_PARAM 3
-#define DEC_RESULT_ERROR 4
-#define DEC_INIT_PICLIST 5
-#define DEC_UNINIT_PICLIST 6
-#define DEC_RESULT_GET_DATA 7
-#define DEC_RESULT_GET_DATA_RETRY 8
-#define DEC_RESULT_EOS 9
-#define DEC_RESULT_FORCE_EXIT 10
-#define DEC_RESULT_DISCARD_DATA 11
-
-#define DEC_S1_RESULT_NONE 0
-#define DEC_S1_RESULT_DONE 1
-#define DEC_S1_RESULT_FORCE_EXIT 2
-#define DEC_S1_RESULT_TEST_TRIGGER_DONE 0xf0
-
-#ifdef FB_DECODING_TEST_SCHEDULE
-#define TEST_SET_NONE 0
-#define TEST_SET_PIC_DONE 1
-#define TEST_SET_S2_DONE 2
-#endif
-
-static void av1_work(struct work_struct *work);
-#endif
-
-#ifdef DUMP_FILMGRAIN
-u32 fg_dump_index = 0xff;
-#endif
-
-#ifdef AOM_AV1_DBLK_INIT
-struct loop_filter_info_n_s;
-struct loopfilter;
-struct segmentation_lf;
-#endif
-
-struct vav1_assit_task {
- bool use_sfgs;
- bool running;
- struct mutex assit_mutex;
- struct semaphore sem;
- struct task_struct *task;
- void *private;
-};
-
-struct AV1HW_s {
- AV1Decoder *pbi;
- union param_u aom_param;
- unsigned char frame_decoded;
- unsigned char one_compressed_data_done;
- unsigned char new_compressed_data;
-#if 1
-/*def CHECK_OBU_REDUNDANT_FRAME_HEADER*/
- int obu_frame_frame_head_come_after_tile;
-#endif
- unsigned char index;
-
- struct device *cma_dev;
- struct platform_device *platform_dev;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- struct vframe_chunk_s *chunk;
- int dec_result;
- struct work_struct work;
- struct work_struct set_clk_work;
- u32 start_shift_bytes;
- u32 data_size;
-
- struct BuffInfo_s work_space_buf_store;
- unsigned long buf_start;
- u32 buf_size;
- u32 cma_alloc_count;
- unsigned long cma_alloc_addr;
- uint8_t eos;
- unsigned long int start_process_time;
- unsigned last_lcu_idx;
- int decode_timeout_count;
- unsigned timeout_num;
- int save_buffer_mode;
-
- int double_write_mode;
-
- long used_4k_num;
-
- unsigned char m_ins_flag;
- char *provider_name;
- union param_u param;
- int frame_count;
- int pic_count;
- u32 stat;
- struct timer_list timer;
- u32 frame_dur;
- u32 frame_ar;
- int fatal_error;
- uint8_t init_flag;
- uint8_t config_next_ref_info_flag;
- uint8_t first_sc_checked;
- uint8_t process_busy;
-#define PROC_STATE_INIT 0
-#define PROC_STATE_DECODESLICE 1
-#define PROC_STATE_SENDAGAIN 2
- uint8_t process_state;
- u32 ucode_pause_pos;
-
- int show_frame_num;
- struct buff_s mc_buf_spec;
- struct dec_sysinfo vav1_amstream_dec_info;
- void *rpm_addr;
- void *lmem_addr;
- dma_addr_t rpm_phy_addr;
- dma_addr_t lmem_phy_addr;
- unsigned short *lmem_ptr;
- unsigned short *debug_ptr;
-#ifdef DUMP_FILMGRAIN
- dma_addr_t fg_phy_addr;
- unsigned char *fg_ptr;
- void *fg_addr;
-#endif
- u32 fgs_valid;
-
- u8 aux_data_dirty;
- u32 prefix_aux_size;
- u32 suffix_aux_size;
- void *aux_addr;
- dma_addr_t aux_phy_addr;
- char *dv_data_buf;
- int dv_data_size;
-#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
- void *ucode_log_addr;
- dma_addr_t ucode_log_phy_addr;
-#endif
-
- void *prob_buffer_addr;
- void *count_buffer_addr;
- dma_addr_t prob_buffer_phy_addr;
- dma_addr_t count_buffer_phy_addr;
-
- void *frame_mmu_map_addr;
- dma_addr_t frame_mmu_map_phy_addr;
-#ifdef AOM_AV1_MMU_DW
- void *dw_frame_mmu_map_addr;
- dma_addr_t dw_frame_mmu_map_phy_addr;
-#endif
- unsigned int use_cma_flag;
-
- struct BUF_s m_BUF[MAX_BUF_NUM];
- struct MVBUF_s m_mv_BUF[MV_BUFFER_NUM];
- u32 used_buf_num;
- u32 mv_buf_margin;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
- atomic_t vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
- int buf_num;
- int pic_num;
- int lcu_size_log2;
- unsigned int losless_comp_body_size;
-
- u32 video_signal_type;
-
- u32 pts_unstable;
- bool av1_first_pts_ready;
- bool dur_recalc_flag;
- u8 first_pts_index;
- u32 frame_mode_pts_save[FRAME_BUFFERS];
- u64 frame_mode_pts64_save[FRAME_BUFFERS];
-
- int last_pts;
- u64 last_pts_us64;
- u64 shift_byte_count;
-
- u32 shift_byte_count_lo;
- u32 shift_byte_count_hi;
- int pts_mode_switching_count;
- int pts_mode_recovery_count;
- bool get_frame_dur;
-
- u32 saved_resolution;
- /**/
- struct AV1_Common_s common;
- struct RefCntBuffer_s *cur_buf;
- int refresh_frame_flags;
- uint8_t need_resync;
- uint8_t hold_ref_buf;
- uint8_t ready_for_new_data;
- struct BufferPool_s av1_buffer_pool;
-
- struct BuffInfo_s *work_space_buf;
-
- struct buff_s *mc_buf;
-
- unsigned int frame_width;
- unsigned int frame_height;
-
- unsigned short *rpm_ptr;
- int init_pic_w;
- int init_pic_h;
- int lcu_total;
-
- int current_lcu_size;
-
- int slice_type;
-
- int skip_flag;
- int decode_idx;
- int result_done_count;
- uint8_t has_keyframe;
- uint8_t has_sequence;
- uint8_t wait_buf;
- uint8_t error_flag;
-
- /* bit 0, for decoding; bit 1, for displaying */
- uint8_t ignore_bufmgr_error;
- int PB_skip_mode;
- int PB_skip_count_after_decoding;
- /*hw*/
-
- /**/
- struct vdec_info *gvs;
-
- u32 pre_stream_offset;
-
- unsigned int dec_status;
- u32 last_put_idx;
- int new_frame_displayed;
- void *mmu_box;
- void *bmmu_box;
- int mmu_enable;
-#ifdef AOM_AV1_MMU_DW
- void *mmu_box_dw;
- int dw_mmu_enable;
-#endif
- struct vframe_master_display_colour_s vf_dp;
- struct firmware_s *fw;
- int max_pic_w;
- int max_pic_h;
- int buffer_spec_index;
- int32_t max_one_mv_buffer_size;
-
- int need_cache_size;
- u64 sc_start_time;
- bool postproc_done;
- int low_latency_flag;
- bool no_head;
- bool pic_list_init_done;
- bool pic_list_init_done2;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- int frameinfo_enable;
- struct vframe_qos_s vframe_qos;
-
-#ifdef AOM_AV1_DBLK_INIT
- /*
- * malloc may not work in real chip, please allocate memory for the following structures
- */
- struct loop_filter_info_n_s *lfi;
- struct loopfilter *lf;
- struct segmentation_lf *seg_4lf;
-#endif
- u32 mem_map_mode;
- u32 dynamic_buf_num_margin;
- struct vframe_s vframe_dummy;
- u32 res_ch_flag;
- int buffer_wrap[FRAME_BUFFERS];
- int sidebind_type;
- int sidebind_channel_id;
- u32 cur_obu_type;
- u32 multi_frame_cnt;
- u32 endian;
- u32 run_ready_min_buf_num;
- int one_package_frame_cnt;
- ulong fb_token;
- bool wait_more_buf;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- u32 aux_data_size;
- bool no_need_aux_data;
- struct trace_decoder_name trace;
- struct vav1_assit_task assit_task;
- int film_grain_present;
- ulong fg_table_handle;
- struct vdec_ge2d *ge2d;
- u32 data_offset;
- u32 data_invalid;
- u32 consume_byte;
-};
-static void av1_dump_state(struct vdec_s *vdec);
-
-int av1_print(struct AV1HW_s *hw,
- int flag, const char *fmt, ...)
-{
-#define HEVC_PRINT_BUF 512
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-
- if (hw == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
-
- va_start(args, fmt);
- if (hw)
- len = sprintf(buf, "[%d]", hw->index);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-unsigned char av1_is_debug(int flag)
-{
- if ((flag == 0) || (debug & flag))
- return 1;
-
- return 0;
-}
-
-int av1_print2(int flag, const char *fmt, ...)
-{
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-
- if ((flag == 0) ||
- (debug & flag)) {
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-
-}
-
-static int is_oversize(int w, int h)
-{
- int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
- MAX_SIZE_8K : MAX_SIZE_4K;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
- if (w <= 0 || h <= 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-static int v4l_alloc_and_config_pic(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic);
-
-static inline bool close_to(int a, int b, int m)
-{
- return (abs(a - b) < m) ? true : false;
-}
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static int av1_print_cont(struct AV1HW_s *hw,
- int flag, const char *fmt, ...)
-{
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-
- if (hw == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_info("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static void trigger_schedule(struct AV1HW_s *hw)
-{
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !hw->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- if (hw->vdec_cb)
- hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg);
-}
-
-static void reset_process_time(struct AV1HW_s *hw)
-{
- if (hw->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - hw->start_process_time) / HZ;
- hw->start_process_time = 0;
- if (process_time > max_process_time[hw->index])
- max_process_time[hw->index] = process_time;
- }
-}
-
-static void start_process_time(struct AV1HW_s *hw)
-{
- hw->start_process_time = jiffies;
- hw->decode_timeout_count = 0;
- hw->last_lcu_idx = 0;
-}
-
-static void timeout_process(struct AV1HW_s *hw)
-{
- reset_process_time(hw);
- if (hw->process_busy) {
- av1_print(hw,
- 0, "%s decoder timeout but process_busy\n", __func__);
- if (debug)
- av1_print(hw, 0, "debug disable timeout notify\n");
- return;
- }
- hw->timeout_num++;
- amhevc_stop();
-
- av1_print(hw,
- 0, "%s decoder timeout\n", __func__);
-
- hw->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&hw->work);
-}
-
-static u32 get_valid_double_write_mode(struct AV1HW_s *hw)
-{
- u32 dw = ((double_write_mode & 0x80000000) == 0) ?
- hw->double_write_mode :
- (double_write_mode & 0x7fffffff);
- if ((dw & 0x20) &&
- ((dw & 0xf) == 2 || (dw & 0xf) == 3)) {
- pr_info("MMU doueble write 1:4 not supported !!!\n");
- dw = 0;
- }
- return dw;
-}
-
-static int get_double_write_mode(struct AV1HW_s *hw)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(hw);
- u32 dw;
- int w, h;
- struct AV1_Common_s *cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config;
-
- if (hw->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(hw->v4l2_ctx, &out);
- dw = out;
- return dw;
- }
-
- cur_pic_config = &cm->cur_frame->buf;
- w = cur_pic_config->y_crop_width;
- h = cur_pic_config->y_crop_height;
-
- dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-
-/* for double write buf alloc */
-static int get_double_write_mode_init(struct AV1HW_s *hw)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(hw);
- u32 dw;
- int w = hw->init_pic_w;
- int h = hw->init_pic_h;
-
- dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-#endif
-
-#define FILM_GRAIN_TASK
-#ifdef FILM_GRAIN_TASK
-
-static u32 use_sfgs;
-module_param(use_sfgs, uint, 0664);
-
-void film_grain_task_wakeup(struct AV1HW_s *hw)
-{
- u32 fg_reg0, fg_reg1, num_y_points, num_cb_points, num_cr_points;
- struct AV1_Common_s *cm = &hw->common;
-
- if (!hw->assit_task.use_sfgs || hw->eos)
- return;
-
- fg_reg0 = cm->cur_frame->film_grain_reg[0];
- fg_reg1 = cm->cur_frame->film_grain_reg[1];
- num_y_points = fg_reg1 & 0xf;
- num_cr_points = (fg_reg1 >> 8) & 0xf;
- num_cb_points = (fg_reg1 >> 4) & 0xf;
- if ((num_y_points > 0) ||
- ((num_cb_points > 0) | ((fg_reg0 >> 17) & 0x1)) ||
- ((num_cr_points > 0) | ((fg_reg0 >> 17) & 0x1)))
- hw->fgs_valid = 1;
- else
- hw->fgs_valid = 0;
-
- if (cm->cur_frame) {
- init_waitqueue_head(&cm->cur_frame->wait_sfgs);
- if (((get_debug_fgs() & DEBUG_FGS_BYPASS) == 0)
- && hw->fgs_valid) {
- atomic_set(&cm->cur_frame->fgs_done, 0);
- hw->assit_task.private = cm->cur_frame;
- up(&hw->assit_task.sem);
- } else {
- atomic_set(&cm->cur_frame->fgs_done, 1);
- }
- }
-}
-EXPORT_SYMBOL(film_grain_task_wakeup);
-
-static int film_grain_task(void *args)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)args;
- struct vav1_assit_task *assit = &hw->assit_task;
- struct sched_param param = {.sched_priority = MAX_RT_PRIO/2};
- RefCntBuffer *cur_frame;
-
- sched_setscheduler(current, SCHED_FIFO, ¶m);
-
- allow_signal(SIGTERM);
-
- while (down_interruptible(&assit->sem) == 0) {
- if (assit->running == false)
- break;
-
- if (assit->private == NULL)
- continue;
-
- mutex_lock(&assit->assit_mutex);
- cur_frame = (RefCntBuffer *)assit->private;
- if ((!hw->eos) && (atomic_read(&cur_frame->fgs_done) == 0)) {
- pic_film_grain_run(hw->frame_count, cur_frame->buf.sfgs_table_ptr,
- cur_frame->film_grain_ctrl, cur_frame->film_grain_reg);
- atomic_set(&cur_frame->fgs_done, 1);
- wake_up_interruptible(&cur_frame->wait_sfgs);
- assit->private = NULL;
- vdec_sync_irq(VDEC_IRQ_0);
- }
- mutex_unlock(&assit->assit_mutex);
- }
-
- while (!kthread_should_stop()) {
- usleep_range(500, 1000);
- }
-
- return 0;
-}
-
-static int film_grain_task_create(struct AV1HW_s *hw)
-{
- struct vav1_assit_task *assit = &hw->assit_task;
-
- mutex_init(&assit->assit_mutex);
-
- if ((!vdec_secure(hw_to_vdec(hw)) || (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_SC2))
- && !use_sfgs)
- return 0;
-
- assit->use_sfgs = 1;
- sema_init(&assit->sem, 0);
-
- assit->task = kthread_run(film_grain_task, hw, "fgs_task");
- if (IS_ERR(assit->task)) {
- pr_err("%s, creat film grain task thread faild %ld\n",
- __func__, PTR_ERR(assit->task));
- return PTR_ERR(assit->task);
- }
- assit->running = true;
- assit->private = NULL;
- av1_print(hw, 0, "%s, task %px create sucess\n", __func__, assit->task);
-
- return 0;
-}
-
-static void film_grain_task_exit(struct AV1HW_s *hw)
-{
- struct vav1_assit_task *assit = &hw->assit_task;
-
- if ((!assit->use_sfgs) || (IS_ERR(assit->task)))
- return;
-
- assit->running = false;
- up(&assit->sem);
-
- if (assit->task) {
- kthread_stop(assit->task);
- assit->task = NULL;
- }
- assit->use_sfgs = 0;
- av1_print(hw, 0, "%s, task kthread stoped\n", __func__);
-}
-#endif
-
-
-/* return page number */
-static int av1_mmu_page_num(struct AV1HW_s *hw,
- int w, int h, int save_mode)
-{
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-
- picture_size = compute_losless_comp_body_size(w, h, save_mode);
- cur_mmu_4k_number = ((picture_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- max_frame_num = MAX_FRAME_8K_NUM;
- else
- max_frame_num = MAX_FRAME_4K_NUM;
-
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, w, h);
- return -1;
- }
-
- return cur_mmu_4k_number;
-}
-
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct AV1HW_s *hw,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct AV1HW_s *hw, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- hw->m_BUF[index].v4l_ref_buf_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-//#define MAX_4K_NUM 0x1200
-int av1_alloc_mmu(
- struct AV1HW_s *hw,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
-{
- int ret = 0;
- int bit_depth_10 = (bit_depth == AOM_BITS_10);
- int cur_mmu_4k_number;
-
- if (get_double_write_mode(hw) & 0x10)
- return 0;
-
- if (bit_depth >= AOM_BITS_12) {
- hw->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- pr_err("fatal_error, un support bit depth 12!\n\n");
- return -1;
- }
-
- cur_mmu_4k_number = av1_mmu_page_num(hw,
- pic_width,
- pic_height,
- bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- if (hw->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, cur_buf_idx);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ret = decoder_mmu_box_alloc_idx(
- hw->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
- }
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- return ret;
-}
-
-#ifdef AOM_AV1_MMU_DW
-static int compute_losless_comp_body_size_dw(int width, int height,
- uint8_t is_bit_depth_10);
-
-int av1_alloc_mmu_dw(
- struct AV1HW_s *hw,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
-{
- int ret = 0;
- int bit_depth_10 = (bit_depth == AOM_BITS_10);
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-
- if (get_double_write_mode(hw) & 0x10)
- return 0;
- if (bit_depth >= AOM_BITS_12) {
- hw->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- pr_err("fatal_error, un support bit depth 12!\n\n");
- return -1;
- }
- picture_size = compute_losless_comp_body_size_dw(pic_width, pic_height,
- bit_depth_10);
- cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- max_frame_num = MAX_FRAME_8K_NUM;
- else
- max_frame_num = MAX_FRAME_4K_NUM;
-
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, pic_width, pic_height);
- return -1;
- }
- if (hw->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, cur_buf_idx);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box_dw,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ret = decoder_mmu_box_alloc_idx(
- hw->mmu_box_dw,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
- }
- return ret;
-}
-#endif
-
-#ifndef MV_USE_FIXED_BUF
-static void dealloc_mv_bufs(struct AV1HW_s *hw)
-{
- int i;
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (hw->m_mv_BUF[i].start_adr) {
- if (debug)
- pr_info(
- "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
- i, hw->m_mv_BUF[i].start_adr,
- hw->m_mv_BUF[i].size,
- hw->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- hw->bmmu_box,
- MV_BUFFER_IDX(i));
- hw->m_mv_BUF[i].start_adr = 0;
- hw->m_mv_BUF[i].size = 0;
- hw->m_mv_BUF[i].used_flag = 0;
- }
- }
-}
-
-static int alloc_mv_buf(struct AV1HW_s *hw,
- int i, int size)
-{
- int ret = 0;
-
- if (hw->m_mv_BUF[i].start_adr &&
- size > hw->m_mv_BUF[i].size) {
- dealloc_mv_bufs(hw);
- } else if (hw->m_mv_BUF[i].start_adr)
- return 0;
-
- if (decoder_bmmu_box_alloc_buf_phy
- (hw->bmmu_box,
- MV_BUFFER_IDX(i), size,
- DRIVER_NAME,
- &hw->m_mv_BUF[i].start_adr) < 0) {
- hw->m_mv_BUF[i].start_adr = 0;
- ret = -1;
- } else {
- hw->m_mv_BUF[i].size = size;
- hw->m_mv_BUF[i].used_flag = 0;
- ret = 0;
- if (debug) {
- pr_info(
- "MV Buffer %d: start_adr %p size %x\n",
- i,
- (void *)hw->m_mv_BUF[i].start_adr,
- hw->m_mv_BUF[i].size);
- }
- }
- return ret;
-}
-
-static int cal_mv_buf_size(struct AV1HW_s *hw, int pic_width, int pic_height)
-{
- unsigned lcu_size = hw->current_lcu_size;
- int extended_pic_width = (pic_width + lcu_size -1)
- & (~(lcu_size - 1));
- int extended_pic_height = (pic_height + lcu_size -1)
- & (~(lcu_size - 1));
-
- int lcu_x_num = extended_pic_width / lcu_size;
- int lcu_y_num = extended_pic_height / lcu_size;
- int size_a, size_b, size;
-
- if (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_SC2)
- /*tm2revb and sc2*/
- size_a = lcu_x_num * lcu_y_num * 16 *
- ((lcu_size == 64) ? 16 : 64);
- else
- size_a = lcu_x_num * lcu_y_num * 16 *
- ((lcu_size == 64) ? 19 : 76);
-
- size_b = lcu_x_num * ((lcu_y_num >> 3) +
- (lcu_y_num & 0x7)) * 16;
- size = ((size_a + size_b) + 0xffff) & (~0xffff);
-
- if (debug & AOM_DEBUG_USE_FIXED_MV_BUF_SIZE)
- size = hw->max_one_mv_buffer_size;
- if (force_max_one_mv_buffer_size)
- size = force_max_one_mv_buffer_size;
- return size;
-}
-
-static int init_mv_buf_list(struct AV1HW_s *hw)
-{
- int i;
- int ret = 0;
- int count = MV_BUFFER_NUM;
- int pic_width = hw->init_pic_w;
- int pic_height = hw->init_pic_h;
- int size = cal_mv_buf_size(hw, pic_width, pic_height);
-
- if (mv_buf_dynamic_alloc)
- return 0;
-#if 0
- if (mv_buf_margin > 0)
- count = REF_FRAMES + mv_buf_margin;
- if (hw->init_pic_w > 2048 && hw->init_pic_h > 1088)
- count = REF_FRAMES_4K + mv_buf_margin;
-#else
- if (debug)
- pr_info("%s, calculated mv size 0x%x\n",
- __func__, size);
-
- if ((hw->is_used_v4l) && !IS_8K_SIZE(pic_width, pic_height)) {
- if (vdec_is_support_4k())
- size = 0xb0000;
- else
- size = 0x30000;
- }
-
- if (hw->init_pic_w > 4096 && hw->init_pic_h > 2048)
- count = REF_FRAMES_4K + hw->mv_buf_margin;
- else if (hw->init_pic_w > 2048 && hw->init_pic_h > 1088)
- count = REF_FRAMES_4K + hw->mv_buf_margin;
- else
- count = REF_FRAMES + hw->mv_buf_margin;
-
-#endif
- if (debug) {
- pr_info("%s w:%d, h:%d, count: %d, size 0x%x\n",
- __func__, hw->init_pic_w, hw->init_pic_h,
- count, size);
- }
-
- for (i = 0;
- i < count && i < MV_BUFFER_NUM; i++) {
- if (alloc_mv_buf(hw, i, size) < 0) {
- ret = -1;
- break;
- }
- }
- return ret;
-}
-
-static int get_mv_buf(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- int i;
- int ret = -1;
- if (mv_buf_dynamic_alloc) {
- int size = cal_mv_buf_size(hw,
- pic_config->y_crop_width, pic_config->y_crop_height);
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (hw->m_mv_BUF[i].start_adr == 0) {
- ret = i;
- break;
- }
- }
- if (i == MV_BUFFER_NUM) {
- pr_info(
- "%s: Error, mv buf MV_BUFFER_NUM is not enough\n",
- __func__);
- return ret;
- }
-
- if (alloc_mv_buf(hw, ret, size) >= 0) {
- pic_config->mv_buf_index = ret;
- pic_config->mpred_mv_wr_start_addr =
- (hw->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- } else {
- pr_info(
- "%s: Error, mv buf alloc fail\n",
- __func__);
- }
- return ret;
- }
-
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (hw->m_mv_BUF[i].start_adr &&
- hw->m_mv_BUF[i].used_flag == 0) {
- hw->m_mv_BUF[i].used_flag = 1;
- ret = i;
- break;
- }
- }
-
- if (ret >= 0) {
- pic_config->mv_buf_index = ret;
- pic_config->mpred_mv_wr_start_addr =
- (hw->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s => %d (%d) size 0x%x\n",
- __func__, ret,
- pic_config->mpred_mv_wr_start_addr,
- hw->m_mv_BUF[ret].size);
- } else {
- pr_info(
- "%s: Error, mv buf is not enough\n",
- __func__);
- }
- return ret;
-}
-static void put_mv_buf(struct AV1HW_s *hw,
- int *mv_buf_index)
-{
- int i = *mv_buf_index;
- if (i >= MV_BUFFER_NUM) {
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s: index %d beyond range\n",
- __func__, i);
- return;
- }
- if (mv_buf_dynamic_alloc) {
- if (hw->m_mv_BUF[i].start_adr) {
- if (debug)
- pr_info(
- "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
- i, hw->m_mv_BUF[i].start_adr,
- hw->m_mv_BUF[i].size,
- hw->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- hw->bmmu_box,
- MV_BUFFER_IDX(i));
- hw->m_mv_BUF[i].start_adr = 0;
- hw->m_mv_BUF[i].size = 0;
- hw->m_mv_BUF[i].used_flag = 0;
- }
- *mv_buf_index = -1;
- return;
- }
-
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s(%d): used_flag(%d)\n",
- __func__, i,
- hw->m_mv_BUF[i].used_flag);
-
- *mv_buf_index = -1;
- if (hw->m_mv_BUF[i].start_adr &&
- hw->m_mv_BUF[i].used_flag)
- hw->m_mv_BUF[i].used_flag = 0;
-}
-static void put_un_used_mv_bufs(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.index != -1) &&
- (frame_bufs[i].buf.mv_buf_index >= 0)
- )
- put_mv_buf(hw, &frame_bufs[i].buf.mv_buf_index);
- }
-}
-#endif
-
-static void init_pic_list_hw(struct AV1HW_s *pbi);
-
-static void update_hide_frame_timestamp(struct AV1HW_s *hw)
-{
- RefCntBuffer *const frame_bufs = hw->common.buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((!frame_bufs[i].show_frame) &&
- (frame_bufs[i].showable_frame) &&
- (!frame_bufs[i].buf.vf_ref) &&
- (frame_bufs[i].buf.BUF_index != -1)) {
- frame_bufs[i].buf.timestamp = hw->chunk->timestamp;
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "%s, update %d hide frame ts: %lld\n",
- __func__, i, frame_bufs[i].buf.timestamp);
- }
- }
-}
-
-int check_buff_has_show(struct RefCntBuffer_s *frame_buf)
-{
- int ret = 1;
-
- if (disable_repeat ||
- ((frame_buf->buf.vf_ref == 0) &&
- (frame_buf->buf.index != -1) &&
- frame_buf->buf.cma_alloc_addr)) {
- ret = 0;
- if (debug & AV1_DEBUG_BUFMGR)
- pr_info("existing buff can use\n");
- } else {
- if (debug & AV1_DEBUG_BUFMGR)
- pr_info("existing buff can't use\n");
- }
- return ret;
-}
-
-static int get_free_fb_idx(AV1_COMMON *cm)
-{
- int i;
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
-
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0))
- break;
- }
-
- return (i != FRAME_BUFFERS) ? i : -1;
-}
-
-static int v4l_get_free_fb(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx * v4l = hw->v4l2_ctx;
- struct v4l_buff_pool *pool = &v4l->cap_pool;
- struct PIC_BUFFER_CONFIG_s *pic = NULL;
- struct PIC_BUFFER_CONFIG_s *free_pic = NULL;
- ulong flags;
- int idx, i;
-
- lock_buffer_pool(cm->buffer_pool, flags);
-
- for (i = 0; i < pool->in; ++i) {
- u32 state = (pool->seq[i] >> 16);
- u32 index = (pool->seq[i] & 0xffff);
-
- switch (state) {
- case V4L_CAP_BUFF_IN_DEC:
- pic = &frame_bufs[i].buf;
- if ((frame_bufs[i].ref_count == 0) &&
- (pic->vf_ref == 0) &&
- (pic->repeat_count == 0) &&
- (pic->index != -1) &&
- pic->cma_alloc_addr) {
- free_pic = pic;
- }
- break;
- case V4L_CAP_BUFF_IN_M2M:
- idx = get_free_fb_idx(cm);
- if (idx < 0)
- break;
-
- pic = &frame_bufs[idx].buf;
- pic->y_crop_width = hw->frame_width;
- pic->y_crop_height = hw->frame_height;
- hw->buffer_wrap[idx] = index;
- if (!v4l_alloc_and_config_pic(hw, pic)) {
- set_canvas(hw, pic);
- init_pic_list_hw(hw);
- free_pic = pic;
- }
- break;
- default:
- break;
- }
-
- if (free_pic) {
- if (frame_bufs[i].buf.use_external_reference_buffers) {
- // If this frame buffer's y_buffer, u_buffer, and v_buffer point to the
- // external reference buffers. Restore the buffer pointers to point to the
- // internally allocated memory.
- PIC_BUFFER_CONFIG *ybf = &frame_bufs[i].buf;
-
- ybf->y_buffer = ybf->store_buf_adr[0];
- ybf->u_buffer = ybf->store_buf_adr[1];
- ybf->v_buffer = ybf->store_buf_adr[2];
- ybf->use_external_reference_buffers = 0;
- }
-
- frame_bufs[i].ref_count = 1;
- break;
- }
- }
-
- if (free_pic && hw->chunk) {
- free_pic->timestamp = hw->chunk->timestamp;
- update_hide_frame_timestamp(hw);
- }
-
- unlock_buffer_pool(cm->buffer_pool, flags);
-
- if (free_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- hw->m_BUF[free_pic->index].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
-
- v4l->aux_infos.bind_sei_buffer(v4l, &free_pic->aux_data_buf,
- &free_pic->aux_data_size, &free_pic->ctx_buf_idx);
-
- }
-
- if (debug & AV1_DEBUG_OUT_PTS) {
- if (free_pic) {
- pr_debug("%s, idx: %d, ts: %lld\n",
- __func__, free_pic->index, free_pic->timestamp);
- } else {
- pr_debug("%s, av1 get free pic null\n", __func__);
- }
- }
-
- return free_pic ? free_pic->index : INVALID_IDX;
-}
-
-static int get_free_fb(AV1_COMMON *cm) {
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
- unsigned long flags;
- int i;
-
- lock_buffer_pool(cm->buffer_pool, flags);
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- if (frame_bufs[i].ref_count == 0
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- && frame_bufs[i].buf.vf_ref == 0
-#endif
- )
- break;
- }
-
- if (i != FRAME_BUFFERS) {
- if (frame_bufs[i].buf.use_external_reference_buffers) {
- // If this frame buffer's y_buffer, u_buffer, and v_buffer point to the
- // external reference buffers. Restore the buffer pointers to point to the
- // internally allocated memory.
- PIC_BUFFER_CONFIG *ybf = &frame_bufs[i].buf;
- ybf->y_buffer = ybf->store_buf_adr[0];
- ybf->u_buffer = ybf->store_buf_adr[1];
- ybf->v_buffer = ybf->store_buf_adr[2];
- ybf->use_external_reference_buffers = 0;
- }
-
- frame_bufs[i].ref_count = 1;
- } else {
- // We should never run out of free buffers. If this assertion fails, there
- // is a reference leak.
- //assert(0 && "Ran out of free frame buffers. Likely a reference leak.");
- // Reset i to be INVALID_IDX to indicate no free buffer found.
- i = INVALID_IDX;
- }
-
- unlock_buffer_pool(cm->buffer_pool, flags);
- return i;
-}
-
-int get_free_frame_buffer(struct AV1_Common_s *cm)
-{
- struct AV1HW_s *hw = container_of(cm, struct AV1HW_s, common);
-
- return hw->is_used_v4l ? v4l_get_free_fb(hw) : get_free_fb(cm);
-}
-
-static int get_free_buf_count(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_buf_count = 0;
-
- //clear_frame_buf_ref_count(hw->pbi);
-
- if (hw->is_used_v4l) {
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_buf_count++;
- }
- }
-
- if (ctx->cap_pool.dec < hw->used_buf_num) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_buf_count +=
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- /* trigger to parse head data. */
- if (!hw->v4l_params_parsed) {
- free_buf_count = hw->run_ready_min_buf_num;
- }
- if ((debug & AV1_DEBUG_BUFMGR_MORE) &&
- (free_buf_count <= 0)) {
- pr_info("%s, free count %d, m2m_ready %d\n",
- __func__,
- free_buf_count,
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
- }
- } else {
- for (i = 0; i < hw->used_buf_num; ++i)
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1)) {
- free_buf_count++;
- }
- }
-
- return free_buf_count;
-}
-
-int aom_bufmgr_init(struct AV1HW_s *hw, struct BuffInfo_s *buf_spec_i,
- struct buff_s *mc_buf_i) {
- struct AV1_Common_s *cm = &hw->common;
- if (debug)
- pr_info("%s %d %p\n", __func__, __LINE__, hw->pbi);
- hw->frame_count = 0;
- hw->pic_count = 0;
- hw->pre_stream_offset = 0;
- spin_lock_init(&cm->buffer_pool->lock);
- cm->prev_fb_idx = INVALID_IDX;
- cm->new_fb_idx = INVALID_IDX;
- hw->used_4k_num = -1;
- cm->cur_fb_idx_mmu = INVALID_IDX;
- pr_debug
- ("After aom_bufmgr_init, prev_fb_idx : %d, new_fb_idx : %d\r\n",
- cm->prev_fb_idx, cm->new_fb_idx);
- hw->need_resync = 1;
-
- cm->current_video_frame = 0;
- hw->ready_for_new_data = 1;
-
- /* private init */
- hw->work_space_buf = buf_spec_i;
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) ||
- (get_double_write_mode(hw) == 0x10)) {
- hw->mc_buf = mc_buf_i;
- }
-
- hw->rpm_addr = NULL;
- hw->lmem_addr = NULL;
-
- hw->use_cma_flag = 0;
- hw->decode_idx = 0;
- hw->result_done_count = 0;
- /*int m_uiMaxCUWidth = 1<<7;*/
- /*int m_uiMaxCUHeight = 1<<7;*/
- hw->has_keyframe = 0;
- hw->has_sequence = 0;
- hw->skip_flag = 0;
- hw->wait_buf = 0;
- hw->error_flag = 0;
-
- hw->last_pts = 0;
- hw->last_pts_us64 = 0;
- hw->shift_byte_count = 0;
- hw->shift_byte_count_lo = 0;
- hw->shift_byte_count_hi = 0;
- hw->pts_mode_switching_count = 0;
- hw->pts_mode_recovery_count = 0;
-
- hw->buf_num = 0;
- hw->pic_num = 0;
-
- return 0;
-}
-
-/*
-struct AV1HW_s av1_decoder;
-union param_u av1_param;
-*/
-/**************************************************
- *
- *AV1 buffer management end
- *
- ***************************************************
- */
-
-
-#define HEVC_CM_BODY_START_ADDR 0x3626
-#define HEVC_CM_BODY_LENGTH 0x3627
-#define HEVC_CM_HEADER_LENGTH 0x3629
-#define HEVC_CM_HEADER_OFFSET 0x362b
-
-#define LOSLESS_COMPRESS_MODE
-
-/*#define DECOMP_HEADR_SURGENT*/
-#ifdef AV1_10B_NV21
-static u32 mem_map_mode = 2 /* 0:linear 1:32x32 2:64x32*/
-#else
-static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
-#endif
-static u32 enable_mem_saving = 1;
-static u32 force_w_h;
-
-static u32 force_fps;
-
-
-const u32 av1_version = 201602101;
-static u32 debug;
-static u32 radr;
-static u32 rval;
-static u32 pop_shorts;
-static u32 dbg_cmd;
-static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
-static u32 multi_frames_in_one_pack = 1;
-#ifdef ERROR_HANDLE_DEBUG
-static u32 dbg_nal_skip_flag;
- /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
-static u32 dbg_nal_skip_count;
-#endif
-/*for debug*/
-static u32 decode_pic_begin;
-static uint slice_parse_begin;
-static u32 step;
-#ifdef MIX_STREAM_SUPPORT
-static u32 buf_alloc_width = 4096;
-static u32 buf_alloc_height = 2304;
-static u32 av1_max_pic_w = 4096;
-static u32 av1_max_pic_h = 2304;
-
-static u32 dynamic_buf_num_margin = 3;
-#else
-static u32 buf_alloc_width;
-static u32 buf_alloc_height;
-static u32 dynamic_buf_num_margin = 7;
-#endif
-static u32 buf_alloc_depth = 10;
-static u32 buf_alloc_size;
-/*
- *bit[0]: 0,
- * bit[1]: 0, always release cma buffer when stop
- * bit[1]: 1, never release cma buffer when stop
- *bit[0]: 1, when stop, release cma buffer if blackout is 1;
- *do not release cma buffer is blackout is not 1
- *
- *bit[2]: 0, when start decoding, check current displayed buffer
- * (only for buffer decoded by AV1) if blackout is 0
- * 1, do not check current displayed buffer
- *
- *bit[3]: 1, if blackout is not 1, do not release current
- * displayed cma buffer always.
- */
-/* set to 1 for fast play;
- * set to 8 for other case of "keep last frame"
- */
-static u32 buffer_mode = 1;
-/* buffer_mode_dbg: debug only*/
-static u32 buffer_mode_dbg = 0xffff0000;
-/**/
-
-/*
- *bit 0, 1: only display I picture;
- *bit 1, 1: only decode I picture;
- */
-static u32 i_only_flag;
-
-static u32 low_latency_flag;
-
-static u32 no_head;
-
-static u32 max_decoding_time;
-/*
- *error handling
- */
-/*error_handle_policy:
- *bit 0: 0, auto skip error_skip_nal_count nals before error recovery;
- *1, skip error_skip_nal_count nals before error recovery;
- *bit 1 (valid only when bit0 == 1):
- *1, wait vps/sps/pps after error recovery;
- *bit 2 (valid only when bit0 == 0):
- *0, auto search after error recovery (av1_recover() called);
- *1, manual search after error recovery
- *(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2))
- *
- *bit 4: 0, set error_mark after reset/recover
- * 1, do not set error_mark after reset/recover
- *bit 5: 0, check total lcu for every picture
- * 1, do not check total lcu
- *
- */
-
-static u32 error_handle_policy;
-/*static u32 parser_sei_enable = 1;*/
-#define MAX_BUF_NUM_NORMAL 16
-/*less bufs num 12 caused frame drop, nts failed*/
-#define MAX_BUF_NUM_LESS 14
-static u32 max_buf_num = MAX_BUF_NUM_NORMAL;
-#define MAX_BUF_NUM_SAVE_BUF 8
-
-static DEFINE_MUTEX(vav1_mutex);
-#ifndef MULTI_INSTANCE_SUPPORT
-static struct device *cma_dev;
-#endif
-#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
-#define HEVC_FG_STATUS HEVC_ASSIST_SCRATCH_B
-#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
-#define AOM_AV1_ADAPT_PROB_REG HEVC_ASSIST_SCRATCH_3
-#define AOM_AV1_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_4 // changed to use HEVC_ASSIST_MMU_MAP_ADDR
-#define AOM_AV1_DAALA_TOP_BUFFER HEVC_ASSIST_SCRATCH_5
-//#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
-//#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
-#define AOM_AV1_CDF_BUFFER_W HEVC_ASSIST_SCRATCH_8
-#define AOM_AV1_CDF_BUFFER_R HEVC_ASSIST_SCRATCH_9
-#define AOM_AV1_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
-#define AOM_AV1_SEG_MAP_BUFFER_W AV1_SEG_W_ADDR // HEVC_ASSIST_SCRATCH_B
-#define AOM_AV1_SEG_MAP_BUFFER_R AV1_SEG_R_ADDR // HEVC_ASSIST_SCRATCH_C
-//#define HEVC_sao_vb_size HEVC_ASSIST_SCRATCH_B
-//#define HEVC_SAO_VB HEVC_ASSIST_SCRATCH_C
-//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
-#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
-#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
-//#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M
-#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
-#else
-#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M
-#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N
-#endif
-#define AOM_AV1_SEGMENT_FEATURE AV1_QUANT_WR
-
-#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
-#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
-
-#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_I
-#define CUR_NAL_UNIT_TYPE HEVC_ASSIST_SCRATCH_J
-#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
-
-#define PIC_END_LCU_COUNT HEVC_ASSIST_SCRATCH_2
-
-#define HEVC_AUX_ADR HEVC_ASSIST_SCRATCH_L
-#define HEVC_AUX_DATA_SIZE HEVC_ASSIST_SCRATCH_7
-#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
-#define HEVC_DBG_LOG_ADR HEVC_ASSIST_SCRATCH_C
-#ifdef DEBUG_CMD
-#define HEVC_D_ADR HEVC_ASSIST_SCRATCH_4
-#endif
-#endif
-/*
- *ucode parser/search control
- *bit 0: 0, header auto parse; 1, header manual parse
- *bit 1: 0, auto skip for noneseamless stream; 1, no skip
- *bit [3:2]: valid when bit1==0;
- *0, auto skip nal before first vps/sps/pps/idr;
- *1, auto skip nal before first vps/sps/pps
- *2, auto skip nal before first vps/sps/pps,
- * and not decode until the first I slice (with slice address of 0)
- *
- *3, auto skip before first I slice (nal_type >=16 && nal_type<=21)
- *bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
- *bit [16]: for NAL_UNIT_EOS when bit0 is 0:
- * 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
- *bit [17]: for NAL_SEI when bit0 is 0:
- * 0, do not parse SEI in ucode; 1, parse SEI in ucode
- *bit [31:20]: used by ucode for debug purpose
- */
-#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
- /*[31:24] chip feature
- 31: 0, use MBOX1; 1, use MBOX0
- [24:16] debug
- 0x1, bufmgr only
- */
-#define DECODE_MODE HEVC_ASSIST_SCRATCH_J
-#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
-
-#define RPM_BUF_SIZE ((RPM_END - RPM_BEGIN) * 2)
-#define LMEM_BUF_SIZE (0x600 * 2)
-
-/*
-#ifdef MAP_8K
-static u32 seg_map_size = 0xd8000;
-#else
-static u32 seg_map_size = 0x36000;
-#endif
-*/
-//static u32 seg_map_size = 0x36000;
-
-//#define VBH_BUF_COUNT 4
-//#define VBH_BUF_SIZE_1080P ((((2 * 16 * 1088) + 0xffff) & (~0xffff)) * VBH_BUF_COUNT)
-//#define VBH_BUF_SIZE_4K ((((2 * 16 * 2304) + 0xffff) & (~0xffff))) * VBH_BUF_COUNT)
-//#define VBH_BUF_SIZE_8K ((((2 * 16 * 4608) + 0xffff) & (~0xffff))) * VBH_BUF_COUNT)
-
- /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
-#define VBH_BUF_SIZE_1080P 0x3000
-#define VBH_BUF_SIZE_4K 0x5000
-#define VBH_BUF_SIZE_8K 0xa000
-#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
- /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
- HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
-#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
-#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
-#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
-#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-
-/* necessary 4K page size align for t7/t3 decoder and after. fix case1440 dec timeout */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 3
-
-static struct BuffInfo_s aom_workbuff_spec[WORK_BUF_SPEC_NUM] = {
- { //8M bytes
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x1E00,
- },
- .sao_abv = {
- .buf_size = 0x0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0x0, //0x30000,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .seg_map = {
- // SEGMENT MAP AREA - 1920x1088/4/4 * 3 bits = 0xBF40 Bytes * 16 = 0xBF400
- .buf_size = 0xBF400,
- },
- .daala_top = {
- // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
- .buf_size = 0xf00,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x0, //0x2800,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .cdf_buf = {
- // for context store/load 1024x256 x16 = 512K bytes 16*0x8000
- .buf_size = 0x80000,
- },
- .gmc_buf = {
- // for gmc_parameter store/load 128 x 16 = 2K bytes 0x800
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x0, //0x8000,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0xd00, /*0xc40*/
- },
- .dblk_data = {
- .buf_size = 0x49000,
- },
- .cdef_data = {
- .buf_size = 0x22400,
- },
- .ups_data = {
- .buf_size = 0x36000,
- },
- .fgs_table = {
- .buf_size = FGS_TABLE_SIZE * FRAME_BUFFERS, // 512x128bits
- },
-#ifdef AOM_AV1_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_1080P, //2*16*(more than 2304)/4, 4K
- },
- .cm_header = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P * FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- #else
- .buf_size = 0,
- #endif
- },
-#endif
-#ifdef AOM_AV1_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_1080P, //2*16*(more than 2304)/4, 4K
- },
- .cm_header_dw = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_1080P*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- #else
- .buf_size = 0,
- #endif
- },
-#endif
- .mpred_above = {
- .buf_size = 0x2800, /*round from 0x2760*/ /* 2 * size of hw*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- .buf_size = MAX_ONE_MV_BUFFER_SIZE_1080P_TM2REVB * FRAME_BUFFERS,/*round from 203A0*/ //1080p, 0x40000 per buffer
- },
-#endif
- .rpm = {
- .buf_size = 0x80*2,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
-#ifdef VPU_FILMGRAIN_DUMP
- .max_width = 640,
- .max_height = 480,
-#else
- .max_width = 4096,
- .max_height = 2304,
-#endif
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0x0, //0x30000,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .seg_map = {
- // SEGMENT MAP AREA - 4096x2304/4/4 * 3 bits = 0x36000 Bytes * 16 = 0x360000
- .buf_size = 0x360000,
- },
- .daala_top = {
- // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x0, //0x2800,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .cdf_buf = {
- // for context store/load 1024x256 x16 = 512K bytes 16*0x8000
- .buf_size = 0x80000,
- },
- .gmc_buf = {
- // for gmc_parameter store/load 128 x 16 = 2K bytes 0x800
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x0, //0x8000,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0x1a00, /*0x1980*/
- },
- .dblk_data = {
- .buf_size = 0x52800,
- },
- .cdef_data = {
- .buf_size = 0x24a00,
- },
- .ups_data = {
- .buf_size = 0x6f000,
- },
- .fgs_table = {
- .buf_size = FGS_TABLE_SIZE * FRAME_BUFFERS, // 512x128bits
- },
-#ifdef AOM_AV1_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_4K, //2*16*(more than 2304)/4, 4K
- },
- .cm_header = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_4K*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- #else
- .buf_size = 0,
- #endif
- },
-#endif
-#ifdef AOM_AV1_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_4K, //2*16*(more than 2304)/4, 4K
- },
- .cm_header_dw = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_4K*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- #else
- .buf_size = 0,
- #endif
- },
-#endif
- .mpred_above = {
- .buf_size = 0x5400, /* 2 * size of hw*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = MAX_ONE_MV_BUFFER_SIZE_4K_TM2REVB * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = 0x80*2,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
-
- },
- {
- .max_width = 8192,
- .max_height = 4608,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x0, //0x30000,
- },
- .sao_vb = {
- .buf_size = 0x0, //0x30000,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .seg_map = {
- // SEGMENT MAP AREA - 4096x2304/4/4 * 3 bits = 0x36000 Bytes * 16 = 0x360000
- .buf_size = 0xd80000,
- },
- .daala_top = {
- // DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x0, //0x2800,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .cdf_buf = {
- // for context store/load 1024x256 x16 = 512K bytes 16*0x8000
- .buf_size = 0x80000,
- },
- .gmc_buf = {
- // for gmc_parameter store/load 128 x 16 = 2K bytes 0x800
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x0, //0x8000,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0x3300, /*0x32a0*/
- },
- .dblk_data = {
- .buf_size = 0xa4800,
- },
- .cdef_data = {
- .buf_size = 0x29200,
- },
- .ups_data = {
- .buf_size = 0xdb000,
- },
- .fgs_table = {
- .buf_size = FGS_TABLE_SIZE * FRAME_BUFFERS, // 512x128bits
- },
-#ifdef AOM_AV1_MMU
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_8K, //2*16*(more than 2304)/4, 4K
- },
- .cm_header = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_8K*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
-#else
- .buf_size = 0,
-#endif
- },
-#endif
-#ifdef AOM_AV1_MMU_DW
- .mmu_vbh_dw = {
- .buf_size = DW_VBH_BUF_SIZE_8K, //2*16*(more than 2304)/4, 4K
- },
- .cm_header_dw = {
- #ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- .buf_size = MMU_COMPRESS_HEADER_SIZE_8K*FRAME_BUFFERS, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- #else
- .buf_size = 0,
- #endif
- },
-#endif
- .mpred_above = {
- .buf_size = 0xA800, /* 2 * size of hw*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = MAX_ONE_MV_BUFFER_SIZE_8K_TM2REVB * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = 0x80*2,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
-
- }
-};
-
-
-/*
-* AUX DATA Process
-*/
-static u32 init_aux_size;
-static int aux_data_is_avaible(struct AV1HW_s *hw)
-{
- u32 reg_val;
-
- reg_val = READ_VREG(HEVC_AUX_DATA_SIZE);
- if (reg_val != 0 && reg_val != init_aux_size)
- return 1;
- else
- return 0;
-}
-
-static void config_aux_buf(struct AV1HW_s *hw)
-{
- WRITE_VREG(HEVC_AUX_ADR, hw->aux_phy_addr);
- init_aux_size = ((hw->prefix_aux_size >> 4) << 16) |
- (hw->suffix_aux_size >> 4);
- WRITE_VREG(HEVC_AUX_DATA_SIZE, init_aux_size);
-}
-
-/*
-* dv_meta_flag: 1, dolby meta (T35) only; 2, not include dolby meta (T35)
-*/
-static void set_aux_data(struct AV1HW_s *hw,
- char **aux_data_buf, int *aux_data_size,
- unsigned char suffix_flag,
- unsigned char dv_meta_flag)
-{
- int i;
- unsigned short *aux_adr;
- unsigned int size_reg_val =
- READ_VREG(HEVC_AUX_DATA_SIZE);
- unsigned int aux_count = 0;
- int aux_size = 0;
- if (0 == aux_data_is_avaible(hw))
- return;
-
- if (hw->aux_data_dirty ||
- hw->m_ins_flag == 0) {
-
- hw->aux_data_dirty = 0;
- }
-
- if (suffix_flag) {
- aux_adr = (unsigned short *)
- (hw->aux_addr +
- hw->prefix_aux_size);
- aux_count =
- ((size_reg_val & 0xffff) << 4)
- >> 1;
- aux_size =
- hw->suffix_aux_size;
- } else {
- aux_adr =
- (unsigned short *)hw->aux_addr;
- aux_count =
- ((size_reg_val >> 16) << 4)
- >> 1;
- aux_size =
- hw->prefix_aux_size;
- }
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- av1_print(hw, 0,
- "%s:old size %d count %d,suf %d dv_flag %d\r\n",
- __func__, *aux_data_size,
- aux_count, suffix_flag, dv_meta_flag);
- }
- if (aux_size > 0 && aux_count > 0) {
- int heads_size = 0;
-
- for (i = 0; i < aux_count; i++) {
- unsigned char tag = aux_adr[i] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- heads_size += 8;
- else if (dv_meta_flag == 1 && tag == 0x14)
- heads_size += 8;
- else if (dv_meta_flag == 2 && tag != 0x14)
- heads_size += 8;
- }
- }
-
- if (*aux_data_buf) {
- unsigned char valid_tag = 0;
- unsigned char *h =
- *aux_data_buf +
- *aux_data_size;
- unsigned char *p = h + 8;
- int len = 0;
- int padding_len = 0;
-
- for (i = 0; i < aux_count; i += 4) {
- int ii;
- unsigned char tag = aux_adr[i + 3] >> 8;
- if (tag != 0 && tag != 0xff) {
- if (dv_meta_flag == 0)
- valid_tag = 1;
- else if (dv_meta_flag == 1
- && tag == 0x14)
- valid_tag = 1;
- else if (dv_meta_flag == 2
- && tag != 0x14)
- valid_tag = 1;
- else
- valid_tag = 0;
- if (valid_tag && len > 0) {
- *aux_data_size +=
- (len + 8);
- h[0] = (len >> 24)
- & 0xff;
- h[1] = (len >> 16)
- & 0xff;
- h[2] = (len >> 8)
- & 0xff;
- h[3] = (len >> 0)
- & 0xff;
- h[6] =
- (padding_len >> 8)
- & 0xff;
- h[7] = (padding_len)
- & 0xff;
- h += (len + 8);
- p += 8;
- len = 0;
- padding_len = 0;
- }
- if (valid_tag) {
- h[4] = tag;
- h[5] = 0;
- h[6] = 0;
- h[7] = 0;
- }
- }
- if (valid_tag) {
- for (ii = 0; ii < 4; ii++) {
- unsigned short aa =
- aux_adr[i + 3
- - ii];
- *p = aa & 0xff;
- p++;
- len++;
- if ((aa >> 8) == 0xff)
- padding_len++;
- }
- }
- }
- if (len > 0) {
- *aux_data_size += (len + 8);
- h[0] = (len >> 24) & 0xff;
- h[1] = (len >> 16) & 0xff;
- h[2] = (len >> 8) & 0xff;
- h[3] = (len >> 0) & 0xff;
- h[6] = (padding_len >> 8) & 0xff;
- h[7] = (padding_len) & 0xff;
- }
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- av1_print(hw, 0,
- "aux: (size %d) suffix_flag %d\n",
- *aux_data_size, suffix_flag);
- for (i = 0; i < *aux_data_size; i++) {
- av1_print_cont(hw, 0,
- "%02x ", (*aux_data_buf)[i]);
- if (((i + 1) & 0xf) == 0)
- av1_print_cont(hw, 0, "\n");
- }
- av1_print_cont(hw, 0, "\n");
- }
- }
- }
-
-}
-
-static void set_dv_data(struct AV1HW_s *hw)
-{
- set_aux_data(hw, &hw->dv_data_buf,
- &hw->dv_data_size, 0, 1);
-
-}
-
-static void set_pic_aux_data(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic, unsigned char suffix_flag,
- unsigned char dv_meta_flag)
-{
- if (pic == NULL)
- return;
- set_aux_data(hw, &pic->aux_data_buf,
- &pic->aux_data_size, suffix_flag, dv_meta_flag);
-}
-
-static void copy_dv_data(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic)
-{
- if (pic->aux_data_buf) {
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- av1_print(hw, 0,
- "%s: (size %d) pic index %d\n",
- __func__,
- hw->dv_data_size, pic->index);
- }
- memcpy(pic->aux_data_buf + pic->aux_data_size, hw->dv_data_buf, hw->dv_data_size);
- pic->aux_data_size += hw->dv_data_size;
- memset(hw->dv_data_buf, 0, hw->aux_data_size);
- hw->dv_data_size = 0;
- }
-}
-
-static void release_aux_data(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic)
-{
-#if 0
- if (pic->aux_data_buf)
- vfree(pic->aux_data_buf);
- pic->aux_data_buf = NULL;
- pic->aux_data_size = 0;
-#endif
-}
-
-static void dump_aux_buf(struct AV1HW_s *hw)
-{
- int i;
- unsigned short *aux_adr =
- (unsigned short *)
- hw->aux_addr;
- unsigned int aux_size =
- (READ_VREG(HEVC_AUX_DATA_SIZE)
- >> 16) << 4;
-
- if (hw->prefix_aux_size > 0) {
- av1_print(hw, 0,
- "prefix aux: (size %d)\n",
- aux_size);
- for (i = 0; i <
- (aux_size >> 1); i++) {
- av1_print_cont(hw, 0,
- "%04x ",
- *(aux_adr + i));
- if (((i + 1) & 0xf)
- == 0)
- av1_print_cont(hw,
- 0, "\n");
- }
- }
- if (hw->suffix_aux_size > 0) {
- aux_adr = (unsigned short *)
- (hw->aux_addr +
- hw->prefix_aux_size);
- aux_size =
- (READ_VREG(HEVC_AUX_DATA_SIZE) & 0xffff)
- << 4;
- av1_print(hw, 0,
- "suffix aux: (size %d)\n",
- aux_size);
- for (i = 0; i <
- (aux_size >> 1); i++) {
- av1_print_cont(hw, 0,
- "%04x ", *(aux_adr + i));
- if (((i + 1) & 0xf) == 0)
- av1_print_cont(hw, 0, "\n");
- }
- }
-}
-
-/*
-*
-*/
-
-/*Losless compression body buffer size 4K per 64x32 (jt)*/
-static int compute_losless_comp_body_size(int width, int height,
- uint8_t is_bit_depth_10)
-{
- int width_x64;
- int height_x32;
- int bsize;
-
- width_x64 = width + 63;
- width_x64 >>= 6;
- height_x32 = height + 31;
- height_x32 >>= 5;
- bsize = (is_bit_depth_10?4096:3200)*width_x64*height_x32;
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info("%s(%d,%d,%d)=>%d\n",
- __func__, width, height,
- is_bit_depth_10, bsize);
-
- return bsize;
-}
-
-/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
-static int compute_losless_comp_header_size(int width, int height)
-{
- int width_x128;
- int height_x64;
- int hsize;
-
- width_x128 = width + 127;
- width_x128 >>= 7;
- height_x64 = height + 63;
- height_x64 >>= 6;
-
- hsize = 32 * width_x128 * height_x64;
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info("%s(%d,%d)=>%d\n",
- __func__, width, height,
- hsize);
-
- return hsize;
-}
-
-#ifdef AOM_AV1_MMU_DW
-static int compute_losless_comp_body_size_dw(int width, int height,
- uint8_t is_bit_depth_10)
-{
-
- return compute_losless_comp_body_size(width, height, is_bit_depth_10);
-}
-
-/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
-static int compute_losless_comp_header_size_dw(int width, int height)
-{
- return compute_losless_comp_header_size(width, height);
-}
-#endif
-
-static void init_buff_spec(struct AV1HW_s *hw,
- struct BuffInfo_s *buf_spec)
-{
- void *mem_start_virt;
-
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
- buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
- buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
- buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
- buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
- buf_spec->seg_map.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
- buf_spec->daala_top.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
- buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->daala_top.buf_start + buf_spec->daala_top.buf_size);
- buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
- buf_spec->cdf_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
- buf_spec->gmc_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->cdf_buf.buf_start + buf_spec->cdf_buf.buf_size);
- buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->gmc_buf.buf_start + buf_spec->gmc_buf.buf_size);
- buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
- buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
- buf_spec->cdef_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
- buf_spec->ups_data.buf_start =
- WORKBUF_ALIGN(buf_spec->cdef_data.buf_start + buf_spec->cdef_data.buf_size);
- buf_spec->fgs_table.buf_start =
- WORKBUF_ALIGN(buf_spec->ups_data.buf_start + buf_spec->ups_data.buf_size);
-#ifdef AOM_AV1_MMU
- buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size);
- buf_spec->cm_header.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-#ifdef AOM_AV1_MMU_DW
- buf_spec->mmu_vbh_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size);
- buf_spec->cm_header_dw.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header_dw.buf_start + buf_spec->cm_header_dw.buf_size);
-#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->cm_header.buf_start + buf_spec->cm_header.buf_size);
-#endif
-#else
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->fgs_table.buf_start + buf_spec->fgs_table.buf_size);
-#endif
-#ifdef MV_USE_FIXED_BUF
- buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
-#else
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
-#endif
- buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
- buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
-
- if (!hw)
- return;
-
- if (!vdec_secure(hw_to_vdec(hw))) {
- mem_start_virt =
- codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
- if (mem_start_virt) {
- memset(mem_start_virt, 0,
- buf_spec->dblk_para.buf_size);
- codec_mm_dma_flush(mem_start_virt,
- buf_spec->dblk_para.buf_size,
- DMA_TO_DEVICE);
- } else {
- mem_start_virt = codec_mm_vmap(
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_para.buf_size);
- if (mem_start_virt) {
- memset(mem_start_virt, 0,
- buf_spec->dblk_para.buf_size);
- codec_mm_dma_flush(mem_start_virt,
- buf_spec->dblk_para.buf_size,
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(mem_start_virt);
- } else {
- /*not virt for tvp playing,
- may need clear on ucode.*/
- pr_err("mem_start_virt failed\n");
- }
- }
- }
-
- if (debug) {
- pr_info("%s workspace (%x %x) size = %x\n", __func__,
- buf_spec->start_adr, buf_spec->end_adr,
- buf_spec->end_adr - buf_spec->start_adr);
- }
-
- if (debug) {
- pr_info("ipp.buf_start :%x\n",
- buf_spec->ipp.buf_start);
- pr_info("sao_abv.buf_start :%x\n",
- buf_spec->sao_abv.buf_start);
- pr_info("sao_vb.buf_start :%x\n",
- buf_spec->sao_vb.buf_start);
- pr_info("short_term_rps.buf_start :%x\n",
- buf_spec->short_term_rps.buf_start);
- pr_info("vps.buf_start :%x\n",
- buf_spec->vps.buf_start);
- pr_info("seg_map.buf_start :%x\n",
- buf_spec->seg_map.buf_start);
- pr_info("daala_top.buf_start :%x\n",
- buf_spec->daala_top.buf_start);
- pr_info("swap_buf.buf_start :%x\n",
- buf_spec->swap_buf.buf_start);
- pr_info("cdf_buf.buf_start :%x\n",
- buf_spec->cdf_buf.buf_start);
- pr_info("gmc_buf.buf_start :%x\n",
- buf_spec->gmc_buf.buf_start);
- pr_info("scalelut.buf_start :%x\n",
- buf_spec->scalelut.buf_start);
- pr_info("dblk_para.buf_start :%x\n",
- buf_spec->dblk_para.buf_start);
- pr_info("dblk_data.buf_start :%x\n",
- buf_spec->dblk_data.buf_start);
- pr_info("cdef_data.buf_start :%x\n",
- buf_spec->cdef_data.buf_start);
- pr_info("ups_data.buf_start :%x\n",
- buf_spec->ups_data.buf_start);
-
-#ifdef AOM_AV1_MMU
- pr_info("mmu_vbh.buf_start :%x\n",
- buf_spec->mmu_vbh.buf_start);
-#endif
- pr_info("mpred_above.buf_start :%x\n",
- buf_spec->mpred_above.buf_start);
-#ifdef MV_USE_FIXED_BUF
- pr_info("mpred_mv.buf_start :%x\n",
- buf_spec->mpred_mv.buf_start);
-#endif
- if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0) {
- pr_info("rpm.buf_start :%x\n",
- buf_spec->rpm.buf_start);
- }
- }
-}
-
-static void uninit_mmu_buffers(struct AV1HW_s *hw)
-{
-#ifndef MV_USE_FIXED_BUF
- dealloc_mv_bufs(hw);
-#endif
- if (hw->mmu_box)
- decoder_mmu_box_free(hw->mmu_box);
- hw->mmu_box = NULL;
-
-#ifdef AOM_AV1_MMU_DW
- if (hw->mmu_box_dw)
- decoder_mmu_box_free(hw->mmu_box_dw);
- hw->mmu_box_dw = NULL;
-#endif
- if (hw->bmmu_box)
- decoder_bmmu_box_free(hw->bmmu_box);
- hw->bmmu_box = NULL;
-}
-
-static int calc_luc_quantity(int lcu_size, u32 w, u32 h)
-{
- int pic_width_64 = (w + 63) & (~0x3f);
- int pic_height_32 = (h + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1 : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1 : pic_height_32 / lcu_size;
-
- return pic_width_lcu * pic_height_lcu;
-}
-
-/* return in MB */
-static int av1_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 48;
-
- if ((max_w * max_h > 1280*736) &&
- (max_w * max_h <= 1920*1088)) {
- buf_size = 12;
- } else if ((max_w * max_h > 0) &&
- (max_w * max_h <= 1280*736)) {
- buf_size = 4;
- }
-
- return buf_size;
-}
-
-static int av1_get_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(w, h))
- return MMU_COMPRESS_HEADER_SIZE_8K;
- if (IS_4K_SIZE(w, h))
- return MMU_COMPRESS_HEADER_SIZE_4K;
-
- return MMU_COMPRESS_HEADER_SIZE_1080P;
-}
-
-static void av1_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vav1_vf_put(vf, vdec_ctx);
-}
-
-static void av1_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vav1_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = av1_get_video_frame,
- .put_vframe = av1_put_video_frame,
-};
-
-static int v4l_alloc_and_config_pic(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic)
-{
- int ret = -1;
- int i = pic->index;
- int dw_mode = get_double_write_mode_init(hw);
- int lcu_total = calc_luc_quantity(hw->current_lcu_size,
- hw->frame_width, hw->frame_height);
-#ifdef MV_USE_FIXED_BUF
- u32 mpred_mv_end = hw->work_space_buf->mpred_mv.buf_start +
- hw->work_space_buf->mpred_mv.buf_size;
-//#ifdef USE_DYNAMIC_MV_BUFFER
-// int32_t MV_MEM_UNIT = (lcu_size == 128) ? (19*4*16) : (19*16);
-// int32_t mv_buffer_size = (lcu_total*MV_MEM_UNIT);
-//#else
- int32_t mv_buffer_size = hw->max_one_mv_buffer_size;
-//#endif
-#endif
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- if (i < 0)
- return ret;
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, hw->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- av1_print(hw, 0, "[%d] AV1 get buffer fail.\n", ctx->id);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, hw);
- fb->status = FB_ST_DECODER;
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hw, fb);
-
- hw->m_BUF[i].header_addr = ibuf->header_addr;
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_adr %d: %ld\n",
- i, hw->m_BUF[i].header_addr);
- }
- }
-
- if (get_double_write_mode(hw) & 0x20) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(hw, fb);
-
- hw->m_BUF[i].header_dw_addr = ibuf->header_dw_addr;
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_adr %d: %ld\n",
- i, hw->m_BUF[i].header_addr);
- }
- }
- pic->repeat_pic = NULL;
- pic->repeat_count = 0;
-#ifdef MV_USE_FIXED_BUF
- if ((hw->work_space_buf->mpred_mv.buf_start +
- ((i + 1) * mv_buffer_size))
- <= mpred_mv_end) {
-#endif
- hw->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
- pic->cma_alloc_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1) {
- hw->m_BUF[i].start_adr = fb->m.mem[0].addr;
- hw->m_BUF[i].luma_size = fb->m.mem[0].offset;
- hw->m_BUF[i].size = fb->m.mem[0].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- pic->dw_y_adr = hw->m_BUF[i].start_adr;
- pic->dw_u_v_adr = pic->dw_y_adr + hw->m_BUF[i].luma_size;
- } else if (fb->num_planes == 2) {
- hw->m_BUF[i].start_adr = fb->m.mem[0].addr;
- hw->m_BUF[i].size = fb->m.mem[0].size;
- hw->m_BUF[i].chroma_addr = fb->m.mem[1].addr;
- hw->m_BUF[i].chroma_size = fb->m.mem[1].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- pic->dw_y_adr = hw->m_BUF[i].start_adr;
- pic->dw_u_v_adr = hw->m_BUF[i].chroma_addr;
- }
-
- /* config frame buffer */
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- pic->header_adr = hw->m_BUF[i].header_addr;
- }
-
- if (get_double_write_mode(hw) & 0x20) {
- pic->header_dw_adr = hw->m_BUF[i].header_dw_addr;
- }
-
- pic->BUF_index = i;
- pic->lcu_total = lcu_total;
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
-
- if (dw_mode & 0x10) {
- pic->mc_canvas_y = (pic->index << 1);
- pic->mc_canvas_u_v = (pic->index << 1) + 1;
- }
-
-#ifdef MV_USE_FIXED_BUF
- pic->mpred_mv_wr_start_addr =
- hw->work_space_buf->mpred_mv.buf_start +
- (pic->index * mv_buffer_size);
-#endif
-
-#ifdef DUMP_FILMGRAIN
- if (pic->index == fg_dump_index) {
- pic->fgs_table_adr = hw->fg_phy_addr;
- pr_info("set buffer %d film grain table 0x%x\n",
- pic->index, pic->fgs_table_adr);
- } else {
-#endif
- if (hw->assit_task.use_sfgs) {
- pic->sfgs_table_phy = hw->fg_phy_addr + (pic->index * FGS_TABLE_SIZE);
- pic->sfgs_table_ptr = hw->fg_ptr + (pic->index * FGS_TABLE_SIZE);
- }
- pic->fgs_table_adr = hw->work_space_buf->fgs_table.buf_start +
- (pic->index * FGS_TABLE_SIZE);
- }
-
- if (debug) {
-
- pr_info("%s index %d BUF_index %d ",
- __func__, pic->index,
- pic->BUF_index);
- pr_info("comp_body_size %x comp_buf_size %x ",
- pic->comp_body_size,
- pic->buf_size);
- pr_info("mpred_mv_wr_start_adr %d\n",
- pic->mpred_mv_wr_start_addr);
- pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n",
- pic->dw_y_adr,
- pic->dw_u_v_adr);
- }
-#ifdef MV_USE_FIXED_BUF
- }
-#endif
- return ret;
-}
-
-static int config_pic(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- int ret = -1;
- int i;
- int pic_width = hw->init_pic_w;
- int pic_height = hw->init_pic_h;
- //int lcu_size = ((params->p.seq_flags >> 6) & 0x1) ? 128 : 64;
- int lcu_size = hw->current_lcu_size;
-
- int pic_width_64 = (pic_width + 63) & (~0x3f);
- int pic_height_32 = (pic_height + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1
- : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1
- : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
-#ifdef MV_USE_FIXED_BUF
- u32 mpred_mv_end = hw->work_space_buf->mpred_mv.buf_start +
- hw->work_space_buf->mpred_mv.buf_size;
-//#ifdef USE_DYNAMIC_MV_BUFFER
-// int32_t MV_MEM_UNIT = (lcu_size == 128) ? (19*4*16) : (19*16);
-// int32_t mv_buffer_size = (lcu_total*MV_MEM_UNIT);
-//#else
- int32_t mv_buffer_size = hw->max_one_mv_buffer_size;
-//#endif
-
-#endif
-
- u32 y_adr = 0;
- int buf_size = 0;
-
- int losless_comp_header_size =
- compute_losless_comp_header_size(pic_width,
- pic_height);
- int losless_comp_body_size = compute_losless_comp_body_size(pic_width,
- pic_height, buf_alloc_depth == 10);
- int mc_buffer_size = losless_comp_header_size + losless_comp_body_size;
- int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16;
- int mc_buffer_size_u_v = 0;
- int mc_buffer_size_u_v_h = 0;
- int dw_mode = get_double_write_mode_init(hw);
-
- hw->lcu_total = lcu_total;
-
- if (dw_mode && (dw_mode & 0x20) == 0) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode & 0xf);
- int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode & 0xf);
-
- int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
- int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
- int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ?
- pic_width_64_dw / lcu_size + 1
- : pic_width_64_dw / lcu_size;
- int pic_height_lcu_dw = (pic_height_32_dw % lcu_size) ?
- pic_height_32_dw / lcu_size + 1
- : pic_height_32_dw / lcu_size;
- int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
- mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2;
- mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
- buf_size = ((buf_size + 0xffff) >> 16) << 16;
- }
-
- if (mc_buffer_size & 0xffff) /*64k alignment*/
- mc_buffer_size_h += 1;
- if ((!hw->mmu_enable) && ((dw_mode & 0x10) == 0))
- buf_size += (mc_buffer_size_h << 16);
-
-#ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- if (hw->mmu_enable) {
- pic_config->header_adr =
- hw->work_space_buf->cm_header.buf_start +
- (pic_config->index * vav1_mmu_compress_header_size(hw));
-
-#ifdef AOM_AV1_MMU_DW
- if (hw->dw_mmu_enable) {
- pic_config->header_dw_adr =
- hw->work_space_buf->cm_header_dw.buf_start +
- (pic_config->index * vav1_mmu_compress_header_size(hw));
-
- }
-#endif
- }
-
-#else
-/*!USE_SPEC_BUF_FOR_MMU_HEAD*/
- if (hw->mmu_enable) {
- pic_config->header_adr = decoder_bmmu_box_get_phy_addr(
- hw->bmmu_box, HEADER_BUFFER_IDX(pic_config->index));
-
-#ifdef AOM_AV1_MMU_DW
- if (hw->dw_mmu_enable) {
- pic_config->header_dw_adr = decoder_bmmu_box_get_phy_addr(
- hw->bmmu_box, DW_HEADER_BUFFER_IDX(pic_config->index));
-
- }
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- pr_info("MMU dw header_adr (%d, %d) %d: %d\n",
- hw->dw_mmu_enable,
- DW_HEADER_BUFFER_IDX(pic_config->index),
- pic_config->index,
- pic_config->header_dw_adr);
- }
-#endif
-
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_adr %d: %d\n",
- pic_config->index, pic_config->header_adr);
- }
- }
-#endif
-
- i = pic_config->index;
-#ifdef MV_USE_FIXED_BUF
- if ((hw->work_space_buf->mpred_mv.buf_start +
- ((i + 1) * mv_buffer_size))
- <= mpred_mv_end
- ) {
-#endif
- if (buf_size > 0) {
- ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box,
- VF_BUFFER_IDX(i),
- buf_size, DRIVER_NAME,
- &pic_config->cma_alloc_addr);
- if (ret < 0) {
- pr_info(
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return ret;
- }
-
- if (pic_config->cma_alloc_addr)
- y_adr = pic_config->cma_alloc_addr;
- else {
- pr_info(
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return -1;
- }
- }
- {
- /*ensure get_pic_by_POC()
- not get the buffer not decoded*/
- pic_config->BUF_index = i;
- pic_config->lcu_total = lcu_total;
-
- pic_config->comp_body_size = losless_comp_body_size;
- pic_config->buf_size = buf_size;
-
- pic_config->mc_canvas_y = pic_config->index;
- pic_config->mc_canvas_u_v = pic_config->index;
- if (dw_mode & 0x10) {
- pic_config->dw_y_adr = y_adr;
- pic_config->dw_u_v_adr = y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
-
- pic_config->mc_canvas_y =
- (pic_config->index << 1);
- pic_config->mc_canvas_u_v =
- (pic_config->index << 1) + 1;
- } else if (dw_mode && (dw_mode & 0x20) == 0) {
- pic_config->dw_y_adr = y_adr;
- pic_config->dw_u_v_adr = pic_config->dw_y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
- }
-#ifdef MV_USE_FIXED_BUF
- pic_config->mpred_mv_wr_start_addr =
- hw->work_space_buf->mpred_mv.buf_start +
- (pic_config->index * mv_buffer_size);
-#endif
-#ifdef DUMP_FILMGRAIN
- if (pic_config->index == fg_dump_index) {
- pic_config->fgs_table_adr = hw->fg_phy_addr;
- pr_info("set buffer %d film grain table 0x%x\n",
- pic_config->index, pic_config->fgs_table_adr);
- } else {
-#endif
- if (hw->assit_task.use_sfgs) {
- pic_config->sfgs_table_phy = hw->fg_phy_addr + (pic_config->index * FGS_TABLE_SIZE);
- pic_config->sfgs_table_ptr = hw->fg_ptr + (pic_config->index * FGS_TABLE_SIZE);
- }
- pic_config->fgs_table_adr =
- hw->work_space_buf->fgs_table.buf_start +
- (pic_config->index * FGS_TABLE_SIZE);
- }
-
- if (debug) {
- pr_info
- ("%s index %d BUF_index %d ",
- __func__, pic_config->index,
- pic_config->BUF_index);
- pr_info
- ("comp_body_size %x comp_buf_size %x ",
- pic_config->comp_body_size,
- pic_config->buf_size);
- pr_info
- ("mpred_mv_wr_start_adr %d\n",
- pic_config->mpred_mv_wr_start_addr);
- pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n",
- pic_config->dw_y_adr,
- pic_config->dw_u_v_adr);
- }
- ret = 0;
- }
-#ifdef MV_USE_FIXED_BUF
- }
-#endif
- return ret;
-}
-
-#ifndef USE_SPEC_BUF_FOR_MMU_HEAD
-static int vav1_mmu_compress_header_size(struct AV1HW_s *hw)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h))
- return (MMU_COMPRESS_HEADER_SIZE_8K);
-
- if (IS_4K_SIZE(hw->max_pic_w, hw->max_pic_h))
- return MMU_COMPRESS_HEADER_SIZE_4K;
-
- return (MMU_COMPRESS_HEADER_SIZE_1080P);
-}
-#endif
-/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/
-static int vav1_frame_mmu_map_size(struct AV1HW_s *hw)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h))
- return (MAX_FRAME_8K_NUM * 4);
-
- return (MAX_FRAME_4K_NUM * 4);
-}
-
-#ifdef AOM_AV1_MMU_DW
-static int vaom_dw_frame_mmu_map_size(struct AV1HW_s *hw)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h))
- return (MAX_FRAME_8K_NUM * 4);
-
- return (MAX_FRAME_4K_NUM * 4);
-}
-#endif
-
-static void init_pic_list(struct AV1HW_s *hw)
-{
- int i;
- struct AV1_Common_s *cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- struct vdec_s *vdec = hw_to_vdec(hw);
-
-#ifndef USE_SPEC_BUF_FOR_MMU_HEAD
- u32 header_size;
-
- if (!hw->is_used_v4l && (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- header_size = vav1_mmu_compress_header_size(hw);
- /*alloc AV1 compress header first*/
- for (i = 0; i < hw->used_buf_num; i++) {
- unsigned long buf_addr;
- if (decoder_bmmu_box_alloc_buf_phy
- (hw->bmmu_box,
- HEADER_BUFFER_IDX(i), header_size,
- DRIVER_HEADER_NAME,
- &buf_addr) < 0) {
- av1_print(hw, 0, "%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, i);
- hw->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
-#ifdef AOM_AV1_MMU_DW
- if (hw->dw_mmu_enable) {
- if (decoder_bmmu_box_alloc_buf_phy
- (hw->bmmu_box,
- DW_HEADER_BUFFER_IDX(i), header_size,
- DRIVER_HEADER_NAME,
- &buf_addr) < 0) {
- av1_print(hw, 0, "%s malloc compress dw header failed %d\n",
- DRIVER_HEADER_NAME, i);
- hw->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
- }
-#endif
- }
- }
-#endif
- for (i = 0; i < hw->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- pic_config->index = i;
- pic_config->BUF_index = -1;
- pic_config->mv_buf_index = -1;
- if (vdec->parallel_dec == 1) {
- pic_config->y_canvas_index = -1;
- pic_config->uv_canvas_index = -1;
- }
- pic_config->y_crop_width = hw->init_pic_w;
- pic_config->y_crop_height = hw->init_pic_h;
- pic_config->double_write_mode = get_double_write_mode(hw);
- hw->buffer_wrap[i] = i;
-
- if (!hw->is_used_v4l) {
- if (config_pic(hw, pic_config) < 0) {
- if (debug)
- av1_print(hw, 0, "Config_pic %d fail\n",
- pic_config->index);
- pic_config->index = -1;
- break;
- }
-
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0) {
- set_canvas(hw, pic_config);
- }
- }
- }
- for (; i < hw->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- pic_config->index = -1;
- pic_config->BUF_index = -1;
- pic_config->mv_buf_index = -1;
- hw->buffer_wrap[i] = i;
- if (vdec->parallel_dec == 1) {
- pic_config->y_canvas_index = -1;
- pic_config->uv_canvas_index = -1;
- }
- }
- av1_print(hw, AV1_DEBUG_BUFMGR, "%s ok, used_buf_num = %d\n",
- __func__, hw->used_buf_num);
-
-}
-
-static void init_pic_list_hw(struct AV1HW_s *hw)
-{
- int i;
- struct AV1_Common_s *cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-
-
- for (i = 0; i < hw->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- if (pic_config->index < 0)
- break;
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->header_adr >> 5);
- } else {
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- * pic_config->mc_y_adr
- * | (pic_config->mc_canvas_y << 8) | 0x1);
- */
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->dw_y_adr >> 5);
- }
-#ifndef LOSLESS_COMPRESS_MODE
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- * pic_config->mc_u_v_adr
- * | (pic_config->mc_canvas_u_v << 8)| 0x1);
- */
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->dw_u_v_adr >> 5);
-#else
- if (pic_config->double_write_mode & 0x10) {
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->dw_u_v_adr >> 5);
- }
-#endif
- }
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-
-#ifdef CHANGE_REMOVED
- /*Zero out canvas registers in IPP -- avoid simulation X*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
-#else
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (1 << 8) | (0 << 1) | 1);
-#endif
- for (i = 0; i < 32; i++)
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
-}
-
-
-static void dump_pic_list(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- int i;
- for (i = 0; i < FRAME_BUFFERS; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- av1_print(hw, 0,
- "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d repeat_count %d dec_idx %d slice_type %d w/h %d/%d adr%ld\n",
- i,
- pic_config->index,
-#ifndef MV_USE_FIXED_BUF
- pic_config->mv_buf_index,
-#else
- -1,
-#endif
- cm->buffer_pool->
- frame_bufs[i].ref_count,
- pic_config->vf_ref,
- pic_config->repeat_count,
- pic_config->decode_idx,
- pic_config->slice_type,
- pic_config->y_crop_width,
- pic_config->y_crop_height,
- pic_config->cma_alloc_addr
- );
- }
- return;
-}
-
-void av1_release_buf(AV1Decoder *pbi, RefCntBuffer *const buf)
-{
-
-#if 0
- //def CHANGE_DONE
- struct AV1HW_s *hw = (struct AV1HW_s *)(pbi->private_data);
- if (!hw->mmu_enable)
- return;
- //release_buffer_4k(&av1_mmumgr_m, buf->buf.index);
- decoder_mmu_box_free_idx(hw->mmu_box, buf->buf.index);
-#ifdef AOM_AV1_MMU_DW
- //release_buffer_4k(&av1_mmumgr_dw, buf->buf.index);
- decoder_mmu_box_free_idx(hw->mmu_box_dw, buf->buf.index);
-#endif
-
-#endif
-}
-
-void av1_release_bufs(struct AV1HW_s *hw)
-{
- AV1_COMMON *cm = &hw->common;
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- if (frame_bufs[i].buf.vf_ref == 0 &&
- frame_bufs[i].ref_count == 0 &&
- frame_bufs[i].buf.index >= 0) {
- if (frame_bufs[i].buf.aux_data_buf)
- release_aux_data(hw, &frame_bufs[i].buf);
- }
- }
-}
-
-#ifdef DEBUG_CMD
-static void d_fill_zero(struct AV1HW_s *hw, unsigned int phyadr, int size)
-{
- WRITE_VREG(HEVC_DBG_LOG_ADR, phyadr);
- WRITE_VREG(DEBUG_REG1,
- 0x20000000 | size);
- debug_cmd_wait_count = 0;
- debug_cmd_wait_type = 1;
- while ((READ_VREG(DEBUG_REG1) & 0x1) == 0
- && debug_cmd_wait_count < 0x7fffffff) {
- debug_cmd_wait_count++;
- }
-
- WRITE_VREG(DEBUG_REG1, 0);
- debug_cmd_wait_type = 0;
-}
-
-static void d_dump(struct AV1HW_s *hw, unsigned int phyadr, int size,
- struct file *fp, loff_t *wr_off)
-{
-
- int jj;
- unsigned char *data = (unsigned char *)
- (hw->ucode_log_addr);
- WRITE_VREG(HEVC_DBG_LOG_ADR, hw->ucode_log_phy_addr);
-
- WRITE_VREG(HEVC_D_ADR, phyadr);
- WRITE_VREG(DEBUG_REG1,
- 0x10000000 | size);
-
- debug_cmd_wait_count = 0;
- debug_cmd_wait_type = 3;
- while ((READ_VREG(DEBUG_REG1) & 0x1) == 0
- && debug_cmd_wait_count < 0x7fffffff) {
- debug_cmd_wait_count++;
- }
-
- if (fp) {
- vfs_write(fp, data,
- size, wr_off);
-
- } else {
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- av1_print(hw, 0,
- "%06x:", jj);
- av1_print_cont(hw, 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- av1_print_cont(hw, 0,
- "\n");
- }
- av1_print(hw, 0, "\n");
- }
-
- WRITE_VREG(DEBUG_REG1, 0);
- debug_cmd_wait_type = 0;
-
-}
-
-static void mv_buffer_fill_zero(struct AV1HW_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- pr_info("fill dummy data pic index %d colocate addreses %x size %x\n",
- pic_config->index, pic_config->mpred_mv_wr_start_addr,
- hw->m_mv_BUF[pic_config->mv_buf_index].size);
- d_fill_zero(hw, pic_config->mpred_mv_wr_start_addr,
- hw->m_mv_BUF[pic_config->mv_buf_index].size);
-}
-
-static void dump_mv_buffer(struct AV1HW_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config)
-{
-
- unsigned int adr, size;
- unsigned int adr_end = pic_config->mpred_mv_wr_start_addr +
- hw->m_mv_BUF[pic_config->mv_buf_index].size;
- mm_segment_t old_fs;
- loff_t off = 0;
- int mode = O_CREAT | O_WRONLY | O_TRUNC;
- char file[64];
- struct file *fp;
- sprintf(&file[0], "/data/tmp/colocate%d", hw->frame_count-1);
- fp = filp_open(file, mode, 0666);
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- for (adr = pic_config->mpred_mv_wr_start_addr;
- adr < adr_end;
- adr += UCODE_LOG_BUF_SIZE) {
- size = UCODE_LOG_BUF_SIZE;
- if (size > (adr_end - adr))
- size = adr_end - adr;
- pr_info("dump pic index %d colocate addreses %x size %x\n",
- pic_config->index, adr, size);
- d_dump(hw, adr, size, fp, &off);
- }
- set_fs(old_fs);
- vfs_fsync(fp, 0);
-
- filp_close(fp, current->files);
-}
-
-#endif
-
-static int config_pic_size(struct AV1HW_s *hw, unsigned short bit_depth)
-{
- uint32_t data32;
- struct AV1_Common_s *cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf;
- int losless_comp_header_size, losless_comp_body_size;
-#ifdef AOM_AV1_MMU_DW
- int losless_comp_header_size_dw, losless_comp_body_size_dw;
-#endif
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " #### config_pic_size ####, bit_depth = %d\n", bit_depth);
-
- frame_width = cur_pic_config->y_crop_width;
- frame_height = cur_pic_config->y_crop_height;
- cur_pic_config->bit_depth = bit_depth;
- cur_pic_config->double_write_mode = get_double_write_mode(hw);
-
- /* use fixed maximum size // 128x128/4/4*3-bits = 384 Bytes
- seg_map_size =
- ((frame_width + 127) >> 7) * ((frame_height + 127) >> 7) * 384 ;
- */
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE,
- (frame_height << 16) | frame_width);
-#ifdef DUAL_DECODE
-#else
- WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ,
- (frame_height << 16) | frame_width);
-#endif
-#ifdef AOM_AV1_MMU
-
- //alloc_mmu(&av1_mmumgr_m, cm->cur_frame->buf.index, frame_width, frame_height, bit_depth);
-#endif
-#ifdef AOM_AV1_MMU_DW
-
- //alloc_mmu(&av1_mmumgr_dw, cm->cur_frame->buf.index, frame_width, frame_height, bit_depth);
- losless_comp_header_size_dw =
- compute_losless_comp_header_size_dw(frame_width, frame_height);
- losless_comp_body_size_dw =
- compute_losless_comp_body_size_dw(frame_width, frame_height,
- (bit_depth == AOM_BITS_10));
-#endif
-
- losless_comp_header_size =
- compute_losless_comp_header_size
- (frame_width, frame_height);
- losless_comp_body_size =
- compute_losless_comp_body_size(frame_width,
- frame_height, (bit_depth == AOM_BITS_10));
-
- cur_pic_config->comp_body_size = losless_comp_body_size;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: width %d height %d depth %d head_size 0x%x body_size 0x%x\r\n",
- __func__, frame_width, frame_height, bit_depth,
- losless_comp_header_size, losless_comp_body_size);
-#ifdef LOSLESS_COMPRESS_MODE
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- if (bit_depth == AOM_BITS_10)
- data32 &= ~(1<<9);
- else
- data32 |= (1<<9);
-
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode
- } else {
- if (bit_depth == AOM_BITS_10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe
- else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe
- }
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,
- (losless_comp_body_size >> 5));
- /*
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,
- (0xff<<20) | (0xff<<10) | 0xff); //8-bit mode
- */
- WRITE_VREG(HEVC_CM_BODY_LENGTH,
- losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET,
- losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH,
- losless_comp_header_size);
-
- if (get_double_write_mode(hw) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31);
-#endif
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- WRITE_VREG(HEVC_CM_BODY_LENGTH2, losless_comp_body_size_dw);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2, losless_comp_body_size_dw);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2, losless_comp_header_size_dw);
- }
-#endif
- return 0;
-
-}
-
-static int config_mc_buffer(struct AV1HW_s *hw, unsigned short bit_depth, unsigned char inter_flag)
-{
- int32_t i;
- AV1_COMMON *cm = &hw->common;
- PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf;
- uint8_t scale_enable = 0;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " #### config_mc_buffer %s ####\n",
- inter_flag ? "inter" : "intra");
-
-#ifdef DEBUG_PRINT
- if (debug&AOM_AV1_DEBUG_BUFMGR)
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "config_mc_buffer entered .....\n");
-#endif
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0<<1) | 1);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (cur_pic_config->order_hint<<24) |
- (cur_pic_config->mc_canvas_u_v<<16) |
- (cur_pic_config->mc_canvas_u_v<<8)|
- cur_pic_config->mc_canvas_y);
- for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- PIC_BUFFER_CONFIG *pic_config; //cm->frame_refs[i].buf;
- if (inter_flag)
- pic_config = av1_get_ref_frame_spec_buf(cm, i);
- else
- pic_config = cur_pic_config;
- if (pic_config) {
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic_config->order_hint<<24) |
- (pic_config->mc_canvas_u_v<<16) |
- (pic_config->mc_canvas_u_v<<8) |
- pic_config->mc_canvas_y);
- if (inter_flag)
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "refid 0x%x mc_canvas_u_v 0x%x mc_canvas_y 0x%x order_hint 0x%x\n",
- i, pic_config->mc_canvas_u_v,
- pic_config->mc_canvas_y, pic_config->order_hint);
- } else {
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
- }
- }
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (0 << 1) | 1);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (cur_pic_config->order_hint << 24) |
- (cur_pic_config->mc_canvas_u_v << 16) |
- (cur_pic_config->mc_canvas_u_v << 8) |
- cur_pic_config->mc_canvas_y);
- for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- PIC_BUFFER_CONFIG *pic_config;
- if (inter_flag)
- pic_config = av1_get_ref_frame_spec_buf(cm, i);
- else
- pic_config = cur_pic_config;
-
- if (pic_config) {
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic_config->order_hint << 24)|
- (pic_config->mc_canvas_u_v << 16) |
- (pic_config->mc_canvas_u_v << 8) |
- pic_config->mc_canvas_y);
- } else {
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
- }
- }
-
- WRITE_VREG(AV1D_MPP_REFINFO_TBL_ACCCONFIG,
- (0x1 << 2) | (0x0 <<3)); // auto_inc start index:0 field:0
- for (i = 0; i <= ALTREF_FRAME; i++) {
- int32_t ref_pic_body_size;
- struct scale_factors * sf = NULL;
- PIC_BUFFER_CONFIG *pic_config;
-
- if (inter_flag && i >= LAST_FRAME)
- pic_config = av1_get_ref_frame_spec_buf(cm, i);
- else
- pic_config = cur_pic_config;
-
- if (pic_config) {
- ref_pic_body_size =
- compute_losless_comp_body_size(pic_config->y_crop_width,
- pic_config->y_crop_height, (bit_depth == AOM_BITS_10));
-
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, pic_config->y_crop_width);
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, pic_config->y_crop_height);
- if (inter_flag && i >= LAST_FRAME) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "refid %d: ref width/height(%d,%d), cur width/height(%d,%d) ref_pic_body_size 0x%x\n",
- i, pic_config->y_crop_width, pic_config->y_crop_height,
- cur_pic_config->y_crop_width, cur_pic_config->y_crop_height,
- ref_pic_body_size);
- }
- } else {
- ref_pic_body_size = 0;
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0);
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0);
- }
-
- if (inter_flag && i >= LAST_FRAME)
- sf = av1_get_ref_scale_factors(cm, i);
-
- if ((sf != NULL) && av1_is_scaled(sf)) {
- scale_enable |= (1 << i);
- }
-
- if (sf) {
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, sf->x_scale_fp);
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, sf->y_scale_fp);
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "x_scale_fp %d, y_scale_fp %d\n",
- sf->x_scale_fp, sf->y_scale_fp);
- } else {
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, REF_NO_SCALE); //1<<14
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, REF_NO_SCALE);
- }
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, 0);
- } else
- WRITE_VREG(AV1D_MPP_REFINFO_DATA, ref_pic_body_size >> 5);
-
- }
- WRITE_VREG(AV1D_MPP_REF_SCALE_ENBL, scale_enable);
- WRITE_VREG(PARSER_REF_SCALE_ENBL, scale_enable);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "WRITE_VREG(PARSER_REF_SCALE_ENBL, 0x%x)\n",
- scale_enable);
- return 0;
-}
-
-static void clear_mpred_hw(struct AV1HW_s *hw)
-{
- unsigned int data32;
-
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 &= (~(1 << 6));
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
-}
-
-static void config_mpred_hw(struct AV1HW_s *hw, unsigned char inter_flag)
-{
- AV1_COMMON *cm = &hw->common;
- PIC_BUFFER_CONFIG *cur_pic_config = &cm->cur_frame->buf;
- //PIC_BUFFER_CONFIG *last_frame_pic_config = NULL;
- int i, j, pos, reg_i;
- int mv_cal_tpl_count = 0;
- unsigned int mv_ref_id[MFMV_STACK_SIZE] = {0, 0, 0};
- unsigned ref_offset_reg[] = {
- HEVC_MPRED_L0_REF06_POC,
- HEVC_MPRED_L0_REF07_POC,
- HEVC_MPRED_L0_REF08_POC,
- HEVC_MPRED_L0_REF09_POC,
- HEVC_MPRED_L0_REF10_POC,
- HEVC_MPRED_L0_REF11_POC,
- };
- unsigned ref_buf_reg[] = {
- HEVC_MPRED_L0_REF03_POC,
- HEVC_MPRED_L0_REF04_POC,
- HEVC_MPRED_L0_REF05_POC
- };
- unsigned ref_offset_val[6] =
- {0, 0, 0, 0, 0, 0};
- unsigned ref_buf_val[3] = {0, 0, 0};
-
- uint32_t data32;
- int32_t mpred_curr_lcu_x;
- int32_t mpred_curr_lcu_y;
- //int32_t mpred_mv_rd_end_addr;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " #### config_mpred_hw ####\n");
-
- /*if (cm->prev_frame)
- last_frame_pic_config = &cm->prev_frame->buf;
- mpred_mv_rd_end_addr = last_frame_pic_config->mpred_mv_wr_start_addr
- + (last_frame_pic_config->lcu_total * MV_MEM_UNIT);
- */
-
- data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
- mpred_curr_lcu_x =data32 & 0xffff;
- mpred_curr_lcu_y =(data32>>16) & 0xffff;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "cur pic index %d\n", cur_pic_config->index);
- /*printk("cur pic index %d col pic index %d\n",
- cur_pic_config->index, last_frame_pic_config->index);*/
-
- //WRITE_VREG(HEVC_MPRED_CTRL3,0x24122412);
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- WRITE_VREG(HEVC_MPRED_CTRL3,0x10151015); // 'd10, 'd21 for AV1
- } else {
- WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1
- }
-#else
- WRITE_VREG(HEVC_MPRED_CTRL3,0x13151315); // 'd19, 'd21 for AV1
-#endif
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,
- hw->pbi->work_space_buf->mpred_above.buf_start);
-
-#if 0
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 &= (~(1<<6));
- data32 |= (cm->use_prev_frame_mvs << 6);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
-#endif
- if (inter_flag) {
- /* config sign_bias */
- //data32 = (cm->cur_frame_force_integer_mv & 0x1) << 9;
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 &= (~(0xff << 12));
- //for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- /* HEVC_MPRED_CTRL4[bit 12] is for cm->ref_frame_sign_bias[0]
- instead of cm->ref_frame_sign_bias[LAST_FRAME] */
- for (i = 0; i <= ALTREF_FRAME; i++) {
- data32 |= ((cm->ref_frame_sign_bias[i] & 0x1) << (12 + i));
- }
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "WRITE_VREG(HEVC_MPRED_CTRL4, 0x%x)\n", data32);
- }
-#if 1
- data32 = ((cm->seq_params.order_hint_info.enable_order_hint << 27) |
- (cm->seq_params.order_hint_info.order_hint_bits_minus_1 << 24) |
- (cm->cur_frame->order_hint << 16 ));
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- data32 |= (0x10 << 8) | (0x10 << 0);
- } else {
- data32 |= (0x13 << 8) | (0x13 << 0);
- }
-#else
- data32 |= (0x13 << 8) | (0x13 << 0);
-#endif
-
-#else
- data32 = READ_VREG(HEVC_MPRED_L0_REF00_POC);
- data32 &= (~(0xff << 16));
- data32 |= (cm->cur_frame->order_hint & 0xff);
- data32 &= (~(1 << 27));
- data32 |= (cm->seq_params.order_hint_info.enable_order_hint << 27);
-#endif
- WRITE_VREG(HEVC_MPRED_L0_REF00_POC, data32);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "WRITE_VREG(HEVC_MPRED_L0_REF00_POC, 0x%x)\n", data32);
-
- if (inter_flag) {
- /* config ref_buf id and order hint */
- data32 = 0;
- pos = 25;
- reg_i = 0;
- for (i = ALTREF_FRAME; i >= LAST_FRAME; i--) {
- PIC_BUFFER_CONFIG *pic_config =
- av1_get_ref_frame_spec_buf(cm, i);
- if (pic_config) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "pic_config for %d th ref: index %d, reg[%d] pos %d\n",
- i, pic_config->index, reg_i, pos);
- data32 |= ((pic_config->index < 0)? 0 : pic_config->index) << pos;
- } else
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "pic_config is null for %d th ref\n", i);
- if (pos == 0) {
- //WRITE_VREG(ref_buf_reg[reg_i], data32);
- ref_buf_val[reg_i] = data32;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n",
- reg_i, ref_buf_reg[reg_i], data32);
- reg_i++;
- data32 = 0;
- pos = 24; //for P_HEVC_MPRED_L0_REF04_POC
- } else {
- if (pos == 24)
- pos -= 8; //for P_HEVC_MPRED_L0_REF04_POC
- else
- pos -= 5; //for P_HEVC_MPRED_L0_REF03_POC
- }
- }
- for (i = ALTREF_FRAME; i >= LAST_FRAME; i--) {
- PIC_BUFFER_CONFIG *pic_config =
- av1_get_ref_frame_spec_buf(cm, i);
- if (pic_config) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "pic_config for %d th ref: order_hint %d, reg[%d] pos %d\n",
- i, pic_config->order_hint, reg_i, pos);
- data32 |= ((pic_config->index < 0)? 0 : pic_config->order_hint) << pos;
- } else
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "pic_config is null for %d th ref\n", i);
- if (pos == 0) {
- //WRITE_VREG(ref_buf_reg[reg_i], data32);
- ref_buf_val[reg_i] = data32;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n",
- reg_i, ref_buf_reg[reg_i], data32);
- reg_i++;
- data32 = 0;
- pos = 24;
- } else
- pos -= 8;
- }
- if (pos != 24) {
- //WRITE_VREG(ref_buf_reg[reg_i], data32);
- ref_buf_val[reg_i] = data32;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "ref_buf_reg[%d], WRITE_VREG(0x%x, 0x%x)\n",
- reg_i, ref_buf_reg[reg_i], data32);
- }
- /* config ref_offset */
- data32 = 0;
- pos = 24;
- mv_cal_tpl_count = 0;
- reg_i = 0;
- for (i = 0; i < cm->mv_ref_id_index; i++) {
- if (cm->mv_cal_tpl_mvs[i]) {
- mv_ref_id[mv_cal_tpl_count] = cm->mv_ref_id[i];
- mv_cal_tpl_count++;
- for (j = LAST_FRAME; j <= ALTREF_FRAME; j++) {
- /*offset can be negative*/
- unsigned char offval =
- cm->mv_ref_offset[i][j] & 0xff;
- data32 |= (offval << pos);
- if (pos == 0) {
- //WRITE_VREG(ref_offset_reg[reg_i], data32);
- ref_offset_val[reg_i] = data32;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "ref_offset_reg[%d], WRITE_VREG(0x%x, 0x%x)\n",
- reg_i, ref_offset_reg[reg_i], data32);
- reg_i++;
- data32 = 0;
- pos = 24;
- } else
- pos -= 8;
- }
- }
- }
- if (pos != 24) {
- //WRITE_VREG(ref_offset_reg[reg_i], data32);
- ref_offset_val[reg_i] = data32;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "ref_offset_reg[%d], WRITE_VREG(0x%x, 0x%x)\n",
- reg_i, ref_offset_reg[reg_i], data32);
- }
-
- data32 = ref_offset_val[5] | //READ_VREG(HEVC_MPRED_L0_REF11_POC) |
- mv_cal_tpl_count | (mv_ref_id[0] << 2) |
- (mv_ref_id[1] << 5) | (mv_ref_id[2] << 8);
- ref_offset_val[5] = data32;
- //WRITE_VREG(HEVC_MPRED_L0_REF11_POC, data32);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "WRITE_VREG(HEVC_MPRED_L0_REF11_POC 0x%x, 0x%x)\n",
- HEVC_MPRED_L0_REF11_POC, data32);
- }
- for (i = 0; i < 3; i++)
- WRITE_VREG(ref_buf_reg[i], ref_buf_val[i]);
- for (i = 0; i < 6; i++)
- WRITE_VREG(ref_offset_reg[i], ref_offset_val[i]);
-
- WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
- cur_pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_WPTR,
- cur_pic_config->mpred_mv_wr_start_addr);
-
- if (inter_flag) {
- for (i = 0; i < mv_cal_tpl_count; i++) {
- PIC_BUFFER_CONFIG *pic_config =
- av1_get_ref_frame_spec_buf(cm, mv_ref_id[i]);
- if (pic_config == NULL)
- continue;
- if (i == 0) {
- WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
- pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RPTR,
- pic_config->mpred_mv_wr_start_addr);
- } else if (i == 1) {
- WRITE_VREG(HEVC_MPRED_L0_REF01_POC,
- pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RPTR_1,
- pic_config->mpred_mv_wr_start_addr);
- } else if (i == 2) {
- WRITE_VREG(HEVC_MPRED_L0_REF02_POC,
- pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RPTR_2,
- pic_config->mpred_mv_wr_start_addr);
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: mv_ref_id error\n", __func__);
- }
- }
- }
- data32 = READ_VREG(HEVC_MPRED_CTRL0);
- data32 &= ~((1 << 10) | (1 << 11));
- data32 |= (1 << 10); /*write enable*/
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "current_frame.frame_type=%d, cur_frame->frame_type=%d, allow_ref_frame_mvs=%d\n",
- cm->current_frame.frame_type, cm->cur_frame->frame_type,
- cm->allow_ref_frame_mvs);
-
- if (av1_frame_is_inter(&hw->common)) {
- if (cm->allow_ref_frame_mvs) {
- data32 |= (1 << 11); /*read enable*/
- }
- }
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "WRITE_VREG(HEVC_MPRED_CTRL0 0x%x, 0x%x)\n",
- HEVC_MPRED_CTRL0, data32);
- WRITE_VREG(HEVC_MPRED_CTRL0, data32);
- /*
- printk("config_mpred: (%x) wr_start_addr %x from indx %d;
- (%x) rd_start_addr %x from index %d\n",
- cur_pic_config, cur_pic_config->mpred_mv_wr_start_addr, cur_pic_config->index,
- last_frame_pic_config, last_frame_pic_config->mpred_mv_wr_start_addr, last_frame_pic_config->index);
- data32 = ((pbi->lcu_x_num - pbi->tile_width_lcu)*MV_MEM_UNIT);
- WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);
- WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);
-
- WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr);
- */
-}
-
-static void config_sao_hw(struct AV1HW_s *hw, union param_u *params)
-{
- /*
- !!!!!!!!!!!!!!!!!!!!!!!!!TODO .... !!!!!!!!!!!
- mem_map_mode, endian, get_double_write_mode
- */
- AV1_COMMON *cm = &hw->common;
- PIC_BUFFER_CONFIG* pic_config = &cm->cur_frame->buf;
- uint32_t data32;
- int32_t lcu_size =
- ((params->p.seq_flags >> 6) & 0x1) ? 128 : 64;
- int32_t mc_buffer_size_u_v =
- pic_config->lcu_total*lcu_size*lcu_size/2;
- int32_t mc_buffer_size_u_v_h =
- (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] #### config_sao_hw ####, lcu_size %d\n", lcu_size);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] lcu_total : %d\n", pic_config->lcu_total);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] mc_y_adr : 0x%x\n", pic_config->mc_y_adr);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] mc_u_v_adr : 0x%x\n", pic_config->mc_u_v_adr);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] header_adr : 0x%x\n", pic_config->header_adr);
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20)
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] header_dw_adr : 0x%x\n", pic_config->header_dw_adr);
-#endif
- data32 = READ_VREG(HEVC_SAO_CTRL9) | (1 << 1);
- WRITE_VREG(HEVC_SAO_CTRL9, data32);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (0x1 << 14); /* av1 mode */
- data32 |= (0xff << 16); /* dw {v1,v0,h1,h0} ctrl_y_cbus */
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- WRITE_VREG(HEVC_SAO_CTRL0,
- lcu_size == 128 ? 0x7 : 0x6); /*lcu_size_log2*/
-#ifdef LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic_config->mc_y_adr);
-#ifdef AOM_AV1_MMU
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->header_adr);
-#endif
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic_config->header_dw_adr);
- }
-#endif
-#else
-/*!LOSLESS_COMPRESS_MODE*/
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->mc_y_adr);
-#endif
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] sao_body_addr:%x\n", pic_config->mc_y_adr);
- //printk("[config_sao_hw] sao_header_addr:%x\n", pic_config->mc_y_adr + losless_comp_body_size );
-
-#ifdef VPU_FILMGRAIN_DUMP
- // Let Microcode to increase
- // WRITE_VREG(HEVC_FGS_TABLE_START, pic_config->fgs_table_adr);
-#else
- WRITE_VREG(HEVC_FGS_TABLE_START, pic_config->fgs_table_adr);
-#endif
- WRITE_VREG(HEVC_FGS_TABLE_LENGTH, FGS_TABLE_SIZE * 8);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[config_sao_hw] fgs_table adr:0x%x , length 0x%x bits\n",
- pic_config->fgs_table_adr, FGS_TABLE_SIZE * 8);
-
- data32 = (mc_buffer_size_u_v_h<<16)<<1;
- //printk("data32 = %x, mc_buffer_size_u_v_h = %x, lcu_total = %x\n", data32, mc_buffer_size_u_v_h, pic_config->lcu_total);
- WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
-
-#ifndef LOSLESS_COMPRESS_MODE
- WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->mc_u_v_adr);
-#else
-#endif
-
- data32 = (mc_buffer_size_u_v_h<<16);
- WRITE_VREG(HEVC_SAO_C_LENGTH ,data32);
-
-#ifndef LOSLESS_COMPRESS_MODE
- /* multi tile to do... */
- WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->mc_y_adr);
-
- WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->mc_u_v_adr);
-#else
- if (get_double_write_mode(hw) &&
- (get_double_write_mode(hw) & 0x20) == 0) {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->dw_u_v_adr);
- WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->dw_u_v_adr);
- } else {
- //WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
- //WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
- }
-#endif
-
-
-#ifndef AOM_AV1_NV21
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- }
-#endif
-#endif
-
-#ifdef AOM_AV1_NV21
-#ifdef DOS_PROJECT
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- data32 &= (~0x3);
- data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
- data32 &= ~(0xff << 16); // set them all 0 for AOM_AV1_NV21 (no down-scale)
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#else
-// m8baby test1902
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); // [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- data32 &= (~0xff0);
- //data32 |= 0x670; // Big-Endian per 64-bit
- data32 |= 0x880; // Big-Endian per 64-bit
- data32 &= (~0x3);
- data32 |= 0x1; // [1]:dw_disable [0]:cm_disable
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5); // [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
- data32 &= ~(0xff << 16); // set them all 0 for AOM_AV1_NV21 (no down-scale)
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- data32 |= (hw->mem_map_mode << 4); // [5:4] -- address_format 00:linear 01:32x32 10:64x32
- data32 &= (~0xF);
- data32 |= 0x8; // Big-Endian per 64-bit
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
-#else
-/*CHANGE_DONE nnn*/
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- data32 |= (hw->mem_map_mode << 12); /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
- data32 &= (~0xff0);
- /* data32 |= 0x670; // Big-Endian per 64-bit */
-#ifdef AOM_AV1_MMU_DW
- if ((get_double_write_mode(hw) & 0x20) == 0)
- data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
-#else
- data32 |= ((hw->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
-#endif
- data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
- if (get_double_write_mode(hw) == 0)
- data32 |= 0x2; /*disable double write*/
- else if (get_double_write_mode(hw) & 0x10)
- data32 |= 0x1; /*disable cm*/
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { /* >= G12A dw write control */
- unsigned int data;
- data = READ_VREG(HEVC_DBLK_CFGB);
- data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (get_double_write_mode(hw) == 0)
- data |= (0x1 << 8); /*enable first write*/
- else if (get_double_write_mode(hw) & 0x10)
- data |= (0x1 << 9); /*double write only*/
- else
- data |= ((0x1 << 8) |(0x1 << 9));
- WRITE_VREG(HEVC_DBLK_CFGB, data);
- }
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- data32 &= ~(1 << 8); /* NV21 */
- else
- data32 |= (1 << 8); /* NV12 */
- }
- data32 &= (~(3 << 14));
- data32 |= (2 << 14);
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- if (get_double_write_mode(hw) & 0x10) {
- /* [23:22] dw_v1_ctrl
- *[21:20] dw_v0_ctrl
- *[19:18] dw_h1_ctrl
- *[17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- } else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 &= (~(0xff << 16));
- if ((get_double_write_mode(hw) & 0xf) == 8) {
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- data32 |= (0xff << 16);
- } else if ((get_double_write_mode(hw) & 0xf) == 2 ||
- (get_double_write_mode(hw) & 0xf) == 3)
- data32 |= (0xff<<16);
- else if ((get_double_write_mode(hw) & 0xf) == 4 ||
- (get_double_write_mode(hw) & 0xf) == 5)
- data32 |= (0x33<<16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (hw->mem_map_mode << 4);
- data32 &= (~0xf);
- data32 |= (hw->endian & 0xf); /* valid only when double write only */
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- data32 |= (1 << 12); /* NV21 */
- else
- data32 &= ~(1 << 12); /* NV12 */
- }
- data32 &= (~(3 << 8));
- data32 |= (2 << 8);
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-
-#endif
-
-}
-
-
-#ifdef AOM_AV1_DBLK_INIT
-/*
- * Defines, declarations, sub-functions for av1 de-block loop filter Thr/Lvl table update
- * - struct segmentation_lf is for loop filter only (removed something)
- * - function "av1_loop_filter_init" and "av1_loop_filter_frame_init" will be instantiated in C_Entry
- * - av1_loop_filter_init run once before decoding start
- * - av1_loop_filter_frame_init run before every frame decoding start
- * - set video format to AOM_AV1 is in av1_loop_filter_init
- */
-#define MAX_LOOP_FILTER 63
-#define MAX_MODE_LF_DELTAS 2
-#define MAX_SEGMENTS 8
-#define MAX_MB_PLANE 3
-
-typedef enum {
- SEG_LVL_ALT_Q, // Use alternate Quantizer ....
- SEG_LVL_ALT_LF_Y_V, // Use alternate loop filter value on y plane vertical
- SEG_LVL_ALT_LF_Y_H, // Use alternate loop filter value on y plane horizontal
- SEG_LVL_ALT_LF_U, // Use alternate loop filter value on u plane
- SEG_LVL_ALT_LF_V, // Use alternate loop filter value on v plane
- SEG_LVL_REF_FRAME, // Optional Segment reference frame
- SEG_LVL_SKIP, // Optional Segment (0,0) + skip mode
- SEG_LVL_GLOBALMV,
- SEG_LVL_MAX
-} SEG_LVL_FEATURES;
-
-static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = {
- { SEG_LVL_ALT_LF_Y_V, SEG_LVL_ALT_LF_Y_H },
- { SEG_LVL_ALT_LF_U, SEG_LVL_ALT_LF_U },
- { SEG_LVL_ALT_LF_V, SEG_LVL_ALT_LF_V }
-};
-
-struct segmentation_lf { // for loopfilter only
- uint8_t enabled;
- /*
- SEG_LVL_ALT_LF_Y_V feature_enable: seg_lf_info_y[bit7]
- SEG_LVL_ALT_LF_Y_V data: seg_lf_info_y[bit0~6]
- SEG_LVL_ALT_LF_Y_H feature enable: seg_lf_info_y[bit15]
- SEG_LVL_ALT_LF_Y_H data: seg_lf_info_y[bit8~14]
- */
- uint16_t seg_lf_info_y[8];
- /*
- SEG_LVL_ALT_LF_U feature_enable: seg_lf_info_c[bit7]
- SEG_LVL_ALT_LF_U data: seg_lf_info_c[bit0~6]
- SEG_LVL_ALT_LF_V feature enable: seg_lf_info_c[bit15]
- SEG_LVL_ALT_LF_V data: seg_lf_info_c[bit8~14]
- */
- uint16_t seg_lf_info_c[8];
-};
-
-typedef struct {
- uint8_t mblim;
- uint8_t lim;
- uint8_t hev_thr;
-} loop_filter_thresh;
-
-typedef struct loop_filter_info_n_s {
- loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
- uint8_t lvl[MAX_MB_PLANE][MAX_SEGMENTS][2][REF_FRAMES][MAX_MODE_LF_DELTAS];
-} loop_filter_info_n;
-
-struct loopfilter {
- int32_t filter_level[2];
- int32_t filter_level_u;
- int32_t filter_level_v;
-
- int32_t sharpness_level;
-
- uint8_t mode_ref_delta_enabled;
- uint8_t mode_ref_delta_update;
-
- // 0 = Intra, Last, Last2+Last3,
- // GF, BRF, ARF2, ARF
- int8_t ref_deltas[REF_FRAMES];
-
- // 0 = ZERO_MV, MV
- int8_t mode_deltas[MAX_MODE_LF_DELTAS];
-
- int32_t combine_vert_horz_lf;
-
- int32_t lf_pic_cnt;
-
-//#if LOOP_FILTER_BITMASK
- //LoopFilterMask *lfm;
- //size_t lfm_num;
- //int lfm_stride;
- //LpfSuperblockInfo neighbor_sb_lpf_info;
-//#endif // LOOP_FILTER_BITMASK
-};
-#ifdef DBG_LPF_DBLK_LVL
-static int32_t myclamp(int32_t value, int32_t low, int32_t high) {
- return value < low ? low : (value > high ? high : value);
-}
-#endif
-/*static int8_t extend_sign_7bits(uint8_t value) {
- return (((value>>6) & 0x1)<<7) | (value&0x7f);
-}*/
-
-// convert data to int8_t variable
-// value : signed data (with any bitwidth<8) which is assigned to uint8_t variable as an input
-// bw : bitwidth of signed data, (from 1 to 7)
-static int8_t conv2int8 (uint8_t value, uint8_t bw) {
- if (bw<1 || bw>7) return (int8_t)value;
- else {
- const uint8_t data_bits = value & ((1<<bw)-1);
- const uint8_t sign_bit = (value>>(bw-1)) & 0x1;
- const uint8_t sign_bit_ext = sign_bit | sign_bit<<1 | sign_bit<<2 | sign_bit<<3 | sign_bit<<4 | sign_bit<<5 | sign_bit<<6 | sign_bit<<7;
- return (int8_t)((sign_bit_ext<<bw) | data_bits);
- }
-}
-
-static void av1_update_sharpness(loop_filter_info_n *lfi, int32_t sharpness_lvl) {
- int32_t lvl;
-
- // For each possible value for the loop filter fill out limits
- for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) {
- // Set loop filter parameters that control sharpness.
- int32_t block_inside_limit =
- lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
-
- if (sharpness_lvl > 0) {
- if (block_inside_limit > (9 - sharpness_lvl))
- block_inside_limit = (9 - sharpness_lvl);
- }
-
- if (block_inside_limit < 1)
- block_inside_limit = 1;
-
- lfi->lfthr[lvl].lim = (uint8_t)block_inside_limit;
- lfi->lfthr[lvl].mblim = (uint8_t)(2 * (lvl + 2) + block_inside_limit);
- }
-}
-
-// instantiate this function once when decode is started
-void av1_loop_filter_init(loop_filter_info_n *lfi, struct loopfilter *lf) {
- int32_t i;
- uint32_t data32;
-
- // init limits for given sharpness
- av1_update_sharpness(lfi, lf->sharpness_level);
-
- // Write to register
- for (i = 0; i < 32; i++) {
- uint32_t thr;
- thr = ((lfi->lfthr[i*2+1].lim & 0x3f)<<8) |
- (lfi->lfthr[i*2+1].mblim & 0xff);
- thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8) |
- (lfi->lfthr[i*2].mblim & 0xff);
- WRITE_VREG(HEVC_DBLK_CFG9, thr);
- }
- // video format is AOM_AV1
- data32 = (0x57 << 8) | // 1st/2nd write both enable
- (0x4 << 0); // aom_av1 video format
- WRITE_VREG(HEVC_DBLK_CFGB, data32);
- av1_print2(AOM_DEBUG_HW_MORE,
- "[DBLK DEBUG] CFGB : 0x%x\n", data32);
-}
-
-// perform this function per frame
-void av1_loop_filter_frame_init(AV1Decoder* pbi, struct segmentation_lf *seg,
- loop_filter_info_n *lfi,
- struct loopfilter *lf,
- int32_t pic_width) {
- BuffInfo_t* buf_spec = pbi->work_space_buf;
- int32_t i;
-#ifdef DBG_LPF_DBLK_LVL
- int32_t dir;
- int32_t filt_lvl[MAX_MB_PLANE], filt_lvl_r[MAX_MB_PLANE];
- int32_t plane;
- int32_t seg_id;
-#endif
- // n_shift is the multiplier for lf_deltas
- // the multiplier is 1 for when filter_lvl is between 0 and 31;
- // 2 when filter_lvl is between 32 and 63
-
- // update limits if sharpness has changed
- av1_update_sharpness(lfi, lf->sharpness_level);
-
- // Write to register
- for (i = 0; i < 32; i++) {
- uint32_t thr;
- thr = ((lfi->lfthr[i*2+1].lim & 0x3f)<<8)
- | (lfi->lfthr[i*2+1].mblim & 0xff);
- thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8)
- | (lfi->lfthr[i*2].mblim & 0xff);
- WRITE_VREG(HEVC_DBLK_CFG9, thr);
- }
-#ifdef DBG_LPF_DBLK_LVL
- filt_lvl[0] = lf->filter_level[0];
- filt_lvl[1] = lf->filter_level_u;
- filt_lvl[2] = lf->filter_level_v;
-
- filt_lvl_r[0] = lf->filter_level[1];
- filt_lvl_r[1] = lf->filter_level_u;
- filt_lvl_r[2] = lf->filter_level_v;
-
-#ifdef DBG_LPF_PRINT
- printk("LF_PRINT: pic_cnt(%d) base_filter_level(%d,%d,%d,%d)\n",
- lf->lf_pic_cnt, lf->filter_level[0],
- lf->filter_level[1], lf->filter_level_u, lf->filter_level_v);
-#endif
-
- for (plane = 0; plane < 3; plane++) {
- if (plane == 0 && !filt_lvl[0] && !filt_lvl_r[0])
- break;
- else if (plane == 1 && !filt_lvl[1])
- continue;
- else if (plane == 2 && !filt_lvl[2])
- continue;
-
- for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { // MAX_SEGMENTS==8
- for (dir = 0; dir < 2; ++dir) {
- int32_t lvl_seg = (dir == 0) ? filt_lvl[plane] : filt_lvl_r[plane];
- //assert(plane >= 0 && plane <= 2);
- const uint8_t seg_lf_info_y0 = seg->seg_lf_info_y[seg_id] & 0xff;
- const uint8_t seg_lf_info_y1 = (seg->seg_lf_info_y[seg_id]>>8) & 0xff;
- const uint8_t seg_lf_info_u = seg->seg_lf_info_c[seg_id] & 0xff;
- const uint8_t seg_lf_info_v = (seg->seg_lf_info_c[seg_id]>>8) & 0xff;
- const uint8_t seg_lf_info = (plane==2) ? seg_lf_info_v : (plane==1) ?
- seg_lf_info_u : ((dir==0) ? seg_lf_info_y0 : seg_lf_info_y1);
- const int8_t seg_lf_active = ((seg->enabled) && ((seg_lf_info>>7) & 0x1));
- const int8_t seg_lf_data = conv2int8(seg_lf_info,7);
-#ifdef DBG_LPF_PRINT
- const int8_t seg_lf_data_clip = (seg_lf_data>63) ? 63 :
- (seg_lf_data<-63) ? -63 : seg_lf_data;
-#endif
- if (seg_lf_active) {
- lvl_seg = myclamp(lvl_seg + (int32_t)seg_lf_data, 0, MAX_LOOP_FILTER);
- }
-
-#ifdef DBG_LPF_PRINT
- printk("LF_PRINT:plane(%d) seg_id(%d) dir(%d) seg_lf_info(%d,0x%x),lvl_seg(0x%x)\n",
- plane,seg_id,dir,seg_lf_active,seg_lf_data_clip,lvl_seg);
-#endif
-
- if (!lf->mode_ref_delta_enabled) {
- // we could get rid of this if we assume that deltas are set to
- // zero when not in use; encoder always uses deltas
- memset(lfi->lvl[plane][seg_id][dir], lvl_seg,
- sizeof(lfi->lvl[plane][seg_id][dir]));
- } else {
- int32_t ref, mode;
- const int32_t scale = 1 << (lvl_seg >> 5);
- const int32_t intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME] * scale;
- lfi->lvl[plane][seg_id][dir][INTRA_FRAME][0] =
- myclamp(intra_lvl, 0, MAX_LOOP_FILTER);
-#ifdef DBG_LPF_PRINT
- printk("LF_PRINT:ref_deltas[INTRA_FRAME](%d)\n",lf->ref_deltas[INTRA_FRAME]);
-#endif
- for (ref = LAST_FRAME; ref < REF_FRAMES; ++ref) { // LAST_FRAME==1 REF_FRAMES==8
- for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) { // MAX_MODE_LF_DELTAS==2
- const int32_t inter_lvl =
- lvl_seg + lf->ref_deltas[ref] * scale +
- lf->mode_deltas[mode] * scale;
- lfi->lvl[plane][seg_id][dir][ref][mode] =
- myclamp(inter_lvl, 0, MAX_LOOP_FILTER);
-#ifdef DBG_LPF_PRINT
- printk("LF_PRINT:ref_deltas(%d) mode_deltas(%d)\n",
- lf->ref_deltas[ref], lf->mode_deltas[mode]);
-#endif
- }
- }
- }
- }
- }
- }
-
-#ifdef DBG_LPF_PRINT
- for (i = 0; i <= MAX_LOOP_FILTER; i++) {
- printk("LF_PRINT:(%2d) thr=%d,blim=%3d,lim=%2d\n",
- i, lfi->lfthr[i].hev_thr,
- lfi->lfthr[i].mblim, lfi->lfthr[i].lim);
- }
- for (plane = 0; plane < 3; plane++) {
- for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) { // MAX_SEGMENTS==8
- for (dir = 0; dir < 2; ++dir) {
- int32_t mode;
- for (mode = 0; mode < 2; ++mode) {
- printk("assign {lvl[%d][%d][%d][0][%d],lvl[%d][%d][%d][1][%d],lvl[%d][%d][%d][2][%d],lvl[%d][%d][%d][3][%d],lvl[%d][%d][%d][4][%d],lvl[%d][%d][%d][5][%d],lvl[%d][%d][%d][6][%d],lvl[%d][%d][%d][7][%d]}={6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d,6'd%2d};\n",
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- plane, seg_id, dir, mode,
- lfi->lvl[plane][seg_id][dir][0][mode],
- lfi->lvl[plane][seg_id][dir][1][mode],
- lfi->lvl[plane][seg_id][dir][2][mode],
- lfi->lvl[plane][seg_id][dir][3][mode],
- lfi->lvl[plane][seg_id][dir][4][mode],
- lfi->lvl[plane][seg_id][dir][5][mode],
- lfi->lvl[plane][seg_id][dir][6][mode],
- lfi->lvl[plane][seg_id][dir][7][mode]);
- }
- }
- }
- }
-#endif
- // Write to register
- for (i = 0; i < 192; i++) {
- uint32_t level;
- level = ((lfi->lvl[i>>6&3][i>>3&7][1][i&7][1] & 0x3f)<<24) |
- ((lfi->lvl[i>>6&3][i>>3&7][1][i&7][0] & 0x3f)<<16) |
- ((lfi->lvl[i>>6&3][i>>3&7][0][i&7][1] & 0x3f)<<8) |
- (lfi->lvl[i>>6&3][i>>3&7][0][i&7][0] & 0x3f);
- if (!lf->filter_level[0] && !lf->filter_level[1])
- level = 0;
- WRITE_VREG(HEVC_DBLK_CFGA, level);
- }
-#endif // DBG_LPF_DBLK_LVL
-
-#ifdef DBG_LPF_DBLK_FORCED_OFF
- if (lf->lf_pic_cnt == 2) {
- printk("LF_PRINT: pic_cnt(%d) dblk forced off !!!\n", lf->lf_pic_cnt);
- WRITE_VREG(HEVC_DBLK_DBLK0, 0);
- } else
- WRITE_VREG(HEVC_DBLK_DBLK0,
- lf->filter_level[0] | lf->filter_level[1] << 6 |
- lf->filter_level_u << 12 | lf->filter_level_v << 18);
-#else
- WRITE_VREG(HEVC_DBLK_DBLK0,
- lf->filter_level[0] | lf->filter_level[1]<<6 |
- lf->filter_level_u<<12 | lf->filter_level_v<<18);
-#endif
- for (i =0; i < 10; i++)
- WRITE_VREG(HEVC_DBLK_DBLK1,
- ((i<2) ? lf->mode_deltas[i&1] : lf->ref_deltas[(i-2)&7]));
- for (i = 0; i < 8; i++)
- WRITE_VREG(HEVC_DBLK_DBLK2,
- (uint32_t)(seg->seg_lf_info_y[i]) | (uint32_t)(seg->seg_lf_info_c[i]<<16));
-
- // Set P_HEVC_DBLK_CFGB again
- {
- uint32_t lpf_data32 = READ_VREG(HEVC_DBLK_CFGB);
- if (lf->mode_ref_delta_enabled)
- lpf_data32 |= (0x1<<28); // mode_ref_delta_enabled
- else
- lpf_data32 &= ~(0x1<<28);
- if (seg->enabled)
- lpf_data32 |= (0x1<<29); // seg enable
- else
- lpf_data32 &= ~(0x1<<29);
- if (pic_width >= 1280)
- lpf_data32 |= (0x1 << 4); // dblk pipeline mode=1 for performance
- else
- lpf_data32 &= ~(0x3 << 4);
- WRITE_VREG(HEVC_DBLK_CFGB, lpf_data32);
- }
- // Set CDEF
- WRITE_VREG(HEVC_DBLK_CDEF0, buf_spec->cdef_data.buf_start);
- {
- uint32_t cdef_data32 = (READ_VREG(HEVC_DBLK_CDEF1) & 0xffffff00);
- cdef_data32 |= 17; // TODO ERROR :: cdef temp dma address left offset
-#ifdef DBG_LPF_CDEF_NO_PIPELINE
- cdef_data32 |= (1<<17); // cdef test no pipeline for very small picture
-#endif
- WRITE_VREG(HEVC_DBLK_CDEF1, cdef_data32);
- }
- // Picture count
- lf->lf_pic_cnt++;
-}
-#endif // #ifdef AOM_AV1_DBLK_INIT
-
-#ifdef AOM_AV1_UPSCALE_INIT
-/*
- * these functions here for upscaling updated in every picture
- */
-#define RS_SUBPEL_BITS 6
-#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1)
-#define RS_SCALE_SUBPEL_BITS 14
-#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1)
-#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS)
-#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1))
-
-static int32_t av1_get_upscale_convolve_step(int32_t in_length, int32_t out_length) {
- return ((in_length << RS_SCALE_SUBPEL_BITS) + out_length / 2) / out_length;
-}
-
-static int32_t get_upscale_convolve_x0(int32_t in_length, int32_t out_length,
- int32_t x_step_qn) {
- const int32_t err = out_length * x_step_qn - (in_length << RS_SCALE_SUBPEL_BITS);
- const int32_t x0 =
- (-((out_length - in_length) << (RS_SCALE_SUBPEL_BITS - 1)) +
- out_length / 2) /
- out_length +
- RS_SCALE_EXTRA_OFF - err / 2;
- return (int32_t)((uint32_t)x0 & RS_SCALE_SUBPEL_MASK);
-}
-
-void av1_upscale_frame_init(AV1Decoder* pbi, AV1_COMMON *cm, param_t* params)
-{
- BuffInfo_t* buf_spec = pbi->work_space_buf;
- //uint32_t data32;
- const int32_t width = cm->dec_width;
- const int32_t superres_upscaled_width = cm->superres_upscaled_width;
- const int32_t x_step_qn_luma = av1_get_upscale_convolve_step(width, superres_upscaled_width);
- const int32_t x0_qn_luma = get_upscale_convolve_x0(width, superres_upscaled_width, x_step_qn_luma);
- const int32_t x_step_qn_chroma = av1_get_upscale_convolve_step((width+1)>>1, (superres_upscaled_width+1)>>1);
- const int32_t x0_qn_chroma = get_upscale_convolve_x0((width+1)>>1, (superres_upscaled_width+1)>>1, x_step_qn_chroma);
- av1_print2(AOM_DEBUG_HW_MORE,
- "UPS_PRINT: width(%d -> %d)\n",
- width, superres_upscaled_width);
- av1_print2(AOM_DEBUG_HW_MORE,
- "UPS_PRINT: xstep(%d,%d)(0x%X, 0x%X) x0qn(%d,%d)(0x%X, 0x%X)\n",
- x_step_qn_luma,x_step_qn_chroma,
- x_step_qn_luma,x_step_qn_chroma,
- x0_qn_luma,x0_qn_chroma,
- x0_qn_luma,x0_qn_chroma);
- WRITE_VREG(HEVC_DBLK_UPS1, buf_spec->ups_data.buf_start);
- WRITE_VREG(HEVC_DBLK_UPS2, x0_qn_luma); // x0_qn y
- WRITE_VREG(HEVC_DBLK_UPS3, x0_qn_chroma); // x0_qn c
- WRITE_VREG(HEVC_DBLK_UPS4, x_step_qn_luma); // x_step y
- WRITE_VREG(HEVC_DBLK_UPS5, x_step_qn_chroma); // x_step c
- WRITE_VREG(AV1_UPSCALE_X0_QN, (x0_qn_chroma<<16)|x0_qn_luma);
- WRITE_VREG(AV1_UPSCALE_STEP_QN, (x_step_qn_chroma<<16)|x_step_qn_luma);
-
-/*
- * TileR calculation here if cm needs an exactly accurate value
- */
-//#define AV1_UPSCALE_TILER_CALCULATION
-#ifdef AV1_UPSCALE_TILER_CALCULATION
- uint32_t upscl_enabled = 1; // 1 just for example, actually this is use_superres flag
- uint32_t tiler_x = 192; // 192 just for example, actually this is tile end
- uint32_t ux;
- uint32_t ux_tiler,ux_tiler_rnd32;
- uint32_t xqn_y;
- uint32_t xqn_c;
- uint32_t tiler_x_y = tiler_x - 8 - 3; // dblk/cdef left-shift-8 plus upscaling extra-3
- uint32_t tiler_x_c = (tiler_x/2) - 4 - 3; // dblk/cdef left-shift-4 plus upscaling extra-3
-
- xqn_y = x0_qn_luma;
- xqn_c = x0_qn_chroma;
- ux_tiler = 0;
- ux_tiler_rnd32 = 0;
- for (ux=0; ux<16384; ux+=8) {
- uint32_t x1qn_y = xqn_y + x_step_qn_luma *( 7+3); // extra-3 is for lrf
- uint32_t x1qn_c = xqn_c + x_step_qn_chroma*( 3+3); // extra-3 is for lrf
- uint32_t x1qn_y_nxt = xqn_y + x_step_qn_luma *(8+7+3); // extra-3 is for lrf
- uint32_t x1qn_c_nxt = xqn_c + x_step_qn_chroma*(4+3+3); // extra-3 is for lrf
-
- uint32_t x1_y = upscl_enabled ? (x1qn_y>>14) : ux +7+3;
- uint32_t x1_c = upscl_enabled ? (x1qn_c>>14) : (ux/2)+3+3;
- uint32_t x1_y_nxt = upscl_enabled ? (x1qn_y_nxt>>14) : ux +8+7+3;
- uint32_t x1_c_nxt = upscl_enabled ? (x1qn_c_nxt>>14) : (ux/2)+4+3+3;
-
- if ((x1_y<tiler_x_y && x1_c<tiler_x_c) &&
- (x1_y_nxt>=tiler_x_y || x1_c_nxt>=tiler_x_c)) {
- ux_tiler = ux;
- ux_tiler_rnd32 = (ux_tiler/32 + (ux_tiler%32 ? 1 : 0)) * 32;
- break;
- }
-
- xqn_y += x_step_qn_luma*8;
- xqn_c += x_step_qn_chroma*4;
- }
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "UPS_PRINT: xqn_y(0x%x), xqn_c(0x%x), x1qn_y(0x%x), x1qn_c(0x%x)\n",
- xqn_y, xqn_c, x1qn_y, x1qn_c);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "UPS_PRINT: ux_tiler(%d)(0x%x), ux_tiler_rnd32(%d)(0x%x)\n",
- ux_tiler, ux_tiler, ux_tiler_rnd32, ux_tiler_rnd32);
-#endif
-
- // TEMP write lrf register here
- //WRITE_VREG(HEVC_DBLK_LRF0, 1<<0 | 1<<2); // LRF UNIT SIZE
- //WRITE_VREG(HEVC_DBLK_LRF1, 3<<0 | 1<<8 | 1<<16 | 1<<24); // LRF UNIT NUMBER
-
- // TEMP Global Enables write here
- /*
- const uint32_t dblk_enable = (!cm->allow_intrabc && !cm->single_tile_decoding && (cm->lf.filter_level[0] || cm->lf.filter_level[1]));
- const uint32_t cdef_enable = (!cm->allow_intrabc && !cm->single_tile_decoding && !cm->skip_loop_filter && !cm->coded_lossless && (cm->cdef_bits || cm->cdef_strengths[0] || cm->cdef_uv_strengths[0]));
- printk("LPF_ENABLES : dblk(%d) cdef(%d)\n", dblk_enable, cdef_enable);
- data32 = READ_VREG(HEVC_DBLK_CFGB );
- data32 &= ~(0xf<<20);
- data32 |= (dblk_enable<<20);
- data32 |= (cdef_enable<<23);
- WRITE_VREG(HEVC_DBLK_CFGB, data32);
- */
-}
-
-#endif // #ifdef AOM_AV1_UPSCALE_INIT
-
-static void release_dblk_struct(struct AV1HW_s *hw)
-{
-#ifdef AOM_AV1_DBLK_INIT
- if (hw->lfi)
- vfree(hw->lfi);
- if (hw->lf)
- vfree(hw->lf);
- if (hw->seg_4lf)
- vfree(hw->seg_4lf);
- hw->lfi = NULL;
- hw->lf = NULL;
- hw->seg_4lf = NULL;
-#endif
-}
-
-static int init_dblk_struc(struct AV1HW_s *hw)
-{
-#ifdef AOM_AV1_DBLK_INIT
- hw->lfi = vmalloc(sizeof(loop_filter_info_n));
- hw->lf = vmalloc(sizeof(struct loopfilter));
- hw->seg_4lf = vmalloc(sizeof(struct segmentation_lf));
-
- if (hw->lfi == NULL || hw->lf == NULL || hw->seg_4lf == NULL) {
- printk("[test.c] aom_loop_filter init malloc error!!!\n");
- release_dblk_struct(hw);
- return -1;
- }
-
- hw->lf->mode_ref_delta_enabled = 1; // set default here
- hw->lf->mode_ref_delta_update = 1; // set default here
- hw->lf->sharpness_level = 0; // init to 0
- hw->lf->lf_pic_cnt = 0; // init to 0
-#endif
- return 0;
-}
-
-static void config_dblk_hw(struct AV1HW_s *hw)
-{
- AV1Decoder *pbi = hw->pbi;
- AV1_COMMON *cm = &hw->common;
- loop_filter_info_n *lfi = hw->lfi;
- struct loopfilter *lf = hw->lf;
- struct segmentation_lf *seg_4lf = hw->seg_4lf;
- BuffInfo_t* buf_spec = pbi->work_space_buf;
- PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf;
- PIC_BUFFER_CONFIG* prev_pic_config = &cm->prev_frame->buf;
- int i;
-
-#ifdef AOM_AV1_DBLK_INIT
-#ifdef DUAL_DECODE
-#else
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c ref_delta] cur_frame : %p prev_frame : %p - %p \n",
- cm->cur_frame, cm->prev_frame,
- av1_get_primary_ref_frame_buf(cm));
- // get lf parameters from parser
- lf->mode_ref_delta_enabled =
- (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 1);
- lf->mode_ref_delta_update =
- ((hw->aom_param.p.loop_filter_mode_ref_delta_enabled >> 1) & 1);
- lf->sharpness_level =
- hw->aom_param.p.loop_filter_sharpness_level;
- if (((hw->aom_param.p.loop_filter_mode_ref_delta_enabled)&3) == 3) { // enabled but and update
- if (cm->prev_frame <= 0) {
- // already initialized in Microcode
- lf->ref_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7);
- lf->ref_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7);
- lf->ref_deltas[2] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1),7);
- lf->ref_deltas[3] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1>>8),7);
- lf->ref_deltas[4] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2),7);
- lf->ref_deltas[5] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2>>8),7);
- lf->ref_deltas[6] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3),7);
- lf->ref_deltas[7] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3>>8),7);
- lf->mode_deltas[0] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0),7);
- lf->mode_deltas[1] = conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0>>8),7);
- } else {
- lf->ref_deltas[0] = (hw->aom_param.p.loop_filter_ref_deltas_0 & 0x80) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0),7) :
- cm->prev_frame->ref_deltas[0];
- lf->ref_deltas[1] = (hw->aom_param.p.loop_filter_ref_deltas_0 & 0x8000) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_0>>8),7) :
- cm->prev_frame->ref_deltas[1];
- lf->ref_deltas[2] = (hw->aom_param.p.loop_filter_ref_deltas_1 & 0x80) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1),7) :
- cm->prev_frame->ref_deltas[2];
- lf->ref_deltas[3] = (hw->aom_param.p.loop_filter_ref_deltas_1 & 0x8000) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_1>>8),7) :
- cm->prev_frame->ref_deltas[3];
- lf->ref_deltas[4] = (hw->aom_param.p.loop_filter_ref_deltas_2 & 0x80) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2),7) :
- cm->prev_frame->ref_deltas[4];
- lf->ref_deltas[5] = (hw->aom_param.p.loop_filter_ref_deltas_2 & 0x8000) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_2>>8),7) :
- cm->prev_frame->ref_deltas[5];
- lf->ref_deltas[6] = (hw->aom_param.p.loop_filter_ref_deltas_3 & 0x80) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3),7) :
- cm->prev_frame->ref_deltas[6];
- lf->ref_deltas[7] = (hw->aom_param.p.loop_filter_ref_deltas_3 & 0x8000) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_ref_deltas_3>>8),7) :
- cm->prev_frame->ref_deltas[7];
- lf->mode_deltas[0] = (hw->aom_param.p.loop_filter_mode_deltas_0 & 0x80) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0),7) :
- cm->prev_frame->mode_deltas[0];
- lf->mode_deltas[1] = (hw->aom_param.p.loop_filter_mode_deltas_0 & 0x8000) ?
- conv2int8((uint8_t)(hw->aom_param.p.loop_filter_mode_deltas_0>>8),7) :
- cm->prev_frame->mode_deltas[1];
- }
- } //else if (hw->aom_param.p.loop_filter_mode_ref_delta_enabled == 1) { // enabled but no update
- else { // match c code -- not enabled, still need to copy prev to used for next
- if ((cm->prev_frame <= 0) | (hw->aom_param.p.loop_filter_mode_ref_delta_enabled & 4)) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] mode_ref_delta set to default\n");
- lf->ref_deltas[0] = conv2int8((uint8_t)1,7);
- lf->ref_deltas[1] = conv2int8((uint8_t)0,7);
- lf->ref_deltas[2] = conv2int8((uint8_t)0,7);
- lf->ref_deltas[3] = conv2int8((uint8_t)0,7);
- lf->ref_deltas[4] = conv2int8((uint8_t)0xff,7);
- lf->ref_deltas[5] = conv2int8((uint8_t)0,7);
- lf->ref_deltas[6] = conv2int8((uint8_t)0xff,7);
- lf->ref_deltas[7] = conv2int8((uint8_t)0xff,7);
- lf->mode_deltas[0] = conv2int8((uint8_t)0,7);
- lf->mode_deltas[1] = conv2int8((uint8_t)0,7);
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] mode_ref_delta copy from prev_frame\n");
- lf->ref_deltas[0] = cm->prev_frame->ref_deltas[0];
- lf->ref_deltas[1] = cm->prev_frame->ref_deltas[1];
- lf->ref_deltas[2] = cm->prev_frame->ref_deltas[2];
- lf->ref_deltas[3] = cm->prev_frame->ref_deltas[3];
- lf->ref_deltas[4] = cm->prev_frame->ref_deltas[4];
- lf->ref_deltas[5] = cm->prev_frame->ref_deltas[5];
- lf->ref_deltas[6] = cm->prev_frame->ref_deltas[6];
- lf->ref_deltas[7] = cm->prev_frame->ref_deltas[7];
- lf->mode_deltas[0] = cm->prev_frame->mode_deltas[0];
- lf->mode_deltas[1] = cm->prev_frame->mode_deltas[1];
- }
- }
- lf->filter_level[0] = hw->aom_param.p.loop_filter_level_0;
- lf->filter_level[1] = hw->aom_param.p.loop_filter_level_1;
- lf->filter_level_u = hw->aom_param.p.loop_filter_level_u;
- lf->filter_level_v = hw->aom_param.p.loop_filter_level_v;
-
- cm->cur_frame->ref_deltas[0] = lf->ref_deltas[0];
- cm->cur_frame->ref_deltas[1] = lf->ref_deltas[1];
- cm->cur_frame->ref_deltas[2] = lf->ref_deltas[2];
- cm->cur_frame->ref_deltas[3] = lf->ref_deltas[3];
- cm->cur_frame->ref_deltas[4] = lf->ref_deltas[4];
- cm->cur_frame->ref_deltas[5] = lf->ref_deltas[5];
- cm->cur_frame->ref_deltas[6] = lf->ref_deltas[6];
- cm->cur_frame->ref_deltas[7] = lf->ref_deltas[7];
- cm->cur_frame->mode_deltas[0] = lf->mode_deltas[0];
- cm->cur_frame->mode_deltas[1] = lf->mode_deltas[1];
-
- // get seg_4lf parameters from parser
- seg_4lf->enabled = hw->aom_param.p.segmentation_enabled & 1;
- cm->cur_frame->segmentation_enabled = hw->aom_param.p.segmentation_enabled & 1;
- cm->cur_frame->intra_only = (hw->aom_param.p.segmentation_enabled >> 2) & 1;
- cm->cur_frame->segmentation_update_map = (hw->aom_param.p.segmentation_enabled >> 3) & 1;
-
- if (hw->aom_param.p.segmentation_enabled & 1) { // segmentation_enabled
- if (hw->aom_param.p.segmentation_enabled & 2) { // segmentation_update_data
- for (i = 0; i < MAX_SEGMENTS; i++) {
- seg_4lf->seg_lf_info_y[i] = hw->aom_param.p.seg_lf_info_y[i];
- seg_4lf->seg_lf_info_c[i] = hw->aom_param.p.seg_lf_info_c[i];
- #ifdef DBG_LPF_PRINT
- printk(" read seg_lf_info [%d] : 0x%x, 0x%x\n",
- i, seg_4lf->seg_lf_info_y[i], seg_4lf->seg_lf_info_c[i]);
- #endif
- }
- } // segmentation_update_data
- else { // no segmentation_update_data
- if (cm->prev_frame <= 0) {
- for (i=0;i<MAX_SEGMENTS;i++) {
- seg_4lf->seg_lf_info_y[i] = 0;
- seg_4lf->seg_lf_info_c[i] = 0;
- }
- } else {
- for (i = 0; i < MAX_SEGMENTS; i++) {
- seg_4lf->seg_lf_info_y[i] = cm->prev_frame->seg_lf_info_y[i];
- seg_4lf->seg_lf_info_c[i] = cm->prev_frame->seg_lf_info_c[i];
- #ifdef DBG_LPF_PRINT
- printk(" Refrence seg_lf_info [%d] : 0x%x, 0x%x\n",
- i, seg_4lf->seg_lf_info_y[i], seg_4lf->seg_lf_info_c[i]);
- #endif
- }
- }
- } // no segmentation_update_data
- } // segmentation_enabled
- else {
- for (i=0;i<MAX_SEGMENTS;i++) {
- seg_4lf->seg_lf_info_y[i] = 0;
- seg_4lf->seg_lf_info_c[i] = 0;
- }
- } // NOT segmentation_enabled
- for (i=0;i<MAX_SEGMENTS;i++) {
- cm->cur_frame->seg_lf_info_y[i] = seg_4lf->seg_lf_info_y[i];
- cm->cur_frame->seg_lf_info_c[i] = seg_4lf->seg_lf_info_c[i];
-#ifdef DBG_LPF_PRINT
- printk(" SAVE seg_lf_info [%d] : 0x%x, 0x%x\n",
- i, cm->cur_frame->seg_lf_info_y[i],
- cm->cur_frame->seg_lf_info_c[i]);
-#endif
- }
-
- /*
- * Update loop filter Thr/Lvl table for every frame
- */
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] av1_loop_filter_frame_init (run before every frame decoding start)\n");
- av1_loop_filter_frame_init(pbi, seg_4lf, lfi, lf, cm->dec_width);
-#endif // not DUAL_DECODE
-#endif
-
-#ifdef AOM_AV1_UPSCALE_INIT
- /*
- * init for upscaling
- */
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] av1_upscale_frame_init (run before every frame decoding start)\n");
- av1_upscale_frame_init(pbi,
- pbi->common, &hw->aom_param);
-#endif // #ifdef AOM_AV1_UPSCALE_INIT
-
- //BuffInfo_t* buf_spec = pbi->work_space_buf;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] cur_frame : %p prev_frame : %p - %p \n",
- cm->cur_frame, cm->prev_frame, av1_get_primary_ref_frame_buf(cm));
- if (cm->cur_frame <= 0) {
- WRITE_VREG(AOM_AV1_CDF_BUFFER_W, buf_spec->cdf_buf.buf_start);
- WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W, buf_spec->seg_map.buf_start);
- }
- else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] Config WRITE CDF_BUF/SEG_MAP_BUF : %d\n",
- cur_pic_config->index);
- WRITE_VREG(AOM_AV1_CDF_BUFFER_W,
- buf_spec->cdf_buf.buf_start + (0x8000*cur_pic_config->index));
- WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_W,
- buf_spec->seg_map.buf_start + ((buf_spec->seg_map.buf_size / 16) * cur_pic_config->index));
- }
- cm->cur_frame->seg_mi_rows = cm->cur_frame->mi_rows;
- cm->cur_frame->seg_mi_cols = cm->cur_frame->mi_cols;
- if (cm->prev_frame <= 0) {
- WRITE_VREG(AOM_AV1_CDF_BUFFER_R, buf_spec->cdf_buf.buf_start);
- WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R, buf_spec->seg_map.buf_start);
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] Config READ CDF_BUF/SEG_MAP_BUF : %d\n",
- prev_pic_config->index);
- WRITE_VREG(AOM_AV1_CDF_BUFFER_R,
- buf_spec->cdf_buf.buf_start + (0x8000*prev_pic_config->index));
- WRITE_VREG(AOM_AV1_SEG_MAP_BUFFER_R,
- buf_spec->seg_map.buf_start + ((buf_spec->seg_map.buf_size / 16) * prev_pic_config->index));
-
- // segmentation_enabled but no segmentation_update_data
- if ((hw->aom_param.p.segmentation_enabled & 3) == 1) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] segfeatures_copy from prev_frame\n");
- for (i = 0; i < 8; i++) {
- WRITE_VREG(AOM_AV1_SEGMENT_FEATURE,
- cm->prev_frame->segment_feature[i]);
- }
- }
- // segmentation_enabled but no segmentation_update_map
- if ((hw->aom_param.p.segmentation_enabled & 9) == 1) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] seg_map_size copy from prev_frame\n");
- cm->cur_frame->seg_mi_rows = cm->prev_frame->seg_mi_rows;
- cm->cur_frame->seg_mi_cols = cm->prev_frame->seg_mi_cols;
- }
- }
-#ifdef PRINT_HEVC_DATA_PATH_MONITOR
- {
- uint32_t total_clk_count;
- uint32_t path_transfer_count;
- uint32_t path_wait_count;
- float path_wait_ratio;
- if (pbi->decode_idx > 1) {
- WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disabble monitor and set rd_idx to 0
- total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
-
- WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disabble monitor and set rd_idx to 0
-
- // parser --> iqit
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else
- path_wait_ratio =
- (float)path_wait_count/(float)path_transfer_count;
- printk("[P%d HEVC PATH] Parser/IQIT/IPP/DBLK/OW/DDR/CMD WAITING \% : %.2f",
- pbi->decode_idx - 2,
- path_wait_ratio);
-
- // iqit --> ipp
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else
- path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
- // dblk <-- ipp
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else
- path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
- // dblk --> ow
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else path_wait_ratio =
- (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
- // <--> DDR
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else path_wait_ratio =
- (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
- // CMD
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0)
- path_wait_ratio = 0.0;
- else
- path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f\n", path_wait_ratio);
- }
- }
-
-#endif
-
-}
-
-static void aom_config_work_space_hw(struct AV1HW_s *hw, u32 mask)
-{
- struct BuffInfo_s *buf_spec = hw->work_space_buf;
- unsigned int data32;
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
- if (debug && hw->init_flag == 0)
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %x %x %x %x %x %x %x %x\n",
- __func__,
- buf_spec->ipp.buf_start,
- buf_spec->start_adr,
- buf_spec->short_term_rps.buf_start,
- buf_spec->sao_up.buf_start,
- buf_spec->swap_buf.buf_start,
- buf_spec->scalelut.buf_start,
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_data.buf_start);
- if (mask & HW_MASK_FRONT) {
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
- if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0)
- WRITE_VREG(HEVC_RPM_BUFFER, (u32)hw->rpm_phy_addr);
-
- /*WRITE_VREG(HEVC_STREAM_SWAP_BUFFER,
- buf_spec->swap_buf.buf_start);*/
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr);
-
- }
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
-
- WRITE_VREG(AOM_AV1_DAALA_TOP_BUFFER,
- buf_spec->daala_top.buf_start);
- WRITE_VREG(AV1_GMC_PARAM_BUFF_ADDR,
- buf_spec->gmc_buf.buf_start);
-
- WRITE_VREG(HEVC_DBLK_CFG4,
- buf_spec->dblk_para.buf_start); // cfg_addr_cif
- WRITE_VREG(HEVC_DBLK_CFG5,
- buf_spec->dblk_data.buf_start); // cfg_addr_xio
-
- if (mask & HW_MASK_BACK) {
-#ifdef LOSLESS_COMPRESS_MODE
- int losless_comp_header_size =
- compute_losless_comp_header_size(hw->init_pic_w,
- hw->init_pic_h);
- int losless_comp_body_size =
- compute_losless_comp_body_size(hw->init_pic_w,
- hw->init_pic_h, buf_alloc_depth == 10);
-#endif
-#ifdef AOM_AV1_MMU_DW
- int losless_comp_header_size_dw =
- compute_losless_comp_header_size_dw(hw->init_pic_w,
- hw->init_pic_h);
- int losless_comp_body_size_dw =
- compute_losless_comp_body_size_dw(hw->init_pic_w,
- hw->init_pic_h, buf_alloc_depth == 10);
-#endif
- WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,
- buf_spec->ipp.buf_start);
- //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
- //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
-#ifdef CHANGE_REMOVED
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- /* cfg_addr_adp*/
- WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start);
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info("Write HEVC_DBLK_CFGE\n");
- }
-#endif
- /* cfg_p_addr */
- WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
- /* cfg_d_addr */
- WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
- WRITE_VREG(HEVC_DBLK_CFG3, 0x404010); //default value
- else
- WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); // make left storage 2 x 4k]
- av1_print(hw, AV1_DEBUG_BUFMGR_MORE,
- "HEVC_DBLK_CFG3 = %x\n", READ_VREG(HEVC_DBLK_CFG3));
- }
-
-#ifdef LOSLESS_COMPRESS_MODE
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- /*bit[4] : paged_mem_mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
-#ifdef CHANGE_REMOVED
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1)
-#endif
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0);
- } else {
- /*if (cur_pic_config->bit_depth == AOM_BITS_10)
- * WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3));
- */
- /*bit[3] smem mdoe*/
- /*else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3));*/
- /*bit[3] smem mdoe*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,
- (losless_comp_body_size >> 5));
- }
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,
- (losless_comp_body_size >> 5));*/
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,
- (0xff<<20) | (0xff<<10) | 0xff);*/
- /*8-bit mode */
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
- if (get_double_write_mode(hw) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start
- + VBH_BUF_SIZE(buf_spec));
- /*data32 = READ_VREG(HEVC_SAO_CTRL9);*/
- /*data32 |= 0x1;*/
- /*WRITE_VREG(HEVC_SAO_CTRL9, data32);*/
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-#ifdef AOM_AV1_MMU_DW
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- if (get_double_write_mode(hw) & 0x20) {
- u32 data_tmp;
- data_tmp = READ_VREG(HEVC_SAO_CTRL9);
- data_tmp |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL9, data_tmp);
-
- WRITE_VREG(HEVC_CM_BODY_LENGTH2,losless_comp_body_size_dw);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET2,losless_comp_body_size_dw);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH2,losless_comp_header_size_dw);
-
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2, buf_spec->mmu_vbh_dw.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2, buf_spec->mmu_vbh_dw.buf_start
- + DW_VBH_BUF_SIZE(buf_spec));
-
- WRITE_VREG(HEVC_DW_VH0_ADDDR, buf_spec->mmu_vbh_dw.buf_start
- + (2 * DW_VBH_BUF_SIZE(buf_spec)));
- WRITE_VREG(HEVC_DW_VH1_ADDDR, buf_spec->mmu_vbh_dw.buf_start
- + (3 * DW_VBH_BUF_SIZE(buf_spec)));
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 |= (1<<15);
- } else
- data32 &= ~(1<<15);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-#endif
-
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr);
-#ifdef CHANGE_REMOVED
-
- WRITE_VREG(AV1_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start);
-
- /**/
- WRITE_VREG(AV1_PROB_SWAP_BUFFER, hw->prob_buffer_phy_addr);
- WRITE_VREG(AV1_COUNT_SWAP_BUFFER, hw->count_buffer_phy_addr);
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, hw->frame_mmu_map_phy_addr);
- else
- WRITE_VREG(AV1_MMU_MAP_BUFFER, hw->frame_mmu_map_phy_addr);
- }
-#else
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL, hw->frame_mmu_map_phy_addr);
- }
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, hw->dw_frame_mmu_map_phy_addr);
- //default of 0xffffffff will disable dw
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
- }
-#endif
-#endif
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T5D) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
-#endif
- }
-
- config_aux_buf(hw);
-}
-
-#ifdef MCRCC_ENABLE
-static u32 mcrcc_cache_alg_flag = 1;
-static void mcrcc_perfcount_reset(struct AV1HW_s *hw);
-static void decomp_perfcount_reset(struct AV1HW_s *hw);
-#endif
-
-static void aom_init_decoder_hw(struct AV1HW_s *hw, u32 mask)
-{
- unsigned int data32;
- int i;
- const unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
- 0x0401, 0x8401, 0x0800, 0x0402, 0x9002, 0x1423,
- 0x8CC3, 0x1423, 0x8804, 0x9825, 0x0800, 0x04FE,
- 0x8406, 0x8411, 0x1800, 0x8408, 0x8409, 0x8C2A,
- 0x9C2B, 0x1C00, 0x840F, 0x8407, 0x8000, 0x8408,
- 0x2000, 0xA800, 0x8410, 0x04DE, 0x840C, 0x840D,
- 0xAC00, 0xA000, 0x08C0, 0x08E0, 0xA40E, 0xFC00,
- 0x7C00
- };
-#if 0
- if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) {
- /* Set MCR fetch priorities*/
- data32 = 0x1 | (0x1 << 2) | (0x1 <<3) |
- (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
- WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
- }
-#endif
- /*if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info("%s\n", __func__);*/
- if (mask & HW_MASK_FRONT) {
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
-#ifdef CHANGE_REMOVED
-#if 1
- /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
- data32 &= ~(7 << 29);
- data32 |= (3 << 29);
-#endif
- data32 = data32 |
- (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
- (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
- (1 << 7) |/*dec_done_int_cpu_enable*/
- (1 << 4) |/*startcode_found_int_cpu_enable*/
- (0 << 3) |/*startcode_found_int_amrisc_enable*/
- (1 << 0) /*parser_int_enable*/
- ;
-#else
- data32 = data32 & 0x03ffffff;
- data32 = data32 |
- (3 << 29) | // stream_buffer_empty_int_ctl ( 0x200 interrupt)
- (3 << 26) | // stream_fifo_empty_int_ctl ( 4 interrupt)
- (1 << 24) | // stream_buffer_empty_int_amrisc_enable
- (1 << 22) | // stream_fifo_empty_int_amrisc_enable
-#ifdef AOM_AV1_HED_FB
-#ifdef DUAL_DECODE
- // For HALT CCPU test. Use Pull inside CCPU to generate interrupt
- // (1 << 9) | // fed_fb_slice_done_int_amrisc_enable
-#else
- (1 << 10) | // fed_fb_slice_done_int_cpu_enable
-#endif
-#endif
- (1 << 7) | // dec_done_int_cpu_enable
- (1 << 4) | // startcode_found_int_cpu_enable
- (0 << 3) | // startcode_found_int_amrisc_enable
- (1 << 0) // parser_int_enable
- ;
-#endif
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STATUS);
- data32 = data32 |
- (0 << 1) |/*emulation_check_off AV1
- do not have emulation*/
- (1 << 0)/*startcode_check_on*/
- ;
- WRITE_VREG(HEVC_SHIFT_STATUS, data32);
- WRITE_VREG(HEVC_SHIFT_CONTROL,
- (0 << 14) | /*disable_start_code_protect*/
- (1 << 10) | /*length_zero_startcode_en for AV1*/
- (1 << 9) | /*length_valid_startcode_en for AV1*/
- (3 << 6) | /*sft_valid_wr_position*/
- (2 << 4) | /*emulate_code_length_sub_1*/
- (3 << 1) | /*start_code_length_sub_1
- AV1 use 0x00000001 as startcode (4 Bytes)*/
- (1 << 0) /*stream_shift_enable*/
- );
-
- WRITE_VREG(HEVC_CABAC_CONTROL,
- (1 << 0)/*cabac_enable*/
- );
-
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
- (1 << 0)/* hevc_parser_core_clk_en*/
- );
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
- }
-
- if (mask & HW_MASK_BACK) {
- /*Initial IQIT_SCALELUT memory
- -- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(hw->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
- }
-
- if (mask & HW_MASK_FRONT) {
- u32 decode_mode;
-/*
-#ifdef ENABLE_SWAP_TEST
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
-#else
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
-#endif
-*/
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hw->m_ins_flag) {
- if (hw->low_latency_flag)
- decode_mode = DECODE_MODE_SINGLE_LOW_LATENCY;
- else
- decode_mode = DECODE_MODE_SINGLE;
- } else if (vdec_frame_based(hw_to_vdec(hw)))
- decode_mode = hw->no_head ?
- DECODE_MODE_MULTI_FRAMEBASE_NOHEAD :
- DECODE_MODE_MULTI_FRAMEBASE;
- else
- decode_mode = DECODE_MODE_MULTI_STREAMBASE;
- if (debug & AOM_DEBUG_BUFMGR_ONLY)
- decode_mode |= (1 << 16);
- WRITE_VREG(DECODE_MODE, decode_mode);
- WRITE_VREG(HEVC_DECODE_SIZE, 0);
- WRITE_VREG(HEVC_DECODE_COUNT, 0);
-#else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
- WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
- WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0x7fffffff); /*to remove*/
-#endif
- /*Send parser_cmd*/
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
- for (i = 0; i < PARSER_CMD_NUMBER; i++)
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
-
-
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- /* (1 << 8) |*/ /*sao_sw_pred_enable*/
- (1 << 5) | /*parser_sao_if_en*/
- (1 << 2) | /*parser_mpred_if_en*/
- (1 << 0) /*parser_scaler_if_en*/
- );
- }
-
- if (mask & HW_MASK_BACK) {
- /*Changed to Start MPRED in microcode*/
- /*
- pr_info("[test.c] Start MPRED\n");
- WRITE_VREG(HEVC_MPRED_INT_STATUS,
- (1<<31)
- );
- */
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (0 << 1) | /*enable ipp*/
- (1 << 0) /*software reset ipp and mpp*/
- );
-#ifdef CHANGE_REMOVED
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (1 << 1) | /*enable ipp*/
- (0 << 0) /*software reset ipp and mpp*/
- );
-#else
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (3 << 4) | // av1
- (1 << 1) | /*enable ipp*/
- (0 << 0) /*software reset ipp and mpp*/
- );
-#endif
- if (get_double_write_mode(hw) & 0x10) {
- /*Enable NV21 reference read mode for MC*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
- }
-#ifdef MCRCC_ENABLE
- /*Initialize mcrcc and decomp perf counters*/
- if (mcrcc_cache_alg_flag &&
- hw->init_flag == 0) {
- mcrcc_perfcount_reset(hw);
- decomp_perfcount_reset(hw);
- }
-#endif
- }
-#ifdef CHANGE_REMOVED
-#else
-// Set MCR fetch priorities
- data32 = 0x1 | (0x1 << 2) | (0x1 <<3) |
- (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
- WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
-#endif
- return;
-}
-
-
-#ifdef CONFIG_HEVC_CLK_FORCED_ON
-static void config_av1_clk_forced_on(void)
-{
- unsigned int rdata32;
- /*IQIT*/
- rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
- WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
-
- /* DBLK*/
- rdata32 = READ_VREG(HEVC_DBLK_CFG0);
- WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
-
- /* SAO*/
- rdata32 = READ_VREG(HEVC_SAO_CTRL1);
- WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
-
- /*MPRED*/
- rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
- WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
-
- /* PARSER*/
- rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
- WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
- WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
- WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
- rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1));
-
- /*IPP*/
- rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
- WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
-
- /* MCRCC*/
- rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
- WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
-}
-#endif
-
-
-static int vav1_mmu_map_alloc(struct AV1HW_s *hw)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- u32 mmu_map_size = vav1_frame_mmu_map_size(hw);
- hw->frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- mmu_map_size,
- &hw->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hw->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(hw->frame_mmu_map_addr, 0, mmu_map_size);
- }
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- u32 mmu_map_size = vaom_dw_frame_mmu_map_size(hw);
- hw->dw_frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- mmu_map_size,
- &hw->dw_frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hw->dw_frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(hw->dw_frame_mmu_map_addr, 0, mmu_map_size);
- }
-#endif
- return 0;
-}
-
-
-static void vav1_mmu_map_free(struct AV1HW_s *hw)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- u32 mmu_map_size = vav1_frame_mmu_map_size(hw);
- if (hw->frame_mmu_map_addr) {
- if (hw->frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- mmu_map_size,
- hw->frame_mmu_map_addr,
- hw->frame_mmu_map_phy_addr);
- hw->frame_mmu_map_addr = NULL;
- }
- }
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- u32 mmu_map_size = vaom_dw_frame_mmu_map_size(hw);
- if (hw->dw_frame_mmu_map_addr) {
- if (hw->dw_frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- mmu_map_size,
- hw->dw_frame_mmu_map_addr,
- hw->dw_frame_mmu_map_phy_addr);
- hw->dw_frame_mmu_map_addr = NULL;
- }
- }
-#endif
-}
-
-
-static void av1_local_uninit(struct AV1HW_s *hw, bool reset_flag)
-{
- hw->rpm_ptr = NULL;
- hw->lmem_ptr = NULL;
-
- if (!reset_flag) {
- hw->fg_ptr = NULL;
- if (hw->fg_addr) {
- if (hw->fg_phy_addr)
- codec_mm_dma_free_coherent(hw->fg_table_handle);
- hw->fg_addr = NULL;
- }
- }
-
- if (hw->rpm_addr) {
- dma_free_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE,
- hw->rpm_addr,
- hw->rpm_phy_addr);
- hw->rpm_addr = NULL;
- }
- if (hw->aux_addr) {
- dma_free_coherent(amports_get_dma_device(),
- hw->prefix_aux_size + hw->suffix_aux_size, hw->aux_addr,
- hw->aux_phy_addr);
- hw->aux_addr = NULL;
- }
-#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
- if (hw->ucode_log_addr) {
- dma_free_coherent(amports_get_dma_device(),
- UCODE_LOG_BUF_SIZE, hw->ucode_log_addr,
- hw->ucode_log_phy_addr);
- hw->ucode_log_addr = NULL;
- }
-#endif
- if (hw->lmem_addr) {
- if (hw->lmem_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, hw->lmem_addr,
- hw->lmem_phy_addr);
- hw->lmem_addr = NULL;
- }
-
- vav1_mmu_map_free(hw);
-
- if (hw->gvs)
- vfree(hw->gvs);
- hw->gvs = NULL;
-}
-
-static int av1_local_init(struct AV1HW_s *hw, bool reset_flag)
-{
- int ret = -1;
- /*int losless_comp_header_size, losless_comp_body_size;*/
-
- struct BuffInfo_s *cur_buf_info = NULL;
-
- memset(&hw->param, 0, sizeof(union param_u));
-#ifdef MULTI_INSTANCE_SUPPORT
- cur_buf_info = &hw->work_space_buf_store;
- hw->pbi->work_space_buf = cur_buf_info;
-#if 0
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &aom_workbuff_spec[1], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &aom_workbuff_spec[0],/* 1080p */
- sizeof(struct BuffInfo_s));
-#endif
- memcpy(cur_buf_info, &aom_workbuff_spec[hw->buffer_spec_index],
- sizeof(struct BuffInfo_s));
-
- cur_buf_info->start_adr = hw->buf_start;
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) ||
- (get_double_write_mode(hw) == 0x10))
- hw->mc_buf_spec.buf_end = hw->buf_start + hw->buf_size;
-
-#else
-/*! MULTI_INSTANCE_SUPPORT*/
-#if 0
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- cur_buf_info = &aom_workbuff_spec[1];/* 8k work space */
- else
- cur_buf_info = &aom_workbuff_spec[1];/* 4k2k work space */
- } else
- cur_buf_info = &aom_workbuff_spec[0];/* 1080p work space */
-#endif
- memcpy(cur_buf_info, &aom_workbuff_spec[hw->buffer_spec_index],
- sizeof(struct BuffInfo_s));
-#endif
-
- init_buff_spec(hw, cur_buf_info);
- aom_bufmgr_init(hw, cur_buf_info, NULL);
-
- if (!vdec_is_support_4k()
- && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
- buf_alloc_width = 1920;
- buf_alloc_height = 1088;
- if (hw->max_pic_w > 1920 && hw->max_pic_h > 1088) {
- hw->max_pic_w = 1920;
- hw->max_pic_h = 1088;
- }
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- buf_alloc_width = 8192;
- buf_alloc_height = 4608;
- }
-
- hw->init_pic_w = hw->max_pic_w ? hw->max_pic_w :
- (hw->vav1_amstream_dec_info.width ? hw->vav1_amstream_dec_info.width :
- (buf_alloc_width ? buf_alloc_width : hw->work_space_buf->max_width));
- hw->init_pic_h = hw->max_pic_h ? hw->max_pic_h :
- (hw->vav1_amstream_dec_info.height ? hw->vav1_amstream_dec_info.height :
- (buf_alloc_height ? buf_alloc_height : hw->work_space_buf->max_height));
-
- hw->pbi->frame_width = hw->init_pic_w;
- hw->pbi->frame_height = hw->init_pic_h;
-
- /* video is not support unaligned with 64 in tl1
- ** vdec canvas mode will be linear when dump yuv is set
- */
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_double_write_mode(hw) != 0) &&
- (((hw->max_pic_w % 64) != 0) ||
- (hw->vav1_amstream_dec_info.width % 64) != 0)) {
- if (hw_to_vdec(hw)->canvas_mode !=
- CANVAS_BLKMODE_LINEAR)
- hw->mem_map_mode = 2;
- else {
- hw->mem_map_mode = 0;
- av1_print(hw, AOM_DEBUG_HW_MORE, "vdec blkmod linear, force mem_map_mode 0\n");
- }
- }
-
-#if 0
-//ndef MV_USE_FIXED_BUF
- if (init_mv_buf_list(hw) < 0) {
- pr_err("%s: init_mv_buf_list fail\n", __func__);
- return -1;
- }
-#endif
-
- hw->mv_buf_margin = mv_buf_margin;
-
- hw->pts_unstable = ((unsigned long)(hw->vav1_amstream_dec_info.param)
- & 0x40) >> 6;
-
- if ((debug & AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) == 0) {
- hw->rpm_addr = dma_alloc_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE,
- &hw->rpm_phy_addr, GFP_KERNEL);
- if (hw->rpm_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
- hw->rpm_ptr = hw->rpm_addr;
- }
-
- if (prefix_aux_buf_size > 0 ||
- suffix_aux_buf_size > 0) {
- u32 aux_buf_size;
-
- hw->prefix_aux_size = AUX_BUF_ALIGN(prefix_aux_buf_size);
- hw->suffix_aux_size = AUX_BUF_ALIGN(suffix_aux_buf_size);
- aux_buf_size = hw->prefix_aux_size + hw->suffix_aux_size;
- hw->aux_addr = dma_alloc_coherent(amports_get_dma_device(),
- aux_buf_size, &hw->aux_phy_addr, GFP_KERNEL);
- if (hw->aux_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- goto dma_alloc_fail;
- }
- }
-#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
- //if (udebug_flag & 0x8) {
- hw->ucode_log_addr = dma_alloc_coherent(amports_get_dma_device(),
- UCODE_LOG_BUF_SIZE, &hw->ucode_log_phy_addr, GFP_KERNEL);
- if (hw->ucode_log_addr == NULL) {
- hw->ucode_log_phy_addr = 0;
- }
- pr_info("%s: alloc ucode log buffer %p\n",
- __func__, hw->ucode_log_addr);
- //}
-#endif
-
- if (!reset_flag) {
- int alloc_num = 1;
- if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_SC2) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5W)) {
- alloc_num = FRAME_BUFFERS;
- }
- hw->fg_addr = codec_mm_dma_alloc_coherent(&hw->fg_table_handle,
- (ulong *)&hw->fg_phy_addr,FGS_TABLE_SIZE * alloc_num, MEM_NAME);
- if (hw->fg_addr == NULL) {
- pr_err("%s: failed to alloc fg buffer\n", __func__);
- }
- hw->fg_ptr = hw->fg_addr;
- pr_info("%s, alloc fg table addr %lx, size 0x%x\n", __func__,
- (ulong)hw->fg_phy_addr, FGS_TABLE_SIZE * alloc_num);
- }
-
- hw->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE,
- &hw->lmem_phy_addr, GFP_KERNEL);
- if (hw->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- goto dma_alloc_fail;
- }
- hw->lmem_ptr = hw->lmem_addr;
-
- vdec_set_vframe_comm(hw_to_vdec(hw), DRIVER_NAME);
- ret = vav1_mmu_map_alloc(hw);
- if (ret < 0)
- goto dma_alloc_fail;
-
- return ret;
-
-dma_alloc_fail:
- av1_local_uninit(hw, reset_flag);
- return -1;
-}
-
-
-#define spec2canvas(x) \
- (((x)->uv_canvas_index << 16) | \
- ((x)->uv_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-
-static void set_canvas(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- struct vdec_s *vdec = hw_to_vdec(hw);
- int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4;
- int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4;
- int blkmode = hw->mem_map_mode;
- /*CANVAS_BLKMODE_64X32*/
- if (pic_config->double_write_mode) {
- canvas_w = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- canvas_h = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
-
- /* sao ctrl1 config aligned with 64, so aligned with 64 same */
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- if (vdec->parallel_dec == 1) {
- if (pic_config->y_canvas_index == -1)
- pic_config->y_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic_config->uv_canvas_index == -1)
- pic_config->uv_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic_config->y_canvas_index = 128 + pic_config->index * 2;
- pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1;
- }
-
- config_cav_lut_ex(pic_config->y_canvas_index,
- pic_config->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic_config->uv_canvas_index,
- pic_config->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, hw->is_used_v4l ? 0 : 7, VDEC_HEVC);
-
-#ifdef MULTI_INSTANCE_SUPPORT
- pic_config->canvas_config[0].phy_addr =
- pic_config->dw_y_adr;
- pic_config->canvas_config[0].width =
- canvas_w;
- pic_config->canvas_config[0].height =
- canvas_h;
- pic_config->canvas_config[0].block_mode =
- blkmode;
- pic_config->canvas_config[0].endian = hw->is_used_v4l ? 0 : 7;
-
- pic_config->canvas_config[1].phy_addr =
- pic_config->dw_u_v_adr;
- pic_config->canvas_config[1].width =
- canvas_w;
- pic_config->canvas_config[1].height =
- canvas_h;
- pic_config->canvas_config[1].block_mode =
- blkmode;
- pic_config->canvas_config[1].endian = hw->is_used_v4l ? 0 : 7;
-#endif
- }
-}
-
-static void set_frame_info(struct AV1HW_s *hw, struct vframe_s *vf)
-{
- unsigned int ar;
- vf->duration = hw->frame_dur;
- vf->duration_pulldown = 0;
- vf->flag = 0;
- vf->prop.master_display_colour = hw->vf_dp;
- vf->signal_type = hw->video_signal_type;
- if (vf->compWidth && vf->compHeight)
- hw->frame_ar = vf->compHeight * 0x100 / vf->compWidth;
- ar = min_t(u32, hw->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
-
- if (hw->is_used_v4l && (vf->signal_type != 0)) {
- struct aml_vdec_hdr_infos hdr;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.signal_type = vf->signal_type;
- hdr.color_parms = hw->vf_dp;
- hdr.color_parms.luminance[0] = hdr.color_parms.luminance[0] / 1000;
- vdec_v4l_set_hdr_infos(ctx, &hdr);
- }
-
- vf->sidebind_type = hw->sidebind_type;
- vf->sidebind_channel_id = hw->sidebind_channel_id;
-}
-
-static int vav1_vf_states(struct vframe_states *states, void *op_arg)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&hw->newframe_q);
- states->buf_avail_num = kfifo_len(&hw->display_q);
-
- if (step == 2)
- states->buf_avail_num = 0;
- return 0;
-}
-
-static struct vframe_s *vav1_vf_peek(void *op_arg)
-{
- struct vframe_s *vf[2] = {0, 0};
- struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
-
- if (step == 2)
- return NULL;
-
- if (kfifo_out_peek(&hw->display_q, (void *)&vf, 2)) {
- if (vf[1]) {
- vf[0]->next_vf_pts_valid = true;
- vf[0]->next_vf_pts = vf[1]->pts;
- } else
- vf[0]->next_vf_pts_valid = false;
- return vf[0];
- }
-
- return NULL;
-}
-
-static struct vframe_s *vav1_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
-
- if (step == 2)
- return NULL;
- else if (step == 1)
- step = 2;
-
- if (kfifo_get(&hw->display_q, &vf)) {
- struct vframe_s *next_vf = NULL;
- uint8_t index = vf->index & 0xff;
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
- if (index < hw->used_buf_num ||
- (vf->type & VIDTYPE_V4L_EOS)) {
- vf->index_disp = atomic_read(&hw->vf_get_count);
- atomic_add(1, &hw->vf_get_count);
- if (debug & AOM_DEBUG_VFRAME) {
- struct BufferPool_s *pool = hw->common.buffer_pool;
- struct PIC_BUFFER_CONFIG_s *pic =
- &pool->frame_bufs[index].buf;
- unsigned long flags;
- lock_buffer_pool(hw->common.buffer_pool, flags);
- av1_print(hw, AOM_DEBUG_VFRAME, "%s vf %px index 0x%x type 0x%x w/h %d/%d, aux size %d, pts %d, %lld, ts: %llu\n",
- __func__, vf, vf->index, vf->type,
- vf->width, vf->height,
- pic->aux_data_size,
- vf->pts,
- vf->pts_us64,
- vf->timestamp);
- unlock_buffer_pool(hw->common.buffer_pool, flags);
- }
-
- if (kfifo_peek(&hw->display_q, &next_vf) && next_vf) {
- vf->next_vf_pts_valid = true;
- vf->next_vf_pts = next_vf->pts;
- } else
- vf->next_vf_pts_valid = false;
-#ifdef DUMP_FILMGRAIN
- if (index == fg_dump_index) {
- unsigned long flags;
- int ii;
- lock_buffer_pool(hw->common.buffer_pool, flags);
- pr_info("FGS_TABLE for buffer %d:\n", index);
- for (ii = 0; ii < FGS_TABLE_SIZE; ii++) {
- pr_info("%02x ", hw->fg_ptr[ii]);
- if (((ii+ 1) & 0xf) == 0)
- pr_info("\n");
- }
- unlock_buffer_pool(hw->common.buffer_pool, flags);
- }
-#endif
-
- return vf;
- }
- }
- return NULL;
-}
-
-static void vav1_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
- uint8_t index = vf->index & 0xff;
- unsigned long flags;
-
- if ((vf == NULL) || (hw == NULL))
- return;
-
- kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
- atomic_add(1, &hw->vf_put_count);
- if (debug & AOM_DEBUG_VFRAME) {
- lock_buffer_pool(hw->common.buffer_pool, flags);
- av1_print(hw, AOM_DEBUG_VFRAME, "%s index 0x%x type 0x%x w/h %d/%d, pts %d, %lld, ts: %llu\n",
- __func__, vf->index, vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64,
- vf->timestamp);
- unlock_buffer_pool(hw->common.buffer_pool, flags);
- }
-
- if (index < hw->used_buf_num) {
- struct AV1_Common_s *cm = &hw->common;
- struct BufferPool_s *pool = cm->buffer_pool;
- PIC_BUFFER_CONFIG *pic = &pool->frame_bufs[index].buf;
-
- if (vf->v4l_mem_handle !=
- hw->m_BUF[pic->BUF_index].v4l_ref_buf_addr) {
- av1_print(hw, PRINT_FLAG_V4L_DETAIL,
- "AV1 update fb handle, old:%llx, new:%llx\n",
- hw->m_BUF[pic->BUF_index].v4l_ref_buf_addr,
- vf->v4l_mem_handle);
-
- hw->m_BUF[pic->BUF_index].v4l_ref_buf_addr =
- vf->v4l_mem_handle;
- }
-
- lock_buffer_pool(hw->common.buffer_pool, flags);
- if (pic->repeat_pic) {
- if (pic->repeat_pic->repeat_count > 0)
- pic->repeat_pic->repeat_count --;
- else
- av1_print(hw, PRINT_FLAG_ERROR, "repeat_count <= 0 pic:%px\n", pic);
- pic->repeat_pic = NULL;
- }
- if ((debug & AV1_DEBUG_IGNORE_VF_REF) == 0) {
- if (pool->frame_bufs[index].buf.vf_ref > 0)
- pool->frame_bufs[index].buf.vf_ref--;
- }
- if (hw->wait_buf)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
-
- hw->last_put_idx = index;
- hw->new_frame_displayed++;
-
- if (hw->wait_more_buf) {
- hw->wait_more_buf = false;
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- }
-
- unlock_buffer_pool(hw->common.buffer_pool, flags);
- }
-}
-
-static int vav1_event_cb(int type, void *data, void *op_arg)
-{
- unsigned long flags;
- struct AV1HW_s *hw = (struct AV1HW_s *)op_arg;
- struct AV1_Common_s *cm = &hw->common;
- struct BufferPool_s *pool = cm->buffer_pool;
-
- if (type & VFRAME_EVENT_RECEIVER_RESET) {
-#if 0
- unsigned long flags;
-
- amhevc_stop();
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_light_unreg_provider(&vav1_vf_prov);
-#endif
- spin_lock_irqsave(&hw->lock, flags);
- vav1_local_init();
- vav1_prot_init();
- spin_unlock_irqrestore(&hw->lock, flags);
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_reg_provider(&vav1_vf_prov);
-#endif
- amhevc_start();
-#endif
- } else if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) {
- struct provider_aux_req_s *req =
- (struct provider_aux_req_s *)data;
- unsigned char index;
-
- lock_buffer_pool(hw->common.buffer_pool, flags);
- index = req->vf->index & 0xff;
- req->aux_buf = NULL;
- req->aux_size = 0;
- if (req->bot_flag)
- index = (req->vf->index >> 8) & 0xff;
- if (index != 0xff
- && index < hw->used_buf_num) {
- struct PIC_BUFFER_CONFIG_s *pic_config =
- &pool->frame_bufs[index].buf;
- req->aux_buf = pic_config->aux_data_buf;
- req->aux_size = pic_config->aux_data_size;
-#if 0
-//def CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (hw->bypass_dvenl && !dolby_meta_with_el)
- req->dv_enhance_exist = false;
- else
- req->dv_enhance_exist =
- pic_config->dv_enhance_exist;
- av1_print(hw, AOM_DEBUG_VFRAME,
- "query dv_enhance_exist for pic (vf 0x%p, poc %d index %d) flag => %d, aux sizd 0x%x\n",
- req->vf,
- pic_config->POC, index,
- req->dv_enhance_exist, req->aux_size);
-#else
- req->dv_enhance_exist = 0;
-#endif
- }
- unlock_buffer_pool(hw->common.buffer_pool, flags);
-
- if (debug & AOM_DEBUG_AUX_DATA)
- av1_print(hw, 0,
- "%s(type 0x%x vf index 0x%x)=>size 0x%x\n",
- __func__, type, index, req->aux_size);
- } else if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(hw_to_vdec(hw));
- else
- req->req_result[0] = 0xffffffff;
- }
- return 0;
-}
-
-void av1_inc_vf_ref(struct AV1HW_s *hw, int index)
-{
- struct AV1_Common_s *cm = &hw->common;
-
- if ((debug & AV1_DEBUG_IGNORE_VF_REF) == 0) {
- cm->buffer_pool->frame_bufs[index].buf.vf_ref++;
-
- av1_print(hw, AV1_DEBUG_BUFMGR_MORE, "%s index = %d new vf_ref = %d\r\n",
- __func__, index,
- cm->buffer_pool->frame_bufs[index].buf.vf_ref);
- }
-}
-#if 0
-static int frame_duration_adapt(struct AV1HW_s *hw, struct vframe_s *vf, u32 valid)
-{
- u32 old_duration, pts_duration = 0;
- u32 pts = vf->pts;
-
- if (hw->get_frame_dur == true)
- return true;
-
- hw->frame_cnt_window++;
- if (!(hw->av1_first_pts_ready == 1)) {
- if (valid) {
- hw->pts1 = pts;
- hw->frame_cnt_window = 0;
- hw->duration_from_pts_done = 0;
- hw->av1_first_pts_ready = 1;
- } else {
- return false;
- }
- } else {
- if (pts < hw->pts1) {
- if (hw->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) {
- hw->pts1 = pts;
- hw->frame_cnt_window = 0;
- }
- }
-
- if (valid && (hw->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) &&
- (pts > hw->pts1) && (hw->duration_from_pts_done == 0)) {
- old_duration = hw->frame_dur;
- hw->pts2 = pts;
- pts_duration = (((hw->pts2 - hw->pts1) * 16) /
- (hw->frame_cnt_window * 15));
-
- if (close_to(pts_duration, old_duration, 2000)) {
- hw->frame_dur = pts_duration;
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "use calc duration %d\n", pts_duration);
- }
-
- if (hw->duration_from_pts_done == 0) {
- if (close_to(pts_duration, old_duration, RATE_CORRECTION_THRESHOLD)) {
- hw->duration_from_pts_done = 1;
- } else {
- if (!close_to(pts_duration,
- old_duration, 1000) &&
- !close_to(pts_duration,
- hw->frame_dur, 1000) &&
- close_to(pts_duration,
- hw->last_duration, 200)) {
- /* frame_dur must
- * wrong,recover it.
- */
- hw->frame_dur = pts_duration;
- }
- hw->pts1 = hw->pts2;
- hw->frame_cnt_window = 0;
- hw->duration_from_pts_done = 0;
- }
- }
- hw->last_duration = pts_duration;
- }
- }
- return true;
-}
-#endif
-
-static void update_vf_memhandle(struct AV1HW_s *hw,
- struct vframe_s *vf, struct PIC_BUFFER_CONFIG_s *pic)
-{
- /* keeper not needed for v4l solution */
- if (hw->is_used_v4l)
- return;
-
- if (pic->index < 0) {
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
- vf->mem_dw_handle = NULL;
- } else if (vf->type & VIDTYPE_SCATTER) {
-#ifdef AOM_AV1_MMU_DW
- if (pic->double_write_mode & 0x20 &&
- (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hw->mmu_box_dw, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box,
- DW_HEADER_BUFFER_IDX(pic->BUF_index));
- vf->mem_dw_handle = NULL;
- } else
-#endif
- {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- hw->mmu_box, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
- if (get_double_write_mode(hw) == 3)
- vf->mem_dw_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box,
- VF_BUFFER_IDX(pic->BUF_index));
- else
- vf->mem_dw_handle = NULL;
- }
-#ifdef USE_SPEC_BUF_FOR_MMU_HEAD
- vf->mem_head_handle = NULL;
-#endif
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- hw->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- vf->mem_head_handle = NULL;
- vf->mem_dw_handle = NULL;
- /*vf->mem_head_handle =
- *decoder_bmmu_box_get_mem_handle(
- *hw->bmmu_box, VF_BUFFER_IDX(BUF_index));
- */
- }
-}
-
-static inline void av1_update_gvs(struct AV1HW_s *hw, struct vframe_s *vf,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- if (hw->gvs->frame_height != pic_config->y_crop_height) {
- hw->gvs->frame_width = pic_config->y_crop_width;
- hw->gvs->frame_height = pic_config->y_crop_height;
- }
- if (hw->gvs->frame_dur != hw->frame_dur) {
- hw->gvs->frame_dur = hw->frame_dur;
- if (hw->frame_dur != 0)
- hw->gvs->frame_rate = ((96000 * 10 / hw->frame_dur) % 10) < 5 ?
- 96000 / hw->frame_dur : (96000 / hw->frame_dur +1);
- else
- hw->gvs->frame_rate = -1;
- }
- if (vf && hw->gvs->ratio_control != vf->ratio_control)
- hw->gvs->ratio_control = vf->ratio_control;
-
- hw->gvs->status = hw->stat | hw->fatal_error;
- hw->gvs->error_count = hw->gvs->error_frame_count;
-
-}
-
-static int prepare_display_buf(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- struct vframe_s *vf = NULL;
- struct vdec_info tmp4x;
- int stream_offset = pic_config->stream_offset;
- struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- ulong nv_order = VIDTYPE_VIU_NV21;
- u32 pts_valid = 0, pts_us64_valid = 0;
- u32 frame_size;
- int i, reclac_flag = 0;
-
- av1_print(hw, AOM_DEBUG_VFRAME, "%s index = %d\r\n", __func__, pic_config->index);
- if (kfifo_get(&hw->newframe_q, &vf) == 0) {
- av1_print(hw, 0, "fatal error, no available buffer slot.");
- return -1;
- }
-
- /* swap uv */
- if (hw->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0)
- set_canvas(hw, pic_config);
-
- display_frame_count[hw->index]++;
- if (vf) {
- if (!force_pts_unstable && hw->av1_first_pts_ready) {
- if ((pic_config->pts == 0) || ((pic_config->pts <= hw->last_pts) &&
- (pic_config->pts64 <= hw->last_pts_us64))) {
- for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- if ((hw->last_pts == hw->frame_mode_pts_save[i]) ||
- (hw->last_pts_us64 == hw->frame_mode_pts64_save[i])) {
- pic_config->pts = hw->frame_mode_pts_save[i - 1];
- pic_config->pts64 = hw->frame_mode_pts64_save[i - 1];
- break;
- }
- }
-
- if ((i == 0) || (pic_config->pts <= hw->last_pts)) {
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "no found pts %d, set 0. %d, %d\n",
- i, pic_config->pts, hw->last_pts);
- pic_config->pts = 0;
- pic_config->pts64 = 0;
- }
- }
- }
-
- if (hw->is_used_v4l) {
- vf->v4l_mem_handle
- = hw->m_BUF[pic_config->v4l_buf_index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- vf->mm_box.bmmu_box = hw->bmmu_box;
- vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(hw->buffer_wrap[pic_config->v4l_buf_index]);
- vf->mm_box.mmu_box = hw->mmu_box;
- vf->mm_box.mmu_idx = hw->buffer_wrap[pic_config->v4l_buf_index];
- }
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(hw_to_vdec(hw))) {
- vf->pts = pic_config->pts;
- vf->pts_us64 = pic_config->pts64;
-
- if (hw->is_used_v4l && v4l_bitstream_id_enable)
- vf->timestamp = pic_config->timestamp;
- else
- vf->timestamp = pic_config->pts64;
-
- if (vf->pts != 0 || vf->pts_us64 != 0) {
- pts_valid = 1;
- pts_us64_valid = 1;
- } else {
- pts_valid = 0;
- pts_us64_valid = 0;
- }
- } else
-#endif
- if (pts_lookup_offset_us64
- (PTS_TYPE_VIDEO, stream_offset, &vf->pts,
- &frame_size, 0,
- &vf->pts_us64) != 0) {
-#ifdef DEBUG_PTS
- hw->pts_missed++;
-#endif
- vf->pts = 0;
- vf->pts_us64 = 0;
- pts_valid = 0;
- pts_us64_valid = 0;
- } else {
-#ifdef DEBUG_PTS
- hw->pts_hit++;
-#endif
- pts_valid = 1;
- pts_us64_valid = 1;
- }
-
- if (hw->av1_first_pts_ready) {
- if (hw->frame_dur && ((vf->pts == 0) || (vf->pts_us64 == 0))) {
- vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
- vf->pts_us64 = hw->last_pts_us64 +
- (DUR2PTS(hw->frame_dur) * 100 / 9);
- reclac_flag = 1;
- }
-
- if (!close_to(vf->pts, (hw->last_pts + DUR2PTS(hw->frame_dur)), 100)) {
- vf->pts = hw->last_pts + DUR2PTS(hw->frame_dur);
- vf->pts_us64 = hw->last_pts_us64 +
- (DUR2PTS(hw->frame_dur) * 100 / 9);
- reclac_flag = 2;
- }
-
- if (hw->is_used_v4l)
- reclac_flag = 0;
-
- /* try find the closed pts in saved pts pool */
- if (reclac_flag) {
- for (i = 0; i < FRAME_BUFFERS - 1; i++) {
- if ((hw->frame_mode_pts_save[i] > vf->pts) &&
- (hw->frame_mode_pts_save[i + 1] < vf->pts)) {
- if ((hw->frame_mode_pts_save[i] - vf->pts) >
- (vf->pts - hw->frame_mode_pts_save[i + 1])) {
- vf->pts = hw->frame_mode_pts_save[i + 1];
- vf->pts_us64 = hw->frame_mode_pts64_save[i + 1];
- } else {
- vf->pts = hw->frame_mode_pts_save[i];
- vf->pts_us64 = hw->frame_mode_pts64_save[i];
- }
- break;
- }
- }
- if (i == (FRAME_BUFFERS - 1))
- hw->dur_recalc_flag = 1;
- }
- } else {
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "first pts %d change to save[%d] %d\n",
- vf->pts, hw->first_pts_index - 1,
- hw->frame_mode_pts_save[hw->first_pts_index - 1]);
- vf->pts = hw->frame_mode_pts_save[hw->first_pts_index - 1];
- vf->pts_us64 = hw->frame_mode_pts64_save[hw->first_pts_index - 1];
- }
- hw->last_pts = vf->pts;
- hw->last_pts_us64 = vf->pts_us64;
- hw->av1_first_pts_ready = true;
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "av1 output slice type %d, dur %d, pts %d, pts64 %lld, ts: %llu\n",
- pic_config->slice_type, hw->frame_dur, vf->pts, vf->pts_us64, vf->timestamp);
-
- fill_frame_info(hw, pic_config, frame_size, vf->pts);
-
- vf->index = 0xff00 | pic_config->v4l_buf_index;
- if (pic_config->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
-#ifdef AOM_AV1_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
-#endif
- } else {
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic_config->header_adr;
- if (((get_debug_fgs() & DEBUG_FGS_BYPASS) == 0)
- && hw->assit_task.use_sfgs)
- vf->fgs_table_adr = pic_config->sfgs_table_phy;
- else
- vf->fgs_table_adr = pic_config->fgs_table_adr;
- vf->fgs_valid = hw->fgs_valid;
-#ifdef AOM_AV1_MMU_DW
- vf->dwBodyAddr = 0;
- vf->dwHeadAddr = 0;
- if (pic_config->double_write_mode & 0x20) {
- u32 mode = pic_config->double_write_mode & 0xf;
- if (mode == 5 || mode == 3)
- vf->dwHeadAddr = pic_config->header_dw_adr;
- else if ((mode == 1 || mode == 2 || mode == 4)
- && (debug & AOM_DEBUG_DW_DISP_MAIN) == 0) {
- vf->compHeadAddr = pic_config->header_dw_adr;
- vf->fgs_valid = 0;
- av1_print(hw, AOM_DEBUG_VFRAME,
- "Use dw mmu for display\n");
- }
- }
-#endif
- } else {
- /*vf->compBodyAddr = pic_config->mc_y_adr;
- *vf->compHeadAddr = pic_config->mc_y_adr +
- *pic_config->comp_body_size; */
- /*head adr*/
- }
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
- if (pic_config->double_write_mode &&
- (pic_config->double_write_mode & 0x20) == 0) {
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
- if ((pic_config->double_write_mode == 3 ||
- pic_config->double_write_mode == 5) &&
- (!IS_8K_SIZE(pic_config->y_crop_width,
- pic_config->y_crop_height))) {
- vf->type |= VIDTYPE_COMPRESS;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- vf->type |= VIDTYPE_SCATTER;
- }
- }
- if (hw->is_used_v4l && pic_config->double_write_mode != 16 &&
- (!IS_8K_SIZE(pic_config->y_crop_width,
- pic_config->y_crop_height))) {
- if ((get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_S4 &&
- get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_S4D)
- || (!hw->film_grain_present) || (get_double_write_mode(hw) != 1)) {
- vf->type |= VIDTYPE_COMPRESS | VIDTYPE_SCATTER;
- }
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic_config->canvas_config[0];
- vf->canvas0_config[1] =
- pic_config->canvas_config[1];
- vf->canvas1_config[0] =
- pic_config->canvas_config[0];
- vf->canvas1_config[1] =
- pic_config->canvas_config[1];
-
- } else
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(pic_config);
- } else {
- vf->canvas0Addr = vf->canvas1Addr = 0;
- vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- vf->type |= VIDTYPE_SCATTER;
- }
- }
-
- switch (pic_config->bit_depth) {
- case AOM_BITS_8:
- vf->bitdepth = BITDEPTH_Y8 |
- BITDEPTH_U8 | BITDEPTH_V8;
- break;
- case AOM_BITS_10:
- case AOM_BITS_12:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- default:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- }
- if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- if (pic_config->bit_depth == AOM_BITS_8)
- vf->bitdepth |= BITDEPTH_SAVING_MODE;
-
- /* if ((vf->width!=pic_config->width)|
- * (vf->height!=pic_config->height))
- */
- /* pr_info("aaa: %d/%d, %d/%d\n",
- vf->width,vf->height, pic_config->width,
- pic_config->height); */
- vf->width = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- vf->height = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- if (force_w_h != 0) {
- vf->width = (force_w_h >> 16) & 0xffff;
- vf->height = force_w_h & 0xffff;
- }
- if ((pic_config->double_write_mode & 0x20) &&
- ((pic_config->double_write_mode & 0xf) == 2 ||
- (pic_config->double_write_mode & 0xf) == 4)) {
- vf->compWidth = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- vf->compHeight = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode & 0xf);
- } else {
- vf->compWidth = pic_config->y_crop_width;
- vf->compHeight = pic_config->y_crop_height;
- }
- set_frame_info(hw, vf);
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
-
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
- update_vf_memhandle(hw, vf, pic_config);
-
- av1_inc_vf_ref(hw, pic_config->v4l_buf_index);
-
- vdec_vframe_ready(hw_to_vdec(hw), vf);
- if (pic_config->double_write_mode &&
- ((pic_config->double_write_mode & 0x20) == 0) &&
- (pic_config->v4l_buf_index != pic_config->BUF_index)) {
- struct PIC_BUFFER_CONFIG_s *dst_pic =
- &hw->common.buffer_pool->frame_bufs[pic_config->v4l_buf_index].buf;
- struct PIC_BUFFER_CONFIG_s *src_pic =
- &hw->common.buffer_pool->frame_bufs[pic_config->BUF_index].buf;
- struct vdec_ge2d_info ge2d_info;
-
- av1_print(hw, PRINT_FLAG_V4L_DETAIL,
- "ge2d copy start v4l_buf_index:%d repeat_buff_index:%d\n",
- pic_config->v4l_buf_index,
- pic_config->BUF_index);
- ge2d_info.dst_vf = vf;
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr = 0;
- if (dst_pic->double_write_mode) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hw->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- dst_pic->canvas_config[0];
- vf->canvas0_config[1] =
- dst_pic->canvas_config[1];
- vf->canvas1_config[0] =
- dst_pic->canvas_config[0];
- vf->canvas1_config[1] =
- dst_pic->canvas_config[1];
- ge2d_info.src_canvas0_config[0] =
- src_pic->canvas_config[0];
- ge2d_info.src_canvas0_config[1] =
- src_pic->canvas_config[1];
- ge2d_info.src_canvas1_config[0] =
- src_pic->canvas_config[0];
- ge2d_info.src_canvas1_config[1] =
- src_pic->canvas_config[1];
- } else
-#endif
- {
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(dst_pic);
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr =
- spec2canvas(src_pic);
- }
- }
-
- if (!hw->ge2d) {
- int mode = nv_order == VIDTYPE_VIU_NV21 ? GE2D_MODE_CONVERT_NV21 : GE2D_MODE_CONVERT_NV12;
- mode |= GE2D_MODE_CONVERT_LE;
- vdec_ge2d_init(&hw->ge2d, mode);
- }
- vdec_ge2d_copy_data(hw->ge2d, &ge2d_info);
- av1_print(hw, PRINT_FLAG_V4L_DETAIL, "ge2d copy done\n");
- }
- decoder_do_frame_check(hw_to_vdec(hw), vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(hw->trace.pts_name, vf->timestamp);
- ATRACE_COUNTER(hw->trace.new_q_name, kfifo_len(&hw->newframe_q));
- ATRACE_COUNTER(hw->trace.disp_q_name, kfifo_len(&hw->display_q));
-
- atomic_add(1, &hw->vf_pre_count);
- /*count info*/
- hw->gvs->frame_dur = hw->frame_dur;
- vdec_count_info(hw->gvs, 0, stream_offset);
- hw_to_vdec(hw)->vdec_fps_detec(hw_to_vdec(hw)->id);
-
-#ifdef AUX_DATA_CRC
- decoder_do_aux_data_check(hw_to_vdec(hw), pic_config->aux_data_buf,
- pic_config->aux_data_size);
-#endif
-
- av1_print(hw, AV1_DEBUG_SEI_DETAIL, "%s aux_data_size = %d\n",
- __func__, pic_config->aux_data_size);
-
- if (debug & AV1_DEBUG_SEI_DETAIL) {
- int i = 0;
- PR_INIT(128);
- for (i = 0; i < pic_config->aux_data_size; i++) {
- PR_FILL("%02x ", pic_config->aux_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- PR_INFO(hw->index);
- }
- PR_INFO(hw->index);
- }
-
- if (hw->is_used_v4l) {
- if ((pic_config->aux_data_size == 0) &&
- (pic_config->slice_type == KEY_FRAME) &&
- (atomic_read(&hw->vf_pre_count) == 1)) {
- hw->no_need_aux_data = true;
- }
-
- if (hw->no_need_aux_data) {
- v4l2_ctx->aux_infos.free_buffer(v4l2_ctx, DV_TYPE);
- v4l2_ctx->aux_infos.free_one_sei_buffer(v4l2_ctx,
- &pic_config->aux_data_buf,
- &pic_config->aux_data_size,
- pic_config->ctx_buf_idx);
- } else {
- v4l2_ctx->aux_infos.bind_dv_buffer(v4l2_ctx, &vf->src_fmt.comp_buf,
- &vf->src_fmt.md_buf);
- }
-
- update_vframe_src_fmt(vf,
- pic_config->aux_data_buf,
- pic_config->aux_data_size,
- false, hw->provider_name, NULL);
- }
-
- av1_update_gvs(hw, vf, pic_config);
- memcpy(&tmp4x, hw->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = bit_depth_luma;
- tmp4x.bit_depth_chroma = bit_depth_chroma;
- tmp4x.double_write_mode = pic_config->double_write_mode;
- vdec_fill_vdec_frame(hw_to_vdec(hw), &hw->vframe_qos, &tmp4x, vf, pic_config->hw_decode_time);
- if (without_display_mode == 0) {
- if (hw->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vav1_vf_put(vav1_vf_get(hw), hw);
- } else {
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- } else
- vav1_vf_put(vav1_vf_get(hw), hw);
- }
-
- return 0;
-}
-
-void av1_raw_write_image(AV1Decoder *pbi, PIC_BUFFER_CONFIG *sd)
-{
- sd->stream_offset = pbi->pre_stream_offset;
- prepare_display_buf((struct AV1HW_s *)(pbi->private_data), sd);
- pbi->pre_stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-}
-
-static bool is_avaliable_buffer(struct AV1HW_s *hw);
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] AV1 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = v4l_get_free_fb(hw);
- if (INVALID_IDX == index) {
- pr_err("[%d] AV1 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->m_BUF[index].v4l_ref_buf_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- vf->v4l_mem_handle = (ulong)fb;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- av1_print(hw, 0, "[%d] AV1 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void get_rpm_param(union param_u *params)
-{
- int i;
- unsigned int data32;
-
- if (debug & AV1_DEBUG_BUFMGR)
- pr_info("enter %s\r\n", __func__);
- for (i = 0; i < 128; i++) {
- do {
- data32 = READ_VREG(RPM_CMD_REG);
- /*pr_info("%x\n", data32);*/
- } while ((data32 & 0x10000) == 0);
- params->l.data[i] = data32&0xffff;
- /*pr_info("%x\n", data32);*/
- WRITE_VREG(RPM_CMD_REG, 0);
- }
- if (debug & AV1_DEBUG_BUFMGR)
- pr_info("leave %s\r\n", __func__);
-}
-
-#ifdef CHANGE_REMOVED
-static int recycle_mmu_buf_tail(struct AV1HW_s *hw,
- bool check_dma)
-{
- struct AV1_Common_s *const cm = &hw->common;
-
- hw->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
-
- av1_print(hw, 0, "pic index %d page_start %d\n",
- cm->cur_fb_idx_mmu, hw->used_4k_num);
-
- if (check_dma)
- hevc_mmu_dma_check(hw_to_vdec(hw));
-
- if (hw->is_used_v4l) {
- int index = cm->cur_fb_idx_mmu;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- hw->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- hw->mmu_box,
- cm->cur_fb_idx_mmu,
- hw->used_4k_num);
- }
-
- cm->cur_fb_idx_mmu = INVALID_IDX;
- hw->used_4k_num = -1;
-
- return 0;
-}
-#endif
-
-#ifdef CHANGE_REMOVED
-static void av1_recycle_mmu_buf_tail(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- if (get_double_write_mode(hw) & 0x10)
- return;
-
- if (cm->cur_fb_idx_mmu != INVALID_IDX) {
- recycle_mmu_buf_tail(hw,
- ((hw->used_4k_num == -1) &&
- hw->m_ins_flag) ? 1 : 0);
- }
-}
-#endif
-
-static void av1_recycle_mmu_buf(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
-
- if (hw->is_used_v4l)
- return;
-
- if (get_double_write_mode(hw) & 0x10)
- return;
- if (cm->cur_fb_idx_mmu != INVALID_IDX) {
- decoder_mmu_box_free_idx(hw->mmu_box,
- cm->cur_fb_idx_mmu);
-
- cm->cur_fb_idx_mmu = INVALID_IDX;
- hw->used_4k_num = -1;
- }
-}
-
-static void dec_again_process(struct AV1HW_s *hw)
-{
- amhevc_stop();
- hw->dec_result = DEC_RESULT_AGAIN;
- if (hw->process_state ==
- PROC_STATE_DECODESLICE) {
- hw->process_state =
- PROC_STATE_SENDAGAIN;
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- av1_recycle_mmu_buf(hw);
- }
- }
- reset_process_time(hw);
- vdec_schedule_work(&hw->work);
-}
-
-static void read_film_grain_reg(struct AV1HW_s *hw)
-{
- AV1_COMMON *cm = &hw->common;
- int i;
- if (cm->cur_frame == NULL) {
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s, cur_frame not exist!!!\n", __func__);
- return;
- } else
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s\n", __func__);
- WRITE_VREG(HEVC_FGS_IDX, 0);
- for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) {
- cm->cur_frame->film_grain_reg[i] = READ_VREG(HEVC_FGS_DATA);
- }
- cm->cur_frame->film_grain_reg_valid = 1;
- cm->cur_frame->film_grain_ctrl = READ_VREG(HEVC_FGS_CTRL);
-}
-
-static void config_film_grain_reg(struct AV1HW_s *hw, int film_grain_params_ref_idx)
-{
- AV1_COMMON *cm = &hw->common;
- int i;
- unsigned char found = 0;
- RefCntBuffer *buf;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " ## %s frome reference idx %d\n",
- __func__, film_grain_params_ref_idx);
- for (i = 0; i < INTER_REFS_PER_FRAME; ++i) {
- if (film_grain_params_ref_idx == cm->remapped_ref_idx[i]) {
- found = 1;
- break;
- }
- }
- if (!found) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s Error, Invalid film grain reference idx %d\n",
- __func__, film_grain_params_ref_idx);
- return;
- }
- buf = cm->ref_frame_map[film_grain_params_ref_idx];
-
- if (buf->film_grain_reg_valid == 0) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s Error, film grain register data invalid for reference idx %d\n",
- __func__, film_grain_params_ref_idx);
- return;
- }
-
- if (cm->cur_frame == NULL) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s, cur_frame not exist!!!\n", __func__);
- }
- WRITE_VREG(HEVC_FGS_IDX, 0);
- for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) {
- WRITE_VREG(HEVC_FGS_DATA, buf->film_grain_reg[i]);
- if (cm->cur_frame)
- cm->cur_frame->film_grain_reg[i] = buf->film_grain_reg[i];
- }
- if (cm->cur_frame)
- cm->cur_frame->film_grain_reg_valid = 1;
- WRITE_VREG(HEVC_FGS_CTRL, READ_VREG(HEVC_FGS_CTRL) | 1); // set fil_grain_start
- if (cm->cur_frame)
- cm->cur_frame->film_grain_ctrl = READ_VREG(HEVC_FGS_CTRL);
-}
-
-void config_next_ref_info_hw(struct AV1HW_s *hw)
-{
- int j;
- AV1_COMMON *const cm = &hw->common;
-
- av1_set_next_ref_frame_map(hw->pbi);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11a0);
- else
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1000);
-
- for (j = 0; j < 12; j++) {
- unsigned int info =
- av1_get_next_used_ref_info(cm, j);
-
- WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, info);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "config next ref info %d 0x%x\n", j, info);
- }
-}
-
-
-
-#ifdef PRINT_HEVC_DATA_PATH_MONITOR
-void datapath_monitor(struct AV1HW_s *hw)
-{
- uint32_t total_clk_count;
- uint32_t path_transfer_count;
- uint32_t path_wait_count;
- float path_wait_ratio;
- if (pbi->decode_idx > 1) {
- WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disabble monitor and set rd_idx to 0
- total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
-
- WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disabble monitor and set rd_idx to 0
-
-// parser --> iqit
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk("[P%d HEVC PATH] Parser/IQIT/IPP/DBLK/OW/DDR/CMD WAITING \% : %.2f",
- pbi->decode_idx - 2, path_wait_ratio);
-
-// iqit --> ipp
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
-// dblk <-- ipp
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
-// dblk --> ow
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
-// <--> DDR
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f", path_wait_ratio);
-
-// CMD
- path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
- if (path_transfer_count == 0) path_wait_ratio = 0.0;
- else path_wait_ratio = (float)path_wait_count/(float)path_transfer_count;
- printk(" %.2f\n", path_wait_ratio);
- }
-}
-
-#endif
-
-#ifdef MCRCC_ENABLE
-
-static int mcrcc_hit_rate;
-static int mcrcc_bypass_rate;
-
-#define C_Reg_Wr WRITE_VREG
-static void C_Reg_Rd(unsigned int adr, unsigned int *val)
-{
- *val = READ_VREG(adr);
-}
-
-static void mcrcc_perfcount_reset(struct AV1HW_s *hw)
-{
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE,
- "[cache_util.c] Entered mcrcc_perfcount_reset...\n");
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static unsigned raw_mcr_cnt_total_prev;
-static unsigned hit_mcr_0_cnt_total_prev;
-static unsigned hit_mcr_1_cnt_total_prev;
-static unsigned byp_mcr_cnt_nchcanv_total_prev;
-static unsigned byp_mcr_cnt_nchoutwin_total_prev;
-
-static void mcrcc_get_hitrate(struct AV1HW_s *hw, unsigned reset_pre)
-{
- unsigned delta_hit_mcr_0_cnt;
- unsigned delta_hit_mcr_1_cnt;
- unsigned delta_raw_mcr_cnt;
- unsigned delta_mcr_cnt_nchcanv;
- unsigned delta_mcr_cnt_nchoutwin;
-
- unsigned tmp;
- unsigned raw_mcr_cnt;
- unsigned hit_mcr_cnt;
- unsigned byp_mcr_cnt_nchoutwin;
- unsigned byp_mcr_cnt_nchcanv;
- int hitrate;
-
- if (reset_pre) {
- raw_mcr_cnt_total_prev = 0;
- hit_mcr_0_cnt_total_prev = 0;
- hit_mcr_1_cnt_total_prev = 0;
- byp_mcr_cnt_nchcanv_total_prev = 0;
- byp_mcr_cnt_nchoutwin_total_prev = 0;
- }
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered mcrcc_get_hitrate...\n");
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &raw_mcr_cnt);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_cnt);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchoutwin);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchcanv);
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "raw_mcr_cnt_total: %d\n",raw_mcr_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_cnt_total: %d\n",hit_mcr_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "byp_mcr_cnt_nchoutwin_total: %d\n",byp_mcr_cnt_nchoutwin);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "byp_mcr_cnt_nchcanv_total: %d\n",byp_mcr_cnt_nchcanv);
-
- delta_raw_mcr_cnt = raw_mcr_cnt - raw_mcr_cnt_total_prev;
- delta_mcr_cnt_nchcanv = byp_mcr_cnt_nchcanv - byp_mcr_cnt_nchcanv_total_prev;
- delta_mcr_cnt_nchoutwin = byp_mcr_cnt_nchoutwin - byp_mcr_cnt_nchoutwin_total_prev;
- raw_mcr_cnt_total_prev = raw_mcr_cnt;
- byp_mcr_cnt_nchcanv_total_prev = byp_mcr_cnt_nchcanv;
- byp_mcr_cnt_nchoutwin_total_prev = byp_mcr_cnt_nchoutwin;
-
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "miss_mcr_0_cnt_total: %d\n",tmp);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "miss_mcr_1_cnt_total: %d\n",tmp);
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_0_cnt_total: %d\n",tmp);
- delta_hit_mcr_0_cnt = tmp - hit_mcr_0_cnt_total_prev;
- hit_mcr_0_cnt_total_prev = tmp;
- C_Reg_Wr(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
- C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hit_mcr_1_cnt_total: %d\n",tmp);
- delta_hit_mcr_1_cnt = tmp - hit_mcr_1_cnt_total_prev;
- hit_mcr_1_cnt_total_prev = tmp;
-
- if ( delta_raw_mcr_cnt != 0 ) {
- hitrate = 100 * delta_hit_mcr_0_cnt/ delta_raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CANV0_HIT_RATE : %d\n", hitrate);
- hitrate = 100 * delta_hit_mcr_1_cnt/delta_raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CANV1_HIT_RATE : %d\n", hitrate);
- hitrate = 100 * delta_mcr_cnt_nchcanv/delta_raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "NONCACH_CANV_BYP_RATE : %d\n", hitrate);
- hitrate = 100 * delta_mcr_cnt_nchoutwin/delta_raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
- }
-
- if (raw_mcr_cnt != 0)
- {
- hitrate = 100*hit_mcr_cnt/raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : %d\n", hitrate);
- hitrate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : %d\n", hitrate);
- } else {
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_HIT_RATE : na\n");
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_BYP_RATE : na\n");
- }
- mcrcc_hit_rate = 100*hit_mcr_cnt/raw_mcr_cnt;
- mcrcc_bypass_rate = 100*(byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)/raw_mcr_cnt;
-
- return;
-}
-
-static void decomp_perfcount_reset(struct AV1HW_s *hw)
-{
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_perfcount_reset...\n");
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static void decomp_get_hitrate(struct AV1HW_s *hw)
-{
- unsigned raw_mcr_cnt;
- unsigned hit_mcr_cnt;
- int hitrate;
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_get_hitrate...\n");
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
-
- if ( raw_mcr_cnt != 0 ) {
- hitrate = 100*hit_mcr_cnt/raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : %.2f\%\n", hitrate);
- } else {
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_HCACHE_HIT_RATE : na\n");
- }
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "dcache_raw_cnt_total: %d\n",raw_mcr_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "dcache_hit_cnt_total: %d\n",hit_mcr_cnt);
-
- if ( raw_mcr_cnt != 0 ) {
- hitrate = 100*hit_mcr_cnt/raw_mcr_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
-
- //hitrate = ((float)hit_mcr_cnt/(float)raw_mcr_cnt);
- //hitrate = (mcrcc_hit_rate + (mcrcc_bypass_rate * hitrate))*100;
- hitrate = mcrcc_hit_rate + (mcrcc_bypass_rate * hit_mcr_cnt/raw_mcr_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate);
-
- } else {
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_DCACHE_HIT_RATE : na\n");
- }
-
- return;
-}
-
-static void decomp_get_comprate(struct AV1HW_s *hw)
-{
- unsigned raw_ucomp_cnt;
- unsigned fast_comp_cnt;
- unsigned slow_comp_cnt;
- int comprate;
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] Entered decomp_get_comprate...\n");
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &fast_comp_cnt);
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &slow_comp_cnt);
- C_Reg_Wr(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
- C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_ucomp_cnt);
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_fast_comp_total: %d\n",fast_comp_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_slow_comp_total: %d\n",slow_comp_cnt);
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "decomp_raw_uncomp_total: %d\n",raw_ucomp_cnt);
-
- if ( raw_ucomp_cnt != 0 )
- {
- comprate = 100*(fast_comp_cnt + slow_comp_cnt)/raw_ucomp_cnt;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_COMP_RATIO : %d\n", comprate);
- } else
- {
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "DECOMP_COMP_RATIO : na\n");
- }
- return;
-}
-
-static void dump_hit_rate(struct AV1HW_s *hw)
-{
- if (debug & AV1_DEBUG_CACHE_HIT_RATE) {
- mcrcc_get_hitrate(hw, hw->m_ins_flag);
- decomp_get_hitrate(hw);
- decomp_get_comprate(hw);
- }
-}
-
-static uint32_t mcrcc_get_abs_frame_distance(struct AV1HW_s *hw, uint32_t refid, uint32_t ref_ohint, uint32_t curr_ohint, uint32_t ohint_bits_min1)
-{
- int32_t diff_ohint0;
- int32_t diff_ohint1;
- uint32_t abs_dist;
- uint32_t m;
- uint32_t m_min1;
-
- diff_ohint0 = ref_ohint - curr_ohint;
-
- m = (1 << ohint_bits_min1);
- m_min1 = m -1;
-
- diff_ohint1 = (diff_ohint0 & m_min1 ) - (diff_ohint0 & m);
-
- abs_dist = (diff_ohint1 < 0) ? -diff_ohint1 : diff_ohint1;
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE,
- "[cache_util.c] refid:%0x ref_orderhint:%0x curr_orderhint:%0x orderhint_bits_min1:%0x abd_dist:%0x\n",
- refid, ref_ohint, curr_ohint, ohint_bits_min1,abs_dist);
-
- return abs_dist;
-}
-
-static void config_mcrcc_axi_hw_nearest_ref(struct AV1HW_s *hw)
-{
- uint32_t i;
- uint32_t rdata32;
- uint32_t dist_array[8];
- uint32_t refcanvas_array[2];
- uint32_t orderhint_bits;
- unsigned char is_inter;
- AV1_COMMON *cm = &hw->common;
- PIC_BUFFER_CONFIG *curr_pic_config;
- int32_t curr_orderhint;
- int cindex0 = LAST_FRAME;
- uint32_t last_ref_orderhint_dist = 1023; // large distance
- uint32_t curr_ref_orderhint_dist = 1023; // large distance
- int cindex1;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE,
- "[test.c] #### config_mcrcc_axi_hw ####\n");
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
-
- is_inter = av1_frame_is_inter(&hw->common); //((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) ? 1 : 0;
- if ( !is_inter ) { // I-PIC
- //WRITE_VREG(HEVCD_MCRCC_CTL1, 0x1); // remove reset -- disables clock
- WRITE_VREG(HEVCD_MCRCC_CTL2, 0xffffffff); // Replace with current-frame canvas
- WRITE_VREG(HEVCD_MCRCC_CTL3, 0xffffffff); //
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
- return;
- }
-
-#if 0
- //printk("before call mcrcc_get_hitrate\r\n");
- mcrcc_get_hitrate(hw);
- decomp_get_hitrate(hw);
- decomp_get_comprate(hw);
-#endif
-
- // Find absolute orderhint delta
- curr_pic_config = &cm->cur_frame->buf;
- curr_orderhint = curr_pic_config->order_hint;
- orderhint_bits = cm->seq_params.order_hint_info.order_hint_bits_minus_1;
- for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- int32_t ref_orderhint = 0;
- PIC_BUFFER_CONFIG *pic_config;
- //int32_t tmp;
- pic_config = av1_get_ref_frame_spec_buf(cm,i);
- if (pic_config)
- ref_orderhint = pic_config->order_hint;
- //tmp = curr_orderhint - ref_orderhint;
- //dist_array[i] = (tmp < 0) ? -tmp : tmp;
- dist_array[i] = mcrcc_get_abs_frame_distance(hw, i,ref_orderhint, curr_orderhint, orderhint_bits);
- }
- // Get smallest orderhint distance refid
- for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- PIC_BUFFER_CONFIG *pic_config;
- pic_config = av1_get_ref_frame_spec_buf(cm, i);
- curr_ref_orderhint_dist = dist_array[i];
- if ( curr_ref_orderhint_dist < last_ref_orderhint_dist) {
- cindex0 = i;
- last_ref_orderhint_dist = curr_ref_orderhint_dist;
- }
- }
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex0 << 8) | (1<<1) | 0);
- refcanvas_array[0] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR) & 0xffff;
-
- last_ref_orderhint_dist = 1023; // large distance
- curr_ref_orderhint_dist = 1023; // large distance
- // Get 2nd smallest orderhint distance refid
- cindex1 = LAST_FRAME;
- for (i = LAST_FRAME; i <= ALTREF_FRAME; i++) {
- PIC_BUFFER_CONFIG *pic_config;
- pic_config = av1_get_ref_frame_spec_buf(cm, i);
- curr_ref_orderhint_dist = dist_array[i];
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (i << 8) | (1<<1) | 0);
- refcanvas_array[1] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR) & 0xffff;
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] curr_ref_orderhint_dist:%x last_ref_orderhint_dist:%x refcanvas_array[0]:%x refcanvas_array[1]:%x\n",
- curr_ref_orderhint_dist, last_ref_orderhint_dist, refcanvas_array[0],refcanvas_array[1]);
- if ((curr_ref_orderhint_dist < last_ref_orderhint_dist) && (refcanvas_array[0] != refcanvas_array[1])) {
- cindex1 = i;
- last_ref_orderhint_dist = curr_ref_orderhint_dist;
- }
- }
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex0 << 8) | (1<<1) | 0);
- refcanvas_array[0] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (cindex1 << 8) | (1<<1) | 0);
- refcanvas_array[1] = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
-
- av1_print(hw, AV1_DEBUG_CACHE_HIT_RATE, "[cache_util.c] refcanvas_array[0](index %d):%x refcanvas_array[1](index %d):%x\n",
- cindex0, refcanvas_array[0], cindex1, refcanvas_array[1]);
-
- // lowest delta_picnum
- rdata32 = refcanvas_array[0];
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | ( rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- // 2nd-lowest delta_picnum
- rdata32 = refcanvas_array[1];
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | ( rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
- return;
-}
-
-
-#endif
-
-int av1_continue_decoding(struct AV1HW_s *hw, int obu_type)
-{
- int ret = 0;
-#ifdef SANITY_CHECK
- param_t* params = &hw->aom_param;
-#endif
-#if 1
- //def CHANGE_DONE
- AV1Decoder *pbi = hw->pbi;
- AV1_COMMON *const cm = pbi->common;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: pbi %p cm %p cur_frame %p %d has_seq %d has_keyframe %d\n",
- __func__, pbi, cm, cm->cur_frame,
- pbi->bufmgr_proc_count,
- hw->has_sequence,
- hw->has_keyframe);
-
- if (hw->has_sequence == 0) {
- av1_print(hw, 0,
- "no sequence head, skip\n");
- if (!hw->m_ins_flag)
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- return -2;
- } else if (hw->has_keyframe == 0 &&
- hw->aom_param.p.frame_type != KEY_FRAME){
- av1_print(hw, 0,
- "no key frame, skip\n");
- on_no_keyframe_skiped++;
- if (!hw->m_ins_flag)
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- return -2;
- }
- hw->has_keyframe = 1;
- on_no_keyframe_skiped = 0;
-
- if (hw->is_used_v4l && ctx->param_sets_from_ucode)
- hw->res_ch_flag = 0;
-
- //pre_decode_idx = pbi->decode_idx;
- if (pbi->bufmgr_proc_count == 0 ||
- hw->one_compressed_data_done) {
- hw->new_compressed_data = 1;
- hw->one_compressed_data_done = 0;
- } else {
- hw->new_compressed_data = 0;
- }
-#ifdef SANITY_CHECK
- ret = 0;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "Check Picture size, max (%d, %d), width/height (%d, %d), dec_width %d\n",
- params->p.max_frame_width,
- params->p.max_frame_height,
- params->p.frame_width_scaled,
- params->p.frame_height,
- params->p.dec_frame_width
- );
-
- if (/*params->p.max_frame_width > MAX_PIC_WIDTH ||
- params->p.max_frame_height > MAX_PIC_HEIGHT ||*/
- (params->p.frame_width_scaled * params->p.frame_height) > MAX_SIZE_8K ||
- (params->p.dec_frame_width * params->p.frame_height) > MAX_SIZE_8K ||
- params->p.frame_width_scaled <= 0 ||
- params->p.dec_frame_width <= 0 ||
- params->p.frame_height <= 0) {
- av1_print(hw, 0, "!!Picture size error, max (%d, %d), width/height (%d, %d), dec_width %d\n",
- params->p.max_frame_width,
- params->p.max_frame_height,
- params->p.frame_width_scaled,
- params->p.frame_height,
- params->p.dec_frame_width
- );
- ret = -1;
- }
-#endif
- if (ret >= 0) {
- ret = av1_bufmgr_process(pbi, &hw->aom_param,
- hw->new_compressed_data, obu_type);
- if (ret < 0)
- return -1;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "%s: pbi %p cm %p cur_frame %p\n",
- __func__, pbi, cm, cm->cur_frame);
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "1+++++++++++++++++++++++++++++++++++%d %p\n",
- ret, cm->cur_frame);
- if (cm->cur_frame) {
- init_waitqueue_head(&cm->cur_frame->wait_sfgs);
- atomic_set(&cm->cur_frame->fgs_done, 1);
- }
- if (hw->new_compressed_data)
- WRITE_VREG(PIC_END_LCU_COUNT, 0);
- }
- if (ret > 0) {
- /* the case when cm->show_existing_frame is 1 */
- /*case 3016*/
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "Decoding done (index=%d, show_existing_frame = %d)\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1,
- cm->show_existing_frame
- );
-
- if (cm->cur_frame) {
- PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf;
- if (debug &
- AV1_DEBUG_BUFMGR_MORE)
- dump_aux_buf(hw);
- set_pic_aux_data(hw,
- cur_pic_config, 0, 0);
- }
- config_next_ref_info_hw(hw);
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "aom_bufmgr_process=> %d,decode done, AOM_AV1_SEARCH_HEAD\r\n", ret);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- pbi->decode_idx++;
- pbi->bufmgr_proc_count++;
- hw->frame_decoded = 1;
- return 0;
- } else if (ret < 0) {
- hw->frame_decoded = 1;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "aom_bufmgr_process=> %d, bufmgr e.r.r.o.r. %d, AOM_AV1_SEARCH_HEAD\r\n",
- ret, cm->error.error_code);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- return 0;
- }
- else if (ret == 0) {
- PIC_BUFFER_CONFIG* cur_pic_config = &cm->cur_frame->buf;
- PIC_BUFFER_CONFIG* prev_pic_config = &cm->prev_frame->buf;
- //struct segmentation_lf *seg_4lf = &hw->seg_4lf_store;
- if (debug &
- AV1_DEBUG_BUFMGR_MORE)
- dump_aux_buf(hw);
- set_dv_data(hw);
- if (cm->show_frame &&
- hw->dv_data_buf != NULL)
- copy_dv_data(hw, cur_pic_config);
- /* to do:..
- set_pic_aux_data(hw,
- cur_pic_config, 0, 2);*/
- hw->frame_decoded = 0;
- pbi->bufmgr_proc_count++;
- if (hw->new_compressed_data == 0) {
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE);
- return 0;
- }
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " [PICTURE %d] cm->cur_frame->mi_size : (%d X %d) y_crop_size :(%d X %d)\n",
- hw->frame_count,
- cm->cur_frame->mi_cols,
- cm->cur_frame->mi_rows,
- cur_pic_config->y_crop_width,
- cur_pic_config->y_crop_height);
- if (cm->prev_frame > 0) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " [SEGMENT] cm->prev_frame->segmentation_enabled : %d\n",
- cm->prev_frame->segmentation_enabled);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " [SEGMENT] cm->prev_frame->mi_size : (%d X %d)\n",
- cm->prev_frame->mi_cols, cm->prev_frame->mi_rows);
- }
- cm->cur_frame->prev_segmentation_enabled = (cm->prev_frame > 0) ?
- (cm->prev_frame->segmentation_enabled & (cm->prev_frame->segmentation_update_map
- | cm->prev_frame->prev_segmentation_enabled) &
- (cm->cur_frame->mi_rows == cm->prev_frame->mi_rows) &
- (cm->cur_frame->mi_cols == cm->prev_frame->mi_cols)) : 0;
- WRITE_VREG(AV1_SKIP_MODE_INFO,
- (cm->cur_frame->prev_segmentation_enabled << 31) |
- (((cm->prev_frame > 0) ? cm->prev_frame->intra_only : 0) << 30) |
- (((cm->prev_frame > 0) ? prev_pic_config->index : 0x1f) << 24) |
- (((cm->cur_frame > 0) ? cur_pic_config->index : 0x1f) << 16) |
- (cm->current_frame.skip_mode_info.ref_frame_idx_0 & 0xf) |
- ((cm->current_frame.skip_mode_info.ref_frame_idx_1 & 0xf) << 4) |
- (cm->current_frame.skip_mode_info.skip_mode_allowed << 8));
- cur_pic_config->decode_idx = pbi->decode_idx;
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "Decode Frame Data %d frame_type %d (%d) bufmgr_proc_count %d\n",
- pbi->decode_idx,
- cm->cur_frame->frame_type,
- cm->current_frame.frame_type,
- pbi->bufmgr_proc_count);
- pbi->decode_idx++;
- hw->frame_count++;
- cur_pic_config->slice_type = cm->cur_frame->frame_type;
- if (hw->chunk) {
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "%s, config pic pts %d, pts64 %lld, ts: %lld\n",
- __func__, hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp);
- cur_pic_config->pts = hw->chunk->pts;
- cur_pic_config->pts64 = hw->chunk->pts64;
-
- if (hw->is_used_v4l && !v4l_bitstream_id_enable) {
- cur_pic_config->pts64 = hw->chunk->timestamp;
- hw->chunk->timestamp = 0;
- }
-
- hw->chunk->pts = 0;
- hw->chunk->pts64 = 0;
- }
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
-#ifdef DUAL_DECODE
-#else
- config_pic_size(hw, hw->aom_param.p.bit_depth);
-#endif
- if (get_mv_buf(hw, &cm->cur_frame->buf) < 0) {
- av1_print(hw, 0,
- "%s: Error get_mv_buf fail\n",
- __func__);
- ret = -1;
- }
-
- if (ret >= 0 && (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- ret = av1_alloc_mmu(hw,
- cm->cur_frame->buf.index,
- cur_pic_config->y_crop_width,
- cur_pic_config->y_crop_height,
- hw->aom_param.p.bit_depth,
- hw->frame_mmu_map_addr);
- if (ret >= 0)
- cm->cur_fb_idx_mmu = cm->cur_frame->buf.index;
- else
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- cm->cur_frame->buf.index, ret);
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- ret = av1_alloc_mmu_dw(hw,
- cm->cur_frame->buf.index,
- cur_pic_config->y_crop_width,
- cur_pic_config->y_crop_height,
- hw->aom_param.p.bit_depth,
- hw->dw_frame_mmu_map_addr);
- if (ret >= 0)
- cm->cur_fb_idx_mmu_dw = cm->cur_frame->buf.index;
- else
- pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
- cm->cur_frame->buf.index, ret);
- }
-#endif
-#ifdef DEBUG_CRC_ERROR
- if (crc_debug_flag & 0x40)
- mv_buffer_fill_zero(hw, &cm->cur_frame->buf);
-#endif
- } else {
- ret = 0;
- }
- if (av1_frame_is_inter(&hw->common)) {
- //if ((pbi->common.frame_type != KEY_FRAME) && (!pbi->common.intra_only)) {
-#ifdef DUAL_DECODE
-#else
- config_mc_buffer(hw, hw->aom_param.p.bit_depth, 1);
-#endif
- config_mpred_hw(hw, 1);
- }
- else {
- config_mc_buffer(hw, hw->aom_param.p.bit_depth, 0);
- clear_mpred_hw(hw);
- config_mpred_hw(hw, 0);
- }
-#ifdef DUAL_DECODE
-#else
-#ifdef MCRCC_ENABLE
- config_mcrcc_axi_hw_nearest_ref(hw);
-#endif
- config_sao_hw(hw, &hw->aom_param);
-#endif
-
- config_dblk_hw(hw);
-
- /* store segment_feature before shared sub-module run to fix mosaic on t5d */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x11b0 + (cur_pic_config->index));
- else
- WRITE_VREG(HEVC_PARSER_MEM_WR_ADDR, 0x1010 + (cur_pic_config->index));
- if (hw->aom_param.p.segmentation_enabled & 1) // segmentation_enabled
- WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, READ_VREG(AV1_REF_SEG_INFO));
- else
- WRITE_VREG(HEVC_PARSER_MEM_RW_DATA, 0);
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "HEVC_DEC_STATUS_REG <= AOM_AV1_DECODE_SLICE\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE);
-
- // Save segment_feature while hardware decoding
- if (hw->seg_4lf->enabled) {
- for (i = 0; i < 8; i++) {
- cm->cur_frame->segment_feature[i] = READ_VREG(AOM_AV1_SEGMENT_FEATURE);
- }
- } else {
- for (i = 0; i < 8; i++) {
- cm->cur_frame->segment_feature[i] = (0x80000000 | (i << 22));
- }
- }
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE, "Sequence head, Search next start code\n");
- cm->prev_fb_idx = INVALID_IDX;
- //skip, search next start code
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DECODE_SLICE);
- }
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
- return ret;
-
-#else
-
- bit_depth_luma = av1_param.p.bit_depth;
- bit_depth_chroma = av1_param.p.bit_depth;
-
- if (hw->process_state != PROC_STATE_SENDAGAIN) {
- ret = av1_bufmgr_process(hw, &av1_param);
- if (!hw->m_ins_flag)
- hw->result_done_count++;
- } else {
- union param_u *params = &av1_param;
- if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) {
- ret = av1_alloc_mmu(hw,
- cm->new_fb_idx,
- params->p.width,
- params->p.height,
- params->p.bit_depth,
- hw->frame_mmu_map_addr);
- if (ret >= 0)
- cm->cur_fb_idx_mmu = cm->new_fb_idx;
- else
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- cm->new_fb_idx, ret);
- } else {
- ret = 0;
- }
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE,
- (params->p.height << 16) | params->p.width);
- }
- if (ret < 0) {
- pr_info("av1_bufmgr_process=> %d, AV1_10B_DISCARD_NAL\r\n", ret);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DISCARD_NAL);
- cm->show_frame = 0;
- if (hw->mmu_enable)
- av1_recycle_mmu_buf(hw);
-
- if (hw->m_ins_flag) {
- hw->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&hw->work);
- }
- return ret;
- } else if (ret == 0) {
- struct PIC_BUFFER_CONFIG_s *cur_pic_config
- = &cm->cur_frame->buf;
- cur_pic_config->decode_idx = hw->frame_count;
-
- if (hw->process_state != PROC_STATE_SENDAGAIN) {
- if (!hw->m_ins_flag) {
- hw->frame_count++;
- decode_frame_count[hw->index]
- = hw->frame_count;
- }
- if (hw->chunk) {
- cur_pic_config->pts = hw->chunk->pts;
- cur_pic_config->pts64 = hw->chunk->pts64;
- }
- }
- /*pr_info("Decode Frame Data %d\n", hw->frame_count);*/
- config_pic_size(hw, av1_param.p.bit_depth);
-
- if ((hw->common.frame_type != KEY_FRAME)
- && (!hw->common.intra_only)) {
- config_mc_buffer(hw, av1_param.p.bit_depth);
- config_mpred_hw(hw);
- } else {
- clear_mpred_hw(hw);
- }
-#ifdef MCRCC_ENABLE
- if (mcrcc_cache_alg_flag)
- config_mcrcc_axi_hw_new(hw);
- else
- config_mcrcc_axi_hw(hw);
-#endif
- config_sao_hw(hw, &av1_param);
- /*pr_info("HEVC_DEC_STATUS_REG <= AV1_10B_DECODE_SLICE\n");*/
- WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DECODE_SLICE);
- } else {
- pr_info("Skip search next start code\n");
- cm->prev_fb_idx = INVALID_IDX;
- /*skip, search next start code*/
- WRITE_VREG(HEVC_DEC_STATUS_REG, AV1_10B_DECODE_SLICE);
- }
- hw->process_state = PROC_STATE_DECODESLICE;
- if (hw->mmu_enable && ((hw->double_write_mode & 0x10) == 0)) {
- if (hw->last_put_idx < hw->used_buf_num) {
- struct RefCntBuffer_s *frame_bufs =
- cm->buffer_pool->frame_bufs;
- int i = hw->last_put_idx;
- /*free not used buffers.*/
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1)) {
- if (pbi->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, i);
-
- decoder_mmu_box_free_idx(ibuf->mmu_box, i);
- } else {
- decoder_mmu_box_free_idx(pbi->mmu_box, i);
- }
- }
- hw->last_put_idx = -1;
- }
- }
- return ret;
-#endif
-}
-
-static void fill_frame_info(struct AV1HW_s *hw,
- struct PIC_BUFFER_CONFIG_s *frame,
- unsigned int framesize,
- unsigned int pts)
-{
- struct vframe_qos_s *vframe_qos = &hw->vframe_qos;
-
- if (frame->slice_type == KEY_FRAME)
- vframe_qos->type = 1;
- else if (frame->slice_type == INTER_FRAME)
- vframe_qos->type = 2;
-/*
-#define SHOW_QOS_INFO
-*/
- vframe_qos->size = framesize;
- vframe_qos->pts = pts;
-#ifdef SHOW_QOS_INFO
- av1_print(hw, 0, "slice:%d\n", frame->slice_type);
-#endif
- vframe_qos->max_mv = frame->max_mv;
- vframe_qos->avg_mv = frame->avg_mv;
- vframe_qos->min_mv = frame->min_mv;
-#ifdef SHOW_QOS_INFO
- av1_print(hw, 0, "mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
-#endif
- vframe_qos->max_qp = frame->max_qp;
- vframe_qos->avg_qp = frame->avg_qp;
- vframe_qos->min_qp = frame->min_qp;
-#ifdef SHOW_QOS_INFO
- av1_print(hw, 0, "qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
-#endif
- vframe_qos->max_skip = frame->max_skip;
- vframe_qos->avg_skip = frame->avg_skip;
- vframe_qos->min_skip = frame->min_skip;
-#ifdef SHOW_QOS_INFO
- av1_print(hw, 0, "skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
-#endif
- vframe_qos->num++;
- /*
- if (hw->frameinfo_enable)
- vdec_fill_frame_info(vframe_qos, 1);
- */
-}
-
-/* only when we decoded one field or one frame,
-we can call this function to get qos info*/
-static void get_picture_qos_info(struct AV1HW_s *hw)
-{
- struct PIC_BUFFER_CONFIG_s *frame = &hw->cur_buf->buf;
-
- if (!frame)
- return;
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
-
- data = READ_VREG(HEVC_MV_INFO);
- if (frame->slice_type == KEY_FRAME)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_mv = a[2];
- frame->avg_mv = a[1];
- frame->min_mv = a[0];
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-
- data = READ_VREG(HEVC_QP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_qp = a[2];
- frame->avg_qp = a[1];
- frame->min_qp = a[0];
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-
- data = READ_VREG(HEVC_SKIP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_skip = a[2];
- frame->avg_skip = a[1];
- frame->min_skip = a[0];
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
- } else {
- uint32_t blk88_y_count;
- uint32_t blk88_c_count;
- uint32_t blk22_mv_count;
- uint32_t rdata32;
- int32_t mv_hi;
- int32_t mv_lo;
- uint32_t rdata32_l;
- uint32_t mvx_L0_hi;
- uint32_t mvy_L0_hi;
- uint32_t mvx_L1_hi;
- uint32_t mvy_L1_hi;
- int64_t value;
- uint64_t temp_value;
- int pic_number = frame->decode_idx;
-
- frame->max_mv = 0;
- frame->avg_mv = 0;
- frame->min_mv = 0;
-
- frame->max_skip = 0;
- frame->avg_skip = 0;
- frame->min_skip = 0;
-
- frame->max_qp = 0;
- frame->avg_qp = 0;
- frame->min_qp = 0;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO, "slice_type:%d, poc:%d\n",
- frame->slice_type,
- pic_number);
-
- /* set rd_idx to 0 */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0);
-
- blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_y_count == 0) {
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_y_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_y_count,
- rdata32, blk88_y_count);
-
- frame->avg_qp = rdata32/blk88_y_count;
- /* intra_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-
- /* skipped_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-
- frame->avg_skip = rdata32*100/blk88_y_count;
- /* coeff_non_zero_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_y_count*1)),
- '%', rdata32);
-
- /* blk66_c_count */
- blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_c_count == 0) {
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_c_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_c_count,
- rdata32, blk88_c_count);
-
- /* intra_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-
- /* skipped_cu_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-
- /* coeff_non_zero_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_c_count*1)),
- '%', rdata32);
-
- /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
- 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
-
- frame->min_qp = (rdata32>>0)&0xff;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
-
- frame->max_qp = (rdata32>>8)&0xff;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
-
- /* blk22_mv_count */
- blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk22_mv_count == 0) {
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO MV Data yet.\n",
- pic_number);
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* mvy_L1_count[39:32], mvx_L1_count[39:32],
- mvy_L0_count[39:32], mvx_L0_count[39:32] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- /* should all be 0x00 or 0xff */
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MV AVG High Bits: 0x%X\n",
- pic_number, rdata32);
-
- mvx_L0_hi = ((rdata32>>0)&0xff);
- mvy_L0_hi = ((rdata32>>8)&0xff);
- mvx_L1_hi = ((rdata32>>16)&0xff);
- mvy_L1_hi = ((rdata32>>24)&0xff);
-
- /* mvx_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvx_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- value = div_s64(value, blk22_mv_count);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
- pic_number, (int)value,
- value, blk22_mv_count);
-
- frame->avg_mv = value;
-
- /* mvy_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvy_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* mvx_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvx_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* mvy_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvy_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 MAX : %d\n",
- pic_number, mv_hi);
-
- frame->max_mv = mv_hi;
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 MIN : %d\n",
- pic_number, mv_lo);
-
- frame->min_mv = mv_lo;
-
- /* {mvy_L0_max, mvy_L0_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 MIN : %d\n",
- pic_number, mv_lo);
-
- /* {mvx_L1_max, mvx_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 MIN : %d\n",
- pic_number, mv_lo);
-
- /* {mvy_L1_max, mvy_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 MIN : %d\n",
- pic_number, mv_lo);
-
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL);
-
- av1_print(hw, AV1_DEBUG_QOS_INFO,
- "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
- pic_number, rdata32);
-
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- }
-}
-
-static int load_param(struct AV1HW_s *hw, union param_u *params, uint32_t dec_status)
-{
- int i;
- unsigned long flags;
- int head_type = 0;
- if (dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE)
- head_type = OBU_SEQUENCE_HEADER;
- else if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE)
- head_type = OBU_FRAME_HEADER;
- else if (dec_status == AOM_AV1_FRAME_PARSER_DONE)
- head_type = OBU_FRAME;
- else if (dec_status == AOM_AV1_REDUNDANT_FRAME_HEAD_PARSER_DONE)
- head_type = OBU_REDUNDANT_FRAME_HEADER;
- else {
- //printf("Error, dec_status of 0x%x, not supported!!!\n", dec_status);
- return -1;
- }
- av1_print2(AOM_DEBUG_HW_MORE, "load_param: ret 0x%x\n", head_type);
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
- if (debug&AOM_AV1_DEBUG_SEND_PARAM_WITH_REG) {
- get_rpm_param(params);
- }
- else {
- for (i = 0; i < (RPM_END-RPM_BEGIN); i += 4) {
- int32_t ii;
- for (ii = 0; ii < 4; ii++) {
- params->l.data[i+ii]=hw->rpm_ptr[i+3-ii];
- }
- }
- }
- ATRACE_COUNTER(hw->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
- params->p.enable_ref_frame_mvs = (params->p.seq_flags >> 7) & 0x1;
- params->p.enable_superres = (params->p.seq_flags >> 15) & 0x1;
-
- if (debug & AV1_DEBUG_BUFMGR_MORE) {
- lock_buffer_pool(hw->common.buffer_pool, flags);
- pr_info("aom_param: (%d)\n", hw->pbi->decode_idx);
- //pbi->slice_idx++;
- for ( i = 0; i < (RPM_END-RPM_BEGIN); i++) {
- pr_info("%04x ", params->l.data[i]);
- if (((i + 1) & 0xf) == 0)
- pr_info("\n");
- }
- unlock_buffer_pool(hw->common.buffer_pool, flags);
- }
- return head_type;
-}
-
-static int av1_postproc(struct AV1HW_s *hw)
-{
- if (hw->postproc_done)
- return 0;
- hw->postproc_done = 1;
- return av1_bufmgr_postproc(hw->pbi, hw->frame_decoded);
-}
-
-static void vav1_get_comp_buf_info(struct AV1HW_s *hw,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = hw->param.p.bit_depth;
-
- info->max_size = av1_max_mmu_buf_size(
- hw->max_pic_w,
- hw->max_pic_h);
- info->header_size = av1_get_header_size(
- hw->frame_width,
- hw->frame_height);
- info->frame_buffer_size = av1_mmu_page_num(
- hw, hw->frame_width,
- hw->frame_height,
- bit_depth == 0);
-}
-
-static int vav1_get_ps_info(struct AV1HW_s *hw, struct aml_vdec_ps_infos *ps)
-{
- ps->visible_width = hw->frame_width;
- ps->visible_height = hw->frame_height;
- ps->coded_width = ALIGN(hw->frame_width, 64);
- ps->coded_height = ALIGN(hw->frame_height, 64);
- ps->dpb_size = hw->used_buf_num;
- ps->dpb_margin = hw->dynamic_buf_num_margin;
- if (hw->frame_width > 1920 && hw->frame_height > 1088)
- ps->dpb_frames = 8;
- else
- ps->dpb_frames = 10;
-
- ps->dpb_frames += 2;
-
- if (ps->dpb_margin + ps->dpb_frames > MAX_BUF_NUM_NORMAL) {
- u32 delta;
- delta = ps->dpb_margin + ps->dpb_frames - MAX_BUF_NUM_NORMAL;
- ps->dpb_margin -= delta;
- hw->dynamic_buf_num_margin = ps->dpb_margin;
- }
- ps->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int v4l_res_change(struct AV1HW_s *hw)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct AV1_Common_s *const cm = &hw->common;
- int ret = 0;
-
- if (ctx->param_sets_from_ucode &&
- hw->res_ch_flag == 0) {
- struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
-
- if ((cm->width != 0 &&
- cm->height != 0) &&
- (hw->frame_width != cm->width ||
- hw->frame_height != cm->height)) {
-
- av1_print(hw, 0,
- "%s (%d,%d)=>(%d,%d)\r\n", __func__, cm->width,
- cm->height, hw->frame_width, hw->frame_height);
-
- if (get_valid_double_write_mode(hw) != 16) {
- vav1_get_comp_buf_info(hw, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
- vav1_get_ps_info(hw, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
- hw->v4l_params_parsed = false;
- hw->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- mutex_lock(&hw->assit_task.assit_mutex);
- hw->eos = 1;
-
- av1_postproc(hw);
-
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- mutex_unlock(&hw->assit_task.assit_mutex);
- ret = 1;
- }
- }
-
- return ret;
-}
-
-static int work_space_size_update(struct AV1HW_s *hw)
-{
- int workbuf_size, cma_alloc_cnt, ret;
- struct BuffInfo_s *p_buf_info = &hw->work_space_buf_store;
-
- /* only for 8k workspace update */
- if (!IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h))
- return 0;
-
- if (hw->cma_alloc_addr && hw->buf_size) {
- memcpy(p_buf_info, &aom_workbuff_spec[2],
- sizeof(struct BuffInfo_s));
- workbuf_size = (p_buf_info->end_adr -
- p_buf_info->start_adr + 0xffff) & (~0xffff);
- cma_alloc_cnt = PAGE_ALIGN(workbuf_size) / PAGE_SIZE;
- if (hw->cma_alloc_count < cma_alloc_cnt) {
- decoder_bmmu_box_free_idx(hw->bmmu_box, WORK_SPACE_BUF_ID);
- hw->buffer_spec_index = 2;
- hw->cma_alloc_count = cma_alloc_cnt;
- ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box,
- WORK_SPACE_BUF_ID, hw->cma_alloc_count * PAGE_SIZE,
- DRIVER_NAME, &hw->cma_alloc_addr);
- if(ret < 0) {
- hw->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- pr_err("8k workspace recalloc failed\n");
- return ret;
- }
- hw->buf_start = hw->cma_alloc_addr;
- hw->buf_size = workbuf_size;
- pr_info("8k work_space_buf recalloc, size 0x%x\n", hw->buf_size);
- p_buf_info->start_adr = hw->buf_start;
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL) ||
- (get_double_write_mode(hw) == 0x10)) {
- hw->mc_buf_spec.buf_end = hw->buf_start + hw->buf_size;
- }
- init_buff_spec(hw, p_buf_info);
- hw->work_space_buf = p_buf_info;
- hw->pbi->work_space_buf = p_buf_info;
- }
- }
-
- return 0;
-}
-
-static irqreturn_t vav1_isr_thread_fn(int irq, void *data)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)data;
- unsigned int dec_status = hw->dec_status;
- int obu_type;
- int ret = 0;
-
- if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_FRAME_PARSER_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == AOM_AV1_DEC_PIC_END ||
- dec_status == AOM_NAL_DECODE_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
- if (hw->eos)
- return IRQ_HANDLED;
- hw->wait_buf = 0;
- if ((dec_status == AOM_NAL_DECODE_DONE) ||
- (dec_status == AOM_SEARCH_BUFEMPTY) ||
- (dec_status == AOM_DECODE_BUFEMPTY)
- ) {
- if (hw->m_ins_flag) {
- reset_process_time(hw);
- if (!vdec_frame_based(hw_to_vdec(hw)))
- dec_again_process(hw);
- else {
- hw->dec_result = DEC_RESULT_DONE;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- vdec_schedule_work(&hw->work);
- }
- }
- hw->process_busy = 0;
- return IRQ_HANDLED;
- } else if (dec_status == AOM_AV1_DEC_PIC_END) {
- struct AV1_Common_s *const cm = &hw->common;
- struct PIC_BUFFER_CONFIG_s *frame = &cm->cur_frame->buf;
- struct vdec_s *vdec = hw_to_vdec(hw);
-#if 1
- u32 fg_reg0, fg_reg1, num_y_points, num_cb_points, num_cr_points;
- WRITE_VREG(HEVC_FGS_IDX, 0);
- fg_reg0 = READ_VREG(HEVC_FGS_DATA);
- fg_reg1 = READ_VREG(HEVC_FGS_DATA);
- num_y_points = fg_reg1 & 0xf;
- num_cr_points = (fg_reg1 >> 8) & 0xf;
- num_cb_points = (fg_reg1 >> 4) & 0xf;
- if ((num_y_points > 0) ||
- ((num_cb_points > 0) | ((fg_reg0 >> 17) & 0x1)) ||
- ((num_cr_points > 0) | ((fg_reg0 >> 17) & 0x1)))
- hw->fgs_valid = 1;
- else
- hw->fgs_valid = 0;
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "fg_data0 0x%x fg_data1 0x%x fg_valid %d\n",
- fg_reg0, fg_reg1, hw->fgs_valid);
-#else
- if (READ_VREG(HEVC_FGS_CTRL) &
- ((1 << 4) | (1 << 5) | (1 << 6)))
- hw->fgs_valid = 1;
- else
- hw->fgs_valid = 0;
-#endif
- decode_frame_count[hw->index] = hw->frame_count;
- if (hw->m_ins_flag) {
-#ifdef USE_DEC_PIC_END
- if (READ_VREG(PIC_END_LCU_COUNT) != 0) {
- hw->frame_decoded = 1;
- if (cm->cur_frame && vdec->mvfrm && frame) {
- frame->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- frame->frame_size2 = vdec->mvfrm->frame_size;
- }
- hw->gvs->frame_count = hw->frame_count;
- /*
- In c module, multi obus are put in one packet, which is decoded
- with av1_receive_compressed_data().
- For STREAM_MODE or SINGLE_MODE, there is no packet boundary,
- we assume each packet must and only include one picture of data (LCUs)
- or cm->show_existing_frame is 1
- */
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "Decoding done (index %d), fgs_valid %d data_size 0x%x shiftbyte 0x%x\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1,
- hw->fgs_valid,
- hw->data_size,
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- hw->config_next_ref_info_flag = 1; /*to do: low_latency_flag case*/
- //config_next_ref_info_hw(hw);
- }
-#endif
-
- if (get_picture_qos)
- get_picture_qos_info(hw);
-
- reset_process_time(hw);
-
- if (hw->m_ins_flag &&
- (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10) &&
- (debug & AOM_DEBUG_DIS_RECYCLE_MMU_TAIL) == 0) {
- long used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- if ((cm->cur_frame != NULL) && (cm->cur_fb_idx_mmu != INVALID_IDX)) {
- hevc_mmu_dma_check(hw_to_vdec(hw));
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "mmu free tail, index %d used_num 0x%x\n",
- cm->cur_fb_idx_mmu, used_4k_num);
- if (hw->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(hw, cm->cur_fb_idx_mmu);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- used_4k_num);
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16);
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box_dw,
- ibuf->index,
- used_4k_num);
- av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%x\n",
- cm->cur_frame->buf.index, used_4k_num);
- }
-#endif
- cm->cur_fb_idx_mmu = INVALID_IDX;
- } else {
- decoder_mmu_box_free_idx_tail(hw->mmu_box,
- cm->cur_frame->buf.index, used_4k_num);
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16);
- decoder_mmu_box_free_idx_tail(hw->mmu_box_dw,
- cm->cur_frame->buf.index, used_4k_num);
- av1_print(hw, AOM_DEBUG_HW_MORE, "dw mmu free tail, index %d used_num 0x%x\n",
- cm->cur_frame->buf.index, used_4k_num);
- }
-#endif
- }
- }
- }
-
- if (hw->assit_task.use_sfgs) {
- ulong start_time;
- start_time = local_clock();
- if (cm->cur_frame)
- wait_event_interruptible_timeout(cm->cur_frame->wait_sfgs,
- (atomic_read(&cm->cur_frame->fgs_done) == 1), msecs_to_jiffies(50));
- if (get_debug_fgs() & DEBUG_FGS_CONSUME_TIME) {
- pr_info("%s, pic %d, fgs_valid %d, wait consume time %d us\n", __func__,
- hw->frame_count - 1, hw->fgs_valid,
- div64_u64(local_clock() - start_time, 1000));
- }
- }
- if (hw->low_latency_flag)
- av1_postproc(hw);
-
- if (multi_frames_in_one_pack &&
- hw->frame_decoded &&
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) < hw->data_size) {
- if (enable_single_slice == 1) {
- hw->consume_byte = READ_VREG(HEVC_SHIFT_BYTE_COUNT) - 4;
- hw->dec_result = DEC_RESULT_UNFINISH;
- amhevc_stop();
-#ifdef MCRCC_ENABLE
- if (mcrcc_cache_alg_flag)
- dump_hit_rate(hw);
-#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- vdec_schedule_work(&hw->work);
- }else {
-#ifdef DEBUG_CRC_ERROR
- if ((crc_debug_flag & 0x40) && cm->cur_frame)
- dump_mv_buffer(hw, &cm->cur_frame->buf);
-#endif
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "PIC_END, fgs_valid %d search head ...\n",
- hw->fgs_valid);
- if (hw->config_next_ref_info_flag)
- config_next_ref_info_hw(hw);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- }
- } else {
- hw->data_size = 0;
- hw->data_offset = 0;
-#ifdef DEBUG_CRC_ERROR
- if ((crc_debug_flag & 0x40) && cm->cur_frame)
- dump_mv_buffer(hw, &cm->cur_frame->buf);
-#endif
- hw->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
-#ifdef MCRCC_ENABLE
- if (mcrcc_cache_alg_flag)
- dump_hit_rate(hw);
-#endif
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- vdec_schedule_work(&hw->work);
- }
- } else {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "PIC_END, fgs_valid %d search head ...\n",
- hw->fgs_valid);
-#ifdef USE_DEC_PIC_END
- if (READ_VREG(PIC_END_LCU_COUNT) != 0) {
- hw->frame_decoded = 1;
- /*
- In c module, multi obus are put in one packet, which is decoded
- with av1_receive_compressed_data().
- For STREAM_MODE or SINGLE_MODE, there is no packet boundary,
- we assume each packet must and only include one picture of data (LCUs)
- or cm->show_existing_frame is 1
- */
- if (cm->cur_frame)
- av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1);
- config_next_ref_info_hw(hw);
- }
-#endif
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
- /*
- if (debug &
- AV1_DEBUG_BUFMGR_MORE)
- dump_aux_buf(hw);
- set_aux_data(hw,
- &cm->cur_frame->buf, 0, 0);
- */
- if (hw->low_latency_flag) {
- av1_postproc(hw);
- vdec_profile(hw_to_vdec(hw), VDEC_PROFILE_EVENT_CB);
- if (debug & PRINT_FLAG_VDEC_DETAIL)
- pr_info("%s AV1 frame done \n", __func__);
- }
- }
-
- start_process_time(hw);
- hw->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (dec_status == AOM_EOS) {
- if (hw->m_ins_flag)
- reset_process_time(hw);
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "AV1_EOS, flush buffer\r\n");
-
- av1_postproc(hw);
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "send AV1_10B_DISCARD_NAL\r\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_DISCARD_NAL);
- hw->process_busy = 0;
- if (hw->m_ins_flag) {
- hw->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&hw->work);
- }
- return IRQ_HANDLED;
- } else if (dec_status == AOM_DECODE_OVER_SIZE) {
- av1_print(hw, AOM_DEBUG_HW_MORE, "av1 decode oversize !!\n");
- /*debug |= (AV1_DEBUG_DIS_LOC_ERROR_PROC |
- AV1_DEBUG_DIS_SYS_ERROR_PROC);*/
- hw->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- hw->process_busy = 0;
- if (hw->m_ins_flag)
- reset_process_time(hw);
- return IRQ_HANDLED;
- }
-
- obu_type = load_param(hw, &hw->aom_param, dec_status);
- if (obu_type < 0) {
- hw->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (obu_type == OBU_SEQUENCE_HEADER) {
- int next_lcu_size;
-
- av1_bufmgr_process(hw->pbi, &hw->aom_param, 0, obu_type);
-
- if ((hw->max_pic_w < hw->aom_param.p.max_frame_width) ||
- (hw->max_pic_h < hw->aom_param.p.max_frame_height)) {
- av1_print(hw, 0, "%s, max size change (%d, %d) -> (%d, %d)\n",
- __func__, hw->max_pic_w, hw->max_pic_h,
- hw->aom_param.p.max_frame_width, hw->aom_param.p.max_frame_height);
-
- vav1_mmu_map_free(hw);
-
- hw->max_pic_w = hw->aom_param.p.max_frame_width;
- hw->max_pic_h = hw->aom_param.p.max_frame_height;
- hw->init_pic_w = hw->max_pic_w;
- hw->init_pic_h = hw->max_pic_h;
- hw->pbi->frame_width = hw->init_pic_w;
- hw->pbi->frame_height = hw->init_pic_h;
-
- vav1_mmu_map_alloc(hw);
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL, hw->frame_mmu_map_phy_addr);
- }
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, hw->dw_frame_mmu_map_phy_addr);
- //default of 0xffffffff will disable dw
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
- }
-#endif
-
- /*v4l2 alloc new mv when max size changed */
- if (hw->is_used_v4l && IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h)) {
- /* now less than 8k use fix mv buf size */
- if (hw->pic_list_init_done) {
- if (init_mv_buf_list(hw) < 0)
- pr_err("%s: !!!!Error, reinit_mv_buf_list fail\n", __func__);
- }
- }
- }
-
- bit_depth_luma = hw->aom_param.p.bit_depth;
- bit_depth_chroma = hw->aom_param.p.bit_depth;
- hw->film_grain_present = hw->aom_param.p.film_grain_present_flag;
-
- next_lcu_size = ((hw->aom_param.p.seq_flags >> 6) & 0x1) ? 128 : 64;
- hw->video_signal_type = (hw->aom_param.p.video_signal_type << 16
- | hw->aom_param.p.color_description);
-
- if (next_lcu_size != hw->current_lcu_size) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- " ## lcu_size changed from %d to %d\n",
- hw->current_lcu_size, next_lcu_size);
- hw->current_lcu_size = next_lcu_size;
- }
-
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "AOM_AV1_SEQ_HEAD_PARSER_DONE, search head ...\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_SEARCH_HEAD);
-
- hw->process_busy = 0;
- hw->has_sequence = 1;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
- }
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- hw->frame_width = hw->common.seq_params.max_frame_width;
- hw->frame_height = hw->common.seq_params.max_frame_height;
-
- if (hw->frame_width == 0 || hw->frame_height == 0) {
- hw->dec_result = DEC_RESULT_DISCARD_DATA;
- hw->process_busy = 0;
- amhevc_stop();
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
-
- if (!v4l_res_change(hw)) {
- if (ctx->param_sets_from_ucode && !hw->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
-
- pr_info("set ucode parse\n");
-
- ctx->film_grain_present = hw->film_grain_present;
- if (ctx->film_grain_present &&
- !disable_fg &&
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4 ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4D)) {
-#ifdef AOM_AV1_MMU_DW
- ctx->config.parm.dec.cfg.double_write_mode = 0x21;
- pr_info("AV1 has fg, use dw 0x21!\n");
- if (hw->dw_frame_mmu_map_addr == NULL) {
- u32 mmu_map_size = vaom_dw_frame_mmu_map_size(hw);
- hw->dw_frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- mmu_map_size,
- &hw->dw_frame_mmu_map_phy_addr, GFP_KERNEL);
- if (hw->dw_frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(hw->dw_frame_mmu_map_addr, 0, mmu_map_size);
- }
-#endif
- }
- if (get_valid_double_write_mode(hw) != 16) {
- vav1_get_comp_buf_info(hw, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
- vav1_get_ps_info(hw, &ps);
- /*notice the v4l2 codec.*/
- vdec_v4l_set_ps_infos(ctx, &ps);
- hw->v4l_params_parsed = true;
- work_space_size_update(hw);
- hw->postproc_done = 0;
- hw->process_busy = 0;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- dec_again_process(hw);
- return IRQ_HANDLED;
- } else {
- struct vdec_pic_info pic;
-
- if (!hw->pic_list_init_done) {
- vdec_v4l_get_pic_info(ctx, &pic);
- hw->used_buf_num = pic.dpb_frames +
- pic.dpb_margin;
-
- if (IS_4K_SIZE(hw->init_pic_w, hw->init_pic_h)) {
- hw->used_buf_num = MAX_BUF_NUM_LESS + pic.dpb_margin;
- if (hw->used_buf_num > REF_FRAMES_4K)
- hw->mv_buf_margin = hw->used_buf_num - REF_FRAMES_4K + 1;
- }
-
- if (IS_8K_SIZE(hw->max_pic_w, hw->max_pic_h)) {
- hw->double_write_mode = 4;
- hw->used_buf_num = MAX_BUF_NUM_LESS;
- if (hw->used_buf_num > REF_FRAMES_4K)
- hw->mv_buf_margin = hw->used_buf_num - REF_FRAMES_4K + 1;
- if (((hw->max_pic_w % 64) != 0) &&
- (hw_to_vdec(hw)->canvas_mode != CANVAS_BLKMODE_LINEAR))
- hw->mem_map_mode = 2;
- av1_print(hw, 0,
- "force 8k double write 4, mem_map_mode %d\n", hw->mem_map_mode);
- }
-
- if (hw->used_buf_num > MAX_BUF_NUM)
- hw->used_buf_num = MAX_BUF_NUM;
-
- init_pic_list(hw);
- init_pic_list_hw(hw);
-#ifndef MV_USE_FIXED_BUF
- if (init_mv_buf_list(hw) < 0) {
- pr_err("%s: !!!!Error, init_mv_buf_list fail\n", __func__);
- }
-#endif
- hw->pic_list_init_done = true;
- }
- }
- } else {
- hw->postproc_done = 0;
- hw->process_busy = 0;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- dec_again_process(hw);
- return IRQ_HANDLED;
- }
- }
-
-#ifndef USE_DEC_PIC_END
- //if (pbi->wait_buf) {
- if (pbi->bufmgr_proc_count > 0) {
- if (READ_VREG(PIC_END_LCU_COUNT) != 0) {
- hw->frame_decoded = 1;
- /*
- In c module, multi obus are put in one packet, which is decoded
- with av1_receive_compressed_data().
- For STREAM_MODE or SINGLE_MODE, there is no packet boundary,
- we assume each packet must and only include one picture of data (LCUs)
- or cm->show_existing_frame is 1
- */
- if (cm->cur_frame)
- av1_print(hw, AOM_DEBUG_HW_MORE, "Decoding done (index %d)\n",
- cm->cur_frame? cm->cur_frame->buf.index:-1);
- }
- }
-#endif
-#if 1
-/*def CHECK_OBU_REDUNDANT_FRAME_HEADER*/
- if (debug & AOM_DEBUG_BUFMGR_ONLY) {
- if (READ_VREG(PIC_END_LCU_COUNT) != 0)
- hw->obu_frame_frame_head_come_after_tile = 0;
-
- if (obu_type == OBU_FRAME_HEADER ||
- obu_type == OBU_FRAME) {
- hw->obu_frame_frame_head_come_after_tile = 1;
- } else if (obu_type == OBU_REDUNDANT_FRAME_HEADER &&
- hw->obu_frame_frame_head_come_after_tile == 0) {
- if (hw->frame_decoded == 1) {
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "Warning, OBU_REDUNDANT_FRAME_HEADER come without OBU_FRAME or OBU_FRAME_HEAD\n");
- hw->frame_decoded = 0;
- }
- }
- }
-#endif
- if (hw->frame_decoded)
- hw->one_compressed_data_done = 1;
-
- if (hw->m_ins_flag)
- reset_process_time(hw);
-
- if (hw->process_state != PROC_STATE_SENDAGAIN
- ) {
- if (hw->one_compressed_data_done) {
- av1_postproc(hw);
- av1_release_bufs(hw);
-#ifndef MV_USE_FIXED_BUF
- put_un_used_mv_bufs(hw);
-#endif
- }
- }
-
- if (hw->one_package_frame_cnt) {
- if (get_free_buf_count(hw) <= 0) {
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- hw->cur_obu_type = obu_type;
- hw->process_busy = 0;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- vdec_schedule_work(&hw->work);
- return IRQ_HANDLED;
- }
- }
- hw->one_package_frame_cnt++;
-
- ret = av1_continue_decoding(hw, obu_type);
- hw->postproc_done = 0;
- hw->process_busy = 0;
-
- if (hw->m_ins_flag) {
- if (ret >= 0)
- start_process_time(hw);
- else {
- hw->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&hw->work);
- }
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t vav1_isr(int irq, void *data)
-{
- int i;
- unsigned int dec_status;
- struct AV1HW_s *hw = (struct AV1HW_s *)data;
- //struct AV1_Common_s *const cm = &hw->common;
- uint debug_tag;
-
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- dec_status = READ_VREG(HEVC_DEC_STATUS_REG) & 0xff;
-
- if (dec_status == AOM_AV1_FRAME_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_SEQ_HEAD_PARSER_DONE ||
- dec_status == AOM_AV1_FRAME_PARSER_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == AOM_AV1_DEC_PIC_END ||
- dec_status == AOM_NAL_DECODE_DONE) {
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
- if (!hw)
- return IRQ_HANDLED;
- if (hw->init_flag == 0)
- return IRQ_HANDLED;
- if (hw->process_busy) {/*on process.*/
- pr_err("err: %s, process busy\n", __func__);
- return IRQ_HANDLED;
- }
-
- ATRACE_COUNTER("V_ST_DEC-decode_state", dec_status);
-
- hw->dec_status = dec_status;
- hw->process_busy = 1;
- if (debug & AV1_DEBUG_BUFMGR)
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "av1 isr (%d) dec status = 0x%x (0x%x), lcu 0x%x shiftbyte 0x%x shifted_data 0x%x (%x %x lev %x, wr %x, rd %x) log %x\n",
- irq,
- dec_status, READ_VREG(HEVC_DEC_STATUS_REG),
- READ_VREG(HEVC_PARSER_LCU_START),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFTED_DATA),
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
-#ifdef DEBUG_UCODE_LOG
- READ_VREG(HEVC_DBG_LOG_ADR)
-#else
- 0
-#endif
- );
-#ifdef DEBUG_UCODE_LOG
- if ((udebug_flag & 0x8) &&
- (hw->ucode_log_addr != 0) &&
- (READ_VREG(HEVC_DEC_STATUS_REG) & 0x100)) {
- unsigned long flags;
- unsigned short *log_adr =
- (unsigned short *)hw->ucode_log_addr;
- lock_buffer_pool(hw->pbi->common.buffer_pool, flags);
- while (*(log_adr + 3)) {
- pr_info("dbg%04x %04x %04x %04x\n",
- *(log_adr + 3), *(log_adr + 2), *(log_adr + 1), *(log_adr + 0)
- );
- log_adr += 4;
- }
- unlock_buffer_pool(hw->pbi->common.buffer_pool, flags);
- }
-#endif
- debug_tag = READ_HREG(DEBUG_REG1);
- if (debug_tag & 0x10000) {
- pr_info("LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- pr_info("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- hw->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- pr_info("\n");
- }
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hw->result_done_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- else if (debug_tag & 0x20000)
- hw->ucode_pause_pos = 0xffffffff;
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- } else if (debug_tag != 0) {
- pr_info(
- "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
- READ_HREG(DEBUG_REG2),
- READ_VREG(HEVC_PARSER_LCU_START));
-
- if (((udebug_pause_pos & 0xffff)
- == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == hw->result_done_count) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2))) {
- udebug_pause_pos &= 0xffff;
- hw->ucode_pause_pos = udebug_pause_pos;
- }
- if (hw->ucode_pause_pos)
- reset_process_time(hw);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- hw->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- //if (READ_VREG(HEVC_FG_STATUS) == AOM_AV1_FGS_PARAM) {
- if (hw->dec_status == AOM_AV1_FGS_PARAM) {
- uint32_t status_val = READ_VREG(HEVC_FG_STATUS);
- WRITE_VREG(HEVC_FG_STATUS, AOM_AV1_FGS_PARAM_CONT);
- WRITE_VREG(HEVC_DEC_STATUS_REG, AOM_AV1_FGS_PARAM_CONT);
- // Bit[11] - 0 Read, 1 - Write
- // Bit[10:8] - film_grain_params_ref_idx // For Write request
- if ((status_val >> 11) & 0x1) {
- uint32_t film_grain_params_ref_idx = (status_val >> 8) & 0x7;
- config_film_grain_reg(hw, film_grain_params_ref_idx);
- }
- else
- read_film_grain_reg(hw);
-
- film_grain_task_wakeup(hw);
-
- hw->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (!hw->m_ins_flag) {
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "error flag = %d\n", hw->error_flag);
- if (hw->error_flag == 1) {
- hw->error_flag = 2;
- hw->process_busy = 0;
- return IRQ_HANDLED;
- } else if (hw->error_flag == 3) {
- hw->process_busy = 0;
- return IRQ_HANDLED;
- }
- if (get_free_buf_count(hw) <= 0) {
- /*
- if (hw->wait_buf == 0)
- pr_info("set wait_buf to 1\r\n");
- */
- hw->wait_buf = 1;
- hw->process_busy = 0;
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "free buf not enough = %d\n",
- get_free_buf_count(hw));
- return IRQ_HANDLED;
- }
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_ISR_END);
- return IRQ_WAKE_THREAD;
-}
-
-static void av1_set_clk(struct work_struct *work)
-{
- struct AV1HW_s *hw = container_of(work,
- struct AV1HW_s, set_clk_work);
- int fps = 96000 / hw->frame_dur;
-
- if (hevc_source_changed(VFORMAT_AV1,
- frame_width, frame_height, fps) > 0)
- hw->saved_resolution = frame_width *
- frame_height * fps;
-}
-
-static void vav1_put_timer_func(struct timer_list *timer)
-{
- struct AV1HW_s *hw = container_of(timer,
- struct AV1HW_s, timer);
- uint8_t empty_flag;
- unsigned int buf_level;
-
- enum receviver_start_e state = RECEIVER_INACTIVE;
-
- if (hw->m_ins_flag) {
- if (hw_to_vdec(hw)->next_status
- == VDEC_STATUS_DISCONNECTED) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- if (!hw->is_used_v4l || ctx->is_stream_off) {
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- pr_debug("vdec requested to be disconnected\n");
- return;
- }
- }
- }
- if (hw->init_flag == 0) {
- if (hw->stat & STAT_TIMER_ARM) {
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(&hw->timer);
- }
- return;
- }
- if (hw->m_ins_flag == 0) {
- if (vf_get_receiver(hw->provider_name)) {
- state =
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- } else
- state = RECEIVER_INACTIVE;
-
- empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
- /* error watchdog */
- if (empty_flag == 0) {
- /* decoder has input */
- if ((debug & AV1_DEBUG_DIS_LOC_ERROR_PROC) == 0) {
-
- buf_level = READ_VREG(HEVC_STREAM_LEVEL);
- /* receiver has no buffer to recycle */
- if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&hw->display_q) &&
- buf_level > 0x200)
- ) {
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
-
- }
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- else {
- av1_print(hw, AV1_DEBUG_TIMEOUT_INFO, "timeout!!!start_process_time %ld\n",
- hw->start_process_time);
- if (
- (decode_timeout_val > 0) &&
- (hw->start_process_time > 0) &&
- ((1000 * (jiffies - hw->start_process_time) / HZ)
- > decode_timeout_val)
- ) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- av1_print(hw, AV1_DEBUG_TIMEOUT_INFO, "timeout!!!current_lcu_idx = %u last_lcu_idx = %u decode_timeout_count = %d\n",
- current_lcu_idx, hw->last_lcu_idx, hw->decode_timeout_count);
- if (hw->last_lcu_idx == current_lcu_idx) {
- if (hw->decode_timeout_count > 0)
- hw->decode_timeout_count--;
- if (hw->decode_timeout_count == 0) {
- if (input_frame_based(
- hw_to_vdec(hw)) ||
- (READ_VREG(HEVC_STREAM_LEVEL) > 0x200))
- timeout_process(hw);
- else {
- av1_print(hw, 0,
- "timeout & empty, again\n");
- dec_again_process(hw);
- }
- }
- } else {
- start_process_time(hw);
- hw->last_lcu_idx = current_lcu_idx;
- }
- }
- }
-#endif
-
- if ((hw->ucode_pause_pos != 0) &&
- (hw->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != hw->ucode_pause_pos) {
- hw->ucode_pause_pos = 0;
- WRITE_HREG(DEBUG_REG1, 0);
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (debug & AV1_DEBUG_DUMP_DATA) {
- debug &= ~AV1_DEBUG_DUMP_DATA;
- av1_print(hw, 0,
- "%s: chunk size 0x%x off 0x%x sum 0x%x\n",
- __func__,
- hw->data_size,
- hw->data_offset,
- get_data_check_sum(hw, hw->data_size)
- );
- dump_data(hw, hw->data_size);
- }
-#endif
- if (debug & AV1_DEBUG_DUMP_PIC_LIST) {
- /*dump_pic_list(hw);*/
- av1_dump_state(hw_to_vdec(hw));
- debug &= ~AV1_DEBUG_DUMP_PIC_LIST;
- }
- if (debug & AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC) {
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- debug &= ~AV1_DEBUG_TRIG_SLICE_SEGMENT_PROC;
- }
- /*if (debug & AV1_DEBUG_HW_RESET) {
- }*/
-
- if (radr != 0) {
- if ((radr >> 24) != 0) {
- int count = radr >> 24;
- int adr = radr & 0xffffff;
- int i;
- for (i = 0; i < count; i++)
- pr_info("READ_VREG(%x)=%x\n", adr+i, READ_VREG(adr+i));
- } else if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
- if (pop_shorts != 0) {
- int i;
- u32 sum = 0;
-
- pr_info("pop stream 0x%x shorts\r\n", pop_shorts);
- for (i = 0; i < pop_shorts; i++) {
- u32 data =
- (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- if ((i & 0xf) == 0)
- pr_info("%04x:", i);
- pr_info("%04x ", data);
- if (((i + 1) & 0xf) == 0)
- pr_info("\r\n");
- sum += data;
- }
- pr_info("\r\nsum = %x\r\n", sum);
- pop_shorts = 0;
- }
- if (dbg_cmd != 0) {
- if (dbg_cmd == 1) {
- u32 disp_laddr;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
- get_double_write_mode(hw) == 0) {
- disp_laddr =
- READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
- } else {
- struct canvas_s cur_canvas;
-
- canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
- & 0xff), &cur_canvas);
- disp_laddr = cur_canvas.addr;
- }
- pr_info("current displayed buffer address %x\r\n",
- disp_laddr);
- }
- dbg_cmd = 0;
- }
- /*don't changed at start.*/
- if (hw->get_frame_dur && hw->show_frame_num > 60 &&
- hw->frame_dur > 0 && hw->saved_resolution !=
- frame_width * frame_height *
- (96000 / hw->frame_dur))
- vdec_schedule_work(&hw->set_clk_work);
-
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(timer);
-}
-
-
-int vav1_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct AV1HW_s *av1 =
- (struct AV1HW_s *)vdec->private;
-
- if (!av1)
- return -1;
-
- vstatus->frame_width = frame_width;
- vstatus->frame_height = frame_height;
- if (av1->frame_dur != 0)
- vstatus->frame_rate = 96000 / av1->frame_dur;
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = 0;
- vstatus->status = av1->stat | av1->fatal_error;
- vstatus->frame_dur = av1->frame_dur;
-//#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vstatus->bit_rate = av1->gvs->bit_rate;
- vstatus->frame_data = av1->gvs->frame_data;
- vstatus->total_data = av1->gvs->total_data;
- vstatus->frame_count = av1->gvs->frame_count;
- vstatus->error_frame_count = av1->gvs->error_frame_count;
- vstatus->drop_frame_count = av1->gvs->drop_frame_count;
- vstatus->samp_cnt = av1->gvs->samp_cnt;
- vstatus->offset = av1->gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
-//#endif
- return 0;
-}
-
-int vav1_set_isreset(struct vdec_s *vdec, int isreset)
-{
- is_reset = isreset;
- return 0;
-}
-
-#if 0
-static void AV1_DECODE_INIT(void)
-{
- /* enable av1 clocks */
- WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
- /* *************************************************************** */
- /* Power ON HEVC */
- /* *************************************************************** */
- /* Powerup HEVC */
- WRITE_VREG(AO_RTI_GEN_PWR_SLEEP0,
- READ_VREG(AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6)));
- WRITE_VREG(DOS_MEM_PD_HEVC, 0x0);
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2));
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2)));
- /* remove isolations */
- WRITE_VREG(AO_RTI_GEN_PWR_ISO0,
- READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10)));
-
-}
-#endif
-
-static void vav1_prot_init(struct AV1HW_s *hw, u32 mask)
-{
- unsigned int data32;
- /* AV1_DECODE_INIT(); */
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
-
- aom_config_work_space_hw(hw, mask);
- if (mask & HW_MASK_BACK) {
- //to do: .. for single instance, called after init_pic_list()
- if (hw->m_ins_flag)
- init_pic_list_hw(hw);
- }
-
- aom_init_decoder_hw(hw, mask);
-
-#ifdef AOM_AV1_DBLK_INIT
- av1_print(hw, AOM_DEBUG_HW_MORE,
- "[test.c] av1_loop_filter_init (run once before decoding start)\n");
- av1_loop_filter_init(hw->lfi, hw->lf);
-#endif
- if ((mask & HW_MASK_FRONT) == 0)
- return;
-#if 1
- if (debug & AV1_DEBUG_BUFMGR_MORE)
- pr_info("%s\n", __func__);
- data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 |
- (1 << 0)/*stream_fetch_enable*/
- ;
- WRITE_VREG(HEVC_STREAM_CONTROL, data32);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- if (debug & AV1_DEBUG_BUFMGR)
- pr_info("[test.c] Config STREAM_FIFO_CTL\n");
- data32 = READ_VREG(HEVC_STREAM_FIFO_CTL);
- data32 = data32 |
- (1 << 29) // stream_fifo_hole
- ;
- WRITE_VREG(HEVC_STREAM_FIFO_CTL, data32);
- }
-#if 0
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- pr_info("av1 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- pr_info("av1 prot init error %d\n", __LINE__);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- pr_info("av1 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- pr_info("av1 prot init error %d\n", __LINE__);
- return;
- }
-#endif
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x000000001);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
-#endif
-
-
-
- WRITE_VREG(HEVC_WAIT_FLAG, 1);
-
- /* WRITE_VREG(HEVC_MPSR, 1); */
-
- /* clear mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(HEVC_PSCALE_CTRL, 0);
-
- WRITE_VREG(DEBUG_REG1, 0x0);
- /*check vps/sps/pps/i-slice in ucode*/
- WRITE_VREG(NAL_SEARCH_CTL, 0x8);
-
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-//#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
-// WRITE_VREG(HEVC_DBG_LOG_ADR, hw->ucode_log_phy_addr);
-//#endif
-}
-
-static int vav1_local_init(struct AV1HW_s *hw, bool reset_flag)
-{
- int i;
- int ret;
- int width, height;
-
- hw->gvs = vzalloc(sizeof(struct vdec_info));
- if (NULL == hw->gvs) {
- pr_info("the struct of vdec status malloc failed.\n");
- return -1;
- }
-#ifdef DEBUG_PTS
- hw->pts_missed = 0;
- hw->pts_hit = 0;
-#endif
- hw->new_frame_displayed = 0;
- hw->last_put_idx = -1;
- hw->saved_resolution = 0;
- hw->get_frame_dur = false;
- on_no_keyframe_skiped = 0;
- hw->first_pts_index = 0;
- hw->dur_recalc_flag = 0;
- hw->av1_first_pts_ready = false;
- width = hw->vav1_amstream_dec_info.width;
- height = hw->vav1_amstream_dec_info.height;
- hw->frame_dur =
- (hw->vav1_amstream_dec_info.rate ==
- 0) ? 3200 : hw->vav1_amstream_dec_info.rate;
- if (width && height)
- hw->frame_ar = height * 0x100 / width;
-/*
- *TODO:FOR VERSION
- */
- pr_info("av1: ver (%d,%d) decinfo: %dx%d rate=%d\n", av1_version,
- 0, width, height, hw->frame_dur);
-
- if (hw->frame_dur == 0)
- hw->frame_dur = 96000 / 24;
-
- INIT_KFIFO(hw->display_q);
- INIT_KFIFO(hw->newframe_q);
-
- for (i = 0; i < FRAME_BUFFERS; i++) {
- hw->buffer_wrap[i] = i;
- }
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &hw->vfpool[i];
-
- hw->vfpool[i].index = -1;
- kfifo_put(&hw->newframe_q, vf);
- }
-
- ret = av1_local_init(hw, reset_flag);
-
- if (force_pts_unstable) {
- if (!hw->pts_unstable) {
- hw->pts_unstable =
- (hw->vav1_amstream_dec_info.rate == 0)?1:0;
- pr_info("set pts unstable\n");
- }
- }
-
- return ret;
-}
-
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static s32 vav1_init(struct vdec_s *vdec)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)vdec->private;
-#else
-static s32 vav1_init(struct AV1HW_s *hw)
-{
-#endif
- int ret;
- int i;
- int fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
-
- hw->stat |= STAT_TIMER_INIT;
-
- if (vav1_local_init(hw, false) < 0)
- return -EBUSY;
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
- if (get_firmware_data(VIDEO_DEC_VP9_MMU, fw->data) < 0) {
-#else
- if (get_firmware_data(VIDEO_DEC_AV1_MMU, fw->data) < 0) {
-#endif
- pr_err("get firmware fail.\n");
- printk("%s %d\n", __func__, __LINE__);
- vfree(fw);
- return -1;
- }
- av1_print(hw, AOM_DEBUG_HW_MORE, "%s %d\n", __func__, __LINE__);
- fw->len = fw_size;
-
- INIT_WORK(&hw->set_clk_work, av1_set_clk);
- timer_setup(&hw->timer, vav1_put_timer_func, 0);
-
- for (i = 0; i < FILM_GRAIN_REG_SIZE; i++) {
- WRITE_VREG(HEVC_FGS_DATA, 0);
- }
- WRITE_VREG(HEVC_FGS_CTRL, 0);
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (hw->m_ins_flag) {
- hw->timer.expires = jiffies + PUT_INTERVAL;
-
- /*add_timer(&hw->timer);
-
- hw->stat |= STAT_TIMER_ARM;
- hw->stat |= STAT_ISR_REG;*/
-
- INIT_WORK(&hw->work, av1_work);
- hw->fw = fw;
-
- return 0; /*multi instance return */
- }
-#endif
- amhevc_enable();
-
- ret = amhevc_loadmc_ex(VFORMAT_AV1, NULL, fw->data);
- if (ret < 0) {
- amhevc_disable();
- vfree(fw);
- pr_err("AV1: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- vfree(fw);
-
- hw->stat |= STAT_MC_LOAD;
-
- /* enable AMRISC side protocol */
- vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK);
-
- if (vdec_request_threaded_irq(VDEC_IRQ_0,
- vav1_isr,
- vav1_isr_thread_fn,
- IRQF_ONESHOT,/*run thread on this irq disabled*/
- "vav1-irq", (void *)hw)) {
- pr_info("vav1 irq register error.\n");
- amhevc_disable();
- return -ENOENT;
- }
-
- hw->stat |= STAT_ISR_REG;
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- if (force_dv_enable)
- hw->provider_name = DV_PROVIDER_NAME;
- else
-#endif
- hw->provider_name = PROVIDER_NAME;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hw->is_used_v4l) {
- vf_provider_init(&vav1_vf_prov, hw->provider_name,
- &vav1_vf_provider, hw);
- vf_reg_provider(&vav1_vf_prov);
- vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL);
- if (hw->frame_dur != 0) {
- if (!is_reset)
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)hw->frame_dur));
- }
- }
-#else
- vf_provider_init(&vav1_vf_prov, hw->provider_name, &vav1_vf_provider,
- hw);
- vf_reg_provider(&vav1_vf_prov);
- vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_START, NULL);
- if (!is_reset)
- vf_notify_receiver(hw->provider_name, VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)hw->frame_dur));
-#endif
- hw->stat |= STAT_VF_HOOK;
-
- hw->timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&hw->timer);
-
- hw->stat |= STAT_VDEC_RUN;
- hw->stat |= STAT_TIMER_ARM;
-
- amhevc_start();
-
- hw->init_flag = 1;
- hw->process_busy = 0;
- pr_info("%d, vav1_init, RP=0x%x\n",
- __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
- return 0;
-}
-
-static int vmav1_stop(struct AV1HW_s *hw)
-{
- hw->init_flag = 0;
-
- if (hw->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
- if (hw->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_0, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-
- if (!hw->is_used_v4l && (hw->stat & STAT_VF_HOOK)) {
- if (!is_reset)
- vf_notify_receiver(hw->provider_name,
- VFRAME_EVENT_PROVIDER_FR_END_HINT,
- NULL);
-
- vf_unreg_provider(&vav1_vf_prov);
- hw->stat &= ~STAT_VF_HOOK;
- }
- av1_local_uninit(hw, false);
- reset_process_time(hw);
- cancel_work_sync(&hw->work);
- cancel_work_sync(&hw->set_clk_work);
- uninit_mmu_buffers(hw);
- if (hw->fw)
- vfree(hw->fw);
- hw->fw = NULL;
- return 0;
-}
-
-static int amvdec_av1_mmu_init(struct AV1HW_s *hw)
-{
- int tvp_flag = vdec_secure(hw_to_vdec(hw)) ?
- CODEC_MM_FLAGS_TVP : 0;
- int buf_size = 48;
-
- if ((hw->max_pic_w * hw->max_pic_h > 1280*736) &&
- (hw->max_pic_w * hw->max_pic_h <= 1920*1088)) {
- buf_size = 12;
- } else if ((hw->max_pic_w * hw->max_pic_h > 0) &&
- (hw->max_pic_w * hw->max_pic_h <= 1280*736)) {
- buf_size = 4;
- }
- hw->need_cache_size = buf_size * SZ_1M;
- hw->sc_start_time = get_jiffies_64();
- if (hw->mmu_enable && !hw->is_used_v4l) {
- int count = FRAME_BUFFERS;
- hw->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- hw->index /* * 2*/, count,
- hw->need_cache_size,
- tvp_flag
- );
- if (!hw->mmu_box) {
- pr_err("av1 alloc mmu box failed!!\n");
- return -1;
- }
-#ifdef AOM_AV1_MMU_DW
- if (get_double_write_mode(hw) & 0x20) {
- hw->mmu_box_dw = decoder_mmu_box_alloc_box(DRIVER_NAME,
- hw->index /** 2 + 1*/, count,
- hw->need_cache_size,
- tvp_flag
- );
- if (!hw->mmu_box_dw) {
- pr_err("av1 alloc dw mmu box failed!!\n");
- return -1;
- }
- }
-#endif
-
- }
- hw->bmmu_box = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- hw->index,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "%s, MAX_BMMU_BUFFER_NUM = %d\n",
- __func__,
- MAX_BMMU_BUFFER_NUM);
- if (!hw->bmmu_box) {
- pr_err("av1 alloc bmmu box failed!!\n");
- return -1;
- }
- return 0;
-}
-
-/****************************************/
-#ifdef CONFIG_PM
-static int av1_suspend(struct device *dev)
-{
- amhevc_suspend(to_platform_device(dev), dev->power.power_state);
- return 0;
-}
-
-static int av1_resume(struct device *dev)
-{
- amhevc_resume(to_platform_device(dev));
- return 0;
-}
-
-static const struct dev_pm_ops av1_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(av1_suspend, av1_resume)
-};
-#endif
-
-static struct codec_profile_t amvdec_av1_profile = {
- .name = "AV1-V4L",
- .profile = ""
-};
-
-static unsigned int get_data_check_sum
- (struct AV1HW_s *hw, int size)
-{
- int sum = 0;
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->data_offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->data_offset;
-
- sum = crc32_le(0, data, size);
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void dump_data(struct AV1HW_s *hw, int size)
-{
- int jj;
- u8 *data = NULL;
- int padding_size = hw->data_offset &
- (VDEC_FIFO_ALIGN - 1);
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->data_offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->data_offset;
-
- av1_print(hw, 0, "padding: ");
- for (jj = padding_size; jj > 0; jj--)
- av1_print_cont(hw,
- 0,
- "%02x ", *(data - jj));
- av1_print_cont(hw, 0, "data adr %p\n",
- data);
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- av1_print(hw,
- 0,
- "%06x:", jj);
- av1_print_cont(hw,
- 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- av1_print(hw,
- 0,
- "\n");
- }
- av1_print(hw,
- 0,
- "\n");
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
-}
-
-static int av1_wait_cap_buf(void *args)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *) args;
- struct AV1_Common_s *const cm = &hw->common;
- struct aml_vcodec_ctx * ctx =
- (struct aml_vcodec_ctx *)hw->v4l2_ctx;
- ulong flags;
- int ret = 0;
-
- ret = wait_event_interruptible_timeout(ctx->cap_wq,
- (ctx->is_stream_off || (get_free_buf_count(hw) > 0)),
- msecs_to_jiffies(300));
- if (ret <= 0){
- av1_print(hw, PRINT_FLAG_V4L_DETAIL, "%s, wait cap buf timeout or err %d\n",
- __func__, ret);
- }
-
- lock_buffer_pool(cm->buffer_pool, flags);
- if (hw->wait_more_buf) {
- hw->wait_more_buf = false;
- hw->dec_result = ctx->is_stream_off ?
- DEC_RESULT_FORCE_EXIT :
- AOM_AV1_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- }
- unlock_buffer_pool(cm->buffer_pool, flags);
-
- av1_print(hw, PRINT_FLAG_V4L_DETAIL,
- "%s wait capture buffer end, ret:%d\n",
- __func__, ret);
- return 0;
-}
-
-static void av1_work(struct work_struct *work)
-{
- struct AV1HW_s *hw = container_of(work,
- struct AV1HW_s, work);
- struct vdec_s *vdec = hw_to_vdec(hw);
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- if (hw->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_AGAIN);
- if (hw->dec_result != AOM_AV1_RESULT_NEED_MORE_BUFFER)
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_START);
- av1_print(hw, PRINT_FLAG_VDEC_DETAIL,
- "%s dec_result %d %x %x %x\n",
- __func__,
- hw->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
-
- ATRACE_COUNTER("V_ST_DEC-work_state", hw->dec_result);
-
- if (hw->dec_result == AOM_AV1_RESULT_NEED_MORE_BUFFER) {
- reset_process_time(hw);
- if (get_free_buf_count(hw) <= 0) {
- struct AV1_Common_s *const cm = &hw->common;
- ulong flags;
- int ret;
-
- lock_buffer_pool(cm->buffer_pool, flags);
-
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
- hw->dec_result = DEC_RESULT_AGAIN;
- vdec_schedule_work(&hw->work);
- } else {
- hw->wait_more_buf = true;
- }
- unlock_buffer_pool(cm->buffer_pool, flags);
-
- if (hw->wait_more_buf) {
- ATRACE_COUNTER("V_ST_DEC-wait_more_buff", __LINE__);
- ret = vdec_post_task(av1_wait_cap_buf, hw);
- if (ret != 0) {
- pr_err("post task create failed!!!! ret %d\n", ret);
- lock_buffer_pool(cm->buffer_pool, flags);
- hw->wait_more_buf = false;
- hw->dec_result = AOM_AV1_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&hw->work);
- unlock_buffer_pool(cm->buffer_pool, flags);
- }
- }
-
- } else {
- ATRACE_COUNTER("V_ST_DEC-wait_more_buff", 0);
- av1_release_bufs(hw);
- av1_continue_decoding(hw, hw->cur_obu_type);
- hw->postproc_done = 0;
- start_process_time(hw);
- }
- return;
- }
-
- if (((hw->dec_result == DEC_RESULT_GET_DATA) ||
- (hw->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(hw)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
-
- if (hw->dec_result == DEC_RESULT_GET_DATA) {
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
- vdec_vframe_dirty(vdec, hw->chunk);
- vdec_clean_input(vdec);
- }
-
- if (get_free_buf_count(hw) >=
- hw->run_ready_min_buf_num) {
- int r;
- int decode_size;
- r = vdec_prepare_input(vdec, &hw->chunk);
- if (r < 0) {
- hw->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- av1_print(hw,
- PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&hw->work);
- return;
- }
- hw->dec_result = DEC_RESULT_NONE;
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s: chunk size 0x%x sum 0x%x\n",
- __func__, r,
- (debug & PRINT_FLAG_VDEC_STATUS) ?
- get_data_check_sum(hw, r) : 0
- );
-
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(hw, hw->data_size);
-
- decode_size = hw->data_size +
- (hw->data_offset & (VDEC_FIFO_ALIGN - 1));
-
- WRITE_VREG(HEVC_DECODE_SIZE,
- READ_VREG(HEVC_DECODE_SIZE) + decode_size);
-
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- start_process_time(hw);
-
- } else {
- hw->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- av1_print(hw, PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&hw->work);
- }
- return;
- } else if (hw->dec_result == DEC_RESULT_DONE) {
- /* if (!hw->ctx_valid)
- hw->ctx_valid = 1; */
- hw->result_done_count++;
- hw->process_state = PROC_STATE_INIT;
-
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s (===> %d) dec_result %d (%d) %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
- __func__,
- hw->frame_count,
- hw->dec_result,
- hw->result_done_count,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- hw->start_shift_bytes
- );
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- } else if (hw->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- hw->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&hw->work);
- return;
- }
- } else if (hw->dec_result == DEC_RESULT_EOS) {
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s: end of stream\n", __func__);
- mutex_lock(&hw->assit_task.assit_mutex);
- hw->eos = 1;
- av1_postproc(hw);
-
- if (hw->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(hw));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
- mutex_unlock(&hw->assit_task.assit_mutex);
-
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
- if (hw->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_ISR_REG) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!hw->m_ins_flag)
-#endif
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0);
- vdec_free_irq(VDEC_IRQ_0, (void *)hw);
- hw->stat &= ~STAT_ISR_REG;
- }
- } else if (hw->dec_result == DEC_RESULT_DISCARD_DATA) {
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s (===> %d) dec_result %d (%d) %x %x %x shiftbytes 0x%x decbytes 0x%x discard pic!\n",
- __func__,
- hw->frame_count,
- hw->dec_result,
- hw->result_done_count,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- hw->start_shift_bytes
- );
- vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
- } else if (hw->dec_result == DEC_RESULT_UNFINISH) {
- hw->result_done_count++;
- hw->process_state = PROC_STATE_INIT;
-
- av1_print(hw, PRINT_FLAG_VDEC_STATUS,
- "%s (===> %d) dec_result %d (%d) %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
- __func__,
- hw->frame_count,
- hw->dec_result,
- hw->result_done_count,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) - hw->start_shift_bytes);
- amhevc_stop();
- }
-
- if (hw->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_WORKER_END);
- /* mark itself has all HW resource released and input released */
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(vdec, CORE_MASK_HEVC);
- else
- vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1
- | CORE_MASK_HEVC);
- trigger_schedule(hw);
-}
-
-static int av1_hw_ctx_restore(struct AV1HW_s *hw)
-{
- vav1_prot_init(hw, HW_MASK_FRONT | HW_MASK_BACK);
- return 0;
-}
-
-static bool is_avaliable_buffer(struct AV1HW_s *hw)
-{
- AV1_COMMON *cm = &hw->common;
- RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- int i, free_count = 0;
- int used_count = 0;
-
- if ((hw->used_buf_num == 0) ||
- (ctx->cap_pool.dec < hw->used_buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &hw->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < hw->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0) &&
- (frame_bufs[i].buf.index >= 0) &&
- frame_bufs[i].buf.cma_alloc_addr) {
- free_count++;
- } else if (frame_bufs[i].buf.cma_alloc_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("av1_free_buff_count", free_count);
- ATRACE_COUNTER("av1_used_buff_count", used_count);
-
- return free_count >= hw->run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- int tvp = vdec_secure(hw_to_vdec(hw)) ?
- CODEC_MM_FLAGS_TVP : 0;
- unsigned long ret = 0;
-
- if (!hw->pic_list_init_done2 || hw->eos)
- return ret;
-
- if (!hw->first_sc_checked &&
- (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) &&
- (get_double_write_mode(hw) != 0x10)) {
- int size;
- void * mmu_box;
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = hw->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
- hw->first_sc_checked = 1;
- av1_print(hw, 0, "av1 cached=%d need_size=%d speed= %d ms\n",
- size, (hw->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - hw->sc_start_time) * 1000/HZ);
-#ifdef AOM_AV1_MMU_DW
- /*!!!!!! To do ... */
- if (get_double_write_mode(hw) & 0x20) {
-
- }
-#endif
- }
-
- if (hw->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
-
- if (hw->v4l_params_parsed) {
- if (is_avaliable_buffer(hw))
- ret = CORE_MASK_HEVC;
- else
- ret = 0;
- } else {
- if (ctx->v4l_resolution_change)
- ret = 0;
- else
- ret = CORE_MASK_HEVC;
- }
- }
-
- if (ret)
- not_run_ready[hw->index] = 0;
- else
- not_run_ready[hw->index]++;
-
- /*av1_print(hw,
- PRINT_FLAG_VDEC_DETAIL, "%s mask %lx=>%lx\r\n",
- __func__, mask, ret);*/
- return ret;
-}
-
-static void av1_frame_mode_pts_save(struct AV1HW_s *hw)
-{
- u64 i, valid_pts_diff_cnt, pts_diff_sum;
- u64 in_pts_diff, last_valid_pts_diff, calc_dur;
-
- if (hw->chunk == NULL)
- return;
- /* no return when first pts is 0 */
- if (!hw->is_used_v4l && hw->first_pts_index) {
- /* filtration pts 0 and continuous same pts */
- if ((hw->chunk->pts == 0) ||
- (hw->frame_mode_pts_save[0] == hw->chunk->pts))
- return;
-
- /* fps change, frame dur change to lower or higher,
- * can't find closed pts in saved pool */
- if (hw->dur_recalc_flag ||
- (hw->last_pts > hw->chunk->pts)) {
- hw->av1_first_pts_ready = 0;
- hw->first_pts_index = 0;
- hw->get_frame_dur = 0;
- hw->dur_recalc_flag = 0;
- memset(hw->frame_mode_pts_save, 0,
- sizeof(hw->frame_mode_pts_save));
- memset(hw->frame_mode_pts64_save, 0,
- sizeof(hw->frame_mode_pts64_save));
- }
- }
- av1_print(hw, AV1_DEBUG_OUT_PTS,
- "run_front: pts %d, pts64 %lld, ts: %lld\n",
- hw->chunk->pts, hw->chunk->pts64, hw->chunk->timestamp);
-
- for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- hw->frame_mode_pts_save[i] = hw->frame_mode_pts_save[i - 1];
- hw->frame_mode_pts64_save[i] = hw->frame_mode_pts64_save[i - 1];
- }
- hw->frame_mode_pts_save[0] = hw->chunk->pts;
- hw->frame_mode_pts64_save[0] = hw->chunk->pts64;
-
- if (hw->is_used_v4l && !v4l_bitstream_id_enable)
- hw->frame_mode_pts64_save[0] = hw->chunk->timestamp;
-
- if (hw->first_pts_index < ARRAY_SIZE(hw->frame_mode_pts_save))
- hw->first_pts_index++;
- /* frame duration check, vdec_secure return for nts problem */
- if ((!hw->first_pts_index) ||
- hw->get_frame_dur ||
- vdec_secure(hw_to_vdec(hw)))
- return;
- valid_pts_diff_cnt = 0;
- pts_diff_sum = 0;
-
- for (i = 0; i < FRAME_BUFFERS - 1; i++) {
- if ((hw->frame_mode_pts_save[i] > hw->frame_mode_pts_save[i + 1]) &&
- (hw->frame_mode_pts_save[i + 1] != 0))
- in_pts_diff = hw->frame_mode_pts_save[i]
- - hw->frame_mode_pts_save[i + 1];
- else
- in_pts_diff = 0;
-
- if (in_pts_diff < 100 ||
- (valid_pts_diff_cnt && (!close_to(in_pts_diff, last_valid_pts_diff, 100))))
- in_pts_diff = 0;
- else {
- last_valid_pts_diff = in_pts_diff;
- valid_pts_diff_cnt++;
- }
-
- pts_diff_sum += in_pts_diff;
- }
-
- if (!valid_pts_diff_cnt) {
- av1_print(hw, AV1_DEBUG_OUT_PTS, "checked no avaliable pts\n");
- return;
- }
-
- calc_dur = PTS2DUR_u64(div_u64(pts_diff_sum, valid_pts_diff_cnt));
-
- if ((!close_to(calc_dur, hw->frame_dur, 10)) &&
- (calc_dur < 4800) && (calc_dur > 800)) {
- av1_print(hw, 0, "change to calc dur %llu, old dur %u\n", calc_dur, hw->frame_dur);
- hw->frame_dur = calc_dur;
- hw->get_frame_dur = true;
- } else {
- if (hw->frame_count > FRAME_BUFFERS)
- hw->get_frame_dur = true;
- }
-}
-
-static void run_front(struct vdec_s *vdec)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- int ret, size;
-
- run_count[hw->index]++;
- /* hw->chunk = vdec_prepare_input(vdec); */
- hevc_reset_core(vdec);
-
- if ((vdec_frame_based(vdec)) &&
- (hw->dec_result == DEC_RESULT_UNFINISH)) {
- u32 res_byte = hw->data_size - hw->consume_byte;
-
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "%s before, consume 0x%x, size 0x%x, offset 0x%x, res 0x%x\n", __func__,
- hw->consume_byte, hw->data_size, hw->data_offset + hw->consume_byte, res_byte);
-
- hw->data_invalid = vdec_offset_prepare_input(vdec, hw->consume_byte, hw->data_offset, hw->data_size);
- hw->data_offset -= (hw->data_invalid - hw->consume_byte);
- hw->data_size += (hw->data_invalid - hw->consume_byte);
- size = hw->data_size;
- WRITE_VREG(HEVC_ASSIST_SCRATCH_C, hw->data_invalid);
-
- av1_print(hw, AV1_DEBUG_BUFMGR,
- "%s after, consume 0x%x, size 0x%x, offset 0x%x, invalid 0x%x, res 0x%x\n", __func__,
- hw->consume_byte, hw->data_size, hw->data_offset, hw->data_invalid, res_byte);
- } else {
- size = vdec_prepare_input(vdec, &hw->chunk);
- if (size < 0) {
- input_empty[hw->index]++;
-
- hw->dec_result = DEC_RESULT_AGAIN;
-
- av1_print(hw, PRINT_FLAG_VDEC_DETAIL,
- "ammvdec_av1: Insufficient data\n");
-
- vdec_schedule_work(&hw->work);
- return;
- }
- if ((vdec_frame_based(vdec)) &&
- (hw->chunk != NULL)) {
- hw->data_offset = hw->chunk->offset;
- hw->data_size = size;
- }
- WRITE_VREG(HEVC_ASSIST_SCRATCH_C, 0);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", size);
-
- input_empty[hw->index] = 0;
- hw->dec_result = DEC_RESULT_NONE;
- hw->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-
- av1_frame_mode_pts_save(hw);
- if (debug & PRINT_FLAG_VDEC_STATUS) {
- if (vdec_frame_based(vdec) && hw->chunk && !vdec_secure(vdec)) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(hw->chunk->block->start +
- hw->data_offset, size);
- else
- data = ((u8 *)hw->chunk->block->start_virt) +
- hw->data_offset;
-
- //print_hex_debug(data, size, size > 64 ? 64 : size);
- av1_print(hw, 0,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, get_data_check_sum(hw, size),
- data[0], data[1], data[2], data[3],
- data[4], data[5], data[size - 4],
- data[size - 3], data[size - 2],
- data[size - 1]);
- av1_print(hw, 0,
- "%s frm cnt (%d): chunk (0x%x 0x%x) (%x %x %x %x %x) bytes 0x%x\n",
- __func__, hw->frame_count, hw->data_size, hw->data_offset,
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- hw->start_shift_bytes);
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- } else {
- av1_print(hw, 0,
- "%s (%d): size 0x%x (0x%x 0x%x) (%x %x %x %x %x) bytes 0x%x\n",
- __func__,
- hw->frame_count, size,
- hw->chunk ? hw->data_size : 0,
- hw->chunk ? hw->data_offset : 0,
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- hw->start_shift_bytes);
- }
- }
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
- ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, hw->fw->data);
-#else
- ret = amhevc_loadmc_ex(VFORMAT_AV1, NULL, hw->fw->data);
-#endif
- if (ret < 0) {
- amhevc_disable();
- av1_print(hw, PRINT_FLAG_ERROR,
- "AV1: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- hw->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&hw->work);
- return;
- }
- vdec->mc_loaded = 1;
-#ifdef DEBUG_USE_VP9_DEVICE_NAME
- vdec->mc_type = VFORMAT_VP9;
-#else
- vdec->mc_type = VFORMAT_AV1;
-#endif
- }
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
-
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
- if (av1_hw_ctx_restore(hw) < 0) {
- vdec_schedule_work(&hw->work);
- return;
- }
- ATRACE_COUNTER(hw->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- if (vdec_frame_based(vdec)) {
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(hw, hw->data_size);
-
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
- size = hw->data_size +
- (hw->data_offset & (VDEC_FIFO_ALIGN - 1));
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = hw->data_size;
- }
- hw->data_size = size;
- WRITE_VREG(HEVC_DECODE_SIZE, size);
- WRITE_VREG(HEVC_DECODE_COUNT, hw->result_done_count);
- WRITE_VREG(LMEM_DUMP_ADR, (u32)hw->lmem_phy_addr);
- if (hw->config_next_ref_info_flag)
- config_next_ref_info_hw(hw);
- hw->config_next_ref_info_flag = 0;
- hw->init_flag = 1;
-
- av1_print(hw, PRINT_FLAG_VDEC_DETAIL,
- "%s: start hw (%x %x %x) HEVC_DECODE_SIZE 0x%x\n",
- __func__,
- READ_VREG(HEVC_DEC_STATUS_REG),
- READ_VREG(HEVC_MPC_E),
- READ_VREG(HEVC_MPSR),
- READ_VREG(HEVC_DECODE_SIZE));
-
- start_process_time(hw);
- mod_timer(&hw->timer, jiffies);
- hw->stat |= STAT_TIMER_ARM;
- hw->stat |= STAT_ISR_REG;
- amhevc_start();
- hw->stat |= STAT_VDEC_RUN;
-}
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_START);
- av1_print(hw,
- PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n",
- __func__, mask);
-
- run_count[hw->index]++;
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- hw->vdec_cb_arg = arg;
- hw->vdec_cb = callback;
- hw->one_package_frame_cnt = 0;
- run_front(vdec);
- ATRACE_COUNTER(hw->trace.decode_time_name, DECODER_RUN_END);
-}
-
-static void av1_decode_ctx_reset(struct AV1HW_s *hw)
-{
- struct AV1_Common_s *const cm = &hw->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- frame_bufs[i].ref_count = 0;
- frame_bufs[i].buf.vf_ref = 0;
- frame_bufs[i].buf.decode_idx = 0;
- frame_bufs[i].buf.cma_alloc_addr = 0;
- frame_bufs[i].buf.index = i;
- frame_bufs[i].buf.BUF_index = -1;
- frame_bufs[i].buf.mv_buf_index = -1;
- frame_bufs[i].buf.repeat_pic = NULL;
- frame_bufs[i].buf.repeat_count = 0;
- }
-
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (hw->m_mv_BUF[i].start_adr) {
- if (mv_buf_dynamic_alloc) {
- decoder_bmmu_box_free_idx(hw->bmmu_box, MV_BUFFER_IDX(i));
- hw->m_mv_BUF[i].start_adr = 0;
- hw->m_mv_BUF[i].size = 0;
- }
- hw->m_mv_BUF[i].used_flag = 0;
- }
- }
-
- hw->one_compressed_data_done = 0;
- hw->config_next_ref_info_flag = 0;
- hw->init_flag = 0;
- hw->first_sc_checked = 0;
- hw->fatal_error = 0;
- hw->show_frame_num = 0;
- hw->postproc_done = 0;
- hw->process_busy = 0;
- hw->process_state = 0;
- hw->frame_decoded = 0;
- hw->eos = 0;
- hw->dec_result = DEC_RESULT_NONE;
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
-
- cancel_work_sync(&hw->work);
- cancel_work_sync(&hw->set_clk_work);
-
- if (hw->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- hw->stat &= ~STAT_VDEC_RUN;
- }
-
- if (hw->stat & STAT_TIMER_ARM) {
- del_timer_sync(&hw->timer);
- hw->stat &= ~STAT_TIMER_ARM;
- }
-
- reset_process_time(hw);
-
- av1_bufmgr_ctx_reset(hw->pbi, &hw->av1_buffer_pool, &hw->common);
- hw->pbi->private_data = hw;
- mutex_lock(&hw->assit_task.assit_mutex);
- av1_local_uninit(hw, true);
- if (vav1_local_init(hw, true) < 0)
- av1_print(hw, 0, "%s local_init failed \r\n", __func__);
- mutex_unlock(&hw->assit_task.assit_mutex);
-
- av1_decode_ctx_reset(hw);
-
- atomic_set(&hw->vf_pre_count, 0);
- atomic_set(&hw->vf_get_count, 0);
- atomic_set(&hw->vf_put_count, 0);
-
- if (hw->ge2d) {
- vdec_ge2d_destroy(hw->ge2d);
- hw->ge2d = NULL;
- }
-
- av1_print(hw, PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
-}
-
-static irqreturn_t av1_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- return vav1_isr(0, hw);
-}
-
-static irqreturn_t av1_threaded_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- return vav1_isr_thread_fn(0, hw);
-}
-
-static void av1_dump_state(struct vdec_s *vdec)
-{
- struct AV1HW_s *hw =
- (struct AV1HW_s *)vdec->private;
- struct AV1_Common_s *const cm = &hw->common;
- int i;
- av1_print(hw, 0, "====== %s\n", __func__);
-
- av1_print(hw, 0,
- "width/height (%d/%d), used_buf_num %d\n",
- cm->width,
- cm->height,
- hw->used_buf_num
- );
-
- av1_print(hw, 0,
- "is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d low_latency %d no_head %d \n",
- input_frame_based(vdec),
- hw->eos,
- hw->dec_result,
- decode_frame_count[hw->index],
- display_frame_count[hw->index],
- run_count[hw->index],
- not_run_ready[hw->index],
- input_empty[hw->index],
- hw->low_latency_flag,
- hw->no_head
- );
-
- if (!hw->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- av1_print(hw, 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- av1_print(hw, 0,
- "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
- __func__,
- kfifo_len(&hw->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&hw->display_q),
- VF_POOL_SIZE,
- hw->vf_pre_count,
- hw->vf_get_count,
- hw->vf_put_count,
- get_free_buf_count(hw),
- hw->run_ready_min_buf_num
- );
-
- dump_pic_list(hw);
-
- for (i = 0; i < MAX_BUF_NUM; i++) {
- av1_print(hw, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
- i,
- hw->m_mv_BUF[i].start_adr,
- hw->m_mv_BUF[i].size,
- hw->m_mv_BUF[i].used_flag);
- }
-
- av1_print(hw, 0,
- "HEVC_DEC_STATUS_REG=0x%x\n",
- READ_VREG(HEVC_DEC_STATUS_REG));
- av1_print(hw, 0,
- "HEVC_MPC_E=0x%x\n",
- READ_VREG(HEVC_MPC_E));
- av1_print(hw, 0,
- "DECODE_MODE=0x%x\n",
- READ_VREG(DECODE_MODE));
- av1_print(hw, 0,
- "NAL_SEARCH_CTL=0x%x\n",
- READ_VREG(NAL_SEARCH_CTL));
- av1_print(hw, 0,
- "HEVC_PARSER_LCU_START=0x%x\n",
- READ_VREG(HEVC_PARSER_LCU_START));
- av1_print(hw, 0,
- "HEVC_DECODE_SIZE=0x%x\n",
- READ_VREG(HEVC_DECODE_SIZE));
- av1_print(hw, 0,
- "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- av1_print(hw, 0,
- "HEVC_SHIFTED_DATA=0x%x\n",
- READ_VREG(HEVC_SHIFTED_DATA));
- av1_print(hw, 0,
- "HEVC_STREAM_START_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_START_ADDR));
- av1_print(hw, 0,
- "HEVC_STREAM_END_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_END_ADDR));
- av1_print(hw, 0,
- "HEVC_STREAM_LEVEL=0x%x\n",
- READ_VREG(HEVC_STREAM_LEVEL));
- av1_print(hw, 0,
- "HEVC_STREAM_WR_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_WR_PTR));
- av1_print(hw, 0,
- "HEVC_STREAM_RD_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_RD_PTR));
- av1_print(hw, 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- av1_print(hw, 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (input_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_DATA)
- ) {
- int jj;
- if (hw->chunk && hw->chunk->block &&
- hw->data_size > 0) {
- u8 *data = NULL;
-
- if (!hw->chunk->block->is_mapped)
- data = codec_mm_vmap(
- hw->chunk->block->start +
- hw->data_offset,
- hw->data_size);
- else
- data = ((u8 *)hw->chunk->block->start_virt)
- + hw->data_offset;
- av1_print(hw, 0,
- "frame data size 0x%x\n",
- hw->data_size);
- for (jj = 0; jj < hw->data_size; jj++) {
- if ((jj & 0xf) == 0)
- av1_print(hw, 0,
- "%06x:", jj);
- av1_print_cont(hw, 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- av1_print_cont(hw, 0,
- "\n");
- }
-
- if (!hw->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-
-}
-
-static int ammvdec_av1_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- int ret;
- int config_val;
- int i;
- struct vframe_content_light_level_s content_light_level;
- struct vframe_master_display_colour_s vf_dp;
- u32 work_buf_size;
- struct BuffInfo_s *p_buf_info;
- struct AV1HW_s *hw = NULL;
-
- if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TM2) ||
- (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
- ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) && !is_meson_rev_b())) {
- pr_err("av1 unsupported on cpu %d, is_tm2_revb %d\n",
- get_cpu_major_id(), is_cpu_tm2_revb());
- return -EINVAL;
- }
-
- if (pdata == NULL) {
- av1_print(hw, 0, "\nammvdec_av1 memory resource undefined.\n");
- return -EFAULT;
- }
- memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
-
- hw = vzalloc(sizeof(struct AV1HW_s));
- if (hw == NULL) {
- av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n");
- return -ENOMEM;
- }
-
- if (init_dblk_struc(hw) < 0) {
- av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n");
- vfree(hw);
- return -ENOMEM;
- }
-
- hw->pbi = av1_decoder_create(&hw->av1_buffer_pool, &hw->common); //&aom_decoder;
- if (hw->pbi == NULL) {
- av1_print(hw, 0, "\nammvdec_av1 device data allocation failed\n");
- release_dblk_struct(hw);
- vfree(hw);
- return -ENOMEM;
- }
-
- hw->pbi->private_data = hw;
- /* the ctx from v4l2 driver. */
- hw->v4l2_ctx = pdata->private;
-
- pdata->private = hw;
- pdata->dec_status = vav1_dec_status;
- /* pdata->set_trickmode = set_trickmode; */
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = av1_irq_cb;
- pdata->threaded_irq_handler = av1_threaded_irq_cb;
- pdata->dump_state = av1_dump_state;
-
- hw->index = pdev->id;
- if (is_rdma_enable()) {
- hw->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &hw->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- hw->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- hw->rdma_adr[i * 4 + 1] = i;
- hw->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- hw->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- hw->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
- snprintf(hw->trace.vdec_name, sizeof(hw->trace.vdec_name),
- "av1-%d", hw->index);
- snprintf(hw->trace.pts_name, sizeof(hw->trace.pts_name),
- "%s-timestamp", hw->trace.vdec_name);
- snprintf(hw->trace.new_q_name, sizeof(hw->trace.new_q_name),
- "%s-newframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.disp_q_name, sizeof(hw->trace.disp_q_name),
- "%s-dispframe_q", hw->trace.vdec_name);
- snprintf(hw->trace.decode_time_name, sizeof(hw->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(hw->trace.decode_run_time_name, sizeof(hw->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(hw->trace.decode_header_memory_time_name, sizeof(hw->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
- snprintf(hw->trace.decode_work_time_name, sizeof(hw->trace.decode_work_time_name),
- "decoder_work_time%d", pdev->id);
- if (pdata->use_vfm_path)
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
- else if (vdec_dual(pdata)) {
- struct AV1HW_s *hevc_pair = NULL;
-
- if (dv_toggle_prov_name) /*debug purpose*/
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVBL_PROVIDER_NAME :
- VFM_DEC_DVEL_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name,
- VDEC_PROVIDER_NAME_SIZE,
- (pdata->master) ? VFM_DEC_DVEL_PROVIDER_NAME :
- VFM_DEC_DVBL_PROVIDER_NAME);
- if (pdata->master)
- hevc_pair = (struct AV1HW_s *)pdata->master->private;
- else if (pdata->slave)
- hevc_pair = (struct AV1HW_s *)pdata->slave->private;
-
- if (hevc_pair)
- hw->shift_byte_count_lo = hevc_pair->shift_byte_count_lo;
- }
-#endif
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- hw->provider_name = pdata->vf_provider_name;
- platform_set_drvdata(pdev, pdata);
-
- hw->platform_dev = pdev;
- hw->video_signal_type = 0;
- hw->m_ins_flag = 1;
-
- film_grain_task_create(hw);
-
- if (pdata->sys_info) {
- hw->vav1_amstream_dec_info = *pdata->sys_info;
- if ((unsigned long) hw->vav1_amstream_dec_info.param
- & 0x08) {
- hw->low_latency_flag = 1;
- } else
- hw->low_latency_flag = 0;
- } else {
- hw->vav1_amstream_dec_info.width = 0;
- hw->vav1_amstream_dec_info.height = 0;
- hw->vav1_amstream_dec_info.rate = 30;
- }
-
- if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
- pdata->config_len) {
-#ifdef MULTI_INSTANCE_SUPPORT
- int av1_buf_width = 0;
- int av1_buf_height = 0;
- /*use ptr config for doubel_write_mode, etc*/
- av1_print(hw, 0, "pdata->config=%s\n", pdata->config);
- if (get_config_int(pdata->config, "av1_double_write_mode",
- &config_val) == 0)
- hw->double_write_mode = config_val;
- else
- hw->double_write_mode = double_write_mode;
-
- if (get_config_int(pdata->config, "save_buffer_mode",
- &config_val) == 0)
- hw->save_buffer_mode = config_val;
- else
- hw->save_buffer_mode = 0;
- if (get_config_int(pdata->config, "av1_buf_width",
- &config_val) == 0) {
- av1_buf_width = config_val;
- }
- if (get_config_int(pdata->config, "av1_buf_height",
- &config_val) == 0) {
- av1_buf_height = config_val;
- }
-
- if (get_config_int(pdata->config, "no_head",
- &config_val) == 0)
- hw->no_head = config_val;
- else
- hw->no_head = no_head;
-
- /*use ptr config for max_pic_w, etc*/
- if (get_config_int(pdata->config, "av1_max_pic_w",
- &config_val) == 0) {
- hw->max_pic_w = config_val;
- }
- if (get_config_int(pdata->config, "av1_max_pic_h",
- &config_val) == 0) {
- hw->max_pic_h = config_val;
- }
- if ((hw->max_pic_w * hw->max_pic_h)
- < (av1_buf_width * av1_buf_height)) {
- hw->max_pic_w = av1_buf_width;
- hw->max_pic_h = av1_buf_height;
- av1_print(hw, 0, "use buf resolution\n");
- }
-
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- hw->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- hw->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- hw->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_buffer_margin",
- &config_val) == 0)
- hw->dynamic_buf_num_margin = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- hw->mem_map_mode = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_low_latency_mode",
- &config_val) == 0)
- hw->low_latency_flag = config_val;
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
-
-#endif
- if (get_config_int(pdata->config, "HDRStaticInfo",
- &vf_dp.present_flag) == 0
- && vf_dp.present_flag == 1) {
- get_config_int(pdata->config, "signal_type",
- &hw->video_signal_type);
- get_config_int(pdata->config, "mG.x",
- &vf_dp.primaries[0][0]);
- get_config_int(pdata->config, "mG.y",
- &vf_dp.primaries[0][1]);
- get_config_int(pdata->config, "mB.x",
- &vf_dp.primaries[1][0]);
- get_config_int(pdata->config, "mB.y",
- &vf_dp.primaries[1][1]);
- get_config_int(pdata->config, "mR.x",
- &vf_dp.primaries[2][0]);
- get_config_int(pdata->config, "mR.y",
- &vf_dp.primaries[2][1]);
- get_config_int(pdata->config, "mW.x",
- &vf_dp.white_point[0]);
- get_config_int(pdata->config, "mW.y",
- &vf_dp.white_point[1]);
- get_config_int(pdata->config, "mMaxDL",
- &vf_dp.luminance[0]);
- get_config_int(pdata->config, "mMinDL",
- &vf_dp.luminance[1]);
- vf_dp.content_light_level.present_flag = 1;
- get_config_int(pdata->config, "mMaxCLL",
- &content_light_level.max_content);
- get_config_int(pdata->config, "mMaxFALL",
- &content_light_level.max_pic_average);
- vf_dp.content_light_level = content_light_level;
- if (!hw->video_signal_type) {
- hw->video_signal_type = (1 << 29)
- | (5 << 26) /* unspecified */
- | (0 << 25) /* limit */
- | (1 << 24) /* color available */
- | (9 << 16) /* 2020 */
- | (16 << 8) /* 2084 */
- | (9 << 0); /* 2020 */
- }
- }
- hw->vf_dp = vf_dp;
- } else {
- u32 force_w, force_h;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
- force_w = 1920;
- force_h = 1088;
- } else {
- force_w = 8192;
- force_h = 4608;
- }
- if (hw->vav1_amstream_dec_info.width)
- hw->max_pic_w = hw->vav1_amstream_dec_info.width;
- else
- hw->max_pic_w = force_w;
-
- if (hw->vav1_amstream_dec_info.height)
- hw->max_pic_h = hw->vav1_amstream_dec_info.height;
- else
- hw->max_pic_h = force_h;
- hw->double_write_mode = double_write_mode;
- }
-
- hw->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (endian)
- hw->endian = endian;
-
- if (is_oversize(hw->max_pic_w, hw->max_pic_h)) {
- pr_err("over size: %dx%d, probe failed\n",
- hw->max_pic_w, hw->max_pic_h);
- return -1;
- }
- if (force_bufspec) {
- hw->buffer_spec_index = force_bufspec & 0xf;
- pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else if (vdec_is_support_4k()) {
- hw->buffer_spec_index = 1;
- } else
- hw->buffer_spec_index = 0;
-
- if (hw->buffer_spec_index == 0)
- hw->max_one_mv_buffer_size =
- (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_SC2) ?
- MAX_ONE_MV_BUFFER_SIZE_1080P : MAX_ONE_MV_BUFFER_SIZE_1080P_TM2REVB;
- else if (hw->buffer_spec_index == 1)
- hw->max_one_mv_buffer_size =
- (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_SC2) ?
- MAX_ONE_MV_BUFFER_SIZE_4K : MAX_ONE_MV_BUFFER_SIZE_4K_TM2REVB;
- else
- hw->max_one_mv_buffer_size =
- (get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_SC2) ?
- MAX_ONE_MV_BUFFER_SIZE_8K : MAX_ONE_MV_BUFFER_SIZE_8K_TM2REVB;
-
- p_buf_info = &aom_workbuff_spec[hw->buffer_spec_index];
- work_buf_size = (p_buf_info->end_adr - p_buf_info->start_adr
- + 0xffff) & (~0xffff);
-
- if (vdec_is_support_4k() &&
- (hw->max_pic_w * hw->max_pic_h < MAX_SIZE_4K)) {
- hw->max_pic_w = 4096;
- hw->max_pic_h = 2304;
- }
- av1_print(hw, 0,
- "vdec_is_support_4k() %d max_pic_w %d max_pic_h %d buffer_spec_index %d work_buf_size 0x%x\n",
- vdec_is_support_4k(), hw->max_pic_w, hw->max_pic_h,
- hw->buffer_spec_index, work_buf_size);
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- hw->double_write_mode == 0x10)
- hw->mmu_enable = 0;
- else
- hw->mmu_enable = 1;
-
- video_signal_type = hw->video_signal_type;
-
- if (pdata->sys_info) {
- hw->vav1_amstream_dec_info = *pdata->sys_info;
- if ((unsigned long) hw->vav1_amstream_dec_info.param
- & 0x08) {
- hw->low_latency_flag = 1;
- } else
- hw->low_latency_flag = 0;
- } else {
- hw->vav1_amstream_dec_info.width = 0;
- hw->vav1_amstream_dec_info.height = 0;
- hw->vav1_amstream_dec_info.rate = 30;
- }
-
-#ifdef AOM_AV1_MMU_DW
- hw->dw_mmu_enable =
- get_double_write_mode_init(hw) & 0x20 ? 1 : 0;
-
-#endif
- av1_print(hw, 0,
- "no_head %d low_latency %d video_signal_type 0x%x\n",
- hw->no_head, hw->low_latency_flag, hw->video_signal_type);
-#if 0
- hw->buf_start = pdata->mem_start;
- hw->buf_size = pdata->mem_end - pdata->mem_start + 1;
-#else
- if (amvdec_av1_mmu_init(hw) < 0) {
- pr_err("av1 alloc bmmu box failed!!\n");
- /* devm_kfree(&pdev->dev, (void *)hw); */
- vfree((void *)hw);
- pdata->dec_status = NULL;
- return -1;
- }
-
- hw->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE;
- ret = decoder_bmmu_box_alloc_buf_phy(hw->bmmu_box, WORK_SPACE_BUF_ID,
- hw->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
- &hw->cma_alloc_addr);
- if (ret < 0) {
- uninit_mmu_buffers(hw);
- /* devm_kfree(&pdev->dev, (void *)hw); */
- vfree((void *)hw);
- pdata->dec_status = NULL;
- return ret;
- }
- hw->buf_start = hw->cma_alloc_addr;
- hw->buf_size = work_buf_size;
-#endif
-
- hw->init_flag = 0;
- hw->first_sc_checked = 0;
- hw->fatal_error = 0;
- hw->show_frame_num = 0;
- hw->run_ready_min_buf_num = run_ready_min_buf_num;
-
- if (hw->is_used_v4l && (hw->v4l2_ctx != NULL)) {
- struct aml_vcodec_ctx *ctx = hw->v4l2_ctx;
-
- ctx->aux_infos.alloc_buffer(ctx, SEI_TYPE | DV_TYPE);
- }
-
- hw->aux_data_size = AUX_BUF_ALIGN(prefix_aux_buf_size) +
- AUX_BUF_ALIGN(suffix_aux_buf_size);
- hw->dv_data_buf = vmalloc(hw->aux_data_size);
- hw->dv_data_size = 0;
-
- if (debug) {
- av1_print(hw, AOM_DEBUG_HW_MORE, "===AV1 decoder mem resource 0x%lx size 0x%x\n",
- hw->buf_start,
- hw->buf_size);
- }
-
- hw->cma_dev = pdata->cma_dev;
- if (vav1_init(pdata) < 0) {
- av1_print(hw, 0, "\namvdec_av1 init failed.\n");
- av1_local_uninit(hw, false);
- uninit_mmu_buffers(hw);
- /* devm_kfree(&pdev->dev, (void *)hw); */
- vfree((void *)hw);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_init(pdata);
-#endif
-
- vdec_set_prepare_level(pdata, start_decode_buf_level);
- hevc_source_changed(VFORMAT_AV1, 4096, 2048, 60);
-
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_HEVC);
- else
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
-
- hw->pic_list_init_done2 = true;
- return 0;
-}
-
-static int ammvdec_av1_remove(struct platform_device *pdev)
-{
- struct AV1HW_s *hw = (struct AV1HW_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec = hw_to_vdec(hw);
- int i;
- if (debug)
- av1_print(hw, AOM_DEBUG_HW_MORE, "amvdec_av1_remove\n");
-
-#ifdef AUX_DATA_CRC
- vdec_aux_data_check_exit(vdec);
-#endif
-
- if (hw->dv_data_buf != NULL) {
- vfree(hw->dv_data_buf);
- hw->dv_data_buf = NULL;
- }
-
- vmav1_stop(hw);
-
- film_grain_task_exit(hw);
-
- if (hw->ge2d) {
- vdec_ge2d_destroy(hw->ge2d);
- hw->ge2d = NULL;
- }
-
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_HEVC);
- else
- vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-
- vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED);
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < FRAME_BUFFERS; i++) {
- vdec->free_canvas_ex
- (hw->common.buffer_pool->frame_bufs[i].buf.y_canvas_index,
- vdec->id);
- vdec->free_canvas_ex
- (hw->common.buffer_pool->frame_bufs[i].buf.uv_canvas_index,
- vdec->id);
- }
- }
-
-#ifdef DEBUG_PTS
- pr_info("pts missed %ld, pts hit %ld, duration %d\n",
- hw->pts_missed, hw->pts_hit, hw->frame_dur);
-#endif
- /* devm_kfree(&pdev->dev, (void *)hw); */
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, hw->rdma_adr, hw->rdma_phy_adr);
- vfree(hw->pbi);
- release_dblk_struct(hw);
- vfree((void *)hw);
- return 0;
-}
-
-static struct platform_driver ammvdec_av1_driver = {
- .probe = ammvdec_av1_probe,
- .remove = ammvdec_av1_remove,
- .driver = {
- .name = MULTI_DRIVER_NAME,
-#ifdef CONFIG_PM
- .pm = &av1_pm_ops,
-#endif
- }
-};
-#endif
-static struct mconfig av1_configs[] = {
- MC_PU32("bit_depth_luma", &bit_depth_luma),
- MC_PU32("bit_depth_chroma", &bit_depth_chroma),
- MC_PU32("frame_width", &frame_width),
- MC_PU32("frame_height", &frame_height),
- MC_PU32("debug", &debug),
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("pop_shorts", &pop_shorts),
- MC_PU32("dbg_cmd", &dbg_cmd),
- MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
- MC_PU32("endian", &endian),
- MC_PU32("step", &step),
- MC_PU32("udebug_flag", &udebug_flag),
- MC_PU32("decode_pic_begin", &decode_pic_begin),
- MC_PU32("slice_parse_begin", &slice_parse_begin),
- MC_PU32("i_only_flag", &i_only_flag),
- MC_PU32("error_handle_policy", &error_handle_policy),
- MC_PU32("buf_alloc_width", &buf_alloc_width),
- MC_PU32("buf_alloc_height", &buf_alloc_height),
- MC_PU32("buf_alloc_depth", &buf_alloc_depth),
- MC_PU32("buf_alloc_size", &buf_alloc_size),
- MC_PU32("buffer_mode", &buffer_mode),
- MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
- MC_PU32("max_buf_num", &max_buf_num),
- MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
- MC_PU32("mem_map_mode", &mem_map_mode),
- MC_PU32("double_write_mode", &double_write_mode),
- MC_PU32("enable_mem_saving", &enable_mem_saving),
- MC_PU32("force_w_h", &force_w_h),
- MC_PU32("force_fps", &force_fps),
- MC_PU32("max_decoding_time", &max_decoding_time),
- MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped),
- MC_PU32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
- MC_PU32("av1_max_pic_w", &av1_max_pic_w),
- MC_PU32("av1_max_pic_h", &av1_max_pic_h),
-};
-static struct mconfig_node av1_node;
-
-static int __init amvdec_av1_driver_init_module(void)
-{
- //struct BuffInfo_s *p_buf_info;
- int i;
-#ifdef BUFMGR_ONLY_OLD_CHIP
- debug |= AOM_DEBUG_BUFMGR_ONLY;
-#endif
- /*
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &aom_workbuff_spec[1];
- else
- p_buf_info = &aom_workbuff_spec[1];
- } else
- p_buf_info = &aom_workbuff_spec[0];
-
- init_buff_spec(NULL, p_buf_info);
- work_buf_size =
- (p_buf_info->end_adr - p_buf_info->start_adr
- + 0xffff) & (~0xffff);
- */
- for (i = 0; i < WORK_BUF_SPEC_NUM; i++)
- init_buff_spec(NULL, &aom_workbuff_spec[i]);
-
- pr_debug("amvdec_av1 module init\n");
-
- error_handle_policy = 0;
-
-#ifdef ERROR_HANDLE_DEBUG
- dbg_nal_skip_flag = 0;
- dbg_nal_skip_count = 0;
-#endif
- udebug_flag = 0;
- decode_pic_begin = 0;
- slice_parse_begin = 0;
- step = 0;
- buf_alloc_size = 0;
-
- if (platform_driver_register(&ammvdec_av1_driver)) {
- pr_err("failed to register ammvdec_av1 driver\n");
- return -ENODEV;
- }
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
- amvdec_av1_profile.profile =
- "10bit, dwrite, compressed, no_head, uvm";
- } else if (((get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2) || is_cpu_tm2_revb())
- && (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5)) {
- amvdec_av1_profile.profile =
- "8k, 10bit, dwrite, compressed, no_head, frame_dv, uvm";
- } else {
- amvdec_av1_profile.name = "av1_unsupport";
- }
-
- vcodec_profile_register(&amvdec_av1_profile);
-
- INIT_REG_NODE_CONFIGS("media.decoder", &av1_node,
- "av1-v4l", av1_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_AV1, 1);
-
- return 0;
-}
-
-static void __exit amvdec_av1_driver_remove_module(void)
-{
- pr_debug("amvdec_av1 module remove.\n");
-
- platform_driver_unregister(&ammvdec_av1_driver);
-}
-
-/****************************************/
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(force_dv_enable, uint, 0664);
-MODULE_PARM_DESC(force_dv_enable, "\n amvdec_av1 force_dv_enable\n");
-#endif
-
-module_param(bit_depth_luma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_av1 bit_depth_luma\n");
-
-module_param(bit_depth_chroma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_av1 bit_depth_chroma\n");
-
-module_param(frame_width, uint, 0664);
-MODULE_PARM_DESC(frame_width, "\n amvdec_av1 frame_width\n");
-
-module_param(frame_height, uint, 0664);
-MODULE_PARM_DESC(frame_height, "\n amvdec_av1 frame_height\n");
-
-module_param(multi_frames_in_one_pack, uint, 0664);
-MODULE_PARM_DESC(multi_frames_in_one_pack, "\n multi_frames_in_one_pack\n");
-
-module_param(debug, uint, 0664);
-MODULE_PARM_DESC(debug, "\n amvdec_av1 debug\n");
-
-module_param(disable_fg, uint, 0664);
-MODULE_PARM_DESC(disable_fg, "\n amvdec_av1 disable_fg\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\n radr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\n rval\n");
-
-module_param(pop_shorts, uint, 0664);
-MODULE_PARM_DESC(pop_shorts, "\n rval\n");
-
-module_param(dbg_cmd, uint, 0664);
-MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n");
-
-module_param(dbg_skip_decode_index, uint, 0664);
-MODULE_PARM_DESC(dbg_skip_decode_index, "\n dbg_skip_decode_index\n");
-
-module_param(endian, uint, 0664);
-MODULE_PARM_DESC(endian, "\n rval\n");
-
-module_param(disable_repeat, uint, 0664);
-MODULE_PARM_DESC(disable_repeat, "\n disable_repeat\n");
-
-module_param(step, uint, 0664);
-MODULE_PARM_DESC(step, "\n amvdec_av1 step\n");
-
-module_param(decode_pic_begin, uint, 0664);
-MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_av1 decode_pic_begin\n");
-
-module_param(slice_parse_begin, uint, 0664);
-MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_av1 slice_parse_begin\n");
-
-module_param(i_only_flag, uint, 0664);
-MODULE_PARM_DESC(i_only_flag, "\n amvdec_av1 i_only_flag\n");
-
-module_param(low_latency_flag, uint, 0664);
-MODULE_PARM_DESC(low_latency_flag, "\n amvdec_av1 low_latency_flag\n");
-
-module_param(no_head, uint, 0664);
-MODULE_PARM_DESC(no_head, "\n amvdec_av1 no_head\n");
-
-module_param(error_handle_policy, uint, 0664);
-MODULE_PARM_DESC(error_handle_policy, "\n amvdec_av1 error_handle_policy\n");
-
-module_param(buf_alloc_width, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
-
-module_param(buf_alloc_height, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
-
-module_param(buf_alloc_depth, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
-
-module_param(buf_alloc_size, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
-
-module_param(buffer_mode, uint, 0664);
-MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
-
-module_param(buffer_mode_dbg, uint, 0664);
-MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
-/*USE_BUF_BLOCK*/
-module_param(max_buf_num, uint, 0664);
-MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-module_param(mv_buf_margin, uint, 0664);
-MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n");
-
-module_param(mv_buf_dynamic_alloc, uint, 0664);
-MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
-
-module_param(force_max_one_mv_buffer_size, uint, 0664);
-MODULE_PARM_DESC(force_max_one_mv_buffer_size, "\n force_max_one_mv_buffer_size\n");
-
-module_param(run_ready_min_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
-
-/**/
-
-module_param(mem_map_mode, uint, 0664);
-MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
-
-#ifdef SUPPORT_10BIT
-module_param(double_write_mode, uint, 0664);
-MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
-
-module_param(enable_mem_saving, uint, 0664);
-MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
-
-module_param(force_w_h, uint, 0664);
-MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
-#endif
-
-module_param(force_fps, uint, 0664);
-MODULE_PARM_DESC(force_fps, "\n force_fps\n");
-
-module_param(max_decoding_time, uint, 0664);
-MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
-
-module_param(on_no_keyframe_skiped, uint, 0664);
-MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
-
-#ifdef MCRCC_ENABLE
-module_param(mcrcc_cache_alg_flag, uint, 0664);
-MODULE_PARM_DESC(mcrcc_cache_alg_flag, "\n mcrcc_cache_alg_flag\n");
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n av1 start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val,
- "\n av1 decode_timeout_val\n");
-
-module_param(av1_max_pic_w, uint, 0664);
-MODULE_PARM_DESC(av1_max_pic_w, "\n av1_max_pic_w\n");
-
-module_param(av1_max_pic_h, uint, 0664);
-MODULE_PARM_DESC(av1_max_pic_h, "\n av1_max_pic_h\n");
-
-module_param_array(decode_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(display_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(input_empty, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(not_run_ready, uint,
- &max_decode_instance_num, 0664);
-
-#ifdef AOM_AV1_MMU_DW
-module_param_array(dw_mmu_enable, uint,
- &max_decode_instance_num, 0664);
-#endif
-
-module_param(prefix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(prefix_aux_buf_size, "\n prefix_aux_buf_size\n");
-
-module_param(suffix_aux_buf_size, uint, 0664);
-MODULE_PARM_DESC(suffix_aux_buf_size, "\n suffix_aux_buf_size\n");
-
-#endif
-
-#ifdef DUMP_FILMGRAIN
-module_param(fg_dump_index, uint, 0664);
-MODULE_PARM_DESC(fg_dump_index, "\n fg_dump_index\n");
-#endif
-
-module_param(get_picture_qos, uint, 0664);
-MODULE_PARM_DESC(get_picture_qos, "\n amvdec_av1 get_picture_qos\n");
-
-module_param(force_bufspec, uint, 0664);
-MODULE_PARM_DESC(force_bufspec, "\n amvdec_h265 force_bufspec\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
-
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-module_param(dv_toggle_prov_name, uint, 0664);
-MODULE_PARM_DESC(dv_toggle_prov_name, "\n dv_toggle_prov_name\n");
-#endif
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-#ifdef DEBUG_CRC_ERROR
-module_param(crc_debug_flag, uint, 0664);
-MODULE_PARM_DESC(crc_debug_flag, "\n crc_debug_flag\n");
-#endif
-
-#ifdef DEBUG_CMD
-module_param(debug_cmd_wait_type, uint, 0664);
-MODULE_PARM_DESC(debug_cmd_wait_type, "\n debug_cmd_wait_type\n");
-
-module_param(debug_cmd_wait_count, uint, 0664);
-MODULE_PARM_DESC(debug_cmd_wait_count, "\n debug_cmd_wait_count\n");
-
-module_param(header_dump_size, uint, 0664);
-MODULE_PARM_DESC(header_dump_size, "\n header_dump_size\n");
-#endif
-
-module_param(force_pts_unstable, uint, 0664);
-MODULE_PARM_DESC(force_pts_unstable, "\n force_pts_unstable\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-
-module_param(v4l_bitstream_id_enable, uint, 0664);
-MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n");
-
-module_param(enable_single_slice, uint, 0664);
-MODULE_PARM_DESC(enable_single_slice, "\n enable_single_slice\n");
-
-module_init(amvdec_av1_driver_init_module);
-module_exit(amvdec_av1_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC av1 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/frame_provider/decoder_v4l/vav1/vav1.h b/drivers/frame_provider/decoder_v4l/vav1/vav1.h
deleted file mode 100644
index 19c715c..0000000
--- a/drivers/frame_provider/decoder_v4l/vav1/vav1.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * drivers/amlogic/amports/vav1.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef VAV1_H
-#define VAV1_H
-
-#define DEBUG_FGS_REGS (1 << 0) //0x00000001
-#define DEBUG_FGS_REGS_PARSE (1 << 1) //0x00000002
-#define DEBUG_FGS_DETAIL (1 << 2) //0x00000004
-#define DEBUG_FGS_TABLE_DUMP (1 << 3) //0x00000008
-#define DEBUG_FGS_CONSUME_TIME (1 << 4) //0x00000010
-#define DEBUG_FGS_BYPASS (1 << 5) //0x00000020
-
-int get_debug_fgs(void);
-int pic_film_grain_run(u32 frame_count, char *fg_table_addr, u32 fgs_ctrl, u32 *fgs_data);
-
-void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
-unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count);
-#endif
diff --git a/drivers/frame_provider/decoder_v4l/vp9/Makefile b/drivers/frame_provider/decoder_v4l/vp9/Makefile
deleted file mode 100644
index ebbd910..0000000
--- a/drivers/frame_provider/decoder_v4l/vp9/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_VP9) += amvdec_vp9_v4l.o
-amvdec_vp9_v4l-objs += vvp9.o
diff --git a/drivers/frame_provider/decoder_v4l/vp9/vvp9.c b/drivers/frame_provider/decoder_v4l/vp9/vvp9.c
deleted file mode 100755
index 5857c68..0000000
--- a/drivers/frame_provider/decoder_v4l/vp9/vvp9.c
+++ /dev/null
@@ -1,12449 +0,0 @@
- /*
- * drivers/amlogic/amports/vvp9.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/semaphore.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/frame_sync/ptsserv.h>
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/vfm/vframe_provider.h>
-#include <linux/amlogic/media/vfm/vframe_receiver.h>
-#include <linux/dma-mapping.h>
-#include <linux/dma-contiguous.h>
-#include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
-#include "../../../stream_input/amports/amports_priv.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../decoder/utils/decoder_mmu_box.h"
-#include "../../decoder/utils/decoder_bmmu_box.h"
-
-#define MEM_NAME "codec_vp9"
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../decoder/utils/vdec.h"
-#include "../../decoder/utils/amvdec.h"
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
-#include "../../decoder/utils/vdec_profile.h"
-#endif
-#include "../../decoder/utils/vdec_ge2d_utils.h"
-
-#include <linux/amlogic/media/video_sink/video.h>
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../../decoder/utils/config_parser.h"
-#include "../../decoder/utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../decoder/utils/vdec_v4l2_buffer_ops.h"
-#include <media/v4l2-mem2mem.h>
-#include "../../decoder/utils/vdec_feature.h"
-
-#define MIX_STREAM_SUPPORT
-
-#include "vvp9.h"
-
-/*#define SUPPORT_FB_DECODING*/
-/*#define FB_DECODING_TEST_SCHEDULE*/
-
-#define CO_MV_COMPRESS
-#define HW_MASK_FRONT 0x1
-#define HW_MASK_BACK 0x2
-
-#define VP9D_MPP_REFINFO_TBL_ACCCONFIG 0x3442
-#define VP9D_MPP_REFINFO_DATA 0x3443
-#define VP9D_MPP_REF_SCALE_ENBL 0x3441
-#define HEVC_MPRED_CTRL4 0x324c
-#define HEVC_CM_HEADER_START_ADDR 0x3628
-#define HEVC_DBLK_CFGB 0x350b
-#define HEVCD_MPP_ANC2AXI_TBL_DATA 0x3464
-#define HEVC_SAO_MMU_VH1_ADDR 0x363b
-#define HEVC_SAO_MMU_VH0_ADDR 0x363a
-
-#define HEVC_MV_INFO 0x310d
-#define HEVC_QP_INFO 0x3137
-#define HEVC_SKIP_INFO 0x3136
-
-#define VP9_10B_DEC_IDLE 0
-#define VP9_10B_DEC_FRAME_HEADER 1
-#define VP9_10B_DEC_SLICE_SEGMENT 2
-#define VP9_10B_DECODE_SLICE 5
-#define VP9_10B_DISCARD_NAL 6
-#define VP9_DUMP_LMEM 7
-#define HEVC_DECPIC_DATA_DONE 0xa
-#define HEVC_DECPIC_DATA_ERROR 0xb
-#define HEVC_NAL_DECODE_DONE 0xe
-#define HEVC_DECODE_BUFEMPTY 0x20
-#define HEVC_DECODE_TIMEOUT 0x21
-#define HEVC_SEARCH_BUFEMPTY 0x22
-#define HEVC_DECODE_OVER_SIZE 0x23
-#define HEVC_S2_DECODING_DONE 0x50
-#define VP9_HEAD_PARSER_DONE 0xf0
-#define VP9_HEAD_SEARCH_DONE 0xf1
-#define VP9_EOS 0xf2
-#define HEVC_ACTION_DONE 0xff
-
-#define VF_POOL_SIZE 32
-
-#undef pr_info
-#define pr_info printk
-
-#define DECODE_MODE_SINGLE ((0x80 << 24) | 0)
-#define DECODE_MODE_MULTI_STREAMBASE ((0x80 << 24) | 1)
-#define DECODE_MODE_MULTI_FRAMEBASE ((0x80 << 24) | 2)
-#define DECODE_MODE_SINGLE_LOW_LATENCY ((0x80 << 24) | 3)
-#define DECODE_MODE_MULTI_FRAMEBASE_NOHEAD ((0x80 << 24) | 4)
-
-#define VP9_TRIGGER_FRAME_DONE 0x100
-#define VP9_TRIGGER_FRAME_ENABLE 0x200
-
-#define MV_MEM_UNIT 0x240
-/*---------------------------------------------------
- * Include "parser_cmd.h"
- *---------------------------------------------------
- */
-#define PARSER_CMD_SKIP_CFG_0 0x0000090b
-
-#define PARSER_CMD_SKIP_CFG_1 0x1b14140f
-
-#define PARSER_CMD_SKIP_CFG_2 0x001b1910
-
-#define PARSER_CMD_NUMBER 37
-
-/*#define HEVC_PIC_STRUCT_SUPPORT*/
-/* to remove, fix build error */
-
-/*#define CODEC_MM_FLAGS_FOR_VDECODER 0*/
-
-#define MULTI_INSTANCE_SUPPORT
-#define SUPPORT_10BIT
-/* #define ERROR_HANDLE_DEBUG */
-
-#ifndef STAT_KTHREAD
-#define STAT_KTHREAD 0x40
-#endif
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define MAX_DECODE_INSTANCE_NUM 9
-#define MULTI_DRIVER_NAME "ammvdec_vp9_v4l"
-
-static unsigned int max_decode_instance_num
- = MAX_DECODE_INSTANCE_NUM;
-static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int display_frame_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int max_process_time[MAX_DECODE_INSTANCE_NUM];
-static unsigned int run_count[MAX_DECODE_INSTANCE_NUM];
-static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
-static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
-
-static u32 decode_timeout_val = 200;
-static int start_decode_buf_level = 0x8000;
-static u32 work_buf_size;
-
-static u32 force_pts_unstable;
-
-static u32 mv_buf_margin;
-
-static u32 mv_buf_dynamic_alloc;
-
-/* DOUBLE_WRITE_MODE is enabled only when NV21 8 bit output is needed */
-/* double_write_mode:
- * 0, no double write;
- * 1, 1:1 ratio;
- * 2, (1/4):(1/4) ratio;
- * 3, (1/4):(1/4) ratio, with both compressed frame included
- * 4, (1/2):(1/2) ratio;
- * 8, (1/8):(1/8) ratio;
- * 0x10, double write only
- * 0x100, if > 1080p,use mode 4,else use mode 1;
- * 0x200, if > 1080p,use mode 2,else use mode 1;
- * 0x300, if > 720p, use mode 4, else use mode 1;
- */
-static u32 double_write_mode;
-
-#define DRIVER_NAME "amvdec_vp9_v4l"
-#define DRIVER_HEADER_NAME "amvdec_vp9_header"
-
-
-#define PUT_INTERVAL (HZ/100)
-#define ERROR_SYSTEM_RESET_COUNT 200
-
-#define PTS_NORMAL 0
-#define PTS_NONE_REF_USE_DURATION 1
-
-#define PTS_MODE_SWITCHING_THRESHOLD 3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
-
-#define DUR2PTS(x) ((x)*90/96)
-
-struct VP9Decoder_s;
-static int vvp9_vf_states(struct vframe_states *states, void *);
-static struct vframe_s *vvp9_vf_peek(void *);
-static struct vframe_s *vvp9_vf_get(void *);
-static void vvp9_vf_put(struct vframe_s *, void *);
-static int vvp9_event_cb(int type, void *data, void *private_data);
-#ifdef MULTI_INSTANCE_SUPPORT
-static s32 vvp9_init(struct vdec_s *vdec);
-#else
-static s32 vvp9_init(struct VP9Decoder_s *pbi);
-#endif
-static void vvp9_prot_init(struct VP9Decoder_s *pbi, u32 mask);
-static int vvp9_local_init(struct VP9Decoder_s *pbi);
-static void vvp9_put_timer_func(struct timer_list *timer);
-static void dump_data(struct VP9Decoder_s *pbi, int size);
-static unsigned char get_data_check_sum
- (struct VP9Decoder_s *pbi, int size);
-static void dump_pic_list(struct VP9Decoder_s *pbi);
-static int vp9_alloc_mmu(
- struct VP9Decoder_s *pbi,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr);
-
-static const char vvp9_dec_id[] = "vvp9-dev";
-
-#define PROVIDER_NAME "decoder.vp9"
-#define MULTI_INSTANCE_PROVIDER_NAME "vdec.vp9"
-
-static const struct vframe_operations_s vvp9_vf_provider = {
- .peek = vvp9_vf_peek,
- .get = vvp9_vf_get,
- .put = vvp9_vf_put,
- .event_cb = vvp9_event_cb,
- .vf_states = vvp9_vf_states,
-};
-
-static struct vframe_provider_s vvp9_vf_prov;
-
-static u32 bit_depth_luma;
-static u32 bit_depth_chroma;
-static u32 frame_width;
-static u32 frame_height;
-static u32 video_signal_type;
-
-static u32 on_no_keyframe_skiped;
-
-#define PROB_SIZE (496 * 2 * 4)
-#define PROB_BUF_SIZE (0x5000)
-#define COUNT_BUF_SIZE (0x300 * 4 * 4)
-/*compute_losless_comp_body_size(4096, 2304, 1) = 18874368(0x1200000)*/
-#define MAX_FRAME_4K_NUM 0x1200
-#define MAX_FRAME_8K_NUM 0x4800
-
-#define HEVC_ASSIST_MMU_MAP_ADDR 0x3009
-
-#ifdef SUPPORT_FB_DECODING
-/* register define */
-#define HEVC_ASSIST_HED_FB_W_CTL 0x3006
-#define HEVC_ASSIST_HED_FB_R_CTL 0x3007
-#define HEVC_ASSIST_HED_FB_ADDR 0x3008
-#define HEVC_ASSIST_FB_MMU_MAP_ADDR 0x300a
-#define HEVC_ASSIST_FBD_MMU_MAP_ADDR 0x300b
-
-
-#define MAX_STAGE_PAGE_NUM 0x1200
-#define STAGE_MMU_MAP_SIZE (MAX_STAGE_PAGE_NUM * 4)
-#endif
-static inline int div_r32(int64_t m, int n)
-{
-/*
- *return (int)(m/n)
- */
-#ifndef CONFIG_ARM64
- int64_t qu = 0;
- qu = div_s64(m, n);
- return (int)qu;
-#else
- return (int)(m/n);
-#endif
-}
-
-/*USE_BUF_BLOCK*/
-struct BUF_s {
- int index;
- unsigned int alloc_flag;
- /*buffer */
- unsigned int cma_page_count;
- unsigned long alloc_addr;
- unsigned long start_adr;
- unsigned int size;
-
- unsigned int free_start_adr;
- ulong v4l_ref_buf_addr;
- ulong header_addr;
- u32 header_size;
- u32 luma_size;
- ulong chroma_addr;
- u32 chroma_size;
-} /*BUF_t */;
-
-struct MVBUF_s {
- unsigned long start_adr;
- unsigned int size;
- int used_flag;
-} /*MVBUF_t */;
-
- /* #undef BUFMGR_ONLY to enable hardware configuration */
-
-/*#define TEST_WR_PTR_INC*/
-/*#define WR_PTR_INC_NUM 128*/
-#define WR_PTR_INC_NUM 1
-
-#define SIMULATION
-#define DOS_PROJECT
-#undef MEMORY_MAP_IN_REAL_CHIP
-
-/*#undef DOS_PROJECT*/
-/*#define MEMORY_MAP_IN_REAL_CHIP*/
-
-/*#define BUFFER_MGR_ONLY*/
-/*#define CONFIG_HEVC_CLK_FORCED_ON*/
-/*#define ENABLE_SWAP_TEST*/
-#define MCRCC_ENABLE
-
-#define VP9_LPF_LVL_UPDATE
-/*#define DBG_LF_PRINT*/
-
-#ifdef VP9_10B_NV21
-#else
-#define LOSLESS_COMPRESS_MODE
-#endif
-
-#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
-#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
-
-#define VP9_DEBUG_BUFMGR 0x01
-#define VP9_DEBUG_BUFMGR_MORE 0x02
-#define VP9_DEBUG_BUFMGR_DETAIL 0x04
-#define VP9_DEBUG_OUT_PTS 0x10
-#define VP9_DEBUG_SEND_PARAM_WITH_REG 0x100
-#define VP9_DEBUG_MERGE 0x200
-#define VP9_DEBUG_DBG_LF_PRINT 0x400
-#define VP9_DEBUG_REG 0x800
-#define VP9_DEBUG_2_STAGE 0x1000
-#define VP9_DEBUG_2_STAGE_MORE 0x2000
-#define VP9_DEBUG_QOS_INFO 0x4000
-#define VP9_DEBUG_DIS_LOC_ERROR_PROC 0x10000
-#define VP9_DEBUG_DIS_SYS_ERROR_PROC 0x20000
-#define VP9_DEBUG_DUMP_PIC_LIST 0x40000
-#define VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC 0x80000
-#define VP9_DEBUG_NO_TRIGGER_FRAME 0x100000
-#define VP9_DEBUG_LOAD_UCODE_FROM_FILE 0x200000
-#define VP9_DEBUG_FORCE_SEND_AGAIN 0x400000
-#define VP9_DEBUG_DUMP_DATA 0x800000
-#define VP9_DEBUG_CACHE 0x1000000
-#define VP9_DEBUG_CACHE_HIT_RATE 0x2000000
-#define IGNORE_PARAM_FROM_CONFIG 0x8000000
-#ifdef MULTI_INSTANCE_SUPPORT
-#define PRINT_FLAG_ERROR 0x0
-#define PRINT_FLAG_V4L_DETAIL 0x10000000
-#define PRINT_FLAG_VDEC_STATUS 0x20000000
-#define PRINT_FLAG_VDEC_DETAIL 0x40000000
-#define PRINT_FLAG_VDEC_DATA 0x80000000
-#endif
-static u32 force_bufspec;
-static u32 debug;
-static bool is_reset;
-/*for debug*/
-/*
- udebug_flag:
- bit 0, enable ucode print
- bit 1, enable ucode detail print
- bit [31:16] not 0, pos to dump lmem
- bit 2, pop bits to lmem
- bit [11:8], pre-pop bits for alignment (when bit 2 is 1)
-*/
-static u32 udebug_flag;
-/*
- when udebug_flag[1:0] is not 0
- udebug_pause_pos not 0,
- pause position
-*/
-static u32 udebug_pause_pos;
-/*
- when udebug_flag[1:0] is not 0
- and udebug_pause_pos is not 0,
- pause only when DEBUG_REG2 is equal to this val
-*/
-static u32 udebug_pause_val;
-
-static u32 udebug_pause_decode_idx;
-
-static u32 disable_repeat;
-
-static u32 without_display_mode;
-
-static u32 v4l_bitstream_id_enable = 1;
-
-/*
- *[3:0] 0: default use config from omx.
- * 1: force enable fence.
- * 2: disable fence.
- *[7:4] 0: fence use for driver.
- * 1: fence fd use for app.
- */
-static u32 force_config_fence;
-
-#define DEBUG_REG
-#ifdef DEBUG_REG
-void WRITE_VREG_DBG2(unsigned int adr, unsigned int val)
-{
- if (debug & VP9_DEBUG_REG)
- pr_info("%s(%x, %x)\n", __func__, adr, val);
- if (adr != 0)
- WRITE_VREG(adr, val);
-}
-
-#undef WRITE_VREG
-#define WRITE_VREG WRITE_VREG_DBG2
-#endif
-
-#define FRAME_CNT_WINDOW_SIZE 59
-#define RATE_CORRECTION_THRESHOLD 5
-/**************************************************
-
-VP9 buffer management start
-
-***************************************************/
-#define MMU_COMPRESS_HEADER_SIZE_1080P 0x10000
-#define MMU_COMPRESS_HEADER_SIZE_4K 0x48000
-#define MMU_COMPRESS_HEADER_SIZE_8K 0x120000
-
-
-//#define MMU_COMPRESS_HEADER_SIZE 0x48000
-//#define MMU_COMPRESS_HEADER_SIZE_DW 0x48000
-//#define MMU_COMPRESS_8K_HEADER_SIZE (MMU_COMPRESS_HEADER_SIZE * 4)
-
-#define MMU_COMPRESS_HEADER_SIZE 0x48000
-#define MMU_COMPRESS_8K_HEADER_SIZE (0x48000*4)
-#define MAX_SIZE_8K (8192 * 4608)
-#define MAX_SIZE_4K (4096 * 2304)
-#define MAX_SIZE_2K (1920 * 1088)
-#define IS_8K_SIZE(w, h) (((w) * (h)) > MAX_SIZE_4K)
-#define IS_4K_SIZE(w, h) (((w) * (h)) > (1920*1088))
-
-#define INVALID_IDX -1 /* Invalid buffer index.*/
-
-#define RPM_BEGIN 0x200
-#define RPM_END 0x280
-
-union param_u {
- struct {
- unsigned short data[RPM_END - RPM_BEGIN];
- } l;
- struct {
- /* from ucode lmem, do not change this struct */
- unsigned short profile;
- unsigned short show_existing_frame;
- unsigned short frame_to_show_idx;
- unsigned short frame_type; /*1 bit*/
- unsigned short show_frame; /*1 bit*/
- unsigned short error_resilient_mode; /*1 bit*/
- unsigned short intra_only; /*1 bit*/
- unsigned short display_size_present; /*1 bit*/
- unsigned short reset_frame_context;
- unsigned short refresh_frame_flags;
- unsigned short width;
- unsigned short height;
- unsigned short display_width;
- unsigned short display_height;
- /*
- *bit[11:8] - ref_frame_info_0 (ref(3-bits), ref_frame_sign_bias(1-bit))
- *bit[7:4] - ref_frame_info_1 (ref(3-bits), ref_frame_sign_bias(1-bit))
- *bit[3:0] - ref_frame_info_2 (ref(3-bits), ref_frame_sign_bias(1-bit))
- */
- unsigned short ref_info;
- /*
- *bit[2]: same_frame_size0
- *bit[1]: same_frame_size1
- *bit[0]: same_frame_size2
- */
- unsigned short same_frame_size;
-
- unsigned short mode_ref_delta_enabled;
- unsigned short ref_deltas[4];
- unsigned short mode_deltas[2];
- unsigned short filter_level;
- unsigned short sharpness_level;
- unsigned short bit_depth;
- unsigned short seg_quant_info[8];
- unsigned short seg_enabled;
- unsigned short seg_abs_delta;
- /* bit 15: feature enabled; bit 8, sign; bit[5:0], data */
- unsigned short seg_lf_info[8];
- } p;
-};
-
-
-struct vpx_codec_frame_buffer_s {
- uint8_t *data; /**< Pointer to the data buffer */
- size_t size; /**< Size of data in bytes */
- void *priv; /**< Frame's private data */
-};
-
-enum vpx_color_space_t {
- VPX_CS_UNKNOWN = 0, /**< Unknown */
- VPX_CS_BT_601 = 1, /**< BT.601 */
- VPX_CS_BT_709 = 2, /**< BT.709 */
- VPX_CS_SMPTE_170 = 3, /**< SMPTE.170 */
- VPX_CS_SMPTE_240 = 4, /**< SMPTE.240 */
- VPX_CS_BT_2020 = 5, /**< BT.2020 */
- VPX_CS_RESERVED = 6, /**< Reserved */
- VPX_CS_SRGB = 7 /**< sRGB */
-}; /**< alias for enum vpx_color_space */
-
-enum vpx_bit_depth_t {
- VPX_BITS_8 = 8, /**< 8 bits */
- VPX_BITS_10 = 10, /**< 10 bits */
- VPX_BITS_12 = 12, /**< 12 bits */
-};
-
-#define MAX_SLICE_NUM 1024
-struct PIC_BUFFER_CONFIG_s {
- int index;
- int BUF_index;
- int mv_buf_index;
- int comp_body_size;
- int buf_size;
- int vf_ref;
- int y_canvas_index;
- int uv_canvas_index;
-#ifdef MULTI_INSTANCE_SUPPORT
- struct canvas_config_s canvas_config[2];
-#endif
- int decode_idx;
- int slice_type;
- int stream_offset;
- u32 pts;
- u64 pts64;
- u64 timestamp;
- uint8_t error_mark;
- /**/
- int slice_idx;
- /*buffer*/
- unsigned long header_adr;
- unsigned long mpred_mv_wr_start_addr;
- int mv_size;
- /*unsigned long mc_y_adr;
- *unsigned long mc_u_v_adr;
- */
- unsigned int dw_y_adr;
- unsigned int dw_u_v_adr;
- u32 luma_size;
- u32 chroma_size;
- int mc_canvas_y;
- int mc_canvas_u_v;
-
- int lcu_total;
- /**/
- int y_width;
- int y_height;
- int y_crop_width;
- int y_crop_height;
- int y_stride;
-
- int uv_width;
- int uv_height;
- int uv_crop_width;
- int uv_crop_height;
- int uv_stride;
-
- int alpha_width;
- int alpha_height;
- int alpha_stride;
-
- uint8_t *y_buffer;
- uint8_t *u_buffer;
- uint8_t *v_buffer;
- uint8_t *alpha_buffer;
-
- uint8_t *buffer_alloc;
- int buffer_alloc_sz;
- int border;
- int frame_size;
- int subsampling_x;
- int subsampling_y;
- unsigned int bit_depth;
- enum vpx_color_space_t color_space;
-
- int corrupted;
- int flags;
- unsigned long cma_alloc_addr;
-
- int double_write_mode;
-
- /* picture qos infomation*/
- int max_qp;
- int avg_qp;
- int min_qp;
- int max_skip;
- int avg_skip;
- int min_skip;
- int max_mv;
- int min_mv;
- int avg_mv;
-
- u32 hw_decode_time;
- u32 frame_size2; // For frame base mode
-
- /* vdec sync. */
- struct dma_fence *fence;
-
- /* hdr10 plus data */
- u32 hdr10p_data_size;
- char *hdr10p_data_buf;
- int v4l_buf_index;
- int repeat_count;
- struct PIC_BUFFER_CONFIG_s *repeat_pic;
-} PIC_BUFFER_CONFIG;
-
-enum BITSTREAM_PROFILE {
- PROFILE_0,
- PROFILE_1,
- PROFILE_2,
- PROFILE_3,
- MAX_PROFILES
-};
-
-enum FRAME_TYPE {
- KEY_FRAME = 0,
- INTER_FRAME = 1,
- FRAME_TYPES,
-};
-
-enum REFERENCE_MODE {
- SINGLE_REFERENCE = 0,
- COMPOUND_REFERENCE = 1,
- REFERENCE_MODE_SELECT = 2,
- REFERENCE_MODES = 3,
-};
-
-#define NONE -1
-#define INTRA_FRAME 0
-#define LAST_FRAME 1
-#define GOLDEN_FRAME 2
-#define ALTREF_FRAME 3
-#define MAX_REF_FRAMES 4
-
-#define REFS_PER_FRAME 3
-
-#define REF_FRAMES_LOG2 3
-#define REF_FRAMES (1 << REF_FRAMES_LOG2)
-#define REF_FRAMES_4K (6)
-
-/*4 scratch frames for the new frames to support a maximum of 4 cores decoding
- *in parallel, 3 for scaled references on the encoder.
- *TODO(hkuang): Add ondemand frame buffers instead of hardcoding the number
- * // of framebuffers.
- *TODO(jkoleszar): These 3 extra references could probably come from the
- *normal reference pool.
- */
-#define FRAME_BUFFERS (REF_FRAMES + 16)
-#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
-#define MAX_BUF_NUM (FRAME_BUFFERS)
-#define MV_BUFFER_NUM FRAME_BUFFERS
-#ifdef SUPPORT_FB_DECODING
-#define STAGE_MAX_BUFFERS 16
-#else
-#define STAGE_MAX_BUFFERS 0
-#endif
-
-#define FRAME_CONTEXTS_LOG2 2
-#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
-/*buffer + header buffer + workspace*/
-#ifdef MV_USE_FIXED_BUF
-#define MAX_BMMU_BUFFER_NUM (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n)
-#define WORK_SPACE_BUF_ID (FRAME_BUFFERS + HEADER_FRAME_BUFFERS)
-#else
-#define MAX_BMMU_BUFFER_NUM \
- (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM + 1)
-#define VF_BUFFER_IDX(n) (n)
-#define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n)
-#define MV_BUFFER_IDX(n) (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + n)
-#define WORK_SPACE_BUF_ID \
- (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + MV_BUFFER_NUM)
-#endif
-
-struct RefCntBuffer_s {
- int ref_count;
- /*MV_REF *mvs;*/
- int mi_rows;
- int mi_cols;
- struct vpx_codec_frame_buffer_s raw_frame_buffer;
- struct PIC_BUFFER_CONFIG_s buf;
-
-/*The Following variables will only be used in frame parallel decode.
- *
- *frame_worker_owner indicates which FrameWorker owns this buffer. NULL means
- *that no FrameWorker owns, or is decoding, this buffer.
- *VP9Worker *frame_worker_owner;
- *
- *row and col indicate which position frame has been decoded to in real
- *pixel unit. They are reset to -1 when decoding begins and set to INT_MAX
- *when the frame is fully decoded.
- */
- int row;
- int col;
-
- int show_frame;
-} RefCntBuffer;
-
-struct RefBuffer_s {
-/*TODO(dkovalev): idx is not really required and should be removed, now it
- *is used in vp9_onyxd_if.c
- */
- int idx;
- struct PIC_BUFFER_CONFIG_s *buf;
- /*struct scale_factors sf;*/
-} RefBuffer;
-
-struct InternalFrameBuffer_s {
- uint8_t *data;
- size_t size;
- int in_use;
-} InternalFrameBuffer;
-
-struct InternalFrameBufferList_s {
- int num_internal_frame_buffers;
- struct InternalFrameBuffer_s *int_fb;
-} InternalFrameBufferList;
-
-struct BufferPool_s {
-/*Protect BufferPool from being accessed by several FrameWorkers at
- *the same time during frame parallel decode.
- *TODO(hkuang): Try to use atomic variable instead of locking the whole pool.
- *
- *Private data associated with the frame buffer callbacks.
- *void *cb_priv;
- *
- *vpx_get_frame_buffer_cb_fn_t get_fb_cb;
- *vpx_release_frame_buffer_cb_fn_t release_fb_cb;
- */
-
- struct RefCntBuffer_s frame_bufs[FRAME_BUFFERS];
-
-/*Frame buffers allocated internally by the codec.*/
- struct InternalFrameBufferList_s int_frame_buffers;
- unsigned long flags;
- spinlock_t lock;
-
-} BufferPool;
-
-#define lock_buffer_pool(pool, flags) \
- spin_lock_irqsave(&pool->lock, flags)
-
-#define unlock_buffer_pool(pool, flags) \
- spin_unlock_irqrestore(&pool->lock, flags)
-
-struct VP9_Common_s {
- enum vpx_color_space_t color_space;
- int width;
- int height;
- int display_width;
- int display_height;
- int last_width;
- int last_height;
-
- int subsampling_x;
- int subsampling_y;
-
- int use_highbitdepth;/*Marks if we need to use 16bit frame buffers.*/
-
- struct PIC_BUFFER_CONFIG_s *frame_to_show;
- struct RefCntBuffer_s *prev_frame;
-
- /*TODO(hkuang): Combine this with cur_buf in macroblockd.*/
- struct RefCntBuffer_s *cur_frame;
-
- int ref_frame_map[REF_FRAMES]; /* maps fb_idx to reference slot */
-
- /*Prepare ref_frame_map for the next frame.
- *Only used in frame parallel decode.
- */
- int next_ref_frame_map[REF_FRAMES];
-
- /* TODO(jkoleszar): could expand active_ref_idx to 4,
- *with 0 as intra, and roll new_fb_idx into it.
- */
-
- /*Each frame can reference REFS_PER_FRAME buffers*/
- struct RefBuffer_s frame_refs[REFS_PER_FRAME];
-
- int prev_fb_idx;
- int new_fb_idx;
- int cur_fb_idx_mmu;
- /*last frame's frame type for motion search*/
- enum FRAME_TYPE last_frame_type;
- enum FRAME_TYPE frame_type;
-
- int show_frame;
- int last_show_frame;
- int show_existing_frame;
-
- /*Flag signaling that the frame is encoded using only INTRA modes.*/
- uint8_t intra_only;
- uint8_t last_intra_only;
-
- int allow_high_precision_mv;
-
- /*Flag signaling that the frame context should be reset to default
- *values. 0 or 1 implies don't reset, 2 reset just the context
- *specified in the frame header, 3 reset all contexts.
- */
- int reset_frame_context;
-
- /*MBs, mb_rows/cols is in 16-pixel units; mi_rows/cols is in
- * MODE_INFO (8-pixel) units.
- */
- int MBs;
- int mb_rows, mi_rows;
- int mb_cols, mi_cols;
- int mi_stride;
-
- /*Whether to use previous frame's motion vectors for prediction.*/
- int use_prev_frame_mvs;
-
- int refresh_frame_context; /* Two state 0 = NO, 1 = YES */
-
- int ref_frame_sign_bias[MAX_REF_FRAMES]; /* Two state 0, 1 */
-
- /*struct loopfilter lf;*/
- /*struct segmentation seg;*/
-
- /*TODO(hkuang):Remove this as it is the same as frame_parallel_decode*/
- /* in pbi.*/
- int frame_parallel_decode; /* frame-based threading.*/
-
- /*Context probabilities for reference frame prediction*/
- /*MV_REFERENCE_FRAME comp_fixed_ref;*/
- /*MV_REFERENCE_FRAME comp_var_ref[2];*/
- enum REFERENCE_MODE reference_mode;
-
- /*FRAME_CONTEXT *fc; */ /* this frame entropy */
- /*FRAME_CONTEXT *frame_contexts; */ /*FRAME_CONTEXTS*/
- /*unsigned int frame_context_idx; *//* Context to use/update */
- /*FRAME_COUNTS counts;*/
-
- unsigned int current_video_frame;
- enum BITSTREAM_PROFILE profile;
-
- enum vpx_bit_depth_t bit_depth;
-
- int error_resilient_mode;
- int frame_parallel_decoding_mode;
-
- int byte_alignment;
- int skip_loop_filter;
-
- /*External BufferPool passed from outside.*/
- struct BufferPool_s *buffer_pool;
-
- int above_context_alloc_cols;
-};
-
-static void set_canvas(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config);
-static int prepare_display_buf(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config);
-
-static void fill_frame_info(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *frame,
- unsigned int framesize,
- unsigned int pts);
-
-static struct PIC_BUFFER_CONFIG_s *get_frame_new_buffer(struct VP9_Common_s *cm)
-{
- return &cm->buffer_pool->frame_bufs[cm->new_fb_idx].buf;
-}
-
-static void ref_cnt_fb(struct RefCntBuffer_s *bufs, int *idx, int new_idx)
-{
- const int ref_index = *idx;
-
- if (ref_index >= 0 && bufs[ref_index].ref_count > 0) {
- bufs[ref_index].ref_count--;
- /*pr_info("[MMU DEBUG 2] dec ref_count[%d] : %d\r\n",
- * ref_index, bufs[ref_index].ref_count);
- */
- }
-
- *idx = new_idx;
-
- bufs[new_idx].ref_count++;
- /*pr_info("[MMU DEBUG 3] inc ref_count[%d] : %d\r\n",
- * new_idx, bufs[new_idx].ref_count);
- */
-}
-
-int vp9_release_frame_buffer(struct vpx_codec_frame_buffer_s *fb)
-{
- struct InternalFrameBuffer_s *const int_fb =
- (struct InternalFrameBuffer_s *)fb->priv;
- if (int_fb)
- int_fb->in_use = 0;
- return 0;
-}
-
-static int compute_losless_comp_body_size(int width, int height,
- uint8_t is_bit_depth_10);
-
-static void setup_display_size(struct VP9_Common_s *cm, union param_u *params,
- int print_header_info)
-{
- cm->display_width = cm->width;
- cm->display_height = cm->height;
- if (params->p.display_size_present) {
- if (print_header_info)
- pr_info(" * 1-bit display_size_present read : 1\n");
- cm->display_width = params->p.display_width;
- cm->display_height = params->p.display_height;
- /*vp9_read_frame_size(rb, &cm->display_width,
- * &cm->display_height);
- */
- } else {
- if (print_header_info)
- pr_info(" * 1-bit display_size_present read : 0\n");
- }
-}
-
-
-uint8_t print_header_info = 0;
-
-struct buff_s {
- u32 buf_start;
- u32 buf_size;
- u32 buf_end;
-} buff_t;
-
-struct BuffInfo_s {
- u32 max_width;
- u32 max_height;
- u32 start_adr;
- u32 end_adr;
- struct buff_s ipp;
- struct buff_s sao_abv;
- struct buff_s sao_vb;
- struct buff_s short_term_rps;
- struct buff_s vps;
- struct buff_s sps;
- struct buff_s pps;
- struct buff_s sao_up;
- struct buff_s swap_buf;
- struct buff_s swap_buf2;
- struct buff_s scalelut;
- struct buff_s dblk_para;
- struct buff_s dblk_data;
- struct buff_s seg_map;
- struct buff_s mmu_vbh;
- struct buff_s cm_header;
- struct buff_s mpred_above;
-#ifdef MV_USE_FIXED_BUF
- struct buff_s mpred_mv;
-#endif
- struct buff_s rpm;
- struct buff_s lmem;
-} BuffInfo_t;
-#ifdef MULTI_INSTANCE_SUPPORT
-#define DEC_RESULT_NONE 0
-#define DEC_RESULT_DONE 1
-#define DEC_RESULT_AGAIN 2
-#define DEC_RESULT_CONFIG_PARAM 3
-#define DEC_RESULT_ERROR 4
-#define DEC_INIT_PICLIST 5
-#define DEC_UNINIT_PICLIST 6
-#define DEC_RESULT_GET_DATA 7
-#define DEC_RESULT_GET_DATA_RETRY 8
-#define DEC_RESULT_EOS 9
-#define DEC_RESULT_FORCE_EXIT 10
-#define DEC_RESULT_NEED_MORE_BUFFER 11
-#define DEC_V4L2_CONTINUE_DECODING 18
-
-#define DEC_S1_RESULT_NONE 0
-#define DEC_S1_RESULT_DONE 1
-#define DEC_S1_RESULT_FORCE_EXIT 2
-#define DEC_S1_RESULT_TEST_TRIGGER_DONE 0xf0
-
-#ifdef FB_DECODING_TEST_SCHEDULE
-#define TEST_SET_NONE 0
-#define TEST_SET_PIC_DONE 1
-#define TEST_SET_S2_DONE 2
-#endif
-
-static void vp9_work(struct work_struct *work);
-#endif
-struct loop_filter_info_n;
-struct loopfilter;
-struct segmentation;
-
-#ifdef SUPPORT_FB_DECODING
-static void mpred_process(struct VP9Decoder_s *pbi);
-static void vp9_s1_work(struct work_struct *work);
-
-struct stage_buf_s {
- int index;
- unsigned short rpm[RPM_END - RPM_BEGIN];
-};
-
-static unsigned int not_run2_ready[MAX_DECODE_INSTANCE_NUM];
-
-static unsigned int run2_count[MAX_DECODE_INSTANCE_NUM];
-
-#ifdef FB_DECODING_TEST_SCHEDULE
-u32 stage_buf_num; /* = 16;*/
-#else
-u32 stage_buf_num;
-#endif
-#endif
-
-struct vp9_fence_vf_t {
- u32 used_size;
- struct vframe_s *fence_vf[VF_POOL_SIZE];
-};
-
-struct VP9Decoder_s {
-#ifdef MULTI_INSTANCE_SUPPORT
- unsigned char index;
-
- struct device *cma_dev;
- struct platform_device *platform_dev;
- void (*vdec_cb)(struct vdec_s *, void *);
- void *vdec_cb_arg;
- struct vframe_chunk_s *chunk;
- int dec_result;
- struct work_struct work;
- struct work_struct recycle_mmu_work;
- struct work_struct set_clk_work;
- u32 start_shift_bytes;
-
- struct BuffInfo_s work_space_buf_store;
- unsigned long buf_start;
- u32 buf_size;
- u32 cma_alloc_count;
- unsigned long cma_alloc_addr;
- uint8_t eos;
- unsigned long int start_process_time;
- unsigned last_lcu_idx;
- int decode_timeout_count;
- unsigned timeout_num;
- int save_buffer_mode;
-
- int double_write_mode;
-#endif
- long used_4k_num;
-
- unsigned char m_ins_flag;
- char *provider_name;
- union param_u param;
- int frame_count;
- int pic_count;
- u32 stat;
- struct timer_list timer;
- u32 frame_dur;
- u32 frame_ar;
- int fatal_error;
- uint8_t init_flag;
- uint8_t first_sc_checked;
- uint8_t process_busy;
-#define PROC_STATE_INIT 0
-#define PROC_STATE_DECODESLICE 1
-#define PROC_STATE_SENDAGAIN 2
- uint8_t process_state;
- u32 ucode_pause_pos;
-
- int show_frame_num;
- struct buff_s mc_buf_spec;
- struct dec_sysinfo vvp9_amstream_dec_info;
- void *rpm_addr;
- void *lmem_addr;
- dma_addr_t rpm_phy_addr;
- dma_addr_t lmem_phy_addr;
- unsigned short *lmem_ptr;
- unsigned short *debug_ptr;
-
- void *prob_buffer_addr;
- void *count_buffer_addr;
- dma_addr_t prob_buffer_phy_addr;
- dma_addr_t count_buffer_phy_addr;
-
- void *frame_mmu_map_addr;
- dma_addr_t frame_mmu_map_phy_addr;
-
- unsigned int use_cma_flag;
-
- struct BUF_s m_BUF[MAX_BUF_NUM];
- struct MVBUF_s m_mv_BUF[MV_BUFFER_NUM];
- u32 used_buf_num;
- DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE);
- DECLARE_KFIFO(pending_q, struct vframe_s *, VF_POOL_SIZE);
- struct vframe_s vfpool[VF_POOL_SIZE];
- atomic_t vf_pre_count;
- atomic_t vf_get_count;
- atomic_t vf_put_count;
- int buf_num;
- int pic_num;
- int lcu_size_log2;
- unsigned int losless_comp_body_size;
-
- u32 video_signal_type;
-
- int pts_mode;
- int last_lookup_pts;
- int last_pts;
- u64 last_lookup_pts_us64;
- u64 last_pts_us64;
- u64 shift_byte_count;
-
- u32 pts_unstable;
- u32 frame_cnt_window;
- u32 pts1, pts2;
- u32 last_duration;
- u32 duration_from_pts_done;
- bool vp9_first_pts_ready;
-
- u32 shift_byte_count_lo;
- u32 shift_byte_count_hi;
- int pts_mode_switching_count;
- int pts_mode_recovery_count;
-
- bool get_frame_dur;
- u32 saved_resolution;
-
- /**/
- struct VP9_Common_s common;
- struct RefCntBuffer_s *cur_buf;
- int refresh_frame_flags;
- uint8_t need_resync;
- uint8_t hold_ref_buf;
- uint8_t ready_for_new_data;
- struct BufferPool_s vp9_buffer_pool;
-
- struct BuffInfo_s *work_space_buf;
-
- struct buff_s *mc_buf;
-
- unsigned int frame_width;
- unsigned int frame_height;
-
- unsigned short *rpm_ptr;
- int init_pic_w;
- int init_pic_h;
- int lcu_total;
- int lcu_size;
-
- int slice_type;
-
- int skip_flag;
- int decode_idx;
- int slice_idx;
- uint8_t has_keyframe;
- uint8_t wait_buf;
- uint8_t error_flag;
-
- /* bit 0, for decoding; bit 1, for displaying */
- uint8_t ignore_bufmgr_error;
- int PB_skip_mode;
- int PB_skip_count_after_decoding;
- /*hw*/
-
- /*lf*/
- int default_filt_lvl;
- struct loop_filter_info_n *lfi;
- struct loopfilter *lf;
- struct segmentation *seg_4lf;
- /**/
- struct vdec_info *gvs;
-
- u32 pre_stream_offset;
-
- unsigned int dec_status;
- u32 last_put_idx;
- int new_frame_displayed;
- void *mmu_box;
- void *bmmu_box;
- int mmu_enable;
- struct vframe_master_display_colour_s vf_dp;
- struct firmware_s *fw;
- int max_pic_w;
- int max_pic_h;
-#ifdef SUPPORT_FB_DECODING
- int dec_s1_result;
- int s1_test_cmd;
- struct work_struct s1_work;
- int used_stage_buf_num;
- int s1_pos;
- int s2_pos;
- void *stage_mmu_map_addr;
- dma_addr_t stage_mmu_map_phy_addr;
- struct stage_buf_s *s1_buf;
- struct stage_buf_s *s2_buf;
- struct stage_buf_s *stage_bufs
- [STAGE_MAX_BUFFERS];
- unsigned char run2_busy;
-
- int s1_mv_buf_index;
- int s1_mv_buf_index_pre;
- int s1_mv_buf_index_pre_pre;
- unsigned long s1_mpred_mv_wr_start_addr;
- unsigned long s1_mpred_mv_wr_start_addr_pre;
- unsigned short s1_intra_only;
- unsigned short s1_frame_type;
- unsigned short s1_width;
- unsigned short s1_height;
- unsigned short s1_last_show_frame;
- union param_u s1_param;
- u8 back_not_run_ready;
-#endif
- int need_cache_size;
- u64 sc_start_time;
- bool postproc_done;
- int low_latency_flag;
- bool no_head;
- bool pic_list_init_done;
- bool pic_list_init_done2;
- bool is_used_v4l;
- void *v4l2_ctx;
- bool v4l_params_parsed;
- int frameinfo_enable;
- struct vframe_qos_s vframe_qos;
- u32 mem_map_mode;
- u32 dynamic_buf_num_margin;
- struct vframe_s vframe_dummy;
- u32 res_ch_flag;
- /*struct VP9Decoder_s vp9_decoder;*/
- union param_u vp9_param;
- int sidebind_type;
- int sidebind_channel_id;
- bool enable_fence;
- int fence_usage;
- u32 frame_mode_pts_save[FRAME_BUFFERS];
- u64 frame_mode_pts64_save[FRAME_BUFFERS];
- int run_ready_min_buf_num;
- int one_package_frame_cnt;
- int buffer_wrap[FRAME_BUFFERS];
- int last_width;
- int last_height;
- u32 error_frame_width;
- u32 error_frame_height;
- u32 endian;
- ulong fb_token;
- bool wait_more_buf;
- spinlock_t wait_buf_lock;
- struct vp9_fence_vf_t fence_vf_s;
- struct mutex fence_mutex;
- dma_addr_t rdma_phy_adr;
- unsigned *rdma_adr;
- struct trace_decoder_name trace;
- struct vdec_ge2d *ge2d;
-};
-
-static int vp9_print(struct VP9Decoder_s *pbi,
- int flag, const char *fmt, ...)
-{
-#define HEVC_PRINT_BUF 512
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-
- if (pbi == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
-
- va_start(args, fmt);
- if (pbi)
- len = sprintf(buf, "[%d]", pbi->index);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_debug("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static int is_oversize(int w, int h)
-{
- int max = (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)?
- MAX_SIZE_8K : MAX_SIZE_4K;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)
- max = MAX_SIZE_2K;
-
- if (w <= 0 || h <= 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-static int vvp9_mmu_compress_header_size(int w, int h)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(w, h))
- return (MMU_COMPRESS_HEADER_SIZE_8K);
- if (IS_4K_SIZE(w, h))
- return (MMU_COMPRESS_HEADER_SIZE_4K);
- return (MMU_COMPRESS_HEADER_SIZE_1080P);
-}
-
-/*#define FRAME_MMU_MAP_SIZE (MAX_FRAME_4K_NUM * 4)*/
-static int vvp9_frame_mmu_map_size(struct VP9Decoder_s *pbi)
-{
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- IS_8K_SIZE(pbi->max_pic_w, pbi->max_pic_h))
- return (MAX_FRAME_8K_NUM << 2);
-
- return (MAX_FRAME_4K_NUM << 2);
-}
-
-static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic);
-
-static void resize_context_buffers(struct VP9Decoder_s *pbi,
- struct VP9_Common_s *cm, int width, int height)
-{
- if (cm->width != width || cm->height != height) {
- /* to do ..*/
- if (pbi != NULL) {
- pbi->vp9_first_pts_ready = 0;
- pbi->duration_from_pts_done = 0;
- }
- pr_info("%s (%d,%d)=>(%d,%d)\r\n", __func__,
- cm->width, cm->height,
- width, height);
- cm->width = width;
- cm->height = height;
- }
- /*
- *if (cm->cur_frame->mvs == NULL ||
- * cm->mi_rows > cm->cur_frame->mi_rows ||
- * cm->mi_cols > cm->cur_frame->mi_cols) {
- * resize_mv_buffer(cm);
- *}
- */
-}
-
-static int valid_ref_frame_size(int ref_width, int ref_height,
- int this_width, int this_height) {
- return 2 * this_width >= ref_width &&
- 2 * this_height >= ref_height &&
- this_width <= 16 * ref_width &&
- this_height <= 16 * ref_height;
-}
-
-/*
- *static int valid_ref_frame_img_fmt(enum vpx_bit_depth_t ref_bit_depth,
- * int ref_xss, int ref_yss,
- * enum vpx_bit_depth_t this_bit_depth,
- * int this_xss, int this_yss) {
- * return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
- * ref_yss == this_yss;
- *}
- */
-
-
-static int setup_frame_size(
- struct VP9Decoder_s *pbi,
- struct VP9_Common_s *cm, union param_u *params,
- unsigned int *mmu_index_adr,
- int print_header_info) {
- int width, height;
- struct BufferPool_s * const pool = cm->buffer_pool;
- struct PIC_BUFFER_CONFIG_s *ybf;
- int ret = 0;
-
- width = params->p.width;
- height = params->p.height;
- if (is_oversize(width, height)) {
- pbi->error_frame_width = width;
- pbi->error_frame_height = height;
- vp9_print(pbi, 0, "%s, Error: Invalid frame size\n", __func__);
- return -1;
- }
- pbi->error_frame_width = 0;
- pbi->error_frame_height = 0;
-
- /*vp9_read_frame_size(rb, &width, &height);*/
- if (print_header_info)
- pr_info(" * 16-bits w read : %d (width : %d)\n", width, height);
- if (print_header_info)
- pr_info
- (" * 16-bits h read : %d (height : %d)\n", width, height);
-
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width);
-#ifdef VP9_10B_HED_FB
- WRITE_VREG(HEVC_ASSIST_PIC_SIZE_FB_READ, (height << 16) | width);
-#endif
- if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- ret = vp9_alloc_mmu(pbi,
- cm->new_fb_idx,
- params->p.width,
- params->p.height,
- params->p.bit_depth,
- mmu_index_adr);
- if (ret != 0) {
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- cm->new_fb_idx,
- ret);
- return ret;
- }
- cm->cur_fb_idx_mmu = cm->new_fb_idx;
- }
-
- resize_context_buffers(pbi, cm, width, height);
- setup_display_size(cm, params, print_header_info);
-#if 0
- lock_buffer_pool(pool);
- if (vp9_realloc_frame_buffer(
- get_frame_new_buffer(cm), cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
-#endif
- VP9_DEC_BORDER_IN_PIXELS,
- cm->byte_alignment,
- &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer,
- pool->get_fb_cb, pool->cb_priv)) {
- unlock_buffer_pool(pool);
- vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
- "Failed to allocate frame buffer");
- }
- unlock_buffer_pool(pool);
-#else
- /* porting */
- ybf = get_frame_new_buffer(cm);
- if (!ybf)
- return -1;
-
- ybf->y_crop_width = width;
- ybf->y_crop_height = height;
- ybf->bit_depth = params->p.bit_depth;
-#endif
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
- pool->frame_bufs[cm->new_fb_idx].buf.bit_depth =
- (unsigned int)cm->bit_depth;
- pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
- return ret;
-}
-
-static int setup_frame_size_with_refs(
- struct VP9Decoder_s *pbi,
- struct VP9_Common_s *cm,
- union param_u *params,
- unsigned int *mmu_index_adr,
- int print_header_info) {
-
- int width, height;
- int found = 0, i;
- int has_valid_ref_frame = 0;
- struct PIC_BUFFER_CONFIG_s *ybf;
- struct BufferPool_s * const pool = cm->buffer_pool;
- int ret = 0;
-
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- if ((params->p.same_frame_size >>
- (REFS_PER_FRAME - i - 1)) & 0x1) {
- struct PIC_BUFFER_CONFIG_s *const buf =
- cm->frame_refs[i].buf;
- /*if (print_header_info)
- * pr_info
- * ("1-bit same_frame_size[%d] read : 1\n", i);
- */
- width = buf->y_crop_width;
- height = buf->y_crop_height;
- /*if (print_header_info)
- * pr_info
- * (" - same_frame_size width : %d\n", width);
- */
- /*if (print_header_info)
- * pr_info
- * (" - same_frame_size height : %d\n", height);
- */
- found = 1;
- break;
- } else {
- /*if (print_header_info)
- * pr_info
- * ("1-bit same_frame_size[%d] read : 0\n", i);
- */
- }
- }
-
- if (!found) {
- /*vp9_read_frame_size(rb, &width, &height);*/
- width = params->p.width;
- height = params->p.height;
- /*if (print_header_info)
- * pr_info
- * (" * 16-bits w read : %d (width : %d)\n",
- * width, height);
- *if (print_header_info)
- * pr_info
- * (" * 16-bits h read : %d (height : %d)\n",
- * width, height);
- */
- }
-
- if (is_oversize(width, height)) {
- pbi->error_frame_width = width;
- pbi->error_frame_height = height;
- vp9_print(pbi, 0, "%s, Error: Invalid frame size\n", __func__);
- return -1;
- }
- pbi->error_frame_width = 0;
- pbi->error_frame_height = 0;
-
- params->p.width = width;
- params->p.height = height;
-
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE, (height << 16) | width);
- if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- /*if(cm->prev_fb_idx >= 0) release_unused_4k(cm->prev_fb_idx);
- *cm->prev_fb_idx = cm->new_fb_idx;
- */
- /* pr_info
- * ("[DEBUG DEBUG]Before alloc_mmu,
- * prev_fb_idx : %d, new_fb_idx : %d\r\n",
- * cm->prev_fb_idx, cm->new_fb_idx);
- */
- ret = vp9_alloc_mmu(pbi, cm->new_fb_idx,
- params->p.width, params->p.height,
- params->p.bit_depth, mmu_index_adr);
- if (ret != 0) {
- pr_err("can't alloc need mmu,idx %d\r\n",
- cm->new_fb_idx);
- return ret;
- }
- cm->cur_fb_idx_mmu = cm->new_fb_idx;
- }
-
- /*Check to make sure at least one of frames that this frame references
- *has valid dimensions.
- */
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- struct RefBuffer_s * const ref_frame = &cm->frame_refs[i];
-
- has_valid_ref_frame |=
- valid_ref_frame_size(ref_frame->buf->y_crop_width,
- ref_frame->buf->y_crop_height,
- width, height);
- }
- if (!has_valid_ref_frame) {
- pr_err("Error: Referenced frame has invalid size\r\n");
- return -1;
- }
-#if 0
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- struct RefBuffer_s * const ref_frame =
- &cm->frame_refs[i];
- if (!valid_ref_frame_img_fmt(
- ref_frame->buf->bit_depth,
- ref_frame->buf->subsampling_x,
- ref_frame->buf->subsampling_y,
- cm->bit_depth,
- cm->subsampling_x,
- cm->subsampling_y))
- pr_err
- ("Referenced frame incompatible color fmt\r\n");
- return -1;
- }
-#endif
- resize_context_buffers(pbi, cm, width, height);
- setup_display_size(cm, params, print_header_info);
-
-#if 0
- lock_buffer_pool(pool);
- if (vp9_realloc_frame_buffer(
- get_frame_new_buffer(cm), cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
-#endif
- VP9_DEC_BORDER_IN_PIXELS,
- cm->byte_alignment,
- &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer,
- pool->get_fb_cb,
- pool->cb_priv)) {
- unlock_buffer_pool(pool);
- vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
- "Failed to allocate frame buffer");
- }
- unlock_buffer_pool(pool);
-#else
- /* porting */
- ybf = get_frame_new_buffer(cm);
- if (!ybf)
- return -1;
-
- ybf->y_crop_width = width;
- ybf->y_crop_height = height;
- ybf->bit_depth = params->p.bit_depth;
-#endif
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
- pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
- pool->frame_bufs[cm->new_fb_idx].buf.bit_depth =
- (unsigned int)cm->bit_depth;
- pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
- return ret;
-}
-
-static inline bool close_to(int a, int b, int m)
-{
- return (abs(a - b) < m) ? true : false;
-}
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static int vp9_print_cont(struct VP9Decoder_s *pbi,
- int flag, const char *fmt, ...)
-{
- unsigned char buf[HEVC_PRINT_BUF];
- int len = 0;
-
- if (pbi == NULL ||
- (flag == 0) ||
- (debug & flag)) {
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
- pr_debug("%s", buf);
- va_end(args);
- }
- return 0;
-}
-
-static void trigger_schedule(struct VP9Decoder_s *pbi)
-{
- if (pbi->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
-
- if (ctx->param_sets_from_ucode &&
- !pbi->v4l_params_parsed)
- vdec_v4l_write_frame_sync(ctx);
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", 0);
-
- if (pbi->vdec_cb)
- pbi->vdec_cb(hw_to_vdec(pbi), pbi->vdec_cb_arg);
-}
-
-static void reset_process_time(struct VP9Decoder_s *pbi)
-{
- if (pbi->start_process_time) {
- unsigned process_time =
- 1000 * (jiffies - pbi->start_process_time) / HZ;
- pbi->start_process_time = 0;
- if (process_time > max_process_time[pbi->index])
- max_process_time[pbi->index] = process_time;
- }
-}
-
-static void start_process_time(struct VP9Decoder_s *pbi)
-{
- pbi->start_process_time = jiffies;
- pbi->decode_timeout_count = 0;
- pbi->last_lcu_idx = 0;
-}
-
-static void timeout_process(struct VP9Decoder_s *pbi)
-{
- pbi->timeout_num++;
- if (pbi->process_busy) {
- vp9_print(pbi,
- 0, "%s decoder timeout but process_busy\n", __func__);
- return;
- }
- amhevc_stop();
- vp9_print(pbi,
- 0, "%s decoder timeout\n", __func__);
-
- pbi->dec_result = DEC_RESULT_DONE;
- reset_process_time(pbi);
- vdec_schedule_work(&pbi->work);
-}
-
-static u32 get_valid_double_write_mode(struct VP9Decoder_s *pbi)
-{
- return ((double_write_mode & 0x80000000) == 0) ?
- pbi->double_write_mode :
- (double_write_mode & 0x7fffffff);
-}
-
-static int get_double_write_mode(struct VP9Decoder_s *pbi)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(pbi);
- u32 dw;
- int w, h;
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config;
-
- if (pbi->is_used_v4l) {
- unsigned int out;
-
- vdec_v4l_get_dw_mode(pbi->v4l2_ctx, &out);
- dw = out;
- return dw;
- }
-
- /* mask for supporting double write value bigger than 0x100 */
- if (valid_dw_mode & 0xffffff00) {
- if (!cm->cur_frame)
- return 1;/*no valid frame,*/
- cur_pic_config = &cm->cur_frame->buf;
- w = cur_pic_config->y_crop_width;
- h = cur_pic_config->y_crop_height;
-
- dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- break;
- }
- return dw;
- }
-
- return valid_dw_mode;
-}
-
-/* for double write buf alloc */
-static int get_double_write_mode_init(struct VP9Decoder_s *pbi)
-{
- u32 valid_dw_mode = get_valid_double_write_mode(pbi);
- u32 dw;
- int w = pbi->init_pic_w;
- int h = pbi->init_pic_h;
-
- dw = 0x1; /*1:1*/
- switch (valid_dw_mode) {
- case 0x100:
- if (w > 1920 && h > 1088)
- dw = 0x4; /*1:2*/
- break;
- case 0x200:
- if (w > 1920 && h > 1088)
- dw = 0x2; /*1:4*/
- break;
- case 0x300:
- if (w > 1280 && h > 720)
- dw = 0x4; /*1:2*/
- break;
- default:
- dw = valid_dw_mode;
- break;
- }
- return dw;
-}
-#endif
-
-//#define MAX_4K_NUM 0x1200
-
-/* return page number */
-static int vp9_mmu_page_num(struct VP9Decoder_s *pbi,
- int w, int h, int save_mode)
-{
- int picture_size;
- int cur_mmu_4k_number, max_frame_num;
-
- picture_size = compute_losless_comp_body_size(w, h, save_mode);
- cur_mmu_4k_number = ((picture_size + (PAGE_SIZE - 1)) >> PAGE_SHIFT);
-
- max_frame_num = (vvp9_frame_mmu_map_size(pbi) >> 2);
-
- if (cur_mmu_4k_number > max_frame_num) {
- pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
- cur_mmu_4k_number, w, h);
- return -1;
- }
-
- return cur_mmu_4k_number;
-}
-
-static struct internal_comp_buf* v4lfb_to_icomp_buf(
- struct VP9Decoder_s *pbi,
- struct vdec_v4l2_buffer *fb)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
-
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-static struct internal_comp_buf* index_to_icomp_buf(
- struct VP9Decoder_s *pbi, int index)
-{
- struct aml_video_dec_buf *aml_fb = NULL;
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- fb = (struct vdec_v4l2_buffer *)
- pbi->m_BUF[index].v4l_ref_buf_addr;
- aml_fb = container_of(fb, struct aml_video_dec_buf, frame_buffer);
- return &v4l2_ctx->comp_bufs[aml_fb->internal_index];
-}
-
-int vp9_alloc_mmu(
- struct VP9Decoder_s *pbi,
- int cur_buf_idx,
- int pic_width,
- int pic_height,
- unsigned short bit_depth,
- unsigned int *mmu_index_adr)
-{
- int ret;
- int bit_depth_10 = (bit_depth == VPX_BITS_10);
- int cur_mmu_4k_number;
-
- if (get_double_write_mode(pbi) == 0x10)
- return 0;
-
- if (bit_depth >= VPX_BITS_12) {
- pbi->fatal_error = DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- pr_err("fatal_error, un support bit depth 12!\n\n");
- return -1;
- }
-
- cur_mmu_4k_number = vp9_mmu_page_num(pbi,
- pic_width,
- pic_height,
- bit_depth_10);
- if (cur_mmu_4k_number < 0)
- return -1;
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- if (pbi->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, cur_buf_idx);
-
- ret = decoder_mmu_box_alloc_idx(
- ibuf->mmu_box,
- ibuf->index,
- ibuf->frame_buffer_size,
- mmu_index_adr);
- } else {
- ret = decoder_mmu_box_alloc_idx(
- pbi->mmu_box,
- cur_buf_idx,
- cur_mmu_4k_number,
- mmu_index_adr);
- }
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- return ret;
-}
-
-#ifndef MV_USE_FIXED_BUF
-static void dealloc_mv_bufs(struct VP9Decoder_s *pbi)
-{
- int i;
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (pbi->m_mv_BUF[i].start_adr) {
- if (debug)
- pr_info(
- "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
- i, pbi->m_mv_BUF[i].start_adr,
- pbi->m_mv_BUF[i].size,
- pbi->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- pbi->bmmu_box,
- MV_BUFFER_IDX(i));
- pbi->m_mv_BUF[i].start_adr = 0;
- pbi->m_mv_BUF[i].size = 0;
- pbi->m_mv_BUF[i].used_flag = 0;
- }
- }
-}
-
-static int alloc_mv_buf(struct VP9Decoder_s *pbi,
- int i, int size)
-{
- int ret = 0;
-
- if (pbi->m_mv_BUF[i].start_adr &&
- size > pbi->m_mv_BUF[i].size) {
- dealloc_mv_bufs(pbi);
- } else if (pbi->m_mv_BUF[i].start_adr)
- return 0;
-
- if (decoder_bmmu_box_alloc_buf_phy
- (pbi->bmmu_box,
- MV_BUFFER_IDX(i), size,
- DRIVER_NAME,
- &pbi->m_mv_BUF[i].start_adr) < 0) {
- pbi->m_mv_BUF[i].start_adr = 0;
- ret = -1;
- } else {
- pbi->m_mv_BUF[i].size = size;
- pbi->m_mv_BUF[i].used_flag = 0;
- ret = 0;
- if (debug) {
- pr_info(
- "MV Buffer %d: start_adr %px size %x\n",
- i,
- (void *)pbi->m_mv_BUF[i].start_adr,
- pbi->m_mv_BUF[i].size);
- }
- }
- return ret;
-}
-
-static int cal_mv_buf_size(struct VP9Decoder_s *pbi, int pic_width, int pic_height)
-{
- int lcu_size = 64; /*fixed 64*/
- int pic_width_64 = (pic_width + 63) & (~0x3f);
- int pic_height_32 = (pic_height + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1
- : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1
- : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
- int size_a = lcu_total * 36 * 16;
- int size_b = pic_width_lcu * 16 *
- ((pic_height_lcu >> 3) + (pic_height_lcu & 0x7));
- int size = (size_a + size_b + 0xffff) &
- (~0xffff);
-
- return size;
-}
-
-
-static int init_mv_buf_list(struct VP9Decoder_s *pbi)
-{
- int i;
- int ret = 0;
- int count = MV_BUFFER_NUM;
- int pic_width = pbi->init_pic_w;
- int pic_height = pbi->init_pic_h;
- int size = cal_mv_buf_size(pbi, pic_width, pic_height);
-
- if (mv_buf_dynamic_alloc)
- return 0;
-
- if (mv_buf_margin > 0)
- count = REF_FRAMES + mv_buf_margin;
-
- if (pbi->init_pic_w > 2048 && pbi->init_pic_h > 1088)
- count = REF_FRAMES_4K + mv_buf_margin;
- else
- count = REF_FRAMES + mv_buf_margin;
-
- if (debug) {
- pr_info("%s w:%d, h:%d, count: %d\n",
- __func__, pbi->init_pic_w, pbi->init_pic_h, count);
- }
-
- for (i = 0;
- i < count && i < MV_BUFFER_NUM; i++) {
- if (alloc_mv_buf(pbi, i, size) < 0) {
- ret = -1;
- break;
- }
- }
- return ret;
-}
-
-static int get_mv_buf(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- int i;
- int ret = -1;
- if (mv_buf_dynamic_alloc) {
- union param_u *params = &pbi->vp9_param;
- int size = cal_mv_buf_size(pbi,
- params->p.width, params->p.height);
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (pbi->m_mv_BUF[i].start_adr == 0) {
- ret = i;
- break;
- }
- }
- if (i == MV_BUFFER_NUM) {
- pr_info(
- "%s: Error, mv buf MV_BUFFER_NUM is not enough\n",
- __func__);
- return ret;
- }
-
- if (alloc_mv_buf(pbi, ret, size) >= 0) {
- pic_config->mv_buf_index = ret;
- pic_config->mpred_mv_wr_start_addr =
- (pbi->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- pic_config->mv_size = size;
-
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s alloc => %d (%ld) size 0x%x\n",
- __func__, ret,
- pic_config->mpred_mv_wr_start_addr,
- pic_config->mv_size);
- } else {
- pr_info(
- "%s: Error, mv buf alloc fail\n",
- __func__);
- }
- return ret;
- }
-
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (pbi->m_mv_BUF[i].start_adr &&
- pbi->m_mv_BUF[i].used_flag == 0) {
- pbi->m_mv_BUF[i].used_flag = 1;
- ret = i;
- break;
- }
- }
-
- if (ret >= 0) {
- pic_config->mv_buf_index = ret;
- pic_config->mpred_mv_wr_start_addr =
- (pbi->m_mv_BUF[ret].start_adr + 0xffff) &
- (~0xffff);
- pic_config->mv_size = pbi->m_mv_BUF[ret].size;
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s => %d (%lx) size 0x%x\n",
- __func__, ret,
- pic_config->mpred_mv_wr_start_addr,
- pic_config->mv_size);
- } else {
- pr_info(
- "%s: Error, mv buf is not enough\n",
- __func__);
- }
- return ret;
-}
-
-static void put_mv_buf(struct VP9Decoder_s *pbi,
- int *mv_buf_index)
-{
- int i = *mv_buf_index;
- if (i >= MV_BUFFER_NUM) {
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s: index %d beyond range\n",
- __func__, i);
- return;
- }
-
- if (mv_buf_dynamic_alloc) {
- if (pbi->m_mv_BUF[i].start_adr) {
- if (debug)
- pr_info(
- "dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
- i, pbi->m_mv_BUF[i].start_adr,
- pbi->m_mv_BUF[i].size,
- pbi->m_mv_BUF[i].used_flag);
- decoder_bmmu_box_free_idx(
- pbi->bmmu_box,
- MV_BUFFER_IDX(i));
- pbi->m_mv_BUF[i].start_adr = 0;
- pbi->m_mv_BUF[i].size = 0;
- pbi->m_mv_BUF[i].used_flag = 0;
- }
- *mv_buf_index = -1;
- return;
- }
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info(
- "%s(%d): used_flag(%d)\n",
- __func__, i,
- pbi->m_mv_BUF[i].used_flag);
-
- *mv_buf_index = -1;
- if (pbi->m_mv_BUF[i].start_adr &&
- pbi->m_mv_BUF[i].used_flag)
- pbi->m_mv_BUF[i].used_flag = 0;
-}
-
-static void put_un_used_mv_bufs(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((&frame_bufs[i] != cm->prev_frame) &&
- (frame_bufs[i].buf.index != -1) &&
- (frame_bufs[i].buf.mv_buf_index >= 0)
- )
- put_mv_buf(pbi, &frame_bufs[i].buf.mv_buf_index);
- }
-}
-
-#ifdef SUPPORT_FB_DECODING
-static bool mv_buf_available(struct VP9Decoder_s *pbi)
-{
- int i;
- bool ret = 0;
- for (i = 0; i < MV_BUFFER_NUM; i++) {
- if (pbi->m_mv_BUF[i].start_adr &&
- pbi->m_mv_BUF[i].used_flag == 0) {
- ret = 1;
- break;
- }
- }
- return ret;
-}
-#endif
-#endif
-
-#ifdef SUPPORT_FB_DECODING
-static void init_stage_buf(struct VP9Decoder_s *pbi)
-{
- uint i;
- for (i = 0; i < STAGE_MAX_BUFFERS
- && i < stage_buf_num; i++) {
- pbi->stage_bufs[i] =
- vmalloc(sizeof(struct stage_buf_s));
- if (pbi->stage_bufs[i] == NULL) {
- vp9_print(pbi,
- 0, "%s vmalloc fail\n", __func__);
- break;
- }
- pbi->stage_bufs[i]->index = i;
- }
- pbi->used_stage_buf_num = i;
- pbi->s1_pos = 0;
- pbi->s2_pos = 0;
- pbi->s1_buf = NULL;
- pbi->s2_buf = NULL;
- pbi->s1_mv_buf_index = FRAME_BUFFERS;
- pbi->s1_mv_buf_index_pre = FRAME_BUFFERS;
- pbi->s1_mv_buf_index_pre_pre = FRAME_BUFFERS;
-
- if (pbi->used_stage_buf_num > 0)
- vp9_print(pbi,
- 0, "%s 2 stage decoding buf %d\n",
- __func__,
- pbi->used_stage_buf_num);
-}
-
-static void uninit_stage_buf(struct VP9Decoder_s *pbi)
-{
- int i;
- for (i = 0; i < pbi->used_stage_buf_num; i++) {
- if (pbi->stage_bufs[i])
- vfree(pbi->stage_bufs[i]);
- pbi->stage_bufs[i] = NULL;
- }
- pbi->used_stage_buf_num = 0;
- pbi->s1_pos = 0;
- pbi->s2_pos = 0;
- pbi->s1_buf = NULL;
- pbi->s2_buf = NULL;
-}
-
-static int get_s1_buf(
- struct VP9Decoder_s *pbi)
-{
- struct stage_buf_s *buf = NULL;
- int ret = -1;
- int buf_page_num = MAX_STAGE_PAGE_NUM;
- int next_s1_pos = pbi->s1_pos + 1;
-
- if (next_s1_pos >= pbi->used_stage_buf_num)
- next_s1_pos = 0;
- if (next_s1_pos == pbi->s2_pos) {
- pbi->s1_buf = NULL;
- return ret;
- }
-
- buf = pbi->stage_bufs[pbi->s1_pos];
- ret = decoder_mmu_box_alloc_idx(
- pbi->mmu_box,
- buf->index,
- buf_page_num,
- pbi->stage_mmu_map_addr);
- if (ret < 0) {
- vp9_print(pbi, 0,
- "%s decoder_mmu_box_alloc fail for index %d (s1_pos %d s2_pos %d)\n",
- __func__, buf->index,
- pbi->s1_pos, pbi->s2_pos);
- buf = NULL;
- } else {
- vp9_print(pbi, VP9_DEBUG_2_STAGE,
- "%s decoder_mmu_box_alloc %d page for index %d (s1_pos %d s2_pos %d)\n",
- __func__, buf_page_num, buf->index,
- pbi->s1_pos, pbi->s2_pos);
- }
- pbi->s1_buf = buf;
- return ret;
-}
-
-static void inc_s1_pos(struct VP9Decoder_s *pbi)
-{
- struct stage_buf_s *buf =
- pbi->stage_bufs[pbi->s1_pos];
-
- int used_page_num =
-#ifdef FB_DECODING_TEST_SCHEDULE
- MAX_STAGE_PAGE_NUM/2;
-#else
- (READ_VREG(HEVC_ASSIST_HED_FB_W_CTL) >> 16);
-#endif
- decoder_mmu_box_free_idx_tail(pbi->mmu_box,
- FRAME_BUFFERS + buf->index, used_page_num);
-
- pbi->s1_pos++;
- if (pbi->s1_pos >= pbi->used_stage_buf_num)
- pbi->s1_pos = 0;
-
- vp9_print(pbi, VP9_DEBUG_2_STAGE,
- "%s (used_page_num %d) for index %d (s1_pos %d s2_pos %d)\n",
- __func__, used_page_num, buf->index,
- pbi->s1_pos, pbi->s2_pos);
-}
-
-#define s2_buf_available(pbi) (pbi->s1_pos != pbi->s2_pos)
-
-static int get_s2_buf(
- struct VP9Decoder_s *pbi)
-{
- int ret = -1;
- struct stage_buf_s *buf = NULL;
- if (s2_buf_available(pbi)) {
- buf = pbi->stage_bufs[pbi->s2_pos];
- vp9_print(pbi, VP9_DEBUG_2_STAGE,
- "%s for index %d (s1_pos %d s2_pos %d)\n",
- __func__, buf->index,
- pbi->s1_pos, pbi->s2_pos);
- pbi->s2_buf = buf;
- ret = 0;
- }
- return ret;
-}
-
-static void inc_s2_pos(struct VP9Decoder_s *pbi)
-{
- struct stage_buf_s *buf =
- pbi->stage_bufs[pbi->s2_pos];
- decoder_mmu_box_free_idx(pbi->mmu_box,
- FRAME_BUFFERS + buf->index);
- pbi->s2_pos++;
- if (pbi->s2_pos >= pbi->used_stage_buf_num)
- pbi->s2_pos = 0;
- vp9_print(pbi, VP9_DEBUG_2_STAGE,
- "%s for index %d (s1_pos %d s2_pos %d)\n",
- __func__, buf->index,
- pbi->s1_pos, pbi->s2_pos);
-}
-
-static int get_free_stage_buf_num(struct VP9Decoder_s *pbi)
-{
- int num;
- if (pbi->s1_pos >= pbi->s2_pos)
- num = pbi->used_stage_buf_num -
- (pbi->s1_pos - pbi->s2_pos) - 1;
- else
- num = (pbi->s2_pos - pbi->s1_pos) - 1;
- return num;
-}
-
-#ifndef FB_DECODING_TEST_SCHEDULE
-static DEFINE_SPINLOCK(fb_core_spin_lock);
-
-static u8 is_s2_decoding_finished(struct VP9Decoder_s *pbi)
-{
- /* to do: VLSI review
- completion of last LCU decoding in BACK
- */
- return 1;
-}
-
-static void start_s1_decoding(struct VP9Decoder_s *pbi)
-{
- /* to do: VLSI review
- after parser, how to start LCU decoding in BACK
- */
-}
-
-static void fb_reset_core(struct vdec_s *vdec, u32 mask)
-{
- /* to do: VLSI review
- 1. how to disconnect DMC for FRONT and BACK
- 2. reset bit 13, 24, FRONT or BACK ??
- */
-
- unsigned long flags;
- u32 reset_bits = 0;
- if (mask & HW_MASK_FRONT)
- WRITE_VREG(HEVC_STREAM_CONTROL, 0);
- spin_lock_irqsave(&fb_core_spin_lock, flags);
- codec_dmcbus_write(DMC_REQ_CTRL,
- codec_dmcbus_read(DMC_REQ_CTRL) & (~(1 << 4)));
- spin_unlock_irqrestore(&fb_core_spin_lock, flags);
-
- while (!(codec_dmcbus_read(DMC_CHAN_STS)
- & (1 << 4)))
- ;
-
- if ((mask & HW_MASK_FRONT) &&
- input_frame_based(vdec))
- WRITE_VREG(HEVC_STREAM_CONTROL, 0);
-
- /*
- * 2: assist
- * 3: parser
- * 4: parser_state
- * 8: dblk
- * 11:mcpu
- * 12:ccpu
- * 13:ddr
- * 14:iqit
- * 15:ipp
- * 17:qdct
- * 18:mpred
- * 19:sao
- * 24:hevc_afifo
- */
- if (mask & HW_MASK_FRONT) {
- reset_bits =
- (1<<3)|(1<<4)|(1<<11)|
- (1<<12)|(1<<18);
- }
- if (mask & HW_MASK_BACK) {
- reset_bits =
- (1<<8)|(1<<13)|(1<<14)|(1<<15)|
- (1<<17)|(1<<19)|(1<<24);
- }
- WRITE_VREG(DOS_SW_RESET3, reset_bits);
-#if 0
- (1<<3)|(1<<4)|(1<<8)|(1<<11)|
- (1<<12)|(1<<13)|(1<<14)|(1<<15)|
- (1<<17)|(1<<18)|(1<<19)|(1<<24);
-#endif
- WRITE_VREG(DOS_SW_RESET3, 0);
-
-
- spin_lock_irqsave(&fb_core_spin_lock, flags);
- codec_dmcbus_write(DMC_REQ_CTRL,
- codec_dmcbus_read(DMC_REQ_CTRL) | (1 << 4));
- spin_unlock_irqrestore(&fb_core_spin_lock, flags);
-
-}
-#endif
-
-#endif
-
-static void init_pic_list_hw(struct VP9Decoder_s *pbi);
-
-static int get_free_fb(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- int i;
- unsigned long flags;
-
- lock_buffer_pool(cm->buffer_pool, flags);
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
- for (i = 0; i < pbi->used_buf_num; ++i) {
- pr_info("%s:%d, ref_count %d vf_ref %d index %d\r\n",
- __func__, i, frame_bufs[i].ref_count,
- frame_bufs[i].buf.vf_ref,
- frame_bufs[i].buf.index);
- }
- }
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1)
- )
- break;
- }
- if (i != pbi->used_buf_num) {
- frame_bufs[i].ref_count = 1;
- /*pr_info("[MMU DEBUG 1] set ref_count[%d] : %d\r\n",
- i, frame_bufs[i].ref_count);*/
- } else {
- /* Reset i to be INVALID_IDX to indicate
- no free buffer found*/
- i = INVALID_IDX;
- }
-
- unlock_buffer_pool(cm->buffer_pool, flags);
- return i;
-}
-
-static void update_hide_frame_timestamp(struct VP9Decoder_s *pbi)
-{
- struct RefCntBuffer_s *const frame_bufs =
- pbi->common.buffer_pool->frame_bufs;
- int i;
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((!frame_bufs[i].show_frame) &&
- (!frame_bufs[i].buf.vf_ref) &&
- (frame_bufs[i].buf.BUF_index != -1)) {
- frame_bufs[i].buf.timestamp = pbi->chunk->timestamp;
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "%s, update %d hide frame ts: %lld\n",
- __func__, i, frame_bufs[i].buf.timestamp);
- }
- }
-}
-
-static int get_free_fb_idx(struct VP9Decoder_s *pbi)
-{
- int i;
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0) &&
- (cm->cur_frame != &frame_bufs[i]))
- break;
- }
-
- return i;
-}
-
-static int v4l_get_free_fb(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx * v4l = pbi->v4l2_ctx;
- struct v4l_buff_pool *pool = &v4l->cap_pool;
- struct PIC_BUFFER_CONFIG_s *pic = NULL;
- struct PIC_BUFFER_CONFIG_s *free_pic = NULL;
- ulong flags;
- int idx, i;
-
- lock_buffer_pool(cm->buffer_pool, flags);
-
- for (i = 0; i < pool->in; ++i) {
- u32 state = (pool->seq[i] >> 16);
- u32 index = (pool->seq[i] & 0xffff);
-
- switch (state) {
- case V4L_CAP_BUFF_IN_DEC:
- pic = &frame_bufs[i].buf;
- if ((frame_bufs[i].ref_count == 0) &&
- (pic->vf_ref == 0) &&
- (pic->repeat_count == 0) &&
- (pic->index != -1) &&
- pic->cma_alloc_addr &&
- (cm->cur_frame != &frame_bufs[i])) {
- free_pic = pic;
- }
- break;
- case V4L_CAP_BUFF_IN_M2M:
- idx = get_free_fb_idx(pbi);
- pic = &frame_bufs[idx].buf;
- pic->y_crop_width = pbi->frame_width;
- pic->y_crop_height = pbi->frame_height;
- pbi->buffer_wrap[idx] = index;
- if (!v4l_alloc_and_config_pic(pbi, pic)) {
- set_canvas(pbi, pic);
- init_pic_list_hw(pbi);
- free_pic = pic;
- }
- break;
- default:
- break;
- }
-
- if (free_pic) {
- frame_bufs[i].ref_count = 1;
- break;
- }
- }
-
- if (free_pic && pbi->chunk) {
- free_pic->timestamp = pbi->chunk->timestamp;
- update_hide_frame_timestamp(pbi);
- }
-
- unlock_buffer_pool(cm->buffer_pool, flags);
-
- if (free_pic) {
- struct vdec_v4l2_buffer *fb =
- (struct vdec_v4l2_buffer *)
- pbi->m_BUF[i].v4l_ref_buf_addr;
-
- fb->status = FB_ST_DECODER;
- }
-
- if (debug & VP9_DEBUG_OUT_PTS) {
- if (free_pic) {
- pr_debug("%s, idx: %d, ts: %lld\n",
- __func__, free_pic->index, free_pic->timestamp);
- } else {
- pr_debug("%s, vp9 get free pic null\n", __func__);
- dump_pic_list(pbi);
- }
- }
-
- return free_pic ? free_pic->index : INVALID_IDX;
-}
-
-static int get_free_buf_count(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- int i, free_buf_count = 0;
-
- if (pbi->is_used_v4l) {
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0) &&
- frame_bufs[i].buf.cma_alloc_addr &&
- (cm->cur_frame != &frame_bufs[i])) {
- free_buf_count++;
- }
- }
-
- if (ctx->cap_pool.dec < pbi->used_buf_num) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &pbi->fb_token)) {
- free_buf_count +=
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- /* trigger to parse head data. */
- if (!pbi->v4l_params_parsed) {
- free_buf_count = pbi->run_ready_min_buf_num;
- }
- } else {
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1))
- free_buf_count++;
- }
- }
-
- return free_buf_count;
-}
-
-static void decrease_ref_count(int idx, struct RefCntBuffer_s *const frame_bufs,
- struct BufferPool_s *const pool)
-{
- if (idx >= 0) {
- --frame_bufs[idx].ref_count;
- /*pr_info("[MMU DEBUG 7] dec ref_count[%d] : %d\r\n", idx,
- * frame_bufs[idx].ref_count);
- */
- /*A worker may only get a free framebuffer index when
- *calling get_free_fb. But the private buffer is not set up
- *until finish decoding header. So any error happens during
- *decoding header, the frame_bufs will not have valid priv
- *buffer.
- */
-
- if (frame_bufs[idx].ref_count == 0 &&
- frame_bufs[idx].raw_frame_buffer.priv)
- vp9_release_frame_buffer
- (&frame_bufs[idx].raw_frame_buffer);
- }
-}
-
-static void generate_next_ref_frames(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
- struct BufferPool_s *const pool = cm->buffer_pool;
- int mask, ref_index = 0;
- unsigned long flags;
-
- /* Generate next_ref_frame_map.*/
- lock_buffer_pool(pool, flags);
- for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
- if (mask & 1) {
- cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
- ++frame_bufs[cm->new_fb_idx].ref_count;
- /*pr_info("[MMU DEBUG 4] inc ref_count[%d] : %d\r\n",
- *cm->new_fb_idx, frame_bufs[cm->new_fb_idx].ref_count);
- */
- } else
- cm->next_ref_frame_map[ref_index] =
- cm->ref_frame_map[ref_index];
- /* Current thread holds the reference frame.*/
- if (cm->ref_frame_map[ref_index] >= 0) {
- ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
- /*pr_info
- *("[MMU DEBUG 5] inc ref_count[%d] : %d\r\n",
- *cm->ref_frame_map[ref_index],
- *frame_bufs[cm->ref_frame_map[ref_index]].ref_count);
- */
- }
- ++ref_index;
- }
-
- for (; ref_index < REF_FRAMES; ++ref_index) {
- cm->next_ref_frame_map[ref_index] =
- cm->ref_frame_map[ref_index];
- /* Current thread holds the reference frame.*/
- if (cm->ref_frame_map[ref_index] >= 0) {
- ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
- /*pr_info("[MMU DEBUG 6] inc ref_count[%d] : %d\r\n",
- *cm->ref_frame_map[ref_index],
- *frame_bufs[cm->ref_frame_map[ref_index]].ref_count);
- */
- }
- }
- unlock_buffer_pool(pool, flags);
- return;
-}
-
-static void refresh_ref_frames(struct VP9Decoder_s *pbi)
-
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct BufferPool_s *pool = cm->buffer_pool;
- struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
- int mask, ref_index = 0;
- unsigned long flags;
-
- lock_buffer_pool(pool, flags);
- for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
- const int old_idx = cm->ref_frame_map[ref_index];
- /*Current thread releases the holding of reference frame.*/
- decrease_ref_count(old_idx, frame_bufs, pool);
-
- /*Release the reference frame in reference map.*/
- if ((mask & 1) && old_idx >= 0)
- decrease_ref_count(old_idx, frame_bufs, pool);
- cm->ref_frame_map[ref_index] =
- cm->next_ref_frame_map[ref_index];
- ++ref_index;
- }
-
- /*Current thread releases the holding of reference frame.*/
- for (; ref_index < REF_FRAMES && !cm->show_existing_frame;
- ++ref_index) {
- const int old_idx = cm->ref_frame_map[ref_index];
-
- decrease_ref_count(old_idx, frame_bufs, pool);
- cm->ref_frame_map[ref_index] =
- cm->next_ref_frame_map[ref_index];
- }
- unlock_buffer_pool(pool, flags);
- return;
-}
-
-static int check_buff_has_show(struct RefCntBuffer_s *frame_buf)
-{
- int ret = 1;
-
- if (disable_repeat ||
- ((frame_buf->buf.vf_ref == 0) &&
- (frame_buf->buf.index != -1) &&
- frame_buf->buf.cma_alloc_addr)) {
- ret = 0;
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("existing buff can use\n");
- } else {
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("existing buff can't use\n");
- }
- return ret;
-}
-
-int vp9_bufmgr_process(struct VP9Decoder_s *pbi, union param_u *params)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct BufferPool_s *pool = cm->buffer_pool;
- struct RefCntBuffer_s *frame_bufs = cm->buffer_pool->frame_bufs;
- struct PIC_BUFFER_CONFIG_s *pic = NULL;
- int i;
- int ret;
-
- pbi->ready_for_new_data = 0;
-
- if ((pbi->has_keyframe == 0) &&
- (params->p.frame_type != KEY_FRAME) &&
- (!params->p.intra_only)){
- on_no_keyframe_skiped++;
- pr_info("vp9_bufmgr_process no key frame return\n");
- return -2;
- }
- pbi->has_keyframe = 1;
- on_no_keyframe_skiped = 0;
-#if 0
- if (pbi->mmu_enable) {
- if (!pbi->m_ins_flag)
- pbi->used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- if (cm->prev_fb_idx >= 0) {
- decoder_mmu_box_free_idx_tail(pbi->mmu_box,
- cm->prev_fb_idx, pbi->used_4k_num);
- }
- }
-#endif
- if (cm->new_fb_idx >= 0
- && frame_bufs[cm->new_fb_idx].ref_count == 0){
- vp9_release_frame_buffer
- (&frame_bufs[cm->new_fb_idx].raw_frame_buffer);
- }
- /*pr_info("Before get_free_fb, prev_fb_idx : %d, new_fb_idx : %d\r\n",
- cm->prev_fb_idx, cm->new_fb_idx);*/
-#ifndef MV_USE_FIXED_BUF
- put_un_used_mv_bufs(pbi);
- if (debug & VP9_DEBUG_BUFMGR_DETAIL)
- dump_pic_list(pbi);
-#endif
- cm->new_fb_idx = pbi->is_used_v4l ?
- v4l_get_free_fb(pbi) :
- get_free_fb(pbi);
- if (cm->new_fb_idx == INVALID_IDX) {
- pr_info("get_free_fb error\r\n");
- return -1;
- }
- frame_bufs[cm->new_fb_idx].buf.v4l_buf_index = cm->new_fb_idx;
-#ifndef MV_USE_FIXED_BUF
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num == 0) {
-#endif
- if (get_mv_buf(pbi,
- &pool->frame_bufs[cm->new_fb_idx].
- buf) < 0) {
- pr_info("get_mv_buf fail\r\n");
- return -1;
- }
- if (debug & VP9_DEBUG_BUFMGR_DETAIL)
- dump_pic_list(pbi);
-#ifdef SUPPORT_FB_DECODING
- }
-#endif
-#endif
- cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
- /*if (debug & VP9_DEBUG_BUFMGR)
- pr_info("[VP9 DEBUG]%s(get_free_fb): %d\r\n", __func__,
- cm->new_fb_idx);*/
-
- pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
- if (pbi->mmu_enable) {
- /* moved to after picture size ready
- *alloc_mmu(cm, params->p.width, params->p.height,
- *params->p.bit_depth, pbi->frame_mmu_map_addr);
- */
- cm->prev_fb_idx = cm->new_fb_idx;
- }
- /*read_uncompressed_header()*/
- cm->last_frame_type = cm->frame_type;
- cm->last_intra_only = cm->intra_only;
- cm->profile = params->p.profile;
- if (cm->profile >= MAX_PROFILES) {
- pr_err("Error: Unsupported profile %d\r\n", cm->profile);
- return -1;
- }
- cm->show_existing_frame = params->p.show_existing_frame;
- if (cm->show_existing_frame) {
- /* Show an existing frame directly.*/
- int frame_to_show_idx = params->p.frame_to_show_idx;
- int frame_to_show;
- unsigned long flags;
- if (frame_to_show_idx >= REF_FRAMES) {
- pr_info("frame_to_show_idx %d exceed max index\r\n",
- frame_to_show_idx);
- return -1;
- }
-
- frame_to_show = cm->ref_frame_map[frame_to_show_idx];
- /*pr_info("frame_to_show %d\r\n", frame_to_show);*/
- lock_buffer_pool(pool, flags);
- if (frame_to_show < 0 ||
- frame_bufs[frame_to_show].ref_count < 1) {
- unlock_buffer_pool(pool, flags);
- pr_err
- ("Error:Buffer %d does not contain a decoded frame",
- frame_to_show);
- return -1;
- }
-
- if (check_buff_has_show(&frame_bufs[frame_to_show])) {
- frame_bufs[frame_to_show].buf.repeat_count ++;
- frame_bufs[frame_to_show].buf.v4l_buf_index = cm->new_fb_idx;
- frame_bufs[cm->new_fb_idx].buf.repeat_pic = &frame_bufs[frame_to_show].buf;
- }
- frame_bufs[frame_to_show].buf.timestamp = frame_bufs[cm->new_fb_idx].buf.timestamp;
- ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show);
- update_hide_frame_timestamp(pbi);
- unlock_buffer_pool(pool, flags);
- pbi->refresh_frame_flags = 0;
- /*cm->lf.filter_level = 0;*/
- cm->show_frame = 1;
- cm->cur_frame->show_frame = 1;
-
- /*
- *if (pbi->frame_parallel_decode) {
- * for (i = 0; i < REF_FRAMES; ++i)
- * cm->next_ref_frame_map[i] =
- * cm->ref_frame_map[i];
- *}
- */
- /* do not decode, search next start code */
- return 1;
- }
- cm->frame_type = params->p.frame_type;
- cm->show_frame = params->p.show_frame;
- cm->bit_depth = params->p.bit_depth;
- cm->error_resilient_mode = params->p.error_resilient_mode;
- cm->cur_frame->show_frame = cm->show_frame;
-
- if (cm->frame_type == KEY_FRAME) {
- pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
-
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- cm->frame_refs[i].idx = INVALID_IDX;
- cm->frame_refs[i].buf = NULL;
- }
-
- ret = setup_frame_size(pbi,
- cm, params, pbi->frame_mmu_map_addr,
- print_header_info);
- if (ret)
- return -1;
- if (pbi->need_resync) {
- memset(&cm->ref_frame_map, -1,
- sizeof(cm->ref_frame_map));
- pbi->need_resync = 0;
- }
- } else {
- cm->intra_only = cm->show_frame ? 0 : params->p.intra_only;
- /*if (print_header_info) {
- * if (cm->show_frame)
- * pr_info
- * ("intra_only set to 0 because of show_frame\n");
- * else
- * pr_info
- * ("1-bit intra_only read: %d\n", cm->intra_only);
- *}
- */
-
-
- cm->reset_frame_context = cm->error_resilient_mode ?
- 0 : params->p.reset_frame_context;
- if (print_header_info) {
- if (cm->error_resilient_mode)
- pr_info
- ("reset to 0 error_resilient_mode\n");
- else
- pr_info
- (" * 2-bits reset_frame_context read : %d\n",
- cm->reset_frame_context);
- }
-
- if (cm->intra_only) {
- if (cm->profile > PROFILE_0) {
- /*read_bitdepth_colorspace_sampling(cm,
- * rb, print_header_info);
- */
- } else {
- /*NOTE: The intra-only frame header
- *does not include the specification
- *of either the color format or
- *color sub-sampling
- *in profile 0. VP9 specifies that the default
- *color format should be YUV 4:2:0 in this
- *case (normative).
- */
- cm->color_space = VPX_CS_BT_601;
- cm->subsampling_y = cm->subsampling_x = 1;
- cm->bit_depth = VPX_BITS_8;
- cm->use_highbitdepth = 0;
- }
-
- pbi->refresh_frame_flags =
- params->p.refresh_frame_flags;
- /*if (print_header_info)
- * pr_info("*%d-bits refresh_frame read:0x%x\n",
- * REF_FRAMES, pbi->refresh_frame_flags);
- */
- ret = setup_frame_size(pbi,
- cm,
- params,
- pbi->frame_mmu_map_addr,
- print_header_info);
- if (ret)
- return -1;
- if (pbi->need_resync) {
- memset(&cm->ref_frame_map, -1,
- sizeof(cm->ref_frame_map));
- pbi->need_resync = 0;
- }
- } else if (pbi->need_resync != 1) { /* Skip if need resync */
- pbi->refresh_frame_flags =
- params->p.refresh_frame_flags;
- if (print_header_info)
- pr_info
- ("*%d-bits refresh_frame read:0x%x\n",
- REF_FRAMES, pbi->refresh_frame_flags);
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- const int ref =
- (params->p.ref_info >>
- (((REFS_PER_FRAME-i-1)*4)+1))
- & 0x7;
- const int idx =
- cm->ref_frame_map[ref];
- struct RefBuffer_s * const ref_frame =
- &cm->frame_refs[i];
- if (print_header_info)
- pr_info("*%d-bits ref[%d]read:%d\n",
- REF_FRAMES_LOG2, i, ref);
- ref_frame->idx = idx;
- ref_frame->buf = &frame_bufs[idx].buf;
- cm->ref_frame_sign_bias[LAST_FRAME + i]
- = (params->p.ref_info >>
- ((REFS_PER_FRAME-i-1)*4)) & 0x1;
- if (print_header_info)
- pr_info("1bit ref_frame_sign_bias");
- /*pr_info
- *("%dread: %d\n",
- *LAST_FRAME+i,
- *cm->ref_frame_sign_bias
- *[LAST_FRAME + i]);
- */
- /*pr_info
- *("[VP9 DEBUG]%s(get ref):%d\r\n",
- *__func__, ref_frame->idx);
- */
-
- }
-
- ret = setup_frame_size_with_refs(
- pbi,
- cm,
- params,
- pbi->frame_mmu_map_addr,
- print_header_info);
- if (ret)
- return -1;
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- /*struct RefBuffer_s *const ref_buf =
- *&cm->frame_refs[i];
- */
- /* to do:
- *vp9_setup_scale_factors_for_frame
- */
- }
- }
- }
-
- pic = get_frame_new_buffer(cm);
- if (!pic)
- return -1;
-
- pic->bit_depth = cm->bit_depth;
- pic->color_space = cm->color_space;
- pic->slice_type = cm->frame_type;
-
- if (pbi->need_resync) {
- pr_err
- ("Error: Keyframe/intra-only frame required to reset\r\n");
- return -1;
- }
- generate_next_ref_frames(pbi);
- pbi->hold_ref_buf = 1;
-
-#if 0
- if (frame_is_intra_only(cm) || cm->error_resilient_mode)
- vp9_setup_past_independence(cm);
- setup_loopfilter(&cm->lf, rb, print_header_info);
- setup_quantization(cm, &pbi->mb, rb, print_header_info);
- setup_segmentation(&cm->seg, rb, print_header_info);
- setup_segmentation_dequant(cm, print_header_info);
-
- setup_tile_info(cm, rb, print_header_info);
- sz = vp9_rb_read_literal(rb, 16);
- if (print_header_info)
- pr_info(" * 16-bits size read : %d (0x%x)\n", sz, sz);
-
- if (sz == 0)
- vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
- "Invalid header size");
-#endif
- /*end read_uncompressed_header()*/
- cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
- cm->width == cm->last_width &&
- cm->height == cm->last_height &&
- !cm->last_intra_only &&
- cm->last_show_frame &&
- (cm->last_frame_type != KEY_FRAME);
-
- /*pr_info
- *("set use_prev_frame_mvs to %d (last_width %d last_height %d",
- *cm->use_prev_frame_mvs, cm->last_width, cm->last_height);
- *pr_info
- *(" last_intra_only %d last_show_frame %d last_frame_type %d)\n",
- *cm->last_intra_only, cm->last_show_frame, cm->last_frame_type);
- */
-
- if (pbi->enable_fence && cm->show_frame) {
- struct PIC_BUFFER_CONFIG_s *pic = &cm->cur_frame->buf;
- struct vdec_s *vdec = hw_to_vdec(pbi);
-
- /* create fence for each buffers. */
- ret = vdec_timeline_create_fence(vdec->sync);
- if (ret < 0)
- return ret;
-
- pic->fence = vdec->sync->fence;
- pic->bit_depth = cm->bit_depth;
- pic->slice_type = cm->frame_type;
- pic->stream_offset = pbi->pre_stream_offset;
-
- if (pbi->chunk) {
- pic->pts = pbi->chunk->pts;
- pic->pts64 = pbi->chunk->pts64;
- pic->timestamp = pbi->chunk->timestamp;
- }
-
- /* post video vframe. */
- prepare_display_buf(pbi, pic);
- }
-
- return 0;
-}
-
-
-void swap_frame_buffers(struct VP9Decoder_s *pbi)
-{
- int ref_index = 0;
- struct VP9_Common_s *const cm = &pbi->common;
- struct BufferPool_s *const pool = cm->buffer_pool;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- unsigned long flags;
- refresh_ref_frames(pbi);
- pbi->hold_ref_buf = 0;
- cm->frame_to_show = get_frame_new_buffer(cm);
-
- if (cm->frame_to_show) {
- /*if (!pbi->frame_parallel_decode || !cm->show_frame) {*/
- lock_buffer_pool(pool, flags);
- --frame_bufs[cm->new_fb_idx].ref_count;
- /*pr_info("[MMU DEBUG 8] dec ref_count[%d] : %d\r\n", cm->new_fb_idx,
- * frame_bufs[cm->new_fb_idx].ref_count);
- */
- unlock_buffer_pool(pool, flags);
- /*}*/
- }
-
- /*Invalidate these references until the next frame starts.*/
- for (ref_index = 0; ref_index < 3; ref_index++)
- cm->frame_refs[ref_index].idx = -1;
-}
-
-#if 0
-static void check_resync(vpx_codec_alg_priv_t *const ctx,
- const struct VP9Decoder_s *const pbi)
-{
- /* Clear resync flag if worker got a key frame or intra only frame.*/
- if (ctx->need_resync == 1 && pbi->need_resync == 0 &&
- (pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME))
- ctx->need_resync = 0;
-}
-#endif
-
-int vp9_get_raw_frame(struct VP9Decoder_s *pbi, struct PIC_BUFFER_CONFIG_s *sd)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- int ret = -1;
-
- if (pbi->ready_for_new_data == 1)
- return ret;
-
- pbi->ready_for_new_data = 1;
-
- /* no raw frame to show!!! */
- if (!cm->show_frame)
- return ret;
-
- /* may not be get buff in v4l2 */
- if (!cm->frame_to_show)
- return ret;
-
- pbi->ready_for_new_data = 1;
-
- *sd = *cm->frame_to_show;
- ret = 0;
-
- return ret;
-}
-
-int vp9_bufmgr_init(struct VP9Decoder_s *pbi, struct BuffInfo_s *buf_spec_i,
- struct buff_s *mc_buf_i) {
- struct VP9_Common_s *cm = &pbi->common;
-
- /*memset(pbi, 0, sizeof(struct VP9Decoder_s));*/
- pbi->frame_count = 0;
- pbi->pic_count = 0;
- pbi->pre_stream_offset = 0;
- cm->buffer_pool = &pbi->vp9_buffer_pool;
- spin_lock_init(&cm->buffer_pool->lock);
- cm->prev_fb_idx = INVALID_IDX;
- cm->new_fb_idx = INVALID_IDX;
- pbi->used_4k_num = -1;
- cm->cur_fb_idx_mmu = INVALID_IDX;
- pr_debug
- ("After vp9_bufmgr_init, prev_fb_idx : %d, new_fb_idx : %d\r\n",
- cm->prev_fb_idx, cm->new_fb_idx);
- pbi->need_resync = 1;
- /* Initialize the references to not point to any frame buffers.*/
- memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
- memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map));
- cm->current_video_frame = 0;
- pbi->ready_for_new_data = 1;
-
- /* private init */
- pbi->work_space_buf = buf_spec_i;
- if (!pbi->mmu_enable)
- pbi->mc_buf = mc_buf_i;
-
- pbi->rpm_addr = NULL;
- pbi->lmem_addr = NULL;
-
- pbi->use_cma_flag = 0;
- pbi->decode_idx = 0;
- pbi->slice_idx = 0;
- /*int m_uiMaxCUWidth = 1<<7;*/
- /*int m_uiMaxCUHeight = 1<<7;*/
- pbi->has_keyframe = 0;
- pbi->skip_flag = 0;
- pbi->wait_buf = 0;
- pbi->error_flag = 0;
-
- pbi->pts_mode = PTS_NORMAL;
- pbi->last_pts = 0;
- pbi->last_lookup_pts = 0;
- pbi->last_pts_us64 = 0;
- pbi->last_lookup_pts_us64 = 0;
- pbi->shift_byte_count = 0;
- pbi->shift_byte_count_lo = 0;
- pbi->shift_byte_count_hi = 0;
- pbi->pts_mode_switching_count = 0;
- pbi->pts_mode_recovery_count = 0;
-
- pbi->buf_num = 0;
- pbi->pic_num = 0;
-
- return 0;
-}
-
-int vp9_bufmgr_postproc(struct VP9Decoder_s *pbi)
-{
- struct vdec_s *vdec = hw_to_vdec(pbi);
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s sd;
-
- if (pbi->postproc_done)
- return 0;
- pbi->postproc_done = 1;
- swap_frame_buffers(pbi);
- if (!cm->show_existing_frame) {
- cm->last_show_frame = cm->show_frame;
- cm->prev_frame = cm->cur_frame;
-#if 0
- if (cm->seg.enabled && !pbi->frame_parallel_decode)
- vp9_swap_current_and_last_seg_map(cm);
-#endif
- }
- cm->last_width = cm->width;
- cm->last_height = cm->height;
- //pbi->last_width = cm->width;
- //pbi->last_height = cm->height;
-
- if (cm->show_frame)
- cm->current_video_frame++;
-
- if (vp9_get_raw_frame(pbi, &sd) == 0) {
- /*pr_info("Display frame index %d\r\n", sd.index);*/
- sd.stream_offset = pbi->pre_stream_offset;
-
- if (pbi->enable_fence) {
- int i, j, used_size, ret;
- int signed_count = 0;
- struct vframe_s *signed_fence[VF_POOL_SIZE];
- /* notify signal to wake up wq of fence. */
- vdec_timeline_increase(vdec->sync, 1);
- mutex_lock(&pbi->fence_mutex);
- used_size = pbi->fence_vf_s.used_size;
- if (used_size) {
- for (i = 0, j = 0; i < VF_POOL_SIZE && j < used_size; i++) {
- if (pbi->fence_vf_s.fence_vf[i] != NULL) {
- ret = dma_fence_get_status(pbi->fence_vf_s.fence_vf[i]->fence);
- if (ret == 1) {
- signed_fence[signed_count] = pbi->fence_vf_s.fence_vf[i];
- pbi->fence_vf_s.fence_vf[i] = NULL;
- pbi->fence_vf_s.used_size--;
- signed_count++;
- }
- j++;
- }
- }
- }
- mutex_unlock(&pbi->fence_mutex);
- if (signed_count != 0) {
- for (i = 0; i < signed_count; i++)
- vvp9_vf_put(signed_fence[i], vdec);
- }
- } else {
- prepare_display_buf(pbi, &sd);
- }
-
- pbi->pre_stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
- }
-
-/* else
- * pr_info
- * ("Not display this frame,ready_for_new_data%d show_frame%d\r\n",
- * pbi->ready_for_new_data, cm->show_frame);
- */
- return 0;
-}
-
-/**************************************************
- *
- *VP9 buffer management end
- *
- ***************************************************
- */
-
-
-#define HEVC_CM_BODY_START_ADDR 0x3626
-#define HEVC_CM_BODY_LENGTH 0x3627
-#define HEVC_CM_HEADER_LENGTH 0x3629
-#define HEVC_CM_HEADER_OFFSET 0x362b
-
-#define LOSLESS_COMPRESS_MODE
-
-/*#define DECOMP_HEADR_SURGENT*/
-#ifdef VP9_10B_NV21
-static u32 mem_map_mode = 2 /* 0:linear 1:32x32 2:64x32*/
-#else
-static u32 mem_map_mode; /* 0:linear 1:32x32 2:64x32 ; m8baby test1902 */
-#endif
-static u32 enable_mem_saving = 1;
-static u32 force_w_h;
-
-static u32 force_fps;
-
-
-const u32 vp9_version = 201602101;
-static u32 debug;
-static u32 radr;
-static u32 rval;
-static u32 pop_shorts;
-static u32 dbg_cmd;
-static u32 dbg_skip_decode_index;
-
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN ((0xff0 << 8) | 0xf)
-
-#ifdef ERROR_HANDLE_DEBUG
-static u32 dbg_nal_skip_flag;
- /* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
-static u32 dbg_nal_skip_count;
-#endif
-/*for debug*/
-static u32 decode_pic_begin;
-static uint slice_parse_begin;
-static u32 step;
-#ifdef MIX_STREAM_SUPPORT
-static u32 buf_alloc_width = 4096;
-static u32 buf_alloc_height = 2304;
-static u32 vp9_max_pic_w = 4096;
-static u32 vp9_max_pic_h = 2304;
-
-static u32 dynamic_buf_num_margin;
-#else
-static u32 buf_alloc_width;
-static u32 buf_alloc_height;
-static u32 dynamic_buf_num_margin = 7;
-#endif
-static u32 buf_alloc_depth = 10;
-static u32 buf_alloc_size;
-/*
- *bit[0]: 0,
- * bit[1]: 0, always release cma buffer when stop
- * bit[1]: 1, never release cma buffer when stop
- *bit[0]: 1, when stop, release cma buffer if blackout is 1;
- *do not release cma buffer is blackout is not 1
- *
- *bit[2]: 0, when start decoding, check current displayed buffer
- * (only for buffer decoded by vp9) if blackout is 0
- * 1, do not check current displayed buffer
- *
- *bit[3]: 1, if blackout is not 1, do not release current
- * displayed cma buffer always.
- */
-/* set to 1 for fast play;
- * set to 8 for other case of "keep last frame"
- */
-static u32 buffer_mode = 1;
-/* buffer_mode_dbg: debug only*/
-static u32 buffer_mode_dbg = 0xffff0000;
-/**/
-
-/*
- *bit 0, 1: only display I picture;
- *bit 1, 1: only decode I picture;
- */
-static u32 i_only_flag;
-
-static u32 low_latency_flag;
-
-static u32 no_head;
-
-static u32 max_decoding_time;
-/*
- *error handling
- */
-/*error_handle_policy:
- *bit 0: 0, auto skip error_skip_nal_count nals before error recovery;
- *1, skip error_skip_nal_count nals before error recovery;
- *bit 1 (valid only when bit0 == 1):
- *1, wait vps/sps/pps after error recovery;
- *bit 2 (valid only when bit0 == 0):
- *0, auto search after error recovery (vp9_recover() called);
- *1, manual search after error recovery
- *(change to auto search after get IDR: WRITE_VREG(NAL_SEARCH_CTL, 0x2))
- *
- *bit 4: 0, set error_mark after reset/recover
- * 1, do not set error_mark after reset/recover
- *bit 5: 0, check total lcu for every picture
- * 1, do not check total lcu
- *
- */
-
-static u32 error_handle_policy;
-/*static u32 parser_sei_enable = 1;*/
-#define MAX_BUF_NUM_NORMAL 15
-#define MAX_BUF_NUM_LESS 10
-static u32 max_buf_num = MAX_BUF_NUM_NORMAL;
-#define MAX_BUF_NUM_SAVE_BUF 8
-
-static u32 run_ready_min_buf_num = 2;
-
-static DEFINE_MUTEX(vvp9_mutex);
-#ifndef MULTI_INSTANCE_SUPPORT
-static struct device *cma_dev;
-#endif
-
-#define HEVC_DEC_STATUS_REG HEVC_ASSIST_SCRATCH_0
-#define HEVC_RPM_BUFFER HEVC_ASSIST_SCRATCH_1
-#define HEVC_SHORT_TERM_RPS HEVC_ASSIST_SCRATCH_2
-#define VP9_ADAPT_PROB_REG HEVC_ASSIST_SCRATCH_3
-#define VP9_MMU_MAP_BUFFER HEVC_ASSIST_SCRATCH_4
-#define HEVC_PPS_BUFFER HEVC_ASSIST_SCRATCH_5
-//#define HEVC_SAO_UP HEVC_ASSIST_SCRATCH_6
-#define HEVC_STREAM_SWAP_BUFFER HEVC_ASSIST_SCRATCH_7
-#define HEVC_STREAM_SWAP_BUFFER2 HEVC_ASSIST_SCRATCH_8
-#define VP9_PROB_SWAP_BUFFER HEVC_ASSIST_SCRATCH_9
-#define VP9_COUNT_SWAP_BUFFER HEVC_ASSIST_SCRATCH_A
-#define VP9_SEG_MAP_BUFFER HEVC_ASSIST_SCRATCH_B
-//#define HEVC_SCALELUT HEVC_ASSIST_SCRATCH_D
-#define HEVC_WAIT_FLAG HEVC_ASSIST_SCRATCH_E
-#define RPM_CMD_REG HEVC_ASSIST_SCRATCH_F
-#define LMEM_DUMP_ADR HEVC_ASSIST_SCRATCH_F
-#define HEVC_STREAM_SWAP_TEST HEVC_ASSIST_SCRATCH_L
-#ifdef MULTI_INSTANCE_SUPPORT
-#define HEVC_DECODE_COUNT HEVC_ASSIST_SCRATCH_M
-#define HEVC_DECODE_SIZE HEVC_ASSIST_SCRATCH_N
-#else
-#define HEVC_DECODE_PIC_BEGIN_REG HEVC_ASSIST_SCRATCH_M
-#define HEVC_DECODE_PIC_NUM_REG HEVC_ASSIST_SCRATCH_N
-#endif
-#define DEBUG_REG1 HEVC_ASSIST_SCRATCH_G
-#define DEBUG_REG2 HEVC_ASSIST_SCRATCH_H
-
-
-/*
- *ucode parser/search control
- *bit 0: 0, header auto parse; 1, header manual parse
- *bit 1: 0, auto skip for noneseamless stream; 1, no skip
- *bit [3:2]: valid when bit1==0;
- *0, auto skip nal before first vps/sps/pps/idr;
- *1, auto skip nal before first vps/sps/pps
- *2, auto skip nal before first vps/sps/pps,
- * and not decode until the first I slice (with slice address of 0)
- *
- *3, auto skip before first I slice (nal_type >=16 && nal_type<=21)
- *bit [15:4] nal skip count (valid when bit0 == 1 (manual mode) )
- *bit [16]: for NAL_UNIT_EOS when bit0 is 0:
- * 0, send SEARCH_DONE to arm ; 1, do not send SEARCH_DONE to arm
- *bit [17]: for NAL_SEI when bit0 is 0:
- * 0, do not parse SEI in ucode; 1, parse SEI in ucode
- *bit [31:20]: used by ucode for debug purpose
- */
-#define NAL_SEARCH_CTL HEVC_ASSIST_SCRATCH_I
- /*[31:24] chip feature
- 31: 0, use MBOX1; 1, use MBOX0
- */
-#define DECODE_MODE HEVC_ASSIST_SCRATCH_J
-#define DECODE_STOP_POS HEVC_ASSIST_SCRATCH_K
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#define RPM_BUF_SIZE (0x400 * 2)
-#else
-#define RPM_BUF_SIZE (0x80*2)
-#endif
-#define LMEM_BUF_SIZE (0x400 * 2)
-
-//#define VBH_BUF_SIZE (2 * 16 * 2304)
-//#define VBH_BUF_COUNT 4
-
- /*mmu_vbh buf is used by HEVC_SAO_MMU_VH0_ADDR, HEVC_SAO_MMU_VH1_ADDR*/
-#define VBH_BUF_SIZE_1080P 0x3000
-#define VBH_BUF_SIZE_4K 0x5000
-#define VBH_BUF_SIZE_8K 0xa000
-#define VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh.buf_size / 2)
- /*mmu_vbh_dw buf is used by HEVC_SAO_MMU_VH0_ADDR2,HEVC_SAO_MMU_VH1_ADDR2,
- HEVC_DW_VH0_ADDDR, HEVC_DW_VH1_ADDDR*/
-#define DW_VBH_BUF_SIZE_1080P (VBH_BUF_SIZE_1080P * 2)
-#define DW_VBH_BUF_SIZE_4K (VBH_BUF_SIZE_4K * 2)
-#define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
-#define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
-
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
-static struct BuffInfo_s amvvp9_workbuff_spec[WORK_BUF_SPEC_NUM] = {
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x80000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800,
- },
- .mmu_vbh = {
- .buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x40000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0x30000,
- },
- .sao_vb = {
- .buf_size = 0x30000,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0x2800,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0x8000,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x80000,
- },
- .dblk_data = {
- .buf_size = 0x80000,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800,
- },
- .mmu_vbh = {
- .buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- * //4k2k , 0x100000 per buffer
- */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096*2,
- .max_height = 2304*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0x30000*2,
- },
- .sao_vb = {
- .buf_size = 0x30000*2,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0x2800*2,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0x8000*2,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0x80000*2,
- },
- .dblk_data = {
- .buf_size = 0x80000*2,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800*4,
- },
- .mmu_vbh = {
- .buf_size = 0x5000*2, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header = {
- //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- .buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x10000*2, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x120000 * FRAME_BUFFERS * 4,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- /* 8M bytes */
- .max_width = 1920,
- .max_height = 1088,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x1e00,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 =
- * 32Kbytes (0x8000)
- */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x49000,
- },
- .dblk_data = {
- .buf_size = 0x49000,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0x3000, //0x2fd0,
- },
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_1080P, /*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x2200, //0x21c0, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {/* 1080p, 0x40000 per buffer */
- .buf_size = 0x48200 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096,
- .max_height = 2304,
- .ipp = {
- /* IPP work space calculation :
- * 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- */
- .buf_size = 0x4000,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- /* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
- * total 64x16x2 = 2048 bytes (0x800)
- */
- .buf_size = 0x800,
- },
- .vps = {
- /* VPS STORE AREA - Max 16 VPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .sps = {
- /* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
- * total 0x0800 bytes
- */
- .buf_size = 0x800,
- },
- .pps = {
- /* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
- * total 0x2000 bytes
- */
- .buf_size = 0x2000,
- },
- .sao_up = {
- /* SAO UP STORE AREA - Max 640(10240/16) LCU,
- * each has 16 bytes total 0x2800 bytes
- */
- .buf_size = 0,
- },
- .swap_buf = {
- /* 256cyclex64bit = 2K bytes 0x800
- * (only 144 cycles valid)
- */
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- /* support up to 32 SCALELUT 1024x32 = 32Kbytes
- * (0x8000)
- */
- .buf_size = 0,
- },
- .dblk_para = {
- /* DBLK -> Max 256(4096/16) LCU,
- *each para 1024bytes(total:0x40000),
- *data 1024bytes(total:0x40000)
- */
- .buf_size = 0x52800,
- },
- .dblk_data = {
- .buf_size = 0x52800,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0xd800,
- },
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_4K,/*2*16*(more than 2304)/4, 4K*/
- },
-#if 0
- .cm_header = {
- /*add one for keeper.*/
- .buf_size = MMU_COMPRESS_HEADER_SIZE *
- (FRAME_BUFFERS + 1),
- /* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
- },
-#endif
- .mpred_above = {
- .buf_size = 0x4800, /* 2 * size of hevc*/
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- /* .buf_size = 0x100000*16,
- * //4k2k , 0x100000 per buffer
- */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x145400 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- },
- {
- .max_width = 4096*2,
- .max_height = 2304*2,
- .ipp = {
- // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
- .buf_size = 0x4000*2,
- },
- .sao_abv = {
- .buf_size = 0,
- },
- .sao_vb = {
- .buf_size = 0,
- },
- .short_term_rps = {
- // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
- .buf_size = 0x800,
- },
- .vps = {
- // VPS STORE AREA - Max 16 VPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .sps = {
- // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
- .buf_size = 0x800,
- },
- .pps = {
- // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
- .buf_size = 0x2000,
- },
- .sao_up = {
- // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
- .buf_size = 0,
- },
- .swap_buf = {
- // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
- .buf_size = 0x800,
- },
- .swap_buf2 = {
- .buf_size = 0x800,
- },
- .scalelut = {
- // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
- .buf_size = 0,
- },
- .dblk_para = {
- // DBLK -> Max 256(4096/16) LCU, each para 1024bytes(total:0x40000), data 1024bytes(total:0x40000)
- .buf_size = 0xa4800,
- },
- .dblk_data = {
- .buf_size = 0xa4800,
- },
- .seg_map = {
- /*4096x2304/64/64 *24 = 0xd800 Bytes*/
- .buf_size = 0x36000,
- },
- .mmu_vbh = {
- .buf_size = VBH_BUF_SIZE_8K, //2*16*(more than 2304)/4, 4K
- },
-#if 0
- .cm_header = {
- //.buf_size = MMU_COMPRESS_HEADER_SIZE*8, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- .buf_size = MMU_COMPRESS_HEADER_SIZE*16, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
- },
-#endif
- .mpred_above = {
- .buf_size = 0x9000,
- },
-#ifdef MV_USE_FIXED_BUF
- .mpred_mv = {
- //4k2k , 0x100000 per buffer */
- /* 4096x2304 , 0x120000 per buffer */
- .buf_size = 0x514800 * FRAME_BUFFERS,
- },
-#endif
- .rpm = {
- .buf_size = RPM_BUF_SIZE,
- },
- .lmem = {
- .buf_size = 0x400 * 2,
- }
- }
-};
-
-
-/*Losless compression body buffer size 4K per 64x32 (jt)*/
-int compute_losless_comp_body_size(int width, int height,
- uint8_t is_bit_depth_10)
-{
- int width_x64;
- int height_x32;
- int bsize;
-
- width_x64 = width + 63;
- width_x64 >>= 6;
- height_x32 = height + 31;
- height_x32 >>= 5;
- bsize = (is_bit_depth_10?4096:3200)*width_x64*height_x32;
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("%s(%d,%d,%d)=>%d\n",
- __func__, width, height,
- is_bit_depth_10, bsize);
-
- return bsize;
-}
-
-/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
-static int compute_losless_comp_header_size(int width, int height)
-{
- int width_x128;
- int height_x64;
- int hsize;
-
- width_x128 = width + 127;
- width_x128 >>= 7;
- height_x64 = height + 63;
- height_x64 >>= 6;
-
- hsize = 32 * width_x128 * height_x64;
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("%s(%d,%d)=>%d\n",
- __func__, width, height,
- hsize);
-
- return hsize;
-}
-
-static void init_buff_spec(struct VP9Decoder_s *pbi,
- struct BuffInfo_s *buf_spec)
-{
- void *mem_start_virt;
-
- buf_spec->ipp.buf_start =
- WORKBUF_ALIGN(buf_spec->start_adr);
- buf_spec->sao_abv.buf_start =
- WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
- buf_spec->sao_vb.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
- buf_spec->short_term_rps.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
- buf_spec->vps.buf_start =
- WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
- buf_spec->sps.buf_start =
- WORKBUF_ALIGN(buf_spec->vps.buf_start + buf_spec->vps.buf_size);
- buf_spec->pps.buf_start =
- WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
- buf_spec->sao_up.buf_start =
- WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
- buf_spec->swap_buf.buf_start =
- WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
- buf_spec->swap_buf2.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
- buf_spec->scalelut.buf_start =
- WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
- buf_spec->dblk_para.buf_start =
- WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
- buf_spec->dblk_data.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
- buf_spec->seg_map.buf_start =
- WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
- if (pbi == NULL || pbi->mmu_enable) {
- buf_spec->mmu_vbh.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
- } else {
- buf_spec->mpred_above.buf_start =
- WORKBUF_ALIGN(buf_spec->seg_map.buf_start + buf_spec->seg_map.buf_size);
- }
-#ifdef MV_USE_FIXED_BUF
- buf_spec->mpred_mv.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
-#else
- buf_spec->rpm.buf_start =
- WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
-#endif
- buf_spec->lmem.buf_start =
- WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
- buf_spec->end_adr =
- WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
-
- if (!pbi)
- return;
-
- if (!vdec_secure(hw_to_vdec(pbi))) {
- mem_start_virt =
- codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
- if (mem_start_virt) {
- memset(mem_start_virt, 0,
- buf_spec->dblk_para.buf_size);
- codec_mm_dma_flush(mem_start_virt,
- buf_spec->dblk_para.buf_size,
- DMA_TO_DEVICE);
- } else {
- mem_start_virt = codec_mm_vmap(
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_para.buf_size);
- if (mem_start_virt) {
- memset(mem_start_virt, 0,
- buf_spec->dblk_para.buf_size);
- codec_mm_dma_flush(mem_start_virt,
- buf_spec->dblk_para.buf_size,
- DMA_TO_DEVICE);
- codec_mm_unmap_phyaddr(mem_start_virt);
- } else {
- /*not virt for tvp playing,
- may need clear on ucode.*/
- pr_err("mem_start_virt failed\n");
- }
- }
- }
-
- if (debug) {
- pr_info("%s workspace (%x %x) size = %x\n", __func__,
- buf_spec->start_adr, buf_spec->end_adr,
- buf_spec->end_adr - buf_spec->start_adr);
- }
-
- if (debug) {
- pr_info("ipp.buf_start :%x\n",
- buf_spec->ipp.buf_start);
- pr_info("sao_abv.buf_start :%x\n",
- buf_spec->sao_abv.buf_start);
- pr_info("sao_vb.buf_start :%x\n",
- buf_spec->sao_vb.buf_start);
- pr_info("short_term_rps.buf_start :%x\n",
- buf_spec->short_term_rps.buf_start);
- pr_info("vps.buf_start :%x\n",
- buf_spec->vps.buf_start);
- pr_info("sps.buf_start :%x\n",
- buf_spec->sps.buf_start);
- pr_info("pps.buf_start :%x\n",
- buf_spec->pps.buf_start);
- pr_info("sao_up.buf_start :%x\n",
- buf_spec->sao_up.buf_start);
- pr_info("swap_buf.buf_start :%x\n",
- buf_spec->swap_buf.buf_start);
- pr_info("swap_buf2.buf_start :%x\n",
- buf_spec->swap_buf2.buf_start);
- pr_info("scalelut.buf_start :%x\n",
- buf_spec->scalelut.buf_start);
- pr_info("dblk_para.buf_start :%x\n",
- buf_spec->dblk_para.buf_start);
- pr_info("dblk_data.buf_start :%x\n",
- buf_spec->dblk_data.buf_start);
- pr_info("seg_map.buf_start :%x\n",
- buf_spec->seg_map.buf_start);
- if (pbi->mmu_enable) {
- pr_info("mmu_vbh.buf_start :%x\n",
- buf_spec->mmu_vbh.buf_start);
- }
- pr_info("mpred_above.buf_start :%x\n",
- buf_spec->mpred_above.buf_start);
-#ifdef MV_USE_FIXED_BUF
- pr_info("mpred_mv.buf_start :%x\n",
- buf_spec->mpred_mv.buf_start);
-#endif
- if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
- pr_info("rpm.buf_start :%x\n",
- buf_spec->rpm.buf_start);
- }
- }
-}
-
-/* cache_util.c */
-#define THODIYIL_MCRCC_CANVAS_ALGX 4
-
-static u32 mcrcc_cache_alg_flag = THODIYIL_MCRCC_CANVAS_ALGX;
-
-static void mcrcc_perfcount_reset(void)
-{
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[cache_util.c] Entered mcrcc_perfcount_reset...\n");
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static unsigned raw_mcr_cnt_total_prev;
-static unsigned hit_mcr_0_cnt_total_prev;
-static unsigned hit_mcr_1_cnt_total_prev;
-static unsigned byp_mcr_cnt_nchcanv_total_prev;
-static unsigned byp_mcr_cnt_nchoutwin_total_prev;
-
-static void mcrcc_get_hitrate(unsigned reset_pre)
-{
- unsigned delta_hit_mcr_0_cnt;
- unsigned delta_hit_mcr_1_cnt;
- unsigned delta_raw_mcr_cnt;
- unsigned delta_mcr_cnt_nchcanv;
- unsigned delta_mcr_cnt_nchoutwin;
-
- unsigned tmp;
- unsigned raw_mcr_cnt;
- unsigned hit_mcr_cnt;
- unsigned byp_mcr_cnt_nchoutwin;
- unsigned byp_mcr_cnt_nchcanv;
- int hitrate;
- if (reset_pre) {
- raw_mcr_cnt_total_prev = 0;
- hit_mcr_0_cnt_total_prev = 0;
- hit_mcr_1_cnt_total_prev = 0;
- byp_mcr_cnt_nchcanv_total_prev = 0;
- byp_mcr_cnt_nchoutwin_total_prev = 0;
- }
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[cache_util.c] Entered mcrcc_get_hitrate...\n");
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
- byp_mcr_cnt_nchoutwin = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
- byp_mcr_cnt_nchcanv = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("raw_mcr_cnt_total: %d\n",
- raw_mcr_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("hit_mcr_cnt_total: %d\n",
- hit_mcr_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("byp_mcr_cnt_nchoutwin_total: %d\n",
- byp_mcr_cnt_nchoutwin);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("byp_mcr_cnt_nchcanv_total: %d\n",
- byp_mcr_cnt_nchcanv);
-
- delta_raw_mcr_cnt = raw_mcr_cnt -
- raw_mcr_cnt_total_prev;
- delta_mcr_cnt_nchcanv = byp_mcr_cnt_nchcanv -
- byp_mcr_cnt_nchcanv_total_prev;
- delta_mcr_cnt_nchoutwin = byp_mcr_cnt_nchoutwin -
- byp_mcr_cnt_nchoutwin_total_prev;
- raw_mcr_cnt_total_prev = raw_mcr_cnt;
- byp_mcr_cnt_nchcanv_total_prev = byp_mcr_cnt_nchcanv;
- byp_mcr_cnt_nchoutwin_total_prev = byp_mcr_cnt_nchoutwin;
-
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("miss_mcr_0_cnt_total: %d\n", tmp);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("miss_mcr_1_cnt_total: %d\n", tmp);
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("hit_mcr_0_cnt_total: %d\n", tmp);
- delta_hit_mcr_0_cnt = tmp - hit_mcr_0_cnt_total_prev;
- hit_mcr_0_cnt_total_prev = tmp;
- WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
- tmp = READ_VREG(HEVCD_MCRCC_PERFMON_DATA);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("hit_mcr_1_cnt_total: %d\n", tmp);
- delta_hit_mcr_1_cnt = tmp - hit_mcr_1_cnt_total_prev;
- hit_mcr_1_cnt_total_prev = tmp;
-
- if (delta_raw_mcr_cnt != 0) {
- hitrate = 100 * delta_hit_mcr_0_cnt
- / delta_raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("CANV0_HIT_RATE : %d\n", hitrate);
- hitrate = 100 * delta_hit_mcr_1_cnt
- / delta_raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("CANV1_HIT_RATE : %d\n", hitrate);
- hitrate = 100 * delta_mcr_cnt_nchcanv
- / delta_raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("NONCACH_CANV_BYP_RATE : %d\n", hitrate);
- hitrate = 100 * delta_mcr_cnt_nchoutwin
- / delta_raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
- }
-
-
- if (raw_mcr_cnt != 0) {
- hitrate = 100 * hit_mcr_cnt / raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("MCRCC_HIT_RATE : %d\n", hitrate);
- hitrate = 100 * (byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv)
- / raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("MCRCC_BYP_RATE : %d\n", hitrate);
- } else {
- if (debug & VP9_DEBUG_CACHE)
- pr_info("MCRCC_HIT_RATE : na\n");
- if (debug & VP9_DEBUG_CACHE)
- pr_info("MCRCC_BYP_RATE : na\n");
- }
- return;
-}
-
-
-static void decomp_perfcount_reset(void)
-{
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[cache_util.c] Entered decomp_perfcount_reset...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
- return;
-}
-
-static void decomp_get_hitrate(void)
-{
- unsigned raw_mcr_cnt;
- unsigned hit_mcr_cnt;
- int hitrate;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_hitrate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("hcache_raw_cnt_total: %d\n", raw_mcr_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("hcache_hit_cnt_total: %d\n", hit_mcr_cnt);
-
- if (raw_mcr_cnt != 0) {
- hitrate = hit_mcr_cnt * 100 / raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
- } else {
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_HCACHE_HIT_RATE : na\n");
- }
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
- raw_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
- hit_mcr_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("dcache_raw_cnt_total: %d\n", raw_mcr_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("dcache_hit_cnt_total: %d\n", hit_mcr_cnt);
-
- if (raw_mcr_cnt != 0) {
- hitrate = hit_mcr_cnt * 100 / raw_mcr_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
- } else {
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_DCACHE_HIT_RATE : na\n");
- }
- return;
-}
-
-static void decomp_get_comprate(void)
-{
- unsigned raw_ucomp_cnt;
- unsigned fast_comp_cnt;
- unsigned slow_comp_cnt;
- int comprate;
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[cache_util.c] Entered decomp_get_comprate...\n");
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
- fast_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
- slow_comp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
- WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
- raw_ucomp_cnt = READ_VREG(HEVCD_MPP_DECOMP_PERFMON_DATA);
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("decomp_fast_comp_total: %d\n", fast_comp_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("decomp_slow_comp_total: %d\n", slow_comp_cnt);
- if (debug & VP9_DEBUG_CACHE)
- pr_info("decomp_raw_uncomp_total: %d\n", raw_ucomp_cnt);
-
- if (raw_ucomp_cnt != 0) {
- comprate = (fast_comp_cnt + slow_comp_cnt)
- * 100 / raw_ucomp_cnt;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_COMP_RATIO : %d\n", comprate);
- } else {
- if (debug & VP9_DEBUG_CACHE)
- pr_info("DECOMP_COMP_RATIO : na\n");
- }
- return;
-}
-/* cache_util.c end */
-
-/*====================================================
- *========================================================================
- *vp9_prob define
- *========================================================================
- */
-#define VP9_PARTITION_START 0
-#define VP9_PARTITION_SIZE_STEP (3 * 4)
-#define VP9_PARTITION_ONE_SIZE (4 * VP9_PARTITION_SIZE_STEP)
-#define VP9_PARTITION_KEY_START 0
-#define VP9_PARTITION_P_START VP9_PARTITION_ONE_SIZE
-#define VP9_PARTITION_SIZE (2 * VP9_PARTITION_ONE_SIZE)
-#define VP9_SKIP_START (VP9_PARTITION_START + VP9_PARTITION_SIZE)
-#define VP9_SKIP_SIZE 4 /* only use 3*/
-#define VP9_TX_MODE_START (VP9_SKIP_START+VP9_SKIP_SIZE)
-#define VP9_TX_MODE_8_0_OFFSET 0
-#define VP9_TX_MODE_8_1_OFFSET 1
-#define VP9_TX_MODE_16_0_OFFSET 2
-#define VP9_TX_MODE_16_1_OFFSET 4
-#define VP9_TX_MODE_32_0_OFFSET 6
-#define VP9_TX_MODE_32_1_OFFSET 9
-#define VP9_TX_MODE_SIZE 12
-#define VP9_COEF_START (VP9_TX_MODE_START+VP9_TX_MODE_SIZE)
-#define VP9_COEF_BAND_0_OFFSET 0
-#define VP9_COEF_BAND_1_OFFSET (VP9_COEF_BAND_0_OFFSET + 3 * 3 + 1)
-#define VP9_COEF_BAND_2_OFFSET (VP9_COEF_BAND_1_OFFSET + 6 * 3)
-#define VP9_COEF_BAND_3_OFFSET (VP9_COEF_BAND_2_OFFSET + 6 * 3)
-#define VP9_COEF_BAND_4_OFFSET (VP9_COEF_BAND_3_OFFSET + 6 * 3)
-#define VP9_COEF_BAND_5_OFFSET (VP9_COEF_BAND_4_OFFSET + 6 * 3)
-#define VP9_COEF_SIZE_ONE_SET 100 /* ((3 +5*6)*3 + 1 padding)*/
-#define VP9_COEF_4X4_START (VP9_COEF_START + 0 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_COEF_8X8_START (VP9_COEF_START + 4 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_COEF_16X16_START (VP9_COEF_START + 8 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_COEF_32X32_START (VP9_COEF_START + 12 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_COEF_SIZE_PLANE (2 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_COEF_SIZE (4 * 2 * 2 * VP9_COEF_SIZE_ONE_SET)
-#define VP9_INTER_MODE_START (VP9_COEF_START+VP9_COEF_SIZE)
-#define VP9_INTER_MODE_SIZE 24 /* only use 21 ( #*7)*/
-#define VP9_INTERP_START (VP9_INTER_MODE_START+VP9_INTER_MODE_SIZE)
-#define VP9_INTERP_SIZE 8
-#define VP9_INTRA_INTER_START (VP9_INTERP_START+VP9_INTERP_SIZE)
-#define VP9_INTRA_INTER_SIZE 4
-#define VP9_INTERP_INTRA_INTER_START VP9_INTERP_START
-#define VP9_INTERP_INTRA_INTER_SIZE (VP9_INTERP_SIZE + VP9_INTRA_INTER_SIZE)
-#define VP9_COMP_INTER_START \
- (VP9_INTERP_INTRA_INTER_START+VP9_INTERP_INTRA_INTER_SIZE)
-#define VP9_COMP_INTER_SIZE 5
-#define VP9_COMP_REF_START (VP9_COMP_INTER_START+VP9_COMP_INTER_SIZE)
-#define VP9_COMP_REF_SIZE 5
-#define VP9_SINGLE_REF_START (VP9_COMP_REF_START+VP9_COMP_REF_SIZE)
-#define VP9_SINGLE_REF_SIZE 10
-#define VP9_REF_MODE_START VP9_COMP_INTER_START
-#define VP9_REF_MODE_SIZE \
- (VP9_COMP_INTER_SIZE+VP9_COMP_REF_SIZE+VP9_SINGLE_REF_SIZE)
-#define VP9_IF_Y_MODE_START (VP9_REF_MODE_START+VP9_REF_MODE_SIZE)
-#define VP9_IF_Y_MODE_SIZE 36
-#define VP9_IF_UV_MODE_START (VP9_IF_Y_MODE_START+VP9_IF_Y_MODE_SIZE)
-#define VP9_IF_UV_MODE_SIZE 92 /* only use 90*/
-#define VP9_MV_JOINTS_START (VP9_IF_UV_MODE_START+VP9_IF_UV_MODE_SIZE)
-#define VP9_MV_JOINTS_SIZE 3
-#define VP9_MV_SIGN_0_START (VP9_MV_JOINTS_START+VP9_MV_JOINTS_SIZE)
-#define VP9_MV_SIGN_0_SIZE 1
-#define VP9_MV_CLASSES_0_START (VP9_MV_SIGN_0_START+VP9_MV_SIGN_0_SIZE)
-#define VP9_MV_CLASSES_0_SIZE 10
-#define VP9_MV_CLASS0_0_START (VP9_MV_CLASSES_0_START+VP9_MV_CLASSES_0_SIZE)
-#define VP9_MV_CLASS0_0_SIZE 1
-#define VP9_MV_BITS_0_START (VP9_MV_CLASS0_0_START+VP9_MV_CLASS0_0_SIZE)
-#define VP9_MV_BITS_0_SIZE 10
-#define VP9_MV_SIGN_1_START (VP9_MV_BITS_0_START+VP9_MV_BITS_0_SIZE)
-#define VP9_MV_SIGN_1_SIZE 1
-#define VP9_MV_CLASSES_1_START \
- (VP9_MV_SIGN_1_START+VP9_MV_SIGN_1_SIZE)
-#define VP9_MV_CLASSES_1_SIZE 10
-#define VP9_MV_CLASS0_1_START \
- (VP9_MV_CLASSES_1_START+VP9_MV_CLASSES_1_SIZE)
-#define VP9_MV_CLASS0_1_SIZE 1
-#define VP9_MV_BITS_1_START \
- (VP9_MV_CLASS0_1_START+VP9_MV_CLASS0_1_SIZE)
-#define VP9_MV_BITS_1_SIZE 10
-#define VP9_MV_CLASS0_FP_0_START \
- (VP9_MV_BITS_1_START+VP9_MV_BITS_1_SIZE)
-#define VP9_MV_CLASS0_FP_0_SIZE 9
-#define VP9_MV_CLASS0_FP_1_START \
- (VP9_MV_CLASS0_FP_0_START+VP9_MV_CLASS0_FP_0_SIZE)
-#define VP9_MV_CLASS0_FP_1_SIZE 9
-#define VP9_MV_CLASS0_HP_0_START \
- (VP9_MV_CLASS0_FP_1_START+VP9_MV_CLASS0_FP_1_SIZE)
-#define VP9_MV_CLASS0_HP_0_SIZE 2
-#define VP9_MV_CLASS0_HP_1_START \
- (VP9_MV_CLASS0_HP_0_START+VP9_MV_CLASS0_HP_0_SIZE)
-#define VP9_MV_CLASS0_HP_1_SIZE 2
-#define VP9_MV_START VP9_MV_JOINTS_START
-#define VP9_MV_SIZE 72 /*only use 69*/
-
-#define VP9_TOTAL_SIZE (VP9_MV_START + VP9_MV_SIZE)
-
-
-/*========================================================================
- * vp9_count_mem define
- *========================================================================
- */
-#define VP9_COEF_COUNT_START 0
-#define VP9_COEF_COUNT_BAND_0_OFFSET 0
-#define VP9_COEF_COUNT_BAND_1_OFFSET \
- (VP9_COEF_COUNT_BAND_0_OFFSET + 3*5)
-#define VP9_COEF_COUNT_BAND_2_OFFSET \
- (VP9_COEF_COUNT_BAND_1_OFFSET + 6*5)
-#define VP9_COEF_COUNT_BAND_3_OFFSET \
- (VP9_COEF_COUNT_BAND_2_OFFSET + 6*5)
-#define VP9_COEF_COUNT_BAND_4_OFFSET \
- (VP9_COEF_COUNT_BAND_3_OFFSET + 6*5)
-#define VP9_COEF_COUNT_BAND_5_OFFSET \
- (VP9_COEF_COUNT_BAND_4_OFFSET + 6*5)
-#define VP9_COEF_COUNT_SIZE_ONE_SET 165 /* ((3 +5*6)*5 */
-#define VP9_COEF_COUNT_4X4_START \
- (VP9_COEF_COUNT_START + 0*VP9_COEF_COUNT_SIZE_ONE_SET)
-#define VP9_COEF_COUNT_8X8_START \
- (VP9_COEF_COUNT_START + 4*VP9_COEF_COUNT_SIZE_ONE_SET)
-#define VP9_COEF_COUNT_16X16_START \
- (VP9_COEF_COUNT_START + 8*VP9_COEF_COUNT_SIZE_ONE_SET)
-#define VP9_COEF_COUNT_32X32_START \
- (VP9_COEF_COUNT_START + 12*VP9_COEF_COUNT_SIZE_ONE_SET)
-#define VP9_COEF_COUNT_SIZE_PLANE (2 * VP9_COEF_COUNT_SIZE_ONE_SET)
-#define VP9_COEF_COUNT_SIZE (4 * 2 * 2 * VP9_COEF_COUNT_SIZE_ONE_SET)
-
-#define VP9_INTRA_INTER_COUNT_START \
- (VP9_COEF_COUNT_START+VP9_COEF_COUNT_SIZE)
-#define VP9_INTRA_INTER_COUNT_SIZE (4*2)
-#define VP9_COMP_INTER_COUNT_START \
- (VP9_INTRA_INTER_COUNT_START+VP9_INTRA_INTER_COUNT_SIZE)
-#define VP9_COMP_INTER_COUNT_SIZE (5*2)
-#define VP9_COMP_REF_COUNT_START \
- (VP9_COMP_INTER_COUNT_START+VP9_COMP_INTER_COUNT_SIZE)
-#define VP9_COMP_REF_COUNT_SIZE (5*2)
-#define VP9_SINGLE_REF_COUNT_START \
- (VP9_COMP_REF_COUNT_START+VP9_COMP_REF_COUNT_SIZE)
-#define VP9_SINGLE_REF_COUNT_SIZE (10*2)
-#define VP9_TX_MODE_COUNT_START \
- (VP9_SINGLE_REF_COUNT_START+VP9_SINGLE_REF_COUNT_SIZE)
-#define VP9_TX_MODE_COUNT_SIZE (12*2)
-#define VP9_SKIP_COUNT_START \
- (VP9_TX_MODE_COUNT_START+VP9_TX_MODE_COUNT_SIZE)
-#define VP9_SKIP_COUNT_SIZE (3*2)
-#define VP9_MV_SIGN_0_COUNT_START \
- (VP9_SKIP_COUNT_START+VP9_SKIP_COUNT_SIZE)
-#define VP9_MV_SIGN_0_COUNT_SIZE (1*2)
-#define VP9_MV_SIGN_1_COUNT_START \
- (VP9_MV_SIGN_0_COUNT_START+VP9_MV_SIGN_0_COUNT_SIZE)
-#define VP9_MV_SIGN_1_COUNT_SIZE (1*2)
-#define VP9_MV_BITS_0_COUNT_START \
- (VP9_MV_SIGN_1_COUNT_START+VP9_MV_SIGN_1_COUNT_SIZE)
-#define VP9_MV_BITS_0_COUNT_SIZE (10*2)
-#define VP9_MV_BITS_1_COUNT_START \
- (VP9_MV_BITS_0_COUNT_START+VP9_MV_BITS_0_COUNT_SIZE)
-#define VP9_MV_BITS_1_COUNT_SIZE (10*2)
-#define VP9_MV_CLASS0_HP_0_COUNT_START \
- (VP9_MV_BITS_1_COUNT_START+VP9_MV_BITS_1_COUNT_SIZE)
-#define VP9_MV_CLASS0_HP_0_COUNT_SIZE (2*2)
-#define VP9_MV_CLASS0_HP_1_COUNT_START \
- (VP9_MV_CLASS0_HP_0_COUNT_START+VP9_MV_CLASS0_HP_0_COUNT_SIZE)
-#define VP9_MV_CLASS0_HP_1_COUNT_SIZE (2*2)
-/* Start merge_tree*/
-#define VP9_INTER_MODE_COUNT_START \
- (VP9_MV_CLASS0_HP_1_COUNT_START+VP9_MV_CLASS0_HP_1_COUNT_SIZE)
-#define VP9_INTER_MODE_COUNT_SIZE (7*4)
-#define VP9_IF_Y_MODE_COUNT_START \
- (VP9_INTER_MODE_COUNT_START+VP9_INTER_MODE_COUNT_SIZE)
-#define VP9_IF_Y_MODE_COUNT_SIZE (10*4)
-#define VP9_IF_UV_MODE_COUNT_START \
- (VP9_IF_Y_MODE_COUNT_START+VP9_IF_Y_MODE_COUNT_SIZE)
-#define VP9_IF_UV_MODE_COUNT_SIZE (10*10)
-#define VP9_PARTITION_P_COUNT_START \
- (VP9_IF_UV_MODE_COUNT_START+VP9_IF_UV_MODE_COUNT_SIZE)
-#define VP9_PARTITION_P_COUNT_SIZE (4*4*4)
-#define VP9_INTERP_COUNT_START \
- (VP9_PARTITION_P_COUNT_START+VP9_PARTITION_P_COUNT_SIZE)
-#define VP9_INTERP_COUNT_SIZE (4*3)
-#define VP9_MV_JOINTS_COUNT_START \
- (VP9_INTERP_COUNT_START+VP9_INTERP_COUNT_SIZE)
-#define VP9_MV_JOINTS_COUNT_SIZE (1 * 4)
-#define VP9_MV_CLASSES_0_COUNT_START \
- (VP9_MV_JOINTS_COUNT_START+VP9_MV_JOINTS_COUNT_SIZE)
-#define VP9_MV_CLASSES_0_COUNT_SIZE (1*11)
-#define VP9_MV_CLASS0_0_COUNT_START \
- (VP9_MV_CLASSES_0_COUNT_START+VP9_MV_CLASSES_0_COUNT_SIZE)
-#define VP9_MV_CLASS0_0_COUNT_SIZE (1*2)
-#define VP9_MV_CLASSES_1_COUNT_START \
- (VP9_MV_CLASS0_0_COUNT_START+VP9_MV_CLASS0_0_COUNT_SIZE)
-#define VP9_MV_CLASSES_1_COUNT_SIZE (1*11)
-#define VP9_MV_CLASS0_1_COUNT_START \
- (VP9_MV_CLASSES_1_COUNT_START+VP9_MV_CLASSES_1_COUNT_SIZE)
-#define VP9_MV_CLASS0_1_COUNT_SIZE (1*2)
-#define VP9_MV_CLASS0_FP_0_COUNT_START \
- (VP9_MV_CLASS0_1_COUNT_START+VP9_MV_CLASS0_1_COUNT_SIZE)
-#define VP9_MV_CLASS0_FP_0_COUNT_SIZE (3*4)
-#define VP9_MV_CLASS0_FP_1_COUNT_START \
- (VP9_MV_CLASS0_FP_0_COUNT_START+VP9_MV_CLASS0_FP_0_COUNT_SIZE)
-#define VP9_MV_CLASS0_FP_1_COUNT_SIZE (3*4)
-
-
-#define DC_PRED 0 /* Average of above and left pixels*/
-#define V_PRED 1 /* Vertical*/
-#define H_PRED 2 /* Horizontal*/
-#define D45_PRED 3 /*Directional 45 deg = round(arctan(1/1) * 180/pi)*/
-#define D135_PRED 4 /* Directional 135 deg = 180 - 45*/
-#define D117_PRED 5 /* Directional 117 deg = 180 - 63*/
-#define D153_PRED 6 /* Directional 153 deg = 180 - 27*/
-#define D207_PRED 7 /* Directional 207 deg = 180 + 27*/
-#define D63_PRED 8 /*Directional 63 deg = round(arctan(2/1) * 180/pi)*/
-#define TM_PRED 9 /*True-motion*/
-
-int clip_prob(int p)
-{
- return (p > 255) ? 255 : (p < 1) ? 1 : p;
-}
-
-#define ROUND_POWER_OF_TWO(value, n) \
- (((value) + (1 << ((n) - 1))) >> (n))
-
-#define MODE_MV_COUNT_SAT 20
-static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = {
- 0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
- 70, 76, 83, 89, 96, 102, 108, 115, 121, 128
-};
-
-void vp9_tree_merge_probs(unsigned int *prev_prob, unsigned int *cur_prob,
- int coef_node_start, int tree_left, int tree_right, int tree_i,
- int node) {
-
- int prob_32, prob_res, prob_shift;
- int pre_prob, new_prob;
- int den, m_count, get_prob, factor;
-
- prob_32 = prev_prob[coef_node_start / 4 * 2];
- prob_res = coef_node_start & 3;
- prob_shift = prob_res * 8;
- pre_prob = (prob_32 >> prob_shift) & 0xff;
-
- den = tree_left + tree_right;
-
- if (den == 0)
- new_prob = pre_prob;
- else {
- m_count = (den < MODE_MV_COUNT_SAT) ?
- den : MODE_MV_COUNT_SAT;
- get_prob = clip_prob(
- div_r32(((int64_t)tree_left * 256 + (den >> 1)),
- den));
- /*weighted_prob*/
- factor = count_to_update_factor[m_count];
- new_prob = ROUND_POWER_OF_TWO(pre_prob * (256 - factor)
- + get_prob * factor, 8);
- }
- cur_prob[coef_node_start / 4 * 2] = (cur_prob[coef_node_start / 4 * 2]
- & (~(0xff << prob_shift))) | (new_prob << prob_shift);
-
- /*pr_info(" - [%d][%d] 0x%02X --> 0x%02X (0x%X 0x%X) (%X)\n",
- *tree_i, node, pre_prob, new_prob, tree_left, tree_right,
- *cur_prob[coef_node_start/4*2]);
- */
-}
-
-
-/*void adapt_coef_probs(void)*/
-void adapt_coef_probs(int pic_count, int prev_kf, int cur_kf, int pre_fc,
- unsigned int *prev_prob, unsigned int *cur_prob, unsigned int *count)
-{
- /* 80 * 64bits = 0xF00 ( use 0x1000 4K bytes)
- *unsigned int prev_prob[496*2];
- *unsigned int cur_prob[496*2];
- *0x300 * 128bits = 0x3000 (32K Bytes)
- *unsigned int count[0x300*4];
- */
-
- int tx_size, coef_tx_size_start, coef_count_tx_size_start;
- int plane, coef_plane_start, coef_count_plane_start;
- int type, coef_type_start, coef_count_type_start;
- int band, coef_band_start, coef_count_band_start;
- int cxt_num;
- int cxt, coef_cxt_start, coef_count_cxt_start;
- int node, coef_node_start, coef_count_node_start;
-
- int tree_i, tree_left, tree_right;
- int mvd_i;
-
- int count_sat = 24;
- /*int update_factor = 112;*/ /*If COEF_MAX_UPDATE_FACTOR_AFTER_KEY,
- *use 128
- */
- /* If COEF_MAX_UPDATE_FACTOR_AFTER_KEY, use 128*/
- /*int update_factor = (pic_count == 1) ? 128 : 112;*/
- int update_factor = cur_kf ? 112 :
- prev_kf ? 128 : 112;
-
- int prob_32;
- int prob_res;
- int prob_shift;
- int pre_prob;
-
- int num, den;
- int get_prob;
- int m_count;
- int factor;
-
- int new_prob;
-
- if (debug & VP9_DEBUG_MERGE)
- pr_info
- ("\n ##adapt_coef_probs (pre_fc : %d ,prev_kf : %d,cur_kf : %d)##\n\n",
- pre_fc, prev_kf, cur_kf);
-
- /*adapt_coef_probs*/
- for (tx_size = 0; tx_size < 4; tx_size++) {
- coef_tx_size_start = VP9_COEF_START
- + tx_size * 4 * VP9_COEF_SIZE_ONE_SET;
- coef_count_tx_size_start = VP9_COEF_COUNT_START
- + tx_size * 4 * VP9_COEF_COUNT_SIZE_ONE_SET;
- coef_plane_start = coef_tx_size_start;
- coef_count_plane_start = coef_count_tx_size_start;
- for (plane = 0; plane < 2; plane++) {
- coef_type_start = coef_plane_start;
- coef_count_type_start = coef_count_plane_start;
- for (type = 0; type < 2; type++) {
- coef_band_start = coef_type_start;
- coef_count_band_start = coef_count_type_start;
- for (band = 0; band < 6; band++) {
- if (band == 0)
- cxt_num = 3;
- else
- cxt_num = 6;
- coef_cxt_start = coef_band_start;
- coef_count_cxt_start =
- coef_count_band_start;
- for (cxt = 0; cxt < cxt_num; cxt++) {
- const int n0 =
- count[coef_count_cxt_start];
- const int n1 =
- count[coef_count_cxt_start + 1];
- const int n2 =
- count[coef_count_cxt_start + 2];
- const int neob =
- count[coef_count_cxt_start + 3];
- const int nneob =
- count[coef_count_cxt_start + 4];
- const unsigned int
- branch_ct[3][2] = {
- { neob, nneob },
- { n0, n1 + n2 },
- { n1, n2 }
- };
- coef_node_start =
- coef_cxt_start;
- for
- (node = 0; node < 3; node++) {
- prob_32 =
- prev_prob[
- coef_node_start
- / 4 * 2];
- prob_res =
- coef_node_start & 3;
- prob_shift =
- prob_res * 8;
- pre_prob =
- (prob_32 >> prob_shift)
- & 0xff;
-
- /*get_binary_prob*/
- num =
- branch_ct[node][0];
- den =
- branch_ct[node][0] +
- branch_ct[node][1];
- m_count = (den <
- count_sat)
- ? den : count_sat;
-
- get_prob =
- (den == 0) ? 128u :
- clip_prob(
- div_r32(((int64_t)
- num * 256
- + (den >> 1)),
- den));
-
- factor =
- update_factor * m_count
- / count_sat;
- new_prob =
- ROUND_POWER_OF_TWO
- (pre_prob *
- (256 - factor) +
- get_prob * factor, 8);
-
- cur_prob[coef_node_start
- / 4 * 2] =
- (cur_prob
- [coef_node_start
- / 4 * 2] & (~(0xff <<
- prob_shift))) |
- (new_prob <<
- prob_shift);
-
- coef_node_start += 1;
- }
-
- coef_cxt_start =
- coef_cxt_start + 3;
- coef_count_cxt_start =
- coef_count_cxt_start
- + 5;
- }
- if (band == 0) {
- coef_band_start += 10;
- coef_count_band_start += 15;
- } else {
- coef_band_start += 18;
- coef_count_band_start += 30;
- }
- }
- coef_type_start += VP9_COEF_SIZE_ONE_SET;
- coef_count_type_start +=
- VP9_COEF_COUNT_SIZE_ONE_SET;
- }
- coef_plane_start += 2 * VP9_COEF_SIZE_ONE_SET;
- coef_count_plane_start +=
- 2 * VP9_COEF_COUNT_SIZE_ONE_SET;
- }
- }
-
- if (cur_kf == 0) {
- /*mode_mv_merge_probs - merge_intra_inter_prob*/
- for (coef_count_node_start = VP9_INTRA_INTER_COUNT_START;
- coef_count_node_start < (VP9_MV_CLASS0_HP_1_COUNT_START +
- VP9_MV_CLASS0_HP_1_COUNT_SIZE); coef_count_node_start += 2) {
-
- if (coef_count_node_start ==
- VP9_INTRA_INTER_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_intra_inter_prob\n");
- coef_node_start = VP9_INTRA_INTER_START;
- } else if (coef_count_node_start ==
- VP9_COMP_INTER_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_comp_inter_prob\n");
- coef_node_start = VP9_COMP_INTER_START;
- }
- /*
- *else if (coef_count_node_start ==
- * VP9_COMP_REF_COUNT_START) {
- * pr_info(" # merge_comp_inter_prob\n");
- * coef_node_start = VP9_COMP_REF_START;
- *}
- *else if (coef_count_node_start ==
- * VP9_SINGLE_REF_COUNT_START) {
- * pr_info(" # merge_comp_inter_prob\n");
- * coef_node_start = VP9_SINGLE_REF_START;
- *}
- */
- else if (coef_count_node_start ==
- VP9_TX_MODE_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_tx_mode_probs\n");
- coef_node_start = VP9_TX_MODE_START;
- } else if (coef_count_node_start ==
- VP9_SKIP_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_skip_probs\n");
- coef_node_start = VP9_SKIP_START;
- } else if (coef_count_node_start ==
- VP9_MV_SIGN_0_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_sign_0\n");
- coef_node_start = VP9_MV_SIGN_0_START;
- } else if (coef_count_node_start ==
- VP9_MV_SIGN_1_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_sign_1\n");
- coef_node_start = VP9_MV_SIGN_1_START;
- } else if (coef_count_node_start ==
- VP9_MV_BITS_0_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_bits_0\n");
- coef_node_start = VP9_MV_BITS_0_START;
- } else if (coef_count_node_start ==
- VP9_MV_BITS_1_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_bits_1\n");
- coef_node_start = VP9_MV_BITS_1_START;
- } else if (coef_count_node_start ==
- VP9_MV_CLASS0_HP_0_COUNT_START) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_class0_hp\n");
- coef_node_start = VP9_MV_CLASS0_HP_0_START;
- }
-
-
- den = count[coef_count_node_start] +
- count[coef_count_node_start + 1];
-
- prob_32 = prev_prob[coef_node_start / 4 * 2];
- prob_res = coef_node_start & 3;
- prob_shift = prob_res * 8;
- pre_prob = (prob_32 >> prob_shift) & 0xff;
-
- if (den == 0)
- new_prob = pre_prob;
- else {
- m_count = (den < MODE_MV_COUNT_SAT) ?
- den : MODE_MV_COUNT_SAT;
- get_prob =
- clip_prob(
- div_r32(((int64_t)count[coef_count_node_start]
- * 256 + (den >> 1)),
- den));
- /*weighted_prob*/
- factor = count_to_update_factor[m_count];
- new_prob =
- ROUND_POWER_OF_TWO(pre_prob * (256 - factor)
- + get_prob * factor, 8);
- }
- cur_prob[coef_node_start / 4 * 2] =
- (cur_prob[coef_node_start / 4 * 2] &
- (~(0xff << prob_shift)))
- | (new_prob << prob_shift);
-
- coef_node_start = coef_node_start + 1;
- }
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_inter_mode_tree\n");
- coef_node_start = VP9_INTER_MODE_START;
- coef_count_node_start = VP9_INTER_MODE_COUNT_START;
- for (tree_i = 0; tree_i < 7; tree_i++) {
- for (node = 0; node < 3; node++) {
- switch (node) {
- case 2:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 3];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1]
- + count[coef_count_node_start + 3];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 2];
- tree_right =
- count[coef_count_node_start + 0]
- + count[coef_count_node_start + 1]
- + count[coef_count_node_start + 3];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start, tree_left, tree_right,
- tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 4;
- }
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_intra_mode_tree\n");
- coef_node_start = VP9_IF_Y_MODE_START;
- coef_count_node_start = VP9_IF_Y_MODE_COUNT_START;
- for (tree_i = 0; tree_i < 14; tree_i++) {
- for (node = 0; node < 9; node++) {
- switch (node) {
- case 8:
- tree_left =
- count[coef_count_node_start+D153_PRED];
- tree_right =
- count[coef_count_node_start+D207_PRED];
- break;
- case 7:
- tree_left =
- count[coef_count_node_start+D63_PRED];
- tree_right =
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED];
- break;
- case 6:
- tree_left =
- count[coef_count_node_start + D45_PRED];
- tree_right =
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED] +
- count[coef_count_node_start+D63_PRED];
- break;
- case 5:
- tree_left =
- count[coef_count_node_start+D135_PRED];
- tree_right =
- count[coef_count_node_start+D117_PRED];
- break;
- case 4:
- tree_left =
- count[coef_count_node_start+H_PRED];
- tree_right =
- count[coef_count_node_start+D117_PRED] +
- count[coef_count_node_start+D135_PRED];
- break;
- case 3:
- tree_left =
- count[coef_count_node_start+H_PRED] +
- count[coef_count_node_start+D117_PRED] +
- count[coef_count_node_start+D135_PRED];
- tree_right =
- count[coef_count_node_start+D45_PRED] +
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED] +
- count[coef_count_node_start+D63_PRED];
- break;
- case 2:
- tree_left =
- count[coef_count_node_start+V_PRED];
- tree_right =
- count[coef_count_node_start+H_PRED] +
- count[coef_count_node_start+D117_PRED] +
- count[coef_count_node_start+D135_PRED] +
- count[coef_count_node_start+D45_PRED] +
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED] +
- count[coef_count_node_start+D63_PRED];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start+TM_PRED];
- tree_right =
- count[coef_count_node_start+V_PRED] +
- count[coef_count_node_start+H_PRED] +
- count[coef_count_node_start+D117_PRED] +
- count[coef_count_node_start+D135_PRED] +
- count[coef_count_node_start+D45_PRED] +
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED] +
- count[coef_count_node_start+D63_PRED];
- break;
- default:
- tree_left =
- count[coef_count_node_start+DC_PRED];
- tree_right =
- count[coef_count_node_start+TM_PRED] +
- count[coef_count_node_start+V_PRED] +
- count[coef_count_node_start+H_PRED] +
- count[coef_count_node_start+D117_PRED] +
- count[coef_count_node_start+D135_PRED] +
- count[coef_count_node_start+D45_PRED] +
- count[coef_count_node_start+D207_PRED] +
- count[coef_count_node_start+D153_PRED] +
- count[coef_count_node_start+D63_PRED];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start, tree_left, tree_right,
- tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 10;
- }
-
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_partition_tree\n");
- coef_node_start = VP9_PARTITION_P_START;
- coef_count_node_start = VP9_PARTITION_P_COUNT_START;
- for (tree_i = 0; tree_i < 16; tree_i++) {
- for (node = 0; node < 3; node++) {
- switch (node) {
- case 2:
- tree_left =
- count[coef_count_node_start + 2];
- tree_right =
- count[coef_count_node_start + 3];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1] +
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start,
- tree_left, tree_right, tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 4;
- }
-
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_switchable_interp_tree\n");
- coef_node_start = VP9_INTERP_START;
- coef_count_node_start = VP9_INTERP_COUNT_START;
- for (tree_i = 0; tree_i < 4; tree_i++) {
- for (node = 0; node < 2; node++) {
- switch (node) {
- case 1:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 2];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1] +
- count[coef_count_node_start + 2];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start,
- tree_left, tree_right, tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 3;
- }
-
- if (debug & VP9_DEBUG_MERGE)
- pr_info("# merge_vp9_mv_joint_tree\n");
- coef_node_start = VP9_MV_JOINTS_START;
- coef_count_node_start = VP9_MV_JOINTS_COUNT_START;
- for (tree_i = 0; tree_i < 1; tree_i++) {
- for (node = 0; node < 3; node++) {
- switch (node) {
- case 2:
- tree_left =
- count[coef_count_node_start + 2];
- tree_right =
- count[coef_count_node_start + 3];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1] +
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3];
- break;
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start,
- tree_left, tree_right, tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 4;
- }
-
- for (mvd_i = 0; mvd_i < 2; mvd_i++) {
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_mv_class_tree [%d] -\n", mvd_i);
- coef_node_start =
- mvd_i ? VP9_MV_CLASSES_1_START : VP9_MV_CLASSES_0_START;
- coef_count_node_start =
- mvd_i ? VP9_MV_CLASSES_1_COUNT_START
- : VP9_MV_CLASSES_0_COUNT_START;
- tree_i = 0;
- for (node = 0; node < 10; node++) {
- switch (node) {
- case 9:
- tree_left =
- count[coef_count_node_start + 9];
- tree_right =
- count[coef_count_node_start + 10];
- break;
- case 8:
- tree_left =
- count[coef_count_node_start + 7];
- tree_right =
- count[coef_count_node_start + 8];
- break;
- case 7:
- tree_left =
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8];
- tree_right =
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
- case 6:
- tree_left =
- count[coef_count_node_start + 6];
- tree_right =
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8] +
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
- case 5:
- tree_left =
- count[coef_count_node_start + 4];
- tree_right =
- count[coef_count_node_start + 5];
- break;
- case 4:
- tree_left =
- count[coef_count_node_start + 4] +
- count[coef_count_node_start + 5];
- tree_right =
- count[coef_count_node_start + 6] +
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8] +
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
- case 3:
- tree_left =
- count[coef_count_node_start + 2];
- tree_right =
- count[coef_count_node_start + 3];
- break;
- case 2:
- tree_left =
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3];
- tree_right =
- count[coef_count_node_start + 4] +
- count[coef_count_node_start + 5] +
- count[coef_count_node_start + 6] +
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8] +
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3] +
- count[coef_count_node_start + 4] +
- count[coef_count_node_start + 5] +
- count[coef_count_node_start + 6] +
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8] +
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1] +
- count[coef_count_node_start + 2] +
- count[coef_count_node_start + 3] +
- count[coef_count_node_start + 4] +
- count[coef_count_node_start + 5] +
- count[coef_count_node_start + 6] +
- count[coef_count_node_start + 7] +
- count[coef_count_node_start + 8] +
- count[coef_count_node_start + 9] +
- count[coef_count_node_start + 10];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start, tree_left, tree_right,
- tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
-
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_mv_class0_tree [%d] -\n", mvd_i);
- coef_node_start =
- mvd_i ? VP9_MV_CLASS0_1_START : VP9_MV_CLASS0_0_START;
- coef_count_node_start =
- mvd_i ? VP9_MV_CLASS0_1_COUNT_START :
- VP9_MV_CLASS0_0_COUNT_START;
- tree_i = 0;
- node = 0;
- tree_left = count[coef_count_node_start + 0];
- tree_right = count[coef_count_node_start + 1];
-
- vp9_tree_merge_probs(prev_prob, cur_prob, coef_node_start,
- tree_left, tree_right, tree_i, node);
- if (debug & VP9_DEBUG_MERGE)
- pr_info(" # merge_vp9_mv_fp_tree_class0_fp [%d] -\n",
- mvd_i);
- coef_node_start =
- mvd_i ? VP9_MV_CLASS0_FP_1_START :
- VP9_MV_CLASS0_FP_0_START;
- coef_count_node_start =
- mvd_i ? VP9_MV_CLASS0_FP_1_COUNT_START :
- VP9_MV_CLASS0_FP_0_COUNT_START;
- for (tree_i = 0; tree_i < 3; tree_i++) {
- for (node = 0; node < 3; node++) {
- switch (node) {
- case 2:
- tree_left =
- count[coef_count_node_start + 2];
- tree_right =
- count[coef_count_node_start + 3];
- break;
- case 1:
- tree_left =
- count[coef_count_node_start + 1];
- tree_right =
- count[coef_count_node_start + 2]
- + count[coef_count_node_start + 3];
- break;
- default:
- tree_left =
- count[coef_count_node_start + 0];
- tree_right =
- count[coef_count_node_start + 1]
- + count[coef_count_node_start + 2]
- + count[coef_count_node_start + 3];
- break;
-
- }
-
- vp9_tree_merge_probs(prev_prob, cur_prob,
- coef_node_start, tree_left, tree_right,
- tree_i, node);
-
- coef_node_start = coef_node_start + 1;
- }
- coef_count_node_start = coef_count_node_start + 4;
- }
-
- } /* for mvd_i (mvd_y or mvd_x)*/
-}
-
-}
-
-static void uninit_mmu_buffers(struct VP9Decoder_s *pbi)
-{
-#ifndef MV_USE_FIXED_BUF
- dealloc_mv_bufs(pbi);
-#endif
- if (pbi->mmu_box) {
- decoder_mmu_box_free(pbi->mmu_box);
- pbi->mmu_box = NULL;
- }
-
- if (pbi->bmmu_box) {
- decoder_bmmu_box_free(pbi->bmmu_box);
- pbi->bmmu_box = NULL;
- }
-}
-
-static int calc_luc_quantity(u32 w, u32 h)
-{
- int lcu_size = 64; /*fixed 64*/
- int pic_width_64 = (w + 63) & (~0x3f);
- int pic_height_32 = (h + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1 : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1 : pic_height_32 / lcu_size;
-
- return pic_width_lcu * pic_height_lcu;
-}
-
-/* return in MB */
-static int vp9_max_mmu_buf_size(int max_w, int max_h)
-{
- int buf_size = 48;
-
- if ((max_w * max_h > 1280*736) &&
- (max_w * max_h <= 1920*1088)) {
- buf_size = 12;
- } else if ((max_w * max_h > 0) &&
- (max_w * max_h <= 1280*736)) {
- buf_size = 4;
- }
-
- return buf_size;
-}
-
-static void vp9_put_video_frame(void *vdec_ctx, struct vframe_s *vf)
-{
- vvp9_vf_put(vf, vdec_ctx);
-}
-
-static void vp9_get_video_frame(void *vdec_ctx, struct vframe_s **vf)
-{
- *vf = vvp9_vf_get(vdec_ctx);
-}
-
-static struct task_ops_s task_dec_ops = {
- .type = TASK_TYPE_DEC,
- .get_vframe = vp9_get_video_frame,
- .put_vframe = vp9_put_video_frame,
-};
-
-static int v4l_alloc_and_config_pic(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic)
-{
- int ret = -1;
- int i = pic->index;
- int dw_mode = get_double_write_mode_init(pbi);
- int lcu_total = calc_luc_quantity(pbi->frame_width, pbi->frame_height);
-#ifdef MV_USE_FIXED_BUF
- u32 mpred_mv_end = pbi->work_space_buf->mpred_mv.buf_start +
- pbi->work_space_buf->mpred_mv.buf_size;
- int mv_size = cal_mv_buf_size(pbi, pbi->frame_width, pbi->frame_height);
-#endif
- struct aml_vcodec_ctx * ctx = (struct aml_vcodec_ctx *)pbi->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
-
- if (i < 0)
- return ret;
-
- ret = ctx->fb_ops.alloc(&ctx->fb_ops, pbi->fb_token, &fb, AML_FB_REQ_DEC);
- if (ret < 0) {
- vp9_print(pbi, 0, "[%d] VP9 get buffer fail.\n", ctx->id);
- return ret;
- }
-
- fb->task->attach(fb->task, &task_dec_ops, pbi);
- fb->status = FB_ST_DECODER;
-
- if (pbi->mmu_enable) {
- struct internal_comp_buf *ibuf = v4lfb_to_icomp_buf(pbi, fb);
-
- pbi->m_BUF[i].header_addr = ibuf->header_addr;
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_adr %d: %ld\n",
- i, pbi->m_BUF[i].header_addr);
- }
- }
-
- pic->repeat_pic = NULL;
- pic->repeat_count = 0;
-#ifdef MV_USE_FIXED_BUF
- if ((pbi->work_space_buf->mpred_mv.buf_start +
- ((i + 1) * mv_size))
- <= mpred_mv_end) {
-#endif
- pbi->m_BUF[i].v4l_ref_buf_addr = (ulong)fb;
- pic->cma_alloc_addr = fb->m.mem[0].addr;
- if (fb->num_planes == 1) {
- pbi->m_BUF[i].start_adr = fb->m.mem[0].addr;
- pbi->m_BUF[i].luma_size = fb->m.mem[0].offset;
- pbi->m_BUF[i].size = fb->m.mem[0].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- pic->dw_y_adr = pbi->m_BUF[i].start_adr;
- pic->dw_u_v_adr = pic->dw_y_adr + pbi->m_BUF[i].luma_size;
- pic->luma_size = fb->m.mem[0].offset;
- pic->chroma_size = fb->m.mem[0].size - fb->m.mem[0].offset;
- } else if (fb->num_planes == 2) {
- pbi->m_BUF[i].start_adr = fb->m.mem[0].addr;
- pbi->m_BUF[i].size = fb->m.mem[0].size;
- pbi->m_BUF[i].chroma_addr = fb->m.mem[1].addr;
- pbi->m_BUF[i].chroma_size = fb->m.mem[1].size;
- fb->m.mem[0].bytes_used = fb->m.mem[0].size;
- fb->m.mem[1].bytes_used = fb->m.mem[1].size;
- pic->dw_y_adr = pbi->m_BUF[i].start_adr;
- pic->dw_u_v_adr = pbi->m_BUF[i].chroma_addr;
- pic->luma_size = fb->m.mem[0].size;
- pic->chroma_size = fb->m.mem[1].size;
- }
-
- /* config frame buffer */
- if (pbi->mmu_enable)
- pic->header_adr = pbi->m_BUF[i].header_addr;
-
- pic->BUF_index = i;
- pic->lcu_total = lcu_total;
- pic->mc_canvas_y = pic->index;
- pic->mc_canvas_u_v = pic->index;
-
- if (dw_mode & 0x10) {
- pic->mc_canvas_y = (pic->index << 1);
- pic->mc_canvas_u_v = (pic->index << 1) + 1;
- }
-
-#ifdef MV_USE_FIXED_BUF
- pic->mpred_mv_wr_start_addr =
- pbi->work_space_buf->mpred_mv.buf_start +
- (pic->index * mv_size);
- pic->mv_size = mv_size;
-#endif
- if (debug) {
- pr_info("%s index %d BUF_index %d ",
- __func__, pic->index,
- pic->BUF_index);
- pr_info("comp_body_size %x comp_buf_size %x ",
- pic->comp_body_size,
- pic->buf_size);
- pr_info("mpred_mv_wr_start_adr %ld\n",
- pic->mpred_mv_wr_start_addr);
- pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n",
- pic->dw_y_adr,
- pic->dw_u_v_adr);
- }
-#ifdef MV_USE_FIXED_BUF
- }
-#endif
- return ret;
-}
-
-static int config_pic(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- int ret = -1;
- int i;
- int pic_width = pbi->init_pic_w;
- int pic_height = pbi->init_pic_h;
- int lcu_size = 64; /*fixed 64*/
- int pic_width_64 = (pic_width + 63) & (~0x3f);
- int pic_height_32 = (pic_height + 31) & (~0x1f);
- int pic_width_lcu = (pic_width_64 % lcu_size) ?
- pic_width_64 / lcu_size + 1
- : pic_width_64 / lcu_size;
- int pic_height_lcu = (pic_height_32 % lcu_size) ?
- pic_height_32 / lcu_size + 1
- : pic_height_32 / lcu_size;
- int lcu_total = pic_width_lcu * pic_height_lcu;
-#ifdef MV_USE_FIXED_BUF
- u32 mpred_mv_end = pbi->work_space_buf->mpred_mv.buf_start +
- pbi->work_space_buf->mpred_mv.buf_size;
- int mv_size = cal_mv_buf_size(pbi, pbi->init_pic_w, pbi->init_pic_h);
-#endif
- u32 y_adr = 0;
- int buf_size = 0;
-
- int losless_comp_header_size =
- compute_losless_comp_header_size(pic_width,
- pic_height);
- int losless_comp_body_size = compute_losless_comp_body_size(pic_width,
- pic_height, buf_alloc_depth == 10);
- int mc_buffer_size = losless_comp_header_size + losless_comp_body_size;
- int mc_buffer_size_h = (mc_buffer_size + 0xffff) >> 16;
- int mc_buffer_size_u_v = 0;
- int mc_buffer_size_u_v_h = 0;
- int dw_mode = get_double_write_mode_init(pbi);
-
- pbi->lcu_total = lcu_total;
-
- if (dw_mode) {
- int pic_width_dw = pic_width /
- get_double_write_ratio(dw_mode);
- int pic_height_dw = pic_height /
- get_double_write_ratio(dw_mode);
-
- int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
- int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
- int pic_width_lcu_dw = (pic_width_64_dw % lcu_size) ?
- pic_width_64_dw / lcu_size + 1
- : pic_width_64_dw / lcu_size;
- int pic_height_lcu_dw = (pic_height_32_dw % lcu_size) ?
- pic_height_32_dw / lcu_size + 1
- : pic_height_32_dw / lcu_size;
- int lcu_total_dw = pic_width_lcu_dw * pic_height_lcu_dw;
- mc_buffer_size_u_v = lcu_total_dw * lcu_size * lcu_size / 2;
- mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff) >> 16;
- /*64k alignment*/
- buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
- buf_size = ((buf_size + 0xffff) >> 16) << 16;
- }
-
- if (mc_buffer_size & 0xffff) /*64k alignment*/
- mc_buffer_size_h += 1;
- if ((!pbi->mmu_enable) && ((dw_mode & 0x10) == 0))
- buf_size += (mc_buffer_size_h << 16);
-
- if (pbi->mmu_enable) {
- pic_config->header_adr = decoder_bmmu_box_get_phy_addr(
- pbi->bmmu_box, HEADER_BUFFER_IDX(pic_config->index));
-
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
- pr_info("MMU header_adr %d: %ld\n",
- pic_config->index, pic_config->header_adr);
- }
- }
-
- i = pic_config->index;
-#ifdef MV_USE_FIXED_BUF
- if ((pbi->work_space_buf->mpred_mv.buf_start +
- ((i + 1) * mv_size))
- <= mpred_mv_end
- ) {
-#endif
- if (buf_size > 0) {
- ret = decoder_bmmu_box_alloc_buf_phy(pbi->bmmu_box,
- VF_BUFFER_IDX(i),
- buf_size, DRIVER_NAME,
- &pic_config->cma_alloc_addr);
- if (ret < 0) {
- pr_info(
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return ret;
- }
-
- if (pic_config->cma_alloc_addr)
- y_adr = pic_config->cma_alloc_addr;
- else {
- pr_info(
- "decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
- VF_BUFFER_IDX(i),
- buf_size
- );
- return -1;
- }
- }
- {
- /*ensure get_pic_by_POC()
- not get the buffer not decoded*/
- pic_config->BUF_index = i;
- pic_config->lcu_total = lcu_total;
-
- pic_config->comp_body_size = losless_comp_body_size;
- pic_config->buf_size = buf_size;
-
- pic_config->mc_canvas_y = pic_config->index;
- pic_config->mc_canvas_u_v = pic_config->index;
- if (dw_mode & 0x10) {
- pic_config->dw_y_adr = y_adr;
- pic_config->dw_u_v_adr = y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
-
- pic_config->mc_canvas_y =
- (pic_config->index << 1);
- pic_config->mc_canvas_u_v =
- (pic_config->index << 1) + 1;
- } else if (dw_mode) {
- pic_config->dw_y_adr = y_adr;
- pic_config->dw_u_v_adr = pic_config->dw_y_adr +
- ((mc_buffer_size_u_v_h << 16) << 1);
- }
-#ifdef MV_USE_FIXED_BUF
- pic_config->mpred_mv_wr_start_addr =
- pbi->work_space_buf->mpred_mv.buf_start +
- (pic_config->index * mv_size);
- pic_config->mv_size = mv_size;
-#endif
- if (debug) {
- pr_info
- ("%s index %d BUF_index %d ",
- __func__, pic_config->index,
- pic_config->BUF_index);
- pr_info
- ("comp_body_size %x comp_buf_size %x ",
- pic_config->comp_body_size,
- pic_config->buf_size);
- pr_info
- ("mpred_mv_wr_start_adr %ld\n",
- pic_config->mpred_mv_wr_start_addr);
- pr_info("dw_y_adr %d, pic_config->dw_u_v_adr =%d\n",
- pic_config->dw_y_adr,
- pic_config->dw_u_v_adr);
- }
- ret = 0;
- }
-#ifdef MV_USE_FIXED_BUF
- }
-#endif
- return ret;
-}
-
-
-static void init_pic_list(struct VP9Decoder_s *pbi)
-{
- int i;
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- u32 header_size;
- struct vdec_s *vdec = hw_to_vdec(pbi);
-
- if (!pbi->is_used_v4l && pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- header_size = vvp9_mmu_compress_header_size(pbi->max_pic_w, pbi->max_pic_h);
- /*alloc VP9 compress header first*/
- for (i = 0; i < pbi->used_buf_num; i++) {
- unsigned long buf_addr;
- if (decoder_bmmu_box_alloc_buf_phy
- (pbi->bmmu_box,
- HEADER_BUFFER_IDX(i), header_size,
- DRIVER_HEADER_NAME,
- &buf_addr) < 0) {
- pr_info("%s malloc compress header failed %d\n",
- DRIVER_HEADER_NAME, i);
- pbi->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
- return;
- }
- }
- }
- for (i = 0; i < pbi->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- pic_config->index = i;
- pic_config->BUF_index = -1;
- pic_config->mv_buf_index = -1;
- if (vdec->parallel_dec == 1) {
- pic_config->y_canvas_index = -1;
- pic_config->uv_canvas_index = -1;
- }
- pic_config->y_crop_width = pbi->init_pic_w;
- pic_config->y_crop_height = pbi->init_pic_h;
- pic_config->double_write_mode = get_double_write_mode(pbi);
-
- if (!pbi->is_used_v4l) {
- if (config_pic(pbi, pic_config) < 0) {
- if (debug)
- pr_info("Config_pic %d fail\n",
- pic_config->index);
- pic_config->index = -1;
- break;
- }
-
- if (pic_config->double_write_mode) {
- set_canvas(pbi, pic_config);
- }
- }
- }
- for (; i < pbi->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- pic_config->index = -1;
- pic_config->BUF_index = -1;
- pic_config->mv_buf_index = -1;
- if (vdec->parallel_dec == 1) {
- pic_config->y_canvas_index = -1;
- pic_config->uv_canvas_index = -1;
- }
- }
- pr_info("%s ok, used_buf_num = %d\n",
- __func__, pbi->used_buf_num);
-}
-
-static void init_pic_list_hw(struct VP9Decoder_s *pbi)
-{
- int i;
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
- (0x1 << 1) | (0x1 << 2));
-
- for (i = 0; i < pbi->used_buf_num; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- if (pic_config->index < 0)
- break;
-
- if (pbi->mmu_enable && ((pic_config->double_write_mode & 0x10) == 0)) {
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->header_adr >> 5);
- } else {
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- * pic_config->mc_y_adr
- * | (pic_config->mc_canvas_y << 8) | 0x1);
- */
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->dw_y_adr >> 5);
- }
-#ifndef LOSLESS_COMPRESS_MODE
- /*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
- * pic_config->mc_u_v_adr
- * | (pic_config->mc_canvas_u_v << 8)| 0x1);
- */
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->header_adr >> 5);
-#else
- if (pic_config->double_write_mode & 0x10) {
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_DATA,
- pic_config->dw_u_v_adr >> 5);
- }
-#endif
- }
- WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
-
- /*Zero out canvas registers in IPP -- avoid simulation X*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
- for (i = 0; i < 32; i++)
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
-}
-
-static void dump_pic_list(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *pic_config;
- int i;
- for (i = 0; i < FRAME_BUFFERS; i++) {
- pic_config = &cm->buffer_pool->frame_bufs[i].buf;
- vp9_print(pbi, 0,
- "Buf(%d) index %d mv_buf_index %d ref_count %d vf_ref %d repeat_count %d dec_idx %d slice_type %d w/h %d/%d adr: %x\n",
- i,
- pic_config->index,
-#ifndef MV_USE_FIXED_BUF
- pic_config->mv_buf_index,
-#else
- -1,
-#endif
- cm->buffer_pool->
- frame_bufs[i].ref_count,
- pic_config->vf_ref,
- pic_config->repeat_count,
- pic_config->decode_idx,
- pic_config->slice_type,
- pic_config->y_crop_width,
- pic_config->y_crop_height,
- pic_config->cma_alloc_addr
- );
- }
- return;
-}
-
-static int config_pic_size(struct VP9Decoder_s *pbi, unsigned short bit_depth)
-{
-#ifdef LOSLESS_COMPRESS_MODE
- unsigned int data32;
-#endif
- int losless_comp_header_size, losless_comp_body_size;
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf;
-
- frame_width = cur_pic_config->y_crop_width;
- frame_height = cur_pic_config->y_crop_height;
- cur_pic_config->bit_depth = bit_depth;
- cur_pic_config->double_write_mode = get_double_write_mode(pbi);
- losless_comp_header_size =
- compute_losless_comp_header_size(cur_pic_config->y_crop_width,
- cur_pic_config->y_crop_height);
- losless_comp_body_size =
- compute_losless_comp_body_size(cur_pic_config->y_crop_width,
- cur_pic_config->y_crop_height, (bit_depth == VPX_BITS_10));
- cur_pic_config->comp_body_size = losless_comp_body_size;
-#ifdef LOSLESS_COMPRESS_MODE
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- if (bit_depth == VPX_BITS_10)
- data32 &= ~(1 << 9);
- else
- data32 |= (1 << 9);
-
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- if (pbi->mmu_enable) {
- /*bit[4] : paged_mem_mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
- } else {
- /*bit[3] smem mdoe*/
- if (bit_depth == VPX_BITS_10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0 << 3));
- else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1 << 3));
- }
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, (losless_comp_body_size >> 5));
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,(0xff<<20) | (0xff<<10) | 0xff);*/
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
- if (get_double_write_mode(pbi) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
- return 0;
-}
-
-static int config_mc_buffer(struct VP9Decoder_s *pbi, unsigned short bit_depth)
-{
- int i;
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf;
- uint8_t scale_enable = 0;
-
- if (debug&VP9_DEBUG_BUFMGR_MORE)
- pr_info("config_mc_buffer entered .....\n");
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (0 << 1) | 1);
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf;
- if (!pic_config)
- continue;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic_config->mc_canvas_u_v << 16)
- | (pic_config->mc_canvas_u_v << 8)
- | pic_config->mc_canvas_y);
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("refid %x mc_canvas_u_v %x mc_canvas_y %x\n",
- i, pic_config->mc_canvas_u_v,
- pic_config->mc_canvas_y);
- }
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (16 << 8) | (0 << 1) | 1);
- for (i = 0; i < REFS_PER_FRAME; ++i) {
- struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf;
- if (!pic_config)
- continue;
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
- (pic_config->mc_canvas_u_v << 16)
- | (pic_config->mc_canvas_u_v << 8)
- | pic_config->mc_canvas_y);
- }
-
- /*auto_inc start index:0 field:0*/
- WRITE_VREG(VP9D_MPP_REFINFO_TBL_ACCCONFIG, 0x1 << 2);
- /*index 0:last 1:golden 2:altref*/
- for (i = 0; i < REFS_PER_FRAME; i++) {
- int ref_pic_body_size;
- struct PIC_BUFFER_CONFIG_s *pic_config = cm->frame_refs[i].buf;
- if (!pic_config)
- continue;
- WRITE_VREG(VP9D_MPP_REFINFO_DATA, pic_config->y_crop_width);
- WRITE_VREG(VP9D_MPP_REFINFO_DATA, pic_config->y_crop_height);
-
- if (pic_config->y_crop_width != cur_pic_config->y_crop_width ||
- pic_config->y_crop_height != cur_pic_config->y_crop_height) {
- scale_enable |= (1 << i);
- }
- ref_pic_body_size =
- compute_losless_comp_body_size(pic_config->y_crop_width,
- pic_config->y_crop_height, (bit_depth == VPX_BITS_10));
- WRITE_VREG(VP9D_MPP_REFINFO_DATA,
- (pic_config->y_crop_width << 14)
- / cur_pic_config->y_crop_width);
- WRITE_VREG(VP9D_MPP_REFINFO_DATA,
- (pic_config->y_crop_height << 14)
- / cur_pic_config->y_crop_height);
- if (pbi->mmu_enable)
- WRITE_VREG(VP9D_MPP_REFINFO_DATA, 0);
- else
- WRITE_VREG(VP9D_MPP_REFINFO_DATA, ref_pic_body_size >> 5);
- }
- WRITE_VREG(VP9D_MPP_REF_SCALE_ENBL, scale_enable);
- return 0;
-}
-
-static void clear_mpred_hw(struct VP9Decoder_s *pbi)
-{
- unsigned int data32;
-
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 &= (~(1 << 6));
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
-}
-
-static void config_mpred_hw(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config = &cm->cur_frame->buf;
- struct PIC_BUFFER_CONFIG_s *last_frame_pic_config =
- &cm->prev_frame->buf;
-
- unsigned int data32;
- int mpred_curr_lcu_x;
- int mpred_curr_lcu_y;
- int mpred_mv_rd_end_addr;
-
-
- mpred_mv_rd_end_addr = last_frame_pic_config->mpred_mv_wr_start_addr
- + last_frame_pic_config->mv_size;
- //+ (last_frame_pic_config->lcu_total * MV_MEM_UNIT);
-
- data32 = READ_VREG(HEVC_MPRED_CURR_LCU);
- mpred_curr_lcu_x = data32 & 0xffff;
- mpred_curr_lcu_y = (data32 >> 16) & 0xffff;
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("cur pic_config index %d col pic_config index %d\n",
- cur_pic_config->index, last_frame_pic_config->index);
- WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412);
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,
- pbi->work_space_buf->mpred_above.buf_start);
-
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
-
- data32 &= (~(1 << 6));
- data32 |= (cm->use_prev_frame_mvs << 6);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
-
- WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
- cur_pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_WPTR, cur_pic_config->mpred_mv_wr_start_addr);
-
- WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
- last_frame_pic_config->mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_RPTR,
- last_frame_pic_config->mpred_mv_wr_start_addr);
- /*data32 = ((pbi->lcu_x_num - pbi->tile_width_lcu)*MV_MEM_UNIT);*/
- /*WRITE_VREG(HEVC_MPRED_MV_WR_ROW_JUMP,data32);*/
- /*WRITE_VREG(HEVC_MPRED_MV_RD_ROW_JUMP,data32);*/
- WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR, mpred_mv_rd_end_addr);
-
-}
-
-static void config_sao_hw(struct VP9Decoder_s *pbi, union param_u *params)
-{
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *pic_config = &cm->cur_frame->buf;
-
- unsigned int data32;
- int lcu_size = 64;
- int mc_buffer_size_u_v =
- pic_config->lcu_total * lcu_size*lcu_size/2;
- int mc_buffer_size_u_v_h =
- (mc_buffer_size_u_v + 0xffff) >> 16;/*64k alignment*/
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
-
- if (get_double_write_mode(pbi)) {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic_config->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, pic_config->dw_u_v_adr);
- WRITE_VREG(HEVC_SAO_Y_WPTR, pic_config->dw_y_adr);
- WRITE_VREG(HEVC_SAO_C_WPTR, pic_config->dw_u_v_adr);
- } else {
- WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
- WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
- }
- if (pbi->mmu_enable)
- WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic_config->header_adr);
-
- if (pbi->is_used_v4l) {
- WRITE_VREG(HEVC_SAO_Y_LENGTH, pic_config->luma_size);
- WRITE_VREG(HEVC_SAO_C_LENGTH, pic_config->chroma_size);
- if (debug & PRINT_FLAG_V4L_DETAIL) {
- pr_info("[%d] config pic, id: %d, Y:(%x, %d) C:(%x, %d).\n",
- v4l2_ctx->id, pic_config->index,
- pic_config->dw_y_adr, pic_config->luma_size,
- pic_config->dw_u_v_adr, pic_config->chroma_size);
- }
- } else {
- data32 = (mc_buffer_size_u_v_h << 16) << 1;
- /*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
- data32, mc_buffer_size_u_v_h, pic_config->lcu_total);*/
-
- WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
-
- data32 = (mc_buffer_size_u_v_h << 16);
- WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
- }
-
-#ifdef VP9_10B_NV21
-#ifdef DOS_PROJECT
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (pbi->mem_map_mode << 12);
- data32 &= (~0x3);
- data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
- /*[23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl
- * [17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (pbi->mem_map_mode << 4);
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#else
- /*m8baby test1902*/
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~0x3000);
- /*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
- data32 |= (pbi->mem_map_mode << 12);
- data32 &= (~0xff0);
- /*data32 |= 0x670;*/ /*Big-Endian per 64-bit*/
- data32 |= 0x880; /*.Big-Endian per 64-bit */
- data32 &= (~0x3);
- data32 |= 0x1; /*[1]:dw_disable [0]:cm_disable*/
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
- /* [23:22] dw_v1_ctrl [21:20] dw_v0_ctrl
- *[19:18] dw_h1_ctrl [17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /* set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /*[5:4] address_format 00:linear 01:32x32 10:64x32*/
- data32 |= (pbi->mem_map_mode << 4);
- data32 &= (~0xF);
- data32 |= 0x8; /*Big-Endian per 64-bit*/
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
-#else
- data32 = READ_VREG(HEVC_SAO_CTRL1);
- data32 &= (~(3 << 14));
- data32 |= (2 << 14); /* line align with 64*/
-
- data32 &= (~0x3000);
- /* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
- data32 |= (pbi->mem_map_mode << 12);
-
- data32 &= (~0xff0);
- data32 |= ((pbi->endian >> 8) & 0xfff); /* Big-Endian per 64-bit */
- data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
- if (get_double_write_mode(pbi) == 0)
- data32 |= 0x2; /*disable double write*/
- else if (get_double_write_mode(pbi) & 0x10)
- data32 |= 0x1; /*disable cm*/
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) { /* >= G12A dw write control */
- unsigned int data;
- data = READ_VREG(HEVC_DBLK_CFGB);
- data &= (~0x300); /*[8]:first write enable (compress) [9]:double write enable (uncompress)*/
- if (get_double_write_mode(pbi) == 0)
- data |= (0x1 << 8); /*enable first write*/
- else if (get_double_write_mode(pbi) & 0x10)
- data |= (0x1 << 9); /*double write only*/
- else
- data |= ((0x1 << 8) |(0x1 << 9));
- WRITE_VREG(HEVC_DBLK_CFGB, data);
- }
-
- /* swap uv */
- if (pbi->is_used_v4l) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- data32 &= ~(1 << 8); /* NV21 */
- else
- data32 |= (1 << 8); /* NV12 */
- }
-
- /*
- * [31:24] ar_fifo1_axi_thred
- * [23:16] ar_fifo0_axi_thred
- * [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
- * [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
- * [11:08] axi_lendian_C
- * [07:04] axi_lendian_Y
- * [3] reserved
- * [2] clk_forceon
- * [1] dw_disable:disable double write output
- * [0] cm_disable:disable compress output
- */
- WRITE_VREG(HEVC_SAO_CTRL1, data32);
-
- if (get_double_write_mode(pbi) & 0x10) {
- /* [23:22] dw_v1_ctrl
- *[21:20] dw_v0_ctrl
- *[19:18] dw_h1_ctrl
- *[17:16] dw_h0_ctrl
- */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- /*set them all 0 for H265_NV21 (no down-scale)*/
- data32 &= ~(0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- } else {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 &= (~(0xff << 16));
- if (get_double_write_mode(pbi) == 8 ||
- get_double_write_mode(pbi) == 9) {
- data32 |= (0xff << 16);
- WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
- } else if (get_double_write_mode(pbi) == 2 ||
- get_double_write_mode(pbi) == 3)
- data32 |= (0xff << 16);
- else if (get_double_write_mode(pbi) == 4)
- data32 |= (0x33 << 16);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
- data32 &= (~0x30);
- /* [5:4] -- address_format 00:linear 01:32x32 10:64x32 */
- data32 |= (pbi->mem_map_mode << 4);
- data32 &= (~0xf);
- data32 |= (pbi->endian & 0xf); /* valid only when double write only */
-
- /* swap uv */
- if (pbi->is_used_v4l) {
- if ((v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21) ||
- (v4l2_ctx->q_data[AML_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_NV21M))
- data32 |= (1 << 12); /* NV21 */
- else
- data32 &= ~(1 << 12); /* NV12 */
- }
- data32 &= (~(3 << 8));
- data32 |= (2 << 8); /* line align with 64 for dw only */
- /*
- * [3:0] little_endian
- * [5:4] address_format 00:linear 01:32x32 10:64x32
- * [7:6] reserved
- * [9:8] Linear_LineAlignment 00:16byte 01:32byte 10:64byte
- * [11:10] reserved
- * [12] CbCr_byte_swap
- * [31:13] reserved
- */
- WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
-#endif
-}
-
-static void vp9_config_work_space_hw(struct VP9Decoder_s *pbi, u32 mask)
-{
- struct BuffInfo_s *buf_spec = pbi->work_space_buf;
- unsigned int data32;
- int losless_comp_header_size, losless_comp_body_size;
-
- if (debug && pbi->init_flag == 0)
- pr_info("%s w %d h %d %x %x %x %x %x %x %x %x %x %x %x %x\n",
- __func__,
- buf_spec->max_width,
- buf_spec->max_height,
- buf_spec->ipp.buf_start,
- buf_spec->start_adr,
- buf_spec->short_term_rps.buf_start,
- buf_spec->vps.buf_start,
- buf_spec->sps.buf_start,
- buf_spec->pps.buf_start,
- buf_spec->sao_up.buf_start,
- buf_spec->swap_buf.buf_start,
- buf_spec->swap_buf2.buf_start,
- buf_spec->scalelut.buf_start,
- buf_spec->dblk_para.buf_start,
- buf_spec->dblk_data.buf_start);
-
- if (mask & HW_MASK_FRONT) {
- if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0)
- WRITE_VREG(HEVC_RPM_BUFFER, (u32)pbi->rpm_phy_addr);
-
- WRITE_VREG(HEVC_SHORT_TERM_RPS,
- buf_spec->short_term_rps.buf_start);
- /*WRITE_VREG(HEVC_VPS_BUFFER, buf_spec->vps.buf_start);*/
- /*WRITE_VREG(HEVC_SPS_BUFFER, buf_spec->sps.buf_start);*/
- WRITE_VREG(HEVC_PPS_BUFFER, buf_spec->pps.buf_start);
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER,
- buf_spec->swap_buf.buf_start);
- WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2,
- buf_spec->swap_buf2.buf_start);
- WRITE_VREG(LMEM_DUMP_ADR, (u32)pbi->lmem_phy_addr);
-
- }
-
- if (mask & HW_MASK_BACK) {
-#ifdef LOSLESS_COMPRESS_MODE
- losless_comp_header_size =
- compute_losless_comp_header_size(pbi->init_pic_w,
- pbi->init_pic_h);
- losless_comp_body_size =
- compute_losless_comp_body_size(pbi->init_pic_w,
- pbi->init_pic_h, buf_alloc_depth == 10);
-#endif
- WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,
- buf_spec->ipp.buf_start);
- //WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
- //WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- /* cfg_addr_adp*/
- WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_para.buf_start);
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("Write HEVC_DBLK_CFGE\n");
- }
- /* cfg_p_addr */
- WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
-
- /* cfg_d_addr */
- WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- /*
- * data32 = (READ_VREG(P_HEVC_DBLK_CFG3)>>8) & 0xff; // xio left offset, default is 0x40
- * data32 = data32 * 2;
- * data32 = (READ_VREG(P_HEVC_DBLK_CFG3)>>16) & 0xff; // adp left offset, default is 0x040
- * data32 = data32 * 2;
- */
- if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
- WRITE_VREG(HEVC_DBLK_CFG3, 0x404010); //default value
- else
- WRITE_VREG(HEVC_DBLK_CFG3, 0x808020); // make left storage 2 x 4k]
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "HEVC_DBLK_CFG3 = %x\n", READ_VREG(HEVC_DBLK_CFG3));
- }
-#ifdef LOSLESS_COMPRESS_MODE
- if (pbi->mmu_enable) {
- /*bit[4] : paged_mem_mode*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0x1 << 4));
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2, 0);
- } else {
- /*if(cur_pic_config->bit_depth == VPX_BITS_10)
- * WRITE_VREG(P_HEVCD_MPP_DECOMP_CTL1, (0<<3));
- */
- /*bit[3] smem mdoe*/
- /*else WRITE_VREG(P_HEVCD_MPP_DECOMP_CTL1, (1<<3));*/
- /*bit[3] smem mdoe*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,
- (losless_comp_body_size >> 5));
- }
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,
- (losless_comp_body_size >> 5));*/
- /*WRITE_VREG(HEVCD_MPP_DECOMP_CTL3,
- (0xff<<20) | (0xff<<10) | 0xff);*/
- /*8-bit mode */
- WRITE_VREG(HEVC_CM_BODY_LENGTH, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_OFFSET, losless_comp_body_size);
- WRITE_VREG(HEVC_CM_HEADER_LENGTH, losless_comp_header_size);
-
- if (get_double_write_mode(pbi) & 0x10)
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#else
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
-#endif
-
- if (pbi->mmu_enable) {
- WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR, buf_spec->mmu_vbh.buf_start);
- WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start
- + VBH_BUF_SIZE(buf_spec));
- /*data32 = READ_VREG(P_HEVC_SAO_CTRL9);*/
- /*data32 |= 0x1;*/
- /*WRITE_VREG(P_HEVC_SAO_CTRL9, data32);*/
-
- /* use HEVC_CM_HEADER_START_ADDR */
- data32 = READ_VREG(HEVC_SAO_CTRL5);
- data32 |= (1<<10);
- WRITE_VREG(HEVC_SAO_CTRL5, data32);
- }
-
- /* config mpred axi burst threshold */
- WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412);
-
-#ifdef CO_MV_COMPRESS
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
- data32 |= (1 << 1);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
- }
-#endif
- WRITE_VREG(VP9_SEG_MAP_BUFFER, buf_spec->seg_map.buf_start);
-
- WRITE_VREG(LMEM_DUMP_ADR, (u32)pbi->lmem_phy_addr);
- /**/
- WRITE_VREG(VP9_PROB_SWAP_BUFFER, pbi->prob_buffer_phy_addr);
- WRITE_VREG(VP9_COUNT_SWAP_BUFFER, pbi->count_buffer_phy_addr);
- if (pbi->mmu_enable) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, pbi->frame_mmu_map_phy_addr);
- else
- WRITE_VREG(VP9_MMU_MAP_BUFFER, pbi->frame_mmu_map_phy_addr);
- }
- }
-}
-
-
-#ifdef VP9_LPF_LVL_UPDATE
-/*
- * Defines, declarations, sub-functions for vp9 de-block loop
- filter Thr/Lvl table update
- * - struct segmentation is for loop filter only (removed something)
- * - function "vp9_loop_filter_init" and "vp9_loop_filter_frame_init" will
- be instantiated in C_Entry
- * - vp9_loop_filter_init run once before decoding start
- * - vp9_loop_filter_frame_init run before every frame decoding start
- * - set video format to VP9 is in vp9_loop_filter_init
- */
-#define MAX_LOOP_FILTER 63
-#define MAX_REF_LF_DELTAS 4
-#define MAX_MODE_LF_DELTAS 2
-/*#define INTRA_FRAME 0*/
-/*#define LAST_FRAME 1*/
-/*#define MAX_REF_FRAMES 4*/
-#define SEGMENT_DELTADATA 0
-#define SEGMENT_ABSDATA 1
-#define MAX_SEGMENTS 8
-/*.#define SEG_TREE_PROBS (MAX_SEGMENTS-1)*/
-/*no use for loop filter, if this struct for common use, pls add it back*/
-/*#define PREDICTION_PROBS 3*/
-/* no use for loop filter, if this struct for common use, pls add it back*/
-
-enum SEG_LVL_FEATURES {
- SEG_LVL_ALT_Q = 0, /*Use alternate Quantizer ....*/
- SEG_LVL_ALT_LF = 1, /*Use alternate loop filter value...*/
- SEG_LVL_REF_FRAME = 2, /*Optional Segment reference frame*/
- SEG_LVL_SKIP = 3, /*Optional Segment (0,0) + skip mode*/
- SEG_LVL_MAX = 4 /*Number of features supported*/
-};
-
-struct segmentation {
- uint8_t enabled;
- uint8_t update_map;
- uint8_t update_data;
- uint8_t abs_delta;
- uint8_t temporal_update;
-
- /*no use for loop filter, if this struct
- *for common use, pls add it back
- */
- /*vp9_prob tree_probs[SEG_TREE_PROBS]; */
- /* no use for loop filter, if this struct
- * for common use, pls add it back
- */
- /*vp9_prob pred_probs[PREDICTION_PROBS];*/
-
- int16_t feature_data[MAX_SEGMENTS][SEG_LVL_MAX];
- unsigned int feature_mask[MAX_SEGMENTS];
-};
-
-struct loop_filter_thresh {
- uint8_t mblim;
- uint8_t lim;
- uint8_t hev_thr;
-};
-
-struct loop_filter_info_n {
- struct loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
- uint8_t lvl[MAX_SEGMENTS][MAX_REF_FRAMES][MAX_MODE_LF_DELTAS];
-};
-
-struct loopfilter {
- int filter_level;
-
- int sharpness_level;
- int last_sharpness_level;
-
- uint8_t mode_ref_delta_enabled;
- uint8_t mode_ref_delta_update;
-
- /*0 = Intra, Last, GF, ARF*/
- signed char ref_deltas[MAX_REF_LF_DELTAS];
- signed char last_ref_deltas[MAX_REF_LF_DELTAS];
-
- /*0 = ZERO_MV, MV*/
- signed char mode_deltas[MAX_MODE_LF_DELTAS];
- signed char last_mode_deltas[MAX_MODE_LF_DELTAS];
-};
-
-static int vp9_clamp(int value, int low, int high)
-{
- return value < low ? low : (value > high ? high : value);
-}
-
-int segfeature_active(struct segmentation *seg,
- int segment_id,
- enum SEG_LVL_FEATURES feature_id) {
- return seg->enabled &&
- (seg->feature_mask[segment_id] & (1 << feature_id));
-}
-
-int get_segdata(struct segmentation *seg, int segment_id,
- enum SEG_LVL_FEATURES feature_id) {
- return seg->feature_data[segment_id][feature_id];
-}
-
-static void vp9_update_sharpness(struct loop_filter_info_n *lfi,
- int sharpness_lvl)
-{
- int lvl;
- /*For each possible value for the loop filter fill out limits*/
- for (lvl = 0; lvl <= MAX_LOOP_FILTER; lvl++) {
- /*Set loop filter parameters that control sharpness.*/
- int block_inside_limit = lvl >> ((sharpness_lvl > 0) +
- (sharpness_lvl > 4));
-
- if (sharpness_lvl > 0) {
- if (block_inside_limit > (9 - sharpness_lvl))
- block_inside_limit = (9 - sharpness_lvl);
- }
-
- if (block_inside_limit < 1)
- block_inside_limit = 1;
-
- lfi->lfthr[lvl].lim = (uint8_t)block_inside_limit;
- lfi->lfthr[lvl].mblim = (uint8_t)(2 * (lvl + 2) +
- block_inside_limit);
- }
-}
-
-/*instantiate this function once when decode is started*/
-void vp9_loop_filter_init(struct VP9Decoder_s *pbi)
-{
- struct loop_filter_info_n *lfi = pbi->lfi;
- struct loopfilter *lf = pbi->lf;
- struct segmentation *seg_4lf = pbi->seg_4lf;
- int i;
- unsigned int data32;
-
- memset(lfi, 0, sizeof(struct loop_filter_info_n));
- memset(lf, 0, sizeof(struct loopfilter));
- memset(seg_4lf, 0, sizeof(struct segmentation));
- lf->sharpness_level = 0; /*init to 0 */
- /*init limits for given sharpness*/
- vp9_update_sharpness(lfi, lf->sharpness_level);
- lf->last_sharpness_level = lf->sharpness_level;
- /*init hev threshold const vectors (actually no use)
- *for (i = 0; i <= MAX_LOOP_FILTER; i++)
- * lfi->lfthr[i].hev_thr = (uint8_t)(i >> 4);
- */
-
- /*Write to register*/
- for (i = 0; i < 32; i++) {
- unsigned int thr;
-
- thr = ((lfi->lfthr[i * 2 + 1].lim & 0x3f)<<8) |
- (lfi->lfthr[i * 2 + 1].mblim & 0xff);
- thr = (thr<<16) | ((lfi->lfthr[i*2].lim & 0x3f)<<8) |
- (lfi->lfthr[i * 2].mblim & 0xff);
- WRITE_VREG(HEVC_DBLK_CFG9, thr);
- }
-
- /*video format is VP9*/
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- data32 = (0x3 << 14) | // (dw fifo thres r and b)
- (0x3 << 12) | // (dw fifo thres r or b)
- (0x3 << 10) | // (dw fifo thres not r/b)
- (0x3 << 8) | // 1st/2nd write both enable
- (0x1 << 0); // vp9 video format
- if (get_double_write_mode(pbi) == 0x10)
- data32 &= (~0x100);
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- data32 = (0x57 << 8) | /*1st/2nd write both enable*/
- (0x1 << 0); /*vp9 video format*/
- if (get_double_write_mode(pbi) == 0x10)
- data32 &= (~0x100);
- } else
- data32 = 0x40400001;
-
- WRITE_VREG(HEVC_DBLK_CFGB, data32);
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("[DBLK DEBUG] CFGB : 0x%x\n", data32);
-}
- /* perform this function per frame*/
-void vp9_loop_filter_frame_init(struct segmentation *seg,
- struct loop_filter_info_n *lfi, struct loopfilter *lf,
- int default_filt_lvl) {
- int i;
- int seg_id;
- /*n_shift is the multiplier for lf_deltas
- *the multiplier is 1 for when filter_lvl is between 0 and 31;
- *2 when filter_lvl is between 32 and 63
- */
- const int scale = 1 << (default_filt_lvl >> 5);
-
- /*update limits if sharpness has changed*/
- if (lf->last_sharpness_level != lf->sharpness_level) {
- vp9_update_sharpness(lfi, lf->sharpness_level);
- lf->last_sharpness_level = lf->sharpness_level;
-
- /*Write to register*/
- for (i = 0; i < 32; i++) {
- unsigned int thr;
-
- thr = ((lfi->lfthr[i * 2 + 1].lim & 0x3f) << 8)
- | (lfi->lfthr[i * 2 + 1].mblim & 0xff);
- thr = (thr << 16) | ((lfi->lfthr[i * 2].lim & 0x3f) << 8)
- | (lfi->lfthr[i * 2].mblim & 0xff);
- WRITE_VREG(HEVC_DBLK_CFG9, thr);
- }
- }
-
- for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) {/*MAX_SEGMENTS = 8*/
- int lvl_seg = default_filt_lvl;
-
- if (segfeature_active(seg, seg_id, SEG_LVL_ALT_LF)) {
- const int data = get_segdata(seg, seg_id,
- SEG_LVL_ALT_LF);
- lvl_seg = vp9_clamp(seg->abs_delta == SEGMENT_ABSDATA ?
- data : default_filt_lvl + data,
- 0, MAX_LOOP_FILTER);
-#ifdef DBG_LF_PRINT
- pr_info("segfeature_active!!!seg_id=%d,lvl_seg=%d\n", seg_id, lvl_seg);
-#endif
- }
-
- if (!lf->mode_ref_delta_enabled) {
- /*we could get rid of this if we assume that deltas are set to
- *zero when not in use; encoder always uses deltas
- */
- memset(lfi->lvl[seg_id], lvl_seg, sizeof(lfi->lvl[seg_id]));
- } else {
- int ref, mode;
- const int intra_lvl = lvl_seg + lf->ref_deltas[INTRA_FRAME]
- * scale;
-#ifdef DBG_LF_PRINT
- pr_info("LF_PRINT:vp9_loop_filter_frame_init,seg_id=%d\n", seg_id);
- pr_info("ref_deltas[INTRA_FRAME]=%d\n", lf->ref_deltas[INTRA_FRAME]);
-#endif
- lfi->lvl[seg_id][INTRA_FRAME][0] =
- vp9_clamp(intra_lvl, 0, MAX_LOOP_FILTER);
-
- for (ref = LAST_FRAME; ref < MAX_REF_FRAMES; ++ref) {
- /* LAST_FRAME = 1, MAX_REF_FRAMES = 4*/
- for (mode = 0; mode < MAX_MODE_LF_DELTAS; ++mode) {
- /*MAX_MODE_LF_DELTAS = 2*/
- const int inter_lvl =
- lvl_seg + lf->ref_deltas[ref] * scale
- + lf->mode_deltas[mode] * scale;
-#ifdef DBG_LF_PRINT
-#endif
- lfi->lvl[seg_id][ref][mode] =
- vp9_clamp(inter_lvl, 0,
- MAX_LOOP_FILTER);
- }
- }
- }
- }
-
-#ifdef DBG_LF_PRINT
- /*print out thr/lvl table per frame*/
- for (i = 0; i <= MAX_LOOP_FILTER; i++) {
- pr_info("LF_PRINT:(%d)thr=%d,blim=%d,lim=%d\n",
- i, lfi->lfthr[i].hev_thr, lfi->lfthr[i].mblim,
- lfi->lfthr[i].lim);
- }
- for (seg_id = 0; seg_id < MAX_SEGMENTS; seg_id++) {
- pr_info("LF_PRINT:lvl(seg_id=%d)(mode=0,%d,%d,%d,%d)\n",
- seg_id, lfi->lvl[seg_id][0][0],
- lfi->lvl[seg_id][1][0], lfi->lvl[seg_id][2][0],
- lfi->lvl[seg_id][3][0]);
- pr_info("i(mode=1,%d,%d,%d,%d)\n", lfi->lvl[seg_id][0][1],
- lfi->lvl[seg_id][1][1], lfi->lvl[seg_id][2][1],
- lfi->lvl[seg_id][3][1]);
- }
-#endif
-
- /*Write to register */
- for (i = 0; i < 16; i++) {
- unsigned int level;
-
- level = ((lfi->lvl[i >> 1][3][i & 1] & 0x3f) << 24) |
- ((lfi->lvl[i >> 1][2][i & 1] & 0x3f) << 16) |
- ((lfi->lvl[i >> 1][1][i & 1] & 0x3f) << 8) |
- (lfi->lvl[i >> 1][0][i & 1] & 0x3f);
- if (!default_filt_lvl)
- level = 0;
- WRITE_VREG(HEVC_DBLK_CFGA, level);
- }
-}
-/* VP9_LPF_LVL_UPDATE */
-#endif
-
-static void vp9_init_decoder_hw(struct VP9Decoder_s *pbi, u32 mask)
-{
- unsigned int data32;
- int i;
- const unsigned short parser_cmd[PARSER_CMD_NUMBER] = {
- 0x0401, 0x8401, 0x0800, 0x0402, 0x9002, 0x1423,
- 0x8CC3, 0x1423, 0x8804, 0x9825, 0x0800, 0x04FE,
- 0x8406, 0x8411, 0x1800, 0x8408, 0x8409, 0x8C2A,
- 0x9C2B, 0x1C00, 0x840F, 0x8407, 0x8000, 0x8408,
- 0x2000, 0xA800, 0x8410, 0x04DE, 0x840C, 0x840D,
- 0xAC00, 0xA000, 0x08C0, 0x08E0, 0xA40E, 0xFC00,
- 0x7C00
- };
-#if 0
- if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A) {
- /* Set MCR fetch priorities*/
- data32 = 0x1 | (0x1 << 2) | (0x1 <<3) |
- (24 << 4) | (32 << 11) | (24 << 18) | (32 << 25);
- WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL, data32);
- }
-#endif
- /*if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("%s\n", __func__);*/
- if (mask & HW_MASK_FRONT) {
- data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
-#if 1
- /* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
- data32 &= ~(7 << 29);
- data32 |= (3 << 29);
-#endif
- data32 = data32 |
- (1 << 24) |/*stream_buffer_empty_int_amrisc_enable*/
- (1 << 22) |/*stream_fifo_empty_int_amrisc_enable*/
- (1 << 7) |/*dec_done_int_cpu_enable*/
- (1 << 4) |/*startcode_found_int_cpu_enable*/
- (0 << 3) |/*startcode_found_int_amrisc_enable*/
- (1 << 0) /*parser_int_enable*/
- ;
-#ifdef SUPPORT_FB_DECODING
-#ifndef FB_DECODING_TEST_SCHEDULE
- /*fed_fb_slice_done_int_cpu_enable*/
- if (pbi->used_stage_buf_num > 0)
- data32 |= (1 << 10);
-#endif
-#endif
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, data32);
-
- data32 = READ_VREG(HEVC_SHIFT_STATUS);
- data32 = data32 |
- (0 << 1) |/*emulation_check_off VP9
- do not have emulation*/
- (1 << 0)/*startcode_check_on*/
- ;
- WRITE_VREG(HEVC_SHIFT_STATUS, data32);
- WRITE_VREG(HEVC_SHIFT_CONTROL,
- (0 << 14) | /*disable_start_code_protect*/
- (1 << 10) | /*length_zero_startcode_en for VP9*/
- (1 << 9) | /*length_valid_startcode_en for VP9*/
- (3 << 6) | /*sft_valid_wr_position*/
- (2 << 4) | /*emulate_code_length_sub_1*/
- (3 << 1) | /*start_code_length_sub_1
- VP9 use 0x00000001 as startcode (4 Bytes)*/
- (1 << 0) /*stream_shift_enable*/
- );
-
- WRITE_VREG(HEVC_CABAC_CONTROL,
- (1 << 0)/*cabac_enable*/
- );
-
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
- (1 << 0)/* hevc_parser_core_clk_en*/
- );
-
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, 0);
-
- }
-
- if (mask & HW_MASK_BACK) {
- /*Initial IQIT_SCALELUT memory
- -- just to avoid X in simulation*/
- if (is_rdma_enable())
- rdma_back_end_work(pbi->rdma_phy_adr, RDMA_SIZE);
- else {
- WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/
- for (i = 0; i < 1024; i++)
- WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0);
- }
- }
-
- if (mask & HW_MASK_FRONT) {
- u32 decode_mode;
-#ifdef ENABLE_SWAP_TEST
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
-#else
- WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
-#endif
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!pbi->m_ins_flag) {
- if (pbi->low_latency_flag)
- decode_mode = DECODE_MODE_SINGLE_LOW_LATENCY;
- else
- decode_mode = DECODE_MODE_SINGLE;
- } else if (vdec_frame_based(hw_to_vdec(pbi)))
- decode_mode = pbi->no_head ?
- DECODE_MODE_MULTI_FRAMEBASE_NOHEAD :
- DECODE_MODE_MULTI_FRAMEBASE;
- else
- decode_mode = DECODE_MODE_MULTI_STREAMBASE;
-#ifdef SUPPORT_FB_DECODING
-#ifndef FB_DECODING_TEST_SCHEDULE
- if (pbi->used_stage_buf_num > 0)
- decode_mode |= (0x01 << 24);
-#endif
-#endif
- WRITE_VREG(DECODE_MODE, decode_mode);
- WRITE_VREG(HEVC_DECODE_SIZE, 0);
- WRITE_VREG(HEVC_DECODE_COUNT, 0);
-#else
- WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE);
- WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
- WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, 0x7fffffff); /*to remove*/
-#endif
- /*Send parser_cmd*/
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, (1 << 16) | (0 << 0));
- for (i = 0; i < PARSER_CMD_NUMBER; i++)
- WRITE_VREG(HEVC_PARSER_CMD_WRITE, parser_cmd[i]);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_0, PARSER_CMD_SKIP_CFG_0);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_1, PARSER_CMD_SKIP_CFG_1);
- WRITE_VREG(HEVC_PARSER_CMD_SKIP_2, PARSER_CMD_SKIP_CFG_2);
-
-
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- /* (1 << 8) |*/ /*sao_sw_pred_enable*/
- (1 << 5) | /*parser_sao_if_en*/
- (1 << 2) | /*parser_mpred_if_en*/
- (1 << 0) /*parser_scaler_if_en*/
- );
- }
-
- if (mask & HW_MASK_BACK) {
- /*Changed to Start MPRED in microcode*/
- /*
- pr_info("[test.c] Start MPRED\n");
- WRITE_VREG(HEVC_MPRED_INT_STATUS,
- (1<<31)
- );
- */
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (0 << 1) | /*enable ipp*/
- (1 << 0) /*software reset ipp and mpp*/
- );
- WRITE_VREG(HEVCD_IPP_TOP_CNTL,
- (1 << 1) | /*enable ipp*/
- (0 << 0) /*software reset ipp and mpp*/
- );
- if (get_double_write_mode(pbi) & 0x10) {
- /*Enable NV21 reference read mode for MC*/
- WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
- }
-
- /*Initialize mcrcc and decomp perf counters*/
- if (mcrcc_cache_alg_flag &&
- pbi->init_flag == 0) {
- mcrcc_perfcount_reset();
- decomp_perfcount_reset();
- }
- }
- return;
-}
-
-
-#ifdef CONFIG_HEVC_CLK_FORCED_ON
-static void config_vp9_clk_forced_on(void)
-{
- unsigned int rdata32;
- /*IQIT*/
- rdata32 = READ_VREG(HEVC_IQIT_CLK_RST_CTRL);
- WRITE_VREG(HEVC_IQIT_CLK_RST_CTRL, rdata32 | (0x1 << 2));
-
- /* DBLK*/
- rdata32 = READ_VREG(HEVC_DBLK_CFG0);
- WRITE_VREG(HEVC_DBLK_CFG0, rdata32 | (0x1 << 2));
-
- /* SAO*/
- rdata32 = READ_VREG(HEVC_SAO_CTRL1);
- WRITE_VREG(HEVC_SAO_CTRL1, rdata32 | (0x1 << 2));
-
- /*MPRED*/
- rdata32 = READ_VREG(HEVC_MPRED_CTRL1);
- WRITE_VREG(HEVC_MPRED_CTRL1, rdata32 | (0x1 << 24));
-
- /* PARSER*/
- rdata32 = READ_VREG(HEVC_STREAM_CONTROL);
- WRITE_VREG(HEVC_STREAM_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_SHIFT_CONTROL);
- WRITE_VREG(HEVC_SHIFT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_CABAC_CONTROL);
- WRITE_VREG(HEVC_CABAC_CONTROL, rdata32 | (0x1 << 13));
- rdata32 = READ_VREG(HEVC_PARSER_CORE_CONTROL);
- WRITE_VREG(HEVC_PARSER_CORE_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
- WRITE_VREG(HEVC_PARSER_INT_CONTROL, rdata32 | (0x1 << 15));
- rdata32 = READ_VREG(HEVC_PARSER_IF_CONTROL);
- WRITE_VREG(HEVC_PARSER_IF_CONTROL,
- rdata32 | (0x1 << 6) | (0x1 << 3) | (0x1 << 1));
-
- /*IPP*/
- rdata32 = READ_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG);
- WRITE_VREG(HEVCD_IPP_DYNCLKGATE_CONFIG, rdata32 | 0xffffffff);
-
- /* MCRCC*/
- rdata32 = READ_VREG(HEVCD_MCRCC_CTL1);
- WRITE_VREG(HEVCD_MCRCC_CTL1, rdata32 | (0x1 << 3));
-}
-#endif
-
-
-#ifdef MCRCC_ENABLE
-static void dump_hit_rate(struct VP9Decoder_s *pbi)
-{
- if (debug & VP9_DEBUG_CACHE_HIT_RATE) {
- mcrcc_get_hitrate(pbi->m_ins_flag);
- decomp_get_hitrate();
- decomp_get_comprate();
- }
-}
-
-static void config_mcrcc_axi_hw(struct VP9Decoder_s *pbi)
-{
- unsigned int rdata32;
- unsigned short is_inter;
- /*pr_info("Entered config_mcrcc_axi_hw...\n");*/
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2);/* reset mcrcc*/
- is_inter = ((pbi->common.frame_type != KEY_FRAME) &&
- (!pbi->common.intra_only)) ? 1 : 0;
- if (!is_inter) { /* I-PIC*/
- /*remove reset -- disables clock*/
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
- return;
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- mcrcc_get_hitrate(pbi->m_ins_flag);
- decomp_get_hitrate();
- decomp_get_comprate();
- }
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (1 << 1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
- /*Programme canvas1 */
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- /*enable mcrcc progressive-mode*/
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0);
-}
-
-static void config_mcrcc_axi_hw_new(struct VP9Decoder_s *pbi)
-{
- u32 curr_picnum = -1;
- u32 lastref_picnum = -1;
- u32 goldenref_picnum = -1;
- u32 altref_picnum = -1;
-
- u32 lastref_delta_picnum;
- u32 goldenref_delta_picnum;
- u32 altref_delta_picnum;
-
- u32 rdata32;
-
- u32 lastcanvas;
- u32 goldencanvas;
- u32 altrefcanvas;
-
- u16 is_inter;
- u16 lastref_inref;
- u16 goldenref_inref;
- u16 altref_inref;
-
- u32 refcanvas_array[3], utmp;
- int deltapicnum_array[3], tmp;
-
- struct VP9_Common_s *cm = &pbi->common;
- struct PIC_BUFFER_CONFIG_s *cur_pic_config
- = &cm->cur_frame->buf;
- curr_picnum = cur_pic_config->decode_idx;
- if (cm->frame_refs[0].buf)
- lastref_picnum = cm->frame_refs[0].buf->decode_idx;
- if (cm->frame_refs[1].buf)
- goldenref_picnum = cm->frame_refs[1].buf->decode_idx;
- if (cm->frame_refs[2].buf)
- altref_picnum = cm->frame_refs[2].buf->decode_idx;
-
- lastref_delta_picnum = (lastref_picnum >= curr_picnum) ?
- (lastref_picnum - curr_picnum) : (curr_picnum - lastref_picnum);
- goldenref_delta_picnum = (goldenref_picnum >= curr_picnum) ?
- (goldenref_picnum - curr_picnum) :
- (curr_picnum - goldenref_picnum);
- altref_delta_picnum =
- (altref_picnum >= curr_picnum) ?
- (altref_picnum - curr_picnum) : (curr_picnum - altref_picnum);
-
- lastref_inref = (cm->frame_refs[0].idx != INVALID_IDX) ? 1 : 0;
- goldenref_inref = (cm->frame_refs[1].idx != INVALID_IDX) ? 1 : 0;
- altref_inref = (cm->frame_refs[2].idx != INVALID_IDX) ? 1 : 0;
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("%s--0--lastref_inref:%d goldenref_inref:%d altref_inref:%d\n",
- __func__, lastref_inref, goldenref_inref, altref_inref);
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); /* reset mcrcc */
-
- is_inter = ((pbi->common.frame_type != KEY_FRAME)
- && (!pbi->common.intra_only)) ? 1 : 0;
-
- if (!is_inter) { /* I-PIC */
- /* remove reset -- disables clock */
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0);
- return;
- }
-
- if (!pbi->m_ins_flag)
- dump_hit_rate(pbi);
-
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
- lastcanvas = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- goldencanvas = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- altrefcanvas = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
-
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[test.c] lastref_canv:%x goldenref_canv:%x altref_canv:%x\n",
- lastcanvas, goldencanvas, altrefcanvas);
-
- altref_inref = ((altref_inref == 1) &&
- (altrefcanvas != (goldenref_inref
- ? goldencanvas : 0xffffffff)) &&
- (altrefcanvas != (lastref_inref ?
- lastcanvas : 0xffffffff))) ? 1 : 0;
- goldenref_inref = ((goldenref_inref == 1) &&
- (goldencanvas != (lastref_inref ?
- lastcanvas : 0xffffffff))) ? 1 : 0;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[test.c]--1--lastref_inref:%d goldenref_inref:%d altref_inref:%d\n",
- lastref_inref, goldenref_inref, altref_inref);
-
- altref_delta_picnum = altref_inref ? altref_delta_picnum : 0x7fffffff;
- goldenref_delta_picnum = goldenref_inref ?
- goldenref_delta_picnum : 0x7fffffff;
- lastref_delta_picnum = lastref_inref ?
- lastref_delta_picnum : 0x7fffffff;
- if (debug & VP9_DEBUG_CACHE)
- pr_info("[test.c]--1--lastref_delta_picnum:%d goldenref_delta_picnum:%d altref_delta_picnum:%d\n",
- lastref_delta_picnum, goldenref_delta_picnum,
- altref_delta_picnum);
- /*ARRAY SORT HERE DELTA/CANVAS ARRAY SORT -- use DELTA*/
-
- refcanvas_array[0] = lastcanvas;
- refcanvas_array[1] = goldencanvas;
- refcanvas_array[2] = altrefcanvas;
-
- deltapicnum_array[0] = lastref_delta_picnum;
- deltapicnum_array[1] = goldenref_delta_picnum;
- deltapicnum_array[2] = altref_delta_picnum;
-
- /* sort0 : 2-to-1 */
- if (deltapicnum_array[2] < deltapicnum_array[1]) {
- utmp = refcanvas_array[2];
- refcanvas_array[2] = refcanvas_array[1];
- refcanvas_array[1] = utmp;
- tmp = deltapicnum_array[2];
- deltapicnum_array[2] = deltapicnum_array[1];
- deltapicnum_array[1] = tmp;
- }
- /* sort1 : 1-to-0 */
- if (deltapicnum_array[1] < deltapicnum_array[0]) {
- utmp = refcanvas_array[1];
- refcanvas_array[1] = refcanvas_array[0];
- refcanvas_array[0] = utmp;
- tmp = deltapicnum_array[1];
- deltapicnum_array[1] = deltapicnum_array[0];
- deltapicnum_array[0] = tmp;
- }
- /* sort2 : 2-to-1 */
- if (deltapicnum_array[2] < deltapicnum_array[1]) {
- utmp = refcanvas_array[2]; refcanvas_array[2] =
- refcanvas_array[1]; refcanvas_array[1] = utmp;
- tmp = deltapicnum_array[2]; deltapicnum_array[2] =
- deltapicnum_array[1]; deltapicnum_array[1] = tmp;
- }
- if (mcrcc_cache_alg_flag ==
- THODIYIL_MCRCC_CANVAS_ALGX) { /*09/15/2017*/
- /* lowest delta_picnum */
- rdata32 = refcanvas_array[0];
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- /* 2nd-lowest delta_picnum */
- rdata32 = refcanvas_array[1];
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- } else {
- /* previous version -- LAST/GOLDEN ALWAYS -- before 09/13/2017*/
- WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
- (0 << 8) | (1<<1) | 0);
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL2, rdata32);
-
- /* Programme canvas1 */
- rdata32 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
- rdata32 = rdata32 & 0xffff;
- rdata32 = rdata32 | (rdata32 << 16);
- WRITE_VREG(HEVCD_MCRCC_CTL3, rdata32);
- }
-
- WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); /* enable mcrcc progressive-mode */
- return;
-}
-
-#endif
-
-
-static void free_lf_buf(struct VP9Decoder_s *pbi)
-{
- if (pbi->lfi)
- vfree(pbi->lfi);
- if (pbi->lf)
- vfree(pbi->lf);
- if (pbi->seg_4lf)
- vfree(pbi->seg_4lf);
- pbi->lfi = NULL;
- pbi->lf = NULL;
- pbi->seg_4lf = NULL;
-}
-
-static int alloc_lf_buf(struct VP9Decoder_s *pbi)
-{
- pbi->lfi = vmalloc(sizeof(struct loop_filter_info_n));
- pbi->lf = vmalloc(sizeof(struct loopfilter));
- pbi->seg_4lf = vmalloc(sizeof(struct segmentation));
- if (pbi->lfi == NULL || pbi->lf == NULL || pbi->seg_4lf == NULL) {
- free_lf_buf(pbi);
- pr_err("[test.c] vp9_loop_filter init malloc error!!!\n");
- return -1;
- }
- return 0;
-}
-
-static void vp9_local_uninit(struct VP9Decoder_s *pbi)
-{
- pbi->rpm_ptr = NULL;
- pbi->lmem_ptr = NULL;
- if (pbi->rpm_addr) {
- dma_free_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE,
- pbi->rpm_addr,
- pbi->rpm_phy_addr);
- pbi->rpm_addr = NULL;
- }
- if (pbi->lmem_addr) {
- if (pbi->lmem_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE, pbi->lmem_addr,
- pbi->lmem_phy_addr);
- pbi->lmem_addr = NULL;
- }
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- tee_vp9_prob_free((u32)pbi->prob_buffer_phy_addr);
- pbi->prob_buffer_phy_addr = 0;
- pbi->count_buffer_phy_addr = 0;
- pbi->prob_buffer_addr = NULL;
- pbi->count_buffer_addr = NULL;
- } else {
- if (pbi->prob_buffer_addr) {
- if (pbi->prob_buffer_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- PROB_BUF_SIZE, pbi->prob_buffer_addr,
- pbi->prob_buffer_phy_addr);
-
- pbi->prob_buffer_addr = NULL;
- }
- if (pbi->count_buffer_addr) {
- if (pbi->count_buffer_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- COUNT_BUF_SIZE, pbi->count_buffer_addr,
- pbi->count_buffer_phy_addr);
-
- pbi->count_buffer_addr = NULL;
- }
- }
- if (pbi->mmu_enable) {
- u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi);
- if (pbi->frame_mmu_map_addr) {
- if (pbi->frame_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- mmu_map_size,
- pbi->frame_mmu_map_addr,
- pbi->frame_mmu_map_phy_addr);
- pbi->frame_mmu_map_addr = NULL;
- }
- }
-#ifdef SUPPORT_FB_DECODING
- if (pbi->stage_mmu_map_addr) {
- if (pbi->stage_mmu_map_phy_addr)
- dma_free_coherent(amports_get_dma_device(),
- STAGE_MMU_MAP_SIZE * STAGE_MAX_BUFFERS,
- pbi->stage_mmu_map_addr,
- pbi->stage_mmu_map_phy_addr);
- pbi->stage_mmu_map_addr = NULL;
- }
-
- uninit_stage_buf(pbi);
-#endif
-
-#ifdef VP9_LPF_LVL_UPDATE
- free_lf_buf(pbi);
-#endif
- if (pbi->gvs)
- vfree(pbi->gvs);
- pbi->gvs = NULL;
-}
-
-static int vp9_local_init(struct VP9Decoder_s *pbi)
-{
- int ret = -1;
- /*int losless_comp_header_size, losless_comp_body_size;*/
-
- struct BuffInfo_s *cur_buf_info = NULL;
-
- memset(&pbi->param, 0, sizeof(union param_u));
- memset(&pbi->common, 0, sizeof(struct VP9_Common_s));
-#ifdef MULTI_INSTANCE_SUPPORT
- cur_buf_info = &pbi->work_space_buf_store;
- if (force_bufspec) {
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[force_bufspec & 0xf],
- sizeof(struct BuffInfo_s));
- pr_info("force buffer spec %d\n", force_bufspec & 0xf);
- } else {
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[2], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[1], /* 4k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[0],/* 1080p */
- sizeof(struct BuffInfo_s));
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[5], /* 8k */
- sizeof(struct BuffInfo_s));
- } else
- memcpy(cur_buf_info, &amvvp9_workbuff_spec[3],/* 1080p */
- sizeof(struct BuffInfo_s));
- }
- }
-
- cur_buf_info->start_adr = pbi->buf_start;
- if (!pbi->mmu_enable)
- pbi->mc_buf_spec.buf_end = pbi->buf_start + pbi->buf_size;
-
-#else
-/*! MULTI_INSTANCE_SUPPORT*/
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- cur_buf_info = &amvvp9_workbuff_spec[2];/* 8k work space */
- else
- cur_buf_info = &amvvp9_workbuff_spec[1];/* 4k2k work space */
- } else
- cur_buf_info = &amvvp9_workbuff_spec[0];/* 1080p work space */
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k()) {
- cur_buf_info = &amvvp9_workbuff_spec[5];/* 8k work space */
- } else
- cur_buf_info = &amvvp9_workbuff_spec[3];/* 1080p work space */
- }
-
-#endif
-
- init_buff_spec(pbi, cur_buf_info);
- vp9_bufmgr_init(pbi, cur_buf_info, NULL);
-
- if (!vdec_is_support_4k()
- && (buf_alloc_width > 1920 && buf_alloc_height > 1088)) {
- buf_alloc_width = 1920;
- buf_alloc_height = 1088;
- if (pbi->max_pic_w > 1920 && pbi->max_pic_h > 1088) {
- pbi->max_pic_w = 1920;
- pbi->max_pic_h = 1088;
- }
- } else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
- buf_alloc_width = 8192;
- buf_alloc_height = 4608;
- }
- pbi->init_pic_w = pbi->max_pic_w ? pbi->max_pic_w :
- (buf_alloc_width ? buf_alloc_width :
- (pbi->vvp9_amstream_dec_info.width ?
- pbi->vvp9_amstream_dec_info.width :
- pbi->work_space_buf->max_width));
- pbi->init_pic_h = pbi->max_pic_h ? pbi->max_pic_h :
- (buf_alloc_height ? buf_alloc_height :
- (pbi->vvp9_amstream_dec_info.height ?
- pbi->vvp9_amstream_dec_info.height :
- pbi->work_space_buf->max_height));
-
- /* video is not support unaligned with 64 in tl1
- ** vdec canvas mode will be linear when dump yuv is set
- */
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (pbi->double_write_mode != 0) &&
- (((pbi->max_pic_w % 64) != 0) ||
- (pbi->vvp9_amstream_dec_info.width % 64) != 0)) {
- if (hw_to_vdec(pbi)->canvas_mode !=
- CANVAS_BLKMODE_LINEAR)
- pbi->mem_map_mode = 2;
- else {
- pbi->mem_map_mode = 0;
- pr_info("vdec blkmod linear, force mem_map_mode 0\n");
- }
- }
-
-#ifndef MV_USE_FIXED_BUF
- if (!pbi->is_used_v4l) {
- if (init_mv_buf_list(pbi) < 0) {
- pr_err("%s: init_mv_buf_list fail\n", __func__);
- return -1;
- }
- }
-#endif
-
- pbi->pts_unstable = ((unsigned long)(pbi->vvp9_amstream_dec_info.param)
- & 0x40) >> 6;
-
- if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
- pbi->rpm_addr = dma_alloc_coherent(amports_get_dma_device(),
- RPM_BUF_SIZE,
- &pbi->rpm_phy_addr, GFP_KERNEL);
- if (pbi->rpm_addr == NULL) {
- pr_err("%s: failed to alloc rpm buffer\n", __func__);
- return -1;
- }
-
- pbi->rpm_ptr = pbi->rpm_addr;
- }
-
- pbi->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
- LMEM_BUF_SIZE,
- &pbi->lmem_phy_addr, GFP_KERNEL);
- if (pbi->lmem_addr == NULL) {
- pr_err("%s: failed to alloc lmem buffer\n", __func__);
- return -1;
- }
- pbi->lmem_ptr = pbi->lmem_addr;
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- u32 prob_addr, id;
- id = tee_vp9_prob_malloc(&prob_addr);
- if (prob_addr <= 0)
- pr_err("%s, tee[%d] malloc prob buf failed\n", __func__, id);
- else {
- pbi->prob_buffer_phy_addr = prob_addr;
- pbi->count_buffer_phy_addr = pbi->prob_buffer_phy_addr + PROB_BUF_SIZE;
- }
- pbi->prob_buffer_addr = NULL;
- pbi->count_buffer_addr = NULL;
- } else {
- pbi->prob_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
- PROB_BUF_SIZE,
- &pbi->prob_buffer_phy_addr, GFP_KERNEL);
- if (pbi->prob_buffer_addr == NULL) {
- pr_err("%s: failed to alloc prob_buffer\n", __func__);
- return -1;
- }
- memset(pbi->prob_buffer_addr, 0, PROB_BUF_SIZE);
- pbi->count_buffer_addr = dma_alloc_coherent(amports_get_dma_device(),
- COUNT_BUF_SIZE,
- &pbi->count_buffer_phy_addr, GFP_KERNEL);
- if (pbi->count_buffer_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(pbi->count_buffer_addr, 0, COUNT_BUF_SIZE);
- }
-
- if (pbi->mmu_enable) {
- u32 mmu_map_size = vvp9_frame_mmu_map_size(pbi);
- pbi->frame_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- mmu_map_size,
- &pbi->frame_mmu_map_phy_addr, GFP_KERNEL);
- if (pbi->frame_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(pbi->frame_mmu_map_addr, 0, COUNT_BUF_SIZE);
- }
-#ifdef SUPPORT_FB_DECODING
- if (pbi->m_ins_flag && stage_buf_num > 0) {
- pbi->stage_mmu_map_addr =
- dma_alloc_coherent(amports_get_dma_device(),
- STAGE_MMU_MAP_SIZE * STAGE_MAX_BUFFERS,
- &pbi->stage_mmu_map_phy_addr, GFP_KERNEL);
- if (pbi->stage_mmu_map_addr == NULL) {
- pr_err("%s: failed to alloc count_buffer\n", __func__);
- return -1;
- }
- memset(pbi->stage_mmu_map_addr,
- 0, STAGE_MMU_MAP_SIZE * STAGE_MAX_BUFFERS);
-
- init_stage_buf(pbi);
- }
-#endif
-
- ret = 0;
- return ret;
-}
-
-/********************************************
- * Mailbox command
- ********************************************/
-#define CMD_FINISHED 0
-#define CMD_ALLOC_VIEW 1
-#define CMD_FRAME_DISPLAY 3
-#define CMD_DEBUG 10
-
-
-#define DECODE_BUFFER_NUM_MAX 32
-#define DISPLAY_BUFFER_NUM 6
-
-#define video_domain_addr(adr) (adr&0x7fffffff)
-#define DECODER_WORK_SPACE_SIZE 0x800000
-
-#define spec2canvas(x) \
- (((x)->uv_canvas_index << 16) | \
- ((x)->uv_canvas_index << 8) | \
- ((x)->y_canvas_index << 0))
-
-
-static void set_canvas(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- struct vdec_s *vdec = hw_to_vdec(pbi);
- int canvas_w = ALIGN(pic_config->y_crop_width, 64)/4;
- int canvas_h = ALIGN(pic_config->y_crop_height, 32)/4;
- int blkmode = pbi->mem_map_mode;
- /*CANVAS_BLKMODE_64X32*/
- if (pic_config->double_write_mode) {
- canvas_w = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode);
- canvas_h = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode);
-
- /* sao ctrl1 reg alignline with 64, align with 64 */
- canvas_w = ALIGN(canvas_w, 64);
- canvas_h = ALIGN(canvas_h, 32);
-
- if (vdec->parallel_dec == 1) {
- if (pic_config->y_canvas_index == -1)
- pic_config->y_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- if (pic_config->uv_canvas_index == -1)
- pic_config->uv_canvas_index =
- vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
- } else {
- pic_config->y_canvas_index = 128 + pic_config->index * 2;
- pic_config->uv_canvas_index = 128 + pic_config->index * 2 + 1;
- }
-
- config_cav_lut_ex(pic_config->y_canvas_index,
- pic_config->dw_y_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC);
- config_cav_lut_ex(pic_config->uv_canvas_index,
- pic_config->dw_u_v_adr, canvas_w, canvas_h,
- CANVAS_ADDR_NOWRAP, blkmode, pbi->is_used_v4l ? 0 : 7, VDEC_HEVC);
-
-#ifdef MULTI_INSTANCE_SUPPORT
- pic_config->canvas_config[0].phy_addr =
- pic_config->dw_y_adr;
- pic_config->canvas_config[0].width =
- canvas_w;
- pic_config->canvas_config[0].height =
- canvas_h;
- pic_config->canvas_config[0].block_mode =
- blkmode;
- pic_config->canvas_config[0].endian = pbi->is_used_v4l ? 0 : 7;
-
- pic_config->canvas_config[1].phy_addr =
- pic_config->dw_u_v_adr;
- pic_config->canvas_config[1].width =
- canvas_w;
- pic_config->canvas_config[1].height =
- canvas_h;
- pic_config->canvas_config[1].block_mode =
- blkmode;
- pic_config->canvas_config[1].endian = pbi->is_used_v4l ? 0 : 7;
-#endif
- }
-}
-
-
-static void set_frame_info(struct VP9Decoder_s *pbi, struct vframe_s *vf)
-{
- unsigned int ar;
- vf->duration = pbi->frame_dur;
- vf->duration_pulldown = 0;
- vf->flag = 0;
- vf->prop.master_display_colour = pbi->vf_dp;
- vf->signal_type = pbi->video_signal_type;
- if (vf->compWidth && vf->compHeight)
- pbi->frame_ar = vf->compHeight * 0x100 / vf->compWidth;
- ar = min_t(u32, pbi->frame_ar, DISP_RATIO_ASPECT_RATIO_MAX);
- vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
-
- if (pbi->is_used_v4l && pbi->vf_dp.present_flag) {
- struct aml_vdec_hdr_infos hdr;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.signal_type = vf->signal_type;
- hdr.color_parms = pbi->vf_dp;
-
- hdr.color_parms.luminance[0] = hdr.color_parms.luminance[0] / 10000;
-
- vdec_v4l_set_hdr_infos(ctx, &hdr);
- }
-
- if ((pbi->chunk != NULL) && (pbi->chunk->hdr10p_data_buf != NULL)
- && (pbi->chunk->hdr10p_data_size != 0)) {
- if (pbi->chunk->hdr10p_data_size <= 128) {
- char *new_buf;
- int i = 0;
- new_buf = kzalloc(pbi->chunk->hdr10p_data_size, GFP_ATOMIC);
-
- if (new_buf) {
- memcpy(new_buf, pbi->chunk->hdr10p_data_buf, pbi->chunk->hdr10p_data_size);
- if (debug & VP9_DEBUG_BUFMGR_MORE) {
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "hdr10p data: (size %d)\n",
- pbi->chunk->hdr10p_data_size);
- for (i = 0; i < pbi->chunk->hdr10p_data_size; i++) {
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "%02x ", pbi->chunk->hdr10p_data_buf[i]);
- if (((i + 1) & 0xf) == 0)
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
- }
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE, "\n");
- }
-
- vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
- set_meta_data_to_vf(vf, UVM_META_DATA_HDR10P_DATA, pbi->v4l2_ctx);
- } else {
- vp9_print(pbi, 0, "%s:hdr10p data vzalloc size(%d) fail\n",
- __func__, pbi->chunk->hdr10p_data_size);
- vf->hdr10p_data_size = pbi->chunk->hdr10p_data_size;
- vf->hdr10p_data_buf = new_buf;
- }
- }
-
- vfree(pbi->chunk->hdr10p_data_buf);
- pbi->chunk->hdr10p_data_buf = NULL;
- pbi->chunk->hdr10p_data_size = 0;
- }
-
- vf->sidebind_type = pbi->sidebind_type;
- vf->sidebind_channel_id = pbi->sidebind_channel_id;
-}
-
-static int vvp9_vf_states(struct vframe_states *states, void *op_arg)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
-
- states->vf_pool_size = VF_POOL_SIZE;
- states->buf_free_num = kfifo_len(&pbi->newframe_q);
- states->buf_avail_num = kfifo_len(&pbi->display_q);
-
- if (step == 2)
- states->buf_avail_num = 0;
- return 0;
-}
-
-static struct vframe_s *vvp9_vf_peek(void *op_arg)
-{
- struct vframe_s *vf[2] = {0, 0};
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
-
- if (step == 2)
- return NULL;
-
- if (kfifo_out_peek(&pbi->display_q, (void *)&vf, 2)) {
- if (vf[1]) {
- vf[0]->next_vf_pts_valid = true;
- vf[0]->next_vf_pts = vf[1]->pts;
- } else
- vf[0]->next_vf_pts_valid = false;
- return vf[0];
- }
-
- return NULL;
-}
-
-static struct vframe_s *vvp9_vf_get(void *op_arg)
-{
- struct vframe_s *vf;
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
-
- if (step == 2)
- return NULL;
- else if (step == 1)
- step = 2;
-
- if (kfifo_get(&pbi->display_q, &vf)) {
- struct vframe_s *next_vf = NULL;
- uint8_t index = vf->index & 0xff;
- ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q));
- if (index < pbi->used_buf_num ||
- (vf->type & VIDTYPE_V4L_EOS)) {
- vf->index_disp = atomic_read(&pbi->vf_get_count);
- atomic_add(1, &pbi->vf_get_count);
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("%s idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n",
- __func__, index, vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64,
- vf->timestamp);
-
- if (kfifo_peek(&pbi->display_q, &next_vf) && next_vf) {
- vf->next_vf_pts_valid = true;
- vf->next_vf_pts = next_vf->pts;
- } else
- vf->next_vf_pts_valid = false;
-
- return vf;
- }
- }
-
- return NULL;
-}
-
-static void vvp9_vf_put(struct vframe_s *vf, void *op_arg)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)op_arg;
- uint8_t index;
-
- if (vf == (&pbi->vframe_dummy))
- return;
-
- if (!vf)
- return;
-
- if (pbi->enable_fence && vf->fence) {
- int ret, i;
-
- mutex_lock(&pbi->fence_mutex);
- ret = dma_fence_get_status(vf->fence);
- if (ret == 0) {
- for (i = 0; i < VF_POOL_SIZE; i++) {
- if (pbi->fence_vf_s.fence_vf[i] == NULL) {
- pbi->fence_vf_s.fence_vf[i] = vf;
- pbi->fence_vf_s.used_size++;
- mutex_unlock(&pbi->fence_mutex);
- return;
- }
- }
- }
- mutex_unlock(&pbi->fence_mutex);
- }
-
- index = vf->index & 0xff;
-
- if (pbi->enable_fence && vf->fence) {
- vdec_fence_put(vf->fence);
- vf->fence = NULL;
- }
-
- if (vf->hdr10p_data_buf) {
- kfree(vf->hdr10p_data_buf);
- vf->hdr10p_data_buf = NULL;
- vf->hdr10p_data_size = 0;
- }
-
- if (vf->meta_data_buf) {
- vf->meta_data_buf = NULL;
- vf->meta_data_size = 0;
- }
-
- kfifo_put(&pbi->newframe_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q));
- atomic_add(1, &pbi->vf_put_count);
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("%s vf:%px, idx: %d, type 0x%x w/h %d/%d, pts %d, %lld, ts: %lld\n",
- __func__, vf, index, vf->type,
- vf->width, vf->height,
- vf->pts,
- vf->pts_us64,
- vf->timestamp);
-
- if (index < pbi->used_buf_num) {
- struct VP9_Common_s *cm = &pbi->common;
- struct BufferPool_s *pool = cm->buffer_pool;
- struct PIC_BUFFER_CONFIG_s *pic = &pool->frame_bufs[index].buf;
- unsigned long flags;
-
- if (vf->v4l_mem_handle !=
- pbi->m_BUF[pic->BUF_index].v4l_ref_buf_addr) {
- vp9_print(pbi, PRINT_FLAG_V4L_DETAIL,
- "VP9 update fb handle, old:%llx, new:%llx\n",
- pbi->m_BUF[pic->BUF_index].v4l_ref_buf_addr,
- vf->v4l_mem_handle);
-
- pbi->m_BUF[pic->BUF_index].v4l_ref_buf_addr =
- vf->v4l_mem_handle;
- }
-
- lock_buffer_pool(pool, flags);
- if (pic->repeat_pic) {
- if (pic->repeat_pic->repeat_count > 0)
- pic->repeat_pic->repeat_count --;
- else
- vp9_print(pbi, PRINT_FLAG_ERROR, "repeat_count <= 0 pic:%px\n", pic);
- pic->repeat_pic = NULL;
- }
- if (pool->frame_bufs[index].buf.vf_ref > 0)
- pool->frame_bufs[index].buf.vf_ref--;
-
- if (pbi->wait_buf)
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- pbi->last_put_idx = index;
- pbi->new_frame_displayed++;
- unlock_buffer_pool(pool, flags);
-
- spin_lock_irqsave(&pbi->wait_buf_lock, flags);
-
- if (pbi->wait_more_buf) {
- pbi->wait_more_buf = false;
- pbi->dec_result = DEC_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&pbi->work);
- }
- spin_unlock_irqrestore(&pbi->wait_buf_lock, flags);
-
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0 &&
- pbi->back_not_run_ready)
- trigger_schedule(pbi);
-#endif
- }
-
-}
-
-
-static int vvp9_event_cb(int type, void *data, void *private_data)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)private_data;
-
- if (type & VFRAME_EVENT_RECEIVER_RESET) {
-#if 0
- unsigned long flags;
-
- amhevc_stop();
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_light_unreg_provider(&vvp9_vf_prov);
-#endif
- spin_lock_irqsave(&pbi->lock, flags);
- vvp9_local_init();
- vvp9_prot_init();
- spin_unlock_irqrestore(&pbi->lock, flags);
-#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
- vf_reg_provider(&vvp9_vf_prov);
-#endif
- amhevc_start();
-#endif
- } else if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) {
- struct provider_state_req_s *req =
- (struct provider_state_req_s *)data;
- if (req->req_type == REQ_STATE_SECURE)
- req->req_result[0] = vdec_secure(hw_to_vdec(pbi));
- else
- req->req_result[0] = 0xffffffff;
- }
-
- return 0;
-}
-
-void inc_vf_ref(struct VP9Decoder_s *pbi, int index)
-{
- struct VP9_Common_s *cm = &pbi->common;
-
- cm->buffer_pool->frame_bufs[index].buf.vf_ref++;
-
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("%s index = %d new vf_ref = %d\r\n",
- __func__, index,
- cm->buffer_pool->frame_bufs[index].buf.vf_ref);
-}
-
-static int frame_duration_adapt(struct VP9Decoder_s *pbi, struct vframe_s *vf, u32 valid)
-{
- u32 old_duration, pts_duration = 0;
- u32 pts = vf->pts;
-
- if (pbi->get_frame_dur == true)
- return true;
-
- pbi->frame_cnt_window++;
- if (!(pbi->vp9_first_pts_ready == 1)) {
- if (valid) {
- pbi->pts1 = pts;
- pbi->frame_cnt_window = 0;
- pbi->duration_from_pts_done = 0;
- pbi->vp9_first_pts_ready = 1;
- } else {
- return false;
- }
- } else {
- if (pts < pbi->pts1) {
- if (pbi->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) {
- pbi->pts1 = pts;
- pbi->frame_cnt_window = 0;
- }
- }
-
- if (valid && (pbi->frame_cnt_window > FRAME_CNT_WINDOW_SIZE) &&
- (pts > pbi->pts1) && (pbi->duration_from_pts_done == 0)) {
- old_duration = pbi->frame_dur;
- pbi->pts2 = pts;
- pts_duration = (((pbi->pts2 - pbi->pts1) * 16) /
- (pbi->frame_cnt_window * 15));
-
- if (close_to(pts_duration, old_duration, 2000)) {
- pbi->frame_dur = pts_duration;
- if ((debug & VP9_DEBUG_OUT_PTS) != 0)
- pr_info("use calc duration %d\n", pts_duration);
- }
-
- if (pbi->duration_from_pts_done == 0) {
- if (close_to(pts_duration, old_duration, RATE_CORRECTION_THRESHOLD)) {
- pbi->duration_from_pts_done = 1;
- } else {
- if (!close_to(pts_duration,
- old_duration, 1000) &&
- !close_to(pts_duration,
- pbi->frame_dur, 1000) &&
- close_to(pts_duration,
- pbi->last_duration, 200)) {
- /* frame_dur must
- * wrong,recover it.
- */
- pbi->frame_dur = pts_duration;
- }
- pbi->pts1 = pbi->pts2;
- pbi->frame_cnt_window = 0;
- pbi->duration_from_pts_done = 0;
- }
- }
- pbi->last_duration = pts_duration;
- }
- }
- return true;
-}
-
-static void update_vf_memhandle(struct VP9Decoder_s *pbi,
- struct vframe_s *vf, struct PIC_BUFFER_CONFIG_s *pic)
-{
- vf->mem_handle = NULL;
- vf->mem_head_handle = NULL;
- vf->mem_dw_handle = NULL;
-
- /* keeper not needed for v4l solution */
- if (pbi->is_used_v4l)
- return;
-
- if (vf->type & VIDTYPE_SCATTER) {
- vf->mem_handle =
- decoder_mmu_box_get_mem_handle(
- pbi->mmu_box, pic->index);
- vf->mem_head_handle =
- decoder_bmmu_box_get_mem_handle(
- pbi->bmmu_box,
- HEADER_BUFFER_IDX(pic->BUF_index));
- if (pbi->double_write_mode == 3)
- vf->mem_dw_handle =
- decoder_bmmu_box_get_mem_handle(
- pbi->bmmu_box,
- VF_BUFFER_IDX(pic->BUF_index));
- else
- vf->mem_dw_handle = NULL;
- } else {
- vf->mem_handle =
- decoder_bmmu_box_get_mem_handle(
- pbi->bmmu_box, VF_BUFFER_IDX(pic->BUF_index));
- vf->mem_head_handle = NULL;
- vf->mem_dw_handle = NULL;
- /*vf->mem_head_handle =
- *decoder_bmmu_box_get_mem_handle(
- *hevc->bmmu_box, VF_BUFFER_IDX(BUF_index));
- */
- }
-}
-
-static inline void pbi_update_gvs(struct VP9Decoder_s *pbi)
-{
- if (pbi->gvs->frame_height != frame_height) {
- pbi->gvs->frame_width = frame_width;
- pbi->gvs->frame_height = frame_height;
- }
- if (pbi->gvs->frame_dur != pbi->frame_dur) {
- pbi->gvs->frame_dur = pbi->frame_dur;
- if (pbi->frame_dur != 0)
- pbi->gvs->frame_rate = ((96000 * 10 / pbi->frame_dur) % 10) < 5 ?
- 96000 / pbi->frame_dur : (96000 / pbi->frame_dur +1);
- else
- pbi->gvs->frame_rate = -1;
- }
- pbi->gvs->status = pbi->stat | pbi->fatal_error;
-}
-
-static int prepare_display_buf(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *pic_config)
-{
- struct vframe_s *vf = NULL;
- struct vdec_s *pvdec = hw_to_vdec(pbi);
- int stream_offset = pic_config->stream_offset;
- unsigned short slice_type = pic_config->slice_type;
- struct aml_vcodec_ctx * v4l2_ctx = pbi->v4l2_ctx;
- struct vdec_v4l2_buffer *fb = NULL;
- ulong nv_order = VIDTYPE_VIU_NV21;
- u32 pts_valid = 0, pts_us64_valid = 0;
- u32 pts_save;
- u64 pts_us64_save;
- u32 frame_size = 0;
- int i = 0;
-
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("%s index = %d\r\n", __func__, pic_config->index);
- if (kfifo_get(&pbi->newframe_q, &vf) == 0) {
- pr_info("fatal error, no available buffer slot.");
- return -1;
- }
-
- /* swap uv */
- if (pbi->is_used_v4l) {
- if ((v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
- (v4l2_ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
- nv_order = VIDTYPE_VIU_NV12;
- }
-
- if (pic_config->double_write_mode)
- set_canvas(pbi, pic_config);
-
- display_frame_count[pbi->index]++;
- if (vf) {
- if (!force_pts_unstable) {
- if ((pic_config->pts == 0) || ((pic_config->pts <= pbi->last_pts) &&
- (pic_config->pts64 <= pbi->last_pts_us64))) {
- for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- if ((pbi->last_pts == pbi->frame_mode_pts_save[i]) ||
- (pbi->last_pts_us64 == pbi->frame_mode_pts64_save[i])) {
- pic_config->pts = pbi->frame_mode_pts_save[i - 1];
- pic_config->pts64 = pbi->frame_mode_pts64_save[i - 1];
- break;
- }
- }
- if ((i == 0) || (pic_config->pts <= pbi->last_pts)) {
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "no found pts %d, set 0. %d, %d\n",
- i, pic_config->pts, pbi->last_pts);
- pic_config->pts = 0;
- pic_config->pts64 = 0;
- }
- }
- }
-
- if (pbi->is_used_v4l) {
- vf->v4l_mem_handle
- = pbi->m_BUF[pic_config->v4l_buf_index].v4l_ref_buf_addr;
- fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
-
- if (pbi->mmu_enable) {
- vf->mm_box.bmmu_box = pbi->bmmu_box;
- vf->mm_box.bmmu_idx = HEADER_BUFFER_IDX(pbi->buffer_wrap[pic_config->v4l_buf_index]);
- vf->mm_box.mmu_box = pbi->mmu_box;
- vf->mm_box.mmu_idx = pbi->buffer_wrap[pic_config->index];
- }
- }
-
- if (pbi->enable_fence) {
- /* fill fence information. */
- if (pbi->fence_usage == FENCE_USE_FOR_DRIVER)
- vf->fence = pic_config->fence;
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (vdec_frame_based(pvdec)) {
- vf->pts = pic_config->pts;
- vf->pts_us64 = pic_config->pts64;
-
- if (pbi->is_used_v4l && v4l_bitstream_id_enable)
- vf->timestamp = pic_config->timestamp;
- else
- vf->timestamp = pic_config->pts64;
-
- if (vf->pts != 0 || vf->pts_us64 != 0) {
- pts_valid = 1;
- pts_us64_valid = 1;
- } else {
- pts_valid = 0;
- pts_us64_valid = 0;
- }
- } else
-#endif
- /* if (pts_lookup_offset(PTS_TYPE_VIDEO,
- * stream_offset, &vf->pts, 0) != 0) {
- */
- if ((pvdec->vbuf.no_parser == 0) || (pvdec->vbuf.use_ptsserv)) {
- if (pts_lookup_offset_us64
- (PTS_TYPE_VIDEO, stream_offset, &vf->pts,
- &frame_size, 0,
- &vf->pts_us64) != 0) {
-#ifdef DEBUG_PTS
- pbi->pts_missed++;
-#endif
- vf->pts = 0;
- vf->pts_us64 = 0;
- pts_valid = 0;
- pts_us64_valid = 0;
- } else {
-#ifdef DEBUG_PTS
- pbi->pts_hit++;
-#endif
- pts_valid = 1;
- pts_us64_valid = 1;
- }
- }
-
- fill_frame_info(pbi, pic_config, frame_size, vf->pts);
-
- pts_save = vf->pts;
- pts_us64_save = vf->pts_us64;
- if (pbi->is_used_v4l || pbi->pts_unstable) {
- frame_duration_adapt(pbi, vf, pts_valid);
- if (pbi->duration_from_pts_done) {
- pbi->pts_mode = PTS_NONE_REF_USE_DURATION;
- } else {
- if (pts_valid || pts_us64_valid)
- pbi->pts_mode = PTS_NORMAL;
- }
- }
-
- if ((pbi->pts_mode == PTS_NORMAL) && (vf->pts != 0)
- && pbi->get_frame_dur) {
- int pts_diff = (int)vf->pts - pbi->last_lookup_pts;
-
- if (pts_diff < 0) {
- pbi->pts_mode_switching_count++;
- pbi->pts_mode_recovery_count = 0;
-
- if (pbi->pts_mode_switching_count >=
- PTS_MODE_SWITCHING_THRESHOLD) {
- pbi->pts_mode =
- PTS_NONE_REF_USE_DURATION;
- pr_info
- ("HEVC: switch to n_d mode.\n");
- }
-
- } else {
- int p = PTS_MODE_SWITCHING_RECOVERY_THREASHOLD;
-
- pbi->pts_mode_recovery_count++;
- if (pbi->pts_mode_recovery_count > p) {
- pbi->pts_mode_switching_count = 0;
- pbi->pts_mode_recovery_count = 0;
- }
- }
- }
-
- if (vf->pts != 0)
- pbi->last_lookup_pts = vf->pts;
-
- if ((pbi->pts_mode == PTS_NONE_REF_USE_DURATION)
- && (slice_type != KEY_FRAME))
- vf->pts = pbi->last_pts + DUR2PTS(pbi->frame_dur);
- pbi->last_pts = vf->pts;
-
- if (vf->pts_us64 != 0)
- pbi->last_lookup_pts_us64 = vf->pts_us64;
-
- if ((pbi->pts_mode == PTS_NONE_REF_USE_DURATION)
- && (slice_type != KEY_FRAME)) {
- vf->pts_us64 =
- pbi->last_pts_us64 +
- (DUR2PTS(pbi->frame_dur) * 100 / 9);
- }
- pbi->last_pts_us64 = vf->pts_us64;
-
- if (pbi->pts_mode == PTS_NONE_REF_USE_DURATION) {
- vf->disp_pts = vf->pts;
- vf->disp_pts_us64 = vf->pts_us64;
- vf->pts = pts_save;
- vf->pts_us64 = pts_us64_save;
- } else {
- vf->disp_pts = 0;
- vf->disp_pts_us64 = 0;
- }
-
- vf->index = 0xff00 | pic_config->v4l_buf_index;
-
- if (pic_config->double_write_mode & 0x10) {
- /* double write only */
- vf->compBodyAddr = 0;
- vf->compHeadAddr = 0;
- } else {
- if (pbi->mmu_enable) {
- vf->compBodyAddr = 0;
- vf->compHeadAddr = pic_config->header_adr;
- } else {
- /*vf->compBodyAddr = pic_config->mc_y_adr;
- *vf->compHeadAddr = pic_config->mc_y_adr +
- *pic_config->comp_body_size; */
- /*head adr*/
- }
- vf->canvas0Addr = vf->canvas1Addr = 0;
- }
- if (pic_config->double_write_mode) {
- vf->type = VIDTYPE_PROGRESSIVE |
- VIDTYPE_VIU_FIELD;
- vf->type |= nv_order;
- if ((pic_config->double_write_mode == 3) &&
- (!IS_8K_SIZE(pic_config->y_crop_width,
- pic_config->y_crop_height))) {
- vf->type |= VIDTYPE_COMPRESS;
- if (pbi->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
- if (pbi->is_used_v4l && pic_config->double_write_mode != 16 &&
- (!IS_8K_SIZE(pic_config->y_crop_width,
- pic_config->y_crop_height)))
- vf->type |= VIDTYPE_COMPRESS | VIDTYPE_SCATTER;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- pic_config->canvas_config[0];
- vf->canvas0_config[1] =
- pic_config->canvas_config[1];
- vf->canvas1_config[0] =
- pic_config->canvas_config[0];
- vf->canvas1_config[1] =
- pic_config->canvas_config[1];
-
- } else
-#endif
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(pic_config);
- } else {
- vf->canvas0Addr = vf->canvas1Addr = 0;
- vf->type = VIDTYPE_COMPRESS | VIDTYPE_VIU_FIELD;
- if (pbi->mmu_enable)
- vf->type |= VIDTYPE_SCATTER;
- }
-
- switch (pic_config->bit_depth) {
- case VPX_BITS_8:
- vf->bitdepth = BITDEPTH_Y8 |
- BITDEPTH_U8 | BITDEPTH_V8;
- break;
- case VPX_BITS_10:
- case VPX_BITS_12:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- default:
- vf->bitdepth = BITDEPTH_Y10 |
- BITDEPTH_U10 | BITDEPTH_V10;
- break;
- }
- if ((vf->type & VIDTYPE_COMPRESS) == 0)
- vf->bitdepth =
- BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
- if (pic_config->bit_depth == VPX_BITS_8)
- vf->bitdepth |= BITDEPTH_SAVING_MODE;
-
- /* if((vf->width!=pic_config->width)|
- * (vf->height!=pic_config->height))
- */
- /* pr_info("aaa: %d/%d, %d/%d\n",
- vf->width,vf->height, pic_config->width,
- pic_config->height); */
- vf->width = pic_config->y_crop_width /
- get_double_write_ratio(
- pic_config->double_write_mode);
- vf->height = pic_config->y_crop_height /
- get_double_write_ratio(
- pic_config->double_write_mode);
- if (force_w_h != 0) {
- vf->width = (force_w_h >> 16) & 0xffff;
- vf->height = force_w_h & 0xffff;
- }
- vf->compWidth = pic_config->y_crop_width;
- vf->compHeight = pic_config->y_crop_height;
- set_frame_info(pbi, vf);
- if (force_fps & 0x100) {
- u32 rate = force_fps & 0xff;
-
- if (rate)
- vf->duration = 96000/rate;
- else
- vf->duration = 0;
- }
- update_vf_memhandle(pbi, vf, pic_config);
- if (vdec_stream_based(pvdec) && (!pvdec->vbuf.use_ptsserv)) {
- vf->pts_us64 = stream_offset;
- vf->pts = 0;
- }
- if ((debug & VP9_DEBUG_OUT_PTS) != 0) {
- pr_info
- ("VP9 dec out pts: pts_mode=%d,dur=%d,pts(%d,%lld,%lld)(%d,%lld)\n",
- pbi->pts_mode, pbi->frame_dur, vf->pts,
- vf->pts_us64, vf->timestamp, pts_save,
- pts_us64_save);
- }
- if (!(pic_config->y_crop_width == 196
- && pic_config->y_crop_height == 196
- && (debug & VP9_DEBUG_NO_TRIGGER_FRAME) == 0
- && (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_TXLX))) {
- struct vdec_info tmp4x;
-
- inc_vf_ref(pbi, pic_config->v4l_buf_index);
-
- vdec_vframe_ready(pvdec, vf);
- if (pic_config->double_write_mode &&
- (pic_config->v4l_buf_index != pic_config->BUF_index)) {
- struct PIC_BUFFER_CONFIG_s *dst_pic =
- &pbi->common.buffer_pool->frame_bufs[pic_config->v4l_buf_index].buf;
- struct PIC_BUFFER_CONFIG_s *src_pic =
- &pbi->common.buffer_pool->frame_bufs[pic_config->BUF_index].buf;
- struct vdec_ge2d_info ge2d_info;
-
- vp9_print(pbi, PRINT_FLAG_V4L_DETAIL,
- "ge2d copy start v4l_buf_index:%d repeat_buff_index:%d\n",
- pic_config->v4l_buf_index,
- pic_config->BUF_index);
- ge2d_info.dst_vf = vf;
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr = 0;
- if (dst_pic->double_write_mode) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag) {
- vf->canvas0Addr = vf->canvas1Addr = -1;
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr = -1;
- vf->plane_num = 2;
- vf->canvas0_config[0] =
- dst_pic->canvas_config[0];
- vf->canvas0_config[1] =
- dst_pic->canvas_config[1];
- vf->canvas1_config[0] =
- dst_pic->canvas_config[0];
- vf->canvas1_config[1] =
- dst_pic->canvas_config[1];
- ge2d_info.src_canvas0_config[0] =
- src_pic->canvas_config[0];
- ge2d_info.src_canvas0_config[1] =
- src_pic->canvas_config[1];
- ge2d_info.src_canvas1_config[0] =
- src_pic->canvas_config[0];
- ge2d_info.src_canvas1_config[1] =
- src_pic->canvas_config[1];
- } else
-#endif
- {
- vf->canvas0Addr = vf->canvas1Addr =
- spec2canvas(dst_pic);
- ge2d_info.src_canvas0Addr = ge2d_info.src_canvas1Addr =
- spec2canvas(src_pic);
- }
- }
-
- if (!pbi->ge2d) {
- int mode = nv_order == VIDTYPE_VIU_NV21 ? GE2D_MODE_CONVERT_NV21 : GE2D_MODE_CONVERT_NV12;
- mode |= GE2D_MODE_CONVERT_LE;
- vdec_ge2d_init(&pbi->ge2d, mode);
- }
- vdec_ge2d_copy_data(pbi->ge2d, &ge2d_info);
- vp9_print(pbi, PRINT_FLAG_V4L_DETAIL, "ge2d copy done\n");
- }
- decoder_do_frame_check(pvdec, vf);
- kfifo_put(&pbi->display_q, (const struct vframe_s *)vf);
- ATRACE_COUNTER(pbi->trace.pts_name, vf->timestamp);
- ATRACE_COUNTER(pbi->trace.new_q_name, kfifo_len(&pbi->newframe_q));
- ATRACE_COUNTER(pbi->trace.disp_q_name, kfifo_len(&pbi->display_q));
- atomic_add(1, &pbi->vf_pre_count);
- pbi_update_gvs(pbi);
- /*count info*/
- vdec_count_info(pbi->gvs, 0, stream_offset);
- if (stream_offset) {
- if (slice_type == KEY_FRAME) {
- pbi->gvs->i_decoded_frames++;
- } else if (slice_type == INTER_FRAME) {
- pbi->gvs->p_decoded_frames++;
- } else if (slice_type == FRAME_TYPES) {
- pbi->gvs->b_decoded_frames++;
- }
- }
- memcpy(&tmp4x, pbi->gvs, sizeof(struct vdec_info));
- tmp4x.bit_depth_luma = pbi->vp9_param.p.bit_depth;
- tmp4x.bit_depth_chroma = pbi->vp9_param.p.bit_depth;
- tmp4x.double_write_mode = pic_config->double_write_mode;
- vdec_fill_vdec_frame(pvdec, &pbi->vframe_qos, &tmp4x,
- vf, pic_config->hw_decode_time);
- pvdec->vdec_fps_detec(pvdec->id);
- if (without_display_mode == 0) {
- if (pbi->is_used_v4l) {
- if (v4l2_ctx->is_stream_off) {
- vvp9_vf_put(vvp9_vf_get(pbi), pbi);
- } else {
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
- }
- } else {
- vf_notify_receiver(pbi->provider_name,
- VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
- }
- } else
- vvp9_vf_put(vvp9_vf_get(pbi), pbi);
- } else {
- pbi->stat |= VP9_TRIGGER_FRAME_DONE;
- hevc_source_changed(VFORMAT_VP9, 196, 196, 30);
- pr_debug("[%s %d] drop trigger frame width %d height %d state 0x%x\n",
- __func__, __LINE__, vf->width,
- vf->height, pbi->stat);
- }
- }
-
- return 0;
-}
-
-static bool is_avaliable_buffer(struct VP9Decoder_s *pbi);
-
-static int notify_v4l_eos(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *hw = (struct VP9Decoder_s *)vdec->private;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(hw->v4l2_ctx);
- struct vframe_s *vf = &hw->vframe_dummy;
- struct vdec_v4l2_buffer *fb = NULL;
- int index = INVALID_IDX;
- ulong expires;
-
- if (hw->eos) {
- expires = jiffies + msecs_to_jiffies(2000);
- while (!is_avaliable_buffer(hw)) {
- if (time_after(jiffies, expires)) {
- pr_err("[%d] VP9 isn't enough buff for notify eos.\n", ctx->id);
- return 0;
- }
- }
-
- index = v4l_get_free_fb(hw);
- if (INVALID_IDX == index) {
- pr_err("[%d] VP9 EOS get free buff fail.\n", ctx->id);
- return 0;
- }
-
- fb = (struct vdec_v4l2_buffer *)
- hw->m_BUF[index].v4l_ref_buf_addr;
-
- vf->type |= VIDTYPE_V4L_EOS;
- vf->timestamp = ULONG_MAX;
- vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
- vf->v4l_mem_handle = (ulong)fb;
-
- vdec_vframe_ready(vdec, vf);
- kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
-
- ATRACE_COUNTER("VC_OUT_DEC-submit", fb->buf_idx);
- fb->task->submit(fb->task, TASK_TYPE_DEC);
-
- pr_info("[%d] VP9 EOS notify.\n", ctx->id);
- }
-
- return 0;
-}
-
-static void get_rpm_param(union param_u *params)
-{
- int i;
- unsigned int data32;
-
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("enter %s\r\n", __func__);
- for (i = 0; i < 128; i++) {
- do {
- data32 = READ_VREG(RPM_CMD_REG);
- /*pr_info("%x\n", data32);*/
- } while ((data32 & 0x10000) == 0);
- params->l.data[i] = data32&0xffff;
- /*pr_info("%x\n", data32);*/
- WRITE_VREG(RPM_CMD_REG, 0);
- }
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("leave %s\r\n", __func__);
-}
-static void debug_buffer_mgr_more(struct VP9Decoder_s *pbi)
-{
- int i;
-
- if (!(debug & VP9_DEBUG_BUFMGR_MORE))
- return;
- pr_info("vp9_param: (%d)\n", pbi->slice_idx);
- for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
- pr_info("%04x ", pbi->vp9_param.l.data[i]);
- if (((i + 1) & 0xf) == 0)
- pr_info("\n");
- }
- pr_info("=============param==========\r\n");
- pr_info("profile %x\r\n", pbi->vp9_param.p.profile);
- pr_info("show_existing_frame %x\r\n",
- pbi->vp9_param.p.show_existing_frame);
- pr_info("frame_to_show_idx %x\r\n",
- pbi->vp9_param.p.frame_to_show_idx);
- pr_info("frame_type %x\r\n", pbi->vp9_param.p.frame_type);
- pr_info("show_frame %x\r\n", pbi->vp9_param.p.show_frame);
- pr_info("e.r.r.o.r_resilient_mode %x\r\n",
- pbi->vp9_param.p.error_resilient_mode);
- pr_info("intra_only %x\r\n", pbi->vp9_param.p.intra_only);
- pr_info("display_size_present %x\r\n",
- pbi->vp9_param.p.display_size_present);
- pr_info("reset_frame_context %x\r\n",
- pbi->vp9_param.p.reset_frame_context);
- pr_info("refresh_frame_flags %x\r\n",
- pbi->vp9_param.p.refresh_frame_flags);
- pr_info("bit_depth %x\r\n", pbi->vp9_param.p.bit_depth);
- pr_info("width %x\r\n", pbi->vp9_param.p.width);
- pr_info("height %x\r\n", pbi->vp9_param.p.height);
- pr_info("display_width %x\r\n", pbi->vp9_param.p.display_width);
- pr_info("display_height %x\r\n", pbi->vp9_param.p.display_height);
- pr_info("ref_info %x\r\n", pbi->vp9_param.p.ref_info);
- pr_info("same_frame_size %x\r\n", pbi->vp9_param.p.same_frame_size);
- if (!(debug & VP9_DEBUG_DBG_LF_PRINT))
- return;
- pr_info("mode_ref_delta_enabled: 0x%x\r\n",
- pbi->vp9_param.p.mode_ref_delta_enabled);
- pr_info("sharpness_level: 0x%x\r\n",
- pbi->vp9_param.p.sharpness_level);
- pr_info("ref_deltas: 0x%x, 0x%x, 0x%x, 0x%x\r\n",
- pbi->vp9_param.p.ref_deltas[0], pbi->vp9_param.p.ref_deltas[1],
- pbi->vp9_param.p.ref_deltas[2], pbi->vp9_param.p.ref_deltas[3]);
- pr_info("mode_deltas: 0x%x, 0x%x\r\n", pbi->vp9_param.p.mode_deltas[0],
- pbi->vp9_param.p.mode_deltas[1]);
- pr_info("filter_level: 0x%x\r\n", pbi->vp9_param.p.filter_level);
- pr_info("seg_enabled: 0x%x\r\n", pbi->vp9_param.p.seg_enabled);
- pr_info("seg_abs_delta: 0x%x\r\n", pbi->vp9_param.p.seg_abs_delta);
- pr_info("seg_lf_feature_enabled: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n",
- (pbi->vp9_param.p.seg_lf_info[0]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[1]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[2]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[3]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[4]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[5]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[6]>>15 & 1),
- (pbi->vp9_param.p.seg_lf_info[7]>>15 & 1));
- pr_info("seg_lf_feature_data: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n",
- (pbi->vp9_param.p.seg_lf_info[0] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[1] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[2] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[3] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[4] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[5] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[6] & 0x13f),
- (pbi->vp9_param.p.seg_lf_info[7] & 0x13f));
-
-}
-
-static int recycle_mmu_buf_tail(struct VP9Decoder_s *pbi,
- bool check_dma)
-{
- struct VP9_Common_s *const cm = &pbi->common;
-
- if (pbi->used_4k_num == -1) {
- pbi->used_4k_num =
- READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
- }
- vp9_print(pbi, VP9_DEBUG_BUFMGR_MORE,
- "pic index %d page_start %d\n",
- cm->cur_fb_idx_mmu, pbi->used_4k_num);
-
- if (check_dma)
- hevc_mmu_dma_check(hw_to_vdec(pbi));
-
- if (pbi->is_used_v4l) {
- int index = cm->cur_fb_idx_mmu;
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, index);
-
- decoder_mmu_box_free_idx_tail(
- ibuf->mmu_box,
- ibuf->index,
- pbi->used_4k_num);
- } else {
- decoder_mmu_box_free_idx_tail(
- pbi->mmu_box,
- cm->cur_fb_idx_mmu,
- pbi->used_4k_num);
- }
-
- cm->cur_fb_idx_mmu = INVALID_IDX;
- pbi->used_4k_num = -1;
-
- return 0;
-}
-
-static void vp9_recycle_mmu_buf_tail(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- if (pbi->double_write_mode & 0x10)
- return;
- if (cm->cur_fb_idx_mmu != INVALID_IDX) {
- recycle_mmu_buf_tail(pbi,
- ((pbi->used_4k_num == -1) &&
- pbi->m_ins_flag) ? 1 : 0);
- }
-}
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static void vp9_recycle_mmu_buf(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
-
- if (pbi->is_used_v4l)
- return;
-
- if (pbi->double_write_mode & 0x10)
- return;
- if (cm->cur_fb_idx_mmu != INVALID_IDX) {
- decoder_mmu_box_free_idx(pbi->mmu_box,
- cm->cur_fb_idx_mmu);
-
- cm->cur_fb_idx_mmu = INVALID_IDX;
- pbi->used_4k_num = -1;
- }
-}
-
-void vp9_recycle_mmu_work(struct work_struct *work)
-{
- struct VP9Decoder_s *pbi = container_of(work,
- struct VP9Decoder_s, recycle_mmu_work);
-
- if (pbi)
- vp9_recycle_mmu_buf(pbi);
-}
-#endif
-
-
-static void dec_again_process(struct VP9Decoder_s *pbi)
-{
- amhevc_stop();
- pbi->dec_result = DEC_RESULT_AGAIN;
- if (pbi->process_state ==
- PROC_STATE_DECODESLICE) {
- pbi->process_state =
- PROC_STATE_SENDAGAIN;
- if (pbi->mmu_enable) {
- /*
- * Because vp9_recycle_mmu_buf has sleep function,we can't
- * call it directly. Use a recycle_mmu_work to substitude it.
- */
- vdec_schedule_work(&pbi->recycle_mmu_work);
- }
- }
- reset_process_time(pbi);
- vdec_schedule_work(&pbi->work);
-}
-
-int continue_decoding(struct VP9Decoder_s *pbi)
-{
- int ret;
- int i;
- struct VP9_Common_s *const cm = &pbi->common;
- struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- debug_buffer_mgr_more(pbi);
-
- if (pbi->is_used_v4l && ctx->param_sets_from_ucode)
- pbi->res_ch_flag = 0;
- bit_depth_luma = pbi->vp9_param.p.bit_depth;
- bit_depth_chroma = pbi->vp9_param.p.bit_depth;
-
- if ((pbi->vp9_param.p.bit_depth >= VPX_BITS_10) &&
- (get_double_write_mode(pbi) == 0x10)) {
- pbi->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
- pr_err("fatal err, bit_depth %d, unsupport dw 0x10\n",
- pbi->vp9_param.p.bit_depth);
- return -1;
- }
-
- if (pbi->process_state != PROC_STATE_SENDAGAIN) {
- ret = vp9_bufmgr_process(pbi, &pbi->vp9_param);
- if (!pbi->m_ins_flag)
- pbi->slice_idx++;
- } else {
- union param_u *params = &pbi->vp9_param;
- if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- ret = vp9_alloc_mmu(pbi,
- cm->new_fb_idx,
- params->p.width,
- params->p.height,
- params->p.bit_depth,
- pbi->frame_mmu_map_addr);
- if (ret >= 0)
- cm->cur_fb_idx_mmu = cm->new_fb_idx;
- else
- pr_err("can't alloc need mmu1,idx %d ret =%d\n",
- cm->new_fb_idx,
- ret);
- } else {
- ret = 0;
- }
- WRITE_VREG(HEVC_PARSER_PICTURE_SIZE,
- (params->p.height << 16) | params->p.width);
- }
- if (ret < 0) {
- pr_info("vp9_bufmgr_process=> %d, VP9_10B_DISCARD_NAL\r\n",
- ret);
- WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL);
- cm->show_frame = 0;
- if (pbi->mmu_enable) {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- vp9_recycle_mmu_buf(pbi);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag) {
- pbi->dec_result = DEC_RESULT_DONE;
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num == 0)
-#endif
- amhevc_stop();
- vdec_schedule_work(&pbi->work);
- }
-#endif
- return ret;
- } else if (ret == 0) {
- struct PIC_BUFFER_CONFIG_s *cur_pic_config
- = &cm->cur_frame->buf;
- cur_pic_config->decode_idx = pbi->frame_count;
-
- if (pbi->process_state != PROC_STATE_SENDAGAIN) {
- if (!pbi->m_ins_flag) {
- pbi->frame_count++;
- decode_frame_count[pbi->index]
- = pbi->frame_count;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->chunk) {
- cur_pic_config->pts = pbi->chunk->pts;
- cur_pic_config->pts64 = pbi->chunk->pts64;
-
- if (pbi->is_used_v4l && !v4l_bitstream_id_enable)
- cur_pic_config->pts64 = pbi->chunk->timestamp;
- }
-#endif
- }
- /*pr_info("Decode Frame Data %d\n", pbi->frame_count);*/
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
- config_pic_size(pbi, pbi->vp9_param.p.bit_depth);
-
- if ((pbi->common.frame_type != KEY_FRAME)
- && (!pbi->common.intra_only)) {
- config_mc_buffer(pbi, pbi->vp9_param.p.bit_depth);
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num == 0)
-#endif
- config_mpred_hw(pbi);
- } else {
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num == 0)
-#endif
- clear_mpred_hw(pbi);
- }
-#ifdef MCRCC_ENABLE
- if (mcrcc_cache_alg_flag)
- config_mcrcc_axi_hw_new(pbi);
- else
- config_mcrcc_axi_hw(pbi);
-#endif
- config_sao_hw(pbi, &pbi->vp9_param);
-
-#ifdef VP9_LPF_LVL_UPDATE
- /*
- * Get loop filter related picture level parameters from Parser
- */
- pbi->lf->mode_ref_delta_enabled = pbi->vp9_param.p.mode_ref_delta_enabled;
- pbi->lf->sharpness_level = pbi->vp9_param.p.sharpness_level;
- for (i = 0; i < 4; i++)
- pbi->lf->ref_deltas[i] = pbi->vp9_param.p.ref_deltas[i];
- for (i = 0; i < 2; i++)
- pbi->lf->mode_deltas[i] = pbi->vp9_param.p.mode_deltas[i];
- pbi->default_filt_lvl = pbi->vp9_param.p.filter_level;
- pbi->seg_4lf->enabled = pbi->vp9_param.p.seg_enabled;
- pbi->seg_4lf->abs_delta = pbi->vp9_param.p.seg_abs_delta;
- for (i = 0; i < MAX_SEGMENTS; i++)
- pbi->seg_4lf->feature_mask[i] = (pbi->vp9_param.p.seg_lf_info[i] &
- 0x8000) ? (1 << SEG_LVL_ALT_LF) : 0;
- for (i = 0; i < MAX_SEGMENTS; i++)
- pbi->seg_4lf->feature_data[i][SEG_LVL_ALT_LF]
- = (pbi->vp9_param.p.seg_lf_info[i]
- & 0x100) ? -(pbi->vp9_param.p.seg_lf_info[i]
- & 0x3f) : (pbi->vp9_param.p.seg_lf_info[i] & 0x3f);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- /*Set pipeline mode*/
- uint32_t lpf_data32 = READ_VREG(HEVC_DBLK_CFGB);
- /*dblk pipeline mode=1 for performance*/
- if (pbi->vp9_param.p.width >= 1280)
- lpf_data32 |= (0x1 << 4);
- else
- lpf_data32 &= ~(0x3 << 4);
- WRITE_VREG(HEVC_DBLK_CFGB, lpf_data32);
- }
- /*
- * Update loop filter Thr/Lvl table for every frame
- */
- /*pr_info
- ("vp9_loop_filter (run before every frame decoding start)\n");*/
- vp9_loop_filter_frame_init(pbi->seg_4lf,
- pbi->lfi, pbi->lf, pbi->default_filt_lvl);
-#endif
- /*pr_info("HEVC_DEC_STATUS_REG <= VP9_10B_DECODE_SLICE\n");*/
- WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DECODE_SLICE);
- } else {
- vp9_print(pbi, VP9_DEBUG_BUFMGR, "Skip search next start code\n");
- cm->prev_fb_idx = INVALID_IDX;
- /*skip, search next start code*/
- WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DECODE_SLICE);
- }
- pbi->process_state = PROC_STATE_DECODESLICE;
- if (pbi->mmu_enable && ((pbi->double_write_mode & 0x10) == 0)) {
- if (pbi->last_put_idx < pbi->used_buf_num) {
- struct RefCntBuffer_s *frame_bufs =
- cm->buffer_pool->frame_bufs;
- int i = pbi->last_put_idx;
- /*free not used buffers.*/
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.index != -1)) {
- if (pbi->is_used_v4l) {
- struct internal_comp_buf *ibuf =
- index_to_icomp_buf(pbi, i);
-
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- } else {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- decoder_mmu_box_free_idx(pbi->mmu_box, i);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
- }
- pbi->last_put_idx = -1;
- }
- }
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
- return ret;
-}
-
-static void fill_frame_info(struct VP9Decoder_s *pbi,
- struct PIC_BUFFER_CONFIG_s *frame,
- unsigned int framesize,
- unsigned int pts)
-{
- struct vframe_qos_s *vframe_qos = &pbi->vframe_qos;
-
- if (frame->slice_type == KEY_FRAME)
- vframe_qos->type = 1;
- else if (frame->slice_type == INTER_FRAME)
- vframe_qos->type = 2;
-/*
-#define SHOW_QOS_INFO
-*/
- if (input_frame_based(hw_to_vdec(pbi)))
- vframe_qos->size = frame->frame_size2;
- else
- vframe_qos->size = framesize;
- vframe_qos->pts = pts;
-#ifdef SHOW_QOS_INFO
- vp9_print(pbi, 0, "slice:%d\n", frame->slice_type);
-#endif
- vframe_qos->max_mv = frame->max_mv;
- vframe_qos->avg_mv = frame->avg_mv;
- vframe_qos->min_mv = frame->min_mv;
-#ifdef SHOW_QOS_INFO
- vp9_print(pbi, 0, "mv: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_mv,
- vframe_qos->avg_mv,
- vframe_qos->min_mv);
-#endif
- vframe_qos->max_qp = frame->max_qp;
- vframe_qos->avg_qp = frame->avg_qp;
- vframe_qos->min_qp = frame->min_qp;
-#ifdef SHOW_QOS_INFO
- vp9_print(pbi, 0, "qp: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_qp,
- vframe_qos->avg_qp,
- vframe_qos->min_qp);
-#endif
- vframe_qos->max_skip = frame->max_skip;
- vframe_qos->avg_skip = frame->avg_skip;
- vframe_qos->min_skip = frame->min_skip;
-#ifdef SHOW_QOS_INFO
- vp9_print(pbi, 0, "skip: max:%d, avg:%d, min:%d\n",
- vframe_qos->max_skip,
- vframe_qos->avg_skip,
- vframe_qos->min_skip);
-#endif
- vframe_qos->num++;
-}
-
-/* only when we decoded one field or one frame,
-we can call this function to get qos info*/
-static void get_picture_qos_info(struct VP9Decoder_s *pbi)
-{
- struct PIC_BUFFER_CONFIG_s *frame = &pbi->cur_buf->buf;
- struct vdec_s *vdec = hw_to_vdec(pbi);
-
- if (!frame)
- return;
- if (vdec->mvfrm) {
- frame->frame_size2 = vdec->mvfrm->frame_size;
- frame->hw_decode_time =
- local_clock() - vdec->mvfrm->hw_decode_start;
- }
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) {
- unsigned char a[3];
- unsigned char i, j, t;
- unsigned long data;
-
- data = READ_VREG(HEVC_MV_INFO);
- if (frame->slice_type == KEY_FRAME)
- data = 0;
- a[0] = data & 0xff;
- a[1] = (data >> 8) & 0xff;
- a[2] = (data >> 16) & 0xff;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_mv = a[2];
- frame->avg_mv = a[1];
- frame->min_mv = a[0];
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "mv data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-
- data = READ_VREG(HEVC_QP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_qp = a[2];
- frame->avg_qp = a[1];
- frame->min_qp = a[0];
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "qp data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
-
- data = READ_VREG(HEVC_SKIP_INFO);
- a[0] = data & 0x1f;
- a[1] = (data >> 8) & 0x3f;
- a[2] = (data >> 16) & 0x7f;
-
- for (i = 0; i < 3; i++) {
- for (j = i+1; j < 3; j++) {
- if (a[j] < a[i]) {
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- } else if (a[j] == a[i]) {
- a[i]++;
- t = a[j];
- a[j] = a[i];
- a[i] = t;
- }
- }
- }
- frame->max_skip = a[2];
- frame->avg_skip = a[1];
- frame->min_skip = a[0];
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "skip data %x a[0]= %x a[1]= %x a[2]= %x\n",
- data, a[0], a[1], a[2]);
- } else {
- uint32_t blk88_y_count;
- uint32_t blk88_c_count;
- uint32_t blk22_mv_count;
- uint32_t rdata32;
- int32_t mv_hi;
- int32_t mv_lo;
- uint32_t rdata32_l;
- uint32_t mvx_L0_hi;
- uint32_t mvy_L0_hi;
- uint32_t mvx_L1_hi;
- uint32_t mvy_L1_hi;
- int64_t value;
- uint64_t temp_value;
- int pic_number = frame->decode_idx;
-
- frame->max_mv = 0;
- frame->avg_mv = 0;
- frame->min_mv = 0;
-
- frame->max_skip = 0;
- frame->avg_skip = 0;
- frame->min_skip = 0;
-
- frame->max_qp = 0;
- frame->avg_qp = 0;
- frame->min_qp = 0;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO, "slice_type:%d, poc:%d\n",
- frame->slice_type,
- pic_number);
-
- /* set rd_idx to 0 */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, 0);
-
- blk88_y_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_y_count == 0) {
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
-
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_y_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_y_count,
- rdata32, blk88_y_count);
-
- frame->avg_qp = rdata32/blk88_y_count;
- /* intra_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-
- /* skipped_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_y_count,
- '%', rdata32);
-
- frame->avg_skip = rdata32*100/blk88_y_count;
- /* coeff_non_zero_y_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_y_count*1)),
- '%', rdata32);
-
- /* blk66_c_count */
- blk88_c_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk88_c_count == 0) {
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO Data yet.\n",
- pic_number);
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* qp_c_sum */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP AVG : %d (%d/%d)\n",
- pic_number, rdata32/blk88_c_count,
- rdata32, blk88_c_count);
-
- /* intra_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C intra rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-
- /* skipped_cu_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C skipped rate : %d%c (%d)\n",
- pic_number, rdata32*100/blk88_c_count,
- '%', rdata32);
-
- /* coeff_non_zero_c_count */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
- pic_number, (100 - rdata32*100/(blk88_c_count*1)),
- '%', rdata32);
-
- /* 1'h0, qp_c_max[6:0], 1'h0, qp_c_min[6:0],
- 1'h0, qp_y_max[6:0], 1'h0, qp_y_min[6:0] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP min : %d\n",
- pic_number, (rdata32>>0)&0xff);
-
- frame->min_qp = (rdata32>>0)&0xff;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] Y QP max : %d\n",
- pic_number, (rdata32>>8)&0xff);
-
- frame->max_qp = (rdata32>>8)&0xff;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP min : %d\n",
- pic_number, (rdata32>>16)&0xff);
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] C QP max : %d\n",
- pic_number, (rdata32>>24)&0xff);
-
- /* blk22_mv_count */
- blk22_mv_count = READ_VREG(HEVC_PIC_QUALITY_DATA);
- if (blk22_mv_count == 0) {
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] NO MV Data yet.\n",
- pic_number);
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- return;
- }
- /* mvy_L1_count[39:32], mvx_L1_count[39:32],
- mvy_L0_count[39:32], mvx_L0_count[39:32] */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- /* should all be 0x00 or 0xff */
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MV AVG High Bits: 0x%X\n",
- pic_number, rdata32);
-
- mvx_L0_hi = ((rdata32>>0)&0xff);
- mvy_L0_hi = ((rdata32>>8)&0xff);
- mvx_L1_hi = ((rdata32>>16)&0xff);
- mvy_L1_hi = ((rdata32>>24)&0xff);
-
- /* mvx_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvx_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- value = div_s64(value, blk22_mv_count);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
- pic_number, (int)value,
- value, blk22_mv_count);
-
- frame->avg_mv = value;
-
- /* mvy_L0_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L0_hi;
- temp_value = (temp_value << 32) | rdata32_l;
-
- if (mvy_L0_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* mvx_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvx_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvx_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* mvy_L1_count[31:0] */
- rdata32_l = READ_VREG(HEVC_PIC_QUALITY_DATA);
- temp_value = mvy_L1_hi;
- temp_value = (temp_value << 32) | rdata32_l;
- if (mvy_L1_hi & 0x80)
- value = 0xFFFFFFF000000000 | temp_value;
- else
- value = temp_value;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 AVG : %d (%lld/%d)\n",
- pic_number, rdata32_l/blk22_mv_count,
- value, blk22_mv_count);
-
- /* {mvx_L0_max, mvx_L0_min} // format : {sign, abs[14:0]} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 MAX : %d\n",
- pic_number, mv_hi);
-
- frame->max_mv = mv_hi;
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L0 MIN : %d\n",
- pic_number, mv_lo);
-
- frame->min_mv = mv_lo;
-
- /* {mvy_L0_max, mvy_L0_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L0 MIN : %d\n",
- pic_number, mv_lo);
-
- /* {mvx_L1_max, mvx_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVX_L1 MIN : %d\n",
- pic_number, mv_lo);
-
- /* {mvy_L1_max, mvy_L1_min} */
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_DATA);
- mv_hi = (rdata32>>16)&0xffff;
- if (mv_hi & 0x8000)
- mv_hi = 0x8000 - mv_hi;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 MAX : %d\n",
- pic_number, mv_hi);
-
- mv_lo = (rdata32>>0)&0xffff;
- if (mv_lo & 0x8000)
- mv_lo = 0x8000 - mv_lo;
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] MVY_L1 MIN : %d\n",
- pic_number, mv_lo);
-
- rdata32 = READ_VREG(HEVC_PIC_QUALITY_CTRL);
-
- vp9_print(pbi, VP9_DEBUG_QOS_INFO,
- "[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
- pic_number, rdata32);
-
- /* reset all counts */
- WRITE_VREG(HEVC_PIC_QUALITY_CTRL, (1<<8));
- }
-}
-
-static void vvp9_get_comp_buf_info(struct VP9Decoder_s *pbi,
- struct vdec_comp_buf_info *info)
-{
- u16 bit_depth = pbi->param.p.bit_depth;
-
- info->max_size = vp9_max_mmu_buf_size(
- pbi->max_pic_w,
- pbi->max_pic_h);
- info->header_size = vvp9_mmu_compress_header_size(
- pbi->frame_width,
- pbi->frame_height);
- info->frame_buffer_size = vp9_mmu_page_num(
- pbi, pbi->frame_width,
- pbi->frame_height,
- bit_depth == 0);
-}
-
-static int vvp9_get_ps_info(struct VP9Decoder_s *pbi, struct aml_vdec_ps_infos *ps)
-{
- ps->visible_width = pbi->frame_width;
- ps->visible_height = pbi->frame_height;
- ps->coded_width = ALIGN(pbi->frame_width, 64);
- ps->coded_height = ALIGN(pbi->frame_height, 64);
- ps->dpb_size = pbi->used_buf_num;
- ps->dpb_margin = pbi->dynamic_buf_num_margin;
- if (pbi->frame_width > 2048 && pbi->frame_height > 1088)
- ps->dpb_frames = 4; /* > level 4.1*/
- else
- ps->dpb_frames = 8; /* < level 4.1 */
- /*
- 1. curruent decoding frame is not include in dpb;
- 2. for frame push out, one more buffer necessary.
- 3. Two consecutive frames cannot use the same buffer.
- */
- ps->dpb_frames += 3;
-
- if (ps->dpb_margin + ps->dpb_frames > MAX_BUF_NUM_NORMAL) {
- u32 delta;
- delta = ps->dpb_margin + ps->dpb_frames - MAX_BUF_NUM_NORMAL;
- ps->dpb_margin -= delta;
- pbi->dynamic_buf_num_margin = ps->dpb_margin;
- }
- ps->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-
-static int v4l_res_change(struct VP9Decoder_s *pbi)
-{
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- int ret = 0;
-
- if (ctx->param_sets_from_ucode &&
- pbi->res_ch_flag == 0) {
- struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
-
- if ((pbi->last_width != 0 &&
- pbi->last_height != 0) &&
- (pbi->frame_width != pbi->last_width ||
- pbi->frame_height != pbi->last_height)) {
-
- vp9_print(pbi, 0, "%s (%d,%d)=>(%d,%d)\r\n", __func__, pbi->last_width,
- pbi->last_height, pbi->frame_width, pbi->frame_height);
-
- if (get_valid_double_write_mode(pbi) != 16) {
- vvp9_get_comp_buf_info(pbi, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
- vvp9_get_ps_info(pbi, &ps);
- vdec_v4l_set_ps_infos(ctx, &ps);
- vdec_v4l_res_ch_event(ctx);
-
- pbi->init_pic_w = pbi->frame_width;
- pbi->init_pic_h = pbi->frame_height;
- init_mv_buf_list(pbi);
-
- pbi->process_state = PROC_STATE_INIT;
- pbi->v4l_params_parsed = false;
- pbi->res_ch_flag = 1;
- ctx->v4l_resolution_change = 1;
- pbi->eos = 1;
- vp9_bufmgr_postproc(pbi);
- //del_timer_sync(&pbi->timer);
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(pbi));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- ret = 1;
- }
- }
-
- return ret;
-}
-
-static irqreturn_t vvp9_isr_thread_fn(int irq, void *data)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data;
- unsigned int dec_status = pbi->dec_status;
- int i;
-
- if (dec_status == VP9_HEAD_PARSER_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
- }
-
- /*if (pbi->wait_buf)
- * pr_info("set wait_buf to 0\r\n");
- */
- if (pbi->eos)
- return IRQ_HANDLED;
- pbi->wait_buf = 0;
-#ifdef MULTI_INSTANCE_SUPPORT
-#ifdef SUPPORT_FB_DECODING
-#ifdef FB_DECODING_TEST_SCHEDULE
- if (pbi->s1_test_cmd == TEST_SET_PIC_DONE)
- dec_status = HEVC_DECPIC_DATA_DONE;
- else if (pbi->s1_test_cmd == TEST_SET_S2_DONE
- && dec_status == HEVC_DECPIC_DATA_DONE)
- dec_status = HEVC_S2_DECODING_DONE;
- pbi->s1_test_cmd = TEST_SET_NONE;
-#else
- /*if (irq != VDEC_IRQ_0)
- dec_status = HEVC_S2_DECODING_DONE;*/
-#endif
- if (dec_status == HEVC_S2_DECODING_DONE) {
- pbi->dec_result = DEC_RESULT_DONE;
- vdec_schedule_work(&pbi->work);
-#ifdef FB_DECODING_TEST_SCHEDULE
- amhevc_stop();
- pbi->dec_s1_result = DEC_S1_RESULT_DONE;
- vdec_schedule_work(&pbi->s1_work);
-#endif
- } else
-#endif
- if ((dec_status == HEVC_NAL_DECODE_DONE) ||
- (dec_status == HEVC_SEARCH_BUFEMPTY) ||
- (dec_status == HEVC_DECODE_BUFEMPTY)
- ) {
- if (pbi->m_ins_flag) {
- reset_process_time(pbi);
- if (!vdec_frame_based(hw_to_vdec(pbi)))
- dec_again_process(pbi);
- else {
- if (pbi->common.show_existing_frame) {
- pbi->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&pbi->work);
- }
- else {
- pbi->dec_result = DEC_RESULT_GET_DATA;
- vdec_schedule_work(&pbi->work);
- }
- }
- }
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- } else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- if (pbi->m_ins_flag) {
- get_picture_qos_info(pbi);
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0) {
- reset_process_time(pbi);
- inc_s1_pos(pbi);
- trigger_schedule(pbi);
-#ifdef FB_DECODING_TEST_SCHEDULE
- pbi->s1_test_cmd = TEST_SET_S2_DONE;
-#else
- amhevc_stop();
- pbi->dec_s1_result = DEC_S1_RESULT_DONE;
- vdec_schedule_work(&pbi->s1_work);
-#endif
- } else
-#endif
- {
- reset_process_time(pbi);
- if (atomic_read(&pbi->vf_pre_count) == 0 || pbi->low_latency_flag)
- vp9_bufmgr_postproc(pbi);
-
- pbi->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- if (mcrcc_cache_alg_flag)
- dump_hit_rate(pbi);
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
- vdec_schedule_work(&pbi->work);
- }
- } else {
- if (pbi->low_latency_flag) {
- vp9_bufmgr_postproc(pbi);
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- vdec_profile(hw_to_vdec(pbi), VDEC_PROFILE_EVENT_CB);
- if (debug & PRINT_FLAG_VDEC_DETAIL)
- pr_info("%s VP9 frame done \n", __func__);
-#endif
- }
- }
-
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-#endif
-
- if (dec_status == VP9_EOS) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag)
- reset_process_time(pbi);
-#endif
-
- pr_info("VP9_EOS, flush buffer\r\n");
-
- vp9_bufmgr_postproc(pbi);
-
- pr_info("send VP9_10B_DISCARD_NAL\r\n");
- WRITE_VREG(HEVC_DEC_STATUS_REG, VP9_10B_DISCARD_NAL);
- pbi->process_busy = 0;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag) {
- pbi->dec_result = DEC_RESULT_DONE;
- amhevc_stop();
- vdec_schedule_work(&pbi->work);
- }
-#endif
- return IRQ_HANDLED;
- } else if (dec_status == HEVC_DECODE_OVER_SIZE) {
- pr_info("vp9 decode oversize !!\n");
- debug |= (VP9_DEBUG_DIS_LOC_ERROR_PROC |
- VP9_DEBUG_DIS_SYS_ERROR_PROC);
- pbi->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag)
- reset_process_time(pbi);
-#endif
- return IRQ_HANDLED;
- }
-
- if (dec_status != VP9_HEAD_PARSER_DONE) {
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (pbi->m_ins_flag &&
- !get_free_buf_count(pbi) && pbi->pic_list_init_done) {
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "detected %d frames in a packet, ts: %lld.\n",
- pbi->one_package_frame_cnt + 1,
- pbi->chunk->timestamp);
- pbi->process_busy = 0;
- pbi->dec_result = DEC_RESULT_NEED_MORE_BUFFER;
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- vdec_schedule_work(&pbi->work);
- return IRQ_HANDLED;
- }
-
- pbi->one_package_frame_cnt++;
-
-#ifdef MULTI_INSTANCE_SUPPORT
-#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
- if (pbi->m_ins_flag ==0 && pbi->low_latency_flag) {
- vdec_profile(hw_to_vdec(pbi), VDEC_PROFILE_EVENT_RUN);
- if (debug & PRINT_FLAG_VDEC_DETAIL)
- pr_info("%s VP9 frame header found \n", __func__);
- }
-#endif
- if (pbi->m_ins_flag)
- reset_process_time(pbi);
-#endif
- if (pbi->process_state != PROC_STATE_SENDAGAIN
-#ifdef SUPPORT_FB_DECODING
- && pbi->used_stage_buf_num == 0
-#endif
- ) {
- if (pbi->mmu_enable) {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
- vp9_recycle_mmu_buf_tail(pbi);
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
- }
-
- if (pbi->frame_count > 0)
- vp9_bufmgr_postproc(pbi);
- }
-
- if (debug & VP9_DEBUG_SEND_PARAM_WITH_REG) {
- get_rpm_param(&pbi->vp9_param);
- } else {
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0) {
- reset_process_time(pbi);
- get_s1_buf(pbi);
-
- if (get_mv_buf(pbi,
- &pbi->s1_mv_buf_index,
- &pbi->s1_mpred_mv_wr_start_addr
- ) < 0) {
- vp9_print(pbi, 0,
- "%s: Error get_mv_buf fail\n",
- __func__);
- }
-
- if (pbi->s1_buf == NULL) {
- vp9_print(pbi, 0,
- "%s: Error get_s1_buf fail\n",
- __func__);
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++) {
- pbi->s1_buf->rpm[i + 3 - ii] =
- pbi->rpm_ptr[i + 3 - ii];
- pbi->s1_param.l.data[i + ii] =
- pbi->rpm_ptr[i + 3 - ii];
- }
- }
-
- mpred_process(pbi);
-#ifdef FB_DECODING_TEST_SCHEDULE
- pbi->dec_s1_result =
- DEC_S1_RESULT_TEST_TRIGGER_DONE;
- vdec_schedule_work(&pbi->s1_work);
-#else
- WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR,
- pbi->stage_mmu_map_phy_addr +
- pbi->s1_buf->index * STAGE_MMU_MAP_SIZE);
-
- start_s1_decoding(pbi);
-#endif
- start_process_time(pbi);
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- } else
-#endif
- {
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++)
- pbi->vp9_param.l.data[i + ii] =
- pbi->rpm_ptr[i + 3 - ii];
- }
- ATRACE_COUNTER(pbi->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
- }
- }
-
- if (pbi->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
-
- pbi->frame_width = pbi->vp9_param.p.width;
- pbi->frame_height = pbi->vp9_param.p.height;
-
- if (is_oversize(pbi->frame_width, pbi->frame_height)) {
- continue_decoding(pbi);
- vp9_print(pbi, 0, "pic size(%d x %d) is oversize\n",
- pbi->frame_width, pbi->frame_height);
- if (pbi->m_ins_flag)
- start_process_time(pbi);
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (!v4l_res_change(pbi)) {
- if (ctx->param_sets_from_ucode && !pbi->v4l_params_parsed) {
- struct aml_vdec_ps_infos ps;
- struct vdec_comp_buf_info comp;
-
- pr_debug("set ucode parse\n");
- if (get_valid_double_write_mode(pbi) != 16) {
- vvp9_get_comp_buf_info(pbi, &comp);
- vdec_v4l_set_comp_buf_info(ctx, &comp);
- }
-
- vvp9_get_ps_info(pbi, &ps);
- /*notice the v4l2 codec.*/
- vdec_v4l_set_ps_infos(ctx, &ps);
-
- pbi->init_pic_w = pbi->frame_width;
- pbi->init_pic_h = pbi->frame_height;
-
- pbi->last_width = pbi->frame_width;
- pbi->last_height = pbi->frame_height;
-
- pbi->v4l_params_parsed = true;
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- dec_again_process(pbi);
- return IRQ_HANDLED;
- } else {
- if (!pbi->pic_list_init_done) {
- struct vdec_pic_info pic;
-
- vdec_v4l_get_pic_info(ctx, &pic);
- pbi->used_buf_num = pic.dpb_frames +
- pic.dpb_margin;
- init_pic_list(pbi);
- init_pic_list_hw(pbi);
-
- init_mv_buf_list(pbi);
- pbi->pic_list_init_done = true;
- }
- }
- } else {
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- dec_again_process(pbi);
- return IRQ_HANDLED;
- }
- }
-
- continue_decoding(pbi);
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag)
- start_process_time(pbi);
-#endif
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t vvp9_isr(int irq, void *data)
-{
- int i;
- unsigned int dec_status;
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)data;
- unsigned int adapt_prob_status;
- uint debug_tag;
-
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
- dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
- ATRACE_COUNTER("V_ST_DEC-decode_state", dec_status);
-
- if (dec_status == VP9_HEAD_PARSER_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
- }
- else if (dec_status == HEVC_DECPIC_DATA_DONE) {
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_PIC_DONE);
- }
-
- adapt_prob_status = READ_VREG(VP9_ADAPT_PROB_REG);
- if (!pbi)
- return IRQ_HANDLED;
- if (pbi->init_flag == 0)
- return IRQ_HANDLED;
- if (pbi->process_busy) { /*on process.*/
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: process_busy isr return\n", __func__);
- return IRQ_HANDLED;
- }
- pbi->dec_status = dec_status;
- pbi->process_busy = 1;
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("vp9 isr (%d) dec status = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x)\n",
- irq,
- dec_status, READ_VREG(HEVC_PARSER_LCU_START),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR)
- );
-#ifdef SUPPORT_FB_DECODING
- /*if (irq != VDEC_IRQ_0)
- return IRQ_WAKE_THREAD;*/
-#endif
-
- debug_tag = READ_HREG(DEBUG_REG1);
- if (debug_tag & 0x10000) {
- pr_info("LMEM<tag %x>:\n", READ_HREG(DEBUG_REG1));
- for (i = 0; i < 0x400; i += 4) {
- int ii;
- if ((i & 0xf) == 0)
- pr_info("%03x: ", i);
- for (ii = 0; ii < 4; ii++) {
- pr_info("%04x ",
- pbi->lmem_ptr[i + 3 - ii]);
- }
- if (((i + ii) & 0xf) == 0)
- pr_info("\n");
- }
-
- if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == pbi->slice_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2)))
- pbi->ucode_pause_pos = udebug_pause_pos;
- else if (debug_tag & 0x20000)
- pbi->ucode_pause_pos = 0xffffffff;
- if (pbi->ucode_pause_pos)
- reset_process_time(pbi);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- } else if (debug_tag != 0) {
- pr_info(
- "dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
- READ_HREG(DEBUG_REG2),
- READ_VREG(HEVC_PARSER_LCU_START));
- if ((udebug_pause_pos == (debug_tag & 0xffff)) &&
- (udebug_pause_decode_idx == 0 ||
- udebug_pause_decode_idx == pbi->slice_idx) &&
- (udebug_pause_val == 0 ||
- udebug_pause_val == READ_HREG(DEBUG_REG2)))
- pbi->ucode_pause_pos = udebug_pause_pos;
- if (pbi->ucode_pause_pos)
- reset_process_time(pbi);
- else
- WRITE_HREG(DEBUG_REG1, 0);
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!pbi->m_ins_flag) {
-#endif
- if (pbi->error_flag == 1) {
- pbi->error_flag = 2;
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- } else if (pbi->error_flag == 3) {
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-
- if (get_free_buf_count(pbi) <= 0) {
- /*
- if (pbi->wait_buf == 0)
- pr_info("set wait_buf to 1\r\n");
- */
- pbi->wait_buf = 1;
- pbi->process_busy = 0;
- return IRQ_HANDLED;
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- }
-#endif
- if ((adapt_prob_status & 0xff) == 0xfd) {
- struct VP9_Common_s *const cm = &pbi->common;
- int pre_fc = 0;
-
- if (pbi->m_ins_flag)
- reset_process_time(pbi);
-
- if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
- (vdec_secure(hw_to_vdec(pbi)))) {
- pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only)) ? 0 : 1;
- tee_vp9_prob_process(pre_fc, cm->last_frame_type,
- adapt_prob_status, (unsigned int)pbi->prob_buffer_phy_addr);
- } else {
- uint8_t *prev_prob_b, *cur_prob_b, *count_b;
-
- /*VP9_REQ_ADAPT_PROB*/
- pre_fc = ((cm->frame_type == KEY_FRAME) || (cm->intra_only));
- prev_prob_b = ((uint8_t *)pbi->prob_buffer_addr) +
- ((adapt_prob_status >> 8) * 0x1000);
- cur_prob_b = ((uint8_t *)pbi->prob_buffer_addr) + 0x4000;
- count_b = (uint8_t *)pbi->count_buffer_addr;
-
- adapt_coef_probs(pbi->pic_count,
- (cm->last_frame_type == KEY_FRAME),
- pre_fc, (adapt_prob_status >> 8),
- (unsigned int *)prev_prob_b,
- (unsigned int *)cur_prob_b, (unsigned int *)count_b);
-
- memcpy(prev_prob_b, cur_prob_b, PROB_SIZE);
- }
-
- WRITE_VREG(VP9_ADAPT_PROB_REG, 0);
- pbi->pic_count += 1;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag)
- start_process_time(pbi);
-#endif
- }
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_ISR_END);
- return IRQ_WAKE_THREAD;
-}
-
-static void vp9_set_clk(struct work_struct *work)
-{
- struct VP9Decoder_s *pbi = container_of(work,
- struct VP9Decoder_s, set_clk_work);
- int fps = 96000 / pbi->frame_dur;
-
- if (hevc_source_changed(VFORMAT_VP9,
- frame_width, frame_height, fps) > 0)
- pbi->saved_resolution = frame_width *
- frame_height * fps;
-}
-
-static void vvp9_put_timer_func(struct timer_list *timer)
-{
- struct VP9Decoder_s *pbi = container_of(timer,
- struct VP9Decoder_s, timer);
- enum receviver_start_e state = RECEIVER_INACTIVE;
- uint8_t empty_flag;
- unsigned int buf_level;
-
- if (pbi->m_ins_flag) {
- if (hw_to_vdec(pbi)->next_status
- == VDEC_STATUS_DISCONNECTED &&
- !pbi->is_used_v4l) {
-#ifdef SUPPORT_FB_DECODING
- if (pbi->run2_busy)
- return;
-
- pbi->dec_s1_result = DEC_S1_RESULT_FORCE_EXIT;
- vdec_schedule_work(&pbi->s1_work);
-#endif
- pbi->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&pbi->work);
- pr_debug(
- "vdec requested to be disconnected\n");
- return;
- }
- }
- if (pbi->init_flag == 0) {
- if (pbi->stat & STAT_TIMER_ARM) {
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(&pbi->timer);
- }
- return;
- }
- if (pbi->m_ins_flag == 0) {
- if (vf_get_receiver(pbi->provider_name)) {
- state =
- vf_notify_receiver(pbi->provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- if ((state == RECEIVER_STATE_NULL)
- || (state == RECEIVER_STATE_NONE))
- state = RECEIVER_INACTIVE;
- } else
- state = RECEIVER_INACTIVE;
-
- empty_flag = (READ_VREG(HEVC_PARSER_INT_STATUS) >> 6) & 0x1;
- /* error watchdog */
- if (empty_flag == 0) {
- /* decoder has input */
- if ((debug & VP9_DEBUG_DIS_LOC_ERROR_PROC) == 0) {
-
- buf_level = READ_VREG(HEVC_STREAM_LEVEL);
- /* receiver has no buffer to recycle */
- if ((state == RECEIVER_INACTIVE) &&
- (kfifo_is_empty(&pbi->display_q) &&
- buf_level > 0x200)
- ) {
- WRITE_VREG
- (HEVC_ASSIST_MBOX0_IRQ_REG,
- 0x1);
- }
- }
-
- if ((debug & VP9_DEBUG_DIS_SYS_ERROR_PROC) == 0) {
- /* receiver has no buffer to recycle */
- /*if ((state == RECEIVER_INACTIVE) &&
- * (kfifo_is_empty(&pbi->display_q))) {
- *pr_info("vp9 something error,need reset\n");
- *}
- */
- }
- }
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- else {
- if (
- (decode_timeout_val > 0) &&
- (pbi->start_process_time > 0) &&
- ((1000 * (jiffies - pbi->start_process_time) / HZ)
- > decode_timeout_val)
- ) {
- int current_lcu_idx =
- READ_VREG(HEVC_PARSER_LCU_START)
- & 0xffffff;
- if (pbi->last_lcu_idx == current_lcu_idx) {
- if (pbi->decode_timeout_count > 0)
- pbi->decode_timeout_count--;
- if (pbi->decode_timeout_count == 0) {
- if (input_frame_based(
- hw_to_vdec(pbi)) ||
- (READ_VREG(HEVC_STREAM_LEVEL) > 0x200))
- timeout_process(pbi);
- else {
- vp9_print(pbi, 0,
- "timeout & empty, again\n");
- dec_again_process(pbi);
- }
- }
- } else {
- start_process_time(pbi);
- pbi->last_lcu_idx = current_lcu_idx;
- }
- }
- }
-#endif
-
- if ((pbi->ucode_pause_pos != 0) &&
- (pbi->ucode_pause_pos != 0xffffffff) &&
- udebug_pause_pos != pbi->ucode_pause_pos) {
- pbi->ucode_pause_pos = 0;
- WRITE_HREG(DEBUG_REG1, 0);
- }
-#ifdef MULTI_INSTANCE_SUPPORT
- if (debug & VP9_DEBUG_FORCE_SEND_AGAIN) {
- pr_info(
- "Force Send Again\r\n");
- debug &= ~VP9_DEBUG_FORCE_SEND_AGAIN;
- reset_process_time(pbi);
- pbi->dec_result = DEC_RESULT_AGAIN;
- if (pbi->process_state ==
- PROC_STATE_DECODESLICE) {
- if (pbi->mmu_enable)
- vp9_recycle_mmu_buf(pbi);
- pbi->process_state =
- PROC_STATE_SENDAGAIN;
- }
- amhevc_stop();
-
- vdec_schedule_work(&pbi->work);
- }
-
- if (debug & VP9_DEBUG_DUMP_DATA) {
- debug &= ~VP9_DEBUG_DUMP_DATA;
- vp9_print(pbi, 0,
- "%s: chunk size 0x%x off 0x%x sum 0x%x\n",
- __func__,
- pbi->chunk->size,
- pbi->chunk->offset,
- get_data_check_sum(pbi, pbi->chunk->size)
- );
- dump_data(pbi, pbi->chunk->size);
- }
-#endif
- if (debug & VP9_DEBUG_DUMP_PIC_LIST) {
- dump_pic_list(pbi);
- debug &= ~VP9_DEBUG_DUMP_PIC_LIST;
- }
- if (debug & VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC) {
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- debug &= ~VP9_DEBUG_TRIG_SLICE_SEGMENT_PROC;
- }
- /*if (debug & VP9_DEBUG_HW_RESET) {
- }*/
-
- if (radr != 0) {
- if (rval != 0) {
- WRITE_VREG(radr, rval);
- pr_info("WRITE_VREG(%x,%x)\n", radr, rval);
- } else
- pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr));
- rval = 0;
- radr = 0;
- }
- if (pop_shorts != 0) {
- int i;
- u32 sum = 0;
-
- pr_info("pop stream 0x%x shorts\r\n", pop_shorts);
- for (i = 0; i < pop_shorts; i++) {
- u32 data =
- (READ_HREG(HEVC_SHIFTED_DATA) >> 16);
- WRITE_HREG(HEVC_SHIFT_COMMAND,
- (1<<7)|16);
- if ((i & 0xf) == 0)
- pr_info("%04x:", i);
- pr_info("%04x ", data);
- if (((i + 1) & 0xf) == 0)
- pr_info("\r\n");
- sum += data;
- }
- pr_info("\r\nsum = %x\r\n", sum);
- pop_shorts = 0;
- }
- if (dbg_cmd != 0) {
- if (dbg_cmd == 1) {
- u32 disp_laddr;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB &&
- get_double_write_mode(pbi) == 0) {
- disp_laddr =
- READ_VCBUS_REG(AFBC_BODY_BADDR) << 4;
- } else {
- struct canvas_s cur_canvas;
-
- canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0)
- & 0xff), &cur_canvas);
- disp_laddr = cur_canvas.addr;
- }
- pr_info("current displayed buffer address %x\r\n",
- disp_laddr);
- }
- dbg_cmd = 0;
- }
- /*don't changed at start.*/
- if (pbi->get_frame_dur && pbi->show_frame_num > 60 &&
- pbi->frame_dur > 0 && pbi->saved_resolution !=
- frame_width * frame_height *
- (96000 / pbi->frame_dur))
- vdec_schedule_work(&pbi->set_clk_work);
-
- timer->expires = jiffies + PUT_INTERVAL;
- add_timer(timer);
-}
-
-
-int vvp9_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
- struct VP9Decoder_s *vp9 =
- (struct VP9Decoder_s *)vdec->private;
-
- if (!vp9)
- return -1;
-
- vstatus->frame_width = frame_width;
- vstatus->frame_height = frame_height;
- if (vp9->error_frame_width &&
- vp9->error_frame_height) {
- vstatus->frame_width = vp9->error_frame_width;
- vstatus->frame_height = vp9->error_frame_height;
- }
-
- if (vp9->frame_dur != 0)
- vstatus->frame_rate = ((96000 * 10 / vp9->frame_dur) % 10) < 5 ?
- 96000 / vp9->frame_dur : (96000 / vp9->frame_dur +1);
- else
- vstatus->frame_rate = -1;
- vstatus->error_count = 0;
- vstatus->status = vp9->stat | vp9->fatal_error;
- vstatus->frame_dur = vp9->frame_dur;
- vstatus->bit_rate = vp9->gvs->bit_rate;
- vstatus->frame_data = vp9->gvs->frame_data;
- vstatus->total_data = vp9->gvs->total_data;
- vstatus->frame_count = vp9->gvs->frame_count;
- vstatus->error_frame_count = vp9->gvs->error_frame_count;
- vstatus->drop_frame_count = vp9->gvs->drop_frame_count;
- vstatus->i_decoded_frames = vp9->gvs->i_decoded_frames;
- vstatus->i_lost_frames = vp9->gvs->i_lost_frames;
- vstatus->i_concealed_frames = vp9->gvs->i_concealed_frames;
- vstatus->p_decoded_frames = vp9->gvs->p_decoded_frames;
- vstatus->p_lost_frames = vp9->gvs->p_lost_frames;
- vstatus->p_concealed_frames = vp9->gvs->p_concealed_frames;
- vstatus->b_decoded_frames = vp9->gvs->b_decoded_frames;
- vstatus->b_lost_frames = vp9->gvs->b_lost_frames;
- vstatus->b_concealed_frames = vp9->gvs->b_concealed_frames;
- vstatus->total_data = vp9->gvs->total_data;
- vstatus->samp_cnt = vp9->gvs->samp_cnt;
- vstatus->offset = vp9->gvs->offset;
- snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
- "%s", DRIVER_NAME);
- return 0;
-}
-
-int vvp9_set_isreset(struct vdec_s *vdec, int isreset)
-{
- is_reset = isreset;
- return 0;
-}
-
-#if 0
-static void VP9_DECODE_INIT(void)
-{
- /* enable vp9 clocks */
- WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
- /* *************************************************************** */
- /* Power ON HEVC */
- /* *************************************************************** */
- /* Powerup HEVC */
- WRITE_VREG(AO_RTI_GEN_PWR_SLEEP0,
- READ_VREG(AO_RTI_GEN_PWR_SLEEP0) & (~(0x3 << 6)));
- WRITE_VREG(DOS_MEM_PD_HEVC, 0x0);
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) | (0x3ffff << 2));
- WRITE_VREG(DOS_SW_RESET3, READ_VREG(DOS_SW_RESET3) & (~(0x3ffff << 2)));
- /* remove isolations */
- WRITE_VREG(AO_RTI_GEN_PWR_ISO0,
- READ_VREG(AO_RTI_GEN_PWR_ISO0) & (~(0x3 << 10)));
-
-}
-#endif
-
-static void vvp9_prot_init(struct VP9Decoder_s *pbi, u32 mask)
-{
- unsigned int data32;
- /* VP9_DECODE_INIT(); */
- vp9_config_work_space_hw(pbi, mask);
- if (mask & HW_MASK_BACK)
- init_pic_list_hw(pbi);
-
- vp9_init_decoder_hw(pbi, mask);
-
-#ifdef VP9_LPF_LVL_UPDATE
- if (mask & HW_MASK_BACK)
- vp9_loop_filter_init(pbi);
-#endif
-
- if ((mask & HW_MASK_FRONT) == 0)
- return;
-#if 1
- if (debug & VP9_DEBUG_BUFMGR_MORE)
- pr_info("%s\n", __func__);
- data32 = READ_VREG(HEVC_STREAM_CONTROL);
- data32 = data32 |
- (1 << 0)/*stream_fetch_enable*/
- ;
- WRITE_VREG(HEVC_STREAM_CONTROL, data32);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
- if (debug & VP9_DEBUG_BUFMGR)
- pr_info("[test.c] Config STREAM_FIFO_CTL\n");
- data32 = READ_VREG(HEVC_STREAM_FIFO_CTL);
- data32 = data32 |
- (1 << 29) // stream_fifo_hole
- ;
- WRITE_VREG(HEVC_STREAM_FIFO_CTL, data32);
- }
-#if 0
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x00000100) {
- pr_info("vp9 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x00000300) {
- pr_info("vp9 prot init error %d\n", __LINE__);
- return;
- }
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x12345678);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x9abcdef0);
- data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
- if (data32 != 0x12345678) {
- pr_info("vp9 prot init error %d\n", __LINE__);
- return;
- }
- data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
- if (data32 != 0x9abcdef0) {
- pr_info("vp9 prot init error %d\n", __LINE__);
- return;
- }
-#endif
- WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x000000001);
- WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000300);
-#endif
-
-
-
- WRITE_VREG(HEVC_WAIT_FLAG, 1);
-
- /* WRITE_VREG(HEVC_MPSR, 1); */
-
- /* clear mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 1);
-
- /* disable PSCALE for hardware sharing */
- WRITE_VREG(HEVC_PSCALE_CTRL, 0);
-
- WRITE_VREG(DEBUG_REG1, 0x0);
- /*check vps/sps/pps/i-slice in ucode*/
- WRITE_VREG(NAL_SEARCH_CTL, 0x8);
-
- WRITE_VREG(DECODE_STOP_POS, udebug_flag);
-#ifdef SUPPORT_FB_DECODING
-#ifndef FB_DECODING_TEST_SCHEDULE
- if (pbi->used_stage_buf_num > 0) {
- if (mask & HW_MASK_FRONT) {
- data32 = READ_VREG(
- HEVC_ASSIST_HED_FB_W_CTL);
- data32 = data32 |
- (1 << 0) /*hed_fb_wr_en*/
- ;
- WRITE_VREG(HEVC_ASSIST_HED_FB_W_CTL,
- data32);
- }
- if (mask & HW_MASK_BACK) {
- data32 = READ_VREG(
- HEVC_ASSIST_HED_FB_R_CTL);
- while (data32 & (1 << 7)) {
- /*wait finish*/
- data32 = READ_VREG(
- HEVC_ASSIST_HED_FB_R_CTL);
- }
- data32 &= (~(0x1 << 0));
- /*hed_fb_rd_addr_auto_rd*/
- data32 &= (~(0x1 << 1));
- /*rd_id = 0, hed_rd_map_auto_halt_num,
- after wr 2 ready, then start reading*/
- data32 |= (0x2 << 16);
- WRITE_VREG(HEVC_ASSIST_HED_FB_R_CTL,
- data32);
-
- data32 |= (0x1 << 11); /*hed_rd_map_auto_halt_en*/
- data32 |= (0x1 << 1); /*hed_fb_rd_addr_auto_rd*/
- data32 |= (0x1 << 0); /*hed_fb_rd_en*/
- WRITE_VREG(HEVC_ASSIST_HED_FB_R_CTL,
- data32);
- }
-
- }
-#endif
-#endif
-}
-
-static int vvp9_local_init(struct VP9Decoder_s *pbi)
-{
- int i;
- int ret;
- int width, height;
- if (alloc_lf_buf(pbi) < 0)
- return -1;
-
- pbi->gvs = vzalloc(sizeof(struct vdec_info));
- if (NULL == pbi->gvs) {
- pr_info("the struct of vdec status malloc failed.\n");
- return -1;
- }
- vdec_set_vframe_comm(hw_to_vdec(pbi), DRIVER_NAME);
-#ifdef DEBUG_PTS
- pbi->pts_missed = 0;
- pbi->pts_hit = 0;
-#endif
- pbi->new_frame_displayed = 0;
- pbi->last_put_idx = -1;
- pbi->saved_resolution = 0;
- pbi->get_frame_dur = false;
- on_no_keyframe_skiped = 0;
- pbi->duration_from_pts_done = 0;
- pbi->vp9_first_pts_ready = 0;
- pbi->frame_cnt_window = 0;
- width = pbi->vvp9_amstream_dec_info.width;
- height = pbi->vvp9_amstream_dec_info.height;
- pbi->frame_dur =
- (pbi->vvp9_amstream_dec_info.rate ==
- 0) ? 3200 : pbi->vvp9_amstream_dec_info.rate;
- if (width && height)
- pbi->frame_ar = height * 0x100 / width;
-/*
- *TODO:FOR VERSION
- */
- pr_info("vp9: ver (%d,%d) decinfo: %dx%d rate=%d\n", vp9_version,
- 0, width, height, pbi->frame_dur);
-
- if (pbi->frame_dur == 0)
- pbi->frame_dur = 96000 / 24;
-
- INIT_KFIFO(pbi->display_q);
- INIT_KFIFO(pbi->newframe_q);
-
- for (i = 0; i < VF_POOL_SIZE; i++) {
- const struct vframe_s *vf = &pbi->vfpool[i];
-
- pbi->vfpool[i].index = -1;
- kfifo_put(&pbi->newframe_q, vf);
- }
-
-
- ret = vp9_local_init(pbi);
-
- if (!pbi->pts_unstable) {
- pbi->pts_unstable =
- (pbi->vvp9_amstream_dec_info.rate == 0)?1:0;
- pr_info("set pts unstable\n");
- }
-
- return ret;
-}
-
-
-#ifdef MULTI_INSTANCE_SUPPORT
-static s32 vvp9_init(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)vdec->private;
-#else
-static s32 vvp9_init(struct VP9Decoder_s *pbi)
-{
-#endif
- int ret;
- int fw_size = 0x1000 * 16;
- struct firmware_s *fw = NULL;
-
- pbi->stat |= STAT_TIMER_INIT;
-
- if (vvp9_local_init(pbi) < 0)
- return -EBUSY;
-
- fw = vmalloc(sizeof(struct firmware_s) + fw_size);
- if (IS_ERR_OR_NULL(fw))
- return -ENOMEM;
-
- if (get_firmware_data(VIDEO_DEC_VP9_MMU, fw->data) < 0) {
- pr_err("get firmware fail.\n");
- vfree(fw);
- return -1;
- }
-
- fw->len = fw_size;
-
- INIT_WORK(&pbi->set_clk_work, vp9_set_clk);
- timer_setup(&pbi->timer, vvp9_put_timer_func, 0);
- spin_lock_init(&pbi->wait_buf_lock);
-
-#ifdef MULTI_INSTANCE_SUPPORT
- if (pbi->m_ins_flag) {
- pbi->timer.expires = jiffies + PUT_INTERVAL;
-
- /*add_timer(&pbi->timer);
-
- pbi->stat |= STAT_TIMER_ARM;
- pbi->stat |= STAT_ISR_REG;*/
-
- INIT_WORK(&pbi->work, vp9_work);
- INIT_WORK(&pbi->recycle_mmu_work, vp9_recycle_mmu_work);
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0)
- INIT_WORK(&pbi->s1_work, vp9_s1_work);
-#endif
- pbi->fw = fw;
-
- return 0;
- }
-#endif
- amhevc_enable();
-
- init_pic_list(pbi);
-
- ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, fw->data);
- if (ret < 0) {
- amhevc_disable();
- vfree(fw);
- pr_err("VP9: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
-
- vfree(fw);
-
- pbi->stat |= STAT_MC_LOAD;
-
- /* enable AMRISC side protocol */
- vvp9_prot_init(pbi, HW_MASK_FRONT | HW_MASK_BACK);
-
- if (vdec_request_threaded_irq(VDEC_IRQ_0,
- vvp9_isr,
- vvp9_isr_thread_fn,
- IRQF_ONESHOT,/*run thread on this irq disabled*/
- "vvp9-irq", (void *)pbi)) {
- pr_info("vvp9 irq register error.\n");
- amhevc_disable();
- return -ENOENT;
- }
-
- pbi->stat |= STAT_ISR_REG;
-
- pbi->provider_name = PROVIDER_NAME;
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!pbi->is_used_v4l) {
- vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME,
- &vvp9_vf_provider, pbi);
- vf_reg_provider(&vvp9_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
- if (pbi->frame_dur != 0) {
- if (!is_reset)
- vf_notify_receiver(pbi->provider_name,
- VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)
- ((unsigned long)pbi->frame_dur));
- }
- }
-#else
- vf_provider_init(&vvp9_vf_prov, PROVIDER_NAME, &vvp9_vf_provider,
- pbi);
- vf_reg_provider(&vvp9_vf_prov);
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
- if (!is_reset)
- vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
- (void *)((unsigned long)pbi->frame_dur));
-#endif
- pbi->stat |= STAT_VF_HOOK;
-
- pbi->timer.expires = jiffies + PUT_INTERVAL;
- add_timer(&pbi->timer);
-
- pbi->stat |= STAT_VDEC_RUN;
-
- pbi->stat |= STAT_TIMER_ARM;
-
- amhevc_start();
-
- pbi->init_flag = 1;
- pbi->process_busy = 0;
- pr_info("%d, vvp9_init, RP=0x%x\n",
- __LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
- return 0;
-}
-
-static int vmvp9_stop(struct VP9Decoder_s *pbi)
-{
- pbi->init_flag = 0;
-
- if (pbi->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- pbi->stat &= ~STAT_VDEC_RUN;
- }
- if (pbi->stat & STAT_ISR_REG) {
- vdec_free_irq(VDEC_IRQ_0, (void *)pbi);
- pbi->stat &= ~STAT_ISR_REG;
- }
- if (pbi->stat & STAT_TIMER_ARM) {
- del_timer_sync(&pbi->timer);
- pbi->stat &= ~STAT_TIMER_ARM;
- }
-
- if (!pbi->is_used_v4l && (pbi->stat & STAT_VF_HOOK)) {
- if (!is_reset)
- vf_notify_receiver(pbi->provider_name,
- VFRAME_EVENT_PROVIDER_FR_END_HINT,
- NULL);
-
- vf_unreg_provider(&vvp9_vf_prov);
- pbi->stat &= ~STAT_VF_HOOK;
- }
- vp9_local_uninit(pbi);
- reset_process_time(pbi);
- cancel_work_sync(&pbi->work);
- cancel_work_sync(&pbi->recycle_mmu_work);
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0)
- cancel_work_sync(&pbi->s1_work);
-#endif
- cancel_work_sync(&pbi->set_clk_work);
- uninit_mmu_buffers(pbi);
- if (pbi->fw)
- vfree(pbi->fw);
- pbi->fw = NULL;
- return 0;
-}
-
-static int amvdec_vp9_mmu_init(struct VP9Decoder_s *pbi)
-{
- int tvp_flag = vdec_secure(hw_to_vdec(pbi)) ?
- CODEC_MM_FLAGS_TVP : 0;
- int buf_size = vp9_max_mmu_buf_size(pbi->max_pic_w, pbi->max_pic_h);
-
- pbi->need_cache_size = buf_size * SZ_1M;
- pbi->sc_start_time = get_jiffies_64();
- if (pbi->mmu_enable && !pbi->is_used_v4l) {
- pbi->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
- pbi->index, FRAME_BUFFERS,
- pbi->need_cache_size,
- tvp_flag
- );
- if (!pbi->mmu_box) {
- pr_err("vp9 alloc mmu box failed!!\n");
- return -1;
- }
- }
- pbi->bmmu_box = decoder_bmmu_box_alloc_box(
- DRIVER_NAME,
- pbi->index,
- MAX_BMMU_BUFFER_NUM,
- 4 + PAGE_SHIFT,
- CODEC_MM_FLAGS_CMA_CLEAR |
- CODEC_MM_FLAGS_FOR_VDECODER |
- tvp_flag);
- if (!pbi->bmmu_box) {
- pr_err("vp9 alloc bmmu box failed!!\n");
- return -1;
- }
- return 0;
-}
-
-static void vdec_fence_release(struct VP9Decoder_s *pbi,
- struct vdec_sync *sync)
-{
- ulong expires;
-
- /* notify signal to wake up all fences. */
- vdec_timeline_increase(sync, VF_POOL_SIZE);
-
- expires = jiffies + msecs_to_jiffies(2000);
- while (!check_objs_all_signaled(sync)) {
- if (time_after(jiffies, expires)) {
- pr_err("wait fence signaled timeout.\n");
- break;
- }
- }
-
- /* decreases refcnt of timeline. */
- vdec_timeline_put(sync);
-}
-
-/****************************************/
-
-static struct codec_profile_t amvdec_vp9_profile = {
- .name = "VP9-V4L",
- .profile = ""
-};
-
-static unsigned char get_data_check_sum
- (struct VP9Decoder_s *pbi, int size)
-{
- int jj;
- int sum = 0;
- u8 *data = NULL;
-
- if (vdec_secure(hw_to_vdec(pbi)))
- return 0;
-
- if (!pbi->chunk->block->is_mapped)
- data = codec_mm_vmap(pbi->chunk->block->start +
- pbi->chunk->offset, size);
- else
- data = ((u8 *)pbi->chunk->block->start_virt) +
- pbi->chunk->offset;
-
- for (jj = 0; jj < size; jj++)
- sum += data[jj];
-
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n",
- __func__, size, sum,
- (size < 1) ? 0 : data[0],
- (size < 2) ? 0 : data[1],
- (size < 3) ? 0 : data[2],
- (size < 4) ? 0 : data[3],
- (size < 5) ? 0 : data[4],
- (size < 6) ? 0 : data[5],
- (size < 4) ? 0 : data[size - 4],
- (size < 3) ? 0 : data[size - 3],
- (size < 2) ? 0 : data[size - 2],
- (size < 1) ? 0 : data[size - 1]);
-
- if (!pbi->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- return sum;
-}
-
-static void dump_data(struct VP9Decoder_s *pbi, int size)
-{
- int jj;
- u8 *data = NULL;
- int padding_size = pbi->chunk->offset &
- (VDEC_FIFO_ALIGN - 1);
-
- if (!pbi->chunk->block->is_mapped)
- data = codec_mm_vmap(pbi->chunk->block->start +
- pbi->chunk->offset, size);
- else
- data = ((u8 *)pbi->chunk->block->start_virt) +
- pbi->chunk->offset;
-
- vp9_print(pbi, 0, "padding: ");
- for (jj = padding_size; jj > 0; jj--)
- vp9_print_cont(pbi,
- 0,
- "%02x ", *(data - jj));
- vp9_print_cont(pbi, 0, "data adr %p\n",
- data);
-
- for (jj = 0; jj < size; jj++) {
- if ((jj & 0xf) == 0)
- vp9_print(pbi,
- 0,
- "%06x:", jj);
- vp9_print_cont(pbi,
- 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- vp9_print(pbi,
- 0,
- "\n");
- }
- vp9_print(pbi,
- 0,
- "\n");
-
- if (!pbi->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
-}
-
-static int vp9_wait_cap_buf(void *args)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *) args;
- struct aml_vcodec_ctx * ctx =
- (struct aml_vcodec_ctx *)pbi->v4l2_ctx;
- ulong flags;
- int ret = 0;
-
- ret = wait_event_interruptible_timeout(ctx->cap_wq,
- (ctx->is_stream_off || (get_free_buf_count(pbi) > 0)),
- msecs_to_jiffies(300));
- if (ret <= 0){
- pr_err("%s, wait cap buf timeout or err %d\n",
- __func__, ret);
- }
-
- spin_lock_irqsave(&pbi->wait_buf_lock, flags);
- if (pbi->wait_more_buf) {
- pbi->wait_more_buf = false;
- pbi->dec_result = ctx->is_stream_off ?
- DEC_RESULT_FORCE_EXIT :
- DEC_RESULT_NEED_MORE_BUFFER;
- vdec_schedule_work(&pbi->work);
- }
- spin_unlock_irqrestore(&pbi->wait_buf_lock, flags);
-
- vp9_print(pbi, PRINT_FLAG_V4L_DETAIL,
- "%s wait capture buffer end, ret:%d\n",
- __func__, ret);
- return 0;
-}
-
-static void vp9_work(struct work_struct *work)
-{
- struct VP9Decoder_s *pbi = container_of(work,
- struct VP9Decoder_s, work);
- struct vdec_s *vdec = hw_to_vdec(pbi);
- /* finished decoding one frame or error,
- * notify vdec core to switch context
- */
- if (pbi->dec_result == DEC_RESULT_AGAIN)
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_AGAIN);
-
- if (pbi->dec_result != DEC_RESULT_NEED_MORE_BUFFER)
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_START);
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "%s dec_result %d %x %x %x\n",
- __func__,
- pbi->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
-
- ATRACE_COUNTER("V_ST_DEC-work_state", pbi->dec_result);
-
- if (pbi->dec_result == DEC_INIT_PICLIST) {
- init_pic_list(pbi);
- pbi->pic_list_init_done = true;
- return;
- }
-
- if (pbi->dec_result == DEC_RESULT_NEED_MORE_BUFFER) {
- reset_process_time(pbi);
- if (!get_free_buf_count(pbi)) {
- ulong flags;
-
- spin_lock_irqsave(&pbi->wait_buf_lock, flags);
- if (vdec->next_status == VDEC_STATUS_DISCONNECTED) {
- pbi->dec_result = DEC_RESULT_AGAIN;
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
- vdec_schedule_work(&pbi->work);
- } else {
- pbi->wait_more_buf = true;
- }
- spin_unlock_irqrestore(&pbi->wait_buf_lock, flags);
-
- if (pbi->wait_more_buf) {
- ATRACE_COUNTER("V_ST_DEC-wait_more_buff", __LINE__);
- vdec_post_task(vp9_wait_cap_buf, pbi);
- }
- } else {
- int i;
-
- ATRACE_COUNTER("V_ST_DEC-wait_more_buff", 0);
-
- if (pbi->mmu_enable)
- vp9_recycle_mmu_buf_tail(pbi);
-
- if (pbi->frame_count > 0)
- vp9_bufmgr_postproc(pbi);
-
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++)
- pbi->vp9_param.l.data[i + ii] =
- pbi->rpm_ptr[i + 3 - ii];
- }
- continue_decoding(pbi);
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
-
- start_process_time(pbi);
- }
-
- return;
- }
-
- if (((pbi->dec_result == DEC_RESULT_GET_DATA) ||
- (pbi->dec_result == DEC_RESULT_GET_DATA_RETRY))
- && (hw_to_vdec(pbi)->next_status !=
- VDEC_STATUS_DISCONNECTED)) {
- if (!vdec_has_more_input(vdec)) {
- pbi->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&pbi->work);
- return;
- }
-
- if (pbi->dec_result == DEC_RESULT_GET_DATA) {
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s DEC_RESULT_GET_DATA %x %x %x\n",
- __func__,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR));
- vdec_vframe_dirty(vdec, pbi->chunk);
- vdec_clean_input(vdec);
- }
-
- if (get_free_buf_count(pbi) >=
- pbi->run_ready_min_buf_num) {
- int r;
- int decode_size;
- r = vdec_prepare_input(vdec, &pbi->chunk);
- if (r < 0) {
- pbi->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- vp9_print(pbi,
- PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&pbi->work);
- return;
- }
- pbi->dec_result = DEC_RESULT_NONE;
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: chunk size 0x%x sum 0x%x\n",
- __func__, r,
- (debug & PRINT_FLAG_VDEC_STATUS) ?
- get_data_check_sum(pbi, r) : 0
- );
-
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(pbi, pbi->chunk->size);
-
- decode_size = pbi->chunk->size +
- (pbi->chunk->offset & (VDEC_FIFO_ALIGN - 1));
-
- WRITE_VREG(HEVC_DECODE_SIZE,
- READ_VREG(HEVC_DECODE_SIZE) + decode_size);
-
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- start_process_time(pbi);
-
- } else{
- pbi->dec_result = DEC_RESULT_GET_DATA_RETRY;
-
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "amvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&pbi->work);
- }
- return;
- } else if (pbi->dec_result == DEC_RESULT_DONE) {
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0) {
-#ifndef FB_DECODING_TEST_SCHEDULE
- if (!is_s2_decoding_finished(pbi)) {
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "s2 decoding not done, check again later\n");
- vdec_schedule_work(&pbi->work);
- }
-#endif
- inc_s2_pos(pbi);
- if (mcrcc_cache_alg_flag)
- dump_hit_rate(pbi);
- }
-#endif
- /* if (!pbi->ctx_valid)
- pbi->ctx_valid = 1; */
- pbi->slice_idx++;
- pbi->frame_count++;
- pbi->process_state = PROC_STATE_INIT;
- decode_frame_count[pbi->index] = pbi->frame_count;
-
- if (pbi->mmu_enable)
- pbi->used_4k_num =
- (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
- __func__,
- pbi->frame_count,
- pbi->dec_result,
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT),
- READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
- pbi->start_shift_bytes
- );
- vdec_vframe_dirty(hw_to_vdec(pbi), pbi->chunk);
- } else if (pbi->dec_result == DEC_RESULT_AGAIN) {
- /*
- stream base: stream buf empty or timeout
- frame base: vdec_prepare_input fail
- */
- if (!vdec_has_more_input(vdec)) {
- pbi->dec_result = DEC_RESULT_EOS;
- vdec_schedule_work(&pbi->work);
- return;
- }
- } else if (pbi->dec_result == DEC_RESULT_EOS) {
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: end of stream\n",
- __func__);
- pbi->eos = 1;
- vp9_bufmgr_postproc(pbi);
-
- if (pbi->is_used_v4l) {
- ATRACE_COUNTER("V_ST_DEC-submit_eos", __LINE__);
- notify_v4l_eos(hw_to_vdec(pbi));
- ATRACE_COUNTER("V_ST_DEC-submit_eos", 0);
- }
-
- vdec_vframe_dirty(hw_to_vdec(pbi), pbi->chunk);
- } else if (pbi->dec_result == DEC_RESULT_FORCE_EXIT) {
- vp9_print(pbi, PRINT_FLAG_VDEC_STATUS,
- "%s: force exit\n",
- __func__);
- if (pbi->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- pbi->stat &= ~STAT_VDEC_RUN;
- }
-
- if (pbi->stat & STAT_ISR_REG) {
-#ifdef MULTI_INSTANCE_SUPPORT
- if (!pbi->m_ins_flag)
-#endif
- WRITE_VREG(HEVC_ASSIST_MBOX0_MASK, 0);
- vdec_free_irq(VDEC_IRQ_0, (void *)pbi);
- pbi->stat &= ~STAT_ISR_REG;
- }
- }
- if (pbi->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- pbi->stat &= ~STAT_VDEC_RUN;
- }
-
- if (pbi->stat & STAT_TIMER_ARM) {
- del_timer_sync(&pbi->timer);
- pbi->stat &= ~STAT_TIMER_ARM;
- }
- if (pbi->dec_result != DEC_RESULT_NEED_MORE_BUFFER)
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_WORKER_END);
- /* mark itself has all HW resource released and input released */
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0)
- vdec_core_finish_run(hw_to_vdec(pbi), CORE_MASK_HEVC_BACK);
- else
- vdec_core_finish_run(hw_to_vdec(pbi), CORE_MASK_VDEC_1
- | CORE_MASK_HEVC
- | CORE_MASK_HEVC_FRONT
- | CORE_MASK_HEVC_BACK
- );
-#else
- if (vdec->parallel_dec == 1)
- vdec_core_finish_run(vdec, CORE_MASK_HEVC);
- else
- vdec_core_finish_run(hw_to_vdec(pbi), CORE_MASK_VDEC_1
- | CORE_MASK_HEVC);
-#endif
- trigger_schedule(pbi);
-}
-
-static int vp9_hw_ctx_restore(struct VP9Decoder_s *pbi)
-{
- /* new to do ... */
-#if (!defined SUPPORT_FB_DECODING)
- vvp9_prot_init(pbi, HW_MASK_FRONT | HW_MASK_BACK);
-#elif (defined FB_DECODING_TEST_SCHEDULE)
- vvp9_prot_init(pbi, HW_MASK_FRONT | HW_MASK_BACK);
-#else
- if (pbi->used_stage_buf_num > 0)
- vvp9_prot_init(pbi, HW_MASK_FRONT);
- else
- vvp9_prot_init(pbi, HW_MASK_FRONT | HW_MASK_BACK);
-#endif
- return 0;
-}
-
-static bool is_avaliable_buffer(struct VP9Decoder_s *pbi)
-{
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- int i, free_count = 0;
- int used_count = 0;
-
- if ((pbi->used_buf_num == 0) ||
- (ctx->cap_pool.dec < pbi->used_buf_num)) {
- if (ctx->fb_ops.query(&ctx->fb_ops, &pbi->fb_token)) {
- free_count =
- v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) + 1;
- }
- }
-
- for (i = 0; i < pbi->used_buf_num; ++i) {
- if ((frame_bufs[i].ref_count == 0) &&
- (frame_bufs[i].buf.vf_ref == 0) &&
- (frame_bufs[i].buf.repeat_count == 0) &&
- frame_bufs[i].buf.cma_alloc_addr &&
- (cm->cur_frame != &frame_bufs[i])) {
- free_count++;
- } else if (frame_bufs[i].buf.cma_alloc_addr)
- used_count++;
- }
-
- ATRACE_COUNTER("V_ST_DEC-free_buff_count", free_count);
- ATRACE_COUNTER("V_ST_DEC-used_buff_count", used_count);
-
- return free_count >= pbi->run_ready_min_buf_num ? 1 : 0;
-}
-
-static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- int tvp = vdec_secure(hw_to_vdec(pbi)) ?
- CODEC_MM_FLAGS_TVP : 0;
- unsigned long ret = 0;
-
- if (!pbi->pic_list_init_done2 || pbi->eos)
- return ret;
- if (!pbi->first_sc_checked && pbi->mmu_enable) {
- int size;
- void * mmu_box;
-
- if (pbi->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- mmu_box = ctx->mmu_box;
- } else
- mmu_box = pbi->mmu_box;
-
- size = decoder_mmu_box_sc_check(mmu_box, tvp);
- pbi->first_sc_checked = 1;
- vp9_print(pbi, 0, "vp9 cached=%d need_size=%d speed= %d ms\n",
- size, (pbi->need_cache_size >> PAGE_SHIFT),
- (int)(get_jiffies_64() - pbi->sc_start_time) * 1000/HZ);
- }
-
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0) {
- if (mask & CORE_MASK_HEVC_FRONT) {
- if (get_free_stage_buf_num(pbi) > 0
- && mv_buf_available(pbi))
- ret |= CORE_MASK_HEVC_FRONT;
- }
- if (mask & CORE_MASK_HEVC_BACK) {
- if (s2_buf_available(pbi) &&
- (get_free_buf_count(pbi) >=
- pbi->run_ready_min_buf_num)) {
- ret |= CORE_MASK_HEVC_BACK;
- pbi->back_not_run_ready = 0;
- } else
- pbi->back_not_run_ready = 1;
-#if 0
- if (get_free_buf_count(pbi) <
- run_ready_min_buf_num)
- dump_pic_list(pbi);
-#endif
- }
- } else if (get_free_buf_count(pbi) >=
- pbi->run_ready_min_buf_num)
- ret = CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_HEVC_FRONT
- | CORE_MASK_HEVC_BACK;
-
- if (ret & CORE_MASK_HEVC_FRONT)
- not_run_ready[pbi->index] = 0;
- else
- not_run_ready[pbi->index]++;
-
- if (ret & CORE_MASK_HEVC_BACK)
- not_run2_ready[pbi->index] = 0;
- else
- not_run2_ready[pbi->index]++;
-
- vp9_print(pbi,
- PRINT_FLAG_VDEC_DETAIL, "%s mask %lx=>%lx (%d %d %d %d)\r\n",
- __func__, mask, ret,
- get_free_stage_buf_num(pbi),
- mv_buf_available(pbi),
- s2_buf_available(pbi),
- get_free_buf_count(pbi)
- );
-
- return ret;
-
-#else
-
- if (pbi->is_used_v4l) {
- struct aml_vcodec_ctx *ctx =
- (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
-
- if (pbi->v4l_params_parsed) {
- if (is_avaliable_buffer(pbi))
- ret = CORE_MASK_HEVC;
- else
- ret = 0;
- } else {
- if (ctx->v4l_resolution_change)
- ret = 0;
- else
- ret = CORE_MASK_HEVC;
- }
- }
-
- if (ret)
- not_run_ready[pbi->index] = 0;
- else
- not_run_ready[pbi->index]++;
-
- vp9_print(pbi,
- PRINT_FLAG_VDEC_DETAIL, "%s mask %lx=>%lx\r\n",
- __func__, mask, ret);
- return ret;
-#endif
-}
-
-static void vp9_frame_mode_pts_save(struct VP9Decoder_s *pbi)
-{
- int i = 0;
-
- if (pbi->chunk == NULL)
- return;
- vp9_print(pbi, VP9_DEBUG_OUT_PTS,
- "run front: pts %d, pts64 %lld, ts: %lld\n",
- pbi->chunk->pts, pbi->chunk->pts64, pbi->chunk->timestamp);
- for (i = (FRAME_BUFFERS - 1); i > 0; i--) {
- pbi->frame_mode_pts_save[i] = pbi->frame_mode_pts_save[i - 1];
- pbi->frame_mode_pts64_save[i] = pbi->frame_mode_pts64_save[i - 1];
- }
- pbi->frame_mode_pts_save[0] = pbi->chunk->pts;
- pbi->frame_mode_pts64_save[0] = pbi->chunk->pts64;
-
- if (pbi->is_used_v4l && !v4l_bitstream_id_enable)
- pbi->frame_mode_pts64_save[0] = pbi->chunk->timestamp;
-}
-
-static void run_front(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- int ret, size;
-
- run_count[pbi->index]++;
- /* pbi->chunk = vdec_prepare_input(vdec); */
-#if (!defined SUPPORT_FB_DECODING)
- hevc_reset_core(vdec);
-#elif (defined FB_DECODING_TEST_SCHEDULE)
- hevc_reset_core(vdec);
-#else
- if (pbi->used_stage_buf_num > 0)
- fb_reset_core(vdec, HW_MASK_FRONT);
- else
- hevc_reset_core(vdec);
-#endif
-
- size = vdec_prepare_input(vdec, &pbi->chunk);
- if (size < 0) {
- input_empty[pbi->index]++;
-
- pbi->dec_result = DEC_RESULT_AGAIN;
-
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "ammvdec_vh265: Insufficient data\n");
-
- vdec_schedule_work(&pbi->work);
- return;
- }
-
- ATRACE_COUNTER("V_ST_DEC-chunk_size", size);
-
- input_empty[pbi->index] = 0;
- pbi->dec_result = DEC_RESULT_NONE;
- pbi->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
-
- vp9_frame_mode_pts_save(pbi);
-
- if (debug & PRINT_FLAG_VDEC_STATUS) {
- int ii;
- vp9_print(pbi, 0,
- "%s (%d): size 0x%x (0x%x 0x%x) sum 0x%x (%x %x %x %x %x) bytes 0x%x",
- __func__,
- pbi->frame_count, size,
- pbi->chunk ? pbi->chunk->size : 0,
- pbi->chunk ? pbi->chunk->offset : 0,
- pbi->chunk ? ((vdec_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_STATUS)) ?
- get_data_check_sum(pbi, size) : 0) : 0,
- READ_VREG(HEVC_STREAM_START_ADDR),
- READ_VREG(HEVC_STREAM_END_ADDR),
- READ_VREG(HEVC_STREAM_LEVEL),
- READ_VREG(HEVC_STREAM_WR_PTR),
- READ_VREG(HEVC_STREAM_RD_PTR),
- pbi->start_shift_bytes);
-
- if (!vdec_secure(hw_to_vdec(pbi)) &&
- vdec_frame_based(vdec) && pbi->chunk) {
- u8 *data = NULL;
-
- if (!pbi->chunk->block->is_mapped)
- data = codec_mm_vmap(pbi->chunk->block->start +
- pbi->chunk->offset, 8);
- else
- data = ((u8 *)pbi->chunk->block->start_virt) +
- pbi->chunk->offset;
-
- vp9_print_cont(pbi, 0, "data adr %p:",
- data);
- for (ii = 0; ii < 8; ii++)
- vp9_print_cont(pbi, 0, "%02x ",
- data[ii]);
-
- if (!pbi->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- vp9_print_cont(pbi, 0, "\r\n");
- }
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START);
- if (vdec->mc_loaded) {
- /*firmware have load before,
- and not changes to another.
- ignore reload.
- */
- } else {
- ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data);
- if (ret < 0) {
- amhevc_disable();
- vp9_print(pbi, PRINT_FLAG_ERROR,
- "VP9: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- pbi->dec_result = DEC_RESULT_FORCE_EXIT;
- vdec_schedule_work(&pbi->work);
- return;
- }
- vdec->mc_loaded = 1;
- vdec->mc_type = VFORMAT_VP9;
- }
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
-
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
- if (vp9_hw_ctx_restore(pbi) < 0) {
- vdec_schedule_work(&pbi->work);
- return;
- }
- ATRACE_COUNTER(pbi->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
- vdec_enable_input(vdec);
-
- WRITE_VREG(HEVC_DEC_STATUS_REG, HEVC_ACTION_DONE);
-
- if (vdec_frame_based(vdec)) {
- if (debug & PRINT_FLAG_VDEC_DATA)
- dump_data(pbi, pbi->chunk->size);
-
- WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
- size = pbi->chunk->size +
- (pbi->chunk->offset & (VDEC_FIFO_ALIGN - 1));
- if (vdec->mvfrm)
- vdec->mvfrm->frame_size = pbi->chunk->size;
- }
- WRITE_VREG(HEVC_DECODE_SIZE, size);
- WRITE_VREG(HEVC_DECODE_COUNT, pbi->slice_idx);
- pbi->init_flag = 1;
-
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "%s: start hevc (%x %x %x)\n",
- __func__,
- READ_VREG(HEVC_DEC_STATUS_REG),
- READ_VREG(HEVC_MPC_E),
- READ_VREG(HEVC_MPSR));
-
- start_process_time(pbi);
- mod_timer(&pbi->timer, jiffies);
- pbi->stat |= STAT_TIMER_ARM;
- pbi->stat |= STAT_ISR_REG;
- amhevc_start();
- pbi->stat |= STAT_VDEC_RUN;
-}
-
-#ifdef SUPPORT_FB_DECODING
-static void mpred_process(struct VP9Decoder_s *pbi)
-{
- union param_u *params = &pbi->s1_param;
- unsigned char use_prev_frame_mvs =
- !params->p.error_resilient_mode &&
- params->p.width == pbi->s1_width &&
- params->p.height == pbi->s1_height &&
- !pbi->s1_intra_only &&
- pbi->s1_last_show_frame &&
- (pbi->s1_frame_type != KEY_FRAME);
- pbi->s1_width = params->p.width;
- pbi->s1_height = params->p.height;
- pbi->s1_frame_type = params->p.frame_type;
- pbi->s1_intra_only =
- (params->p.show_frame ||
- params->p.show_existing_frame)
- ? 0 : params->p.intra_only;
- if ((pbi->s1_frame_type != KEY_FRAME)
- && (!pbi->s1_intra_only)) {
- unsigned int data32;
- int mpred_mv_rd_end_addr;
-
- mpred_mv_rd_end_addr =
- pbi->s1_mpred_mv_wr_start_addr_pre
- + (pbi->lcu_total * MV_MEM_UNIT);
-
- WRITE_VREG(HEVC_MPRED_CTRL3, 0x24122412);
- WRITE_VREG(HEVC_MPRED_ABV_START_ADDR,
- pbi->work_space_buf->
- mpred_above.buf_start);
-
- data32 = READ_VREG(HEVC_MPRED_CTRL4);
-
- data32 &= (~(1 << 6));
- data32 |= (use_prev_frame_mvs << 6);
- WRITE_VREG(HEVC_MPRED_CTRL4, data32);
-
- WRITE_VREG(HEVC_MPRED_MV_WR_START_ADDR,
- pbi->s1_mpred_mv_wr_start_addr);
- WRITE_VREG(HEVC_MPRED_MV_WPTR,
- pbi->s1_mpred_mv_wr_start_addr);
-
- WRITE_VREG(HEVC_MPRED_MV_RD_START_ADDR,
- pbi->s1_mpred_mv_wr_start_addr_pre);
- WRITE_VREG(HEVC_MPRED_MV_RPTR,
- pbi->s1_mpred_mv_wr_start_addr_pre);
-
- WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,
- mpred_mv_rd_end_addr);
-
- } else
- clear_mpred_hw(pbi);
-
- if (!params->p.show_existing_frame) {
- pbi->s1_mpred_mv_wr_start_addr_pre =
- pbi->s1_mpred_mv_wr_start_addr;
- pbi->s1_last_show_frame =
- params->p.show_frame;
- if (pbi->s1_mv_buf_index_pre_pre != MV_BUFFER_NUM)
- put_mv_buf(pbi, &pbi->s1_mv_buf_index_pre_pre);
- pbi->s1_mv_buf_index_pre_pre =
- pbi->s1_mv_buf_index_pre;
- pbi->s1_mv_buf_index_pre = pbi->s1_mv_buf_index;
- } else
- put_mv_buf(pbi, &pbi->s1_mv_buf_index);
-}
-
-static void vp9_s1_work(struct work_struct *s1_work)
-{
- struct VP9Decoder_s *pbi = container_of(s1_work,
- struct VP9Decoder_s, s1_work);
- vp9_print(pbi, PRINT_FLAG_VDEC_DETAIL,
- "%s dec_s1_result %d\n",
- __func__,
- pbi->dec_s1_result);
-
-#ifdef FB_DECODING_TEST_SCHEDULE
- if (pbi->dec_s1_result ==
- DEC_S1_RESULT_TEST_TRIGGER_DONE) {
- pbi->s1_test_cmd = TEST_SET_PIC_DONE;
- WRITE_VREG(HEVC_ASSIST_MBOX0_IRQ_REG, 0x1);
- }
-#endif
- if (pbi->dec_s1_result == DEC_S1_RESULT_DONE ||
- pbi->dec_s1_result == DEC_S1_RESULT_FORCE_EXIT) {
-
- vdec_core_finish_run(hw_to_vdec(pbi),
- CORE_MASK_HEVC_FRONT);
-
- trigger_schedule(pbi);
- /*pbi->dec_s1_result = DEC_S1_RESULT_NONE;*/
- }
-
-}
-
-static void run_back(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- int i;
- run2_count[pbi->index]++;
- if (debug & PRINT_FLAG_VDEC_STATUS) {
- vp9_print(pbi, 0,
- "%s", __func__);
- }
- pbi->run2_busy = 1;
-#ifndef FB_DECODING_TEST_SCHEDULE
- fb_reset_core(vdec, HW_MASK_BACK);
-
- vvp9_prot_init(pbi, HW_MASK_BACK);
-#endif
- vp9_recycle_mmu_buf_tail(pbi);
-
- if (pbi->frame_count > 0)
- vp9_bufmgr_postproc(pbi);
-
- if (get_s2_buf(pbi) >= 0) {
- for (i = 0; i < (RPM_END - RPM_BEGIN); i += 4) {
- int ii;
- for (ii = 0; ii < 4; ii++)
- pbi->vp9_param.l.data[i + ii] =
- pbi->s2_buf->rpm[i + 3 - ii];
- }
-#ifndef FB_DECODING_TEST_SCHEDULE
- WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR,
- pbi->stage_mmu_map_phy_addr +
- pbi->s2_buf->index * STAGE_MMU_MAP_SIZE);
-#endif
- continue_decoding(pbi);
- }
- pbi->run2_busy = 0;
-}
-#endif
-
-static void run(struct vdec_s *vdec, unsigned long mask,
- void (*callback)(struct vdec_s *, void *), void *arg)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_START);
- vp9_print(pbi,
- PRINT_FLAG_VDEC_DETAIL, "%s mask %lx\r\n",
- __func__, mask);
-
- if (vdec->mvfrm)
- vdec->mvfrm->hw_decode_start = local_clock();
- run_count[pbi->index]++;
- pbi->vdec_cb_arg = arg;
- pbi->vdec_cb = callback;
- pbi->one_package_frame_cnt = 0;
-#ifdef SUPPORT_FB_DECODING
- if ((mask & CORE_MASK_HEVC) ||
- (mask & CORE_MASK_HEVC_FRONT))
- run_front(vdec);
-
- if ((pbi->used_stage_buf_num > 0)
- && (mask & CORE_MASK_HEVC_BACK))
- run_back(vdec);
-#else
- run_front(vdec);
-#endif
- ATRACE_COUNTER(pbi->trace.decode_time_name, DECODER_RUN_END);
-}
-
-static void vp9_decoder_ctx_reset(struct VP9Decoder_s *pbi)
-{
- struct vdec_s *vdec = hw_to_vdec(pbi);
- struct VP9_Common_s *const cm = &pbi->common;
- struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
- struct BufferPool_s *buffer_pool = cm->buffer_pool;
- int i;
-
- cm->buffer_pool = buffer_pool;
-
- for (i = 0; i < FRAME_BUFFERS; ++i) {
- frame_bufs[i].buf.index = i;
- frame_bufs[i].ref_count = 0;
- frame_bufs[i].buf.vf_ref = 0;
- frame_bufs[i].buf.decode_idx = 0;
- frame_bufs[i].buf.cma_alloc_addr = 0;
- frame_bufs[i].buf.BUF_index = -1;
- frame_bufs[i].buf.slice_type = 0;
- frame_bufs[i].buf.repeat_pic = NULL;
- frame_bufs[i].buf.repeat_count = 0;
- }
-
- for (i = 0; i < MV_BUFFER_NUM; ++i) {
- pbi->m_mv_BUF[i].used_flag = 0;
- }
-
- for (i = 0; i < FRAME_BUFFERS; i++) {
- pbi->buffer_wrap[i] = i;
- }
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < FRAME_BUFFERS; i++) {
- vdec->free_canvas_ex
- (pbi->common.buffer_pool->frame_bufs[i].buf.y_canvas_index,
- vdec->id);
- vdec->free_canvas_ex
- (pbi->common.buffer_pool->frame_bufs[i].buf.uv_canvas_index,
- vdec->id);
- }
- }
-
- pbi->init_flag = 0;
- pbi->first_sc_checked = 0;
- pbi->fatal_error = 0;
- pbi->show_frame_num = 0;
- pbi->eos = 0;
- pbi->postproc_done = 0;
- pbi->process_busy = 0;
-}
-
-static void reset(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
-
- cancel_work_sync(&pbi->set_clk_work);
- cancel_work_sync(&pbi->work);
- if (pbi->stat & STAT_VDEC_RUN) {
- amhevc_stop();
- pbi->stat &= ~STAT_VDEC_RUN;
- }
-
- if (pbi->stat & STAT_TIMER_ARM) {
- del_timer_sync(&pbi->timer);
- pbi->stat &= ~STAT_TIMER_ARM;
- }
-
- reset_process_time(pbi);
-
- vp9_local_uninit(pbi);
- if (vvp9_local_init(pbi) < 0)
- vp9_print(pbi, 0, "%s local_init failed \r\n", __func__);
-
- vp9_decoder_ctx_reset(pbi);
-
- atomic_set(&pbi->vf_pre_count, 0);
- atomic_set(&pbi->vf_get_count, 0);
- atomic_set(&pbi->vf_put_count, 0);
-
- if (pbi->ge2d) {
- vdec_ge2d_destroy(pbi->ge2d);
- pbi->ge2d = NULL;
- }
-
- vp9_print(pbi, 0, "%s\r\n", __func__);
-}
-
-static irqreturn_t vp9_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- return vvp9_isr(0, pbi);
-}
-
-static irqreturn_t vp9_threaded_irq_cb(struct vdec_s *vdec, int irq)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- return vvp9_isr_thread_fn(0, pbi);
-}
-
-static void vp9_dump_state(struct vdec_s *vdec)
-{
- struct VP9Decoder_s *pbi =
- (struct VP9Decoder_s *)vdec->private;
- struct VP9_Common_s *const cm = &pbi->common;
- int i;
- vp9_print(pbi, 0, "====== %s\n", __func__);
-
- vp9_print(pbi, 0,
- "width/height (%d/%d), used_buf_num %d video_signal_type 0x%x\n",
- cm->width,
- cm->height,
- pbi->used_buf_num,
- pbi->video_signal_type
- );
-
- vp9_print(pbi, 0,
- "is_framebase(%d), eos %d, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d low_latency %d no_head %d \n",
- input_frame_based(vdec),
- pbi->eos,
- pbi->dec_result,
- decode_frame_count[pbi->index],
- display_frame_count[pbi->index],
- run_count[pbi->index],
- not_run_ready[pbi->index],
- input_empty[pbi->index],
- pbi->low_latency_flag,
- pbi->no_head
- );
-
- if (!pbi->is_used_v4l && vf_get_receiver(vdec->vf_provider_name)) {
- enum receviver_start_e state =
- vf_notify_receiver(vdec->vf_provider_name,
- VFRAME_EVENT_PROVIDER_QUREY_STATE,
- NULL);
- vp9_print(pbi, 0,
- "\nreceiver(%s) state %d\n",
- vdec->vf_provider_name,
- state);
- }
-
- vp9_print(pbi, 0,
- "%s, newq(%d/%d), dispq(%d/%d), vf prepare/get/put (%d/%d/%d), free_buf_count %d (min %d for run_ready)\n",
- __func__,
- kfifo_len(&pbi->newframe_q),
- VF_POOL_SIZE,
- kfifo_len(&pbi->display_q),
- VF_POOL_SIZE,
- pbi->vf_pre_count,
- pbi->vf_get_count,
- pbi->vf_put_count,
- get_free_buf_count(pbi),
- pbi->run_ready_min_buf_num
- );
-
- dump_pic_list(pbi);
-
- for (i = 0; i < MAX_BUF_NUM; i++) {
- vp9_print(pbi, 0,
- "mv_Buf(%d) start_adr 0x%x size 0x%x used %d\n",
- i,
- pbi->m_mv_BUF[i].start_adr,
- pbi->m_mv_BUF[i].size,
- pbi->m_mv_BUF[i].used_flag);
- }
-
- vp9_print(pbi, 0,
- "HEVC_DEC_STATUS_REG=0x%x\n",
- READ_VREG(HEVC_DEC_STATUS_REG));
- vp9_print(pbi, 0,
- "HEVC_MPC_E=0x%x\n",
- READ_VREG(HEVC_MPC_E));
- vp9_print(pbi, 0,
- "DECODE_MODE=0x%x\n",
- READ_VREG(DECODE_MODE));
- vp9_print(pbi, 0,
- "NAL_SEARCH_CTL=0x%x\n",
- READ_VREG(NAL_SEARCH_CTL));
- vp9_print(pbi, 0,
- "HEVC_PARSER_LCU_START=0x%x\n",
- READ_VREG(HEVC_PARSER_LCU_START));
- vp9_print(pbi, 0,
- "HEVC_DECODE_SIZE=0x%x\n",
- READ_VREG(HEVC_DECODE_SIZE));
- vp9_print(pbi, 0,
- "HEVC_SHIFT_BYTE_COUNT=0x%x\n",
- READ_VREG(HEVC_SHIFT_BYTE_COUNT));
- vp9_print(pbi, 0,
- "HEVC_STREAM_START_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_START_ADDR));
- vp9_print(pbi, 0,
- "HEVC_STREAM_END_ADDR=0x%x\n",
- READ_VREG(HEVC_STREAM_END_ADDR));
- vp9_print(pbi, 0,
- "HEVC_STREAM_LEVEL=0x%x\n",
- READ_VREG(HEVC_STREAM_LEVEL));
- vp9_print(pbi, 0,
- "HEVC_STREAM_WR_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_WR_PTR));
- vp9_print(pbi, 0,
- "HEVC_STREAM_RD_PTR=0x%x\n",
- READ_VREG(HEVC_STREAM_RD_PTR));
- vp9_print(pbi, 0,
- "PARSER_VIDEO_RP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_rp));
- vp9_print(pbi, 0,
- "PARSER_VIDEO_WP=0x%x\n",
- STBUF_READ(&vdec->vbuf, get_wp));
-
- if (input_frame_based(vdec) &&
- (debug & PRINT_FLAG_VDEC_DATA)
- ) {
- int jj;
- if (pbi->chunk && pbi->chunk->block &&
- pbi->chunk->size > 0) {
- u8 *data = NULL;
-
- if (!pbi->chunk->block->is_mapped)
- data = codec_mm_vmap(
- pbi->chunk->block->start +
- pbi->chunk->offset,
- pbi->chunk->size);
- else
- data = ((u8 *)pbi->chunk->block->start_virt)
- + pbi->chunk->offset;
- vp9_print(pbi, 0,
- "frame data size 0x%x\n",
- pbi->chunk->size);
- for (jj = 0; jj < pbi->chunk->size; jj++) {
- if ((jj & 0xf) == 0)
- vp9_print(pbi, 0,
- "%06x:", jj);
- vp9_print_cont(pbi, 0,
- "%02x ", data[jj]);
- if (((jj + 1) & 0xf) == 0)
- vp9_print_cont(pbi, 0,
- "\n");
- }
-
- if (!pbi->chunk->block->is_mapped)
- codec_mm_unmap_phyaddr(data);
- }
- }
-
-}
-
-static int ammvdec_vp9_probe(struct platform_device *pdev)
-{
- struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
- int ret;
- int i;
- int config_val;
- int transfer_val;
- struct vframe_content_light_level_s content_light_level;
- struct vframe_master_display_colour_s vf_dp;
-
- struct VP9Decoder_s *pbi = NULL;
- struct aml_vcodec_ctx *ctx = NULL;
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) {
- pr_info("vp9 unsupported on cpu 0x%x\n", get_cpu_major_id());
- return -EINVAL;
- }
- pr_debug("%s\n", __func__);
-
- if (pdata == NULL) {
- pr_info("\nammvdec_vp9 memory resource undefined.\n");
- return -EFAULT;
- }
- /*pbi = (struct VP9Decoder_s *)devm_kzalloc(&pdev->dev,
- sizeof(struct VP9Decoder_s), GFP_KERNEL);*/
- memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
- pbi = vmalloc(sizeof(struct VP9Decoder_s));
- if (pbi == NULL) {
- pr_info("\nammvdec_vp9 device data allocation failed\n");
- return -ENOMEM;
- }
- memset(pbi, 0, sizeof(struct VP9Decoder_s));
-
- /* the ctx from v4l2 driver. */
- pbi->v4l2_ctx = pdata->private;
- ctx = (struct aml_vcodec_ctx *)(pbi->v4l2_ctx);
- pdata->private = pbi;
- pdata->dec_status = vvp9_dec_status;
- /* pdata->set_trickmode = set_trickmode; */
- pdata->run_ready = run_ready;
- pdata->run = run;
- pdata->reset = reset;
- pdata->irq_handler = vp9_irq_cb;
- pdata->threaded_irq_handler = vp9_threaded_irq_cb;
- pdata->dump_state = vp9_dump_state;
-
- pbi->index = pdev->id;
-
- if (is_rdma_enable()) {
- pbi->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &pbi->rdma_phy_adr, GFP_KERNEL);
- for (i = 0; i < SCALELUT_DATA_WRITE_NUM; i++) {
- pbi->rdma_adr[i * 4] = HEVC_IQIT_SCALELUT_WR_ADDR & 0xfff;
- pbi->rdma_adr[i * 4 + 1] = i;
- pbi->rdma_adr[i * 4 + 2] = HEVC_IQIT_SCALELUT_DATA & 0xfff;
- pbi->rdma_adr[i * 4 + 3] = 0;
- if (i == SCALELUT_DATA_WRITE_NUM - 1) {
- pbi->rdma_adr[i * 4 + 2] = (HEVC_IQIT_SCALELUT_DATA & 0xfff) | 0x20000;
- }
- }
- }
-
- snprintf(pbi->trace.vdec_name, sizeof(pbi->trace.vdec_name),
- "vp9-%d", pbi->index);
- snprintf(pbi->trace.pts_name, sizeof(pbi->trace.pts_name),
- "%s-timestamp", pbi->trace.vdec_name);
- snprintf(pbi->trace.new_q_name, sizeof(pbi->trace.new_q_name),
- "%s-newframe_q", pbi->trace.vdec_name);
- snprintf(pbi->trace.disp_q_name, sizeof(pbi->trace.disp_q_name),
- "%s-dispframe_q", pbi->trace.vdec_name);
- snprintf(pbi->trace.decode_time_name, sizeof(pbi->trace.decode_time_name),
- "decoder_time%d", pdev->id);
- snprintf(pbi->trace.decode_run_time_name, sizeof(pbi->trace.decode_run_time_name),
- "decoder_run_time%d", pdev->id);
- snprintf(pbi->trace.decode_header_memory_time_name, sizeof(pbi->trace.decode_header_memory_time_name),
- "decoder_header_time%d", pdev->id);
-
- if (pdata->use_vfm_path)
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- VFM_DEC_PROVIDER_NAME);
- else
- snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
- MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
-
- pbi->provider_name = pdata->vf_provider_name;
- platform_set_drvdata(pdev, pdata);
-
- pbi->platform_dev = pdev;
- pbi->video_signal_type = 0;
- pbi->m_ins_flag = 1;
- if (!vdec_is_support_4k()) {
- pbi->max_pic_w = 1920;
- pbi->max_pic_h = 1088;
- } else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
- pbi->max_pic_w = 4096;
- pbi->max_pic_h = 2304;
- } else {
- pbi->max_pic_w = 8192;
- pbi->max_pic_h = 4608;
- }
-
- if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 &&
- pdata->config_len) {
-#ifdef MULTI_INSTANCE_SUPPORT
- int vp9_buf_width = 0;
- int vp9_buf_height = 0;
- /*use ptr config for doubel_write_mode, etc*/
- vp9_print(pbi, 0, "pdata->config=%s\n", pdata->config);
- if (get_config_int(pdata->config, "vp9_double_write_mode",
- &config_val) == 0)
- pbi->double_write_mode = config_val;
- else
- pbi->double_write_mode = double_write_mode;
-
- if (get_config_int(pdata->config, "save_buffer_mode",
- &config_val) == 0)
- pbi->save_buffer_mode = config_val;
- else
- pbi->save_buffer_mode = 0;
- if (get_config_int(pdata->config, "vp9_buf_width",
- &config_val) == 0) {
- vp9_buf_width = config_val;
- }
- if (get_config_int(pdata->config, "vp9_buf_height",
- &config_val) == 0) {
- vp9_buf_height = config_val;
- }
-
- if (get_config_int(pdata->config, "no_head",
- &config_val) == 0)
- pbi->no_head = config_val;
- else
- pbi->no_head = no_head;
-
- /*use ptr config for max_pic_w, etc*/
- if (get_config_int(pdata->config, "vp9_max_pic_w",
- &config_val) == 0) {
- pbi->max_pic_w = config_val;
- }
- if (get_config_int(pdata->config, "vp9_max_pic_h",
- &config_val) == 0) {
- pbi->max_pic_h = config_val;
- }
-
- if ((pbi->max_pic_w * pbi->max_pic_h)
- < (vp9_buf_width * vp9_buf_height)) {
- pbi->max_pic_w = vp9_buf_width;
- pbi->max_pic_h = vp9_buf_height;
- vp9_print(pbi, 0, "use buf resolution\n");
- }
-
- if (get_config_int(pdata->config, "sidebind_type",
- &config_val) == 0)
- pbi->sidebind_type = config_val;
-
- if (get_config_int(pdata->config, "sidebind_channel_id",
- &config_val) == 0)
- pbi->sidebind_channel_id = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_codec_enable",
- &config_val) == 0)
- pbi->is_used_v4l = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_buffer_margin",
- &config_val) == 0)
- pbi->dynamic_buf_num_margin = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_canvas_mem_mode",
- &config_val) == 0)
- pbi->mem_map_mode = config_val;
-
- if (get_config_int(pdata->config,
- "parm_enable_fence",
- &config_val) == 0)
- pbi->enable_fence = config_val;
-
- if (get_config_int(pdata->config,
- "parm_fence_usage",
- &config_val) == 0)
- pbi->fence_usage = config_val;
-
- if (get_config_int(pdata->config,
- "parm_v4l_low_latency_mode",
- &config_val) == 0) {
- pbi->low_latency_flag = (config_val & 1) ? 1 : 0;
- pbi->enable_fence = (config_val & 2) ? 1 : 0;
- }
-
- /*if (get_config_int(pdata->config,
- "parm_v4l_duration",
- &config_val) == 0)
- vdec_frame_rate_uevent(config_val);*/
-#endif
- if (get_config_int(pdata->config, "HDRStaticInfo",
- &vf_dp.present_flag) == 0
- && vf_dp.present_flag == 1) {
- get_config_int(pdata->config, "signal_type",
- &pbi->video_signal_type);
- get_config_int(pdata->config, "mG.x",
- &vf_dp.primaries[0][0]);
- get_config_int(pdata->config, "mG.y",
- &vf_dp.primaries[0][1]);
- get_config_int(pdata->config, "mB.x",
- &vf_dp.primaries[1][0]);
- get_config_int(pdata->config, "mB.y",
- &vf_dp.primaries[1][1]);
- get_config_int(pdata->config, "mR.x",
- &vf_dp.primaries[2][0]);
- get_config_int(pdata->config, "mR.y",
- &vf_dp.primaries[2][1]);
- get_config_int(pdata->config, "mW.x",
- &vf_dp.white_point[0]);
- get_config_int(pdata->config, "mW.y",
- &vf_dp.white_point[1]);
- get_config_int(pdata->config, "mMaxDL",
- &vf_dp.luminance[0]);
- get_config_int(pdata->config, "mMinDL",
- &vf_dp.luminance[1]);
- vf_dp.content_light_level.present_flag = 1;
- get_config_int(pdata->config, "mMaxCLL",
- &content_light_level.max_content);
- get_config_int(pdata->config, "mMaxFALL",
- &content_light_level.max_pic_average);
-
- get_config_int(pdata->config, "mTransfer",
- &transfer_val);
-
- if (transfer_val == 0)
- transfer_val = 16;
-
- vp9_print(pbi, 0, "transfer_val=%d\n",transfer_val);
-
- vf_dp.content_light_level = content_light_level;
- if (!pbi->video_signal_type) {
- pbi->video_signal_type = (1 << 29)
- | (5 << 26) /* unspecified */
- | (0 << 25) /* limit */
- | (1 << 24) /* color available */
- | (9 << 16) /* 2020 */
- | (transfer_val << 8) /* 2084 */
- | (9 << 0); /* 2020 */
- }
- }
- pbi->vf_dp = vf_dp;
- } else {
- if (pdata->sys_info) {
- pbi->vvp9_amstream_dec_info = *pdata->sys_info;
- if ((pbi->vvp9_amstream_dec_info.width != 0) &&
- (pbi->vvp9_amstream_dec_info.height != 0)) {
- pbi->max_pic_w = pbi->vvp9_amstream_dec_info.width;
- pbi->max_pic_h = pbi->vvp9_amstream_dec_info.height;
- }
- }
- /*pbi->vvp9_amstream_dec_info.width = 0;
- pbi->vvp9_amstream_dec_info.height = 0;
- pbi->vvp9_amstream_dec_info.rate = 30;*/
- pbi->double_write_mode = double_write_mode;
- }
-
- if (!pbi->is_used_v4l) {
- vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
- &vvp9_vf_provider, pbi);
- }
-
- if (no_head & 0x10) {
- pbi->no_head = (no_head & 0xf);
- }
-
- pbi->endian = HEVC_CONFIG_LITTLE_ENDIAN;
- if (!pbi->is_used_v4l) {
- pbi->mem_map_mode = mem_map_mode;
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
- pbi->endian = HEVC_CONFIG_BIG_ENDIAN;
- }
- if (endian)
- pbi->endian = endian;
-
- if (pbi->is_used_v4l)
- pbi->run_ready_min_buf_num = run_ready_min_buf_num - 1 ;
- else
- pbi->run_ready_min_buf_num = run_ready_min_buf_num;
-
- if (is_oversize(pbi->max_pic_w, pbi->max_pic_h)) {
- pr_err("over size: %dx%d, probe failed\n",
- pbi->max_pic_w, pbi->max_pic_h);
- return -1;
- }
-
- if (force_config_fence) {
- pbi->enable_fence = true;
- pbi->fence_usage =
- (force_config_fence >> 4) & 0xf;
- if (force_config_fence & 0x2)
- pbi->enable_fence = false;
- vp9_print(pbi, 0, "enable fence: %d, fence usage: %d\n",
- pbi->enable_fence, pbi->fence_usage);
- }
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- pbi->double_write_mode == 0x10)
- pbi->mmu_enable = 0;
- else
- pbi->mmu_enable = 1;
-
- video_signal_type = pbi->video_signal_type;
-
- if (pdata->sys_info) {
- pbi->vvp9_amstream_dec_info = *pdata->sys_info;
- } else {
- pbi->vvp9_amstream_dec_info.width = 0;
- pbi->vvp9_amstream_dec_info.height = 0;
- pbi->vvp9_amstream_dec_info.rate = 30;
- }
-
- pbi->low_latency_flag = 1;
- vp9_print(pbi, 0,
- "no_head %d low_latency %d video_signal_type 0x%x\n",
- pbi->no_head, pbi->low_latency_flag, pbi->video_signal_type);
-#if 0
- pbi->buf_start = pdata->mem_start;
- pbi->buf_size = pdata->mem_end - pdata->mem_start + 1;
-#else
- if (amvdec_vp9_mmu_init(pbi) < 0) {
- pr_err("vp9 alloc bmmu box failed!!\n");
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- pdata->dec_status = NULL;
- return -1;
- }
-
- pbi->cma_alloc_count = PAGE_ALIGN(work_buf_size) / PAGE_SIZE;
- ret = decoder_bmmu_box_alloc_buf_phy(pbi->bmmu_box, WORK_SPACE_BUF_ID,
- pbi->cma_alloc_count * PAGE_SIZE, DRIVER_NAME,
- &pbi->cma_alloc_addr);
- if (ret < 0) {
- uninit_mmu_buffers(pbi);
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- pdata->dec_status = NULL;
- return ret;
- }
- pbi->buf_start = pbi->cma_alloc_addr;
- pbi->buf_size = work_buf_size;
-#endif
-
- pbi->init_flag = 0;
- pbi->first_sc_checked = 0;
- pbi->fatal_error = 0;
- pbi->show_frame_num = 0;
-
- if (debug) {
- pr_info("===VP9 decoder mem resource 0x%lx size 0x%x\n",
- pbi->buf_start,
- pbi->buf_size);
- }
-
- pbi->cma_dev = pdata->cma_dev;
-
- mutex_init(&pbi->fence_mutex);
-
- if (pbi->enable_fence) {
- pdata->sync = vdec_sync_get();
- if (!pdata->sync) {
- vp9_print(pbi, 0, "alloc fence timeline error\n");
- vp9_local_uninit(pbi);
- uninit_mmu_buffers(pbi);
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- pdata->dec_status = NULL;
- return -1;
- }
- ctx->sync = pdata->sync;
- pdata->sync->usage = pbi->fence_usage;
- vdec_timeline_create(pdata->sync, DRIVER_NAME);
- vdec_timeline_get(pdata->sync);
- }
-
- if (vvp9_init(pdata) < 0) {
- pr_info("\namvdec_vp9 init failed.\n");
- vdec_timeline_put(pdata->sync);
- vp9_local_uninit(pbi);
- uninit_mmu_buffers(pbi);
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- pdata->dec_status = NULL;
- return -ENODEV;
- }
- vdec_set_prepare_level(pdata, start_decode_buf_level);
- hevc_source_changed(VFORMAT_VP9,
- 4096, 2048, 60);
-#ifdef SUPPORT_FB_DECODING
- if (pbi->used_stage_buf_num > 0)
- vdec_core_request(pdata,
- CORE_MASK_HEVC_FRONT | CORE_MASK_HEVC_BACK);
- else
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_HEVC_FRONT | CORE_MASK_HEVC_BACK
- | CORE_MASK_COMBINE);
-#else
- if (pdata->parallel_dec == 1)
- vdec_core_request(pdata, CORE_MASK_HEVC);
- else
- vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_COMBINE);
-#endif
- pbi->pic_list_init_done2 = true;
-
- return 0;
-}
-
-static int ammvdec_vp9_remove(struct platform_device *pdev)
-{
- struct VP9Decoder_s *pbi = (struct VP9Decoder_s *)
- (((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
- struct vdec_s *vdec = hw_to_vdec(pbi);
- int i;
- if (debug)
- pr_info("amvdec_vp9_remove\n");
-
- vmvp9_stop(pbi);
-
- if (pbi->ge2d) {
- vdec_ge2d_destroy(pbi->ge2d);
- pbi->ge2d = NULL;
- }
-
-#ifdef SUPPORT_FB_DECODING
- vdec_core_release(hw_to_vdec(pbi), CORE_MASK_VDEC_1 | CORE_MASK_HEVC
- | CORE_MASK_HEVC_FRONT | CORE_MASK_HEVC_BACK
- );
-#else
- if (vdec->parallel_dec == 1)
- vdec_core_release(hw_to_vdec(pbi), CORE_MASK_HEVC);
- else
- vdec_core_release(hw_to_vdec(pbi), CORE_MASK_VDEC_1 | CORE_MASK_HEVC);
-#endif
- vdec_set_status(hw_to_vdec(pbi), VDEC_STATUS_DISCONNECTED);
-
- if (vdec->parallel_dec == 1) {
- for (i = 0; i < FRAME_BUFFERS; i++) {
- vdec->free_canvas_ex
- (pbi->common.buffer_pool->frame_bufs[i].buf.y_canvas_index,
- vdec->id);
- vdec->free_canvas_ex
- (pbi->common.buffer_pool->frame_bufs[i].buf.uv_canvas_index,
- vdec->id);
- }
- }
-
- if (pbi->enable_fence)
- vdec_fence_release(pbi, vdec->sync);
-
-#ifdef DEBUG_PTS
- pr_info("pts missed %ld, pts hit %ld, duration %d\n",
- pbi->pts_missed, pbi->pts_hit, pbi->frame_dur);
-#endif
- mem_map_mode = 0;
- if (is_rdma_enable())
- dma_free_coherent(amports_get_dma_device(), RDMA_SIZE, pbi->rdma_adr, pbi->rdma_phy_adr);
-
- /* devm_kfree(&pdev->dev, (void *)pbi); */
- vfree((void *)pbi);
- return 0;
-}
-
-static struct platform_driver ammvdec_vp9_driver = {
- .probe = ammvdec_vp9_probe,
- .remove = ammvdec_vp9_remove,
-#ifdef CONFIG_PM
- .suspend = amhevc_suspend,
- .resume = amhevc_resume,
-#endif
- .driver = {
- .name = MULTI_DRIVER_NAME,
- }
-};
-#endif
-static struct mconfig vp9_configs[] = {
- MC_PU32("bit_depth_luma", &bit_depth_luma),
- MC_PU32("bit_depth_chroma", &bit_depth_chroma),
- MC_PU32("frame_width", &frame_width),
- MC_PU32("frame_height", &frame_height),
- MC_PU32("debug", &debug),
- MC_PU32("radr", &radr),
- MC_PU32("rval", &rval),
- MC_PU32("pop_shorts", &pop_shorts),
- MC_PU32("dbg_cmd", &dbg_cmd),
- MC_PU32("dbg_skip_decode_index", &dbg_skip_decode_index),
- MC_PU32("endian", &endian),
- MC_PU32("step", &step),
- MC_PU32("udebug_flag", &udebug_flag),
- MC_PU32("decode_pic_begin", &decode_pic_begin),
- MC_PU32("slice_parse_begin", &slice_parse_begin),
- MC_PU32("i_only_flag", &i_only_flag),
- MC_PU32("error_handle_policy", &error_handle_policy),
- MC_PU32("buf_alloc_width", &buf_alloc_width),
- MC_PU32("buf_alloc_height", &buf_alloc_height),
- MC_PU32("buf_alloc_depth", &buf_alloc_depth),
- MC_PU32("buf_alloc_size", &buf_alloc_size),
- MC_PU32("buffer_mode", &buffer_mode),
- MC_PU32("buffer_mode_dbg", &buffer_mode_dbg),
- MC_PU32("max_buf_num", &max_buf_num),
- MC_PU32("dynamic_buf_num_margin", &dynamic_buf_num_margin),
- MC_PU32("mem_map_mode", &mem_map_mode),
- MC_PU32("double_write_mode", &double_write_mode),
- MC_PU32("enable_mem_saving", &enable_mem_saving),
- MC_PU32("force_w_h", &force_w_h),
- MC_PU32("force_fps", &force_fps),
- MC_PU32("max_decoding_time", &max_decoding_time),
- MC_PU32("on_no_keyframe_skiped", &on_no_keyframe_skiped),
- MC_PU32("start_decode_buf_level", &start_decode_buf_level),
- MC_PU32("decode_timeout_val", &decode_timeout_val),
- MC_PU32("vp9_max_pic_w", &vp9_max_pic_w),
- MC_PU32("vp9_max_pic_h", &vp9_max_pic_h),
-};
-static struct mconfig_node vp9_node;
-
-static int __init amvdec_vp9_driver_init_module(void)
-{
-
- struct BuffInfo_s *p_buf_info;
-
- if (get_cpu_major_id() <= AM_MESON_CPU_MAJOR_ID_TM2 && !is_cpu_tm2_revb()) {
- if (vdec_is_support_4k()) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
- p_buf_info = &amvvp9_workbuff_spec[2];
- else
- p_buf_info = &amvvp9_workbuff_spec[1];
- } else
- p_buf_info = &amvvp9_workbuff_spec[0];
- } else { //get_cpu_major_id() > AM_MESON_CPU_MAJOR_ID_TM2 || is_cpu_tm2_revb()
- if (vdec_is_support_4k())
- p_buf_info = &amvvp9_workbuff_spec[5];
- else
- p_buf_info = &amvvp9_workbuff_spec[4];
- }
-
-
- init_buff_spec(NULL, p_buf_info);
- work_buf_size =
- (p_buf_info->end_adr - p_buf_info->start_adr
- + 0xffff) & (~0xffff);
-
- pr_debug("amvdec_vp9 module init\n");
-
- error_handle_policy = 0;
-
-#ifdef ERROR_HANDLE_DEBUG
- dbg_nal_skip_flag = 0;
- dbg_nal_skip_count = 0;
-#endif
- udebug_flag = 0;
- decode_pic_begin = 0;
- slice_parse_begin = 0;
- step = 0;
- buf_alloc_size = 0;
-
- if (platform_driver_register(&ammvdec_vp9_driver)) {
- pr_err("failed to register ammvdec_vp9 driver\n");
- return -ENODEV;
- }
-
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_GXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXL ||
- get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) {
- amvdec_vp9_profile.name = "vp9_unsupport";
- } else if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
- (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)) {
- amvdec_vp9_profile.profile =
- "8k, 10bit, dwrite, compressed, fence, uvm";
- } else {
- if (vdec_is_support_4k())
- amvdec_vp9_profile.profile =
- "4k, 10bit, dwrite, compressed, fence, uvm";
- else
- amvdec_vp9_profile.profile =
- "10bit, dwrite, compressed, fence, uvm";
- }
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
- max_buf_num = MAX_BUF_NUM_LESS;
-
- vcodec_profile_register(&amvdec_vp9_profile);
- INIT_REG_NODE_CONFIGS("media.decoder", &vp9_node,
- "vp9-v4l", vp9_configs, CONFIG_FOR_RW);
- vcodec_feature_register(VFORMAT_VP9, 1);
-
- return 0;
-}
-
-static void __exit amvdec_vp9_driver_remove_module(void)
-{
- pr_debug("amvdec_vp9 module remove.\n");
-
- platform_driver_unregister(&ammvdec_vp9_driver);
-}
-
-/****************************************/
-
-module_param(bit_depth_luma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_vp9 bit_depth_luma\n");
-
-module_param(bit_depth_chroma, uint, 0664);
-MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_vp9 bit_depth_chroma\n");
-
-module_param(frame_width, uint, 0664);
-MODULE_PARM_DESC(frame_width, "\n amvdec_vp9 frame_width\n");
-
-module_param(frame_height, uint, 0664);
-MODULE_PARM_DESC(frame_height, "\n amvdec_vp9 frame_height\n");
-
-module_param(debug, uint, 0664);
-MODULE_PARM_DESC(debug, "\n amvdec_vp9 debug\n");
-
-module_param(radr, uint, 0664);
-MODULE_PARM_DESC(radr, "\n radr\n");
-
-module_param(rval, uint, 0664);
-MODULE_PARM_DESC(rval, "\n rval\n");
-
-module_param(pop_shorts, uint, 0664);
-MODULE_PARM_DESC(pop_shorts, "\n rval\n");
-
-module_param(dbg_cmd, uint, 0664);
-MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n");
-
-module_param(dbg_skip_decode_index, uint, 0664);
-MODULE_PARM_DESC(dbg_skip_decode_index, "\n dbg_skip_decode_index\n");
-
-module_param(endian, uint, 0664);
-MODULE_PARM_DESC(endian, "\n rval\n");
-
-module_param(step, uint, 0664);
-MODULE_PARM_DESC(step, "\n amvdec_vp9 step\n");
-
-module_param(decode_pic_begin, uint, 0664);
-MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_vp9 decode_pic_begin\n");
-
-module_param(slice_parse_begin, uint, 0664);
-MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_vp9 slice_parse_begin\n");
-
-module_param(i_only_flag, uint, 0664);
-MODULE_PARM_DESC(i_only_flag, "\n amvdec_vp9 i_only_flag\n");
-
-module_param(low_latency_flag, uint, 0664);
-MODULE_PARM_DESC(low_latency_flag, "\n amvdec_vp9 low_latency_flag\n");
-
-module_param(no_head, uint, 0664);
-MODULE_PARM_DESC(no_head, "\n amvdec_vp9 no_head\n");
-
-module_param(error_handle_policy, uint, 0664);
-MODULE_PARM_DESC(error_handle_policy, "\n amvdec_vp9 error_handle_policy\n");
-
-module_param(buf_alloc_width, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_width, "\n buf_alloc_width\n");
-
-module_param(disable_repeat, uint, 0664);
-MODULE_PARM_DESC(disable_repeat, "\n disable_repeat\n");
-
-module_param(buf_alloc_height, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_height, "\n buf_alloc_height\n");
-
-module_param(buf_alloc_depth, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_depth, "\n buf_alloc_depth\n");
-
-module_param(buf_alloc_size, uint, 0664);
-MODULE_PARM_DESC(buf_alloc_size, "\n buf_alloc_size\n");
-
-module_param(buffer_mode, uint, 0664);
-MODULE_PARM_DESC(buffer_mode, "\n buffer_mode\n");
-
-module_param(buffer_mode_dbg, uint, 0664);
-MODULE_PARM_DESC(buffer_mode_dbg, "\n buffer_mode_dbg\n");
-/*USE_BUF_BLOCK*/
-module_param(max_buf_num, uint, 0664);
-MODULE_PARM_DESC(max_buf_num, "\n max_buf_num\n");
-
-module_param(dynamic_buf_num_margin, uint, 0664);
-MODULE_PARM_DESC(dynamic_buf_num_margin, "\n dynamic_buf_num_margin\n");
-
-module_param(mv_buf_margin, uint, 0664);
-MODULE_PARM_DESC(mv_buf_margin, "\n mv_buf_margin\n");
-
-module_param(mv_buf_dynamic_alloc, uint, 0664);
-MODULE_PARM_DESC(mv_buf_dynamic_alloc, "\n mv_buf_dynamic_alloc\n");
-
-module_param(run_ready_min_buf_num, uint, 0664);
-MODULE_PARM_DESC(run_ready_min_buf_num, "\n run_ready_min_buf_num\n");
-
-/**/
-
-module_param(mem_map_mode, uint, 0664);
-MODULE_PARM_DESC(mem_map_mode, "\n mem_map_mode\n");
-
-#ifdef SUPPORT_10BIT
-module_param(double_write_mode, uint, 0664);
-MODULE_PARM_DESC(double_write_mode, "\n double_write_mode\n");
-
-module_param(enable_mem_saving, uint, 0664);
-MODULE_PARM_DESC(enable_mem_saving, "\n enable_mem_saving\n");
-
-module_param(force_w_h, uint, 0664);
-MODULE_PARM_DESC(force_w_h, "\n force_w_h\n");
-#endif
-
-module_param(force_fps, uint, 0664);
-MODULE_PARM_DESC(force_fps, "\n force_fps\n");
-
-module_param(max_decoding_time, uint, 0664);
-MODULE_PARM_DESC(max_decoding_time, "\n max_decoding_time\n");
-
-module_param(on_no_keyframe_skiped, uint, 0664);
-MODULE_PARM_DESC(on_no_keyframe_skiped, "\n on_no_keyframe_skiped\n");
-
-module_param(mcrcc_cache_alg_flag, uint, 0664);
-MODULE_PARM_DESC(mcrcc_cache_alg_flag, "\n mcrcc_cache_alg_flag\n");
-
-#ifdef MULTI_INSTANCE_SUPPORT
-module_param(start_decode_buf_level, int, 0664);
-MODULE_PARM_DESC(start_decode_buf_level,
- "\n vp9 start_decode_buf_level\n");
-
-module_param(decode_timeout_val, uint, 0664);
-MODULE_PARM_DESC(decode_timeout_val,
- "\n vp9 decode_timeout_val\n");
-
-module_param(vp9_max_pic_w, uint, 0664);
-MODULE_PARM_DESC(vp9_max_pic_w, "\n vp9_max_pic_w\n");
-
-module_param(vp9_max_pic_h, uint, 0664);
-MODULE_PARM_DESC(vp9_max_pic_h, "\n vp9_max_pic_h\n");
-
-module_param_array(decode_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(display_frame_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(max_process_time, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(run_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(input_empty, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(not_run_ready, uint,
- &max_decode_instance_num, 0664);
-#endif
-
-#ifdef SUPPORT_FB_DECODING
-module_param_array(not_run2_ready, uint,
- &max_decode_instance_num, 0664);
-
-module_param_array(run2_count, uint,
- &max_decode_instance_num, 0664);
-
-module_param(stage_buf_num, uint, 0664);
-MODULE_PARM_DESC(stage_buf_num, "\n amvdec_h265 stage_buf_num\n");
-#endif
-module_param(force_bufspec, uint, 0664);
-MODULE_PARM_DESC(force_bufspec, "\n amvdec_h265 force_bufspec\n");
-
-module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
-
-module_param(udebug_pause_pos, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
-
-module_param(udebug_pause_val, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n");
-
-module_param(udebug_pause_decode_idx, uint, 0664);
-MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n");
-
-module_param(without_display_mode, uint, 0664);
-MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
-
-module_param(force_config_fence, uint, 0664);
-MODULE_PARM_DESC(force_config_fence, "\n force enable fence\n");
-
-module_param(force_pts_unstable, uint, 0664);
-MODULE_PARM_DESC(force_pts_unstable, "\n force_pts_unstable\n");
-
-module_param(v4l_bitstream_id_enable, uint, 0664);
-MODULE_PARM_DESC(v4l_bitstream_id_enable, "\n v4l_bitstream_id_enable\n");
-
-module_init(amvdec_vp9_driver_init_module);
-module_exit(amvdec_vp9_driver_remove_module);
-
-MODULE_DESCRIPTION("AMLOGIC vp9 Video Decoder Driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/frame_sink/encoder/Makefile b/drivers/frame_sink/encoder/Makefile
index a531bb7..214c6c1 100644
--- a/drivers/frame_sink/encoder/Makefile
+++ b/drivers/frame_sink/encoder/Makefile
@@ -1,4 +1,3 @@
obj-$(CONFIG_AMLOGIC_MEDIA_VENC_H264) += h264/
obj-$(CONFIG_AMLOGIC_MEDIA_VENC_H265) += h265/
-obj-$(CONFIG_AMLOGIC_MEDIA_VENC_MULTI) += multi/
-obj-$(CONFIG_AMLOGIC_MEDIA_VENC_JPEG) += jpeg/
+obj-$(CONFIG_AMLOGIC_MEDIA_VENC_JPEG) += jpeg/
\ No newline at end of file
diff --git a/drivers/frame_sink/encoder/h264/encoder.c b/drivers/frame_sink/encoder/h264/encoder.c
index c44ea56..7141997 100644
--- a/drivers/frame_sink/encoder/h264/encoder.c
+++ b/drivers/frame_sink/encoder/h264/encoder.c
@@ -15,6 +15,7 @@
*
*/
+#define LOG_LINE() pr_err("[%s:%d]\n", __FUNCTION__, __LINE__);
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -29,17 +30,12 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/ctype.h>
-#include <linux/fs.h>
-#include <linux/compat.h>
-//#include <asm/segment.h>
-#include <asm/uaccess.h>
-#include <linux/buffer_head.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include "../../../frame_provider/decoder/utils/vdec_canvas_utils.h"
+
#include <linux/amlogic/media/utils/vdec_reg.h>
#include "../../../frame_provider/decoder/utils/vdec.h"
#include <linux/delay.h>
@@ -52,28 +48,17 @@
#include <linux/amlogic/media/utils/amports_config.h>
#include "encoder.h"
#include "../../../frame_provider/decoder/utils/amvdec.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../../frame_provider/decoder/utils/vdec.h"
#include "../../../frame_provider/decoder/utils/vdec_power_ctrl.h"
-
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/power_ctrl.h>
#include <dt-bindings/power/sc2-pd.h>
-#include <dt-bindings/power/t3-pd.h>
-#include <linux/amlogic/power_domain.h>
-#include <linux/amlogic/power_ctrl.h>
+#include <linux/amlogic/pwr_ctrl.h>
#include <linux/amlogic/media/utils/amlog.h>
#include "../../../stream_input/amports/amports_priv.h"
#include "../../../frame_provider/decoder/utils/firmware.h"
-#include <linux/amlogic/media/registers/register.h>
#include <linux/of_reserved_mem.h>
-#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,1)
-#include <uapi/linux/sched/types.h>
-#include <linux/sched/signal.h>
-#endif
#ifdef CONFIG_AM_JPEG_ENCODER
#include "jpegenc.h"
@@ -86,8 +71,8 @@
__FUNCTION__, __LINE__, _ret);}
#define ENCODE_NAME "encoder"
-#define AMVENC_CANVAS_INDEX 0x64
-#define AMVENC_CANVAS_MAX_INDEX 0x6F
+#define AMVENC_CANVAS_INDEX 0xE4
+#define AMVENC_CANVAS_MAX_INDEX 0xEF
#define MIN_SIZE amvenc_buffspec[0].min_buffsize
#define DUMP_INFO_BYTES_PER_MB 80
@@ -125,7 +110,6 @@
static u32 qp_table_debug;
static u32 use_reset_control;
static u32 use_ge2d;
-static u32 dump_input;
#ifdef H264_ENC_SVC
static u32 svc_enable = 0; /* Enable sac feature or not */
@@ -472,155 +456,6 @@
static int enc_dma_buf_get_phys(struct enc_dma_cfg *cfg, unsigned long *addr);
static void enc_dma_buf_unmap(struct enc_dma_cfg *cfg);
-//static struct canvas_status_s canvas_stat[CANVAS_MAX_SIZE];
-//static struct canvas_status_s mdec_cav_stat[MDEC_CAV_LUT_MAX];
-/*
-static struct canvas_config_s *mdec_cav_pool = NULL;
-
-static void cav_lut_info_store(u32 index, ulong addr, u32 width,
- u32 height, u32 wrap, u32 blkmode, u32 endian)
-{
- struct canvas_config_s *pool = NULL;
-
- if (index < 0 || index >= MDEC_CAV_LUT_MAX) {
- pr_err("%s, error index %d\n", __func__, index);
- return;
- }
- if (mdec_cav_pool == NULL)
- mdec_cav_pool = vzalloc(sizeof(struct canvas_config_s)
- * (MDEC_CAV_LUT_MAX + 1));
-
- if (mdec_cav_pool == NULL) {
- pr_err("%s failed, mdec_cav_pool null\n", __func__);
- return;
- }
- pool = &mdec_cav_pool[index];
- pool->width = width;
- pool->height = height;
- pool->block_mode = blkmode;
- pool->endian = endian;
- pool->phy_addr = addr;
-}
-
-*/
-
-static struct file *file_open(const char *path, int flags, int rights)
-{
- struct file *filp = NULL;
- mm_segment_t oldfs;
- int err = 0;
-
- oldfs = get_fs();
- //set_fs(get_ds());
- set_fs(KERNEL_DS);
- filp = filp_open(path, flags, rights);
- set_fs(oldfs);
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
- return NULL;
- }
- return filp;
-}
-static void file_close(struct file *file)
-{
- filp_close(file, NULL);
-}
-/*
-static int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
-{
- mm_segment_t oldfs;
- int ret;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- ret = vfs_read(file, data, size, &offset);
-
- set_fs(oldfs);
- return ret;
-}*/
-static int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
-{
- mm_segment_t oldfs;
- int ret;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- ret = vfs_write(file, data, size, &offset);
-
- set_fs(oldfs);
- return ret;
-}
-static int file_sync(struct file *file)
-{
- vfs_fsync(file, 0);
- return 0;
-}
-
-static void canvas_config_proxy(u32 index, ulong addr, u32 width, u32 height,
- u32 wrap, u32 blkmode) {
- unsigned long datah_temp, datal_temp;
-
- if (!is_support_vdec_canvas()) {
- canvas_config(index, addr, width, height, wrap, blkmode);
- } else {
-#if 1
- ulong start_addr = addr >> 3;
- u32 cav_width = (((width + 31)>>5)<<2);
- u32 cav_height = height;
- u32 x_wrap_en = 0;
- u32 y_wrap_en = 0;
- u32 blk_mode = 0;//blkmode;
- u32 cav_endian = 0;
-
- datal_temp = (start_addr & 0x1fffffff) |
- ((cav_width & 0x7 ) << 29 );
-
- datah_temp = ((cav_width >> 3) & 0x1ff) |
- ((cav_height & 0x1fff) <<9 ) |
- ((x_wrap_en & 1) << 22 ) |
- ((y_wrap_en & 1) << 23) |
- ((blk_mode & 0x3) << 24) |
- ( cav_endian << 26);
-
-#else
- u32 endian = 0;
- u32 addr_bits_l = ((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) << CAV_WADDR_LBIT);
- u32 width_l = ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CAV_WIDTH_LBIT);
- u32 width_h = ((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) << CAV_WIDTH_HBIT);
- u32 height_h = (height & CANVAS_HEIGHT_MASK) << CAV_HEIGHT_HBIT;
- u32 blkmod_h = (blkmode & CANVAS_BLKMODE_MASK) << CAV_BLKMODE_HBIT;
- u32 switch_bits_ctl = (endian & 0xf) << CAV_ENDIAN_HBIT;
- u32 wrap_h = (0 << 23);
- datal_temp = addr_bits_l | width_l;
- datah_temp = width_h | height_h | wrap_h | blkmod_h | switch_bits_ctl;
-#endif
- /*
- if (core == VDEC_1) {
- WRITE_VREG(MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
- WRITE_VREG(MDEC_CAV_LUT_DATAL, datal_temp);
- WRITE_VREG(MDEC_CAV_LUT_DATAH, datah_temp);
- WRITE_VREG(MDEC_CAV_LUT_ADDR, index);
- } else if (core == VDEC_HCODEC) */ {
- WRITE_HREG(HCODEC_MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_DATAL, datal_temp);
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_DATAH, datah_temp);
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_ADDR, index);
- }
-
- /*
- cav_lut_info_store(index, addr, width, height, wrap, blkmode, 0);
-
- if (vdec_get_debug() & 0x40000000) {
- pr_info("(%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
- __func__, index, addr, width, height, blkmode, 0);
- pr_info("data(h,l): 0x%8lx, 0x%8lx\n", datah_temp, datal_temp);
- }
- */
- }
-}
-
s32 hcodec_hw_reset(void)
{
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2 && use_reset_control) {
@@ -928,33 +763,34 @@
{
u32 canvas_width, canvas_height;
u32 start_addr = wq->mem.buf_start;
+
canvas_width = ((wq->pic.encoder_width + 31) >> 5) << 5;
canvas_height = ((wq->pic.encoder_height + 15) >> 4) << 4;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
+ canvas_config(ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec0_y.buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(1 + ENC_CANVAS_OFFSET,
+ canvas_config(1 + ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec0_uv.buf_start,
canvas_width, canvas_height / 2,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
/*here the third plane use the same address as the second plane*/
- canvas_config_proxy(2 + ENC_CANVAS_OFFSET,
+ canvas_config(2 + ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec0_uv.buf_start,
canvas_width, canvas_height / 2,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(3 + ENC_CANVAS_OFFSET,
+ canvas_config(3 + ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec1_y.buf_start,
canvas_width, canvas_height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(4 + ENC_CANVAS_OFFSET,
+ canvas_config(4 + ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec1_uv.buf_start,
canvas_width, canvas_height / 2,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
/*here the third plane use the same address as the second plane*/
- canvas_config_proxy(5 + ENC_CANVAS_OFFSET,
+ canvas_config(5 + ENC_CANVAS_OFFSET,
start_addr + wq->mem.bufspec.dec1_uv.buf_start,
canvas_width, canvas_height / 2,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
@@ -1249,6 +1085,7 @@
(interp_en << 9) | (r2y_en << 12) |
(r2y_mode << 13) | (ifmt_extra << 16) |
(nr_enable << 19));
+
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
(picsize_x << 16) | (picsize_y << 0));
@@ -1321,7 +1158,7 @@
src_left = request->crop_left;
src_width = request->src_w - src_left - request->crop_right;
src_height = request->src_h - src_top - request->crop_bottom;
- enc_pr(LOG_INFO, "request->fmt=%d, %d %d, canvas=%d\n", request->fmt, FMT_NV21, FMT_BGR888, canvas);
+ pr_info("request->fmt=%d, %d %d, canvas=%d\n", request->fmt, FMT_NV21, FMT_BGR888, canvas);
if (canvas) {
if ((request->fmt == FMT_NV21)
@@ -1491,39 +1328,6 @@
}
#endif
-static s32 dump_raw_input(struct encode_wq_s *wq, struct encode_request_s *request) {
- u8 *data;
- struct canvas_s cs0, cs1;//, cs2
- u32 y_addr, uv_addr, canvas_w, picsize_y;
- u32 input = request->src;
- //u8 iformat = MAX_FRAME_FMT;
- struct file *filp;
- if (request->type == CANVAS_BUFF) {
- if ((request->fmt == FMT_NV21) || (request->fmt == FMT_NV12)) {
- input = input & 0xffff;
- canvas_read(input & 0xff, &cs0);
- canvas_read((input >> 8) & 0xff, &cs1);
- pr_err("dump raw input for canvas source\n");
- y_addr = cs0.addr;
- uv_addr = cs1.addr;
-
- canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
- picsize_y = wq->pic.encoder_height;
-
- data = (u8*)phys_to_virt(y_addr);
- filp = file_open("/data/encoder.yuv", O_APPEND | O_RDWR, 0644);
- if (filp) {
- file_write(filp, 0, data, canvas_w * picsize_y);
- file_sync(filp);
- file_close(filp);
- } else
- pr_err("open encoder.yuv failed\n");
-
- }
- }
- return 0;
-}
-
static s32 set_input_format(struct encode_wq_s *wq,
struct encode_request_s *request)
{
@@ -1540,9 +1344,6 @@
if ((request->fmt == FMT_RGB565) || (request->fmt >= MAX_FRAME_FMT))
return -1;
- if (dump_input)
- dump_raw_input(wq, request);
-
picsize_x = ((wq->pic.encoder_width + 15) >> 4) << 4;
picsize_y = ((wq->pic.encoder_height + 15) >> 4) << 4;
oformat = 0;
@@ -1592,6 +1393,7 @@
src_addr = input;
picsize_y = wq->pic.encoder_height;
}
+
if (request->scale_enable) {
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
struct config_para_ex_s ge2d_config;
@@ -1608,30 +1410,6 @@
input = ((ENC_CANVAS_OFFSET + 7) << 8) |
(ENC_CANVAS_OFFSET + 6);
ret = 0;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- /*
- * for t3, after scaling before goto MFDIN, need to config canvas with scaler buffer
- * */
- enc_pr(LOG_INFO, "reconfig with scaler buffer\n");
- canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
- iformat = 2;
-
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
- wq->mem.scaler_buff_start_addr,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
- wq->mem.scaler_buff_start_addr + canvas_w * picsize_y,
- canvas_w, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
-
- input = ((ENC_CANVAS_OFFSET + 7) << 8) |
- (ENC_CANVAS_OFFSET + 6);
- }
-
goto MFDIN;
#else
enc_pr(LOG_ERROR,
@@ -1655,7 +1433,7 @@
else
canvas_w = (picsize_x * 20 + 7) / 8;
canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
@@ -1671,7 +1449,7 @@
r2y_en = 1;
canvas_w = picsize_x * 3;
canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
@@ -1682,23 +1460,23 @@
canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
iformat = (request->fmt == FMT_NV21) ? 2 : 3;
if (request->type == DMA_BUFF) {
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input_y,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
+ canvas_config(ENC_CANVAS_OFFSET + 7,
input_u,
canvas_w, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
} else {
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
+ canvas_config(ENC_CANVAS_OFFSET + 7,
input + canvas_w * picsize_y,
canvas_w, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
@@ -1710,33 +1488,33 @@
iformat = 4;
canvas_w = ((wq->pic.encoder_width + 63) >> 6) << 6;
if (request->type == DMA_BUFF) {
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input_y,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
+ canvas_config(ENC_CANVAS_OFFSET + 7,
input_u,
canvas_w / 2, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 8,
+ canvas_config(ENC_CANVAS_OFFSET + 8,
input_v,
canvas_w / 2, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
} else {
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
+ canvas_config(ENC_CANVAS_OFFSET + 7,
input + canvas_w * picsize_y,
canvas_w / 2, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 8,
+ canvas_config(ENC_CANVAS_OFFSET + 8,
input + canvas_w * picsize_y * 5 / 4,
canvas_w / 2, picsize_y / 2,
CANVAS_ADDR_NOWRAP,
@@ -1752,17 +1530,17 @@
r2y_en = 1;
iformat = 5;
canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
+ canvas_config(ENC_CANVAS_OFFSET + 6,
input,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
+ canvas_config(ENC_CANVAS_OFFSET + 7,
input + canvas_w * picsize_y,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 8,
+ canvas_config(ENC_CANVAS_OFFSET + 8,
input + canvas_w * picsize_y * 2,
canvas_w, picsize_y,
CANVAS_ADDR_NOWRAP,
@@ -1776,7 +1554,6 @@
}
ret = 0;
} else if (request->type == CANVAS_BUFF) {
-
r2y_en = 0;
if (request->scale_enable) {
#ifdef CONFIG_AMLOGIC_MEDIA_GE2D
@@ -1792,29 +1569,6 @@
input = ((ENC_CANVAS_OFFSET + 7) << 8) |
(ENC_CANVAS_OFFSET + 6);
ret = 0;
-
- /*
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- pr_info("reconfig with scaler buffer\n");
- canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
- iformat = 2;
-
- canvas_config_proxy(ENC_CANVAS_OFFSET + 6,
- wq->mem.scaler_buff_start_addr,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 7,
- wq->mem.scaler_buff_start_addr + canvas_w * picsize_y,
- canvas_w, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
-
- input = ((ENC_CANVAS_OFFSET + 7) << 8) |
- (ENC_CANVAS_OFFSET + 6);
- }
- */
-
goto MFDIN;
#else
enc_pr(LOG_ERROR,
@@ -1822,7 +1576,6 @@
return -1;
#endif
}
- //pr_err("request->type=%u\n", request->type);
if (request->fmt == FMT_YUV422_SINGLE) {
iformat = 0;
input = input & 0xff;
@@ -1833,40 +1586,6 @@
|| (request->fmt == FMT_NV12)) {
iformat = (request->fmt == FMT_NV21) ? 2 : 3;
input = input & 0xffff;
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- struct canvas_s cs0, cs1;//, cs2
- u32 y_addr, uv_addr, canvas_w, picsize_y;
- u8 iformat = MAX_FRAME_FMT;
- canvas_read(input & 0xff, &cs0);
- canvas_read((input >> 8) & 0xff, &cs1);
- //pr_err("t3 canvas source input reconfig\n");
- y_addr = cs0.addr;
- uv_addr = cs1.addr;
-
- canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
- picsize_y = wq->pic.encoder_height;
- iformat = (request->fmt == FMT_NV21) ? 2 : 3;
-
- canvas_config_proxy(
- ENC_CANVAS_OFFSET + 6,
- y_addr,
- canvas_w,
- picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
-
- canvas_config_proxy(
- ENC_CANVAS_OFFSET + 7,
- uv_addr,
- canvas_w,
- picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
-
- input = ((ENC_CANVAS_OFFSET + 7) << 8) |
- (ENC_CANVAS_OFFSET + 6);
- }
} else if (request->fmt == FMT_YUV420) {
iformat = 4;
input = input & 0xffffff;
@@ -2732,9 +2451,11 @@
READ_VREG(DOS_SW_RESET1);
READ_VREG(DOS_SW_RESET1);
READ_VREG(DOS_SW_RESET1);
+
WRITE_VREG(DOS_SW_RESET1,
(1 << 12) | (1 << 11));
WRITE_VREG(DOS_SW_RESET1, 0);
+
READ_VREG(DOS_SW_RESET1);
READ_VREG(DOS_SW_RESET1);
READ_VREG(DOS_SW_RESET1);
@@ -2786,31 +2507,6 @@
{
ulong timeout;
s32 ret = 0;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- char *buf = vmalloc(0x1000 * 16);
- int ret = -1;
- pr_err("load firmware for t3 avc encoder\n");
- if (get_firmware_data(VIDEO_ENC_H264, buf) < 0) {
- //amvdec_disable();
- pr_err("get firmware for 264 enc fail!\n");
- vfree(buf);
- return -1;
- }
-
- WRITE_HREG(HCODEC_MPSR, 0);
- WRITE_HREG(HCODEC_CPSR, 0);
- ret = amvdec_loadmc_ex(VFORMAT_H264_ENC, NULL, buf);
-
- if (ret < 0) {
- //amvdec_disable();
- vfree(buf);
- pr_err("amvenc: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
- vfree(buf);
- return 0;
- }
/* use static mempry*/
if (mc_addr == NULL) {
@@ -2851,8 +2547,7 @@
WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map);
WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000);
- //WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
- WRITE_VREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (0xf << 16)));
+ WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
if (time_before(jiffies, timeout))
@@ -2935,25 +2630,21 @@
u32 data32;
data32 = 0;
+
amports_switch_gate("vdec", 1);
+
+ spin_lock_irqsave(&lock, flags);
+
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
hcodec_clk_config(1);
udelay(20);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- vdec_poweron(VDEC_HCODEC);
- pr_err("vdec_poweron VDEC_HCODEC\n");
- } else {
- pwr_ctrl_psci_smc(PDID_T3_DOS_HCODEC, PWR_ON);
- pr_err("pwr_ctrl_psci_smc PDID_T3_DOS_HCODEC off\n");
- }
+
+ pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_ON);
udelay(20);
- /*
- pr_err("hcodec powered on, hcodec clk rate:%ld, pwr_state:%d\n",
- clk_get_rate(s_hcodec_clks.hcodec_aclk),
- !pwr_ctrl_status_psci_smc(PDID_T3_DOS_HCODEC));
- */
+ pr_err("hcodec powered on, hcodec clk rate:%ld, pwr_state:%d\n",
+ clk_get_rate(s_hcodec_clks.hcodec_aclk),
+ !pwr_ctrl_status_psci_smc(PDID_DOS_HCODEC));
} else {
- spin_lock_irqsave(&lock, flags);
WRITE_AOREG(AO_RTI_PWR_CNTL_REG0,
(READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18)));
udelay(10);
@@ -2964,24 +2655,21 @@
((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
? ~0x1 : ~0x3));
+
udelay(10);
- spin_unlock_irqrestore(&lock, flags);
}
- spin_lock_irqsave(&lock, flags);
+
WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
WRITE_VREG(DOS_SW_RESET1, 0);
+
/* Enable Dos internal clock gating */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);
- /*
- * WRITE_VREG(DOS_GCLK_EN0, 0xffffffff);
- */
- } else
- hvdec_clock_enable(clock);
+ hvdec_clock_enable(clock);
+
/* Powerup HCODEC memories */
WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+
} else {
/* Remove HCODEC ISO */
WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
@@ -2990,15 +2678,17 @@
get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
? ~0x1 : ~0x30));
}
+
udelay(10);
/* Disable auto-clock gate */
WRITE_VREG(DOS_GEN_CTRL0,
(READ_VREG(DOS_GEN_CTRL0) | 0x1));
WRITE_VREG(DOS_GEN_CTRL0,
(READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE));
- spin_unlock_irqrestore(&lock, flags);
- mdelay(10);
+ spin_unlock_irqrestore(&lock, flags);
+
+ mdelay(10);
return 0;
}
@@ -3006,37 +2696,26 @@
{
ulong flags;
+ spin_lock_irqsave(&lock, flags);
+
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
hcodec_clk_config(0);
udelay(20);
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- vdec_poweroff(VDEC_HCODEC);
- pr_err("vdec_poweroff VDEC_HCODEC\n");
- } else {
- pwr_ctrl_psci_smc(PDID_T3_DOS_HCODEC, PWR_OFF);
- pr_err("pwr_ctrl_psci_smc PDID_T3_DOS_HCODEC on\n");
- }
+ pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_OFF);
udelay(20);
} else {
/* enable HCODEC isolation */
- spin_lock_irqsave(&lock, flags);
WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
READ_AOREG(AO_RTI_GEN_PWR_ISO0) |
((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
? 0x1 : 0x30));
- spin_unlock_irqrestore(&lock, flags);
}
- spin_lock_irqsave(&lock, flags);
/* power off HCODEC memories */
WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
/* disable HCODEC clock */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- WRITE_VREG_BITS(DOS_GCLK_EN0, 0, 12, 15);
- } else
- hvdec_clock_disable();
+ hvdec_clock_disable();
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
@@ -3118,7 +2797,6 @@
manager->process_irq = true;
if (manager->encode_hw_status != ENCODER_SEQUENCE_DONE)
manager->need_reset = true;
-
tasklet_schedule(&manager->encode_tasklet);
}
return IRQ_HANDLED;
@@ -3137,7 +2815,6 @@
if (!wq)
return -1;
-
memset(&wq->request, 0, sizeof(struct encode_request_s));
wq->request.me_weight = ME_WEIGHT_OFFSET;
wq->request.i4_weight = I4MB_WEIGHT_OFFSET;
@@ -3148,7 +2825,7 @@
wq->request.ucode_mode = cmd_info[1];
wq->request.quant = cmd_info[2];
wq->request.flush_flag = cmd_info[3];
- //wq->request.timeout = cmd_info[4];
+ wq->request.timeout = cmd_info[4];
wq->request.timeout = 5000; /* 5000 ms */
} else if ((cmd == ENCODER_IDR) || (cmd == ENCODER_NON_IDR)) {
wq->request.cmd = cmd;
@@ -3180,14 +2857,6 @@
wq->request.src_h = wq->pic.encoder_height;
enc_pr(LOG_INFO, "hwenc: force wq->request.scale_enable=%d\n", wq->request.scale_enable);
}
- /*
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3 && wq->request.type == CANVAS_BUFF) {
- wq->request.scale_enable = 1;
- wq->request.src_w = wq->pic.encoder_width;
- wq->request.src_h = wq->pic.encoder_height;
- enc_pr(LOG_DEBUG, "hwenc: t3 canvas source, force wq->request.scale_enable=%d\n", wq->request.scale_enable);
- }
- */
wq->request.nr_mode =
(nr_mode > 0) ? nr_mode : cmd_info[16];
@@ -3247,36 +2916,6 @@
sizeof(wq->quant_tbl_i16));
data_offset += 3;
}
- //add qp range check
- enc_pr(LOG_INFO, "wq->request.quant %d \n", wq->request.quant);
- {
- u8 *qp_tb = (u8 *)(&wq->quant_tbl_i4[0]);
- for (i = 0; i < 32; i++) {
- if (*qp_tb > 51) {
- enc_pr(LOG_ERROR, "i4 %d ", *qp_tb);
- *qp_tb = 51;
- }
- qp_tb++;
- }
-
- qp_tb = (u8 *)(&wq->quant_tbl_i16[0]);
- for (i = 0; i < 32; i++) {
- if (*qp_tb > 51) {
- enc_pr(LOG_ERROR, "i16 %d ", *qp_tb);
- *qp_tb = 51;
- }
- qp_tb++;
- }
-
- qp_tb = (u8 *)(&wq->quant_tbl_me[0]);
- for (i = 0; i < 32; i++) {
- if (*qp_tb > 51) {
- enc_pr(LOG_ERROR, "me %d ", *qp_tb);
- *qp_tb = 51;
- }
- qp_tb++;
- }
- }
#ifdef H264_ENC_CBR
wq->cbr_info.block_w = cmd_info[data_offset++];
wq->cbr_info.block_h = cmd_info[data_offset++];
@@ -3297,11 +2936,6 @@
if (wq->request.fmt == FMT_NV12 ||
wq->request.fmt == FMT_NV21 ||
wq->request.fmt == FMT_YUV420) {
- if (wq->request.plane_num > 3) {
- enc_pr(LOG_ERROR, "wq->request.plane_num is invalid %d.\n",
- wq->request.plane_num);
- return -1;
- }
for (i = 0; i < wq->request.plane_num; i++) {
cfg = &wq->request.dma_cfg[i];
cfg->dir = DMA_TO_DEVICE;
@@ -3506,13 +3140,13 @@
const char *p = select_ucode(encode_manager.ucode_index);
avc_poweron(clock);
-
avc_canvas_init(wq);
WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
if (amvenc_loadmc(p, wq) < 0)
return -EBUSY;
+
encode_manager.need_reset = true;
encode_manager.process_irq = false;
encode_manager.encode_hw_status = ENCODER_IDLE;
@@ -3523,6 +3157,7 @@
ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT;
avc_prot_init(wq, NULL, wq->pic.init_qppicture, true);
+
if (request_irq(encode_manager.irq_num, enc_isr, IRQF_SHARED,
"enc-irq", (void *)&encode_manager) == 0)
encode_manager.irq_requested = true;
@@ -3552,9 +3187,7 @@
#else
WRITE_HREG(FIXED_SLICE_CFG, 0);
#endif
-
amvenc_start();
-
return 0;
}
@@ -3562,8 +3195,8 @@
{
if ((encode_manager.irq_num >= 0) &&
(encode_manager.irq_requested == true)) {
- encode_manager.irq_requested = false;
free_irq(encode_manager.irq_num, &encode_manager);
+ encode_manager.irq_requested = false;
}
amvenc_stop();
avc_poweroff();
@@ -3621,7 +3254,6 @@
file->private_data = NULL;
enc_pr(LOG_DEBUG, "avc open\n");
-
#ifdef CONFIG_AM_JPEG_ENCODER
if (jpegenc_on() == true) {
enc_pr(LOG_ERROR,
@@ -3717,8 +3349,7 @@
u32 buf_start;
s32 canvas = -1;
struct canvas_s dst;
- u32 cpuid;
- memset(&dst, 0, sizeof(struct canvas_s));
+
switch (cmd) {
case AMVENC_AVC_IOC_GET_ADDR:
if ((wq->mem.ref_buf_canvas & 0xff) == (ENC_CANVAS_OFFSET))
@@ -3782,21 +3413,17 @@
wq->mem.bufspec.max_height, (void *)wq);
return -1;
}
-
+ pr_err("hwenc: AMVENC_AVC_IOC_CONFIG_INIT: w:%d, h:%d\n", wq->pic.encoder_width, wq->pic.encoder_height);
wq->pic.encoder_width = addr_info[2];
wq->pic.encoder_height = addr_info[3];
- pr_err("hwenc: AMVENC_AVC_IOC_CONFIG_INIT: w:%d, h:%d\n", wq->pic.encoder_width, wq->pic.encoder_height);
wq->pic.color_space = addr_info[4];
pr_err("hwenc: AMVENC_AVC_IOC_CONFIG_INIT, wq->pic.color_space=%#x\n", wq->pic.color_space);
-
- /*
if (wq->pic.encoder_width *
wq->pic.encoder_height >= 1280 * 720)
clock_level = 6;
else
clock_level = 5;
- */
avc_buffspec_init(wq);
complete(&encode_manager.event.request_in_com);
addr_info[1] = wq->mem.bufspec.dct.buf_start;
@@ -3934,11 +3561,6 @@
get_user(qp_mode, ((u32 *)arg));
pr_info("qp_mode %d\n", qp_mode);
break;
- case AMVENC_AVC_IOC_GET_CPU_ID:
- cpuid = (u32) get_cpu_major_id();
- pr_err("AMVENC_AVC_IOC_GET_CPU_ID return %u\n", cpuid);
- put_user(cpuid, (u32 *)arg);
- break;
default:
r = -1;
break;
@@ -3995,6 +3617,7 @@
atomic_dec(&wq->request_ready);
return POLLIN | POLLRDNORM;
}
+
return 0;
}
@@ -4017,8 +3640,10 @@
s32 ret = 0;
struct encode_wq_s *wq = pitem->request.parent;
struct encode_request_s *request = &pitem->request;
+
u32 timeout = (request->timeout == 0) ?
1 : msecs_to_jiffies(request->timeout);
+
u32 buf_start = 0;
u32 size = 0;
u32 flush_size = ((wq->pic.encoder_width + 31) >> 5 << 5) *
@@ -4033,14 +3658,12 @@
&& get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
void *vaddr = wq->mem.cbr_info_ddr_virt_addr;
ConvertTable2Risc(vaddr, 0xa00);
- //buf_start = getbuffer(wq, ENCODER_BUFFER_CBR);
+ buf_start = getbuffer(wq, ENCODER_BUFFER_CBR);
codec_mm_dma_flush(vaddr, wq->mem.cbr_info_ddr_size, DMA_TO_DEVICE);
}
}
#endif
-
-
Again:
amvenc_avc_start_cmd(wq, request);
@@ -4196,11 +3819,9 @@
pitem->request.cmd, pitem->request.ucode_mode,
(void *)wq);
complete(&encode_manager.event.request_in_com);/* new cmd come in */
-
return 0;
error:
spin_unlock(&encode_manager.event.sem_lock);
-
return -1;
}
@@ -4535,10 +4156,9 @@
struct encode_queue_item_s *pitem = NULL;
enc_pr(LOG_DEBUG, "encode_wq_init.\n");
+ encode_manager.irq_requested = false;
spin_lock_init(&encode_manager.event.sem_lock);
- spin_lock(&encode_manager.event.sem_lock);
- encode_manager.irq_requested = false;
init_completion(&encode_manager.event.request_in_com);
init_waitqueue_head(&encode_manager.event.hw_complete);
init_completion(&encode_manager.event.process_complete);
@@ -4550,7 +4170,6 @@
encode_isr_tasklet,
(ulong)&encode_manager);
- spin_unlock(&encode_manager.event.sem_lock);
for (i = 0; i < MAX_ENCODE_REQUEST; i++) {
pitem = kcalloc(1,
sizeof(struct encode_queue_item_s),
@@ -4562,14 +4181,12 @@
pitem->request.parent = NULL;
list_add_tail(&pitem->list, &encode_manager.free_queue);
}
- spin_lock(&encode_manager.event.sem_lock);
encode_manager.current_wq = NULL;
encode_manager.last_wq = NULL;
encode_manager.encode_thread = NULL;
encode_manager.current_item = NULL;
encode_manager.wq_count = 0;
encode_manager.remove_flag = false;
- spin_unlock(&encode_manager.event.sem_lock);
InitEncodeWeight();
if (encode_start_monitor()) {
enc_pr(LOG_ERROR, "encode create thread error.\n");
@@ -4655,7 +4272,7 @@
head = &encode_manager.process_queue;
list_for_each_entry(pitem, head, list) {
process_count++;
- if (process_count > MAX_ENCODE_REQUEST)
+ if (free_count > MAX_ENCODE_REQUEST)
break;
}
@@ -4712,7 +4329,7 @@
}
return snprintf(buf, 40, "encode max instance: %d\n", max_instance);
}
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,13,1)
+
static struct class_attribute amvenc_class_attrs[] = {
__ATTR(encode_status,
S_IRUGO | S_IWUSR,
@@ -4725,21 +4342,7 @@
.name = CLASS_NAME,
.class_attrs = amvenc_class_attrs,
};
-#else /* LINUX_VERSION_CODE <= KERNEL_VERSION(4,13,1) */
-static CLASS_ATTR_RO(encode_status);
-static struct attribute *amvenc_avc_class_attrs[] = {
- &class_attr_encode_status.attr,
- NULL
-};
-
-ATTRIBUTE_GROUPS(amvenc_avc_class);
-
-static struct class amvenc_avc_class = {
- .name = CLASS_NAME,
- .class_groups = amvenc_avc_class_groups,
-};
-#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4,13,1) */
s32 init_avc_device(void)
{
s32 r = 0;
@@ -4858,7 +4461,7 @@
s32 idx;
s32 r;
- enc_pr(LOG_INFO, "amvenc_avc probe start.\n");
+ enc_pr(LOG_ERROR, "amvenc_avc probe start.\n");
encode_manager.this_pdev = pdev;
#ifdef CONFIG_CMA
@@ -4924,7 +4527,6 @@
r = init_avc_device();
enc_pr(LOG_INFO, "amvenc_avc probe end.\n");
-
return r;
}
@@ -4956,20 +4558,13 @@
}
};
-/*
static struct codec_profile_t amvenc_avc_profile = {
.name = "avc",
.profile = ""
};
-*/
static s32 __init amvenc_avc_driver_init_module(void)
{
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("T7 doesn't support hcodec avc encoder!!\n");
- return -1;
- }
-
enc_pr(LOG_INFO, "amvenc_avc module init\n");
if (platform_driver_register(&amvenc_avc_driver)) {
@@ -4977,7 +4572,7 @@
"failed to register amvenc_avc driver\n");
return -ENODEV;
}
- //vcodec_profile_register(&amvenc_avc_profile);
+ vcodec_profile_register(&amvenc_avc_profile);
return 0;
}
@@ -5156,9 +4751,6 @@
module_param(use_ge2d, uint, 0664);
MODULE_PARM_DESC(use_ge2d, "\n use_ge2d\n");
-module_param(dump_input, uint, 0664);
-MODULE_PARM_DESC(dump_input, "\n dump_input\n");
-
#ifdef H264_ENC_SVC
module_param(svc_enable, uint, 0664);
MODULE_PARM_DESC(svc_enable, "\n svc enable\n");
diff --git a/drivers/frame_sink/encoder/h264/encoder.h b/drivers/frame_sink/encoder/h264/encoder.h
index bd97bb6..b5bbe7d 100644
--- a/drivers/frame_sink/encoder/h264/encoder.h
+++ b/drivers/frame_sink/encoder/h264/encoder.h
@@ -113,7 +113,6 @@
#define AMVENC_AVC_IOC_GET_DEVINFO _IOW(AMVENC_AVC_IOC_MAGIC, 0xf0, u32)
#define AMVENC_AVC_IOC_MAX_INSTANCE _IOW(AMVENC_AVC_IOC_MAGIC, 0xf1, u32)
-#define AMVENC_AVC_IOC_GET_CPU_ID _IOW(AMVENC_AVC_IOC_MAGIC, 0xf2, u32)
#define AMVENC_AVC_IOC_GET_ADDR _IOW(AMVENC_AVC_IOC_MAGIC, 0x00, u32)
#define AMVENC_AVC_IOC_INPUT_UPDATE _IOW(AMVENC_AVC_IOC_MAGIC, 0x01, u32)
diff --git a/drivers/frame_sink/encoder/h265/vpu.c b/drivers/frame_sink/encoder/h265/vpu.c
index 55cb054..70598b3 100644
--- a/drivers/frame_sink/encoder/h265/vpu.c
+++ b/drivers/frame_sink/encoder/h265/vpu.c
@@ -39,17 +39,14 @@
#include <linux/compat.h>
#include <linux/of_reserved_mem.h>
#include <linux/of_address.h>
-#include <linux/compat.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
-
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include <linux/version.h>
#include "../../../frame_provider/decoder/utils/vdec_power_ctrl.h"
#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/power_ctrl.h>
#include <dt-bindings/power/sc2-pd.h>
-#include <linux/amlogic/power_domain.h>
-#include <linux/amlogic/power_ctrl.h>
+#include <linux/amlogic/pwr_ctrl.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,1)
#include <linux/sched/signal.h>
#endif
@@ -422,20 +419,16 @@
bool alloc_buffer = false;
s32 r = 0;
- enc_pr(LOG_DEBUG, "[+] %s, open_count=%d\n", __func__,
- s_vpu_drv_context.open_count);
- enc_pr(LOG_DEBUG, "vpu_open, calling process: %d:%s\n", current->pid, current->comm);
+ enc_pr(LOG_DEBUG, "[+] %s\n", __func__);
spin_lock(&s_vpu_lock);
s_vpu_drv_context.open_count++;
if (s_vpu_drv_context.open_count == 1) {
alloc_buffer = true;
} else {
r = -EBUSY;
- enc_pr(LOG_ERROR, "vpu_open, device is busy, s_vpu_drv_context.open_count=%d\n",
- s_vpu_drv_context.open_count);
s_vpu_drv_context.open_count--;
spin_unlock(&s_vpu_lock);
- return r;
+ goto Err;
}
filp->private_data = (void *)(&s_vpu_drv_context);
spin_unlock(&s_vpu_lock);
@@ -498,14 +491,13 @@
if (err) {
enc_pr(LOG_ERROR,
"fail to register interrupt handler\n");
- spin_lock(&s_vpu_lock);
s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
return -EFAULT;
}
s_vpu_irq_requested = true;
}
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+
} else
amports_switch_gate("vdec", 1);
@@ -513,7 +505,7 @@
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
//vpu_clk_config(1);
- pwr_ctrl_psci_smc(PDID_SC2_DOS_WAVE, PWR_ON);
+ pwr_ctrl_psci_smc(PDID_DOS_WAVE, PWR_ON);
} else {
WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
@@ -570,14 +562,9 @@
dma_cfg[0].fd = -1;
dma_cfg[1].fd = -1;
dma_cfg[2].fd = -1;
-
- if (r != 0) {
- spin_lock(&s_vpu_lock);
- enc_pr(LOG_DEBUG, "vpu_open, error handling, r=%d, s_vpu_drv_context.open_count=%d\n",
- r, s_vpu_drv_context.open_count);
+Err:
+ if (r != 0)
s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
- }
enc_pr(LOG_DEBUG, "[-] %s, ret: %d\n", __func__, r);
return r;
}
@@ -648,7 +635,6 @@
enc_pr(LOG_ALL,
"[+]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32\n");
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
ret = down_interruptible(&s_vpu_sem);
if (ret == 0) {
vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
@@ -813,7 +799,6 @@
{
struct compat_vpudrv_buffer_t buf32;
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
enc_pr(LOG_ALL,
"[+]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32\n");
@@ -962,7 +947,6 @@
{
struct compat_vpudrv_buffer_t buf32;
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
enc_pr(LOG_ALL,
"[+]VDI_IOCTL_GET_INSTANCE_POOL32\n");
ret = down_interruptible(&s_vpu_sem);
@@ -1065,7 +1049,6 @@
{
struct compat_vpudrv_buffer_t buf32;
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
enc_pr(LOG_ALL,
"[+]VDI_IOCTL_GET_COMMON_MEMORY32\n");
@@ -1127,10 +1110,7 @@
if (copy_from_user(&inst_info,
(struct vpudrv_inst_info_t *)arg,
sizeof(struct vpudrv_inst_info_t)))
- {
- kfree(vil);
return -EFAULT;
- }
vil->inst_idx = inst_info.inst_idx;
vil->core_idx = inst_info.core_idx;
@@ -1291,7 +1271,6 @@
{
struct compat_vpudrv_buffer_t buf32;
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
enc_pr(LOG_ALL,
"[+]VDI_IOCTL_GET_REGISTER_INFO32\n");
@@ -1486,7 +1465,6 @@
if (copy_from_user(bit_firmware_info, buf, len)) {
enc_pr(LOG_ERROR,
"vpu_write copy_from_user error for bit_firmware_info\n");
- kfree(bit_firmware_info);
return -EFAULT;
}
@@ -1509,15 +1487,9 @@
enc_pr(LOG_ERROR,
"exceeded than MAX_NUM_VPU_CORE[%d]\n",
MAX_NUM_VPU_CORE);
- kfree(bit_firmware_info);
return -ENODEV;
}
- if (bit_firmware_info->core_idx >= MAX_NUM_VPU_CORE)
- {
- enc_pr(LOG_ERROR,"bit_firmware_info->core_idx %d is invalid!\n", bit_firmware_info->core_idx);
- kfree(bit_firmware_info);
- return -1;
- }
+
memcpy((void *)&s_bit_firmware_info
[bit_firmware_info->core_idx],
bit_firmware_info,
@@ -1535,32 +1507,14 @@
s32 ret = 0;
ulong flags;
- enc_pr(LOG_DEBUG, "vpu_release, calling process: %d:%s\n", current->pid, current->comm);
+ enc_pr(LOG_DEBUG, "vpu_release\n");
ret = down_interruptible(&s_vpu_sem);
- enc_pr(LOG_DEBUG, "vpu_release, ret = %d\n", ret);
-
- spin_lock(&s_vpu_lock);
- if (s_vpu_drv_context.open_count <= 0) {
- enc_pr(LOG_DEBUG, "vpu_release, open_count=%d, already released or even not inited\n",
- s_vpu_drv_context.open_count);
- s_vpu_drv_context.open_count = 0;
- spin_unlock(&s_vpu_lock);
- goto exit_release;
- }
- spin_unlock(&s_vpu_lock);
-
if (ret == 0) {
vpu_free_buffers(filp);
vpu_free_instances(filp);
-
- spin_lock(&s_vpu_lock);
- enc_pr(LOG_DEBUG, "vpu_release, decrease open_count from %d\n",
- s_vpu_drv_context.open_count);
-
s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
if (s_vpu_drv_context.open_count == 0) {
- enc_pr(LOG_DEBUG,
+ enc_pr(LOG_INFO,
"vpu_release: s_interrupt_flag(%d), reason(0x%08lx)\n",
s_interrupt_flag, s_vpu_drv_context.interrupt_reason);
s_vpu_drv_context.interrupt_reason = 0;
@@ -1596,7 +1550,7 @@
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
//vpu_clk_config(0);
- pwr_ctrl_psci_smc(PDID_SC2_DOS_WAVE, PWR_OFF);
+ pwr_ctrl_psci_smc(PDID_DOS_WAVE, PWR_OFF);
} else {
WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
READ_AOREG(AO_RTI_GEN_PWR_ISO0) |
@@ -1627,7 +1581,6 @@
amports_switch_gate("vdec", 0);
}
}
-exit_release:
up(&s_vpu_sem);
return 0;
}
@@ -2030,7 +1983,7 @@
struct resource res;
struct device_node *np, *child;
- enc_pr(LOG_DEBUG, "vpu_probe, clock_a: %d, clock_b: %d, clock_c: %d\n",
+ enc_pr(LOG_DEBUG, "vpu_probe fuck, clock_a: %d, clock_b: %d, clock_c: %d\n",
wave_clocka, wave_clockb, wave_clockc);
s_vpu_major = 0;
@@ -2392,13 +2345,11 @@
WriteVpuRegister(W4_HW_OPTION, hwOption);
/* Interrupt */
-#if 0
regVal = (1 << W4_INT_DEC_PIC_HDR);
regVal |= (1 << W4_INT_DEC_PIC);
regVal |= (1 << W4_INT_QUERY_DEC);
regVal |= (1 << W4_INT_SLEEP_VPU);
regVal |= (1 << W4_INT_BSBUF_EMPTY);
-#endif
regVal = 0xfffffefe;
WriteVpuRegister(W4_VPU_VINT_ENABLE, regVal);
Wave4BitIssueCommand(core, W4_CMD_INIT_VPU);
diff --git a/drivers/frame_sink/encoder/jpeg/Makefile b/drivers/frame_sink/encoder/jpeg/Makefile
index 4f6c498..5d06732 100644
--- a/drivers/frame_sink/encoder/jpeg/Makefile
+++ b/drivers/frame_sink/encoder/jpeg/Makefile
@@ -1,2 +1,6 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VENC_JPEG) += jpegenc.o
+#obj-$(CONFIG_AMLOGIC_MEDIA_VENC_JPEG) += amvenc_jpeg.o
+#obj-m += amvenc_jpeg.o
#amvenc_jpeg-objs += jpegenc.o
+#obj-m += jpegenc.o
+
+obj-$(CONFIG_AMLOGIC_MEDIA_VENC_JPEG) += jpegenc.o
\ No newline at end of file
diff --git a/drivers/frame_sink/encoder/jpeg/jpegenc.c b/drivers/frame_sink/encoder/jpeg/jpegenc.c
index 4416378..8878fc9 100644
--- a/drivers/frame_sink/encoder/jpeg/jpegenc.c
+++ b/drivers/frame_sink/encoder/jpeg/jpegenc.c
@@ -14,19 +14,14 @@
* more details.
*
*/
-#define LOG_LINE()
-//pr_err("[%s:%d]\n", __FUNCTION__, __LINE__);
-#include <linux/module.h>
+#define LOG_LINE() pr_err("[%s:%d]\n", __FUNCTION__, __LINE__);
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/compat.h>
-#include <linux/ktime.h>
-#include <linux/timekeeping.h>
-
-#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/slab.h>
@@ -38,38 +33,35 @@
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../frame_provider/decoder/utils/vdec_canvas_utils.h"
+#include "../../../frame_provider/decoder/utils/vdec.h"
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/dma-contiguous.h>
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../../frame_provider/decoder/utils/amvdec.h"
-#include "../../../stream_input/amports/amports_priv.h"
+#include <linux/amlogic/media/utils/amports_config.h>
#include "../../../frame_provider/decoder/utils/firmware.h"
-#include "../../../frame_provider/decoder/utils/vdec.h"
-#include "../../../frame_provider/decoder/utils/vdec_power_ctrl.h"
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include "../../../frame_provider/decoder/utils/amvdec.h"
#include "jpegenc.h"
-#include <linux/of_reserved_mem.h>
+#include "../../../frame_provider/decoder/utils/vdec_power_ctrl.h"
+#include <linux/amlogic/media/utils/vdec_reg.h>
#include <linux/amlogic/power_ctrl.h>
-#include <dt-bindings/power/t7-pd.h>
-#include <linux/amlogic/power_domain.h>
+#include <dt-bindings/power/sc2-pd.h>
+#include <linux/amlogic/pwr_ctrl.h>
-#include <linux/clk.h>
-#define HCODEC_MFDIN_REG17 0x101f
-#define HCODEC_MFDIN_REG18 0x1020
-#define HCODEC_MFDIN_REG19 0x1021
+#include <linux/amlogic/media/utils/amlog.h>
+//#include "amports_priv.h"
+#include <linux/of_reserved_mem.h>
#ifdef CONFIG_AM_ENCODER
#include "encoder.h"
#endif
-#define JPEGENC_CANVAS_INDEX 0x64
-#define JPEGENC_CANVAS_MAX_INDEX 0x67
+#define JPEGENC_CANVAS_INDEX 0xE4
+#define JPEGENC_CANVAS_MAX_INDEX 0xE7
#define ENC_CANVAS_OFFSET JPEGENC_CANVAS_INDEX
@@ -79,36 +71,21 @@
#define LOG_ERROR 3
#define jenc_pr(level, x...) \
- do { \
- if (level >= jpegenc_print_level) \
- printk(x); \
- } while (0)
+ do { \
+ if (level >= jpegenc_print_level) \
+ printk(x); \
+ } while (0)
#define DRIVER_NAME "jpegenc"
#define CLASS_NAME "jpegenc"
#define DEVICE_NAME "jpegenc"
+#define MIN_SIZE jpegenc_buffspec[0].min_buffsize
/* #define EXTEAN_QUANT_TABLE */
-/*######### DEBUG-BRINGUP#########*/
-static u32 manual_clock;
-static u32 manual_irq_num = 2;
-static u32 manual_interrupt = 0;
-/*################################*/
-
static s32 jpegenc_device_major;
static struct device *jpegenc_dev;
-static u32 jpegenc_print_level = LOG_ERROR;
-
-static s32 reg_offset;
-
-static u32 use_dma_io = 1;
-
-static u32 use_quality=1;
-static u32 legacy_load=0;
-
-static u32 dumpmem_line = 0;
-static u32 pointer = 0;
+static u32 jpegenc_print_level = 0;
static u32 clock_level = 1;
static u16 gQuantTable[2][DCTSIZE2];
@@ -117,19 +94,7 @@
static bool external_quant_table_available;
#endif
-static u32 simulation_enable;
-static u32 g_block_mode;
-static u32 g_canv0_stride;
-static u32 g_canv1_stride;
-static u32 g_canv2_stride;
-static u32 g_canvas_height;
-
-static u32 jpeg_in_full_hcodec;
-static u32 mfdin_ambus_canv_conv;
-
-#define MHz (1000000)
-
-//static DEFINE_SPINLOCK(lock);
+static DEFINE_SPINLOCK(lock);
#define JPEGENC_BUFFER_LEVEL_VGA 0
#define JPEGENC_BUFFER_LEVEL_2M 1
@@ -139,3239 +104,2663 @@
#define JPEGENC_BUFFER_LEVEL_13M 5
#define JPEGENC_BUFFER_LEVEL_HD 6
+
+#define MHz (1000000)
+
+#define CHECK_RET(_ret) if (ret) {pr_err(\
+ "%s:%d:function call failed with result: %d\n",\
+ __FUNCTION__, __LINE__, _ret);}
+
+
+struct jpegenc_clks {
+ struct clk *jpegenc_aclk;
+ //struct clk *hcodec_bclk;
+ //struct clk *hcodec_cclk;
+};
+
+static struct jpegenc_clks s_jpegenc_clks;
+struct reset_control *jpegenc_rst;
+
+/*
+s32 jpegenc_hw_reset(void)
+{
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ reset_control_reset(jpegenc_rst);
+ pr_err("request jpegenc reset from application.\n");
+ }
+ return 0;
+}
+*/
+
+s32 jpegenc_clk_prepare(struct device *dev, struct jpegenc_clks *clks)
+{
+ int ret;
+
+ clks->jpegenc_aclk = devm_clk_get(dev, "cts_jpegenc_aclk");
+
+ if (IS_ERR_OR_NULL(clks->jpegenc_aclk)) {
+ pr_err("failed to get jpegenc aclk: %px, %ld, dev=%px\n",
+ clks->jpegenc_aclk,
+ PTR_ERR(clks->jpegenc_aclk),
+ dev);
+ return -1;
+ }
+
+ ret = clk_set_rate(clks->jpegenc_aclk, 667 * MHz);
+ CHECK_RET(ret);
+
+ ret = clk_prepare(clks->jpegenc_aclk);
+ CHECK_RET(ret);
+
+ pr_err("jpegenc_clk_a: %lu MHz\n", clk_get_rate(clks->jpegenc_aclk) / 1000000);
+
+ return 0;
+}
+
+void jpegenc_clk_unprepare(struct device *dev, struct jpegenc_clks *clks)
+{
+ clk_unprepare(clks->jpegenc_aclk);
+ devm_clk_put(dev, clks->jpegenc_aclk);
+
+ //clk_unprepare(clks->wave_bclk);
+ //devm_clk_put(dev, clks->wave_bclk);
+
+ //clk_unprepare(clks->wave_aclk);
+ //devm_clk_put(dev, clks->wave_aclk);
+}
+
+static s32 jpegenc_clk_config(u32 enable)
+{
+ if (enable) {
+ clk_enable(s_jpegenc_clks.jpegenc_aclk);
+ //clk_enable(s_hcodec_clks.wave_bclk);
+ //clk_enable(s_hcodec_clks.wave_cclk);
+ } else {
+ clk_disable(s_jpegenc_clks.jpegenc_aclk);
+ //clk_disable(s_hcodec_clks.wave_bclk);
+ //clk_disable(s_hcodec_clks.wave_aclk);
+ }
+
+ return 0;
+}
+
const s8 *glevel_str[] = {
- "VGA",
- "2M",
- "3M",
- "5M",
- "8M",
- "13M",
- "HD",
+ "VGA",
+ "2M",
+ "3M",
+ "5M",
+ "8M",
+ "13M",
+ "HD",
};
const struct Jpegenc_BuffInfo_s jpegenc_buffspec[] = {
- {
- .lev_id = JPEGENC_BUFFER_LEVEL_VGA,
- .max_width = 640,
- .max_height = 640,
- .min_buffsize = 0x330000,
- .input = {
- .buf_start = 0,
- .buf_size = 0x12c000,
- },
- .assit = {
- .buf_start = 0x12d000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0x130000,
- .buf_size = 0x200000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_2M,
- .max_width = 1600,
- .max_height = 1600,
- .min_buffsize = 0x960000,
- .input = {
- .buf_start = 0,
- .buf_size = 0x753000,
- },
- .assit = {
- .buf_start = 0x754000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0x760000,
- .buf_size = 0x200000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_3M,
- .max_width = 2048,
- .max_height = 2048,
- .min_buffsize = 0xe10000,
- .input = {
- .buf_start = 0,
- .buf_size = 0xc00000,
- },
- .assit = {
- .buf_start = 0xc01000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0xc10000,
- .buf_size = 0x200000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_5M,
- .max_width = 2624,
- .max_height = 2624,
- .min_buffsize = 0x1800000,
- .input = {
- .buf_start = 0,
- .buf_size = 0x13B3000,
- },
- .assit = {
- .buf_start = 0x13B4000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0x1400000,
- .buf_size = 0x400000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_8M,
- .max_width = 3264,
- .max_height = 3264,
- .min_buffsize = 0x2300000,
- .input = {
- .buf_start = 0,
- .buf_size = 0x1e7b000,
- },
- .assit = {
- .buf_start = 0x1e7c000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0x1f00000,
- .buf_size = 0x400000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_13M,
- .max_width = 8192,
- .max_height = 8192,
- .min_buffsize = 0xc400000,
- .input = {
- .buf_start = 0,
- .buf_size = 0xc000000,
- },
- .assit = {
- .buf_start = 0xc001000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0xc010000,
- .buf_size = 0x3f0000,
- }
- }, {
- .lev_id = JPEGENC_BUFFER_LEVEL_HD,
- .max_width = 8192,
- .max_height = 8192,
- .min_buffsize = 0xc400000,
- .input = {
- .buf_start = 0,
- .buf_size = 0xc000000,
- },
- .assit = {
- .buf_start = 0xc001000,
- .buf_size = 0x2000,
- },
- .bitstream = {
- .buf_start = 0xc010000,
- .buf_size = 0x3f0000,
- }
- }
+ {
+ .lev_id = JPEGENC_BUFFER_LEVEL_VGA,
+ .max_width = 640,
+ .max_height = 640,
+ .min_buffsize = 0x330000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0x12c000,
+ },
+ .assit = {
+ .buf_start = 0x12d000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0x130000,
+ .buf_size = 0x200000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_2M,
+ .max_width = 1600,
+ .max_height = 1600,
+ .min_buffsize = 0x960000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0x753000,
+ },
+ .assit = {
+ .buf_start = 0x754000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0x760000,
+ .buf_size = 0x200000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_3M,
+ .max_width = 2048,
+ .max_height = 2048,
+ .min_buffsize = 0xe10000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0xc00000,
+ },
+ .assit = {
+ .buf_start = 0xc01000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0xc10000,
+ .buf_size = 0x200000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_5M,
+ .max_width = 2624,
+ .max_height = 2624,
+ .min_buffsize = 0x1800000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0x13B3000,
+ },
+ .assit = {
+ .buf_start = 0x13B4000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0x1400000,
+ .buf_size = 0x400000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_8M,
+ .max_width = 3264,
+ .max_height = 3264,
+ .min_buffsize = 0x2300000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0x1e7b000,
+ },
+ .assit = {
+ .buf_start = 0x1e7c000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0x1f00000,
+ .buf_size = 0x400000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_13M,
+ .max_width = 8192,
+ .max_height = 8192,
+ .min_buffsize = 0xc400000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0xc000000,
+ },
+ .assit = {
+ .buf_start = 0xc001000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0xc010000,
+ .buf_size = 0x3f0000,
+ }
+ }, {
+ .lev_id = JPEGENC_BUFFER_LEVEL_HD,
+ .max_width = 8192,
+ .max_height = 8192,
+ .min_buffsize = 0xc400000,
+ .input = {
+ .buf_start = 0,
+ .buf_size = 0xc000000,
+ },
+ .assit = {
+ .buf_start = 0xc001000,
+ .buf_size = 0x2000,
+ },
+ .bitstream = {
+ .buf_start = 0xc010000,
+ .buf_size = 0x3f0000,
+ }
+ }
};
const char *jpegenc_ucode[] = {
- "jpegenc_mc",
+ "gxl_jpeg_enc",//"jpegenc_mc",
};
static struct jpegenc_manager_s gJpegenc;
static const u16 jpeg_quant[7][DCTSIZE2] = {
- { /* jpeg_quant[0][] : Luma, Canon */
- 0x06, 0x06, 0x08, 0x0A, 0x0A, 0x10, 0x15, 0x19,
- 0x06, 0x0A, 0x0A, 0x0E, 0x12, 0x1F, 0x29, 0x29,
- 0x08, 0x0A, 0x0E, 0x12, 0x21, 0x29, 0x29, 0x29,
- 0x0A, 0x0E, 0x12, 0x14, 0x23, 0x29, 0x29, 0x29,
- 0x0A, 0x12, 0x21, 0x23, 0x27, 0x29, 0x29, 0x29,
- 0x10, 0x1F, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x15, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x19, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
- },
- { /* jpeg_quant[1][] : Chroma, Canon */
- 0x0A, 0x0E, 0x10, 0x14, 0x15, 0x1D, 0x2B, 0x35,
- 0x0E, 0x12, 0x14, 0x1D, 0x25, 0x3E, 0x54, 0x54,
- 0x10, 0x14, 0x19, 0x25, 0x40, 0x54, 0x54, 0x54,
- 0x14, 0x1D, 0x25, 0x27, 0x48, 0x54, 0x54, 0x54,
- 0x15, 0x25, 0x40, 0x48, 0x4E, 0x54, 0x54, 0x54,
- 0x1D, 0x3E, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
- 0x2B, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
- 0x35, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54
- },
- { /* jpeg_quant[2][] : Luma, spec example Table K.1 */
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
- },
- { /* jpeg_quant[3][] : Chroma, spec example Table K.2 */
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- },
- { /* jpeg_quant[4][] : Luma, spec example Table K.1,
- modified to create long ZRL */
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 16
- },
- { /* jpeg_quant[5][] : Chroma, spec example Table K.2,
- modified to create long ZRL */
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 17
- },
- { /* jpeg_quant[6][] : no compression */
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
- }
+ { /* jpeg_quant[0][] : Luma, Canon */
+ 0x06, 0x06, 0x08, 0x0A, 0x0A, 0x10, 0x15, 0x19,
+ 0x06, 0x0A, 0x0A, 0x0E, 0x12, 0x1F, 0x29, 0x29,
+ 0x08, 0x0A, 0x0E, 0x12, 0x21, 0x29, 0x29, 0x29,
+ 0x0A, 0x0E, 0x12, 0x14, 0x23, 0x29, 0x29, 0x29,
+ 0x0A, 0x12, 0x21, 0x23, 0x27, 0x29, 0x29, 0x29,
+ 0x10, 0x1F, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x15, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x19, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
+ },
+ { /* jpeg_quant[1][] : Chroma, Canon */
+ 0x0A, 0x0E, 0x10, 0x14, 0x15, 0x1D, 0x2B, 0x35,
+ 0x0E, 0x12, 0x14, 0x1D, 0x25, 0x3E, 0x54, 0x54,
+ 0x10, 0x14, 0x19, 0x25, 0x40, 0x54, 0x54, 0x54,
+ 0x14, 0x1D, 0x25, 0x27, 0x48, 0x54, 0x54, 0x54,
+ 0x15, 0x25, 0x40, 0x48, 0x4E, 0x54, 0x54, 0x54,
+ 0x1D, 0x3E, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
+ 0x2B, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
+ 0x35, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54
+ },
+ { /* jpeg_quant[2][] : Luma, spec example Table K.1 */
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+ },
+ { /* jpeg_quant[3][] : Chroma, spec example Table K.2 */
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+ },
+ { /* jpeg_quant[4][] : Luma, spec example Table K.1,
+ modified to create long ZRL */
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 16
+ },
+ { /* jpeg_quant[5][] : Chroma, spec example Table K.2,
+ modified to create long ZRL */
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 17
+ },
+ { /* jpeg_quant[6][] : no compression */
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1
+ }
}; /* jpeg_quant */
static const u8 jpeg_huffman_dc[2][16 + 12] = {
- { /* jpeg_huffman_dc[0][] */
- 0x00, /* number of code length=1 */
- 0x01,
- 0x05,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00, /* number of code length=16 */
+ { /* jpeg_huffman_dc[0][] */
+ 0x00, /* number of code length=1 */
+ 0x01,
+ 0x05,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00, /* number of code length=16 */
- /* Entry index for code with
- minimum code length (=2 in this case) */
- 0x00,
- 0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06,
- 0x07,
- 0x08,
- 0x09,
- 0x0A,
- 0x0B
- },
- { /* jpeg_huffman_dc[1][] */
- 0x00, /* number of code length=1 */
- 0x03,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x01,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00, /* number of code length=16 */
+ /* Entry index for code with
+ minimum code length (=2 in this case) */
+ 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0A,
+ 0x0B
+ },
+ { /* jpeg_huffman_dc[1][] */
+ 0x00, /* number of code length=1 */
+ 0x03,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x01,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00, /* number of code length=16 */
- /* Entry index for code with
- minimum code length (=2 in this case) */
- 0x00, 0x01, 0x02,
- 0x03,
- 0x04,
- 0x05,
- 0x06,
- 0x07,
- 0x08,
- 0x09,
- 0x0A,
- 0x0B
- }
+ /* Entry index for code with
+ minimum code length (=2 in this case) */
+ 0x00, 0x01, 0x02,
+ 0x03,
+ 0x04,
+ 0x05,
+ 0x06,
+ 0x07,
+ 0x08,
+ 0x09,
+ 0x0A,
+ 0x0B
+ }
}; /* jpeg_huffman_dc */
static const u8 jpeg_huffman_ac[2][16 + 162] = {
- { /* jpeg_huffman_ac[0][] */
- 0x00, /* number of code length=1 */
- 0x02,
- 0x01,
- 0x03,
- 0x03,
- 0x02,
- 0x04,
- 0x03,
- 0x05,
- 0x05,
- 0x04,
- 0x04,
- 0x00,
- 0x00,
- 0x01,
- 0x7D, /* number of code length=16 */
+ { /* jpeg_huffman_ac[0][] */
+ 0x00, /* number of code length=1 */
+ 0x02,
+ 0x01,
+ 0x03,
+ 0x03,
+ 0x02,
+ 0x04,
+ 0x03,
+ 0x05,
+ 0x05,
+ 0x04,
+ 0x04,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x7D, /* number of code length=16 */
- /* Entry index for code with
- minimum code length (=2 in this case) */
- 0x01, 0x02,
- 0x03,
- 0x00, 0x04, 0x11,
- 0x05, 0x12, 0x21,
- 0x31, 0x41,
- 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71,
- 0x14, 0x32, 0x81, 0x91, 0xA1,
- 0x08, 0x23, 0x42, 0xB1, 0xC1,
- 0x15, 0x52, 0xD1, 0xF0,
- 0x24, 0x33, 0x62, 0x72,
- 0x82,
- 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
- 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29,
- 0x2A, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
- 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
- 0x53, 0x54, 0x55, 0x56,
- 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
- 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
- 0x92, 0x93, 0x94, 0x95,
- 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2,
- 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
- 0xA9, 0xAA, 0xB2, 0xB3,
- 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
- 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
- 0xC7, 0xC8, 0xC9, 0xCA,
- 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
- 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3,
- 0xE4, 0xE5, 0xE6, 0xE7,
- 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
- 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
- 0xFA
- },
- { /* jpeg_huffman_ac[1][] */
- 0x00, /* number of code length=1 */
- 0x02,
- 0x01,
- 0x02,
- 0x04,
- 0x04,
- 0x03,
- 0x04,
- 0x07,
- 0x05,
- 0x04,
- 0x04,
- 0x00,
- 0x01,
- 0x02,
- 0x77, /* number of code length=16 */
+ /* Entry index for code with
+ minimum code length (=2 in this case) */
+ 0x01, 0x02,
+ 0x03,
+ 0x00, 0x04, 0x11,
+ 0x05, 0x12, 0x21,
+ 0x31, 0x41,
+ 0x06, 0x13, 0x51, 0x61,
+ 0x07, 0x22, 0x71,
+ 0x14, 0x32, 0x81, 0x91, 0xA1,
+ 0x08, 0x23, 0x42, 0xB1, 0xC1,
+ 0x15, 0x52, 0xD1, 0xF0,
+ 0x24, 0x33, 0x62, 0x72,
+ 0x82,
+ 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
+ 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x2A, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
+ 0x53, 0x54, 0x55, 0x56,
+ 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
+ 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+ 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
+ 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2,
+ 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
+ 0xA9, 0xAA, 0xB2, 0xB3,
+ 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
+ 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
+ 0xC7, 0xC8, 0xC9, 0xCA,
+ 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3,
+ 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
+ 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
+ 0xFA
+ },
+ { /* jpeg_huffman_ac[1][] */
+ 0x00, /* number of code length=1 */
+ 0x02,
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x04,
+ 0x03,
+ 0x04,
+ 0x07,
+ 0x05,
+ 0x04,
+ 0x04,
+ 0x00,
+ 0x01,
+ 0x02,
+ 0x77, /* number of code length=16 */
- /* Entry index for code with
- minimum code length (=2 in this case) */
- 0x00, 0x01,
- 0x02,
- 0x03, 0x11,
- 0x04, 0x05, 0x21, 0x31,
- 0x06, 0x12, 0x41, 0x51,
- 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81,
- 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
- 0x09, 0x23, 0x33, 0x52, 0xF0,
- 0x15, 0x62, 0x72, 0xD1,
- 0x0A, 0x16, 0x24, 0x34,
+ /* Entry index for code with
+ minimum code length (=2 in this case) */
+ 0x00, 0x01,
+ 0x02,
+ 0x03, 0x11,
+ 0x04, 0x05, 0x21, 0x31,
+ 0x06, 0x12, 0x41, 0x51,
+ 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81,
+ 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
+ 0x09, 0x23, 0x33, 0x52, 0xF0,
+ 0x15, 0x62, 0x72, 0xD1,
+ 0x0A, 0x16, 0x24, 0x34,
- 0xE1,
- 0x25, 0xF1,
- 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
- 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3A, 0x43,
- 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5A, 0x63,
- 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7A, 0x82,
- 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95,
- 0x96, 0x97, 0x98, 0x99,
- 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3,
- 0xB4, 0xB5, 0xB6, 0xB7,
- 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
- 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
- 0xD2, 0xD3, 0xD4, 0xD5,
- 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2,
- 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
- 0xE9, 0xEA, 0xF2, 0xF3,
- 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
- }
-}; /* jpeg_huffman_ac */
-
-static u64 time_cnt = 0;
-
-static int enc_dma_buf_get_phys(struct enc_dma_cfg *cfg, unsigned long *addr);
-static void enc_dma_buf_unmap(struct enc_dma_cfg *cfg);
-
-static void dump_requst(struct jpegenc_request_s *request) {
- jenc_pr(LOG_DEBUG, "jpegenc: dump request start\n");
- jenc_pr(LOG_DEBUG, "src=%u\n", request->src);
- jenc_pr(LOG_DEBUG, "encoder_width=%u\n", request->encoder_width);
- jenc_pr(LOG_DEBUG, "encoder_height=%u\n", request->encoder_height);
- jenc_pr(LOG_DEBUG, "framesize=%u\n", request->framesize);
- jenc_pr(LOG_DEBUG, "jpeg_quality=%u\n", request->jpeg_quality);
- jenc_pr(LOG_DEBUG, "QuantTable_id=%u\n", request->QuantTable_id);
- jenc_pr(LOG_DEBUG, "flush_flag=%u\n", request->flush_flag);
- jenc_pr(LOG_DEBUG, "block_mode=%u\n", request->block_mode);
- jenc_pr(LOG_DEBUG, "type=%d\n", request->type);
- jenc_pr(LOG_DEBUG, "input_fmt=%d\n", request->input_fmt);
- jenc_pr(LOG_DEBUG, "output_fmt=%d\n", request->output_fmt);
-
- jenc_pr(LOG_DEBUG, "y_off=%u\n", request->y_off);
- jenc_pr(LOG_DEBUG, "u_off=%u\n", request->u_off);
- jenc_pr(LOG_DEBUG, "v_off=%u\n", request->v_off);
- jenc_pr(LOG_DEBUG, "y_stride=%u\n", request->y_stride);
- jenc_pr(LOG_DEBUG, "u_stride=%u\n", request->u_stride);
- jenc_pr(LOG_DEBUG, "v_stride=%u\n", request->v_stride);
- jenc_pr(LOG_DEBUG, "h_stride=%u\n", request->h_stride);
- jenc_pr(LOG_DEBUG, "jpegenc: dump request end\n");
-}
-
-static void canvas_config_proxy(u32 index, ulong addr, u32 width, u32 height,
- u32 wrap, u32 blkmode) {
- unsigned long datah_temp, datal_temp;
-
- if (!is_support_vdec_canvas()) {
- canvas_config(index, addr, width, height, wrap, blkmode);
- } else {
-#if 1
- ulong start_addr = addr >> 3;
- u32 cav_width = (((width + 31)>>5)<<2);
- u32 cav_height = height;
- u32 x_wrap_en = 0;
- u32 y_wrap_en = 0;
- u32 blk_mode = 0;//blkmode;
- u32 cav_endian = 0;
-
- datal_temp = (start_addr & 0x1fffffff) |
- ((cav_width & 0x7 ) << 29 );
-
- datah_temp = ((cav_width >> 3) & 0x1ff) |
- ((cav_height & 0x1fff) <<9 ) |
- ((x_wrap_en & 1) << 22 ) |
- ((y_wrap_en & 1) << 23) |
- ((blk_mode & 0x3) << 24) |
- ( cav_endian << 26);
-
-#else
- u32 endian = 0;
- u32 addr_bits_l = ((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) << CAV_WADDR_LBIT);
- u32 width_l = ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CAV_WIDTH_LBIT);
- u32 width_h = ((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) << CAV_WIDTH_HBIT);
- u32 height_h = (height & CANVAS_HEIGHT_MASK) << CAV_HEIGHT_HBIT;
- u32 blkmod_h = (blkmode & CANVAS_BLKMODE_MASK) << CAV_BLKMODE_HBIT;
- u32 switch_bits_ctl = (endian & 0xf) << CAV_ENDIAN_HBIT;
- u32 wrap_h = (0 << 23);
- datal_temp = addr_bits_l | width_l;
- datah_temp = width_h | height_h | wrap_h | blkmod_h | switch_bits_ctl;
-#endif
- /*
- if (core == VDEC_1) {
- WRITE_VREG(MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
- WRITE_VREG(MDEC_CAV_LUT_DATAL, datal_temp);
- WRITE_VREG(MDEC_CAV_LUT_DATAH, datah_temp);
- WRITE_VREG(MDEC_CAV_LUT_ADDR, index);
- } else if (core == VDEC_HCODEC) */ {
- WRITE_HREG(HCODEC_MDEC_CAV_CFG0, 0); //[0]canv_mode, by default is non-canv-mode
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_DATAL, datal_temp);
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_DATAH, datah_temp);
- WRITE_HREG(HCODEC_MDEC_CAV_LUT_ADDR, index);
- }
-
- /*
- cav_lut_info_store(index, addr, width, height, wrap, blkmode, 0);
-
- if (vdec_get_debug() & 0x40000000) {
- pr_info("(%s %2d) addr: %lx, width: %d, height: %d, blkm: %d, endian: %d\n",
- __func__, index, addr, width, height, blkmode, 0);
- pr_info("data(h,l): 0x%8lx, 0x%8lx\n", datah_temp, datal_temp);
- }
- */
+ 0xE1,
+ 0x25, 0xF1,
+ 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
+ 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5A, 0x63,
+ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x82,
+ 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+ 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x97, 0x98, 0x99,
+ 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3,
+ 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
+ 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
+ 0xD2, 0xD3, 0xD4, 0xD5,
+ 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2,
+ 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
+ 0xE9, 0xEA, 0xF2, 0xF3,
+ 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
}
-}
-
-static u64 jpegenc_time_count_start(void)
-{
- //struct timeval tv;
-
- //do_gettimeofday(&tv);
- //efi_gettimeofday(&tv);
- //return div64_u64(timeval_to_ns(&tv), 1000);
- return 0;
-}
-
-static void jpegenc_time_count_end(u64 *time)
-{
- jenc_pr(LOG_INFO, "the encoder takes time %lld us.\n",
- jpegenc_time_count_start() - *time);
- *time = 0;
-}
-
-static int is_oversize(int w, int h, int max)
-{
- if (w < 0 || h < 0)
- return true;
-
- if (h != 0 && (w > max / h))
- return true;
-
- return false;
-}
-
-struct jpeg_enc_clks {
- struct clk *dos_clk;
- struct clk *dos_apb_clk;
- struct clk *jpeg_enc_clk;
-
-};
-
-static struct jpeg_enc_clks g_jpeg_enc_clks;
-
-static void jpeg_enc_clk_put(struct device *dev, struct jpeg_enc_clks *clks)
-{
- if (!(clks->jpeg_enc_clk == NULL || IS_ERR(clks->jpeg_enc_clk)))
- devm_clk_put(dev, clks->jpeg_enc_clk);
-
- if (!(clks->dos_apb_clk == NULL || IS_ERR(clks->dos_apb_clk)))
- devm_clk_put(dev, clks->dos_apb_clk);
-
- if (!(clks->dos_clk == NULL || IS_ERR(clks->dos_clk)))
- devm_clk_put(dev, clks->dos_clk);
-}
-
-static int jpeg_enc_clk_get(struct device *dev, struct jpeg_enc_clks *clks)
-{
- //int ret = 0;
-
- clks->dos_clk = devm_clk_get(dev, "clk_dos");
- if (IS_ERR(clks->dos_clk)) {
- jenc_pr(LOG_ERROR, "cannot get clk_dos clock\n");
- clks->dos_clk = NULL;
- //ret = -ENOENT;
- //goto err;
- } else
- pr_err("jpeg_enc_clk_get: get clk_dos OK\n");
-
- clks->dos_apb_clk = devm_clk_get(dev, "clk_apb_dos");
- if (IS_ERR(clks->dos_apb_clk)) {
- jenc_pr(LOG_ERROR, "cannot get clk_apb_dos clock\n");
- clks->dos_apb_clk = NULL;
- //ret = -ENOENT;
- //goto err;
- } else
- pr_err("jpeg_enc_clk_get: get clk_apb_dos OK\n");
-
- clks->jpeg_enc_clk = devm_clk_get(dev, "clk_jpeg_enc");
- if (IS_ERR(clks->jpeg_enc_clk)) {
- jenc_pr(LOG_ERROR, "cannot get clk_jpeg_enc clock\n");
- clks->jpeg_enc_clk = NULL;
- //ret = -ENOENT;
- //goto err;
- } else
- pr_err("jpeg_enc_clk_get: get clk_jpeg_enc OK\n");
-
- return 0;
-//err:
-// jpeg_enc_clk_put(dev, clks);
-
-// return ret;
-}
-
-static void jpeg_enc_clk_enable(struct jpeg_enc_clks *clks, u32 frq)
-{
- if (clks->dos_clk != NULL) {
- clk_set_rate(clks->dos_clk, 400 * MHz);
- clk_prepare_enable(clks->dos_clk);
- pr_err("dos clk: %ld\n", clk_get_rate(clks->dos_clk));
- }
-
- if (clks->dos_apb_clk != NULL) {
- clk_set_rate(clks->dos_apb_clk, 400 * MHz);
- clk_prepare_enable(clks->dos_apb_clk);
- pr_err("apb clk: %ld\n", clk_get_rate(clks->dos_apb_clk));
- }
-
- if (clks->jpeg_enc_clk != NULL) {
- clk_set_rate(clks->jpeg_enc_clk, 666666666);
- clk_prepare_enable(clks->jpeg_enc_clk);
- pr_err("jpegenc clk: %ld\n", clk_get_rate(clks->jpeg_enc_clk));
- }
-
- /*
- clk_prepare_enable(clks->dos_clk);
- clk_prepare_enable(clks->dos_apb_clk);
- clk_prepare_enable(clks->jpeg_enc_clk);
- */
- pr_err("dos: %ld, dos_apb: %ld, jpeg clk: %ld\n",
- clk_get_rate(clks->dos_clk),
- clk_get_rate(clks->dos_apb_clk),
- clk_get_rate(clks->jpeg_enc_clk));
-
-}
-
-static void jpeg_enc_clk_disable(struct jpeg_enc_clks *clks)
-{
- pr_err("set jpeg_enc_clk rate to 0\n");
- clk_set_rate(clks->jpeg_enc_clk, 0);
- clk_disable_unprepare(clks->jpeg_enc_clk);
-
- //clk_disable_unprepare(clks->dos_apb_clk);
- //clk_disable_unprepare(clks->dos_clk);
-}
+}; /* jpeg_huffman_ac */
static void dma_flush(u32 buf_start, u32 buf_size);
static s32 zigzag(s32 i)
{
- s32 zigzag_i;
- switch (i) {
- case 0:
- zigzag_i = 0;
- break;
- case 1:
- zigzag_i = 1;
- break;
- case 2:
- zigzag_i = 8;
- break;
- case 3:
- zigzag_i = 16;
- break;
- case 4:
- zigzag_i = 9;
- break;
- case 5:
- zigzag_i = 2;
- break;
- case 6:
- zigzag_i = 3;
- break;
- case 7:
- zigzag_i = 10;
- break;
- case 8:
- zigzag_i = 17;
- break;
- case 9:
- zigzag_i = 24;
- break;
- case 10:
- zigzag_i = 32;
- break;
- case 11:
- zigzag_i = 25;
- break;
- case 12:
- zigzag_i = 18;
- break;
- case 13:
- zigzag_i = 11;
- break;
- case 14:
- zigzag_i = 4;
- break;
- case 15:
- zigzag_i = 5;
- break;
- case 16:
- zigzag_i = 12;
- break;
- case 17:
- zigzag_i = 19;
- break;
- case 18:
- zigzag_i = 26;
- break;
- case 19:
- zigzag_i = 33;
- break;
- case 20:
- zigzag_i = 40;
- break;
- case 21:
- zigzag_i = 48;
- break;
- case 22:
- zigzag_i = 41;
- break;
- case 23:
- zigzag_i = 34;
- break;
- case 24:
- zigzag_i = 27;
- break;
- case 25:
- zigzag_i = 20;
- break;
- case 26:
- zigzag_i = 13;
- break;
- case 27:
- zigzag_i = 6;
- break;
- case 28:
- zigzag_i = 7;
- break;
- case 29:
- zigzag_i = 14;
- break;
- case 30:
- zigzag_i = 21;
- break;
- case 31:
- zigzag_i = 28;
- break;
- case 32:
- zigzag_i = 35;
- break;
- case 33:
- zigzag_i = 42;
- break;
- case 34:
- zigzag_i = 49;
- break;
- case 35:
- zigzag_i = 56;
- break;
- case 36:
- zigzag_i = 57;
- break;
- case 37:
- zigzag_i = 50;
- break;
- case 38:
- zigzag_i = 43;
- break;
- case 39:
- zigzag_i = 36;
- break;
- case 40:
- zigzag_i = 29;
- break;
- case 41:
- zigzag_i = 22;
- break;
- case 42:
- zigzag_i = 15;
- break;
- case 43:
- zigzag_i = 23;
- break;
- case 44:
- zigzag_i = 30;
- break;
- case 45:
- zigzag_i = 37;
- break;
- case 46:
- zigzag_i = 44;
- break;
- case 47:
- zigzag_i = 51;
- break;
- case 48:
- zigzag_i = 58;
- break;
- case 49:
- zigzag_i = 59;
- break;
- case 50:
- zigzag_i = 52;
- break;
- case 51:
- zigzag_i = 45;
- break;
- case 52:
- zigzag_i = 38;
- break;
- case 53:
- zigzag_i = 31;
- break;
- case 54:
- zigzag_i = 39;
- break;
- case 55:
- zigzag_i = 46;
- break;
- case 56:
- zigzag_i = 53;
- break;
- case 57:
- zigzag_i = 60;
- break;
- case 58:
- zigzag_i = 61;
- break;
- case 59:
- zigzag_i = 54;
- break;
- case 60:
- zigzag_i = 47;
- break;
- case 61:
- zigzag_i = 55;
- break;
- case 62:
- zigzag_i = 62;
- break;
- default:
- zigzag_i = 63;
- break;
- }
- return zigzag_i;
+ s32 zigzag_i;
+ switch (i) {
+ case 0:
+ zigzag_i = 0;
+ break;
+ case 1:
+ zigzag_i = 1;
+ break;
+ case 2:
+ zigzag_i = 8;
+ break;
+ case 3:
+ zigzag_i = 16;
+ break;
+ case 4:
+ zigzag_i = 9;
+ break;
+ case 5:
+ zigzag_i = 2;
+ break;
+ case 6:
+ zigzag_i = 3;
+ break;
+ case 7:
+ zigzag_i = 10;
+ break;
+ case 8:
+ zigzag_i = 17;
+ break;
+ case 9:
+ zigzag_i = 24;
+ break;
+ case 10:
+ zigzag_i = 32;
+ break;
+ case 11:
+ zigzag_i = 25;
+ break;
+ case 12:
+ zigzag_i = 18;
+ break;
+ case 13:
+ zigzag_i = 11;
+ break;
+ case 14:
+ zigzag_i = 4;
+ break;
+ case 15:
+ zigzag_i = 5;
+ break;
+ case 16:
+ zigzag_i = 12;
+ break;
+ case 17:
+ zigzag_i = 19;
+ break;
+ case 18:
+ zigzag_i = 26;
+ break;
+ case 19:
+ zigzag_i = 33;
+ break;
+ case 20:
+ zigzag_i = 40;
+ break;
+ case 21:
+ zigzag_i = 48;
+ break;
+ case 22:
+ zigzag_i = 41;
+ break;
+ case 23:
+ zigzag_i = 34;
+ break;
+ case 24:
+ zigzag_i = 27;
+ break;
+ case 25:
+ zigzag_i = 20;
+ break;
+ case 26:
+ zigzag_i = 13;
+ break;
+ case 27:
+ zigzag_i = 6;
+ break;
+ case 28:
+ zigzag_i = 7;
+ break;
+ case 29:
+ zigzag_i = 14;
+ break;
+ case 30:
+ zigzag_i = 21;
+ break;
+ case 31:
+ zigzag_i = 28;
+ break;
+ case 32:
+ zigzag_i = 35;
+ break;
+ case 33:
+ zigzag_i = 42;
+ break;
+ case 34:
+ zigzag_i = 49;
+ break;
+ case 35:
+ zigzag_i = 56;
+ break;
+ case 36:
+ zigzag_i = 57;
+ break;
+ case 37:
+ zigzag_i = 50;
+ break;
+ case 38:
+ zigzag_i = 43;
+ break;
+ case 39:
+ zigzag_i = 36;
+ break;
+ case 40:
+ zigzag_i = 29;
+ break;
+ case 41:
+ zigzag_i = 22;
+ break;
+ case 42:
+ zigzag_i = 15;
+ break;
+ case 43:
+ zigzag_i = 23;
+ break;
+ case 44:
+ zigzag_i = 30;
+ break;
+ case 45:
+ zigzag_i = 37;
+ break;
+ case 46:
+ zigzag_i = 44;
+ break;
+ case 47:
+ zigzag_i = 51;
+ break;
+ case 48:
+ zigzag_i = 58;
+ break;
+ case 49:
+ zigzag_i = 59;
+ break;
+ case 50:
+ zigzag_i = 52;
+ break;
+ case 51:
+ zigzag_i = 45;
+ break;
+ case 52:
+ zigzag_i = 38;
+ break;
+ case 53:
+ zigzag_i = 31;
+ break;
+ case 54:
+ zigzag_i = 39;
+ break;
+ case 55:
+ zigzag_i = 46;
+ break;
+ case 56:
+ zigzag_i = 53;
+ break;
+ case 57:
+ zigzag_i = 60;
+ break;
+ case 58:
+ zigzag_i = 61;
+ break;
+ case 59:
+ zigzag_i = 54;
+ break;
+ case 60:
+ zigzag_i = 47;
+ break;
+ case 61:
+ zigzag_i = 55;
+ break;
+ case 62:
+ zigzag_i = 62;
+ break;
+ default:
+ zigzag_i = 63;
+ break;
+ }
+ return zigzag_i;
}
/* Perform convertion from Q to 1/Q */
u32 reciprocal(u32 q)
{
- u32 q_recip;
+ u32 q_recip;
- /* 65535 * (1/q) */
- switch (q) {
- case 0:
- q_recip = 0;
- break;
- case 1:
- q_recip = 65535;
- break;
- case 2:
- q_recip = 32768;
- break;
- case 3:
- q_recip = 21845;
- break;
- case 4:
- q_recip = 16384;
- break;
- case 5:
- q_recip = 13107;
- break;
- case 6:
- q_recip = 10923;
- break;
- case 7:
- q_recip = 9362;
- break;
- case 8:
- q_recip = 8192;
- break;
- case 9:
- q_recip = 7282;
- break;
- case 10:
- q_recip = 6554;
- break;
- case 11:
- q_recip = 5958;
- break;
- case 12:
- q_recip = 5461;
- break;
- case 13:
- q_recip = 5041;
- break;
- case 14:
- q_recip = 4681;
- break;
- case 15:
- q_recip = 4369;
- break;
- case 16:
- q_recip = 4096;
- break;
- case 17:
- q_recip = 3855;
- break;
- case 18:
- q_recip = 3641;
- break;
- case 19:
- q_recip = 3449;
- break;
- case 20:
- q_recip = 3277;
- break;
- case 21:
- q_recip = 3121;
- break;
- case 22:
- q_recip = 2979;
- break;
- case 23:
- q_recip = 2849;
- break;
- case 24:
- q_recip = 2731;
- break;
- case 25:
- q_recip = 2621;
- break;
- case 26:
- q_recip = 2521;
- break;
- case 27:
- q_recip = 2427;
- break;
- case 28:
- q_recip = 2341;
- break;
- case 29:
- q_recip = 2260;
- break;
- case 30:
- q_recip = 2185;
- break;
- case 31:
- q_recip = 2114;
- break;
- case 32:
- q_recip = 2048;
- break;
- case 33:
- q_recip = 1986;
- break;
- case 34:
- q_recip = 1928;
- break;
- case 35:
- q_recip = 1872;
- break;
- case 36:
- q_recip = 1820;
- break;
- case 37:
- q_recip = 1771;
- break;
- case 38:
- q_recip = 1725;
- break;
- case 39:
- q_recip = 1680;
- break;
- case 40:
- q_recip = 1638;
- break;
- case 41:
- q_recip = 1598;
- break;
- case 42:
- q_recip = 1560;
- break;
- case 43:
- q_recip = 1524;
- break;
- case 44:
- q_recip = 1489;
- break;
- case 45:
- q_recip = 1456;
- break;
- case 46:
- q_recip = 1425;
- break;
- case 47:
- q_recip = 1394;
- break;
- case 48:
- q_recip = 1365;
- break;
- case 49:
- q_recip = 1337;
- break;
- case 50:
- q_recip = 1311;
- break;
- case 51:
- q_recip = 1285;
- break;
- case 52:
- q_recip = 1260;
- break;
- case 53:
- q_recip = 1237;
- break;
- case 54:
- q_recip = 1214;
- break;
- case 55:
- q_recip = 1192;
- break;
- case 56:
- q_recip = 1170;
- break;
- case 57:
- q_recip = 1150;
- break;
- case 58:
- q_recip = 1130;
- break;
- case 59:
- q_recip = 1111;
- break;
- case 60:
- q_recip = 1092;
- break;
- case 61:
- q_recip = 1074;
- break;
- case 62:
- q_recip = 1057;
- break;
- case 63:
- q_recip = 1040;
- break;
- case 64:
- q_recip = 1024;
- break;
- case 65:
- q_recip = 1008;
- break;
- case 66:
- q_recip = 993;
- break;
- case 67:
- q_recip = 978;
- break;
- case 68:
- q_recip = 964;
- break;
- case 69:
- q_recip = 950;
- break;
- case 70:
- q_recip = 936;
- break;
- case 71:
- q_recip = 923;
- break;
- case 72:
- q_recip = 910;
- break;
- case 73:
- q_recip = 898;
- break;
- case 74:
- q_recip = 886;
- break;
- case 75:
- q_recip = 874;
- break;
- case 76:
- q_recip = 862;
- break;
- case 77:
- q_recip = 851;
- break;
- case 78:
- q_recip = 840;
- break;
- case 79:
- q_recip = 830;
- break;
- case 80:
- q_recip = 819;
- break;
- case 81:
- q_recip = 809;
- break;
- case 82:
- q_recip = 799;
- break;
- case 83:
- q_recip = 790;
- break;
- case 84:
- q_recip = 780;
- break;
- case 85:
- q_recip = 771;
- break;
- case 86:
- q_recip = 762;
- break;
- case 87:
- q_recip = 753;
- break;
- case 88:
- q_recip = 745;
- break;
- case 89:
- q_recip = 736;
- break;
- case 90:
- q_recip = 728;
- break;
- case 91:
- q_recip = 720;
- break;
- case 92:
- q_recip = 712;
- break;
- case 93:
- q_recip = 705;
- break;
- case 94:
- q_recip = 697;
- break;
- case 95:
- q_recip = 690;
- break;
- case 96:
- q_recip = 683;
- break;
- case 97:
- q_recip = 676;
- break;
- case 98:
- q_recip = 669;
- break;
- case 99:
- q_recip = 662;
- break;
- case 100:
- q_recip = 655;
- break;
- case 101:
- q_recip = 649;
- break;
- case 102:
- q_recip = 643;
- break;
- case 103:
- q_recip = 636;
- break;
- case 104:
- q_recip = 630;
- break;
- case 105:
- q_recip = 624;
- break;
- case 106:
- q_recip = 618;
- break;
- case 107:
- q_recip = 612;
- break;
- case 108:
- q_recip = 607;
- break;
- case 109:
- q_recip = 601;
- break;
- case 110:
- q_recip = 596;
- break;
- case 111:
- q_recip = 590;
- break;
- case 112:
- q_recip = 585;
- break;
- case 113:
- q_recip = 580;
- break;
- case 114:
- q_recip = 575;
- break;
- case 115:
- q_recip = 570;
- break;
- case 116:
- q_recip = 565;
- break;
- case 117:
- q_recip = 560;
- break;
- case 118:
- q_recip = 555;
- break;
- case 119:
- q_recip = 551;
- break;
- case 120:
- q_recip = 546;
- break;
- case 121:
- q_recip = 542;
- break;
- case 122:
- q_recip = 537;
- break;
- case 123:
- q_recip = 533;
- break;
- case 124:
- q_recip = 529;
- break;
- case 125:
- q_recip = 524;
- break;
- case 126:
- q_recip = 520;
- break;
- case 127:
- q_recip = 516;
- break;
- case 128:
- q_recip = 512;
- break;
- case 129:
- q_recip = 508;
- break;
- case 130:
- q_recip = 504;
- break;
- case 131:
- q_recip = 500;
- break;
- case 132:
- q_recip = 496;
- break;
- case 133:
- q_recip = 493;
- break;
- case 134:
- q_recip = 489;
- break;
- case 135:
- q_recip = 485;
- break;
- case 136:
- q_recip = 482;
- break;
- case 137:
- q_recip = 478;
- break;
- case 138:
- q_recip = 475;
- break;
- case 139:
- q_recip = 471;
- break;
- case 140:
- q_recip = 468;
- break;
- case 141:
- q_recip = 465;
- break;
- case 142:
- q_recip = 462;
- break;
- case 143:
- q_recip = 458;
- break;
- case 144:
- q_recip = 455;
- break;
- case 145:
- q_recip = 452;
- break;
- case 146:
- q_recip = 449;
- break;
- case 147:
- q_recip = 446;
- break;
- case 148:
- q_recip = 443;
- break;
- case 149:
- q_recip = 440;
- break;
- case 150:
- q_recip = 437;
- break;
- case 151:
- q_recip = 434;
- break;
- case 152:
- q_recip = 431;
- break;
- case 153:
- q_recip = 428;
- break;
- case 154:
- q_recip = 426;
- break;
- case 155:
- q_recip = 423;
- break;
- case 156:
- q_recip = 420;
- break;
- case 157:
- q_recip = 417;
- break;
- case 158:
- q_recip = 415;
- break;
- case 159:
- q_recip = 412;
- break;
- case 160:
- q_recip = 410;
- break;
- case 161:
- q_recip = 407;
- break;
- case 162:
- q_recip = 405;
- break;
- case 163:
- q_recip = 402;
- break;
- case 164:
- q_recip = 400;
- break;
- case 165:
- q_recip = 397;
- break;
- case 166:
- q_recip = 395;
- break;
- case 167:
- q_recip = 392;
- break;
- case 168:
- q_recip = 390;
- break;
- case 169:
- q_recip = 388;
- break;
- case 170:
- q_recip = 386;
- break;
- case 171:
- q_recip = 383;
- break;
- case 172:
- q_recip = 381;
- break;
- case 173:
- q_recip = 379;
- break;
- case 174:
- q_recip = 377;
- break;
- case 175:
- q_recip = 374;
- break;
- case 176:
- q_recip = 372;
- break;
- case 177:
- q_recip = 370;
- break;
- case 178:
- q_recip = 368;
- break;
- case 179:
- q_recip = 366;
- break;
- case 180:
- q_recip = 364;
- break;
- case 181:
- q_recip = 362;
- break;
- case 182:
- q_recip = 360;
- break;
- case 183:
- q_recip = 358;
- break;
- case 184:
- q_recip = 356;
- break;
- case 185:
- q_recip = 354;
- break;
- case 186:
- q_recip = 352;
- break;
- case 187:
- q_recip = 350;
- break;
- case 188:
- q_recip = 349;
- break;
- case 189:
- q_recip = 347;
- break;
- case 190:
- q_recip = 345;
- break;
- case 191:
- q_recip = 343;
- break;
- case 192:
- q_recip = 341;
- break;
- case 193:
- q_recip = 340;
- break;
- case 194:
- q_recip = 338;
- break;
- case 195:
- q_recip = 336;
- break;
- case 196:
- q_recip = 334;
- break;
- case 197:
- q_recip = 333;
- break;
- case 198:
- q_recip = 331;
- break;
- case 199:
- q_recip = 329;
- break;
- case 200:
- q_recip = 328;
- break;
- case 201:
- q_recip = 326;
- break;
- case 202:
- q_recip = 324;
- break;
- case 203:
- q_recip = 323;
- break;
- case 204:
- q_recip = 321;
- break;
- case 205:
- q_recip = 320;
- break;
- case 206:
- q_recip = 318;
- break;
- case 207:
- q_recip = 317;
- break;
- case 208:
- q_recip = 315;
- break;
- case 209:
- q_recip = 314;
- break;
- case 210:
- q_recip = 312;
- break;
- case 211:
- q_recip = 311;
- break;
- case 212:
- q_recip = 309;
- break;
- case 213:
- q_recip = 308;
- break;
- case 214:
- q_recip = 306;
- break;
- case 215:
- q_recip = 305;
- break;
- case 216:
- q_recip = 303;
- break;
- case 217:
- q_recip = 302;
- break;
- case 218:
- q_recip = 301;
- break;
- case 219:
- q_recip = 299;
- break;
- case 220:
- q_recip = 298;
- break;
- case 221:
- q_recip = 297;
- break;
- case 222:
- q_recip = 295;
- break;
- case 223:
- q_recip = 294;
- break;
- case 224:
- q_recip = 293;
- break;
- case 225:
- q_recip = 291;
- break;
- case 226:
- q_recip = 290;
- break;
- case 227:
- q_recip = 289;
- break;
- case 228:
- q_recip = 287;
- break;
- case 229:
- q_recip = 286;
- break;
- case 230:
- q_recip = 285;
- break;
- case 231:
- q_recip = 284;
- break;
- case 232:
- q_recip = 282;
- break;
- case 233:
- q_recip = 281;
- break;
- case 234:
- q_recip = 280;
- break;
- case 235:
- q_recip = 279;
- break;
- case 236:
- q_recip = 278;
- break;
- case 237:
- q_recip = 277;
- break;
- case 238:
- q_recip = 275;
- break;
- case 239:
- q_recip = 274;
- break;
- case 240:
- q_recip = 273;
- break;
- case 241:
- q_recip = 272;
- break;
- case 242:
- q_recip = 271;
- break;
- case 243:
- q_recip = 270;
- break;
- case 244:
- q_recip = 269;
- break;
- case 245:
- q_recip = 267;
- break;
- case 246:
- q_recip = 266;
- break;
- case 247:
- q_recip = 265;
- break;
- case 248:
- q_recip = 264;
- break;
- case 249:
- q_recip = 263;
- break;
- case 250:
- q_recip = 262;
- break;
- case 251:
- q_recip = 261;
- break;
- case 252:
- q_recip = 260;
- break;
- case 253:
- q_recip = 259;
- break;
- case 254:
- q_recip = 258;
- break;
- default:
- q_recip = 257;
- break;
- }
- return q_recip;
+ /* 65535 * (1/q) */
+ switch (q) {
+ case 0:
+ q_recip = 0;
+ break;
+ case 1:
+ q_recip = 65535;
+ break;
+ case 2:
+ q_recip = 32768;
+ break;
+ case 3:
+ q_recip = 21845;
+ break;
+ case 4:
+ q_recip = 16384;
+ break;
+ case 5:
+ q_recip = 13107;
+ break;
+ case 6:
+ q_recip = 10923;
+ break;
+ case 7:
+ q_recip = 9362;
+ break;
+ case 8:
+ q_recip = 8192;
+ break;
+ case 9:
+ q_recip = 7282;
+ break;
+ case 10:
+ q_recip = 6554;
+ break;
+ case 11:
+ q_recip = 5958;
+ break;
+ case 12:
+ q_recip = 5461;
+ break;
+ case 13:
+ q_recip = 5041;
+ break;
+ case 14:
+ q_recip = 4681;
+ break;
+ case 15:
+ q_recip = 4369;
+ break;
+ case 16:
+ q_recip = 4096;
+ break;
+ case 17:
+ q_recip = 3855;
+ break;
+ case 18:
+ q_recip = 3641;
+ break;
+ case 19:
+ q_recip = 3449;
+ break;
+ case 20:
+ q_recip = 3277;
+ break;
+ case 21:
+ q_recip = 3121;
+ break;
+ case 22:
+ q_recip = 2979;
+ break;
+ case 23:
+ q_recip = 2849;
+ break;
+ case 24:
+ q_recip = 2731;
+ break;
+ case 25:
+ q_recip = 2621;
+ break;
+ case 26:
+ q_recip = 2521;
+ break;
+ case 27:
+ q_recip = 2427;
+ break;
+ case 28:
+ q_recip = 2341;
+ break;
+ case 29:
+ q_recip = 2260;
+ break;
+ case 30:
+ q_recip = 2185;
+ break;
+ case 31:
+ q_recip = 2114;
+ break;
+ case 32:
+ q_recip = 2048;
+ break;
+ case 33:
+ q_recip = 1986;
+ break;
+ case 34:
+ q_recip = 1928;
+ break;
+ case 35:
+ q_recip = 1872;
+ break;
+ case 36:
+ q_recip = 1820;
+ break;
+ case 37:
+ q_recip = 1771;
+ break;
+ case 38:
+ q_recip = 1725;
+ break;
+ case 39:
+ q_recip = 1680;
+ break;
+ case 40:
+ q_recip = 1638;
+ break;
+ case 41:
+ q_recip = 1598;
+ break;
+ case 42:
+ q_recip = 1560;
+ break;
+ case 43:
+ q_recip = 1524;
+ break;
+ case 44:
+ q_recip = 1489;
+ break;
+ case 45:
+ q_recip = 1456;
+ break;
+ case 46:
+ q_recip = 1425;
+ break;
+ case 47:
+ q_recip = 1394;
+ break;
+ case 48:
+ q_recip = 1365;
+ break;
+ case 49:
+ q_recip = 1337;
+ break;
+ case 50:
+ q_recip = 1311;
+ break;
+ case 51:
+ q_recip = 1285;
+ break;
+ case 52:
+ q_recip = 1260;
+ break;
+ case 53:
+ q_recip = 1237;
+ break;
+ case 54:
+ q_recip = 1214;
+ break;
+ case 55:
+ q_recip = 1192;
+ break;
+ case 56:
+ q_recip = 1170;
+ break;
+ case 57:
+ q_recip = 1150;
+ break;
+ case 58:
+ q_recip = 1130;
+ break;
+ case 59:
+ q_recip = 1111;
+ break;
+ case 60:
+ q_recip = 1092;
+ break;
+ case 61:
+ q_recip = 1074;
+ break;
+ case 62:
+ q_recip = 1057;
+ break;
+ case 63:
+ q_recip = 1040;
+ break;
+ case 64:
+ q_recip = 1024;
+ break;
+ case 65:
+ q_recip = 1008;
+ break;
+ case 66:
+ q_recip = 993;
+ break;
+ case 67:
+ q_recip = 978;
+ break;
+ case 68:
+ q_recip = 964;
+ break;
+ case 69:
+ q_recip = 950;
+ break;
+ case 70:
+ q_recip = 936;
+ break;
+ case 71:
+ q_recip = 923;
+ break;
+ case 72:
+ q_recip = 910;
+ break;
+ case 73:
+ q_recip = 898;
+ break;
+ case 74:
+ q_recip = 886;
+ break;
+ case 75:
+ q_recip = 874;
+ break;
+ case 76:
+ q_recip = 862;
+ break;
+ case 77:
+ q_recip = 851;
+ break;
+ case 78:
+ q_recip = 840;
+ break;
+ case 79:
+ q_recip = 830;
+ break;
+ case 80:
+ q_recip = 819;
+ break;
+ case 81:
+ q_recip = 809;
+ break;
+ case 82:
+ q_recip = 799;
+ break;
+ case 83:
+ q_recip = 790;
+ break;
+ case 84:
+ q_recip = 780;
+ break;
+ case 85:
+ q_recip = 771;
+ break;
+ case 86:
+ q_recip = 762;
+ break;
+ case 87:
+ q_recip = 753;
+ break;
+ case 88:
+ q_recip = 745;
+ break;
+ case 89:
+ q_recip = 736;
+ break;
+ case 90:
+ q_recip = 728;
+ break;
+ case 91:
+ q_recip = 720;
+ break;
+ case 92:
+ q_recip = 712;
+ break;
+ case 93:
+ q_recip = 705;
+ break;
+ case 94:
+ q_recip = 697;
+ break;
+ case 95:
+ q_recip = 690;
+ break;
+ case 96:
+ q_recip = 683;
+ break;
+ case 97:
+ q_recip = 676;
+ break;
+ case 98:
+ q_recip = 669;
+ break;
+ case 99:
+ q_recip = 662;
+ break;
+ case 100:
+ q_recip = 655;
+ break;
+ case 101:
+ q_recip = 649;
+ break;
+ case 102:
+ q_recip = 643;
+ break;
+ case 103:
+ q_recip = 636;
+ break;
+ case 104:
+ q_recip = 630;
+ break;
+ case 105:
+ q_recip = 624;
+ break;
+ case 106:
+ q_recip = 618;
+ break;
+ case 107:
+ q_recip = 612;
+ break;
+ case 108:
+ q_recip = 607;
+ break;
+ case 109:
+ q_recip = 601;
+ break;
+ case 110:
+ q_recip = 596;
+ break;
+ case 111:
+ q_recip = 590;
+ break;
+ case 112:
+ q_recip = 585;
+ break;
+ case 113:
+ q_recip = 580;
+ break;
+ case 114:
+ q_recip = 575;
+ break;
+ case 115:
+ q_recip = 570;
+ break;
+ case 116:
+ q_recip = 565;
+ break;
+ case 117:
+ q_recip = 560;
+ break;
+ case 118:
+ q_recip = 555;
+ break;
+ case 119:
+ q_recip = 551;
+ break;
+ case 120:
+ q_recip = 546;
+ break;
+ case 121:
+ q_recip = 542;
+ break;
+ case 122:
+ q_recip = 537;
+ break;
+ case 123:
+ q_recip = 533;
+ break;
+ case 124:
+ q_recip = 529;
+ break;
+ case 125:
+ q_recip = 524;
+ break;
+ case 126:
+ q_recip = 520;
+ break;
+ case 127:
+ q_recip = 516;
+ break;
+ case 128:
+ q_recip = 512;
+ break;
+ case 129:
+ q_recip = 508;
+ break;
+ case 130:
+ q_recip = 504;
+ break;
+ case 131:
+ q_recip = 500;
+ break;
+ case 132:
+ q_recip = 496;
+ break;
+ case 133:
+ q_recip = 493;
+ break;
+ case 134:
+ q_recip = 489;
+ break;
+ case 135:
+ q_recip = 485;
+ break;
+ case 136:
+ q_recip = 482;
+ break;
+ case 137:
+ q_recip = 478;
+ break;
+ case 138:
+ q_recip = 475;
+ break;
+ case 139:
+ q_recip = 471;
+ break;
+ case 140:
+ q_recip = 468;
+ break;
+ case 141:
+ q_recip = 465;
+ break;
+ case 142:
+ q_recip = 462;
+ break;
+ case 143:
+ q_recip = 458;
+ break;
+ case 144:
+ q_recip = 455;
+ break;
+ case 145:
+ q_recip = 452;
+ break;
+ case 146:
+ q_recip = 449;
+ break;
+ case 147:
+ q_recip = 446;
+ break;
+ case 148:
+ q_recip = 443;
+ break;
+ case 149:
+ q_recip = 440;
+ break;
+ case 150:
+ q_recip = 437;
+ break;
+ case 151:
+ q_recip = 434;
+ break;
+ case 152:
+ q_recip = 431;
+ break;
+ case 153:
+ q_recip = 428;
+ break;
+ case 154:
+ q_recip = 426;
+ break;
+ case 155:
+ q_recip = 423;
+ break;
+ case 156:
+ q_recip = 420;
+ break;
+ case 157:
+ q_recip = 417;
+ break;
+ case 158:
+ q_recip = 415;
+ break;
+ case 159:
+ q_recip = 412;
+ break;
+ case 160:
+ q_recip = 410;
+ break;
+ case 161:
+ q_recip = 407;
+ break;
+ case 162:
+ q_recip = 405;
+ break;
+ case 163:
+ q_recip = 402;
+ break;
+ case 164:
+ q_recip = 400;
+ break;
+ case 165:
+ q_recip = 397;
+ break;
+ case 166:
+ q_recip = 395;
+ break;
+ case 167:
+ q_recip = 392;
+ break;
+ case 168:
+ q_recip = 390;
+ break;
+ case 169:
+ q_recip = 388;
+ break;
+ case 170:
+ q_recip = 386;
+ break;
+ case 171:
+ q_recip = 383;
+ break;
+ case 172:
+ q_recip = 381;
+ break;
+ case 173:
+ q_recip = 379;
+ break;
+ case 174:
+ q_recip = 377;
+ break;
+ case 175:
+ q_recip = 374;
+ break;
+ case 176:
+ q_recip = 372;
+ break;
+ case 177:
+ q_recip = 370;
+ break;
+ case 178:
+ q_recip = 368;
+ break;
+ case 179:
+ q_recip = 366;
+ break;
+ case 180:
+ q_recip = 364;
+ break;
+ case 181:
+ q_recip = 362;
+ break;
+ case 182:
+ q_recip = 360;
+ break;
+ case 183:
+ q_recip = 358;
+ break;
+ case 184:
+ q_recip = 356;
+ break;
+ case 185:
+ q_recip = 354;
+ break;
+ case 186:
+ q_recip = 352;
+ break;
+ case 187:
+ q_recip = 350;
+ break;
+ case 188:
+ q_recip = 349;
+ break;
+ case 189:
+ q_recip = 347;
+ break;
+ case 190:
+ q_recip = 345;
+ break;
+ case 191:
+ q_recip = 343;
+ break;
+ case 192:
+ q_recip = 341;
+ break;
+ case 193:
+ q_recip = 340;
+ break;
+ case 194:
+ q_recip = 338;
+ break;
+ case 195:
+ q_recip = 336;
+ break;
+ case 196:
+ q_recip = 334;
+ break;
+ case 197:
+ q_recip = 333;
+ break;
+ case 198:
+ q_recip = 331;
+ break;
+ case 199:
+ q_recip = 329;
+ break;
+ case 200:
+ q_recip = 328;
+ break;
+ case 201:
+ q_recip = 326;
+ break;
+ case 202:
+ q_recip = 324;
+ break;
+ case 203:
+ q_recip = 323;
+ break;
+ case 204:
+ q_recip = 321;
+ break;
+ case 205:
+ q_recip = 320;
+ break;
+ case 206:
+ q_recip = 318;
+ break;
+ case 207:
+ q_recip = 317;
+ break;
+ case 208:
+ q_recip = 315;
+ break;
+ case 209:
+ q_recip = 314;
+ break;
+ case 210:
+ q_recip = 312;
+ break;
+ case 211:
+ q_recip = 311;
+ break;
+ case 212:
+ q_recip = 309;
+ break;
+ case 213:
+ q_recip = 308;
+ break;
+ case 214:
+ q_recip = 306;
+ break;
+ case 215:
+ q_recip = 305;
+ break;
+ case 216:
+ q_recip = 303;
+ break;
+ case 217:
+ q_recip = 302;
+ break;
+ case 218:
+ q_recip = 301;
+ break;
+ case 219:
+ q_recip = 299;
+ break;
+ case 220:
+ q_recip = 298;
+ break;
+ case 221:
+ q_recip = 297;
+ break;
+ case 222:
+ q_recip = 295;
+ break;
+ case 223:
+ q_recip = 294;
+ break;
+ case 224:
+ q_recip = 293;
+ break;
+ case 225:
+ q_recip = 291;
+ break;
+ case 226:
+ q_recip = 290;
+ break;
+ case 227:
+ q_recip = 289;
+ break;
+ case 228:
+ q_recip = 287;
+ break;
+ case 229:
+ q_recip = 286;
+ break;
+ case 230:
+ q_recip = 285;
+ break;
+ case 231:
+ q_recip = 284;
+ break;
+ case 232:
+ q_recip = 282;
+ break;
+ case 233:
+ q_recip = 281;
+ break;
+ case 234:
+ q_recip = 280;
+ break;
+ case 235:
+ q_recip = 279;
+ break;
+ case 236:
+ q_recip = 278;
+ break;
+ case 237:
+ q_recip = 277;
+ break;
+ case 238:
+ q_recip = 275;
+ break;
+ case 239:
+ q_recip = 274;
+ break;
+ case 240:
+ q_recip = 273;
+ break;
+ case 241:
+ q_recip = 272;
+ break;
+ case 242:
+ q_recip = 271;
+ break;
+ case 243:
+ q_recip = 270;
+ break;
+ case 244:
+ q_recip = 269;
+ break;
+ case 245:
+ q_recip = 267;
+ break;
+ case 246:
+ q_recip = 266;
+ break;
+ case 247:
+ q_recip = 265;
+ break;
+ case 248:
+ q_recip = 264;
+ break;
+ case 249:
+ q_recip = 263;
+ break;
+ case 250:
+ q_recip = 262;
+ break;
+ case 251:
+ q_recip = 261;
+ break;
+ case 252:
+ q_recip = 260;
+ break;
+ case 253:
+ q_recip = 259;
+ break;
+ case 254:
+ q_recip = 258;
+ break;
+ default:
+ q_recip = 257;
+ break;
+ }
+ return q_recip;
} /* reciprocal */
static void push_word(u8 *base, s32 *offset, u32 word)
{
- u8 *ptr;
- s32 i;
- s32 bytes = (word >> 24) & 0xff;
- for (i = bytes - 1; i >= 0; i--) {
- ptr = base + *offset;
- (*offset)++;
- if (i == 0)
- *ptr = word & 0xff;
- else if (i == 1)
- *ptr = (word >> 8) & 0xff;
- else if (i == 2)
- *ptr = (word >> 16) & 0xff;
- }
+ u8 *ptr;
+ s32 i;
+ s32 bytes = (word >> 24) & 0xff;
+ for (i = bytes - 1; i >= 0; i--) {
+ ptr = base + *offset;
+ (*offset)++;
+ if (i == 0)
+ *ptr = word & 0xff;
+ else if (i == 1)
+ *ptr = (word >> 8) & 0xff;
+ else if (i == 2)
+ *ptr = (word >> 16) & 0xff;
+ }
}
static s32 jpeg_quality_scaling(s32 quality)
{
- if (quality <= 0)
- quality = 1;
- if (quality > 100)
- quality = 100;
+ if (quality <= 0)
+ quality = 1;
+ if (quality > 100)
+ quality = 100;
- if (quality < 50)
- quality = 5000 / quality;
- else
- quality = 200 - quality * 2;
- return quality;
+ if (quality < 50)
+ quality = 5000 / quality;
+ else
+ quality = 200 - quality * 2;
+ return quality;
}
static void _convert_quant_table(u16 *qtable, u16 *basic_table,
- s32 scale_factor, bool force_baseline)
+ s32 scale_factor, bool force_baseline)
{
- s32 i = 0;
- s32 temp;
- for (i = 0; i < DCTSIZE2; i++) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if (use_quality) {
- //jenc_pr(LOG_ALL, "c1 using quality factor %d\n", scale_factor);
- temp = ((s32)basic_table[i] * scale_factor + 50) / 100;
- } else {
- //jenc_pr(LOG_INFO, "c1 ignore quality factor\n");
- temp = (s32)basic_table[i];
- }
- }else
- temp = ((s32)basic_table[i] * scale_factor + 50) / 100;
- /* limit the values to the valid range */
- if (temp <= 0)
- temp = 1;
- /* max quantizer needed for 12 bits */
- if (temp > 32767)
- temp = 32767;
- /* limit to baseline range if requested */
- if (force_baseline && temp > 255)
- temp = 255;
- qtable[i] = (u16)temp;
- }
+ s32 i = 0;
+ s32 temp;
+ for (i = 0; i < DCTSIZE2; i++) {
+ temp = ((s32)basic_table[i] * scale_factor + 50) / 100;
+ /* limit the values to the valid range */
+ if (temp <= 0)
+ temp = 1;
+ /* max quantizer needed for 12 bits */
+ if (temp > 32767)
+ temp = 32767;
+ /* limit to baseline range if requested */
+ if (force_baseline && temp > 255)
+ temp = 255;
+ qtable[i] = (u16)temp;
+ }
}
static void convert_quant_table(u16 *qtable, u16 *basic_table,
- s32 scale_factor)
+ s32 scale_factor)
{
- _convert_quant_table(qtable, basic_table, scale_factor, true);
+ _convert_quant_table(qtable, basic_table, scale_factor, true);
}
static void write_jpeg_quant_lut(s32 table_num)
{
- s32 i;
- u32 data32;
+ s32 i;
+ u32 data32;
- for (i = 0; i < DCTSIZE2; i += 2) {
- data32 = reciprocal(gQuantTable[table_num][i]);
- data32 |= reciprocal(gQuantTable[table_num][i + 1]) << 16;
- WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_DATA, data32);
- }
+ for (i = 0; i < DCTSIZE2; i += 2) {
+ data32 = reciprocal(gQuantTable[table_num][i]);
+ data32 |= reciprocal(gQuantTable[table_num][i + 1]) << 16;
+ WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_DATA, data32);
+ }
}
static void write_jpeg_huffman_lut_dc(s32 table_num)
{
- u32 code_len, code_word, pos, addr;
- u32 num_code_len;
- u32 lut[12];
- u32 i, j;
+ u32 code_len, code_word, pos, addr;
+ u32 num_code_len;
+ u32 lut[12];
+ u32 i, j;
- code_len = 1;
- code_word = 1;
- pos = 16;
+ code_len = 1;
+ code_word = 1;
+ pos = 16;
- /* Construct DC Huffman table */
- for (i = 0; i < 16; i++) {
- num_code_len = jpeg_huffman_dc[table_num][i];
- for (j = 0; j < num_code_len; j++) {
- code_word = (code_word + 1) & ((1 << code_len) - 1);
- if (code_len < i + 1) {
- code_word <<= (i + 1 - code_len);
- code_len = i + 1;
- }
- addr = jpeg_huffman_dc[table_num][pos];
- lut[addr] = ((code_len - 1) << 16) | (code_word);
- pos++;
- }
- }
+ /* Construct DC Huffman table */
+ for (i = 0; i < 16; i++) {
+ num_code_len = jpeg_huffman_dc[table_num][i];
+ for (j = 0; j < num_code_len; j++) {
+ code_word = (code_word + 1) & ((1 << code_len) - 1);
+ if (code_len < i + 1) {
+ code_word <<= (i + 1 - code_len);
+ code_len = i + 1;
+ }
+ addr = jpeg_huffman_dc[table_num][pos];
+ lut[addr] = ((code_len - 1) << 16) | (code_word);
+ pos++;
+ }
+ }
- /* Write DC Huffman table to HW */
- for (i = 0; i < 12; i++)
- WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
+ /* Write DC Huffman table to HW */
+ for (i = 0; i < 12; i++)
+ WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
}
static void write_jpeg_huffman_lut_ac(s32 table_num)
{
- u32 code_len, code_word, pos;
- u32 num_code_len;
- u32 run, size;
- u32 data, addr = 0;
- u32 *lut = NULL;
- u32 i, j;
- code_len = 1;
- code_word = 1;
- pos = 16;
+ u32 code_len, code_word, pos;
+ u32 num_code_len;
+ u32 run, size;
+ u32 data, addr = 0;
+ u32 lut[162];
+ u32 i, j;
+ code_len = 1;
+ code_word = 1;
+ pos = 16;
- lut = (u32 *)vmalloc(162 * sizeof(u32));
- if (!lut) {
- pr_err("alloc lut failed.\n");
- return;
- }
+ /* Construct AC Huffman table */
+ for (i = 0; i < 16; i++) {
+ num_code_len = jpeg_huffman_ac[table_num][i];
+ for (j = 0; j < num_code_len; j++) {
+ code_word = (code_word + 1) & ((1 << code_len) - 1);
+ if (code_len < i + 1) {
+ code_word <<= (i + 1 - code_len);
+ code_len = i + 1;
+ }
+ run = jpeg_huffman_ac[table_num][pos] >> 4;
+ size = jpeg_huffman_ac[table_num][pos] & 0xf;
+ data = ((code_len - 1) << 16) | (code_word);
+ if (size == 0) {
+ if (run == 0)
+ addr = 0; /* EOB */
+ else if (run == 0xf)
+ addr = 161; /* ZRL */
+ else
+ jenc_pr(LOG_ERROR,
+ "Error: Illegal AC Huffman table format!\n");
+ } else if (size <= 0xa)
+ addr = 1 + 16 * (size - 1) + run;
+ else
+ jenc_pr(LOG_ERROR,
+ "Error: Illegal AC Huffman table format!\n");
+ lut[addr] = data;
+ pos++;
+ }
+ }
- /* Construct AC Huffman table */
- for (i = 0; i < 16; i++) {
- num_code_len = jpeg_huffman_ac[table_num][i];
- for (j = 0; j < num_code_len; j++) {
- code_word = (code_word + 1) & ((1 << code_len) - 1);
- if (code_len < i + 1) {
- code_word <<= (i + 1 - code_len);
- code_len = i + 1;
- }
- run = jpeg_huffman_ac[table_num][pos] >> 4;
- size = jpeg_huffman_ac[table_num][pos] & 0xf;
- data = ((code_len - 1) << 16) | (code_word);
- if (size == 0) {
- if (run == 0)
- addr = 0; /* EOB */
- else if (run == 0xf)
- addr = 161; /* ZRL */
- else
- jenc_pr(LOG_ERROR,
- "Error: Illegal AC Huffman table format!\n");
- } else if (size <= 0xa)
- addr = 1 + 16 * (size - 1) + run;
- else
- jenc_pr(LOG_ERROR,
- "Error: Illegal AC Huffman table format!\n");
- lut[addr] = data;
- pos++;
- }
- }
-
- /* Write AC Huffman table to HW */
- for (i = 0; i < 162; i++)
- WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
-
- vfree(lut);
+ /* Write AC Huffman table to HW */
+ for (i = 0; i < 162; i++)
+ WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
}
static void prepare_jpeg_header(struct jpegenc_wq_s *wq)
{
- s32 pic_format;
- s32 pic_width, pic_height;
- s32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
- s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
- s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
- s32 lastcoeff_sel;
- s32 jdct_intr_sel;
- s32 h_factor_comp0, v_factor_comp0;
- s32 h_factor_comp1, v_factor_comp1;
- s32 h_factor_comp2, v_factor_comp2;
- s32 q_num;
- s32 tq[2];
- s32 dc_huff_num, ac_huff_num;
- s32 dc_th[2], ac_th[2];
- u32 header_bytes = 0;
- u32 bak_header_bytes = 0;
- s32 i, j;
- u8 *assitbuf = (u8 *)wq->AssitstreamStartVirtAddr;
+ s32 pic_format;
+ s32 pic_width, pic_height;
+ s32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
+ s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
+ s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
+ s32 lastcoeff_sel;
+ s32 jdct_intr_sel;
+ s32 h_factor_comp0, v_factor_comp0;
+ s32 h_factor_comp1, v_factor_comp1;
+ s32 h_factor_comp2, v_factor_comp2;
+ s32 q_num;
+ s32 tq[2];
+ s32 dc_huff_num, ac_huff_num;
+ s32 dc_th[2], ac_th[2];
+ u32 header_bytes = 0;
+ u32 bak_header_bytes = 0;
+ s32 i, j;
+ u8 *assitbuf = (u8 *)wq->AssitstreamStartVirtAddr;
- if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
- jenc_pr(LOG_ERROR, "Input format is wrong!\n");
- switch (wq->cmd.output_fmt) {
- case JPEGENC_FMT_NV21:
- case JPEGENC_FMT_NV12:
- case JPEGENC_FMT_YUV420:
- pic_format = 3;
- break;
- case JPEGENC_FMT_YUV422_SINGLE:
- pic_format = 2;
- break;
- case JPEGENC_FMT_YUV444_SINGLE:
- case JPEGENC_FMT_YUV444_PLANE:
- pic_format = 1;
- break;
- default:
- pic_format = 0;
- break;
- }
+ if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
+ jenc_pr(LOG_ERROR, "Input format is wrong!\n");
+ switch (wq->cmd.output_fmt) {
+ case JPEGENC_FMT_NV21:
+ case JPEGENC_FMT_NV12:
+ case JPEGENC_FMT_YUV420:
+ pic_format = 3;
+ break;
+ case JPEGENC_FMT_YUV422_SINGLE:
+ pic_format = 2;
+ break;
+ case JPEGENC_FMT_YUV444_SINGLE:
+ case JPEGENC_FMT_YUV444_PLANE:
+ pic_format = 1;
+ break;
+ default:
+ pic_format = 0;
+ break;
+ }
- pic_width = wq->cmd.encoder_width;
- pic_height = wq->cmd.encoder_height;
+ pic_width = wq->cmd.encoder_width;
+ pic_height = wq->cmd.encoder_height;
- q_sel_comp0 = QUANT_SEL_COMP0;
- q_sel_comp1 = QUANT_SEL_COMP1;
- q_sel_comp2 = QUANT_SEL_COMP2;
+ q_sel_comp0 = QUANT_SEL_COMP0;
+ q_sel_comp1 = QUANT_SEL_COMP1;
+ q_sel_comp2 = QUANT_SEL_COMP2;
- dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
- dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
- dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
- ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
- ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
- ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
- lastcoeff_sel = JDCT_LASTCOEFF_SEL;
- jdct_intr_sel = JDCT_INTR_SEL;
+ dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
+ dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
+ dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
+ ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
+ ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
+ ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
+ lastcoeff_sel = JDCT_LASTCOEFF_SEL;
+ jdct_intr_sel = JDCT_INTR_SEL;
- if (pic_format == 2) {
- /* YUV422 */
- h_factor_comp0 = 1;
- v_factor_comp0 = 0;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- } else if (pic_format == 3) {
- /* YUV420 */
- h_factor_comp0 = 1;
- v_factor_comp0 = 1;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- } else {
- /* RGB or YUV */
- h_factor_comp0 = 0;
- v_factor_comp0 = 0;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- }
+ if (pic_format == 2) {
+ /* YUV422 */
+ h_factor_comp0 = 1;
+ v_factor_comp0 = 0;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ } else if (pic_format == 3) {
+ /* YUV420 */
+ h_factor_comp0 = 1;
+ v_factor_comp0 = 1;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ } else {
+ /* RGB or YUV */
+ h_factor_comp0 = 0;
+ v_factor_comp0 = 0;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ }
- /* SOI marke */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | /* Number of bytes */
- (0xffd8 << 0)); /* data: SOI marker */
+ /* SOI marke */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | /* Number of bytes */
+ (0xffd8 << 0)); /* data: SOI marker */
- /* Define quantization tables */
- q_num = 1;
+ /* Define quantization tables */
+ q_num = 1;
#if 0
- if ((q_sel_comp0 != q_sel_comp1) ||
- (q_sel_comp0 != q_sel_comp2) ||
- (q_sel_comp1 != q_sel_comp2))
+ if ((q_sel_comp0 != q_sel_comp1) ||
+ (q_sel_comp0 != q_sel_comp2) ||
+ (q_sel_comp1 != q_sel_comp2))
#endif
- q_num++;
+ q_num++;
#if 0
- tq[0] = q_sel_comp0;
- tq[1] = (q_sel_comp0 != q_sel_comp1) ? q_sel_comp1 :
- (q_sel_comp0 != q_sel_comp2) ? q_sel_comp2 :
- q_sel_comp0;
+ tq[0] = q_sel_comp0;
+ tq[1] = (q_sel_comp0 != q_sel_comp1) ? q_sel_comp1 :
+ (q_sel_comp0 != q_sel_comp2) ? q_sel_comp2 :
+ q_sel_comp0;
#endif
- tq[0] = 0;
- tq[1] = q_num - 1;
+ tq[0] = 0;
+ tq[1] = q_num - 1;
- /* data: DQT marker */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | (0xffdb << 0));
- /* data: Lq */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | ((2 + 65 * q_num) << 0));
+ /* data: DQT marker */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | (0xffdb << 0));
+ /* data: Lq */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | ((2 + 65 * q_num) << 0));
- /* Add Quantization table bytes */
- /* header_bytes += (2 + (2 + 65 * q_num)); */
- for (i = 0; i < q_num; i++) {
- /* data: {Pq,Tq} */
- push_word(assitbuf, &header_bytes,
- (1 << 24) | (i << 0));
- for (j = 0; j < DCTSIZE2; j++) {
- /* data: Qk */
- push_word(assitbuf, &header_bytes,
- (1 << 24) |
- ((gQuantTable[tq[i]][zigzag(j)]) << 0));
- }
- }
+ /* Add Quantization table bytes */
+ /* header_bytes += (2 + (2 + 65 * q_num)); */
+ for (i = 0; i < q_num; i++) {
+ /* data: {Pq,Tq} */
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) | (i << 0));
+ for (j = 0; j < DCTSIZE2; j++) {
+ /* data: Qk */
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) |
+ ((gQuantTable[tq[i]][zigzag(j)]) << 0));
+ }
+ }
- /* Define Huffman tables */
- dc_huff_num = 1;
- if ((dc_huff_sel_comp0 != dc_huff_sel_comp1) ||
- (dc_huff_sel_comp0 != dc_huff_sel_comp2) ||
- (dc_huff_sel_comp1 != dc_huff_sel_comp2))
- dc_huff_num++;
+ /* Define Huffman tables */
+ dc_huff_num = 1;
+ if ((dc_huff_sel_comp0 != dc_huff_sel_comp1) ||
+ (dc_huff_sel_comp0 != dc_huff_sel_comp2) ||
+ (dc_huff_sel_comp1 != dc_huff_sel_comp2))
+ dc_huff_num++;
- ac_huff_num = 1;
- if ((ac_huff_sel_comp0 != ac_huff_sel_comp1) ||
- (ac_huff_sel_comp0 != ac_huff_sel_comp2) ||
- (ac_huff_sel_comp1 != ac_huff_sel_comp2))
- ac_huff_num++;
+ ac_huff_num = 1;
+ if ((ac_huff_sel_comp0 != ac_huff_sel_comp1) ||
+ (ac_huff_sel_comp0 != ac_huff_sel_comp2) ||
+ (ac_huff_sel_comp1 != ac_huff_sel_comp2))
+ ac_huff_num++;
- dc_th[0] = dc_huff_sel_comp0;
- dc_th[1] = (dc_huff_sel_comp0 != dc_huff_sel_comp1) ?
- dc_huff_sel_comp1 : (dc_huff_sel_comp0 != dc_huff_sel_comp2) ?
- dc_huff_sel_comp2 : dc_huff_sel_comp0;
+ dc_th[0] = dc_huff_sel_comp0;
+ dc_th[1] = (dc_huff_sel_comp0 != dc_huff_sel_comp1) ?
+ dc_huff_sel_comp1 : (dc_huff_sel_comp0 != dc_huff_sel_comp2) ?
+ dc_huff_sel_comp2 : dc_huff_sel_comp0;
- ac_th[0] = ac_huff_sel_comp0;
- ac_th[1] = (ac_huff_sel_comp0 != ac_huff_sel_comp1) ?
- ac_huff_sel_comp1 : (ac_huff_sel_comp0 != ac_huff_sel_comp2) ?
- ac_huff_sel_comp2 : ac_huff_sel_comp0;
+ ac_th[0] = ac_huff_sel_comp0;
+ ac_th[1] = (ac_huff_sel_comp0 != ac_huff_sel_comp1) ?
+ ac_huff_sel_comp1 : (ac_huff_sel_comp0 != ac_huff_sel_comp2) ?
+ ac_huff_sel_comp2 : ac_huff_sel_comp0;
- /* data: DHT marker */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | (0xffc4 << 0));
- /* data: Lh */
- push_word(assitbuf, &header_bytes,
- (2 << 24) |
- ((2 + (1 + 16 + 12) * dc_huff_num +
- (1 + 16 + 162) * ac_huff_num) << 0));
+ /* data: DHT marker */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | (0xffc4 << 0));
+ /* data: Lh */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) |
+ ((2 + (1 + 16 + 12) * dc_huff_num +
+ (1 + 16 + 162) * ac_huff_num) << 0));
- /* Add Huffman table bytes */
- /* data: {Tc,Th} */
- for (i = 0; i < dc_huff_num; i++) {
- push_word(assitbuf, &header_bytes,
- (1 << 24) | (i << 0));
- for (j = 0; j < 16 + 12; j++) {
- /* data: Li then Vi,j */
- push_word(assitbuf, &header_bytes,
- (1 << 24) |
- ((jpeg_huffman_dc[dc_th[i]][j]) << 0));
- }
- }
- for (i = 0; i < ac_huff_num; i++) {
- push_word(assitbuf, &header_bytes,
- (1 << 24) |
- (1 << 4) | /* data: Tc */
- (i << 0)); /* data: Th */
- for (j = 0; j < 16 + 162; j++) {
- /* data: Li then Vi,j */
- push_word(assitbuf, &header_bytes,
- (1 << 24) |
- ((jpeg_huffman_ac[ac_th[i]][j]) << 0));
- }
- }
+ /* Add Huffman table bytes */
+ /* data: {Tc,Th} */
+ for (i = 0; i < dc_huff_num; i++) {
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) | (i << 0));
+ for (j = 0; j < 16 + 12; j++) {
+ /* data: Li then Vi,j */
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) |
+ ((jpeg_huffman_dc[dc_th[i]][j]) << 0));
+ }
+ }
+ for (i = 0; i < ac_huff_num; i++) {
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) |
+ (1 << 4) | /* data: Tc */
+ (i << 0)); /* data: Th */
+ for (j = 0; j < 16 + 162; j++) {
+ /* data: Li then Vi,j */
+ push_word(assitbuf, &header_bytes,
+ (1 << 24) |
+ ((jpeg_huffman_ac[ac_th[i]][j]) << 0));
+ }
+ }
- /* Frame header */
- /* Add Frame header bytes */
- /* header_bytes += (2 + (8 + 3 * 3)); */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | /* Number of bytes */
- (0xffc0 << 0)); /* data: SOF_0 marker */
- /* data: Lf */
- push_word(assitbuf, &header_bytes,
- (2 << 24) | ((8 + 3 * 3) << 0));
- /* data: P -- Sample precision */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (8 << 0));
- /* data: Y -- Number of lines */
- push_word(assitbuf,
- &header_bytes, (2 << 24) | (pic_height << 0));
- /* data: X -- Number of samples per line */
- push_word(assitbuf,
- &header_bytes, (2 << 24) | (pic_width << 0));
- /* data: Nf -- Number of components in a frame */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (3 << 0));
- /* data: C0 -- Comp0 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (0 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- /* data: H0 -- Comp0 horizontal sampling factor */
- ((h_factor_comp0 + 1) << 4) |
- /* data: V0 -- Comp0 vertical sampling factor */
- ((v_factor_comp0 + 1) << 0));
+ /* Frame header */
+ /* Add Frame header bytes */
+ /* header_bytes += (2 + (8 + 3 * 3)); */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | /* Number of bytes */
+ (0xffc0 << 0)); /* data: SOF_0 marker */
+ /* data: Lf */
+ push_word(assitbuf, &header_bytes,
+ (2 << 24) | ((8 + 3 * 3) << 0));
+ /* data: P -- Sample precision */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (8 << 0));
+ /* data: Y -- Number of lines */
+ push_word(assitbuf,
+ &header_bytes, (2 << 24) | (pic_height << 0));
+ /* data: X -- Number of samples per line */
+ push_word(assitbuf,
+ &header_bytes, (2 << 24) | (pic_width << 0));
+ /* data: Nf -- Number of components in a frame */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (3 << 0));
+ /* data: C0 -- Comp0 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (0 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ /* data: H0 -- Comp0 horizontal sampling factor */
+ ((h_factor_comp0 + 1) << 4) |
+ /* data: V0 -- Comp0 vertical sampling factor */
+ ((v_factor_comp0 + 1) << 0));
- /* data: Tq0 -- Comp0 quantization table seletor */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (0 << 0));
- /* data: C1 -- Comp1 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (1 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- /* data: H1 -- Comp1 horizontal sampling factor */
- ((h_factor_comp1 + 1) << 4) |
- /* data: V1 -- Comp1 vertical sampling factor */
- ((v_factor_comp1 + 1) << 0));
- /* data: Tq1 -- Comp1 quantization table seletor */
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- (((q_sel_comp0 != q_sel_comp1) ? 1 : 0) << 0));
- /* data: C2 -- Comp2 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (2 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- /* data: H2 -- Comp2 horizontal sampling factor */
- ((h_factor_comp2 + 1) << 4) |
- /* data: V2 -- Comp2 vertical sampling factor */
- ((v_factor_comp2 + 1) << 0));
- /* data: Tq2 -- Comp2 quantization table seletor */
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- (((q_sel_comp0 != q_sel_comp2) ? 1 : 0) << 0));
+ /* data: Tq0 -- Comp0 quantization table seletor */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (0 << 0));
+ /* data: C1 -- Comp1 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (1 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ /* data: H1 -- Comp1 horizontal sampling factor */
+ ((h_factor_comp1 + 1) << 4) |
+ /* data: V1 -- Comp1 vertical sampling factor */
+ ((v_factor_comp1 + 1) << 0));
+ /* data: Tq1 -- Comp1 quantization table seletor */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ (((q_sel_comp0 != q_sel_comp1) ? 1 : 0) << 0));
+ /* data: C2 -- Comp2 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (2 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ /* data: H2 -- Comp2 horizontal sampling factor */
+ ((h_factor_comp2 + 1) << 4) |
+ /* data: V2 -- Comp2 vertical sampling factor */
+ ((v_factor_comp2 + 1) << 0));
+ /* data: Tq2 -- Comp2 quantization table seletor */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ (((q_sel_comp0 != q_sel_comp2) ? 1 : 0) << 0));
- /* Scan header */
- bak_header_bytes = header_bytes + (2 + (6 + 2 * 3));
+ /* Scan header */
+ bak_header_bytes = header_bytes + (2 + (6 + 2 * 3));
- /* Add Scan header bytes */
- /* header_bytes += (2 + (6+2*3)); */
- /* If total header bytes is not multiple of 8,
- then fill 0xff byte between Frame header segment
- and the Scan header segment. */
- /* header_bytes = ((header_bytes + 7)/8)*8; */
- bak_header_bytes = ((bak_header_bytes + 7) / 8) * 8 - bak_header_bytes;
- for (i = 0; i < bak_header_bytes; i++)
- push_word(assitbuf,
- &header_bytes,
- (1 << 24) | (0xff << 0)); /* 0xff filler */
+ /* Add Scan header bytes */
+ /* header_bytes += (2 + (6+2*3)); */
+ /* If total header bytes is not multiple of 8,
+ then fill 0xff byte between Frame header segment
+ and the Scan header segment. */
+ /* header_bytes = ((header_bytes + 7)/8)*8; */
+ bak_header_bytes = ((bak_header_bytes + 7) / 8) * 8 - bak_header_bytes;
+ for (i = 0; i < bak_header_bytes; i++)
+ push_word(assitbuf,
+ &header_bytes,
+ (1 << 24) | (0xff << 0)); /* 0xff filler */
- push_word(assitbuf,
- &header_bytes,
- (2 << 24) | /* Number of bytes */
- (0xffda << 0)); /* data: SOS marker */
+ push_word(assitbuf,
+ &header_bytes,
+ (2 << 24) | /* Number of bytes */
+ (0xffda << 0)); /* data: SOS marker */
- /* data: Ls */
- push_word(assitbuf,
- &header_bytes, (2 << 24) | ((6 + 2 * 3) << 0));
- /* data: Ns -- Number of components in a scan */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (3 << 0));
- /* data: Cs0 -- Comp0 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (0 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- (0 << 4) | /* data: Td0 -- Comp0 DC Huffman table selector */
- (0 << 0)); /* data: Ta0 -- Comp0 AC Huffman table selector */
- /* data: Cs1 -- Comp1 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (1 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- /* data: Td1 -- Comp1 DC Huffman table selector */
- (((dc_huff_sel_comp0 != dc_huff_sel_comp1) ? 1 : 0) << 4) |
- /* data: Ta1 -- Comp1 AC Huffman table selector */
- (((ac_huff_sel_comp0 != ac_huff_sel_comp1) ? 1 : 0) << 0));
- /* data: Cs2 -- Comp2 identifier */
- push_word(assitbuf,
- &header_bytes, (1 << 24) | (2 << 0));
- push_word(assitbuf,
- &header_bytes, (1 << 24) |
- /* data: Td2 -- Comp2 DC Huffman table selector */
- (((dc_huff_sel_comp0 != dc_huff_sel_comp2) ? 1 : 0) << 4) |
- /* data: Ta2 -- Comp2 AC Huffman table selector */
- (((ac_huff_sel_comp0 != ac_huff_sel_comp2) ? 1 : 0) << 0));
- push_word(assitbuf, &header_bytes,
- (3 << 24) |
- (0 << 16) | /* data: Ss = 0 */
- (63 << 8) | /* data: Se = 63 */
- (0 << 4) | /* data: Ah = 0 */
- (0 << 0)); /* data: Al = 0 */
- jenc_pr(LOG_INFO, "jpeg header bytes is %d\n", header_bytes);
- wq->headbytes = header_bytes;
+ /* data: Ls */
+ push_word(assitbuf,
+ &header_bytes, (2 << 24) | ((6 + 2 * 3) << 0));
+ /* data: Ns -- Number of components in a scan */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (3 << 0));
+ /* data: Cs0 -- Comp0 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (0 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ (0 << 4) | /* data: Td0 -- Comp0 DC Huffman table selector */
+ (0 << 0)); /* data: Ta0 -- Comp0 AC Huffman table selector */
+ /* data: Cs1 -- Comp1 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (1 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ /* data: Td1 -- Comp1 DC Huffman table selector */
+ (((dc_huff_sel_comp0 != dc_huff_sel_comp1) ? 1 : 0) << 4) |
+ /* data: Ta1 -- Comp1 AC Huffman table selector */
+ (((ac_huff_sel_comp0 != ac_huff_sel_comp1) ? 1 : 0) << 0));
+ /* data: Cs2 -- Comp2 identifier */
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) | (2 << 0));
+ push_word(assitbuf,
+ &header_bytes, (1 << 24) |
+ /* data: Td2 -- Comp2 DC Huffman table selector */
+ (((dc_huff_sel_comp0 != dc_huff_sel_comp2) ? 1 : 0) << 4) |
+ /* data: Ta2 -- Comp2 AC Huffman table selector */
+ (((ac_huff_sel_comp0 != ac_huff_sel_comp2) ? 1 : 0) << 0));
+ push_word(assitbuf, &header_bytes,
+ (3 << 24) |
+ (0 << 16) | /* data: Ss = 0 */
+ (63 << 8) | /* data: Se = 63 */
+ (0 << 4) | /* data: Ah = 0 */
+ (0 << 0)); /* data: Al = 0 */
+ jenc_pr(LOG_INFO, "jpeg header bytes is %d\n", header_bytes);
+ wq->headbytes = header_bytes;
}
static void init_jpeg_encoder(struct jpegenc_wq_s *wq)
{
- u32 data32;
- s32 pic_format; /* 0=RGB; 1=YUV; 2=YUV422; 3=YUV420 */
- s32 pic_x_start, pic_x_end, pic_y_start, pic_y_end;
- s32 pic_width, pic_height;
- u32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
- s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
- s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
- s32 lastcoeff_sel;
- s32 jdct_intr_sel;
- s32 h_factor_comp0, v_factor_comp0;
- s32 h_factor_comp1, v_factor_comp1;
- s32 h_factor_comp2, v_factor_comp2;
+ u32 data32;
+ s32 pic_format; /* 0=RGB; 1=YUV; 2=YUV422; 3=YUV420 */
+ s32 pic_x_start, pic_x_end, pic_y_start, pic_y_end;
+ s32 pic_width, pic_height;
+ s32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
+ s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
+ s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
+ s32 lastcoeff_sel;
+ s32 jdct_intr_sel;
+ s32 h_factor_comp0, v_factor_comp0;
+ s32 h_factor_comp1, v_factor_comp1;
+ s32 h_factor_comp2, v_factor_comp2;
- jenc_pr(LOG_INFO, "Initialize JPEG Encoder ....\n");
- if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
- jenc_pr(LOG_ERROR, "Input format is wrong!\n");
- switch (wq->cmd.output_fmt) {
- case JPEGENC_FMT_NV21:
- case JPEGENC_FMT_NV12:
- case JPEGENC_FMT_YUV420:
- pic_format = 3;
- break;
- case JPEGENC_FMT_YUV422_SINGLE:
- pic_format = 2;
- break;
- case JPEGENC_FMT_YUV444_SINGLE:
- case JPEGENC_FMT_YUV444_PLANE:
- pic_format = 1;
- break;
- default:
- pic_format = 0;
- break;
- }
+ jenc_pr(LOG_INFO, "Initialize JPEG Encoder ....\n");
+ if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
+ jenc_pr(LOG_ERROR, "Input format is wrong!\n");
+ switch (wq->cmd.output_fmt) {
+ case JPEGENC_FMT_NV21:
+ case JPEGENC_FMT_NV12:
+ case JPEGENC_FMT_YUV420:
+ pic_format = 3;
+ break;
+ case JPEGENC_FMT_YUV422_SINGLE:
+ pic_format = 2;
+ break;
+ case JPEGENC_FMT_YUV444_SINGLE:
+ case JPEGENC_FMT_YUV444_PLANE:
+ pic_format = 1;
+ break;
+ default:
+ pic_format = 0;
+ break;
+ }
- pic_x_start = 0;
- pic_x_end = wq->cmd.encoder_width - 1;
+ pic_x_start = 0;
+ pic_x_end = wq->cmd.encoder_width - 1;
+ pic_y_start = 0;
+ pic_y_end = wq->cmd.encoder_height - 1;
+ pic_width = wq->cmd.encoder_width;
+ pic_height = wq->cmd.encoder_height;
- pic_y_start = 0;
- pic_y_end = wq->cmd.encoder_height - 1;
+ q_sel_comp0 = wq->cmd.QuantTable_id * 2;
+ q_sel_comp1 = q_sel_comp0 + 1;
+ q_sel_comp2 = q_sel_comp1;
- pic_width = wq->cmd.encoder_width;
- pic_height = wq->cmd.encoder_height;
+ dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
+ dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
+ dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
+ ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
+ ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
+ ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
+ lastcoeff_sel = JDCT_LASTCOEFF_SEL;
+ jdct_intr_sel = JDCT_INTR_SEL;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- q_sel_comp0 = QUANT_SEL_COMP0 & 0xff;
- q_sel_comp1 = QUANT_SEL_COMP1 & 0xff;
- q_sel_comp2 = QUANT_SEL_COMP2 & 0xff;
- } else {
- q_sel_comp0 = wq->cmd.QuantTable_id * 2;
- q_sel_comp1 = q_sel_comp0 + 1;
- q_sel_comp2 = q_sel_comp1;
- }
- if (q_sel_comp0 >= 6 || q_sel_comp1 >= 6)
- {
- jenc_pr(LOG_ERROR, "error, q_sel_comp0, q_sel_comp1 is invalid %d,%d\n",
- q_sel_comp0, q_sel_comp1);
- return;
- }
- dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
- dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
- dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
- ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
- ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
- ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
- lastcoeff_sel = JDCT_LASTCOEFF_SEL;
- jdct_intr_sel = JDCT_INTR_SEL;
+ if (pic_format == 2) {
+ /* YUV422 */
+ h_factor_comp0 = 1;
+ v_factor_comp0 = 0;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ } else if (pic_format == 3) {
+ /* YUV420 */
+ h_factor_comp0 = 1;
+ v_factor_comp0 = 1;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ } else {
+ /* RGB or YUV */
+ h_factor_comp0 = 0;
+ v_factor_comp0 = 0;
+ h_factor_comp1 = 0;
+ v_factor_comp1 = 0;
+ h_factor_comp2 = 0;
+ v_factor_comp2 = 0;
+ }
- if (pic_format == 2) {
- /* YUV422 */
- h_factor_comp0 = 1;
- v_factor_comp0 = 0;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- } else if (pic_format == 3) {
- /* YUV420 */
- h_factor_comp0 = 1;
- v_factor_comp0 = 1;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- } else {
- /* RGB or YUV */
- h_factor_comp0 = 0;
- v_factor_comp0 = 0;
- h_factor_comp1 = 0;
- v_factor_comp1 = 0;
- h_factor_comp2 = 0;
- v_factor_comp2 = 0;
- }
+ /* Configure picture size and format */
+ WRITE_HREG(HCODEC_VLC_PIC_SIZE, pic_width | (pic_height << 16));
+ WRITE_HREG(HCODEC_VLC_PIC_POSITION, pic_format | (lastcoeff_sel << 4));
+ WRITE_HREG(HCODEC_QDCT_JPEG_X_START_END,
+ ((pic_x_end << 16) | (pic_x_start << 0)));
+ WRITE_HREG(HCODEC_QDCT_JPEG_Y_START_END,
+ ((pic_y_end << 16) | (pic_y_start << 0)));
- /* Configure picture size and format */
- WRITE_HREG(HCODEC_VLC_PIC_SIZE, pic_width | (pic_height << 16));
- WRITE_HREG(HCODEC_VLC_PIC_POSITION, pic_format | (lastcoeff_sel << 4));
- WRITE_HREG(HCODEC_QDCT_JPEG_X_START_END,
- ((pic_x_end << 16) | (pic_x_start << 0)));
- WRITE_HREG(HCODEC_QDCT_JPEG_Y_START_END,
- ((pic_y_end << 16) | (pic_y_start << 0)));
-
- /* Configure quantization tables */
+ /* Configure quantization tables */
#ifdef EXTEAN_QUANT_TABLE
- if (external_quant_table_available) {
- convert_quant_table(&gQuantTable[0][0],
- &gExternalQuantTablePtr[0],
- wq->cmd.jpeg_quality);
- convert_quant_table(&gQuantTable[1][0],
- &gExternalQuantTablePtr[DCTSIZE2],
- wq->cmd.jpeg_quality);
- q_sel_comp0 = 0;
- q_sel_comp1 = 1;
- q_sel_comp2 = 1;
- } else
+ if (external_quant_table_available) {
+ convert_quant_table(&gQuantTable[0][0],
+ &gExternalQuantTablePtr[0],
+ wq->cmd.jpeg_quality);
+ convert_quant_table(&gQuantTable[1][0],
+ &gExternalQuantTablePtr[DCTSIZE2],
+ wq->cmd.jpeg_quality);
+ q_sel_comp0 = 0;
+ q_sel_comp1 = 1;
+ q_sel_comp2 = 1;
+ } else
#endif
- {
- s32 tq[2];
- tq[0] = q_sel_comp0;
- tq[1] = (q_sel_comp0 != q_sel_comp1) ?
- q_sel_comp1 : (q_sel_comp0 != q_sel_comp2) ?
- q_sel_comp2 : q_sel_comp0;
- convert_quant_table(&gQuantTable[0][0],
- (u16 *)&jpeg_quant[tq[0]],
- wq->cmd.jpeg_quality);
- if (tq[0] != tq[1])
- convert_quant_table(&gQuantTable[1][0],
- (u16 *)&jpeg_quant[tq[1]],
- wq->cmd.jpeg_quality);
- q_sel_comp0 = tq[0];
- q_sel_comp1 = tq[1];
- q_sel_comp2 = tq[1];
- }
+ {
+ s32 tq[2];
+ tq[0] = q_sel_comp0;
+ tq[1] = (q_sel_comp0 != q_sel_comp1) ?
+ q_sel_comp1 : (q_sel_comp0 != q_sel_comp2) ?
+ q_sel_comp2 : q_sel_comp0;
+ convert_quant_table(&gQuantTable[0][0],
+ (u16 *)&jpeg_quant[tq[0]],
+ wq->cmd.jpeg_quality);
+ if (tq[0] != tq[1])
+ convert_quant_table(&gQuantTable[1][0],
+ (u16 *)&jpeg_quant[tq[1]],
+ wq->cmd.jpeg_quality);
+ q_sel_comp0 = tq[0];
+ q_sel_comp1 = tq[1];
+ q_sel_comp2 = tq[1];
+ }
- /* Set Quantization LUT start address */
- data32 = 0;
- data32 |= 0 << 8; /* [8] 0=Write LUT, 1=Read */
- data32 |= 0 << 0; /* [5:0] Start addr = 0 */
+ /* Set Quantization LUT start address */
+ data32 = 0;
+ data32 |= 0 << 8; /* [8] 0=Write LUT, 1=Read */
+ data32 |= 0 << 0; /* [5:0] Start addr = 0 */
- WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_ADDR, data32);
+ WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_ADDR, data32);
- /* Burst-write Quantization LUT data */
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_C1) {
- write_jpeg_quant_lut(0);
- if (q_sel_comp0 != q_sel_comp1)
- write_jpeg_quant_lut(1);
- } else {
- write_jpeg_quant_lut(q_sel_comp0);
- if (q_sel_comp1 != q_sel_comp0)
- write_jpeg_quant_lut(q_sel_comp1);
- if ((q_sel_comp2 != q_sel_comp0) && (q_sel_comp2 != q_sel_comp1))
- write_jpeg_quant_lut(q_sel_comp2);
- }
+ /* Burst-write Quantization LUT data */
+ write_jpeg_quant_lut(0);
+ if (q_sel_comp0 != q_sel_comp1)
+ write_jpeg_quant_lut(1);
+#if 0
+ write_jpeg_quant_lut(q_sel_comp0);
+ if (q_sel_comp1 != q_sel_comp0)
+ write_jpeg_quant_lut(q_sel_comp1);
+ if ((q_sel_comp2 != q_sel_comp0) && (q_sel_comp2 != q_sel_comp1))
+ write_jpeg_quant_lut(q_sel_comp2);
+#endif
- /* Configure Huffman tables */
+ /* Configure Huffman tables */
- /* Set DC Huffman LUT start address */
- data32 = 0;
- data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
- data32 |= 0 << 0; /* [8:0] Start addr = 0 */
- WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
+ /* Set DC Huffman LUT start address */
+ data32 = 0;
+ data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
+ data32 |= 0 << 0; /* [8:0] Start addr = 0 */
+ WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
- /* Burst-write DC Huffman LUT data */
- write_jpeg_huffman_lut_dc(dc_huff_sel_comp0);
- if (dc_huff_sel_comp1 != dc_huff_sel_comp0)
- write_jpeg_huffman_lut_dc(dc_huff_sel_comp1);
+ /* Burst-write DC Huffman LUT data */
+ write_jpeg_huffman_lut_dc(dc_huff_sel_comp0);
+ if (dc_huff_sel_comp1 != dc_huff_sel_comp0)
+ write_jpeg_huffman_lut_dc(dc_huff_sel_comp1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if ((dc_huff_sel_comp2 != dc_huff_sel_comp0)
- && (dc_huff_sel_comp2 != dc_huff_sel_comp1))
- write_jpeg_huffman_lut_dc(dc_huff_sel_comp2);
- }
+#if 0
+ if ((dc_huff_sel_comp2 != dc_huff_sel_comp0)
+ && (dc_huff_sel_comp2 != dc_huff_sel_comp1))
+ write_jpeg_huffman_lut_dc(dc_huff_sel_comp2);
+#endif
- /* Set AC Huffman LUT start address */
- data32 = 0;
- data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
- data32 |= 24 << 0; /* [8:0] Start addr = 0 */
- WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
+ /* Set AC Huffman LUT start address */
+ data32 = 0;
+ data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
+ data32 |= 24 << 0; /* [8:0] Start addr = 0 */
+ WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
- /* Burst-write AC Huffman LUT data */
- write_jpeg_huffman_lut_ac(ac_huff_sel_comp0);
- if (ac_huff_sel_comp1 != ac_huff_sel_comp0)
- write_jpeg_huffman_lut_ac(ac_huff_sel_comp1);
+ /* Burst-write AC Huffman LUT data */
+ write_jpeg_huffman_lut_ac(ac_huff_sel_comp0);
+ if (ac_huff_sel_comp1 != ac_huff_sel_comp0)
+ write_jpeg_huffman_lut_ac(ac_huff_sel_comp1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if ((ac_huff_sel_comp2 != ac_huff_sel_comp0)
- && (ac_huff_sel_comp2 != ac_huff_sel_comp1))
- write_jpeg_huffman_lut_ac(ac_huff_sel_comp2);
- }
+#if 0
+ if ((ac_huff_sel_comp2 != ac_huff_sel_comp0)
+ && (ac_huff_sel_comp2 != ac_huff_sel_comp1))
+ write_jpeg_huffman_lut_ac(ac_huff_sel_comp2);
+#endif
- /* Configure general control registers */
- data32 = 0;
- /* [19:18] dct_inflow_ctrl: 0=No halt; */
- /* 1=DCT halts request at end of each 8x8 block; */
- /* 2=DCT halts request at end of each MCU. */
- data32 |= 0 << 18;
- /* [17:16] jpeg_coeff_last_sel: */
- /* 0=Mark last coeff at the end of an 8x8 block, */
- /* 1=Mark last coeff at the end of an MCU */
- /* 2=Mark last coeff at the end of a scan */
- data32 |= lastcoeff_sel << 16;
- /* [15] jpeg_quant_sel_comp2 */
- data32 |= ((q_sel_comp2 == q_sel_comp0) ? 0 : 1) << 15;
- /* [14] jpeg_v_factor_comp2 */
- data32 |= v_factor_comp2 << 14;
- /* [13] jpeg_h_factor_comp2 */
- data32 |= h_factor_comp2 << 13;
- /* [12] jpeg_comp2_en */
- data32 |= 1 << 12;
- /* [11] jpeg_quant_sel_comp1 */
- data32 |= ((q_sel_comp1 == q_sel_comp0) ? 0 : 1) << 11;
- /* [10] jpeg_v_factor_comp1 */
- data32 |= v_factor_comp1 << 10;
- /* [9] jpeg_h_factor_comp1 */
- data32 |= h_factor_comp1 << 9;
- /* [8] jpeg_comp1_en */
- data32 |= 1 << 8;
- /* [7] jpeg_quant_sel_comp0 */
- data32 |= 0 << 7;
- /* [6] jpeg_v_factor_comp0 */
- data32 |= v_factor_comp0 << 6;
- /* [5] jpeg_h_factor_comp0 */
- data32 |= h_factor_comp0 << 5;
- /* [4] jpeg_comp0_en */
- data32 |= 1 << 4;
- /* [3:1] jdct_intr_sel:0=Disable intr; */
- /* 1=Intr at end of each 8x8 block of DCT input; */
- /* 2=Intr at end of each MCU of DCT input; */
- /* 3=Intr at end of a scan of DCT input; */
- /* 4=Intr at end of each 8x8 block of DCT output; */
- /* 5=Intr at end of each MCU of DCT output; */
- /* 6=Intr at end of a scan of DCT output. */
- data32 |= jdct_intr_sel << 1;
- /* [0] jpeg_en */
- data32 |= 1 << 0;
- WRITE_HREG(HCODEC_QDCT_JPEG_CTRL, data32);
+ /* Configure general control registers */
+ data32 = 0;
+ /* [19:18] dct_inflow_ctrl: 0=No halt; */
+ /* 1=DCT halts request at end of each 8x8 block; */
+ /* 2=DCT halts request at end of each MCU. */
+ data32 |= 0 << 18;
+ /* [17:16] jpeg_coeff_last_sel: */
+ /* 0=Mark last coeff at the end of an 8x8 block, */
+ /* 1=Mark last coeff at the end of an MCU */
+ /* 2=Mark last coeff at the end of a scan */
+ data32 |= lastcoeff_sel << 16;
+ /* [15] jpeg_quant_sel_comp2 */
+ data32 |= ((q_sel_comp2 == q_sel_comp0) ? 0 : 1) << 15;
+ /* [14] jpeg_v_factor_comp2 */
+ data32 |= v_factor_comp2 << 14;
+ /* [13] jpeg_h_factor_comp2 */
+ data32 |= h_factor_comp2 << 13;
+ /* [12] jpeg_comp2_en */
+ data32 |= 1 << 12;
+ /* [11] jpeg_quant_sel_comp1 */
+ data32 |= ((q_sel_comp1 == q_sel_comp0) ? 0 : 1) << 11;
+ /* [10] jpeg_v_factor_comp1 */
+ data32 |= v_factor_comp1 << 10;
+ /* [9] jpeg_h_factor_comp1 */
+ data32 |= h_factor_comp1 << 9;
+ /* [8] jpeg_comp1_en */
+ data32 |= 1 << 8;
+ /* [7] jpeg_quant_sel_comp0 */
+ data32 |= 0 << 7;
+ /* [6] jpeg_v_factor_comp0 */
+ data32 |= v_factor_comp0 << 6;
+ /* [5] jpeg_h_factor_comp0 */
+ data32 |= h_factor_comp0 << 5;
+ /* [4] jpeg_comp0_en */
+ data32 |= 1 << 4;
+ /* [3:1] jdct_intr_sel:0=Disable intr; */
+ /* 1=Intr at end of each 8x8 block of DCT input; */
+ /* 2=Intr at end of each MCU of DCT input; */
+ /* 3=Intr at end of a scan of DCT input; */
+ /* 4=Intr at end of each 8x8 block of DCT output; */
+ /* 5=Intr at end of each MCU of DCT output; */
+ /* 6=Intr at end of a scan of DCT output. */
+ data32 |= jdct_intr_sel << 1;
+ /* [0] jpeg_en */
+ data32 |= 1 << 0;
+ WRITE_HREG(HCODEC_QDCT_JPEG_CTRL, data32);
- data32 = 0;
- data32 |= ((ac_huff_sel_comp2 == ac_huff_sel_comp0)? 0 : 1) << 29; // [ 29] jpeg_comp2_ac_table_sel
- data32 |= ((dc_huff_sel_comp2 == dc_huff_sel_comp0)? 0 : 1) << 28; // [ 28] jpeg_comp2_dc_table_sel
- /* [26:25] jpeg_comp2_cnt_max */
- data32 |= ((h_factor_comp2 + 1) * (v_factor_comp2 + 1) - 1) << 25;
- /* [24] jpeg_comp2_en */
- data32 |= 1 << 24;
- data32 |= ((ac_huff_sel_comp1 == ac_huff_sel_comp0)? 0 : 1) << 21; // [ 21] jpeg_comp1_ac_table_sel
- data32 |= ((dc_huff_sel_comp1 == dc_huff_sel_comp0)? 0 : 1) << 20; // [ 20] jpeg_comp1_dc_table_sel
- /* [18:17] jpeg_comp1_cnt_max */
- data32 |= ((h_factor_comp1 + 1) * (v_factor_comp1 + 1) - 1) << 17;
- /* [16] jpeg_comp1_en */
- data32 |= 1 << 16;
- /* [13] jpeg_comp0_ac_table_sel */
- data32 |= 0 << 13;
- /* [12] jpeg_comp0_dc_table_sel */
- data32 |= 0 << 12;
- /* [10:9] jpeg_comp0_cnt_max */
- data32 |= ((h_factor_comp0 + 1) * (v_factor_comp0 + 1) - 1) << 9;
- /* [8] jpeg_comp0_en */
- data32 |= 1 << 8;
- /* [0] jpeg_en, will be enbled by amrisc */
- data32 |= 0 << 0;
- WRITE_HREG(HCODEC_VLC_JPEG_CTRL, data32);
+ data32 = 0;
+ /* [29] jpeg_comp2_ac_table_sel */
+ /*
+ data32 |= ((ac_huff_sel_comp2 == ac_huff_sel_comp0) ? 0 : 1 << 29;
+ */
+ data32 |= 1 << 29;
+ /* [28] jpeg_comp2_dc_table_sel */
+ /*
+ data32 |= ((dc_huff_sel_comp2 == dc_huff_sel_comp0) ? 0 : 1) << 28;
+ */
+ data32 |= 1 << 28;
+ /* [26:25] jpeg_comp2_cnt_max */
+ data32 |= ((h_factor_comp2 + 1) * (v_factor_comp2 + 1) - 1) << 25;
+ /* [24] jpeg_comp2_en */
+ data32 |= 1 << 24;
+ /* [21] jpeg_comp1_ac_table_sel */
+ /*
+ data32 |= ((ac_huff_sel_comp1 == ac_huff_sel_comp0) ? 0 : 1) << 21;
+ */
+ data32 |= 1 << 21;
+ /* [20] jpeg_comp1_dc_table_sel */
+ /*
+ data32 |= ((dc_huff_sel_comp1 == dc_huff_sel_comp0) ? 0 : 1) << 20;
+ */
+ data32 |= 1 << 20;
+ /* [18:17] jpeg_comp1_cnt_max */
+ data32 |= ((h_factor_comp1 + 1) * (v_factor_comp1 + 1) - 1) << 17;
+ /* [16] jpeg_comp1_en */
+ data32 |= 1 << 16;
+ /* [13] jpeg_comp0_ac_table_sel */
+ data32 |= 0 << 13;
+ /* [12] jpeg_comp0_dc_table_sel */
+ data32 |= 0 << 12;
+ /* [10:9] jpeg_comp0_cnt_max */
+ data32 |= ((h_factor_comp0 + 1) * (v_factor_comp0 + 1) - 1) << 9;
+ /* [8] jpeg_comp0_en */
+ data32 |= 1 << 8;
+ /* [0] jpeg_en, will be enbled by amrisc */
+ data32 |= 0 << 0;
+ WRITE_HREG(HCODEC_VLC_JPEG_CTRL, data32);
- WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
- (1 << 9) | /* mb_info_soft_reset */
- (1 << 0)); /* mb read buffer soft reset */
+ WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
+ (1 << 9) | /* mb_info_soft_reset */
+ (1 << 0)); /* mb read buffer soft reset */
- WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
- (0 << 28) | /* ignore_t_p8x8 */
- (0 << 27) | /* zero_mc_out_null_non_skipped_mb */
- (0 << 26) | /* no_mc_out_null_non_skipped_mb */
- (0 << 25) | /* mc_out_even_skipped_mb */
- (0 << 24) | /* mc_out_wait_cbp_ready */
- (0 << 23) | /* mc_out_wait_mb_type_ready */
- (0 << 29) | /* ie_start_int_enable */
- (0 << 19) | /* i_pred_enable */
- (0 << 20) | /* ie_sub_enable */
- (0 << 18) | /* iq_enable */
- (0 << 17) | /* idct_enable */
- (0 << 14) | /* mb_pause_enable */
- (1 << 13) | /* q_enable */
- (1 << 12) | /* dct_enable */
- (0 << 10) | /* mb_info_en */
- (0 << 3) | /* endian */
- (0 << 1) | /* mb_read_en */
- (0 << 0)); /* soft reset */
+ WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
+ (0 << 28) | /* ignore_t_p8x8 */
+ (0 << 27) | /* zero_mc_out_null_non_skipped_mb */
+ (0 << 26) | /* no_mc_out_null_non_skipped_mb */
+ (0 << 25) | /* mc_out_even_skipped_mb */
+ (0 << 24) | /* mc_out_wait_cbp_ready */
+ (0 << 23) | /* mc_out_wait_mb_type_ready */
+ (0 << 29) | /* ie_start_int_enable */
+ (0 << 19) | /* i_pred_enable */
+ (0 << 20) | /* ie_sub_enable */
+ (0 << 18) | /* iq_enable */
+ (0 << 17) | /* idct_enable */
+ (0 << 14) | /* mb_pause_enable */
+ (1 << 13) | /* q_enable */
+ (1 << 12) | /* dct_enable */
+ (0 << 10) | /* mb_info_en */
+ (0 << 3) | /* endian */
+ (0 << 1) | /* mb_read_en */
+ (0 << 0)); /* soft reset */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- // INIT_ENCODER
- WRITE_HREG(HCODEC_VLC_TOTAL_BYTES, 0);
- WRITE_HREG(HCODEC_VLC_INT_CONTROL, 0);// disable vlc interrupt
-
- WRITE_HREG(HCODEC_HENC_SCRATCH_0, 0);// mtspi ENCODER_IDLE = ( ENCODER_STATUS
- WRITE_HREG(HCODEC_HENC_SCRATCH_1, 0xffffffff);// reset MCU_XY_REG
-
- WRITE_HREG(HCODEC_ASSIST_AMR1_INT0, 0x15);// vb_full_isr
- WRITE_HREG(HCODEC_ASSIST_AMR1_INT1, 8);// vlc_isr
- WRITE_HREG(HCODEC_ASSIST_AMR1_INT3, 0x14);// qdct_isr
- }
-
- /* Assember JPEG file header */
- prepare_jpeg_header(wq);
+ /* Assember JPEG file header */
+ prepare_jpeg_header(wq);
}
static void jpegenc_init_output_buffer(struct jpegenc_wq_s *wq)
{
- WRITE_HREG(HCODEC_VLC_VB_MEM_CTL,
- ((1 << 31) | (0x3f << 24) |
- (0x20 << 16) | (2 << 0)));
-
- WRITE_HREG(HCODEC_VLC_VB_START_PTR, wq->BitstreamStart);
- WRITE_HREG(HCODEC_VLC_VB_WR_PTR, wq->BitstreamStart);
- WRITE_HREG(HCODEC_VLC_VB_SW_RD_PTR, wq->BitstreamStart);
- WRITE_HREG(HCODEC_VLC_VB_END_PTR, wq->BitstreamEnd);
- WRITE_HREG(HCODEC_VLC_VB_CONTROL, 1);
- WRITE_HREG(HCODEC_VLC_VB_CONTROL,
- ((0 << 14) | (7 << 3) |
- (1 << 1) | (0 << 0)));
+ WRITE_HREG(HCODEC_VLC_VB_MEM_CTL,
+ ((1 << 31) | (0x3f << 24) |
+ (0x20 << 16) | (2 << 0)));
+ WRITE_HREG(HCODEC_VLC_VB_START_PTR,
+ wq->BitstreamStart);
+ WRITE_HREG(HCODEC_VLC_VB_WR_PTR,
+ wq->BitstreamStart);
+ WRITE_HREG(HCODEC_VLC_VB_SW_RD_PTR,
+ wq->BitstreamStart);
+ WRITE_HREG(HCODEC_VLC_VB_END_PTR,
+ wq->BitstreamEnd);
+ WRITE_HREG(HCODEC_VLC_VB_CONTROL, 1);
+ WRITE_HREG(HCODEC_VLC_VB_CONTROL,
+ ((0 << 14) | (7 << 3) |
+ (1 << 1) | (0 << 0)));
}
static void jpegenc_buffspec_init(struct jpegenc_wq_s *wq)
{
- /* input dct buffer config */
- wq->InputBuffStart = wq->buf_start + gJpegenc.mem.bufspec->input.buf_start;
- wq->InputBuffEnd = wq->InputBuffStart + gJpegenc.mem.bufspec->input.buf_size - 1;
- jenc_pr(LOG_INFO, "InputBuffStart is 0x%x\n", wq->InputBuffStart);
+ /* input dct buffer config */
+ wq->InputBuffStart = wq->buf_start +
+ gJpegenc.mem.bufspec->input.buf_start;
+ wq->InputBuffEnd = wq->InputBuffStart +
+ gJpegenc.mem.bufspec->input.buf_size - 1;
+ jenc_pr(LOG_INFO, "InputBuffStart is 0x%x\n", wq->InputBuffStart);
- /* assit stream buffer config */
- wq->AssitStart = wq->buf_start + gJpegenc.mem.bufspec->assit.buf_start;
- wq->AssitEnd = wq->AssitStart + gJpegenc.mem.bufspec->assit.buf_size - 1;
- /* output stream buffer config */
- wq->BitstreamStart = wq->buf_start + gJpegenc.mem.bufspec->bitstream.buf_start;
- wq->BitstreamEnd = wq->BitstreamStart + gJpegenc.mem.bufspec->bitstream.buf_size - 1;
- jenc_pr(LOG_INFO, "BitstreamStart is 0x%x\n", wq->BitstreamStart);
+ /* assit stream buffer config */
+ //wq->AssitStart = wq->buf_start + gJpegenc.mem.bufspec->assit.buf_start;
+ //wq->AssitEnd = wq->BitstreamStart + gJpegenc.mem.bufspec->assit.buf_size - 1;
+ wq->AssitStart = wq->buf_start + gJpegenc.mem.bufspec->assit.buf_start;
+ wq->AssitEnd = wq->AssitStart + gJpegenc.mem.bufspec->assit.buf_size - 1;
+ /* output stream buffer config */
+ wq->BitstreamStart = wq->buf_start +
+ gJpegenc.mem.bufspec->bitstream.buf_start;
+ wq->BitstreamEnd = wq->BitstreamStart +
+ gJpegenc.mem.bufspec->bitstream.buf_size - 1;
+ jenc_pr(LOG_INFO, "BitstreamStart is 0x%x\n", wq->BitstreamStart);
- wq->AssitstreamStartVirtAddr = phys_to_virt(wq->AssitStart);
- jenc_pr(LOG_INFO, "AssitstreamStartVirtAddr is %p\n", wq->AssitstreamStartVirtAddr);
+#if 0
+ wq->AssitstreamStartVirtAddr = phys_to_virt(wq->AssitStart);
+#else
+ wq->AssitstreamStartVirtAddr =
+ codec_mm_vmap(wq->AssitStart, (wq->AssitEnd - wq->AssitStart + 1));
+#endif
+ //jenc_pr(LOG_ERROR, "[%s:%d], (wq->AssitEnd - wq->AssitStart + 1)=%d\n",
+ //__FUNCTION__, __LINE__, (wq->AssitEnd - wq->AssitStart + 1));
+ jenc_pr(LOG_ERROR, "AssitstreamStartVirtAddr is %p\n",
+ wq->AssitstreamStartVirtAddr);
}
/* for temp */
-#define HCODEC_MFDIN_REGC_MBLP (HCODEC_MFDIN_REGB_AMPC + 0x1)
-#define HCODEC_MFDIN_REG0D (HCODEC_MFDIN_REGB_AMPC + 0x2)
-#define HCODEC_MFDIN_REG0E (HCODEC_MFDIN_REGB_AMPC + 0x3)
-#define HCODEC_MFDIN_REG0F (HCODEC_MFDIN_REGB_AMPC + 0x4)
-#define HCODEC_MFDIN_REG10 (HCODEC_MFDIN_REGB_AMPC + 0x5)
-#define HCODEC_MFDIN_REG11 (HCODEC_MFDIN_REGB_AMPC + 0x6)
-#define HCODEC_MFDIN_REG12 (HCODEC_MFDIN_REGB_AMPC + 0x7)
-#define HCODEC_MFDIN_REG13 (HCODEC_MFDIN_REGB_AMPC + 0x8)
-#define HCODEC_MFDIN_REG14 (HCODEC_MFDIN_REGB_AMPC + 0x9)
-#define HCODEC_MFDIN_REG15 (HCODEC_MFDIN_REGB_AMPC + 0xa)
-#define HCODEC_MFDIN_REG16 (HCODEC_MFDIN_REGB_AMPC + 0xb)
+#define HCODEC_MFDIN_REGC_MBLP (HCODEC_MFDIN_REGB_AMPC + 0x1)
+#define HCODEC_MFDIN_REG0D (HCODEC_MFDIN_REGB_AMPC + 0x2)
+#define HCODEC_MFDIN_REG0E (HCODEC_MFDIN_REGB_AMPC + 0x3)
+#define HCODEC_MFDIN_REG0F (HCODEC_MFDIN_REGB_AMPC + 0x4)
+#define HCODEC_MFDIN_REG10 (HCODEC_MFDIN_REGB_AMPC + 0x5)
+#define HCODEC_MFDIN_REG11 (HCODEC_MFDIN_REGB_AMPC + 0x6)
+#define HCODEC_MFDIN_REG12 (HCODEC_MFDIN_REGB_AMPC + 0x7)
+#define HCODEC_MFDIN_REG13 (HCODEC_MFDIN_REGB_AMPC + 0x8)
+#define HCODEC_MFDIN_REG14 (HCODEC_MFDIN_REGB_AMPC + 0x9)
+#define HCODEC_MFDIN_REG15 (HCODEC_MFDIN_REGB_AMPC + 0xa)
+#define HCODEC_MFDIN_REG16 (HCODEC_MFDIN_REGB_AMPC + 0xb)
static void mfdin_basic_jpeg(
- u32 input, u8 iformat, u8 oformat, u32 picsize_x,
- u32 picsize_y, u8 r2y_en, u8 ifmt_extra,
- int mfdin_canvas0_stride,
- int mfdin_canvas1_stride,
- int mfdin_canvas2_stride,
- int mfdin_canvas0_blkmode,
- int mfdin_canvas1_blkmode,
- int mfdin_canvas2_blkmode,
- int mfdin_canvas0_addr,
- int mfdin_canvas1_addr,
- int mfdin_canvas2_addr,
- int mfdin_canvas_bias,
- bool mfdin_big_endian)
+ u32 input, u8 iformat, u8 oformat, u32 picsize_x,
+ u32 picsize_y, u8 r2y_en, u8 ifmt_extra)
{
- u8 dsample_en; /* Downsample Enable */
- u8 interp_en; /* Interpolation Enable */
- u8 y_size; /* 0:16 Pixels for y direction pickup; 1:8 pixels */
- u8 r2y_mode; /* RGB2YUV Mode, range(0~3) */
- /* mfdin_reg3_canv[25:24]; */
- /* bytes per pixel in x direction for index0, 0:half 1:1 2:2 3:3 */
- u8 canv_idx0_bppx;
- /* mfdin_reg3_canv[27:26]; */
- /* bytes per pixel in x direction for index1-2, 0:half 1:1 2:2 3:3 */
- u8 canv_idx1_bppx;
- /* mfdin_reg3_canv[29:28]; */
- /* bytes per pixel in y direction for index0, 0:half 1:1 2:2 3:3 */
- u8 canv_idx0_bppy;
- /* mfdin_reg3_canv[31:30]; */
- /* bytes per pixel in y direction for index1-2, 0:half 1:1 2:2 3:3 */
- u8 canv_idx1_bppy;
- u8 ifmt444, ifmt422, ifmt420, linear_bytes4p;
- u32 linear_bytesperline;
- int mfdin_input_mode = 0;
- //s32 reg_offset;
- bool format_err = false;
- u32 data32;
+ u8 dsample_en; /* Downsample Enable */
+ u8 interp_en; /* Interpolation Enable */
+ u8 y_size; /* 0:16 Pixels for y direction pickup; 1:8 pixels */
+ u8 r2y_mode; /* RGB2YUV Mode, range(0~3) */
+ /* mfdin_reg3_canv[25:24]; */
+ /* bytes per pixel in x direction for index0, 0:half 1:1 2:2 3:3 */
+ u8 canv_idx0_bppx;
+ /* mfdin_reg3_canv[27:26]; */
+ /* bytes per pixel in x direction for index1-2, 0:half 1:1 2:2 3:3 */
+ u8 canv_idx1_bppx;
+ /* mfdin_reg3_canv[29:28]; */
+ /* bytes per pixel in y direction for index0, 0:half 1:1 2:2 3:3 */
+ u8 canv_idx0_bppy;
+ /* mfdin_reg3_canv[31:30]; */
+ /* bytes per pixel in y direction for index1-2, 0:half 1:1 2:2 3:3 */
+ u8 canv_idx1_bppy;
+ u8 ifmt444, ifmt422, ifmt420, linear_bytes4p;
+ u32 linear_bytesperline;
+ bool linear_enable = false;
+ s32 reg_offset;
+ bool format_err = false;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXL) {
- if ((iformat == 7) && (ifmt_extra > 2))
- format_err = true;
- } else if (iformat == 7)
- format_err = true;
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) {
+ if ((iformat == 7) && (ifmt_extra > 2))
+ format_err = true;
+ } else if (iformat == 7)
+ format_err = true;
- if (format_err) {
- jenc_pr(LOG_ERROR,
- "mfdin format err, iformat:%d, ifmt_extra:%d\n",
- iformat, ifmt_extra);
- return;
- }
- if (iformat != 7)
- ifmt_extra = 0;
+ if (format_err) {
+ jenc_pr(LOG_ERROR,
+ "mfdin format err, iformat:%d, ifmt_extra:%d\n",
+ iformat, ifmt_extra);
+ return;
+ }
+ if (iformat != 7)
+ ifmt_extra = 0;
- ifmt444 = ((iformat == 1) || (iformat == 5) || (iformat == 8)
- || (iformat == 9) || (iformat == 12)) ? 1 : 0;
- if (iformat == 7 && ifmt_extra == 1)
- ifmt444 = 1;
- ifmt422 = ((iformat == 0) || (iformat == 10)) ? 1 : 0;
- if (iformat == 7 && ifmt_extra != 1)
- ifmt422 = 1;
- ifmt420 = ((iformat == 2) || (iformat == 3) || (iformat == 4)
- || (iformat == 11)) ? 1 : 0;
- dsample_en = ((ifmt444 && (oformat != 2))
- || (ifmt422 && (oformat == 0))) ? 1 : 0;
- interp_en = ((ifmt422 && (oformat == 2))
- || (ifmt420 && (oformat != 0))) ? 1 : 0;
- y_size = (oformat != 0) ? 1 : 0;
- /* r2y_mode = (r2y_en == 1) ? 1 : 0; */
- r2y_mode = 1;
- canv_idx0_bppx = (iformat == 1) ? 3 : (iformat == 0) ? 2 : 1;
- canv_idx1_bppx = (iformat == 4) ? 0 : 1;
- canv_idx0_bppy = 1;
- canv_idx1_bppy = (iformat == 5) ? 1 : 0;
+ ifmt444 = ((iformat == 1) || (iformat == 5) || (iformat == 8)
+ || (iformat == 9) || (iformat == 12)) ? 1 : 0;
+ if (iformat == 7 && ifmt_extra == 1)
+ ifmt444 = 1;
+ ifmt422 = ((iformat == 0) || (iformat == 10)) ? 1 : 0;
+ if (iformat == 7 && ifmt_extra != 1)
+ ifmt422 = 1;
+ ifmt420 = ((iformat == 2) || (iformat == 3) || (iformat == 4)
+ || (iformat == 11)) ? 1 : 0;
+ dsample_en = ((ifmt444 && (oformat != 2))
+ || (ifmt422 && (oformat == 0))) ? 1 : 0;
+ interp_en = ((ifmt422 && (oformat == 2))
+ || (ifmt420 && (oformat != 0))) ? 1 : 0;
+ y_size = (oformat != 0) ? 1 : 0;
+ /* r2y_mode = (r2y_en == 1) ? 1 : 0; */
+ r2y_mode = 1;
+ canv_idx0_bppx = (iformat == 1) ? 3 : (iformat == 0) ? 2 : 1;
+ canv_idx1_bppx = (iformat == 4) ? 0 : 1;
+ canv_idx0_bppy = 1;
+ canv_idx1_bppy = (iformat == 5) ? 1 : 0;
+ if ((iformat == 8) || (iformat == 9) || (iformat == 12))
+ linear_bytes4p = 3;
+ else if (iformat == 10)
+ linear_bytes4p = 2;
+ else if (iformat == 11)
+ linear_bytes4p = 1;
+ else
+ linear_bytes4p = 0;
+ linear_bytesperline = picsize_x * linear_bytes4p;
- if ((iformat == 8) || (iformat == 9) || (iformat == 12))
- linear_bytes4p = 3;
- else if (iformat == 10)
- linear_bytes4p = 2;
- else if (iformat == 11)
- linear_bytes4p = 1;
- else
- linear_bytes4p = 0;
- linear_bytesperline = picsize_x * linear_bytes4p;
+ if (iformat < 8)
+ linear_enable = false;
+ else
+ linear_enable = true;
- if (iformat < 8)
- mfdin_input_mode = 0;
- else
- mfdin_input_mode = 1;
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
+ reg_offset = -8;
+
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
+ (picsize_x << 16) | (picsize_y << 0));
+ } else {
+ WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
+ (picsize_x << 14) | (picsize_y << 0));
+ }
+ } else {
+ reg_offset = 0;
+ WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
+ (picsize_x << 12) | (picsize_y << 0));
+ }
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1)
- mfdin_input_mode = 2;
+ WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset),
+ (iformat << 0) | (oformat << 4) |
+ (dsample_en << 6) | (y_size << 8) |
+ (interp_en << 9) | (r2y_en << 12) |
+ (r2y_mode << 13) | (ifmt_extra << 16) |
+ (2 << 29));
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) {
- reg_offset = -8;
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1)
- WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
- (picsize_x << 16) | (picsize_y << 0));
- else
- WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
- (picsize_x << 14) | (picsize_y << 0));
- } else {
- reg_offset = 0;
- WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
- (picsize_x << 12) | (picsize_y << 0));
- }
+ if (linear_enable == false) {
+ WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
+ (input & 0xffffff) |
+ (canv_idx1_bppy << 30) |
+ (canv_idx0_bppy << 28) |
+ (canv_idx1_bppx << 26) |
+ (canv_idx0_bppx << 24));
+ WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
+ (0 << 16) | (0 << 0));
+ WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), 0);
+ } else {
+ WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
+ (canv_idx1_bppy << 30) |
+ (canv_idx0_bppy << 28) |
+ (canv_idx1_bppx << 26) |
+ (canv_idx0_bppx << 24));
+ WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
+ (linear_bytes4p << 16) | (linear_bytesperline << 0));
+ WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), input);
+ }
- WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset),
- (iformat << 0) |
- (oformat << 4) |
- (dsample_en << 6) |
- (y_size << 8) |
- (interp_en << 9) |
- (r2y_en << 12) |
- (r2y_mode << 13) |
- (ifmt_extra << 16) |
- (0 <<19) | // 0:NR Not Enabled
- (2 <<29) | // 0:H264_I_PIC_ALL_4x4, 1:H264_P_PIC_Y_16x16_C_8x8, 2:JPEG_ALL_8x8, 3:Reserved
- (0 <<31)); // 0:YC interleaved 1:YC non-interleaved(for JPEG)
-
- if (mfdin_input_mode == 0) {
- WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
- (input & 0xffffff) |
- (canv_idx1_bppy << 30) |
- (canv_idx0_bppy << 28) |
- (canv_idx1_bppx << 26) |
- (canv_idx0_bppx << 24));
- WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
- (0 << 16) | (0 << 0));
- WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), 0);
- } else if (mfdin_input_mode == 1) {
- WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
- (canv_idx1_bppy << 30) |
- (canv_idx0_bppy << 28) |
- (canv_idx1_bppx << 26) |
- (canv_idx0_bppx << 24));
- WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
- (linear_bytes4p << 16) | (linear_bytesperline << 0));
- WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), input);
- } else if (mfdin_input_mode == 2) {
- WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
- (canv_idx1_bppy << 30) |
- (canv_idx0_bppy << 28) |
- (canv_idx1_bppx << 26) |
- (canv_idx0_bppx << 24));
- WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
- mfdin_canvas0_stride << 0);
- WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), mfdin_canvas0_addr);
-
- WRITE_HREG(HCODEC_MFDIN_REG17, mfdin_canvas1_addr); // U canvas initial address
- WRITE_HREG(HCODEC_MFDIN_REG18, mfdin_canvas2_addr); // V canvas initial address
- WRITE_HREG(HCODEC_MFDIN_REG19, (mfdin_canvas1_stride << 16) | // U canvas stride
- (mfdin_canvas2_stride << 0));
-
- data32 = READ_HREG(HCODEC_MFDIN_REG6_DCFG + reg_offset);
- data32 = data32 & 0x3ff;
-
- if (jpeg_in_full_hcodec) {
- pr_err("JPEG_IN_FULL_HCODEC\n");
- data32 |= (0<<16);
-
- if(mfdin_ambus_canv_conv) {
- data32 |= (1<<17); // AMBUS
- }
- } else {
- data32 |= (1 << 16); // AXI Enable
- }
-
- data32 |= (mfdin_canvas0_blkmode << 14) | // V canvas block mode
- (mfdin_canvas1_blkmode << 12) | // U canvas block mode
- (mfdin_canvas2_blkmode << 10); // Y canvas block mode
-
- WRITE_HREG(HCODEC_MFDIN_REG6_DCFG + reg_offset, data32);
-
- if (mfdin_canvas_bias)
- WRITE_HREG(HCODEC_MFDIN_REGA_CAV1 + reg_offset, mfdin_canvas_bias);
- }
-
- if (!mfdin_big_endian) {
- WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset),
- (7 << 0) | (6 << 3) | (5 << 6) |
- (4 << 9) | (3 << 12) | (2 << 15) |
- (1 << 18) | (0 << 21));
- }
-
- if (jpeg_in_full_hcodec) {//#ifdef JPEG_IN_FULL_HCODEC
- data32 = READ_HREG(HCODEC_MFDIN_REG3_CANV + reg_offset);
- WRITE_HREG(HCODEC_MFDIN_REG3_CANV + reg_offset, data32|(0x1 << 8)|(0x2 << 16));
- }
-
- data32 = READ_HREG(HCODEC_MFDIN_REG7_SCMD + reg_offset);
- WRITE_HREG(HCODEC_MFDIN_REG7_SCMD + reg_offset, data32 | (0x1 << 28)); // MFDIN Enabled
-
- jenc_pr(LOG_INFO, "MFDIN Enabled\n");
-
- return;
+ WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset),
+ (7 << 0) | (6 << 3) | (5 << 6) |
+ (4 << 9) | (3 << 12) | (2 << 15) |
+ (1 << 18) | (0 << 21));
+ return;
}
-//#define CONFIG_AMLOGIC_MEDIA_CANVAS
-
static s32 set_jpeg_input_format(struct jpegenc_wq_s *wq,
- struct jpegenc_request_s *cmd)
+ struct jpegenc_request_s *cmd)
{
- s32 ret = 0;
- u8 iformat = JPEGENC_MAX_FRAME_FMT;
- u8 oformat = JPEGENC_MAX_FRAME_FMT;
- u8 r2y_en = 0;
- u32 picsize_x = 0, picsize_y = 0;
- u32 input = cmd->src;
- u8 ifmt_extra = 0;
- int mfdin_canvas0_stride = 0, mfdin_canvas1_stride = 0, mfdin_canvas2_stride = 0;
- int mfdin_canvas0_blkmode = 0, mfdin_canvas1_blkmode = 0, mfdin_canvas2_blkmode = 0;
- int mfdin_canvas0_addr = 0, mfdin_canvas1_addr = 0, mfdin_canvas2_addr = 0;
- int mfdin_canvas_height = 0;
- int mfdin_canvas_bias = 0;
- bool mfdin_big_endian = false;
- u32 block_mode = 0;
+ s32 ret = 0;
+ u8 iformat = JPEGENC_MAX_FRAME_FMT;
+ u8 oformat = JPEGENC_MAX_FRAME_FMT;
+ u8 r2y_en = 0;
+ u32 picsize_x, picsize_y;
+ u32 canvas_w = 0;
+ u32 input = cmd->src;
+ u8 ifmt_extra = 0;
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- u32 canvas_w = 0;
-#endif
+ jenc_pr(LOG_INFO, "************begin set input format**************\n");
+ jenc_pr(LOG_INFO, "type is %d\n", cmd->type);
+ jenc_pr(LOG_INFO, "input_fmt is %d\n", cmd->input_fmt);
+ jenc_pr(LOG_INFO, "output_fmt is %d\n", cmd->output_fmt);
+ jenc_pr(LOG_INFO, "input is 0x%x\n", cmd->src);
+ jenc_pr(LOG_INFO, "size is %d\n", cmd->framesize);
+ jenc_pr(LOG_INFO, "quality is %d\n", cmd->jpeg_quality);
+ jenc_pr(LOG_INFO, "quant tbl_id is %d\n", cmd->QuantTable_id);
+ jenc_pr(LOG_INFO, "flush flag is %d\n", cmd->flush_flag);
+ jenc_pr(LOG_INFO, "************end set input format**************\n");
- jenc_pr(LOG_INFO, "************begin set input format**************\n");
- jenc_pr(LOG_INFO, "type is %d\n", cmd->type);
- jenc_pr(LOG_INFO, "input_fmt is %d\n", cmd->input_fmt);
- jenc_pr(LOG_INFO, "output_fmt is %d\n", cmd->output_fmt);
- jenc_pr(LOG_INFO, "input is 0x%x\n", cmd->src);
- jenc_pr(LOG_INFO, "size is %d\n", cmd->framesize);
- jenc_pr(LOG_INFO, "quality is %d\n", cmd->jpeg_quality);
- jenc_pr(LOG_INFO, "quant tbl_id is %d\n", cmd->QuantTable_id);
- jenc_pr(LOG_INFO, "flush flag is %d\n", cmd->flush_flag);
- jenc_pr(LOG_INFO, "block mode is %d\n", cmd->block_mode);
- jenc_pr(LOG_INFO, "************end set input format**************\n");
+ if ((cmd->input_fmt == JPEGENC_FMT_RGB565)
+ || (cmd->input_fmt >= JPEGENC_MAX_FRAME_FMT))
+ return -1;
- if ((cmd->type == JPEGENC_LOCAL_BUFF) ||
- (cmd->type == JPEGENC_DMA_BUFF) ||
- (cmd->type == JPEGENC_PHYSICAL_BUFF)) {
+ picsize_x = ((cmd->encoder_width + 15) >> 4) << 4;
+ picsize_y = ((cmd->encoder_height + 15) >> 4) << 4;
+ if (cmd->output_fmt == JPEGENC_FMT_YUV422_SINGLE)
+ oformat = 1;
+ else
+ oformat = 0;
+ if ((cmd->type == JPEGENC_LOCAL_BUFF) ||
+ (cmd->type == JPEGENC_PHYSICAL_BUFF)) {
+ if (cmd->type == JPEGENC_LOCAL_BUFF) {
+ if (cmd->flush_flag & JPEGENC_FLUSH_FLAG_INPUT)
+ dma_flush(wq->InputBuffStart,
+ cmd->framesize);
+ input = wq->InputBuffStart;
+ }
+ if ((cmd->input_fmt <= JPEGENC_FMT_YUV444_PLANE) ||
+ (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT))
+ r2y_en = 0;
+ else
+ r2y_en = 1;
- if (cmd->type == JPEGENC_LOCAL_BUFF) {
- if (cmd->flush_flag & JPEGENC_FLUSH_FLAG_INPUT)
- dma_flush(wq->InputBuffStart, cmd->framesize);
- }
+ if (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT) {
+ iformat = 7;
+ ifmt_extra =
+ cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
+ if (cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
+ canvas_w = picsize_x * 24 / 8;
+ else if (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
+ canvas_w = picsize_x * 32 / 8;
+ else
+ canvas_w = (picsize_x * 20 + 7) / 8;
+ canvas_w = ((canvas_w + 31) >> 5) << 5;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ input = ENC_CANVAS_OFFSET;
+ input = input & 0xff;
+ } else if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
+ iformat = 0;
+ canvas_w = picsize_x * 2;
+ canvas_w = ((canvas_w + 31) >> 5) << 5;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ input = ENC_CANVAS_OFFSET;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE)
+ || (cmd->input_fmt == JPEGENC_FMT_RGB888)) {
+ iformat = 1;
+ if (cmd->input_fmt == JPEGENC_FMT_RGB888)
+ r2y_en = 1;
+ canvas_w = picsize_x * 3;
+ canvas_w = ((canvas_w + 31) >> 5) << 5;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ input = ENC_CANVAS_OFFSET;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
+ || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
+ canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
+ iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
- if (cmd->type == JPEGENC_LOCAL_BUFF || cmd->type == JPEGENC_DMA_BUFF)
- input = wq->InputBuffStart;
+ canvas_config(ENC_CANVAS_OFFSET + 1,
+ input + canvas_w * picsize_y, canvas_w,
+ picsize_y / 2, CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
- picsize_x = ((cmd->encoder_width + 15) >> 4) << 4;
- picsize_y = ((cmd->encoder_height + 15) >> 4) << 4;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- /*
- * mfdin in fmt: 0:422 single, 1:444 single, 2:NV21, 3:NV12, 4:420 plane, 5:444 plane
- * mfdin out fmt: 0:420, 1:422, 2:444
- * picture fmt: 0:RGB, 1:444, 2:422, 3:420
- * (out, pic) : (0,3), (1,2), (2,1)
- */
- if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE)
- iformat = 0;
-
- else if (cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE)
- iformat = 1;
-
- else if (cmd->input_fmt == JPEGENC_FMT_NV21)
- iformat = 2;
-
- else if (cmd->input_fmt == JPEGENC_FMT_NV12)
- iformat = 3;
-
- else if (cmd->input_fmt == JPEGENC_FMT_YUV420)
- iformat = 4;
-
- else if (cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
- iformat = 5;
-
- if (cmd->output_fmt == JPEGENC_FMT_YUV420)
- oformat = 0;
- else if (cmd->output_fmt == JPEGENC_FMT_YUV422_SINGLE)
- oformat = 1;
- else if (cmd->output_fmt == JPEGENC_FMT_YUV444_SINGLE)
- oformat = 2;
-
- block_mode = cmd->block_mode;
- mfdin_canvas0_stride = cmd->y_stride;
- mfdin_canvas1_stride = cmd->u_stride;
- mfdin_canvas2_stride = cmd->v_stride;
- mfdin_canvas_height = cmd->h_stride;
-
- if (simulation_enable) {
- if (g_block_mode)
- block_mode = g_block_mode;
- if (g_canv0_stride)
- mfdin_canvas0_stride = g_canv0_stride;
- if (g_canv1_stride)
- mfdin_canvas1_stride = g_canv1_stride;
- if (g_canv2_stride)
- mfdin_canvas2_stride = g_canv2_stride;
- if (g_canvas_height)
- mfdin_canvas_height = g_canvas_height;
- }
-
- if (block_mode) {
- mfdin_canvas0_blkmode = 1;
- mfdin_canvas1_blkmode = 1;
- mfdin_canvas2_blkmode = 1;
- } else {
- mfdin_canvas0_blkmode = 0;
- mfdin_canvas1_blkmode = 0;
- mfdin_canvas2_blkmode = 0;
- }
-
- if ((iformat == 0 && oformat == 0) || /*case1013, 422 single -> 420*/
- (iformat == 0 && oformat == 1) || /*case1002, 422 single -> 422*/
- (iformat == 0 && oformat == 2) || /*case1004, 422 single -> 444*/
- (iformat == 1 && oformat == 1) || /*case1003, 444 single -> 444*/
- (iformat == 1 && oformat == 0) ||
- (iformat == 1 && oformat == 2)) { /*case1005, 444 single -> 444*/
- mfdin_canvas0_addr = input;
- mfdin_canvas1_addr = input;
- mfdin_canvas2_addr = input;
-
- if (iformat == 0) {
- mfdin_canvas0_stride = cmd->y_stride * 2;
- mfdin_canvas1_stride = cmd->u_stride * 2;
- mfdin_canvas2_stride = cmd->v_stride * 3;
- } else if (iformat == 1) {
- mfdin_canvas0_stride = cmd->y_stride * 3;
- mfdin_canvas1_stride = cmd->u_stride * 3;
- mfdin_canvas2_stride = cmd->v_stride * 3;
- }
- } else if ((iformat == 2 && oformat == 0) ||
- (iformat == 3 && oformat == 0) || /*case1001, NV21 -> 420*/
- (iformat == 3 && oformat == 1) || /*case1000, NV21 -> 422*/
- (iformat == 3 && oformat == 2) || /*case1006, NV21 -> 444*/
- (iformat == 2 && oformat == 2) ||
- (iformat == 2 && oformat == 1)) { /*case1006, NV12 -> 444, linear*/
- mfdin_canvas0_addr = input;
- mfdin_canvas1_addr = input + mfdin_canvas0_stride * mfdin_canvas_height;
- mfdin_canvas2_addr = mfdin_canvas1_addr;
- } else if ((iformat == 4 && oformat == 0) || /*case1010, 420 plane -> 420*/
- (iformat == 4 && oformat == 2) ||
- (iformat == 4 && oformat == 1)) { /*case1008, case1011, case1012, 420 plane -> 444*/
- if (!simulation_enable) {
- mfdin_canvas1_stride = mfdin_canvas0_stride / 2;
- mfdin_canvas2_stride = mfdin_canvas0_stride / 2;
- }
- mfdin_canvas0_addr = input;
- mfdin_canvas1_addr = input + mfdin_canvas0_stride * mfdin_canvas_height;
-
- mfdin_canvas2_addr = input + mfdin_canvas0_stride * mfdin_canvas_height +
- mfdin_canvas0_stride * mfdin_canvas_height / 4;
-
- jenc_pr(LOG_INFO, "%x:%x:%x, mfdin_canvas0_stride=%d, mfdin_canvas1_stride=%d, mfdin_canvas2_stride=%d, mfdin_canvas_height=%d\n",
- mfdin_canvas0_addr, mfdin_canvas1_addr, mfdin_canvas2_addr,
- mfdin_canvas0_stride,
- mfdin_canvas1_stride,
- mfdin_canvas2_stride,
- mfdin_canvas_height);
-
- jenc_pr(LOG_INFO, "process yuv420p input, uoff=%d, voff=%d\n",
- mfdin_canvas0_stride * mfdin_canvas_height,
- mfdin_canvas0_stride * mfdin_canvas_height +
- mfdin_canvas0_stride * mfdin_canvas_height / 4);
- } else if (iformat == 4 && oformat == 1) { /*case1009, 420 plane -> 422*/
- if (!simulation_enable) {
- mfdin_canvas1_stride = mfdin_canvas0_stride / 2;
- mfdin_canvas2_stride = mfdin_canvas0_stride / 2;
- }
- mfdin_canvas0_addr = input;
- mfdin_canvas1_addr = input + mfdin_canvas0_stride * mfdin_canvas_height;
- mfdin_canvas2_addr = input + mfdin_canvas0_stride * mfdin_canvas_height +
- mfdin_canvas0_stride * mfdin_canvas_height / 4;
-
- //mfdin_canvas_bias = mfdin_canvas1_stride << 16;
- } else if (iformat == 5 /*&& oformat == 0*/) { /*case1007, 444 plane -> 420*/
- mfdin_canvas1_stride = mfdin_canvas0_stride;
- mfdin_canvas2_stride = mfdin_canvas0_stride;
- mfdin_canvas0_addr = input;
- mfdin_canvas1_addr = input + mfdin_canvas0_stride * mfdin_canvas_height;
- mfdin_canvas2_addr = mfdin_canvas1_addr + mfdin_canvas1_stride * mfdin_canvas_height;
- //mfdin_big_endian = true;
- } else {
- pr_err("config input or output format err!\n");
- return -1;
- }
-
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- if ((cmd->input_fmt == JPEGENC_FMT_RGB565)
- || (cmd->input_fmt >= JPEGENC_MAX_FRAME_FMT))
- return -1;
-
- if (cmd->output_fmt == JPEGENC_FMT_YUV420) {
- oformat = 0;
- } else if (cmd->output_fmt == JPEGENC_FMT_YUV422_SINGLE) {
- oformat = 1;
- } else if (cmd->output_fmt == JPEGENC_FMT_YUV444_SINGLE) {
- oformat = 2;
- }
-
- if ((cmd->input_fmt <= JPEGENC_FMT_YUV444_PLANE) ||
- (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT))
- r2y_en = 0;
- else
- r2y_en = 1;
-
- if (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT) {
- iformat = 7;
- ifmt_extra =
- cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
-
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
-
- if (cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
- canvas_w = picsize_x * 24 / 8;
- else if (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
- canvas_w = picsize_x * 32 / 8;
- else
- canvas_w = (picsize_x * 20 + 7) / 8;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
- input = input & 0xff;
- #endif
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
- iformat = 0;
-
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = picsize_x * 2;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
- #endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE)
- || (cmd->input_fmt == JPEGENC_FMT_RGB888)) {
- iformat = 1;
- if (cmd->input_fmt == JPEGENC_FMT_RGB888)
- r2y_en = 1;
-
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = picsize_x * 3;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
- #endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
- || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
- iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 1,
- input + canvas_w * picsize_y, canvas_w,
- picsize_y / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
- #endif
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
- iformat = 4;
-
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 63) >> 6) << 6;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y,
- canvas_w / 2, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y * 5 / 4,
- canvas_w / 2, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 2) << 16) |
- ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
- #endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
- || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
- iformat = 5;
- if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
- r2y_en = 1;
-
- #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 1,
- input + canvas_w * picsize_y, canvas_w,
- picsize_y, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y * 2,
- canvas_w, picsize_y, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 2) << 16) |
- ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
- #endif
- } else if (cmd->input_fmt == JPEGENC_FMT_RGBA8888) {
- iformat = 12;
- r2y_en = 1;
- }
- ret = 0;
- }
-
- } else {
- if ((cmd->input_fmt == JPEGENC_FMT_RGB565)
- || (cmd->input_fmt >= JPEGENC_MAX_FRAME_FMT))
- return -1;
-
- if (cmd->output_fmt == JPEGENC_FMT_YUV422_SINGLE)
- oformat = 1;
- else
- oformat = 0;
-
- if ((cmd->input_fmt <= JPEGENC_FMT_YUV444_PLANE) ||
- (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT))
- r2y_en = 0;
- else
- r2y_en = 1;
-
- if (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT) {
- iformat = 7;
- ifmt_extra =
- cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- if (cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
- canvas_w = picsize_x * 24 / 8;
- else if (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
- canvas_w = picsize_x * 32 / 8;
- else
- canvas_w = (picsize_x * 20 + 7) / 8;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
- input = input & 0xff;
-#endif
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
- iformat = 0;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = picsize_x * 2;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
-#endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE)
- || (cmd->input_fmt == JPEGENC_FMT_RGB888)) {
- iformat = 1;
- if (cmd->input_fmt == JPEGENC_FMT_RGB888)
- r2y_en = 1;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = picsize_x * 3;
- canvas_w = ((canvas_w + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ENC_CANVAS_OFFSET;
-#endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
- || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
- iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 1,
- input + canvas_w * picsize_y, canvas_w,
- picsize_y / 2, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
-#endif
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
- iformat = 4;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 63) >> 6) << 6;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y,
- canvas_w / 2, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y * 5 / 4,
- canvas_w / 2, picsize_y / 2,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 2) << 16) |
- ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
-#endif
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
- || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
- iformat = 5;
- if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
- r2y_en = 1;
-
-#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
- canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
- canvas_config_proxy(ENC_CANVAS_OFFSET,
- input,
- canvas_w, picsize_y,
- CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 1,
- input + canvas_w * picsize_y, canvas_w,
- picsize_y, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- canvas_config_proxy(ENC_CANVAS_OFFSET + 2,
- input + canvas_w * picsize_y * 2,
- canvas_w, picsize_y, CANVAS_ADDR_NOWRAP,
- CANVAS_BLKMODE_LINEAR);
- input = ((ENC_CANVAS_OFFSET + 2) << 16) |
- ((ENC_CANVAS_OFFSET + 1) << 8) |
- ENC_CANVAS_OFFSET;
-#endif
- } else if (cmd->input_fmt == JPEGENC_FMT_RGBA8888) {
- iformat = 12;
- r2y_en = 1;
- }
- }
- ret = 0;
- } else if (cmd->type == JPEGENC_CANVAS_BUFF) {
- r2y_en = 0;
- if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
- iformat = 0;
- input = input & 0xff;
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE) {
- iformat = 1;
- input = input & 0xff;
- } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
- || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
- iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
- input = input & 0xffff;
- } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
- iformat = 4;
- input = input & 0xffffff;
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
- || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
- if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
- r2y_en = 1;
- iformat = 5;
- input = input & 0xffffff;
- } else if ((cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
- || (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
- || (cmd->input_fmt == JPEGENC_FMT_YUV422_10BIT)) {
- iformat = 7;
- ifmt_extra = cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
- input = input & 0xff;
- } else
- ret = -1;
- }
-
- if (ret == 0)
- mfdin_basic_jpeg(input, iformat, oformat,
- picsize_x, picsize_y, r2y_en, ifmt_extra,
- mfdin_canvas0_stride,
- mfdin_canvas1_stride,
- mfdin_canvas2_stride,
- mfdin_canvas0_blkmode,
- mfdin_canvas1_blkmode,
- mfdin_canvas2_blkmode,
- mfdin_canvas0_addr,
- mfdin_canvas1_addr,
- mfdin_canvas2_addr,
- mfdin_canvas_bias,
- mfdin_big_endian);
- return ret;
+ input = ((ENC_CANVAS_OFFSET + 1) << 8) | ENC_CANVAS_OFFSET;
+ } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
+ iformat = 4;
+ canvas_w = ((cmd->encoder_width + 63) >> 6) << 6;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(ENC_CANVAS_OFFSET + 2,
+ input + canvas_w * picsize_y,
+ canvas_w / 2, picsize_y / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(ENC_CANVAS_OFFSET + 2,
+ input + canvas_w * picsize_y * 5 / 4,
+ canvas_w / 2, picsize_y / 2,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ input = ((ENC_CANVAS_OFFSET + 2) << 16) |
+ ((ENC_CANVAS_OFFSET + 1) << 8) |
+ ENC_CANVAS_OFFSET;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
+ || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
+ iformat = 5;
+ if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
+ r2y_en = 1;
+ canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
+ canvas_config(ENC_CANVAS_OFFSET,
+ input,
+ canvas_w, picsize_y,
+ CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(ENC_CANVAS_OFFSET + 1,
+ input + canvas_w * picsize_y, canvas_w,
+ picsize_y, CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ canvas_config(ENC_CANVAS_OFFSET + 2,
+ input + canvas_w * picsize_y * 2,
+ canvas_w, picsize_y, CANVAS_ADDR_NOWRAP,
+ CANVAS_BLKMODE_LINEAR);
+ input = ((ENC_CANVAS_OFFSET + 2) << 16) |
+ ((ENC_CANVAS_OFFSET + 1) << 8) |
+ ENC_CANVAS_OFFSET;
+ } else if (cmd->input_fmt == JPEGENC_FMT_RGBA8888) {
+ iformat = 12;
+ r2y_en = 1;
+ }
+ ret = 0;
+ } else if (cmd->type == JPEGENC_CANVAS_BUFF) {
+ r2y_en = 0;
+ if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
+ iformat = 0;
+ input = input & 0xff;
+ } else if (cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE) {
+ iformat = 1;
+ input = input & 0xff;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
+ || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
+ iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
+ input = input & 0xffff;
+ } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
+ iformat = 4;
+ input = input & 0xffffff;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
+ || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
+ if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
+ r2y_en = 1;
+ iformat = 5;
+ input = input & 0xffffff;
+ } else if ((cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
+ || (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
+ || (cmd->input_fmt == JPEGENC_FMT_YUV422_10BIT)) {
+ iformat = 7;
+ ifmt_extra = cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
+ input = input & 0xff;
+ } else
+ ret = -1;
+ }
+ if (ret == 0)
+ mfdin_basic_jpeg(input, iformat, oformat,
+ picsize_x, picsize_y, r2y_en, ifmt_extra);
+ return ret;
}
static void jpegenc_isr_tasklet(ulong data)
{
- struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)data;
-
- jenc_pr(LOG_INFO, "encoder is done %d\n", manager->encode_hw_status);
-
- if ((manager->encode_hw_status == JPEGENC_ENCODER_DONE)
- && (manager->process_irq)) {
- manager->wq.hw_status = manager->encode_hw_status;
- manager->wq.output_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES);
- jenc_pr(LOG_INFO, "encoder size %d\n", manager->wq.output_size);
- atomic_inc(&manager->wq.ready);
- wake_up_interruptible(&manager->wq.complete);
- }
+ struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)data;
+ jenc_pr(LOG_INFO, "encoder is done %d\n", manager->encode_hw_status);
+ if ((manager->encode_hw_status == JPEGENC_ENCODER_DONE)
+ && (manager->process_irq)) {
+ manager->wq.hw_status = manager->encode_hw_status;
+ manager->wq.output_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES);
+ jenc_pr(LOG_INFO, "encoder size %d\n", manager->wq.output_size);
+ atomic_inc(&manager->wq.ready);
+ wake_up_interruptible(&manager->wq.complete);
+ }
}
static irqreturn_t jpegenc_isr(s32 irq_number, void *para)
{
- struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)para;
- jenc_pr(LOG_ALL, "jpegenc intr is fired\n");
-
- if (manager->irq_requested == false)
- return IRQ_NONE;
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
- else
- WRITE_HREG(HCODEC_ASSIST_MBOX0_CLR_REG, 1);
- } else
- WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
-
- manager->encode_hw_status = READ_HREG(JPEGENC_ENCODER_STATUS);
-
- if (manager->encode_hw_status == JPEGENC_ENCODER_DONE) {
- jpegenc_time_count_end(&time_cnt);
- manager->process_irq = true;
- tasklet_schedule(&manager->tasklet);
- }
-
- return IRQ_HANDLED;
+ struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)para;
+ jenc_pr(LOG_INFO, "*****JPEGENC_ISR*****");
+ WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
+ manager->encode_hw_status = READ_HREG(JPEGENC_ENCODER_STATUS);
+ if (manager->encode_hw_status == JPEGENC_ENCODER_DONE) {
+ manager->process_irq = true;
+ tasklet_schedule(&manager->tasklet);
+ }
+ return IRQ_HANDLED;
}
static void jpegenc_start(void)
{
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- WRITE_VREG(DOS_SW_RESET1, (1 << 12) | (1 << 11));
- WRITE_VREG(DOS_SW_RESET1, 0);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- WRITE_HREG(HCODEC_MPSR, 0x0001);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ WRITE_VREG(DOS_SW_RESET1, (1 << 12) | (1 << 11));
+ WRITE_VREG(DOS_SW_RESET1, 0);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
+ WRITE_HREG((HCODEC_MFDIN_REG7_SCMD - 8), (1 << 28)),
+
+ WRITE_HREG(HCODEC_MPSR, 0x0001);
}
static void _jpegenc_stop(void)
{
- ulong timeout = jiffies + HZ;
+ ulong timeout = jiffies + HZ;
- WRITE_HREG(HCODEC_MPSR, 0);
- WRITE_HREG(HCODEC_CPSR, 0);
+ WRITE_HREG(HCODEC_MPSR, 0);
+ WRITE_HREG(HCODEC_CPSR, 0);
+ while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
+ if (time_after(jiffies, timeout))
+ break;
+ }
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
- while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
- if (time_after(jiffies, timeout))
- break;
- }
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
+ WRITE_VREG(DOS_SW_RESET1,
+ (1 << 12) | (1 << 11) |
+ (1 << 2) | (1 << 6) |
+ (1 << 7) | (1 << 8) |
+ (1 << 14) | (1 << 16) |
+ (1 << 17));
+ else
+ WRITE_VREG(DOS_SW_RESET1,
+ (1 << 12) | (1 << 11) |
+ (1 << 2) | (1 << 6) |
+ (1 << 7) | (1 << 8) |
+ (1 << 16) | (1 << 17));
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- WRITE_VREG(DOS_SW_RESET1,
- (1 << 12) | (1 << 11) |
- (1 << 2) | (1 << 6) |
- (1 << 7) | (1 << 8) |
- (1 << 14) | (1 << 16) |
- (1 << 17));
- else
- WRITE_VREG(DOS_SW_RESET1,
- (1 << 12) | (1 << 11) |
- (1 << 2) | (1 << 6) |
- (1 << 7) | (1 << 8) |
- (1 << 16) | (1 << 17));
+ WRITE_VREG(DOS_SW_RESET1, 0);
- WRITE_VREG(DOS_SW_RESET1, 0);
-
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
-}
-
-static void dump_mem(u8 *addr) {
- int i;
- u8 *offset = addr;
-
- for (i=0;i<dumpmem_line;i++) {
- offset += i * 8;
- pr_err("%#x\t%#x\t%#x\t%#x\t%#x\t%#x\t%#x\t%#x\n",
- *(offset+0), *(offset+1), *(offset+2), *(offset+3),
- *(offset+4), *(offset+5), *(offset+6), *(offset+7));
- }
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
}
static void __iomem *mc_addr;
@@ -3379,1488 +2768,966 @@
#define MC_SIZE (4096 * 4)
s32 jpegenc_loadmc(const char *p)
{
- ulong timeout;
- s32 ret = 0;
- //int i=0;
+ ulong timeout;
+ s32 ret = 0;
- /* use static mempry*/
- if (mc_addr == NULL) {
- mc_addr = kmalloc(MC_SIZE, GFP_KERNEL);
+ /* use static mempry*/
+ if (mc_addr == NULL) {
+ mc_addr = kmalloc(MC_SIZE, GFP_KERNEL);
+ if (!mc_addr) {
+ jenc_pr(LOG_ERROR,
+ "jpegenc loadmc iomap mc addr error.\n");
+ return -ENOMEM;
+ }
+ }
- if (!mc_addr) {
- jenc_pr(LOG_ERROR, "jpegenc loadmc iomap mc addr error.\n");
- return -ENOMEM;
- }
- memset(mc_addr, 0, MC_SIZE);
- }
+#ifdef KER49
+ ret = get_decoder_firmware_data(VFORMAT_JPEG_ENC, p,
+ (u8 *)mc_addr, MC_SIZE);
+#else
+ ret = get_data_from_name(p, (u8 *)mc_addr);
+#endif
+ if (ret < 0) {
+ jenc_pr(LOG_ERROR,
+ "jpegenc microcode fail ret=%d, name: %s.\n",
+ ret, p);
+ }
- //ret = get_data_from_name("c1_jpeg_enc", (u8 *)mc_addr);
- ret = get_firmware_data(VIDEO_ENC_JPEG, (u8 *)mc_addr);
+ mc_addr_map = dma_map_single(
+ &gJpegenc.this_pdev->dev,
+ mc_addr, MC_SIZE, DMA_TO_DEVICE);
- dump_mem(mc_addr);
+ WRITE_HREG(HCODEC_MPSR, 0);
+ WRITE_HREG(HCODEC_CPSR, 0);
- if (ret < 0)
- jenc_pr(LOG_ERROR, "jpegenc microcode fail ret=%d, name: %s.\n", ret, p);
+ /* Read CBUS register for timing */
+ timeout = READ_HREG(HCODEC_MPSR);
+ timeout = READ_HREG(HCODEC_MPSR);
- mc_addr_map = dma_map_single(&gJpegenc.this_pdev->dev, mc_addr, MC_SIZE, DMA_TO_DEVICE);
+ timeout = jiffies + HZ;
- WRITE_HREG(HCODEC_MPSR, 0);
- WRITE_HREG(HCODEC_CPSR, 0);
+ WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map);
+ WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000);
+ WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
- /* Read CBUS register for timing */
- //timeout = READ_HREG(HCODEC_MPSR);
- //timeout = READ_HREG(HCODEC_MPSR);
- timeout = jiffies + HZ;
- WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map);
- WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000);
+ while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
+ if (time_before(jiffies, timeout))
+ schedule();
+ else {
+ jenc_pr(LOG_ERROR, "hcodec load mc error\n");
+ ret = -EBUSY;
+ break;
+ }
+ }
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (0xf << 16))); // ucode test c is 0x8000 | (0xf << 16)
- else if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- pr_err("t3 HCODEC_IMEM_DMA_CTRL (0x8000 | (0 & 0xffff))\n");
- WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (0 & 0xffff))); // Endian : 4'b1000);
- } else
- WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (0 & 0xffff))); // Endian : 4'b1000);
-
- while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
- if (time_before(jiffies, timeout)) {
- schedule();
- } else {
- jenc_pr(LOG_ERROR, "hcodec load mc error\n");
- ret = -EBUSY;
- break;
- }
- }
-
- dma_unmap_single(&gJpegenc.this_pdev->dev, mc_addr_map, MC_SIZE, DMA_TO_DEVICE);
- return ret;
+ dma_unmap_single(
+ &gJpegenc.this_pdev->dev,
+ mc_addr_map, MC_SIZE, DMA_TO_DEVICE);
+ return ret;
}
-static s32 jpegenc_poweron_ex(u32 clock)
-{
- u32 frq;
-
- if (clock == 1)
- frq = 200;
- else if (clock == 3)
- frq = 300;
- else
- frq = 400;
-
- jpeg_enc_clk_enable(&g_jpeg_enc_clks, frq);
-
- /* Powerup HCODEC memories */
- WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("powering on hcodec\n");
- vdec_poweron(VDEC_HCODEC);
- pr_err("hcodec power status after poweron:%d\n", vdec_on(VDEC_HCODEC));
- } else {
- pwr_ctrl_psci_smc(PDID_T7_DOS_HCODEC, true);
- }
-
- /*
- * [21] hcodec clk_en for henc qdct
- * [20] hcodec clk_en for henc vlc
- * [19] hcodec clk_en for assist and cbus
- * [18] hcodec clk_en for ddr
- * [17] hcodec clk_en for vcpu
- * [16] hcodec clk_en for hdec assist
- * [15] hcodec clk_en for hdec dblk
- * [14] reserved
- * [13] hcodec clk_en for hdec mc
- * [12] hcodec clk_en for hdec pic_dc
- */
- WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);
-
- return 0;
-}
-
-static s32 jpegenc_poweroff_ex(void)
-{
- WRITE_VREG_BITS(DOS_GCLK_EN0, 0, 12, 15);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("powering off hcodec for t7\n");
- vdec_poweroff(VDEC_HCODEC);
- pr_err("hcodec power status after poweroff:%d\n", vdec_on(VDEC_HCODEC));
- } else
- pwr_ctrl_psci_smc(PDID_T7_DOS_HCODEC, false);
-
- /* power off HCODEC memories */
- WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
-
- jpeg_enc_clk_disable(&g_jpeg_enc_clks);
-
- return 0;
-}
-
-#if 0
+/*
bool jpegenc_on(void)
{
- bool hcodec_on;
- ulong flags;
+ bool hcodec_on;
+ ulong flags;
- spin_lock_irqsave(&lock, flags);
+ spin_lock_irqsave(&lock, flags);
- hcodec_on = vdec_on(VDEC_HCODEC);
- hcodec_on &= (gJpegenc.opened > 0);
+ hcodec_on = vdec_on(VDEC_HCODEC);
+ hcodec_on &= (gJpegenc.opened > 0);
- spin_unlock_irqrestore(&lock, flags);
- return hcodec_on;
+ spin_unlock_irqrestore(&lock, flags);
+ return hcodec_on;
}
-#endif
-
+*/
static s32 jpegenc_poweron(u32 clock)
{
- //ulong flags;
- u32 data32;
+ ulong flags;
+ u32 data32;
- //spin_lock_irqsave(&lock, flags);
+ data32 = 0;
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_C1) {
- data32 = 0;
- amports_switch_gate("vdec", 1);
+ amports_switch_gate("vdec", 1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
- WRITE_AOREG(AO_RTI_PWR_CNTL_REG0,
- (READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18)));
- udelay(10);
- /* Powerup HCODEC */
- /* [1:0] HCODEC */
- WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
- (READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) & (~0x3)));
- udelay(10);
- }
+ spin_lock_irqsave(&lock, flags);
- WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
- WRITE_VREG(DOS_SW_RESET1, 0);
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ jpegenc_clk_config(1);
- /* Enable Dos internal clock gating */
- jpegenc_clock_enable(clock);
+ pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_ON);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
- /* Powerup HCODEC memories */
- WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
+ //hvdec_clock_enable(clock);
+ } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
+ WRITE_AOREG(AO_RTI_PWR_CNTL_REG0,
+ (READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18)));
+ udelay(10);
+ /* Powerup HCODEC */
+ /* [1:0] HCODEC */
+ WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
+ READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
+ ((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
+ get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
+ ? ~0x1 : ~0x3));
+ udelay(10);
+ }
- /* Remove HCODEC ISO */
- WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
- (READ_AOREG(AO_RTI_GEN_PWR_ISO0) & (~0x30)));
- udelay(10);
- }
- /* Disable auto-clock gate */
- WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) | 0x1));
- WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE));
- } else {
- jpegenc_poweron_ex(clock);
- }
- //spin_unlock_irqrestore(&lock, flags);
+ WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
+ WRITE_VREG(DOS_SW_RESET1, 0);
- mdelay(10);
- return 0;
+ /* Enable Dos internal clock gating */
+ jpegenc_clock_enable(clock);
+
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
+ /* Powerup HCODEC memories */
+ WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
+
+ /* Remove HCODEC ISO */
+ WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
+ READ_AOREG(AO_RTI_GEN_PWR_ISO0) &
+ ((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
+ get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
+ ? ~0x1 : ~0x30));
+ udelay(10);
+ }
+ /* Disable auto-clock gate */
+ WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) | 0x1));
+ WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE));
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ mdelay(10);
+ return 0;
}
static s32 jpegenc_poweroff(void)
{
- //ulong flags;
- //spin_lock_irqsave(&lock, flags);
+ ulong flags;
- if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_C1) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
- /* enable HCODEC isolation */
- WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
- READ_AOREG(AO_RTI_GEN_PWR_ISO0) | 0x30);
- /* power off HCODEC memories */
- WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
- }
- /* disable HCODEC clock */
- jpegenc_clock_disable();
+ spin_lock_irqsave(&lock, flags);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
- /* HCODEC power off */
- WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
- READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 0x3);
- }
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ jpegenc_clk_config(0);
+ pwr_ctrl_psci_smc(PDID_DOS_HCODEC, PWR_OFF);
+ //hvdec_clock_disable();
+ LOG_LINE();
+ } else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
+ /* enable HCODEC isolation */
+ WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
+ READ_AOREG(AO_RTI_GEN_PWR_ISO0) | 0x30);
+ /* power off HCODEC memories */
+ WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
+ }
+ /* disable HCODEC clock */
+ jpegenc_clock_disable();
- /* release DOS clk81 clock gating */
- amports_switch_gate("vdec", 0);
- } else {
- jpegenc_poweroff_ex();
- }
- //spin_unlock_irqrestore(&lock, flags);
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
+ /* HCODEC power off */
+ WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
+ READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 0x3);
+ }
- return 0;
+ spin_unlock_irqrestore(&lock, flags);
+
+ /* release DOS clk81 clock gating */
+ amports_switch_gate("vdec", 0);
+ return 0;
}
void jpegenc_reset(void)
{
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- WRITE_VREG(DOS_SW_RESET1,
- (1 << 2) | (1 << 6) |
- (1 << 7) | (1 << 8) |
- (1 << 14) | (1 << 16) |
- (1 << 17));
- else
- WRITE_VREG(DOS_SW_RESET1,
- (1 << 2) | (1 << 6) | (1 << 7) |
- (1 << 8) | (1 << 16) | (1 << 17));
- WRITE_VREG(DOS_SW_RESET1, 0);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
- READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
+ WRITE_VREG(DOS_SW_RESET1,
+ (1 << 2) | (1 << 6) |
+ (1 << 7) | (1 << 8) |
+ (1 << 14) | (1 << 16) |
+ (1 << 17));
+ else
+ WRITE_VREG(DOS_SW_RESET1,
+ (1 << 2) | (1 << 6) | (1 << 7) |
+ (1 << 8) | (1 << 16) | (1 << 17));
+ WRITE_VREG(DOS_SW_RESET1, 0);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
+ READ_VREG(DOS_SW_RESET1);
}
static s32 jpegenc_init(void)
{
- jpegenc_poweron(clock_level);
+ jpegenc_poweron(clock_level);
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_MG9TV) {
+ WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
+ } else {
+ WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x2);
+ }
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_MG9TV)
- WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
- else
- WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x2);
+ jenc_pr(LOG_ALL, "start to load microcode: %s\n", jpegenc_ucode[0]);
+ if (jpegenc_loadmc(jpegenc_ucode[0]) < 0)
+ return -EBUSY;
- jenc_pr(LOG_ALL, "start to load microcode\n");
+ jenc_pr(LOG_ALL, "succeed to load microcode\n");
+ gJpegenc.process_irq = false;
- if (!legacy_load && (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7 )) {
- char *buf = vmalloc(0x1000 * 16);
- int ret = -1;
- pr_err("load ucode\n");
- if (get_firmware_data(VIDEO_ENC_JPEG, buf) < 0) {
- //amvdec_disable();
- pr_err("get firmware for jpeg enc fail!\n");
- vfree(buf);
- return -1;
- }
- WRITE_HREG(HCODEC_MPSR, 0);
- WRITE_HREG(HCODEC_CPSR, 0);
- ret = amvdec_loadmc_ex(VFORMAT_JPEG_ENC, NULL, buf);
+ if (request_irq(gJpegenc.irq_num, jpegenc_isr, IRQF_SHARED,
+ "jpegenc-irq", (void *)&gJpegenc) == 0)
+ gJpegenc.irq_requested = true;
+ else
+ gJpegenc.irq_requested = false;
- if (ret < 0) {
- //amvdec_disable();
- vfree(buf);
- pr_err("jpegenc: the %s fw loading failed, err: %x\n",
- tee_enabled() ? "TEE" : "local", ret);
- return -EBUSY;
- }
- vfree(buf);
- } else {
- if (jpegenc_loadmc(jpegenc_ucode[0]) < 0)
- return -EBUSY;
- }
+ WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
- jenc_pr(LOG_ALL, "jpegenc load microcode success.\n");
- gJpegenc.process_irq = false;
+ gJpegenc.inited = true;
- if (request_irq(gJpegenc.irq_num, jpegenc_isr, IRQF_SHARED,
- "jpegenc-irq", (void *)&gJpegenc) == 0)
- gJpegenc.irq_requested = true;
- else
- gJpegenc.irq_requested = false;
-
- WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
- gJpegenc.inited = true;
- return 0;
+ return 0;
}
static s32 convert_cmd(struct jpegenc_wq_s *wq, u32 *cmd_info)
{
- if (!wq) {
- jenc_pr(LOG_ERROR, "jpegenc convert_cmd error\n");
- return -1;
- }
-
- memset(&wq->cmd, 0, sizeof(struct jpegenc_request_s));
- wq->cmd.type = cmd_info[0];
- wq->cmd.input_fmt = cmd_info[1];
- wq->cmd.output_fmt = cmd_info[2];
- wq->cmd.encoder_width = cmd_info[3];
- wq->cmd.encoder_height = cmd_info[4];
- wq->cmd.framesize = cmd_info[5];
- wq->cmd.src = cmd_info[6];
- wq->cmd.jpeg_quality = cmd_info[7];
- wq->cmd.QuantTable_id = cmd_info[8];
- wq->cmd.flush_flag = cmd_info[9];
- wq->cmd.block_mode = cmd_info[10];
-
- wq->cmd.y_stride = cmd_info[11];
- wq->cmd.u_stride = cmd_info[12];
- wq->cmd.v_stride = cmd_info[13];
- wq->cmd.h_stride = cmd_info[14];
- jenc_pr(LOG_DEBUG, "convert_cmd: ystride:%d, h_stride:%d\n",
- cmd_info[11], cmd_info[14]);
-
- if (is_oversize(wq->cmd.encoder_width,
- wq->cmd.encoder_height,
- wq->max_width * wq->max_height)) {
- jenc_pr(LOG_ERROR,
- "set encode size %dx%d is larger than supported (%dx%d).\n",
- wq->cmd.encoder_width,
- wq->cmd.encoder_height,
- wq->max_width,
- wq->max_height);
- return -1;
- }
-
- wq->cmd.jpeg_quality = jpeg_quality_scaling(wq->cmd.jpeg_quality);
- if (wq->cmd.QuantTable_id < 4) {
- jenc_pr(LOG_INFO,
- "JPEGENC_SEL_QUANT_TABLE : %d.\n",
- wq->cmd.QuantTable_id);
- } else {
- wq->cmd.QuantTable_id = 0;
- jenc_pr(LOG_ERROR,
- "JPEGENC_SEL_QUANT_TABLE invaild. target value: %d.\n",
- cmd_info[8]);
- }
- jenc_pr(LOG_INFO,
- "target quality : %d, jpeg_quality value: %d.\n",
- cmd_info[7], wq->cmd.jpeg_quality);
- return 0;
+ if (!wq) {
+ jenc_pr(LOG_ERROR, "jpegenc convert_cmd error\n");
+ return -1;
+ }
+ memset(&wq->cmd, 0, sizeof(struct jpegenc_request_s));
+ wq->cmd.type = cmd_info[0];
+ wq->cmd.input_fmt = cmd_info[1];
+ wq->cmd.output_fmt = cmd_info[2];
+ wq->cmd.encoder_width = cmd_info[3];
+ wq->cmd.encoder_height = cmd_info[4];
+ wq->cmd.framesize = cmd_info[5];
+ wq->cmd.src = cmd_info[6];
+ wq->cmd.jpeg_quality = cmd_info[7];
+ wq->cmd.QuantTable_id = cmd_info[8];
+ wq->cmd.flush_flag = cmd_info[9];
+ if ((wq->cmd.encoder_width > wq->max_width) ||
+ (wq->cmd.encoder_height > wq->max_height)) {
+ jenc_pr(LOG_ERROR,
+ "set encode size %dx%d is larger than supported (%dx%d).\n",
+ wq->cmd.encoder_width,
+ wq->cmd.encoder_height,
+ wq->max_width,
+ wq->max_height);
+ return -1;
+ }
+ wq->cmd.jpeg_quality = jpeg_quality_scaling((s32)cmd_info[7]);
+ if (wq->cmd.QuantTable_id < 4) {
+ jenc_pr(LOG_INFO,
+ "JPEGENC_SEL_QUANT_TABLE : %d.\n",
+ wq->cmd.QuantTable_id);
+ } else {
+ wq->cmd.QuantTable_id = 0;
+ jenc_pr(LOG_ERROR,
+ "JPEGENC_SEL_QUANT_TABLE invaild. target value: %d.\n",
+ cmd_info[8]);
+ }
+ jenc_pr(LOG_INFO,
+ "target quality : %d, jpeg_quality value: %d.\n",
+ cmd_info[7], wq->cmd.jpeg_quality);
+ return 0;
}
static void jpegenc_start_cmd(struct jpegenc_wq_s *wq)
{
- gJpegenc.process_irq = false;
- gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
+ gJpegenc.process_irq = false;
+ gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
- jpegenc_reset();
+ jpegenc_reset();
+ set_jpeg_input_format(wq, &wq->cmd);
- set_jpeg_input_format(wq, &wq->cmd);
+ init_jpeg_encoder(wq);
+ jpegenc_init_output_buffer(wq);
+ /* clear mailbox interrupt */
+ WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
- init_jpeg_encoder(wq);
-
- jpegenc_init_output_buffer(wq);
-
- /* clear mailbox interrupt */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
- else
- WRITE_HREG(HCODEC_ASSIST_MBOX0_CLR_REG, 1);
- } else
- WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
-
- /* enable mailbox interrupt */
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
- WRITE_HREG(HCODEC_ASSIST_MBOX2_MASK, 0xffffffff);
- else
- WRITE_HREG(HCODEC_ASSIST_MBOX0_MASK, 0xffffffff);
- } else
- WRITE_HREG(HCODEC_ASSIST_MBOX2_MASK, 1);
-
- gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
- WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
- gJpegenc.process_irq = false;
-
- time_cnt = jpegenc_time_count_start();
-
- jpegenc_start();
- jenc_pr(LOG_INFO, "jpegenc_start\n");
+ /* enable mailbox interrupt */
+ WRITE_HREG(HCODEC_ASSIST_MBOX2_MASK, 1);
+ gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
+ WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
+ gJpegenc.process_irq = false;
+ jpegenc_start();
+ jenc_pr(LOG_INFO, "jpegenc_start\n");
}
static void jpegenc_stop(void)
{
- if ((gJpegenc.irq_num >= 0) &&
- (gJpegenc.irq_requested == true)) {
- gJpegenc.irq_requested = false;
- free_irq(gJpegenc.irq_num, &gJpegenc);
- }
- _jpegenc_stop();
- jpegenc_poweroff();
- jenc_pr(LOG_INFO, "jpegenc_stop\n");
+ if ((gJpegenc.irq_num >= 0) &&
+ (gJpegenc.irq_requested == true)) {
+ free_irq(gJpegenc.irq_num, &gJpegenc);
+ gJpegenc.irq_requested = false;
+ }
+ _jpegenc_stop();
+ jpegenc_poweroff();
+ jenc_pr(LOG_INFO, "jpegenc_stop\n");
}
static void dma_flush(u32 buf_start, u32 buf_size)
{
- dma_sync_single_for_device(&gJpegenc.this_pdev->dev,
- buf_start, buf_size, DMA_TO_DEVICE);
+ dma_sync_single_for_device(&gJpegenc.this_pdev->dev,
+ buf_start, buf_size, DMA_TO_DEVICE);
}
static void cache_flush(u32 buf_start, u32 buf_size)
{
- dma_sync_single_for_cpu(&gJpegenc.this_pdev->dev,
- buf_start, buf_size, DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(&gJpegenc.this_pdev->dev,
+ buf_start, buf_size, DMA_FROM_DEVICE);
}
static s32 jpegenc_open(struct inode *inode, struct file *file)
{
- struct jpegenc_wq_s *wq;
- s32 r;
- pr_err("jpegenc open, filp=%lu\n", (unsigned long)file);
+ struct jpegenc_wq_s *wq;
+ s32 r;
+ jenc_pr(LOG_DEBUG, "jpegenc open\n");
+
#ifdef CONFIG_AM_ENCODER
- if (amvenc_avc_on() == true) {
- jenc_pr(LOG_ERROR, "hcodec in use for AVC Encode now.\n");
- return -EBUSY;
- }
+ if (amvenc_avc_on() == true) {
+ jenc_pr(LOG_ERROR, "hcodec in use for AVC Encode now.\n");
+ return -EBUSY;
+ }
#endif
- file->private_data = NULL;
- spin_lock(&gJpegenc.sem_lock);
- if (gJpegenc.opened > 0) {
- spin_unlock(&gJpegenc.sem_lock);
- jenc_pr(LOG_ERROR, "jpegenc open busy.\n");
- return -EBUSY;
- }
- wq = &gJpegenc.wq;
- wq->buf_start = gJpegenc.mem.buf_start;
- wq->buf_size = gJpegenc.mem.buf_size;
- gJpegenc.opened++;
- spin_unlock(&gJpegenc.sem_lock);
+ file->private_data = NULL;
+ spin_lock(&gJpegenc.sem_lock);
+
+ if (gJpegenc.opened > 0) {
+ spin_unlock(&gJpegenc.sem_lock);
+ jenc_pr(LOG_ERROR, "jpegenc open busy.\n");
+ return -EBUSY;
+ }
+
+ wq = &gJpegenc.wq;
+ wq->buf_start = gJpegenc.mem.buf_start;
+ wq->buf_size = gJpegenc.mem.buf_size;
+ gJpegenc.opened++;
+ spin_unlock(&gJpegenc.sem_lock);
#ifdef CONFIG_CMA
- if (gJpegenc.use_reserve == false) {
- if (gJpegenc.use_cma) {
- struct page *cma_pages;
- cma_pages = dma_alloc_from_contiguous(&gJpegenc.this_pdev->dev,
- gJpegenc.mem.buf_size >> PAGE_SHIFT, 0, true);
- if (cma_pages) {
- wq->buf_start = page_to_phys(cma_pages);
- wq->buf_size = gJpegenc.mem.buf_size;
- } else {
- jenc_pr(LOG_ERROR, "jpegenc - cma allocation failed\n");
- }
- }
+ jenc_pr(LOG_ERROR, "use_reserve:%d, gJpegenc.mem.buf_sizea:%u\n",
+ gJpegenc.use_reserve, gJpegenc.mem.buf_size);
- if (!wq->buf_start) {
- gJpegenc.use_cma = false;
- wq->buf_start = codec_mm_alloc_for_dma(DRIVER_NAME,
- gJpegenc.mem.buf_size >> PAGE_SHIFT, 0, 0);
- if (wq->buf_start) {
- wq->buf_size = gJpegenc.mem.buf_size;
- } else {
- jenc_pr(LOG_ERROR,
- "jpegenc - codec_mm allocation failed\n");
- spin_lock(&gJpegenc.sem_lock);
- gJpegenc.opened--;
- spin_unlock(&gJpegenc.sem_lock);
- return -ENOMEM;
- }
- }
- }
+ if (gJpegenc.use_reserve == false) {
+ /*wq->venc_pages = dma_alloc_from_contiguous(&gJpegenc.this_pdev->dev, gJpegenc.mem.buf_size >> PAGE_SHIFT, 0);
+ if (wq->venc_pages) {
+ wq->buf_start = page_to_phys(wq->venc_pages);
+ wq->buf_size = gJpegenc.mem.buf_size;
+ jenc_pr(LOG_DEBUG,
+ "allocating phys 0x%x, size %dk.\n",
+ wq->buf_start, wq->buf_size >> 10);
+ } else {
+ jenc_pr(LOG_ERROR,
+ "CMA failed to allocate dma buffer for %s.\n",
+ gJpegenc.this_pdev->name);
+ spin_lock(&gJpegenc.sem_lock);
+ gJpegenc.opened--;
+ spin_unlock(&gJpegenc.sem_lock);
+ return -ENOMEM;
+ }*/
+ wq->buf_start = codec_mm_alloc_for_dma(DRIVER_NAME, gJpegenc.mem.buf_size >> PAGE_SHIFT, 0, 0);
+
+ if (wq->buf_start) {
+ wq->buf_size = gJpegenc.mem.buf_size;
+
+ jenc_pr(LOG_ERROR,
+ "allocating phys 0x%x, sizeeee %dk\n",
+ wq->buf_start, wq->buf_size >> 10);//, codec_mm_vmap(wq->buf_start, wq->buf_size));
+ } else {
+ jenc_pr(LOG_ERROR,
+ "CMA failed to allocate dma buffer for %s.\n",
+ gJpegenc.this_pdev->name);
+ spin_lock(&gJpegenc.sem_lock);
+ gJpegenc.opened--;
+ spin_unlock(&gJpegenc.sem_lock);
+ return -ENOMEM;
+ }
+ }
#endif
- jenc_pr(LOG_DEBUG,
- "jpegenc - allocated from %s: start:0x%x, %d MB.\n",
- gJpegenc.use_reserve ? "reserved" :
- gJpegenc.use_cma ? "cma" : "codec_mm",
- wq->buf_start, gJpegenc.mem.buf_size / SZ_1M);
+ spin_lock(&gJpegenc.sem_lock);
+ init_waitqueue_head(&wq->complete);
+ atomic_set(&wq->ready, 0);
+ wq->AssitstreamStartVirtAddr = NULL;
+ memset(gQuantTable, 0, sizeof(gQuantTable));
+ wq->cmd.QuantTable_id = 0;
+ wq->cmd.jpeg_quality = 90;
+ wq->max_width = gJpegenc.mem.bufspec->max_width;
+ wq->max_height = gJpegenc.mem.bufspec->max_height;
+ wq->headbytes = 0;
+ file->private_data = (void *)wq;
- spin_lock(&gJpegenc.sem_lock);
- init_waitqueue_head(&wq->complete);
- atomic_set(&wq->ready, 0);
- wq->AssitstreamStartVirtAddr = NULL;
- memset(gQuantTable, 0, sizeof(gQuantTable));
- wq->cmd.QuantTable_id = 0;
- wq->cmd.jpeg_quality = 90;
- wq->max_width = gJpegenc.mem.bufspec->max_width;
- wq->max_height = gJpegenc.mem.bufspec->max_height;
- wq->headbytes = 0;
- file->private_data = (void *)wq;
#ifdef EXTEAN_QUANT_TABLE
- gExternalQuantTablePtr = NULL;
- external_quant_table_available = false;
+ gExternalQuantTablePtr = NULL;
+ external_quant_table_available = false;
#endif
- spin_unlock(&gJpegenc.sem_lock);
- r = 0;
-
- return r;
+ spin_unlock(&gJpegenc.sem_lock);
+ r = 0;
+ return r;
}
static s32 jpegenc_release(struct inode *inode, struct file *file)
{
- struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
+ struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
- if (wq != &gJpegenc.wq) {
- jenc_pr(LOG_ERROR, "jpegenc release error\n");
- return -1;
- }
- if (gJpegenc.inited) {
- jpegenc_stop();
- gJpegenc.inited = false;
- }
- if (wq->dma_input != NULL) {
- enc_dma_buf_unmap(wq->dma_input);
- kfree(wq->dma_input);
- wq->dma_input = NULL;
- }
- memset(gQuantTable, 0, sizeof(gQuantTable));
+ if (wq != &gJpegenc.wq) {
+ jenc_pr(LOG_ERROR, "jpegenc release error\n");
+ return -1;
+ }
+ if (gJpegenc.inited) {
+ jpegenc_stop();
+ gJpegenc.inited = false;
+ }
+ memset(gQuantTable, 0, sizeof(gQuantTable));
- if (wq->AssitstreamStartVirtAddr)
- wq->AssitstreamStartVirtAddr = NULL;
+ if (wq->AssitstreamStartVirtAddr)
+ wq->AssitstreamStartVirtAddr = NULL;
#ifdef CONFIG_CMA
- if (wq->buf_start) {
- if (gJpegenc.use_cma) {
- struct page *cma_pages;
- cma_pages = phys_to_page(wq->buf_start);
- if (!dma_release_from_contiguous(&gJpegenc.this_pdev->dev, cma_pages,
- wq->buf_size >> PAGE_SHIFT)) {
- jenc_pr(LOG_ERROR, "[%s] failed to release cma buffer\n", __FUNCTION__);
- }
- } else {
- codec_mm_free_for_dma(DRIVER_NAME, wq->buf_start);
- }
- }
+#if 0
+ if (wq->venc_pages) {
+ dma_release_from_contiguous(
+ &gJpegenc.this_pdev->dev,
+ wq->venc_pages,
+ wq->buf_size >> PAGE_SHIFT);
+ wq->venc_pages = NULL;
+ }
#endif
- wq->buf_start = 0;
- wq->buf_size = 0;
+ if (wq->buf_start) {
+ wq->venc_pages = NULL;
+ codec_mm_free_for_dma(DRIVER_NAME, wq->buf_start);
+ jenc_pr(LOG_ERROR, "jpegenc release memory\n");
+ wq->buf_start = 0;
+ }
+#endif
+ wq->buf_start = 0;
+ wq->buf_size = 0;
#ifdef EXTEAN_QUANT_TABLE
- kfree(gExternalQuantTablePtr);
- gExternalQuantTablePtr = NULL;
- external_quant_table_available = false;
+ kfree(gExternalQuantTablePtr);
+ gExternalQuantTablePtr = NULL;
+ external_quant_table_available = false;
#endif
- spin_lock(&gJpegenc.sem_lock);
- if (gJpegenc.opened > 0)
- gJpegenc.opened--;
- spin_unlock(&gJpegenc.sem_lock);
- jenc_pr(LOG_DEBUG, "jpegenc release\n");
- return 0;
+ spin_lock(&gJpegenc.sem_lock);
+ if (gJpegenc.opened > 0)
+ gJpegenc.opened--;
+ spin_unlock(&gJpegenc.sem_lock);
+ jenc_pr(LOG_DEBUG, "jpegenc release\n");
+ return 0;
}
-static void jpegenc_reconfig_input(struct jpegenc_wq_s *wq, u32 new_addr, u32 new_size) {
- wq->InputBuffStart = new_addr;
- wq->InputBuffEnd = wq->InputBuffStart + new_size - 1;
-}
-
-static void jpegenc_restore_input(struct jpegenc_wq_s *wq) {
- wq->InputBuffStart = wq->buf_start + gJpegenc.mem.bufspec->input.buf_start;
- wq->InputBuffEnd = wq->InputBuffStart + gJpegenc.mem.bufspec->input.buf_size - 1;
-}
static long jpegenc_ioctl(struct file *file, u32 cmd, ulong arg)
{
- long r = 0;
- struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
+ long r = 0;
+ struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
#define MAX_ADDR_INFO_SIZE 30
- u32 addr_info[MAX_ADDR_INFO_SIZE + 4];
- int shared_fd = -1;
- //struct jpegenc_frame_params *frm_params;
+ u32 addr_info[MAX_ADDR_INFO_SIZE + 4];
+ switch (cmd) {
+ case JPEGENC_IOC_NEW_CMD:
+ if (copy_from_user(addr_info, (void *)arg,
+ MAX_ADDR_INFO_SIZE * sizeof(u32))) {
+ jenc_pr(LOG_ERROR,
+ "jpegenc get new cmd error.\n");
+ return -1;
+ }
+ if (!convert_cmd(wq, addr_info))
+ jpegenc_start_cmd(wq);
+ break;
+ case JPEGENC_IOC_GET_STAGE:
+ put_user(wq->hw_status, (u32 *)arg);
+ break;
+ case JPEGENC_IOC_GET_OUTPUT_SIZE:
+ cache_flush(wq->BitstreamStart, wq->output_size);
+ addr_info[0] = wq->headbytes;
+ addr_info[1] = wq->output_size;
+ r = copy_to_user((u32 *)arg, addr_info , 2 * sizeof(u32));
+ break;
+ case JPEGENC_IOC_CONFIG_INIT:
+ jpegenc_init();
+ jpegenc_buffspec_init(wq);
+ break;
+ case JPEGENC_IOC_GET_BUFFINFO:
+ addr_info[0] = gJpegenc.mem.buf_size;
+ addr_info[1] = gJpegenc.mem.bufspec->input.buf_start;
+ addr_info[2] = gJpegenc.mem.bufspec->input.buf_size;
+ addr_info[3] = gJpegenc.mem.bufspec->assit.buf_start;
+ addr_info[4] = gJpegenc.mem.bufspec->assit.buf_size;
+ addr_info[5] = gJpegenc.mem.bufspec->bitstream.buf_start;
+ addr_info[6] = gJpegenc.mem.bufspec->bitstream.buf_size;
+ r = copy_to_user((u32 *)arg, addr_info , 7 * sizeof(u32));
- struct platform_device *pdev;
- unsigned long paddr = 0;
-
- switch (cmd) {
- case JPEGENC_IOC_QUERY_DMA_SUPPORT:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_QUERY_DMA_SUPPORT\n");
- jenc_pr(LOG_INFO, "use_dma_io=%u\n", use_dma_io);
- put_user(use_dma_io, (u32 *)arg);
- break;
- case JPEGENC_IOC_CONFIG_DMA_INPUT:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_CONFIG_DMA_INPUT\n");
- if (copy_from_user(&shared_fd, (void *)arg, sizeof(s32))) {
- jenc_pr(LOG_ERROR,
- "jpegenc JPEGENC_IOC_CONFIG_DMA_INPUT error.\n");
- return -1;
- }
-
- jenc_pr(LOG_INFO, "JPEGENC_IOC_CONFIG_DMA_INPUT, shared_fd:%d\n",
- shared_fd);
-
- if (wq->dma_input != NULL) {
- jenc_pr(LOG_INFO, "[%d] release old stale dma buffer\n", __LINE__);
- enc_dma_buf_unmap(wq->dma_input);
- wq->dma_input->fd = -1;
- }
-
- if (wq->dma_input == NULL)
- wq->dma_input = kmalloc(sizeof(struct enc_dma_cfg), GFP_KERNEL);
-
- if (wq->dma_input != NULL) {
- wq->dma_input->dir = DMA_TO_DEVICE;
- wq->dma_input->fd = shared_fd;
- pdev = gJpegenc.this_pdev;
- wq->dma_input->dev = &(pdev->dev);
-
- r = enc_dma_buf_get_phys(wq->dma_input, &paddr);
-
- if (r < 0) {
- jenc_pr(LOG_ERROR,
- "import fd %d failed\n",
- wq->dma_input->fd);
- wq->dma_input->paddr = NULL;
- wq->dma_input->vaddr = NULL;
- enc_dma_buf_unmap(wq->dma_input);
- kfree(wq->dma_input);
- return -1;
- }
-
- wq->dma_input->paddr = (void *)paddr;
- jenc_pr(LOG_INFO, "paddr %p\n",
- wq->dma_input->paddr);
- } else {
- jenc_pr(LOG_ERROR, "kmalloc struct enc_dma_cfg failed\n");
- return -1;
- }
-
- jpegenc_reconfig_input(wq, paddr, wq->dma_input->size);
- break;
- case JPEGENC_IOC_RELEASE_DMA_INPUT:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_RELEASE_DMA_INPUT\n");
- if (wq->dma_input != NULL) {
- jenc_pr(LOG_INFO, "[%d] release dma buffer\n", __LINE__);
- enc_dma_buf_unmap(wq->dma_input);
- wq->dma_input->fd = -1;
- // restore to original input buffer config if dma buffer is revoked
- jpegenc_restore_input(wq);
- }
- break;
- case JPEGENC_IOC_NEW_CMD:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_NEW_CMD\n");
- if (copy_from_user(addr_info, (void *)arg,
- MAX_ADDR_INFO_SIZE * sizeof(u32))) {
- jenc_pr(LOG_ERROR,
- "jpegenc get new cmd error.\n");
- return -1;
- }
- if (!convert_cmd(wq, addr_info))
- jpegenc_start_cmd(wq);
- break;
- case JPEGENC_IOC_NEW_CMD2:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_NEW_CMD2\n");
- if (copy_from_user(&(wq->cmd), (void *)arg, (unsigned long) sizeof(struct jpegenc_request_s))) {
- jenc_pr(LOG_ERROR,
- "jpegenc get new cmd2 error.\n");
- return -1;
- }
-
- dump_requst(&(wq->cmd));
-
- if (is_oversize(wq->cmd.encoder_width,
- wq->cmd.encoder_height,
- wq->max_width * wq->max_height)) {
- jenc_pr(LOG_ERROR,
- "set encode size %dx%d is larger than supported (%dx%d).\n",
- wq->cmd.encoder_width,
- wq->cmd.encoder_height,
- wq->max_width,
- wq->max_height);
- return -1;
- }
-
- wq->cmd.jpeg_quality = jpeg_quality_scaling(wq->cmd.jpeg_quality);
-
- if (wq->cmd.QuantTable_id < 4) {
- jenc_pr(LOG_INFO, "JPEGENC_SEL_QUANT_TABLE: %d\n", wq->cmd.QuantTable_id);
- } else {
- wq->cmd.QuantTable_id = 0;
- jenc_pr(LOG_ERROR, "JPEGENC_SEL_QUANT_TABLE invaild, use 0 instead\n");
- }
-
- jenc_pr(LOG_INFO, "scaled jpeg_quality: %d\n", wq->cmd.jpeg_quality);
-
- //if (!convert_cmd(wq, addr_info))
- jpegenc_start_cmd(wq);
-
- break;
- case JPEGENC_IOC_GET_STAGE:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_GET_STAGE\n");
- put_user(wq->hw_status, (u32 *)arg);
- break;
- case JPEGENC_IOC_GET_OUTPUT_SIZE:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_GET_OUTPUT_SIZE\n");
- cache_flush(wq->BitstreamStart, wq->output_size);
- addr_info[0] = wq->headbytes;
- addr_info[1] = wq->output_size;
- r = copy_to_user((u32 *)arg, addr_info , 2 * sizeof(u32));
- break;
- case JPEGENC_IOC_CONFIG_INIT:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_CONFIG_INIT\n");
- jpegenc_init();
- jpegenc_buffspec_init(wq);
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_CONFIG_INIT end\n");
- break;
- case JPEGENC_IOC_GET_BUFFINFO:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_GET_BUFFINFO\n");
- addr_info[0] = gJpegenc.mem.buf_size;
- addr_info[1] = gJpegenc.mem.bufspec->input.buf_start;
- addr_info[2] = gJpegenc.mem.bufspec->input.buf_size;
- addr_info[3] = gJpegenc.mem.bufspec->assit.buf_start;
- addr_info[4] = gJpegenc.mem.bufspec->assit.buf_size;
- addr_info[5] = gJpegenc.mem.bufspec->bitstream.buf_start;
- addr_info[6] = gJpegenc.mem.bufspec->bitstream.buf_size;
- r = copy_to_user((u32 *)arg, addr_info , 7 * sizeof(u32));
- break;
- case JPEGENC_IOC_GET_DEVINFO:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_GET_DEVINFO\n");
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
- /* GXL send same id of GXTVBB to upper*/
- r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
- strlen(JPEGENC_DEVINFO_GXTVBB));
- } else if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_GXTVBB) {
- r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
- strlen(JPEGENC_DEVINFO_GXTVBB));
- } else if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_GXBB) {
- r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXBB,
- strlen(JPEGENC_DEVINFO_GXBB));
- } else if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_MG9TV) {
- r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_G9,
- strlen(JPEGENC_DEVINFO_G9));
- } else {
- r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_M8,
- strlen(JPEGENC_DEVINFO_M8));
- }
- break;
- case JPEGENC_IOC_SET_EXT_QUANT_TABLE:
- jenc_pr(LOG_DEBUG, "ioctl JPEGENC_IOC_SET_EXT_QUANT_TABLE\n");
+ break;
+ case JPEGENC_IOC_GET_DEVINFO:
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
+ /* GXL send same id of GXTVBB to upper*/
+ r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
+ strlen(JPEGENC_DEVINFO_GXTVBB));
+ } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) {
+ r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
+ strlen(JPEGENC_DEVINFO_GXTVBB));
+ } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) {
+ r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXBB,
+ strlen(JPEGENC_DEVINFO_GXBB));
+ } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_MG9TV) {
+ r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_G9,
+ strlen(JPEGENC_DEVINFO_G9));
+ } else {
+ r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_M8,
+ strlen(JPEGENC_DEVINFO_M8));
+ }
+ break;
+ case JPEGENC_IOC_SET_EXT_QUANT_TABLE:
#ifdef EXTEAN_QUANT_TABLE
- if (arg == 0) {
- kfree(gExternalQuantTablePtr);
- gExternalQuantTablePtr = NULL;
- external_quant_table_available = false;
- } else {
- void __user *argp = (void __user *)arg;
- gExternalQuantTablePtr =
- kmalloc(sizeof(u16) * DCTSIZE2 * 2,
- GFP_KERNEL);
- if (gExternalQuantTablePtr) {
- if (copy_from_user
- (gExternalQuantTablePtr, argp,
- sizeof(u16) * DCTSIZE2 * 2)) {
- r = -1;
- break;
- }
- external_quant_table_available = true;
- r = 0;
- } else {
- jenc_pr(LOG_ERROR,
- "gExternalQuantTablePtr malloc fail\n");
- r = -1;
- }
- }
+ if (arg == 0) {
+ kfree(gExternalQuantTablePtr);
+ gExternalQuantTablePtr = NULL;
+ external_quant_table_available = false;
+ } else {
+ void __user *argp = (void __user *)arg;
+ gExternalQuantTablePtr =
+ kmalloc(sizeof(u16) * DCTSIZE2 * 2,
+ GFP_KERNEL);
+ if (gExternalQuantTablePtr) {
+ if (copy_from_user
+ (gExternalQuantTablePtr, argp,
+ sizeof(u16) * DCTSIZE2 * 2)) {
+ r = -1;
+ break;
+ }
+ external_quant_table_available = true;
+ r = 0;
+ } else {
+ jenc_pr(LOG_ERROR,
+ "gExternalQuantTablePtr malloc fail\n");
+ r = -1;
+ }
+ }
#else
- r = 0;
+ r = 0;
#endif
- break;
- default:
- jenc_pr(LOG_DEBUG, "ioctl BAD cmd\n");
- r = -1;
- break;
- }
- return r;
+ break;
+ default:
+ r = -1;
+ break;
+ }
+ return r;
}
#ifdef CONFIG_COMPAT
static long jpegenc_compat_ioctl(struct file *filp,
- unsigned int cmd, unsigned long args)
+ unsigned int cmd, unsigned long args)
{
- unsigned long ret;
+ unsigned long ret;
- args = (unsigned long)compat_ptr(args);
- ret = jpegenc_ioctl(filp, cmd, args);
- return ret;
+ args = (unsigned long)compat_ptr(args);
+ ret = jpegenc_ioctl(filp, cmd, args);
+ return ret;
}
#endif
static s32 jpegenc_mmap(struct file *filp, struct vm_area_struct *vma)
{
- struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)filp->private_data;
- ulong off = vma->vm_pgoff << PAGE_SHIFT;
- ulong vma_size = vma->vm_end - vma->vm_start;
+ struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)filp->private_data;
+ ulong off = vma->vm_pgoff << PAGE_SHIFT;
+ ulong vma_size = vma->vm_end - vma->vm_start;
- if (vma_size == 0) {
- jenc_pr(LOG_ERROR, "vma_size is 0\n");
- return -EAGAIN;
- }
- off += wq->buf_start;
- jenc_pr(LOG_INFO, "vma_size is %ld, off is %ld\n", vma_size, off);
- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
- /* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
- if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- jenc_pr(LOG_ERROR, "set_cached: failed remap_pfn_range\n");
- return -EAGAIN;
- }
- return 0;
+ if (vma_size == 0) {
+ jenc_pr(LOG_ERROR, "vma_size is 0\n");
+ return -EAGAIN;
+ }
+ off += wq->buf_start;
+ jenc_pr(LOG_INFO, "vma_size is %ld, off is %ld\n", vma_size, off);
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
+ /* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
+ if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+ jenc_pr(LOG_ERROR, "set_cached: failed remap_pfn_range\n");
+ return -EAGAIN;
+ }
+ return 0;
}
static u32 jpegenc_poll(struct file *file, poll_table *wait_table)
{
- struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
- poll_wait(file, &wq->complete, wait_table);
+ struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
+ poll_wait(file, &wq->complete, wait_table);
- if (atomic_read(&wq->ready)) {
- atomic_dec(&wq->ready);
- return POLLIN | POLLRDNORM;
- }
- return 0;
+ if (atomic_read(&wq->ready)) {
+ atomic_dec(&wq->ready);
+ return POLLIN | POLLRDNORM;
+ }
+ return 0;
}
static const struct file_operations jpegenc_fops = {
- .owner = THIS_MODULE,
- .open = jpegenc_open,
- .mmap = jpegenc_mmap,
- .release = jpegenc_release,
- .unlocked_ioctl = jpegenc_ioctl,
+ .owner = THIS_MODULE,
+ .open = jpegenc_open,
+ .mmap = jpegenc_mmap,
+ .release = jpegenc_release,
+ .unlocked_ioctl = jpegenc_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = jpegenc_compat_ioctl,
+ .compat_ioctl = jpegenc_compat_ioctl,
#endif
- .poll = jpegenc_poll,
+ .poll = jpegenc_poll,
};
static s32 jpegenc_wq_init(void)
{
- jenc_pr(LOG_DEBUG, "jpegenc_wq_init.\n");
- spin_lock_init(&gJpegenc.sem_lock);
- spin_lock(&gJpegenc.sem_lock);
- gJpegenc.irq_requested = false;
- gJpegenc.process_irq = false;
- gJpegenc.inited = false;
- gJpegenc.opened = 0;
- gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
+ jenc_pr(LOG_DEBUG, "jpegenc_wq_init.\n");
+ gJpegenc.irq_requested = false;
+ gJpegenc.process_irq = false;
+ gJpegenc.inited = false;
+ gJpegenc.opened = 0;
+ gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
+ spin_lock_init(&gJpegenc.sem_lock);
- tasklet_init(&gJpegenc.tasklet,
- jpegenc_isr_tasklet,
- (ulong)&gJpegenc);
- spin_unlock(&gJpegenc.sem_lock);
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
- clock_level = 5;
- else if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8M2)
- clock_level = 3;
- else
- clock_level = 1;
- return 0;
+ tasklet_init(&gJpegenc.tasklet,
+ jpegenc_isr_tasklet,
+ (ulong)&gJpegenc);
+
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
+ clock_level = 5;
+ else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8M2)
+ clock_level = 3;
+ else
+ clock_level = 1;
+ return 0;
}
static s32 jpegenc_wq_uninit(void)
{
- s32 r = -1;
- jenc_pr(LOG_DEBUG, "uninit encode wq.\n");
- if (gJpegenc.encode_hw_status == JPEGENC_ENCODER_IDLE) {
- if ((gJpegenc.irq_num >= 0) &&
- (gJpegenc.irq_requested == true)) {
- free_irq(gJpegenc.irq_num, &gJpegenc);
- gJpegenc.irq_requested = false;
- }
- r = 0;
- }
- return r;
+ s32 r = -1;
+ jenc_pr(LOG_DEBUG, "uninit encode wq.\n");
+ if (gJpegenc.encode_hw_status == JPEGENC_ENCODER_IDLE) {
+ if ((gJpegenc.irq_num >= 0) &&
+ (gJpegenc.irq_requested == true)) {
+ free_irq(gJpegenc.irq_num, &gJpegenc);
+ gJpegenc.irq_requested = false;
+ }
+ r = 0;
+ }
+ return r;
}
-static ssize_t encode_status_show(struct class *cla,
- struct class_attribute *attr, char *buf)
+static ssize_t jpegenc_status_show(struct class *cla,
+ struct class_attribute *attr, char *buf)
{
- s32 irq_num;
- u32 hw_status, width, height;
- bool process_irq;
- bool inited;
- bool use_reserve;
- u32 cma_size, max_w, max_h;
- u32 buffer_start, buffer_size;
- u8 lev, opened;
- struct Jpegenc_Buff_s res;
+ s32 irq_num;
+ u32 hw_status, width, height;
+ bool process_irq;
+ bool inited;
+ bool use_reserve;
+ u32 cma_size, max_w, max_h;
+ u32 buffer_start, buffer_size;
+ u8 lev, opened;
+ struct Jpegenc_Buff_s res;
- spin_lock(&gJpegenc.sem_lock);
+ spin_lock(&gJpegenc.sem_lock);
- irq_num = gJpegenc.irq_num;
- hw_status = gJpegenc.encode_hw_status;
- process_irq = gJpegenc.process_irq;
- inited = gJpegenc.inited;
- opened = gJpegenc.opened;
- use_reserve = gJpegenc.use_reserve;
- res.buf_start = gJpegenc.mem.reserve_mem.buf_start;
- res.buf_size = gJpegenc.mem.reserve_mem.buf_size;
- buffer_start = gJpegenc.mem.buf_start;
- buffer_size = gJpegenc.mem.buf_size;
- lev = gJpegenc.mem.cur_buf_lev;
- max_w = gJpegenc.mem.bufspec->max_width;
- max_h = gJpegenc.mem.bufspec->max_height;
- width = gJpegenc.wq.cmd.encoder_width;
- height = gJpegenc.wq.cmd.encoder_height;
+ irq_num = gJpegenc.irq_num;
+ hw_status = gJpegenc.encode_hw_status;
+ process_irq = gJpegenc.process_irq;
+ inited = gJpegenc.inited;
+ opened = gJpegenc.opened;
+ use_reserve = gJpegenc.use_reserve;
+ res.buf_start = gJpegenc.mem.reserve_mem.buf_start;
+ res.buf_size = gJpegenc.mem.reserve_mem.buf_size;
+ buffer_start = gJpegenc.mem.buf_start;
+ buffer_size = gJpegenc.mem.buf_size;
+ lev = gJpegenc.mem.cur_buf_lev;
+ max_w = gJpegenc.mem.bufspec->max_width;
+ max_h = gJpegenc.mem.bufspec->max_height;
+ width = gJpegenc.wq.cmd.encoder_width;
+ height = gJpegenc.wq.cmd.encoder_height;
#ifdef CONFIG_CMA
- cma_size = gJpegenc.mem.cma_pool_size / SZ_1M;
+ cma_size = gJpegenc.mem.cma_pool_size / SZ_1M;
#endif
- spin_unlock(&gJpegenc.sem_lock);
+ spin_unlock(&gJpegenc.sem_lock);
- jenc_pr(LOG_DEBUG,
- "jpegenc width: %d, encode height: %d.\n",
- width, height);
- jenc_pr(LOG_DEBUG,
- "jpegenc hw_status: %d, process_irq: %s.\n",
- hw_status, process_irq ? "true" : "false");
- jenc_pr(LOG_DEBUG,
- "jpegenc irq num: %d, inited: %s, opened: %d\n",
- irq_num, inited ? "true" : "false", opened);
- if (use_reserve) {
- jenc_pr(LOG_DEBUG,
- "jpegenc reserve memory, buffer start: 0x%x, size: %d MB.\n",
- res.buf_start, res.buf_size / SZ_1M);
- } else {
+ jenc_pr(LOG_DEBUG,
+ "jpegenc width: %d, encode height: %d.\n",
+ width, height);
+ jenc_pr(LOG_DEBUG,
+ "jpegenc hw_status: %d, process_irq: %s.\n",
+ hw_status, process_irq ? "true" : "false");
+ jenc_pr(LOG_DEBUG,
+ "jpegenc irq num: %d, inited: %s, opened: %d\n",
+ irq_num, inited ? "true" : "false", opened);
+ if (use_reserve) {
+ jenc_pr(LOG_DEBUG,
+ "jpegenc reserve memory, buffer start: 0x%x, size: %d MB.\n",
+ res.buf_start, res.buf_size / SZ_1M);
+ } else {
#ifdef CONFIG_CMA
- jenc_pr(LOG_DEBUG, "jpegenc cma pool size: %d.\n", cma_size);
+ jenc_pr(LOG_DEBUG, "jpegenc cma pool size: %d.\n", cma_size);
#endif
- }
- jenc_pr(LOG_DEBUG, "jpegenc buffer start: 0x%x, size: 0x%x\n",
- buffer_start, buffer_size);
- jenc_pr(LOG_DEBUG, "buffer level: %s\n", glevel_str[lev]);
- return snprintf(buf, 40, "max size: %dx%d\n", max_w, max_h);
+ }
+ jenc_pr(LOG_DEBUG, "jpegenc buffer start: 0x%x, size: 0x%x\n",
+ buffer_start, buffer_size);
+ jenc_pr(LOG_DEBUG, "buffer level: %s\n", glevel_str[lev]);
+ return snprintf(buf, 40, "max size: %dx%d\n", max_w, max_h);
}
-static int enc_dma_buf_map(struct enc_dma_cfg *cfg)
-{
- long ret = -1;
- int fd = -1;
- struct dma_buf *dbuf = NULL;
- struct dma_buf_attachment *d_att = NULL;
- struct sg_table *sg = NULL;
- void *vaddr = NULL;
- struct device *dev = NULL;
- enum dma_data_direction dir;
-
- if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL) {
- jenc_pr(LOG_ERROR, "error input param\n");
- return -EINVAL;
- }
-
- jenc_pr(LOG_INFO, "enc_dma_buf_map, fd %d\n", cfg->fd);
-
- fd = cfg->fd;
- dev = cfg->dev;
- dir = cfg->dir;
- jenc_pr(LOG_INFO, "enc_dma_buffer_map fd %d\n", fd);
-
- dbuf = dma_buf_get(fd);
-
- if (dbuf == NULL) {
- jenc_pr(LOG_ERROR, "failed to get dma buffer,fd %d\n",fd);
- return -EINVAL;
- }
-
- d_att = dma_buf_attach(dbuf, dev);
-
- if (d_att == NULL) {
- jenc_pr(LOG_ERROR, "failed to set dma attach\n");
- goto attach_err;
- }
-
- sg = dma_buf_map_attachment(d_att, dir);
-
- if (sg == NULL) {
- jenc_pr(LOG_ERROR, "failed to get dma sg\n");
- goto map_attach_err;
- }
-
- ret = dma_buf_begin_cpu_access(dbuf, dir);
-
- if (ret != 0) {
- jenc_pr(LOG_ERROR, "failed to access dma buff\n");
- goto access_err;
- }
-
- vaddr = dma_buf_vmap(dbuf);
-
- if (vaddr == NULL) {
- jenc_pr(LOG_ERROR, "failed to vmap dma buf\n");
- goto vmap_err;
- }
-
- cfg->dbuf = dbuf;
- cfg->attach = d_att;
- cfg->vaddr = vaddr;
- cfg->sg = sg;
- cfg->size = dbuf->size;
- jenc_pr(LOG_INFO, "dmabuf size is %zu\n", cfg->size);
-
- return ret;
-
-vmap_err:
- dma_buf_end_cpu_access(dbuf, dir);
-
-access_err:
- dma_buf_unmap_attachment(d_att, sg, dir);
-
-map_attach_err:
- dma_buf_detach(dbuf, d_att);
-
-attach_err:
- dma_buf_put(dbuf);
-
- return ret;
-}
-
-static int enc_dma_buf_get_phys(struct enc_dma_cfg *cfg, unsigned long *addr)
-{
- struct sg_table *sg_table;
- struct page *page;
- int ret;
- jenc_pr(LOG_INFO, "jpegenc_dma_buf_get_phys in\n");
-
- ret = enc_dma_buf_map(cfg);
-
- if (ret < 0) {
- jenc_pr(LOG_ERROR, "jpegenc_dma_buf_get_phys failed\n");
- return ret;
- }
-
- if (cfg->sg) {
- sg_table = cfg->sg;
- page = sg_page(sg_table->sgl);
- *addr = PFN_PHYS(page_to_pfn(page));
- ret = 0;
- }
-
- jenc_pr(LOG_INFO, "jpegenc_dma_buf_get_phys 0x%lx\n", *addr);
- return ret;
-}
-
-static void enc_dma_buf_unmap(struct enc_dma_cfg *cfg)
-{
- int fd = -1;
- struct dma_buf *dbuf = NULL;
- struct dma_buf_attachment *d_att = NULL;
- struct sg_table *sg = NULL;
- void *vaddr = NULL;
- struct device *dev = NULL;
- enum dma_data_direction dir;
-
- if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL
- || cfg->dbuf == NULL || cfg->vaddr == NULL
- || cfg->attach == NULL || cfg->sg == NULL) {
- jenc_pr(LOG_ERROR, "Error input param\n");
- return;
- }
-
- fd = cfg->fd;
- dev = cfg->dev;
- dir = cfg->dir;
- dbuf = cfg->dbuf;
- vaddr = cfg->vaddr;
- d_att = cfg->attach;
- sg = cfg->sg;
-
- dma_buf_vunmap(dbuf, vaddr);
-
- dma_buf_end_cpu_access(dbuf, dir);
-
- dma_buf_unmap_attachment(d_att, sg, dir);
-
- dma_buf_detach(dbuf, d_att);
-
- dma_buf_put(dbuf);
- jenc_pr(LOG_DEBUG, "enc_dma_buffer_unmap vaddr %p\n",(unsigned *)vaddr);
-}
-
-static ssize_t power_ctrl_show(struct class *cla, struct class_attribute *attr, char *buf) {
- pr_err("power status: %lu\n", pwr_ctrl_status_psci_smc(PDID_T7_DOS_HCODEC));
- pr_err("jpeg clk: %ld\n", clk_get_rate(g_jpeg_enc_clks.jpeg_enc_clk));
- return 1;//snprintf(buf, PAGE_SIZE, "power control show done\n");
-}
-
-static ssize_t power_ctrl_store(struct class *class,struct class_attribute *attr,
- const char *buf, size_t count) {
- if (strncmp(buf, "poweron", 7) == 0) {
- pr_err("now powering on:\n");
- //pwr_ctrl_psci_smc(PM_HCODEC, true);
- //jpegenc_poweron_ex(6);
- jpegenc_init();
- } else if (strncmp(buf, "poweroff", 8) == 0) {
- pr_err("now powering off:\n");
- //pwr_ctrl_psci_smc(PM_HCODEC, false);
- jpegenc_poweroff_ex();
- } else if (strncmp(buf, "mbox0", 5) == 0) {
- pr_err("trigger mbox0:\n");
-
- WRITE_HREG(HCODEC_ASSIST_MBOX0_MASK, 1); //enable irq
- WRITE_VREG(HCODEC_ASSIST_MBOX0_IRQ_REG, 0x1); // set irq
- } else if (strncmp(buf, "mbox1", 5) == 0) {
- pr_err("trigger mbox1:\n");
-
- WRITE_HREG(HCODEC_ASSIST_MBOX1_MASK, 1); //enable irq
- WRITE_VREG(HCODEC_ASSIST_MBOX1_IRQ_REG, 0x1); // set irq
- } else if (strncmp(buf, "mbox2", 5) == 0) {
- pr_err("trigger mbox2:\n");
-
- WRITE_HREG(HCODEC_ASSIST_MBOX2_MASK, 1); //enable irq
- WRITE_VREG(HCODEC_ASSIST_MBOX2_IRQ_REG, 0x1); // set irq
- }
-
- return 1;//snprintf(buf, PAGE_SIZE, "policy read,just for test\n");
-}
-
-static CLASS_ATTR_RO(encode_status);
-static CLASS_ATTR_RW(power_ctrl);
-//static CLASS_ATTR(clock_ctrl, 0664, clock_ctrl_show, clock_ctrl_store);
-
-static struct attribute *jpegenc_class_attrs[] = {
- &class_attr_encode_status.attr,
- &class_attr_power_ctrl.attr,
- //&class_attr_clock_ctrl.attr,
- NULL
+static struct class_attribute jpegenc_class_attrs[] = {
+ __ATTR(encode_status,
+ S_IRUGO | S_IWUSR,
+ jpegenc_status_show,
+ NULL),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(jpegenc_class);
-
static struct class jpegenc_class = {
- .name = CLASS_NAME,
- .class_groups = jpegenc_class_groups,
+ .name = CLASS_NAME,
+ .class_attrs = jpegenc_class_attrs,
};
s32 init_jpegenc_device(void)
{
- s32 r = 0;
- r = register_chrdev(0, DEVICE_NAME, &jpegenc_fops);
- if (r <= 0) {
- jenc_pr(LOG_ERROR, "register jpegenc device error\n");
- return r;
- }
- jpegenc_device_major = r;
+ s32 r = 0;
+ r = register_chrdev(0, DEVICE_NAME, &jpegenc_fops);
+ if (r <= 0) {
+ jenc_pr(LOG_ERROR, "register jpegenc device error\n");
+ return r;
+ }
+ jpegenc_device_major = r;
- r = class_register(&jpegenc_class);
- if (r < 0) {
- jenc_pr(LOG_ERROR, "error create jpegenc class.\n");
- return r;
- }
+ r = class_register(&jpegenc_class);
+ if (r < 0) {
+ jenc_pr(LOG_ERROR, "error create jpegenc class.\n");
+ return r;
+ }
- jpegenc_dev = device_create(&jpegenc_class, NULL,
- MKDEV(jpegenc_device_major, 0), NULL,
- DEVICE_NAME);
+ jpegenc_dev = device_create(&jpegenc_class, NULL,
+ MKDEV(jpegenc_device_major, 0), NULL,
+ DEVICE_NAME);
- if (IS_ERR(jpegenc_dev)) {
- jenc_pr(LOG_ERROR, "create jpegenc device error.\n");
- class_unregister(&jpegenc_class);
- return -1;
- }
- return r;
+ if (IS_ERR(jpegenc_dev)) {
+ jenc_pr(LOG_ERROR, "create jpegenc device error.\n");
+ class_unregister(&jpegenc_class);
+ return -1;
+ }
+ return r;
}
s32 uninit_jpegenc_device(void)
{
- if (jpegenc_dev)
- device_destroy(&jpegenc_class, MKDEV(jpegenc_device_major, 0));
+ if (jpegenc_dev)
+ device_destroy(&jpegenc_class, MKDEV(jpegenc_device_major, 0));
- class_destroy(&jpegenc_class);
+ class_destroy(&jpegenc_class);
- unregister_chrdev(jpegenc_device_major, DEVICE_NAME);
- return 0;
+ unregister_chrdev(jpegenc_device_major, DEVICE_NAME);
+ return 0;
}
static s32 jpegenc_mem_device_init(struct reserved_mem *rmem,
- struct device *dev)
+ struct device *dev)
{
- s32 r = 0;
- struct resource res;
- if (!rmem) {
- jenc_pr(LOG_ERROR,
- "Can't obtain I/O memory, will allocate jpegenc buffer!\n");
- r = -EFAULT;
- return r;
- }
- res.start = (phys_addr_t) rmem->base;
- res.end = res.start + (phys_addr_t) rmem->size - 1;
- gJpegenc.mem.reserve_mem.buf_start = res.start;
- gJpegenc.mem.reserve_mem.buf_size = res.end - res.start + 1;
- jenc_pr(LOG_DEBUG, "found reserved memory device(start:0x%llux, size:0x%llux)\n",
- rmem->base, rmem->size);
- if (gJpegenc.mem.reserve_mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize)
- gJpegenc.use_reserve = true;
- else {
- jenc_pr(LOG_ERROR,
- "jpegenc reserve_mem too small, size is %d.\n",
- gJpegenc.mem.reserve_mem.buf_size);
- gJpegenc.mem.reserve_mem.buf_start = 0;
- gJpegenc.mem.reserve_mem.buf_size = 0;
- return -EFAULT;
- }
- return r;
+ s32 r;
+ struct resource res;
+ if (!rmem) {
+ jenc_pr(LOG_ERROR,
+ "Can't obtain I/O memory, will allocate jpegenc buffer!\n");
+ r = -EFAULT;
+ return r;
+ }
+ res.start = (phys_addr_t) rmem->base;
+ res.end = res.start + (phys_addr_t) rmem->size - 1;
+ gJpegenc.mem.reserve_mem.buf_start = res.start;
+ gJpegenc.mem.reserve_mem.buf_size = res.end - res.start + 1;
+ if (gJpegenc.mem.reserve_mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize)
+ gJpegenc.use_reserve = true;
+ else {
+ jenc_pr(LOG_ERROR,
+ "jpegenc reserve_mem too small, size is %d.\n",
+ gJpegenc.mem.reserve_mem.buf_size);
+ gJpegenc.mem.reserve_mem.buf_start = 0;
+ gJpegenc.mem.reserve_mem.buf_size = 0;
+ return -EFAULT;
+ }
+ return r;
}
static s32 jpegenc_probe(struct platform_device *pdev)
{
- s32 res_irq;
- s32 idx;
+ s32 res_irq;
+ s32 idx;
- jenc_pr(LOG_DEBUG, "jpegenc probe start.\n");
+ jenc_pr(LOG_DEBUG, "jpegenc probe start.\n");
- gJpegenc.this_pdev = pdev;
- gJpegenc.use_reserve = false;
- gJpegenc.use_cma = false;
+ gJpegenc.this_pdev = pdev;
+ gJpegenc.use_reserve = false;
+ memset(&gJpegenc.mem, 0, sizeof(struct jpegenc_meminfo_s));
- jpeg_in_full_hcodec = 0;
- mfdin_ambus_canv_conv = 0;
+ idx = of_reserved_mem_device_init(&pdev->dev);
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3) {
- pr_err("jpegenc_probe: jpeg_in_full_hcodec\n");
- jpeg_in_full_hcodec = 1;
- mfdin_ambus_canv_conv = 1;
- }
+ if (idx != 0) {
+ jenc_pr(LOG_DEBUG,
+ "jpegenc memory resource undefined.\n");
+ }
- memset(&gJpegenc.mem, 0, sizeof(struct jpegenc_meminfo_s));
-
- idx = of_reserved_mem_device_init(&pdev->dev);
- if (idx != 0) {
- jenc_pr(LOG_DEBUG,
- "jpegenc memory resource undefined. err=%d\n", idx);
- }
-
- if (gJpegenc.use_reserve == false) {
+ if (gJpegenc.use_reserve == false) {
#ifndef CONFIG_CMA
- jenc_pr(LOG_ERROR,
- "jpegenc memory is invaild, probe fail!\n");
- return -EFAULT;
+ jenc_pr(LOG_ERROR,
+ "jpegenc memory is invaild, probe fail!\n");
+ return -EFAULT;
#else
- struct device_node *mem_node;
- struct reserved_mem *rmem = NULL;
+ gJpegenc.mem.cma_pool_size = 0x2300000;
+ //codec_mm_get_total_size();
- mem_node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
- if (mem_node)
- rmem = of_reserved_mem_lookup(mem_node);
- of_node_put(mem_node);
+ jenc_pr(LOG_ERROR,
+ "jpegenc - cma memory pool size: %d MB\n",
+ (u32)gJpegenc.mem.cma_pool_size / SZ_1M);
- if (rmem) {
- jenc_pr(LOG_DEBUG,
- "jpegenc - reserved cma node found: %s.\n", rmem->name);
- gJpegenc.mem.cma_pool_size = rmem->size;
- gJpegenc.use_cma = true;
- jenc_pr(LOG_DEBUG,
- "jpegenc - codec mm pool size: %d MB.\n", codec_mm_get_free_size() / SZ_1M);
-
- } else {
- jenc_pr(LOG_DEBUG,
- "jpegenc - reserved cma node not found, using codec mm pool size.\n");
- gJpegenc.mem.cma_pool_size = codec_mm_get_free_size();
- }
-
- jenc_pr(LOG_DEBUG,
- "jpegenc - cma memory pool size: %d MB\n",
- (u32)gJpegenc.mem.cma_pool_size / SZ_1M);
- gJpegenc.mem.buf_size = gJpegenc.mem.cma_pool_size;
+ gJpegenc.mem.buf_size = gJpegenc.mem.cma_pool_size;
+ gJpegenc.mem.buf_size = 0x2300000;
#endif
- } else {
+ } else {
+ gJpegenc.mem.buf_start = gJpegenc.mem.reserve_mem.buf_start;
+ gJpegenc.mem.buf_size = gJpegenc.mem.reserve_mem.buf_size;
+ }
- jenc_pr(LOG_DEBUG, "using reserved memory(start:0x%x, size:%d MB)\n",
- gJpegenc.mem.reserve_mem.buf_start,
- (u32)gJpegenc.mem.reserve_mem.buf_size / SZ_1M);
- gJpegenc.mem.buf_start = gJpegenc.mem.reserve_mem.buf_start;
- gJpegenc.mem.buf_size = gJpegenc.mem.reserve_mem.buf_size;
- }
+ if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_HD;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_13M;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_8M;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_5M;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_3M;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_2M;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M];
+ } else if (gJpegenc.mem.buf_size >=
+ jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize) {
+ gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_VGA;
+ gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
+ &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA];
+ } else {
+ jenc_pr(LOG_ERROR,
+ "jpegenc probe memory too small, size is %d.\n",
+ gJpegenc.mem.buf_size);
+ gJpegenc.mem.buf_start = 0;
+ gJpegenc.mem.buf_size = 0;
+ return -EFAULT;
+ }
- // when use_cma is false, choose JPEGENC_BUFFER_LEVEL_8M as default
- if (gJpegenc.use_cma == false) {
- jenc_pr(LOG_ERROR, "set mem spec to JPEGENC_BUFFER_LEVEL_8M\n");
- gJpegenc.mem.buf_size = jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M].min_buffsize;
- }
+ if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ if (jpegenc_clk_prepare(&pdev->dev, &s_jpegenc_clks)) {
+ //err = -ENOENT;
+ pr_err("[%s:%d] prepare jpegenc clk failed\n", __FUNCTION__, __LINE__);
+ //goto ERROR_PROBE_DEVICE;
+ return -EINVAL;
+ }
+ }
- if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_HD;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_13M;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_8M;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_5M;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_3M;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_2M;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M];
- } else if (gJpegenc.mem.buf_size >=
- jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize) {
- gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_VGA;
- gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
- &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA];
- } else {
- jenc_pr(LOG_ERROR,
- "jpegenc probe memory too small, size is %d.\n",
- gJpegenc.mem.buf_size);
- gJpegenc.mem.buf_start = 0;
- gJpegenc.mem.buf_size = 0;
- return -EFAULT;
- }
-#if 1
- res_irq = platform_get_irq(pdev, 0);
-#else
- switch (manual_irq_num) {
- case 0:
- res_irq = platform_get_irq_byname(pdev, "dos_mbox_slow_irq0");
- pr_err("[%s:%d] get irq dos_mbox_slow_irq0, res_irq=%d\n", __FUNCTION__, __LINE__, res_irq);
- break;
- case 1:
- res_irq = platform_get_irq_byname(pdev, "dos_mbox_slow_irq1");
- pr_err("[%s:%d] get irq dos_mbox_slow_irq1, res_irq=%d\n", __FUNCTION__, __LINE__, res_irq);
- break;
- case 2:
- res_irq = platform_get_irq_byname(pdev, "dos_mbox_slow_irq2");
- pr_err("[%s:%d] get irq dos_mbox_slow_irq2, res_irq=%d\n", __FUNCTION__, __LINE__, res_irq);
- break;
- default:
+ //if (get_cpu_type() >= MESON_CPU_MAJOR_ID_SC2) {
+ // jpegenc_rst = devm_reset_control_get(&pdev->dev, "jpegenc_rst");
+ // if (IS_ERR(jpegenc_rst))
+ // pr_err("amvenc probe, jpegenc get reset failed: %ld\n", PTR_ERR(jpegenc_rst));
+ //}
- res_irq = platform_get_irq_byname(pdev, "dos_mbox_slow_irq0");
- pr_err("[%s:%d] get irq dos_mbox_slow_irq0, res_irq=%d\n", __FUNCTION__, __LINE__, res_irq);
- break;
- }
-#endif
+ res_irq = platform_get_irq(pdev, 0);
+ if (res_irq < 0) {
+ jenc_pr(LOG_ERROR, "[%s] get irq error!", __func__);
+ return -EINVAL;
+ }
- if (res_irq < 0) {
- jenc_pr(LOG_ERROR, "[%s] get irq error!", __func__);
- return -EINVAL;
- } else
- jenc_pr(LOG_ERROR, "[%s] get irq success: %d!, manual_irq_num=%d\n", __func__, res_irq, manual_irq_num);
+ gJpegenc.irq_num = res_irq;
- gJpegenc.irq_num = res_irq;
+ jenc_pr(LOG_DEBUG,
+ "jpegenc memory config sucess, buff size is 0x%x, level: %s\n",
+ gJpegenc.mem.buf_size,
+ glevel_str[gJpegenc.mem.cur_buf_lev]);
- jenc_pr(LOG_DEBUG,
- "jpegenc memory config sucess, buff size is 0x%x, level: %s\n",
- gJpegenc.mem.buf_size,
- glevel_str[gJpegenc.mem.cur_buf_lev]);
-
- jpegenc_wq_init();
- init_jpegenc_device();
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1) {
- if (jpeg_enc_clk_get(&pdev->dev, &g_jpeg_enc_clks) != 0) {
- pr_err("jpeg_enc_clk_get failed\n");
- return -1;
- }
- }
-
- jenc_pr(LOG_DEBUG, "jpegenc probe end.\n");
- return 0;
+ jpegenc_wq_init();
+ init_jpegenc_device();
+ jenc_pr(LOG_DEBUG, "jpegenc probe end.\n");
+ return 0;
}
static s32 jpegenc_remove(struct platform_device *pdev)
{
- if (jpegenc_wq_uninit())
- jenc_pr(LOG_ERROR, "jpegenc_wq_uninit error.\n");
-
- of_reserved_mem_device_release(&pdev->dev);
-
- if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_C1)
- jpeg_enc_clk_put(&pdev->dev, &g_jpeg_enc_clks);
-
- uninit_jpegenc_device();
- jenc_pr(LOG_DEBUG, "jpegenc remove.\n");
- return 0;
+ if (jpegenc_wq_uninit())
+ jenc_pr(LOG_ERROR, "jpegenc_wq_uninit error.\n");
+ uninit_jpegenc_device();
+ jenc_pr(LOG_DEBUG, "jpegenc remove.\n");
+ return 0;
}
static const struct of_device_id amlogic_jpegenc_dt_match[] = {
- {
- .compatible = "amlogic, jpegenc",
- },
- {},
+ {
+ .compatible = "amlogic, jpegenc",
+ },
+ {},
};
static struct platform_driver jpegenc_driver = {
- .probe = jpegenc_probe,
- .remove = jpegenc_remove,
- .driver = {
- .name = DRIVER_NAME,
- .of_match_table = amlogic_jpegenc_dt_match,
- }
+ .probe = jpegenc_probe,
+ .remove = jpegenc_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = amlogic_jpegenc_dt_match,
+ }
};
-#if 0
static struct codec_profile_t jpegenc_profile = {
- .name = "jpegenc",
- .profile = ""
+ .name = "jpegenc",
+ .profile = ""
};
-#endif
static s32 __init jpegenc_driver_init_module(void)
{
- jenc_pr(LOG_DEBUG, "jpegenc module init\n");
+ jenc_pr(LOG_DEBUG, "jpegenc module init\n");
- if (platform_driver_register(&jpegenc_driver)) {
- jenc_pr(LOG_ERROR, "failed to register jpegenc driver\n");
- return -ENODEV;
- }
-
-#if 0
- vcodec_profile_register(&jpegenc_profile);
-#endif
- return 0;
+ if (platform_driver_register(&jpegenc_driver)) {
+ jenc_pr(LOG_ERROR, "failed to register jpegenc driver\n");
+ return -ENODEV;
+ }
+ vcodec_profile_register(&jpegenc_profile);
+ return 0;
}
static void __exit jpegenc_driver_remove_module(void)
{
- jenc_pr(LOG_DEBUG, "jpegenc module remove.\n");
- platform_driver_unregister(&jpegenc_driver);
+ jenc_pr(LOG_DEBUG, "jpegenc module remove.\n");
+ platform_driver_unregister(&jpegenc_driver);
}
static const struct reserved_mem_ops rmem_jpegenc_ops = {
- .device_init = jpegenc_mem_device_init,
+ .device_init = jpegenc_mem_device_init,
};
static s32 __init jpegenc_mem_setup(struct reserved_mem *rmem)
{
- rmem->ops = &rmem_jpegenc_ops;
- jenc_pr(LOG_DEBUG, "jpegenc reserved mem setup.\n");
- return 0;
+ rmem->ops = &rmem_jpegenc_ops;
+ jenc_pr(LOG_DEBUG, "jpegenc reserved mem setup.\n");
+ return 0;
}
-module_param(simulation_enable, uint, 0664);
-MODULE_PARM_DESC(simulation_enable, "\n simulation_enable\n");
-
-module_param(g_block_mode, uint, 0664);
-MODULE_PARM_DESC(g_block_mode, "\n g_block_mode\n");
-
-module_param(g_canv0_stride, uint, 0664);
-MODULE_PARM_DESC(g_canv0_stride, "\n g_canv0_stride\n");
-
-module_param(g_canv1_stride, uint, 0664);
-MODULE_PARM_DESC(g_canv1_stride, "\n g_canv1_stride\n");
-
-module_param(g_canv2_stride, uint, 0664);
-MODULE_PARM_DESC(g_canv2_stride, "\n g_canv2_stride\n");
-
-module_param(g_canvas_height, uint, 0664);
-MODULE_PARM_DESC(g_canvas_height, "\n g_canvas_height\n");
-
module_param(clock_level, uint, 0664);
MODULE_PARM_DESC(clock_level, "\n clock_level\n");
module_param(jpegenc_print_level, uint, 0664);
MODULE_PARM_DESC(jpegenc_print_level, "\n jpegenc_print_level\n");
-module_param(reg_offset, int, 0664);
-MODULE_PARM_DESC(reg_offset, "\n reg_offset\n");
-
-module_param(use_dma_io, uint, 0664);
-MODULE_PARM_DESC(use_dma_io, "\n use dma io or not\n");
-
-module_param(use_quality, uint, 0664);
-MODULE_PARM_DESC(use_quality, "\n use_quality\n");
-
-module_param(legacy_load, uint, 0664);
-MODULE_PARM_DESC(legacy_load, "\n legacy_load\n");
-
-module_param(dumpmem_line, uint, 0664);
-MODULE_PARM_DESC(dumpmem_line, "\n dumpmem_line\n");
-
-module_param(pointer, uint, 0664);
-MODULE_PARM_DESC(pointer, "\n pointer\n");
-
-/*######### DEBUG-BRINGUP#########*/
-module_param(manual_clock, uint, 0664);
-MODULE_PARM_DESC(manual_clock, "\n manual_clock\n");
-
-module_param(manual_irq_num, uint, 0664);
-MODULE_PARM_DESC(manual_irq_num, "\n manual_irq_num\n");
-
-module_param(manual_interrupt, uint, 0664);
-MODULE_PARM_DESC(manual_interrupt, "\n manual_interrupt\n");
-/*################################*/
-
module_init(jpegenc_driver_init_module);
module_exit(jpegenc_driver_remove_module);
RESERVEDMEM_OF_DECLARE(jpegenc, "amlogic, jpegenc-memory", jpegenc_mem_setup);
diff --git a/drivers/frame_sink/encoder/jpeg/jpegenc.h b/drivers/frame_sink/encoder/jpeg/jpegenc.h
index d8dcf84..61062fb 100644
--- a/drivers/frame_sink/encoder/jpeg/jpegenc.h
+++ b/drivers/frame_sink/encoder/jpeg/jpegenc.h
@@ -1,7 +1,22 @@
+/*
+ * drivers/amlogic/amports/jpegenc.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+*/
#ifndef __JPEG_ENC_H_
#define __JPEG_ENC_H_
-#include <linux/dma-buf.h>
#define JPEGENC_DEVINFO_M8 "AML-M8"
#define JPEGENC_DEVINFO_G9 "AML-G9"
#define JPEGENC_DEVINFO_GXBB "AML-GXBB"
@@ -66,15 +81,12 @@
#define JPEGENC_IOC_GET_DEVINFO _IOW(JPEGENC_IOC_MAGIC, 0xf0, u32)
-#define JPEGENC_IOC_GET_BUFFINFO _IOW(JPEGENC_IOC_MAGIC, 0x00, u32)
-#define JPEGENC_IOC_CONFIG_INIT _IOW(JPEGENC_IOC_MAGIC, 0x01, u32)
-#define JPEGENC_IOC_NEW_CMD _IOW(JPEGENC_IOC_MAGIC, 0x02, u32)
-#define JPEGENC_IOC_GET_STAGE _IOW(JPEGENC_IOC_MAGIC, 0x03, u32)
-#define JPEGENC_IOC_GET_OUTPUT_SIZE _IOW(JPEGENC_IOC_MAGIC, 0x04, u32)
+#define JPEGENC_IOC_GET_BUFFINFO _IOW(JPEGENC_IOC_MAGIC, 0x00, u32)
+#define JPEGENC_IOC_CONFIG_INIT _IOW(JPEGENC_IOC_MAGIC, 0x01, u32)
+#define JPEGENC_IOC_NEW_CMD _IOW(JPEGENC_IOC_MAGIC, 0x02, u32)
+#define JPEGENC_IOC_GET_STAGE _IOW(JPEGENC_IOC_MAGIC, 0x03, u32)
+#define JPEGENC_IOC_GET_OUTPUT_SIZE _IOW(JPEGENC_IOC_MAGIC, 0x04, u32)
#define JPEGENC_IOC_SET_EXT_QUANT_TABLE _IOW(JPEGENC_IOC_MAGIC, 0x05, u32)
-#define JPEGENC_IOC_QUERY_DMA_SUPPORT _IOW(JPEGENC_IOC_MAGIC, 0x06, u32)
-#define JPEGENC_IOC_CONFIG_DMA_INPUT _IOW(JPEGENC_IOC_MAGIC, 0x07, s32)
-#define JPEGENC_IOC_RELEASE_DMA_INPUT _IOW(JPEGENC_IOC_MAGIC, 0x08, u32)
#define DCTSIZE2 64
@@ -112,7 +124,6 @@
JPEGENC_LOCAL_BUFF = 0,
JPEGENC_CANVAS_BUFF,
JPEGENC_PHYSICAL_BUFF,
- JPEGENC_DMA_BUFF,
JPEGENC_MAX_BUFF_TYPE
};
@@ -156,20 +167,9 @@
u32 jpeg_quality;
u32 QuantTable_id;
u32 flush_flag;
- u32 block_mode;
enum jpegenc_mem_type_e type;
enum jpegenc_frame_fmt_e input_fmt;
enum jpegenc_frame_fmt_e output_fmt;
-
- u32 y_off;
- u32 u_off;
- u32 v_off;
-
- u32 y_stride;
- u32 u_stride;
- u32 v_stride;
-
- u32 h_stride;
};
struct jpegenc_meminfo_s {
@@ -180,7 +180,6 @@
#ifdef CONFIG_CMA
ulong cma_pool_size;
#endif
-
struct Jpegenc_Buff_s reserve_mem;
struct Jpegenc_BuffInfo_s *bufspec;
};
@@ -212,7 +211,6 @@
#ifdef CONFIG_CMA
struct page *venc_pages;
#endif
- struct enc_dma_cfg *dma_input;
};
struct jpegenc_manager_s {
@@ -223,8 +221,6 @@
bool process_irq;
bool inited;
bool use_reserve;
- bool use_cma;
-
u8 opened;
spinlock_t sem_lock;
@@ -234,18 +230,6 @@
struct tasklet_struct tasklet;
};
-struct enc_dma_cfg {
- int fd;
- size_t size;
- void *dev;
- void *vaddr;
- void *paddr;
- struct dma_buf *dbuf;
- struct dma_buf_attachment *attach;
- struct sg_table *sg;
- enum dma_data_direction dir;
-};
-
/********************************************
* AV Scratch Register Re-Define
********************************************/
@@ -262,5 +246,4 @@
#define JPEGENC_ENCODER_DONE 4
extern bool jpegenc_on(void);
-#define JPEGENC_IOC_NEW_CMD2 _IOW(JPEGENC_IOC_MAGIC, 0x09, struct jpegenc_request_s)
#endif
diff --git a/drivers/frame_sink/encoder/multi/Makefile b/drivers/frame_sink/encoder/multi/Makefile
deleted file mode 100644
index 711ffe7..0000000
--- a/drivers/frame_sink/encoder/multi/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VENC_MULTI) += amvenc_multi.o
-amvenc_multi-objs += vpu_multi.o
diff --git a/drivers/frame_sink/encoder/multi/vmm_multi.h b/drivers/frame_sink/encoder/multi/vmm_multi.h
deleted file mode 100644
index 0c5cbae..0000000
--- a/drivers/frame_sink/encoder/multi/vmm_multi.h
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- *
- * Copyright (C) 2019 by Amlogic, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#ifndef __CNM_VIDEO_MEMORY_MANAGEMENT_H__
-#define __CNM_VIDEO_MEMORY_MANAGEMENT_H__
-
-#define VMEM_PAGE_SIZE (16 * 1024)
-#define MAKE_KEY(_a, _b) (((vmem_key_t)_a) << 32 | _b)
-#define KEY_TO_VALUE(_key) (_key >> 32)
-
-#define VMEM_P_ALLOC(_x) vmalloc(_x)
-#define VMEM_P_FREE(_x) vfree(_x)
-
-#define VMEM_ASSERT \
- pr_info("VMEM_ASSERT at %s:%d\n", __FILE__, __LINE__)
-
-
-#define VMEM_HEIGHT(_tree) (_tree == NULL ? -1 : _tree->height)
-
-#define MAX(_a, _b) (_a >= _b ? _a : _b)
-
-struct avl_node_t;
-#define vmem_key_t unsigned long long
-
-struct vmem_info_t {
- ulong total_pages;
- ulong alloc_pages;
- ulong free_pages;
- ulong page_size;
-};
-
-struct page_t {
- s32 pageno;
- ulong addr;
- s32 used;
- s32 alloc_pages;
- s32 first_pageno;
-};
-
-struct avl_node_t {
- vmem_key_t key;
- s32 height;
- struct page_t *page;
- struct avl_node_t *left;
- struct avl_node_t *right;
-};
-
-struct video_mm_t {
- struct avl_node_t *free_tree;
- struct avl_node_t *alloc_tree;
- struct page_t *page_list;
- s32 num_pages;
- ulong base_addr;
- ulong mem_size;
- s32 free_page_count;
- s32 alloc_page_count;
-};
-
-enum rotation_dir_t {
- LEFT,
- RIGHT
-};
-
-struct avl_node_data_t {
- s32 key;
- struct page_t *page;
-};
-
-static struct avl_node_t *make_avl_node(
- vmem_key_t key,
- struct page_t *page)
-{
- struct avl_node_t *node =
- (struct avl_node_t *)VMEM_P_ALLOC(sizeof(struct avl_node_t));
- node->key = key;
- node->page = page;
- node->height = 0;
- node->left = NULL;
- node->right = NULL;
- return node;
-}
-
-static s32 get_balance_factor(struct avl_node_t *tree)
-{
- s32 factor = 0;
-
- if (tree)
- factor = VMEM_HEIGHT(tree->right) - VMEM_HEIGHT(tree->left);
- return factor;
-}
-
-/*
- * Left Rotation
- *
- * A B
- * \ / \
- * B => A C
- * / \ \
- * D C D
- *
- */
-static struct avl_node_t *rotation_left(struct avl_node_t *tree)
-{
- struct avl_node_t *rchild;
- struct avl_node_t *lchild;
-
- if (tree == NULL)
- return NULL;
-
- rchild = tree->right;
- if (rchild == NULL)
- return tree;
-
- lchild = rchild->left;
- rchild->left = tree;
- tree->right = lchild;
-
- tree->height =
- MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
- rchild->height =
- MAX(VMEM_HEIGHT(rchild->left), VMEM_HEIGHT(rchild->right)) + 1;
- return rchild;
-}
-
-
-/*
- * Reft Rotation
- *
- * A B
- * \ / \
- * B => D A
- * / \ /
- * D C C
- *
- */
-static struct avl_node_t *rotation_right(struct avl_node_t *tree)
-{
- struct avl_node_t *rchild;
- struct avl_node_t *lchild;
-
- if (tree == NULL)
- return NULL;
-
- lchild = tree->left;
- if (lchild == NULL)
- return NULL;
-
- rchild = lchild->right;
- lchild->right = tree;
- tree->left = rchild;
-
- tree->height =
- MAX(VMEM_HEIGHT(tree->left),
- VMEM_HEIGHT(tree->right)) + 1;
- lchild->height =
- MAX(VMEM_HEIGHT(lchild->left),
- VMEM_HEIGHT(lchild->right)) + 1;
- return lchild;
-}
-
-static struct avl_node_t *do_balance(struct avl_node_t *tree)
-{
- s32 bfactor = 0, child_bfactor;
-
- bfactor = get_balance_factor(tree);
- if (bfactor >= 2) {
- child_bfactor = get_balance_factor(tree->right);
- if (child_bfactor == 1 || child_bfactor == 0) {
- tree = rotation_left(tree);
- } else if (child_bfactor == -1) {
- tree->right = rotation_right(tree->right);
- tree = rotation_left(tree);
- } else {
- pr_info(
- "invalid balancing factor: %d\n",
- child_bfactor);
- VMEM_ASSERT;
- return NULL;
- }
- } else if (bfactor <= -2) {
- child_bfactor = get_balance_factor(tree->left);
- if (child_bfactor == -1 || child_bfactor == 0) {
- tree = rotation_right(tree);
- } else if (child_bfactor == 1) {
- tree->left = rotation_left(tree->left);
- tree = rotation_right(tree);
- } else {
- pr_info(
- "invalid balancing factor: %d\n",
- child_bfactor);
- VMEM_ASSERT;
- return NULL;
- }
- }
- return tree;
-}
-
-static struct avl_node_t *unlink_end_node(
- struct avl_node_t *tree,
- s32 dir,
- struct avl_node_t **found_node)
-{
- struct avl_node_t *node;
- *found_node = NULL;
-
- if (tree == NULL)
- return NULL;
-
- if (dir == LEFT) {
- if (tree->left == NULL) {
- *found_node = tree;
- return NULL;
- }
- } else {
- if (tree->right == NULL) {
- *found_node = tree;
- return NULL;
- }
- }
-
- if (dir == LEFT) {
- node = tree->left;
- tree->left = unlink_end_node(tree->left, LEFT, found_node);
- if (tree->left == NULL) {
- tree->left = (*found_node)->right;
- (*found_node)->left = NULL;
- (*found_node)->right = NULL;
- }
- } else {
- node = tree->right;
- tree->right = unlink_end_node(tree->right, RIGHT, found_node);
- if (tree->right == NULL) {
- tree->right = (*found_node)->left;
- (*found_node)->left = NULL;
- (*found_node)->right = NULL;
- }
- }
- tree->height =
- MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
- return do_balance(tree);
-}
-
-
-static struct avl_node_t *avltree_insert(
- struct avl_node_t *tree,
- vmem_key_t key,
- struct page_t *page)
-{
- if (tree == NULL) {
- tree = make_avl_node(key, page);
- } else {
- if (key >= tree->key)
- tree->right =
- avltree_insert(tree->right, key, page);
- else
- tree->left =
- avltree_insert(tree->left, key, page);
- }
- tree = do_balance(tree);
- tree->height =
- MAX(VMEM_HEIGHT(tree->left), VMEM_HEIGHT(tree->right)) + 1;
- return tree;
-}
-
-static struct avl_node_t *do_unlink(struct avl_node_t *tree)
-{
- struct avl_node_t *node;
- struct avl_node_t *end_node;
-
- node = unlink_end_node(tree->right, LEFT, &end_node);
- if (node) {
- tree->right = node;
- } else {
- node =
- unlink_end_node(tree->left, RIGHT, &end_node);
- if (node)
- tree->left = node;
- }
-
- if (node == NULL) {
- node = tree->right ? tree->right : tree->left;
- end_node = node;
- }
-
- if (end_node) {
- end_node->left =
- (tree->left != end_node) ?
- tree->left : end_node->left;
- end_node->right =
- (tree->right != end_node) ?
- tree->right : end_node->right;
- end_node->height =
- MAX(VMEM_HEIGHT(end_node->left),
- VMEM_HEIGHT(end_node->right)) + 1;
- }
- tree = end_node;
- return tree;
-}
-
-static struct avl_node_t *avltree_remove(
- struct avl_node_t *tree,
- struct avl_node_t **found_node,
- vmem_key_t key)
-{
- *found_node = NULL;
- if (tree == NULL) {
- pr_info("failed to find key %d\n", (int)key);
- return NULL;
- }
-
- if (key == tree->key) {
- *found_node = tree;
- tree = do_unlink(tree);
- } else if (key > tree->key) {
- tree->right =
- avltree_remove(tree->right, found_node, key);
- } else {
- tree->left =
- avltree_remove(tree->left, found_node, key);
- }
-
- if (tree)
- tree->height =
- MAX(VMEM_HEIGHT(tree->left),
- VMEM_HEIGHT(tree->right)) + 1;
-
- tree = do_balance(tree);
- return tree;
-}
-
-void avltree_free(struct avl_node_t *tree)
-{
- if (tree == NULL)
- return;
- if (tree->left == NULL && tree->right == NULL) {
- VMEM_P_FREE(tree);
- return;
- }
-
- avltree_free(tree->left);
- tree->left = NULL;
- avltree_free(tree->right);
- tree->right = NULL;
- VMEM_P_FREE(tree);
-}
-
-static struct avl_node_t *remove_approx_value(
- struct avl_node_t *tree,
- struct avl_node_t **found,
- vmem_key_t key)
-{
- *found = NULL;
- if (tree == NULL)
- return NULL;
-
- if (key == tree->key) {
- *found = tree;
- tree = do_unlink(tree);
- } else if (key > tree->key) {
- tree->right = remove_approx_value(tree->right, found, key);
- } else {
- tree->left = remove_approx_value(tree->left, found, key);
- if (*found == NULL) {
- *found = tree;
- tree = do_unlink(tree);
- }
- }
- if (tree)
- tree->height =
- MAX(VMEM_HEIGHT(tree->left),
- VMEM_HEIGHT(tree->right)) + 1;
- tree = do_balance(tree);
- return tree;
-}
-
-static void set_blocks_free(
- struct video_mm_t *mm,
- s32 pageno,
- s32 npages)
-{
- s32 last_pageno = pageno + npages - 1;
- s32 i;
- struct page_t *page;
- struct page_t *last_page;
-
- if (npages == 0)
- VMEM_ASSERT;
-
- if (last_pageno >= mm->num_pages) {
- pr_info(
- "set_blocks_free: invalid last page number: %d\n",
- last_pageno);
- VMEM_ASSERT;
- return;
- }
-
- for (i = pageno; i <= last_pageno; i++) {
- mm->page_list[i].used = 0;
- mm->page_list[i].alloc_pages = 0;
- mm->page_list[i].first_pageno = -1;
- }
-
- page = &mm->page_list[pageno];
- page->alloc_pages = npages;
- last_page = &mm->page_list[last_pageno];
- last_page->first_pageno = pageno;
- mm->free_tree =
- avltree_insert(mm->free_tree, MAKE_KEY(npages, pageno), page);
-}
-
-static void set_blocks_alloc(
- struct video_mm_t *mm,
- s32 pageno,
- s32 npages)
-{
- s32 last_pageno = pageno + npages - 1;
- s32 i;
- struct page_t *page;
- struct page_t *last_page;
-
- if (last_pageno >= mm->num_pages) {
- pr_info(
- "set_blocks_free: invalid last page number: %d\n",
- last_pageno);
- VMEM_ASSERT;
- return;
- }
-
- for (i = pageno; i <= last_pageno; i++) {
- mm->page_list[i].used = 1;
- mm->page_list[i].alloc_pages = 0;
- mm->page_list[i].first_pageno = -1;
- }
-
- page = &mm->page_list[pageno];
- page->alloc_pages = npages;
- last_page = &mm->page_list[last_pageno];
- last_page->first_pageno = pageno;
- mm->alloc_tree =
- avltree_insert(mm->alloc_tree, MAKE_KEY(page->addr, 0), page);
-}
-
-
-s32 vmem_init(struct video_mm_t *mm, ulong addr, ulong size)
-{
- s32 i;
-
- if (mm == NULL)
- return -1;
-
- mm->base_addr = (addr + (VMEM_PAGE_SIZE - 1))
- & ~(VMEM_PAGE_SIZE - 1);
- mm->mem_size = size & ~VMEM_PAGE_SIZE;
- mm->num_pages = mm->mem_size / VMEM_PAGE_SIZE;
- mm->free_tree = NULL;
- mm->alloc_tree = NULL;
- mm->free_page_count = mm->num_pages;
- mm->alloc_page_count = 0;
- mm->page_list =
- (struct page_t *)VMEM_P_ALLOC(
- mm->num_pages * sizeof(struct page_t));
- if (mm->page_list == NULL) {
- pr_err("%s:%d failed to kmalloc(%ld)\n",
- __func__, __LINE__,
- (long)mm->num_pages * sizeof(struct page_t));
- return -1;
- }
-
- for (i = 0; i < mm->num_pages; i++) {
- mm->page_list[i].pageno = i;
- mm->page_list[i].addr =
- mm->base_addr + i * VMEM_PAGE_SIZE;
- mm->page_list[i].alloc_pages = 0;
- mm->page_list[i].used = 0;
- mm->page_list[i].first_pageno = -1;
- }
- set_blocks_free(mm, 0, mm->num_pages);
- return 0;
-}
-
-s32 vmem_exit(struct video_mm_t *mm)
-{
- if (mm == NULL) {
- pr_info("vmem_exit: invalid handle\n");
- return -1;
- }
-
- if (mm->free_tree)
- avltree_free(mm->free_tree);
- if (mm->alloc_tree)
- avltree_free(mm->alloc_tree);
-
- if (mm->page_list) {
- VMEM_P_FREE(mm->page_list);
- mm->page_list = NULL;
- }
-
- mm->base_addr = 0;
- mm->mem_size = 0;
- mm->num_pages = 0;
- mm->page_list = NULL;
- mm->free_tree = NULL;
- mm->alloc_tree = NULL;
- mm->free_page_count = 0;
- mm->alloc_page_count = 0;
- return 0;
-}
-
-ulong vmem_alloc(struct video_mm_t *mm, s32 size, ulong pid)
-{
- struct avl_node_t *node;
- struct page_t *free_page;
- s32 npages, free_size;
- s32 alloc_pageno;
- ulong ptr;
-
- if (mm == NULL) {
- pr_info("vmem_alloc: invalid handle\n");
- return -1;
- }
-
- if (size <= 0)
- return -1;
-
- npages = (size + VMEM_PAGE_SIZE - 1) / VMEM_PAGE_SIZE;
- mm->free_tree = remove_approx_value(mm->free_tree,
- &node, MAKE_KEY(npages, 0));
-
- if (node == NULL)
- return -1;
-
- free_page = node->page;
- free_size = KEY_TO_VALUE(node->key);
- alloc_pageno = free_page->pageno;
- set_blocks_alloc(mm, alloc_pageno, npages);
- if (npages != free_size) {
- s32 free_pageno = alloc_pageno + npages;
-
- set_blocks_free(mm, free_pageno, (free_size-npages));
- }
- VMEM_P_FREE(node);
-
- ptr = mm->page_list[alloc_pageno].addr;
- mm->alloc_page_count += npages;
- mm->free_page_count -= npages;
- return ptr;
-}
-
-s32 vmem_free(struct video_mm_t *mm, ulong ptr, ulong pid)
-{
- ulong addr;
- struct avl_node_t *found;
- struct page_t *page;
- s32 pageno, prev_free_pageno, next_free_pageno;
- s32 prev_size, next_size;
- s32 merge_page_no, merge_page_size, free_page_size;
-
- if (mm == NULL) {
- pr_info("vmem_free: invalid handle\n");
- return -1;
- }
-
- addr = ptr;
- mm->alloc_tree = avltree_remove(mm->alloc_tree, &found,
- MAKE_KEY(addr, 0));
-
- if (found == NULL) {
- pr_info("vmem_free: 0x%08x not found\n", (s32)addr);
- VMEM_ASSERT;
- return -1;
- }
-
- /* find previous free block */
- page = found->page;
- pageno = page->pageno;
- free_page_size = page->alloc_pages;
- prev_free_pageno = pageno - 1;
- prev_size = -1;
- if (prev_free_pageno >= 0) {
- if (mm->page_list[prev_free_pageno].used == 0) {
- prev_free_pageno =
- mm->page_list[prev_free_pageno].first_pageno;
- prev_size =
- mm->page_list[prev_free_pageno].alloc_pages;
- }
- }
-
- /* find next free block */
- next_free_pageno = pageno + page->alloc_pages;
- next_free_pageno =
- (next_free_pageno == mm->num_pages) ? -1 : next_free_pageno;
- next_size = -1;
- if (next_free_pageno >= 0) {
- if (mm->page_list[next_free_pageno].used == 0) {
- next_size =
- mm->page_list[next_free_pageno].alloc_pages;
- }
- }
- VMEM_P_FREE(found);
-
- /* merge */
- merge_page_no = page->pageno;
- merge_page_size = page->alloc_pages;
- if (prev_size >= 0) {
- mm->free_tree = avltree_remove(mm->free_tree, &found,
- MAKE_KEY(prev_size, prev_free_pageno));
- if (found == NULL) {
- VMEM_ASSERT;
- return -1;
- }
- merge_page_no = found->page->pageno;
- merge_page_size += found->page->alloc_pages;
- VMEM_P_FREE(found);
- }
- if (next_size >= 0) {
- mm->free_tree = avltree_remove(mm->free_tree, &found,
- MAKE_KEY(next_size, next_free_pageno));
- if (found == NULL) {
- VMEM_ASSERT;
- return -1;
- }
- merge_page_size += found->page->alloc_pages;
- VMEM_P_FREE(found);
- }
- page->alloc_pages = 0;
- page->first_pageno = -1;
- set_blocks_free(mm, merge_page_no, merge_page_size);
- mm->alloc_page_count -= free_page_size;
- mm->free_page_count += free_page_size;
- return 0;
-}
-
-s32 vmem_get_info(struct video_mm_t *mm, struct vmem_info_t *info)
-{
- if (mm == NULL) {
- pr_info("vmem_get_info: invalid handle\n");
- return -1;
- }
-
- if (info == NULL)
- return -1;
-
- info->total_pages = mm->num_pages;
- info->alloc_pages = mm->alloc_page_count;
- info->free_pages = mm->free_page_count;
- info->page_size = VMEM_PAGE_SIZE;
- return 0;
-}
-#endif /* __CNM_VIDEO_MEMORY_MANAGEMENT_H__ */
diff --git a/drivers/frame_sink/encoder/multi/vpu_multi.c b/drivers/frame_sink/encoder/multi/vpu_multi.c
deleted file mode 100644
index fda8c28..0000000
--- a/drivers/frame_sink/encoder/multi/vpu_multi.c
+++ /dev/null
@@ -1,3489 +0,0 @@
-/*
- *
- * Copyright (C) 2019 by Amlogic, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#define LOG_LINE() pr_err("[%s:%d]\n", __FUNCTION__, __LINE__);
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/uaccess.h>
-#include <linux/cdev.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
-#include <linux/reset.h>
-#include <linux/clk.h>
-#include <linux/compat.h>
-#include <linux/of_reserved_mem.h>
-#include <linux/of_address.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/kfifo.h>
-#include <linux/kthread.h>
-#include <linux/sched/signal.h>
-#include <linux/amlogic/cpu_version.h>
-//#include <linux/amlogic/pwr_ctrl.h>
-
-#include <linux/amlogic/media/canvas/canvas.h>
-#include <linux/amlogic/media/canvas/canvas_mgr.h>
-
-#include <linux/amlogic/power_ctrl.h>
-#include <dt-bindings/power/t7-pd.h>
-#include <linux/amlogic/power_domain.h>
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../../../frame_provider/decoder/utils/vdec.h"
-#include "../../../frame_provider/decoder/utils/vdec_power_ctrl.h"
-#include "vpu_multi.h"
-#include "vmm_multi.h"
-
-#define MAX_INTERRUPT_QUEUE (16*MAX_NUM_INSTANCE)
-
-/* definitions to be changed as customer configuration */
-/* if you want to have clock gating scheme frame by frame */
-#define VPU_SUPPORT_CLOCK_CONTROL
-
-#define VPU_PLATFORM_DEVICE_NAME "amvenc_multi"
-#define VPU_DEV_NAME "amvenc_multi"
-#define VPU_CLASS_NAME "amvenc_multi"
-
-#ifndef VM_RESERVED /*for kernel up to 3.7.0 version*/
-#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
-#endif
-
-#define MHz (1000000)
-
-#define VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE (256 * SZ_1M)
-
-#define LOG_ALL 0
-#define LOG_INFO 1
-#define LOG_DEBUG 2
-#define LOG_ERROR 3
-
-#define enc_pr(level, x...) \
- do { \
- if (level >= print_level) \
- printk(x); \
- } while (0)
-
-static s32 print_level = LOG_DEBUG;
-static s32 clock_level = 4;
-static s32 clock_gate_count = 0;
-static u32 set_clock_freq = 0;
-
-static struct video_mm_t s_vmem;
-static struct vpudrv_buffer_t s_video_memory = {0};
-static bool use_reserve;
-static ulong cma_pool_size;
-static u32 cma_cfg_size;
-
-static u32 clock_a, clock_b, clock_c;
-static int dump_input;
-static int dump_es;
-static int vpu_hw_reset(void);
-static void hw_reset(bool reset);
-
-struct vpu_clks {
- struct clk *dos_clk;
- struct clk *dos_apb_clk;
- struct clk *a_clk;
- struct clk *b_clk;
- struct clk *c_clk;
-};
-
-static struct vpu_clks s_vpu_clks;
-
-#ifdef CONFIG_COMPAT
-static struct file *file_open(const char *path, int flags, int rights)
-{
- struct file *filp = NULL;
- mm_segment_t oldfs;
- long err1 = 0;
- void *err2 = NULL;
-
- oldfs = get_fs();
- //set_fs(get_ds());
- set_fs(KERNEL_DS);
- filp = filp_open(path, flags, rights);
- set_fs(oldfs);
-
- if (IS_ERR(filp)) {
- err1 = PTR_ERR(filp);
- err2 = ERR_PTR(err1);
- pr_err("filp_open return %p, %ld, %p\n", filp, err1, err2);
- return NULL;
- }
-
- return filp;
-}
-
-static void file_close(struct file *file)
-{
- filp_close(file, NULL);
-}
-/*
-static int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
-{
- mm_segment_t oldfs;
- int ret;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- ret = vfs_read(file, data, size, &offset);
-
- set_fs(oldfs);
- return ret;
-}*/
-static int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
-{
- mm_segment_t oldfs;
- int ret;
- //loff_t pos;
-
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- //pos = file->f_pos;
- ret = vfs_write(file, data, size, &offset);
- //file->f_pos = pos;
-
- set_fs(oldfs);
- return ret;
-}
-
-static int file_sync(struct file *file)
-{
- vfs_fsync(file, 0);
- return 0;
-}
-static s32 dump_raw_input(struct canvas_s *cs0) {
- u8 *data;
-
- u32 addr, canvas_w, picsize_y;
- //u32 input = request->src;
- //u8 iformat = MAX_FRAME_FMT;
- struct file *filp;
- int ret;
-
- addr = cs0->addr;
-
- canvas_w = ((cs0->width + 31) >> 5) << 5;
- picsize_y = cs0->height;
-
- filp = file_open("/data/multienc.yuv", O_CREAT | O_RDWR | O_APPEND, 0777);
-
- if (filp) {
- data = (u8*)phys_to_virt(addr);
- ret = file_write(filp, 0, data, canvas_w * picsize_y);
-
- file_sync(filp);
- file_close(filp);
- } else
- pr_err("open encoder.yuv failed\n");
-
- return 0;
-}
-
-static s32 dump_data(u32 phy_addr, u32 size) {
- u8 *data ;
-
- struct file *filp;
- int ret;
-
- filp = file_open("/data/multienc.es", O_CREAT | O_RDWR | O_APPEND, 0777);
-
- if (filp) {
- data = (u8*)phys_to_virt(phy_addr);
- ret = file_write(filp, 0, data, size);
-
- file_sync(filp);
- file_close(filp);
- } else
- pr_err("open encoder.es failed\n");
-
- return 0;
-}
-#endif
-
-/*static s32 dump_encoded_data(u8 *data, u32 size) {
- struct file *filp;
-
- filp = file_open("/data/multienc_output.es", O_APPEND | O_RDWR, 0644);
-
- if (filp) {
- file_write(filp, 0, data, size);
- file_sync(filp);
- file_close(filp);
- } else
- pr_err("/data/multienc_output.es failed\n");
-
- return 0;
-}*/
-
-static void vpu_clk_put(struct device *dev, struct vpu_clks *clks)
-{
- if (!(clks->c_clk == NULL || IS_ERR(clks->c_clk)))
- devm_clk_put(dev, clks->c_clk);
- if (!(clks->b_clk == NULL || IS_ERR(clks->b_clk)))
- devm_clk_put(dev, clks->b_clk);
- if (!(clks->a_clk == NULL || IS_ERR(clks->a_clk)))
- devm_clk_put(dev, clks->a_clk);
- if (!(clks->dos_apb_clk == NULL || IS_ERR(clks->dos_apb_clk)))
- devm_clk_put(dev, clks->dos_apb_clk);
- if (!(clks->dos_clk == NULL || IS_ERR(clks->dos_clk)))
- devm_clk_put(dev, clks->dos_clk);
-}
-
-static int vpu_clk_get(struct device *dev, struct vpu_clks *clks)
-{
- int ret = 0;
-
- clks->dos_clk = devm_clk_get(dev, "clk_dos");
-
- if (IS_ERR(clks->dos_clk)) {
- enc_pr(LOG_ERROR, "cannot get clk_dos clock\n");
- clks->dos_clk = NULL;
- ret = -ENOENT;
- goto err;
- }
-
- clks->dos_apb_clk = devm_clk_get(dev, "clk_apb_dos");
-
- if (IS_ERR(clks->dos_apb_clk)) {
- enc_pr(LOG_ERROR, "cannot get clk_apb_dos clock\n");
- clks->dos_apb_clk = NULL;
- ret = -ENOENT;
- goto err;
- }
-
- clks->a_clk = devm_clk_get(dev, "clk_MultiEnc_A");
-
- if (IS_ERR(clks->a_clk)) {
- enc_pr(LOG_ERROR, "cannot get clock\n");
- clks->a_clk = NULL;
- ret = -ENOENT;
- goto err;
- }
-
- clks->b_clk = devm_clk_get(dev, "clk_MultiEnc_B");
-
- if (IS_ERR(clks->b_clk)) {
- enc_pr(LOG_ERROR, "cannot get clk_MultiEnc_B clock\n");
- clks->b_clk = NULL;
- ret = -ENOENT;
- goto err;
- }
-
- clks->c_clk = devm_clk_get(dev, "clk_MultiEnc_C");
-
- if (IS_ERR(clks->c_clk)) {
- enc_pr(LOG_ERROR, "cannot get clk_MultiEnc_C clock\n");
- clks->c_clk = NULL;
- ret = -ENOENT;
- goto err;
- }
-
- return 0;
-err:
- vpu_clk_put(dev, clks);
-
- return ret;
-}
-
-static void vpu_clk_enable(struct vpu_clks *clks)
-{
- u32 freq = 400;
-
- if (set_clock_freq && set_clock_freq <= 400)
- freq = set_clock_freq;
-
- clk_set_rate(clks->dos_clk, freq * MHz);
- clk_set_rate(clks->dos_apb_clk, freq * MHz);
-
- if (clock_a > 0) {
- pr_info("vpu_multi: desired clock_a freq %u\n", clock_a);
- clk_set_rate(clks->a_clk, clock_a);
- } else
- clk_set_rate(clks->a_clk, 666666666);
-
- if (clock_b > 0) {
- pr_info("vpu_multi: desired clock_b freq %u\n", clock_b);
- clk_set_rate(clks->b_clk, clock_b);
- } else
- clk_set_rate(clks->b_clk, 500 * MHz);
-
- if (clock_c > 0) {
- pr_info("vpu_multi: desired clock_c freq %u\n", clock_c);
- clk_set_rate(clks->c_clk, clock_c);
- } else
- clk_set_rate(clks->c_clk, 500 * MHz);
-
- clk_prepare_enable(clks->dos_clk);
- clk_prepare_enable(clks->dos_apb_clk);
- clk_prepare_enable(clks->a_clk);
- clk_prepare_enable(clks->b_clk);
- clk_prepare_enable(clks->c_clk);
-
- enc_pr(LOG_DEBUG, "dos: %ld, dos_apb: %ld, a: %ld, b: %ld, c: %ld\n",
- clk_get_rate(clks->dos_clk), clk_get_rate(clks->dos_apb_clk),
- clk_get_rate(clks->a_clk), clk_get_rate(clks->b_clk),
- clk_get_rate(clks->c_clk));
-
- /* the power on */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("powering on wave521 for t7\n");
- vdec_poweron(VDEC_WAVE);
- mdelay(5);
- pr_err("wave power stauts after poweron: %d\n", vdec_on(VDEC_WAVE));
- } else {
- pwr_ctrl_psci_smc(PDID_T7_DOS_WAVE, true);
- mdelay(5);
- pr_err("wave power stauts after poweron: %lu\n", pwr_ctrl_status_psci_smc(PDID_T7_DOS_WAVE));
- }
-
- /* reset */
- hw_reset(true);
- mdelay(5);
- hw_reset(false);
- /* gate the clocks */
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- pr_err("vpu_clk_enable, now gate off the clock\n");
- clk_disable(clks->c_clk);
- clk_disable(clks->b_clk);
- clk_disable(clks->a_clk);
-#endif
-}
-
-static void vpu_clk_disable(struct vpu_clks *clks)
-{
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- if (clock_gate_count > 0)
-#endif
- {
- enc_pr(LOG_INFO, "vpu unclosed clock %d\n", clock_gate_count);
- clk_disable(clks->c_clk);
- clk_disable(clks->b_clk);
- clk_disable(clks->a_clk);
- clock_gate_count = 0;
- }
- clk_unprepare(clks->c_clk);
- clk_unprepare(clks->b_clk);
- clk_unprepare(clks->a_clk);
- clk_disable_unprepare(clks->dos_apb_clk);
- clk_disable_unprepare(clks->dos_clk);
- /* the power off */
- /* the power on */
- if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("powering off wave521 for t7\n");
- vdec_poweron(VDEC_WAVE);
- mdelay(5);
- pr_err("wave power stauts after poweroff: %d\n", vdec_on(VDEC_WAVE));
- } else {
- pwr_ctrl_psci_smc(PDID_T7_DOS_WAVE, false);
- mdelay(5);
- pr_err("wave power stauts after poweroff: %lu\n", pwr_ctrl_status_psci_smc(PDID_T7_DOS_WAVE));
- }
-}
-
-/* end customer definition */
-static struct vpudrv_buffer_t s_instance_pool = {0};
-static struct vpudrv_buffer_t s_common_memory = {0};
-static struct vpu_drv_context_t s_vpu_drv_context;
-static s32 s_vpu_major;
-static s32 s_register_flag;
-static struct device *multienc_dev;
-
-static s32 s_vpu_open_ref_count;
-static s32 s_vpu_irq;
-static bool s_vpu_irq_requested;
-
-static struct vpudrv_buffer_t s_vpu_register = {0};
-
-static s32 s_interrupt_flag[MAX_NUM_INSTANCE];
-static wait_queue_head_t s_interrupt_wait_q[MAX_NUM_INSTANCE];
-static struct kfifo s_interrupt_pending_q[MAX_NUM_INSTANCE];
-static s32 s_fifo_alloc_flag[MAX_NUM_INSTANCE];
-static spinlock_t s_kfifo_lock = __SPIN_LOCK_UNLOCKED(s_kfifo_lock);
-
-static spinlock_t s_vpu_lock = __SPIN_LOCK_UNLOCKED(s_vpu_lock);
-static DEFINE_SEMAPHORE(s_vpu_sem);
-static struct list_head s_vbp_head = LIST_HEAD_INIT(s_vbp_head);
-static struct list_head s_inst_list_head = LIST_HEAD_INIT(s_inst_list_head);
-static struct tasklet_struct multienc_tasklet;
-static struct platform_device *multienc_pdev;
-
-static struct vpu_bit_firmware_info_t s_bit_firmware_info[MAX_NUM_VPU_CORE];
-
-static spinlock_t s_dma_buf_lock = __SPIN_LOCK_UNLOCKED(s_dma_buf_lock);
-static struct list_head s_dma_bufp_head = LIST_HEAD_INIT(s_dma_bufp_head);
-
-static s32 vpu_src_addr_config(struct vpudrv_dma_buf_info_t *dma_info,
- struct file *filp);
-static s32 vpu_src_addr_unmap(struct vpudrv_dma_buf_info_t *dma_info,
- struct file *filp);
-static void vpu_dma_buffer_unmap(struct vpu_dma_cfg *cfg);
-
-static void dma_flush(u32 buf_start, u32 buf_size)
-{
- if (multienc_pdev)
- dma_sync_single_for_device(
- &multienc_pdev->dev, buf_start,
- buf_size, DMA_TO_DEVICE);
-}
-
-static void cache_flush(u32 buf_start, u32 buf_size)
-{
- if (multienc_pdev)
- dma_sync_single_for_cpu(
- &multienc_pdev->dev, buf_start,
- buf_size, DMA_FROM_DEVICE);
-}
-
-s32 vpu_hw_reset(void)
-{
- enc_pr(LOG_DEBUG, "request vpu reset from application\n");
- return 0;
-}
-
-static void vpu_clk_config(int enable)
-{
- struct vpu_clks *clks = &s_vpu_clks;
-
- enc_pr(LOG_INFO, " vpu clock config %d\n", enable);
-
- if (enable == 0) {
- clock_gate_count --;
- if (clock_gate_count == 0) {
- clk_disable(clks->c_clk);
- clk_disable(clks->b_clk);
- clk_disable(clks->a_clk);
- } else if (clock_gate_count < 0)
- enc_pr(LOG_ERROR, "vpu clock alredy closed %d\n",
- clock_gate_count);
- } else {
- clock_gate_count ++;
- if (clock_gate_count == 1) {
- clk_enable(clks->a_clk);
- clk_enable(clks->b_clk);
- clk_enable(clks->c_clk);
- }
- }
-}
-
-static s32 vpu_alloc_dma_buffer(struct vpudrv_buffer_t *vb)
-{
- if (!vb)
- return -1;
-
- vb->phys_addr = (ulong)vmem_alloc(&s_vmem, vb->size, 0);
- if ((ulong)vb->phys_addr == (ulong)-1) {
- enc_pr(LOG_ERROR,
- "Physical memory allocation error size=%d\n",
- vb->size);
- return -1;
- }
-
- enc_pr(LOG_INFO,
- "%s: vb->phys_addr 0x%lx\n", __func__,
- vb->phys_addr);
- return 0;
-}
-
-static void vpu_free_dma_buffer(struct vpudrv_buffer_t *vb)
-{
- if (!vb)
- return;
- enc_pr(LOG_INFO, "vpu_free_dma_buffer 0x%lx\n",vb->phys_addr);
-
- if (vb->phys_addr)
- vmem_free(&s_vmem, vb->phys_addr, 0);
-}
-
-static s32 vpu_free_instances(struct file *filp)
-{
- struct vpudrv_instanace_list_t *vil, *n;
- struct vpudrv_instance_pool_t *vip;
- void *vip_base;
- s32 instance_pool_size_per_core;
- void *vdi_mutexes_base;
- const s32 PTHREAD_MUTEX_T_DESTROY_VALUE = 0xdead10cc;
-
- enc_pr(LOG_DEBUG, "[VPUDRV] vpu_free_instances\n");
-
- /* s_instance_pool.size was assigned to the size of all core once
- call VDI_IOCTL_GET_INSTANCE_POOL by user. */
- instance_pool_size_per_core = (s_instance_pool.size/MAX_NUM_VPU_CORE);
-
- list_for_each_entry_safe(vil, n, &s_inst_list_head, list) {
- if (vil->filp == filp) {
- vip_base = (void *)(s_instance_pool.base +
- (instance_pool_size_per_core*vil->core_idx));
- enc_pr(LOG_INFO,
- "free_ins Idx=%d, core=%d, base=%p, sz=%d\n",
- (s32)vil->inst_idx, (s32)vil->core_idx,
- vip_base,
- (s32)instance_pool_size_per_core);
- vip = (struct vpudrv_instance_pool_t *)vip_base;
- if (vip) {
- /* only first 4 byte is key point
- * (inUse of CodecInst in vpuapi)
- * to free the corresponding instance.
- */
- memset(&vip->codecInstPool[vil->inst_idx],
- 0x00, 4);
-
-#define PTHREAD_MUTEX_T_HANDLE_SIZE 4
- vdi_mutexes_base = (vip_base +
- (instance_pool_size_per_core -
- PTHREAD_MUTEX_T_HANDLE_SIZE*4));
- enc_pr(LOG_INFO,
- "Force destroy in user space ");
- enc_pr(LOG_INFO," vdi_mutex_base=%p \n",
- vdi_mutexes_base);
- if (vdi_mutexes_base) {
- s32 i;
- for (i = 0; i < 4; i++) {
- memcpy(vdi_mutexes_base,
- &PTHREAD_MUTEX_T_DESTROY_VALUE,
- PTHREAD_MUTEX_T_HANDLE_SIZE);
- vdi_mutexes_base +=
- PTHREAD_MUTEX_T_HANDLE_SIZE;
- }
- }
- }
- spin_lock(&s_vpu_lock);
- s_vpu_open_ref_count--;
- list_del(&vil->list);
- spin_unlock(&s_vpu_lock);
- kfree(vil);
- }
- }
- return 1;
-}
-
-static s32 vpu_free_buffers(struct file *filp)
-{
- struct vpudrv_buffer_pool_t *pool, *n;
- struct vpudrv_buffer_t vb;
-
- enc_pr(LOG_DEBUG, "vpu_free_buffers\n");
- list_for_each_entry_safe(pool, n, &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if (vb.phys_addr) {
- vpu_free_dma_buffer(&vb);
- spin_lock(&s_vpu_lock);
- list_del(&pool->list);
- spin_unlock(&s_vpu_lock);
- kfree(pool);
- }
- }
- }
- return 0;
-}
-
-static u32 vpu_is_buffer_cached(struct file *filp, ulong vm_pgoff)
-{
- struct vpudrv_buffer_pool_t *pool, *n;
- struct vpudrv_buffer_t vb;
- bool find = false;
- u32 cached = 0;
-
- enc_pr(LOG_ALL, "[+]vpu_is_buffer_cached\n");
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(pool, n, &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if (((vb.phys_addr >> PAGE_SHIFT) == vm_pgoff)
- && find == false){
- cached = vb.cached;
- find = true;
- break;
- }
- }
- }
- spin_unlock(&s_vpu_lock);
- enc_pr(LOG_ALL, "[-]vpu_is_buffer_cached, ret:%d\n", cached);
- return cached;
-}
-
-static s32 vpu_dma_buf_release(struct file *filp)
-{
- struct vpudrv_dma_buf_pool_t *pool, *n;
- struct vpu_dma_cfg vb;
-
- enc_pr(LOG_DEBUG, "vpu_release_dma_buffers\n");
- list_for_each_entry_safe(pool, n, &s_dma_bufp_head, list) {
- if (pool->filp == filp) {
- vb = pool->dma_cfg;
- if (vb.attach) {
- vpu_dma_buffer_unmap(&vb);
- spin_lock(&s_dma_buf_lock);
- list_del(&pool->list);
- spin_unlock(&s_dma_buf_lock);
- kfree(pool);
- }
- }
- }
- return 0;
-}
-
-static inline u32 get_inst_idx(u32 reg_val)
-{
- u32 inst_idx;
- int i;
- for (i=0; i < MAX_NUM_INSTANCE; i++)
- {
- if (((reg_val >> i)&0x01) == 1)
- break;
- }
- inst_idx = i;
- return inst_idx;
-}
-
-static s32 get_vpu_inst_idx(struct vpu_drv_context_t *dev, u32 *reason,
- u32 empty_inst, u32 done_inst, u32 seq_inst)
-{
- s32 inst_idx;
- u32 reg_val;
- u32 int_reason;
-
- int_reason = *reason;
- enc_pr(LOG_INFO,
- "[+]%s, reason=0x%x, empty_inst=0x%x, done_inst=0x%x\n",
- __func__, int_reason, empty_inst, done_inst);
-
- if (int_reason & (1 << INT_BSBUF_EMPTY))
- {
- reg_val = (empty_inst & 0xffff);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_BSBUF_EMPTY);
- enc_pr(LOG_DEBUG,
- "%s, RET_BS_EMPTY_INST reg_val=0x%x, inst_idx=%d\n",
- __func__, reg_val, inst_idx);
- goto GET_VPU_INST_IDX_HANDLED;
- }
-
- if (int_reason & (1 << INT_INIT_SEQ))
- {
- reg_val = (seq_inst & 0xffff);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_INIT_SEQ);
- enc_pr(LOG_DEBUG,
- "%s, RET_QUEUE_CMD_DONE INIT_SEQ val=0x%x, idx=%d\n",
- __func__, reg_val, inst_idx);
- goto GET_VPU_INST_IDX_HANDLED;
- }
-
- if (int_reason & (1 << INT_DEC_PIC))
- {
- reg_val = (done_inst & 0xffff);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_DEC_PIC);
- enc_pr(LOG_INFO,
- "%s, RET_QUEUE_CMD_DONE DEC_PIC val=0x%x, idx=%d\n",
- __func__, reg_val, inst_idx);
-
- if (int_reason & (1 << INT_ENC_LOW_LATENCY))
- {
- u32 ll_inst_idx;
- reg_val = (done_inst >> 16);
- ll_inst_idx = get_inst_idx(reg_val);
- if (ll_inst_idx == inst_idx)
- *reason = ((1 << INT_DEC_PIC)
- | (1 << INT_ENC_LOW_LATENCY));
- enc_pr(LOG_DEBUG, "%s, LOW_LATENCY ", __func__);
- enc_pr(LOG_DEBUG, "val=0x%x, idx=%d, ll_idx=%d\n",
- reg_val, inst_idx, ll_inst_idx);
- }
- goto GET_VPU_INST_IDX_HANDLED;
- }
-
- if (int_reason & (1 << INT_ENC_SET_PARAM))
- {
- reg_val = (seq_inst & 0xffff);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_ENC_SET_PARAM);
- enc_pr(LOG_DEBUG,
- "%s, RET_QUEUE_CMD_DONE SET_PARAM val=0x%x, idx=%d\n",
- __func__, reg_val, inst_idx);
- goto GET_VPU_INST_IDX_HANDLED;
- }
-
-#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
- if (int_reason & (1 << INT_ENC_SRC_RELEASE))
- {
- reg_val = (done_inst & 0xffff);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_ENC_SRC_RELEASE);
- enc_pr(LOG_DEBUG,
- "%s, RET_QUEUE_CMD_DONE SRC_RELEASE ",
- __func__);
- enc_pr(LOG_DEBUG,
- "val=0x%x, idx=%d\n", reg_val, inst_idx);
- goto GET_VPU_INST_IDX_HANDLED;
- }
-#endif
-
- if (int_reason & (1 << INT_ENC_LOW_LATENCY))
- {
- reg_val = (done_inst >> 16);
- inst_idx = get_inst_idx(reg_val);
- *reason = (1 << INT_ENC_LOW_LATENCY);
- enc_pr(LOG_DEBUG,
- "%s, RET_QUEUE_CMD_DONE LOW_LATENCY ",
- __func__);
- enc_pr(LOG_DEBUG,
- "val=0x%x, idx=%d\n", reg_val, inst_idx);
- goto GET_VPU_INST_IDX_HANDLED;
- }
-
- inst_idx = -1;
- *reason = 0;
- enc_pr(LOG_DEBUG,
- "%s, UNKNOWN INTERRUPT REASON: 0x%08x\n",
- __func__, int_reason);
-
-GET_VPU_INST_IDX_HANDLED:
-
- enc_pr(LOG_INFO, "[-]%s, inst_idx=%d. *reason=0x%x\n", __func__,
- inst_idx, *reason);
-
- return inst_idx;
-}
-
-static void multienc_isr_tasklet(ulong data)
-{
- u32 intr_reason;
- u32 inst_index;
- struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)data;
-
- /* notify the interrupt to user space */
- if (dev->async_queue) {
- enc_pr(LOG_ALL, "kill_fasync e %s\n", __func__);
- kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
- }
-
- for (inst_index=0; inst_index < MAX_NUM_INSTANCE; inst_index++) {
- intr_reason = dev->interrupt_flag[inst_index];
- if (intr_reason) {
- dev->interrupt_flag[inst_index] = 0;
- enc_pr(LOG_INFO,
- "isr_tasklet intr:0x%08x ins_index %d\n",
- intr_reason, inst_index);
- s_interrupt_flag[inst_index] = 1;
- wake_up_interruptible(&s_interrupt_wait_q[inst_index]);
- }
- }
- enc_pr(LOG_ALL, "[-]%s\n", __func__);
-}
-
-static irqreturn_t vpu_irq_handler(s32 irq, void *dev_id)
-{
- struct vpu_drv_context_t *dev = (struct vpu_drv_context_t *)dev_id;
- /* this can be removed.
- * it also work in VPU_WaitInterrupt of API function
- */
- u32 core;
- u32 intr_reason;
- u32 intr_inst_index;
-
- enc_pr(LOG_ALL, "[+]%s\n", __func__);
-
-#ifdef VPU_IRQ_CONTROL
- disable_irq_nosync(s_vpu_irq);
-#endif
-
- intr_inst_index = 0;
- intr_reason = 0;
-
- for (core = 0; core < MAX_NUM_VPU_CORE; core++) {
- u32 empty_inst;
- u32 done_inst;
- u32 seq_inst;
- u32 i, reason, reason_clr;
- if (s_bit_firmware_info[core].size == 0) {
- /* it means that we didn't get an information
- * the current core from API layer.
- * No core activated.
- */
- enc_pr(LOG_ERROR,
- "s_bit_firmware_info[core].size is zero\n");
- continue;
- }
- if (ReadVpuRegister(VP5_VPU_VPU_INT_STS) == 0)
- continue;
- reason = ReadVpuRegister(VP5_VPU_INT_REASON);
- empty_inst = ReadVpuRegister(VP5_RET_BS_EMPTY_INST);
- done_inst = ReadVpuRegister(VP5_RET_QUEUE_CMD_DONE_INST);
- seq_inst = ReadVpuRegister(VP5_RET_SEQ_DONE_INSTANCE_INFO);
- reason_clr = reason;
- enc_pr(LOG_INFO, "irq reason=0x%x, inst: empty=0x%x,",
- reason, empty_inst);
- enc_pr(LOG_INFO, " done=0x%x, seq_inst=0x%x\n",
- done_inst, seq_inst);
- for (i = 0; i < MAX_NUM_INSTANCE; i++) {
- if (empty_inst == 0 && done_inst == 0 && seq_inst == 0)
- break;
-
- intr_reason = reason;
- intr_inst_index = get_vpu_inst_idx(dev,
- &intr_reason,
- empty_inst,
- done_inst,
- seq_inst);
-
- enc_pr(LOG_INFO, "irq instance: %d", intr_inst_index);
- enc_pr(LOG_INFO, " reason: %08x", intr_reason);
- enc_pr(LOG_INFO, " empty_inst: %08x", empty_inst);
- enc_pr(LOG_INFO, " done_inst: %08x", done_inst);
- enc_pr(LOG_INFO, " seq_inst: %08x\n", seq_inst);
-
- if (intr_inst_index < MAX_NUM_INSTANCE) {
- if (intr_reason == (1 << INT_BSBUF_EMPTY)) {
- empty_inst = empty_inst &
- ~(1 << intr_inst_index);
- WriteVpuRegister(VP5_RET_BS_EMPTY_INST,
- empty_inst);
- if (empty_inst == 0)
- reason &=
- ~(1 << INT_BSBUF_EMPTY);
- enc_pr(LOG_INFO,
- "%s, RET_BS_EMPTY_INST Clear ",
- __func__);
- enc_pr(LOG_INFO,
- "inst=0x%x, index=%d\n",
- empty_inst, intr_inst_index);
- }
- if (intr_reason == (1 << INT_DEC_PIC)) {
- done_inst = done_inst &
- ~(1 << intr_inst_index);
- WriteVpuRegister(
- VP5_RET_QUEUE_CMD_DONE_INST,
- done_inst);
- if (done_inst == 0)
- reason &= ~(1 << INT_DEC_PIC);
- enc_pr(LOG_INFO,
- "%s, RET_QUEUE_CMD_DONE ",
- __func__);
- enc_pr(LOG_INFO,
- "inst=0x%x, index=%d\n",
- done_inst, intr_inst_index);
- }
- if ((intr_reason == (1 << INT_INIT_SEQ)) ||
- (intr_reason ==
- (1 << INT_ENC_SET_PARAM))) {
- seq_inst = seq_inst &
- ~(1 << intr_inst_index);
- WriteVpuRegister
- (VP5_RET_SEQ_DONE_INSTANCE_INFO,
- seq_inst);
- if (seq_inst == 0)
- reason &= ~(1 << INT_INIT_SEQ |
- 1 << INT_ENC_SET_PARAM);
-
- enc_pr(LOG_INFO, "%s, RET_", __func__);
- enc_pr(LOG_INFO,
- "SEQ_DONE_INSTANCE_INFO inst");
- enc_pr(LOG_INFO,
- "=0x%x, intr_inst_index=%d\n",
- done_inst, intr_inst_index);
- }
- if (intr_reason == (1 << INT_ENC_LOW_LATENCY)) {
- done_inst = (done_inst >> 16);
- done_inst = done_inst
- & ~(1 << intr_inst_index);
- done_inst = (done_inst << 16);
- WriteVpuRegister(
- VP5_RET_QUEUE_CMD_DONE_INST,
- done_inst);
- if (done_inst == 0)
- reason &=
- ~(1 << INT_ENC_LOW_LATENCY);
-
- enc_pr(LOG_INFO,
- "%s, LOW_LATENCY Clear ",
- __func__);
- enc_pr(LOG_INFO,
- "inst=0x%x, index=%d\n",
- done_inst, intr_inst_index);
- }
- if (!kfifo_is_full(
- &s_interrupt_pending_q[intr_inst_index]
- )) {
- if (intr_reason ==
- ((1 << INT_ENC_PIC) |
- (1 <<
- INT_ENC_LOW_LATENCY))) {
- u32 ll_intr_reason =
- (1 <<
- INT_ENC_PIC);
- kfifo_in_spinlocked(
- &s_interrupt_pending_q[
- intr_inst_index],
- &ll_intr_reason,
- sizeof(u32),
- &s_kfifo_lock);
- } else
- kfifo_in_spinlocked(
- &s_interrupt_pending_q[
- intr_inst_index],
- &intr_reason,
- sizeof(u32),
- &s_kfifo_lock);
- }
- else {
- enc_pr(LOG_ERROR, "kfifo_is_full ");
- enc_pr(LOG_ERROR,
- "kfifo_count %d index %d\n",
- kfifo_len(
- &s_interrupt_pending_q[
- intr_inst_index]),
- intr_inst_index);
- }
- dev->interrupt_flag[intr_inst_index] =
- intr_reason;
- }
- else {
- enc_pr(LOG_ERROR,
- "intr_inst_index (%d) is wrong \n",
- intr_inst_index);
- }
- enc_pr(LOG_INFO,
- "intr_reason: 0x%08x\n", intr_reason);
- }
- if (reason != 0) {
- enc_pr(LOG_ERROR, "INTERRUPT REASON REMAINED: %08x\n",
- reason);
- }
- WriteVpuRegister(VP5_VPU_INT_REASON_CLEAR, reason_clr);
- WriteVpuRegister(VP5_VPU_VINT_CLEAR, 0x1);
- }
-
- tasklet_schedule(&multienc_tasklet);
- enc_pr(LOG_ALL, "[-]%s\n", __func__);
- return IRQ_HANDLED;
-}
-
-#define RESETCTRL_RESET1_LEVEL (0xfe000044)
-
-static void hw_reset(bool reset)
-{
- void __iomem *reset_addr;
- uint32_t val;
-
- reset_addr = ioremap_nocache(RESETCTRL_RESET1_LEVEL, 8);
- if (reset_addr == NULL) {
- enc_pr(LOG_ERROR, "%s: Failed to ioremap\n", __func__);
- return;
- }
-
- val = __raw_readl(reset_addr);
- if (reset)
- val &= ~(1 << 28);
- else
- val |= (1 << 28);
- __raw_writel(val, reset_addr);
-
- mdelay(5);
-
- iounmap(reset_addr);
- if (reset)
- enc_pr(LOG_INFO, "%s:reset\n", __func__);
- else
- enc_pr(LOG_INFO, "%s:release reset\n", __func__);
-
-}
-
-static s32 vpu_open(struct inode *inode, struct file *filp)
-{
- bool first_open = false;
- s32 r = 0;
-
- //enc_pr(LOG_DEBUG, "[+] %s, filp=%lu, %lu, f_count=%lld\n", __func__,
- //(unsigned long)filp, ( ((unsigned long)filp)%8), filp->f_count.counter);
- spin_lock(&s_vpu_lock);
- s_vpu_drv_context.open_count++;
- if (s_vpu_drv_context.open_count == 1) {
- first_open = true;
- } /*else {
- r = -EBUSY;
- s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
- return r;
- }*/
- filp->private_data = (void *)(&s_vpu_drv_context);
- spin_unlock(&s_vpu_lock);
- if (first_open && !use_reserve) {
-#ifdef CONFIG_CMA
- s_video_memory.size = cma_cfg_size;
- s_video_memory.phys_addr = (ulong)codec_mm_alloc_for_dma(VPU_DEV_NAME, cma_cfg_size >> PAGE_SHIFT, 0, 0);
-
- if (s_video_memory.phys_addr) {
- enc_pr(LOG_DEBUG, "allocating phys 0x%lx, ", s_video_memory.phys_addr);
- enc_pr(LOG_DEBUG, "virt addr 0x%lx, size %dk\n", s_video_memory.base, s_video_memory.size >> 10);
-
- if (vmem_init(&s_vmem, s_video_memory.phys_addr, s_video_memory.size) < 0) {
- enc_pr(LOG_ERROR, "fail to init vmem system\n");
- r = -ENOMEM;
-
- codec_mm_free_for_dma(VPU_DEV_NAME, (u32)s_video_memory.phys_addr);
- vmem_exit(&s_vmem);
- memset(&s_video_memory, 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vmem, 0, sizeof(struct video_mm_t));
- }
- } else {
- enc_pr(LOG_ERROR, "Failed to alloc dma buffer %s, phys:0x%lx\n", VPU_DEV_NAME, s_video_memory.phys_addr);
-
- if (s_video_memory.phys_addr)
- codec_mm_free_for_dma(VPU_DEV_NAME, (u32)s_video_memory.phys_addr);
-
- s_video_memory.phys_addr = 0;
- r = -ENOMEM;
- }
-#else
- enc_pr(LOG_ERROR, "No CMA and reserved memory for MultiEnc!!!\n");
- r = -ENOMEM;
-#endif
- } else if (!s_video_memory.phys_addr) {
- enc_pr(LOG_ERROR, "MultiEnc memory is not malloced yet wait & retry!\n");
- r = -EBUSY;
- }
-
- if (first_open) {
- if ((s_vpu_irq >= 0) && (s_vpu_irq_requested == false)) {
- s32 err;
-
- err = request_irq(s_vpu_irq, vpu_irq_handler, 0, "MultiEnc-irq", (void *)(&s_vpu_drv_context));
-
- if (err) {
- enc_pr(LOG_ERROR, "Failed to register irq handler\n");
- spin_lock(&s_vpu_lock);
- s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
- return -EFAULT;
- }
-
- s_vpu_irq_requested = true;
- }
-
- /* enable vpu clks and power*/
- vpu_clk_enable(&s_vpu_clks);
- }
-
- if (r != 0) {
- spin_lock(&s_vpu_lock);
- s_vpu_drv_context.open_count--;
- spin_unlock(&s_vpu_lock);
- }
-
- enc_pr(LOG_DEBUG, "[-] %s, ret: %d\n", __func__, r);
- return r;
-}
-ulong phys_addrY;
-ulong phys_addrU;
-ulong phys_addrV;
-
-static long vpu_ioctl(struct file *filp, u32 cmd, ulong arg)
-{
- s32 ret = 0;
- struct vpu_drv_context_t *dev =
- (struct vpu_drv_context_t *)filp->private_data;
-
- switch (cmd) {
- case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
- {
- struct vpudrv_buffer_pool_t *vbp;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
- ret = down_interruptible(&s_vpu_sem);
- if (ret == 0) {
- vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
- if (!vbp) {
- up(&s_vpu_sem);
- return -ENOMEM;
- }
-
- ret = copy_from_user(&(vbp->vb),
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret) {
- kfree(vbp);
- up(&s_vpu_sem);
- return -EFAULT;
- }
-
- ret = vpu_alloc_dma_buffer(&(vbp->vb));
- if (ret == -1) {
- ret = -ENOMEM;
- kfree(vbp);
- up(&s_vpu_sem);
- break;
- }
- ret = copy_to_user((void __user *)arg,
- &(vbp->vb),
- sizeof(struct vpudrv_buffer_t));
- if (ret) {
- kfree(vbp);
- ret = -EFAULT;
- up(&s_vpu_sem);
- break;
- }
-
- vbp->filp = filp;
- spin_lock(&s_vpu_lock);
- list_add(&vbp->list, &s_vbp_head);
- spin_unlock(&s_vpu_lock);
-
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32:
- {
- struct vpudrv_buffer_pool_t *vbp;
- struct compat_vpudrv_buffer_t buf32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32\n");
- ret = down_interruptible(&s_vpu_sem);
- if (ret == 0) {
- vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
- if (!vbp) {
- up(&s_vpu_sem);
- return -ENOMEM;
- }
-
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret) {
- kfree(vbp);
- up(&s_vpu_sem);
- return -EFAULT;
- }
-
- vbp->vb.size = buf32.size;
- vbp->vb.cached = buf32.cached;
- vbp->vb.phys_addr =
- (ulong)buf32.phys_addr;
- vbp->vb.virt_addr =
- (ulong)buf32.virt_addr;
- ret = vpu_alloc_dma_buffer(&(vbp->vb));
- if (ret == -1) {
- ret = -ENOMEM;
- kfree(vbp);
- up(&s_vpu_sem);
- break;
- }
-
- buf32.size = vbp->vb.size;
- buf32.phys_addr =
- (compat_ulong_t)vbp->vb.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)vbp->vb.virt_addr;
-
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret) {
- kfree(vbp);
- ret = -EFAULT;
- up(&s_vpu_sem);
- break;
- }
-
- vbp->filp = filp;
- spin_lock(&s_vpu_lock);
- list_add(&vbp->list, &s_vbp_head);
- spin_unlock(&s_vpu_lock);
-
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32\n");
- }
- break;
-#endif
- case VDI_IOCTL_FREE_PHYSICALMEMORY:
- {
- struct vpudrv_buffer_pool_t *vbp, *n;
- struct vpudrv_buffer_t vb;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
- ret = down_interruptible(&s_vpu_sem);
- if (ret == 0) {
- ret = copy_from_user(&vb,
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret) {
- up(&s_vpu_sem);
- return -EACCES;
- }
-
- if (vb.phys_addr)
- vpu_free_dma_buffer(&vb);
-
- list_for_each_entry_safe(vbp, n,
- &s_vbp_head, list) {
- if (vbp->vb.phys_addr
- == vb.phys_addr) {
- spin_lock(&s_vpu_lock);
- list_del(&vbp->list);
- spin_unlock(&s_vpu_lock);
- kfree(vbp);
- break;
- }
- }
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_FREE_PHYSICALMEMORY32:
- {
- struct vpudrv_buffer_pool_t *vbp, *n;
- struct compat_vpudrv_buffer_t buf32;
- struct vpudrv_buffer_t vb;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_FREE_PHYSICALMEMORY32\n");
- ret = down_interruptible(&s_vpu_sem);
- if (ret == 0) {
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret) {
- up(&s_vpu_sem);
- return -EACCES;
- }
-
- vb.size = buf32.size;
- vb.phys_addr =
- (ulong)buf32.phys_addr;
- vb.virt_addr =
- (ulong)buf32.virt_addr;
-
- if (vb.phys_addr)
- vpu_free_dma_buffer(&vb);
- /*TODO check equal condition*/
- list_for_each_entry_safe(vbp, n,
- &s_vbp_head, list) {
- if ((compat_ulong_t)vbp->vb.phys_addr
- == buf32.phys_addr) {
- spin_lock(&s_vpu_lock);
- list_del(&vbp->list);
- spin_unlock(&s_vpu_lock);
- kfree(vbp);
- break;
- }
- }
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_FREE_PHYSICALMEMORY32\n");
- }
- break;
-#endif
- case VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO:
- {
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY\n");
- if (s_video_memory.phys_addr != 0) {
- ret = copy_to_user((void __user *)arg,
- &s_video_memory,
- sizeof(struct vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else {
- ret = -EFAULT;
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32:
- {
- struct compat_vpudrv_buffer_t buf32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY32\n");
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
- buf32.size = s_video_memory.size;
- buf32.phys_addr =
- (compat_ulong_t)s_video_memory.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)s_video_memory.virt_addr;
- if (s_video_memory.phys_addr != 0) {
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else {
- ret = -EFAULT;
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY32\n");
- }
- break;
-#endif
- case VDI_IOCTL_WAIT_INTERRUPT:
- {
- struct vpudrv_intr_info_t info;
- u32 intr_inst_index;
- u32 intr_reason_in_q;
- u32 interrupt_flag_in_q;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_WAIT_INTERRUPT\n");
- ret = copy_from_user(&info,
- (struct vpudrv_intr_info_t *)arg,
- sizeof(struct vpudrv_intr_info_t));
- if (ret != 0)
- return -EFAULT;
- intr_inst_index = info.intr_inst_index;
-
- intr_reason_in_q = 0;
- if (intr_inst_index >= MAX_NUM_INSTANCE)
- {
- enc_pr(LOG_ALL,
- "error, intr_inst_index is invalid !\n");
- return -EFAULT;
- }
- interrupt_flag_in_q = kfifo_out_spinlocked(
- &s_interrupt_pending_q[intr_inst_index],
- &intr_reason_in_q, sizeof(u32),
- &s_kfifo_lock);
- if (interrupt_flag_in_q > 0)
- {
- dev->interrupt_reason[intr_inst_index] =
- intr_reason_in_q;
- enc_pr(LOG_ALL,
- "Intr Remain in Q: inst_index= %d, ",
- intr_inst_index);
- enc_pr(LOG_ALL, "reason= 0x%x, flag= %d\n",
- intr_reason_in_q,
- interrupt_flag_in_q);
- goto INTERRUPT_REMAIN_IN_QUEUE;
- }
-
- ret = wait_event_interruptible_timeout(
- s_interrupt_wait_q[intr_inst_index],
- s_interrupt_flag[intr_inst_index] != 0,
- msecs_to_jiffies(info.timeout));
- if (!ret) {
- ret = -ETIME;
- break;
- }
-
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
-
- intr_reason_in_q = 0;
- interrupt_flag_in_q = kfifo_out_spinlocked(
- &s_interrupt_pending_q[intr_inst_index],
- &intr_reason_in_q, sizeof(u32), &s_kfifo_lock);
- if (interrupt_flag_in_q > 0) {
- dev->interrupt_reason[intr_inst_index] =
- intr_reason_in_q;
- }
- else {
- dev->interrupt_reason[intr_inst_index] = 0;
- }
- enc_pr(LOG_INFO,
- "inst_index(%d),s_interrupt_flag(%d), ",
- intr_inst_index,
- s_interrupt_flag[intr_inst_index]);
- enc_pr(LOG_INFO,
- "reason(0x%08lx)\n",
- dev->interrupt_reason[intr_inst_index]);
-
-INTERRUPT_REMAIN_IN_QUEUE:
- info.intr_reason =
- dev->interrupt_reason[intr_inst_index];
- s_interrupt_flag[intr_inst_index] = 0;
- dev->interrupt_reason[intr_inst_index] = 0;
-
-#ifdef VPU_IRQ_CONTROL
- enable_irq(s_vpu_irq);
-#endif
- ret = copy_to_user((void __user *)arg,
- &info, sizeof(struct vpudrv_intr_info_t));
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_WAIT_INTERRUPT\n");
- if (ret != 0)
- return -EFAULT;
- }
- break;
- case VDI_IOCTL_SET_CLOCK_GATE:
- {
- u32 clkgate;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_SET_CLOCK_GATE\n");
- if (get_user(clkgate, (u32 __user *) arg))
- return -EFAULT;
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- return -EFAULT;
- vpu_clk_config(clkgate);
- up(&s_vpu_sem);
-#endif
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_SET_CLOCK_GATE\n");
- }
- break;
- case VDI_IOCTL_GET_INSTANCE_POOL:
- {
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_INSTANCE_POOL\n");
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
-
- if (s_instance_pool.base != 0) {
- ret = copy_to_user((void __user *)arg,
- &s_instance_pool,
- sizeof(struct vpudrv_buffer_t));
- ret = (ret != 0) ? -EFAULT : 0;
- } else {
- ret = copy_from_user(&s_instance_pool,
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret == 0) {
- s_instance_pool.size =
- PAGE_ALIGN(
- s_instance_pool.size);
- s_instance_pool.base =
- (ulong)vmalloc(
- s_instance_pool.size);
- s_instance_pool.phys_addr =
- s_instance_pool.base;
- if (s_instance_pool.base == 0) {
- ret = -EFAULT;
- up(&s_vpu_sem);
- break;
- }
- /*clearing memory*/
- memset((void *)s_instance_pool.base,
- 0, s_instance_pool.size);
- ret = copy_to_user((void __user *)arg,
- &s_instance_pool,
- sizeof(struct
- vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else
- ret = -EFAULT;
- }
- up(&s_vpu_sem);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_INSTANCE_POOL\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_GET_INSTANCE_POOL32:
- {
- struct compat_vpudrv_buffer_t buf32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_INSTANCE_POOL32\n");
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (s_instance_pool.base != 0) {
- buf32.size = s_instance_pool.size;
- buf32.phys_addr =
- (compat_ulong_t)
- s_instance_pool.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)
- s_instance_pool.virt_addr;
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(struct
- compat_vpudrv_buffer_t));
- ret = (ret != 0) ? -EFAULT : 0;
- } else {
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct
- compat_vpudrv_buffer_t));
- if (ret == 0) {
- s_instance_pool.size = buf32.size;
- s_instance_pool.size =
- PAGE_ALIGN(
- s_instance_pool.size);
- s_instance_pool.base =
- (ulong)vmalloc(
- s_instance_pool.size);
- s_instance_pool.phys_addr =
- s_instance_pool.base;
- buf32.size =
- s_instance_pool.size;
- buf32.phys_addr =
- (compat_ulong_t)
- s_instance_pool.phys_addr;
- buf32.base =
- (compat_ulong_t)
- s_instance_pool.base;
- buf32.virt_addr =
- (compat_ulong_t)
- s_instance_pool.virt_addr;
- if (s_instance_pool.base == 0) {
- ret = -EFAULT;
- up(&s_vpu_sem);
- break;
- }
- /*clearing memory*/
- memset((void *)s_instance_pool.base,
- 0x0, s_instance_pool.size);
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(struct
- compat_vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else
- ret = -EFAULT;
- }
- up(&s_vpu_sem);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_INSTANCE_POOL32\n");
- }
- break;
-#endif
- case VDI_IOCTL_GET_COMMON_MEMORY:
- {
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_COMMON_MEMORY\n");
- if (s_common_memory.phys_addr != 0) {
- ret = copy_to_user((void __user *)arg,
- &s_common_memory,
- sizeof(struct vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else {
- ret = copy_from_user(&s_common_memory,
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret != 0) {
- ret = -EFAULT;
- break;
- }
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_alloc_dma_buffer(
- &s_common_memory) != -1) {
- ret = copy_to_user((void __user *)arg,
- &s_common_memory,
- sizeof(struct
- vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else
- ret = -EFAULT;
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_COMMON_MEMORY\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_GET_COMMON_MEMORY32:
- {
- struct compat_vpudrv_buffer_t buf32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_COMMON_MEMORY32\n");
-
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
- buf32.size = s_common_memory.size;
- buf32.phys_addr =
- (compat_ulong_t)
- s_common_memory.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)
- s_common_memory.virt_addr;
- if (s_common_memory.phys_addr != 0) {
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else {
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret != 0) {
- ret = -EFAULT;
- break;
- }
- s_common_memory.size = buf32.size;
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_alloc_dma_buffer(
- &s_common_memory) != -1) {
- buf32.size =
- s_common_memory.size;
- buf32.phys_addr =
- (compat_ulong_t)
- s_common_memory.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)
- s_common_memory.virt_addr;
- ret = copy_to_user((void __user *)arg,
- &buf32, sizeof(struct
- compat_vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- } else
- ret = -EFAULT;
- up(&s_vpu_sem);
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_COMMON_MEMORY32\n");
- }
- break;
-#endif
- case VDI_IOCTL_OPEN_INSTANCE:
- {
- struct vpudrv_inst_info_t inst_info;
- struct vpudrv_instanace_list_t *vil, *n;
-
- enc_pr(LOG_DEBUG,
- "[+]VDI_IOCTL_OPEN_INSTANCE\n");
-
- vil = kzalloc(sizeof(*vil), GFP_KERNEL);
- if (!vil)
- return -ENOMEM;
-
- if (copy_from_user(&inst_info,
- (struct vpudrv_inst_info_t *)arg,
- sizeof(struct vpudrv_inst_info_t)))
- {
- kfree(vil);
- return -EFAULT;
- }
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- {
- kfree(vil);
- break;
- }
- vil->inst_idx = inst_info.inst_idx;
- vil->core_idx = inst_info.core_idx;
- vil->filp = filp;
- /* counting the current open instance number */
- inst_info.inst_open_count = 0;
- spin_lock(&s_vpu_lock);
- list_add(&vil->list, &s_inst_list_head);
- list_for_each_entry_safe(vil, n,
- &s_inst_list_head, list) {
- if (vil->core_idx == inst_info.core_idx)
- inst_info.inst_open_count++;
- }
- if (inst_info.inst_idx >= MAX_NUM_INSTANCE)
- {
- enc_pr(LOG_ALL,
- "error, inst_info.inst_idx is invalid !\n");
- kfree(vil);
- spin_unlock(&s_vpu_lock);
- return -EFAULT;
- }
- kfifo_reset(
- &s_interrupt_pending_q[inst_info.inst_idx]);
-
- /* flag just for that vpu is in opened or closed */
- s_vpu_open_ref_count++;
- spin_unlock(&s_vpu_lock);
- up(&s_vpu_sem);
- if (copy_to_user((void __user *)arg,
- &inst_info,
- sizeof(struct vpudrv_inst_info_t))) {
- kfree(vil);
- return -EFAULT;
- }
-
- enc_pr(LOG_DEBUG,
- "[-]VDI_IOCTL_OPEN_INSTANCE ");
- enc_pr(LOG_DEBUG,
- "core_idx = %d, inst_idx = %d, ",
- (u32)inst_info.core_idx,
- (u32)inst_info.inst_idx);
- enc_pr(LOG_DEBUG,
- "s_vpu_open_ref_count = %d, ",
- s_vpu_open_ref_count);
- enc_pr(LOG_DEBUG,
- "inst_open_count = %d\n",
- inst_info.inst_open_count);
- }
- break;
- case VDI_IOCTL_CLOSE_INSTANCE:
- {
- struct vpudrv_inst_info_t inst_info;
- struct vpudrv_instanace_list_t *vil, *n;
- u32 found = 0;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_CLOSE_INSTANCE\n");
- if (copy_from_user(&inst_info,
- (struct vpudrv_inst_info_t *)arg,
- sizeof(struct vpudrv_inst_info_t)))
- return -EFAULT;
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
-
- list_for_each_entry_safe(vil, n,
- &s_inst_list_head, list) {
- if (vil->inst_idx == inst_info.inst_idx &&
- vil->core_idx == inst_info.core_idx) {
- spin_lock(&s_vpu_lock);
- list_del(&vil->list);
- spin_unlock(&s_vpu_lock);
- kfree(vil);
- found = 1;
- break;
- }
- }
-
- if (found == 0) {
- up(&s_vpu_sem);
- return -EINVAL;
- }
-
- /* counting the current open instance number */
- inst_info.inst_open_count = 0;
- list_for_each_entry_safe(vil, n,
- &s_inst_list_head, list) {
- if (vil->core_idx == inst_info.core_idx)
- inst_info.inst_open_count++;
- }
-
- kfifo_reset(
- &s_interrupt_pending_q[inst_info.inst_idx]);
- /* flag just for that vpu is in opened or closed */
- spin_lock(&s_vpu_lock);
- s_vpu_open_ref_count--;
- spin_unlock(&s_vpu_lock);
- up(&s_vpu_sem);
- if (copy_to_user((void __user *)arg,
- &inst_info,
- sizeof(struct vpudrv_inst_info_t)))
- return -EFAULT;
-
- enc_pr(LOG_DEBUG,
- "[-]VDI_IOCTL_CLOSE_INSTANCE ");
- enc_pr(LOG_DEBUG,
- "core_idx= %d, inst_idx= %d, ",
- (u32)inst_info.core_idx,
- (u32)inst_info.inst_idx);
- enc_pr(LOG_DEBUG,
- "s_vpu_open_ref_count= %d, ",
- s_vpu_open_ref_count);
- enc_pr(LOG_DEBUG,
- "inst_open_count= %d\n",
- inst_info.inst_open_count);
- }
- break;
- case VDI_IOCTL_GET_INSTANCE_NUM:
- {
- struct vpudrv_inst_info_t inst_info;
- struct vpudrv_instanace_list_t *vil, *n;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_INSTANCE_NUM\n");
-
- ret = copy_from_user(&inst_info,
- (struct vpudrv_inst_info_t *)arg,
- sizeof(struct vpudrv_inst_info_t));
- if (ret != 0)
- break;
-
- inst_info.inst_open_count = 0;
-
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(vil, n,
- &s_inst_list_head, list) {
- if (vil->core_idx == inst_info.core_idx)
- inst_info.inst_open_count++;
- }
- spin_unlock(&s_vpu_lock);
-
- ret = copy_to_user((void __user *)arg,
- &inst_info,
- sizeof(struct vpudrv_inst_info_t));
-
- enc_pr(LOG_DEBUG,
- "[-]VDI_IOCTL_GET_INSTANCE_NUM ");
- enc_pr(LOG_DEBUG,
- "core_idx=%d, inst_idx=%d, open_count=%d\n",
- (u32)inst_info.core_idx,
- (u32)inst_info.inst_idx,
- inst_info.inst_open_count);
- }
- break;
- case VDI_IOCTL_RESET:
- {
- vpu_hw_reset();
- }
- break;
- case VDI_IOCTL_GET_REGISTER_INFO:
- {
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_REGISTER_INFO\n");
- ret = copy_to_user((void __user *)arg,
- &s_vpu_register,
- sizeof(struct vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_REGISTER_INFO ");
- enc_pr(LOG_ALL,
- "s_vpu_register.phys_addr=0x%lx, ",
- s_vpu_register.phys_addr);
- enc_pr(LOG_ALL,
- "s_vpu_register.virt_addr=0x%lx, ",
- s_vpu_register.virt_addr);
- enc_pr(LOG_ALL,
- "s_vpu_register.size=0x%x\n",
- s_vpu_register.size);
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_GET_REGISTER_INFO32:
- {
- struct compat_vpudrv_buffer_t buf32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_GET_REGISTER_INFO32\n");
-
- memset(&buf32, 0, sizeof(struct compat_vpudrv_buffer_t));
- buf32.size = s_vpu_register.size;
- buf32.phys_addr =
- (compat_ulong_t)
- s_vpu_register.phys_addr;
- buf32.virt_addr =
- (compat_ulong_t)
- s_vpu_register.virt_addr;
- ret = copy_to_user((void __user *)arg,
- &buf32,
- sizeof(
- struct compat_vpudrv_buffer_t));
- if (ret != 0)
- ret = -EFAULT;
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_GET_REGISTER_INFO32 ");
- enc_pr(LOG_ALL,
- "s_vpu_register.phys_addr=0x%lx, ",
- s_vpu_register.phys_addr);
- enc_pr(LOG_ALL,
- "s_vpu_register.virt_addr=0x%lx, ",
- s_vpu_register.virt_addr);
- enc_pr(LOG_ALL,
- "s_vpu_register.size=0x%x\n",
- s_vpu_register.size);
- }
- break;
- case VDI_IOCTL_FLUSH_BUFFER32:
- {
- struct vpudrv_buffer_pool_t *pool, *n;
- struct compat_vpudrv_buffer_t buf32;
- struct vpudrv_buffer_t vb;
- bool find = false;
- u32 cached = 0;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_FLUSH_BUFFER32\n");
-
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret)
- return -EFAULT;
-
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(pool, n,
- &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if (((compat_ulong_t)vb.phys_addr <=
- buf32.phys_addr) &&
- (((compat_ulong_t)vb.phys_addr
- + vb.size)
- > buf32.phys_addr)
- && find == false){
- cached = vb.cached;
- find = true;
- break;
- }
- }
- }
- spin_unlock(&s_vpu_lock);
-
- if (find && cached)
- dma_flush(
- (u32)buf32.phys_addr,
- (u32)buf32.size);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_FLUSH_BUFFER32\n");
- }
- break;
-#endif
- case VDI_IOCTL_FLUSH_BUFFER:
- {
- struct vpudrv_buffer_pool_t *pool, *n;
- struct vpudrv_buffer_t vb, buf;
- bool find = false;
- u32 cached = 0;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_FLUSH_BUFFER\n");
-
- ret = copy_from_user(&buf,
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret)
- return -EFAULT;
-
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(pool, n,
- &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if ((vb.phys_addr <= buf.phys_addr)
- && ((vb.phys_addr + vb.size)
- > buf.phys_addr)
- && find == false){
- cached = vb.cached;
- find = true;
- break;
- }
- }
- }
- spin_unlock(&s_vpu_lock);
- if (find && cached)
- dma_flush(
- (u32)buf.phys_addr,
- (u32)buf.size);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_FLUSH_BUFFER\n");
- }
- break;
- case VDI_IOCTL_CACHE_INV_BUFFER:
- {
- struct vpudrv_buffer_t buf;
- struct vpudrv_buffer_pool_t *pool, *n;
- struct vpudrv_buffer_t vb;
- bool find = false;
- u32 cached = 0;
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_CACHE_INV_BUFFER\n");
-
- ret = copy_from_user(&buf,
- (struct vpudrv_buffer_t *)arg,
- sizeof(struct vpudrv_buffer_t));
- if (ret)
- return -EFAULT;
-
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(pool, n, &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if ((vb.phys_addr <= buf.phys_addr) && ((vb.phys_addr + vb.size) > buf.phys_addr) && find == false) {
- cached = vb.cached;
- find = true;
- break;
- }
- }
- }
- spin_unlock(&s_vpu_lock);
- if (find && cached) {
- //pr_err("[%d]doing cache flush for %p~%p\n", __LINE__, (long)(buf.phys_addr), (long)(buf.phys_addr+buf.size));
- cache_flush((u32)buf.phys_addr,(u32)buf.size);
- }
-
- enc_pr(LOG_ALL,"[-]VDI_IOCTL_CACHE_INV_BUFFER\n");
- }
- break;
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_CACHE_INV_BUFFER32:
- {
- struct compat_vpudrv_buffer_t buf32;
- struct vpudrv_buffer_pool_t *pool, *n;
- struct vpudrv_buffer_t vb;
- bool find = false;
- u32 cached = 0;
- enc_pr(LOG_ALL, "[+]VDI_IOCTL_CACHE_INV_BUFFER32\n");
-
- ret = copy_from_user(&buf32,
- (struct compat_vpudrv_buffer_t *)arg,
- sizeof(struct compat_vpudrv_buffer_t));
- if (ret)
- return -EFAULT;
-
- spin_lock(&s_vpu_lock);
- list_for_each_entry_safe(pool, n,
- &s_vbp_head, list) {
- if (pool->filp == filp) {
- vb = pool->vb;
- if (((compat_ulong_t)vb.phys_addr
- <= buf32.phys_addr)
- && (((compat_ulong_t)vb.phys_addr +
- vb.size) > buf32.phys_addr)
- && find == false){
- cached = vb.cached;
- find = true;
- break;
- }
- }
- }
- spin_unlock(&s_vpu_lock);
-
- if (find && cached) {
- cache_flush((u32)buf32.phys_addr, (u32)buf32.size);
-
- if (dump_es) {
- pr_err("dump es frame, size=%u\n", (u32)buf32.size);
- dump_data((u32)buf32.phys_addr, (u32)buf32.size);
- }
- }
- enc_pr(LOG_INFO, "[-]VVDI_IOCTL_CACHE_INV_BUFFER32\n");
- }
- break;
-#endif
- case VDI_IOCTL_CONFIG_DMA:
- {
- struct vpudrv_dma_buf_info_t dma_info;
- enc_pr(LOG_DEBUG,
- "[+]VDI_IOCTL_CONFIG_DMA_BUF\n");
-
- if (copy_from_user(&dma_info,
- (struct vpudrv_dma_buf_info_t *)arg,
- sizeof(struct vpudrv_dma_buf_info_t)))
- return -EFAULT;
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_src_addr_config(&dma_info, filp)) {
- up(&s_vpu_sem);
- enc_pr(LOG_ERROR,
- "src addr config error\n");
- ret = -EFAULT;
- break;
- }
- up(&s_vpu_sem);
- ret = copy_to_user((void __user *)arg,
- &dma_info,
- sizeof(struct vpudrv_dma_buf_info_t));
- if (ret) {
- ret = -EFAULT;
- break;
- }
- enc_pr(LOG_DEBUG,
- "[-]VDI_IOCTL_CONFIG_DMA_BUF %d, %d, %d\n",
- dma_info.fd[0],
- dma_info.fd[1],
- dma_info.fd[2]);
- }
- break;
-
- //hoan add for canvas
- case VDI_IOCTL_READ_CANVAS:
- {
- struct vpudrv_dma_buf_canvas_info_t dma_info;
-
- struct canvas_s dst ;
- u32 canvas = 0;
-
- if (copy_from_user(&dma_info,
- (struct vpudrv_dma_buf_canvas_info_t *)arg,
- sizeof(struct vpudrv_dma_buf_canvas_info_t)))
- {
- return -EFAULT;
- }
-
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- {
- up(&s_vpu_sem);
- break;
- }
-
- canvas = dma_info.canvas_index;
- enc_pr(LOG_DEBUG,"[+]VDI_IOCTL_READ_CANVAS,canvas = 0x%x\n",canvas);
- if (canvas & 0xff)
- {
- canvas_read(canvas & 0xff, &dst);
- dma_info.phys_addr[0] = dst.addr;
-
- if ((canvas & 0xff00) >> 8)
- {
- canvas_read((canvas & 0xff00) >> 8, &dst);
- dma_info.phys_addr[1] = dst.addr;
-
- }
-
- if ((canvas & 0xff0000) >> 16)
- {
- canvas_read((canvas & 0xff0000) >> 16, &dst);
- dma_info.phys_addr[2] = dst.addr;
- }
-
- enc_pr(LOG_DEBUG,"[+]VDI_IOCTL_READ_CANVAS,phys_addr[0] = 0x%lx,phys_addr[1] = 0x%lx,phys_addr[2] = 0x%lx\n",dma_info.phys_addr[0],dma_info.phys_addr[1],dma_info.phys_addr[2]);
-
- }
- else
- {
- dma_info.phys_addr[0] = 0;
- dma_info.phys_addr[1] = 0;
- dma_info.phys_addr[2] = 0;
- }
- up(&s_vpu_sem);
- #if 0
- dma_info.phys_addr[0] = phys_addrY;
- dma_info.phys_addr[1] = phys_addrU;
- dma_info.phys_addr[2] = phys_addrV;
- #endif
-
- ret = copy_to_user((void __user *)arg,
- &dma_info,
- sizeof(struct vpudrv_dma_buf_canvas_info_t));
-
- enc_pr(LOG_DEBUG,"[-]VDI_IOCTL_READ_CANVAS,copy_to_user End\n");
- if (ret)
- {
- ret = -EFAULT;
- break;
- }
-
- }
- break;
- //end
-
-#ifdef CONFIG_COMPAT
- case VDI_IOCTL_CONFIG_DMA32:
- {
- struct vpudrv_dma_buf_info_t dma_info;
- struct compat_vpudrv_dma_buf_info_t dma_info32;
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_CONFIG_DMA_BUF32\n");
-
- if (copy_from_user(&dma_info32,
- (struct compat_vpudrv_dma_buf_info_t *)arg,
- sizeof(struct compat_vpudrv_dma_buf_info_t)))
- return -EFAULT;
- dma_info.num_planes = dma_info32.num_planes;
- dma_info.fd[0] = (int) dma_info32.fd[0];
- dma_info.fd[1] = (int) dma_info32.fd[1];
- dma_info.fd[2] = (int) dma_info32.fd[2];
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_src_addr_config(&dma_info, filp)) {
- up(&s_vpu_sem);
- enc_pr(LOG_ERROR,
- "src addr config error\n");
- ret = -EFAULT;
- break;
- }
- up(&s_vpu_sem);
- dma_info32.phys_addr[0] =
- (compat_ulong_t) dma_info.phys_addr[0];
- dma_info32.phys_addr[1] =
- (compat_ulong_t) dma_info.phys_addr[1];
- dma_info32.phys_addr[2] =
- (compat_ulong_t) dma_info.phys_addr[2];
- ret = copy_to_user((void __user *)arg,
- &dma_info32,
- sizeof(struct compat_vpudrv_dma_buf_info_t));
- if (ret) {
- ret = -EFAULT;
- break;
- }
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_CONFIG_DMA_BUF32 %d, %d, %d\n",
- dma_info.fd[0],
- dma_info.fd[1],
- dma_info.fd[2]);
- }
- break;
-
-#if 1
-
- //hoan add for canvas
- case VDI_IOCTL_READ_CANVAS32:
- {
- struct vpudrv_dma_buf_canvas_info_t dma_info;
- struct compat_vpudrv_dma_buf_canvas_info_t dma_info32;
- struct canvas_s dst;
- u32 canvas = 0;
-
- if (copy_from_user(&dma_info32,
- (struct compat_vpudrv_dma_buf_canvas_info_t *)arg,
- sizeof(struct compat_vpudrv_dma_buf_canvas_info_t)))
- {
- return -EFAULT;
- }
-
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- {
- up(&s_vpu_sem);
- break;
- }
-
- canvas = dma_info32.canvas_index;
- enc_pr(LOG_INFO,"[+]VDI_IOCTL_READ_CANVAS32,canvas = 0x%x\n",dma_info32.canvas_index);
- if (canvas & 0xff)
- {
- canvas_read(canvas & 0xff, &dst);
- dma_info.phys_addr[0] = dst.addr;
-
- if (dump_input) {
- dump_raw_input(&dst);
- }
-
- if ((canvas & 0xff00) >> 8)
- {
- canvas_read((canvas & 0xff00) >> 8, &dst);
- dma_info.phys_addr[1] = dst.addr;
- if (dump_input) {
- dump_raw_input(&dst);
- }
- }
-
- if ((canvas & 0xff0000) >> 16)
- {
- canvas_read((canvas & 0xff0000) >> 16, &dst);
- dma_info.phys_addr[2] = dst.addr;
- if (dump_input) {
- dump_raw_input(&dst);
- }
- }
-
- enc_pr(LOG_INFO,"VDI_IOCTL_READ_CANVAS32_1,phys_addr[0] = 0x%lx,phys_addr[1] = 0x%lx,phys_addr[2] = 0x%lx\n",
- dma_info.phys_addr[0],dma_info.phys_addr[1],dma_info.phys_addr[2]);
- }
- else
- {
- dma_info.phys_addr[0] = 0;
- dma_info.phys_addr[1] = 0;
- dma_info.phys_addr[2] = 0;
- }
-
- up(&s_vpu_sem);
-
- dma_info32.phys_addr[0] = (compat_ulong_t)dma_info.phys_addr[0];
- dma_info32.phys_addr[1] = (compat_ulong_t)dma_info.phys_addr[1];
- dma_info32.phys_addr[2] = (compat_ulong_t)dma_info.phys_addr[2];
-
- enc_pr(LOG_INFO,"VDI_IOCTL_READ_CANVAS32_2,phys_addr[0] = 0x%lx,phys_addr[1] = 0x%lx,phys_addr[2] = 0x%lx\n",dma_info.phys_addr[0], dma_info.phys_addr[1], dma_info.phys_addr[2]);
- enc_pr(LOG_INFO,"VDI_IOCTL_READ_CANVAS32_3,phys_addr[0] = 0x%x,phys_addr[1] = 0x%x,phys_addr[2] = 0x%x\n", dma_info32.phys_addr[0],dma_info32.phys_addr[1],dma_info32.phys_addr[2]);
-
- ret = copy_to_user((void __user *)arg,
- &dma_info32,
- sizeof(struct compat_vpudrv_dma_buf_canvas_info_t));
-
- enc_pr(LOG_INFO,"[-]VDI_IOCTL_READ_CANVAS,copy_to_user End\n");
- if (ret)
- {
- ret = -EFAULT;
- break;
- }
-
- }
- break;
- //end
-#endif
-
- case VDI_IOCTL_UNMAP_DMA32:
- {
- struct vpudrv_dma_buf_info_t dma_info;
- struct compat_vpudrv_dma_buf_info_t dma_info32;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_UNMAP_DMA32\n");
-
- if (copy_from_user(&dma_info32,
- (struct compat_vpudrv_dma_buf_info_t *)arg,
- sizeof(struct compat_vpudrv_dma_buf_info_t)))
- return -EFAULT;
- dma_info.num_planes = dma_info32.num_planes;
- dma_info.fd[0] = (int) dma_info32.fd[0];
- dma_info.fd[1] = (int) dma_info32.fd[1];
- dma_info.fd[2] = (int) dma_info32.fd[2];
- dma_info.phys_addr[0] =
- (ulong) dma_info32.phys_addr[0];
- dma_info.phys_addr[1] =
- (ulong) dma_info32.phys_addr[1];
- dma_info.phys_addr[2] =
- (ulong) dma_info32.phys_addr[2];
-
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_src_addr_unmap(&dma_info, filp)) {
- up(&s_vpu_sem);
- enc_pr(LOG_ERROR,
- "dma addr unmap config error\n");
- ret = -EFAULT;
- break;
- }
- up(&s_vpu_sem);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_UNMAP_DMA32\n");
- }
- break;
-#endif
- case VDI_IOCTL_UNMAP_DMA:
- {
- struct vpudrv_dma_buf_info_t dma_info;
-
- enc_pr(LOG_ALL,
- "[+]VDI_IOCTL_UNMAP_DMA\n");
-
- if (copy_from_user(&dma_info,
- (struct vpudrv_dma_buf_info_t *)arg,
- sizeof(struct vpudrv_dma_buf_info_t)))
- return -EFAULT;
- ret = down_interruptible(&s_vpu_sem);
- if (ret != 0)
- break;
- if (vpu_src_addr_unmap(&dma_info, filp)) {
- up(&s_vpu_sem);
- enc_pr(LOG_ERROR,
- "dma addr unmap config error\n");
- ret = -EFAULT;
- break;
- }
- up(&s_vpu_sem);
- enc_pr(LOG_ALL,
- "[-]VDI_IOCTL_UNMAP_DMA\n");
- }
- break;
- default:
- {
- enc_pr(LOG_ERROR,
- "No such IOCTL, cmd is 0x%x\n", cmd);
- ret = -EFAULT;
- }
- break;
- }
- return ret;
-}
-
-#ifdef CONFIG_COMPAT
-static long vpu_compat_ioctl(struct file *filp, u32 cmd, ulong arg)
-{
- long ret;
-
- arg = (ulong)compat_ptr(arg);
- ret = vpu_ioctl(filp, cmd, arg);
- return ret;
-}
-#endif
-
-static ssize_t vpu_write(struct file *filp,
- const char *buf,
- size_t len,
- loff_t *ppos)
-{
- enc_pr(LOG_INFO, "vpu_write len=%d\n", (int)len);
-
- if (!buf) {
- enc_pr(LOG_ERROR, "vpu_write buf = NULL error\n");
- return -EFAULT;
- }
-
- if (len == sizeof(struct vpu_bit_firmware_info_t)) {
- struct vpu_bit_firmware_info_t *bit_firmware_info;
-
- bit_firmware_info =
- kmalloc(sizeof(struct vpu_bit_firmware_info_t),
- GFP_KERNEL);
- if (!bit_firmware_info) {
- enc_pr(LOG_ERROR,
- "bit_firmware_info allocation error\n");
- return -EFAULT;
- }
-
- if (copy_from_user(bit_firmware_info, buf, len)) {
- enc_pr(LOG_ERROR,
- "copy_from_user error for firmware_info\n");
- kfree(bit_firmware_info);
- return -EFAULT;
- }
-
- if (bit_firmware_info->size ==
- sizeof(struct vpu_bit_firmware_info_t)) {
- enc_pr(LOG_INFO,
- "set bit_firmware_info coreIdx= 0x%x, ",
- bit_firmware_info->core_idx);
-
- enc_pr(LOG_INFO,
- "base_offset = 0x%x, size = 0x%x, ",
- bit_firmware_info->reg_base_offset,
- bit_firmware_info->size);
-
- enc_pr(LOG_INFO,"bit_code[0] = 0x%x\n",
- bit_firmware_info->bit_code[0]);
-
- if (bit_firmware_info->core_idx
- > MAX_NUM_VPU_CORE) {
- enc_pr(LOG_ERROR,
- "vpu_write coreIdx[%d] is ",
- bit_firmware_info->core_idx);
- enc_pr(LOG_ERROR,
- "exceeded than MAX_NUM_VPU_CORE[%d]\n",
- MAX_NUM_VPU_CORE);
- kfree(bit_firmware_info);
- return -ENODEV;
- }
- if (bit_firmware_info->core_idx >= MAX_NUM_VPU_CORE)
- {
- enc_pr(LOG_ERROR,
- "bit_firmware_info->core_idx invalid\n");
- kfree(bit_firmware_info);
- return -ENODEV;
-
- }
- memcpy((void *)&s_bit_firmware_info[bit_firmware_info->core_idx], bit_firmware_info, sizeof(struct vpu_bit_firmware_info_t));
- kfree(bit_firmware_info);
- return len;
- }
-
- kfree(bit_firmware_info);
- }
- return -1;
-}
-
-static s32 vpu_release(struct inode *inode, struct file *filp)
-{
- s32 ret = 0;
- u32 open_count;
- s32 i;
-
- //enc_pr(LOG_DEBUG, "vpu_release filp=%lu, f_counter=%lld\n",
- //(unsigned long)filp, filp->f_count.counter);
- ret = down_interruptible(&s_vpu_sem);
-
- if (ret == 0) {
- /* found and free the not handled
- buffer by user applications */
- vpu_free_buffers(filp);
- vpu_dma_buf_release(filp);
- /* found and free the not closed
- instance by user applications */
- vpu_free_instances(filp);
-
- spin_lock(&s_vpu_lock);
- s_vpu_drv_context.open_count--;
- open_count = s_vpu_drv_context.open_count;
- spin_unlock(&s_vpu_lock);
-
- pr_err("open_count=%u\n", open_count);
-
- if (open_count == 0) {
- for (i=0; i<MAX_NUM_INSTANCE; i++) {
- kfifo_reset(&s_interrupt_pending_q[i]);
- s_interrupt_flag[i] = 0;
- s_vpu_drv_context.interrupt_reason[i] = 0;
- s_vpu_drv_context.interrupt_flag[i] = 0;
- }
- if (s_instance_pool.base) {
- enc_pr(LOG_DEBUG, "free instance pool\n");
- vfree((const void *)s_instance_pool.base);
- s_instance_pool.base = 0;
- }
- if (s_common_memory.phys_addr) {
- enc_pr(LOG_INFO,
- "vpu_release, s_common_memory 0x%lx\n",
- s_common_memory.phys_addr);
- vpu_free_dma_buffer(&s_common_memory);
- s_common_memory.phys_addr = 0;
- }
-
- if (s_video_memory.phys_addr && !use_reserve) {
- enc_pr(LOG_DEBUG,
- "vpu_release, s_video_memory 0x%lx\n",
- s_video_memory.phys_addr);
- codec_mm_free_for_dma(
- VPU_DEV_NAME,
- (u32)s_video_memory.phys_addr);
- vmem_exit(&s_vmem);
- memset(&s_video_memory,
- 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vmem,
- 0, sizeof(struct video_mm_t));
- }
- if ((s_vpu_irq >= 0)
- && (s_vpu_irq_requested == true)) {
- free_irq(s_vpu_irq, &s_vpu_drv_context);
- s_vpu_irq_requested = false;
- }
-
- /* disable vpu clks.*/
- vpu_clk_disable(&s_vpu_clks);
- }
- }
- up(&s_vpu_sem);
- return 0;
-}
-
-static s32 vpu_fasync(s32 fd, struct file *filp, s32 mode)
-{
- struct vpu_drv_context_t *dev =
- (struct vpu_drv_context_t *)filp->private_data;
- return fasync_helper(fd, filp, mode, &dev->async_queue);
-}
-
-static s32 vpu_map_to_register(struct file *fp, struct vm_area_struct *vm)
-{
- ulong pfn;
-
- vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot =
- pgprot_noncached(vm->vm_page_prot);
- pfn = s_vpu_register.phys_addr >> PAGE_SHIFT;
- return remap_pfn_range(vm, vm->vm_start, pfn,
- vm->vm_end - vm->vm_start,
- vm->vm_page_prot) ? -EAGAIN : 0;
-}
-
-static s32 vpu_map_to_physical_memory(
- struct file *fp, struct vm_area_struct *vm)
-{
- vm->vm_flags |= VM_IO | VM_RESERVED;
- if (vm->vm_pgoff ==
- (s_common_memory.phys_addr >> PAGE_SHIFT)) {
- vm->vm_page_prot =
- pgprot_noncached(vm->vm_page_prot);
- } else {
- if (vpu_is_buffer_cached(fp, vm->vm_pgoff) == 0)
- vm->vm_page_prot =
- pgprot_noncached(vm->vm_page_prot);
- }
- /* vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot); */
- return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
- vm->vm_end - vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
-}
-
-static s32 vpu_map_to_instance_pool_memory(
- struct file *fp, struct vm_area_struct *vm)
-{
- s32 ret;
- long length = vm->vm_end - vm->vm_start;
- ulong start = vm->vm_start;
- s8 *vmalloc_area_ptr = (s8 *)s_instance_pool.base;
- ulong pfn;
-
- vm->vm_flags |= VM_RESERVED;
-
- /* loop over all pages, map it page individually */
- while (length > 0) {
- pfn = vmalloc_to_pfn(vmalloc_area_ptr);
- ret = remap_pfn_range(vm, start, pfn,
- PAGE_SIZE, PAGE_SHARED);
- if (ret < 0)
- return ret;
- start += PAGE_SIZE;
- vmalloc_area_ptr += PAGE_SIZE;
- length -= PAGE_SIZE;
- }
- return 0;
-}
-
-/*
- * @brief memory map interface for vpu file operation
- * @return 0 on success or negative error code on error
- */
-static s32 vpu_mmap(struct file *fp, struct vm_area_struct *vm)
-{
- /* if (vm->vm_pgoff == (s_vpu_register.phys_addr >> PAGE_SHIFT)) */
- if ((vm->vm_end - vm->vm_start) == (s_vpu_register.size + 1) &&
- (vm->vm_pgoff == 0)) {
- vm->vm_pgoff = (s_vpu_register.phys_addr >> PAGE_SHIFT);
- return vpu_map_to_register(fp, vm);
- }
-
- if (vm->vm_pgoff == 0)
- return vpu_map_to_instance_pool_memory(fp, vm);
-
- return vpu_map_to_physical_memory(fp, vm);
-}
-static int vpu_dma_buffer_map(struct vpu_dma_cfg *cfg)
-{
- int ret = -1;
- int fd = -1;
- struct page *page = NULL;
- struct dma_buf *dbuf = NULL;
- struct dma_buf_attachment *d_att = NULL;
- struct sg_table *sg = NULL;
- void *vaddr = NULL;
- struct device *dev = NULL;
- enum dma_data_direction dir;
-
- if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL) {
- enc_pr(LOG_ERROR, "error dma param\n");
- return -EINVAL;
- }
- fd = cfg->fd;
- dev = cfg->dev;
- dir = cfg->dir;
-
- dbuf = dma_buf_get(fd);
- if (IS_ERR_OR_NULL(dbuf)) {
- enc_pr(LOG_ERROR, "failed to get dma buffer,fd %d\n",fd);
- return -EINVAL;
- }
-
- d_att = dma_buf_attach(dbuf, dev);
- if (IS_ERR(d_att)) {
- enc_pr(LOG_ERROR, "failed to set dma attach\n");
- goto attach_err;
- }
-
- sg = dma_buf_map_attachment(d_att, dir);
- if (IS_ERR(sg)) {
- enc_pr(LOG_ERROR, "failed to get dma sg\n");
- goto map_attach_err;
- }
-
- page = sg_page(sg->sgl);
- cfg->paddr = PFN_PHYS(page_to_pfn(page));
- cfg->dbuf = dbuf;
- cfg->attach = d_att;
- cfg->vaddr = vaddr;
- cfg->sg = sg;
-
- return 0;
-
-map_attach_err:
- dma_buf_detach(dbuf, d_att);
-attach_err:
- dma_buf_put(dbuf);
-
- return ret;
-}
-
-static void vpu_dma_buffer_unmap(struct vpu_dma_cfg *cfg)
-{
- int fd = -1;
- struct dma_buf *dbuf = NULL;
- struct dma_buf_attachment *d_att = NULL;
- struct sg_table *sg = NULL;
- /*void *vaddr = NULL;*/
- struct device *dev = NULL;
- enum dma_data_direction dir;
-
- if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL
- || cfg->dbuf == NULL /*|| cfg->vaddr == NULL*/
- || cfg->attach == NULL || cfg->sg == NULL) {
- enc_pr(LOG_ERROR, "unmap: Error dma param\n");
- return;
- }
-
- fd = cfg->fd;
- dev = cfg->dev;
- dir = cfg->dir;
- dbuf = cfg->dbuf;
- d_att = cfg->attach;
- sg = cfg->sg;
-
- dma_buf_unmap_attachment(d_att, sg, dir);
- dma_buf_detach(dbuf, d_att);
- dma_buf_put(dbuf);
-
- enc_pr(LOG_INFO, "vpu_dma_buffer_unmap fd %d\n",fd);
-}
-
-static s32 vpu_dma_buffer_get_phys(struct vpu_dma_cfg *cfg,
- unsigned long *addr)
-{
- int ret = 0;
- if (cfg->paddr == 0)
- { /* only mapp once */
- ret = vpu_dma_buffer_map(cfg);
- if (ret < 0) {
- enc_pr(LOG_ERROR, "vpu_dma_buffer_map failed\n");
- return ret;
- }
- }
- if (cfg->paddr) *addr = cfg->paddr;
- enc_pr(LOG_INFO,"vpu_dma_buffer_get_phys 0x%lx\n", cfg->paddr);
- return ret;
-}
-
-static s32 vpu_src_addr_config(struct vpudrv_dma_buf_info_t *pinfo,
- struct file *filp)
-{
- struct vpudrv_dma_buf_pool_t *vbp;
- unsigned long phy_addr;
- struct vpu_dma_cfg *cfg;
- s32 idx, ret = 0;
- if (pinfo->num_planes == 0 || pinfo->num_planes > 3)
- return -EFAULT;
-
- for (idx = 0; idx < pinfo->num_planes; idx++)
- pinfo->phys_addr[idx] = 0;
- for (idx = 0; idx < pinfo->num_planes; idx++) {
- vbp = kzalloc(sizeof(*vbp), GFP_KERNEL);
- if (!vbp) {
- ret = -ENOMEM;
- break;
- }
- memset(vbp, 0, sizeof(struct vpudrv_dma_buf_pool_t));
- cfg = &vbp->dma_cfg;
- cfg->dir = DMA_TO_DEVICE;
- cfg->fd = pinfo->fd[idx];
- cfg->dev = &(multienc_pdev->dev);
- phy_addr = 0;
- ret = vpu_dma_buffer_get_phys(cfg, &phy_addr);
- if (ret < 0) {
- enc_pr(LOG_ERROR, "import fd %d failed\n", cfg->fd);
- kfree(vbp);
- ret = -1;
- break;
- }
- pinfo->phys_addr[idx] = (ulong) phy_addr;
- vbp->filp = filp;
- spin_lock(&s_dma_buf_lock);
- list_add(&vbp->list, &s_dma_bufp_head);
- spin_unlock(&s_dma_buf_lock);
- }
- enc_pr(LOG_INFO, "vpu_src_addr_config phy_addr 0x%lx, 0x%lx, 0x%lx\n",
- pinfo->phys_addr[0], pinfo->phys_addr[1], pinfo->phys_addr[2]);
- //hoan add for canvas test
- phys_addrY = pinfo->phys_addr[0];
- phys_addrU = pinfo->phys_addr[1];
- phys_addrV = pinfo->phys_addr[2];
-
- //end
- return ret;
-}
-
-static s32 vpu_src_addr_unmap(struct vpudrv_dma_buf_info_t *pinfo,
- struct file *filp)
-{
- struct vpudrv_dma_buf_pool_t *pool, *n;
- struct vpu_dma_cfg vb;
- ulong phys_addr;
- s32 plane_idx = 0;
- s32 ret = 0;
- s32 found;
-
- if (pinfo->num_planes == 0 || pinfo->num_planes > 3)
- return -EFAULT;
-
- enc_pr(LOG_INFO,
- "dma_unmap planes %d fd: %d-%d-%d, phy_add: 0x%lx-%lx-%lx\n",
- pinfo->num_planes, pinfo->fd[0],pinfo->fd[1], pinfo->fd[2],
- pinfo->phys_addr[0], pinfo->phys_addr[1], pinfo->phys_addr[2]);
-
- list_for_each_entry_safe(pool, n, &s_dma_bufp_head, list) {
- found = 0;
- if (pool->filp == filp) {
- vb = pool->dma_cfg;
- phys_addr = vb.paddr;
- if (vb.fd == pinfo->fd[0])
- {
- if (phys_addr != pinfo->phys_addr[0]) {
- enc_pr(LOG_ERROR, "dma_unmap plane 0");
- enc_pr(LOG_ERROR, " no match ");
- enc_pr(LOG_ERROR, "0x%lx %lx\n",
- phys_addr, pinfo->phys_addr[0]);
- }
- found = 1;
- plane_idx++;
- }
- else if (vb.fd == pinfo->fd[1]
- && pinfo->num_planes > 1) {
- if (phys_addr != pinfo->phys_addr[1]) {
- enc_pr(LOG_ERROR, "dma_unmap plane 1");
- enc_pr(LOG_ERROR, " no match ");
- enc_pr(LOG_ERROR, "0x%lx %lx\n",
- phys_addr, pinfo->phys_addr[1]);
- }
- plane_idx++;
- found = 1;
- }
- else if (vb.fd == pinfo->fd[2]
- && pinfo->num_planes > 2) {
- if (phys_addr != pinfo->phys_addr[2]) {
- enc_pr(LOG_ERROR, "dma_unmap plane 2");
- enc_pr(LOG_ERROR, " no match ");
- enc_pr(LOG_ERROR, "0x%lx %lx\n",
- phys_addr, pinfo->phys_addr[2]);
- }
- plane_idx++;
- found = 1;
- }
- if (found && vb.attach) {
- vpu_dma_buffer_unmap(&vb);
- spin_lock(&s_dma_buf_lock);
- list_del(&pool->list);
- spin_unlock(&s_dma_buf_lock);
- kfree(pool);
- }
- }
- }
-
- if (plane_idx != pinfo->num_planes) {
- enc_pr(LOG_DEBUG, "dma_unmap fd planes not match\n");
- enc_pr(LOG_DEBUG, " found %d need %d\n",
- plane_idx, pinfo->num_planes);
- }
- return ret;
-}
-
-static const struct file_operations vpu_fops = {
- .owner = THIS_MODULE,
- .open = vpu_open,
- .release = vpu_release,
- .write = vpu_write,
- .unlocked_ioctl = vpu_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = vpu_compat_ioctl,
-#endif
- .fasync = vpu_fasync,
- .mmap = vpu_mmap,
-};
-
-static ssize_t encode_status_show(struct class *cla,
- struct class_attribute *attr, char *buf)
-{
- struct vmem_info_t info;
- char *pbuf = buf;
- s32 open_count;
-
- spin_lock(&s_vpu_lock);
- open_count = s_vpu_drv_context.open_count;
- spin_unlock(&s_vpu_lock);
-
- vmem_get_info(&s_vmem, &info);
- pbuf += snprintf(buf, 40, "\nmultienc memory usage info:\n");
- pbuf += snprintf(buf, 120, "Total %ld used %ld free %ld page sz %ld, open_count=%u, in_interrupt=%lu, flag=%u\n",
- info.total_pages*info.page_size,
- info.alloc_pages*info.page_size,
- info.free_pages*info.page_size,
- info.page_size,
- open_count,
- in_interrupt(),
- current->flags & PF_KTHREAD);
- return pbuf - buf;
-}
-
-static CLASS_ATTR_RO(encode_status);
-static struct attribute *multienc_class_attrs[] = {
- &class_attr_encode_status.attr,
- NULL
-};
-
-ATTRIBUTE_GROUPS(multienc_class);
-
-static struct class multienc_class = {
- .name = VPU_CLASS_NAME,
- .class_groups = multienc_class_groups,
-};
-
-s32 init_MultiEnc_device(void)
-{
- s32 r = 0;
-
- r = register_chrdev(0, VPU_DEV_NAME, &vpu_fops);
- if (r <= 0) {
- enc_pr(LOG_ERROR, "register multienc device error.\n");
- return r;
- }
- s_vpu_major = r;
-
- r = class_register(&multienc_class);
- if (r < 0) {
- enc_pr(LOG_ERROR, "error create multienc class.\n");
- return r;
- }
- s_register_flag = 1;
- multienc_dev = device_create(&multienc_class, NULL,
- MKDEV(s_vpu_major, 0), NULL,
- VPU_DEV_NAME);
-
- if (IS_ERR(multienc_dev)) {
- enc_pr(LOG_ERROR, "create multienc device error.\n");
- class_unregister(&multienc_class);
- return -1;
- }
- return r;
-}
-
-s32 uninit_MultiEnc_device(void)
-{
- if (multienc_dev)
- device_destroy(&multienc_class, MKDEV(s_vpu_major, 0));
-
- if (s_register_flag)
- class_destroy(&multienc_class);
- s_register_flag = 0;
-
- if (s_vpu_major)
- unregister_chrdev(s_vpu_major, VPU_DEV_NAME);
- s_vpu_major = 0;
- return 0;
-}
-
-static s32 multienc_mem_device_init(
- struct reserved_mem *rmem, struct device *dev)
-{
- s32 r;
-
- if (!rmem) {
- enc_pr(LOG_ERROR, "Can not obtain I/O memory, ");
- enc_pr(LOG_ERROR, "will allocate multienc buffer!\n");
-
- r = -EFAULT;
- return r;
- }
-
- if ((!rmem->base) ||
- (rmem->size < cma_cfg_size)) {
- enc_pr(LOG_ERROR,
- "memory range error, 0x%lx - 0x%lx\n",
- (ulong)rmem->base, (ulong)rmem->size);
- r = -EFAULT;
- return r;
- }
- r = 0;
- s_video_memory.size = rmem->size;
- s_video_memory.phys_addr = (ulong)rmem->base;
- enc_pr(LOG_DEBUG, "multienc_mem_device_init %d, 0x%lx\n",
- s_video_memory.size,s_video_memory.phys_addr);
-
- return r;
-}
-
-static s32 vpu_probe(struct platform_device *pdev)
-{
- s32 err = 0, irq, reg_count, idx;
- struct resource res;
- struct device_node *np, *child;
-
- enc_pr(LOG_DEBUG, "vpu_probe\n");
-
- s_vpu_major = 0;
- use_reserve = false;
- s_vpu_irq = -1;
- cma_pool_size = 0;
- s_vpu_irq_requested = false;
- spin_lock(&s_vpu_lock);
- s_vpu_open_ref_count = 0;
- spin_unlock(&s_vpu_lock);
- multienc_dev = NULL;
- multienc_pdev = NULL;
- s_register_flag = 0;
- memset(&s_video_memory, 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vpu_register, 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vmem, 0, sizeof(struct video_mm_t));
- memset(&s_bit_firmware_info[0], 0, sizeof(s_bit_firmware_info));
- memset(&res, 0, sizeof(struct resource));
- memset(&s_fifo_alloc_flag, 0, sizeof(s_fifo_alloc_flag));
- np = pdev->dev.of_node;
- err = of_property_read_u32(np, "config_mm_sz_mb", &cma_cfg_size);
-
- cma_cfg_size = 100;
- enc_pr(LOG_ERROR, "reset cma_cfg_size to 200");
-
- if (err) {
- enc_pr(LOG_ERROR, "failed to get config_mm_sz_mb node, use default\n");
- cma_cfg_size = VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE;
- err = 0;
- } else
- cma_cfg_size = cma_cfg_size*SZ_1M;
-
- enc_pr(LOG_INFO, "cma cfg size %d\n", cma_cfg_size);
- idx = of_reserved_mem_device_init(&pdev->dev);
-
- if (idx != 0)
- enc_pr(LOG_DEBUG, "MultiEnc reserved memory config fail.\n");
- else if (s_video_memory.phys_addr)
- use_reserve = true;
-
- if (use_reserve == false) {
-#ifndef CONFIG_CMA
- enc_pr(LOG_ERROR, "MultiEnc reserved memory is invaild, probe fail!\n");
- err = -EFAULT;
- goto ERROR_PROVE_DEVICE;
-#else
- cma_pool_size =
- (codec_mm_get_total_size() > (cma_cfg_size)) ?
- (cma_cfg_size) :
- codec_mm_get_total_size();
-
- enc_pr(LOG_DEBUG, "MultiEnc - cma memory pool size: %d MB\n", (u32)cma_pool_size / SZ_1M);
-#endif
- }
-
- /* get interrupt resource */
- irq = platform_get_irq_byname(pdev, "multienc_irq");
-
- if (irq < 0) {
- enc_pr(LOG_ERROR, "get MultiEnc irq resource error\n");
- err = -EFAULT;
-
- goto ERROR_PROVE_DEVICE;
- }
-
- s_vpu_irq = irq;
- enc_pr(LOG_DEBUG, "MultiEnc -irq: %d\n", s_vpu_irq);
-
- /* get vpu clks */
- if (vpu_clk_get(&pdev->dev, &s_vpu_clks)) {
- enc_pr(LOG_DEBUG, "get vpu clks fail.\n");
- goto ERROR_PROVE_DEVICE;
- } else
- enc_pr(LOG_DEBUG, "MultiEnc. clock get success\n");
-
- reg_count = 0;
- np = pdev->dev.of_node;
-
- for_each_child_of_node(np, child) {
- if (of_address_to_resource(child, 0, &res) || (reg_count > 1)) {
- enc_pr(LOG_ERROR, "no reg ranges or more reg ranges %d\n", reg_count);
- err = -ENXIO;
- goto ERROR_PROVE_DEVICE;
- }
-
- /* if platform driver is implemented */
- if (res.start != 0) {
- s_vpu_register.phys_addr = res.start;
- s_vpu_register.virt_addr = (ulong)ioremap_nocache(res.start, resource_size(&res));
- s_vpu_register.size = res.end - res.start;
-
- enc_pr(LOG_DEBUG, "vpu base address get from platform driver ");
- enc_pr(LOG_DEBUG, "physical addr=0x%lx, virtual addr=0x%lx\n",
- s_vpu_register.phys_addr, s_vpu_register.virt_addr);
- } else {
- s_vpu_register.phys_addr = VPU_REG_BASE_ADDR;
- s_vpu_register.virt_addr = (ulong)ioremap_nocache(s_vpu_register.phys_addr, VPU_REG_SIZE);
- s_vpu_register.size = VPU_REG_SIZE;
-
- enc_pr(LOG_DEBUG, "vpu base address get from defined value ");
- enc_pr(LOG_DEBUG, "physical addr=0x%lx, virtual addr=0x%lx\n",
- s_vpu_register.phys_addr, s_vpu_register.virt_addr);
- }
-
- reg_count++;
- }
-
- /* get the major number of the character device */
- if (init_MultiEnc_device()) {
- err = -EBUSY;
- enc_pr(LOG_ERROR, "could not allocate major number\n");
-
- goto ERROR_PROVE_DEVICE;
- }
-
- enc_pr(LOG_INFO, "SUCCESS alloc_chrdev_region\n");
-
- for (idx = 0; idx < MAX_NUM_INSTANCE; idx ++)
- init_waitqueue_head(&s_interrupt_wait_q[idx]);
-
- for (idx = 0; idx < MAX_NUM_INSTANCE; idx ++) {
- err = kfifo_alloc(&s_interrupt_pending_q[idx], MAX_INTERRUPT_QUEUE*sizeof(u32), GFP_KERNEL);
-
- if (err) {
- enc_pr(LOG_ERROR,"kfifo_alloc failed 0x%x\n", err);
- goto ERROR_PROVE_DEVICE;
- }
-
- s_fifo_alloc_flag[idx] = 1;
- }
-
- tasklet_init(&multienc_tasklet, multienc_isr_tasklet, (ulong)&s_vpu_drv_context);
-
- s_common_memory.base = 0;
- s_instance_pool.base = 0;
-
- if (use_reserve == true) {
- if (vmem_init(&s_vmem, s_video_memory.phys_addr, s_video_memory.size) < 0) {
- enc_pr(LOG_ERROR, "fail to init vmem system\n");
- goto ERROR_PROVE_DEVICE;
- }
-
- enc_pr(LOG_DEBUG, "success to probe vpu device with video memory");
- enc_pr(LOG_DEBUG, "phys_addr=0x%lx, base = 0x%lx\n",
- (ulong)s_video_memory.phys_addr, (ulong)s_video_memory.base);
- } else {
- enc_pr(LOG_DEBUG, "success to probe vpu device with video memory \n");
- }
-
- enc_pr(LOG_DEBUG, "to be allocate from CMA pool_size 0x%lx\n", cma_pool_size);
- multienc_pdev = pdev;
-
- return 0;
-
-ERROR_PROVE_DEVICE:
- for (idx = 0; idx < MAX_NUM_INSTANCE; idx++) {
- if (s_fifo_alloc_flag[idx])
- kfifo_free(&s_interrupt_pending_q[idx]);
- s_fifo_alloc_flag[idx] = 0;
- }
-
- if (s_vpu_register.virt_addr) {
- iounmap((void *)s_vpu_register.virt_addr);
- memset(&s_vpu_register, 0, sizeof(struct vpudrv_buffer_t));
- }
-
- if (s_video_memory.phys_addr) {
- vmem_exit(&s_vmem);
- memset(&s_video_memory, 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vmem, 0, sizeof(struct video_mm_t));
- }
-
- if (s_vpu_irq_requested == true) {
- if (s_vpu_irq >= 0) {
- free_irq(s_vpu_irq, &s_vpu_drv_context);
- s_vpu_irq = -1;
- }
- s_vpu_irq_requested = false;
- }
- uninit_MultiEnc_device();
- return err;
-}
-
-static s32 vpu_remove(struct platform_device *pdev)
-{
- s32 idx;
- enc_pr(LOG_DEBUG, "vpu_remove\n");
-
- if (s_instance_pool.base) {
- vfree((const void *)s_instance_pool.base);
- s_instance_pool.base = 0;
- }
-
- if (s_common_memory.phys_addr) {
- vpu_free_dma_buffer(&s_common_memory);
- s_common_memory.phys_addr = 0;
- }
-
- if (s_video_memory.phys_addr) {
- if (!use_reserve) {
- codec_mm_free_for_dma(
- VPU_DEV_NAME,
- (u32)s_video_memory.phys_addr);
- }
- vmem_exit(&s_vmem);
- memset(&s_video_memory,
- 0, sizeof(struct vpudrv_buffer_t));
- memset(&s_vmem,
- 0, sizeof(struct video_mm_t));
- }
-
- if (s_vpu_irq_requested == true) {
- if (s_vpu_irq >= 0) {
- free_irq(s_vpu_irq, &s_vpu_drv_context);
- s_vpu_irq = -1;
- }
- s_vpu_irq_requested = false;
- }
- for (idx = 0; idx < MAX_NUM_INSTANCE; idx++)
- kfifo_free(&s_interrupt_pending_q[idx]);
-
- if (s_vpu_register.virt_addr) {
- iounmap((void *)s_vpu_register.virt_addr);
- memset(&s_vpu_register,
- 0, sizeof(struct vpudrv_buffer_t));
- }
- if (clock_gate_count > 0)
- {
- vpu_clk_disable(&s_vpu_clks);
- }
- vpu_clk_put(&multienc_pdev->dev, &s_vpu_clks);
- multienc_pdev = NULL;
- uninit_MultiEnc_device();
- return 0;
-}
-
-#ifdef CONFIG_PM
-#define VP5_CMD_INIT_VPU (0x0001)
-#define VP5_CMD_SLEEP_VPU (0x0004)
-#define VP5_CMD_WAKEUP_VPU (0x0002)
-
-static void Vp5BitIssueCommand(int core, u32 cmd)
-{
- WriteVpuRegister(VP5_VPU_BUSY_STATUS, 1);
- WriteVpuRegister(VP5_COMMAND, cmd);
- WriteVpuRegister(VP5_VPU_HOST_INT_REQ, 1);
-
- return;
-}
-
-static s32 vpu_suspend(struct platform_device *pdev, pm_message_t state)
-{
- u32 core;
- ulong timeout = jiffies + HZ; /* vpu wait timeout to 1sec */
-
- enc_pr(LOG_DEBUG, "vpu_suspend\n");
-
- if (s_vpu_open_ref_count > 0) {
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- vpu_clk_config(1);
-#endif
- for (core = 0; core < MAX_NUM_VPU_CORE; core++) {
- if (s_bit_firmware_info[core].size == 0)
- continue;
- while (ReadVpuRegister(VP5_VPU_BUSY_STATUS)) {
- if (time_after(jiffies, timeout)) {
- enc_pr(LOG_ERROR,
- "SLEEP_VPU BUSY timeout");
- goto DONE_SUSPEND;
- }
- }
- Vp5BitIssueCommand(core, VP5_CMD_SLEEP_VPU);
- while (ReadVpuRegister(VP5_VPU_BUSY_STATUS)) {
- if (time_after(jiffies, timeout)) {
- enc_pr(LOG_ERROR,
- "SLEEP_VPU BUSY timeout");
- goto DONE_SUSPEND;
- }
- }
- if (ReadVpuRegister(VP5_RET_SUCCESS) == 0) {
- enc_pr(LOG_ERROR,
- "SLEEP_VPU failed [0x%x]",
- ReadVpuRegister(VP5_RET_FAIL_REASON));
- goto DONE_SUSPEND;
- }
- }
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- vpu_clk_config(0);
- if (clock_gate_count > 0)
-#endif
- {
- clk_disable(s_vpu_clks.c_clk);
- clk_disable(s_vpu_clks.b_clk);
- clk_disable(s_vpu_clks.a_clk);
- }
- /* the power off */
- pwr_ctrl_psci_smc(PDID_T7_DOS_WAVE, false);
- }
- return 0;
-
-DONE_SUSPEND:
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- vpu_clk_config(0);
-#endif
- return -EAGAIN;
-}
-static s32 vpu_resume(struct platform_device *pdev)
-{
- u32 core;
- ulong timeout = jiffies + HZ; /* vpu wait timeout to 1sec */
- ulong code_base;
- u32 code_size;
- u32 remap_size;
- u32 regVal;
- u32 hwOption = 0;
-
- enc_pr(LOG_DEBUG, "vpu_resume\n");
-
- if (s_vpu_open_ref_count > 0) {
-#ifdef VPU_SUPPORT_CLOCK_CONTROL
- if (clock_gate_count > 0)
-#endif
- {
- clk_enable(s_vpu_clks.a_clk);
- clk_enable(s_vpu_clks.b_clk);
- clk_enable(s_vpu_clks.c_clk);
- }
- vpu_clk_config(1);
- /* the power on */
- pwr_ctrl_psci_smc(PDID_T7_DOS_WAVE, true);
- for (core = 0; core < MAX_NUM_VPU_CORE; core++) {
- if (s_bit_firmware_info[core].size == 0)
- continue;
- code_base = s_common_memory.phys_addr;
- /* ALIGN TO 4KB */
- code_size = (s_common_memory.size & ~0xfff);
- if (code_size < s_bit_firmware_info[core].size * 2)
- goto DONE_WAKEUP;
- regVal = 0;
- WriteVpuRegister(VP5_PO_CONF, regVal);
-
- /* Reset All blocks */
- regVal = 0x7ffffff;
- WriteVpuRegister(VP5_VPU_RESET_REQ, regVal);
- /* Waiting reset done */
- while (ReadVpuRegister(VP5_VPU_RESET_STATUS)) {
- if (time_after(jiffies, timeout))
- goto DONE_WAKEUP;
- }
- WriteVpuRegister(VP5_VPU_RESET_REQ, 0);
-
- /* remap page size */
- remap_size = (code_size >> 12) & 0x1ff;
- regVal = 0x80000000 | (VP5_REMAP_CODE_INDEX<<12)
- | (0 << 16) | (1<<11) | remap_size;
- WriteVpuRegister(VP5_VPU_REMAP_CTRL, regVal);
- /* DO NOT CHANGE! */
- WriteVpuRegister(VP5_VPU_REMAP_VADDR, 0x00000000);
- WriteVpuRegister(VP5_VPU_REMAP_PADDR, code_base);
- WriteVpuRegister(VP5_ADDR_CODE_BASE, code_base);
- WriteVpuRegister(VP5_CODE_SIZE, code_size);
- WriteVpuRegister(VP5_CODE_PARAM, 0);
- WriteVpuRegister(VP5_INIT_VPU_TIME_OUT_CNT, timeout);
- WriteVpuRegister(VP5_HW_OPTION, hwOption);
-
- /* Interrupt */
- regVal = (1 << INT_ENC_SET_PARAM);
- regVal |= (1 << INT_ENC_PIC);
- regVal |= (1 << INT_INIT_SEQ);
- regVal |= (1 << INT_DEC_PIC);
- regVal |= (1 << INT_BSBUF_EMPTY);
- WriteVpuRegister(VP5_VPU_VINT_ENABLE, regVal);
- Vp5BitIssueCommand(core, VP5_CMD_INIT_VPU);
- WriteVpuRegister(VP5_VPU_REMAP_CORE_START, 1);
- while (ReadVpuRegister(VP5_VPU_BUSY_STATUS)) {
- if (time_after(jiffies, timeout))
- goto DONE_WAKEUP;
- }
-
- if (ReadVpuRegister(VP5_RET_SUCCESS) == 0) {
- enc_pr(LOG_ERROR,
- "WAKEUP_VPU failed [0x%x]",
- ReadVpuRegister(VP5_RET_FAIL_REASON));
- goto DONE_WAKEUP;
- }
- }
- }
-DONE_WAKEUP:
- if (s_vpu_open_ref_count > 0)
- vpu_clk_config(0);
- return 0;
-}
-#else
-#define vpu_suspend NULL
-#define vpu_resume NULL
-#endif /* !CONFIG_PM */
-
-static const struct of_device_id cnm_multienc_dt_match[] = {
- {
- .compatible = "cnm, MultiEnc",
- },
- {},
-};
-
-static struct platform_driver vpu_driver = {
- .driver = {
- .name = VPU_PLATFORM_DEVICE_NAME,
- .of_match_table = cnm_multienc_dt_match,
- },
- .probe = vpu_probe,
- .remove = vpu_remove,
- .suspend = vpu_suspend,
- .resume = vpu_resume,
-};
-
-static s32 __init vpu_init(void)
-{
- s32 res;
-
- enc_pr(LOG_DEBUG, "vpu_init\n");
-
- if (get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T7) {
- pr_err("The chip is not support multi encoder!!\n");
- return -1;
- }
-
- res = platform_driver_register(&vpu_driver);
- enc_pr(LOG_INFO,
- "end vpu_init result=0x%x\n", res);
- return res;
-}
-
-static void __exit vpu_exit(void)
-{
- enc_pr(LOG_DEBUG, "vpu_exit\n");
- platform_driver_unregister(&vpu_driver);
-}
-
-static const struct reserved_mem_ops rmem_multienc_ops = {
- .device_init = multienc_mem_device_init,
-};
-
-static s32 __init multienc_mem_setup(struct reserved_mem *rmem)
-{
- rmem->ops = &rmem_multienc_ops;
- enc_pr(LOG_DEBUG, "MultiEnc reserved mem setup.\n");
- return 0;
-}
-
-module_param(print_level, uint, 0664);
-MODULE_PARM_DESC(print_level, "\n print_level\n");
-
-module_param(clock_level, uint, 0664);
-MODULE_PARM_DESC(clock_level, "\n clock_level\n");
-
-module_param(clock_gate_count, uint, 0664);
-MODULE_PARM_DESC(clock_gate_count, "\n clock_gate_count\n");
-
-module_param(set_clock_freq, uint, 0664);
-MODULE_PARM_DESC(set_clock_freq, "\n set clk freq\n");
-
-module_param(clock_a, uint, 0664);
-MODULE_PARM_DESC(clock_a, "\n clock_a\n");
-
-module_param(clock_b, uint, 0664);
-MODULE_PARM_DESC(clock_b, "\n clock_b\n");
-
-module_param(clock_c, uint, 0664);
-MODULE_PARM_DESC(clock_c, "\n clock_c\n");
-
-module_param(dump_input, uint, 0664);
-MODULE_PARM_DESC(dump_input, "\n dump_input\n");
-
-module_param(dump_es, uint, 0664);
-MODULE_PARM_DESC(dump_es, "\n dump_es\n");
-
-MODULE_AUTHOR("Amlogic Inc.");
-MODULE_DESCRIPTION("VPU linux driver");
-MODULE_LICENSE("GPL");
-
-module_init(vpu_init);
-module_exit(vpu_exit);
-RESERVEDMEM_OF_DECLARE(cnm_multienc, "cnm, MultiEnc-mem", multienc_mem_setup);
diff --git a/drivers/frame_sink/encoder/multi/vpu_multi.h b/drivers/frame_sink/encoder/multi/vpu_multi.h
deleted file mode 100644
index 912df01..0000000
--- a/drivers/frame_sink/encoder/multi/vpu_multi.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- *
- * Copyright (C) 2019 by Amlogic, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#ifndef __VPU_MULTI_DRV_H__
-#define __VPU_MULTI_DRV_H__
-
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/compat.h>
-#include <linux/dma-buf.h>
-
-#define SUPPORT_SOURCE_RELEASE_INTERRUPT
-
-/* DO NOT CHANGE THIS VALUE */
-#define MAX_INST_HANDLE_SIZE 48
-#define MAX_NUM_INSTANCE 6
-#define MAX_NUM_VPU_CORE 1
-
-#ifdef CONFIG_COMPAT
-struct compat_vpudrv_buffer_t {
- u32 size;
- u32 cached;
- compat_ulong_t phys_addr;
- compat_ulong_t base; /* kernel logical address in use kernel */
- compat_ulong_t virt_addr; /* virtual user space address */
-};
-#endif
-
-struct vpudrv_buffer_t {
- u32 size;
- u32 cached;
- ulong phys_addr;
- ulong base; /* kernel logical address in use kernel */
- ulong virt_addr; /* virtual user space address */
-};
-
-struct vpu_bit_firmware_info_t {
- u32 size; /* size of this structure*/
- u32 core_idx;
- u32 reg_base_offset;
- u16 bit_code[512];
-};
-
-struct vpudrv_inst_info_t {
- u32 core_idx;
- u32 inst_idx;
- s32 inst_open_count; /* for output only*/
-};
-
-struct vpudrv_intr_info_t {
- u32 timeout;
- s32 intr_reason;
- s32 intr_inst_index;
-};
-
-struct vpu_drv_context_t {
- struct fasync_struct *async_queue;
- ulong interrupt_reason[MAX_NUM_INSTANCE];
- u32 interrupt_flag[MAX_NUM_INSTANCE];
- u32 open_count; /*!<< device reference count. Not instance count */
-};
-
-/* To track the allocated memory buffer */
-struct vpudrv_buffer_pool_t {
- struct list_head list;
- struct vpudrv_buffer_t vb;
- struct file *filp;
-};
-
-/* To track the instance index and buffer in instance pool */
-struct vpudrv_instanace_list_t {
- struct list_head list;
- ulong inst_idx;
- ulong core_idx;
- struct file *filp;
-};
-
-struct vpudrv_instance_pool_t {
- u8 codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
-};
-
-struct vpudrv_dma_buf_info_t {
- u32 num_planes;
- int fd[3];
- ulong phys_addr[3]; /* phys address for DMA buffer */
-};
-
-//hoan add for canvas
-struct vpudrv_dma_buf_canvas_info_t {
- u32 num_planes;
- u32 canvas_index;
- int fd[3];
- ulong phys_addr[3]; /* phys address for DMA buffer */
-};
-
-
-
-//end
-
-
-
-#ifdef CONFIG_COMPAT
-struct compat_vpudrv_dma_buf_info_t {
- u32 num_planes;
- compat_int_t fd[3];
- compat_ulong_t phys_addr[3]; /* phys address for DMA buffer */
-};
-
-
-struct compat_vpudrv_dma_buf_canvas_info_t {
- u32 num_planes;
- u32 canvas_index;
- compat_int_t fd[3];
- compat_ulong_t phys_addr[3]; /* phys address for DMA buffer */
-};
-
-
-#endif
-
-struct vpu_dma_cfg {
- int fd;
- void *dev;
- void *vaddr;
- unsigned long paddr;
- struct dma_buf *dbuf;
- struct dma_buf_attachment *attach;
- struct sg_table *sg;
- enum dma_data_direction dir;
-};
-
-/* To track the occupied dma_buf */
-struct vpudrv_dma_buf_pool_t {
- struct list_head list;
- struct vpu_dma_cfg dma_cfg;
- struct file *filp;
-};
-
-#define VPUDRV_BUF_LEN struct vpudrv_buffer_t
-#define VPUDRV_INST_LEN struct vpudrv_inst_info_t
-#define VPUDRV_DMABUF_LEN struct vpudrv_dma_buf_info_t
- //hoan add for canvas
-#define VPUDRV_DMABUF_CANVAS_LEN struct vpudrv_dma_buf_canvas_info_t
- //end
-
-#ifdef CONFIG_COMPAT
-#define VPUDRV_BUF_LEN32 struct compat_vpudrv_buffer_t
-#define VPUDRV_DMABUF_LEN32 struct compat_vpudrv_dma_buf_info_t
- //hoan add for canvas
-#define VPUDRV_DMABUF_CANVAS_LEN32 struct compat_vpudrv_dma_buf_canvas_info_t
- //end
-
-#endif
-
-#define VDI_MAGIC 'V'
-#define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY \
- _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_FREE_PHYSICALMEMORY \
- _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_WAIT_INTERRUPT \
- _IOW(VDI_MAGIC, 2, struct vpudrv_intr_info_t)
-
-#define VDI_IOCTL_SET_CLOCK_GATE \
- _IOW(VDI_MAGIC, 3, u32)
-
-#define VDI_IOCTL_RESET \
- _IOW(VDI_MAGIC, 4, u32)
-
-#define VDI_IOCTL_GET_INSTANCE_POOL \
- _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_GET_COMMON_MEMORY \
- _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO \
- _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_OPEN_INSTANCE \
- _IOW(VDI_MAGIC, 9, VPUDRV_INST_LEN)
-
-#define VDI_IOCTL_CLOSE_INSTANCE \
- _IOW(VDI_MAGIC, 10, VPUDRV_INST_LEN)
-
-#define VDI_IOCTL_GET_INSTANCE_NUM \
- _IOW(VDI_MAGIC, 11, VPUDRV_INST_LEN)
-
-#define VDI_IOCTL_GET_REGISTER_INFO \
- _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_GET_FREE_MEM_SIZE \
- _IOW(VDI_MAGIC, 13, u32)
-
-#define VDI_IOCTL_FLUSH_BUFFER \
- _IOW(VDI_MAGIC, 14, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_CACHE_INV_BUFFER \
- _IOW(VDI_MAGIC, 15, VPUDRV_BUF_LEN)
-
-#define VDI_IOCTL_CONFIG_DMA \
- _IOW(VDI_MAGIC, 16, VPUDRV_DMABUF_LEN)
-
-#define VDI_IOCTL_UNMAP_DMA \
- _IOW(VDI_MAGIC, 17, VPUDRV_DMABUF_LEN)
-
-
-//hoan add for canvas
-#define VDI_IOCTL_READ_CANVAS \
- _IOW(VDI_MAGIC, 20, VPUDRV_DMABUF_CANVAS_LEN)
-//end
-
-#ifdef CONFIG_COMPAT
-#define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32 \
- _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_FREE_PHYSICALMEMORY32 \
- _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_GET_INSTANCE_POOL32 \
- _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_GET_COMMON_MEMORY32 \
- _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32 \
- _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_GET_REGISTER_INFO32 \
- _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_FLUSH_BUFFER32 \
- _IOW(VDI_MAGIC, 14, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_CACHE_INV_BUFFER32 \
- _IOW(VDI_MAGIC, 15, VPUDRV_BUF_LEN32)
-
-#define VDI_IOCTL_CONFIG_DMA32 \
- _IOW(VDI_MAGIC, 16, VPUDRV_DMABUF_LEN32)
-
-#define VDI_IOCTL_UNMAP_DMA32 \
- _IOW(VDI_MAGIC, 17, VPUDRV_DMABUF_LEN32)
-
-//hoan add for canvas
-#define VDI_IOCTL_READ_CANVAS32 \
- _IOW(VDI_MAGIC, 20, VPUDRV_DMABUF_CANVAS_LEN32)
-//end
-
-
-
-#endif
-/* implement to power management functions */
-#define BIT_BASE 0x0000
-#define BIT_CODE_RUN (BIT_BASE + 0x000)
-#define BIT_CODE_DOWN (BIT_BASE + 0x004)
-#define BIT_INT_CLEAR (BIT_BASE + 0x00C)
-#define BIT_INT_STS (BIT_BASE + 0x010)
-#define BIT_CODE_RESET (BIT_BASE + 0x014)
-#define BIT_INT_REASON (BIT_BASE + 0x174)
-#define BIT_BUSY_FLAG (BIT_BASE + 0x160)
-#define BIT_RUN_COMMAND (BIT_BASE + 0x164)
-#define BIT_RUN_INDEX (BIT_BASE + 0x168)
-#define BIT_RUN_COD_STD (BIT_BASE + 0x16C)
-
-
-#define VPU_REG_BASE_ADDR 0xFE070000
-#define VPU_REG_SIZE (0x4000*MAX_NUM_VPU_CORE)
-
-/* registers */
-#define VP5_REG_BASE 0x0000
-#define VP5_VPU_BUSY_STATUS (VP5_REG_BASE + 0x0070)
-#define VP5_VPU_INT_REASON_CLEAR (VP5_REG_BASE + 0x0034)
-#define VP5_VPU_VINT_CLEAR (VP5_REG_BASE + 0x003C)
-#define VP5_VPU_VPU_INT_STS (VP5_REG_BASE + 0x0044)
-#define VP5_VPU_INT_REASON (VP5_REG_BASE + 0x004c)
-#define VP5_RET_FAIL_REASON (VP5_REG_BASE + 0x010C)
-
-#define VP5_RET_BS_EMPTY_INST (VP5_REG_BASE + 0x01E4)
-#define VP5_RET_QUEUE_CMD_DONE_INST (VP5_REG_BASE + 0x01E8)
-#define VP5_RET_SEQ_DONE_INSTANCE_INFO (VP5_REG_BASE + 0x01FC)
-
-/* interrrupt bits */
-enum {
- INT_INIT_VPU = 0,
- INT_WAKEUP_VPU = 1,
- INT_SLEEP_VPU = 2,
- INT_CREATE_INSTANCE = 3,
- INT_FLUSH_INSTANCE = 4,
- INT_DESTORY_INSTANCE = 5,
- INT_INIT_SEQ = 6,
- INT_SET_FRAMEBUF = 7,
- INT_DEC_PIC = 8,
- INT_ENC_PIC = 8,
- INT_ENC_SET_PARAM = 9,
-#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
- INT_ENC_SRC_RELEASE = 10,
-#endif
- INT_ENC_LOW_LATENCY = 13,
- INT_DEC_QUERY = 14,
- INT_BSBUF_EMPTY = 15,
- INT_BSBUF_FULL = 15,
-};
-
-/* INIT, WAKEUP */
-#define VP5_PO_CONF (VP5_REG_BASE + 0x0000)
-#define VP5_VPU_VINT_ENABLE (VP5_REG_BASE + 0x0048)
-
-#define VP5_VPU_RESET_REQ (VP5_REG_BASE + 0x0050)
-#define VP5_VPU_RESET_STATUS (VP5_REG_BASE + 0x0054)
-
-#define VP5_VPU_REMAP_CTRL (VP5_REG_BASE + 0x0060)
-#define VP5_VPU_REMAP_VADDR (VP5_REG_BASE + 0x0064)
-#define VP5_VPU_REMAP_PADDR (VP5_REG_BASE + 0x0068)
-#define VP5_VPU_REMAP_CORE_START (VP5_REG_BASE + 0x006C)
-
-#define VP5_REMAP_CODE_INDEX 0
-
-/*VPU registers */
-#define VP5_ADDR_CODE_BASE (VP5_REG_BASE + 0x0110)
-#define VP5_CODE_SIZE (VP5_REG_BASE + 0x0114)
-#define VP5_CODE_PARAM (VP5_REG_BASE + 0x0118)
-#define VP5_INIT_VPU_TIME_OUT_CNT (VP5_REG_BASE + 0x0130)
-#define VP5_HW_OPTION (VP5_REG_BASE + 0x012C)
-#define VP5_RET_SUCCESS (VP5_REG_BASE + 0x0108)
-#define VP5_COMMAND (VP5_REG_BASE + 0x0100)
-#define VP5_VPU_HOST_INT_REQ (VP5_REG_BASE + 0x0038)
-/* Product register */
-#define VPU_PRODUCT_CODE_REGISTER (BIT_BASE + 0x1044)
-
-#define ReadVpuRegister(addr) \
- readl((void __iomem *)(s_vpu_register.virt_addr \
- + s_bit_firmware_info[core].reg_base_offset + addr))
-
-#define WriteVpuRegister(addr, val) \
- writel((u32)val, (void __iomem *)(s_vpu_register.virt_addr \
- + s_bit_firmware_info[core].reg_base_offset + addr))
-
-#define WriteVpu(addr, val) writel((u32)val, (void __iomem *)addr)
-#endif
diff --git a/drivers/framerate_adapter/video_framerate_adapter.c b/drivers/framerate_adapter/video_framerate_adapter.c
index e59bd65..f920954 100644
--- a/drivers/framerate_adapter/video_framerate_adapter.c
+++ b/drivers/framerate_adapter/video_framerate_adapter.c
@@ -1,15 +1,29 @@
+/*
+ * drivers/framerate_adapter/video_framerate_adapter.c
+ *
+ * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <uapi/linux/major.h>
#include "video_framerate_adapter.h"
#define CLASS_NAME "framerate_adapter"
#define DEV_NAME "framerate_dev"
#ifndef VIDEOFRAME_MAJOR
-#define VIDEOFRAME_MAJOR AMSTREAM_MAJOR
+#define VIDEOFRAME_MAJOR 550
#endif
struct frame_rate_dev_s* frame_rate_dev;
@@ -35,15 +49,13 @@
.owner = THIS_MODULE
};
-static struct attribute *frame_rate_class_attrs[] = {
- NULL
+static struct class_attribute frame_rate_class_attrs[] = {
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(frame_rate_class);
-
static struct class frame_rate_class = {
.name = CLASS_NAME,
- .class_groups = frame_rate_class_groups,
+ .class_attrs = frame_rate_class_attrs,
};
static int frame_rate_driver_init(void)
@@ -54,7 +66,7 @@
if (IS_ERR_OR_NULL(frame_rate_dev))
return -ENOMEM;
- frame_rate_dev->dev_no = MKDEV(VIDEOFRAME_MAJOR, 101);
+ frame_rate_dev->dev_no = MKDEV(VIDEOFRAME_MAJOR, 100);
ret = register_chrdev_region(frame_rate_dev->dev_no, 1, DEV_NAME);
if (ret < 0) {
diff --git a/drivers/media_sync/media_sync_core.c b/drivers/media_sync/media_sync_core.c
index abc016f..abe3450 100644
--- a/drivers/media_sync/media_sync_core.c
+++ b/drivers/media_sync/media_sync_core.c
@@ -14,13 +14,9 @@
#define MAX_INSTANCE_NUM 10
mediasync_ins* vMediaSyncInsList[MAX_INSTANCE_NUM] = {0};
-u64 last_system;
-u64 last_pcr;
-typedef int (*pfun_amldemux_pcrscr_get)(int demux_device_index, int index,
- u64 *stc);
-static pfun_amldemux_pcrscr_get amldemux_pcrscr_get = NULL;
-//extern int demux_get_stc(int demux_device_index, int index,
-// u64 *stc, unsigned int *base);
+
+extern int demux_get_stc(int demux_device_index, int index,
+ u64 *stc, unsigned int *base);
extern int demux_get_pcr(int demux_device_index, int index, u64 *pcr);
static u64 get_llabs(s64 value){
@@ -33,7 +29,7 @@
}
}
-static u64 get_stc_time_us(s32 sSyncInsId)
+static u64 get_stc_time_us(s32 sSyncInsId, u64 *systemtime)
{
/*mediasync_ins* pInstance = NULL;
u64 stc;
@@ -45,7 +41,7 @@
pInstance = vMediaSyncInsList[index];
demux_get_stc(pInstance->mDemuxId, 0, &stc, &base);*/
mediasync_ins* pInstance = NULL;
- int ret = -1;
+ int ret;
u64 stc;
u64 timeus;
u64 pcr;
@@ -56,58 +52,51 @@
if (index < 0 || index >= MAX_INSTANCE_NUM)
return -1;
pInstance = vMediaSyncInsList[index];
- if (pInstance->mSyncMode != MEDIA_SYNC_PCRMASTER)
- return 0;
- if (!amldemux_pcrscr_get)
- amldemux_pcrscr_get = symbol_request(demux_get_pcr);
- if (!amldemux_pcrscr_get)
- return 0;
ktime_get_ts64(&ts_monotonic);
- timeus = ts_monotonic.tv_sec * 1000000LL + div_u64(ts_monotonic.tv_nsec , 1000);
+ timeus = ts_monotonic.tv_sec * 1000000LL + ts_monotonic.tv_nsec / 1000LL;
+ *systemtime = timeus;
if (pInstance->mDemuxId < 0)
return timeus;
-
- ret = amldemux_pcrscr_get(pInstance->mDemuxId, 0, &pcr);
-
+ ret = demux_get_pcr(pInstance->mDemuxId, 0, &pcr);
if (ret != 0) {
stc = timeus;
} else {
- if (last_pcr == 0) {
+ if (pInstance->last_pcr == 0) {
stc = timeus;
- last_pcr = div_u64(pcr * 100 , 9);
- last_system = timeus;
+ pInstance->last_pcr = pcr * 100 / 9;
+ pInstance->last_system = timeus;
} else {
- pcr_diff = div_u64(pcr * 100 , 9) - last_pcr;
- time_diff = timeus - last_system;
- if (time_diff && (div_u64(get_llabs(pcr_diff) , (s32)time_diff)
+ pcr_diff = pcr * 100 / 9 - pInstance->last_pcr;
+ time_diff = timeus - pInstance->last_system;
+ if (time_diff && (get_llabs(pcr_diff) / time_diff
> 100)) {
- last_pcr = div_u64(pcr * 100 , 9);
- last_system = timeus;
+ pInstance->last_pcr = pcr * 100 / 9;
+ pInstance->last_system = timeus;
stc = timeus;
} else {
if (time_diff)
- stc = last_system + pcr_diff;
+ stc = pInstance->last_system + pcr_diff;
else
stc = timeus;
- last_pcr = div_u64(pcr * 100 , 9);
- last_system = stc;
+ pInstance->last_pcr = pcr * 100 / 9;
+ pInstance->last_system = stc;
}
}
}
- pr_debug("get_stc_time_us stc:%lld pcr:%lld system_time:%lld\n", stc, div_u64(pcr * 100 , 9), timeus);
+ pr_debug("get_stc_time_us stc:%lld pcr:%lld system_time:%lld\n", stc, pcr * 100 / 9, timeus);
return stc;
}
-static s64 get_system_time_us(void) {
+/*static s64 get_system_time_us(void) {
s64 TimeUs;
struct timespec64 ts_monotonic;
ktime_get_ts64(&ts_monotonic);
- TimeUs = ts_monotonic.tv_sec * 1000000LL + div_u64(ts_monotonic.tv_nsec , 1000);
+ TimeUs = ts_monotonic.tv_sec * 1000000LL + ts_monotonic.tv_nsec / 1000LL;
pr_debug("get_system_time_us %lld\n", TimeUs);
return TimeUs;
-}
+}*/
long mediasync_ins_alloc(s32 sDemuxId,
s32 sPcrPid,
@@ -137,17 +126,6 @@
pInstance->mDemuxId = sDemuxId;
pInstance->mPcrPid = sPcrPid;
- mediasync_ins_init_syncinfo(pInstance->mSyncInsId);
- pInstance->mHasAudio = -1;
- pInstance->mHasVideo = -1;
- pInstance->mVideoWorkMode = 0;
- pInstance->mFccEnable = 0;
- pInstance->mSourceClockType = UNKNOWN_CLOCK;
- pInstance->mSyncInfo.state = MEDIASYNC_INIT;
- pInstance->mSourceClockState = CLOCK_PROVIDER_NORMAL;
- pInstance->mute_flag = false;
- pInstance->mSourceType = TS_DEMOD;
- pInstance->mUpdateTimeThreshold = MIN_UPDATETIME_THRESHOLD_US;
*pIns = pInstance;
return 0;
}
@@ -202,40 +180,6 @@
return 0;
}
-long mediasync_ins_init_syncinfo(s32 sSyncInsId) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.state = MEDIASYNC_INIT;
- pInstance->mSyncInfo.firstAframeInfo.framePts = -1;
- pInstance->mSyncInfo.firstAframeInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.firstVframeInfo.framePts = -1;
- pInstance->mSyncInfo.firstVframeInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.firstDmxPcrInfo.framePts = -1;
- pInstance->mSyncInfo.firstDmxPcrInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.refClockInfo.framePts = -1;
- pInstance->mSyncInfo.refClockInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.curAudioInfo.framePts = -1;
- pInstance->mSyncInfo.curAudioInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.curVideoInfo.framePts = -1;
- pInstance->mSyncInfo.curVideoInfo.frameSystemTime = -1;
- pInstance->mSyncInfo.curDmxPcrInfo.framePts = -1;
- pInstance->mSyncInfo.curDmxPcrInfo.frameSystemTime = -1;
- pInstance->mAudioInfo.cacheSize = -1;
- pInstance->mAudioInfo.cacheDuration = -1;
- pInstance->mVideoInfo.cacheSize = -1;
- pInstance->mVideoInfo.cacheDuration = -1;
- pInstance->mPauseResumeFlag = 0;
-
- return 0;
-}
-
long mediasync_ins_update_mediatime(s32 sSyncInsId,
s64 lMediaTime,
s64 lSystemTime, bool forceUpdate) {
@@ -252,11 +196,9 @@
if (pInstance == NULL)
return -1;
- current_stc = get_stc_time_us(sSyncInsId);
- current_systemtime = get_system_time_us();
-#if 0
- pInstance->mSyncMode = MEDIA_SYNC_PCRMASTER;
-#endif
+ current_stc = get_stc_time_us(sSyncInsId, ¤t_systemtime);
+ //pInstance->mSyncMode = MEDIA_SYNC_PCRMASTER;
+
if (pInstance->mSyncMode == MEDIA_SYNC_PCRMASTER) {
if (lSystemTime == 0) {
if (current_stc != 0) {
@@ -266,74 +208,48 @@
diff_system_time = current_systemtime - pInstance->mLastRealTime;
diff_mediatime = lMediaTime - pInstance->mLastMediaTime;
}
- if (pInstance->mSyncModeChange == 1
- || diff_mediatime < 0
+ if (diff_mediatime < 0
|| ((diff_mediatime > 0)
- && (get_llabs(diff_system_time - diff_mediatime) > pInstance->mUpdateTimeThreshold))) {
- pr_info("MEDIA_SYNC_PCRMASTER update time\n");
+ && (get_llabs(diff_system_time - diff_mediatime) > MIN_UPDATETIME_THRESHOLD_US ))) {
+ pr_info("MEDIA_SYNC_PCRMASTER update time system diff:%lld media diff:%lld current:%lld\n",
+ diff_system_time,
+ diff_mediatime,
+ current_systemtime);
pInstance->mLastMediaTime = lMediaTime;
pInstance->mLastRealTime = current_systemtime;
pInstance->mLastStc = current_stc;
- pInstance->mSyncModeChange = 0;
}
} else {
if (current_stc != 0) {
- diff_system_time = lSystemTime - pInstance->mLastRealTime;
+ diff_system_time = current_stc + lSystemTime - current_systemtime - pInstance->mLastStc;
diff_mediatime = lMediaTime - pInstance->mLastMediaTime;
} else {
diff_system_time = lSystemTime - pInstance->mLastRealTime;
diff_mediatime = lMediaTime - pInstance->mLastMediaTime;
}
- if (pInstance->mSyncModeChange == 1
- || diff_mediatime < 0
+ if (diff_mediatime < 0
|| ((diff_mediatime > 0)
- && (get_llabs(diff_system_time - diff_mediatime) > pInstance->mUpdateTimeThreshold))) {
+ && (get_llabs(diff_system_time - diff_mediatime) > MIN_UPDATETIME_THRESHOLD_US ))) {
+ pr_info("MEDIA_SYNC_PCRMASTER update time stc diff:%lld media diff:%lld lSystemTime:%lld lMediaTime:%lld\n",
+ diff_system_time,
+ diff_mediatime,
+ lSystemTime,
+ lMediaTime);
pInstance->mLastMediaTime = lMediaTime;
pInstance->mLastRealTime = lSystemTime;
pInstance->mLastStc = current_stc + lSystemTime - current_systemtime;
- pInstance->mSyncModeChange = 0;
}
}
} else {
if (lSystemTime == 0) {
- diff_system_time = current_systemtime - pInstance->mLastRealTime;
- diff_mediatime = lMediaTime - pInstance->mLastMediaTime;
-
- if (pInstance->mSyncModeChange == 1
- || forceUpdate
- || diff_mediatime < 0
- || ((diff_mediatime > 0)
- && (get_llabs(diff_system_time - diff_mediatime) > pInstance->mUpdateTimeThreshold))) {
- pr_info("mSyncMode:%d update time system diff:%lld media diff:%lld current:%lld\n",
- pInstance->mSyncMode,
- diff_system_time,
- diff_mediatime,
- current_systemtime);
- pInstance->mLastMediaTime = lMediaTime;
- pInstance->mLastRealTime = current_systemtime;
- pInstance->mLastStc = current_stc;
- pInstance->mSyncModeChange = 0;
- }
- } else {
- diff_system_time = lSystemTime - pInstance->mLastRealTime;
- diff_mediatime = lMediaTime - pInstance->mLastMediaTime;
- if (pInstance->mSyncModeChange == 1
- || forceUpdate
- || diff_mediatime < 0
- || ((diff_mediatime > 0)
- && (get_llabs(diff_system_time - diff_mediatime) > pInstance->mUpdateTimeThreshold))) {
- pr_info("mSyncMode:%d update time stc diff:%lld media diff:%lld lSystemTime:%lld lMediaTime:%lld\n",
- pInstance->mSyncMode,
- diff_system_time,
- diff_mediatime,
- lSystemTime,
- lMediaTime);
- pInstance->mLastMediaTime = lMediaTime;
- pInstance->mLastRealTime = lSystemTime;
- pInstance->mLastStc = current_stc + lSystemTime - current_systemtime;
- pInstance->mSyncModeChange = 0;
- }
+ pInstance->mLastMediaTime = lMediaTime;
+ pInstance->mLastRealTime = current_systemtime;
+ pInstance->mLastStc = current_stc;
+ } else {
+ pInstance->mLastMediaTime = lMediaTime;
+ pInstance->mLastRealTime = lSystemTime;
+ pInstance->mLastStc = current_stc + lSystemTime - current_systemtime;
}
}
pInstance->mTrackMediaTime = lMediaTime;
@@ -369,20 +285,13 @@
if (pInstance == NULL)
return -1;
- if (sPaused != 0 && sPaused != 1)
+ if ((sPaused != 0 && sPaused != 1)
+ || (sPaused == pInstance->mPaused))
return -1;
- if (sPaused == pInstance->mPaused)
- return 0;
- current_stc = get_stc_time_us(sSyncInsId);
- current_systemtime = get_system_time_us();
+ current_stc = get_stc_time_us(sSyncInsId, ¤t_systemtime);
pInstance->mPaused = sPaused;
-
- if (pInstance->mSyncMode == MEDIA_SYNC_AMASTER)
- pInstance->mLastMediaTime = pInstance->mLastMediaTime +
- (current_systemtime - pInstance->mLastRealTime);
-
pInstance->mLastRealTime = current_systemtime;
pInstance->mLastStc = current_stc;
@@ -414,7 +323,6 @@
return -1;
pInstance->mSyncMode = sSyncMode;
- pInstance->mSyncModeChange = 1;
return 0;
}
@@ -446,9 +354,9 @@
}
long mediasync_ins_get_anchor_time(s32 sSyncInsId,
- s64* lpMediaTime,
- s64* lpSTCTime,
- s64* lpSystemTime) {
+ s64* lpMediaTime,
+ s64* lpSTCTime,
+ s64* lpSystemTime) {
mediasync_ins* pInstance = NULL;
s32 index = sSyncInsId;
@@ -459,7 +367,7 @@
if (pInstance == NULL)
return -1;
- *lpMediaTime = pInstance->mLastMediaTime;
+ *lpMediaTime = pInstance->mLastMediaTime;
*lpSTCTime = pInstance->mLastStc;
*lpSystemTime = pInstance->mLastRealTime;
return 0;
@@ -478,8 +386,7 @@
if (pInstance == NULL)
return -1;
- current_stc = get_stc_time_us(sSyncInsId);
- current_systemtime = get_system_time_us();
+ current_stc = get_stc_time_us(sSyncInsId, ¤t_systemtime);
*lpSTC = current_stc;
*lpSystemTime = current_systemtime;
@@ -492,32 +399,6 @@
return 0;
}
-long mediasync_ins_set_updatetime_threshold(s32 sSyncInsId, s64 lTimeThreshold) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- pInstance->mUpdateTimeThreshold = lTimeThreshold;
- return 0;
-}
-
-long mediasync_ins_get_updatetime_threshold(s32 sSyncInsId, s64* lpTimeThreshold) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- *lpTimeThreshold = pInstance->mUpdateTimeThreshold;
- return 0;
-}
-
long mediasync_ins_get_trackmediatime(s32 sSyncInsId, s64* lpTrackMediaTime) {
mediasync_ins* pInstance = NULL;
@@ -531,726 +412,13 @@
*lpTrackMediaTime = pInstance->mTrackMediaTime;
return 0;
}
-long mediasync_ins_set_clocktype(s32 sSyncInsId, mediasync_clocktype type) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSourceClockType = type;
- return 0;
-}
-
-long mediasync_ins_get_clocktype(s32 sSyncInsId, mediasync_clocktype* type) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *type = pInstance->mSourceClockType;
- return 0;
-}
-
-long mediasync_ins_set_clockstate(s32 sSyncInsId, mediasync_clockprovider_state state) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSourceClockState = state;
- return 0;
-}
-
-long mediasync_ins_get_clockstate(s32 sSyncInsId, mediasync_clockprovider_state* state) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *state = pInstance->mSourceClockState;
- return 0;
-}
-
-long mediasync_ins_set_hasaudio(s32 sSyncInsId, int hasaudio) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mHasAudio = hasaudio;
- return 0;
-}
-
-long mediasync_ins_get_hasaudio(s32 sSyncInsId, int* hasaudio) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *hasaudio = pInstance->mHasAudio;
- return 0;
-}
-long mediasync_ins_set_hasvideo(s32 sSyncInsId, int hasvideo) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mHasVideo = hasvideo;
- return 0;
-}
-
-long mediasync_ins_get_hasvideo(s32 sSyncInsId, int* hasvideo) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *hasvideo = pInstance->mHasVideo;
- return 0;
-}
-
-long mediasync_ins_set_firstaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.firstAframeInfo.framePts = info.framePts;
- pInstance->mSyncInfo.firstAframeInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_firstaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->framePts = pInstance->mSyncInfo.firstAframeInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.firstAframeInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_firstvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.firstVframeInfo.framePts = info.framePts;
- pInstance->mSyncInfo.firstVframeInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_firstvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->framePts = pInstance->mSyncInfo.firstVframeInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.firstVframeInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_firstdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.firstDmxPcrInfo.framePts = info.framePts;
- pInstance->mSyncInfo.firstDmxPcrInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_firstdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- int64_t pcr = -1;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- if (pInstance->mSyncInfo.firstDmxPcrInfo.framePts == -1) {
- if (amldemux_pcrscr_get) {
- amldemux_pcrscr_get(pInstance->mDemuxId, 0, &pcr);
- pInstance->mSyncInfo.firstDmxPcrInfo.framePts = pcr;
- pInstance->mSyncInfo.firstDmxPcrInfo.frameSystemTime = get_system_time_us();
- }
- }
-
- info->framePts = pInstance->mSyncInfo.firstDmxPcrInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.firstDmxPcrInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_refclockinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.refClockInfo.framePts = info.framePts;
- pInstance->mSyncInfo.refClockInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_refclockinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->framePts = pInstance->mSyncInfo.refClockInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.refClockInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_curaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.curAudioInfo.framePts = info.framePts;
- pInstance->mSyncInfo.curAudioInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_curaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->framePts = pInstance->mSyncInfo.curAudioInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.curAudioInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_curvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.curVideoInfo.framePts = info.framePts;
- pInstance->mSyncInfo.curVideoInfo.frameSystemTime = info.frameSystemTime;
- pInstance->mTrackMediaTime = div_u64(info.framePts * 100 , 9);
-
- return 0;
-}
-
-long mediasync_ins_get_curvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->framePts = pInstance->mSyncInfo.curVideoInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.curVideoInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_curdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.curDmxPcrInfo.framePts = info.framePts;
- pInstance->mSyncInfo.curDmxPcrInfo.frameSystemTime = info.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_get_curdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- int64_t pcr = -1;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- if (amldemux_pcrscr_get) {
- amldemux_pcrscr_get(pInstance->mDemuxId, 0, &pcr);
- pInstance->mSyncInfo.curDmxPcrInfo.framePts = pcr;
- pInstance->mSyncInfo.curDmxPcrInfo.frameSystemTime = get_system_time_us();
- }
-
- info->framePts = pInstance->mSyncInfo.curDmxPcrInfo.framePts;
- info->frameSystemTime = pInstance->mSyncInfo.curDmxPcrInfo.frameSystemTime;
- return 0;
-}
-
-long mediasync_ins_set_audiomute(s32 sSyncInsId, int mute_flag) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mute_flag = mute_flag;
-
- return 0;
-}
-
-long mediasync_ins_get_audiomute(s32 sSyncInsId, int* mute_flag) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *mute_flag = pInstance->mute_flag;
- return 0;
-}
-
-long mediasync_ins_set_audioinfo(s32 sSyncInsId, mediasync_audioinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mAudioInfo.cacheDuration = info.cacheDuration;
- pInstance->mAudioInfo.cacheSize = info.cacheSize;
- return 0;
-}
-
-long mediasync_ins_get_audioinfo(s32 sSyncInsId, mediasync_audioinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->cacheDuration = pInstance->mAudioInfo.cacheDuration;
- info->cacheDuration = pInstance->mAudioInfo.cacheDuration;
- return 0;
-}
-
-long mediasync_ins_set_videoinfo(s32 sSyncInsId, mediasync_videoinfo info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mVideoInfo.cacheDuration = info.cacheDuration;
- pInstance->mVideoInfo.cacheSize = info.cacheSize;
- pInstance->mVideoInfo.specialSizeCount = info.specialSizeCount;
- return 0;
-
-}
-
-long mediasync_ins_get_videoinfo(s32 sSyncInsId, mediasync_videoinfo* info) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- info->cacheDuration = pInstance->mVideoInfo.cacheDuration;
- info->cacheSize = pInstance->mVideoInfo.cacheSize;
- info->specialSizeCount = pInstance->mVideoInfo.specialSizeCount;
- return 0;
-}
-
-long mediasync_ins_set_avsyncstate(s32 sSyncInsId, s32 state) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSyncInfo.state = state;
- return 0;
-}
-
-long mediasync_ins_get_avsyncstate(s32 sSyncInsId, s32* state) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *state = pInstance->mSyncInfo.state;
- return 0;
-}
-
-long mediasync_ins_set_startthreshold(s32 sSyncInsId, s32 threshold) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mStartThreshold = threshold;
- return 0;
-}
-
-long mediasync_ins_get_startthreshold(s32 sSyncInsId, s32* threshold) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *threshold = pInstance->mStartThreshold;
- return 0;
-}
-
-long mediasync_ins_set_ptsadjust(s32 sSyncInsId, s32 adujstpts) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mPtsAdjust = adujstpts;
- return 0;
-}
-
-long mediasync_ins_get_ptsadjust(s32 sSyncInsId, s32* adujstpts) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *adujstpts = pInstance->mPtsAdjust;
- return 0;
-}
-
-long mediasync_ins_set_videoworkmode(s32 sSyncInsId, s64 mode) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mVideoWorkMode = mode;
- return 0;
-}
-
-long mediasync_ins_get_videoworkmode(s32 sSyncInsId, s64* mode) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *mode = pInstance->mVideoWorkMode;
- return 0;
-}
-
-long mediasync_ins_set_fccenable(s32 sSyncInsId, s64 enable) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mFccEnable = enable;
- return 0;
-}
-
-long mediasync_ins_get_fccenable(s32 sSyncInsId, s64* enable) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *enable = pInstance->mFccEnable;
- return 0;
-}
-
-
-long mediasync_ins_set_source_type(s32 sSyncInsId, aml_Source_Type sourceType) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mSourceType = sourceType;
- return 0;
-}
-
-long mediasync_ins_get_source_type(s32 sSyncInsId, aml_Source_Type* sourceType) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- *sourceType = pInstance->mSourceType;
- return 0;
-}
-
-long mediasync_ins_set_start_media_time(s32 sSyncInsId, s64 startime) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- pInstance->mStartMediaTime = startime;
- return 0;
-}
-
-long mediasync_ins_get_start_media_time(s32 sSyncInsId, s64* starttime) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- *starttime = pInstance->mStartMediaTime;
- return 0;
-}
-
-long mediasync_ins_set_audioformat(s32 sSyncInsId, mediasync_audio_format format) {
-
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- pInstance->mAudioFormat.channels = format.channels;
- pInstance->mAudioFormat.datawidth = format.datawidth;
- pInstance->mAudioFormat.format = format.format;
- pInstance->mAudioFormat.samplerate = format.samplerate;
- return 0;
-
-}
-
-long mediasync_ins_get_audioformat(s32 sSyncInsId, mediasync_audio_format* format) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- format->channels = pInstance->mAudioFormat.channels;
- format->datawidth = pInstance->mAudioFormat.datawidth;
- format->format = pInstance->mAudioFormat.format;
- format->samplerate = pInstance->mAudioFormat.samplerate;
-
- return 0;
-}
-
-long mediasync_ins_set_pauseresume(s32 sSyncInsId, int flag) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
-
- pInstance->mPauseResumeFlag = flag;
-
- return 0;
-}
-
-long mediasync_ins_get_pauseresume(s32 sSyncInsId, int* flag) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
-
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- *flag = pInstance->mPauseResumeFlag;
- return 0;
-}
-long mediasync_ins_set_pcrslope(s32 sSyncInsId, mediasync_speed pcrslope) {
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- pInstance->mPcrSlope.mNumerator = pcrslope.mNumerator;
- pInstance->mPcrSlope.mDenominator = pcrslope.mDenominator;
- return 0;
-}
-long mediasync_ins_get_pcrslope(s32 sSyncInsId, mediasync_speed *pcrslope){
- mediasync_ins* pInstance = NULL;
- s32 index = sSyncInsId;
- if (index < 0 || index >= MAX_INSTANCE_NUM)
- return -1;
- pInstance = vMediaSyncInsList[index];
- if (pInstance == NULL)
- return -1;
- pcrslope->mNumerator = pInstance->mPcrSlope.mNumerator;
- pcrslope->mDenominator = pInstance->mPcrSlope.mDenominator;
- return 0;
-}
diff --git a/drivers/media_sync/media_sync_core.h b/drivers/media_sync/media_sync_core.h
index 4e05e89..41b8910 100644
--- a/drivers/media_sync/media_sync_core.h
+++ b/drivers/media_sync/media_sync_core.h
@@ -21,74 +21,6 @@
u32 mDenominator;
}mediasync_speed;
-typedef enum {
- MEDIASYNC_INIT = 0,
- MEDIASYNC_AUDIO_ARRIVED,
- MEDIASYNC_VIDEO_ARRIVED,
- MEDIASYNC_AV_ARRIVED,
- MEDIASYNC_AV_SYNCED,
- MEDIASYNC_RUNNING,
- MEDIASYNC_LOST_SYNC,
- MEDIASYNC_EXIT,
-} avsync_state;
-
-typedef enum {
- UNKNOWN_CLOCK = 0,
- AUDIO_CLOCK,
- VIDEO_CLOCK,
- PCR_CLOCK,
- REF_CLOCK,
-} mediasync_clocktype;
-
-typedef struct frameinfo{
- int64_t framePts;
- int64_t frameSystemTime;
-}mediasync_frameinfo;
-
-typedef struct syncinfo {
- avsync_state state;
- mediasync_frameinfo firstAframeInfo;
- mediasync_frameinfo firstVframeInfo;
- mediasync_frameinfo firstDmxPcrInfo;
- mediasync_frameinfo refClockInfo;
- mediasync_frameinfo curAudioInfo;
- mediasync_frameinfo curVideoInfo;
- mediasync_frameinfo curDmxPcrInfo;
-}mediasync_syncinfo;
-
-typedef struct audioinfo{
- int cacheSize;
- int cacheDuration;
-}mediasync_audioinfo;
-
-typedef struct videoinfo{
- int cacheSize;
- int specialSizeCount;
- int cacheDuration;
-}mediasync_videoinfo;
-
-typedef struct audioforamt{
- int samplerate;
- int datawidth;
- int channels;
- int format;
-}mediasync_audio_format;
-
-typedef enum
-{
- TS_DEMOD = 0, // TS Data input from demod
- TS_MEMORY = 1, // TS Data input from memory
- ES_MEMORY = 2, // ES Data input from memory
-} aml_Source_Type;
-
-typedef enum {
- CLOCK_PROVIDER_NONE = 0,
- CLOCK_PROVIDER_DISCONTINUE,
- CLOCK_PROVIDER_NORMAL,
- CLOCK_PROVIDER_LOST,
- CLOCK_PROVIDER_RECOVERING,
-} mediasync_clockprovider_state;
-
typedef struct instance{
s32 mSyncInsId;
s32 mDemuxId;
@@ -100,27 +32,9 @@
s64 mLastRealTime;
s64 mLastMediaTime;
s64 mTrackMediaTime;
- s64 mStartMediaTime;
mediasync_speed mSpeed;
- mediasync_speed mPcrSlope;
- s32 mSyncModeChange;
- s64 mUpdateTimeThreshold;
-
- int mHasAudio;
- int mHasVideo;
- int mute_flag;
- int mStartThreshold;
- int mPtsAdjust;
- int mVideoWorkMode;
- int mFccEnable;
- int mPauseResumeFlag;
- mediasync_clocktype mSourceClockType;
- mediasync_clockprovider_state mSourceClockState;
- mediasync_audioinfo mAudioInfo;
- mediasync_videoinfo mVideoInfo;
- mediasync_syncinfo mSyncInfo;
- aml_Source_Type mSourceType;
- mediasync_audio_format mAudioFormat;
+ u64 last_system;
+ u64 last_pcr;
}mediasync_ins;
long mediasync_ins_alloc(s32 sDemuxId,
@@ -143,66 +57,13 @@
long mediasync_ins_get_syncmode(s32 sSyncInsId, s32 *sSyncMode);
long mediasync_ins_get_mediatime_speed(s32 sSyncInsId, mediasync_speed *fpSpeed);
long mediasync_ins_get_anchor_time(s32 sSyncInsId,
- s64* lpMediaTime,
- s64* lpSTCTime,
- s64* lpSystemTime);
+ s64* lpMediaTime,
+ s64* lpSTCTime,
+ s64* lpSystemTime);
long mediasync_ins_get_systemtime(s32 sSyncInsId,
s64* lpSTC,
s64* lpSystemTime);
long mediasync_ins_get_nextvsync_systemtime(s32 sSyncInsId, s64* lpSystemTime);
-long mediasync_ins_set_updatetime_threshold(s32 sSyncInsId, s64 lTimeThreshold);
-long mediasync_ins_get_updatetime_threshold(s32 sSyncInsId, s64* lpTimeThreshold);
-
-long mediasync_ins_init_syncinfo(s32 sSyncInsId);
-long mediasync_ins_set_clocktype(s32 sSyncInsId, mediasync_clocktype type);
-long mediasync_ins_get_clocktype(s32 sSyncInsId, mediasync_clocktype* type);
-long mediasync_ins_set_avsyncstate(s32 sSyncInsId, s32 state);
-long mediasync_ins_get_avsyncstate(s32 sSyncInsId, s32* state);
-long mediasync_ins_set_hasaudio(s32 sSyncInsId, int hasaudio);
-long mediasync_ins_get_hasaudio(s32 sSyncInsId, int* hasaudio);
-long mediasync_ins_set_hasvideo(s32 sSyncInsId, int hasvideo);
-long mediasync_ins_get_hasvideo(s32 sSyncInsId, int* hasvideo);
-long mediasync_ins_set_audioinfo(s32 sSyncInsId, mediasync_audioinfo info);
-long mediasync_ins_get_audioinfo(s32 sSyncInsId, mediasync_audioinfo* info);
-long mediasync_ins_set_videoinfo(s32 sSyncInsId, mediasync_videoinfo info);
-long mediasync_ins_set_audiomute(s32 sSyncInsId, int mute_flag);
-long mediasync_ins_get_audiomute(s32 sSyncInsId, int* mute_flag);
-long mediasync_ins_get_videoinfo(s32 sSyncInsId, mediasync_videoinfo* info);
-long mediasync_ins_set_firstaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_firstaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_firstvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_firstvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_firstdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_firstdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_refclockinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_refclockinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_curaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_curaudioframeinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_curvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_curvideoframeinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_curdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo info);
-long mediasync_ins_get_curdmxpcrinfo(s32 sSyncInsId, mediasync_frameinfo* info);
-long mediasync_ins_set_clockstate(s32 sSyncInsId, mediasync_clockprovider_state state);
-long mediasync_ins_get_clockstate(s32 sSyncInsId, mediasync_clockprovider_state* state);
-long mediasync_ins_set_startthreshold(s32 sSyncInsId, s32 threshold);
-long mediasync_ins_get_startthreshold(s32 sSyncInsId, s32* threshold);
-long mediasync_ins_set_ptsadjust(s32 sSyncInsId, s32 adujstpts);
-long mediasync_ins_get_ptsadjust(s32 sSyncInsId, s32* adujstpts);
-long mediasync_ins_set_videoworkmode(s32 sSyncInsId, s64 mode);
-long mediasync_ins_get_videoworkmode(s32 sSyncInsId, s64* mode);
-long mediasync_ins_set_fccenable(s32 sSyncInsId, s64 enable);
-long mediasync_ins_get_fccenable(s32 sSyncInsId, s64* enable);
-long mediasync_ins_set_source_type(s32 sSyncInsId, aml_Source_Type sourceType);
-long mediasync_ins_get_source_type(s32 sSyncInsId, aml_Source_Type* sourceType);
-long mediasync_ins_set_start_media_time(s32 sSyncInsId, s64 startime);
-long mediasync_ins_get_start_media_time(s32 sSyncInsId, s64* starttime);
-long mediasync_ins_set_audioformat(s32 sSyncInsId, mediasync_audio_format format);
-long mediasync_ins_get_audioformat(s32 sSyncInsId, mediasync_audio_format* format);
-long mediasync_ins_set_pauseresume(s32 sSyncInsId, int flag);
-long mediasync_ins_get_pauseresume(s32 sSyncInsId, int* flag);
-long mediasync_ins_set_pcrslope(s32 sSyncInsId, mediasync_speed pcrslope);
-long mediasync_ins_get_pcrslope(s32 sSyncInsId, mediasync_speed *pcrslope);
-
-
-
#endif
+
+
diff --git a/drivers/media_sync/media_sync_dev.c b/drivers/media_sync/media_sync_dev.c
index 0e0df27..af0f786 100644
--- a/drivers/media_sync/media_sync_dev.c
+++ b/drivers/media_sync/media_sync_dev.c
@@ -91,38 +91,18 @@
{
long ret = 0;
mediasync_speed SyncSpeed = {0};
- mediasync_speed PcrSlope = {0};
- mediasync_frameinfo FrameInfo = {-1, -1};
- mediasync_audioinfo AudioInfo = {0, 0};
- mediasync_videoinfo VideoInfo = {0, 0};
- mediasync_audio_format AudioFormat;
- mediasync_clocktype ClockType = UNKNOWN_CLOCK;
- mediasync_clockprovider_state state;
s32 SyncInsId = -1;
s32 SyncPaused = 0;
s32 SyncMode = -1;
- s32 SyncState = 0;
s64 NextVsyncSystemTime = 0;
s64 TrackMediaTime = 0;
- int HasAudio = -1;
- int HasVideo = -1;
- s32 StartThreshold = 0;
- s32 PtsAdjust = 0;
- s64 VideoWorkMode = 0;
- s64 FccEnable = 0;
- int mute_flag = 0;
- int PauseResumeFlag = 0;
+
mediasync_priv_s *priv = (mediasync_priv_s *)file->private_data;
mediasync_ins *SyncIns = NULL;
mediasync_alloc_para parm = {0};
mediasync_arthortime_para ArthorTime = {0};
mediasync_updatetime_para UpdateTime = {0};
mediasync_systime_para SystemTime = {0};
- aml_Source_Type sourceType = TS_DEMOD;
- s64 UpdateTimeThreshold = 0;
- s64 StartMediaTime = -1;
-
-
switch (cmd) {
case MEDIASYNC_IOC_INSTANCE_ALLOC:
if (copy_from_user ((void *)&parm,
@@ -160,7 +140,7 @@
case MEDIASYNC_IOC_INSTANCE_BINDER:
if (copy_from_user((void *)&SyncInsId,
(void *)arg,
- sizeof(SyncInsId))) {
+ sizeof(parm))) {
return -EFAULT;
}
ret = mediasync_ins_binder(SyncInsId, &SyncIns);
@@ -193,9 +173,9 @@
return -EFAULT;
}
ret = mediasync_ins_get_anchor_time(priv->mSyncInsId,
- &(ArthorTime.mMediaTimeUs),
- &(ArthorTime.mStcTimeUs),
- &(ArthorTime.mSystemTimeUs));
+ &(ArthorTime.mMediaTimeUs),
+ &(ArthorTime.mStcTimeUs),
+ &(ArthorTime.mSystemTimeUs));
if (ret == 0) {
if (copy_to_user((void *)arg,
&ArthorTime,
@@ -212,8 +192,8 @@
}
ret = mediasync_ins_get_systemtime(priv->mSyncInsId,
- &(SystemTime.mStcUs),
- &(SystemTime.mSystemTimeUs));
+ &(SystemTime.mStcUs),
+ &(SystemTime.mSystemTimeUs));
if (ret == 0) {
if (copy_to_user((void *)arg,
&SystemTime,
@@ -333,680 +313,6 @@
}
break;
- case MEDIASYNC_IOC_SET_FIRST_AFRAME_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_firstaudioframeinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_FIRST_AFRAME_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_firstaudioframeinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_FIRST_VFRAME_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_firstvideoframeinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_FIRST_VFRAME_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_firstvideoframeinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
-
- case MEDIASYNC_IOC_SET_FIRST_DMXPCR_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_firstdmxpcrinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_FIRST_DMXPCR_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_firstdmxpcrinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_REFCLOCK_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_refclockinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_REFCLOCK_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_refclockinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_CUR_AFRAME_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_curaudioframeinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_CUR_AFRAME_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_curaudioframeinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_CUR_VFRAME_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_curvideoframeinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_CUR_VFRAME_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_curvideoframeinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_CUR_DMXPCR_INFO:
- if (copy_from_user((void *)&FrameInfo,
- (void *)arg,
- sizeof(FrameInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_curdmxpcrinfo(priv->mSyncInsId,
- FrameInfo);
- break;
-
- case MEDIASYNC_IOC_GET_CUR_DMXPCR_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_curdmxpcrinfo(priv->mSyncInsId,
- &FrameInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FrameInfo,
- sizeof(FrameInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_AUDIO_INFO:
- if (copy_from_user((void *)&AudioInfo,
- (void *)arg,
- sizeof(AudioInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_audioinfo(priv->mSyncInsId,
- AudioInfo);
- break;
-
- case MEDIASYNC_IOC_GET_AUDIO_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_audioinfo(priv->mSyncInsId,
- &AudioInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &AudioInfo,
- sizeof(AudioInfo)))
- return -EFAULT;
- }
- break;
-
-
- case MEDIASYNC_IOC_SET_AUDIO_MUTEFLAG:
- if (copy_from_user((void *)&mute_flag,
- (void *)arg,
- sizeof(mute_flag))) {
- return -EFAULT;
- }
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_audiomute(priv->mSyncInsId,
- mute_flag);
- break;
-
- case MEDIASYNC_IOC_GET_AUDIO_MUTEFLAG:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_audiomute(priv->mSyncInsId,
- &mute_flag);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &mute_flag,
- sizeof(mute_flag)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_VIDEO_INFO:
- if (copy_from_user((void *)&VideoInfo,
- (void *)arg,
- sizeof(VideoInfo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_videoinfo(priv->mSyncInsId,
- VideoInfo);
- break;
-
- case MEDIASYNC_IOC_GET_VIDEO_INFO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_videoinfo(priv->mSyncInsId,
- &VideoInfo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &VideoInfo,
- sizeof(VideoInfo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_HASAUDIO:
- if (copy_from_user((void *)&HasAudio,
- (void *)arg,
- sizeof(HasAudio)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_hasaudio(priv->mSyncInsId,
- HasAudio);
- break;
-
- case MEDIASYNC_IOC_GET_HASAUDIO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_hasaudio(priv->mSyncInsId,
- &HasAudio);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &HasAudio,
- sizeof(HasAudio)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_HASVIDEO:
- if (copy_from_user((void *)&HasVideo,
- (void *)arg,
- sizeof(HasVideo)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_hasvideo(priv->mSyncInsId,
- HasVideo);
- break;
-
- case MEDIASYNC_IOC_GET_HASVIDEO:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_hasvideo(priv->mSyncInsId,
- &HasVideo);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &HasVideo,
- sizeof(HasVideo)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_AVSTATE:
- if (copy_from_user((void *)&SyncState,
- (void *)arg,
- sizeof(SyncState)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_avsyncstate(priv->mSyncInsId,
- SyncState);
- break;
-
- case MEDIASYNC_IOC_GET_AVSTATE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_avsyncstate(priv->mSyncInsId,
- &SyncState);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &SyncState,
- sizeof(SyncState)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_CLOCKTYPE:
- if (copy_from_user((void *)&ClockType,
- (void *)arg,
- sizeof(ClockType)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_clocktype(priv->mSyncInsId,
- ClockType);
- break;
-
- case MEDIASYNC_IOC_GET_CLOCKTYPE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_clocktype(priv->mSyncInsId,
- &ClockType);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &ClockType,
- sizeof(ClockType)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_CLOCKSTATE:
- if (copy_from_user((void *)&state,
- (void *)arg,
- sizeof(state)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_clockstate(priv->mSyncInsId,
- state);
- break;
-
- case MEDIASYNC_IOC_GET_CLOCKSTATE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_clockstate(priv->mSyncInsId,
- &state);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &state,
- sizeof(state)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_STARTTHRESHOLD:
- if (copy_from_user((void *)&StartThreshold,
- (void *)arg,
- sizeof(StartThreshold)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_startthreshold(priv->mSyncInsId,
- StartThreshold);
- break;
-
- case MEDIASYNC_IOC_GET_STARTTHRESHOLD:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_startthreshold(priv->mSyncInsId,
- &StartThreshold);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &StartThreshold,
- sizeof(StartThreshold)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_PTSADJUST:
- if (copy_from_user((void *)&PtsAdjust,
- (void *)arg,
- sizeof(PtsAdjust)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_ptsadjust(priv->mSyncInsId,
- PtsAdjust);
- break;
-
- case MEDIASYNC_IOC_GET_PTSADJUST:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_ptsadjust(priv->mSyncInsId,
- &PtsAdjust);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &PtsAdjust,
- sizeof(PtsAdjust)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_VIDEOWORKMODE:
- if (copy_from_user((void *)&VideoWorkMode,
- (void *)arg,
- sizeof(VideoWorkMode)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_videoworkmode(priv->mSyncInsId,
- VideoWorkMode);
- break;
-
- case MEDIASYNC_IOC_GET_VIDEOWORKMODE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_videoworkmode(priv->mSyncInsId,
- &VideoWorkMode);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &VideoWorkMode,
- sizeof(VideoWorkMode)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_FCCENABLE:
- if (copy_from_user((void *)&FccEnable,
- (void *)arg,
- sizeof(FccEnable)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_fccenable(priv->mSyncInsId,
- FccEnable);
- break;
-
- case MEDIASYNC_IOC_GET_FCCENABLE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_fccenable(priv->mSyncInsId,
- &FccEnable);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &FccEnable,
- sizeof(FccEnable)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_SOURCE_TYPE:
- if (copy_from_user((void *)&sourceType,
- (void *)arg,
- sizeof(sourceType)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_source_type(priv->mSyncInsId,
- sourceType);
- break;
-
- case MEDIASYNC_IOC_GET_SOURCE_TYPE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_source_type(priv->mSyncInsId,
- &sourceType);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &sourceType,
- sizeof(sourceType)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_UPDATETIME_THRESHOLD:
- if (copy_from_user((void *)&UpdateTimeThreshold,
- (void *)arg,
- sizeof(UpdateTimeThreshold)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_updatetime_threshold(priv->mSyncInsId,
- UpdateTimeThreshold);
- break;
-
- case MEDIASYNC_IOC_GET_UPDATETIME_THRESHOLD:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_updatetime_threshold(priv->mSyncInsId,
- &UpdateTimeThreshold);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &UpdateTimeThreshold,
- sizeof(UpdateTimeThreshold)))
- return -EFAULT;
- }
- break;
- case MEDIASYNC_IOC_SET_START_MEDIA_TIME:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- if (copy_from_user((void *)&StartMediaTime,
- (void *)arg,
- sizeof(StartMediaTime)))
- return -EFAULT;
- ret = mediasync_ins_set_start_media_time(priv->mSyncInsId, StartMediaTime);
- break;
-
- case MEDIASYNC_IOC_GET_START_MEDIA_TIME:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_start_media_time(priv->mSyncInsId, &StartMediaTime);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &StartMediaTime,
- sizeof(StartMediaTime)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_AUDIO_FORMAT:
- if (copy_from_user((void *)&AudioFormat,
- (void *)arg,
- sizeof(AudioFormat)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_audioformat(priv->mSyncInsId,
- AudioFormat);
- break;
-
- case MEDIASYNC_IOC_GET_AUDIO_FORMAT:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_audioformat(priv->mSyncInsId,
- &AudioFormat);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &AudioFormat,
- sizeof(AudioFormat)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_PAUSERESUME_FLAG:
- if (copy_from_user((void *)&PauseResumeFlag,
- (void *)arg,
- sizeof(PauseResumeFlag)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_pauseresume(priv->mSyncInsId,
- PauseResumeFlag);
- break;
-
- case MEDIASYNC_IOC_GET_PAUSERESUME_FLAG:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_pauseresume(priv->mSyncInsId,
- &PauseResumeFlag);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &PauseResumeFlag,
- sizeof(PauseResumeFlag)))
- return -EFAULT;
- }
- break;
-
- case MEDIASYNC_IOC_SET_PCRSLOPE:
- if (copy_from_user((void *)&PcrSlope,
- (void *)arg,
- sizeof(PcrSlope)))
- return -EFAULT;
-
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_set_pcrslope(priv->mSyncInsId,
- PcrSlope);
- break;
-
- case MEDIASYNC_IOC_GET_PCRSLOPE:
- if (priv->mSyncIns == NULL)
- return -EFAULT;
-
- ret = mediasync_ins_get_pcrslope(priv->mSyncInsId,
- &PcrSlope);
- if (ret == 0) {
- if (copy_to_user((void *)arg,
- &PcrSlope,
- sizeof(PcrSlope)))
- return -EFAULT;
- }
- break;
-
default:
pr_info("invalid cmd:%d\n", cmd);
break;
@@ -1034,57 +340,6 @@
case MEDIASYNC_IOC_SET_SYNCMODE:
case MEDIASYNC_IOC_GET_SYNCMODE:
case MEDIASYNC_IOC_GET_TRACKMEDIATIME:
- case MEDIASYNC_IOC_SET_FIRST_AFRAME_INFO:
- case MEDIASYNC_IOC_GET_FIRST_AFRAME_INFO:
- case MEDIASYNC_IOC_SET_FIRST_VFRAME_INFO:
- case MEDIASYNC_IOC_GET_FIRST_VFRAME_INFO:
- case MEDIASYNC_IOC_SET_FIRST_DMXPCR_INFO:
- case MEDIASYNC_IOC_GET_FIRST_DMXPCR_INFO:
- case MEDIASYNC_IOC_SET_REFCLOCK_INFO:
- case MEDIASYNC_IOC_GET_REFCLOCK_INFO:
- case MEDIASYNC_IOC_SET_CUR_AFRAME_INFO:
- case MEDIASYNC_IOC_GET_CUR_AFRAME_INFO:
- case MEDIASYNC_IOC_SET_CUR_VFRAME_INFO:
- case MEDIASYNC_IOC_GET_CUR_VFRAME_INFO:
- case MEDIASYNC_IOC_SET_CUR_DMXPCR_INFO:
- case MEDIASYNC_IOC_GET_CUR_DMXPCR_INFO:
- case MEDIASYNC_IOC_SET_AUDIO_INFO:
- case MEDIASYNC_IOC_GET_AUDIO_INFO:
- case MEDIASYNC_IOC_SET_VIDEO_INFO:
- case MEDIASYNC_IOC_GET_VIDEO_INFO:
- case MEDIASYNC_IOC_SET_AVSTATE:
- case MEDIASYNC_IOC_GET_AVSTATE:
- case MEDIASYNC_IOC_SET_HASAUDIO:
- case MEDIASYNC_IOC_GET_HASAUDIO:
- case MEDIASYNC_IOC_SET_HASVIDEO:
- case MEDIASYNC_IOC_GET_HASVIDEO:
- case MEDIASYNC_IOC_GET_CLOCKTYPE:
- case MEDIASYNC_IOC_SET_CLOCKTYPE:
- case MEDIASYNC_IOC_GET_CLOCKSTATE:
- case MEDIASYNC_IOC_SET_CLOCKSTATE:
- case MEDIASYNC_IOC_SET_STARTTHRESHOLD:
- case MEDIASYNC_IOC_GET_STARTTHRESHOLD:
- case MEDIASYNC_IOC_SET_PTSADJUST:
- case MEDIASYNC_IOC_GET_PTSADJUST:
- case MEDIASYNC_IOC_SET_VIDEOWORKMODE:
- case MEDIASYNC_IOC_GET_VIDEOWORKMODE:
- case MEDIASYNC_IOC_SET_FCCENABLE:
- case MEDIASYNC_IOC_GET_FCCENABLE:
- case MEDIASYNC_IOC_SET_AUDIO_MUTEFLAG:
- case MEDIASYNC_IOC_GET_AUDIO_MUTEFLAG:
- case MEDIASYNC_IOC_SET_SOURCE_TYPE:
- case MEDIASYNC_IOC_GET_SOURCE_TYPE:
- case MEDIASYNC_IOC_SET_UPDATETIME_THRESHOLD:
- case MEDIASYNC_IOC_GET_UPDATETIME_THRESHOLD:
- case MEDIASYNC_IOC_SET_START_MEDIA_TIME:
- case MEDIASYNC_IOC_GET_START_MEDIA_TIME:
- case MEDIASYNC_IOC_SET_AUDIO_FORMAT:
- case MEDIASYNC_IOC_GET_AUDIO_FORMAT:
- case MEDIASYNC_IOC_SET_PAUSERESUME_FLAG:
- case MEDIASYNC_IOC_GET_PAUSERESUME_FLAG:
- case MEDIASYNC_IOC_SET_PCRSLOPE:
- case MEDIASYNC_IOC_GET_PCRSLOPE:
-
return mediasync_ioctl(file, cmd, arg);
default:
return -EINVAL;
@@ -1103,15 +358,13 @@
#endif
};
-static struct attribute *mediasync_class_attrs[] = {
- NULL
+static struct class_attribute mediasync_class_attrs[] = {
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(mediasync_class);
-
static struct class mediasync_class = {
.name = "mediasync",
- .class_groups = mediasync_class_groups,
+ .class_attrs = mediasync_class_attrs,
};
static int __init mediasync_module_init(void)
diff --git a/drivers/media_sync/media_sync_dev.h b/drivers/media_sync/media_sync_dev.h
index 52c28e9..3e0c147 100644
--- a/drivers/media_sync/media_sync_dev.h
+++ b/drivers/media_sync/media_sync_dev.h
@@ -18,55 +18,4 @@
#define MEDIASYNC_IOC_GET_SYNCMODE _IOW(MEDIASYNC_IOC_MAGIC, 0x0D, int)
#define MEDIASYNC_IOC_GET_TRACKMEDIATIME _IOW(MEDIASYNC_IOC_MAGIC, 0x0E, int)
-#define MEDIASYNC_IOC_SET_FIRST_AFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x0F, int)
-#define MEDIASYNC_IOC_GET_FIRST_AFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x10, int)
-#define MEDIASYNC_IOC_SET_FIRST_VFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x11, int)
-#define MEDIASYNC_IOC_GET_FIRST_VFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x12, int)
-#define MEDIASYNC_IOC_SET_FIRST_DMXPCR_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x13, int)
-#define MEDIASYNC_IOC_GET_FIRST_DMXPCR_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x14, int)
-#define MEDIASYNC_IOC_SET_REFCLOCK_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x15, int)
-#define MEDIASYNC_IOC_GET_REFCLOCK_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x16, int)
-#define MEDIASYNC_IOC_SET_CUR_AFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x17, int)
-#define MEDIASYNC_IOC_GET_CUR_AFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x18, int)
-#define MEDIASYNC_IOC_SET_CUR_VFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x19, int)
-#define MEDIASYNC_IOC_GET_CUR_VFRAME_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1A, int)
-#define MEDIASYNC_IOC_SET_CUR_DMXPCR_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1B, int)
-#define MEDIASYNC_IOC_GET_CUR_DMXPCR_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1C, int)
-#define MEDIASYNC_IOC_SET_AUDIO_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1D, int)
-#define MEDIASYNC_IOC_GET_AUDIO_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1E, int)
-#define MEDIASYNC_IOC_SET_VIDEO_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x1F, int)
-#define MEDIASYNC_IOC_GET_VIDEO_INFO _IOW(MEDIASYNC_IOC_MAGIC, 0x20, int)
-#define MEDIASYNC_IOC_SET_AVSTATE _IOW(MEDIASYNC_IOC_MAGIC, 0x21, int)
-#define MEDIASYNC_IOC_GET_AVSTATE _IOW(MEDIASYNC_IOC_MAGIC, 0x22, int)
-#define MEDIASYNC_IOC_SET_HASAUDIO _IOW(MEDIASYNC_IOC_MAGIC, 0x23, int)
-#define MEDIASYNC_IOC_GET_HASAUDIO _IOW(MEDIASYNC_IOC_MAGIC, 0x24, int)
-#define MEDIASYNC_IOC_SET_HASVIDEO _IOW(MEDIASYNC_IOC_MAGIC, 0x25, int)
-#define MEDIASYNC_IOC_GET_HASVIDEO _IOW(MEDIASYNC_IOC_MAGIC, 0x26, int)
-#define MEDIASYNC_IOC_SET_CLOCKTYPE _IOW(MEDIASYNC_IOC_MAGIC, 0x27, int)
-#define MEDIASYNC_IOC_GET_CLOCKTYPE _IOW(MEDIASYNC_IOC_MAGIC, 0x28, int)
-#define MEDIASYNC_IOC_SET_CLOCKSTATE _IOW(MEDIASYNC_IOC_MAGIC, 0x29, int)
-#define MEDIASYNC_IOC_GET_CLOCKSTATE _IOW(MEDIASYNC_IOC_MAGIC, 0x2A, int)
-#define MEDIASYNC_IOC_SET_STARTTHRESHOLD _IOW(MEDIASYNC_IOC_MAGIC, 0x2B, int)
-#define MEDIASYNC_IOC_GET_STARTTHRESHOLD _IOW(MEDIASYNC_IOC_MAGIC, 0x2C, int)
-#define MEDIASYNC_IOC_SET_PTSADJUST _IOW(MEDIASYNC_IOC_MAGIC, 0x2D, int)
-#define MEDIASYNC_IOC_GET_PTSADJUST _IOW(MEDIASYNC_IOC_MAGIC, 0x2E, int)
-#define MEDIASYNC_IOC_SET_VIDEOWORKMODE _IOW(MEDIASYNC_IOC_MAGIC, 0x2F, int)
-#define MEDIASYNC_IOC_GET_VIDEOWORKMODE _IOW(MEDIASYNC_IOC_MAGIC, 0x30, int)
-#define MEDIASYNC_IOC_SET_FCCENABLE _IOW(MEDIASYNC_IOC_MAGIC, 0x31, int)
-#define MEDIASYNC_IOC_GET_FCCENABLE _IOW(MEDIASYNC_IOC_MAGIC, 0x32, int)
-#define MEDIASYNC_IOC_SET_AUDIO_MUTEFLAG _IOW(MEDIASYNC_IOC_MAGIC, 0x33, int)
-#define MEDIASYNC_IOC_GET_AUDIO_MUTEFLAG _IOW(MEDIASYNC_IOC_MAGIC, 0x34, int)
-#define MEDIASYNC_IOC_SET_SOURCE_TYPE _IOW(MEDIASYNC_IOC_MAGIC, 0x35, int)
-#define MEDIASYNC_IOC_GET_SOURCE_TYPE _IOW(MEDIASYNC_IOC_MAGIC, 0x36, int)
-#define MEDIASYNC_IOC_SET_UPDATETIME_THRESHOLD _IOW(MEDIASYNC_IOC_MAGIC, 0x37, int)
-#define MEDIASYNC_IOC_GET_UPDATETIME_THRESHOLD _IOW(MEDIASYNC_IOC_MAGIC, 0x38, int)
-#define MEDIASYNC_IOC_SET_START_MEDIA_TIME _IOW(MEDIASYNC_IOC_MAGIC, 0x39, int)
-#define MEDIASYNC_IOC_GET_START_MEDIA_TIME _IOW(MEDIASYNC_IOC_MAGIC, 0x3A, int)
-#define MEDIASYNC_IOC_SET_AUDIO_FORMAT _IOW(MEDIASYNC_IOC_MAGIC, 0x3B, int)
-#define MEDIASYNC_IOC_GET_AUDIO_FORMAT _IOW(MEDIASYNC_IOC_MAGIC, 0x3C, int)
-#define MEDIASYNC_IOC_SET_PAUSERESUME_FLAG _IOW(MEDIASYNC_IOC_MAGIC, 0x3D, int)
-#define MEDIASYNC_IOC_GET_PAUSERESUME_FLAG _IOW(MEDIASYNC_IOC_MAGIC, 0x3E, int)
-#define MEDIASYNC_IOC_SET_PCRSLOPE _IOW(MEDIASYNC_IOC_MAGIC, 0x3F, int)
-#define MEDIASYNC_IOC_GET_PCRSLOPE _IOW(MEDIASYNC_IOC_MAGIC, 0x40, int)
-
#endif
diff --git a/drivers/stream_input/Makefile b/drivers/stream_input/Makefile
index 2e7d5d9..aa248ea 100644
--- a/drivers/stream_input/Makefile
+++ b/drivers/stream_input/Makefile
@@ -11,14 +11,14 @@
stream_input-objs += parser/tsdemux.o
stream_input-objs += parser/psparser.o
stream_input-objs += parser/rmparser.o
+stream_input-objs += parser/dvb_common.o
stream_input-objs += subtitle/subtitle.o
-stream_input-objs += parser/dvb_common.o
obj-$(CONFIG_AMLOGIC_DVB) += parser/hw_demux/
obj-$(CONFIG_AMLOGIC_DVB) += parser/dvb_ci/
ccflags-y += -I.
-ccflags-y += -I$(srctree)/include/media
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
#obj-y += tv_frontend/
# obj-y += box-frontend/avl6211/
diff --git a/drivers/stream_input/amports/adec.c b/drivers/stream_input/amports/adec.c
index 3ab5e5a..b6da9ea 100644
--- a/drivers/stream_input/amports/adec.c
+++ b/drivers/stream_input/amports/adec.c
@@ -19,7 +19,6 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
-#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uio_driver.h>
#include <linux/amlogic/media/utils/aformat.h>
@@ -141,29 +140,20 @@
return sprintf(buf, "%d\n", astream_dev->offset);
}
-static CLASS_ATTR_RO(format);
-static CLASS_ATTR_RO(samplerate);
-static CLASS_ATTR_RO(channum);
-static CLASS_ATTR_RO(datawidth);
-static CLASS_ATTR_RO(pts);
-static CLASS_ATTR_RO(addr_offset);
-
-static struct attribute *astream_class_attrs[] = {
- &class_attr_format.attr,
- &class_attr_samplerate.attr,
- &class_attr_channum.attr,
- &class_attr_datawidth.attr,
- &class_attr_pts.attr,
- &class_attr_addr_offset.attr,
- NULL
+static struct class_attribute astream_class_attrs[] = {
+ __ATTR_RO(format),
+ __ATTR_RO(samplerate),
+ __ATTR_RO(channum),
+ __ATTR_RO(datawidth),
+ __ATTR_RO(pts),
+ __ATTR_RO(addr_offset),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(astream_class);
-
static struct class astream_class = {
- .name = "astream",
- .class_groups = astream_class_groups,
-};
+ .name = "astream",
+ .class_attrs = astream_class_attrs,
+ };
#if 1
#define IO_CBUS_PHY_BASE 0xc1100000ULL
@@ -351,24 +341,23 @@
goto err_2;
}
- if (AM_MESON_CPU_MAJOR_ID_TXL < get_cpu_major_id()) {
- struct resource *res_mem;
- struct platform_device *pdev;
-
- node = of_find_node_by_path("/codec_io");
+ if (AM_MESON_CPU_MAJOR_ID_TXL < get_cpu_major_id()
+ && MESON_CPU_MAJOR_ID_GXLX != get_cpu_type()) {
+ node = of_find_node_by_path("/codec_io/io_cbus_base");
if (!node) {
pr_info("No io_cbus_base node found.");
goto err_1;
}
- pdev = of_find_device_by_node(node);
- res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cbus");
- if (!res_mem) {
+#ifdef CONFIG_ARM64_A32
+ r = of_property_read_u32_index(node, "reg", 0, &cbus_base);
+#else
+ r = of_property_read_u32_index(node, "reg", 1, &cbus_base);
+#endif
+ if (r) {
pr_info("No find node.\n");
goto err_1;
}
- cbus_base = res_mem->start;
- of_node_put(node);
/*need to offset -0x100 in txlx.*/
astream_dev->offset = -0x100;
@@ -424,4 +413,3 @@
class_unregister(&astream_class);
}
}
-
diff --git a/drivers/stream_input/amports/amports_priv.h b/drivers/stream_input/amports/amports_priv.h
index ffead01..296b94a 100644
--- a/drivers/stream_input/amports/amports_priv.h
+++ b/drivers/stream_input/amports/amports_priv.h
@@ -51,4 +51,6 @@
struct device *amports_get_dma_device(void);
struct device *get_codec_cma_device(void);
+void amstream_wakeup_fcc_poll(struct vdec_s *vdec);
+
#endif
diff --git a/drivers/stream_input/amports/amstream.c b/drivers/stream_input/amports/amstream.c
index 3b217f2..a089a6b 100644
--- a/drivers/stream_input/amports/amstream.c
+++ b/drivers/stream_input/amports/amstream.c
@@ -24,20 +24,27 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
-#include <uapi/linux/major.h>
+#include <linux/amlogic/major.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+
+#include <linux/amlogic/media/video_sink/video.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/amlogic/media/utils/vformat.h>
#include <linux/amlogic/media/utils/aformat.h>
+
+#include <linux/amlogic/media/video_sink/video.h>
#include <linux/amlogic/media/frame_sync/tsync.h>
#include <linux/amlogic/media/frame_sync/ptsserv.h>
#include <linux/amlogic/media/frame_sync/timestamp.h>
+
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/io.h>
+/* #include <mach/am_regs.h> */
+
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/poll.h>
@@ -77,7 +84,6 @@
#include "../../common/chips/decoder_cpu_ver_info.h"
#include "../subtitle/subtitle.h"
#include "stream_buffer_base.h"
-#include "../../frame_provider/decoder/utils/vdec_feature.h"
//#define G12A_BRINGUP_DEBUG
@@ -120,7 +126,6 @@
/* #define DATA_DEBUG */
static int use_bufferlevelx10000 = 10000;
static int reset_canuse_buferlevel(int level);
-
static struct platform_device *amstream_pdev;
struct device *amports_get_dma_device(void)
{
@@ -185,11 +190,18 @@
static ssize_t amstream_mprm_write
(struct file *file, const char *buf, size_t count, loff_t *ppos);
#endif
+#ifdef VDEC_FCC_SUPPORT
+static unsigned int amstream_offset_poll
+(struct file *file, poll_table *wait_table);
+#endif
static const struct file_operations vbuf_fops = {
.owner = THIS_MODULE,
.open = amstream_open,
.release = amstream_release,
+#ifdef VDEC_FCC_SUPPORT
+ .poll = amstream_offset_poll,
+#endif
.write = amstream_vbuf_write,
.unlocked_ioctl = amstream_ioctl,
#ifdef CONFIG_COMPAT
@@ -312,10 +324,24 @@
static int userdata_length;
static wait_queue_head_t amstream_userdata_wait;
#define USERDATA_FIFO_NUM 1024
-static struct userdata_poc_info_t *userdata_poc_info;
+static struct userdata_poc_info_t userdata_poc_info[USERDATA_FIFO_NUM];
static int userdata_poc_ri, userdata_poc_wi;
static int last_read_wi;
+#define MAX_USERDATA_CHANNEL_NUM 9
+
+typedef struct {
+ struct mutex mutex;
+ wait_queue_head_t userdata_wait;
+ u32 video_id;
+ u32 set_id_flag;
+ u32 ready_flag[MAX_USERDATA_CHANNEL_NUM];
+ int used[MAX_USERDATA_CHANNEL_NUM];
+ u32 id[MAX_USERDATA_CHANNEL_NUM];
+} st_userdata;
+
+st_userdata userdata;
+
/*bit 1 force dual layer
*bit 2 force frame mode
*/
@@ -323,6 +349,25 @@
static DEFINE_MUTEX(userdata_mutex);
+#ifdef VDEC_FCC_SUPPORT
+static void amstream_fcc_get_one_slot(struct vdec_s *vdec);
+static void amstream_fcc_release_one_slot(struct vdec_s *vdec);
+
+#define MAX_FCC_CHANNEL_NUM 5
+
+typedef struct {
+ struct mutex mutex;
+ wait_queue_head_t offset_wait;
+ u32 offset[MAX_FCC_CHANNEL_NUM];
+ u32 offset_ready_flag[MAX_FCC_CHANNEL_NUM];
+ int used[MAX_FCC_CHANNEL_NUM];
+ int id[MAX_FCC_CHANNEL_NUM];
+} st_fcc;
+
+st_fcc fcc;
+static u32 fcc_enable;
+#endif
+
static struct stream_port_s ports[] = {
{
.name = "amstream_vbuf",
@@ -591,6 +636,10 @@
/*fallthrough*/
case 0: /*release all */
case 3:
+#ifdef VDEC_FCC_SUPPORT
+ if (fcc_enable & 0x1)
+ amstream_fcc_release_one_slot(vdec);
+#endif
if (vdec->slave)
slave = vdec->slave;
vdec_release(vdec);
@@ -610,6 +659,11 @@
struct stream_port_s *port = priv->port;
struct vdec_s *vdec = priv->vdec;
+ if (vdec == NULL) {
+ pr_err("vdec is null\n");
+ return -EPERM;
+ }
+
if ((vdec->port_flag & PORT_FLAG_VFORMAT) == 0) {
pr_err("vformat not set\n");
return -EPERM;
@@ -633,7 +687,7 @@
if (port->type & PORT_TYPE_FRAME) {
r = vdec_init(vdec,
(priv->vdec->sys_info->height *
- priv->vdec->sys_info->width) > 1920*1088, false);
+ priv->vdec->sys_info->width) > 1920*1088);
if (r < 0) {
pr_err("video_port_init %d, vdec_init failed\n",
__LINE__);
@@ -671,7 +725,7 @@
/* todo: set path based on port flag */
r = vdec_init(vdec,
(priv->vdec->sys_info->height *
- priv->vdec->sys_info->width) > 1920*1088, false);
+ priv->vdec->sys_info->width) > 1920*1088);
if (r < 0) {
pr_err("video_port_init %d, vdec_init failed\n", __LINE__);
@@ -681,19 +735,24 @@
if (vdec_dual(vdec)) {
r = vdec_init(vdec->slave,
(priv->vdec->sys_info->height *
- priv->vdec->sys_info->width) > 1920*1088, false);
+ priv->vdec->sys_info->width) > 1920*1088);
if (r < 0) {
pr_err("video_port_init %d, vdec_init failed\n", __LINE__);
goto err;
}
}
+#ifdef VDEC_FCC_SUPPORT
+ if (fcc_enable & 0x1)
+ amstream_fcc_get_one_slot(vdec);
+#endif
return 0;
err:
if (vdec->slave)
vdec_release(vdec->slave);
- if (vdec)
- vdec_release(vdec);
+
+ vdec_release(vdec);
+
priv->vdec = NULL;
return r;
@@ -1077,9 +1136,8 @@
psparser_release();
}
- if (port->type & PORT_TYPE_VIDEO) {
+ if (port->type & PORT_TYPE_VIDEO)
video_port_release(priv, pvbuf, 0);
- }
if (port->type & PORT_TYPE_AUDIO)
audio_port_release(port, pabuf, 0);
@@ -1381,6 +1439,7 @@
if (userdata_poc_wi == USERDATA_FIFO_NUM)
userdata_poc_wi = 0;
}
+EXPORT_SYMBOL(set_userdata_poc);
void init_userdata_fifo(void)
{
@@ -1452,40 +1511,33 @@
void amstream_wakeup_userdata_poll(struct vdec_s *vdec)
{
int i;
- st_userdata *userdata = get_vdec_userdata_ctx();
if (vdec == NULL) {
pr_info("Error, invalid vdec instance!\n");
return;
}
- mutex_lock(&userdata->mutex);
+ mutex_lock(&userdata.mutex);
for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
- if (userdata->set_id_flag && (userdata->id[i] == vdec->video_id)) {
- userdata->ready_flag[i] = 1;
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, wakeup! id = %d\n", __func__, vdec->video_id);
+ if (userdata.set_id_flag && (userdata.id[i] == vdec->video_id)) {
+ userdata.ready_flag[i] = 1;
break;
- } else if (!userdata->set_id_flag) {
- if (!userdata->used[0]) {
+ } else if (!userdata.set_id_flag) {
+ if (!userdata.used[0]) {
vdec->video_id = vdec->id;
- userdata->id[0] = vdec->id;
- userdata->used[0] = 1;
+ userdata.id[0] = vdec->id;
+ userdata.used[0] = 1;
}
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s[%d] userdata instance %d ready!\n",
- __func__, i, userdata->id[i]);
-
- userdata->ready_flag[i] = 1;
+ userdata.ready_flag[i] = 1;
break;
}
}
- mutex_unlock(&userdata->mutex);
+ mutex_unlock(&userdata.mutex);
- wake_up_interruptible(&userdata->userdata_wait);
+ wake_up_interruptible(&userdata.userdata_wait);
}
EXPORT_SYMBOL(amstream_wakeup_userdata_poll);
@@ -1494,46 +1546,182 @@
{
int fd_match = 0;
int i;
- st_userdata *userdata = get_vdec_userdata_ctx();
- poll_wait(file, &userdata->userdata_wait, wait_table);
- mutex_lock(&userdata->mutex);
+ poll_wait(file, &userdata.userdata_wait, wait_table);
+ mutex_lock(&userdata.mutex);
for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
- if (userdata->id[i] == userdata->video_id && userdata->ready_flag[i] == 1) {
+ if (userdata.id[i] == userdata.video_id && userdata.ready_flag[i] == 1) {
fd_match = 1;
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, success! id = %d\n", __func__, userdata->video_id);
break;
}
}
if (fd_match) {
- mutex_unlock(&userdata->mutex);
+ mutex_unlock(&userdata.mutex);
return POLLIN | POLLRDNORM;
}
- mutex_unlock(&userdata->mutex);
+ mutex_unlock(&userdata.mutex);
return 0;
}
static void amstream_userdata_init(void)
{
int i;
- st_userdata *userdata = get_vdec_userdata_ctx();
- init_waitqueue_head(&userdata->userdata_wait);
- mutex_init(&userdata->mutex);
- userdata->set_id_flag = 0;
+ init_waitqueue_head(&userdata.userdata_wait);
+ mutex_init(&userdata.mutex);
+ userdata.set_id_flag = 0;
for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
- userdata->ready_flag[i] = 0;
- userdata->id[i] = -1;
- userdata->used[i] = 0;
+ userdata.ready_flag[i] = 0;
+ userdata.id[i] = -1;
+ userdata.used[i] = 0;
}
return;
}
+static void amstream_userdata_deinit(void)
+{
+ int i;
+
+ mutex_lock(&userdata.mutex);
+
+ userdata.set_id_flag = 0;
+ for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
+ if (userdata.used[i] == 1) {
+ userdata.ready_flag[i] = 0;
+ userdata.id[i] = -1;
+ userdata.used[i] = 0;
+ }
+ }
+
+ mutex_unlock(&userdata.mutex);
+
+ return;
+}
+
+#ifdef VDEC_FCC_SUPPORT
+static unsigned int amstream_offset_poll(struct file *file,
+ poll_table *wait_table)
+{
+ struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
+ struct vdec_s *vdec = priv->vdec;
+ int fd_match = 0;
+ int i;
+
+ if ((fcc_enable & 1) == 0)
+ return 0;
+
+ poll_wait(file, &fcc.offset_wait, wait_table);
+ mutex_lock(&fcc.mutex);
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ if (fcc.id[i] == vdec->id && fcc.offset_ready_flag[i] == 1) {
+ fd_match = 1;
+ if (fcc_debug_enable())
+ pr_info("i = %d vdec->id = %d offset_ready_flag = %d\n",
+ i, vdec->id, fcc.offset_ready_flag[i]);
+ break;
+ }
+ }
+
+ if (fd_match) {
+ mutex_unlock(&fcc.mutex);
+ return POLLIN | POLLRDNORM;
+ }
+
+ mutex_unlock(&fcc.mutex);
+ return 0;
+}
+
+void amstream_wakeup_fcc_poll(struct vdec_s *vdec)
+{
+ int i;
+
+ if (vdec == NULL) {
+ pr_info("Error, invalid vdec instance!\n");
+ return;
+ }
+
+ mutex_lock(&fcc.mutex);
+
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ if (fcc.id[i] == vdec->id) {
+ fcc.offset[i] = vdec->stream_offset;
+ fcc.offset_ready_flag[i] = 1;
+ if (fcc_debug_enable())
+ pr_info("i = %d vdec->id = %d stream_offset = %d\n",
+ i, vdec->id, vdec->stream_offset);
+ break;
+ }
+ }
+
+ mutex_unlock(&fcc.mutex);
+
+ wake_up_interruptible(&fcc.offset_wait);
+}
+EXPORT_SYMBOL(amstream_wakeup_fcc_poll);
+
+static void amstream_fcc_init(void)
+{
+ int i;
+
+ init_waitqueue_head(&fcc.offset_wait);
+ mutex_init(&fcc.mutex);
+
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ fcc.offset_ready_flag[i] = 0;
+ fcc.id[i] = -1;
+ fcc.used[i] = 0;
+ }
+
+ return;
+}
+
+static void amstream_fcc_get_one_slot(struct vdec_s *vdec)
+{
+ int i;
+
+ mutex_lock(&fcc.mutex);
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ if (!fcc.used[i]) {
+ fcc.offset_ready_flag[i] = 0;
+ fcc.id[i] = vdec->id;
+ fcc.used[i] = 1;
+ break;
+ }
+ }
+ mutex_unlock(&fcc.mutex);
+
+ if (i >= MAX_FCC_CHANNEL_NUM)
+ pr_info("Error, no free fcc slot\n");
+
+ return;
+}
+
+static void amstream_fcc_release_one_slot(struct vdec_s *vdec)
+{
+ int i;
+
+ mutex_lock(&fcc.mutex);
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ if (fcc.used[i] && vdec->id == fcc.id[i]) {
+ fcc.offset_ready_flag[i] = 0;
+ fcc.id[i] = -1;
+ fcc.used[i] = 0;
+ break;
+ }
+ }
+ mutex_unlock(&fcc.mutex);
+
+ if (i >= MAX_FCC_CHANNEL_NUM)
+ pr_info("Error, no fcc slot matched to release\n");
+
+ return;
+}
+#endif
+
static int amstream_open(struct inode *inode, struct file *file)
{
s32 i;
@@ -1542,8 +1730,6 @@
struct port_priv_s *priv;
VDEC_PRINT_FUN_LINENO(__func__, __LINE__);
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, port type %d\n", __func__, port->type);
#ifdef G12A_BRINGUP_DEBUG
if (vdec_get_debug_flags() & 0xff0000) {
pr_info("%s force open port %d\n",
@@ -1556,6 +1742,8 @@
if (iminor(inode) >= amstream_port_num)
return -ENODEV;
+ //pr_err("%s, port name %s\n", __func__, port->name);
+ //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
mutex_lock(&amstream_mutex);
if (port->type & PORT_TYPE_VIDEO) {
@@ -1695,9 +1883,6 @@
#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
u32 port_flag = 0;
#endif
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, port type %d\n", __func__, port->type);
-
if (iminor(inode) >= amstream_port_num)
return -ENODEV;
@@ -1792,6 +1977,8 @@
amports_switch_gate("demux", 0);
}
+ amstream_userdata_deinit();
+
mutex_destroy(&priv->mutex);
kfree(priv);
@@ -1813,7 +2000,9 @@
{
struct stream_port_s *this = priv->port;
long r = 0;
-
+#ifdef VDEC_FCC_SUPPORT
+ int i;
+#endif
struct am_ioctl_parm parm;
if (copy_from_user
@@ -1878,7 +2067,7 @@
parm.data_64 = timestamp_apts_get_u64();
break;
case AMSTREAM_GET_PCRSCR:
- //parm.data_32 = timestamp_pcrscr_get();
+ parm.data_32 = timestamp_pcrscr_get();
break;
case AMSTREAM_GET_LAST_CHECKIN_APTS:
parm.data_32 = get_last_checkin_pts(PTS_TYPE_AUDIO);
@@ -1957,6 +2146,22 @@
case AMSTREAM_GET_FREED_HANDLE:
parm.data_32 = vdec_input_get_freed_handle(priv->vdec);
break;
+ case AMSTREAM_GET_OFFSET:
+#ifdef VDEC_FCC_SUPPORT
+ mutex_lock(&fcc.mutex);
+ for (i = 0; i < MAX_FCC_CHANNEL_NUM; i++) {
+ if (priv->vdec->id == fcc.id[i] &&
+ fcc.offset_ready_flag[i]) {
+ parm.data_32 = fcc.offset[i];
+ fcc.offset_ready_flag[i] = 0;
+ break;
+ }
+ }
+ mutex_unlock(&fcc.mutex);
+ if (i >= MAX_FCC_CHANNEL_NUM)
+ pr_info("Error, Get offset fail!\n");
+#endif
+ break;
default:
r = -ENOIOCTLCMD;
break;
@@ -1976,7 +2181,6 @@
struct am_ioctl_parm parm;
long r = 0;
int i;
- st_userdata *userdata = get_vdec_userdata_ctx();
if (copy_from_user
((void *)&parm, (void *)arg,
@@ -2207,6 +2411,41 @@
pr_debug("no drmmode\n");
}
break;
+ case AMSTREAM_SET_WORKMODE:
+ case AMSTREAM_SET_FCC_MODE:
+#ifdef VDEC_FCC_SUPPORT
+ if (parm.cmd == AMSTREAM_SET_FCC_MODE) {
+ priv->vdec->fcc_new_msg = 1;
+ if (priv->vdec->fcc_mode == FCC_DEC_MODE) {
+ priv->vdec->fcc_new_msg = 0;
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Current is dec mode, ignore discard message!\n",
+ priv->vdec->id);
+ break;
+ }
+ }
+
+ if (parm.data_32 == FCC_DISCARD_MODE) {
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: Set discard pic mode!\n",
+ priv->vdec->id);
+ if ((this->type & PORT_TYPE_VIDEO) &&
+ (priv->vdec)) {
+ priv->vdec->fcc_mode = FCC_DISCARD_MODE;
+ }
+ } else if (parm.data_32 == FCC_DEC_MODE) {
+ if ((this->type & PORT_TYPE_VIDEO) &&
+ (priv->vdec)) {
+ priv->vdec->fcc_mode = FCC_DEC_MODE;
+ }
+ if (fcc_debug_enable()) {
+ pr_info("[%d][FCC]: Set dec pic mode!\n", priv->vdec->id);
+ }
+ } else {
+ pr_info("Para error! Unknow FCC Mode! vdec id: %d\n", priv->vdec->id);
+ }
+#endif
+ break;
case AMSTREAM_SET_APTS: {
unsigned int pts;
@@ -2251,20 +2490,24 @@
break;
case AMSTREAM_SET_VIDEO_ID:
priv->vdec->video_id = parm.data_32;
- mutex_lock(&userdata->mutex);
+ mutex_lock(&userdata.mutex);
for (i = 0;i < MAX_USERDATA_CHANNEL_NUM; i++) {
- if (userdata->used[i] == 0) {
- userdata->id[i] = priv->vdec->video_id;
- userdata->used[i] = 1;
- userdata->video_id = priv->vdec->video_id;
- userdata->set_id_flag = 1;
+ if (userdata.used[i] == 0) {
+ userdata.id[i] = priv->vdec->video_id;
+ userdata.used[i] = 1;
+ userdata.video_id = priv->vdec->video_id;
+ userdata.set_id_flag = 1;
break;
}
}
- mutex_unlock(&userdata->mutex);
+ mutex_unlock(&userdata.mutex);
pr_info("AMSTREAM_SET_VIDEO_ID video_id: %d\n", parm.data_32);
break;
+ case AMSTREAM_SET_DMC_URGENT:
+ vdec_set_dmc_urgent(priv->vdec, parm.data_32);
+ break;
+
default:
r = -ENOIOCTLCMD;
break;
@@ -2667,15 +2910,20 @@
if (struct_size == sizeof(struct av_param_mvdec_t_old)) {//old struct
struct av_param_mvdec_t_old __user *uarg_old = (void *)arg;
int m;
- for (m=0; m<slots; m++)
+ for (m=0; m<slots; m++) {
if (copy_to_user((void *)&uarg_old->minfo[m],
&tmpbuf[m],
sizeof(struct vframe_counter_s_old))) {
r = -EFAULT;
- kfree(tmpbuf);
mutex_unlock(&amstream_mutex);
break;
}
+ }
+ if (r < 0) {
+ kfree(tmpbuf);
+ mutex_unlock(&amstream_mutex);
+ break;
+ }
} else if (struct_size == sizeof(struct av_param_mvdec_t)) {//new struct
if (copy_to_user((void *)&uarg->minfo[0],
tmpbuf,
@@ -2693,15 +2941,20 @@
}else { //For compatibility, only copy the qos
struct av_param_qosinfo_t __user *uarg = (void *)arg;
int i;
- for (i=0; i<slots; i++)
+ for (i=0; i<slots; i++) {
if (copy_to_user((void *)&uarg->vframe_qos[i],
&tmpbuf[i].qos,
sizeof(struct vframe_qos_s))) {
r = -EFAULT;
- kfree(tmpbuf);
mutex_unlock(&amstream_mutex);
break;
}
+ }
+ if (r < 0) {
+ kfree(tmpbuf);
+ mutex_unlock(&amstream_mutex);
+ break;
+ }
}
} else {
/*Vdec didn't produce item,wait for 10 ms to avoid user application
@@ -2715,16 +2968,16 @@
case AMSTREAM_IOC_GET_AVINFO:
{
struct av_param_info_t __user *uarg = (void *)arg;
- struct av_info_t av_info;
+ struct av_info_t av_info = {0};
int delay;
u32 avgbps;
if (this->type & PORT_TYPE_VIDEO) {
av_info.first_pic_coming = get_first_pic_coming();
av_info.current_fps = -1;
av_info.vpts = timestamp_vpts_get();
- //av_info.vpts_err = tsync_get_vpts_error_num();
+ av_info.vpts_err = tsync_get_vpts_error_num();
av_info.apts = timestamp_apts_get();
- //av_info.apts_err = tsync_get_apts_error_num();
+ av_info.apts_err = tsync_get_apts_error_num();
av_info.ts_error = get_discontinue_counter();
av_info.first_vpts = timestamp_firstvpts_get();
av_info.toggle_frame_count = get_toggle_frame_count();
@@ -2993,14 +3246,8 @@
r = vdec_set_pts64(priv->vdec, pts);
} else if ((this->type & PORT_TYPE_HEVC) ||
(this->type & PORT_TYPE_VIDEO)) {
- struct stream_buf_s *vbuf = &priv->vdec->vbuf;
- if (vbuf->no_parser && !vdec_single(priv->vdec)) {
- pts_checkin_offset_us64(PTS_TYPE_VIDEO,
- vbuf->stream_offset, pts);
- } else {
- r = es_vpts_checkin_us64(
- &priv->vdec->vbuf, pts);
- }
+ r = es_vpts_checkin_us64(
+ &priv->vdec->vbuf, pts);
} else if (this->type & PORT_TYPE_AUDIO) {
r = es_vpts_checkin_us64(
&bufs[BUF_TYPE_AUDIO], pts);
@@ -3225,8 +3472,6 @@
break;
}
mutex_lock(&amstream_mutex);
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, instance_id = %d\n", __func__, p_userdata_param->instance_id);
vdec = vdec_get_vdec_by_video_id(p_userdata_param->instance_id);
if (vdec) {
if (vdec_read_user_data(vdec,
@@ -3251,27 +3496,22 @@
{
unsigned int ready_vdec = 0;
u32 ready_flag = 0;
- st_userdata *userdata = get_vdec_userdata_ctx();
- mutex_lock(&userdata->mutex);
+ mutex_lock(&userdata.mutex);
for (i = 0; i < MAX_USERDATA_CHANNEL_NUM; i++) {
- if (userdata->video_id == userdata->id[i] &&
- userdata->ready_flag[i] == 1) {
- ready_vdec = userdata->id[i];
- userdata->ready_flag[i] = 0;
+ if (userdata.video_id == userdata.id[i] &&
+ userdata.ready_flag[i] == 1) {
+ ready_vdec = userdata.id[i];
+ userdata.ready_flag[i] = 0;
ready_flag = 1;
break;
}
}
- if (!ready_flag) {
- pr_info("instance %d not ready!\n", userdata->video_id);
+ if (!ready_flag)
r = -EINVAL;
- }
- mutex_unlock(&userdata->mutex);
+ mutex_unlock(&userdata.mutex);
put_user(ready_vdec, (uint32_t __user *)arg);
- if (vdec_get_debug_flags() & 0x10000000)
- pr_info("%s, ready_vdec = %u\n", __func__, ready_vdec);
}
break;
@@ -3286,16 +3526,14 @@
case AMSTREAM_IOC_UD_FLUSH_USERDATA:
if (this->type & PORT_TYPE_USERDATA) {
struct vdec_s *vdec;
- int video_id;
+ int vdec_id;
mutex_lock(&amstream_mutex);
- get_user(video_id, (int __user *)arg);
- pr_info("userdata flush id: %d\n", video_id);
- vdec = vdec_get_vdec_by_video_id(video_id);
+ get_user(vdec_id, (int __user *)arg);
+ vdec = vdec_get_vdec_by_id(vdec_id);
if (vdec) {
vdec_reset_userdata_fifo(vdec, 0);
- pr_info("reset_userdata_fifo for vdec_id: %d video_id: %d\\n",
- vdec->id, vdec->video_id);
+ pr_info("reset_userdata_fifo for vdec: %d\n", vdec_id);
}
mutex_unlock(&amstream_mutex);
} else
@@ -3343,7 +3581,7 @@
break;
case AMSTREAM_IOC_PCRSCR:
- //put_user(timestamp_pcrscr_get(), (int __user *)arg);
+ put_user(timestamp_pcrscr_get(), (int __user *)arg);
break;
case AMSTREAM_IOC_SET_PCRSCR:
@@ -3367,17 +3605,10 @@
case AMSTREAM_IOC_SUB_INFO:
if (arg > 0) {
- struct subtitle_info *msub_info =
- vzalloc(sizeof(struct subtitle_info) * MAX_SUB_NUM);
- struct subtitle_info **psub_info =
- vzalloc(sizeof(struct subtitle_info) * MAX_SUB_NUM);
+ struct subtitle_info msub_info[MAX_SUB_NUM];
+ struct subtitle_info *psub_info[MAX_SUB_NUM];
int i;
- if (!msub_info || !psub_info) {
- r = -ENOMEM;
- break;
- }
-
for (i = 0; i < MAX_SUB_NUM; i++)
psub_info[i] = &msub_info[i];
@@ -3388,8 +3619,6 @@
sizeof(struct subtitle_info) * MAX_SUB_NUM))
r = -EFAULT;
}
- vfree(msub_info);
- vfree(psub_info);
}
break;
case AMSTREAM_IOC_SET_DEMUX:
@@ -3594,7 +3823,7 @@
break;
}
case AMSTREAM_IOC_GET_STBUF_STATUS: {
- struct stream_buffer_status st;
+ struct stream_buffer_status st = {0};
struct stream_buf_s *pbuf = NULL;
if (priv->vdec == NULL) {
@@ -3716,7 +3945,7 @@
return -EFAULT;
data = compat_alloc_user_space(sizeof(*data));
- if (!access_ok(data, sizeof(*data)))
+ if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
return -EFAULT;
if (put_user(param.cmd, &data->cmd) ||
@@ -3745,7 +3974,7 @@
return -EFAULT;
data = compat_alloc_user_space(sizeof(*data));
- if (!access_ok(data, sizeof(*data)))
+ if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
return -EFAULT;
if (copy_in_user(data, data32, 7 * sizeof(u32)))
return -EFAULT;
@@ -3794,7 +4023,7 @@
return -EFAULT;
data = compat_alloc_user_space(sizeof(*data));
- if (!access_ok(data, sizeof(*data)))
+ if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
return -EFAULT;
if (copy_in_user(data, data32, 4 * sizeof(u32)))
@@ -4134,12 +4363,6 @@
return vcodec_profile_read(buf);
}
-static ssize_t vcodec_feature_show(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- return vcodec_feature_read(buf);
-}
-
static int reset_canuse_buferlevel(int levelx10000)
{
int i;
@@ -4161,7 +4384,7 @@
return 0;
}
-static ssize_t canuse_buferlevel_show(struct class *class,
+static ssize_t show_canuse_buferlevel(struct class *class,
struct class_attribute *attr, char *buf)
{
ssize_t size = sprintf(buf,
@@ -4170,7 +4393,7 @@
return size;
}
-static ssize_t canuse_buferlevel_store(struct class *class,
+static ssize_t store_canuse_buferlevel(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4182,12 +4405,12 @@
if (ret != 0)
return -EINVAL;
- (void)val;
+ val = val;
reset_canuse_buferlevel(val);
return size;
}
-static ssize_t max_buffer_delay_ms_store(struct class *class,
+static ssize_t store_maxdelay(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4204,7 +4427,7 @@
return size;
}
-static ssize_t max_buffer_delay_ms_show(struct class *class,
+static ssize_t show_maxdelay(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -4217,7 +4440,7 @@
return size;
}
-static ssize_t reset_audio_port_store(struct class *class,
+static ssize_t audio_path_store(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -4226,7 +4449,6 @@
ssize_t ret;
struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
struct stream_port_s *this;
-
ret = kstrtoint(buf, 0, &val);
if (ret != 0)
return -EINVAL;
@@ -4337,7 +4559,6 @@
pr_info("fail write retry, total %d, write %d\n", vmap_size, write_size);
if (write_size < vmap_size) {
pr_info("retry fail, interrupt dump stream, break\n");
- set_fs(old_fs);
break;
}
}
@@ -4356,32 +4577,28 @@
return size;
}
-static CLASS_ATTR_RO(ports);
-static CLASS_ATTR_RO(bufs);
-static CLASS_ATTR_RO(vcodec_profile);
-static CLASS_ATTR_RO(vcodec_feature);
-static CLASS_ATTR_RO(videobufused);
-static CLASS_ATTR_RW(canuse_buferlevel);
-static CLASS_ATTR_RW(max_buffer_delay_ms);
-static CLASS_ATTR_WO(reset_audio_port);
-static struct attribute *amstream_class_attrs[] = {
- &class_attr_ports.attr,
- &class_attr_bufs.attr,
- &class_attr_vcodec_profile.attr,
- &class_attr_vcodec_feature.attr,
- &class_attr_videobufused.attr,
- &class_attr_canuse_buferlevel.attr,
- &class_attr_max_buffer_delay_ms.attr,
- &class_attr_reset_audio_port.attr,
- NULL
+
+
+static struct class_attribute amstream_class_attrs[] = {
+ __ATTR_RO(ports),
+ __ATTR_RO(bufs),
+ __ATTR_RO(vcodec_profile),
+ __ATTR_RO(videobufused),
+ __ATTR(canuse_buferlevel, S_IRUGO | S_IWUSR | S_IWGRP,
+ show_canuse_buferlevel, store_canuse_buferlevel),
+ __ATTR(max_buffer_delay_ms, S_IRUGO | S_IWUSR | S_IWGRP, show_maxdelay,
+ store_maxdelay),
+ __ATTR(reset_audio_port, S_IRUGO | S_IWUSR | S_IWGRP,
+ NULL, audio_path_store),
+ __ATTR(dump_stream, S_IRUGO | S_IWUSR | S_IWGRP,
+ dump_stream_show, dump_stream_store),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(amstream_class);
-
static struct class amstream_class = {
- .name = "amstream",
- .class_groups = amstream_class_groups,
+ .name = "amstream",
+ .class_attrs = amstream_class_attrs,
};
int amstream_request_firmware_from_sys(const char *file_name,
@@ -4520,6 +4737,10 @@
/*prealloc fetch buf to avoid no continue buffer later...*/
stbuf_fetch_init();
REG_PATH_CONFIGS("media.amports", amports_configs);
+#ifdef VDEC_FCC_SUPPORT
+ if (fcc_enable & 0x1)
+ amstream_fcc_init();
+#endif
amstream_userdata_init();
/* poweroff the decode core because dos can not be reset when reboot */
@@ -4645,6 +4866,12 @@
MODULE_PARM_DESC(force_dv_mode,
"\n force_dv_mode \n");
+#ifdef VDEC_FCC_SUPPORT
+module_param(fcc_enable, uint, 0664);
+MODULE_PARM_DESC(fcc_enable,
+ "\n fcc_enable \n");
+#endif
+
module_param(def_4k_vstreambuf_sizeM, uint, 0664);
MODULE_PARM_DESC(def_4k_vstreambuf_sizeM,
"\nDefault video Stream buf size for 4K MByptes\n");
@@ -4656,7 +4883,6 @@
module_param(slow_input, uint, 0664);
MODULE_PARM_DESC(slow_input, "\n amstream slow_input\n");
-
MODULE_DESCRIPTION("AMLOGIC streaming port driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
diff --git a/drivers/stream_input/amports/stream_buffer_base.c b/drivers/stream_input/amports/stream_buffer_base.c
index 71df8e4..b5e06db 100644
--- a/drivers/stream_input/amports/stream_buffer_base.c
+++ b/drivers/stream_input/amports/stream_buffer_base.c
@@ -126,13 +126,50 @@
}
EXPORT_SYMBOL(stream_buffer_set_ext_buf);
+#ifdef VDEC_FCC_SUPPORT
+void fcc_wakeup_jump_back(struct vdec_s *vdec,
+ struct stream_buffer_metainfo *meta)
+{
+ u32 first_ptr;
+ u32 round_down_size = 0;
+ if (fcc_debug_enable())
+ pr_info("[%d][FCC]: jump_back_done = %d jump_back_flag = %d stbuf_pktaddr = 0x%x size = 0x%x\n",
+ vdec->id, vdec->jump_back_done, meta->jump_back_flag,
+ meta->stbuf_pktaddr, meta->stbuf_size);
+ if (vdec->fcc_mode == FCC_DEC_MODE && vdec->fcc_status != SWITCH_DONE_STATUS) {
+ mutex_lock(&vdec->jump_back_mutex);
+ if (meta->jump_back_flag && !vdec->jump_back_done) {
+ if (vdec->input.target == VDEC_INPUT_TARGET_HEVC)
+ round_down_size = 0x80;
+ else if (vdec->input.target == VDEC_INPUT_TARGET_VLD)
+ round_down_size = 0x100;
+
+ if (vdec->vbuf.ext_buf_addr > (meta->stbuf_pktaddr - round_down_size))
+ first_ptr = vdec->vbuf.ext_buf_addr;
+ else {
+ first_ptr = round_down(meta->stbuf_pktaddr, round_down_size);
+ }
+ vdec->jump_back_done = 1;
+ vdec->jump_back_rp = first_ptr;
+ wake_up_interruptible(&vdec->jump_back_wq);
+ } else if (!vdec->jump_back_done && !vdec->jump_back_error) {
+ vdec->jump_back_error = 1;
+ wake_up_interruptible(&vdec->jump_back_wq);
+ }
+ mutex_unlock(&vdec->jump_back_mutex);
+ }
+
+ return;
+}
+#endif
+
void stream_buffer_meta_write(struct stream_buf_s *stbuf,
struct stream_buffer_metainfo *meta)
{
u32 wp = stbuf->ops->get_wp(stbuf);
if ((stbuf->stream_offset == 0) &&
- (wp == stbuf->ext_buf_addr) &&
+ /*(wp == stbuf->ext_buf_addr) &&*/ /*For fcc, when switching to dec mode it doesn't meet*/
(meta->stbuf_pktaddr > stbuf->ext_buf_addr)) {
struct vdec_s *vdec = container_of(stbuf, struct vdec_s, vbuf);
u32 first_ptr;
@@ -161,7 +198,6 @@
stbuf->stream_offset += (meta->stbuf_pktaddr - stbuf->ext_buf_addr);
else
stbuf->stream_offset += (meta->stbuf_pktaddr - first_ptr);
-
}
if (meta->stbuf_pktaddr + meta->stbuf_pktsize < stbuf->buf_start + stbuf->buf_size)
@@ -172,8 +208,10 @@
stbuf->ops->set_wp(stbuf, wp);
stbuf->stream_offset += meta->stbuf_pktsize;
- stbuf->last_offset[stbuf->write_count % 2] = stbuf->stream_offset;
- stbuf->write_count++;
+
+#ifdef VDEC_FCC_SUPPORT
+ fcc_wakeup_jump_back(container_of(stbuf, struct vdec_s, vbuf), meta);
+#endif
/*
pr_debug("%s, update wp 0x%x + sz 0x%x --> 0x%x, stream_offset 0x%x\n",
__func__, meta->stbuf_pktaddr, meta->stbuf_pktsize, wp, stbuf->stream_offset);
diff --git a/drivers/stream_input/amports/stream_buffer_interface.c b/drivers/stream_input/amports/stream_buffer_interface.c
index 64a14ee..04ceaf5 100644
--- a/drivers/stream_input/amports/stream_buffer_interface.c
+++ b/drivers/stream_input/amports/stream_buffer_interface.c
@@ -132,8 +132,7 @@
stbuf->flag |= BUF_FLAG_ALLOC;
stbuf->flag |= BUF_FLAG_IN_USE;
- if (vdec_single(vdec))
- pts_start(stbuf->type);
+
pr_info("[%d]: [%s-%s] addr: %lx, size: %x, thrRW: %d, extbuf: %d, secure: %d\n",
stbuf->id, type_to_str(stbuf->type), stbuf->name,
stbuf->buf_start, stbuf->buf_size,
@@ -152,8 +151,6 @@
{
if (stbuf->write_thread)
threadrw_release(stbuf);
- if (vdec_single(container_of(stbuf, struct vdec_s, vbuf)))
- pts_stop(stbuf->type);
if (stbuf->flag & BUF_FLAG_ALLOC && stbuf->buf_start) {
if (!stbuf->ext_buf_addr)
@@ -190,7 +187,7 @@
{
int ret =0;
- if (likely(access_ok(from, n)))
+ if (likely(access_ok(VERIFY_READ, from, n)))
ret = copy_from_user(to, from, n);
else
memcpy(to, from, n);
diff --git a/drivers/stream_input/amports/streambuf.c b/drivers/stream_input/amports/streambuf.c
index c267879..fe360f2 100644
--- a/drivers/stream_input/amports/streambuf.c
+++ b/drivers/stream_input/amports/streambuf.c
@@ -194,7 +194,7 @@
}
}
-static void _stbuf_timer_func(struct timer_list *arg)
+static void _stbuf_timer_func(unsigned long arg)
{
struct stream_buf_s *p = (struct stream_buf_s *)arg;
@@ -412,7 +412,7 @@
p->wcnt = count;
- timer_setup(&p->timer, _stbuf_timer_func, (ulong) p);
+ setup_timer(&p->timer, _stbuf_timer_func, (ulong) p);
mod_timer(&p->timer, jiffies + STBUF_WAIT_INTERVAL);
diff --git a/drivers/stream_input/amports/streambuf.h b/drivers/stream_input/amports/streambuf.h
index 88f0926..afb2ebe 100644
--- a/drivers/stream_input/amports/streambuf.h
+++ b/drivers/stream_input/amports/streambuf.h
@@ -96,8 +96,6 @@
u32 stream_offset;
struct parser_args pars;
struct stream_buf_ops *ops;
- u32 last_offset[2];
- u32 write_count;
} /*stream_buf_t */;
struct stream_port_s {
@@ -158,7 +156,8 @@
};
u32 stbuf_flag;
u32 stbuf_private;
- u32 reserved[16];
+ u32 jump_back_flag;
+ u32 reserved[15];
};
struct stream_buffer_status {
diff --git a/drivers/stream_input/parser/dvb_ci/Makefile b/drivers/stream_input/parser/dvb_ci/Makefile
index 47e295d..25cdcb9 100644
--- a/drivers/stream_input/parser/dvb_ci/Makefile
+++ b/drivers/stream_input/parser/dvb_ci/Makefile
@@ -1,22 +1,16 @@
-obj-m += ci.o
-#cimax-usb.o
+obj-m += ci.o cimax-usb.o
-ci-objs = $(amlci-objs) $(cimcu-objs)
-#$(cimax-objs)
+ci-objs = $(amlci-objs) $(cimcu-objs) $(cimax-objs)
-amlci-objs = aml_pcmcia.o aml_ci.o aml_ci_bus.o
-#aml_spi.o
-cimcu-objs = cimax/dvb_ringbuffer.o cimcu/dvb_ca_en50221_cimcu.o
-#cimax-objs = cimax/dvb_ca_en50221_cimax.o cimax/aml_cimax.o cimax/dvb_ringbuffer.o
-KBUILD_CFLAGS += -Wno-implicit-fallthrough
-#cimax-usb-objs += cimax/usb/SRC/cimax+usb-driver.o cimax/usb/SRC/cimax+usb_fw.o
-#cimax-usb-objs += cimax/usb/SRC/cimax+usb_config.o
-#cimax-objs += cimax/aml_cimax_usb.o
+amlci-objs = aml_pcmcia.o aml_ci.o aml_spi.o
+cimcu-objs = cimcu/dvb_ca_en50221_cimcu.o
+cimax-objs = cimax/dvb_ca_en50221_cimax.o cimax/aml_cimax.o cimax/dvb_ringbuffer.o
+cimax-usb-objs += cimax/usb/SRC/cimax+usb-driver.o cimax/usb/SRC/cimax+usb_fw.o
+cimax-usb-objs += cimax/usb/SRC/cimax+usb_config.o
+cimax-objs += cimax/aml_cimax_usb.o
ccflags-y += -I$(srctree)/
ccflags-y += -I$(srctree)/include
ccflags-y += -I$(srctree)/drivers/gpio
ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/include/media
-ccflags-y += -I$(srctree)/drivers/media/pci/ttpci
diff --git a/drivers/stream_input/parser/dvb_ci/aml_ci.c b/drivers/stream_input/parser/dvb_ci/aml_ci.c
index f6c27fd..d457a05 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_ci.c
+++ b/drivers/stream_input/parser/dvb_ci/aml_ci.c
@@ -26,12 +26,9 @@
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
-#include <linux/sysfs.h>
-#include <linux/of.h>
#include "aml_ci.h"
-//#include "aml_spi.h"
-#include "aml_ci_bus.h"
-//#include "cimax/aml_cimax.h"
+#include "aml_spi.h"
+#include "cimax/aml_cimax.h"
//#include "dvb_ca_en50221.h"
#include <dvbdev.h>
@@ -216,7 +213,7 @@
{
struct aml_ci *ci = en50221->data;
- //pr_dbg("Slot(%d): Poll Slot status\n", slot);
+ pr_dbg("Slot(%d): Poll Slot status\n", slot);
if (ci->ci_poll_slot_status != NULL) {
return ci->ci_poll_slot_status(ci, slot, open);
@@ -226,29 +223,6 @@
return 0;
}
-/**\brief aml_ci_slot_status:get slot status
- * \param en50221: en50221 obj,used this data to get dvb_ci obj
- * \param slot: slot index
- * \param open: no used
- * \return
- * - cam status
- * - -EINVAL : error
- */
-static int aml_ci_slot_wakeup(struct dvb_ca_en50221_cimcu *en50221,
- int slot)
-{
- struct aml_ci *ci = en50221->data;
-
- if (ci->ci_get_slot_wakeup != NULL) {
- return ci->ci_get_slot_wakeup(ci, slot);
- } else {
- /*pr_error("aml_ci_slot_wakeup is null %s\r\n", __func__);*/
- }
-
- return 1;
-}
-
-#if 0
static int aml_ci_cimax_slot_reset(struct dvb_ca_en50221_cimax *en50221,
int slot)
{
@@ -507,7 +481,7 @@
pr_error("ci_get_capbility is null %s\r\n", __func__);
return 0;
}
-#endif
+
/**\brief get ci config from dts
* \param np: device node
@@ -556,7 +530,6 @@
// ci->priv = dvb;
/* register CA interface */
-#if 0
if (ci->io_type == AML_DVB_IO_TYPE_CIMAX) {
ci->en50221_cimax.owner = THIS_MODULE;
ci->en50221_cimax.read_cis = aml_ci_read_cis;
@@ -581,10 +554,8 @@
result);
goto err;
}
- } else
-#endif
- {
- ca_flags = ~DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
+ } else {
+ ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
/* register CA interface */
ci->en50221_cimcu.owner = THIS_MODULE;
ci->en50221_cimcu.read_attribute_mem = aml_ci_mem_read;
@@ -595,8 +566,6 @@
ci->en50221_cimcu.slot_shutdown = aml_ci_slot_shutdown;
ci->en50221_cimcu.slot_ts_enable = aml_ci_ts_control;
ci->en50221_cimcu.poll_slot_status = aml_ci_slot_status;
- ci->en50221_cimcu.get_slot_wakeup = aml_ci_slot_wakeup;
-
ci->en50221_cimcu.data = ci;
@@ -611,7 +580,7 @@
}
*cip = ci;
pr_dbg("Registered EN50221 device\n");
-#if 0
+
if (ci->io_type == AML_DVB_IO_TYPE_SPI || ci->io_type == AML_DVB_IO_TYPE_SPI_T312) {
/* spi init */
ci->ci_init = aml_spi_init;
@@ -619,11 +588,6 @@
} else if (ci->io_type == AML_DVB_IO_TYPE_CIMAX) {
ci->ci_init = aml_cimax_init;
ci->ci_exit = aml_cimax_exit;
- } else
-#endif
- if (ci->io_type == AML_DVB_IO_TYPE_CIBUS) {
- ci->ci_init = aml_ci_bus_init;
- ci->ci_exit = aml_ci_bus_exit;
} else {
/* no io dev init,is error */
pr_dbg("unknown io type, please check io_type in dts file\r\n");
@@ -631,12 +595,10 @@
if (ci->ci_init)
result = ci->ci_init(pdev, ci);
-#if 0
if (ci->io_type == AML_DVB_IO_TYPE_CIMAX) {
if (result)
dvb_ca_en50221_cimax_release(&ci->en50221_cimax);
}
-#endif
return result;
err:
kfree(ci);
@@ -647,12 +609,10 @@
{
pr_dbg("Unregistering EN50221 device\n");
if (ci) {
-#if 0
if (ci->io_type == AML_DVB_IO_TYPE_CIMAX)
dvb_ca_en50221_cimax_release(&ci->en50221_cimax);
else
-#endif
- dvb_ca_en50221_cimcu_release(&ci->en50221_cimcu);
+ dvb_ca_en50221_cimcu_release(&ci->en50221_cimcu);
if (ci->ci_exit)
ci->ci_exit(ci);
kfree(ci);
@@ -661,22 +621,19 @@
static struct aml_ci *ci_dev;
-static ssize_t ts_show(struct class *class,
+static ssize_t aml_ci_ts_show(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
ret = sprintf(buf, "ts%d\n", 1);
return ret;
}
-static CLASS_ATTR_RO(ts);
-static struct attribute *aml_ci_attrs[] = {
- &class_attr_ts.attr,
- NULL
+static struct class_attribute amlci_class_attrs[] = {
+ __ATTR(ts, S_IRUGO | S_IWUSR, aml_ci_ts_show, NULL),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(aml_ci);
-
static int aml_ci_register_class(struct aml_ci *ci)
{
#define CLASS_NAME_LEN 48
@@ -691,7 +648,7 @@
snprintf((char *)clp->name, CLASS_NAME_LEN, "amlci-%d", ci->id);
clp->owner = THIS_MODULE;
- clp->class_groups = aml_ci_groups;
+ clp->class_attrs = amlci_class_attrs;
ret = class_register(clp);
if (ret)
kfree(clp->name);
@@ -711,18 +668,15 @@
{
struct dvb_adapter *dvb_adapter = aml_get_dvb_adapter();
int err = 0;
- pr_dbg("---Amlogic CI Init---[%p]\n", dvb_adapter);
-
+ pr_dbg("---Amlogic CI Init---\n");
err = aml_ci_init(pdev, dvb_adapter, &ci_dev);
if (err < 0)
return err;
platform_set_drvdata(pdev, ci_dev);
aml_ci_register_class(ci_dev);
-#if 0
if (ci_dev->io_type == AML_DVB_IO_TYPE_SPI ||
ci_dev->io_type == AML_DVB_IO_TYPE_SPI_T312)
aml_spi_mod_init();
-#endif
return 0;
}
@@ -730,7 +684,6 @@
{
aml_ci_unregister_class(ci_dev);
platform_set_drvdata(pdev, NULL);
-#if 0
if (ci_dev->io_type == AML_DVB_IO_TYPE_SPI ||
ci_dev->io_type == AML_DVB_IO_TYPE_SPI_T312) {
aml_spi_exit(ci_dev);
@@ -739,10 +692,6 @@
else if (ci_dev->io_type == AML_DVB_IO_TYPE_CIMAX)
aml_cimax_exit(ci_dev);
else
-#endif
- if (ci_dev->io_type == AML_DVB_IO_TYPE_CIBUS)
- aml_ci_bus_exit(ci_dev);
- else
pr_dbg("---Amlogic CI remove unkown io type---\n");
aml_ci_exit(ci_dev);
@@ -752,7 +701,6 @@
static int aml_ci_suspend(struct platform_device *pdev, pm_message_t state)
{
pr_dbg("Amlogic CI Suspend!\n");
-#if 0
if (ci_dev->io_type == AML_DVB_IO_TYPE_SPI ||
ci_dev->io_type == AML_DVB_IO_TYPE_SPI_T312) {
aml_spi_exit(ci_dev);
@@ -760,10 +708,6 @@
else if (ci_dev->io_type == AML_DVB_IO_TYPE_CIMAX)
aml_cimax_exit(ci_dev);
else
-#endif
- if (ci_dev->io_type == AML_DVB_IO_TYPE_CIBUS)
- aml_ci_bus_exit(ci_dev);
- else
pr_dbg("---Amlogic CI remove unkown io type---\n");
return 0;
@@ -773,7 +717,6 @@
{
int err = 0;
pr_dbg("Amlogic CI Resume!\n");
-#if 0
if (ci_dev->io_type == AML_DVB_IO_TYPE_SPI ||
ci_dev->io_type == AML_DVB_IO_TYPE_SPI_T312) {
aml_spi_init(pdev, ci_dev);
@@ -781,10 +724,6 @@
else if (ci_dev->io_type == AML_DVB_IO_TYPE_CIMAX)
aml_cimax_init(pdev, ci_dev);
else
-#endif
- if (ci_dev->io_type == AML_DVB_IO_TYPE_CIBUS)
- aml_ci_bus_init(pdev, ci_dev);
- else
pr_dbg("---Amlogic CI remove unkown io type---\n");
return err;
}
diff --git a/drivers/stream_input/parser/dvb_ci/aml_ci.h b/drivers/stream_input/parser/dvb_ci/aml_ci.h
index d534557..9006b7e 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_ci.h
+++ b/drivers/stream_input/parser/dvb_ci/aml_ci.h
@@ -23,7 +23,7 @@
//#include "drivers/media/dvb-core/dvb_ca_en50221.h"
#include "cimcu/dvb_ca_en50221_cimcu.h"
-//#include "cimax/dvb_ca_en50221_cimax.h"
+#include "cimax/dvb_ca_en50221_cimax.h"
#include <linux/platform_device.h>
enum aml_dvb_io_type_e {
@@ -31,27 +31,9 @@
AML_DVB_IO_TYPE_SPI,
AML_DVB_IO_TYPE_CIMAX,
AML_DVB_IO_TYPE_SPI_T312,
- AML_DVB_IO_TYPE_CIBUS,
AML_DVB_IO_TYPE_MAX,
};
-enum aml_gpio_level_e {
- AML_GPIO_LOW = 0,
- AML_GPIO_HIGH
-};
-enum AM_CI_CMD {
- AM_CI_CMD_IOR = 0,
- AM_CI_CMD_IOW,
- AM_CI_CMD_MEMR,
- AM_CI_CMD_MEMW,
- AM_CI_CMD_FULLTEST,
- AM_CI_CMD_CISTEST,
- AM_CI_CMD_GETCD12,
- AM_CI_CMD_POWER,
- AM_CI_CMD_RESET,
- AM_CI_CMD_CONGPIO,
-};
-
struct aml_ci {
// struct dvb_ca_en50221 en50221;
struct dvb_ca_en50221_cimcu en50221_cimcu;
@@ -88,23 +70,22 @@
*/
int (*ci_poll_slot_status)(struct aml_ci *ca, int slot, int open);
- int (*ci_get_slot_wakeup)(struct aml_ci *ca, int slot);
- //struct dvb_ca_en50221_cimax en50221_cimax;
+ struct dvb_ca_en50221_cimax en50221_cimax;
- //int (*ci_read_cis)(struct aml_ci *ca, int slot, u8 *buf, int size);
- //int (*ci_write_cor)(struct aml_ci *ca, int slot, int address, u8 *buf);
+ int (*ci_read_cis)(struct aml_ci *ca, int slot, u8 *buf, int size);
+ int (*ci_write_cor)(struct aml_ci *ca, int slot, int address, u8 *buf);
/*return the final size or -1 for error*/
- //int (*ci_negotiate)(struct aml_ci *ca, int slot, int size);
+ int (*ci_negotiate)(struct aml_ci *ca, int slot, int size);
/* functions for accessing the control interface on the CAM */
- //int (*ci_read_lpdu)(struct aml_ci *ca, int slot, u8 *buf, int size);
- //int (*ci_write_lpdu)(struct aml_ci *ca, int slot, u8 *buf, int size);
+ int (*ci_read_lpdu)(struct aml_ci *ca, int slot, u8 *buf, int size);
+ int (*ci_write_lpdu)(struct aml_ci *ca, int slot, u8 *buf, int size);
- //int (*ci_get_capbility)(struct aml_ci *ca, int slot);
+ int (*ci_get_capbility)(struct aml_ci *ca, int slot);
- //int (*ci_cam_reset)(struct aml_ci *ca, int slot);
- //int (*ci_read_cam_status)(struct aml_ci *ca, int slot);
+ int (*ci_cam_reset)(struct aml_ci *ca, int slot);
+ int (*ci_read_cam_status)(struct aml_ci *ca, int slot);
/* private data, used by caller */
void *data;
diff --git a/drivers/stream_input/parser/dvb_ci/aml_ci_bus.c b/drivers/stream_input/parser/dvb_ci/aml_ci_bus.c
deleted file mode 100644
index 7138dfd..0000000
--- a/drivers/stream_input/parser/dvb_ci/aml_ci_bus.c
+++ /dev/null
@@ -1,1903 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/amlogic/aml_gpio_consumer.h>
-#include <linux/gpio/consumer.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/of_irq.h>
-#include <linux/irq.h>
-#include <linux/compat.h>
-#include "aml_ci_bus.h"
-#include "aml_ci.h"
-
-
-
-//can see jtag dts and driver to select gpio function.
-//write dts config for cam/tsin/out
-//gpio irq is can used.
-//
-static struct aml_ci_bus ci_bus;
-static int aml_ci_bus_debug = 1;
-static int aml_ci_bus_time = 500;
-static int aml_ci_bus_set_delay = 0;
-
-static DECLARE_WAIT_QUEUE_HEAD(wq);
-static u32 fetch_done;
-
-module_param_named(ci_bus_debug, aml_ci_bus_debug, int, 0644);
-MODULE_PARM_DESC(ci_bus_debug, "enable verbose debug messages");
-
-module_param_named(ci_bus_set_delay, aml_ci_bus_set_delay, int, 0644);
-MODULE_PARM_DESC(ci_bus_set_delay, "enable ci bus delay set");
-
-module_param_named(ci_bus_time, aml_ci_bus_time, int, 0644);
-MODULE_PARM_DESC(ci_bus_time, "set ci bus time");
-
-
-#define pr_dbg(args...)\
- do {\
- if (aml_ci_bus_debug)\
- printk(args);\
- } while (0)
-#define pr_error(fmt, args...) printk("AML_CI_BUS: " fmt, ## args)
-
-
-#define INPUT 0
-#define OUTPUT 1
-#define OUTLEVEL_LOW 0
-#define OUTLEVEL_HIGH 1
-#define PULLLOW 1
-#define PULLHIGH 0
-
-#define AML_MODE_NAME "aml_dvbci_bus"
-
-int aml_ci_bus_mod_init(void);
-void aml_ci_bus_mod_exit(void);
-static int aml_read_self(unsigned int reg);
-static void aml_write_self(unsigned int reg, unsigned int val);
-static int aml_set_gpio_out(struct gpio_desc *gpio, int val);
-static int aml_set_gpio_in(struct gpio_desc *gpio);
-
-#define WRITE_CIBUS_REG(_r, _v) aml_write_self(_r, _v)
-#define READ_CIBUS_REG(_r) aml_read_self(_r)
-
-#define USED_IRQ 0
-
-static void *p_hw_base;
-//write reg
-static void aml_write_self(unsigned int reg, unsigned int val)
-{
- void *ptr = (void *)(p_hw_base + reg);
- writel(val, ptr);
-}
-//read reg
-static int aml_read_self(unsigned int reg)
-{
- void *addr = p_hw_base + reg;
- int ret = readl(addr);
- return ret;
-}
-
-/**\brief init_ci_addr:ci bus init mem addr
-* \param pdev:
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-int init_ci_addr(struct platform_device *pdev)
-{
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- pr_dbg("%s fail\n", __func__);
- return -1;
- }
-
- p_hw_base = devm_ioremap_nocache(&pdev->dev, res->start,
- resource_size(res));
- if (p_hw_base) {
- pr_dbg("%s base addr = %lx\n", __func__,
- (unsigned long)p_hw_base);
- } else {
- pr_dbg("%s base addr error\n", __func__);
- }
- return 0;
-}
-
-
-/**\brief aml_ci_bus_io:ci bus read or write api with bus
-* \param ci_bus_dev: ci_bus_dev obj,used this data to ctl
-* \param val: read or write value
-* \param addr: rw addr
-* \param mode: cmd
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_select_gpio(struct aml_ci_bus *ci_bus_dev,
- int select/*, int enable*/)
-{
- //SELECT GPIO FUNCTION
- unsigned int old_select = ci_bus_dev->select;
- struct pinctrl_state *s;
- int ret = 0;
-
- if (old_select == select)
- return 0;
-
- if (ci_bus_dev->addr_ts_mode_multiplex == 0) {
- //not multiplex ts and ci addr, so no need to
- //change ts and addr
- if (select == AML_GPIO_ADDR) {
- return 0;
- }
- }
- if (!ci_bus_dev->pinctrl) {
- ci_bus_dev->pinctrl = devm_pinctrl_get(&ci_bus_dev->pdev->dev);
- if (IS_ERR_OR_NULL(ci_bus_dev->pinctrl)) {
- dev_err(&ci_bus_dev->pdev->dev, "could not get pinctrl handle\n");
- return -EINVAL;
- }
- }
- if (IS_ERR_OR_NULL(ci_bus_dev->pinctrl)) {
- dev_err(&ci_bus_dev->pdev->dev, "return, could not get pinctrl handle\n");
- return -EINVAL;
- }
- /* set pinmux */
- switch (select) {
- case AML_GPIO_ADDR:
- s = pinctrl_lookup_state(ci_bus_dev->pinctrl, "ci_addr_pins");
- if (IS_ERR_OR_NULL(s)) {
- dev_err(&ci_bus_dev->pdev->dev,
- "could not get ci_addr_pins state\n");
- return -EINVAL;
- }
- ret = pinctrl_select_state(ci_bus_dev->pinctrl, s);
- if (ret) {
- dev_err(&ci_bus_dev->pdev->dev, "failed to set ci_addr_pins pinctrl\n");
- return -EINVAL;
- }
- if (ci_bus_dev->le_pin) {
- aml_set_gpio_out(ci_bus_dev->le_pin, ci_bus_dev->le_enable_level);
- pr_dbg("set le pin to low");
- }
- break;
- case AML_GPIO_TS:
- if (ci_bus_dev->le_pin) {
- aml_set_gpio_out(ci_bus_dev->le_pin, !ci_bus_dev->le_enable_level);
- pr_dbg("set le pin to high");
- }
- s = pinctrl_lookup_state(ci_bus_dev->pinctrl, "ci_ts_pins");
- if (IS_ERR_OR_NULL(s)) {
- dev_err(&ci_bus_dev->pdev->dev,
- "could not get ci_ts_pins state\n");
- return -EINVAL;
- }
- ret = pinctrl_select_state(ci_bus_dev->pinctrl, s);
- if (ret) {
- dev_err(&ci_bus_dev->pdev->dev, "failed to set ci_ts_pins pinctrl\n");
- return -EINVAL;
- }
- break;
- default:
- break;
- }
- ci_bus_dev->select = select;
- return 0;
-}
-
-/**\brief aml_ci_bus_set_delay_time:set ci bus delay time
-* \param mode: cmd,io rd/wr or mem rd/wr
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_set_delay_time(int mode)
-{
- u32 delay0 = 0, delay1 = 0;
- //set cmd delay
- if (mode == AM_CI_CMD_IOR) {
- //delay0
- delay0 = delay0 | (DELAY_RIO_INIT_ADDR << 0);
- delay0 = delay0 | (DELAY_RIO_ADDR_CE << 8);
- delay0 = delay0 | (DELAY_RIO_CE_RD << 16);
- delay0 = delay0 | (DELAY_RIO_RD_RWAIT << 24);
- //delay1
- delay1 = delay1 | (DELAY_RIO_RWAIT_DATA << 0);
- delay1 = delay1 | (DELAY_RIO_DATA_DRD << 8);
- delay1 = delay1 | (DELAY_RIO_DRD_DCE << 16);
- delay1 = delay1 | (DELAY_RIO_DCE_INIT << 24);
- } else if (mode == AM_CI_CMD_IOW) {
- //delay0
- delay0 = delay0 | (DELAY_WIO_INIT_ADDR << 0);
- delay0 = delay0 | (DELAY_WIO_ADDR_CE << 8);
- delay0 = delay0 | (DELAY_WIO_CE_WR << 16);
- delay0 = delay0 | (DELAY_WIO_WR_RWAIT << 24);
- //delay1
- delay1 = delay1 | (DELAY_WIO_RWAIT_DATA << 0);
- delay1 = delay1 | (DELAY_WIO_DATA_DWR << 8);
- delay1 = delay1 | (DELAY_WIO_DWR_DCE << 16);
- delay1 = delay1 | (DELAY_WIO_DCE_INIT << 24);
- } else if (mode == AM_CI_CMD_MEMR) {
- //delay0
- delay0 = delay0 | (DELAY_RMEM_INIT_ADDR << 0);
- delay0 = delay0 | (DELAY_RMEM_ADDR_CE << 8);
- delay0 = delay0 | (DELAY_RMEM_CE_RD << 16);
- delay0 = delay0 | (DELAY_RMEM_RD_RWAIT << 24);
- //delay1
- delay1 = delay1 | (DELAY_RMEM_RWAIT_DATA << 0);
- delay1 = delay1 | (DELAY_RMEM_DATA_DRD << 8);
- delay1 = delay1 | (DELAY_RMEM_DRD_DCE << 16);
- delay1 = delay1 | (DELAY_RMEM_DCE_INIT << 24);
- } else if (mode == AM_CI_CMD_MEMW) {
- //delay0
- delay0 = delay0 | (DELAY_WMEM_INIT_ADDR << 0);
- delay0 = delay0 | (DELAY_WMEM_ADDR_CE << 8);
- delay0 = delay0 | (DELAY_WMEM_CE_WR << 16);
- delay0 = delay0 | (DELAY_WMEM_WR_RWAIT << 24);
- //delay1
- delay1 = delay1 | (DELAY_WMEM_RWAIT_DATA << 0);
- delay1 = delay1 | (DELAY_WMEM_DATA_DWR << 8);
- delay1 = delay1 | (DELAY_WMEM_DWR_DCE << 16);
- delay1 = delay1 | (DELAY_WMEM_DCE_INIT << 24);
- }
- //Wwrite cmd
- WRITE_CIBUS_REG(CIPLUS_DELAY_CTRL0, delay0);
- WRITE_CIBUS_REG(CIPLUS_DELAY_CTRL1, delay1);
- return 0;
-}
-
-
-/**\brief aml_ci_bus_io:ci bus read or write api with bus
-* \param ci_bus_dev: ci_bus_dev obj,used this data to ctl
-* \param val: read or write value
-* \param addr: rw addr
-* \param mode: cmd
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_io(struct aml_ci_bus *ci_bus_dev,
- u8 val, u16 addr, int mode)
-{
- int rd;
- int ret = -1;
- u32 address = addr;
- u32 data = val;
- u32 reg = 0;
- u32 ctrl = 0;
- int enable = 0;
- int count = 0;
- u32 int_status;
- //only used hi addr. we to change tsout to addr
- if (addr >= 4) {
- enable = 1;
- }
- //clear irq
- ctrl = READ_CIBUS_REG(CIPLUS_CTRL_REG);
- ctrl = ctrl | (1 << CLEAR_CMP_IRQ);
- ctrl = ctrl | (1 << CLEAR_TIMEOUT_IRQ);
- //Wwrite cmd crtl
- WRITE_CIBUS_REG(CIPLUS_CTRL_REG, ctrl);
- fetch_done = 0;
- //gpio select gpio func
- //aml_ci_bus_select_gpio(ci_bus_dev, enable ? AML_GPIO_ADDR : AML_GPIO_TS);
- while (1) {
- count++;
- if (count < aml_ci_bus_time)
- break;
- }
- //enable delay reg,defalue is disable
- if (aml_ci_bus_set_delay)
- aml_ci_bus_set_delay_time(mode);
- //cmd vilad
- reg = reg | (1 << CI_CMD_VALID);
- //set addr
- reg = reg | ((address & 0xeFFF) << CI_CMD_ADDR);
- //set cmd and write data
- if (mode == AM_CI_CMD_IOR) {
- reg = reg | (IORD << CI_CMD_TYPE);
- } else if (mode == AM_CI_CMD_IOW) {
- reg = reg | (data << CI_CMD_WDATA);
- reg = reg | (IOWR << CI_CMD_TYPE);
- } else if (mode == AM_CI_CMD_MEMR) {
- reg = reg | (MEMRD << CI_CMD_TYPE);
- } else if (mode == AM_CI_CMD_MEMW) {
- reg = reg | (data << CI_CMD_WDATA);
- reg = reg | (MEMWR << CI_CMD_TYPE);
- }
- //clear irq
- ctrl = READ_CIBUS_REG(CIPLUS_CTRL_REG);
- ctrl = ctrl | (1 << CLEAR_CMP_IRQ);
- ctrl = ctrl | (1 << CLEAR_TIMEOUT_IRQ);
- //Wwrite cmd crtl
- WRITE_CIBUS_REG(CIPLUS_CTRL_REG, ctrl);
- //Wwrite cmd reg
- WRITE_CIBUS_REG(CIPLUS_CMD_REG, reg);
- //wait cmp irq or timwout irq
- if (USED_IRQ == 1) {
- ret =
- wait_event_interruptible_timeout(wq, fetch_done != 0,
- HZ / 100);//10ms
- } else {
- count = 0;
- while(1) {
- count++;
- int_status = READ_CIBUS_REG(CIPLUS_STATUS_REG);
- if ((int_status&(1 << COMPLETE_IRQ_STATE)) == (1 << COMPLETE_IRQ_STATE)) {
- break;
- }
- if (count > 50) {
- printk("count timeout:%d\r\n", count);
- break;
- }
- }
- }
- rd = READ_CIBUS_REG(CIPLUS_RDATA_REG);
- //gpio select tsout func
- //aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_TS, enable);
- return rd;
-}
-/**\brief aml_ci_bus_init_reg:ci bus init reg,enable ci bus
-* \param ci_bus_dev: ci_bus_dev obj,used this data to ctl
-* \return
-* - 0:ok
-*/
-static int aml_ci_bus_init_reg(struct aml_ci_bus *ci_bus_dev)
-{
- u32 ctrl = 0;
-
- if (ci_bus_dev->addr_ts_mode_multiplex == 0) {
- aml_ci_bus_select_gpio(ci_bus_dev,AML_GPIO_TS);
- } else {
- aml_ci_bus_select_gpio(ci_bus_dev,AML_GPIO_ADDR);
- }
-
- //init ci bus reg
- pr_dbg("aml_ci_bus_init_reg---\r\n");
- ctrl = READ_CIBUS_REG(CIPLUS_CTRL_REG);
- ctrl = ctrl | (1 << CI_ENABLE);
- ctrl = ctrl | (1 << ENABLE_CMP_IRQ);
- WRITE_CIBUS_REG(CIPLUS_CTRL_REG, ctrl);
-
- ctrl = 0;
- ctrl = ctrl | (1 << ENABEL_TIMEOUT_IRQ);
- ctrl = ctrl | (TIMEOUT_IRQ_HOLD_TIME << WATT_TIMEOUT_TIME);
- //timeout hold time
- //WRITE_CIBUS_REG(CIPLUS_WAIT_TIMEOUT, ctrl);
- //aml_ci_bus_select_gpio(ci_bus_dev,AML_GPIO_TS);
- return 0;
-}
-/********************************************************/
-/********************************************************/
-/******* gpio api *************/
-/********************************************************/
-/********************************************************/
-/**\brief aml_set_gpio_out:set gio out and set val value
-* \param gpio: gpio_desc obj,
-* \param val: set val
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_set_gpio_out(struct gpio_desc *gpio, int val)
-{
- int ret = 0;
- if (val < 0) {
- pr_dbg("gpio out val = -1.\n");
- return -1;
- }
- if (val != 0)
- val = 1;
- ret = gpiod_direction_output(gpio, val);
- pr_dbg("dvb ci gpio out ret %d set val:%d\n", ret, val);
- return ret;
-}
-
-/**\brief aml_set_gpio_in:set gio in
-* \param gpio: gpio_desc obj,
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_set_gpio_in(struct gpio_desc *gpio)
-{
- gpiod_direction_input(gpio);
- return 0;
-}
-
-/**\brief aml_get_gpio_value:get gio value
-* \param gpio: gpio_desc obj,
-* \return
-* - gpio value:ok
-* - -EINVAL : error
-*/
-static int aml_get_gpio_value(struct gpio_desc *gpio)
-{
- int ret = 0;
- ret = gpiod_get_value(gpio);
- return ret;
-}
-/**\brief aml_gpio_free:free gio
-* \param gpio: gpio_desc obj,
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_gpio_free(struct gpio_desc *gpio)
-{
- gpiod_put(gpio);
- return 0;
-}
-/**\brief ci_bus_get_gpio_by_name:get gpio desc from dts file
-* \param ci_bus_dev: aml_ci_bus obj
-* \param gpiod: gpio_desc * obj
-* \param str: gpio name at dts file
-* \param input_output: gpio input or output type
-* \param output_value: gpio out put value
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int ci_bus_get_gpio_by_name(struct aml_ci_bus *ci_bus_dev,
-struct gpio_desc **gpiod, int *pin_value,
-char *str, int input_output, int output_level)
-{
- int ret = 0;
- struct device_node *child = NULL;
- struct platform_device *pdev = ci_bus_dev->pdev;
- struct device_node *np = pdev->dev.of_node;
-
- /*get gpio config from dts*/
- /* get device config for dvbci_io*/
- child = of_get_child_by_name(np, "dvbci_io");
- if (IS_ERR(*gpiod)) {
- pr_dbg("dvb ci bus %s request failed\n", str);
- return -1;
- }
-
- *pin_value = of_get_named_gpio_flags(child, str, 0, NULL);
- *gpiod = gpio_to_desc(*pin_value);
- if (IS_ERR(*gpiod)) {
- pr_dbg("ci bus %s request failed\n", str);
- return -1;
- }
- pr_dbg("ci bus get_gpio %s %p %d\n", str, *gpiod, *pin_value);
- gpio_request(*pin_value, AML_MODE_NAME);
-
- if (input_output == OUTPUT) {
- ret = gpiod_direction_output(*gpiod, output_level);
- } else if (input_output == INPUT) {
- ret = gpiod_direction_input(*gpiod);
- /*ret |= gpiod_set_pullup(*gpiod, 1);*/
- } else {
- pr_error("ci bus Request gpio direction invalid\n");
- }
- return ret;
-}
-/********************************************************/
-/********************************************************/
-/******* gpio ci bus api end *************/
-/********************************************************/
-/********************************************************/
-/**\brief aml_ci_bus_mem_read:io read from cam
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \param addr: read addr
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_mem_read(
- struct aml_ci *ci_dev, int slot, int addr)
-{
- u8 data = 0;
- u16 addres = addr;
- int value = 0;
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- mutex_lock(&(ci_bus_dev->mutex));
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_ADDR);
- value = aml_ci_bus_io(ci_bus_dev, data, addres, AM_CI_CMD_MEMR);
- mutex_unlock(&(ci_bus_dev->mutex));
- return value;
-}
-/**\brief aml_ci_bus_mem_write:io write to cam by bus api
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \param addr: write addr
-* \param addr: write value
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_mem_write(
- struct aml_ci *ci_dev, int slot, int addr, u8 val)
-{
- u8 data = val;
- u16 addres = addr;
- int value = 0;
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- mutex_lock(&(ci_bus_dev->mutex));
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_ADDR);
- value = aml_ci_bus_io(ci_bus_dev, data, addres, AM_CI_CMD_MEMW);
- mutex_unlock(&(ci_bus_dev->mutex));
- return value;
-}
-/**\brief aml_ci_bus_io_read:io read from cam by bus api
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \param addr: read addr
-* \return
-* - read value:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_io_read(
- struct aml_ci *ci_dev, int slot, int addr)
-{
- u8 data = 0;
- u16 addres = addr;
- int value = 0;
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- mutex_lock(&(ci_bus_dev->mutex));
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_TS);
- value = aml_ci_bus_io(ci_bus_dev, data, addres, AM_CI_CMD_IOR);
- mutex_unlock(&(ci_bus_dev->mutex));
- return value;
-}
-/**\brief aml_ci_bus_io_write:io write to cam
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \param addr: write addr
-* \param addr: write value
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_io_write(
- struct aml_ci *ci_dev, int slot, int addr, u8 val)
-{
- u8 data = val;
- u16 addres = addr;
- int value = 0;
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- mutex_lock(&(ci_bus_dev->mutex));
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_TS);
- value = aml_ci_bus_io(ci_bus_dev, data, addres, AM_CI_CMD_IOW);
- mutex_unlock(&(ci_bus_dev->mutex));
- return value;
-}
-
-
-/**\brief aml_ci_bus_rst:reset cam by ci bus
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_ci_bus_rst(
- struct aml_ci *ci_dev, int slot, int level)
-{
- int value = 0;
- u32 ctrl = 0;
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- mutex_lock(&(ci_bus_dev->mutex));
- ctrl = READ_CIBUS_REG(CIPLUS_CTRL_REG);
- if (level == AML_H)
- ctrl = ctrl | (1 << CAM_RESET);
- else
- ctrl = ctrl & (~(1 << CAM_RESET));
- //Wwrite cmd crtl
- WRITE_CIBUS_REG(CIPLUS_CTRL_REG, ctrl);
- mutex_unlock(&(ci_bus_dev->mutex));
- return value;
-}
-
-/**\brief aml_ci_slot_reset:reset slot
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \return
-* - 0:ok
-* - -EINVAL : error
-*/
-static int aml_ci_slot_reset(struct aml_ci *ci_dev, int slot)
-{
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- pr_dbg("Slot(%d): Slot RESET CAM\n", slot);
- aml_pcmcia_reset(&ci_bus_dev->pc);
- dvb_ca_en50221_cimcu_camready_irq(&ci_dev->en50221_cimcu, 0);
- return 0;
-}
-/**\brief aml_ci_slot_shutdown:show slot
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \return
-* - 0:ok
-* - -EINVAL : error
-* readme:no use this api
-*/
-static int aml_ci_slot_shutdown(struct aml_ci *ci_dev, int slot)
-{
- pr_dbg("Slot(%d): Slot shutdown\n", slot);
- return 0;
-}
-/**\brief aml_ci_ts_control:control slot ts
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \return
-* - 0:ok
-* - -EINVAL : error
-* readme:no use this api
-*/
-static int aml_ci_ts_control(struct aml_ci *ci_dev, int slot)
-{
- pr_dbg("Slot(%d): TS control\n", slot);
- return 0;
-}
-/**\brief aml_ci_slot_status:get slot status
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \param open: no used
-* \return
-* - cam status
-* - -EINVAL : error
-*/
-static int aml_ci_slot_status(struct aml_ci *ci_dev, int slot, int open)
-{
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- int state = 0;
- if (ci_bus_dev->pc.start_work == 0) {
- return 0;
- }
- if (ci_bus_dev->pc.slot_state == MODULE_INSERTED) {
- state = DVB_CA_EN50221_POLL_CAM_PRESENT |
- DVB_CA_EN50221_POLL_CAM_READY;
- }
- if (ci_bus_dev->slot_state != ci_bus_dev->pc.slot_state)
- {
- printk("cam crad change-----\r\n");
- ci_bus_dev->slot_state = ci_bus_dev->pc.slot_state;
- state = state | DVB_CA_EN50221_POLL_CAM_CHANGED;
- }
- return state;
-}
-/**\brief aml_ci_slot_wakeup:get slot wake up thread flag
-* \param ci_dev: aml_ci obj,used this data to get ci_bus_dev obj
-* \param slot: slot index
-* \return
-* - cam wake up flag
-* - -EINVAL : error
-*/
-static int aml_ci_slot_wakeup(struct aml_ci *ci_dev, int slot)
-{
- struct aml_ci_bus *ci_bus_dev = ci_dev->data;
- if (ci_bus_dev) {
- return ci_bus_dev->wakeup_thread;
- }
- return 1;
-}
-
-/**\brief aml_ci_gio_get_irq:get gpio cd1 irq pin value
-* \return
-* - irq pin value
-* - -EINVAL : error
-*/
-static int aml_ci_gio_get_irq(void)
-{
- int ret = 0;
- ret = aml_get_gpio_value(ci_bus.cd_pin1);
- return ret;
-}
-
-/********************************************************/
-/********************************************************/
-/******* for pcmcid api *************/
-/********************************************************/
-/********************************************************/
-/**\brief aml_gio_power:set power gpio hi or low
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \param enable: power pin hi or low
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static int aml_gio_power(struct aml_pcmcia *pc, int enable)
-{
- int ret = 0;
- struct aml_ci_bus *ci_bus_dev = pc->priv;
- if (ci_bus_dev == NULL) {
- pr_dbg("ci bus dev is null %s : %d\r\n", __func__, enable);
- return -1;
- }
- pr_dbg("%s : %d\r\n", __func__, enable);
-
- if (enable == AML_PWR_OPEN) {
- /*hi level ,open power*/
- ret = aml_set_gpio_out(ci_bus_dev->pwr_pin, AML_GPIO_LOW);
- } else {
- /*low level ,close power*/
- ret = aml_set_gpio_in(ci_bus_dev->pwr_pin);
- }
-
- return ret;
-}
-/**\brief aml_gio_reset:set reset gpio hi or low
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \param enable: reset pin hi or low
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static int aml_gio_reset(struct aml_pcmcia *pc, int enable)
-{
- /*need set hi and sleep set low*/
- int ret = 0;
- struct aml_ci_bus *ci_bus_dev = pc->priv;
-
- if (ci_bus_dev == NULL) {
- pr_dbg("ci bus dev is null %s : %d\r\n", __func__, enable);
- return -1;
- }
-
- pr_dbg("%s : %d type: %d\r\n", __func__, enable, ci_bus_dev->io_device_type);
- if (ci_bus_dev == NULL || ci_bus_dev->priv == NULL) {
- pr_dbg("rst by ci bus- ci bus dev-null-\r\n");
- return -1;
- }
- /*if (enable == AML_H) {*/
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_ADDR);
- /*ci_bus_dev->select = AML_GPIO_TS;
- }*/
-
- aml_ci_bus_rst((struct aml_ci *)ci_bus_dev->priv, 0, enable);
- pr_dbg("rst by ci bus- ci bus [%d]-\r\n", ci_bus_dev->select);
- /*if (enable == AML_L)
- aml_ci_bus_select_gpio(ci_bus_dev, AML_GPIO_TS);*/
- return ret;
-}
-
-/**\brief aml_gio_init_irq:set gpio irq
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \param flag: rising or falling or hi or low
-* \return
-* - 0
-* - -EINVAL : error
-*/
-/*need change*/
-static int aml_gio_init_irq(struct aml_pcmcia *pc, int flag)
-{
- struct aml_ci_bus *ci_bus_dev = (struct aml_ci_bus *)pc->priv;
- gpiod_to_irq(ci_bus_dev->cd_pin1);
- return 0;
-}
-
-/**\brief aml_gio_get_cd1:get gpio cd1 pin value
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \return
-* - cd1 pin value
-* - -EINVAL : error
-*/
-static int aml_gio_get_cd1(struct aml_pcmcia *pc)
-{
- int ret = 1;
- struct aml_ci_bus *ci_bus_dev = pc->priv;
- ret = aml_get_gpio_value(ci_bus_dev->cd_pin1);
- pr_dbg("%s :cd: %d\r\n", __func__, ret);
- return ret;
-}
-/**\brief aml_gio_get_cd2:get gpio cd2 pin value
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \return
-* - cd2 pin value
-* - -EINVAL : error
-*/
-static int aml_gio_get_cd2(struct aml_pcmcia *pc)
-{
- int ret = 0;
- struct aml_ci_bus *ci_bus_dev = pc->priv;
- ret = aml_get_gpio_value(ci_bus_dev->cd_pin1);
- pr_dbg("%s :cd: %d\r\n", __func__, ret);
- return ret;
-}
-/**\brief aml_cam_plugin:notify en50221 cam card in or out
-* \param pc: aml_pcmcia obj,used this priv to get ci_bus_dev obj
-* \plugin: 0:remove;1:in
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static int aml_cam_plugin(struct aml_pcmcia *pc, int plugin)
-{
- struct aml_ci *ci = (struct aml_ci *)
- ((struct aml_ci_bus *)(pc->priv))->priv;
- pr_dbg("%s : %d\r\n", __func__, plugin);
- if (plugin) {
- aml_ci_bus_select_gpio((struct aml_ci_bus *)(pc->priv), AML_GPIO_TS);
- dvb_ca_en50221_cimcu_camchange_irq(&ci->en50221_cimcu,
- 0, DVB_CA_EN50221_CAMCHANGE_INSERTED);
- } else {
- aml_ci_bus_select_gpio((struct aml_ci_bus *)(pc->priv), AML_GPIO_ADDR);
- dvb_ca_en50221_cimcu_camchange_irq(&ci->en50221_cimcu,
- 0, DVB_CA_EN50221_CAMCHANGE_REMOVED);
- }
- return 0;
-}
-/**\brief aml_pcmcia_alloc:alloc nad init pcmcia obj
-* \param ci_bus_dev: aml_ci_bus obj,
-* \param pcmcia: aml_pcmcia * obj,
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static void aml_pcmcia_alloc(struct aml_ci_bus *ci_bus_dev,
- struct aml_pcmcia **pcmcia)
-{
- pr_dbg("aml_pcmcia_alloc----\n");
- *pcmcia = &ci_bus_dev->pc;
- (*pcmcia)->irq = ci_bus_dev->irq;
- (*pcmcia)->init_irq = aml_gio_init_irq;
- (*pcmcia)->get_cd1 = aml_gio_get_cd1;
- (*pcmcia)->get_cd2 = aml_gio_get_cd2;
- (*pcmcia)->pwr = aml_gio_power;
- (*pcmcia)->rst = aml_gio_reset;
- (*pcmcia)->pcmcia_plugin = aml_cam_plugin;
- (*pcmcia)->slot_state = MODULE_XTRACTED;
- (*pcmcia)->priv = ci_bus_dev;
- (*pcmcia)->run_type = 0;/*0:irq;1:poll*/
- (*pcmcia)->io_device_type = AML_DVB_IO_TYPE_CIMAX;
- (*pcmcia)->start_work = 0;
-}
-
-/**\brief aml_ci_bus_get_config_from_dts:
- * get gpio config from dts
-* \param ci_bus_dev: aml_ci_bus obj,
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static int aml_ci_bus_get_config_from_dts(struct aml_ci_bus *ci_bus_dev)
-{
- struct device_node *child = NULL;
- struct platform_device *pdev = ci_bus_dev->pdev;
- struct device_node *np = pdev->dev.of_node;
- int ret = 0;
- pr_dbg("into get ci bus dts -----\r\n");
- /*get gpio config from dts*/
- /* get device config for dvbci_io*/
- child = of_get_child_by_name(np, "dvbci_io");
- if (child == NULL) {
- pr_error("failed to get dvbci_io\n");
- return -1;
- }
- //below is get cd1 cd2 pwr irq reset gpio info
- if (ci_bus_dev->io_device_type == AML_DVB_IO_TYPE_CIBUS) {
- struct resource *res;
- char buf[32];
- int ival;
-
- /*get irq value*/
- ci_bus_dev->irq_cmp = 186;
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "%s", "irq_cmp");
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, buf);
- if (res)
- ci_bus_dev->irq_cmp = res->start;
- else
- pr_err("get irq cmp error\r\n");
-
- ci_bus_dev->irq_timeout = 187;
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "%s", "irq_timeout");
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, buf);
- if (res)
- ci_bus_dev->irq_timeout = res->start;
- else
- pr_err("get irq irq_timeout error\r\n");
- //pin config
- pr_dbg("ci bus irq[%d]cmp[%d] \r\n",ci_bus_dev->irq_cmp, ci_bus_dev->irq_timeout);
- if (!ci_bus_dev->pinctrl) {
- ci_bus_dev->pinctrl = devm_pinctrl_get(&pdev->dev);
- if (IS_ERR_OR_NULL(ci_bus_dev->pinctrl)) {
- pr_error("get pinctl could not get pinctrl handle\n");
- return -EINVAL;
- }
- }
-
- if (ci_bus_dev->pinctrl) {
- struct pinctrl_state *s;
- pr_dbg("ci bus get ts pin\r\n");
- s = pinctrl_lookup_state(ci_bus_dev->pinctrl, "ci_ts_pins");
- if (IS_ERR_OR_NULL(s)) {
- pr_error("could not get jtag_apee_pins state\n");
- return -1;
- }
- pr_dbg("ci bus select ts pin\r\n");
- ret = pinctrl_select_state(ci_bus_dev->pinctrl, s);
- if (ret) {
- pr_error("failed to set pinctrl\n");
- return -1;
- }
- ci_bus_dev->select = AML_GPIO_TS;
- } else if (IS_ERR_OR_NULL(ci_bus_dev->pinctrl)) {
- pr_error("could not get pinctrl handle\n");
- return -EINVAL;
- }
- /*get reset pwd cd1 cd2 gpio pin*/
- ci_bus_dev->cd_pin1 = NULL;
- pr_dbg("ci bus get cd1\r\n");
- ret = ci_bus_get_gpio_by_name(ci_bus_dev,
- &ci_bus_dev->cd_pin1,
- &ci_bus_dev->cd_pin1_value, "cd_pin1",
- INPUT, OUTLEVEL_HIGH);
- if (ret) {
- pr_error("dvb ci cd_pin1 pin request failed\n");
- return -1;
- }
- ci_bus_dev->cd_pin2 = ci_bus_dev->cd_pin1;
- ci_bus_dev->cd_pin2_value = ci_bus_dev->cd_pin1_value;
- ci_bus_dev->pwr_pin = NULL;
- pr_dbg("ci_bus_dev->cd_pin1_value==%d\r\n", ci_bus_dev->cd_pin1_value);
- ci_bus_dev->irq = gpiod_to_irq(ci_bus_dev->cd_pin1) ;
- pr_dbg("ci_bus_dev->irq==%d get from gpio cd1\r\n", ci_bus_dev->irq);
-
- ret = ci_bus_get_gpio_by_name(ci_bus_dev,
- &ci_bus_dev->pwr_pin, &ci_bus_dev->pwr_pin_value,
- "pwr_pin", OUTPUT, OUTLEVEL_HIGH);
- if (ret) {
- pr_error("dvb ci pwr_pin pin request failed\n");
- return -1;
- }
- aml_set_gpio_in(ci_bus_dev->pwr_pin);
-
- /*get le pin*/
- ci_bus_dev->le_pin = NULL;
- ci_bus_dev->le_enable_level = 1;
- ret = ci_bus_get_gpio_by_name(ci_bus_dev,
- &ci_bus_dev->le_pin, &ci_bus_dev->le_pin_value,
- "le_pin", OUTPUT, OUTLEVEL_HIGH);
- if (ret) {
- pr_error("dvb ci le_pin pin request failed\n");
- } else {
- pr_dbg("ci_bus_dev->le_value %d\n", ci_bus_dev->le_pin_value);
- }
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "%s", "le_enable_level");
- ret = of_property_read_u32(pdev->dev.of_node, buf, &ival);
- if (ret) {
- pr_error("dvb ci le_enable_level request failed\n");
- } else {
- ci_bus_dev->le_enable_level = ival;
- pr_dbg("ci_bus_dev->le_enable_level-- %d\n", ci_bus_dev->le_enable_level);
- }
- /*get addr_ts_mode_multiplex mode*/
- ci_bus_dev->addr_ts_mode_multiplex = 1;
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "%s", "addr_ts_mode_multiplex");
- ret = of_property_read_u32(pdev->dev.of_node, buf, &ival);
- if (ret) {
- pr_error("dvb ci addr_ts_mode_multiplex request failed\n");
- } else {
- ci_bus_dev->addr_ts_mode_multiplex = ival;
- pr_dbg("ci_bus_dev->addr_ts_mode_multiplex %d ******\n", ci_bus_dev->addr_ts_mode_multiplex);
- }
-
-
- }
- return 0;
-}
-/**\brief aml_ci_free_gpio:free ci gpio
-* \param ci_bus_dev: aml_ci_bus obj,
-* \return
-* - 0
-* - -EINVAL : error
-*/
-static void aml_ci_free_gpio(struct aml_ci_bus *ci_bus_dev)
-{
- if (ci_bus_dev == NULL) {
- pr_error("ci_bus_dev is NULL,no need free gpio res\r\n");
- return;
- }
-
- if (ci_bus_dev->pwr_pin) {
- aml_gpio_free(ci_bus_dev->pwr_pin);
- ci_bus_dev->pwr_pin = NULL;
- }
- if (ci_bus_dev->cd_pin1) {
- aml_gpio_free(ci_bus_dev->cd_pin1);
- ci_bus_dev->cd_pin1 = NULL;
- ci_bus_dev->cd_pin2 = NULL;
- }
- if (ci_bus_dev->le_pin) {
- aml_gpio_free(ci_bus_dev->le_pin);
- ci_bus_dev->le_pin = NULL;
- }
- return;
-}
-
-static irqreturn_t timeout_isr(int irq, void *dev_id)
-{
- u32 int_status = READ_CIBUS_REG(CIPLUS_STATUS_REG);
-
- if ((int_status & (1 << TIMEOUT_IRQ_STATE)) == (1 << TIMEOUT_IRQ_STATE)) {
- fetch_done = 1;
- wake_up_interruptible(&wq);
- }
- return IRQ_HANDLED;
-}
-
-static irqreturn_t cmp_isr(int irq, void *dev_id)
-{
- u32 int_status = READ_CIBUS_REG(CIPLUS_STATUS_REG);
-
- if ((int_status&(1 << COMPLETE_IRQ_STATE)) == (1 << COMPLETE_IRQ_STATE)) {
- fetch_done = 1;
- wake_up_interruptible(&wq);
- }
- return IRQ_HANDLED;
-}
-
-/**\brief aml_ci_bus_init:ci_bus_dev init
-* \param ci_dev: aml_ci obj,
-* \param pdev: platform_device obj,used to get dts info
-* \return
-* - 0
-* - -EINVAL : error
-*/
-int aml_ci_bus_init(struct platform_device *pdev, struct aml_ci *ci_dev)
-{
- struct aml_ci_bus *ci_bus_dev = NULL;
- struct aml_pcmcia *pc;
- int result,irq;
-
- ci_bus_dev = &ci_bus;
- ci_bus_dev->pdev = pdev;
- ci_bus_dev->priv = ci_dev;
- ci_bus_dev->bus_pinctrl = NULL;
- ci_bus_dev->pinctrl = NULL;
- /*default mode is wake up,when trans a lot data,used sleep mode*/
- ci_bus_dev->wakeup_thread = 1;
- mutex_init(&(ci_bus_dev->mutex));
- /*init io device type*/
- ci_bus_dev->io_device_type = ci_dev->io_type;
- pr_dbg("*********ci bus Dev type [%d]\n", ci_dev->io_type);
- /*get config from dts*/
- aml_ci_bus_get_config_from_dts(ci_bus_dev);
- //iomap ci reg
- init_ci_addr(pdev);
- /*Register irq handlers */
- if (ci_bus_dev->irq_cmp != -1) {
- if (USED_IRQ) {
- irq = request_irq(ci_bus_dev->irq_cmp,
- cmp_isr,
- IRQF_SHARED|IRQF_TRIGGER_RISING,
- "ciplus cmp irq", ci_bus_dev);
- if (irq == 0)
- pr_dbg("request cmp irq sucess\r\n");
- else if (irq == -EBUSY)
- pr_err("request cmp irq busy\r\n");
- else
- pr_err("request cmp irq error [%d]\r\n", irq);
- } else {
- disable_irq(ci_bus_dev->irq_cmp);
- }
- }
- /*Register irq handlers */
- if (ci_bus_dev->irq_timeout != -1) {
- if (USED_IRQ) {
- pr_dbg("request timeout irq\n");
- irq = request_irq(ci_bus_dev->irq_timeout,
- timeout_isr,
- IRQF_SHARED|IRQF_TRIGGER_RISING,
- "ciplus timeout irq", ci_bus_dev);
- if (irq == 0)
- pr_err("request timeout irq sucess\r\n");
- else if (irq == -EBUSY)
- pr_err("request timeout irq busy\r\n");
- else
- pr_err("request timeout irq error [%d]\r\n", irq);
- } else {
- disable_irq(ci_bus_dev->irq_timeout);
- }
- }
- pr_dbg("*********ci bus init bus reg\n");
- aml_ci_bus_init_reg(ci_bus_dev);
- /*init ci_dev used api.*/
- ci_dev->ci_mem_read = aml_ci_bus_mem_read;
- ci_dev->ci_mem_write = aml_ci_bus_mem_write;
- ci_dev->ci_io_read = aml_ci_bus_io_read;
- ci_dev->ci_io_write = aml_ci_bus_io_write;
- ci_dev->ci_slot_reset = aml_ci_slot_reset;
- ci_dev->ci_slot_shutdown = aml_ci_slot_shutdown;
- ci_dev->ci_slot_ts_enable = aml_ci_ts_control;
- ci_dev->ci_poll_slot_status = aml_ci_slot_status;
- ci_dev->ci_get_slot_wakeup = aml_ci_slot_wakeup;
- ci_dev->data = ci_bus_dev;
-
- aml_pcmcia_alloc(ci_bus_dev, &pc);
- pc->io_device_type = ci_bus_dev->io_device_type;
- pr_dbg("*********ci bus aml_pcmcia_init start_work:%d\n", pc->start_work);
- result = aml_pcmcia_init(pc);
- if (result < 0) {
- pr_error("aml_pcmcia_init failed\n");
- goto fail1;
- }
- pr_dbg("*********ci bus aml_ci_bus_mod_init---\n");
- aml_ci_bus_mod_init();
- return 0;
-fail1:
- kfree(ci_bus_dev);
- ci_bus_dev = NULL;
- return 0;
-}
-EXPORT_SYMBOL(aml_ci_bus_init);
-/**\brief aml_ci_bus_exit:ci_bus exit
-* \return
-* - 0
-* - -EINVAL : error
-*/
-int aml_ci_bus_exit(struct aml_ci *ci)
-{
- aml_ci_bus_mod_exit();
- /*exit pc card*/
- aml_pcmcia_exit(&ci_bus.pc);
- /*free gpio*/
- aml_ci_free_gpio(&ci_bus);
-
- return 0;
-}
-EXPORT_SYMBOL(aml_ci_bus_exit);
-
-#if 1
-/********************************************************/
-/********************************************************/
-/******* for ci bus test api *************/
-/********************************************************/
-/********************************************************/
-
-/*cam difines*/
-#define DA 0x80
-#define FR 0x40
-#define WE 0x02
-#define RE 0x01
-
-#define RS 0x08
-#define SR 0x04
-#define SW 0x02
-#define HC 0x01
-#define DATA_REG 0
-#define COM_STA_REG 1
-#define SIZE_REG_L 2
-#define SIZE_REG_M 3
-
-static void aml_ci_bus_full_test(struct aml_ci *ci_dev)
-{
- unsigned int BUF_SIZE = 0;
- unsigned int i = 0;
- unsigned char cc = 0;
- unsigned char reg;
- unsigned int bsize = 0;
- int cnt = 0;
- unsigned char buf[10];
- int count = 1000;
- mdelay(1000);
- pr_dbg("READ CIS START\r\n");
- for (i = 0; i < 200; i++) {
- mdelay(100);
- cc = aml_ci_bus_mem_read(ci_dev, 0, i);
- pr_dbg("0x%x ", cc);
- if ((i + 1) % 16 == 0)
- pr_dbg(" \r\n");
- }
- pr_dbg("READ CIS OVER\r\n");
- mdelay(1000);
- pr_dbg("SW rst CAM...\r\n");
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, RS);
- pr_dbg("SW rst over.\r\n");
- pr_dbg("-----------------------------------\r\n");
- pr_dbg("TO delay 2000ms\r\n");
- mdelay(2000);
- pr_dbg("\r\n");
- pr_dbg("--------------clear rs--!!!-YOU MUST CLEAR RS BIT--no sleep--------\r\n");
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, 0);
- pr_dbg("--------------sleep---------------------\r\n");
- mdelay(2000);
- pr_dbg("TO check sw-rst is OK\r\n");
- pr_dbg("start read fr \r\n");
- if (1) {
- unsigned char reg;
- unsigned char reg1;
- int count1 = 4000;
- while (1) {
- mdelay(20);
- count1--;
- reg1 = aml_ci_bus_io_read(
- ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg1)) {
- continue;
- } else {
- pr_dbg("CAM Reset Ok\r\n");
- break;
- }
- }
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- pr_dbg("STA_REG = 0x%2.2x\r\n", reg);
- if (FR & reg) {
- pr_dbg("SW-RST is OK!\r\n");
- } else {
- pr_dbg("SW-RST is ERR!\r\n");
- goto end;
- }
- }
-end:
- pr_dbg("TO check sw-rst over.\r\n");
- pr_dbg("\r\n");
- pr_dbg("-----------------------------------\r\n");
- pr_dbg("TO buffer size negotiation protocol...\r\n");
- pr_dbg("Get which buf size CAM can support\r\n");
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, SR);
- mdelay(1000);
- while (1) {
-
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if ((reg & DA) == DA) {
- pr_dbg("Buffer negotiate size date avalible.\r\n");
- break;
- } else {
- /*pr_dbg("Buffer negotiate
- size date NOT avalible\r\n");*/
- continue;
- }
- mdelay(100);
- }
- cnt = (aml_ci_bus_io_read(ci_dev, 0, SIZE_REG_L)) +
- ((aml_ci_bus_io_read(ci_dev, 0, SIZE_REG_M)) * 256);
- pr_dbg("Moudle have <%d> Bytes send to host.\r\n", cnt);
- if (cnt != 2) {
- pr_dbg("The Bytes will be tx is ERR!\r\n");
- return;
- }
- for (i = 0; i < cnt; i++)
- buf[i] = aml_ci_bus_io_read(ci_dev, 0, DATA_REG);
-
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (RE == (RE & reg)) {
- pr_dbg("(1)Read CAM buf size ERR!\r\n");
- return;
- }
- aml_ci_bus_io_write(ci_dev, 0, (COM_STA_REG), 0);
-
- mdelay(1000);
-
- while (count--) {
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg)) {
- pr_dbg("CAM is busy 2, waiting...\r\n");
- continue;
- } else {
- pr_dbg("CAM is OK 2.\r\n");
- break;
- }
- }
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg)) {
- pr_dbg("(2)Read CAM buf size ERR!-\r\n");
- return;
- }
- bsize = (buf[0] * 256) + buf[1];
-
- pr_dbg("CAM can support buf size is: <%d>B\r\n", bsize);
-
- pr_dbg("Tell CAM which size buf is be used\r\n");
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg))
- pr_dbg("CAM is busy, waiting free\r\n");
- while (1) {
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg)) {
- pr_dbg("CAM is busy 3, waiting\r\n");
- continue;
- } else {
- pr_dbg("CAM is OK 3\r\n");
- break;
- }
- }
-
- bsize = bsize - 0;
- BUF_SIZE = bsize;
- pr_dbg("We will use this buf size: <%d>B\r\n", bsize);
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, SW);
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg))
- pr_dbg("CAM is busy, waiting\r\n");
-
- while (1) {
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (FR != (FR & reg)) {
- pr_dbg("CAM is busy 4, waiting\r\n");
- continue;
- } else {
- pr_dbg("CAM is OK 4\r\n");
- break;
- }
- }
- /*SHOULD CHECK DA!!!!!*/
- /*PLS ADD THIS CHECK CODE:*/
- pr_dbg("PRIOR to check CAM'S DA\r\n");
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if ((reg & DA) == DA) {
- pr_dbg("CAM have data send to HOST\r\n");
- return;
- }
-
-
- buf[0] = (unsigned char)((bsize >> 8) & 0xff);
- buf[1] = (unsigned char)(bsize & 0xff);
-
- while (1) {
- mdelay(10);
- aml_ci_bus_io_write(ci_dev,
- 0, COM_STA_REG, HC | SW);
- mdelay(100);
- reg = aml_ci_bus_io_read(ci_dev,
- 0, COM_STA_REG);
- if (FR != (FR & reg)) {
- pr_dbg("CAM is busy 5, waiting\r\n");
- aml_ci_bus_io_write(ci_dev,
- 0, COM_STA_REG, SW);
- continue;
- } else {
- pr_dbg("CAM is OK 5\r\n");
- break;
- }
- }
- pr_dbg("<2> Bytes send to CAM\r\n");
- aml_ci_bus_io_write(ci_dev, 0, SIZE_REG_M, 0);
- aml_ci_bus_io_write(ci_dev, 0, SIZE_REG_L, 2);
- for (i = 0; i < 2; i++)
- aml_ci_bus_io_write(ci_dev, 0, DATA_REG, buf[i]);
-
- reg = aml_ci_bus_io_read(ci_dev, 0, COM_STA_REG);
- if (WE == (WE & reg)) {
- pr_dbg("Write CAM ERR!\r\n");
- return;
- } else {
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, SW);
- mdelay(100);
- aml_ci_bus_io_write(ci_dev, 0, COM_STA_REG, 0);
- pr_dbg("Buffer size negotiation over!\r\n");
- pr_dbg("NOW, HOST can communicates with CAM\r\n");
- pr_dbg("NOW, TEST END\r\n");
- }
-}
-
-/**
-* Read a tuple from attribute memory.
-*
-* @param ca CA instance.
-* @param slot Slot id.
-* @param address Address to read from. Updated.
-* @param tupleType Tuple id byte. Updated.
-* @param tupleLength Tuple length. Updated.
-* @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
-*
-* @return 0 on success, nonzero on error.
-*/
-static int dvb_ca_en50221_read_tuple(
-int *address, int *tupleType, int *tupleLength, u8 *tuple)
-{
- int i;
- int _tupleType;
- int _tupleLength;
- int _address = *address;
-
- /* grab the next tuple length and type */
- _tupleType = aml_ci_bus_mem_read((struct aml_ci *)
- ci_bus.priv, 0, _address);
- if (_tupleType < 0)
- return _tupleType;
- if (_tupleType == 0xff) {
- pr_dbg("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
- *address += 2;
- *tupleType = _tupleType;
- *tupleLength = 0;
- return 0;
- }
- _tupleLength = aml_ci_bus_mem_read((struct aml_ci *)
- ci_bus.priv, 0, _address + 2);
- if (_tupleLength < 0)
- return _tupleLength;
- _address += 4;
-
- pr_dbg("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
-
- /* read in the whole tuple */
- for (i = 0; i < _tupleLength; i++) {
- tuple[i] = aml_ci_bus_mem_read((struct aml_ci *)
- ci_bus.priv, 0, _address + (i * 2));
- pr_dbg(" 0x%02x: 0x%02x %c\n",
- i, tuple[i] & 0xff,
- ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
- }
- _address += (_tupleLength * 2);
-
- /* success */
- *tupleType = _tupleType;
- *tupleLength = _tupleLength;
- *address = _address;
- return 0;
-}
-static char *findstr(char *haystack, int hlen, char *needle, int nlen)
-{
- int i;
-
- if (hlen < nlen)
- return NULL;
-
- for (i = 0; i <= hlen - nlen; i++) {
- if (!strncmp(haystack + i, needle, nlen))
- return haystack + i;
- }
-
- return NULL;
-}
-
-/**
-* Parse attribute memory of a CAM module, extracting Config register, and checking
-* it is a DVB CAM module.
-*
-* @param ca CA instance.
-* @param slot Slot id.
-*
-* @return 0 on success, <0 on failure.
-*/
-static int dvb_ca_en50221_parse_attributes(void)
-{
- int address = 0;
- int tupleLength;
- int tupleType;
- u8 tuple[257];
- char *dvb_str;
- int rasz;
- int status;
- int got_cftableentry = 0;
- int end_chain = 0;
- int i;
- u16 manfid = 0;
- u16 devid = 0;
- int config_base = 0;
- int config_option;
-
- /* CISTPL_DEVICE_0A */
- status = dvb_ca_en50221_read_tuple(&address,
- &tupleType, &tupleLength, tuple);
- if (status < 0) {
- pr_error("read status error\r\n");
- return status;
- }
- if (tupleType != 0x1D) {
- pr_error("read tupleType error [0x%x]\r\n", tupleType);
- return -EINVAL;
- }
-
- /* CISTPL_DEVICE_0C */
- status = dvb_ca_en50221_read_tuple(&address,
- &tupleType, &tupleLength, tuple);
- if (status < 0) {
- pr_error("read read cis error\r\n");
- return status;
- }
- if (tupleType != 0x1C) {
- pr_error("read read cis type error\r\n");
- return -EINVAL;
- }
-
- /* CISTPL_VERS_1 */
- status = dvb_ca_en50221_read_tuple(&address,
- &tupleType, &tupleLength, tuple);
- if (status < 0) {
- pr_error("read read cis version error\r\n");
- return status;
- }
- if (tupleType != 0x15) {
- pr_error("read read cis version type error\r\n");
- return -EINVAL;
- }
-
- /* CISTPL_MANFID */
- status = dvb_ca_en50221_read_tuple(&address, &tupleType,
- &tupleLength, tuple);
- if (status < 0) {
- pr_error("read read cis manfid error\r\n");
- return status;
- }
- if (tupleType != 0x20) {
- pr_error("read read cis manfid type error\r\n");
- return -EINVAL;
- }
- if (tupleLength != 4) {
- pr_error("read read cis manfid len error\r\n");
- return -EINVAL;
- }
- manfid = (tuple[1] << 8) | tuple[0];
- devid = (tuple[3] << 8) | tuple[2];
-
- /* CISTPL_CONFIG */
- status = dvb_ca_en50221_read_tuple(&address, &tupleType,
- &tupleLength, tuple);
- if (status < 0) {
- pr_error("read read cis config error\r\n");
- return status;
- }
- if (tupleType != 0x1A) {
- pr_error("read read cis config type error\r\n");
- return -EINVAL;
- }
- if (tupleLength < 3) {
- pr_error("read read cis config len error\r\n");
- return -EINVAL;
- }
-
- /* extract the configbase */
- rasz = tuple[0] & 3;
- if (tupleLength < (3 + rasz + 14)) {
- pr_error("read extract the configbase error\r\n");
- return -EINVAL;
- }
-
- for (i = 0; i < rasz + 1; i++)
- config_base |= (tuple[2 + i] << (8 * i));
-
- /* check it contains the correct DVB string */
- dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8);
- if (dvb_str == NULL) {
- pr_error("find dvb str DVB_CI_V error\r\n");
- return -EINVAL;
- }
- if (tupleLength < ((dvb_str - (char *) tuple) + 12)) {
- pr_error("find dvb str DVB_CI_V len error\r\n");
- return -EINVAL;
- }
-
- /* is it a version we support? */
- if (strncmp(dvb_str + 8, "1.00", 4)) {
- pr_error(" Unsupported DVB CAM module version %c%c%c%c\n",
- dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
- return -EINVAL;
- }
-
- /* process the CFTABLE_ENTRY tuples, and any after those */
- while ((!end_chain) && (address < 0x1000)) {
- status = dvb_ca_en50221_read_tuple(&address, &tupleType,
- &tupleLength, tuple);
- if (status < 0) {
- pr_error("process the CFTABLE_ENTRY tuples error\r\n");
- return status;
- }
-
- switch (tupleType) {
- case 0x1B: /* CISTPL_CFTABLE_ENTRY */
- if (tupleLength < (2 + 11 + 17))
- break;
-
- /* if we've already parsed one, just use it */
- if (got_cftableentry)
- break;
-
- /* get the config option */
- config_option = tuple[0] & 0x3f;
-
- /* OK, check it contains the correct strings */
- if ((findstr((char *)tuple,
- tupleLength, "DVB_HOST", 8) == NULL) ||
- (findstr((char *)tuple,
- tupleLength, "DVB_CI_MODULE", 13) == NULL))
- break;
-
- got_cftableentry = 1;
- break;
-
- case 0x14: /* CISTPL_NO_LINK*/
- break;
-
- case 0xFF: /* CISTPL_END */
- end_chain = 1;
- break;
-
- default:
- /* Unknown tuple type - just skip
- *this tuple and move to the next one
- */
- pr_error("Skipping unknown tupletype:0x%x L:0x%x\n",
- tupleType, tupleLength);
- break;
- }
- }
-
- if ((address > 0x1000) || (!got_cftableentry)) {
- pr_error("got_cftableentry :%d\r\n", got_cftableentry);
- return -EINVAL;
- }
-
- pr_error("----------ci cis ok------\r\n");
- return 0;
-}
-
-static ssize_t reset_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = sprintf(buf, "echo 1 > %s\n\t", attr->attr.name);
- return ret;
-}
-
-static ssize_t reset_store(struct class *class,
-struct class_attribute *attr, const char *buf, size_t size)
-{
- int ret;
- struct aml_ci *ci = (struct aml_ci *)ci_bus.priv;
- ret = aml_ci_slot_reset(ci, 0);
- return size;
-}
-static CLASS_ATTR_RW(reset);
-static ssize_t pwr_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = sprintf(buf, "echo 1|0> %s\n\t", attr->attr.name);
- return ret;
-}
-
-static ssize_t pwr_store(struct class *class,
-struct class_attribute *attr, const char *buf, size_t size)
-{
- int ret = 0;
- int enable = 0;
- long value;
- if (kstrtol(buf, 0, &value) == 0)
- enable = (int)value;
- ret = aml_gio_power(&ci_bus.pc, enable);
- return size;
-}
-
-static CLASS_ATTR_RW(pwr);
-
-static ssize_t start_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = sprintf(buf, "start:%d\n", ci_bus.pc.start_work);
- return ret;
-}
-
-static ssize_t start_store(struct class *class,
-struct class_attribute *attr, const char *buf, size_t size)
-{
- int enable = 0;
- long value;
- if (kstrtol(buf, 0, &value) == 0) {
- enable = (int)value;
- ci_bus.pc.start_work = enable;
- printk("start set start\n");
- aml_pcmcia_detect_cam(&ci_bus.pc);
- }
- return size;
-}
-
-static CLASS_ATTR_RW(start);
-
-static ssize_t wakeup_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = sprintf(buf, "wakeup:%d\n", ci_bus.wakeup_thread);
- return ret;
-}
-
-static ssize_t wakeup_store(struct class *class,
-struct class_attribute *attr, const char *buf, size_t size)
-{
- int enable = 0;
- long value;
- if (kstrtol(buf, 0, &value) == 0) {
- enable = (int)value;
- ci_bus.wakeup_thread = enable;
- printk("wakeup is set\n");
- }
- return size;
-}
-
-static CLASS_ATTR_RW(wakeup);
-
-static ssize_t status_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- struct aml_ci *ci = (struct aml_ci *)ci_bus.priv;
- ret = aml_ci_slot_status(ci, 0, 0);
- ret = sprintf(buf, "%s: %d;\n\t", attr->attr.name, ret);
- return ret;
-}
-static CLASS_ATTR_RO(status);
-
-static ssize_t irq_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = aml_ci_gio_get_irq();
- ret = sprintf(buf, "%s irq: %d\n\t", attr->attr.name, ret);
- return ret;
-}
-static CLASS_ATTR_RO(irq);
-
-static ssize_t iotest_show(struct class *class,
-struct class_attribute *attr, char *buf)
-{
- int ret;
- ret = sprintf(buf, "echo (r|w|f|c)(i|a) addr data > %s\n",
- attr->attr.name);
- return ret;
-}
-
-static ssize_t iotest_store(struct class *class,
-struct class_attribute *attr, const char *buf, size_t size)
-{
- int n = 0;
- int i = 0;
- char *buf_orig, *ps, *token;
- char *parm[3];
- unsigned int addr = 0, val = 0, retval = 0;
- long value = 0;
- struct aml_ci *ci = (struct aml_ci *)ci_bus.priv;
- buf_orig = kstrdup(buf, GFP_KERNEL);
- ps = buf_orig;
- while (1) {
- /*need set '\n' to ' \n'*/
- token = strsep(&ps, " ");
- if (token == NULL)
- break;
- if (*token == '\0')
- continue;
- parm[n++] = token;
- }
-
- if (!n || ((n > 0) && (strlen(parm[0]) != 2))) {
- pr_err("invalid command n[%x]p[%x][%s]\n", n,(int)strlen(parm[0]),parm[0]);
- kfree(buf_orig);
- return size;
- }
-
- if ((parm[0][0] == 'r')) {
- if (n > 2) {
- pr_err("read: invalid parameter\n");
- kfree(buf_orig);
- return size;
- }
- if (kstrtol(parm[1], 0, &value) == 0)
- addr = (int)value;
- pr_err("%s 0x%x\n", parm[0], addr);
- switch ((char)parm[0][1]) {
- case 'i':
- for (i = 0; i < 1000; i++)
- retval = aml_ci_bus_io_read(ci, 0, addr);
- break;
- case 'a':
- for (i = 0; i < 1000; i++)
- retval = aml_ci_bus_mem_read(ci, 0, addr);
- break;
- default:
- break;
- }
- pr_dbg("%s: 0x%x --> 0x%x\n", parm[0], addr, retval);
- } else if ((parm[0][0] == 'w')) {
- if (n != 3) {
- pr_err("write: invalid parameter\n");
- kfree(buf_orig);
- return size;
- }
- if (kstrtol(parm[1], 0, &value) == 0)
- addr = (int)value;
- if (kstrtol(parm[2], 0, &value) == 0)
- val = (int)value;
-
- pr_err("%s 0x%x 0x%x", parm[0], addr, val);
- switch ((char)parm[0][1]) {
- case 'i':
- retval = aml_ci_bus_io_write(ci, 0, addr, val);
- break;
- case 'a':
- retval = aml_ci_bus_mem_write(ci, 0, addr, val);
- break;
- default:
- break;
- }
- pr_dbg("%s: 0x%x <-- 0x%x\n", parm[0], addr, retval);
- } else if ((parm[0][0] == 'f')) {
- pr_dbg("full test----\r\n");
- aml_ci_bus_full_test(ci);
- } else if ((parm[0][0] == 'p')) {
- pr_dbg("cis dvb_ca_en50221_parse_attributes----\r\n");
- dvb_ca_en50221_parse_attributes();
- }
-
- kfree(buf_orig);
- return size;
-}
-
-static CLASS_ATTR_RW(iotest);
-
-static struct attribute *aml_ci_bus_attrs[] = {
- &class_attr_iotest.attr,
- &class_attr_status.attr,
- &class_attr_irq.attr,
- &class_attr_reset.attr,
- &class_attr_pwr.attr,
- &class_attr_start.attr,
- &class_attr_wakeup.attr,
- NULL
-};
-
-ATTRIBUTE_GROUPS(aml_ci_bus);
-
-
-int aml_ci_bus_mod_init(void)
-{
- int ret;
- struct class *clp;
- #define CLASS_NAME_LEN 48
- pr_dbg("Amlogic DVB CI BUS Init\n");
-
- clp = &(ci_bus.cls);
-
- clp->name = kzalloc(CLASS_NAME_LEN, GFP_KERNEL);
- if (!clp->name)
- return -ENOMEM;
-
- snprintf((char *)clp->name, CLASS_NAME_LEN, "aml_ci_bus_%s", "test");
- clp->owner = THIS_MODULE;
- clp->class_groups = aml_ci_bus_groups;
- ret = class_register(clp);
- if (ret)
- kfree(clp->name);
- return 0;
-}
-
-void aml_ci_bus_mod_exit(void)
-{
- pr_dbg("Amlogic DVB CI BUS Exit\n");
- class_unregister(&(ci_bus.cls));
-}
-
-#endif
-#if 0
-module_init(aml_ci_bus_mod_init);
-module_exit(aml_ci_bus_mod_exit);
-
-MODULE_LICENSE("GPL");
-#endif
diff --git a/drivers/stream_input/parser/dvb_ci/aml_ci_bus.h b/drivers/stream_input/parser/dvb_ci/aml_ci_bus.h
deleted file mode 100644
index e238253..0000000
--- a/drivers/stream_input/parser/dvb_ci/aml_ci_bus.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef __AML_CI_BUS_H_
-#define __AML_CI_BUS_H_
-
-#include <linux/amlogic/iomap.h>
-#include <linux/amlogic/aml_gpio_consumer.h>
-#include <linux/gpio/consumer.h>
-#include "aml_pcmcia.h"
-#include "aml_ci.h"
-#include "dvb_ca_en50221.h"
-
-/*
-aml spi dev
-*/
-struct aml_ci_bus {
- struct mutex mutex;
- struct class cls;
- /* add gpio pin */
- struct gpio_desc *cd_pin1;
- int cd_pin1_value;
- struct gpio_desc *cd_pin2;
- int cd_pin2_value;
- struct gpio_desc *pwr_pin;
- int pwr_pin_value;
- struct gpio_desc *le_pin;
- int le_pin_value;
- int le_enable_level;
- int addr_ts_mode_multiplex;
- /* cam irq */
- int irq;
- int irq_cmp;
- int irq_timeout;
- struct aml_pcmcia pc;
- void *priv;
- /*device type*/
- int io_device_type;
- /*select gpio group*/
- int select;
- struct pinctrl *pinctrl;
- struct pinctrl *bus_pinctrl;
- struct platform_device *pdev;
- /*save cam cur state*/
- enum aml_slot_state slot_state;
- /*wake up thread mode at cimcu thread*/
- int wakeup_thread;
-};
-
-enum aml_gpio_select_e {
- AML_GPIO_ADDR = 0,
- AML_GPIO_TS,
-};
-
-#define IORD 0x0
-#define IOWR 0x1
-#define MEMRD 0x2
-#define MEMWR 0x3
-
-//24M cyccles, 42 ns
-#define CYCLES (42)
-//mem rd
-#define DELAY_RMEM_INIT_ADDR (0)
-#define DELAY_RMEM_ADDR_CE (0)
-#define DELAY_RMEM_CE_RD (3)
-#define DELAY_RMEM_RD_RWAIT (0)
-#define DELAY_RMEM_RWAIT_DATA (0)
-#define DELAY_RMEM_DATA_DRD (0)
-#define DELAY_RMEM_DRD_DCE (0)
-#define DELAY_RMEM_DCE_INIT (0)
-//mem wr
-#define DELAY_WMEM_INIT_ADDR (0)
-#define DELAY_WMEM_ADDR_CE (1)
-#define DELAY_WMEM_CE_WR (1)
-#define DELAY_WMEM_WR_RWAIT (0)
-#define DELAY_WMEM_RWAIT_DATA (0)
-#define DELAY_WMEM_DATA_DWR (0)
-#define DELAY_WMEM_DWR_DCE (1)
-#define DELAY_WMEM_DCE_INIT (1)
-//iord
-#define DELAY_RIO_INIT_ADDR (0)
-#define DELAY_RIO_ADDR_CE (0)
-#define DELAY_RIO_CE_RD (2)
-#define DELAY_RIO_RD_RWAIT (0)
-#define DELAY_RIO_RWAIT_DATA (0)
-#define DELAY_RIO_DATA_DRD (0)
-#define DELAY_RIO_DRD_DCE (0)
-#define DELAY_RIO_DCE_INIT (0)
-//iowr
-#define DELAY_WIO_INIT_ADDR (0)
-#define DELAY_WIO_ADDR_CE (1)
-#define DELAY_WIO_CE_WR (1)
-#define DELAY_WIO_WR_RWAIT (0)
-#define DELAY_WIO_RWAIT_DATA (0)
-#define DELAY_WIO_DATA_DWR (0)
-#define DELAY_WIO_DWR_DCE (1)
-#define DELAY_WIO_DCE_INIT (1)
-
-//timeout irq hold time,10MS
-#define TIMEOUT_IRQ_HOLD_TIME (200)
-
-//reg define
-#define CIPLUS_CMD_REG 0x0
-/*
-31:24 rw, wdata:the data write in cam
-23 reserved
-22:8 addr A0-A14
-7:6 reserved
-5:4 cmd type:00: iord,01:iowr 10: oe 11:we
-3:1 reserved
-0 cmd valid,1:cmd is valid.need be executed.
- 0: cmd is invalid
-*/
-#define CI_CMD_WDATA 24
-#define CI_CMD_ADDR 8
-#define CI_CMD_TYPE 4
-#define CI_CMD_VALID 0
-
-
-#define CIPLUS_RDATA_REG 0x4
-/*
-31:8 reserved
-7:0 data read from cam
-*/
-#define CIPLUS_CTRL_REG 0x8
-/*
-31:21 reserved
-10 ctrl clk 1:disable clk gated;
- 0:enable clk gated
-9 completion irq en,1: disable;0:able
-8 inv_cam_iowrn
-7 inv_cam_iordn
-6 inv_cam_wen
-5 inv_cam_oen
-4 inv_cam_cen
-3 clear transfer complete irq;1:clear
-2 clear timeout ieq, 1:clear
-1 cam reset: =1 assert =0 deassert
-0 control enable: 1:enable ciplus ctrl,0:disable
-*/
-#define ENABLE_CMP_IRQ 9
-#define INV_CAM_IOWR 8
-#define INV_CAM_IORD 7
-#define INV_CAM_WE 6
-#define INV_CAM_OE 5
-#define INV_CAM_CE 4
-#define CLEAR_CMP_IRQ 3
-#define CLEAR_TIMEOUT_IRQ 2
-#define CAM_RESET 1
-#define CI_ENABLE 0
-
-
-
-#define CIPLUS_DELAY_CTRL0 0xc
-/*
-31:24 0xf,delay cycles between assert IORD/IOWR/MEMRD/MEMWR
- and WAIT# RELEASED
-23:16 0xf,delay cycles between assert CE and assert IORD/IOWR/MEMRD/MEMWR
-15:8 0x8,delay cycles between send addr and assert CE
-7:0 0x4,delay cycles between INIT and send ADDR/DATA
-*/
-#define CIPLUS_DELAY_CTRL1 0x10
-/*
-31:24 0xf,delay cycles between DEassert CE and IDLE
-23:16 0xf,delay cycles between DEassert IORD/IOWR/MEMRD/MEMWR and deassert CE
-15:8 0x8,delay cycles between SAMPLE DATA and DEassert IORD/IOWR/MEMRD/MEMWR
-7:0 0xF,delay cycles between WAIT# RELEASE and (SAMPLEDATA OR DEASSERT IORD
- IOWR/MEMRD/MEMWR)
-*/
-#define CIPLUS_WAIT_TIMEOUT 0x14
-/*
-31 wait timeout irq enable,defalut 1;
-30:0 data read from cam;time out threshold
- if wait time > threshold,than timeout irq.
-*/
-#define ENABEL_TIMEOUT_IRQ 31
-#define WATT_TIMEOUT_TIME 0
-
-
-#define CIPLUS_STATUS_REG 0x18
-/*
-31:6 reserved
-5:2 fsm state
-1 timeout irq
-0 complete irq
-*/
-#define TIMEOUT_IRQ_STATE 1
-#define COMPLETE_IRQ_STATE 0
-
-
-extern void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot);
-extern int aml_ci_bus_init(struct platform_device *pdev, struct aml_ci *ci_dev);
-extern int aml_ci_bus_exit(struct aml_ci *ci);
-#endif /* __AML_CI_BUS_H_ */
diff --git a/drivers/stream_input/parser/dvb_ci/aml_pcmcia.c b/drivers/stream_input/parser/dvb_ci/aml_pcmcia.c
index 2961d73..e84f376 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_pcmcia.c
+++ b/drivers/stream_input/parser/dvb_ci/aml_pcmcia.c
@@ -40,26 +40,21 @@
#define pr_error(fmt, args...) printk("PCMCIA: " fmt, ## args)
-static int pcmcia_plugin(struct aml_pcmcia *pc, int reset)
+static int pcmcia_plugin(struct aml_pcmcia *pc)
{
if (pc->slot_state == MODULE_XTRACTED) {
- pc->pwr(pc, AML_PWR_OPEN);/*hi is open power*/
pr_dbg(" CAM Plugged IN: Adapter(%d) Slot(0)\n", 0);
udelay(50);
- //if (pc->io_device_type != AML_DVB_IO_TYPE_CIBUS)
- aml_pcmcia_reset(pc);
+ aml_pcmcia_reset(pc);
/*wait unplug*/
pc->init_irq(pc, IRQF_TRIGGER_RISING);
udelay(500);
pc->slot_state = MODULE_INSERTED;
-
} else {
pr_error("repeat into pcmcia insert \r\n");
- if (reset)
- aml_pcmcia_reset(pc);
+ aml_pcmcia_reset(pc);
}
-
- msleep(1);
+ udelay(100);
pc->pcmcia_plugin(pc, 1);
return 0;
@@ -74,11 +69,9 @@
/*wait plugin*/
pc->init_irq(pc, IRQF_TRIGGER_FALLING);
udelay(500);
- pc->pwr(pc, AML_PWR_CLOSE);/*hi is open power*/
-
pc->slot_state = MODULE_XTRACTED;
}
- msleep(1);
+ udelay(100);
pc->pcmcia_plugin(pc, 0);
return 0;
@@ -100,35 +93,27 @@
struct aml_pcmcia *pc = container_of(
work, struct aml_pcmcia, pcmcia_work);
- if (pc->start_work == 0) {
- return;
- }
cd1 = pc->get_cd1(pc);
cd2 = pc->get_cd2(pc);
if (cd1 != cd2)
- pr_error("work CAM card not inerted.\n");
+ pr_error("CAM card not inerted.\n");
else {
if (!cd1) {
- pr_error("work Adapter(%d) Slot(0): CAM Plugin\n", 0);
- pcmcia_plugin(pc, 0);
+ pr_error("Adapter(%d) Slot(0): CAM Plugin\n", 0);
+ pcmcia_plugin(pc);
} else {
- pr_error("work Adapter(%d) Slot(0): CAM Unplug\n", 0);
+ pr_error("Adapter(%d) Slot(0): CAM Unplug\n", 0);
pcmcia_unplug(pc);
}
}
}
-void aml_pcmcia_detect_cam(struct aml_pcmcia *pc)
+static void aml_pcmcia_detect_cam(struct aml_pcmcia *pc)
{
int cd1, cd2;
if (pc == NULL) {
- pr_error("pc is null\n");
- return;
- }
- if (pc->start_work == 0) {
- pr_error("pc start work is 0\n");
return;
}
cd1 = pc->get_cd1(pc);
@@ -139,14 +124,13 @@
else {
if (!cd1) {
pr_error("Adapter(%d) Slot(0): CAM Plugin\n", 0);
- pcmcia_plugin(pc, 1);
+ pcmcia_plugin(pc);
} else {
pr_error("Adapter(%d) Slot(0): CAM Unplug\n", 0);
pcmcia_unplug(pc);
}
}
}
-EXPORT_SYMBOL(aml_pcmcia_detect_cam);
static struct aml_pcmcia *pc_cur;
int aml_pcmcia_init(struct aml_pcmcia *pc)
@@ -156,15 +140,14 @@
pr_dbg("aml_pcmcia_init start pc->irq=%d\r\n", pc->irq);
pc->rst(pc, AML_L);
/*power on*/
- if (pc->io_device_type != AML_DVB_IO_TYPE_CIBUS)
- pc->pwr(pc, AML_PWR_OPEN);/*hi is open power*/
+ pc->pwr(pc, AML_PWR_OPEN);/*hi is open power*/
/*assuming cam unpluged, config the INT to waiting-for-plugin mode*/
pc->init_irq(pc, IRQF_TRIGGER_LOW);
INIT_WORK(&pc->pcmcia_work, aml_pcmcia_work);
mode = IRQF_ONESHOT;
- if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312 || pc->io_device_type == AML_DVB_IO_TYPE_CIBUS) {
+ if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312) {
mode = mode | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
}
@@ -178,7 +161,7 @@
pc_cur = pc;
pr_dbg("aml_pcmcia_init ok\r\n");
- if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312 || pc->io_device_type == AML_DVB_IO_TYPE_CIBUS) {
+ if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312) {
//mcu start very fast,so she can detect cam before soc init end.
//so we need add detect cam fun for first time.
aml_pcmcia_detect_cam(pc);
@@ -189,7 +172,6 @@
int aml_pcmcia_exit(struct aml_pcmcia *pc)
{
- pc->pwr(pc, AML_PWR_CLOSE);/*hi is open power*/
free_irq(pc->irq, pc);
return 0;
}
@@ -197,14 +179,15 @@
int aml_pcmcia_reset(struct aml_pcmcia *pc)
{
- pr_dbg("CAM RESET-->start\n");
+ pr_dbg("CAM RESET-->\n");
/* viaccess neotion cam need delay 2000 and 3000 */
/* smit cam need delay 1000 and 1500 */
/* need change delay according cam vendor */
pc->rst(pc, AML_H);/*HI is reset*/
- msleep(2000);
+ mdelay(1000);
pc->rst(pc, AML_L);/*defaule LOW*/
- msleep(2500);
+ pr_dbg("CAM RESET--\n");
+ mdelay(1500);
pr_dbg("CAM RESET--end\n");
return 0;
}
@@ -260,6 +243,7 @@
}
+
module_init(aml_pcmcia_mod_init);
module_exit(aml_pcmcia_mod_exit);
diff --git a/drivers/stream_input/parser/dvb_ci/aml_pcmcia.h b/drivers/stream_input/parser/dvb_ci/aml_pcmcia.h
index 2119358..7d0a275 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_pcmcia.h
+++ b/drivers/stream_input/parser/dvb_ci/aml_pcmcia.h
@@ -50,14 +50,12 @@
void *priv;
/*device type*/
int io_device_type;
- /*start detect card and work*/
- int start_work;
};
int aml_pcmcia_init(struct aml_pcmcia *pc);
int aml_pcmcia_exit(struct aml_pcmcia *pc);
int aml_pcmcia_reset(struct aml_pcmcia *pc);
-void aml_pcmcia_detect_cam(struct aml_pcmcia *pc);
+
#endif /*_AML_PCMCIA_*/
diff --git a/drivers/stream_input/parser/dvb_ci/aml_spi.c b/drivers/stream_input/parser/dvb_ci/aml_spi.c
index 97fef8f..49498fa 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_spi.c
+++ b/drivers/stream_input/parser/dvb_ci/aml_spi.c
@@ -31,8 +31,7 @@
#include <linux/gpio/consumer.h>
#include <linux/device.h>
#include <linux/slab.h>
-//#include <linux/amlogic/sd.h>
-#include <linux/mmc/sd.h>
+#include <linux/amlogic/sd.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include "aml_spi.h"
@@ -934,8 +933,8 @@
spi_dev->irq = irq_of_parse_and_map(
pdev->dev.of_node, 0);
AML_CI_GPIO_IRQ_BASE = spi_dev->irq - val;
- pr_dbg("get spi irq : %d USEDBASE:%d val:%d\r\n",
- spi_dev->irq, AML_CI_GPIO_IRQ_BASE, val);
+ pr_dbg("get spi irq : %d 0:%d USEDBASE:%d val:%d\r\n",
+ spi_dev->irq, INT_GPIO_0, AML_CI_GPIO_IRQ_BASE, val);
/*get reset pwd cd1 cd2 gpio pin*/
spi_dev->reset_pin = NULL;
ret = spi_get_gpio_by_name(spi_dev, &spi_dev->reset_pin,
@@ -1102,8 +1101,7 @@
spin_lock_init(&(spi_dev->spi_lock));
/*regist api dev*/
pr_dbg("*********spi Dev regist**********\r\n");
- //not support mcu mode on kernel 5.4
- //result = dirspi_register_board_info(spi_dev->spi_bdinfo, 1);
+ result = dirspi_register_board_info(spi_dev->spi_bdinfo, 1);
if (result) {
pr_error("register amlspi_dev spi boardinfo failed\n");
goto fail1;
@@ -1648,7 +1646,7 @@
return 0;
}
-static ssize_t reset_show(struct class *class,
+static ssize_t aml_spi_ci_reset_help(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -1656,7 +1654,7 @@
return ret;
}
-static ssize_t reset_store(struct class *class,
+static ssize_t aml_spi_ci_reset(struct class *class,
struct class_attribute *attr, const char *buf, size_t size)
{
int ret;
@@ -1665,7 +1663,7 @@
return size;
}
-static ssize_t pwr_show(struct class *class,
+static ssize_t aml_spi_ci_pwr_help(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -1673,7 +1671,7 @@
return ret;
}
-static ssize_t pwr_store(struct class *class,
+static ssize_t aml_spi_ci_pwr(struct class *class,
struct class_attribute *attr, const char *buf, size_t size)
{
int ret = 0;
@@ -1684,7 +1682,7 @@
ret = aml_gio_power(&g_spi_dev->pc, enable);
return size;
}
-static ssize_t status_show(struct class *class,
+static ssize_t aml_spi_ci_state_show(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -1694,7 +1692,7 @@
return ret;
}
-static ssize_t irq_show(struct class *class,
+static ssize_t aml_spi_ci_irq_show(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -1703,7 +1701,7 @@
return ret;
}
-static ssize_t iotest_show(struct class *class,
+static ssize_t aml_spi_io_test_help(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -1712,7 +1710,7 @@
return ret;
}
-static ssize_t iotest_store(struct class *class,
+static ssize_t aml_spi_io_test(struct class *class,
struct class_attribute *attr, const char *buf, size_t size)
{
int n = 0;
@@ -1799,28 +1797,27 @@
kfree(buf_orig);
return size;
}
-static CLASS_ATTR_RW(reset);
-static CLASS_ATTR_RW(pwr);
-static CLASS_ATTR_RO(irq);
-static CLASS_ATTR_RO(status);
-static CLASS_ATTR_RW(iotest);
-static struct attribute *aml_spi_class_attrs[] = {
- &class_attr_reset.attr,
- &class_attr_pwr.attr,
- &class_attr_irq.attr,
- &class_attr_status.attr,
- &class_attr_iotest.attr,
- NULL
+static struct class_attribute aml_spi_class_attrs[] = {
+ __ATTR(reset, S_IRUGO | S_IWUSR,
+ aml_spi_ci_reset_help, aml_spi_ci_reset),
+ __ATTR(pwr, S_IRUGO | S_IWUSR,
+ aml_spi_ci_pwr_help, aml_spi_ci_pwr),
+ __ATTR(irq, S_IRUGO | S_IWUSR,
+ aml_spi_ci_irq_show, NULL),
+ __ATTR(status, S_IRUGO | S_IWUSR,
+ aml_spi_ci_state_show, NULL),
+ __ATTR(iotest, S_IRUGO | S_IWUSR,
+ aml_spi_io_test_help, aml_spi_io_test),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(aml_spi_class);
-
static struct class aml_spi_class = {
.name = "aml_dvb_spi_test",
- .class_groups = aml_spi_class_groups,
+ .class_attrs = aml_spi_class_attrs,
};
+
/**\brief aml_con_gpio_by_spi:control gpio by spi
* \param gpio: the value is from AM_CON_GPIO def
* \param level: 0: set low,1:set hight
diff --git a/drivers/stream_input/parser/dvb_ci/aml_spi.h b/drivers/stream_input/parser/dvb_ci/aml_spi.h
index 9c2dc1e..7a9493e 100644
--- a/drivers/stream_input/parser/dvb_ci/aml_spi.h
+++ b/drivers/stream_input/parser/dvb_ci/aml_spi.h
@@ -20,11 +20,11 @@
#ifndef __AML_SPI_H_
#define __AML_SPI_H_
-//#include <linux/amlogic/aml_gpio_consumer.h>
+#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/gpio/consumer.h>
#include "aml_pcmcia.h"
#include "aml_ci.h"
-#include "dvb_ca_en50221.h"
+#include "drivers/media/dvb-core/dvb_ca_en50221.h"
/*
aml spi dev
@@ -65,12 +65,26 @@
/*device type*/
int io_device_type;
};
-
+enum aml_gpio_level_e {
+ AML_GPIO_LOW = 0,
+ AML_GPIO_HIGH
+};
/* used to mcu */
#define DATASTART 0xef
#define DATAEND 0xfe
-
+enum AM_CI_CMD {
+ AM_CI_CMD_IOR = 0,
+ AM_CI_CMD_IOW,
+ AM_CI_CMD_MEMR,
+ AM_CI_CMD_MEMW,
+ AM_CI_CMD_FULLTEST,
+ AM_CI_CMD_CISTEST,
+ AM_CI_CMD_GETCD12,
+ AM_CI_CMD_POWER,
+ AM_CI_CMD_RESET,
+ AM_CI_CMD_CONGPIO,
+};
enum AM_SPI_RECIVERSTEP {
AM_SPI_STEP_INIT = 0,
AM_SPI_STEP_START1,
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/aml_cimax_usb.c b/drivers/stream_input/parser/dvb_ci/cimax/aml_cimax_usb.c
index bb0c71f..b74b34a 100644
--- a/drivers/stream_input/parser/dvb_ci/cimax/aml_cimax_usb.c
+++ b/drivers/stream_input/parser/dvb_ci/cimax/aml_cimax_usb.c
@@ -24,9 +24,6 @@
#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/delay.h>
-#include <linux/of_gpio.h>
-#include <linux/sched/clock.h>
-
//#include <linux/switch.h>
#include "aml_cimax.h"
@@ -472,8 +469,8 @@
#define REG_TIMEOUT 500
#define CAM_TIMEOUT 5000
-static int aml_cimax_usb_mod_init(struct platform_device *pdev);
-static void aml_cimax_usb_mod_exit(struct platform_device *pdev);
+static int aml_cimax_usb_mod_init(void);
+static void aml_cimax_usb_mod_exit(void);
static int cimax_usb_set_loop(struct cimax_usb *usb, int loop);
@@ -1188,7 +1185,7 @@
if (!g_usb)
return 0;
- (void)id;
+ id = id;
cimax_usb_device_open(dev);
cimax_usb_select_interface(dev, 3);
@@ -1227,7 +1224,7 @@
pr_dbg("dev remove\n");
if (!g_usb)
return 0;
- (void)id;
+ id = id;
pr_dbg("setup poll -> stop\n");
cimax_usb_setup_poll(g_usb, STOP_MODE);
pr_dbg("setup poll end\n");
@@ -1325,7 +1322,7 @@
g_usb = cimax_usb;
- aml_cimax_usb_mod_init(pdev);
+ aml_cimax_usb_mod_init();
cimax_usb_set_cb(cimax_usb_dev_add, cimax_usb_dev_remove);
@@ -1340,7 +1337,7 @@
if (!usb)
return -ENODEV;
- aml_cimax_usb_mod_exit(usb->pdev);
+ aml_cimax_usb_mod_exit();
cimax_usb_device_close(usb->dev);
cimax_usb_setup_poll(usb, STOP_MODE);
@@ -1682,50 +1679,34 @@
return size;
}
-static CLASS_ATTR_RW(reset);
-static CLASS_ATTR_RO(debug);
-static CLASS_ATTR_RW(addr);
-static CLASS_ATTR_RW(reg);
-static CLASS_ATTR_RW(cis);
-static CLASS_ATTR_RO(ts_rate);
-static CLASS_ATTR_RW(loop);
-static CLASS_ATTR_WO(slot_reset);
-static CLASS_ATTR_WO(detect);
-#define CLASS_ATTR(name) &class_attr_##name.attr
-
-static struct attribute *cimax_usb_class_attrs[] = {
- CLASS_ATTR(reset),
- CLASS_ATTR(debug),
- CLASS_ATTR(addr),
- CLASS_ATTR(reg),
- CLASS_ATTR(cis),
- CLASS_ATTR(ts_rate),
- CLASS_ATTR(loop),
- CLASS_ATTR(slot_reset),
- CLASS_ATTR(detect),
- NULL
+static struct class_attribute cimax_usb_class_attrs[] = {
+ __ATTR_RW(reset),
+ __ATTR_RO(debug),
+ __ATTR_RW(addr),
+ __ATTR_RW(reg),
+ __ATTR_RW(cis),
+ __ATTR_RO(ts_rate),
+ __ATTR_RW(loop),
+ __ATTR_WO(slot_reset),
+ __ATTR_WO(detect),
+ __ATTR_NULL
};
-
-ATTRIBUTE_GROUPS(cimax_usb_class);
-
static struct class cimax_usb_class = {
.name = "cimax_usb",
- .class_groups = cimax_usb_class_groups,
+ .class_attrs = cimax_usb_class_attrs,
};
-static int aml_cimax_usb_mod_init(struct platform_device *pdev)
+static int aml_cimax_usb_mod_init(void)
{
int ret;
pr_dbg("Amlogic CIMAX USB Init\n");
-
ret = class_register(&cimax_usb_class);
-
return 0;
}
-static void aml_cimax_usb_mod_exit(struct platform_device *pdev)
+static void aml_cimax_usb_mod_exit(void)
{
pr_dbg("Amlogic CIMAX USB Exit\n");
class_unregister(&cimax_usb_class);
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/dvb_ca_en50221_cimax.c b/drivers/stream_input/parser/dvb_ci/cimax/dvb_ca_en50221_cimax.c
index c3c6511..0f09799 100644
--- a/drivers/stream_input/parser/dvb_ci/cimax/dvb_ca_en50221_cimax.c
+++ b/drivers/stream_input/parser/dvb_ci/cimax/dvb_ca_en50221_cimax.c
@@ -27,9 +27,7 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
-#include <linux/sched/signal.h>
#include <linux/kthread.h>
-#include <linux/compat.h>
#include "dvb_ca_en50221_cimax.h"
#include "dvb_ringbuffer.h"
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/dvb_ringbuffer.c b/drivers/stream_input/parser/dvb_ci/cimax/dvb_ringbuffer.c
index 40615d2..fa5c163 100644
--- a/drivers/stream_input/parser/dvb_ci/cimax/dvb_ringbuffer.c
+++ b/drivers/stream_input/parser/dvb_ci/cimax/dvb_ringbuffer.c
@@ -31,7 +31,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/string.h>
-#include <linux/uaccess.h>
+#include <asm/uaccess.h>
#include "dvb_ringbuffer.h"
@@ -70,12 +70,12 @@
{
ssize_t free;
- /* READ_ONCE() to load read pointer on writer side
+ /* ACCESS_ONCE() to load read pointer on writer side
* this pairs with smp_store_release() in dvb_ringbuffer_read(),
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
* or dvb_ringbuffer_reset()
*/
- free = READ_ONCE(rbuf->pread) - rbuf->pwrite;
+ free = ACCESS_ONCE(rbuf->pread) - rbuf->pwrite;
if (free <= 0)
free += rbuf->size;
return free-1;
@@ -371,11 +371,11 @@
EXPORT_SYMBOL(dvb_ringbuffer_read);
EXPORT_SYMBOL(dvb_ringbuffer_write);
EXPORT_SYMBOL(dvb_ringbuffer_write_user);
-
+#endif
EXPORT_SYMBOL(dvb_ringbuffer_pkt_read);
EXPORT_SYMBOL(dvb_ringbuffer_pkt_write);
EXPORT_SYMBOL(dvb_ringbuffer_pkt_next);
EXPORT_SYMBOL(dvb_ringbuffer_pkt_dispose);
EXPORT_SYMBOL(dvb_ringbuffer_pkt_read_user);
-#endif
+
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.c b/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.c
new file mode 100644
index 0000000..0e9599b
--- /dev/null
+++ b/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.c
@@ -0,0 +1,968 @@
+/*
+ * dvbdev.c
+ *
+ * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
+ * & Marcus Metzler <marcus@convergence.de>
+ * for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include "dvbdev.h"
+
+/* Due to enum tuner_pad_index */
+#include <media/tuner.h>
+
+static DEFINE_MUTEX(dvbdev_mutex);
+static int dvbdev_debug;
+
+module_param(dvbdev_debug, int, 0644);
+MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
+
+#define dprintk if (dvbdev_debug) printk
+
+static LIST_HEAD(dvb_adapter_list);
+static DEFINE_MUTEX(dvbdev_register_lock);
+
+static const char * const dnames[] = {
+ "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
+ "net", "osd"
+};
+
+#ifdef CONFIG_DVB_DYNAMIC_MINORS
+#define MAX_DVB_MINORS 256
+#define DVB_MAX_IDS MAX_DVB_MINORS
+#else
+#define DVB_MAX_IDS 4
+#define nums2minor(num, type, id) ((num << 6) | (id << 4) | type)
+#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
+#endif
+
+static struct class *dvb_class;
+
+static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
+static DECLARE_RWSEM(minor_rwsem);
+
+static int dvb_device_open(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev;
+
+ mutex_lock(&dvbdev_mutex);
+ down_read(&minor_rwsem);
+ dvbdev = dvb_minors[iminor(inode)];
+
+ if (dvbdev && dvbdev->fops) {
+ int err = 0;
+ const struct file_operations *new_fops;
+
+ new_fops = fops_get(dvbdev->fops);
+ if (!new_fops)
+ goto fail;
+ file->private_data = dvbdev;
+ replace_fops(file, new_fops);
+ if (file->f_op->open)
+ err = file->f_op->open(inode, file);
+ up_read(&minor_rwsem);
+ mutex_unlock(&dvbdev_mutex);
+ return err;
+ }
+fail:
+ up_read(&minor_rwsem);
+ mutex_unlock(&dvbdev_mutex);
+ return -ENODEV;
+}
+
+
+static const struct file_operations dvb_device_fops =
+{
+ .owner = THIS_MODULE,
+ .open = dvb_device_open,
+ .llseek = noop_llseek,
+};
+
+static struct cdev dvb_device_cdev;
+
+int dvb_generic_open(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ if (!dvbdev->users)
+ return -EBUSY;
+
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ if (!dvbdev->readers)
+ return -EBUSY;
+ dvbdev->readers--;
+ } else {
+ if (!dvbdev->writers)
+ return -EBUSY;
+ dvbdev->writers--;
+ }
+
+ dvbdev->users--;
+ return 0;
+}
+EXPORT_SYMBOL(dvb_generic_open);
+
+
+int dvb_generic_release(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
+ } else {
+ dvbdev->writers++;
+ }
+
+ dvbdev->users++;
+ return 0;
+}
+EXPORT_SYMBOL(dvb_generic_release);
+
+
+long dvb_generic_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ if (!dvbdev->kernel_ioctl)
+ return -EINVAL;
+
+ return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
+}
+EXPORT_SYMBOL(dvb_generic_ioctl);
+
+
+static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
+{
+ u32 id = 0;
+
+ while (id < DVB_MAX_IDS) {
+ struct dvb_device *dev;
+ list_for_each_entry(dev, &adap->device_list, list_head)
+ if (dev->type == type && dev->id == id)
+ goto skip;
+ return id;
+skip:
+ id++;
+ }
+ return -ENFILE;
+}
+
+static void dvb_media_device_free(struct dvb_device *dvbdev)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+ if (dvbdev->entity) {
+ media_device_unregister_entity(dvbdev->entity);
+ kfree(dvbdev->entity);
+ kfree(dvbdev->pads);
+ dvbdev->entity = NULL;
+ dvbdev->pads = NULL;
+ }
+
+ if (dvbdev->tsout_entity) {
+ int i;
+
+ for (i = 0; i < dvbdev->tsout_num_entities; i++) {
+ media_device_unregister_entity(&dvbdev->tsout_entity[i]);
+ kfree(dvbdev->tsout_entity[i].name);
+ }
+ kfree(dvbdev->tsout_entity);
+ kfree(dvbdev->tsout_pads);
+ dvbdev->tsout_entity = NULL;
+ dvbdev->tsout_pads = NULL;
+
+ dvbdev->tsout_num_entities = 0;
+ }
+
+ if (dvbdev->intf_devnode) {
+ media_devnode_remove(dvbdev->intf_devnode);
+ dvbdev->intf_devnode = NULL;
+ }
+
+ if (dvbdev->adapter->conn) {
+ media_device_unregister_entity(dvbdev->adapter->conn);
+ dvbdev->adapter->conn = NULL;
+ kfree(dvbdev->adapter->conn_pads);
+ dvbdev->adapter->conn_pads = NULL;
+ }
+#endif
+}
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
+ const char *name, int npads)
+{
+ int i, ret = 0;
+
+ dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
+ GFP_KERNEL);
+ if (!dvbdev->tsout_pads)
+ return -ENOMEM;
+
+ dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
+ GFP_KERNEL);
+ if (!dvbdev->tsout_entity)
+ return -ENOMEM;
+
+ dvbdev->tsout_num_entities = npads;
+
+ for (i = 0; i < npads; i++) {
+ struct media_pad *pads = &dvbdev->tsout_pads[i];
+ struct media_entity *entity = &dvbdev->tsout_entity[i];
+
+ entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
+ if (!entity->name)
+ return -ENOMEM;
+
+ entity->function = MEDIA_ENT_F_IO_DTV;
+ pads->flags = MEDIA_PAD_FL_SINK;
+
+ ret = media_entity_pads_init(entity, 1, pads);
+ if (ret < 0)
+ return ret;
+
+ ret = media_device_register_entity(dvbdev->adapter->mdev,
+ entity);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+#define DEMUX_TSOUT "demux-tsout"
+#define DVR_TSOUT "dvr-tsout"
+
+static int dvb_create_media_entity(struct dvb_device *dvbdev,
+ int type, int demux_sink_pads)
+{
+ int i, ret, npads;
+
+ switch (type) {
+ case DVB_DEVICE_FRONTEND:
+ npads = 2;
+ break;
+ case DVB_DEVICE_DVR:
+ ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT,
+ demux_sink_pads);
+ return ret;
+ case DVB_DEVICE_DEMUX:
+ npads = 1 + demux_sink_pads;
+ ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT,
+ demux_sink_pads);
+ if (ret < 0)
+ return ret;
+ break;
+ case DVB_DEVICE_CA:
+ npads = 2;
+ break;
+ case DVB_DEVICE_NET:
+ /*
+ * We should be creating entities for the MPE/ULE
+ * decapsulation hardware (or software implementation).
+ *
+ * However, the number of for the MPE/ULE decaps may not be
+ * fixed. As we don't have yet dynamic support for PADs at
+ * the Media Controller, let's not create the decap
+ * entities yet.
+ */
+ return 0;
+ default:
+ return 0;
+ }
+
+ dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
+ if (!dvbdev->entity)
+ return -ENOMEM;
+
+ dvbdev->entity->name = dvbdev->name;
+
+ if (npads) {
+ dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
+ GFP_KERNEL);
+ if (!dvbdev->pads)
+ return -ENOMEM;
+ }
+
+ switch (type) {
+ case DVB_DEVICE_FRONTEND:
+ dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD;
+ dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+ dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+ break;
+ case DVB_DEVICE_DEMUX:
+ dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX;
+ dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+ for (i = 1; i < npads; i++)
+ dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+ break;
+ case DVB_DEVICE_CA:
+ dvbdev->entity->function = MEDIA_ENT_F_DTV_CA;
+ dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
+ dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+ break;
+ default:
+ /* Should never happen, as the first switch prevents it */
+ kfree(dvbdev->entity);
+ kfree(dvbdev->pads);
+ dvbdev->entity = NULL;
+ dvbdev->pads = NULL;
+ return 0;
+ }
+
+ if (npads) {
+ ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads);
+ if (ret)
+ return ret;
+ }
+ ret = media_device_register_entity(dvbdev->adapter->mdev,
+ dvbdev->entity);
+ if (ret)
+ return ret;
+
+ printk(KERN_DEBUG "%s: media entity '%s' registered.\n",
+ __func__, dvbdev->entity->name);
+
+ return 0;
+}
+#endif
+
+static int dvb_register_media_device(struct dvb_device *dvbdev,
+ int type, int minor,
+ unsigned demux_sink_pads)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+ struct media_link *link;
+ u32 intf_type;
+ int ret;
+
+ if (!dvbdev->adapter->mdev)
+ return 0;
+
+ ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads);
+ if (ret)
+ return ret;
+
+ switch (type) {
+ case DVB_DEVICE_FRONTEND:
+ intf_type = MEDIA_INTF_T_DVB_FE;
+ break;
+ case DVB_DEVICE_DEMUX:
+ intf_type = MEDIA_INTF_T_DVB_DEMUX;
+ break;
+ case DVB_DEVICE_DVR:
+ intf_type = MEDIA_INTF_T_DVB_DVR;
+ break;
+ case DVB_DEVICE_CA:
+ intf_type = MEDIA_INTF_T_DVB_CA;
+ break;
+ case DVB_DEVICE_NET:
+ intf_type = MEDIA_INTF_T_DVB_NET;
+ break;
+ default:
+ return 0;
+ }
+
+ dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev,
+ intf_type, 0,
+ DVB_MAJOR, minor);
+
+ if (!dvbdev->intf_devnode)
+ return -ENOMEM;
+
+ /*
+ * Create the "obvious" link, e. g. the ones that represent
+ * a direct association between an interface and an entity.
+ * Other links should be created elsewhere, like:
+ * DVB FE intf -> tuner
+ * DVB demux intf -> dvr
+ */
+
+ if (!dvbdev->entity)
+ return 0;
+
+ link = media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf,
+ MEDIA_LNK_FL_ENABLED);
+ if (!link)
+ return -ENOMEM;
+#endif
+ return 0;
+}
+
+int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ const struct dvb_device *template, void *priv, int type,
+ int demux_sink_pads)
+{
+ struct dvb_device *dvbdev;
+ struct file_operations *dvbdevfops;
+ struct device *clsdev;
+ int minor;
+ int id, ret;
+
+ mutex_lock(&dvbdev_register_lock);
+
+ if ((id = dvbdev_get_free_id (adap, type)) < 0){
+ mutex_unlock(&dvbdev_register_lock);
+ *pdvbdev = NULL;
+ printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
+ return -ENFILE;
+ }
+
+ *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
+
+ if (!dvbdev){
+ mutex_unlock(&dvbdev_register_lock);
+ return -ENOMEM;
+ }
+
+ dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
+
+ if (!dvbdevfops){
+ kfree (dvbdev);
+ mutex_unlock(&dvbdev_register_lock);
+ return -ENOMEM;
+ }
+
+ memcpy(dvbdev, template, sizeof(struct dvb_device));
+ dvbdev->type = type;
+ dvbdev->id = id;
+ dvbdev->adapter = adap;
+ dvbdev->priv = priv;
+ dvbdev->fops = dvbdevfops;
+ init_waitqueue_head (&dvbdev->wait_queue);
+
+ memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+ dvbdevfops->owner = adap->module;
+
+ list_add_tail (&dvbdev->list_head, &adap->device_list);
+
+ down_write(&minor_rwsem);
+#ifdef CONFIG_DVB_DYNAMIC_MINORS
+ for (minor = 0; minor < MAX_DVB_MINORS; minor++)
+ if (dvb_minors[minor] == NULL)
+ break;
+
+ if (minor == MAX_DVB_MINORS) {
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ up_write(&minor_rwsem);
+ mutex_unlock(&dvbdev_register_lock);
+ return -EINVAL;
+ }
+#else
+ minor = nums2minor(adap->num, type, id);
+#endif
+
+ dvbdev->minor = minor;
+ dvb_minors[minor] = dvbdev;
+ up_write(&minor_rwsem);
+
+ ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
+ if (ret) {
+ printk(KERN_ERR
+ "%s: dvb_register_media_device failed to create the mediagraph\n",
+ __func__);
+
+ dvb_media_device_free(dvbdev);
+ kfree(dvbdevfops);
+ kfree(dvbdev);
+ up_write(&minor_rwsem);
+ mutex_unlock(&dvbdev_register_lock);
+ return ret;
+ }
+
+ mutex_unlock(&dvbdev_register_lock);
+
+ clsdev = device_create(dvb_class, adap->device,
+ MKDEV(DVB_MAJOR, minor),
+ dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
+ if (IS_ERR(clsdev)) {
+ printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
+ __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+ return PTR_ERR(clsdev);
+ }
+ dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
+ adap->num, dnames[type], id, minor, minor);
+
+ return 0;
+}
+EXPORT_SYMBOL(dvb_register_device);
+
+
+void dvb_unregister_device(struct dvb_device *dvbdev)
+{
+ if (!dvbdev)
+ return;
+
+ down_write(&minor_rwsem);
+ dvb_minors[dvbdev->minor] = NULL;
+ up_write(&minor_rwsem);
+
+ dvb_media_device_free(dvbdev);
+
+ device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
+
+ list_del (&dvbdev->list_head);
+ kfree (dvbdev->fops);
+ kfree (dvbdev);
+}
+EXPORT_SYMBOL(dvb_unregister_device);
+
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+
+static int dvb_create_io_intf_links(struct dvb_adapter *adap,
+ struct media_interface *intf,
+ char *name)
+{
+ struct media_device *mdev = adap->mdev;
+ struct media_entity *entity;
+ struct media_link *link;
+
+ media_device_for_each_entity(entity, mdev) {
+ if (entity->function == MEDIA_ENT_F_IO_DTV) {
+ if (strncmp(entity->name, name, strlen(name)))
+ continue;
+ link = media_create_intf_link(entity, intf,
+ MEDIA_LNK_FL_ENABLED);
+ if (!link)
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+int dvb_create_media_graph(struct dvb_adapter *adap,
+ bool create_rf_connector)
+{
+ struct media_device *mdev = adap->mdev;
+ struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
+ struct media_entity *demux = NULL, *ca = NULL;
+ struct media_link *link;
+ struct media_interface *intf;
+ unsigned demux_pad = 0;
+ unsigned dvr_pad = 0;
+ unsigned ntuner = 0, ndemod = 0;
+ int ret;
+ static const char *connector_name = "Television";
+
+ if (!mdev)
+ return 0;
+
+ media_device_for_each_entity(entity, mdev) {
+ switch (entity->function) {
+ case MEDIA_ENT_F_TUNER:
+ tuner = entity;
+ ntuner++;
+ break;
+ case MEDIA_ENT_F_DTV_DEMOD:
+ demod = entity;
+ ndemod++;
+ break;
+ case MEDIA_ENT_F_TS_DEMUX:
+ demux = entity;
+ break;
+ case MEDIA_ENT_F_DTV_CA:
+ ca = entity;
+ break;
+ }
+ }
+
+ /*
+ * Prepare to signalize to media_create_pad_links() that multiple
+ * entities of the same type exists and a 1:n or n:1 links need to be
+ * created.
+ * NOTE: if both tuner and demod have multiple instances, it is up
+ * to the caller driver to create such links.
+ */
+ if (ntuner > 1)
+ tuner = NULL;
+ if (ndemod > 1)
+ demod = NULL;
+
+ if (create_rf_connector) {
+ conn = kzalloc(sizeof(*conn), GFP_KERNEL);
+ if (!conn)
+ return -ENOMEM;
+ adap->conn = conn;
+
+ adap->conn_pads = kzalloc(sizeof(*adap->conn_pads), GFP_KERNEL);
+ if (!adap->conn_pads)
+ return -ENOMEM;
+
+ conn->flags = MEDIA_ENT_FL_CONNECTOR;
+ conn->function = MEDIA_ENT_F_CONN_RF;
+ conn->name = connector_name;
+ adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(conn, 1, adap->conn_pads);
+ if (ret)
+ return ret;
+
+ ret = media_device_register_entity(mdev, conn);
+ if (ret)
+ return ret;
+
+ if (!ntuner)
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_CONN_RF,
+ conn, 0,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 0,
+ MEDIA_LNK_FL_ENABLED,
+ false);
+ else
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_CONN_RF,
+ conn, 0,
+ MEDIA_ENT_F_TUNER,
+ tuner, TUNER_PAD_RF_INPUT,
+ MEDIA_LNK_FL_ENABLED,
+ false);
+ if (ret)
+ return ret;
+ }
+
+ if (ntuner && ndemod) {
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_TUNER,
+ tuner, TUNER_PAD_OUTPUT,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 0, MEDIA_LNK_FL_ENABLED,
+ false);
+ if (ret)
+ return ret;
+ }
+
+ if (ndemod && demux) {
+ ret = media_create_pad_links(mdev,
+ MEDIA_ENT_F_DTV_DEMOD,
+ demod, 1,
+ MEDIA_ENT_F_TS_DEMUX,
+ demux, 0, MEDIA_LNK_FL_ENABLED,
+ false);
+ if (ret)
+ return ret;
+ }
+ if (demux && ca) {
+ ret = media_create_pad_link(demux, 1, ca,
+ 0, MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+ }
+
+ /* Create demux links for each ringbuffer/pad */
+ if (demux) {
+ media_device_for_each_entity(entity, mdev) {
+ if (entity->function == MEDIA_ENT_F_IO_DTV) {
+ if (!strncmp(entity->name, DVR_TSOUT,
+ strlen(DVR_TSOUT))) {
+ ret = media_create_pad_link(demux,
+ ++dvr_pad,
+ entity, 0, 0);
+ if (ret)
+ return ret;
+ }
+ if (!strncmp(entity->name, DEMUX_TSOUT,
+ strlen(DEMUX_TSOUT))) {
+ ret = media_create_pad_link(demux,
+ ++demux_pad,
+ entity, 0, 0);
+ if (ret)
+ return ret;
+ }
+ }
+ }
+ }
+
+ /* Create interface links for FE->tuner, DVR->demux and CA->ca */
+ media_device_for_each_intf(intf, mdev) {
+ if (intf->type == MEDIA_INTF_T_DVB_CA && ca) {
+ link = media_create_intf_link(ca, intf,
+ MEDIA_LNK_FL_ENABLED);
+ if (!link)
+ return -ENOMEM;
+ }
+
+ if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) {
+ link = media_create_intf_link(tuner, intf,
+ MEDIA_LNK_FL_ENABLED);
+ if (!link)
+ return -ENOMEM;
+ }
+#if 0
+ /*
+ * Indirect link - let's not create yet, as we don't know how
+ * to handle indirect links, nor if this will
+ * actually be needed.
+ */
+ if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) {
+ link = media_create_intf_link(demux, intf,
+ MEDIA_LNK_FL_ENABLED);
+ if (!link)
+ return -ENOMEM;
+ }
+#endif
+ if (intf->type == MEDIA_INTF_T_DVB_DVR) {
+ ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT);
+ if (ret)
+ return ret;
+ }
+ if (intf->type == MEDIA_INTF_T_DVB_DEMUX) {
+ ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT);
+ if (ret)
+ return ret;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dvb_create_media_graph);
+#endif
+
+static int dvbdev_check_free_adapter_num(int num)
+{
+ struct list_head *entry;
+ list_for_each(entry, &dvb_adapter_list) {
+ struct dvb_adapter *adap;
+ adap = list_entry(entry, struct dvb_adapter, list_head);
+ if (adap->num == num)
+ return 0;
+ }
+ return 1;
+}
+
+static int dvbdev_get_free_adapter_num (void)
+{
+ int num = 0;
+
+ while (num < DVB_MAX_ADAPTERS) {
+ if (dvbdev_check_free_adapter_num(num))
+ return num;
+ num++;
+ }
+
+ return -ENFILE;
+}
+
+
+int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
+ struct module *module, struct device *device,
+ short *adapter_nums)
+{
+ int i, num;
+
+ mutex_lock(&dvbdev_register_lock);
+
+ for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
+ num = adapter_nums[i];
+ if (num >= 0 && num < DVB_MAX_ADAPTERS) {
+ /* use the one the driver asked for */
+ if (dvbdev_check_free_adapter_num(num))
+ break;
+ } else {
+ num = dvbdev_get_free_adapter_num();
+ break;
+ }
+ num = -1;
+ }
+
+ if (num < 0) {
+ mutex_unlock(&dvbdev_register_lock);
+ return -ENFILE;
+ }
+
+ memset (adap, 0, sizeof(struct dvb_adapter));
+ INIT_LIST_HEAD (&adap->device_list);
+
+ printk(KERN_INFO "DVB: registering new adapter (%s)\n", name);
+
+ adap->num = num;
+ adap->name = name;
+ adap->module = module;
+ adap->device = device;
+ adap->mfe_shared = 0;
+ adap->mfe_dvbdev = NULL;
+ mutex_init (&adap->mfe_lock);
+
+ list_add_tail (&adap->list_head, &dvb_adapter_list);
+
+ mutex_unlock(&dvbdev_register_lock);
+
+ return num;
+}
+EXPORT_SYMBOL(dvb_register_adapter);
+
+
+int dvb_unregister_adapter(struct dvb_adapter *adap)
+{
+ mutex_lock(&dvbdev_register_lock);
+ list_del (&adap->list_head);
+ mutex_unlock(&dvbdev_register_lock);
+ return 0;
+}
+EXPORT_SYMBOL(dvb_unregister_adapter);
+
+/* if the miracle happens and "generic_usercopy()" is included into
+ the kernel, then this can vanish. please don't make the mistake and
+ define this as video_usercopy(). this will introduce a dependecy
+ to the v4l "videodev.o" module, which is unnecessary for some
+ cards (ie. the budget dvb-cards don't need the v4l module...) */
+int dvb_usercopy(struct file *file,
+ unsigned int cmd, unsigned long arg,
+ int (*func)(struct file *file,
+ unsigned int cmd, void *arg))
+{
+ char sbuf[128];
+ void *mbuf = NULL;
+ void *parg = NULL;
+ int err = -EINVAL;
+
+ /* Copy arguments into temp kernel buffer */
+ switch (_IOC_DIR(cmd)) {
+ case _IOC_NONE:
+ /*
+ * For this command, the pointer is actually an integer
+ * argument.
+ */
+ parg = (void *) arg;
+ break;
+ case _IOC_READ: /* some v4l ioctls are marked wrong ... */
+ case _IOC_WRITE:
+ case (_IOC_WRITE | _IOC_READ):
+ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+ parg = sbuf;
+ } else {
+ /* too big to allocate from stack */
+ mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (NULL == mbuf)
+ return -ENOMEM;
+ parg = mbuf;
+ }
+
+ err = -EFAULT;
+ if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+ goto out;
+ break;
+ }
+
+ /* call driver */
+ if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
+ err = -ENOTTY;
+
+ if (err < 0)
+ goto out;
+
+ /* Copy results into user buffer */
+ switch (_IOC_DIR(cmd))
+ {
+ case _IOC_READ:
+ case (_IOC_WRITE | _IOC_READ):
+ if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+ err = -EFAULT;
+ break;
+ }
+
+out:
+ kfree(mbuf);
+ return err;
+}
+EXPORT_SYMBOL(dvb_usercopy);
+static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+ add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
+ add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
+ add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
+ return 0;
+}
+
+static char *dvb_devnode(struct device *dev, umode_t *mode)
+{
+ struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+ return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
+ dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
+}
+
+
+static int __init init_dvbdev(void)
+{
+ int retval;
+ dev_t dev = MKDEV(DVB_MAJOR, 0);
+
+ if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
+ printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR);
+ return retval;
+ }
+
+ cdev_init(&dvb_device_cdev, &dvb_device_fops);
+ if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
+ printk(KERN_ERR "dvb-core: unable register character device\n");
+ goto error;
+ }
+
+ dvb_class = class_create(THIS_MODULE, "dvb");
+ if (IS_ERR(dvb_class)) {
+ retval = PTR_ERR(dvb_class);
+ goto error;
+ }
+ dvb_class->dev_uevent = dvb_uevent;
+ dvb_class->devnode = dvb_devnode;
+ return 0;
+
+error:
+ cdev_del(&dvb_device_cdev);
+ unregister_chrdev_region(dev, MAX_DVB_MINORS);
+ return retval;
+}
+
+
+static void __exit exit_dvbdev(void)
+{
+ class_destroy(dvb_class);
+ cdev_del(&dvb_device_cdev);
+ unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
+}
+#if 0
+subsys_initcall(init_dvbdev);
+module_exit(exit_dvbdev);
+
+MODULE_DESCRIPTION("DVB Core Driver");
+MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
+MODULE_LICENSE("GPL");
+#endif
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.h b/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.h
new file mode 100644
index 0000000..4aff7bd
--- /dev/null
+++ b/drivers/stream_input/parser/dvb_ci/cimax/dvbdev.h
@@ -0,0 +1,299 @@
+/*
+ * dvbdev.h
+ *
+ * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
+ * for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _DVBDEV_H_
+#define _DVBDEV_H_
+
+#include <linux/types.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <media/media-device.h>
+
+#define DVB_MAJOR 212
+
+#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
+ #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
+#else
+ #define DVB_MAX_ADAPTERS 8
+#endif
+
+#define DVB_UNSET (-1)
+
+#define DVB_DEVICE_VIDEO 0
+#define DVB_DEVICE_AUDIO 1
+#define DVB_DEVICE_SEC 2
+#define DVB_DEVICE_FRONTEND 3
+#define DVB_DEVICE_DEMUX 4
+#define DVB_DEVICE_DVR 5
+#define DVB_DEVICE_CA 6
+#define DVB_DEVICE_NET 7
+#define DVB_DEVICE_OSD 8
+
+#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
+ static short adapter_nr[] = \
+ {[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \
+ module_param_array(adapter_nr, short, NULL, 0444); \
+ MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
+
+struct dvb_frontend;
+
+/**
+ * struct dvb_adapter - represents a Digital TV adapter using Linux DVB API
+ *
+ * @num: Number of the adapter
+ * @list_head: List with the DVB adapters
+ * @device_list: List with the DVB devices
+ * @name: Name of the adapter
+ * @proposed_mac: proposed MAC address for the adapter
+ * @priv: private data
+ * @device: pointer to struct device
+ * @module: pointer to struct module
+ * @mfe_shared: mfe shared: indicates mutually exclusive frontends
+ * Thie usage of this flag is currently deprecated
+ * @mfe_dvbdev: Frontend device in use, in the case of MFE
+ * @mfe_lock: Lock to prevent using the other frontends when MFE is
+ * used.
+ * @mdev: pointer to struct media_device, used when the media
+ * controller is used.
+ * @conn: RF connector. Used only if the device has no separate
+ * tuner.
+ * @conn_pads: pointer to struct media_pad associated with @conn;
+ */
+struct dvb_adapter {
+ int num;
+ struct list_head list_head;
+ struct list_head device_list;
+ const char *name;
+ u8 proposed_mac [6];
+ void* priv;
+
+ struct device *device;
+
+ struct module *module;
+
+ int mfe_shared; /* indicates mutually exclusive frontends */
+ struct dvb_device *mfe_dvbdev; /* frontend device in use */
+ struct mutex mfe_lock; /* access lock for thread creation */
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+ struct media_device *mdev;
+ struct media_entity *conn;
+ struct media_pad *conn_pads;
+#endif
+};
+
+/**
+ * struct dvb_device - represents a DVB device node
+ *
+ * @list_head: List head with all DVB devices
+ * @fops: pointer to struct file_operations
+ * @adapter: pointer to the adapter that holds this device node
+ * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
+ * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
+ * @minor: devnode minor number. Major number is always DVB_MAJOR.
+ * @id: device ID number, inside the adapter
+ * @readers: Initialized by the caller. Each call to open() in Read Only mode
+ * decreases this counter by one.
+ * @writers: Initialized by the caller. Each call to open() in Read/Write
+ * mode decreases this counter by one.
+ * @users: Initialized by the caller. Each call to open() in any mode
+ * decreases this counter by one.
+ * @wait_queue: wait queue, used to wait for certain events inside one of
+ * the DVB API callers
+ * @kernel_ioctl: callback function used to handle ioctl calls from userspace.
+ * @name: Name to be used for the device at the Media Controller
+ * @entity: pointer to struct media_entity associated with the device node
+ * @pads: pointer to struct media_pad associated with @entity;
+ * @priv: private data
+ * @intf_devnode: Pointer to media_intf_devnode. Used by the dvbdev core to
+ * store the MC device node interface
+ * @tsout_num_entities: Number of Transport Stream output entities
+ * @tsout_entity: array with MC entities associated to each TS output node
+ * @tsout_pads: array with the source pads for each @tsout_entity
+ *
+ * This structure is used by the DVB core (frontend, CA, net, demux) in
+ * order to create the device nodes. Usually, driver should not initialize
+ * this struct diretly.
+ */
+struct dvb_device {
+ struct list_head list_head;
+ const struct file_operations *fops;
+ struct dvb_adapter *adapter;
+ int type;
+ int minor;
+ u32 id;
+
+ /* in theory, 'users' can vanish now,
+ but I don't want to change too much now... */
+ int readers;
+ int writers;
+ int users;
+
+ wait_queue_head_t wait_queue;
+ /* don't really need those !? -- FIXME: use video_usercopy */
+ int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
+
+ /* Needed for media controller register/unregister */
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+ const char *name;
+
+ /* Allocated and filled inside dvbdev.c */
+ struct media_intf_devnode *intf_devnode;
+
+ unsigned tsout_num_entities;
+ struct media_entity *entity, *tsout_entity;
+ struct media_pad *pads, *tsout_pads;
+#endif
+
+ void *priv;
+};
+
+/**
+ * dvb_register_adapter - Registers a new DVB adapter
+ *
+ * @adap: pointer to struct dvb_adapter
+ * @name: Adapter's name
+ * @module: initialized with THIS_MODULE at the caller
+ * @device: pointer to struct device that corresponds to the device driver
+ * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
+ * to select among them. Typically, initialized with:
+ * DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
+ */
+int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
+ struct module *module, struct device *device,
+ short *adapter_nums);
+
+/**
+ * dvb_unregister_adapter - Unregisters a DVB adapter
+ *
+ * @adap: pointer to struct dvb_adapter
+ */
+int dvb_unregister_adapter(struct dvb_adapter *adap);
+
+/**
+ * dvb_register_device - Registers a new DVB device
+ *
+ * @adap: pointer to struct dvb_adapter
+ * @pdvbdev: pointer to the place where the new struct dvb_device will be
+ * stored
+ * @template: Template used to create &pdvbdev;
+ * @priv: private data
+ * @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND,
+ * %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA,
+ * %DVB_DEVICE_NET
+ * @demux_sink_pads: Number of demux outputs, to be used to create the TS
+ * outputs via the Media Controller.
+ */
+int dvb_register_device(struct dvb_adapter *adap,
+ struct dvb_device **pdvbdev,
+ const struct dvb_device *template,
+ void *priv,
+ int type,
+ int demux_sink_pads);
+
+/**
+ * dvb_unregister_device - Unregisters a DVB device
+ *
+ * @dvbdev: pointer to struct dvb_device
+ */
+void dvb_unregister_device(struct dvb_device *dvbdev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+/**
+ * dvb_create_media_graph - Creates media graph for the Digital TV part of the
+ * device.
+ *
+ * @adap: pointer to struct dvb_adapter
+ * @create_rf_connector: if true, it creates the RF connector too
+ *
+ * This function checks all DVB-related functions at the media controller
+ * entities and creates the needed links for the media graph. It is
+ * capable of working with multiple tuners or multiple frontends, but it
+ * won't create links if the device has multiple tuners and multiple frontends
+ * or if the device has multiple muxes. In such case, the caller driver should
+ * manually create the remaining links.
+ */
+__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
+ bool create_rf_connector);
+
+static inline void dvb_register_media_controller(struct dvb_adapter *adap,
+ struct media_device *mdev)
+{
+ adap->mdev = mdev;
+}
+
+static inline struct media_device
+*dvb_get_media_controller(struct dvb_adapter *adap)
+{
+ return adap->mdev;
+}
+#else
+static inline
+int dvb_create_media_graph(struct dvb_adapter *adap,
+ bool create_rf_connector)
+{
+ return 0;
+};
+#define dvb_register_media_controller(a, b) {}
+#define dvb_get_media_controller(a) NULL
+#endif
+
+int dvb_generic_open (struct inode *inode, struct file *file);
+int dvb_generic_release (struct inode *inode, struct file *file);
+long dvb_generic_ioctl (struct file *file,
+ unsigned int cmd, unsigned long arg);
+
+/* we don't mess with video_usercopy() any more,
+we simply define out own dvb_usercopy(), which will hopefully become
+generic_usercopy() someday... */
+
+int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
+ int (*func)(struct file *file, unsigned int cmd, void *arg));
+
+/** generic DVB attach function. */
+#ifdef CONFIG_MEDIA_ATTACH
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+ void *__r = NULL; \
+ typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
+ if (__a) { \
+ __r = (void *) __a(ARGS); \
+ if (__r == NULL) \
+ symbol_put(FUNCTION); \
+ } else { \
+ printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
+ } \
+ __r; \
+})
+
+#define dvb_detach(FUNC) symbol_put_addr(FUNC)
+
+#else
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+ FUNCTION(ARGS); \
+})
+
+#define dvb_detach(FUNC) {}
+
+#endif
+
+#endif /* #ifndef _DVBDEV_H_ */
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.c b/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.c
index 34bbbc7..a941326 100644
--- a/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.c
+++ b/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.c
@@ -41,7 +41,6 @@
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/dvb/ca.h>
-#include <linux/compat.h>
#include "cimax+usb-driver.h"
#include "cimax+usb_fw.h"
@@ -1496,7 +1495,7 @@
/*dbg("Transmit %d bytes\n",urb->transfer_buffer_length);*/
/*dbg_dump("txBuf",
urb->transfer_buffer, urb->transfer_buffer_length);*/
- mod_timer(&(gbulk_timer[index].StartBulkReadTimer),
+ mod_timer(&(device->channel[index].StartBulkReadTimer),
usecs_to_jiffies(50));
if (usb_submit_urb(urb, GFP_KERNEL) < 0) {
@@ -1511,9 +1510,9 @@
} /* device_tsbulk_send */
/* ---------------------------------------------------------- */
-static void StartBulkRead_func(struct timer_list * timer)
+static void StartBulkRead_func(unsigned long context)
{
- struct bulk_timer_s *bulk_time = from_timer(bulk_time,timer,StartBulkReadTimer) ;
+ struct bulk_timer_s *bulk_time = (struct bulk_timer_s *) context;
device_start_tsbulk_in(bulk_time->device, bulk_time->index);
}
@@ -1553,8 +1552,9 @@
device->channel[index].FirstTransfer = true;
gbulk_timer[index].device = device;
gbulk_timer[index].index = index;
- timer_setup(&gbulk_timer[index].StartBulkReadTimer,
- StartBulkRead_func,0);
+ setup_timer(&device->channel[index].StartBulkReadTimer,
+ StartBulkRead_func,
+ (unsigned long)&(gbulk_timer[index]));
}
#ifdef DEBUG_CONTINUITY
init_tab_cc();
@@ -1821,11 +1821,9 @@
/* Verify direction (read/write) */
if (_IOC_DIR(cmd) & _IOC_READ)
-// err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
- err = !access_ok((void *)arg, _IOC_SIZE(cmd));
+ err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
-// err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
- err = !access_ok((void *)arg, _IOC_SIZE(cmd));
+ err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
if (err)
return -EFAULT;
@@ -2535,3 +2533,4 @@
module_init(device_init_module);
module_exit(device_exit_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.h b/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.h
index 774c50a..e4656e0 100644
--- a/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.h
+++ b/drivers/stream_input/parser/dvb_ci/cimax/usb/SRC/cimax+usb-driver.h
@@ -298,7 +298,6 @@
/**
* @brief
* TS channel (can use isoc or bulk interface).
- * x
*/
struct ts_channel_s {
spinlock_t inLock;
@@ -321,6 +320,7 @@
int nbByteSend;
int nbByteRead;
__u8 FirstTransfer;
+ struct timer_list StartBulkReadTimer;
#ifdef DEBUG_BITRATE
ktime_t bitrateTime
@@ -344,7 +344,6 @@
struct bulk_timer_s {
struct device_s *device;
__u8 index;
- struct timer_list StartBulkReadTimer;
};
int cimax_usb_select_interface(struct device_s *device, unsigned long intf);
diff --git a/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.c b/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.c
index 87bec4e..762f5ff 100644
--- a/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.c
+++ b/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.c
@@ -37,8 +37,6 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kthread.h>
-#include <linux/sched/signal.h>
-#include <linux/compat.h>
#include "dvb_ca_en50221_cimcu.h"
#include "../cimax/dvb_ringbuffer.h"
@@ -50,19 +48,6 @@
module_param_named(cammcu_debug, dvb_ca_en50221_debug, int, 0644);
MODULE_PARM_DESC(cammcu_debug, "enable verbose debug messages");
-static int dvb_ca_en50221_usleep = 800;
-
-module_param_named(cammcu_usleep, dvb_ca_en50221_usleep, int, 0644);
-MODULE_PARM_DESC(cammcu_usleep, "enable sleep");
-
-static int dvb_ca_ciplus_enable = 0;
-module_param_named(ciplus_enable, dvb_ca_ciplus_enable, int, 0644);
-MODULE_PARM_DESC(ciplus_enable, "get ci plus enable");
-
-static unsigned int dvb_ca_ci_profire = 0;
-module_param_named(ci_profire, dvb_ca_ci_profire, int, 0644);
-MODULE_PARM_DESC(ci_profire, "get ci plus profire");
-
#define dprintk if (dvb_ca_en50221_debug) printk
#define INIT_TIMEOUT_SECS 10
@@ -334,7 +319,7 @@
msleep(1);
}
- printk("%s failed timeout:%lu\n", __func__, jiffies - start);
+ dprintk("%s failed timeout:%lu\n", __func__, jiffies - start);
/* if we get here, we've timed out */
return -ETIMEDOUT;
@@ -420,32 +405,25 @@
int _address = *address;
/* grab the next tuple length and type */
- msleep(10);
- if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0) {
- printk("read_attribute_mem error\r\n");
+ if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0)
return _tupleType;
- }
-
if (_tupleType == 0xff) {
- printk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
+ dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
*address += 2;
*tupleType = _tupleType;
*tupleLength = 0;
return 0;
}
- msleep(10);
if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0)
return _tupleLength;
_address += 4;
dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
- msleep(10);
/* read in the whole tuple */
for (i = 0; i < _tupleLength; i++) {
- msleep(10);
tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2));
- printk(" 0x%02x: 0x%02x %c\n",
+ dprintk(" 0x%02x: 0x%02x %c\n",
i, tuple[i] & 0xff,
((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
}
@@ -458,136 +436,6 @@
return 0;
}
-static void parseCiplusCompatibility(char *tuple, int len, int *ci_plus_enabled)
-{
- char flag = '+';
- int number;
- int i;
-
- number = 0;
- if (tuple[0] == '0') {
- flag = '0';
- } else if (tuple[0] == '*') {
- flag = '*';
- } else {
- flag = '+';
- }
-// printk("--flag[%c]----\r\n", flag);
-/* Expected one or more decimal digits */
- for (i = 0; i < len; i++)
- {
- if (tuple[i] >= '0' && tuple[i] <= '9') {
- number *= 10;
- number += tuple[i] - '0';
- printk("--tuple[%d]=[%c]----\r\n", i, tuple[i]);
- } else if (tuple[i] == '*' || tuple[i] == '+' || tuple[i] == '-') {
- continue;
- } else {
- break;
- }
- }
- if ((flag == '-') && (number == 1))
- {
- /* CI+ "v1" not supported */
- printk("--tuple[%s]=set 0----\r\n",tuple);
- *ci_plus_enabled = 0;
- }
- else if ((flag == '*') && (number >= 1))
- {
- /* CI+ "v1" is supported */
- *ci_plus_enabled = 1;
- printk("--tuple[%s]=set 1----\r\n",tuple);
- }
- else if ((flag == '+') && (number == 1))
- {
- /* CI+ "v1" is supported */
- *ci_plus_enabled = 1;
- printk("--tuple[%s]=set 1----\r\n",tuple);
- }
-}
-
-/**
- * @brief Handle "ciprof" compatibilty item in compatiblity string
- * @param identity - item's identity
- * @param flag - compatibility flag
- * @param ci_plus_profile - the value of ciprof
- */
-static void parseCiprofCompatibility(char *tuple, int len, unsigned int *ci_plus_profile)
-{
- int valid;
- int number;
- int i;
-
- valid = 1;
- number = 0;
-
- /* Expected decimal or hexadecimal number (note: string is lowercase) */
- if ((len >= 2) &&
- (tuple[0] == '0') && (tuple[1] == 'x'))
- {
- /* Hexadecimal prefix */
- for (i = 2; (valid) && (i < len); i++)
- {
- printk("--tuple[%d]=[%c]----\r\n", i, tuple[i]);
- if (tuple[i] >= '0' && tuple[i] <= '9')
- {
- number *= 16;
- number += tuple[i] - '0';
- }
- else if (tuple[i] >= 'a' && tuple[i] <= 'f')
- {
- number *= 16;
- number += tuple[i] + 10 - 'a';
- }
- else
- {
- break;
- }
- }
- }
- else
- {
- /* Decimal expected */
- for (i = 0; (valid) && (i < len); i++)
- {
- printk("--tuple[%d]=[%c]----\r\n", i, tuple[i]);
- if (tuple[i] >= '0' && tuple[i] <= '9')
- {
- number *= 10;
- number += tuple[i] - '0';
- }
- else
- {
- break;
- }
- }
- }
-
- if (valid)
- {
- printk("--tuple[%s] number [%u]-[0x%x]---\r\n", tuple, number, number);
- *ci_plus_profile = number;
- }
-}
-
-static int dvb_ca_parse_ciinfo(struct dvb_ca_private *ca, char *tuple, int len) {
-
- /* check it contains the correct ciplus= string */
- char * ciplus_str = findstr((char *)tuple, len, "ciplus=", 7);
-
- if (ciplus_str == NULL)
- printk("ciplus_str error line[%d]\r\n", __LINE__);
- else
- parseCiplusCompatibility(ciplus_str + 7, len - (ciplus_str + 7 - tuple), &dvb_ca_ciplus_enable);
-
- ciplus_str = findstr((char *)tuple, len, "ciprof=", 7);
- if (ciplus_str == NULL)
- printk("ciprof str error line[%d]\r\n", __LINE__);
- else
- parseCiprofCompatibility(ciplus_str + 7, len - (ciplus_str + 7 - tuple), &dvb_ca_ci_profire);
-
- return 0;
-}
/**
* dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module,
@@ -616,61 +464,39 @@
// CISTPL_DEVICE_0A
if ((status =
- dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) {
- printk("read tuple error\r\n");
- return status;
- }
- if (tupleType != 0x1D) {
- printk("read tupleType error\r\n");
+ dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
+ return status;
+ if (tupleType != 0x1D)
return -EINVAL;
- }
+
+
// CISTPL_DEVICE_0C
if ((status =
- dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) {
- printk("read tupleType error line[%d]\r\n", __LINE__);
- return status;
- }
-
- if (tupleType != 0x1C) {
- printk("read tupleType error line[%d]\r\n", __LINE__);
+ dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
+ return status;
+ if (tupleType != 0x1C)
return -EINVAL;
- }
// CISTPL_VERS_1
if ((status =
- dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0){
- printk("dvb ci error line[%d]\r\n", __LINE__);
- return status;
- }
-
- if (tupleType != 0x15) {
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
+ return status;
+ if (tupleType != 0x15)
return -EINVAL;
- }
- //parse cipls and prof info
- printk("dvb ci parse ci line[%d]\r\n", __LINE__);
- dvb_ca_parse_ciinfo(ca, (char *)tuple, tupleLength);
+
+
// CISTPL_MANFID
if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
- &tupleLength, tuple)) < 0) {
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ &tupleLength, tuple)) < 0)
return status;
- }
-
- if (tupleType != 0x20){
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ if (tupleType != 0x20)
return -EINVAL;
- }
-
- if (tupleLength != 4) {
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ if (tupleLength != 4)
return -EINVAL;
- }
-
manfid = (tuple[1] << 8) | tuple[0];
devid = (tuple[3] << 8) | tuple[2];
@@ -679,28 +505,16 @@
// CISTPL_CONFIG
if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
&tupleLength, tuple)) < 0)
- {
- printk("dvb ci error line[%d]\r\n", __LINE__);
return status;
- }
-
- if (tupleType != 0x1A) {
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ if (tupleType != 0x1A)
return -EINVAL;
- }
- if (tupleLength < 3) {
- printk("dvb ci error line[%d]\r\n", __LINE__);
+ if (tupleLength < 3)
return -EINVAL;
- }
/* extract the configbase */
rasz = tuple[0] & 3;
if (tupleLength < (3 + rasz + 14))
- {
- printk("dvb ci error line[%d]\r\n", __LINE__);
return -EINVAL;
- }
-
ca->slot_info[slot].config_base = 0;
for (i = 0; i < rasz + 1; i++) {
ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i));
@@ -708,17 +522,10 @@
/* check it contains the correct DVB string */
dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8);
- if (dvb_str == NULL){
- printk("dvb ci error 5 line[%d]\r\n", __LINE__);
+ if (dvb_str == NULL)
return -EINVAL;
- }
-
if (tupleLength < ((dvb_str - (char *) tuple) + 12))
- {
- printk("dvb ci error line[%d]\r\n", __LINE__);
return -EINVAL;
- }
-
/* is it a version we support? */
if (strncmp(dvb_str + 8, "1.00", 4)) {
@@ -731,17 +538,11 @@
while ((!end_chain) && (address < 0x1000)) {
if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
&tupleLength, tuple)) < 0)
- {
- printk("dvb ci error line[%d]\r\n", __LINE__);
return status;
- }
-
switch (tupleType) {
case 0x1B: // CISTPL_CFTABLE_ENTRY
- if (tupleLength < (2 + 11 + 17)) {
- printk("dvb ci error 0x1b error line[%d]\r\n", __LINE__);
+ if (tupleLength < (2 + 11 + 17))
break;
- }
/* if we've already parsed one, just use it */
if (got_cftableentry)
@@ -759,7 +560,6 @@
break;
case 0x14: // CISTPL_NO_LINK
- printk("dvb ci no link");
break;
case 0xFF: // CISTPL_END
@@ -767,17 +567,14 @@
break;
default: /* Unknown tuple type - just skip this tuple and move to the next one */
- printk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
+ dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
tupleLength);
break;
}
}
if ((address > 0x1000) || (!got_cftableentry))
- {
- printk("dvb ci error line[%d]\r\n", __LINE__);
return -EINVAL;
- }
dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option);
@@ -1216,11 +1013,11 @@
case DVB_CA_SLOTSTATE_RUNNING:
delay = HZ * 60; /* 60s */
if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
- delay = HZ / 100; /* 100ms */
+ delay = HZ / 10; /* 100ms */
if (ca->open) {
if ((!ca->slot_info[slot].da_irq_supported) ||
(!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
- delay = HZ / 100; /* 100ms */
+ delay = HZ / 10; /* 100ms */
}
break;
}
@@ -1255,19 +1052,10 @@
while (!kthread_should_stop()) {
/* sleep for a bit */
if (!ca->wakeup) {
- if (ca->slot_count > 0
- && ca->slot_info[0].slot_state == DVB_CA_SLOTSTATE_RUNNING
- && ca->pub->get_slot_wakeup(ca->pub, 0) == 0) {
- usleep_range(dvb_ca_en50221_usleep, dvb_ca_en50221_usleep + 100);
- } else {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(ca->delay);
- }
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(ca->delay);
if (kthread_should_stop())
return 0;
- } else {
- if (ca->pub->get_slot_wakeup(ca->pub, 0) == 0)
- usleep_range(dvb_ca_en50221_usleep, dvb_ca_en50221_usleep + 100);
}
ca->wakeup = 0;
@@ -1331,8 +1119,7 @@
printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
ca->dvbdev->adapter->num);
- //ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
+ ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
dvb_ca_en50221_thread_update_delay(ca);
break;
}
@@ -1445,7 +1232,7 @@
}
-int cam_state = 0;
+
/* ******************************************************************************** */
/* EN50221 IO interface functions */
@@ -1467,45 +1254,32 @@
struct dvb_ca_private *ca = dvbdev->priv;
int err = 0;
int slot;
- u8 info = 0x80;
+
+ dprintk("%s\n", __func__);
if (mutex_lock_interruptible(&ca->ioctl_mutex)) {
printk("ci lock interrupt error\r\n");
return -ERESTARTSYS;
}
+
switch (cmd) {
- case CA_RESET: {
- if (copy_from_user(&info, (void __user *)parg, 1))
- printk("ci reset-cp error--\r\n");
- if (info >> 7 == 1 ) {
- for (slot = 0; slot < ca->slot_count; slot++) {
- mutex_lock(&ca->slot_info[slot].slot_lock);
- if (ca->pub->write_cam_control(ca->pub, slot,
- CTRLIF_COMMAND, CMDREG_RS) != 0) {
- printk("dvb_ca adapter %d: Unable to reset CAM IF\n",
- ca->dvbdev->adapter->num);
- }
- mutex_unlock(&ca->slot_info[slot].slot_lock);
+ case CA_RESET:
+ dprintk("ci reset---\r\n");
+ for (slot = 0; slot < ca->slot_count; slot++) {
+ mutex_lock(&ca->slot_info[slot].slot_lock);
+ if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
+ dvb_ca_en50221_slot_shutdown(ca, slot);
+ if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
+ dvb_ca_en50221_cimcu_camchange_irq(ca->pub,
+ slot,
+ DVB_CA_EN50221_CAMCHANGE_INSERTED);
}
- } else {
- for (slot = 0; slot < ca->slot_count; slot++) {
- mutex_lock(&ca->slot_info[slot].slot_lock);
- if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
- //if reset camcard,need send all state to app
- cam_state = 0;
- dvb_ca_en50221_slot_shutdown(ca, slot);
- if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
- dvb_ca_en50221_cimcu_camchange_irq(ca->pub,
- slot,
- DVB_CA_EN50221_CAMCHANGE_INSERTED);
- }
- mutex_unlock(&ca->slot_info[slot].slot_lock);
- }
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
}
ca->next_read_slot = 0;
dvb_ca_en50221_thread_wakeup(ca);
break;
- }
+
case CA_GET_CAP: {
struct ca_caps *caps = parg;
@@ -1521,29 +1295,18 @@
if ((info->num > ca->slot_count) || (info->num < 0)) {
err = -EINVAL;
- printk("info->num==%d\r\n",info->num);
goto out_unlock;
}
info->type = CA_CI_LINK;
info->flags = 0;
- if (cam_state != 0 && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
+ if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
&& (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) {
info->flags = CA_CI_MODULE_PRESENT;
}
-
- if (cam_state != 0 && cam_state != 1 && ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
+ if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
info->flags |= CA_CI_MODULE_READY;
}
- if (cam_state == 1 && ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
- info->flags = CA_CI_MODULE_PRESENT;
- cam_state++;
- printk("info->flags==%d\r\n",info->flags);
- }
- if (cam_state == 0) {
- cam_state++;
- printk("info->flags==%d\r\n",info->flags);
- }
break;
}
@@ -1711,8 +1474,7 @@
if (status != -EAGAIN)
goto exit;
- //msleep(1);
- usleep_range(dvb_ca_en50221_usleep, dvb_ca_en50221_usleep + 100);
+ msleep(1);
}
if (!written) {
status = -EIO;
@@ -1751,11 +1513,6 @@
return 0;
#ifdef READ_LPDU_PKT
if (ca->slot_info[slot].rx_offset != 0) {
- idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
- if (idx == -1) {
- //printk("no data to read----[%d]-\r\n", ca->slot_info[slot].rx_offset);
- return 0;
- }
*_slot = slot;
return 1;
}
@@ -1957,7 +1714,7 @@
int err;
int i;
- printk("%s\n", __func__);
+ dprintk("%s\n", __func__);
if (!try_module_get(ca->pub->owner))
return -EIO;
diff --git a/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.h b/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.h
index 3b14d17..7102b3c 100644
--- a/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.h
+++ b/drivers/stream_input/parser/dvb_ci/cimcu/dvb_ca_en50221_cimcu.h
@@ -20,7 +20,7 @@
#include <linux/list.h>
#include <linux/dvb/ca.h>
-#include "dvbdev.h"
+#include "../cimax/dvbdev.h"
#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
@@ -71,7 +71,6 @@
int (*slot_ts_enable)(struct dvb_ca_en50221_cimcu *ca, int slot);
int (*poll_slot_status)(struct dvb_ca_en50221_cimcu *ca, int slot, int open);
- int (*get_slot_wakeup)(struct dvb_ca_en50221_cimcu *ca, int slot);
void *data;
diff --git a/drivers/stream_input/parser/dvb_common.h b/drivers/stream_input/parser/dvb_common.h
index c4c597b..eae2625 100644
--- a/drivers/stream_input/parser/dvb_common.h
+++ b/drivers/stream_input/parser/dvb_common.h
@@ -22,46 +22,4 @@
#include "dvb_frontend.h"
-typedef enum dmx_source {
- DMX_SOURCE_FRONT0 = 0,
- DMX_SOURCE_FRONT1,
- DMX_SOURCE_FRONT2,
- DMX_SOURCE_FRONT3,
- DMX_SOURCE_DVR0 = 16,
- DMX_SOURCE_DVR1,
- DMX_SOURCE_DVR2,
- DMX_SOURCE_DVR3,
-
-#ifdef CONFIG_AMLOGIC_DVB_COMPAT
- DMX_SOURCE_FRONT0_OFFSET = 100,
- DMX_SOURCE_FRONT1_OFFSET,
- DMX_SOURCE_FRONT2_OFFSET
-#endif
-} dmx_source_t;
-
-enum aml_dmx_id_t {
- AM_DMX_0 = 0,
- AM_DMX_1,
- AM_DMX_2,
- AM_DMX_MAX,
-};
-
-enum aml_ts_source_t {
- AM_TS_SRC_TS0,
- AM_TS_SRC_TS1,
- AM_TS_SRC_TS2,
- AM_TS_SRC_TS3,
-
- AM_TS_SRC_S_TS0,
- AM_TS_SRC_S_TS1,
- AM_TS_SRC_S_TS2,
- AM_TS_SRC_S_TS3,
-
- AM_TS_SRC_HIU,
- AM_TS_SRC_HIU1,
- AM_TS_SRC_DMX0,
- AM_TS_SRC_DMX1,
- AM_TS_SRC_DMX2
-};
-
#endif /* __DVB_COMMON_H__ */
diff --git a/drivers/stream_input/parser/hw_demux/Makefile b/drivers/stream_input/parser/hw_demux/Makefile
index 93454ae..e031594 100644
--- a/drivers/stream_input/parser/hw_demux/Makefile
+++ b/drivers/stream_input/parser/hw_demux/Makefile
@@ -1,6 +1,6 @@
obj-m += aml_hardware_dmx.o
-ccflags-y += -I$(srctree)/include/media -I$(srctree)/drivers/media/pci/ttpci -I$(srctree)/drivers/gpio -I$(srctree)/include -DENABLE_DEMUX_DRIVER
+ccflags-y += -I$(srctree)/drivers/media/dvb-core -I$(srctree)/drivers/gpio -I$(srctree)/include -DENABLE_DEMUX_DRIVER
aml_hardware_dmx-objs += aml_dvb.o
aml_hardware_dmx-objs += aml_dmx.o
diff --git a/drivers/stream_input/parser/hw_demux/aml_dmx.c b/drivers/stream_input/parser/hw_demux/aml_dmx.c
index 7d9d7de..ad34987 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dmx.c
+++ b/drivers/stream_input/parser/hw_demux/aml_dmx.c
@@ -50,7 +50,6 @@
#include "c_stb_regs_define.h"
#include "aml_dvb.h"
#include "aml_dvb_reg.h"
-#include <linux/sched/signal.h>
#define ENABLE_SEC_BUFF_WATCHDOG
@@ -193,18 +192,6 @@
static int use_of_sop;
module_param(use_of_sop, int, 0644);
-/*
- As the default value of unused channel's PID_TYPE is 0x7,
- if we use PID_TYPE(RECORDER_STREAM:0x7) for recording channel,
- the data with the pid which assigned in unused channel's setting will be captured also.
- To avoid the high bitrate(exists) of this pid's data flood the buffers in the data path,
- which will causes the record data corruption, and bad picture decoded.
-*/
-MODULE_PARM_DESC(g_chan_def_pid, "\n\t\t default pid for unused channel");
-static int g_chan_def_pid = 0x1FFE;
-module_param(g_chan_def_pid, int, 0644);
-
-
/*#define CIPLUS_KEY0 0x16f8
#define CIPLUS_KEY1 0x16f9
#define CIPLUS_KEY2 0x16fa
@@ -513,28 +500,11 @@
#define asyncfifo_get_dev(afifo) ((afifo)->dvb->dev)
-int dmx_phyreg_access(unsigned int reg, unsigned int writeval,
- unsigned int *readval)
-{
- void __iomem *vaddr;
-
- reg = round_down(reg, 0x3);
- vaddr = ioremap(reg, 0x4);
- if (!vaddr)
- return -ENOMEM;
-
- if (readval)
- *readval = readl_relaxed(vaddr);
- else
- writel_relaxed(writeval, vaddr);
- iounmap(vaddr);
- return 0;
-}
/*Section buffer watchdog*/
-static void section_buffer_watchdog_func(struct timer_list * timer)
+static void section_buffer_watchdog_func(unsigned long arg)
{
- struct aml_dvb *dvb = from_timer(dvb,timer,watchdog_timer);
+ struct aml_dvb *dvb = (struct aml_dvb *)arg;
struct aml_dmx *dmx;
u32 section_busy32 = 0, om_cmd_status32 = 0,
demux_channel_activity32 = 0;
@@ -785,7 +755,7 @@
struct dvb_demux_feed *feed = dmx->channel[f->chan_id].feed;
if (feed && feed->cb.sec)
- feed->cb.sec(p, sec_len, NULL, 0, f->filter,0);
+ feed->cb.sec(p, sec_len, NULL, 0, f->filter);
}
static void hardware_match_section(struct aml_dmx *dmx,
@@ -1241,7 +1211,7 @@
{
dmx->channel[2].feed->cb.ts(buffer1_virt, len1,
buffer2_virt, len2,
- &dmx->channel[2].feed->feed.ts,0);
+ &dmx->channel[2].feed->feed.ts);
}
}
WRITE_MPEG_REG(PARSER_SUB_RP, rd_ptr);
@@ -1302,7 +1272,7 @@
if (ch->feed->ts_type & TS_PAYLOAD_ONLY) {
ch->feed->cb.ts(buffer1,
len1, buffer2, len2,
- &ch->feed->feed.ts,0);
+ &ch->feed->feed.ts);
}
}
}
@@ -1498,7 +1468,7 @@
channel->dvr_feed->cb.ts(
(u8 *)afifo->pages+afifo->buf_read*size,
cnt*size, NULL, 0,
- &channel->dvr_feed->feed.ts,0);
+ &channel->dvr_feed->feed.ts);
} else {
blk.addr = afifo->blk.addr+afifo->buf_read*size;
blk.len = cnt*size;
@@ -1511,7 +1481,7 @@
(u8 *)&blk,
sizeof(struct aml_dvr_block),
NULL, 0,
- &channel->dvr_feed->feed.ts,0);
+ &channel->dvr_feed->feed.ts);
}
}
afifo->buf_read = 0;
@@ -1533,7 +1503,7 @@
channel->dvr_feed->cb.ts(
(u8 *)afifo->pages+afifo->buf_read*size,
cnt*size, NULL, 0,
- &channel->dvr_feed->feed.ts,0);
+ &channel->dvr_feed->feed.ts);
}
} else {
blk.addr = afifo->blk.addr+afifo->buf_read*size;
@@ -1547,7 +1517,7 @@
(u8 *)&blk,
sizeof(struct aml_dvr_block),
NULL, 0,
- &channel->dvr_feed->feed.ts,0);
+ &channel->dvr_feed->feed.ts);
}
}
afifo->buf_read = afifo->buf_toggle;
@@ -1910,10 +1880,10 @@
case CA_CW_SM4_ODD:
case CA_CW_SM4_EVEN_IV:
case CA_CW_SM4_ODD_IV:
+ am_ci_plus_set_output(ch);
ret = dsc_set_aes_des_sm4_key(ch, flags, type, key);
if (ret != 0)
goto END;
- am_ci_plus_set_output(ch);
/* Different with old mode, do change */
if (ch->work_mode == DVBCSA_MODE || ch->work_mode == -1) {
if (ch->work_mode == -1)
@@ -2233,46 +2203,12 @@
pr_dbg("CIPLUS_CONFIG is 0x%x\n",data);
}
-static void set_fec_core_sel (struct aml_dvb *dvb)
-{
- int i;
-
- for (i = 0; i < DMX_DEV_COUNT; i ++) {
- int set = 0;
- u32 ctrl = DMX_READ_REG(i, FEC_INPUT_CONTROL);
-
- if ((dvb->dsc[0].dst != -1) && (dvb->dsc[0].dst - AM_TS_SRC_DMX0 == i)) {
- set = 1;
- } else if ((dvb->dsc[1].dst != -1) && (dvb->dsc[1].dst - AM_TS_SRC_DMX0 == i)) {
- set = 1;
- } else {
- u32 cfg = READ_MPEG_REG(CIPLUS_CONFIG);
-
- if (cfg & (1 << CNTL_ENABLE)) {
- if (!ciplus_out_auto_mode) {
- if (ciplus_out_sel & (1 << i))
- set = 1;
- }
- }
- }
-
- if (set) {
- ctrl |= (1 << FEC_CORE_SEL);
- } else {
- ctrl &= ~(1 << FEC_CORE_SEL);
- }
-
- DMX_WRITE_REG(i, FEC_INPUT_CONTROL, ctrl);
- }
-}
-
/*
* Set output to demux set.
*/
static void am_ci_plus_set_output(struct aml_dsc_channel *ch)
{
struct aml_dsc *dsc = ch->dsc;
- struct aml_dvb *dvb = dsc->dvb;
u32 data;
u32 in = 0, out = 0;
int set = 0;
@@ -2333,8 +2269,6 @@
WRITE_MPEG_REG(STB_TOP_CONFIG, data);
pr_inf("dsc ciplus in[%x] out[%x] %s\n", in, out,
(ciplus_out_auto_mode) ? "" : "force");
-
- set_fec_core_sel(dvb);
}
}
@@ -2513,7 +2447,7 @@
void dsc_release(void)
{
- //aml_ci_plus_disable();
+ aml_ci_plus_disable();
}
/************************* AES DESC************************************/
void set_ciplus_input_source(struct aml_dsc *dsc)
@@ -3083,9 +3017,13 @@
return -1;
/*Reset the hardware */
if (!dvb->dmx_init) {
- timer_setup(&dvb->watchdog_timer, section_buffer_watchdog_func,0);
+ init_timer(&dvb->watchdog_timer);
+ dvb->watchdog_timer.function = section_buffer_watchdog_func;
+ dvb->watchdog_timer.expires =
+ jiffies + msecs_to_jiffies(WATCHDOG_TIMER);
+ dvb->watchdog_timer.data = (unsigned long)dvb;
#ifdef ENABLE_SEC_BUFF_WATCHDOG
- mod_timer(&dvb->watchdog_timer,jiffies + msecs_to_jiffies(WATCHDOG_TIMER));
+ add_timer(&dvb->watchdog_timer);
#endif
dmx_reset_hw(dvb);
}
@@ -3463,6 +3401,7 @@
(1 << AUDIO_PACKET) |
(1 << SUB_PACKET) |
(1 << SCR_ONLY_PACKET) |
+ (1 << RECORDER_STREAM) |
(1 << OTHER_PES_PACKET));
DMX_WRITE_REG(dmx->id, PES_STRONG_SYNC, 0x1234);
DMX_WRITE_REG(dmx->id, DEMUX_ENDIAN,
@@ -3484,19 +3423,6 @@
(hi_bsf << USE_HI_BSF_INTERFACE));
}
- if (!fec_core_sel) {
- u32 cfg = READ_MPEG_REG(CIPLUS_CONFIG);
-
- if (cfg & (1 << CNTL_ENABLE)) {
- if (!ciplus_out_auto_mode) {
- int mask = 1 << dmx->id;
-
- if (ciplus_out_sel & mask)
- fec_core_sel = 1;
- }
- }
- }
-
if (fec_sel == -1) {
dmx_cascade_set(dmx->id,dmx->source);
DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL,
@@ -3518,15 +3444,8 @@
(0x40 << MAX_OM_DMA_COUNT) |
(0x7f << LAST_OM_ADDR));
- /*RECORDER_STREAM depends on video2*/
- /*VIDEO_STREAM_ID: video2_stream_id (bit[31:16])*/
- /*DEMUX_CONTROL:
- bit[25] video2_en
- bit[24:22] video2_type*/
- #define VIDEO2_FOR_RECORDER_STREAM (1 << 25 | 7 << 22)
-
DMX_WRITE_REG(dmx->id, VIDEO_STREAM_ID,
- ((record) ? 0xFFFF0000 : 0));
+ ((record && !hi_bsf) ? 0xFFFF : 0));
DMX_WRITE_REG(dmx->id, DEMUX_CONTROL,
(0 << BYPASS_USE_RECODER_PATH) |
@@ -3541,14 +3460,10 @@
(1 << ENABLE_FREE_CLK_FEC_DATA_VALID) |
(1 << ENABLE_FREE_CLK_STB_REG) |
(1 << STB_DEMUX_ENABLE) |
- (use_sop << NOT_USE_OF_SOP_INPUT) |
- ((record)? VIDEO2_FOR_RECORDER_STREAM : 0));
- pr_dbg("dmx control[%#x]\n",
- DMX_READ_REG(dmx->id, DEMUX_CONTROL));
+ (use_sop << NOT_USE_OF_SOP_INPUT));
} else {
DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
- /* if disable FEC_INPUT_CONTROL, background and unattended record will fail */
- // DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL, 0);
+ DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL, 0);
DMX_WRITE_REG(dmx->id, DEMUX_CONTROL, 0);
//dmx not used, but it can cascade for other dmx
if ((dmx->source == AM_TS_SRC_DMX0 ||
@@ -3609,7 +3524,7 @@
u32 type;
if (!dmx->channel[cid].used)
- return (0x7 << PID_TYPE) | g_chan_def_pid;
+ return 0xFFFF;
if (dmx->channel[cid].type == DMX_TYPE_SEC) {
type = SECTION_PACKET;
@@ -3632,7 +3547,8 @@
type = OTHER_PES_PACKET;
break;
default:
- type = RECORDER_STREAM;
+ type = (dmx->channel[0].used || dmx->channel[1].used) ?
+ RECORDER_STREAM : VIDEO_PACKET;
break;
}
}
@@ -4202,13 +4118,6 @@
}
}
}
-
- /*{
- u32 data;
- data = READ_MPEG_REG(STB_TOP_CONFIG);
- ciplus = 0x7C000000 & data;
- }*/
-
WRITE_MPEG_REG(RESET1_REGISTER, RESET_DEMUXSTB);
/*WRITE_MPEG_REG(RESET3_REGISTER, RESET_DEMUX2|RESET_DEMUX1|RESET_DEMUX0|RESET_S2P1|RESET_S2P0|RESET_TOP);*/
@@ -4219,6 +4128,11 @@
break;
}
}
+ {
+ u32 data;
+ data = READ_MPEG_REG(STB_TOP_CONFIG);
+ ciplus = 0x7C000000 & data;
+ }
WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
WRITE_MPEG_REG(STB_S2P2_CONFIG, 0);
@@ -4379,7 +4293,7 @@
dsc_set_pid(ch, ch->pid);
if (flag)
ch->used = 0;
- dsc_set_keys(ch);
+ //dsc_set_keys(ch);
}
}
}
@@ -4422,13 +4336,6 @@
dvb->dmx_watchdog_disable[dmx->id] = 1;
}
#endif
-
- /*{
- u32 data;
- data = READ_MPEG_REG(STB_TOP_CONFIG);
- ciplus = 0x7C000000 & data;
- }*/
-
pr_error("dmx_reset_dmx_hw_ex_unlock into\n");
WRITE_MPEG_REG(RESET3_REGISTER,
(dmx->id) ? ((dmx->id ==
@@ -4447,6 +4354,11 @@
}
/*WRITE_MPEG_REG(STB_TOP_CONFIG, 0); */
+ {
+ u32 data;
+ data = READ_MPEG_REG(STB_TOP_CONFIG);
+ ciplus = 0x7C000000 & data;
+ }
{
u32 version, data;
@@ -4610,7 +4522,7 @@
dsc_set_pid(ch, ch->pid);
if (flag)
ch->used = 0;
- dsc_set_keys(ch);
+ //dsc_set_keys(ch);
}
}
}
@@ -4836,6 +4748,19 @@
dmx_set_chan_regs(dmx, id);
+ /* If video/audio channel started,
+ * visit all channels with type:VIDEO_PACKET
+ * change them to type:RECORDER_STREAM
+ */
+ if (id == 0 || id == 1) {
+ int i;
+ for (i = SYS_CHAN_COUNT; i < CHANNEL_COUNT; i++) {
+ if (dmx->channel[i].used
+ && dmx->channel[i].pkt_type == VIDEO_PACKET)
+ dmx_set_chan_regs(dmx, i);
+ }
+ }
+
set_debug_dmx_chanpids(dmx->id, id, pid);
dmx->chan_count++;
@@ -4853,6 +4778,25 @@
dmx->channel[cid].pid = 0x1fff;
dmx_set_chan_regs(dmx, cid);
+ /* video/audio channel gone,
+ * RECORDER_STREAM channels depends on AV channel's existence
+ * setup one fake video channel,
+ * then other RECORDER_STREAM channels will be happy to run.
+ */
+ if (cid == 0 || cid == 1) {
+ int i;
+ struct aml_channel *pch;
+
+ for (i = SYS_CHAN_COUNT; i < CHANNEL_COUNT; i++) {
+ pch = &dmx->channel[i];
+
+ if (pch->used) {
+ if (pch->pkt_type == RECORDER_STREAM)
+ dmx_set_chan_regs(dmx, i);
+ }
+ }
+ }
+
if (cid == 2) {
u32 parser_sub_start_ptr;
@@ -5967,7 +5911,7 @@
return 0;
}
-static ssize_t tsfile_clkdiv_store(struct class *class,
+static ssize_t stb_set_tsfile_clkdiv(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -5979,7 +5923,7 @@
return size;
}
-static ssize_t tsfile_clkdiv_show(struct class *class,
+static ssize_t stb_get_tsfile_clkdiv(struct class *class,
struct class_attribute *attr, char *buf)
{
ssize_t ret;
@@ -6049,7 +5993,7 @@
#define DEMUX_SCAMBLE_FUNC_DECL(i) \
-static ssize_t demux##i##_scramble_show(struct class *class, \
+static ssize_t dmx_reg_value_show_demux##i##_scramble(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
int data = 0;\
@@ -6109,9 +6053,7 @@
struct class_attribute *attr,
const char *buf, size_t size)
{
- struct aml_dvb *dvb = aml_get_dvb_device();
int i, tmp;
- u32 top_cfg, ci_cfg;
i = kstrtoint(buf, -1, &tmp);
if (tmp > 8 || tmp < 0)
@@ -6125,27 +6067,6 @@
ciplus_out_sel = tmp;
pr_error("Auto set output mode disable\n");
}
-
- top_cfg = READ_MPEG_REG(STB_TOP_CONFIG);
- ci_cfg = READ_MPEG_REG(CIPLUS_CONFIG);
-
- if (ci_cfg & (1 << CNTL_ENABLE)) {
- int out = 0;
-
- if (ciplus_out_auto_mode) {
- if (dvb->dsc[0].source != -1)
- out = 1 << (dvb->dsc[0].source - AM_TS_SRC_DMX0);
- } else {
- out = ciplus_out_sel;
- }
-
- top_cfg &= ~(7<<CIPLUS_OUT_SEL);
- top_cfg |= (out<<CIPLUS_OUT_SEL);
- WRITE_MPEG_REG(STB_TOP_CONFIG, top_cfg);
-
- set_fec_core_sel(dvb);
- }
-
return size;
}
static ssize_t reset_fec_input_ctrl_show(struct class *class,
@@ -6169,21 +6090,21 @@
return size;
}
-static ssize_t register_addr_show(struct class *class,
+static ssize_t dmx_reg_addr_show_source(struct class *class,
struct class_attribute *attr,
char *buf);
-static ssize_t register_addr_store(struct class *class,
+static ssize_t dmx_reg_addr_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size);
-static ssize_t dmx_id_show(struct class *class,
+static ssize_t dmx_id_show_source(struct class *class,
struct class_attribute *attr, char *buf);
-static ssize_t dmx_id_store(struct class *class,
+static ssize_t dmx_id_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size);
-static ssize_t register_value_show(struct class *class,
+static ssize_t dmx_reg_value_show_source(struct class *class,
struct class_attribute *attr,
char *buf);
-static ssize_t register_value_store(struct class *class,
+static ssize_t dmx_reg_value_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size);
static ssize_t dmx_sec_statistics_show(struct class *class,
@@ -6191,63 +6112,51 @@
char *buf);
static int reg_addr;
-static CLASS_ATTR_RW(dmx_id);
-static CLASS_ATTR_RW(register_addr);
-static CLASS_ATTR_RW(register_value);
-static CLASS_ATTR_RW(tsfile_clkdiv);
+static struct class_attribute aml_dmx_class_attrs[] = {
+ __ATTR(dmx_id, 0644, dmx_id_show_source,
+ dmx_id_store_source),
+ __ATTR(register_addr, 0644, dmx_reg_addr_show_source,
+ dmx_reg_addr_store_source),
+ __ATTR(register_value, 0644, dmx_reg_value_show_source,
+ dmx_reg_value_store_source),
+ __ATTR(tsfile_clkdiv, 0644, stb_get_tsfile_clkdiv,
+ stb_set_tsfile_clkdiv),
#define DEMUX_SCAMBLE_ATTR_DECL(i)\
- CLASS_ATTR_RO(demux##i##_scramble);
+ __ATTR(demux##i##_scramble, 0644, \
+ dmx_reg_value_show_demux##i##_scramble, NULL)
#if DMX_DEV_COUNT > 0
-DEMUX_SCAMBLE_ATTR_DECL(0);
+ DEMUX_SCAMBLE_ATTR_DECL(0),
#endif
#if DMX_DEV_COUNT > 1
-DEMUX_SCAMBLE_ATTR_DECL(1);
+ DEMUX_SCAMBLE_ATTR_DECL(1),
#endif
#if DMX_DEV_COUNT > 2
-DEMUX_SCAMBLE_ATTR_DECL(2);
+ DEMUX_SCAMBLE_ATTR_DECL(2),
#endif
-static CLASS_ATTR_RW(dmx_smallsec);
-static CLASS_ATTR_RW(dmx_timeout);
-static CLASS_ATTR_RW(reset_fec_input_ctrl);
-static CLASS_ATTR_RW(ciplus_output_ctrl);
-static CLASS_ATTR_RO(dmx_sec_statistics);
-
-#define DMX_ATTR(name) &class_attr_##name.attr
-
-static struct attribute *aml_dmx_class_attrs[] = {
- DMX_ATTR(dmx_id),
- DMX_ATTR(register_addr),
- DMX_ATTR(register_value),
- DMX_ATTR(tsfile_clkdiv),
- DMX_ATTR(dmx_smallsec),
- DMX_ATTR(dmx_timeout),
- DMX_ATTR(reset_fec_input_ctrl),
- DMX_ATTR(ciplus_output_ctrl),
- DMX_ATTR(dmx_sec_statistics),
-#define DEMUX_SCRAMBLE(i) \
- DMX_ATTR(demux##i##_scramble)
-#if DMX_DEV_COUNT > 0
- DEMUX_SCRAMBLE(0),
-#endif
-#if DMX_DEV_COUNT > 1
- DEMUX_SCRAMBLE(1),
-#endif
-#if DMX_DEV_COUNT > 2
- DEMUX_SCRAMBLE(2),
-#endif
- NULL,
+ __ATTR(dmx_smallsec, 0644,
+ dmx_smallsec_show,
+ dmx_smallsec_store),
+ __ATTR(dmx_timeout, 0644,
+ dmx_timeout_show,
+ dmx_timeout_store),
+ __ATTR(reset_fec_input_ctrl, 0644,
+ reset_fec_input_ctrl_show,
+ reset_fec_input_ctrl_store),
+ __ATTR(ciplus_output_ctrl, 0644,
+ ciplus_output_ctrl_show,
+ ciplus_output_ctrl_store),
+ __ATTR_RO(dmx_sec_statistics),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(aml_dmx_class);
-
static struct class aml_dmx_class = {
.name = "dmx",
- .class_groups = aml_dmx_class_groups,
+ .class_attrs = aml_dmx_class_attrs,
};
-static ssize_t dmx_id_show(struct class *class,
+static ssize_t dmx_id_show_source(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret;
@@ -6256,7 +6165,7 @@
return ret;
}
-static ssize_t dmx_id_store(struct class *class,
+static ssize_t dmx_id_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -6275,7 +6184,7 @@
return size;
}
-static ssize_t register_addr_show(struct class *class,
+static ssize_t dmx_reg_addr_show_source(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -6285,7 +6194,7 @@
return ret;
}
-static ssize_t register_addr_store(struct class *class,
+static ssize_t dmx_reg_addr_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -6299,7 +6208,7 @@
return size;
}
-static ssize_t register_value_show(struct class *class,
+static ssize_t dmx_reg_value_show_source(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -6310,7 +6219,7 @@
return ret;
}
-static ssize_t register_value_store(struct class *class,
+static ssize_t dmx_reg_value_store_source(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.c b/drivers/stream_input/parser/hw_demux/aml_dvb.c
index 6889e89..4e1549c 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dvb.c
+++ b/drivers/stream_input/parser/hw_demux/aml_dvb.c
@@ -48,10 +48,8 @@
#include <linux/reset.h>
#include <linux/of_gpio.h>
#include <linux/amlogic/media/utils/amstream.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
#include <linux/clk.h>
-#include <linux/of_irq.h>
-#include <linux/compat.h>
#include "c_stb_define.h"
#include "c_stb_regs_define.h"
#include "aml_dvb.h"
@@ -76,12 +74,6 @@
#define DVB_VERSION "V2.02"
-
-//echo 0xff646180 0x40 > /sys/kernel/debug/aml_reg/paddr
-//echo 0xff634590 0x1 > /sys/kernel/debug/aml_reg/paddr
-#define TSINB_DEGLITCH0 0xff646180
-#define TSINB_DEGLITCH1 0xff634590
-
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
MODULE_PARM_DESC(dsc_max, "max number of dsc");
@@ -181,7 +173,8 @@
static int aml_dvb_dmx_init(struct aml_dvb *advb, struct aml_dmx *dmx, int id)
{
int i, ret;
- struct device_node *node_dmx = NULL;
+
+ struct resource *res;
char buf[32];
switch (id) {
@@ -195,19 +188,13 @@
dmx->dmx_irq = INT_DEMUX_2;
break;
}
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "dmx");
- node_dmx = of_parse_phandle(advb->pdev->dev.of_node, buf, 0);
- if (node_dmx) {
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "demux%d_irq", id);
- ret = of_irq_get_byname(node_dmx, buf);
- if (ret > 0)
- dmx->dmx_irq = ret;
- printk("get irq num demux%d_irq:%d\n",id,dmx->dmx_irq);
- } else {
- printk("get default demux%d_irq:%d\n",id,dmx->dmx_irq);
- }
+
+ snprintf(buf, sizeof(buf), "demux%d_irq", id);
+ res = platform_get_resource_byname(advb->pdev, IORESOURCE_IRQ, buf);
+ if (res)
+ dmx->dmx_irq = res->start;
+
+ pr_dbg("%s irq num:%d \r\n", buf, dmx->dmx_irq);
dmx->source = -1;
dmx->dump_ts_select = 0;
@@ -493,7 +480,7 @@
dsc_reset(dsc);
break;
case CA_GET_CAP: {
- struct ca_caps *cap = parg;
+ ca_caps_t *cap = parg;
cap->slot_num = 1;
cap->slot_type = CA_DESCR;
@@ -502,7 +489,7 @@
break;
}
case CA_GET_SLOT_INFO: {
- struct ca_slot_info *slot = parg;
+ ca_slot_info_t *slot = parg;
slot->num = 1;
slot->type = CA_DESCR;
@@ -510,14 +497,14 @@
break;
}
case CA_GET_DESCR_INFO: {
- struct ca_descr_info *descr = parg;
+ ca_descr_info_t *descr = parg;
descr->num = DSC_COUNT;
descr->type = 0;
break;
}
case CA_SET_DESCR: {
- struct ca_descr *d = parg;
+ ca_descr_t *d = parg;
struct ca_descr_ex dex;
dex.index = d->index;
@@ -530,7 +517,7 @@
break;
}
case CA_SET_PID: {
- struct ca_pid *pi = parg;
+ ca_pid_t *pi = parg;
int i;
if (pi->index == -1) {
@@ -696,9 +683,8 @@
static int aml_dvb_asyncfifo_init(struct aml_dvb *advb,
struct aml_asyncfifo *asyncfifo, int id)
{
+ struct resource *res;
char buf[32];
- int ret = 0;
- struct device_node *node_dmx = NULL;
if (id == 0)
asyncfifo->asyncfifo_irq = INT_ASYNC_FIFO_FLUSH;
@@ -707,19 +693,11 @@
else
asyncfifo->asyncfifo_irq = INT_ASYNC_FIFO2_FLUSH;
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "dmx");
- node_dmx = of_parse_phandle(advb->pdev->dev.of_node, buf, 0);
- if (node_dmx) {
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "dvr%d_irq", id);
- ret = of_irq_get_byname(node_dmx, buf);
- if (ret > 0)
- asyncfifo->asyncfifo_irq = ret;
- printk("get async%d_irq:%d\n",id,asyncfifo->asyncfifo_irq);
- } else {
- printk("get default async%d_irq:%d\n",id,asyncfifo->asyncfifo_irq);
- }
+ snprintf(buf, sizeof(buf), "dvr%d_irq", id);
+ res = platform_get_resource_byname(advb->pdev, IORESOURCE_IRQ, buf);
+ if (res)
+ asyncfifo->asyncfifo_irq = res->start;
+ pr_dbg("%s irq num:%d \n", buf, asyncfifo->asyncfifo_irq);
asyncfifo->dvb = advb;
asyncfifo->id = id;
asyncfifo->init = 0;
@@ -768,7 +746,7 @@
/*Show the STB input source*/
-static ssize_t source_show(struct class *class,
+static ssize_t stb_show_source(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -815,7 +793,7 @@
return ret;
}
-static ssize_t clear_av_store(struct class *class,
+static ssize_t stb_clear_av(struct class *class,
struct class_attribute *attr, const char *buf,
size_t size)
{
@@ -876,7 +854,7 @@
}
/*Set the STB input source*/
-static ssize_t source_store(struct class *class,
+static ssize_t stb_store_source(struct class *class,
struct class_attribute *attr, const char *buf,
size_t size)
{
@@ -908,7 +886,7 @@
return size;
}
-static ssize_t demux_reset_all_flag_show(struct class *class,
+static ssize_t show_dmx_reset_all_flag(struct class *class,
struct class_attribute *attr, char *buf)
{
ssize_t ret = 0;
@@ -921,7 +899,7 @@
ret = sprintf(buf, "%s\n", src);
return ret;
}
-static ssize_t demux_reset_all_flag_store(struct class *class,
+static ssize_t set_dmx_reset_all_flag(struct class *class,
struct class_attribute *attr, const char *buf,
size_t size)
{
@@ -936,7 +914,7 @@
/*Show the descrambler's input source*/
#define DSC_SOURCE_FUNC_DECL(i) \
-static ssize_t dsc##i##_source_show(struct class *class, \
+static ssize_t dsc##i##_show_source(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -974,7 +952,7 @@
ret = sprintf(buf, "%s-%s\n", src, dst);\
return ret;\
} \
-static ssize_t dsc##i##_source_store(struct class *class, \
+static ssize_t dsc##i##_store_source(struct class *class, \
struct class_attribute *attr, const char *buf, size_t size)\
{\
dmx_source_t src = -1, dst = -1;\
@@ -1003,7 +981,7 @@
/*Show free descramblers count*/
#define DSC_FREE_FUNC_DECL(i) \
-static ssize_t dsc##i##_free_dscs_show(struct class *class, \
+static ssize_t dsc##i##_show_free_dscs(struct class *class, \
struct class_attribute *attr, char *buf) \
{ \
struct aml_dvb *dvb = &aml_dvb_device; \
@@ -1033,7 +1011,7 @@
#endif
/*Show the TS output source*/
-static ssize_t tso_source_show(struct class *class,
+static ssize_t tso_show_source(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1078,7 +1056,7 @@
}
/*Set the TS output source*/
-static ssize_t tso_source_store(struct class *class,
+static ssize_t tso_store_source(struct class *class,
struct class_attribute *attr, const char *buf,
size_t size)
{
@@ -1108,7 +1086,7 @@
/*Show PCR*/
#define DEMUX_PCR_FUNC_DECL(i) \
-static ssize_t demux##i##_pcr_show(struct class *class, \
+static ssize_t demux##i##_show_pcr(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
int f = 0;\
@@ -1170,7 +1148,7 @@
/*Show the STB input source*/
#define DEMUX_SOURCE_FUNC_DECL(i) \
-static ssize_t demux##i##_source_show(struct class *class, \
+static ssize_t demux##i##_show_source(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1215,7 +1193,7 @@
ret = sprintf(buf, "%s\n", src);\
return ret;\
} \
-static ssize_t demux##i##_source_store(struct class *class, \
+static ssize_t demux##i##_store_source(struct class *class, \
struct class_attribute *attr, const char *buf, size_t size)\
{\
dmx_source_t src = -1;\
@@ -1250,7 +1228,7 @@
/*Show free filters count*/
#define DEMUX_FREE_FILTERS_FUNC_DECL(i) \
-static ssize_t demux##i##_free_filters_show(struct class *class, \
+static ssize_t demux##i##_show_free_filters(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1271,7 +1249,7 @@
/*Show dmx dev open count*/
#define DEMUX_DEV_USERS_FUNC_DECL(i) \
-static ssize_t demux##i##_dev_users_show(struct class *class, \
+static ssize_t demux##i##_show_dev_users(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1368,7 +1346,7 @@
/*Show filter users count*/
#define DEMUX_FILTER_USERS_FUNC_DECL(i) \
-static ssize_t demux##i##_filter_users_show(struct class *class, \
+static ssize_t demux##i##_show_filter_users(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1392,7 +1370,7 @@
ret = sprintf(buf, "%d\n", count);\
return ret;\
} \
-static ssize_t demux##i##_filter_users_store(struct class *class, \
+static ssize_t demux##i##_store_filter_used(struct class *class, \
struct class_attribute *attr, const char *buf, size_t size)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1415,7 +1393,7 @@
/*Show ts header*/
#define DEMUX_TS_HEADER_FUNC_DECL(i) \
-static ssize_t demux##i##_ts_header_show(struct class *class, \
+static ssize_t demux##i##_show_ts_header(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
int hdr = 0;\
@@ -1430,7 +1408,7 @@
/*Show channel activity*/
#define DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(i) \
-static ssize_t demux##i##_channel_activity_show(struct class *class, \
+static ssize_t demux##i##_show_channel_activity(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
int f = 0;\
@@ -1458,7 +1436,7 @@
/*DVR record mode*/
#define DVR_MODE_FUNC_DECL(i) \
-static ssize_t dvr##i##_mode_show(struct class *class, \
+static ssize_t dvr##i##_show_mode(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1473,7 +1451,7 @@
ret = sprintf(buf, "%s\n", mode);\
return ret;\
} \
-static ssize_t dvr##i##_mode_store(struct class *class, \
+static ssize_t dvr##i##_store_mode(struct class *class, \
struct class_attribute *attr, const char *buf, size_t size)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1528,7 +1506,7 @@
/*Show the async fifo source*/
#define ASYNCFIFO_SOURCE_FUNC_DECL(i) \
-static ssize_t asyncfifo##i##_source_show(struct class *class, \
+static ssize_t asyncfifo##i##_show_source(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1554,7 +1532,7 @@
ret = sprintf(buf, "%s\n", src);\
return ret;\
} \
-static ssize_t asyncfifo##i##_source_store(struct class *class, \
+static ssize_t asyncfifo##i##_store_source(struct class *class, \
struct class_attribute *attr, const char *buf, size_t size)\
{\
enum aml_dmx_id_t src = -1;\
@@ -1587,7 +1565,7 @@
/*Show the async fifo flush size*/
#define ASYNCFIFO_FLUSHSIZE_FUNC_DECL(i) \
-static ssize_t asyncfifo##i##_flush_size_show(struct class *class, \
+static ssize_t asyncfifo##i##_show_flush_size(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1598,7 +1576,7 @@
ret = sprintf(buf, "%d\n", afifo->flush_size);\
return ret;\
} \
-static ssize_t asyncfifo##i##_flush_size_store(struct class *class, \
+static ssize_t asyncfifo##i##_store_flush_size(struct class *class, \
struct class_attribute *attr, \
const char *buf, size_t size)\
{\
@@ -1634,7 +1612,7 @@
/*Show the async fifo secure buffer addr*/
#define ASYNCFIFO_SECUREADDR_FUNC_DECL(i) \
-static ssize_t asyncfifo##i##_secure_addr_show(struct class *class, \
+static ssize_t asyncfifo##i##_show_secure_addr(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1645,7 +1623,7 @@
ret = sprintf(buf, "0x%x\n", afifo->blk.addr);\
return ret;\
} \
-static ssize_t asyncfifo##i##_secure_addr_store(struct class *class, \
+static ssize_t asyncfifo##i##_store_secure_addr(struct class *class, \
struct class_attribute *attr, \
const char *buf, size_t size)\
{\
@@ -1677,7 +1655,7 @@
/*Show the async fifo secure buffer size*/
#define ASYNCFIFO_SECUREADDR_SIZE_FUNC_DECL(i) \
-static ssize_t asyncfifo##i##_secure_addr_size_show(struct class *class, \
+static ssize_t asyncfifo##i##_show_secure_addr_size(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1688,7 +1666,7 @@
ret = sprintf(buf, "0x%x\n", afifo->blk.len);\
return ret;\
} \
-static ssize_t asyncfifo##i##_secure_addr_size_store(struct class *class, \
+static ssize_t asyncfifo##i##_store_secure_addr_size(struct class *class, \
struct class_attribute *attr, \
const char *buf, size_t size)\
{\
@@ -1721,7 +1699,7 @@
/*Show the async fifo secure enable*/
#define ASYNCFIFO_SECURENABLE_FUNC_DECL(i) \
-static ssize_t asyncfifo##i##_secure_enable_show(struct class *class, \
+static ssize_t asyncfifo##i##_show_secure_enable(struct class *class, \
struct class_attribute *attr, char *buf)\
{\
struct aml_dvb *dvb = &aml_dvb_device;\
@@ -1732,7 +1710,7 @@
ret = sprintf(buf, "%d\n", afifo->secure_enable);\
return ret;\
} \
-static ssize_t asyncfifo##i##_secure_enable_store(struct class *class, \
+static ssize_t asyncfifo##i##_store_secure_enable(struct class *class, \
struct class_attribute *attr, \
const char *buf, size_t size)\
{\
@@ -1766,7 +1744,7 @@
#endif
/*Reset the Demux*/
-static ssize_t demux_reset_store(struct class *class,
+static ssize_t demux_do_reset(struct class *class,
struct class_attribute *attr,
const char *buf, size_t size)
{
@@ -1775,7 +1753,7 @@
unsigned long flags;
spin_lock_irqsave(&dvb->slock, flags);
- pr_dbg("Reset demux, call dmx_reset_hw\n");
+ pr_inf("Reset demux, call dmx_reset_hw\n");
dmx_reset_hw_ex(dvb, 0);
spin_unlock_irqrestore(&dvb->slock, flags);
}
@@ -1784,7 +1762,7 @@
}
/*Show the Video PTS value*/
-static ssize_t video_pts_show(struct class *class,
+static ssize_t demux_show_video_pts(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1796,7 +1774,7 @@
}
/*Show the Audio PTS value*/
-static ssize_t audio_pts_show(struct class *class,
+static ssize_t demux_show_audio_pts(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1808,7 +1786,7 @@
}
/*Show the Video PTS bit32 value*/
-static ssize_t video_pts_bit32_show(struct class *class,
+static ssize_t demux_show_video_pts_bit32(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1820,7 +1798,7 @@
}
/*Show the Audio PTS bit32 value*/
-static ssize_t audio_pts_bit32_show(struct class *class,
+static ssize_t demux_show_audio_pts_bit32(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1832,7 +1810,7 @@
}
/*Show the 33bit Video PTS value*/
-static ssize_t video_pts_u64_show(struct class *class,
+static ssize_t demux_show_video_pts_u64(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1851,7 +1829,7 @@
}
/*Show the 33bit Audio PTS value*/
-static ssize_t audio_pts_u64_show(struct class *class,
+static ssize_t demux_show_audio_pts_u64(struct class *class,
struct class_attribute *attr, char *buf)
{
struct aml_dvb *dvb = &aml_dvb_device;
@@ -1870,7 +1848,7 @@
}
/*Show the First Video PTS value*/
-static ssize_t first_video_pts_show(struct class *class,
+static ssize_t demux_show_first_video_pts(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -1883,7 +1861,7 @@
}
/*Show the First Audio PTS value*/
-static ssize_t first_audio_pts_show(struct class *class,
+static ssize_t demux_show_first_audio_pts(struct class *class,
struct class_attribute *attr,
char *buf)
{
@@ -1895,7 +1873,7 @@
return ret;
}
-static ssize_t hw_setting_show(struct class *class,
+static ssize_t stb_show_hw_setting(struct class *class,
struct class_attribute *attr, char *buf)
{
int r, total = 0;
@@ -1924,7 +1902,7 @@
return total;
}
-static ssize_t hw_setting_store(struct class *class,
+static ssize_t stb_store_hw_setting(struct class *class,
struct class_attribute *attr,
const char *buf, size_t count)
{
@@ -1993,270 +1971,157 @@
return count;
}
-
-static CLASS_ATTR_RW(hw_setting);
-static CLASS_ATTR_RW(source);
-static CLASS_ATTR_RW(demux_reset_all_flag);
-static CLASS_ATTR_RW(tso_source);
+static struct class_attribute aml_stb_class_attrs[] = {
+ __ATTR(hw_setting, 0664, stb_show_hw_setting,
+ stb_store_hw_setting),
+ __ATTR(source, 0664, stb_show_source,
+ stb_store_source),
+ __ATTR(demux_reset_all_flag, 0664, show_dmx_reset_all_flag,
+ set_dmx_reset_all_flag),
+ __ATTR(tso_source, 0644, tso_show_source,
+ tso_store_source),
#define DEMUX_SOURCE_ATTR_PCR(i)\
- static CLASS_ATTR_RO(demux##i##_pcr)
+ __ATTR(demux##i##_pcr, 0644, demux##i##_show_pcr, NULL)
#define DEMUX_SOURCE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(demux##i##_source)
+ __ATTR(demux##i##_source, 0664,\
+ demux##i##_show_source, demux##i##_store_source)
#define DEMUX_FREE_FILTERS_ATTR_DECL(i)\
- static CLASS_ATTR_RO(demux##i##_free_filters)
+ __ATTR(demux##i##_free_filters, 0644, \
+ demux##i##_show_free_filters, NULL)
#define DEMUX_FILTER_USERS_ATTR_DECL(i)\
- static CLASS_ATTR_RW(demux##i##_filter_users)
+ __ATTR(demux##i##_filter_users, 0644, \
+ demux##i##_show_filter_users, demux##i##_store_filter_used)
#define DEMUX_DEV_USERS_ATTR_DECL(i)\
- static CLASS_ATTR_RO(demux##i##_dev_users)
+ __ATTR(demux##i##_dev_users, 0644, \
+ demux##i##_show_dev_users, NULL)
#define DVR_MODE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(dvr##i##_mode)
+ __ATTR(dvr##i##_mode, 0644, dvr##i##_show_mode, \
+ dvr##i##_store_mode)
#define DEMUX_TS_HEADER_ATTR_DECL(i)\
- static CLASS_ATTR_RO(demux##i##_ts_header)
+ __ATTR(demux##i##_ts_header, 0644, \
+ demux##i##_show_ts_header, NULL)
#define DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(i)\
- static CLASS_ATTR_RO(demux##i##_channel_activity)
+ __ATTR(demux##i##_channel_activity, 0644, \
+ demux##i##_show_channel_activity, NULL)
#define DMX_RESET_ATTR_DECL(i)\
- static CLASS_ATTR_WO(demux##i##_reset)
+ __ATTR(demux##i##_reset, 0644, NULL, \
+ demux##i##_reset_store)
#if DMX_DEV_COUNT > 0
- DEMUX_SOURCE_ATTR_PCR(0);
- DEMUX_SOURCE_ATTR_DECL(0);
- DEMUX_FREE_FILTERS_ATTR_DECL(0);
- DEMUX_FILTER_USERS_ATTR_DECL(0);
- DEMUX_DEV_USERS_ATTR_DECL(0);
- DVR_MODE_ATTR_DECL(0);
- DEMUX_TS_HEADER_ATTR_DECL(0);
- DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(0);
- DMX_RESET_ATTR_DECL(0);
+ DEMUX_SOURCE_ATTR_PCR(0),
+ DEMUX_SOURCE_ATTR_DECL(0),
+ DEMUX_FREE_FILTERS_ATTR_DECL(0),
+ DEMUX_FILTER_USERS_ATTR_DECL(0),
+ DEMUX_DEV_USERS_ATTR_DECL(0),
+ DVR_MODE_ATTR_DECL(0),
+ DEMUX_TS_HEADER_ATTR_DECL(0),
+ DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(0),
+ DMX_RESET_ATTR_DECL(0),
#endif
#if DMX_DEV_COUNT > 1
- DEMUX_SOURCE_ATTR_PCR(1);
- DEMUX_SOURCE_ATTR_DECL(1);
- DEMUX_FREE_FILTERS_ATTR_DECL(1);
- DEMUX_FILTER_USERS_ATTR_DECL(1);
- DEMUX_DEV_USERS_ATTR_DECL(1);
- DVR_MODE_ATTR_DECL(1);
- DEMUX_TS_HEADER_ATTR_DECL(1);
- DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(1);
- DMX_RESET_ATTR_DECL(1);
+ DEMUX_SOURCE_ATTR_PCR(1),
+ DEMUX_SOURCE_ATTR_DECL(1),
+ DEMUX_FREE_FILTERS_ATTR_DECL(1),
+ DEMUX_FILTER_USERS_ATTR_DECL(1),
+ DEMUX_DEV_USERS_ATTR_DECL(1),
+ DVR_MODE_ATTR_DECL(1),
+ DEMUX_TS_HEADER_ATTR_DECL(1),
+ DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(1),
+ DMX_RESET_ATTR_DECL(1),
#endif
#if DMX_DEV_COUNT > 2
- DEMUX_SOURCE_ATTR_PCR(2);
- DEMUX_SOURCE_ATTR_DECL(2);
- DEMUX_FREE_FILTERS_ATTR_DECL(2);
- DEMUX_FILTER_USERS_ATTR_DECL(2);
- DEMUX_DEV_USERS_ATTR_DECL(2);
- DVR_MODE_ATTR_DECL(2);
- DEMUX_TS_HEADER_ATTR_DECL(2);
- DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(2);
- DMX_RESET_ATTR_DECL(2);
+ DEMUX_SOURCE_ATTR_PCR(2),
+ DEMUX_SOURCE_ATTR_DECL(2),
+ DEMUX_FREE_FILTERS_ATTR_DECL(2),
+ DEMUX_FILTER_USERS_ATTR_DECL(2),
+ DEMUX_DEV_USERS_ATTR_DECL(2),
+ DVR_MODE_ATTR_DECL(2),
+ DEMUX_TS_HEADER_ATTR_DECL(2),
+ DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(2),
+ DMX_RESET_ATTR_DECL(2),
#endif
#define ASYNCFIFO_SOURCE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(asyncfifo##i##_source)
+ __ATTR(asyncfifo##i##_source, 0664, \
+ asyncfifo##i##_show_source, asyncfifo##i##_store_source)
#define ASYNCFIFO_FLUSHSIZE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(asyncfifo##i##_flush_size)
+ __ATTR(asyncfifo##i##_flush_size, 0664,\
+ asyncfifo##i##_show_flush_size, \
+ asyncfifo##i##_store_flush_size)
#define ASYNCFIFO_SECUREADDR_ATTR_DECL(i)\
- static CLASS_ATTR_RW(asyncfifo##i##_secure_addr)
+ __ATTR(asyncfifo##i##_secure_addr, S_IRUGO | S_IWUSR | S_IWGRP,\
+ asyncfifo##i##_show_secure_addr, \
+ asyncfifo##i##_store_secure_addr)
#define ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(asyncfifo##i##_secure_addr_size)
+ __ATTR(asyncfifo##i##_secure_addr_size, S_IRUGO | S_IWUSR | S_IWGRP,\
+ asyncfifo##i##_show_secure_addr_size, \
+ asyncfifo##i##_store_secure_addr_size)
#define ASYNCFIFO_SECURENABLE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(asyncfifo##i##_secure_enable)
+ __ATTR(asyncfifo##i##_secure_enable, S_IRUGO | S_IWUSR | S_IWGRP,\
+ asyncfifo##i##_show_secure_enable, \
+ asyncfifo##i##_store_secure_enable)
#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_SOURCE_ATTR_DECL(0);
- ASYNCFIFO_FLUSHSIZE_ATTR_DECL(0);
- ASYNCFIFO_SECUREADDR_ATTR_DECL(0);
- ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(0);
- ASYNCFIFO_SECURENABLE_ATTR_DECL(0);
+ ASYNCFIFO_SOURCE_ATTR_DECL(0),
+ ASYNCFIFO_FLUSHSIZE_ATTR_DECL(0),
+ ASYNCFIFO_SECUREADDR_ATTR_DECL(0),
+ ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(0),
+ ASYNCFIFO_SECURENABLE_ATTR_DECL(0),
#endif
#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_SOURCE_ATTR_DECL(1);
- ASYNCFIFO_FLUSHSIZE_ATTR_DECL(1);
- ASYNCFIFO_SECUREADDR_ATTR_DECL(1);
- ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(1);
- ASYNCFIFO_SECURENABLE_ATTR_DECL(1);
+ ASYNCFIFO_SOURCE_ATTR_DECL(1),
+ ASYNCFIFO_FLUSHSIZE_ATTR_DECL(1),
+ ASYNCFIFO_SECUREADDR_ATTR_DECL(1),
+ ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(1),
+ ASYNCFIFO_SECURENABLE_ATTR_DECL(1),
#endif
#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_SOURCE_ATTR_DECL(2);
- ASYNCFIFO_FLUSHSIZE_ATTR_DECL(2);
- ASYNCFIFO_SECUREADDR_ATTR_DECL(2);
- ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(2);
- ASYNCFIFO_SECURENABLE_ATTR_DECL(2);
+ ASYNCFIFO_SOURCE_ATTR_DECL(2),
+ ASYNCFIFO_FLUSHSIZE_ATTR_DECL(2),
+ ASYNCFIFO_SECUREADDR_ATTR_DECL(2),
+ ASYNCFIFO_SECUREADDR_SIZE_ATTR_DECL(2),
+ ASYNCFIFO_SECURENABLE_ATTR_DECL(2),
#endif
- static CLASS_ATTR_WO(demux_reset);
- static CLASS_ATTR_RO(video_pts);
- static CLASS_ATTR_RO(audio_pts);
- static CLASS_ATTR_RO(video_pts_bit32);
- static CLASS_ATTR_RO(audio_pts_bit32);
- static CLASS_ATTR_RO(video_pts_u64);
- static CLASS_ATTR_RO(audio_pts_u64);
- static CLASS_ATTR_RO(first_video_pts);
- static CLASS_ATTR_RO(first_audio_pts);
- static CLASS_ATTR_WO(clear_av);
- static CLASS_ATTR_RO(demux_state);
+ __ATTR(demux_reset, 0644, NULL, demux_do_reset),
+ __ATTR(video_pts, 0664, demux_show_video_pts,
+ NULL),
+ __ATTR(audio_pts, 0664, demux_show_audio_pts,
+ NULL),
+ __ATTR(video_pts_bit32, 0644, demux_show_video_pts_bit32, NULL),
+ __ATTR(audio_pts_bit32, 0644, demux_show_audio_pts_bit32, NULL),
+ __ATTR(video_pts_u64, 0644, demux_show_video_pts_u64, NULL),
+ __ATTR(audio_pts_u64, 0644, demux_show_audio_pts_u64, NULL),
+ __ATTR(first_video_pts, 0644, demux_show_first_video_pts,
+ NULL),
+ __ATTR(first_audio_pts, 0644, demux_show_first_audio_pts,
+ NULL),
+ __ATTR(clear_av, 0644, NULL, stb_clear_av),
+ __ATTR(demux_state, 0644, demux_state_show, NULL),
#define DSC_SOURCE_ATTR_DECL(i)\
- static CLASS_ATTR_RW(dsc##i##_source)
+ __ATTR(dsc##i##_source, 0664,\
+ dsc##i##_show_source, dsc##i##_store_source)
#define DSC_FREE_ATTR_DECL(i) \
- static CLASS_ATTR_RO(dsc##i##_free_dscs)
+ __ATTR(dsc##i##_free_dscs, 0644, \
+ dsc##i##_show_free_dscs, NULL)
#if DSC_DEV_COUNT > 0
- DSC_SOURCE_ATTR_DECL(0);
- DSC_FREE_ATTR_DECL(0);
+ DSC_SOURCE_ATTR_DECL(0),
+ DSC_FREE_ATTR_DECL(0),
#endif
#if DSC_DEV_COUNT > 1
- DSC_SOURCE_ATTR_DECL(1);
- DSC_FREE_ATTR_DECL(1);
+ DSC_SOURCE_ATTR_DECL(1),
+ DSC_FREE_ATTR_DECL(1),
#endif
-#define STB_ATTR(name) &class_attr_##name.attr
-
-static struct attribute *aml_stb_class_attrs[] = {
- STB_ATTR(hw_setting),
- STB_ATTR(source),
- STB_ATTR(demux_reset_all_flag),
- STB_ATTR(tso_source),
- STB_ATTR(demux_reset),
- STB_ATTR(video_pts),
- STB_ATTR(audio_pts),
- STB_ATTR(video_pts_bit32),
- STB_ATTR(audio_pts_bit32),
- STB_ATTR(video_pts_u64),
- STB_ATTR(audio_pts_u64),
- STB_ATTR(first_video_pts),
- STB_ATTR(first_audio_pts),
- STB_ATTR(clear_av),
- STB_ATTR(demux_state),
-#define DEMUX_PCR(i) \
- STB_ATTR(demux##i##_pcr)
- DEMUX_PCR(0),
- DEMUX_PCR(1),
- DEMUX_PCR(2),
-#define DEMUX_SOURCE(i) \
- STB_ATTR(demux##i##_source)
- DEMUX_SOURCE(0),
- DEMUX_SOURCE(1),
- DEMUX_SOURCE(2),
-#define DEMUX_FREE_FILTER(i) \
- STB_ATTR(demux##i##_free_filters)
- DEMUX_FREE_FILTER(0),
- DEMUX_FREE_FILTER(1),
- DEMUX_FREE_FILTER(2),
-#define DEMUX_FILTER_USERS(i) \
- STB_ATTR(demux##i##_filter_users)
- DEMUX_FILTER_USERS(0),
- DEMUX_FILTER_USERS(1),
- DEMUX_FILTER_USERS(2),
-#define DEMUX_DEV_USERS(i) \
- STB_ATTR(demux##i##_dev_users)
- DEMUX_DEV_USERS(0),
- DEMUX_DEV_USERS(1),
- DEMUX_DEV_USERS(2),
-#define DEMUX_TS_HEADER(i) \
- STB_ATTR(demux##i##_ts_header)
- DEMUX_TS_HEADER(0),
- DEMUX_TS_HEADER(1),
- DEMUX_TS_HEADER(2),
-#define DEMUX_CHANNEL_ACTIVITY_ATTR(i) \
- STB_ATTR(demux##i##_channel_activity)
- DEMUX_CHANNEL_ACTIVITY_ATTR(0),
- DEMUX_CHANNEL_ACTIVITY_ATTR(1),
- DEMUX_CHANNEL_ACTIVITY_ATTR(2),
-#define DEMUX_RESET(i) \
- STB_ATTR(demux##i##_reset)
- DEMUX_RESET(0),
- DEMUX_RESET(1),
- DEMUX_RESET(2),
-#define DVR_MODE(i)\
- STB_ATTR(dvr##i##_mode)
- DVR_MODE(0),
- DVR_MODE(1),
- DVR_MODE(2),
-#define ASYNCFIFO_SOURCE(i) \
- STB_ATTR(asyncfifo##i##_source)
-#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_SOURCE(0),
-#endif
-#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_SOURCE(1),
-#endif
-#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_SOURCE(2),
-#endif
-#define ASYNCFIFO_FLUSH_SIZE(i) \
- STB_ATTR(asyncfifo##i##_flush_size)
-#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_FLUSH_SIZE(0),
-#endif
-#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_FLUSH_SIZE(1),
-#endif
-#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_FLUSH_SIZE(2),
-#endif
-
-#define ASYNCFIFO_SECURE_ADDR(i) \
- STB_ATTR(asyncfifo##i##_secure_addr)
-#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_SECURE_ADDR(0),
-#endif
-#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_SECURE_ADDR(1),
-#endif
-#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_SECURE_ADDR(2),
-#endif
-
-#define ASYNCFIFO_SECURE_ADDR_SIZE(i) \
- STB_ATTR(asyncfifo##i##_secure_addr_size)
-#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_SECURE_ADDR_SIZE(0),
-#endif
-#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_SECURE_ADDR_SIZE(1),
-#endif
-#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_SECURE_ADDR_SIZE(2),
-#endif
-
-#define ASYNCFIFO_SECURE_ENABLE(i)\
- STB_ATTR(asyncfifo##i##_secure_enable)
-#if ASYNCFIFO_COUNT > 0
- ASYNCFIFO_SECURE_ENABLE(0),
-#endif
-#if ASYNCFIFO_COUNT > 1
- ASYNCFIFO_SECURE_ENABLE(1),
-#endif
-#if ASYNCFIFO_COUNT > 2
- ASYNCFIFO_SECURE_ENABLE(2),
-#endif
-#define DSC_SOURCE(i) \
- STB_ATTR(dsc##i##_source)
-#if DSC_DEV_COUNT > 0
- DSC_SOURCE(0),
-#endif
-#if DSC_DEV_COUNT > 1
- DSC_SOURCE(1),
-#endif
-#define DSC_FREE_DSCS(i) \
- STB_ATTR(dsc##i##_free_dscs)
-#if DSC_DEV_COUNT > 0
- DSC_FREE_DSCS(0),
-#endif
-#if DSC_DEV_COUNT > 1
- DSC_FREE_DSCS(1),
-#endif
- NULL
+ __ATTR_NULL
};
-
-ATTRIBUTE_GROUPS(aml_stb_class);
-
static struct class aml_stb_class = {
.name = "stb",
- .class_groups = aml_stb_class_groups,
+ .class_attrs = aml_stb_class_attrs,
};
/*
@@ -2281,6 +2146,30 @@
pr_inf("probe amlogic dvb driver [%s]\n", DVB_VERSION);
+ /*switch_mod_gate_by_name("demux", 1); */
+#if 0
+ /*no used reset ctl to set clk*/
+ aml_dvb_demux_reset_ctl =
+ devm_reset_control_get(&pdev->dev, "demux");
+ pr_inf("dmx rst ctl = %p\n", aml_dvb_demux_reset_ctl);
+ reset_control_deassert(aml_dvb_demux_reset_ctl);
+
+ aml_dvb_afifo_reset_ctl =
+ devm_reset_control_get(&pdev->dev, "asyncfifo");
+ pr_inf("asyncfifo rst ctl = %p\n", aml_dvb_afifo_reset_ctl);
+ reset_control_deassert(aml_dvb_afifo_reset_ctl);
+
+ aml_dvb_ahbarb0_reset_ctl =
+ devm_reset_control_get(&pdev->dev, "ahbarb0");
+ pr_inf("ahbarb0 rst ctl = %p\n", aml_dvb_ahbarb0_reset_ctl);
+ reset_control_deassert(aml_dvb_ahbarb0_reset_ctl);
+
+ aml_dvb_uparsertop_reset_ctl =
+ devm_reset_control_get(&pdev->dev, "uparsertop");
+ pr_inf("uparsertop rst ctl = %p\n", aml_dvb_uparsertop_reset_ctl);
+ reset_control_deassert(aml_dvb_uparsertop_reset_ctl);
+#else
+
if (get_cpu_type() < MESON_CPU_MAJOR_ID_G12A)
{
aml_dvb_demux_clk =
@@ -2324,13 +2213,14 @@
{
aml_dvb_afifo_clk =
devm_clk_get(&pdev->dev, "asyncfifo");
- if (IS_ERR_OR_NULL(aml_dvb_afifo_clk))
+ if (IS_ERR_OR_NULL(aml_dvb_afifo_clk)) {
dev_err(&pdev->dev, "get asyncfifo clk fail\n");
- else
- clk_prepare_enable(aml_dvb_afifo_clk);
+ return -1;
+ }
+ clk_prepare_enable(aml_dvb_afifo_clk);
}
}
-
+#endif
advb = &aml_dvb_device;
memset(advb, 0, sizeof(aml_dvb_device));
@@ -2375,7 +2265,7 @@
&str);
if (!ret) {
if (!strcmp(str, "serial")) {
- pr_inf("%s: serial\n", buf);
+ pr_dbg("%s: serial\n", buf);
if (s2p_id >= advb->s2p_total_count)
pr_error("no free s2p\n");
@@ -2391,7 +2281,7 @@
s2p_id++;
}
} else if (!strcmp(str, "parallel")) {
- pr_inf("%s: parallel\n", buf);
+ pr_dbg("%s: parallel\n", buf);
memset(buf, 0, 32);
snprintf(buf, sizeof(buf), "p_ts%d", i);
advb->ts[i].mode = AM_TS_PARALLEL;
@@ -2412,10 +2302,10 @@
of_property_read_u32(pdev->dev.of_node, buf,
&value);
if (!ret) {
- pr_inf("%s: 0x%x\n", buf, value);
+ pr_dbg("%s: 0x%x\n", buf, value);
advb->ts[i].control = value;
} else {
- pr_inf("read error:%s: 0x%x\n", buf, value);
+ pr_dbg("read error:%s: 0x%x\n", buf, value);
}
if (advb->ts[i].s2p_id != -1) {
@@ -2425,7 +2315,7 @@
of_property_read_u32(pdev->dev.of_node, buf,
&value);
if (!ret) {
- pr_inf("%s: 0x%x\n", buf, value);
+ pr_dbg("%s: 0x%x\n", buf, value);
advb->s2p[advb->ts[i].s2p_id].invert =
value;
}
@@ -2437,22 +2327,9 @@
of_property_read_u32(pdev->dev.of_node, buf,
&value);
if (!ret) {
- pr_inf("%s: 0x%x\n", buf, value);
+ pr_dbg("%s: 0x%x\n", buf, value);
advb->ts_out_invert = value;
}
- memset(buf, 0, 32);
- snprintf(buf, sizeof(buf), "tsin_deglitch");
- ret =
- of_property_read_u32(pdev->dev.of_node, buf,
- &value);
- if (!ret) {
- pr_inf("%s: 0x%x\n", buf, value);
- if (value) {
- pr_inf("TSINB_DEGLITCH0 is set %s: 0x%x\n", buf, value);
- dmx_phyreg_access(TSINB_DEGLITCH0, 0x40, NULL);
- dmx_phyreg_access(TSINB_DEGLITCH1, 0x1, NULL);
- }
- }
}
#endif
@@ -2509,8 +2386,7 @@
tsdemux_set_ops(NULL);
#endif
-#if (defined CONFIG_AMLOGIC_DVB_EXTERN ||\
- defined CONFIG_AMLOGIC_DVB_EXTERN_MODULE)
+#if (defined CONFIG_AMLOGIC_DVB_EXTERN)
ret = dvb_extern_register_frontend(&advb->dvb_adapter);
if (ret) {
pr_error("aml register dvb frontend failed\n");
@@ -2540,7 +2416,6 @@
return ret;
}
-
static int aml_dvb_remove(struct platform_device *pdev)
{
struct aml_dvb *advb = (struct aml_dvb *)dev_get_drvdata(&pdev->dev);
@@ -2548,8 +2423,7 @@
pr_inf("[dmx_kpi] %s Enter.\n", __func__);
-#if (defined CONFIG_AMLOGIC_DVB_EXTERN ||\
- defined CONFIG_AMLOGIC_DVB_EXTERN_MODULE)
+#if (defined CONFIG_AMLOGIC_DVB_EXTERN)
dvb_extern_unregister_frontend();
#endif
@@ -2601,7 +2475,7 @@
amports_switch_gate("ahbarb0", 0);
amports_switch_gate("parser_top", 0);
- if (!IS_ERR_OR_NULL(aml_dvb_afifo_clk)) {
+ if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
clk_disable_unprepare(aml_dvb_afifo_clk);
}
}
@@ -2912,18 +2786,18 @@
static unsigned long aml_tsdemux_hwdmx_spin_lock(unsigned long flags)
{
- struct aml_dvb *dvb = &aml_dvb_device;
+ struct aml_dvb *dvb = &aml_dvb_device;
- spin_lock_irqsave(&dvb->slock, flags);
- return flags;
+ spin_lock_irqsave(&dvb->slock, flags);
+ return flags;
}
static int aml_tsdemux_hwdmx_spin_unlock(unsigned long flags)
{
- struct aml_dvb *dvb = &aml_dvb_device;
+ struct aml_dvb *dvb = &aml_dvb_device;
- spin_unlock_irqrestore(&dvb->slock, flags);
- return 0;
+ spin_unlock_irqrestore(&dvb->slock, flags);
+ return 0;
}
module_init(aml_dvb_init);
diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb.h b/drivers/stream_input/parser/hw_demux/aml_dvb.h
index 7bfce38..12ed65b 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dvb.h
+++ b/drivers/stream_input/parser/hw_demux/aml_dvb.h
@@ -75,6 +75,30 @@
#define SEC_BUF_BUSY_SIZE 4
#define SEC_BUF_COUNT (SEC_BUF_GRP_COUNT*8)
+enum aml_dmx_id_t {
+ AM_DMX_0 = 0,
+ AM_DMX_1,
+ AM_DMX_2,
+ AM_DMX_MAX,
+};
+
+enum aml_ts_source_t {
+ AM_TS_SRC_TS0,
+ AM_TS_SRC_TS1,
+ AM_TS_SRC_TS2,
+ AM_TS_SRC_TS3,
+
+ AM_TS_SRC_S_TS0,
+ AM_TS_SRC_S_TS1,
+ AM_TS_SRC_S_TS2,
+ AM_TS_SRC_S_TS3,
+
+ AM_TS_SRC_HIU,
+ AM_TS_SRC_HIU1,
+ AM_TS_SRC_DMX0,
+ AM_TS_SRC_DMX1,
+ AM_TS_SRC_DMX2
+};
struct aml_sec_buf {
unsigned long addr;
@@ -373,9 +397,6 @@
extern int aml_unregist_dmx_class(void);
extern void aml_register_parser_mconfig(void);
-extern int dmx_phyreg_access(unsigned int reg, unsigned int writeval,
- unsigned int *readval);
-
struct devio_aml_platform_data {
int (*io_setup)(void *);
int (*io_cleanup)(void *);
diff --git a/drivers/stream_input/parser/hw_demux/aml_dvb_reg.h b/drivers/stream_input/parser/hw_demux/aml_dvb_reg.h
index ac47688..dbfa6ba 100644
--- a/drivers/stream_input/parser/hw_demux/aml_dvb_reg.h
+++ b/drivers/stream_input/parser/hw_demux/aml_dvb_reg.h
@@ -18,9 +18,9 @@
#ifndef _DVB_REG_H_
#define _DVB_REG_H_
-//#include <linux/amlogic/iomap.h>
-#include <linux/amlogic/media/registers/register_map.h>
-//#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/iomap.h>
+
+#include <linux/amlogic/cpu_version.h>
#define ID_STB_CBUS_BASE 0
#define ID_SMARTCARD_REG_BASE 1
diff --git a/drivers/stream_input/parser/hw_demux/c_stb_regs_define.h b/drivers/stream_input/parser/hw_demux/c_stb_regs_define.h
index e351771..b12db68 100644
--- a/drivers/stream_input/parser/hw_demux/c_stb_regs_define.h
+++ b/drivers/stream_input/parser/hw_demux/c_stb_regs_define.h
@@ -27,7 +27,7 @@
#ifndef __MACH_MESON8_REG_ADDR_H_
#define __MACH_MESON8_REG_ADDR_H_
-#include <linux/amlogic/media/registers/register_map.h>
+#include <linux/amlogic/iomap.h>
#define CBUS_REG_ADDR(_r) aml_read_cbus(_r)
diff --git a/drivers/stream_input/parser/tsdemux.c b/drivers/stream_input/parser/tsdemux.c
index 81c94c0..7d5788e 100644
--- a/drivers/stream_input/parser/tsdemux.c
+++ b/drivers/stream_input/parser/tsdemux.c
@@ -29,7 +29,6 @@
#include <linux/amlogic/media/vfm/vframe_provider.h>
#include <linux/device.h>
#include <linux/delay.h>
-#include <linux/module.h>
#include <linux/uaccess.h>
/* #include <mach/am_regs.h> */
@@ -52,10 +51,6 @@
#define MAX_DRM_PACKAGE_SIZE 0x500000
-MODULE_PARM_DESC(reset_demux_enable, "\n\t\t Reset demux enable");
-static int reset_demux_enable = 0;
-module_param(reset_demux_enable, int, 0644);
-
static const char tsdemux_fetch_id[] = "tsdemux-fetch-id";
static const char tsdemux_irq_id[] = "tsdemux-irq-id";
@@ -408,6 +403,7 @@
{
u32 pcr_num;
u32 pcr_regs = 0;
+
if (curr_pcr_id >= 0x1FFF)
return 0;
/* set paramater to fetch pcr */
@@ -770,9 +766,6 @@
WRITE_PARSER_REG(PARSER_VIDEO_RP, 0);
#endif
- if (enable_demux_driver())
- tsdemux_reset();
-
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
/*TODO clk */
/*
@@ -1034,25 +1027,21 @@
}
EXPORT_SYMBOL(get_discontinue_counter);
-static ssize_t discontinue_counter_show(struct class *class,
+static ssize_t show_discontinue_counter(struct class *class,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", discontinued_counter);
}
-static CLASS_ATTR_RO(discontinue_counter);
-
-static struct attribute *tsdemux_class_attrs[] = {
- &class_attr_discontinue_counter.attr,
- NULL
+static struct class_attribute tsdemux_class_attrs[] = {
+ __ATTR(discontinue_counter, S_IRUGO, show_discontinue_counter, NULL),
+ __ATTR_NULL
};
-ATTRIBUTE_GROUPS(tsdemux_class);
-
static struct class tsdemux_class = {
- .name = "tsdemux",
- .class_groups = tsdemux_class_groups,
-};
+ .name = "tsdemux",
+ .class_attrs = tsdemux_class_attrs,
+ };
int tsdemux_class_register(void)
{
@@ -1078,7 +1067,9 @@
WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000);
while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
;
- } else {
+ }
+ else
+ {
if (curr_vid_id != vid) {
tsdemux_set_vid(vid);
curr_vid_id = vid;
@@ -1136,8 +1127,6 @@
if (demux_ops && demux_ops->hw_dmx_unlock)
demux_ops->hw_dmx_unlock(xflags);
spin_unlock_irqrestore(&demux_ops_lock, flags);
- if (reset_demux_enable == 1)
- tsdemux_reset();
}
void tsdemux_sub_reset(void)
diff --git a/drivers/stream_input/subtitle/subtitle.c b/drivers/stream_input/subtitle/subtitle.c
index 915ee38..bfcf612 100644
--- a/drivers/stream_input/subtitle/subtitle.c
+++ b/drivers/stream_input/subtitle/subtitle.c
@@ -27,7 +27,6 @@
#include <linux/interrupt.h>
#include <linux/amlogic/media/utils/amstream.h>
#include <linux/uaccess.h>
-#include <linux/compat.h>
//#include "amports_priv.h"
//#include "amlog.h"
@@ -339,7 +338,7 @@
ssize_t r;
r = kstrtoint(buf, 0, &address);
- if (r == (ssize_t)0)
+ if ((r == 0))
return -EINVAL;
#if 0
if (subtitle_data[subtitle_write_pos].subtitle_size > 0) {
diff --git a/firmware/checkmsg b/firmware/checkmsg
deleted file mode 100755
index 8ba42db..0000000
--- a/firmware/checkmsg
+++ /dev/null
Binary files differ
diff --git a/firmware/video_ucode.bin b/firmware/video_ucode.bin
index 46d2ca3..ec54a6b 100755
--- a/firmware/video_ucode.bin
+++ b/firmware/video_ucode.bin
Binary files differ
diff --git a/submit_tool.sh b/submit_tool.sh
deleted file mode 100755
index 60e36e5..0000000
--- a/submit_tool.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-ChangeID=$(git log -1 | grep "Change-Id:" | sed 's/^[ \t]*//g')
-Signed=$(git log -1 | grep "Signed-off-by:" | sed 's/^[ \t]*//g')
-
-git log -1 | sed '/Change-Id:/,$d' | sed '/Signed-off-by/,$d' | sed '/SourceCode:/,$d' | sed '/media_module version:/,$d' | sed -n '/^$/,$p' | sed '/^$/d' | sed 's/^[ \t]*//g' > tmp.txt
-
-#echo "media_module version:" >> tmp.txt
-#echo $(./version_control.sh) | awk '{print $1}' | awk -F [=] '{print $2}' >> tmp.txt
-
-if [ "0$(git log --stat -1 | grep "video_ucode.bin")" != "0" ]; then
-echo "SourceCode:
-ucode:" >> tmp.txt
- ./firmware/checkmsg ./firmware/video_ucode.bin | grep ver | awk '{print $3}' | sed 's/v//g' > version.txt
- ./firmware/checkmsg ./firmware/video_ucode.bin | grep -A 5 "change id history:" >> version.txt
- chmod 644 version.txt
- ./firmware/checkmsg ./firmware/video_ucode.bin | grep ver | awk '{print $3}' | sed 's/v//g' >> tmp.txt
- cat version.txt | sed -n '3,7p' >> tmp.txt
-
- git add version.txt
-fi
-
-echo "" >> tmp.txt
-echo ${ChangeID} >> tmp.txt
-echo ${Signed} >> tmp.txt
-
-
-git status
-cat tmp.txt | xargs -0 git commit --amend -m
-
-rm -f tmp.txt
diff --git a/version.txt b/version.txt
deleted file mode 100644
index a994c18..0000000
--- a/version.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-0.3.41-g645c87e
-I9b5e8
-If13e3
-I234d5
-I3f003
-Ibb6f2
diff --git a/version_control.sh b/version_control.sh
deleted file mode 100755
index 9069a58..0000000
--- a/version_control.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-MEDIA_MODULE_PATH=$(cd "$(dirname "$0")";pwd)
-Major_V=$(cd ${MEDIA_MODULE_PATH}/; grep "Major_V" VERSION | awk -F [=] '{print $2}')
-Minor_V=$(cd ${MEDIA_MODULE_PATH}/; grep "Minor_V" VERSION | awk -F [=] '{print $2}')
-BASE_CHANGEID=$(cd ${MEDIA_MODULE_PATH}/; grep "^BaseChangeId" VERSION | awk -F [=] '{print $2}' | cut -c1-6)
-#MEDIAMODULE_CHANGEID=$(cd ${MEDIA_MODULE_PATH}; git log -1 ${MEDIA_MODULE_PATH} | grep "Change-Id: " | awk '{ print $2}' | cut -c1-6 | tail -1)
-COMMIT_COUNT=$(cd ${MEDIA_MODULE_PATH}/; git log | grep "Change-Id: " | grep -n ${BASE_CHANGEID} | awk -F ":" '{printf "%d", $1-1}' )
-MEDIAMODULE_COMMITID=$(cd ${MEDIA_MODULE_PATH}/; git rev-parse --short HEAD)
-UCODE_VERSION_DETAIL=$(cd ${MEDIA_MODULE_PATH}/; ./firmware/checkmsg ./firmware/video_ucode.bin | grep "ver :" | awk '{print $3}' | sed 's/v//g')
-UCODE_VERSION=$(cd ${MEDIA_MODULE_PATH}/; ./firmware/checkmsg ./firmware/video_ucode.bin | grep "ver :" | awk -F '[v-]' '{print $3}' | awk -F [\.] '{printf "%d%02d%03d", $1,$2,$3}')
-RELEASED_VERSION=$(cd ${MEDIA_MODULE_PATH}/; grep "^#V" VERSION | head -1 | awk '{print $1}' | sed 's/#//g')
-
-if [ "x${COMMIT_COUNT}" != "x" ]; then
-VERSION_CONTROL_CFLAGS="-DDECODER_VERSION=${Major_V}.${Minor_V}.${COMMIT_COUNT}-g${MEDIAMODULE_COMMITID}.${UCODE_VERSION}"
-else
-VERSION_CONTROL_CFLAGS="${VERSION_CONTROL_CFLAGS} -DRELEASED_VERSION=${RELEASED_VERSION}"
-fi
-VERSION_CONTROL_CFLAGS="${VERSION_CONTROL_CFLAGS} -DUCODE_VERSION=${UCODE_VERSION_DETAIL}"
-
-echo ${VERSION_CONTROL_CFLAGS}