Project import generated by Copybara.

GitOrigin-RevId: c52e92328723791fd1b14149053ef1a25223a45e
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..39eb163
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,68 @@
+load("//build/kernel/kleaf:kernel.bzl", "kernel_module")
+
+kernel_module(
+    name = "media",
+    srcs = glob(
+        ["**"],
+        exclude = [
+            "BUILD.bazel",
+            "**/*.bzl",
+            "**/*.mk",
+            "**/*.bp",
+        ],
+    ),
+    outs = [
+        "amvdec_ports/amvdec_ports.ko",
+        "common/firmware/firmware.ko",
+        "common/media_clock/media_clock.ko",
+        "frame_provider/decoder/avs2/amvdec_avs2.ko",
+        "frame_provider/decoder/avs2_fb/amvdec_avs2_fb.ko",
+        "frame_provider/decoder/avs3/amvdec_avs3.ko",
+        "frame_provider/decoder/avs_multi/amvdec_mavs.ko",
+        "frame_provider/decoder/h264_multi/amvdec_mh264.ko",
+        "frame_provider/decoder/h264_mvc/amvdec_h264mvc.ko",
+        "frame_provider/decoder/h265/amvdec_h265.ko",
+        "frame_provider/decoder/h265_fb/amvdec_h265_fb.ko",
+        "frame_provider/decoder/mjpeg/amvdec_mmjpeg.ko",
+        "frame_provider/decoder/mpeg12/amvdec_mmpeg12.ko",
+        "frame_provider/decoder/mpeg4/amvdec_mmpeg4.ko",
+        "frame_provider/decoder/utils/amvdec_debug_port.ko",
+        "frame_provider/decoder/utils/decoder_common.ko",
+        "frame_provider/decoder_v4l/avs2/amvdec_avs2_v4l.ko",
+        "frame_provider/decoder_v4l/avs2_fb/amvdec_avs2_fb_v4l.ko",
+        "frame_provider/decoder_v4l/avs3/amvdec_avs3_v4l.ko",
+        "frame_provider/decoder_v4l/avs_multi/amvdec_mavs_v4l.ko",
+        "frame_provider/decoder_v4l/h264_multi/amvdec_mh264_v4l.ko",
+        "frame_provider/decoder_v4l/h265/amvdec_h265_v4l.ko",
+        "frame_provider/decoder_v4l/h265_fb/amvdec_h265_fb_v4l.ko",
+        "frame_provider/decoder_v4l/mjpeg/amvdec_mmjpeg_v4l.ko",
+        "frame_provider/decoder_v4l/mpeg12/amvdec_mmpeg12_v4l.ko",
+        "frame_provider/decoder_v4l/mpeg4/amvdec_mmpeg4_v4l.ko",
+        "frame_provider/decoder_v4l/vav1/amvdec_av1_v4l.ko",
+        "frame_provider/decoder_v4l/vav1_fb/amvdec_av1_fb_v4l.ko",
+        "frame_provider/decoder_v4l/vav1_t5d/amvdec_av1_t5d_v4l.ko",
+        "frame_provider/decoder_v4l/vp9/amvdec_vp9_v4l.ko",
+        "frame_provider/decoder_v4l/vp9_fb/amvdec_vp9_fb_v4l.ko",
+        "frame_provider/decoder/vav1/amvdec_av1.ko",
+        "frame_provider/decoder/vav1_fb/amvdec_av1_fb.ko",
+        "frame_provider/decoder/vc1/amvdec_vc1.ko",
+	"frame_provider/decoder_v4l/vc1/amvdec_vc1_v4l.ko",
+        "frame_provider/decoder/vp9/amvdec_vp9.ko",
+        "frame_provider/decoder/vp9_fb/amvdec_vp9_fb.ko",
+        "framerate_adapter/video_framerate_adapter.ko",
+        "frame_sink/encoder/h264/amlogic-encoder.ko",
+        "frame_sink/encoder/h265/amlogic-vpu.ko",
+        "frame_sink/encoder/jpeg/amlogic-jpegenc.ko",
+        "frame_sink/encoder/memalloc/amlogic-memalloc.ko",
+        "frame_sink/encoder/multi/amlogic-multienc.ko",
+        "frame_sink/encoder/vcenc/amlogic-vc8000.ko",
+        "media_sync/av_sync/media_sync.ko",
+        "media_sync/pts_server/pts_server.ko",
+        "stream_input/parser/hw_demux/aml_hardware_dmx.ko",
+        "stream_input/stream_input.ko",
+    ],
+    kernel_build = "//common:amlogic",
+    visibility = [
+        "//common:__pkg__",
+    ],
+)
diff --git a/Makefile b/Makefile
old mode 100755
new mode 100644
index 7481eee..56e42d3
--- a/Makefile
+++ b/Makefile
@@ -21,10 +21,19 @@
 	CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
 	CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS3=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_JPEG=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_VP9_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H265_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AV1_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AV1_T5D=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_MEMALLOC=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_VCENC=m \
+	CONFIG_AMLOGIC_HW_DEMUX=m
 
 EXTRA_INCLUDE := -I$(KERNEL_SRC)/$(M)/drivers/include
 
@@ -35,6 +44,23 @@
 
 KBUILD_CFLAGS_MODULE += $(GKI_EXT_MODULE_PREDEFINE)
 
+ifeq ($(strip $(CONFIG_AMLOGIC_ZAPPER_CUT)),)
+        CONFIGS += CONFIG_AMLOGIC_MEDIA_V4L_DEC=y
+endif
+
+ifeq (${VERSION},5)
+ifeq (${PATCHLEVEL},15)
+	CONFIGS += CONFIG_AMLOGIC_MEDIA_MULTI_DEC=y
+endif
+endif
+
+ifeq ($(O),)
+out_dir := .
+else
+out_dir := $(O)
+endif
+include $(out_dir)/include/config/auto.conf
+
 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)
 
@@ -42,10 +68,17 @@
 
 modules_install:
 	$(MAKE) INSTALL_MOD_STRIP=1 M=$(M)/drivers -C $(KERNEL_SRC) modules_install
-	mkdir -p ${OUT_DIR}/../vendor_lib/modules
-	cd ${OUT_DIR}/$(M)/; find -name "*.ko" -exec cp {} ${OUT_DIR}/../vendor_lib/modules/ \;
-	mkdir -p ${OUT_DIR}/../vendor_lib/firmware/video
-	cp $(KERNEL_SRC)/$(M)/firmware/* ${OUT_DIR}/../vendor_lib/firmware/video/
+	$(Q)mkdir -p ${out_dir}/../vendor_lib/modules
+	$(Q)mkdir -p ${out_dir}/../vendor_lib/firmware/video
+	$(Q)cp $(KERNEL_SRC)/$(M)/firmware/* ${out_dir}/../vendor_lib/firmware/video/ -rf
+	$(Q)if [ -z "$(CONFIG_AMLOGIC_KERNEL_VERSION)" ]; then \
+		cd ${out_dir}/$(M)/; find -name "*.ko" -exec cp {} ${out_dir}/../vendor_lib/modules/ \; ; \
+	else \
+		find $(INSTALL_MOD_PATH)/lib/modules/*/$(INSTALL_MOD_DIR) -name "*.ko" -exec cp {} ${out_dir}/../vendor_lib/modules \; ; \
+	fi;
+	if [ -e ${out_dir}/$(M)/drivers/Module.symvers ]; then \
+		ln -sf ${out_dir}/$(M)/drivers/Module.symvers ${out_dir}/$(M)/Module.symvers;\
+	fi;
 
 clean:
-	$(MAKE) -C $(KERNEL_SRC) M=$(M) clean
+	$(MAKE) -C $(KERNEL_SRC) M=$(M)  clean
diff --git a/Media.mk b/Media.mk
index 58db63b..5f9c57f 100644
--- a/Media.mk
+++ b/Media.mk
@@ -21,10 +21,17 @@
 	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_VDEC_AVS3=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_JPEG=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_VP9_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H265_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AV1_FB=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AV1_T5D=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB=m
 
 define copy-media-modules
 $(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\
diff --git a/VERSION b/VERSION
index 4b1504d..5ab40d7 100644
--- a/VERSION
+++ b/VERSION
@@ -1,58 +1,57 @@
-Major_V=5
-Minor_V=3
-BaseChangeId=Ifc17e92ef9c9e211b8f01ebae1e97c5855fea084
+#Developing Version
+Major_V=6
+Minor_V=8
+DevelopingChangeId=Ia7339b3a1afe89afc9eecae3e7a55c39799768ff
 
 
 #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.
+#V6.7 Release Notes
+#Release_ChangeId_V6_7=Iabfa01c63da558d842d3252c7612559fa830ec7d
+#New feature detail information:
+#H265 dual-core mosaic mode development
+#H264\H265 save one output buffer optimization
+#Add T5D  AV1 fg support
+#Encoder bringup of C1
+#Optimization H264 software decoding time
+#V4ldec supports p010 decoding output
+#Optimized for redundant decoding memory usage
+#Decoder bringup of txhd2
+#V6.6 Release Notes
+#Release_ChangeId_V6_6=I7906e7fb1fc9cd2ae2f5e3b35a85146077f647ed
+#V6.5 Release Notes
+#Release_ChangeId_V6_5=I1fb4d74a26b20c810af5fabe70d11b30038f52cd
+#V6.4 Release Notes
+#Release_ChangeId_V6_4=I3e3ba6e50ff95c9bdee77ecf9b6a14054c7db016
+#V6.3 Release Notes
+#Release_ChangeId_V6_3=Id88c63edf8568ce8f5c52203db4020db6ad12d54
+#V6.2 Release Notes
+#Release_ChangeId_V6_2=I38197e6c418dee6183605006ca63b85337be2b19
+#V6.1 Release Notes
+#Release_ChangeId_V6_1=I3343779b4ad29ab1be55a002fbc43ecdbc440993
+#Support T7C, T3
+#Support new DOS Reg management
+#V6.0 Release Notes
+#Release_ChangeId_V6_0=Ie5dd8015a9663f3be43a0867348b70812bdfb25e
+#Support DMABUF heap Feature
+#Support Decoder new Buffer management for V4Ldec
+#Support  Kernel 5.15
+#Support non-V4ldec  feature of the all V5 version and so on
+#Kernel 5.15 Support Chip SC2
+#Support Codec2 for Android T, all CTS test clean
 #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
+#v4ldec driver separate from amports drivers
 #
 #V4.0.0 Release Notes
 #upgrade Kernel version to 4.19
-#v4l2 support  for h264/h265/vp9 
+#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 
+#media_module remove from kernel
 #new firmware management
 #mjpeg/mpeg12/mpeg2 multi-instance decoder support
 #h264 4k afbc support
@@ -63,8 +62,8 @@
 #upgrade TA ucode to 0.2 version
 #
 #V2.0.0 Release Notes
-#upgrade  Kernel version to 3.14 
-#Introduce codec_mm memory managment
+#upgrade  Kernel version to 3.14
+#Introduce codec_mm memory management
 #add afbc scatter memory support
 #add vp9 decoder support
 #add 264/265/vp9 multi-instance decoder support
diff --git a/drivers/Makefile b/drivers/Makefile
index e96ba44..0eed9e0 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -2,7 +2,6 @@
 obj-y	+=	frame_provider/
 obj-y	+=	frame_sink/
 obj-y	+=	stream_input/
-obj-y	+=	amvdec_ports/
 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..1bee4e0 100644
--- a/drivers/amvdec_ports/Makefile
+++ b/drivers/amvdec_ports/Makefile
@@ -1,26 +1,39 @@
-obj-m += amvdec_ports.o
-amvdec_ports-objs += aml_vcodec_dec_drv.o
-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 += 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
-amvdec_ports-objs += decoder/vdec_mpeg12_if.o
-amvdec_ports-objs += decoder/vdec_mpeg4_if.o
-amvdec_ports-objs += decoder/vdec_mjpeg_if.o
-amvdec_ports-objs += decoder/vdec_av1_if.o
+MODULE_NAME = amvdec_ports
+obj-m += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += aml_vcodec_dec_drv.o
+${MODULE_NAME}-objs += aml_vcodec_dec.o
+${MODULE_NAME}-objs += aml_vcodec_util.o
+${MODULE_NAME}-objs += aml_vcodec_adapt.o
+${MODULE_NAME}-objs += aml_vcodec_vpp.o
+${MODULE_NAME}-objs += aml_vcodec_ge2d.o
+${MODULE_NAME}-objs += aml_vcodec_ts.o
+${MODULE_NAME}-objs += vdec_drv_if.o
+${MODULE_NAME}-objs += aml_task_chain.o
+${MODULE_NAME}-objs += aml_buf_mgr.o
+${MODULE_NAME}-objs += aml_buf_core.o
+${MODULE_NAME}-objs += decoder/vdec_h264_if.o
+${MODULE_NAME}-objs += decoder/vdec_hevc_if.o
+${MODULE_NAME}-objs += decoder/vdec_vp9_if.o
+${MODULE_NAME}-objs += decoder/vdec_mpeg12_if.o
+${MODULE_NAME}-objs += decoder/vdec_mpeg4_if.o
+${MODULE_NAME}-objs += decoder/vdec_mjpeg_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs_if.o
+${MODULE_NAME}-objs += decoder/vdec_av1_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs2_if.o
+${MODULE_NAME}-objs += decoder/vdec_avs3_if.o
+${MODULE_NAME}-objs += decoder/vdec_vc1_if.o
 ifdef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
-amvdec_ports-objs += decoder/aml_h264_parser.o
-amvdec_ports-objs += decoder/aml_hevc_parser.o
-amvdec_ports-objs += decoder/aml_vp9_parser.o
-amvdec_ports-objs += decoder/aml_mpeg12_parser.o
-amvdec_ports-objs += decoder/aml_mpeg4_parser.o
-amvdec_ports-objs += decoder/aml_mjpeg_parser.o
-amvdec_ports-objs += utils/golomb.o
+${MODULE_NAME}-objs += decoder/aml_h264_parser.o
+${MODULE_NAME}-objs += decoder/aml_hevc_parser.o
+${MODULE_NAME}-objs += decoder/aml_vp9_parser.o
+${MODULE_NAME}-objs += decoder/aml_mpeg12_parser.o
+${MODULE_NAME}-objs += decoder/aml_mpeg4_parser.o
+${MODULE_NAME}-objs += decoder/aml_mjpeg_parser.o
+${MODULE_NAME}-objs += utils/golomb.o
 endif
-amvdec_ports-objs += utils/common.o
+${MODULE_NAME}-objs += utils/common.o
+${MODULE_NAME}-objs += utils/aml_dec_trace.o
+
+PR_FMT = "amlv4l"
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/amvdec_ports/aml_buf_core.c b/drivers/amvdec_ports/aml_buf_core.c
new file mode 100644
index 0000000..b98a0ea
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_core.c
@@ -0,0 +1,872 @@
+/*
+* 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/atomic.h>
+#include <linux/dma-buf.h>
+
+#include "aml_buf_core.h"
+#include "aml_vcodec_util.h"
+
+static bool bc_sanity_check(struct buf_core_mgr_s *bc)
+{
+	return (bc->state == BM_STATE_ACTIVE) ? true : false;
+}
+
+/* In mmap mode, key is phy_addr; And in dma mode, key is dma buf handle */
+static bool is_dma_mode(ulong key, ulong phy_addr)
+{
+	return (key != phy_addr) ? true : false;
+}
+
+static void buf_core_destroy(struct kref *kref);
+
+static void direction_buf_get(struct buf_core_mgr_s *bc,
+			  struct buf_core_entry *entry,
+			  enum buf_core_user user)
+{
+	int type;
+	switch (user) {
+		case BUF_USER_DEC:
+			entry->holder = BUF_HOLDER_DEC;
+			entry->ref_bit_map += DEC_BIT;
+
+			break;
+		case BUF_USER_VPP:
+			entry->holder = BUF_HOLDER_VPP;
+			entry->ref_bit_map += VPP_BIT;
+
+			type = bc->get_pre_user(bc, entry, user);
+			if (type == BUF_USER_DEC)
+				entry->ref_bit_map -= DEC_BIT;
+			if (type == BUF_USER_GE2D)
+				entry->ref_bit_map -= GE2D_BIT;
+
+			break;
+		case BUF_USER_GE2D:
+			entry->holder = BUF_HOLDER_GE2D;
+			entry->ref_bit_map += GE2D_BIT;
+			entry->ref_bit_map -= DEC_BIT;
+
+			break;
+		case BUF_USER_VSINK:
+			entry->holder = BUF_HOLDER_VSINK;
+			entry->ref_bit_map += VSINK_BIT;
+
+			type = bc->get_pre_user(bc, entry, user);
+			if (type == BUF_USER_VPP)
+				entry->ref_bit_map -= VPP_BIT;
+			if (type == BUF_USER_DEC)
+				entry->ref_bit_map -= DEC_BIT;
+			if (type == BUF_USER_GE2D)
+				entry->ref_bit_map -= GE2D_BIT;
+
+			break;
+		case BUF_USER_DI:
+			entry->ref_bit_map += DI_BIT;
+
+			break;
+		default:
+			break;
+	}
+}
+
+static void direction_buf_put(struct buf_core_mgr_s *bc,
+			  struct buf_core_entry *entry,
+			  enum buf_core_user user)
+{
+	switch (user) {
+		case BUF_USER_DEC:
+			if (entry->ref_bit_map & DEC_MASK)
+				entry->ref_bit_map -= DEC_BIT;
+			if (entry->ref_bit_map & GE2D_MASK)
+				entry->holder = BUF_HOLDER_GE2D;
+			if (entry->ref_bit_map & VPP_MASK)
+				entry->holder = BUF_HOLDER_VPP;
+			if (entry->ref_bit_map & VSINK_MASK)
+				entry->holder = BUF_HOLDER_VSINK;
+
+			break;
+		case BUF_USER_VPP:
+			entry->ref_bit_map -= VPP_BIT;
+			if (entry->ref_bit_map & VPP_MASK)
+				entry->holder = BUF_HOLDER_VPP;
+			else {
+				if (entry->ref_bit_map & GE2D_MASK)
+					entry->holder = BUF_HOLDER_GE2D;
+				if (entry->ref_bit_map & DEC_MASK)
+					entry->holder = BUF_HOLDER_DEC;
+			}
+
+			break;
+		case BUF_USER_GE2D:
+			entry->ref_bit_map -= GE2D_BIT;
+			if (entry->ref_bit_map & GE2D_MASK)
+				entry->holder = BUF_HOLDER_GE2D;
+			else
+				entry->holder = BUF_HOLDER_DEC;
+
+			break;
+		case BUF_USER_VSINK:
+			entry->ref_bit_map -= VSINK_BIT;
+			if (entry->ref_bit_map & DEC_MASK)
+				entry->holder = BUF_HOLDER_DEC;
+			if (entry->ref_bit_map & VSINK_MASK)
+				entry->holder = BUF_HOLDER_VSINK;
+			else if (entry->ref_bit_map & DI_MASK)
+				entry->holder = BUF_HOLDER_DI;
+
+			break;
+		case BUF_USER_DI:
+			entry->ref_bit_map -= DI_BIT;
+
+			break;
+		default:
+			break;
+	}
+}
+
+static void buf_core_update_holder(struct buf_core_mgr_s *bc,
+			  struct buf_core_entry *entry,
+			  enum buf_core_user user,
+			  enum buf_direction direction)
+{
+	struct buf_core_entry *master = entry->pair != BUF_MASTER ? entry->master_entry : entry;
+
+	if (direction == BUF_GET)
+		direction_buf_get(bc, master, user);
+	else
+		direction_buf_put(bc, master, user);
+
+	if (master->ref_bit_map & 0x8888)
+		v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"error! ref_bit_map(0x%x)\n", master->ref_bit_map);
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, holder:%d, key:%lx, ref_bit_map(0x%x)\n",
+		__func__, user, master->holder, master->key, master->ref_bit_map);
+
+	return;
+}
+
+static void buf_core_free_que(struct buf_core_mgr_s *bc,
+			     struct buf_core_entry *entry)
+{
+	entry->state = BUF_STATE_FREE;
+	entry->holder = BUF_HOLDER_FREE;
+	entry->ref_bit_map = 0;
+	list_add_tail(&entry->node, &bc->free_que);
+	bc->free_num++;
+	entry->inited = true;
+	entry->queued_mask = 0;
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+}
+
+static void buf_core_get(struct buf_core_mgr_s *bc,
+			enum buf_core_user user,
+			struct buf_core_entry **out_entry,
+			bool more_ref)
+{
+	struct buf_core_entry *entry = NULL, *sub_entry;
+	bool user_change = false;
+
+	mutex_lock(&bc->mutex);
+
+	if (!bc_sanity_check(bc)) {
+		goto out;
+	}
+
+	if (list_empty(&bc->free_que)) {
+		goto out;
+	}
+
+	entry = list_first_entry(&bc->free_que, struct buf_core_entry, node);
+	list_del(&entry->node);
+	bc->free_num--;
+
+	user_change	= entry->user != user ? 1 : 0;
+	entry->user	= user;
+	entry->state	= BUF_STATE_USE;
+	atomic_inc(&entry->ref);
+
+	if (entry->sub_entry[0]) {
+		sub_entry = (struct buf_core_entry *)entry->sub_entry[0];
+		sub_entry->user = user;
+		sub_entry->state = BUF_STATE_USE;
+	}
+
+	if (entry->sub_entry[1]) {
+		sub_entry = (struct buf_core_entry *)entry->sub_entry[1];
+		sub_entry->user = user;
+		sub_entry->state = BUF_STATE_USE;
+	}
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__, user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	if (bc->prepare /*&&
+		user_change*/) {
+		bc->prepare(bc, entry);
+	}
+	buf_core_update_holder(bc, entry, user, BUF_GET);
+out:
+	*out_entry = entry;
+
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put(struct buf_core_mgr_s *bc,
+			struct buf_core_entry *entry)
+{
+	mutex_lock(&bc->mutex);
+
+	if (!bc_sanity_check(bc)) {
+		mutex_unlock(&bc->mutex);
+		return;
+	}
+
+	atomic_dec_return(&entry->ref);
+
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_get_ref(struct buf_core_mgr_s *bc,
+			    struct buf_core_entry *entry)
+{
+	mutex_lock(&bc->mutex);
+
+	if (!bc_sanity_check(bc)) {
+		mutex_unlock(&bc->mutex);
+		return;
+	}
+
+	entry->state = BUF_STATE_REF;
+	atomic_inc(&entry->ref);
+	//kref_get(&bc->core_ref);
+	buf_core_update_holder(bc, entry, BUF_USER_DEC, BUF_GET);
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put_ref(struct buf_core_mgr_s *bc,
+			    struct buf_core_entry *entry)
+{
+	mutex_lock(&bc->mutex);
+
+	if (!atomic_read(&entry->ref) && !bc_sanity_check(bc)) {
+		v4l_dbg_ext(bc->id, 0,
+		"%s, user:%d, key:%lx, phy:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+		mutex_unlock(&bc->mutex);
+		return;
+	}
+
+	if (!atomic_dec_return(&entry->ref)) {
+		buf_core_free_que(bc, entry);
+	} else {
+		entry->state = BUF_STATE_REF;
+		buf_core_update_holder(bc, entry, BUF_USER_DEC, BUF_PUT);
+	}
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	//kref_put(&bc->core_ref, buf_core_destroy);
+
+	mutex_unlock(&bc->mutex);
+}
+
+static int buf_core_done(struct buf_core_mgr_s *bc,
+			   struct buf_core_entry *entry,
+			   enum buf_core_user user)
+{
+	int ret = 0;
+	struct buf_core_entry *master;
+	mutex_lock(&bc->mutex);
+
+	master = entry;
+	if (entry->pair != BUF_MASTER)
+		master = entry->master_entry;
+
+	if (!bc_sanity_check(bc)) {
+		goto out;
+	}
+
+	if (WARN_ON((entry->state != BUF_STATE_USE) &&
+		(entry->state != BUF_STATE_REF) &&
+		(entry->state != BUF_STATE_DONE))) {
+		ret = -1;
+		goto out;
+	}
+
+	entry->state = BUF_STATE_DONE;
+
+	ret = bc->output(bc, entry, user);
+
+	if (bc->vpp_dque && /* Submit to GE2D doesn't call vpp_dque! */
+		bc->get_next_user(bc, entry, user) == BUF_USER_VSINK &&
+		!bc->vpp_dque(bc, entry)) {
+		atomic_inc(&master->ref);
+		buf_core_update_holder(bc, entry, BUF_USER_DI, BUF_GET);
+	}
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__, user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&master->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+out:
+	mutex_unlock(&bc->mutex);
+
+	return ret;
+}
+
+static void buf_core_fill(struct buf_core_mgr_s *bc,
+			    struct buf_core_entry *entry,
+			    enum buf_core_user user)
+{
+	if (bc->vpp_que && user == BUF_USER_VSINK &&
+		!bc->vpp_que(bc, entry)) {
+		/*
+		 * For DI post scenario, if seek or change resolution is doing,
+		 * the reset callback will be executed in this process, and
+		 * the state of all entries will be cleaned, but in fact
+		 * the memory associated with entry may still be used
+		 * as reference in DI mgr. If vpp_que returns 0, this entry
+		 * is referenced by DI mgr, wait for DI mgr to be used, and
+		 * then call callback to retrieve the buffer.
+		 */
+		mutex_lock(&bc->mutex);
+		if (!entry->inited || entry->state == BUF_STATE_FREE)
+			goto out;
+		mutex_unlock(&bc->mutex);
+	}
+
+	mutex_lock(&bc->mutex);
+
+	if (!bc_sanity_check(bc)) {
+		goto out;
+	}
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__, user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	if (WARN_ON((entry->state != BUF_STATE_INIT) &&
+		(entry->state != BUF_STATE_DONE) &&
+		(entry->state != BUF_STATE_REF))) {
+		goto out;
+	}
+
+	if (bc->external_process)
+		bc->external_process(bc, entry);
+
+	if (!atomic_dec_return(&entry->ref)) {
+		buf_core_free_que(bc, entry);
+	} else {
+		entry->state = BUF_STATE_REF;
+		buf_core_update_holder(bc, entry, user, BUF_PUT);
+	}
+
+out:
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_vpp_cb(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+	mutex_lock(&bc->mutex);
+	if (entry->pair != BUF_MASTER)
+		entry = (struct buf_core_entry *)entry->master_entry;
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__, entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	if (!atomic_dec_return(&entry->ref)) {
+		buf_core_free_que(bc, entry);
+	} else {
+		entry->state = BUF_STATE_REF;
+		buf_core_update_holder(bc, entry, BUF_USER_DI, BUF_PUT);
+	}
+	mutex_unlock(&bc->mutex);
+}
+
+static int buf_core_ready_num(struct buf_core_mgr_s *bc)
+{
+	if (!bc_sanity_check(bc)) {
+		return 0;
+	}
+
+	return bc->free_num;
+}
+
+static bool buf_core_empty(struct buf_core_mgr_s *bc)
+{
+	if (!bc_sanity_check(bc)) {
+		return true;
+	}
+
+	return list_empty(&bc->free_que);
+}
+
+static void buf_core_reset(struct buf_core_mgr_s *bc)
+{
+	struct buf_core_entry *entry, *tmp;
+	struct hlist_node *h_tmp;
+	ulong bucket;
+
+	if (bc->vpp_reset)
+		bc->vpp_reset(bc);
+
+	mutex_lock(&bc->mutex);
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, core st:%d, core ref:%d, free:%d\n",
+		__func__,
+		bc->state,
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+		list_del(&entry->node);
+	}
+
+	hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+		entry->user = BUF_USER_MAX;
+		entry->state = BUF_STATE_INIT;
+		entry->queued_mask = 0;
+		entry->inited = false;
+
+		if (entry->pair == BUF_MASTER) {
+			atomic_set(&entry->ref, 1);
+			if (entry->sub_entry[0])
+				atomic_inc(&entry->ref);
+			if (entry->sub_entry[1])
+				atomic_inc(&entry->ref);
+		}
+	}
+
+	bc->free_num = 0;
+
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_destroy(struct kref *kref)
+{
+	struct buf_core_mgr_s *bc =
+		container_of(kref, struct buf_core_mgr_s, core_ref);
+	struct buf_core_entry *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+		list_del(&entry->node);
+	}
+
+	bc->free_num	= 0;
+	bc->buf_num	= 0;
+	bc->state	= BM_STATE_EXIT;
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+}
+
+static int buf_core_attach(struct buf_core_mgr_s *bc, ulong key,
+					ulong phy_addr, void *priv)
+{
+	int ret = 0;
+	struct buf_core_entry *entry;
+	struct hlist_node *tmp;
+
+	mutex_lock(&bc->mutex);
+
+	hash_for_each_possible_safe(bc->buf_table, entry, tmp, h_node, key) {
+		if (key == entry->key) {
+			if (is_dma_mode(key, phy_addr) && !entry->dma_ref) {
+				get_dma_buf((struct dma_buf *)key);
+				entry->dma_ref++;
+			}
+			v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+				"reuse buffer, user:%d, key:%lx, phy:%lx idx:%d, "
+				"st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+				entry->user,
+				entry->key,
+				entry->phy_addr,
+				entry->index,
+				entry->state,
+				bc->state,
+				entry->dma_ref,
+				atomic_read(&entry->ref),
+				kref_read(&bc->core_ref),
+				bc->free_num);
+
+			entry->user	= BUF_USER_MAX;
+			entry->state	= BUF_STATE_INIT;
+			entry->vb2 	= priv;
+
+			bc->prepare(bc, entry);
+
+			goto out;
+		}
+	}
+
+	ret = bc->mem_ops.alloc(bc, &entry, priv);
+	if (ret) {
+		goto out;
+	}
+
+	entry->key	= key;
+	entry->phy_addr = phy_addr;
+	entry->priv	= bc;
+	entry->vb2	= priv;
+	entry->user	= BUF_USER_MAX;
+	entry->state	= BUF_STATE_INIT;
+	atomic_set(&entry->ref, 1);
+
+	hash_add(bc->buf_table, &entry->h_node, key);
+
+	bc->state	= BM_STATE_ACTIVE;
+	bc->buf_num++;
+	kref_get(&bc->core_ref);
+	if (is_dma_mode(key, phy_addr)) {
+		get_dma_buf((struct dma_buf *)key);
+		entry->dma_ref++;
+	}
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->phy_addr,
+		entry->index,
+		entry->state,
+		bc->state,
+		entry->dma_ref,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+out:
+	mutex_unlock(&bc->mutex);
+
+	return ret;
+}
+
+static void buf_core_detach(struct buf_core_mgr_s *bc, ulong key)
+{
+	struct buf_core_entry *entry;
+	struct hlist_node *h_tmp;
+
+	mutex_lock(&bc->mutex);
+
+	hash_for_each_possible_safe(bc->buf_table, entry, h_tmp, h_node, key) {
+		if (key == entry->key) {
+			v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+				"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+				__func__,
+				entry->user,
+				entry->key,
+				entry->phy_addr,
+				entry->index,
+				entry->state,
+				bc->state,
+				atomic_read(&entry->ref),
+				kref_read(&bc->core_ref),
+				bc->free_num);
+
+			entry->state = BUF_STATE_ERR;
+			hash_del(&entry->h_node);
+			bc->mem_ops.free(bc, entry);
+
+			kref_put(&bc->core_ref, buf_core_destroy);
+			break;
+		}
+	}
+
+	mutex_unlock(&bc->mutex);
+}
+
+static void buf_core_put_dma(struct buf_core_mgr_s *bc)
+{
+	struct buf_core_entry *entry;
+	struct hlist_node *h_tmp;
+	ulong bucket;
+
+	mutex_lock(&bc->mutex);
+
+	hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+		if (is_dma_mode(entry->key, entry->phy_addr) &&
+			entry->dma_ref) {
+			entry->dma_ref--;
+			v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+				"%s, user:%d, key:%lx, phy:%lx, idx:%d, st:(%d, %d), ref:(%d, %d, %d), free:%d\n",
+				__func__,
+				entry->user,
+				entry->key,
+				entry->phy_addr,
+				entry->index,
+				entry->state,
+				bc->state,
+				entry->dma_ref,
+				atomic_read(&entry->ref),
+				kref_read(&bc->core_ref),
+				bc->free_num);
+			dma_buf_put((struct dma_buf *)entry->key);
+		}
+	}
+
+	mutex_unlock(&bc->mutex);
+}
+
+
+static void buf_core_update(struct buf_core_mgr_s *bc, struct buf_core_entry *entry,
+					ulong phy_addr, enum buf_pair pair)
+{
+	mutex_lock(&bc->mutex);
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR,
+			"%s, user:%d, key:%lx, phy:(%lx->%lx), "
+			"idx:%d, pair:%d st:(%d, %d), ref:(%d, %d), free:%d\n",
+			__func__,
+			entry->user,
+			entry->key,
+			entry->phy_addr,
+			phy_addr,
+			entry->index,
+			pair,
+			entry->state,
+			bc->state,
+			atomic_read(&entry->ref),
+			kref_read(&bc->core_ref),
+			bc->free_num);
+
+	entry->phy_addr = phy_addr;
+	entry->pair = pair;
+
+	bc->prepare(bc, entry);
+
+	mutex_unlock(&bc->mutex);
+}
+
+void buf_core_replace(struct buf_core_mgr_s *bc,
+				struct buf_core_entry *entry, void *priv)
+{
+	mutex_lock(&bc->mutex);
+
+	entry->vb2	= priv;
+	entry->user	= BUF_USER_MAX;
+	entry->state	= BUF_STATE_INIT;
+
+	bc->prepare(bc, entry);
+
+	mutex_unlock(&bc->mutex);
+}
+
+ssize_t buf_core_walk(struct buf_core_mgr_s *bc, char *buf)
+{
+	struct buf_core_entry *entry, *tmp;
+	struct hlist_node *h_tmp;
+	ulong bucket;
+	int dec_holders = 0;
+	int ge2d_holders = 0;
+	int vpp_holders = 0;
+	int vsink_holders = 0;
+	int di_holders = 0;
+	char *pbuf = buf;
+
+	mutex_lock(&bc->mutex);
+
+	pbuf += sprintf(pbuf, "\nFree queue elements:\n");
+	list_for_each_entry_safe(entry, tmp, &bc->free_que, node) {
+		pbuf += sprintf(pbuf,
+			"--> key:%lx, phy:%lx, idx:%d, user:%d, holder:%d, "
+			"st:(%d, %d), ref:(%d, %d), free:%d\n",
+			entry->key,
+			entry->phy_addr,
+			entry->index,
+			entry->user,
+			entry->holder,
+			entry->state,
+			bc->state,
+			atomic_read(&entry->ref),
+			kref_read(&bc->core_ref),
+			bc->free_num);
+	}
+
+	pbuf += sprintf(pbuf, "\nHash table elements:\n");
+	hash_for_each_safe(bc->buf_table, bucket, h_tmp, entry, h_node) {
+		if (entry->pair == BUF_MASTER) {
+			if (entry->holder == BUF_HOLDER_DEC)
+				dec_holders++;
+			if (entry->holder == BUF_HOLDER_GE2D)
+				ge2d_holders++;
+			if (entry->holder == BUF_HOLDER_VPP)
+				vpp_holders++;
+			if (entry->holder == BUF_HOLDER_VSINK)
+				vsink_holders++;
+			if (entry->ref_bit_map & DI_MASK)
+				di_holders++;
+
+			pbuf += sprintf(pbuf,
+				"--> key:%lx, phy:%lx, idx:%d, user:%d, holder:%d, st:(%d, %d), ref:(%d, %d), free:%d, ref_map:0x%x\n",
+				entry->key,
+				entry->phy_addr,
+				entry->index,
+				entry->user,
+				entry->holder,
+				entry->state,
+				bc->state,
+				atomic_read(&entry->ref),
+				kref_read(&bc->core_ref),
+				bc->free_num,
+				entry->ref_bit_map);
+		}
+	}
+	pbuf += sprintf(pbuf, "holders: dec(%d), ge2d(%d), vpp(%d), vsink(%d) di(%d)\n",
+		dec_holders, ge2d_holders, vpp_holders, vsink_holders, di_holders);
+
+	mutex_unlock(&bc->mutex);
+
+	return pbuf - buf;
+}
+EXPORT_SYMBOL(buf_core_walk);
+
+int buf_core_mgr_init(struct buf_core_mgr_s *bc)
+{
+	/* Sanity check of mandatory interfaces. */
+	if (WARN_ON(!bc->config) ||
+		WARN_ON(!bc->input) ||
+		WARN_ON(!bc->output) ||
+		WARN_ON(!bc->mem_ops.alloc) ||
+		WARN_ON(!bc->mem_ops.free)) {
+		return -1;
+	}
+
+	hash_init(bc->buf_table);
+	INIT_LIST_HEAD(&bc->free_que);
+	mutex_init(&bc->mutex);
+	kref_init(&bc->core_ref);
+
+	bc->free_num		= 0;
+	bc->buf_num		= 0;
+	bc->state		= BM_STATE_INIT;
+
+	/* The external interfaces of BC context. */
+	bc->attach		= buf_core_attach;
+	bc->detach		= buf_core_detach;
+	bc->reset		= buf_core_reset;
+	bc->update		= buf_core_update;
+	bc->replace		= buf_core_replace;
+	bc->put_dma		= buf_core_put_dma;
+
+	/* The interface set of the buffer core operation. */
+	bc->buf_ops.get		= buf_core_get;
+	bc->buf_ops.put		= buf_core_put;
+	bc->buf_ops.get_ref	= buf_core_get_ref;
+	bc->buf_ops.put_ref	= buf_core_put_ref;
+	bc->buf_ops.done	= buf_core_done;
+	bc->buf_ops.fill	= buf_core_fill;
+	bc->buf_ops.ready_num	= buf_core_ready_num;
+	bc->buf_ops.empty	= buf_core_empty;
+	bc->buf_ops.vpp_cb	= buf_core_vpp_cb;
+	bc->buf_ops.update_holder = buf_core_update_holder;
+
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+	return 0;
+}
+EXPORT_SYMBOL(buf_core_mgr_init);
+
+void buf_core_mgr_release(struct buf_core_mgr_s *bc)
+{
+	v4l_dbg_ext(bc->id, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+	kref_put(&bc->core_ref, buf_core_destroy);
+}
+EXPORT_SYMBOL(buf_core_mgr_release);
+
diff --git a/drivers/amvdec_ports/aml_buf_core.h b/drivers/amvdec_ports/aml_buf_core.h
new file mode 100644
index 0000000..ad5d600
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_core.h
@@ -0,0 +1,315 @@
+/*
+* 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_BUF_CORE_H_
+#define _AML_BUF_CORE_H_
+
+#include <linux/kref.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/hashtable.h>
+
+#define NEW_FB_CODE
+
+#define BUF_HASH_BITS	(10)
+
+#define DEC_BIT  (UL(1) << (0))
+#define GE2D_BIT  (UL(1) << (4))
+#define VPP_BIT  (UL(1) << (8))
+#define VSINK_BIT  (UL(1) << (12))
+#define DI_BIT  (UL(1) << (16))
+
+#define DEC_MASK  (0xf)
+#define GE2D_MASK  (0xf0)
+#define VPP_MASK  (0xf00)
+#define VSINK_MASK  (0xf000)
+#define DI_MASK  (0xf0000)
+
+#define MASTER_DONE  (1)
+#define SUB0_DONE  (2)
+#define SUB1_DONE  (3)
+#define PAIR_DONE  (3)
+
+struct buf_core_mgr_s;
+
+/*
+ * enum buf_core_state - The state of the buffer to be used.
+ *
+ * @BUF_STATE_INIT	: The initialization state of the buffer.
+ * @BUF_STATE_FREE	: The idle state of the buffer that can be used.
+ * @BUF_STATE_USE	: The status of the buffer being allocated by the user.
+ * @BUF_STATE_REF	: The state of the buffer referenced by the user.
+ * @BUF_STATE_DONE	: The state of the buffer is filled done by user.
+ * @BUF_STATE_ERR     	: The buffer has an error or is about to be released.
+ */
+enum buf_core_state {
+	BUF_STATE_INIT,
+	BUF_STATE_FREE,
+	BUF_STATE_USE,
+	BUF_STATE_REF,
+	BUF_STATE_DONE,
+	BUF_STATE_ERR
+};
+
+/*
+ * enum buf_core_state - The state of the buffer core manager context.
+ *
+ * @BM_STATE_INIT	: The initialization state of context.
+ * @BM_STATE_ACTIVE	: Status indicates that there are available buffers to manage.
+ * @BM_STATE_EXIT	: The buffer core manager context release.
+ */
+enum buf_core_mgr_state {
+	BM_STATE_INIT,
+	BM_STATE_ACTIVE,
+	BM_STATE_EXIT
+};
+
+/*
+ * enum buf_core_user - Buffer users.
+ *
+ * @BUF_USER_DEC	: Indicates that the current buffer user is decoder.
+ * @BUF_USER_VPP	: Indicates that the current buffer user is vpp wrapper.
+ * @BUF_USER_GE2D	: Indicates that the current buffer user is ge2d wrapper.
+ * @BUF_USER_VSINK	: Indicates that the current buffer user is vsink.
+ * @BUF_USER_MAX	: Invalid user.
+ */
+enum buf_core_user {
+	BUF_USER_DEC,
+	BUF_USER_VPP,
+	BUF_USER_GE2D,
+	BUF_USER_VSINK,
+	BUF_USER_DI,
+	BUF_USER_MAX
+};
+
+/*
+ * enum buf_core_holder - Buffer holders.
+ *
+ * @BUF_HOLDER_DEC	: Indicates that the current buffer holder is decoder.
+ * @BUF_HOLDER_VPP	: Indicates that the current buffer holder is vpp wrapper.
+ * @BUF_HOLDER_GE2D	: Indicates that the current buffer holder is ge2d wrapper.
+ * @BUF_HOLDER_VSINK	: Indicates that the current buffer holder is vsink.
+ * @BUF_HOLDER_MAX	: Invalid holder.
+ */
+enum buf_core_holder {
+	BUF_HOLDER_DEC,
+	BUF_HOLDER_VPP,
+	BUF_HOLDER_GE2D,
+	BUF_HOLDER_VSINK,
+	BUF_HOLDER_DI,
+	BUF_HOLDER_FREE,
+};
+
+enum buf_direction {
+	BUF_GET,
+	BUF_PUT
+};
+
+/*
+ * enum buf_pair - For di post.
+ *
+ * @BUF_MASTER	: Indicates that the first field.
+ * @BUF_SUB0	: Indicates that the second field.
+ * @BUF_SUB1	: Indicates that the third field.
+ */
+enum buf_pair {
+	BUF_MASTER,
+	BUF_SUB0,
+	BUF_SUB1
+};
+
+/*
+ * struct buf_core_entry - The entry of buffer.
+ *
+ * @key		: Record the actual physical address associated with vb.
+ * @ref		: Decode buffer's reference count status.
+ * @master_ref	: Point to master buf ref.
+ * @node	: The position of the decoded buffer entry.
+ * @h_node	: The node of hash list used for query buffer.
+ * @state	: The state of the buffer to be used.
+ * @user	: Indicates the user that holds the current entry.
+ * @vb2		: The handle of v4l2 video buffer2.
+ * @priv	: Record associated private data.
+ * @ref_bit_map	: [0, 3]: dec ref, [4, 7]: ge2d ref,
+ *		  [8, 11]: vpp ref, [12, 15]: vsink ref.
+ * @sub_entry[2]: sub_entry[0]: The second filed buf entry;
+ *		  sub_entry[1]: The third filed buf entry;
+ * @master_entry: The first filed buf entry.
+ * @pair	: Buf attributes: master, sub0, sub1.
+ * @pair_state	: Buffer pairing status.
+ * @index	: Aml buf index.
+ * @inited	: The pairing is completed and enters the free queue.
+ * @queued_mask	: Field buffer return times.
+ */
+struct buf_core_entry {
+	ulong			key;
+	ulong			phy_addr;
+	atomic_t		ref;
+	atomic_t		*master_ref;
+	u32			dma_ref;
+	struct list_head	node;
+	struct hlist_node	h_node;
+	enum buf_core_state	state;
+	enum buf_core_user	user;
+	enum buf_core_holder	holder;
+	void			*vb2;
+	void			*priv;
+	u32			ref_bit_map;
+	void			*sub_entry[2];
+	void			*master_entry;
+	enum buf_pair		pair;
+	u32			pair_state;
+	u32			index;
+	u32			inited;
+	u32			queued_mask; /* bit0: master; bit1: sub0; bit1: sub1*/
+};
+
+/*
+ * struct buf_core_ops - The interface set of the buffer core operation.
+ *
+ * @get		: Get a free buffer from free queue.
+ * @put		: Put an unused buffer to the free queue.
+ * @get_ref	: Increase a reference count to the buffer and switch state to REF.
+ * @put_ref	: Decrease a reference count to the buffer.
+ * @done	: The done interface is called if the user finishes fill the data.
+ * @fill	: The fill interface is called if the user consumes the data.
+ * @ready_num	: Query the number of buffers in the free queue.
+ * @empty	: Check whether the free queue is empty.
+ */
+struct buf_core_ops {
+	void	(*get)(struct buf_core_mgr_s *, enum buf_core_user, struct buf_core_entry **, bool);
+	void	(*put)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	void	(*get_ref)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	void	(*put_ref)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	int	(*done)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	void	(*fill)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	int	(*ready_num)(struct buf_core_mgr_s *);
+	bool	(*empty)(struct buf_core_mgr_s *);
+	void	(*vpp_cb)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	void	(*update_holder)(struct buf_core_mgr_s *, struct buf_core_entry *,
+		enum buf_core_user, enum buf_direction direction);
+};
+
+/*
+ * struct buf_core_mem_ops - The memory operation of entry.
+ *
+ * @alloc	: Allocates an instance of an entry.
+ * @free	: Releases an instance of an entry.
+ */
+struct buf_core_mem_ops {
+	int	(*alloc)(struct buf_core_mgr_s *, struct buf_core_entry **, void *);
+	void	(*free)(struct buf_core_mgr_s *, struct buf_core_entry *);
+};
+
+/*
+ * struct buf_core_mgr_s - Decoder buffer management structure.
+ *
+ * @id		: Instance ID of the buffer core manager context.
+ * @name	: Name of the buffer core manager context.
+ * @state	: State of the buffer core manager context.
+ * @mutex	: Lock is used to ensure interface serialization.
+ * @core_ref	: Reference count of the buffer core manager context.
+ * @free_num	: The number of free buffers available.
+ * @free_que	: Queue for storing free buffers.
+ * @buf_num	: Record the serial number of buffer attached to the buffer manager.
+ * @buf_table	: Used to store the attached buffer.
+ * @config	: Interface Settings parameters to buffer manager.
+ * @attach	: The interface is used to attach buffer to buffer manager.
+ * @detach	: Interface for detach buffer to buffer manager.
+ * @reset	: Interface used to reset the state of the buffer manager.
+ * @prepare	: The interface is used for the preprocessing of buffer data.
+ * @input	: The interface uses data input and is triggered after calling the interface fill.
+ * @output	: The interface uses data output and is triggered after the interface is called done.
+ * vpp_que	: Interact with DI mgr to notify the buffer that has been displayed back to the driver.
+ * vpp_dque	: The decoded buffer is submitted to DI mgr for post-processing.
+ * vpp_reset	: Used to reset the buffer information managed by DI mgr.
+ * @mem_ops	: Set of interfaces for memory-related operations.
+ * @buf_ops	: Set of interfaces for buffer operations.
+ */
+struct buf_core_mgr_s {
+	int			id;
+	char			*name;
+	enum buf_core_mgr_state	state;
+	struct mutex		mutex;
+	struct kref		core_ref;
+
+	int			free_num;
+	struct list_head	free_que;
+
+	int			buf_num;
+	DECLARE_HASHTABLE(buf_table, BUF_HASH_BITS);
+
+	void	(*config)(struct buf_core_mgr_s *, void *);
+	int	(*attach)(struct buf_core_mgr_s *, ulong, ulong, void *);
+	void	(*detach)(struct buf_core_mgr_s *, ulong);
+	void	(*reset)(struct buf_core_mgr_s *);
+	void	(*prepare)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	void	(*input)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	int	(*output)(struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	int	(*vpp_que)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	int	(*vpp_dque)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	int	(*vpp_reset)(struct buf_core_mgr_s *);
+	void    (*external_process)(struct buf_core_mgr_s *, struct buf_core_entry *);
+	int	(*get_pre_user) (struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	int	(*get_next_user) (struct buf_core_mgr_s *, struct buf_core_entry *, enum buf_core_user);
+	void	(*update)(struct buf_core_mgr_s *, struct buf_core_entry *, ulong, enum buf_pair);
+	void	(*replace)(struct buf_core_mgr_s *, struct buf_core_entry *, void *);
+	void	(*put_dma)(struct buf_core_mgr_s *);
+
+	struct buf_core_mem_ops	mem_ops;
+	struct buf_core_ops	buf_ops;
+};
+
+/*
+ * buf_core_walk() - Iterate over the buffer entities used for debugging.
+ *
+ * @bc	: pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Iterate over information about the used buffer entities
+ * for debugging, including available buffers recorded in
+ * the Free queue and managed buffers attached to the hash table,
+ * and their states are iterated and printed out.
+ */
+ssize_t buf_core_walk(struct buf_core_mgr_s *bc, char *buf);
+
+/*
+ * buf_core_mgr_init() - buffer core management initialization.
+ *
+ * @bc		: pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Used to initialize the buffer core manager context.
+ *
+ * Return	: returns zero on success; an error code otherwise
+ */
+int buf_core_mgr_init(struct buf_core_mgr_s *bc);
+
+/*
+ * buf_core_mgr_release() - buffer core management release.
+ *
+ * @bc		: pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * Used to release buffer core manager context
+ */
+void buf_core_mgr_release(struct buf_core_mgr_s *bc);
+
+#endif //_AML_BUF_CORE_H_
+
diff --git a/drivers/amvdec_ports/aml_buf_mgr.c b/drivers/amvdec_ports/aml_buf_mgr.c
new file mode 100644
index 0000000..0a455a8
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_mgr.c
@@ -0,0 +1,1010 @@
+/*
+* 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/device.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/meson_uvm_core.h>
+
+#include "../frame_provider/decoder/utils/decoder_bmmu_box.h"
+#include "../frame_provider/decoder/utils/decoder_mmu_box.h"
+#include "aml_vcodec_drv.h"
+#include "aml_vcodec_dec.h"
+#include "aml_task_chain.h"
+#include "aml_buf_mgr.h"
+#include "aml_vcodec_util.h"
+#include "vdec_drv_if.h"
+#include "utils/common.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/amlogic/media/video_processor/di_proc_buf_mgr.h>
+#endif
+
+#define IS_VPP_POST(bm)	(bm->vpp_work_mode == VPP_WORK_MODE_DI_POST)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+static void aml_buf_vpp_callback(void *caller_data, struct file *file, int id)
+{
+	struct buf_core_mgr_s *bc = caller_data;
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct buf_core_entry *entry = NULL;
+	struct dma_buf *dbuf = file->private_data;
+	ulong key = (ulong)dbuf;
+
+	hash_for_each_possible(bc->buf_table, entry, h_node, key) {
+		if (key == entry->key) {
+			break;
+		}
+	}
+
+	if (entry && bc->buf_ops.vpp_cb)
+		bc->buf_ops.vpp_cb(bc, entry);
+	else
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR, "entry is NULL\n");
+}
+
+static int aml_buf_vpp_que(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	int ret = -1;
+
+	if (buf->queued_mask & (1 << BUF_SUB0))
+		buf = entry_to_aml_buf(entry->sub_entry[0]);
+
+	if (buf->queued_mask & (1 << BUF_SUB1))
+		buf = entry_to_aml_buf(entry->sub_entry[1]);
+
+	ret = buf_mgr_q_checkin(bm->vpp_handle, buf->planes[0].dbuf->file);
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, idx: %d, ret:%d\n",
+		__func__, buf->index, ret);
+
+	return ret;
+}
+
+static int aml_buf_vpp_dque(struct buf_core_mgr_s *bc, struct buf_core_entry *entry)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	struct vframe_s *vf = &buf->vframe;
+	int ret = -1;
+
+	vf->index_disp	= bm->frm_cnt;
+	vf->omx_index	= bm->frm_cnt;
+
+	if (!(vf->type & VIDTYPE_V4L_EOS))
+		bm->frm_cnt++;
+
+	dmabuf_set_vframe(buf->planes[0].dbuf, &buf->vframe, VF_SRC_DECODER);
+
+	ret = buf_mgr_dq_checkin(bm->vpp_handle, buf->planes[0].dbuf->file);
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, idx: %d, ret:%d\n",
+		__func__, buf->index, ret);
+
+	return ret;
+}
+
+static int aml_buf_vpp_reset(struct buf_core_mgr_s *bc)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	int ret = -1;
+
+	ret = buf_mgr_reset(bm->vpp_handle);
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, ret:%d\n",
+		__func__, ret);
+
+	return ret;
+}
+
+static int aml_buf_vpp_mgr_init(struct aml_buf_mgr_s *bm)
+{
+	if (!IS_VPP_POST(bm))
+		return 0;
+
+	if (!bm->vpp_handle) {
+		bm->vpp_handle = buf_mgr_creat(DEC_TYPE_V4L_DEC,
+					      bm->bc.id,
+					      &bm->bc,
+					      aml_buf_vpp_callback);
+		if (!bm->vpp_handle) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"%s, The vpp buf mgr creat fail.\n",
+				__func__);
+			return -1;
+		}
+
+		bm->bc.vpp_que	= aml_buf_vpp_que;
+		bm->bc.vpp_dque = aml_buf_vpp_dque;
+		bm->bc.vpp_reset = aml_buf_vpp_reset;
+	}
+
+	return 0;
+}
+
+static void aml_buf_vpp_mgr_release(struct aml_buf_mgr_s *bm)
+{
+	if (bm->vpp_handle)
+		buf_mgr_release(bm->vpp_handle);
+}
+#endif
+
+static int aml_buf_box_alloc(struct aml_buf_mgr_s *bm, void **mmu, void **mmu_1, void **bmmu) {
+	struct aml_buf_fbc_info fbc_info;
+	int mmu_flag = bm->config.enable_secure ? CODEC_MM_FLAGS_TVP : 0;
+	int bmmu_flag = mmu_flag;
+	struct aml_vcodec_ctx *ctx = container_of(bm,
+		struct aml_vcodec_ctx, bm);
+
+	bm->get_fbc_info(bm, &fbc_info);
+
+	/* init mmu box */
+	*mmu = decoder_mmu_box_alloc_box(bm->bc.name,
+		bm->bc.id,
+		BUF_FBC_NUM_MAX,
+		fbc_info.max_size * SZ_1M,
+		mmu_flag);
+	if (!(*mmu)) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to create mmu box\n");
+		return -EINVAL;
+	}
+
+#ifdef NEW_FB_CODE
+	if (ctx->front_back_mode) {
+		*mmu_1 = decoder_mmu_box_alloc_box(bm->bc.name,
+			bm->bc.id,
+			BUF_FBC_NUM_MAX,
+			fbc_info.max_size * SZ_1M,
+			mmu_flag);
+		if (!(*mmu_1)) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to create mmu_1 box\n");
+			goto free_mmubox;
+		}
+	}
+#endif
+
+	/* init bmmu box */
+	bmmu_flag |= (CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER);
+	*bmmu = decoder_bmmu_box_alloc_box(bm->bc.name,
+		bm->bc.id,
+		BUF_FBC_NUM_MAX,
+		4 + PAGE_SHIFT,
+		bmmu_flag, BMMU_ALLOC_FLAGS_WAIT);
+	if (!(*bmmu)) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to create bmmu box\n");
+		goto free_mmubox1;
+	}
+
+	return 0;
+
+free_mmubox1:
+	decoder_mmu_box_free(*mmu_1);
+	*mmu_1 = NULL;
+
+free_mmubox:
+	decoder_mmu_box_free(*mmu);
+	*mmu = NULL;
+
+	return -1;
+}
+
+static int aml_buf_box_init(struct aml_buf_mgr_s *bm)
+{
+	u32 dw_mode = DM_YUV_ONLY;
+	struct aml_vcodec_ctx *ctx = container_of(bm,
+		struct aml_vcodec_ctx, bm);
+	bool buff_alloc_done = false;
+
+	if (!bm->mmu || !bm->bmmu) {
+		bm->fbc_array = vzalloc(sizeof(*bm->fbc_array) * BUF_FBC_NUM_MAX);
+		if (!bm->fbc_array)
+			return -ENOMEM;
+		if (aml_buf_box_alloc(bm, &bm->mmu, &bm->mmu_1, &bm->bmmu)) {
+			vfree(bm->fbc_array);
+			bm->fbc_array = NULL;
+			return -EINVAL;
+		}
+		buff_alloc_done = true;
+	}
+
+	if (!bm->mmu_dw || !bm->bmmu_dw) {
+		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+			return -EINVAL;
+		}
+		if (dw_mode & VDEC_MODE_MMU_DW_MASK) {
+			if (aml_buf_box_alloc(bm, &bm->mmu_dw, &bm->mmu_dw_1, &bm->bmmu_dw)) {
+				return -EINVAL;
+			}
+			buff_alloc_done = true;
+		}
+	}
+
+	if (buff_alloc_done)
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+			"box init, bmmu: %px, mmu: %px, bmmu_dw: %px mmu_dw: %px mmu_1: %px, mmu_dw_1: %px\n",
+			bm->bmmu, bm->mmu, bm->bmmu_dw, bm->mmu_dw, bm->mmu_1, bm->mmu_dw_1);
+
+	return 0;
+}
+
+static int aml_buf_fbc_init(struct aml_buf_mgr_s *bm, struct aml_buf *buf)
+{
+	struct aml_buf_fbc_info fbc_info;
+	struct aml_buf_fbc *fbc;
+	int ret, i;
+
+	if (aml_buf_box_init(bm))
+		return -EINVAL;
+
+
+	for (i = 0; i < BUF_FBC_NUM_MAX; i++) {
+		if (!bm->fbc_array[i].ref)
+			break;
+	}
+
+	if (i == BUF_FBC_NUM_MAX) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"out of fbc buf\n");
+		return -EINVAL;
+	}
+
+	bm->get_fbc_info(bm, &fbc_info);
+
+	fbc		= &bm->fbc_array[i];
+	fbc->index	= i;
+	fbc->hsize	= fbc_info.header_size;
+	fbc->hsize_dw   = fbc_info.header_size;
+	fbc->frame_size	= fbc_info.frame_size;
+	fbc->bmmu	= bm->bmmu;
+	fbc->mmu	= bm->mmu;
+	fbc->bmmu_dw	= bm->bmmu_dw;
+	fbc->mmu_dw	= bm->mmu_dw;
+#ifdef NEW_FB_CODE
+	fbc->mmu_1	= bm->mmu_1;
+	fbc->mmu_dw_1	= bm->mmu_dw_1;
+#endif
+	fbc->used[i]	= 0;
+	fbc->ref	= 1;
+
+	/* allocate header */
+	ret = decoder_bmmu_box_alloc_buf_phy(bm->bmmu,
+					    fbc->index,
+					    fbc->hsize,
+					    bm->bc.name,
+					    &fbc->haddr);
+	if (ret < 0) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to alloc %dth bmmu\n", i);
+		return -ENOMEM;
+	}
+	if (!bm->config.enable_secure) {
+		codec_mm_memset(fbc->haddr, 0, fbc->hsize);
+	}
+
+	if (bm->bmmu_dw) {
+		ret = decoder_bmmu_box_alloc_buf_phy(bm->bmmu_dw,
+						    fbc->index,
+						    fbc->hsize_dw,
+						    "v4ldec-m2m-dw",
+						    &fbc->haddr_dw);
+		if (ret < 0) {
+			decoder_bmmu_box_free_idx(bm->bmmu, fbc->index);
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to alloc %dth bmmu dw\n", i);
+			return -ENOMEM;
+		}
+		if (!bm->config.enable_secure) {
+			codec_mm_memset(fbc->haddr_dw, 0, fbc->hsize_dw);
+		}
+	}
+
+	buf->fbc = fbc;
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, fbc:%d, haddr:%lx, hsize:%d, frm size:%d "
+		"haddr_dw:%lx, hsize_dw:%d\n",
+		__func__,
+		fbc->index,
+		fbc->haddr,
+		fbc->hsize,
+		fbc->frame_size,
+		fbc->haddr_dw,
+		fbc->hsize_dw);
+
+	return 0;
+}
+
+static int aml_buf_fbc_release(struct aml_buf_mgr_s *bm, struct aml_buf *buf)
+{
+	struct aml_buf_fbc *fbc = buf->fbc;
+	int ret;
+	struct aml_vcodec_ctx *ctx = container_of(bm,
+		struct aml_vcodec_ctx, bm);
+
+	ret = decoder_bmmu_box_free_idx(bm->bmmu, fbc->index);
+	if (ret < 0) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to free %dth bmmu\n", fbc->index);
+		return -ENOMEM;
+	}
+
+	ret = decoder_mmu_box_free_idx(bm->mmu, fbc->index);
+	if (ret < 0) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to free %dth mmu\n", fbc->index);
+		return -ENOMEM;
+	}
+
+#ifdef NEW_FB_CODE
+	if (ctx->front_back_mode) {
+		ret = decoder_mmu_box_free_idx(bm->mmu_1, fbc->index);
+		if (ret < 0) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to free %dth mmu 1\n", fbc->index);
+			return -ENOMEM;
+		}
+	}
+#endif
+
+	if (bm->mmu_dw) {
+		ret = decoder_mmu_box_free_idx(bm->mmu_dw, fbc->index);
+		if (ret < 0) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to free %dth mmu dw\n", fbc->index);
+			return -ENOMEM;
+		}
+	}
+
+#ifdef NEW_FB_CODE
+	if (ctx->front_back_mode && bm->mmu_dw_1) {
+		ret = decoder_mmu_box_free_idx(bm->mmu_dw_1, fbc->index);
+		if (ret < 0) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to free %dth mmu dw 1\n", fbc->index);
+			return -ENOMEM;
+		}
+	}
+#endif
+
+	if (bm->bmmu_dw) {
+		decoder_bmmu_box_free_idx(bm->bmmu_dw, fbc->index);
+		if (ret < 0) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"fail to free %dth bmmu dw\n", fbc->index);
+			return -ENOMEM;
+		}
+	}
+
+	fbc->used[fbc->index] = 0;
+	fbc->ref = 0;
+	buf->fbc = NULL;
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, fbc:%d, haddr:%lx, hsize:%d, frm size:%d "
+		"haddr_dw:%lx, hsize_dw:%d\n",
+		__func__,
+		fbc->index,
+		fbc->haddr,
+		fbc->hsize,
+		fbc->frame_size,
+		fbc->haddr_dw,
+		fbc->hsize_dw);
+
+	return 0;
+}
+
+static void aml_buf_get_fbc_info(struct aml_buf_mgr_s *bm,
+				struct aml_buf_fbc_info *info)
+{
+	struct vdec_comp_buf_info comp_info;
+
+	if (vdec_if_get_param(bm->priv, GET_PARAM_COMP_BUF_INFO, &comp_info)) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"fail to get comp info\n");
+		return;
+	}
+
+	info->max_size		= comp_info.max_size;
+	info->header_size	= comp_info.header_size;
+	info->frame_size	= comp_info.frame_buffer_size;
+}
+
+static void aml_buf_fbc_destroy(struct aml_buf_mgr_s *bm)
+{
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR, "%s %d\n", __func__, __LINE__);
+	if (bm->bmmu)
+		decoder_bmmu_box_free(bm->bmmu);
+	if (bm->mmu)
+		decoder_mmu_box_free(bm->mmu);
+
+	if (bm->mmu_dw)
+		decoder_mmu_box_free(bm->mmu_dw);
+	if (bm->bmmu_dw)
+		decoder_bmmu_box_free(bm->bmmu_dw);
+
+#ifdef NEW_FB_CODE
+	if (bm->mmu_1)
+		decoder_mmu_box_free(bm->mmu_1);
+	if (bm->mmu_dw_1)
+		decoder_mmu_box_free(bm->mmu_dw_1);
+#endif
+	if (bm->fbc_array)
+		vfree(bm->fbc_array);
+	bm->fbc_array = NULL;
+}
+
+static void aml_buf_mgr_destroy(struct kref *kref)
+{
+	struct aml_buf_mgr_s *bm =
+		container_of(kref, struct aml_buf_mgr_s, ref);
+
+	if (bm->fbc_array) {
+		aml_buf_fbc_destroy(bm);
+	}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+	aml_buf_vpp_mgr_release(bm);
+#endif
+}
+
+static void aml_buf_flush(struct aml_buf_mgr_s *bm,
+				struct aml_buf *aml_buf)
+{
+	struct aml_buf_config *cfg = &bm->config;
+	void *buf = NULL;
+	int i;
+
+	if (aml_buf->flush_flag)
+		return;
+
+	if (cfg->enable_secure)
+		return;
+
+	for (i = 0 ; i < aml_buf->num_planes ; i++) {
+		buf = codec_mm_phys_to_virt(aml_buf->planes_tw[i].addr);
+		if (buf) {
+			codec_mm_dma_flush(buf,
+				aml_buf->planes_tw[i].length, DMA_FROM_DEVICE);
+		} else {
+			buf = codec_mm_vmap(aml_buf->planes_tw[i].addr,
+				aml_buf->planes_tw[i].length);
+			if (!buf) {
+				v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+					"%s flush tw dma buffer fail!\n", __func__);
+				return;
+			}
+
+			codec_mm_dma_flush(buf,
+				aml_buf->planes_tw[i].length, DMA_FROM_DEVICE);
+			codec_mm_unmap_phyaddr(buf);
+		}
+	}
+
+	aml_buf->flush_flag = true;
+}
+
+void aml_buf_set_planes_v4l2(struct aml_buf_mgr_s *bm,
+				   struct aml_buf *aml_buf,
+				   void *priv)
+{
+	struct vb2_buffer *vb = (struct vb2_buffer *)priv;
+	struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+	struct aml_v4l2_buf *aml_vb = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+	struct aml_buf_config *cfg = &bm->config;
+	struct aml_buf *master_buf;
+	char plane_n[3] = {'Y','U','V'};
+	int i;
+
+	aml_buf->vb		= vb;
+	aml_buf->num_planes	= vb->num_planes;
+	aml_vb->aml_buf		= aml_buf;
+	aml_buf->entry.index	= aml_buf->index;
+	aml_buf->inited		= aml_buf->entry.inited;
+	aml_buf->entry.pair_state	= aml_buf->pair_state;
+
+	for (i = 0 ; i < vb->num_planes ; i++) {
+		if (i == 0) {
+			//Y
+			if (vb->num_planes == 1) {
+				aml_buf->planes[0].length	= cfg->luma_length + cfg->chroma_length;
+				aml_buf->planes[0].offset	= cfg->luma_length;
+			} else {
+				aml_buf->planes[0].length	= cfg->luma_length;
+				aml_buf->planes[0].offset	= 0;
+			}
+		} else {
+			if (vb->num_planes == 2) {
+				//UV
+				aml_buf->planes[1].length	= cfg->chroma_length;
+				aml_buf->planes[1].offset	= cfg->chroma_length >> 1;
+			} else {
+				aml_buf->planes[i].length	= cfg->chroma_length >> 1;
+				aml_buf->planes[i].offset	= 0;
+			}
+		}
+
+		aml_buf->planes[i].addr	= get_addr(vb, i);
+		aml_buf->planes[i].dbuf	= vb->planes[i].dbuf;
+
+		if (aml_buf->pair == BUF_SUB0) {
+			master_buf = (struct aml_buf *)aml_buf->master_buf;
+			master_buf->entry.master_ref = &master_buf->entry.ref;
+			master_buf->entry.sub_entry[0] = (void *)&aml_buf->entry;
+
+			aml_buf->entry.master_entry = (void *)&master_buf->entry;
+			aml_buf->entry.master_ref = &master_buf->entry.ref;
+		}
+
+		if (aml_buf->pair == BUF_SUB1) {
+			master_buf = (struct aml_buf *)aml_buf->master_buf;
+			master_buf->entry.sub_entry[1] = (void *)&aml_buf->entry;
+
+			aml_buf->entry.master_entry = (void *)&master_buf->entry;
+			aml_buf->entry.master_ref = &master_buf->entry.ref;
+		}
+
+		/* Make a fake used size for DW/TW:(0, 0). */
+		if (!cfg->dw_mode)
+			aml_buf->planes[i].bytes_used = 1;
+
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+			"Buffer info, id:%x, %c:(0x%lx, %d), DW:%x\n",
+			vb->index,
+			plane_n[i],
+			aml_buf->planes[i].addr,
+			aml_buf->planes[i].length,
+			cfg->dw_mode);
+	}
+
+	if (cfg->tw_mode) {
+		for (i = 0 ; i < vb->num_planes ; i++) {
+			if (i == 0) {
+				//Y
+				if (vb->num_planes == 1) {
+					aml_buf->planes_tw[0].length	= cfg->luma_length_tw + cfg->chroma_length_tw;
+					aml_buf->planes_tw[0].offset	= cfg->luma_length_tw;
+				} else {
+					aml_buf->planes_tw[0].length	= cfg->luma_length_tw;
+					aml_buf->planes_tw[0].offset	= 0;
+				}
+			} else {
+				if (vb->num_planes == 2) {
+					//UV
+					aml_buf->planes_tw[1].length	= cfg->chroma_length_tw;
+					aml_buf->planes_tw[1].offset	= cfg->chroma_length_tw >> 1;
+				} else {
+					aml_buf->planes_tw[i].length	= cfg->chroma_length_tw >> 1;
+					aml_buf->planes_tw[i].offset	= 0;
+				}
+			}
+
+			aml_buf->planes_tw[i].addr = (cfg->dw_mode == DM_AVBC_ONLY) ?
+				vb2_dma_contig_plane_dma_addr(vb, i):
+				(aml_buf->planes_tw[i].addr ?
+					aml_buf->planes_tw[i].addr:
+					codec_mm_alloc_for_dma_ex("tw_buf",
+						(cfg->luma_length_tw +
+						cfg->chroma_length_tw) / PAGE_SIZE,
+						4,
+						CODEC_MM_FLAGS_FOR_VDECODER,
+						bm->bc.id,
+						i));
+			aml_buf->planes_tw[i].dbuf = vb->planes[i].dbuf;
+			aml_buf_flush(bm, aml_buf);
+
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+				"Buffer info, id:%d, %c:(0x%lx, %d), TW:%x\n",
+				vb->index,
+				plane_n[i],
+				aml_buf->planes_tw[i].addr,
+				aml_buf->planes_tw[i].length,
+				cfg->tw_mode);
+		}
+	}
+}
+
+static void aml_buf_set_planes(struct aml_buf_mgr_s *bm,
+			      struct aml_buf *buf)
+{
+	//todo
+}
+
+static int aml_buf_set_default_parms(struct aml_buf_mgr_s *bm,
+				     struct aml_buf *buf,
+				     void *priv)
+{
+	int ret;
+
+	buf->index = bm->bc.buf_num;
+
+	if (bm->config.enable_extbuf) {
+		aml_buf_set_planes_v4l2(bm, buf, priv);
+
+		ret = aml_uvm_buff_attach(buf->vb);
+		if (ret) {
+			v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+				"uvm buffer attach failed.\n");
+			return ret;
+		}
+	} else {
+		// alloc buffer
+		aml_buf_set_planes(bm, buf);
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+	ret = aml_buf_vpp_mgr_init(bm);
+	if (ret) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"VPP buf mgr init failed.\n");
+		return ret;
+	}
+#endif
+
+	ret = task_chain_init(&buf->task, bm->priv, buf, buf->index);
+	if (ret) {
+		v4l_dbg(bm->priv, V4L_DEBUG_CODEC_ERROR,
+			"task chain init failed.\n");
+	}
+
+	return ret;
+}
+
+static int aml_buf_alloc(struct buf_core_mgr_s *bc,
+			struct buf_core_entry **entry,
+			void *priv)
+{
+	int ret;
+	struct aml_buf *buf;
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+
+	buf = vzalloc(sizeof(struct aml_buf));
+	if (buf == NULL) {
+		return -ENOMEM;
+	}
+
+	/* afbc init. */
+	if (bm->config.enable_fbc) {
+		ret = aml_buf_fbc_init(bm, buf);
+		if (ret) {
+			goto err1;
+		}
+	}
+
+	ret = aml_buf_set_default_parms(bm, buf, priv);
+	if (ret) {
+		goto err2;
+	}
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, entry:%px, free:%d\n",
+		__func__,
+		&buf->entry,
+		bc->free_num);
+
+	kref_get(&bm->ref);
+
+	*entry = &buf->entry;
+
+	return 0;
+
+err2:
+	aml_buf_fbc_destroy(bm);
+err1:
+	vfree(buf);
+
+	return ret;
+}
+
+static void aml_buf_free(struct buf_core_mgr_s *bc,
+			struct buf_core_entry *entry)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	int i;
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, entry:%px, user:%d, key:%lx, idx:%d, st:(%d, %d), ref:(%d, %d)\n",
+		__func__,
+		entry,
+		entry->user,
+		entry->key,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref));
+
+	/* afbc free */
+	if (buf->fbc) {
+		aml_buf_fbc_release(bm, buf);
+	}
+
+	/* task chain clean */
+	task_chain_clean(buf->task);
+	/* task chain release */
+	task_chain_release(buf->task);
+
+	/* free triple write buffer. */
+	if (bm->config.tw_mode &&
+		(bm->config.dw_mode != DM_AVBC_ONLY)) {
+		for (i = 0 ; i < buf->num_planes ; i++) {
+			if (buf->planes_tw[i].addr)
+				codec_mm_free_for_dma("tw_buf", buf->planes_tw[i].addr);
+		}
+	}
+
+	kref_put(&bm->ref, aml_buf_mgr_destroy);
+
+	if (buf->vpp_buf)
+		vfree(buf->vpp_buf);
+
+	if (buf->ge2d_buf)
+		vfree(buf->ge2d_buf);
+
+	vfree(buf);
+}
+
+static void aml_buf_configure(struct buf_core_mgr_s *bc, void *cfg)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+
+	bm->config = *(struct aml_buf_config *)cfg;
+}
+
+static void aml_external_process(struct buf_core_mgr_s *bc,
+				struct buf_core_entry *entry)
+{
+	struct aml_buf *aml_buf = entry_to_aml_buf(entry);
+	struct aml_buf_mgr_s *bm =
+			container_of(bc, struct aml_buf_mgr_s, bc);
+
+	aml_vdec_recycle_dec_resource(bm->priv, aml_buf);
+}
+
+static void aml_buf_prepare(struct buf_core_mgr_s *bc,
+				struct buf_core_entry *entry)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	struct aml_buf_fbc_info fbc_info = { 0 };
+	struct aml_buf *sub_buf[2];
+	struct buf_core_entry *sub_entry;
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, idx:%d, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->index,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	if (entry->sub_entry[0]) {
+		sub_entry = (struct buf_core_entry *)entry->sub_entry[0];
+		sub_buf[0] = (struct aml_buf *)buf->sub_buf[0];
+	}
+
+	if (entry->sub_entry[1]) {
+		sub_entry = (struct buf_core_entry *)entry->sub_entry[1];
+		sub_buf[1] = (struct aml_buf *)buf->sub_buf[1];
+	}
+
+	if (entry->user != BUF_USER_MAX && !task_chain_empty(buf->task)) {
+		task_chain_clean(buf->task);
+		if (entry->sub_entry[0])
+			task_chain_clean(sub_buf[0]->task);
+		if (entry->sub_entry[1])
+			task_chain_clean(sub_buf[1]->task);
+	}
+
+	if (bm->config.enable_fbc)
+		bm->get_fbc_info(bm, &fbc_info);
+
+	if (buf->fbc &&
+		((fbc_info.frame_size != buf->fbc->frame_size) ||
+		(fbc_info.header_size != buf->fbc->hsize) ||
+		!bm->config.enable_fbc)) {
+		aml_buf_fbc_release(bm, buf);
+	}
+
+	if (bm->config.enable_fbc &&
+		!buf->fbc) {
+		aml_buf_fbc_init(bm, buf);
+	}
+
+	if (bm->config.enable_extbuf) {
+		aml_buf_set_planes_v4l2(bm, buf, entry->vb2);
+	} else {
+		aml_buf_set_planes(bm, buf);
+	}
+
+	if (entry->user != BUF_USER_MAX) {
+		aml_creat_pipeline(bm->priv, buf, entry->user);
+		if (entry->sub_entry[0])
+			aml_creat_pipeline(bm->priv, sub_buf[0], entry->user);
+		if (entry->sub_entry[1])
+			aml_creat_pipeline(bm->priv, sub_buf[1], entry->user);
+	}
+}
+
+static int aml_buf_output(struct buf_core_mgr_s *bc,
+			  struct buf_core_entry *entry,
+			  enum buf_core_user user)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	struct aml_buf *master_buf;
+	struct buf_core_entry *master_entry;
+	int i;
+
+	if (task_chain_empty(buf->task))
+		return -1;
+
+	if (entry->pair != BUF_MASTER) {
+		master_entry = (struct buf_core_entry *)entry->master_entry;
+		master_buf = entry_to_aml_buf(master_entry);
+
+		for (i = 0; i < buf->num_planes; i++) {
+			buf->planes[i].bytes_used = master_buf->planes[i].bytes_used;
+		}
+	}
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	return buf->task->submit(buf->task, user_to_task(user));
+}
+
+static void aml_buf_input(struct buf_core_mgr_s *bc,
+		   struct buf_core_entry *entry,
+		   enum buf_core_user user)
+{
+	struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+
+	if (task_chain_empty(buf->task))
+		return;
+
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+
+	buf->task->recycle(buf->task, user_to_task(user));
+}
+
+static int aml_buf_get_pre_user(struct buf_core_mgr_s *bc,
+		   struct buf_core_entry *entry,
+		   enum buf_core_user user)
+{
+	//struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	int type;
+
+	if (task_chain_empty(buf->task))
+		return BUF_USER_MAX;
+#if 0
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+#endif
+	type = buf->task->get_pre_user(buf->task, user_to_task(user));
+
+	return task_to_user(type);
+}
+
+static int aml_buf_get_next_user(struct buf_core_mgr_s *bc,
+		   struct buf_core_entry *entry,
+		   enum buf_core_user user)
+{
+	//struct aml_buf_mgr_s *bm = bc_to_bm(bc);
+	struct aml_buf *buf = entry_to_aml_buf(entry);
+	int type;
+
+	if (task_chain_empty(buf->task))
+		return BUF_USER_MAX;
+#if 0
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, user:%d, key:%lx, st:(%d, %d), ref:(%d, %d), free:%d\n",
+		__func__,
+		entry->user,
+		entry->key,
+		entry->state,
+		bc->state,
+		atomic_read(&entry->ref),
+		kref_read(&bc->core_ref),
+		bc->free_num);
+#endif
+	type = buf->task->get_next_user(buf->task, user_to_task(user));
+
+	return task_to_user(type);
+}
+
+int aml_buf_mgr_init(struct aml_buf_mgr_s *bm, char *name, int id, void *priv)
+{
+	int ret = -1;
+
+	bm->bc.id		= id;
+	bm->bc.name		= name;
+	bm->priv		= priv;
+	bm->get_fbc_info	= aml_buf_get_fbc_info;
+
+	bm->bc.config		= aml_buf_configure;
+	bm->bc.prepare		= aml_buf_prepare;
+	bm->bc.input		= aml_buf_input;
+	bm->bc.output		= aml_buf_output;
+	bm->bc.get_pre_user	= aml_buf_get_pre_user;
+	bm->bc.get_next_user	= aml_buf_get_next_user;
+	bm->bc.external_process	= aml_external_process;
+	bm->bc.mem_ops.alloc	= aml_buf_alloc;
+	bm->bc.mem_ops.free	= aml_buf_free;
+
+	kref_init(&bm->ref);
+
+	ret = buf_core_mgr_init(&bm->bc);
+	if (ret) {
+		v4l_dbg(priv, V4L_DEBUG_CODEC_ERROR,
+			"%s, init fail.\n", __func__);
+	} else {
+		v4l_dbg(priv, V4L_DEBUG_CODEC_BUFMGR,
+			"%s\n", __func__);
+	}
+
+	return ret;
+}
+
+void aml_buf_mgr_release(struct aml_buf_mgr_s *bm)
+{
+	v4l_dbg(bm->priv, V4L_DEBUG_CODEC_BUFMGR, "%s\n", __func__);
+
+	kref_put(&bm->ref, aml_buf_mgr_destroy);
+	buf_core_mgr_release(&bm->bc);
+}
+
diff --git a/drivers/amvdec_ports/aml_buf_mgr.h b/drivers/amvdec_ports/aml_buf_mgr.h
new file mode 100644
index 0000000..458c2b9
--- /dev/null
+++ b/drivers/amvdec_ports/aml_buf_mgr.h
@@ -0,0 +1,297 @@
+/*
+* 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_DEC_BUFMGR_H_
+#define _AML_DEC_BUFMGR_H_
+
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "aml_buf_core.h"
+
+#define BUF_FBC_NUM_MAX		(64)
+#define BUF_MAX_PLANES		(3)
+
+/* VPP work mode. */
+#define VPP_WORK_MODE_DI_M2M	(0)
+#define VPP_WORK_MODE_DI_POST	(1)
+
+struct aml_buf_mgr_s;
+
+/*
+ * struct aml_buf_config - Parameter configuration structure.
+ *
+ * @enable_extbuf	: Configure the external buffer mode.
+ * @buf_size		: The size of buffer that should be allocated.
+ * @enable_fbc		: Enables the AFBC feature.
+ * @enable_secure	: Indicates the secure mode.
+ * @memory_mode		: memory mode used by v4l2 vb queue.
+ * @vpp_work_mode	: 0: used DI m2m interface, 1: DI post process mode.
+ * @planes		: The number of planes used.
+ * @luma_length		: The size of the image brightness data.
+ * @chroma_length	: The size of the image chroma data.
+ */
+struct aml_buf_config {
+	bool	enable_extbuf;
+	bool	enable_fbc;
+	bool 	enable_secure;
+	int	memory_mode;
+	int	planes;
+	u32	luma_length;
+	u32	chroma_length;
+	u32	luma_length_tw;
+	u32	chroma_length_tw;
+	u32	dw_mode;
+	u32	tw_mode;
+};
+
+/*
+ * struct aml_buf_plane - Buffer plane information.
+ *
+ * @dbuf	: The address of dmabuf.
+ * @addr	: Indicates the associated physical address.
+ * @vaddr	: Indicates the virtual address associated with plane.
+ * @length	: The actual size of the buffer.
+ * @bytes_used	: The size of the buffer to be used.
+ * @offset	: The offset position used by buffer.
+ * @stride	: The size of each line of image data.
+ * @uvm_fd	: The file handle of UVM buffer.
+ */
+struct aml_buf_plane {
+	struct dma_buf	*dbuf;
+	ulong		addr;
+	void		*vaddr;
+	u32		length;
+	u32		bytes_used;
+	u32		offset;
+	int		stride;
+	int		uvm_fd;
+};
+
+/*
+ * struct aml_buf_fbc_info - AFBC buffer size information.
+ *
+ * @max_size	: Max size needed for mmu box.
+ * @header_size	: Continuous size for the compressed header.
+ * @frame_size	: SG page number to store the frame.
+ */
+struct aml_buf_fbc_info {
+	u32		max_size;
+	u32		header_size;
+	u32		frame_size;
+};
+
+typedef void (*get_fbc_info)(struct aml_buf_mgr_s *,
+			    struct aml_buf_fbc_info *);
+
+/*
+ * struct aml_buf_fbc - AFBC buffer information.
+ *
+ * @index	: The serial number of the buffer.
+ * @bmmu	: The context of bmmu box.
+ * @mmu		: The context of mmu box.
+ * @ref		: Reference count of AFBC buffer.
+ * @haddr	: The address of header data.
+ * @hsize	: The size of header data.
+ * @frame_size	: the size of AFBC data per frame.
+ * @used: bit[0]: 0, idle; 1, decoder alloc from mmu
+ *        bit[1]: 0, idle; 1, decoder alloc from mmu_dw.
+ */
+struct aml_buf_fbc {
+	u32		index;
+	void		*bmmu;
+	void		*mmu;
+	void		*bmmu_dw;
+	void		*mmu_dw;
+	int		ref;
+	ulong		haddr;
+	u32		hsize;
+	ulong		haddr_dw;
+	u32		hsize_dw;
+	u32		frame_size;
+#ifdef NEW_FB_CODE
+	void		*mmu_1;
+	void		*mmu_dw_1;
+#endif
+	int		used[BUF_FBC_NUM_MAX];
+};
+
+/*
+ * struct aml_buf - aml_buf structure.
+ *
+ * @index	: The serial number of the buffer.
+ * @state	: Indicates the usage status of the aml_buf.
+ * @num_planes	: The number of planes used.
+ * @planes	: Buffer plane information.
+ * @planes_tw	: Used for another buffer planes storage.
+ * @fbc		: AFBC buffer information.
+ * @entry	: Buffer entity embedded in aml_buf.
+ * @task	: The context of task chain.
+ * @vframe	: The video frame struct.
+ * @vb		: The vb2 struct defined by v4l2.
+ * @meta_ptr	: The handle of meta date.
+ * @flush_flag	: Mark the buffer flush at the first time to alloc.
+ * @is_delay_allocated	: Dma buffer allocated and replaced.
+ * @cap_sgt	: Point to new capture buffer sg table.
+ * @idmabuf[2]	: Delayed allocated dma buffer.
+ * @uvm_buf	: Uvm buf.
+ * @master_buf	: The first filed buf entry.
+ * @sub_buf[2]	: sub_buf[0]: The second filed buf entry;
+ *		  sub_buf[1]: The third filed buf entry;
+ * @pair	: Buf attributes: master, sub0, sub1.
+ * @pair_state	: Buffer pairing status.
+ * @inited	: The pairing is completed and enters the free queue.
+ * @queued_mask	: Field buffer return times.
+ */
+struct aml_buf {
+	u32			index;
+	int			state;
+	u32			num_planes;
+	u64			timestamp;
+	struct aml_buf_plane	planes[BUF_MAX_PLANES];
+	struct aml_buf_plane	planes_tw[BUF_MAX_PLANES];
+	struct aml_buf_fbc	*fbc;
+	struct buf_core_entry	entry;
+
+	struct task_chain_s	*task;
+	struct vframe_s		vframe;
+	struct vb2_buffer	*vb;
+	ulong			meta_ptr;
+	void			*vpp_buf;
+	void			*ge2d_buf;
+	bool			flush_flag;
+	bool 			is_delay_allocated;
+	struct 			sg_table *cap_sgt;
+	struct dma_buf 		*idmabuf[2];
+	void			*uvm_buf;
+	void 			*master_buf;
+	void 			*sub_buf[2];
+	enum buf_pair		pair;
+	u32			pair_state;
+	u32			inited;
+	u32			queued_mask;
+};
+
+/*
+ * struct aml_buf_mgr_s - aml_buf manager context.
+ *
+ * @bc		: The buffer core manager context.
+ * @ref		: The reference count of buffer manager.
+ * @priv	: Records the context of the caller.
+ * @config	: Parameter configuration structure.
+ * @bmmu	: The context of bmmu box.
+ * @mmu		: The context of mmu box.
+ * @fbc_array	: AFBC buffer array data.
+ * @get_fbc_info : Used to get AFBC data size information.
+ * @vpp_handle	: The handle of DI post mode.
+ */
+struct aml_buf_mgr_s {
+	struct buf_core_mgr_s		bc;
+	struct kref			ref;
+	void				*priv;
+
+	struct aml_buf_config		config;
+
+	/* fbc information */
+	void				*bmmu;
+	void				*mmu;
+	void				*bmmu_dw;
+	void				*mmu_dw;
+#ifdef NEW_FB_CODE
+	void				*mmu_1;
+	void				*mmu_dw_1;
+#endif
+	struct aml_buf_fbc		*fbc_array;
+	get_fbc_info			get_fbc_info;
+
+	void				*vpp_handle;
+	u32				frm_cnt;
+	int				vpp_work_mode;
+};
+
+/*
+ * bc_to_bm() - Used for BC to BM.
+ *
+ * @bc		: Pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * It is easy to convert BC to BM.
+ *
+ * Return	: returns bm context.
+ */
+static inline struct aml_buf_mgr_s *bc_to_bm(struct buf_core_mgr_s *bc)
+{
+	return container_of(bc, struct aml_buf_mgr_s, bc);
+}
+
+/*
+ * entry_to_aml_buf() - Used for entry to aml_buf.
+ *
+ * @bc		: Pointer to &struct buf_core_mgr_s buffer core manager context.
+ *
+ * It is easy to convert entry to aml_buf.
+ *
+ * Return	: returns aml_buf
+ */
+static inline struct aml_buf *entry_to_aml_buf(void *entry)
+{
+	return container_of(entry, struct aml_buf, entry);
+}
+
+/*
+ * aml_buf_set_vframe() - Copy the contents of vf into ambuf.
+ *
+ * @ambuf	: The struct of aml_buf.
+ * @vf		: The struct of vframe.
+ *
+ * Used to associate vframe within aml_buf.
+ */
+static inline void aml_buf_set_vframe(struct aml_buf *ambuf, struct vframe_s *vf)
+{
+	ambuf->vframe = *vf;
+}
+
+/*
+ * aml_buf_mgr_init() - buffer core management initialization.
+ *
+ * @bm		: Pointer to &struct aml_buf_mgr_s buffer manager context.
+ * @name	: The name of buffer manager.
+ * @id		: The instance ID of buffer manager.
+ * @priv	: The private date from caller.
+ *
+ * Used to initialize the buffer manager context.
+ *
+ * Return	: returns zero on success; an error code otherwise
+ */
+int aml_buf_mgr_init(struct aml_buf_mgr_s *bm, char *name, int id, void *priv);
+
+/*
+ * aml_buf_mgr_release() - buffer core management initialization.
+ *
+ * @bm		: pointer to &struct buf_core_mgr_s buffer manager context.
+ *
+ * Used to initialize the buffer manager context.
+ */
+void aml_buf_mgr_release(struct aml_buf_mgr_s *bm);
+
+#endif //_AML_DEC_BUFMGR_H_
+
diff --git a/drivers/amvdec_ports/aml_task_chain.c b/drivers/amvdec_ports/aml_task_chain.c
index 8dfe014..7450d8e 100644
--- a/drivers/amvdec_ports/aml_task_chain.c
+++ b/drivers/amvdec_ports/aml_task_chain.c
@@ -1,23 +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:
-*/
-
+ * 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>
 
@@ -53,6 +52,19 @@
 	return name;
 }
 
+static enum task_type_e name_to_type(const u8 *name)
+{
+	enum task_type_e type;
+	int i, size = ARRAY_SIZE(iname);
+
+	for (i = 0; i < size; i++) {
+		if (name == iname[i].name)
+			type = iname[i].type;
+	}
+
+	return type;
+}
+
 static struct task_item_s *find_task_item(struct task_chain_s *task,
 					  enum task_type_e type)
 {
@@ -87,8 +99,8 @@
 	int i = 0;
 
 	for (i = 0 ; i < 3; i++) {
-		if (item->vframe[i] == NULL) {
-			item->vframe[i] = vframe;
+		if (item->vframe[i].index == -1) {
+			memcpy(&item->vframe[i], vframe, sizeof(struct vframe_s));
 			break;
 		}
 	}
@@ -96,18 +108,32 @@
 
 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;
+		if (item->vframe[i].index != -1) {
 			break;
 		}
 	}
 
-	return vframe;
+	if (i >= 3) {
+		pr_info("[ERR] vframe pop fail!\n");
+	}
+
+	return &item->vframe[i];
+}
+
+static void task_item_vframe_reset(struct task_item_s *item,
+							struct vframe_s * vf)
+{
+	int i = 0;
+
+	for (i = 0 ; i < 3; i++) {
+		if (vf == &item->vframe[i]) {
+			item->vframe[i].index = -1;
+			break;
+		}
+	}
 }
 
 static struct task_item_s *task_item_get(struct task_chain_s *task,
@@ -116,10 +142,6 @@
 	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;
 }
@@ -129,44 +151,61 @@
 	return kref_put(&item->ref, task_item_release);
 }
 
-static void task_buffer_submit(struct task_chain_s *task,
+static int 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 aml_buf *aml_buf =
+		(struct aml_buf *)task->obj;
 	struct task_item_s *item = NULL;
 	struct task_item_s *item2 = NULL;
-	struct vframe_s *vf = NULL;
+	int ret = 0;
+
+	memset(task->vf_tmp, 0, sizeof(struct vframe_s));
 
 	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->ops->get_vframe(item->caller, task->vf_tmp);
+		memcpy(&aml_buf->vframe, task->vf_tmp, sizeof(struct vframe_s));
+		task_item_vframe_push(item, &aml_buf->vframe);
 		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);
+
+			item2->ops->fill_buffer(task->ctx, aml_buf);
 
 			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,
+				"TSK(%px):%d, vf idx:0x%x, phy:%lx, submit %d => %d.\n",
+				task, task->id, task->vf_tmp->index, aml_buf->planes[0].addr,
 				type, task->map[0][type]);
 
 			task->direction = TASK_DIR_SUBMIT;
+
 			task_item_put(item2);
+
+			ret = 0;
+		} else {
+			v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+				"TSK(%px):%d get item:%d fail.\n", task, task->id, type);
+			ret = -1;
 		}
 		task_item_put(item);
+
+	} else {
+		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+			"TSK(%px):%d get item:%d fail.\n", task, task->id, type);
+		ret = -1;
 	}
+
+	return ret;
 }
 
 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 aml_buf *aml_buf =
+		(struct aml_buf *)task->obj;
 	struct task_item_s *item = NULL;
 	struct task_item_s *item2 = NULL;
 
@@ -181,13 +220,15 @@
 			item2->is_active = true;
 
 			vf = task_item_vframe_pop(item2);
+			memcpy(vf, &aml_buf->vframe, sizeof(struct vframe_s));
 			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,
+				"TSK(%px):%d, vf idx:%d, phy:%lx, recycle %d => %d.\n",
+				task, task->id, vf->index, aml_buf->planes[0].addr,
 				type, task->map[1][type]);
 
+			task_item_vframe_reset(item2, vf);
 			task->direction = TASK_DIR_RECYCLE;
 			task_item_put(item2);
 		}
@@ -195,38 +236,82 @@
 	}
 }
 
-void task_chain_show(struct task_chain_s *task)
+static enum task_type_e task_buffer_get_pre_user(struct task_chain_s *task,
+			       enum task_type_e type)
 {
 	struct task_item_s *item = NULL;
-	char buf[128] = {0};
+	struct task_item_s *item2 = NULL;
+	enum task_type_e type2 = TASK_TYPE_MAX;
+
+	item = task_item_get(task, type);
+	if (item) {
+		item2 = task_item_get(task, task->map[1][type]);
+
+		if (item2) {
+			type2 = name_to_type(item2->name);
+			task_item_put(item2);
+		}
+		task_item_put(item);
+	}
+
+	return type2;
+}
+
+static enum task_type_e task_buffer_get_next_user(struct task_chain_s *task,
+			       enum task_type_e type)
+{
+	struct task_item_s *item = NULL;
+	struct task_item_s *item2 = NULL;
+	enum task_type_e type2 = TASK_TYPE_MAX;
+
+	item = task_item_get(task, type);
+	if (item) {
+		item2 = task_item_get(task, task->map[0][type]);
+
+		if (item2) {
+			type2 = name_to_type(item2->name);
+			task_item_put(item2);
+		}
+		task_item_put(item);
+	}
+
+	return type2;
+}
+
+ssize_t task_chain_show(struct task_chain_s *task, char *buf)
+{
+	struct task_item_s *item = NULL;
+	char tempbuf[128] = {0};
+	char *ptbuf = tempbuf;
 	char *pbuf = buf;
 	ulong flags;
 
 	if (!task || !task->ctx)
-		return;
+		return 0;
 
 	spin_lock_irqsave(&task->slock, flags);
 
 	if (!list_empty(&task->list_item)) {
-		struct vdec_v4l2_buffer *fb =
-			(struct vdec_v4l2_buffer *)task->obj;
+		struct aml_buf *aml_buf =
+			(struct aml_buf *)task->obj;
 
 		list_for_each_entry(item, &task->list_item, node) {
-			pbuf += sprintf(pbuf, "%s(%d)",
+			ptbuf += sprintf(ptbuf, "%s(%d)",
 				item->name, item->is_active);
 			if (item->node.next != &task->list_item) {
 				if (task->direction == TASK_DIR_SUBMIT)
-					pbuf += sprintf(pbuf, " ==> ");
+					ptbuf += sprintf(ptbuf, " ==> ");
 				else
-					pbuf += sprintf(pbuf, " <== ");
+					ptbuf += sprintf(ptbuf, " <== ");
 			}
 		}
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_PRINFO,
-			"vb:%2d, phy:%lx  %s\n",
-			task->id, fb->m.mem[0].addr, buf);
+		pbuf += sprintf(pbuf, "vb:%2d, phy:%lx  %s\n",
+			task->id, aml_buf->planes[0].addr, tempbuf);
 	}
 
 	spin_unlock_irqrestore(&task->slock, flags);
+
+	return pbuf - buf;
 }
 EXPORT_SYMBOL(task_chain_show);
 
@@ -238,6 +323,7 @@
 
 	task->cur_type = TASK_TYPE_MAX;
 	memset(task->map, 0, sizeof(task->map));
+	kfree(task->vf_tmp);
 
 	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
 		"TSK(%px):%d task chain destroyed.\n", task, task->id);
@@ -261,6 +347,12 @@
 	kfree(item);
 }
 
+bool task_chain_empty(struct task_chain_s *task)
+{
+	return task->cur_type == TASK_TYPE_MAX ? true : false;
+}
+EXPORT_SYMBOL(task_chain_empty);
+
 void task_chain_clean(struct task_chain_s *task)
 {
 	struct task_item_s *item, *tmp;
@@ -289,8 +381,9 @@
 			 void *caller)
 {
 	struct task_item_s *item;
+	int i;
 
-	item = kzalloc(sizeof(struct task_item_s), GFP_ATOMIC);
+	item = kzalloc(sizeof(struct task_item_s), GFP_KERNEL);
 	if (!item) {
 		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
 			"TSK(%px):%d alloc item fail.\n", task, task->id);
@@ -302,6 +395,9 @@
 	item->caller	= caller;
 	item->name	= type_to_name(ops->type);
 	kref_init(&item->ref);
+	for (i = 0 ; i < 3; i++) {
+		item->vframe[i].index = -1;
+	}
 
 	task->map[0][ops->type] = task->cur_type;
 	task->map[1][task->cur_type] = ops->type;
@@ -337,16 +433,25 @@
 {
 	struct task_chain_s *task;
 
-	task = kzalloc(sizeof(struct task_chain_s), GFP_ATOMIC);
+	task = kzalloc(sizeof(struct task_chain_s), GFP_KERNEL);
 	if (!task) {
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
-			"TSK(%px):%d alloc task fail.\n", task, task->id);
+		v4l_dbg(v4l_ctx, V4L_DEBUG_CODEC_ERROR,
+			"%s alloc task %d fail.\n", __func__, vb_idx);
 		return -ENOMEM;
 	}
 
 	task->id	= vb_idx;
 	task->obj	= obj;
 	task->ctx	= v4l_ctx;
+	task->cur_type	= TASK_TYPE_MAX;
+
+	task->vf_tmp = kzalloc(sizeof(struct vframe_s), GFP_KERNEL);
+	if (!task->vf_tmp) {
+		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
+			"%s alloc failed!\n", __func__);
+		kfree(task);
+		return -ENOMEM;
+	}
 	kref_init(&task->ref);
 	spin_lock_init(&task->slock);
 	INIT_LIST_HEAD(&task->list_item);
@@ -354,6 +459,8 @@
 	task->attach	= task_order_attach;
 	task->submit	= task_buffer_submit;
 	task->recycle	= task_buffer_recycle;
+	task->get_pre_user	= task_buffer_get_pre_user;
+	task->get_next_user	= task_buffer_get_next_user;
 
 	*task_out = task;
 
diff --git a/drivers/amvdec_ports/aml_task_chain.h b/drivers/amvdec_ports/aml_task_chain.h
index fdbe2fb..16e658a 100644
--- a/drivers/amvdec_ports/aml_task_chain.h
+++ b/drivers/amvdec_ports/aml_task_chain.h
@@ -1,23 +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:
-*/
-
+ * 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
 
@@ -48,7 +47,7 @@
  */
 struct task_ops_s {
 	enum task_type_e type;
-	void	(*get_vframe) (void *caller, struct vframe_s **vf);
+	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);
 };
@@ -69,7 +68,7 @@
 	struct kref		ref;
 	const u8		*name;
 	bool			is_active;
-	void			*vframe[3];
+	struct vframe_s		vframe[3];
 	struct task_chain_s	*task;
 	void			*caller;
 	struct task_ops_s	*ops;
@@ -95,6 +94,7 @@
 	struct list_head	list_item;
 	struct list_head	node;
 	struct kref		ref;
+	struct vframe_s		*vf_tmp;
 	spinlock_t		slock;
 	int			id;
 	void			*ctx;
@@ -104,8 +104,10 @@
 	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);
+	int	(*submit) (struct task_chain_s *, enum task_type_e);
 	void	(*recycle) (struct task_chain_s *, enum task_type_e);
+	enum task_type_e (*get_pre_user) (struct task_chain_s *, enum task_type_e);
+	enum task_type_e (*get_next_user) (struct task_chain_s *, enum task_type_e);
 };
 
 
@@ -118,8 +120,9 @@
 		       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);
+ssize_t task_chain_show(struct task_chain_s *task, char *buf);
 void task_chain_update_object(struct task_chain_s *task, void *obj);
+bool task_chain_empty(struct task_chain_s *task);
 
 #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..87ad57a 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -1,23 +1,24 @@
 /*
-* 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:
-*/
+ * 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 <media/v4l2-mem2mem.h>
 #include <linux/amlogic/media/utils/amstream.h>
 #include <linux/amlogic/media/utils/vformat.h>
 #include <linux/amlogic/media/utils/aformat.h>
@@ -34,14 +35,14 @@
 #include "../stream_input/amports/adec.h"
 #include "../stream_input/amports/streambuf.h"
 #include "../stream_input/amports/streambuf_reg.h"
-#include "../stream_input/parser/tsdemux.h"
-#include "../stream_input/parser/psparser.h"
-#include "../stream_input/parser/esparser.h"
 #include "../frame_provider/decoder/utils/vdec.h"
 #include "../common/media_clock/switch/amports_gate.h"
+#include "../stream_input/parser/stream_parser.h"
 #include <linux/delay.h>
 #include "aml_vcodec_adapt.h"
+#include "aml_vcodec_ts.h"
 #include <linux/crc32.h>
+#include "../common/media_utils/media_utils.h"
 
 #define DEFAULT_VIDEO_BUFFER_SIZE		(1024 * 1024 * 3)
 #define DEFAULT_VIDEO_BUFFER_SIZE_4K		(1024 * 1024 * 6)
@@ -54,8 +55,9 @@
 #define SYNC_OUTSIDE	(2)
 
 //#define DATA_DEBUG
-
+extern int dump_es_output_frame;
 extern int dump_output_frame;
+extern char dump_path[32];
 extern u32 dump_output_start_position;
 extern void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle);
 
@@ -200,14 +202,7 @@
 		return -EPERM;
 	}
 
-	if ((vdec->sys_info->height * vdec->sys_info->width) > 1920 * 1088
-		|| port->vformat == VFORMAT_H264_4K2K) {
-		port->is_4k = true;
-		if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
-				&& (port->vformat == VFORMAT_H264))
-			vdec_poweron(VDEC_HEVC);
-	} else
-		port->is_4k = false;
+	port->is_4k = false;
 
 	if (port->type & PORT_TYPE_FRAME ||
 		(port->type & PORT_TYPE_ES)) {
@@ -237,9 +232,6 @@
 		tsdemux_release();
 	}
 
-	if (port->type & PORT_TYPE_MPPS)
-		psparser_release();
-
 	if (port->type & PORT_TYPE_VIDEO)
 		video_component_release(port);
 
@@ -249,7 +241,7 @@
 	return 0;
 }
 
-static void set_vdec_properity(struct vdec_s *vdec,
+static void set_vdec_property(struct vdec_s *vdec,
 	struct aml_vdec_adapt *ada_ctx)
 {
 	vdec->sys_info	= &ada_ctx->dec_prop;
@@ -273,18 +265,19 @@
 	vdec->port->type |= PORT_TYPE_FRAME;
 	vdec->frame_base_video_path = FRAME_BASE_PATH_V4L_OSD;
 
-	if (aml_set_vdec_type_enable) {
-		if (aml_set_vdec_type == VDEC_TYPE_STREAM_PARSER) {
-			vdec->type = VDEC_TYPE_STREAM_PARSER;
-			vdec->port->type &= ~PORT_TYPE_FRAME;
-			vdec->port->type |= PORT_TYPE_ES;
-		} else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
-			vdec->type = VDEC_TYPE_FRAME_BLOCK;
-			vdec->port->type &= ~PORT_TYPE_ES;
-			vdec->port->type |= PORT_TYPE_FRAME;
-		}
+	if (ada_ctx->ctx->stream_mode) {
+		vdec->type = VDEC_TYPE_STREAM_PARSER;
+		vdec->port->type &= ~PORT_TYPE_FRAME;
+		vdec->port->type |= PORT_TYPE_ES;
+	} else {
+		vdec->type = VDEC_TYPE_FRAME_BLOCK;
+		vdec->port->type &= ~PORT_TYPE_ES;
+		vdec->port->type |= PORT_TYPE_FRAME;
 	}
 
+	if (vdec->format == VFORMAT_VC1)
+		vdec->type = VDEC_TYPE_SINGLE;
+
 	if (aml_set_vfm_enable)
 		vdec->frame_base_video_path = aml_set_vfm_path;
 
@@ -309,7 +302,7 @@
 		return -1;
 
 	vdec->disable_vfm = true;
-	set_vdec_properity(vdec, ada_ctx);
+	set_vdec_property(vdec, ada_ctx);
 
 	/* init hw and gate*/
 	ret = enable_hardware(vdec->port);
@@ -329,7 +322,17 @@
 				vdec->port->vformat == VFORMAT_VP9)
 				pvbuf = &bufs[BUF_TYPE_HEVC];
 		}
+		if (vdec_stream_based(vdec)) {
+			struct parser_args pars;
+			struct stream_buf_ops *ops = get_stbuf_ops();
 
+			ret = stream_buffer_base_init(&vdec->vbuf, ops, &pars);
+			if (ret) {
+				v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+					"stream buffer base init failed\n");
+				return ret;
+			}
+		}
 		ret = video_component_init(vdec->port, pvbuf);
 		if (ret < 0) {
 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "video_component_init  failed\n");
@@ -337,7 +340,7 @@
 		}
 
 		/* connect vdec at the end after all HW initialization */
-		vdec_connect(vdec);
+		aml_codec_connect(ada_ctx);
 	}
 
 	return 0;
@@ -385,11 +388,11 @@
 {
 	struct file *fp;
 
-	fp = filp_open(path,
-			O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+	fp = media_open(path,
+			O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0666);
 	if (!IS_ERR(fp)) {
-		kernel_write(fp, data, size, 0);
-		filp_close(fp, NULL);
+		media_write(fp, data, size, 0);
+		media_close(fp, NULL);
 	} else {
 		pr_info("Dump ES fail, should check RW permission, size:%x\n", size);
 	}
@@ -444,12 +447,17 @@
 bool vdec_input_full(struct aml_vdec_adapt *ada_ctx)
 {
 	struct vdec_s *vdec = ada_ctx->vdec;
+	struct aml_vcodec_ctx *ctx = ada_ctx->ctx;
 
-	return (vdec->input.have_frame_num > 60) ? true : false;
+	/* The driver ignores the stream ctrl if in stream mode. */
+	if (vdec_stream_based(vdec))
+		return false;
+
+	return (vdec->input.have_frame_num > ctx->cache_input_buffer_num) ? true : false;
 }
 
-int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
-	const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr)
+int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, const char *buf,
+	unsigned int count, u64 timestamp, ulong meta_ptr, chunk_free free)
 {
 	int ret = -1;
 	struct vdec_s *vdec = ada_ctx->vdec;
@@ -460,7 +468,7 @@
 	/* set metadata */
 	vdec_set_metadata(vdec, meta_ptr);
 
-	ret = vdec_write_vframe(vdec, buf, count);
+	ret = vdec_write_vframe(vdec, buf, count, free, ada_ctx->ctx);
 
 	if (slow_input) {
 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
@@ -471,14 +479,20 @@
 	if (dump_output_frame > 0 &&
 		(!dump_output_start_position ||
 		(dump_output_start_position == crc32_le(0, buf, count)))) {
-		dump("/data/es.data", buf, count);
+		char file_name[64] = {0};
+
+		snprintf(file_name, 64, "%s/es.data", dump_path);
+		dump(file_name, buf, count);
 		dump_output_frame--;
 		dump_output_start_position = 0;
 	}
 
 	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
-		"write frames, vbuf: %p, size: %u, ret: %d, crc: %x, ts: %llu\n",
-		buf, count, ret, crc32_le(0, buf, count), timestamp);
+		"write frames[%d], vbuf: %p, size: %u, ret: %d, crc: %x, ts: %llu\n",
+		ada_ctx->ctx->write_frames, buf, count, ret,
+		crc32_le(0, buf, count), timestamp);
+
+	ada_ctx->ctx->write_frames++;
 
 	return ret;
 }
@@ -487,7 +501,11 @@
 {
 	struct aml_vcodec_ctx *ctx = priv;
 
-	aml_recycle_dma_buffers(ctx, handle);
+	if (ctx->output_dma_mode)
+		aml_recycle_dma_buffers(ctx, handle);
+
+	if (!vdec_input_full(ctx->ada_ctx))
+		v4l2_m2m_try_schedule(ctx->m2m_ctx);
 }
 
 int vdec_vframe_write_with_dma(struct aml_vdec_adapt *ada_ctx,
@@ -496,7 +514,6 @@
 {
 	int ret = -1;
 	struct vdec_s *vdec = ada_ctx->vdec;
-
 	/* set timestamp */
 	vdec_set_timestamp(vdec, timestamp);
 
@@ -510,8 +527,10 @@
 	}
 
 	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
-		"write frames, vbuf: %lx, size: %u, ret: %d, ts: %llu\n",
-		addr, count, ret, timestamp);
+		"write frames[%d], vbuf: %lx, size: %u, ret: %d, ts: %llu\n",
+		ada_ctx->ctx->write_frames, addr, count, ret, timestamp);
+
+	ada_ctx->ctx->write_frames++;
 
 	return ret;
 }
@@ -546,6 +565,26 @@
 	return ret;
 }
 
+void aml_codec_disconnect(struct aml_vdec_adapt *ada_ctx)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+
+	if (vdec) {
+		vdec_disconnect(vdec);
+		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, "set vdec disconnect\n");
+	}
+}
+
+void aml_codec_connect(struct aml_vdec_adapt *ada_ctx)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+
+	if (vdec) {
+		vdec_connect(vdec);
+		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT, "set vdec connect\n");
+	}
+}
+
 bool is_input_ready(struct aml_vdec_adapt *ada_ctx)
 {
 	struct vdec_s *vdec = ada_ctx->vdec;
@@ -572,11 +611,52 @@
 		return -1;
 }
 
+void vdec_thread_wakeup(struct aml_vdec_adapt *ada_ctx)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+
+	if (vdec) {
+		vdec_up(vdec);
+	}
+}
+
+void vdec_set_dmabuf_type(struct aml_vdec_adapt *ada_ctx, bool dmabuf_type)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+
+	if (vdec) {
+		if (dmabuf_type)
+			vdec->port_flag |= PORT_FLAG_DMABUF;
+		else
+			vdec->port_flag &= ~PORT_FLAG_DMABUF;
+	}
+}
+
 int vdec_get_instance_num(void)
 {
 	return vdec_get_core_nr();
 }
 
+bool vdec_check_is_available(u32 fmt)
+{
+	if ((fmt == V4L2_PIX_FMT_VC1_ANNEX_G) || (fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+		if (vdec_get_instance_num() != 0)
+			return false;
+	} else {
+		if (vdec_has_single_mode())
+			return false;
+	}
+
+	return true;
+}
+
+int vdec_get_vdec_id(struct aml_vdec_adapt *ada_ctx)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+
+	return vdec ? vdec->id : -1;
+}
+
 void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
 {
 	struct vdec_s *vdec = ada_ctx->vdec;
@@ -589,3 +669,132 @@
 {
 	vdec_frame_rate_uevent(duration);
 }
+
+void aml_vdec_recycle_dec_resource(struct aml_vcodec_ctx * ctx,
+					struct aml_buf *aml_buf)
+{
+	if (ctx->vdec_recycle_dec_resource)
+		ctx->vdec_recycle_dec_resource(ctx->ada_ctx->vdec->private, aml_buf);
+}
+
+void vdec_dump_strea_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size)
+{
+	char file_name[64] = {0};
+	ulong buf_start = ada_ctx->vdec->vbuf.buf_start;
+	ulong buf_end = ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size;
+	u32 first_size = size;
+	u32 second_size = 0;
+	void *stbuf_vaddr;
+
+	if ((addr +size) > buf_end) {
+		first_size = buf_end - addr;
+		second_size = size - first_size;
+	}
+
+	stbuf_vaddr = codec_mm_vmap(addr, first_size);
+	if (stbuf_vaddr) {
+		codec_mm_dma_flush(stbuf_vaddr, first_size, DMA_FROM_DEVICE);
+		snprintf(file_name, 64, "%s/es.data", dump_path);
+		dump(file_name, stbuf_vaddr, first_size);
+
+		codec_mm_unmap_phyaddr(stbuf_vaddr);
+		pr_info("dump es buffer (%x, %u)\n", addr, first_size);
+	} else {
+		pr_err("es buffer (%x, %u) vmap fail\n", addr, first_size);
+	}
+
+	if (second_size) {
+		stbuf_vaddr = codec_mm_vmap(buf_start, second_size);
+		if (stbuf_vaddr) {
+			codec_mm_dma_flush(stbuf_vaddr, second_size, DMA_FROM_DEVICE);
+			snprintf(file_name, 64, "%s/es.data", dump_path);
+			dump(file_name, stbuf_vaddr, second_size);
+
+			codec_mm_unmap_phyaddr(stbuf_vaddr);
+			pr_info("dump next part es buffer (%lx, %u)\n", buf_start, second_size);
+		} else {
+			pr_err("next part es buffer (%lx, %u) vmap fail\n", buf_start, second_size);
+		}
+	}
+}
+
+void vdec_write_stream_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size)
+{
+	struct stream_buffer_metainfo stbuf_data = { 0 };
+	stbuf_data.stbuf_pktaddr = addr;
+	stbuf_data.stbuf_pktsize = size;
+	stream_buffer_meta_write(&ada_ctx->vdec->vbuf, &stbuf_data);
+
+	if (dump_es_output_frame) {
+		vdec_dump_strea_data(ada_ctx, addr, size);
+	}
+}
+
+void vdec_write_stream_data_inner(struct aml_vdec_adapt *ada_ctx, char *addr,
+	u32 size, u64 timestamp)
+{
+	bool stbuf_around = false;
+	u32 around_size;
+
+	// calculate whether the remaining space is enougth
+	if ((ada_ctx->vdec->vbuf.buf_wp + size) >
+		(ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size)) {
+		stbuf_around = true;
+		around_size = (ada_ctx->vdec->vbuf.buf_wp + size) -
+			(ada_ctx->vdec->vbuf.buf_start + ada_ctx->vdec->vbuf.buf_size);
+	}
+
+	// if not enougth, write two times
+	if (!stbuf_around)
+		stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+			addr, size);
+	else {
+		stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+			addr, size - around_size);
+
+		stream_buffer_write_vc1(ada_ctx->filp, &ada_ctx->vdec->vbuf,
+			addr + size - around_size, around_size);
+	}
+
+	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
+		"VC1 input: es(add data size %d) -> stbuf(addr 0x%lx wp 0x%x) timestamp: %llu\n",
+		size, ada_ctx->vdec->vbuf.buf_start, ada_ctx->vdec->vbuf.buf_wp, timestamp);
+}
+
+#if 0
+void v4l2_set_rp_addr(struct aml_vdec_adapt *ada_ctx, struct dma_buf *dbuf)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+	u32 rp_addr;
+	struct dmabuf_dmx_sec_es_data *es_data;
+
+	/* get rp addr from vdec */
+	rp_addr = STBUF_READ(&vdec->vbuf, get_rp);
+	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_OUTPUT, "stream rp_addr is %x\n",rp_addr);
+
+	if (dmabuf_manage_get_type(dbuf) != DMA_BUF_TYPE_DMX_ES) {
+		pr_err("current dmabuf type is not DMA_BUF_TYPE_DMX_ES\n");
+		return;
+	}
+
+	es_data = (struct dmabuf_dmx_sec_es_data *)dmabuf_manage_get_info(dbuf, DMA_BUF_TYPE_DMX_ES);
+
+	es_data->buf_rp = rp_addr;
+}
+#endif
+void v4l2_set_ext_buf_addr(struct aml_vdec_adapt *ada_ctx, struct dmabuf_dmx_sec_es_data *es_data, int offset)
+{
+	struct vdec_s *vdec = ada_ctx->vdec;
+	u32 buf_size = 0;
+
+	buf_size = es_data->buf_end - es_data->buf_start;
+	ada_ctx->ctx->es_mgr.buf_start = es_data->buf_start;
+	ada_ctx->ctx->es_mgr.buf_size = buf_size;
+
+	stream_buffer_set_ext_buf(&vdec->vbuf, es_data->buf_start, buf_size, ada_ctx->ctx->is_drm_mode);
+	vdec_init_stbuf_info(vdec);
+	ada_ctx->ctx->pts_serves_ops->first_checkin(ada_ctx->ctx->output_pix_fmt, ada_ctx->ctx->ptsserver_id,
+		es_data->data_start + offset, es_data->buf_start);
+
+	return;
+}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h
index c8641ce..66ed2a6 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.h
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -1,27 +1,28 @@
 /*
-* 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:
-*/
+ * 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 VDEC_ADAPT_H
 #define VDEC_ADAPT_H
 
 #include <linux/amlogic/media/utils/vformat.h>
 #include <linux/amlogic/media/utils/amstream.h>
+#include <linux/amlogic/media/codec_mm/dmabuf_manage.h>
 #include "../stream_input/amports/streambuf.h"
 #include "../frame_provider/decoder/utils/vdec_input.h"
 #include "aml_vcodec_drv.h"
@@ -50,8 +51,8 @@
 int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
 	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);
+int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx, const char *buf,
+	unsigned int count, u64 timestamp, ulong meta_ptr, chunk_free free);
 
 void vdec_vframe_input_free(void *priv, u32 handle);
 
@@ -64,6 +65,8 @@
 void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx);
 
 int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *flag);
+void aml_codec_connect(struct aml_vdec_adapt *ada_ctx);
+void aml_codec_disconnect(struct aml_vdec_adapt *ada_ctx);
 
 extern void dump_write(const char __user *buf, size_t count);
 
@@ -71,9 +74,23 @@
 
 int vdec_frame_number(struct aml_vdec_adapt *ada_ctx);
 
+void vdec_set_dmabuf_type(struct aml_vdec_adapt *ada_ctx, bool dmabuf_type);
+
 int vdec_get_instance_num(void);
 
+bool vdec_check_is_available(u32 fmt);
+
 void vdec_set_duration(s32 duration);
 
+void vdec_write_stream_data(struct aml_vdec_adapt *ada_ctx, u32 addr, u32 size);
+
+void vdec_write_stream_data_inner(struct aml_vdec_adapt *ada_ctx, char *addr, u32 size, u64 timestamp);
+
+void v4l2_set_ext_buf_addr(struct aml_vdec_adapt *ada_ctx, struct dmabuf_dmx_sec_es_data *es_data, int offset);
+
+int vdec_get_vdec_id(struct aml_vdec_adapt *ada_ctx);
+
+void vdec_thread_wakeup(struct aml_vdec_adapt *ada_ctx);
+
 #endif /* VDEC_ADAPT_H */
 
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index f40d3fd..86c2fbe 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -1,22 +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:
-*/
+ * 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 <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
@@ -31,7 +31,13 @@
 #include <linux/scatterlist.h>
 #include <linux/sched/clock.h>
 #include <linux/highmem.h>
+#include <linux/version.h>
 #include <uapi/linux/sched/types.h>
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/media/codec_mm/dmabuf_manage.h>
+#include <linux/dma-heap.h>
+#include <uapi/linux/dma-heap.h>
+#include <linux/amlogic/media/meson_uvm_allocator.h>
 
 #include "aml_vcodec_drv.h"
 #include "aml_vcodec_dec.h"
@@ -45,16 +51,27 @@
 #include "../frame_provider/decoder/utils/decoder_mmu_box.h"
 #include "../common/chips/decoder_cpu_ver_info.h"
 #include "utils/common.h"
+#include "../media_sync/pts_server/pts_server_core.h"
 #include "../frame_provider/decoder/utils/vdec_sync.h"
-
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
+#include "../common/media_utils/media_utils.h"
+#include "../frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h"
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
+#endif
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/amlogic/media/dmabuf_heaps/amlogic_dmabuf_heap.h>
+#include <linux/amlogic/ion.h>
+#else
+#include <linux/meson_ion.h>
+#endif
 
 
 #define OUT_FMT_IDX		(0) //default h264
-#define CAP_FMT_IDX		(9) //capture nv21
-#define CAP_FMT_I420_IDX	(12) //use for mjpeg
+#define CAP_FMT_IDX		(14) //capture nv21m
+#define CAP_FMT_I420_IDX	(18) //use for mjpeg
 
 #define AML_VDEC_MIN_W	64U
 #define AML_VDEC_MIN_H	64U
@@ -66,12 +83,29 @@
 #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 AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE (V4L2_CID_USER_AMLOGIC_BASE + 4)
+#define AML_V4L2_GET_DECODER_INFO (V4L2_CID_USER_AMLOGIC_BASE + 5)
+
+/*V4L2_CID_USER_AMLOGIC_BASE + 5 occupied*/
+#define AML_V4L2_GET_BITDEPTH (V4L2_CID_USER_AMLOGIC_BASE + 6)
+#define AML_V4L2_DEC_PARMS_CONFIG (V4L2_CID_USER_AMLOGIC_BASE + 7)
+#define AML_V4L2_GET_INST_ID (V4L2_CID_USER_AMLOGIC_BASE + 8)
+#define AML_V4L2_SET_STREAM_MODE (V4L2_CID_USER_AMLOGIC_BASE + 9)
+#define AML_V4L2_SET_ES_DMABUF_TYPE (V4L2_CID_USER_AMLOGIC_BASE + 10)
+
+#define V4L2_EVENT_PRIVATE_EXT_VSC_BASE (V4L2_EVENT_PRIVATE_START + 0x2000)
+#define V4L2_EVENT_PRIVATE_EXT_VSC_EVENT (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 1)
+#define V4L2_EVENT_PRIVATE_EXT_SEND_ERROR (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 2)
+#define V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME (V4L2_EVENT_PRIVATE_EXT_VSC_BASE + 3)
 
 #define WORK_ITEMS_MAX (32)
 #define MAX_DI_INSTANCE (2)
 
+#define PAGE_NUM_ONE_MB	(256)
 //#define USEC_PER_SEC 1000000
 
+#define INVALID_IDX -1
+
 #define call_void_memop(vb, op, args...)				\
 	do {								\
 		if ((vb)->vb2_queue->mem_ops->op)			\
@@ -122,12 +156,42 @@
 		.num_planes = 1,
 	},
 	{
+		.name = "AVS",
+		.fourcc = V4L2_PIX_FMT_AVS,
+		.type = AML_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
 		.name = "AV1",
 		.fourcc = V4L2_PIX_FMT_AV1,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
+		.name = "AVS2",
+		.fourcc = V4L2_PIX_FMT_AVS2,
+		.type = AML_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
+		.name = "AVS3",
+		.fourcc = V4L2_PIX_FMT_AVS3,
+		.type = AML_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
+		.name = "VC1L",
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.type = AML_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
+		.name = "VC1G",
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.type = AML_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
 		.name = "NV21",
 		.fourcc = V4L2_PIX_FMT_NV21,
 		.type = AML_FMT_FRAME,
@@ -202,11 +266,36 @@
 				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
 	},
 	{
+		.fourcc = V4L2_PIX_FMT_AVS,
+		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+				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_AVS2,
+		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_AVS3,
+		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
+				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.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},
@@ -243,6 +332,7 @@
 
 extern bool multiplanar;
 extern int dump_capture_frame;
+extern char dump_path[32];
 extern int bypass_vpp;
 extern int bypass_ge2d;
 extern bool support_format_I420;
@@ -252,18 +342,21 @@
 extern int force_enable_di_local_buffer;
 extern int max_di_instance;
 extern int bypass_nr_flag;
+extern int es_node_expand;
+extern int force_di_permission;
+extern int enable_di_post;
 
-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);
+extern int vdec_get_size_ratio(int dw_mode);
 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,
+static void copy_v4l2_format_dimension(struct aml_vcodec_ctx *ctx,
+				       struct v4l2_pix_format_mplane *pix_mp,
 				       struct v4l2_pix_format *pix,
 				       struct aml_q_data *q_data,
 				       u32 type);
+static void vidioc_vdec_s_parm_ext(struct v4l2_ctrl *, struct aml_vcodec_ctx *);
+static void vidioc_vdec_g_parm_ext(struct v4l2_ctrl *, struct aml_vcodec_ctx *);
+static int is_vdec_core_fmt(struct aml_vcodec_ctx *ctx);
+
 
 static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
 {
@@ -334,6 +427,15 @@
 	case V4L2_EVENT_SEND_EOS:
 		event.type = V4L2_EVENT_EOS;
 		break;
+	case V4L2_EVENT_SEND_ERROR:
+		event.type = V4L2_EVENT_PRIVATE_EXT_SEND_ERROR;
+		break;
+	case V4L2_EVENT_REPORT_ERROR_FRAME:
+		event.type = V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME;
+		memcpy(event.u.data, &ctx->current_timestamp, sizeof(u64));
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "report error frame timestamp: %llu\n",
+			ctx->current_timestamp);
+		break;
 	default:
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"unsupport dispatch event %x\n", changes);
@@ -354,6 +456,22 @@
 	aml_decoder_flush(ctx->ada_ctx);
 }
 
+static bool is_di_support(int width, int height)
+{
+	int di_max_width = 1920;
+	int di_max_height = 1088;
+	int di_min_width = 128;
+	int di_min_height = 16;
+
+	if (width > di_max_width || height > di_max_height) {
+		return false;
+	} else if (width < di_min_width || height < di_min_height) {
+		return false;
+	}
+
+	return true;
+}
+
 /* 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
@@ -366,26 +484,31 @@
 {
 	int width = ctx->picinfo.coded_width;
 	int height = ctx->picinfo.coded_height;
-	int size = 1920 * 1088;
 
-	if (bypass_vpp)
+	if (bypass_vpp || ctx->enable_di_post)
+		return false;
+
+	if (ctx->vpp_cfg.bypass)
 		return false;
 
 	if (!ctx->vpp_cfg.enable_nr &&
-		(ctx->picinfo.field == V4L2_FIELD_NONE)) {
+		(ctx->picinfo.field == V4L2_FIELD_NONE) &&
+		!((ctx->config.parm.dec.cfg.double_write_mode & VDEC_MODE_MMU_DW_MASK) &&
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4 ||
+		get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4D))) {
 		return false;
 	}
 
 	if (!ctx->vpp_cfg.enable_nr &&
 		(ctx->output_pix_fmt == V4L2_PIX_FMT_HEVC)) {
-		if (is_over_size(width, height, size)) {
+		if (!is_di_support(width, height)) {
 			return false;
 		}
 	}
 
 	if ((ctx->output_pix_fmt == V4L2_PIX_FMT_H264) &&
 		(ctx->picinfo.field != V4L2_FIELD_NONE)) {
-		if (is_over_size(width, height, size)) {
+		if (!is_di_support(width, height)) {
 			return false;
 		}
 	}
@@ -402,6 +525,12 @@
 			*mode = VPP_MODE_DI;
 	}
 
+	if (!disable_vpp_dw_mmu &&
+		(ctx->config.parm.dec.cfg.double_write_mode & VDEC_MODE_MMU_DW_MASK) &&
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4 ||
+		get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4D)) {
+		*mode = VPP_MODE_S4_DW_MMU;
+	}
 #if 0//enable later
 	if (ctx->colorspace != V4L2_COLORSPACE_DEFAULT &&
 		!is_over_size(width, height, size)) {
@@ -426,12 +555,16 @@
 	if (bypass_ge2d)
 		return false;
 
-	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
+	if (ctx->ge2d_cfg.bypass)
+		return false;
+
+	if (is_cpu_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)) {
+			(ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) &&
+			(ctx->output_pix_fmt != V4L2_PIX_FMT_AVS)) {
 			return false;
 		}
 	} else if (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) {
@@ -442,16 +575,7 @@
 		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;
+	*mode = GE2D_MODE_CONVERT_LE;
 
 	return true;
 }
@@ -504,9 +628,25 @@
 	ctx->vpp_size = vpp->buf_size;
 	ctx->ge2d_size = ge2d->buf_size;
 
+	if (ctx->enable_di_post &&
+		ctx->picinfo.field != V4L2_FIELD_NONE &&
+		is_vdec_core_fmt(ctx))
+		ctx->dpb_size *= PAIR_DONE;
+
+	if (ctx->enable_di_post && (is_vdec_core_fmt(ctx)) &&
+		ctx->dpb_size > 2 * V4L_CAP_BUFF_MAX) {
+		ctx->dpb_size = ctx->dpb_size / PAIR_DONE * 2;
+	}
+
 	total_size = ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size;
 
-	if (total_size > V4L_CAP_BUFF_MAX) {
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+		"dpb_size: %d dpb_frames: %d dpb_margin: %d vpp_size: %d ge2d_size: %d\n",
+			ctx->dpb_size, picinfo->dpb_frames, picinfo->dpb_margin,
+			ctx->vpp_size, ctx->ge2d_size);
+
+	if ((total_size > V4L_CAP_BUFF_MAX) &&
+		!(ctx->enable_di_post && ctx->picinfo.field != V4L2_FIELD_NONE)) {
 		if (ctx->ge2d_size) {
 			ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->ge2d_size - ctx->vpp_size;
 		} else if (ctx->vpp_size) {
@@ -522,18 +662,68 @@
 	return total_size;
 }
 
+static void aml_buf_configure_update(struct aml_vcodec_ctx *ctx)
+{
+	struct aml_buf_config config = {0};
+	struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
+	u32 dw = DM_YUV_ONLY;
+	u32 tw = DM_INVALID;
+
+	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+		return;
+
+	}
+	if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+		return;
+
+	}
+
+	config.enable_extbuf	= true;
+	config.enable_fbc	= ((dw != DM_YUV_ONLY) || tw) ? true : false;
+	config.enable_secure	= ctx->is_drm_mode;
+	config.memory_mode	= que->memory;
+	config.planes		= V4L2_TYPE_IS_MULTIPLANAR(que->type) ? 2 : 1;
+	config.luma_length	= ctx->picinfo.y_len_sz;
+	config.chroma_length	= ctx->picinfo.c_len_sz;
+	config.luma_length_tw	= ctx->picinfo.y_len_sz_tw;
+	config.chroma_length_tw	= ctx->picinfo.c_len_sz_tw;
+	config.dw_mode		= dw;
+	config.tw_mode		= tw;
+
+	aml_buf_configure(&ctx->bm, &config);
+}
+
 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)) {
+	struct aml_buf_config config;
+	struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
+	u32 dw = DM_YUV_ONLY;
+	u32 tw = DM_INVALID;
+
+	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"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) {
+	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+		return;
+
+	}
+
+	if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+		return;
+
+	}
+
+	if (ctx->picinfo.visible_width == 0 ||
+		ctx->picinfo.visible_height == 0 ||
+		ctx->picinfo.coded_width == 0 ||
+		ctx->picinfo.coded_height == 0) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"Cannot get correct pic info\n");
 		return;
@@ -545,19 +735,34 @@
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 		"new(%d,%d), old(%d,%d), real(%d,%d)\n",
+			ctx->picinfo.visible_width,
+			ctx->picinfo.visible_height,
 			ctx->last_decoded_picinfo.visible_width,
 			ctx->last_decoded_picinfo.visible_height,
-			ctx->picinfo.visible_width, ctx->picinfo.visible_height,
-			ctx->last_decoded_picinfo.coded_width,
-			ctx->last_decoded_picinfo.coded_width);
-
-	ctx->picinfo = ctx->last_decoded_picinfo;
+			ctx->picinfo.coded_width,
+			ctx->picinfo.coded_width);
 
 	if (ctx->vpp_is_need)
 		ctx->vpp_cfg.is_vpp_reset = true;
 
 	v4l_buf_size_decision(ctx);
 
+	config.enable_extbuf	= true;
+	config.enable_fbc	= ((dw != DM_YUV_ONLY) || tw) ? true : false;
+	config.enable_secure	= ctx->is_drm_mode;
+	config.memory_mode	= que->memory;
+	config.planes		= V4L2_TYPE_IS_MULTIPLANAR(que->type) ? 2 : 1;
+	config.luma_length	= ctx->picinfo.y_len_sz;
+	config.chroma_length	= ctx->picinfo.c_len_sz;
+	config.luma_length_tw	= ctx->picinfo.y_len_sz_tw;
+	config.chroma_length_tw	= ctx->picinfo.c_len_sz_tw;
+	config.dw_mode			= dw;
+	config.tw_mode			= tw;
+
+	aml_buf_configure(&ctx->bm, &config);
+
+	aml_buf_put_dma(&ctx->bm);
+
 	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,
@@ -571,7 +776,7 @@
 		(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_v4l2_buf *vb = (struct aml_v4l2_buf *)
 		priv_data->vb_handle;
 	struct uvm_hook_mod_info *uvm = NULL;
 
@@ -584,6 +789,20 @@
 	kfree(data);
 }
 
+void aml_clean_proxy_uvm(struct aml_vcodec_ctx *ctx)
+{
+	struct uvm_hook_mod_info *uvm = NULL;
+	int i;
+
+	for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+		if (ctx && ctx->uvm_proxy) {
+			uvm = &ctx->uvm_proxy[i];
+			if (uvm->free)
+				uvm->free(uvm->arg);
+		}
+	}
+}
+
 static void v4l2_buff_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
 {
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(buf->vb2_buf.vb2_queue);
@@ -606,209 +825,209 @@
 	dmabuf_set_vframe(vb->planes[0].dbuf, vf, VF_SRC_DECODER);
 }
 
-static void fb_map_table_clean(struct aml_vcodec_ctx *ctx)
+void fbc_transcode_and_set_vf(struct aml_vcodec_ctx *ctx,
+						  struct aml_buf *aml_buf,
+						  struct vframe_s *vf)
 {
-	int i;
-	ulong flags;
+	struct vb2_buffer *vb2_buf = aml_buf->vb;
+	struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
+	struct aml_v4l2_buf *dstbuf =
+		container_of(vb, struct aml_v4l2_buf, vb);
 
-	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 (is_cpu_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 (aml_buf->state == 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;
 	}
+	if (!ctx->enable_di_post) {
+		vf->index_disp = ctx->index_disp;
+		vf->omx_index = vf->index_disp;
 
-	aml_vcodec_ctx_unlock(ctx, flags);
+		if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
+			struct dma_buf * dma;
 
-	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;
+			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);
+			}
 		}
 	}
-
-	aml_vcodec_ctx_unlock(ctx, flags);
-
-	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);
-	}
 }
 
-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)
+ssize_t dump_cma_and_sys_memsize(struct aml_vcodec_ctx *ctx, char *buf)
 {
-	int i;
-	ulong addr, flags;
+	struct cma_sys_size_info *info = &ctx->mem_size_info;
+	int cma_size = codec_mm_alloc_cma_size();
+	int sys_size = codec_mm_alloc_sys_size();
+	int total_size = cma_size + sys_size;
+	char *pbuf = buf;
 
-	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;
-		}
+	if (total_size > info->max_total_size) {
+		info->max_total_size = total_size;
+		info->cma_part = cma_size;
+		info->sys_part = sys_size;
 	}
 
-	aml_vcodec_ctx_unlock(ctx, flags);
+	info->max_cma_size = cma_size > info->max_cma_size ?
+	cma_size : info->max_cma_size;
 
-	if (i >= ARRAY_SIZE(ctx->fb_map)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-			"%s, there is new addr:%lx.\n",
-			__func__, addr);
-	}
-}
+	info->max_sys_size = sys_size > info->max_sys_size ?
+	sys_size : info->max_sys_size;
 
-static bool is_fb_mapped(struct aml_vcodec_ctx *ctx, ulong addr)
-{
-	int i;
-	ulong flags;
+	info->cur_cma_size = cma_size;
+	info->cur_sys_size = sys_size;
 
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
-		if (addr == ctx->fb_map[i].addr)
-			break;
+	if (pbuf) {
+		pbuf += sprintf(pbuf, "TOTAL[Max:%dM(CMA:%dM, SYS:%dM), CUR:%dM], "
+			"CMA[%dM, Max:%dM], SYS[%dM, Max:%dM]\n",
+			info->max_total_size, info->cma_part,
+			info->sys_part, total_size,
+			info->cur_cma_size, info->max_cma_size,
+			info->cur_sys_size, info->max_sys_size);
+	} else {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_COUNT,
+			"TOTAL[Max:%dM(CMA:%dM, SYS:%dM), CUR:%dM], "
+			"CMA[%dM, Max:%dM], SYS[%dM, Max:%dM]\n",
+			info->max_total_size, info->cma_part,
+			info->sys_part, total_size,
+			info->cur_cma_size, info->max_cma_size,
+			info->cur_sys_size, info->max_sys_size);
 	}
 
-	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 true;
+	return pbuf - buf;
 }
 
  static void post_frame_to_upper(struct aml_vcodec_ctx *ctx,
-	struct vdec_v4l2_buffer *fb)
+	struct aml_buf *aml_buf)
 {
-	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;
+	struct vb2_buffer *vb2_buf = aml_buf->vb;
+	struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
+	struct aml_v4l2_buf *dstbuf =
+		container_of(vb, struct aml_v4l2_buf, vb);
+	struct vframe_s *vf = &aml_buf->vframe;
+	struct aml_vdec_cfg_infos *cfg = &ctx->config.parm.dec.cfg;
+	struct aml_buf_plane *planes = aml_buf->planes; // DW def.
 
-	vf->index_disp = ctx->index_disp;
-	ctx->index_disp++;
+	dump_cma_and_sys_memsize(ctx, NULL);
+
+	if (!ctx->enable_di_post) {
+		vf->index_disp = ctx->index_disp;
+		if ((vf->type & VIDTYPE_V4L_EOS) == 0)
+			ctx->index_disp++;
+	}
+
 	ctx->post_to_upper_done = false;
 
+	if ((cfg->double_write_mode == DM_AVBC_ONLY) ||
+		(ctx->force_tw_output && cfg->triple_write_mode)) {
+		if (aml_buf->planes_tw[0].bytes_used)
+			planes = aml_buf->planes_tw;
+	}
+
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
-		"OUT_BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+		"OUT_BUFF (%s, st:%d, seq:%d, idx:%d) vb:(%d, %px), vf:(%d, %px), ts:%llu, flag: 0x%x "
 		"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
-		ctx->ada_ctx->frm_name, fb->status, vf->index_disp,
+		ctx->ada_ctx->frm_name, aml_buf->state, ctx->out_buff_cnt, aml_buf->index,
 		vb2_buf->index, vb2_buf,
 		vf->index & 0xff, vf,
 		vf->timestamp,
-		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);
+		vf->flag,
+		planes[0].addr, planes[0].length,
+		planes[1].addr, planes[1].length,
+		planes[2].addr, planes[2].length);
+	ctx->out_buff_cnt++;
 
-	vb2_v4l2 = container_of(vb2_buf, struct vb2_v4l2_buffer, vb2_buf);
-
-	if (dstbuf->frame_buffer.num_planes == 1) {
-		vb2_set_plane_payload(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);
+	if (dstbuf->aml_buf->num_planes == 1) {
+		vb2_set_plane_payload(vb2_buf, 0, planes[0].bytes_used);
+	} else if (dstbuf->aml_buf->num_planes == 2) {
+		vb2_set_plane_payload(vb2_buf, 0, planes[0].bytes_used);
+		vb2_set_plane_payload(vb2_buf, 1, planes[1].bytes_used);
 	}
+
 	vb2_buf->timestamp = vf->timestamp;
 	dstbuf->vb.flags |= vf->frame_type;
 
 	if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) {
-		vb2_v4l2->field = V4L2_FIELD_INTERLACED;
+		vb->field = V4L2_FIELD_INTERLACED;
 	}
 
 	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
+		u32 dw_mode = DM_YUV_ONLY;
+		u32 tw_mode = DM_INVALID;
 		struct file *fp;
-		char file_name[32] = {0};
+		char file_name[64] = {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)
+
+		if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
 			break;
 
-		snprintf(file_name, 32, "/data/dec_dump_%ux%u.raw", vf->width, vf->height);
+		if ((dw_mode == DM_AVBC_ONLY) && (tw_mode == DM_INVALID))
+			break;
 
-		fp = filp_open(file_name,
-				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+		snprintf(file_name, 64, "%s/dec_dump_%ux%u.raw", dump_path, vf->width, vf->height);
+
+		fp = media_open(file_name,
+				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0666);
 
 		if (!IS_ERR(fp)) {
 			struct vb2_buffer *vb = vb2_buf;
+			// dump y data
+			u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+				vf->width, vf->height, 64);
+			// dump uv data
+			if (vb->num_planes == 1) {
+				aml_yuv_dump(fp, yuv_data_addr, vf->width,
+					vf->height / 2, 64);
+			} else {
+				aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+					vf->width, vf->height / 2, 64);
+			}
 
-			kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
-			if (dstbuf->frame_buffer.num_planes == 2)
-				kernel_write(fp,vb2_plane_vaddr(vb, 1),
-						vb->planes[1].length, 0);
 			pr_info("dump idx: %d %dx%d\n", dump_capture_frame, vf->width, vf->height);
 			dump_capture_frame--;
-			filp_close(fp, NULL);
+			media_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));
+
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_6, vb2_buf->index);
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_1, vdec_frame_number(ctx->ada_ctx));
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_10,
+			CTX_BUF_TOTAL(ctx) + ctx->out_buff_cnt - ctx->in_buff_cnt);
 
 	if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
 		dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
-		if (dstbuf->frame_buffer.num_planes == 1) {
+		if (dstbuf->aml_buf->num_planes == 1) {
 			vb2_set_plane_payload(vb2_buf, 0, 0);
-		} else if (dstbuf->frame_buffer.num_planes == 2) {
+		} else if (dstbuf->aml_buf->num_planes == 2) {
 			vb2_set_plane_payload(vb2_buf, 0, 0);
 			vb2_set_plane_payload(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",
+			"receive a empty frame. idx: %d, state: %d\n",
 			vb2_buf->index, vb2_buf->state);
 	}
 
@@ -818,11 +1037,10 @@
 
 	if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
 		if (ctx->v4l_resolution_change) {
-			/* make the run to stanby until new buffs to enque. */
-			ctx->v4l_codec_dpb_ready = false;
+			/* make the run to stanby until new buffs to enqueue. */
 			ctx->reset_flag = V4L_RESET_MODE_LIGHT;
 			ctx->vpp_cfg.res_chg = true;
-
+			ctx->last_decoded_picinfo = ctx->picinfo;
 			/*
 			 * After all buffers containing decoded frames from
 			 * before the resolution change point ready to be
@@ -837,54 +1055,26 @@
 	}
 
 	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;
+		if (!ctx->no_fbc_output &&
+			!(vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L)) {
+			ctx->fbc_transcode_and_set_vf(ctx, aml_buf, vf);
 		}
 
-		vf->omx_index = vf->index_disp;
 		dstbuf->privdata.vf = *vf;
 
-		if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
-			struct dma_buf * dma;
+		if (vf->frame_type & V4L2_BUF_FLAG_ERROR)
+			v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_ERROR);
+		else
+			v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
 
-			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;
+		aml_buf->state = FB_ST_DISPLAY;
 	}
 
 	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);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_FLUSHED)\n");
 	}
@@ -902,174 +1092,31 @@
 {
 	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;
-
+	struct aml_buf *aml_buf = (struct aml_buf *)fb_ctx;
+	struct vb2_buffer *vb2_buf = aml_buf->vb;
+	struct vb2_v4l2_buffer *vb = to_vb2_v4l2_buffer(vb2_buf);
 	if (ctx->is_stream_off) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
-			"ignore buff idx: %d streamoff\n", fb->buf_idx);
+			"ignore buff idx: %d streamoff\n", aml_buf->index);
 		return;
 	}
 
-	ATRACE_COUNTER("VC_OUT_VSINK-0.receive", vb->vb2_buf.index);
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_5, 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)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s, table is full. token:%lx\n",
-			__func__, vb_handle);
-		return false;
-	}
-
-	*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)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s, remove token err, token:%lx.\n",
-			__func__, token);
-	}
-}
-
-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);
-	}
+	aml_buf_update_holder(&ctx->bm, aml_buf, BUF_USER_VSINK, BUF_GET);
 }
 
 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)
+void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
+		       struct aml_buf *aml_buf,
+		       u32 requester)
 {
-	struct task_chain_s *task = fb->task;
+	struct task_chain_s *task = aml_buf->task;
 	/*
 	 * line 1: dec <==> vpp <==> v4l-sink, for P / P + DI.NR.
 	 * line 2: dec <==> vpp, vpp <==> v4l-sink, for I / I + DI.NR.
@@ -1129,71 +1176,33 @@
 			"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)
+void cal_compress_buff_info(ulong used_page_num, struct aml_vcodec_ctx *ctx)
 {
-	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;
+	struct v4l_compressed_buffer_info *buf_info = &ctx->compressed_buf_info;
+	u32 total_buffer_num = ctx->dpb_size;
+	u32 cur_index = buf_info->recycle_num % total_buffer_num;
+	u32 cur_avg_val_by_group;
 
-	flags = aml_vcodec_ctx_lock(ctx);
+	if (!(debug_mode & V4L_DEBUG_CODEC_COUNT))
+		return;
 
-	if (ctx->is_stream_off) {
-		aml_vcodec_ctx_unlock(ctx, flags);
-		return -1;
-	}
+	mutex_lock(&ctx->compressed_buf_info_lock);
+	buf_info->used_page_sum += used_page_num;
+	buf_info->used_page_distributed_array[(u32)used_page_num / PAGE_NUM_ONE_MB]++;
 
-	v4l_buf = (struct vb2_v4l2_buffer *) token;
-	if (!v4l_buf) {
-		aml_vcodec_ctx_unlock(ctx, flags);
-		return -1;
-	}
+	buf_info->used_page_by_group = buf_info->used_page_by_group -
+		buf_info->used_page_in_group[cur_index] + used_page_num;
+	buf_info->used_page_in_group[cur_index] = used_page_num;
+	cur_avg_val_by_group = buf_info->used_page_by_group / total_buffer_num;
+	if (cur_avg_val_by_group > buf_info->max_avg_val_by_group)
+		buf_info->max_avg_val_by_group = cur_avg_val_by_group;
 
-	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);
-
+	buf_info->recycle_num++;
 	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;
+		"4k_used_num %ld used_page_sum %llu used_page_by_group %u max_avg_val %u cur_avg_val %u buffer_num %d recycle_num %u\n",
+		used_page_num, buf_info->used_page_sum, buf_info->used_page_by_group,
+			buf_info->max_avg_val_by_group, cur_avg_val_by_group, total_buffer_num, buf_info->recycle_num);
+	mutex_unlock(&ctx->compressed_buf_info_lock);
 }
 
 static struct task_ops_s v4l_sink_ops = {
@@ -1206,59 +1215,62 @@
 	return &v4l_sink_ops;
 }
 
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx)
+ssize_t aml_vdec_basic_information(struct aml_vcodec_ctx *ctx, char *buf)
 {
 	struct aml_q_data *outq = NULL;
 	struct aml_q_data *capq = NULL;
 	struct vdec_pic_info pic;
+	u32 dw_mode = -1;
+	u32 tw_mode = -1;
+	char *pbuf = buf;
 
 	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &pic)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"get pic info err\n");
-		return;
+		return 0;
 	}
 
+	vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode);
+	vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode);
+
 	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",
+	pbuf += sprintf(pbuf, "\n==== Show Basic Information ==== \n");
+	pbuf += sprintf(pbuf, "Format     : %s\n", outq->fmt->name);
+	pbuf += sprintf(pbuf, "Color space: %s\n", capq->fmt->name);
+	pbuf += sprintf(pbuf, "Scan type  : %s\n",
+		(pic.field == V4L2_FIELD_NONE) ? "Progressive" : "Interlaced");
+	pbuf += sprintf(pbuf, "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",
+	pbuf += sprintf(pbuf, "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,
+
+	pbuf += sprintf(pbuf, "Config     : DW/TW:(0x%x, 0x%x), drm:%d, byp:%d, lc:%d, nr:%d, ge2d:%x\n",
+		dw_mode,
+		tw_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);
+	pbuf += sprintf(pbuf, "write frames : %d, out_buff : %d in_buff : %d\n",
+		ctx->write_frames, ctx->out_buff_cnt, ctx->in_buff_cnt);
+
+	return pbuf - buf;
 }
 
-void aml_buffer_status(struct aml_vcodec_ctx *ctx)
+ssize_t aml_buffer_status(struct aml_vcodec_ctx *ctx, char *buf)
 {
 	struct vb2_v4l2_buffer *vb = NULL;
-	struct aml_video_dec_buf *aml_buff = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
+	struct aml_v4l2_buf *aml_buff = NULL;
+	struct aml_buf *aml_buf = NULL;
 	struct vb2_queue *q = NULL;
 	ulong flags;
 	int i;
+	char *pbuf = buf;
 
 	flags = aml_vcodec_ctx_lock(ctx);
 
@@ -1267,35 +1279,86 @@
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"can't achieve buffers status before start streaming.\n");
 	}
+	if (!ctx->enable_di_post) {
+		pbuf += sprintf(pbuf, "\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_v4l2_buf, vb);
+			aml_buf = aml_buff->aml_buf;
 
-	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);
+			/* print out task chain status. */
+			if (aml_buf)
+				pbuf += task_chain_show(aml_buf->task, pbuf);
+		}
 	}
 
 	aml_vcodec_ctx_unlock(ctx, flags);
+
+	pbuf += sprintf(pbuf, "\n==== Show Buffer Status ======== \n");
+	pbuf += buf_core_walk(&ctx->bm.bc, pbuf);
+
+	return pbuf - buf;
 }
 
-static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
+void aml_compressed_info_show(struct aml_vcodec_ctx *ctx)
 {
-	if (!ctx->v4l_codec_dpb_ready) {
-		/*
-		 * make sure enough dst bufs for decoding.
-		 */
-		if ((ctx->dpb_size) && (ctx->cap_pool.in >= ctx->dpb_size))
-			ctx->v4l_codec_dpb_ready = true;
+	struct aml_q_data *outq = NULL;
+	struct vdec_pic_info pic;
+	int i;
+	u32 aerage_mem_size;
+	u32 max_avg_val_by_proup;
+	struct v4l_compressed_buffer_info *buffer = &ctx->compressed_buf_info;
+	u64 used_page_sum = buffer->used_page_sum;
 
-		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),
-			ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no");
+	if (!(debug_mode & V4L_DEBUG_CODEC_COUNT))
+		return;
+
+	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);
+
+	pr_info("==== Show mmu buffer info ======== \n");
+	if (buffer->recycle_num == 0) {
+		pr_info("No valid info \n");
+		return;
+	}
+	mutex_lock(&ctx->compressed_buf_info_lock);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		"Fmt:%s, DW/TW:(%x, %x), Res:%dx%d, DPB:%d\n",
+		outq->fmt->name,
+		ctx->config.parm.dec.cfg.double_write_mode,
+		ctx->config.parm.dec.cfg.triple_write_mode,
+		pic.visible_width,
+		pic.visible_height,
+		ctx->dpb_size);
+
+	do_div(used_page_sum, buffer->recycle_num);
+	aerage_mem_size = ((u32)used_page_sum * 100) / PAGE_NUM_ONE_MB;
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		"mmu mem recycle num: %u, average used mmu mem %u.%u%u(MB)\n",
+		buffer->recycle_num, aerage_mem_size / 100, (aerage_mem_size % 100) / 10, aerage_mem_size % 10);
+
+	max_avg_val_by_proup = buffer->max_avg_val_by_group * 100 / PAGE_NUM_ONE_MB;
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		"%d buffer in group, max avg used mem by group %u.%u%u(MB)\n", ctx->dpb_size,
+		max_avg_val_by_proup / 100, (max_avg_val_by_proup % 100) / 10, max_avg_val_by_proup % 10);
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,"mmu mem used distribution ratio\n");
+
+	for (i = 0; i < MAX_AVBC_BUFFER_SIZE; i++) {
+		u32 count = buffer->used_page_distributed_array[i];
+		//if (count)
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+				"range %d [%dMB ~ %dMB] distribution num %d ratio %u%%\n",
+				i, i, i+1, count, (count * 100) / buffer->recycle_num);
+	}
+
+	mutex_unlock(&ctx->compressed_buf_info_lock);
+	pr_info("==== End Show mmu buffer info ========");
 }
 
 static void reconfig_vpp_status(struct aml_vcodec_ctx *ctx)
@@ -1313,12 +1376,9 @@
 
 static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
 {
-	struct aml_vcodec_dev *dev = ctx->dev;
-
 	if (!is_input_ready(ctx->ada_ctx)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"the decoder input has not ready.\n");
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 		return 0;
 	}
 
@@ -1326,7 +1386,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);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_READY)\n");
 		}
@@ -1338,89 +1398,38 @@
 		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);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_ACTIVE)\n");
 		}
 	}
 	mutex_unlock(&ctx->state_lock);
 
-	/* check dpb ready */
-	//aml_check_dpb_ready(ctx);
-
 	return 1;
 }
 
-static bool is_enough_work_items(struct aml_vcodec_ctx *ctx)
-{
-	struct aml_vcodec_dev *dev = ctx->dev;
-
-	if (vdec_frame_number(ctx->ada_ctx) >= WORK_ITEMS_MAX) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		return false;
-	}
-
-	return true;
-}
-
-static void aml_wait_buf_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)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"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_BUF_TOTAL(ctx))
-			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);
+		container_of(work, struct aml_vcodec_ctx, es_wkr_out);
 	struct vb2_v4l2_buffer *vb = NULL;
-	struct aml_video_dec_buf *buf = NULL;
-	unsigned long flags;
+	struct aml_v4l2_buf *buf = NULL;
 
-	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);
+	if (ctx->es_wkr_stop ||
+		!kfifo_get(&ctx->dmabuff_recycle, &vb))
+		return;
 
-		buf = container_of(vb, struct aml_video_dec_buf, vb);
+	buf = container_of(vb, struct aml_v4l2_buf, vb);
 
-		if (ctx->is_out_stream_off)
-			continue;
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
+		"recycle buff idx: %d, vbuf: %lx\n", vb->vb2_buf.index,
+		buf->addr ? buf->addr: (ulong)sg_dma_address(buf->out_sgt->sgl));
 
-		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");
-		}
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_9, vb->vb2_buf.index);
 
-		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);
-	}
+	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)
@@ -1429,44 +1438,51 @@
 	struct vb2_v4l2_buffer *vb = NULL;
 	struct vb2_queue *q = NULL;
 	int index = handle & 0xf;
-	unsigned long flags;
+	ulong flags;
 
-	if (ctx->is_out_stream_off) {
+retry:
+	spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+
+	if (ctx->es_wkr_stop) {
+		spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
 			"ignore buff idx: %d streamoff\n", index);
 		return;
 	}
 
+	if (work_pending(&ctx->es_wkr_out)) {
+		spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
+		flush_work(&ctx->es_wkr_out);
+
+		goto retry;
+	}
+
 	q = v4l2_m2m_get_vq(ctx->m2m_ctx,
 		V4L2_BUF_TYPE_VIDEO_OUTPUT);
 
 	vb = to_vb2_v4l2_buffer(q->bufs[index]);
 
-	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);
+	queue_work(dev->decode_workqueue, &ctx->es_wkr_out);
+
+	spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
 }
 
 static void aml_vdec_worker(struct work_struct *work)
 {
 	struct aml_vcodec_ctx *ctx =
-		container_of(work, struct aml_vcodec_ctx, decode_work);
+		container_of(work, struct aml_vcodec_ctx, es_wkr_in);
 	struct aml_vcodec_dev *dev = ctx->dev;
-	struct aml_video_dec_buf *aml_buf;
+	struct aml_v4l2_buf *aml_vb;
 	struct vb2_v4l2_buffer *vb2_v4l2;
 	struct vb2_buffer *vb;
 	struct aml_vcodec_mem buf;
 	bool res_chg = false;
 	int ret;
 
-	if (ctx->state < AML_STATE_INIT ||
-		ctx->state > AML_STATE_FLUSHED) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		goto out;
-	}
-
 	if (!is_vdec_ready(ctx)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"the decoder has not ready.\n");
@@ -1482,50 +1498,21 @@
 
 	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;
-
-		/*the empty data use to flushed the decoder.*/
+	aml_vb = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+	if (aml_vb->lastframe) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"Got empty flush input buffer.\n");
 
-		/*
-		 * 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);
-		}
-
 		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);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, 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);
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 
 		/* sets eos data for vdec input. */
 		aml_vdec_flush_decoder(ctx);
@@ -1533,23 +1520,35 @@
 		goto out;
 	}
 
+	if (ctx->stream_mode &&
+		!(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+		struct dmabuf_dmx_sec_es_data *es_data = (struct dmabuf_dmx_sec_es_data *)aml_vb->dma_buf;
+		int offset = vb->planes[0].data_offset;
+		buf.addr = es_data->data_start + offset;
+		buf.size = vb->planes[0].bytesused - offset;
+		buf.dbuf = vb->planes[0].dbuf;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, "stream update wp 0x%lx + sz 0x%x offset 0x%x ori start 0x%x ts %llu\n",
+			buf.addr, buf.size, offset, es_data->data_start, vb->timestamp);
+	} else {
+		buf.addr	= aml_vb->addr ? aml_vb->addr : sg_dma_address(aml_vb->out_sgt->sgl);
+		buf.size	= vb->planes[0].bytesused;
+	}
 	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;
+	if (!ctx->is_drm_mode)
+		buf.vaddr = vb2_plane_vaddr(vb, 0);
+
 	buf.model	= vb->memory;
-	buf.timestamp	= vb->timestamp;
-	buf.meta_ptr	= (ulong)aml_buf->meta_data;
+	buf.timestamp = vb->timestamp;
+	buf.meta_ptr	= (ulong)aml_vb->meta_data;
 
 	if (!buf.vaddr && !buf.addr) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"id=%d src_addr is NULL.\n", vb->index);
 		goto out;
 	}
 
-	aml_buf->used = true;
-
 	/* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 		"size: 0x%zx, crc: 0x%x\n",
 		buf.size, crc32(0, buf.va, buf.size));*/
@@ -1558,86 +1557,42 @@
 	/*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);
+	if ((!ctx->stream_mode) && ctx->output_dma_mode) {
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_3, buf.size);
 	} else {
-		ATRACE_COUNTER("VO_IN_VSINK-2.write", buf.size);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_2, buf.size);
 	}
 
-	ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_1, 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,
+		/* frame mode and non-dbuf mode. */
+		if (ctx->stream_mode || !ctx->output_dma_mode) {
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_8, buf.size);
+			v4l2_buff_done(&aml_vb->vb,
 				VB2_BUF_STATE_DONE);
 		}
 	} else if (ret && ret != -EAGAIN) {
-		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-3.write_error", buf.size);
-			v4l2_buff_done(&aml_buf->vb,
+		/* frame mode and non-dbuf mode. */
+		if (ctx->stream_mode || !ctx->output_dma_mode) {
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_10, buf.size);
+			v4l2_buff_done(&aml_vb->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_buf->used = false;
-		aml_vdec_pic_info_update(ctx);
-		/*
-		 * On encountering a resolution change in the stream.
-		 * The driver must first process and decode all
-		 * remaining buffers from before the resolution change
-		 * point, so call flush decode here
-		 */
-		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);
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
-				"vcodec state (AML_STATE_FLUSHING-RESCHG)\n");
-		}
-		mutex_unlock(&ctx->state_lock);
-
-		ctx->v4l_resolution_change = true;
-		while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
-			v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
-		}
-
-		aml_vdec_flush_decoder(ctx);
-
-		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);
+		/* ES frame write again. */
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_11, buf.size);
 	}
-
-	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 out:
-	return;
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
 static void aml_vdec_reset(struct aml_vcodec_ctx *ctx)
@@ -1648,15 +1603,29 @@
 		goto out;
 	}
 
+	aml_codec_disconnect(ctx->ada_ctx);
+
 	if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) {
 		ctx->state = AML_STATE_ABORT;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_ABORT).\n");
 	}
 out:
 	complete(&ctx->comp);
-	return;
+}
+
+void stop_pipeline(struct aml_vcodec_ctx *ctx)
+{
+	if (ctx->ge2d) {
+		aml_v4l2_ge2d_thread_stop(ctx->ge2d);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "ge2d stop.\n");
+	}
+
+	if (ctx->vpp) {
+		aml_v4l2_vpp_thread_stop(ctx->vpp);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "vpp stop\n");
+	}
 }
 
 void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
@@ -1666,26 +1635,21 @@
 	ctx->is_stream_off = true;
 
 	/* flush output buffer worker. */
-	cancel_work_sync(&ctx->decode_work);
-	cancel_work_sync(&ctx->dmabuff_recycle_work);
+	cancel_work_sync(&ctx->es_wkr_in);
+	cancel_work_sync(&ctx->es_wkr_out);
 
 	/* clean output cache and decoder status . */
 	if (ctx->state > AML_STATE_INIT)
 		aml_vdec_reset(ctx);
 
-	/* pause the job and clean trans status. */
-	while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
-		v4l2_m2m_job_pause(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
-	}
-
-	ctx->v4l_codec_dpb_ready = false;
+	stop_pipeline(ctx);
 }
 
 void aml_thread_capture_worker(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 aml_v4l2_buf *aml_buff = NULL;
+	struct aml_buf *aml_buf = NULL;
 
 	for (;;) {
 		mutex_lock(&ctx->capture_buffer_lock);
@@ -1695,13 +1659,13 @@
 		}
 		mutex_unlock(&ctx->capture_buffer_lock);
 
-		aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
-		fb = &aml_buff->frame_buffer;
+		aml_buff = container_of(vb, struct aml_v4l2_buf, vb);
+		aml_buf = aml_buff->aml_buf;
 
 		if (ctx->is_stream_off)
 			continue;
 
-		post_frame_to_upper(ctx, fb);
+		post_frame_to_upper(ctx, aml_buf);
 	}
 }
 EXPORT_SYMBOL_GPL(aml_thread_capture_worker);
@@ -1870,13 +1834,15 @@
 			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;
+		if ((vdec_frame_number(ctx->ada_ctx) <= 0) && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) == 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 */
@@ -1884,7 +1850,7 @@
 		v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
 		ctx->receive_cmd_stop = true;
 
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"%s, receive cmd stop and prepare flush pipeline.\n", __func__);
 		break;
 
@@ -1894,7 +1860,7 @@
 			V4L2_BUF_TYPE_VIDEO_CAPTURE);
 		vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
 
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"%s, receive cmd start.\n", __func__);
 		break;
 
@@ -1905,6 +1871,272 @@
 	return 0;
 }
 
+ulong get_addr(struct vb2_buffer *vb, int i)
+{
+	struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
+		struct vb2_v4l2_buffer, vb2_buf);
+	struct aml_v4l2_buf *buf = container_of(vb2_v4l2,
+		struct aml_v4l2_buf, vb);
+	struct aml_buf *am_buf = buf->aml_buf;
+
+	return am_buf->is_delay_allocated ?
+		sg_dma_address(am_buf->cap_sgt->sgl) :
+		vb2_dma_contig_plane_dma_addr(vb, i);
+}
+
+static void aml_uvm_buf_delay_free(struct uvm_buf_obj *obj)
+{
+	struct mua_buffer *mbuf;
+	struct aml_vcodec_ctx *ctx = obj->arg;
+
+	mbuf = container_of(obj, struct mua_buffer, base);
+	if (!mbuf)
+		return;
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s ion buffer:%px/%px, dbuf:%px/%px\n",
+		__func__, mbuf->ibuffer[0], mbuf->ibuffer[1],
+		mbuf->idmabuf[0], mbuf->idmabuf[1]);
+
+	if (mbuf->idmabuf[0]) {
+		dma_buf_put(mbuf->idmabuf[0]);
+	}
+	if (mbuf->idmabuf[1]) {
+		dma_buf_put(mbuf->idmabuf[1]);
+	}
+
+	kfree(mbuf);
+}
+
+static void aml_uvm_copy_sgt(struct sg_table *dst_table,
+			     struct sg_table *src_table)
+{
+	struct scatterlist *dst_sgl = NULL;
+	struct scatterlist *src_sgl = NULL;
+	int i;
+
+	dst_table->nents = src_table->nents;
+	dst_table->orig_nents = src_table->orig_nents;
+
+	dst_sgl = dst_table->sgl;
+	src_sgl = src_table->sgl;
+
+	for (i = 0; i < src_table->nents; i++) {
+		sg_set_page(dst_sgl, sg_page(src_sgl), src_sgl->length, 0);
+		sg_dma_address(dst_sgl) = sg_phys(src_sgl);
+		sg_dma_len(dst_sgl) = sg_dma_len(src_sgl);
+		dst_sgl = sg_next(dst_sgl);
+		src_sgl = sg_next(src_sgl);
+	}
+}
+
+static int aml_uvm_buf_delay_alloc(struct aml_vcodec_ctx *ctx,
+				  struct vb2_v4l2_buffer *vb)
+{
+	struct aml_v4l2_buf *buf =
+		container_of(vb, struct aml_v4l2_buf, vb);
+	struct aml_buf *am_buf = buf->aml_buf;
+	struct dma_buf *dbuf = vb->vb2_buf.planes[0].dbuf;
+	struct device *dev = vb->vb2_buf.vb2_queue->alloc_devs[0];
+	struct uvm_handle *handle;
+	struct mua_buffer *mbuf = NULL;
+	struct dma_buf *idbuf = NULL;
+	struct uvm_alloc *ua = NULL;
+	struct uvm_buf_obj *obj = NULL;
+	/* ion heap*/
+	struct ion_buffer *ibuf = NULL;
+	struct page *page = NULL;
+
+	u64 time = local_clock();
+	struct sg_table *cap_sgt;
+	struct aml_uvm_buff_ref *ubuf = (struct aml_uvm_buff_ref *)am_buf->uvm_buf;
+	struct sg_table *sgt;
+	struct dma_buf_attachment *dba = NULL;
+
+	if (!ctx->enable_di_post || ctx->picinfo.field == V4L2_FIELD_NONE ||
+		!is_vdec_core_fmt(ctx))
+		return 0;
+
+	if ((vb->vb2_buf.memory != VB2_MEMORY_DMABUF) ||
+		!dbuf ||
+		!dmabuf_is_uvm(dbuf) ||
+		am_buf->is_delay_allocated)
+		return 0;
+
+	obj = dmabuf_get_uvm_buf_obj(dbuf);
+	mbuf = container_of(obj, struct mua_buffer, base);
+
+	/* free fake dma buffer. */
+	if (mbuf->idmabuf[0])
+		dma_buf_put(mbuf->idmabuf[0]);
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"dma buffer size(fake: %zu, real: %d)\n",
+				mbuf->size,
+				ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz);
+
+	mbuf->size =  ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
+
+	handle = dbuf->priv;
+
+	if (ctx->master_buf) {
+		struct aml_buf *master_buf = ctx->master_buf;
+
+		if (master_buf->pair_state == MASTER_DONE) {
+			master_buf->sub_buf[0] = (void *)am_buf;
+			am_buf->master_buf = (void *)master_buf;
+			am_buf->pair = BUF_SUB0;
+			aml_buf_put(&ctx->bm, am_buf);
+		}
+
+		if (master_buf->pair_state == SUB0_DONE) {
+			master_buf->sub_buf[1] = (void *)am_buf;
+			am_buf->master_buf = (void *)master_buf;
+			am_buf->pair = BUF_SUB1;
+			aml_buf_put(&ctx->bm, am_buf);
+		}
+
+		am_buf->is_delay_allocated = true;
+		master_buf->pair_state++;
+		if (master_buf->pair_state == PAIR_DONE)
+			ctx->master_buf = NULL;
+		else
+			aml_buf_get_ref(&ctx->bm, master_buf);
+		idbuf = master_buf->idmabuf[0];
+		sgt = master_buf->cap_sgt;
+		get_dma_buf(idbuf);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"[Paired]index(%d, %d), pair(%d), uvm dbuf: %px\n",
+				master_buf->index, am_buf->index, am_buf->pair,dbuf);
+	} else {
+		if (ctx->alloc_type) { /* ion */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
+			u32 flags = 0;
+
+			/* alloc real ion buffer relace older one. */
+			if (mbuf->ion_flags & MUA_USAGE_PROTECTED)
+				flags |= ION_FLAG_PROTECTED;
+
+			flags |= ION_FLAG_EXTEND_MESON_HEAP;
+
+			idbuf = ion_alloc(mbuf->size, (1 << ION_HEAP_TYPE_CUSTOM), flags);
+			if (IS_ERR(idbuf) || !idbuf->priv) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+					"%s: ion alloc fail.\n", __func__);
+				return -ENOMEM;
+			}
+#endif
+		} else {  /* dma heap */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+			char *name = CODECMM_HEAP_NAME;
+			struct dma_heap *heap;
+
+			/* alloc real dma buffer relace older one. */
+			if (mbuf->ion_flags & MUA_USAGE_PROTECTED)
+				name = CODECMM_SECURE_HEAP_NAME;
+			else if (mbuf->ion_flags & MUA_BUFFER_CACHED)
+				name = CODECMM_CACHED_HEAP_NAME;
+
+			heap = dma_heap_find(name);
+			if (!heap) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+					"%s: dma_heap_find fail. heap name is %s\n", __func__, name);
+				return -ENOMEM;
+			}
+			idbuf = dma_heap_buffer_alloc(heap, mbuf->size, O_RDWR,
+					DMA_HEAP_VALID_HEAP_FLAGS);
+
+			/* create attachment for the dmabuf with the user device */
+			dba = dma_buf_attach(idbuf, dev);
+			if (IS_ERR(dba)) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "failed to attach dmabuf\n");
+				return 0;
+			}
+
+			/* get the associated scatterlist for this buffer */
+			sgt = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
+			if (IS_ERR(sgt)) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Error getting dmabuf scatterlist\n");
+				return 0;
+			}
+#endif
+		}
+
+		ctx->master_buf = am_buf;
+		am_buf->pair_state++;
+		am_buf->pair = BUF_MASTER;
+		aml_buf_get_ref(&ctx->bm, am_buf);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"[Pairing]index(%d), pair(%d), uvm dbuf: %px\n",
+				am_buf->index, am_buf->pair, dbuf);
+	}
+
+	/* replace free cb. */
+	ua		= handle->ua;
+	ua->obj->arg	= ctx;
+	ua->obj->dev	= dev;
+	ua->free	= aml_uvm_buf_delay_free;
+
+	if (ctx->alloc_type) {
+		ibuf		= idbuf->priv;
+		page		= sg_page(ibuf->sg_table->sgl);
+		mbuf->paddr	= PFN_PHYS(page_to_pfn(page));
+		mbuf->sg_table	= ibuf->sg_table;
+		mbuf->ibuffer[0] = ibuf;
+		mbuf->idmabuf[0] = idbuf;
+		sgt		= ibuf->sg_table;
+	} else {
+		mbuf->paddr	= sg_dma_address(sgt->sgl);
+		mbuf->sg_table	= ua->sgt;
+		mbuf->ibuffer[0] = (void *)idbuf->priv;
+		mbuf->idmabuf[0] = idbuf;
+	}
+	am_buf->idmabuf[0] = idbuf;
+	/* update sg table. */
+	aml_uvm_copy_sgt(ua->sgt, sgt);
+
+	/* fill aml buffer information. */
+	am_buf->cap_sgt	= ua->sgt;
+	cap_sgt         = vb2_dma_sg_plane_desc(&vb->vb2_buf, 0);
+	memcpy(cap_sgt, am_buf->cap_sgt, sizeof(struct sg_table));
+	am_buf->is_delay_allocated = true;
+	ubuf->addr	= get_addr(&vb->vb2_buf, 0);
+
+	if (am_buf->pair == BUF_MASTER) {
+		/* no need clear cache. If dev is ion, the cache has been flushed in ion_alloc;
+		 * if dev is dma heap, dma_buf_map_attachment includes flush cache operation */
+		#if 0
+		/* clear cache. */
+		if (dma_map_sg(dev, mbuf->sg_table->sgl,
+			mbuf->sg_table->nents, DMA_FROM_DEVICE) <= 0) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+				"dma map sg %u bytes error\n", (u32)mbuf->size);
+			return -ENOMEM;
+		}
+		dma_sync_sg_for_device(dev, mbuf->sg_table->sgl,
+			mbuf->sg_table->nents, DMA_FROM_DEVICE);
+
+		dma_unmap_sg(ua->obj->dev, mbuf->sg_table->sgl,
+			mbuf->sg_table->nents, DMA_FROM_DEVICE);
+		#endif
+		/* unmap attachment and detach dbuf */
+		if (dba) {
+			dma_buf_unmap_attachment(dba, sgt, DMA_BIDIRECTIONAL);
+			dma_buf_detach(mbuf->idmabuf[0], dba);
+		}
+	}
+
+	aml_buf_update(&ctx->bm, get_addr(&vb->vb2_buf, 0), am_buf);
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, Res:%ux%u, stride:%d, addr:%lx, size:%u, flags:%x, cost:%llu ms\n",
+		__func__, mbuf->width, mbuf->height, mbuf->byte_stride,
+		(ulong)mbuf->paddr, (u32)mbuf->size, mbuf->ion_flags,
+		div64_u64(local_clock() - time, 1000000));
+
+	return 0;
+}
+
 static void aml_wait_resource(struct aml_vcodec_ctx *ctx)
 {
 	ulong expires = jiffies + msecs_to_jiffies(1000);
@@ -1929,6 +2161,22 @@
 	q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
 	if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
 		ctx->is_stream_off) {
+		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;
+			}
+		}
+
 		if (ctx->vpp_is_need) {
 			int ret;
 
@@ -1948,22 +2196,21 @@
 					aml_v4l2_vpp_reset(ctx->vpp);
 				} else {
 					if (ctx->vpp) {
-						atomic_dec(&ctx->dev->vpp_count);
 						aml_v4l2_vpp_destroy(ctx->vpp);
+						atomic_dec(&ctx->dev->vpp_count);
 						ctx->vpp = NULL;
 					}
-
+					atomic_inc(&ctx->dev->vpp_count);
 					ret = aml_v4l2_vpp_init(ctx, &ctx->vpp_cfg, &ctx->vpp);
 					if (ret) {
+						atomic_dec(&ctx->dev->vpp_count);
 						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,
+					v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 						"vpp_wrapper instance count: %d\n",
 						atomic_read(&ctx->dev->vpp_count));
 				}
@@ -1979,32 +2226,30 @@
 			ctx->vpp_cfg.is_vpp_reset = false;
 		} else {
 			if (ctx->vpp) {
-				atomic_dec(&ctx->dev->vpp_count);
 				aml_v4l2_vpp_destroy(ctx->vpp);
+				atomic_dec(&ctx->dev->vpp_count);
 				ctx->vpp = NULL;
 			}
 		}
 
-		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
+	} else {
 		ctx->is_out_stream_off = false;
+		ctx->es_wkr_stop = false;
+		aml_codec_connect(ctx->ada_ctx); /* for seek */
 
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+		if (ctx->dv_id < 0) {
+			dv_inst_map(&ctx->dv_id);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"%s: dv_inst_map ctx %p, dv_id %d\n",__func__, ctx, ctx->dv_id);
+		}
+#endif
+	}
+	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+		memset(&ctx->decoder_status_info, 0,
+			sizeof(ctx->decoder_status_info));
+	}
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, type: %d\n", __func__, q->type);
 
@@ -2087,9 +2332,14 @@
 					ctx->vpp_size);
 			//rb->count = ctx->dpb_size;
 		}
+		ctx->v4l_reqbuff_flag = true;
+		ctx->capture_memory_mode = rb->memory;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
+			"capture buffer memory mode is %d\n", rb->memory);
 	} else {
 		ctx->output_dma_mode =
 			(rb->memory == VB2_MEMORY_DMABUF) ? 1 : 0;
+		vdec_set_dmabuf_type(ctx->ada_ctx, ctx->output_dma_mode);
 
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
 			"output buffer memory mode is %d\n", rb->memory);
@@ -2120,16 +2370,252 @@
 	return v4l2_m2m_ioctl_expbuf(file, priv, eb);
 }
 
+static bool is_turn_around(struct aml_es_ref_elem *elem)
+{
+	return (elem->au_addr + elem->au_size) >=
+		(elem->buf_start + elem->buf_size);
+}
+
+static ulong get_remain_pos(struct aml_es_ref_elem *elem)
+{
+	return is_turn_around(elem) ?
+		elem->buf_start + (elem->au_size -
+		(elem->buf_start + elem->buf_size - elem->au_addr)) :
+		elem->au_addr + elem->au_size;
+}
+
+static int aml_es_ref_que(struct aml_es_mgr *stmgr, struct dma_buf *dbuf,
+			    ulong addr, u32 size, u64 timestamp)
+{
+	struct aml_es_ref_elem *elem;
+
+	/* 1.Get stbuf from free pool. */
+	if (!kfifo_get(&stmgr->free_q, &elem)) {
+		v4l_dbg(stmgr->ctx, 0, "Get elem from free queue fail.\n");
+		return -EBADSLT;
+	}
+
+	/* 2.Fill stbuf info from dbuf. */
+	elem->dbuf		= dbuf;
+	elem->buf_start		= stmgr->buf_start;
+	elem->buf_size		= stmgr->buf_size;
+	elem->au_addr		= addr;
+	elem->au_size		= size;
+	elem->timestamp		= timestamp;
+
+	if (stmgr->cursor_Wp == -1)
+		stmgr->cursor_Wp = elem->au_addr;
+
+	/* 3.Get dmabuf ref in driver. */
+	get_dma_buf(elem->dbuf);
+
+	atomic_inc(&stmgr->buf_cache);
+
+	/* 4.Add stbuf into the management queue. */
+	kfifo_put(&stmgr->ref_q, elem);
+	v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+		"Get-ref, CPB(%lx, %d), AU(%lx, %d, %d), "
+		"cursor_Wp:%lx, ts:%llu, buf_cache:%d\n",
+		elem->buf_start,
+		elem->buf_size,
+		elem->au_addr,
+		elem->au_size,
+		is_turn_around(elem),
+		stmgr->cursor_Wp,
+		elem->timestamp,
+		atomic_read(&stmgr->buf_cache));
+
+	return 0;
+}
+
+static void aml_es_put_ref(struct aml_es_mgr *stmgr,
+			     struct aml_es_ref_elem *elem)
+{
+	/* Update cursor Wp. */
+	stmgr->cursor_Wp = get_remain_pos(elem);
+	atomic_dec(&stmgr->buf_cache);
+	v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+		"Put-ref, CPB(%lx, %d), AU(%lx, %d, %d), "
+		"cursor_Wp:%lx, ts:%llu, buf_cache:%d\n",
+		elem->buf_start,
+		elem->buf_size,
+		elem->au_addr,
+		elem->au_size,
+		is_turn_around(elem),
+		stmgr->cursor_Wp,
+		elem->timestamp,
+		atomic_read(&stmgr->buf_cache));
+
+	dma_buf_put(elem->dbuf);
+
+	kfifo_put(&stmgr->free_q, elem);
+}
+
+static int aml_es_ref_dque(struct aml_es_mgr *stmgr, ulong Rp)
+{
+	struct aml_es_ref_elem *elem;
+	ulong cursor_Wp = stmgr->cursor_Wp;
+
+	v4l_dbg(stmgr->ctx, V4L_DEBUG_CODEC_INPUT,
+		"Put-ref-start, cursor_Wp:%lx, Rp:%lx\n", cursor_Wp, Rp);
+
+	/* Get stbuf from management queue. */
+	if (kfifo_is_empty(&stmgr->ref_q)) {
+		v4l_dbg(stmgr->ctx, 0, "There is no ref elem to process.\n");
+		return 0;
+	}
+retry:
+	if (!kfifo_peek(&stmgr->ref_q, &elem)) {
+		v4l_dbg(stmgr->ctx, 0, "Peek elem from ref queue fail.\n");
+		return -EINVAL;
+	}
+
+	/* Checks the stbuf whether was consumed. */
+	if (Rp >= cursor_Wp) {
+		/*
+		 * If Rp is to the right of the cursor_Wp, except the AU_end
+		 * with around, the others just should be checked Rp >= AU_end,
+		 * means that the AU-data has been consumed.
+		 */
+		if (!is_turn_around(elem) &&
+			(Rp >= get_remain_pos(elem))) {
+			if (!kfifo_get(&stmgr->ref_q, &elem)) {
+				v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+				return -EINVAL;
+			}
+
+			aml_es_put_ref(stmgr, elem);
+
+			if (!kfifo_is_empty(&stmgr->ref_q))
+				goto retry;
+		}
+	} else {
+		/*
+		 * Otherwise, there are 2 cases:
+		 * 1. As long as the AU-data is on the right side of the cursor_Wp
+		 *    and the AU_end is not around, then the AU-data is consumed
+		 * 2. If Rp > AU_end then indicates that the AU-data is consumed.
+		 */
+		if ((!is_turn_around(elem) &&
+			(elem->au_addr >= cursor_Wp)) ||
+			(Rp >= get_remain_pos(elem))) {
+			if (!kfifo_get(&stmgr->ref_q, &elem)) {
+				v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+				return -EINVAL;
+			}
+
+			aml_es_put_ref(stmgr, elem);
+
+			if (!kfifo_is_empty(&stmgr->ref_q))
+				goto retry;
+		}
+	}
+
+	return 0;
+}
+
+int aml_es_write(struct aml_vcodec_ctx *ctx, struct dma_buf *dbuf,
+			ulong addr, u32 size, u64 timestamp)
+{
+	int ret = -1;
+
+	/* 1.Increase dmabuf reference. */
+	ret = aml_es_ref_que(&ctx->es_mgr, dbuf, addr, size, timestamp);
+	if (ret)
+		return ret;
+
+	/* 2.PTS checkin. */
+	ctx->pts_serves_ops->checkin(ctx->ptsserver_id, size, timestamp);
+
+	return ret;
+}
+
+void aml_es_input_free(struct aml_vcodec_ctx *ctx, ulong addr)
+{
+	aml_es_ref_dque(&ctx->es_mgr, addr);
+}
+
+int aml_es_mgr_init(struct aml_vcodec_ctx *ctx)
+{
+	struct aml_es_ref_elem *elems = NULL;
+	struct aml_es_mgr *stmgr = &ctx->es_mgr;
+	int ret = -1, i;
+
+	INIT_KFIFO(stmgr->free_q);
+	INIT_KFIFO(stmgr->ref_q);
+
+	ret = kfifo_alloc(&stmgr->free_q, AML_ES_REF_MAX, GFP_KERNEL);
+	if (ret) {
+		v4l_dbg(stmgr->ctx, 0, "Alloc free_q fifo fail.\n");
+		return -ENOMEM;
+	}
+
+	ret = kfifo_alloc(&stmgr->ref_q, AML_ES_REF_MAX, GFP_KERNEL);
+	if (ret) {
+		kfifo_free(&stmgr->free_q);
+		v4l_dbg(stmgr->ctx, 0, "Alloc ref_q fifo fail.\n");
+		return -ENOMEM;
+	}
+
+	elems = vzalloc(sizeof(*elems) * AML_ES_REF_MAX);
+	if (!elems) {
+		kfifo_free(&stmgr->free_q);
+		kfifo_free(&stmgr->ref_q);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < AML_ES_REF_MAX; i++) {
+		kfifo_put(&stmgr->free_q, &elems[i]);
+	}
+
+	atomic_set(&stmgr->buf_cache, 0);
+
+	stmgr->cursor_Wp	= -1;
+	stmgr->elems		= elems;
+	stmgr->ctx		= ctx;
+
+	return 0;
+}
+
+void aml_es_mgr_release(struct aml_vcodec_ctx *ctx)
+{
+	struct aml_es_ref_elem *elem;
+	struct aml_es_mgr *stmgr = &ctx->es_mgr;
+
+	if (!stmgr->elems)
+		return;
+
+retry:
+	if (!kfifo_is_empty(&stmgr->ref_q)) {
+		if (!kfifo_get(&stmgr->ref_q, &elem)) {
+			v4l_dbg(stmgr->ctx, 0, "Get elem from ref queue fail.\n");
+			goto out;
+		}
+
+		aml_es_put_ref(stmgr, elem);
+
+		goto retry;
+	}
+out:
+	kfifo_free(&stmgr->free_q);
+
+	kfifo_free(&stmgr->ref_q);
+
+	vfree(stmgr->elems);
+}
+
 void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx)
 {
 	ulong flags;
-
-	if (kref_read(&ctx->box_ref))
-		kref_put(&ctx->box_ref, box_release);
+	if (ctx->capture_memory_mode == VB2_MEMORY_MMAP) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,"clean proxy uvm\n");
+		aml_clean_proxy_uvm(ctx);
+	} else
+		aml_buf_put_dma(&ctx->bm);
 
 	flags = aml_vcodec_ctx_lock(ctx);
 	ctx->state = AML_STATE_ABORT;
-	ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 		"vcodec state (AML_STATE_ABORT)\n");
 	aml_vcodec_ctx_unlock(ctx, flags);
@@ -2141,15 +2627,21 @@
 {
 	struct aml_q_data *q_data;
 
-	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+	ctx->m2m_ctx->q_lock = &ctx->v4l_intf_lock;
 	ctx->fh.m2m_ctx = ctx->m2m_ctx;
 	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
-	INIT_WORK(&ctx->decode_work, aml_vdec_worker);
+	INIT_WORK(&ctx->es_wkr_in, aml_vdec_worker);
 	ctx->colorspace = V4L2_COLORSPACE_REC709;
 	ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 	ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
 	ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
 	ctx->dev->dec_capability = 0;//VCODEC_CAPABILITY_4K_DISABLED;//disable 4k
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+		ctx->dev->dec_capability = VCODEC_CAPABILITY_4K_DISABLED;
+	}
+
+	if (t3x_tw_output && (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X))
+		ctx->force_tw_output = 1;
 
 	q_data = &ctx->q_data[AML_Q_DATA_SRC];
 	memset(q_data, 0, sizeof(struct aml_q_data));
@@ -2186,13 +2678,18 @@
 	q_data->bytesperline[0] = q_data->coded_width;
 	q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
 	q_data->bytesperline[1] = q_data->coded_width;
+
+	q_data->sizeimage_tw[0] = q_data->sizeimage[0];
+	q_data->bytesperline_tw[0] = q_data->bytesperline[0];
+	q_data->sizeimage_tw[1] = q_data->sizeimage[1];
+	q_data->bytesperline_tw[1] = q_data->bytesperline[1];
+
 	ctx->reset_flag = V4L_RESET_MODE_NORMAL;
 
-	ctx->fb_ops.query	= fb_buff_query;
-	ctx->fb_ops.alloc	= fb_buff_from_queue;
+	vdec_trace_init(&ctx->vtr, ctx->id, -1);
 
 	ctx->state = AML_STATE_IDLE;
-	ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+	vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 		"vcodec state (AML_STATE_IDLE)\n");
 }
@@ -2218,20 +2715,22 @@
 	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);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_1, buf->m.planes[0].bytesused);
 			else
-				ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->m.planes[0].bytesused);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_0, buf->m.planes[0].bytesused);
 		} else {
 			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->length);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_1, buf->length);
 			else
-				ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->length);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_0, buf->length);
 		}
+
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_12, timeval_to_ns(&buf->timestamp));
 	} else {
 		if (ret == -EAGAIN)
-			ATRACE_COUNTER("VC_IN_VSINK-1.que_again", buf->index);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_1, buf->index);
 		else
-			ATRACE_COUNTER("VC_IN_VSINK-0.que", buf->index);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_0, buf->index);
 	}
 
 	return ret;
@@ -2255,47 +2754,26 @@
 	}
 
 	ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-	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.v4l_dec_ctx	= (ulong) ctx;
-
-		file = fget(vb2_v4l2->private);
-		if (file && is_v4l2_buf_file(file)) {
-			dmabuf_fd_install_data(vb2_v4l2->private,
-				(void*)&aml_buf->privdata,
-				sizeof(struct file_private_data));
-			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);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_7, buf->m.planes[0].bytesused);
 			else
-				ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->m.planes[0].bytesused);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_6, buf->m.planes[0].bytesused);
 		} else {
 			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->length);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_7, buf->length);
 			else
-				ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->length);
+				vdec_tracing(&ctx->vtr, VTRACE_V4L_ES_6, buf->length);
 		}
 	} else {
 		if (ret == -EAGAIN)
-			ATRACE_COUNTER("VC_OUT_VSINK-3.deque_again", buf->index);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_8, buf->index);
 		else
-			ATRACE_COUNTER("VC_OUT_VSINK-2.deque", buf->index);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_7, buf->index);
+
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_9, timeval_to_ns(&buf->timestamp));
 	}
 
 	return ret;
@@ -2330,6 +2808,10 @@
 		return v4l2_event_subscribe(fh, sub, 2, NULL);
 	case V4L2_EVENT_SOURCE_CHANGE:
 		return v4l2_src_change_event_subscribe(fh, sub);
+	case V4L2_EVENT_PRIVATE_EXT_REPORT_ERROR_FRAME:
+		return v4l2_event_subscribe(fh, sub, 10, NULL);
+	case V4L2_EVENT_PRIVATE_EXT_SEND_ERROR:
+		return v4l2_event_subscribe(fh, sub, 5, NULL);
 	default:
 		return v4l2_ctrl_subscribe_event(fh, sub);
 	}
@@ -2346,7 +2828,8 @@
 	return v4l2_event_unsubscribe(fh, sub);
 }
 
-static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
+static int vidioc_try_fmt(struct aml_vcodec_ctx *ctx, struct v4l2_format *f,
+	struct aml_video_fmt *fmt)
 {
 	int i;
 	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
@@ -2365,7 +2848,7 @@
 				if (pix_mp->field == V4L2_FIELD_ANY)
 					pix_mp->field = V4L2_FIELD_NONE;
 
-				pr_info("%s, field: %u, fmt: %x\n",
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, field: %u, fmt: %x\n",
 					__func__, pix_mp->field,
 					pix_mp->pixelformat);
 			}
@@ -2408,7 +2891,7 @@
 				if (pix->field == V4L2_FIELD_ANY)
 					pix->field = V4L2_FIELD_NONE;
 
-				pr_info("%s, field: %u, fmt: %x\n",
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, field: %u, fmt: %x\n",
 					__func__, pix->field,
 					pix->pixelformat);
 			}
@@ -2468,7 +2951,7 @@
 		fmt = aml_vdec_find_format(f);
 	}
 
-	vidioc_try_fmt(f, fmt);
+	vidioc_try_fmt(ctx, f, fmt);
 
 	q_data = aml_vdec_get_q_data(ctx, f->type);
 	if (!q_data)
@@ -2476,7 +2959,7 @@
 
 	if (ctx->state >= AML_STATE_PROBE)
 		update_ctx_dimension(ctx, f->type);
-	copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+	copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
 
 	if (!V4L2_TYPE_IS_OUTPUT(f->type))
 		return 0;
@@ -2511,10 +2994,19 @@
 
 	if (ctx->internal_dw_scale) {
 		if (ctx->state >= AML_STATE_PROBE) {
-			unsigned int dw_mode = VDEC_DW_NO_AFBC;
+			u32 dw_mode = DM_YUV_ONLY;
+			u32 tw_mode = DM_INVALID;
+
 			if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
 				return -EBUSY;
-			ratio = get_double_write_ratio(dw_mode);
+
+			if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+				return -EBUSY;
+
+			if ((dw_mode == DM_AVBC_ONLY) && tw_mode)
+				ratio = vdec_get_size_ratio(tw_mode);
+			else
+				ratio = vdec_get_size_ratio(dw_mode);
 		}
 	}
 
@@ -2534,6 +3026,18 @@
 		s->r.width = ctx->picinfo.coded_width / ratio;
 		s->r.height = ctx->picinfo.coded_height / ratio;
 		break;
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = ctx->picinfo.visible_width;
+		s->r.height = ctx->picinfo.visible_height;
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = ctx->picinfo.coded_width;
+		s->r.height = ctx->picinfo.coded_height;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2566,10 +3070,19 @@
 
 	if (ctx->internal_dw_scale) {
 		if (ctx->state >= AML_STATE_PROBE) {
-			unsigned int dw_mode = VDEC_DW_NO_AFBC;
+			u32 dw_mode = DM_YUV_ONLY;
+			u32 tw_mode = DM_INVALID;
+
 			if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
 				return -EBUSY;
-			ratio = get_double_write_ratio(dw_mode);
+
+			if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+				return -EBUSY;
+
+			if ((dw_mode == DM_AVBC_ONLY) && tw_mode)
+				ratio = vdec_get_size_ratio(tw_mode);
+			else
+				ratio = vdec_get_size_ratio(dw_mode);
 		}
 	}
 
@@ -2587,20 +3100,37 @@
 	return 0;
 }
 
+static int is_vdec_core_fmt(struct aml_vcodec_ctx *ctx)
+{
+	if (ctx->output_pix_fmt == V4L2_PIX_FMT_H264 ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_MPEG ||
+		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_AVS ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_MJPEG ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)
+		return true;
+
+	return false;
+}
+
 /* 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;
+	unsigned int dw_mode = DM_YUV_ONLY;
+	unsigned int tw_mode = DM_INVALID;
 	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 (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+		return;
+
+	if (ctx->internal_dw_scale)
+		ratio = vdec_get_size_ratio(dw_mode);
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
 		q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
@@ -2611,25 +3141,69 @@
 
 		q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
 		q_data->bytesperline[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+
+		q_data->bytesperline[0] = q_data->bytesperline[0] << is_output_p010(dw_mode);
+		q_data->bytesperline[1] = q_data->bytesperline[1] << is_output_p010(dw_mode);
 	} 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);
+		q_data->bytesperline[0] = q_data->bytesperline[0] << is_output_p010(dw_mode);
+	}
+
+	/* For triple write. */
+	if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+		return;
+
+	if (tw_mode == DM_INVALID)
+		return;
+
+	if (ctx->internal_dw_scale)
+		ratio = vdec_get_size_ratio(tw_mode);
+
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		q_data->sizeimage_tw[0] = ctx->picinfo.y_len_sz_tw;
+		q_data->sizeimage_tw[1] = ctx->picinfo.c_len_sz_tw;
+
+		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_tw[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+		q_data->bytesperline_tw[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+
+		q_data->bytesperline_tw[0] = q_data->bytesperline_tw[0] << is_output_p010(tw_mode);
+		q_data->bytesperline_tw[1] = q_data->bytesperline_tw[1] << is_output_p010(tw_mode);
+	} 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_tw[0] = ctx->picinfo.y_len_sz_tw;
+		q_data->sizeimage_tw[0] += ctx->picinfo.c_len_sz_tw;
+		q_data->bytesperline_tw[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
+		q_data->bytesperline_tw[0] = q_data->bytesperline_tw[0] << is_output_p010(tw_mode);
 	}
 }
 
-static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
+static void copy_v4l2_format_dimension(struct aml_vcodec_ctx *ctx,
+				       struct v4l2_pix_format_mplane *pix_mp,
 				       struct v4l2_pix_format *pix,
 				       struct aml_q_data *q_data,
 				       u32 type)
 {
+	u32 dw_mode = DM_YUV_ONLY;
+	u32 tw_mode = DM_INVALID;
 	int i;
 
 	if (!pix || !pix_mp || !q_data)
 		return;
 
+	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+		return;
+
+	if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+		return;
+
 	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
 		pix_mp->width		= q_data->coded_width;
 		pix_mp->height		= q_data->coded_height;
@@ -2639,6 +3213,11 @@
 		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 ((dw_mode == DM_AVBC_ONLY) && tw_mode) {
+				pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline_tw[i];
+				pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage_tw[i];
+			}
 		}
 	} else {
 		pix->width		= q_data->coded_width;
@@ -2646,6 +3225,11 @@
 		pix->pixelformat	= q_data->fmt->fourcc;
 		pix->bytesperline	= q_data->bytesperline[0];
 		pix->sizeimage		= q_data->sizeimage[0];
+
+		if ((dw_mode == DM_AVBC_ONLY) && tw_mode) {
+			pix->bytesperline	= q_data->bytesperline_tw[0];
+			pix->sizeimage		= q_data->sizeimage_tw[0];
+		}
 	}
 }
 
@@ -2685,14 +3269,14 @@
 	    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;
+		return -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;
+		return -EBUSY;
 	}
 
 	fmt = aml_vdec_find_format(f);
@@ -2705,7 +3289,16 @@
 	}
 
 	q_data->fmt = fmt;
-	vidioc_try_fmt(f, q_data->fmt);
+	vidioc_try_fmt(ctx, f, q_data->fmt);
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type) && ctx->drv_handle && ctx->receive_cmd_stop) {
+		ctx->state = AML_STATE_IDLE;
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+			"vcodec state (AML_STATE_IDLE)\n");
+		vdec_if_deinit(ctx);
+		ctx->receive_cmd_stop = 0;
+	}
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
@@ -2732,8 +3325,11 @@
 				mutex_unlock(&ctx->state_lock);
 				return -EINVAL;
 			}
+
+			vdec_trace_init(&ctx->vtr, ctx->id, vdec_get_vdec_id(ctx->ada_ctx));
+
 			ctx->state = AML_STATE_INIT;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_INIT)\n");
 		}
@@ -2743,6 +3339,12 @@
 		q_data->coded_width = pix->width;
 		q_data->coded_height = pix->height;
 
+		if (!vdec_check_is_available(pix->pixelformat)) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+				"VC-1 only support single mode. \n");
+			return -EINVAL;
+		}
+
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 			"w: %d, h: %d, size: %d\n",
 			pix->width, pix->height,
@@ -2763,8 +3365,11 @@
 				mutex_unlock(&ctx->state_lock);
 				return -EINVAL;
 			}
+
+			vdec_trace_init(&ctx->vtr, ctx->id, vdec_get_vdec_id(ctx->ada_ctx));
+
 			ctx->state = AML_STATE_INIT;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_INIT)\n");
 		}
@@ -2776,8 +3381,7 @@
 			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);
+			copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
 		}
 	}
 
@@ -2854,6 +3458,7 @@
 
 		if (j == f->index) {
 			f->pixelformat = fmt->fourcc;
+			strncpy(f->description, fmt->name, sizeof(f->description));
 			return 0;
 		}
 		++j;
@@ -2926,13 +3531,15 @@
 	}
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
-		pix_mp->field = ret ? V4L2_FIELD_NONE : ctx->picinfo.field;
+		pix_mp->field = ctx->force_report_interlace ? V4L2_FIELD_INTERLACED :
+			(ret ? V4L2_FIELD_NONE : ctx->picinfo.field);
 		pix_mp->colorspace = ctx->colorspace;
 		pix_mp->ycbcr_enc = ctx->ycbcr_enc;
 		pix_mp->quantization = ctx->quantization;
 		pix_mp->xfer_func = ctx->xfer_func;
 	} else {
-		pix->field = ret ? V4L2_FIELD_NONE : ctx->picinfo.field;
+		pix->field = ctx->force_report_interlace ? V4L2_FIELD_INTERLACED :
+			(ret ? V4L2_FIELD_NONE : ctx->picinfo.field);
 		pix->colorspace = ctx->colorspace;
 		pix->ycbcr_enc = ctx->ycbcr_enc;
 		pix->quantization = ctx->quantization;
@@ -2942,7 +3549,7 @@
 	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);
+		copy_v4l2_format_dimension(ctx, pix_mp, pix, q_data, f->type);
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		/*
 		 * This is run on OUTPUT
@@ -2950,9 +3557,9 @@
 		 * 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_dimension(ctx, pix_mp, pix, q_data, f->type);
 	} else {
-		copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+		copy_v4l2_format_dimension(ctx, pix_mp, pix, 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",
@@ -3022,29 +3629,49 @@
 				return -EINVAL;
 			alloc_devs[i] = &ctx->dev->plat_dev->dev;
 
-			if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+			if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
+				(vq->memory == VB2_MEMORY_MMAP))
 				alloc_devs[i] = v4l_get_dev_from_codec_mm();
+			else if (vq->memory == VB2_MEMORY_MMAP)
+				dma_coerce_mask_and_coherent(alloc_devs[i], DMA_BIT_MASK(64));
 		}
 	} else {
-		int dw_mode = VDEC_DW_NO_AFBC;
+		int dw_mode = DM_YUV_ONLY;
+		int tw_mode = DM_INVALID;
 
 		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;
-		}
+		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
+			return -EINVAL;
+
+		if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw_mode))
+			return -EINVAL;
+
+		if ((dw_mode == DM_AVBC_ONLY) && (tw_mode == DM_INVALID))
+			*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;
+			sizes[i] = (dw_mode != DM_AVBC_ONLY) ? q_data->sizeimage[i] :
+				(tw_mode != DM_INVALID) ? q_data->sizeimage_tw[i] :
+				PAGE_SIZE;
 
-			if (!V4L2_TYPE_IS_OUTPUT(vq->type))
+			if (ctx->enable_di_post && is_vdec_core_fmt(ctx) &&
+				ctx->picinfo.field != V4L2_FIELD_NONE)
+				sizes[i] = PAGE_SIZE;
+
+			if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+				if (ctx->output_dma_mode)
+					sizes[i] = 1;
+				else
+					sizes[i] = q_data->sizeimage[i];
+
+				if (vq->memory == VB2_MEMORY_MMAP)
+					dma_coerce_mask_and_coherent(alloc_devs[i], DMA_BIT_MASK(64));
+			} else
 				alloc_devs[i] = v4l_get_dev_from_codec_mm();
 		}
 	}
@@ -3061,21 +3688,48 @@
 	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;
+	struct aml_v4l2_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);
 
-	if (vb->memory == VB2_MEMORY_DMABUF
-		&& V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
+	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+	buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+
+	if (vb->memory == VB2_MEMORY_DMABUF && V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+		if (!ctx->is_drm_mode) {
+			struct dmabuf_videodec_es_data *videodec_es_data;
+			if (dmabuf_manage_get_type(vb->planes[0].dbuf) != DMA_BUF_TYPE_VIDEODEC_ES) {
+				return 0;
+			}
+			videodec_es_data = (struct dmabuf_videodec_es_data *)dmabuf_manage_get_info(vb->planes[0].dbuf,
+					DMA_BUF_TYPE_VIDEODEC_ES);
+
+			if (videodec_es_data && videodec_es_data->data_type == DMA_BUF_VIDEODEC_HDR10PLUS) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "buf_prepare hdr10+ info type %d, len: %d\n",
+					videodec_es_data->data_type, videodec_es_data->data_len);
+				memcpy(buf->meta_data, (void *)videodec_es_data->data, videodec_es_data->data_len);
+			}
+		}
+#endif
 		return 0;
+	}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
+	if (vb2_v4l2->meta_ptr && (copy_from_user(buf->meta_data,
+		(void *)vb2_v4l2->meta_ptr, VDEC_META_DATA_SIZE + 4))) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"%s:copy meta data error. ptr: %lx\n", __func__, vb2_v4l2->meta_ptr);
+	}
+#endif
 
 	q_data = aml_vdec_get_q_data(ctx, vb->vb2_queue->type);
 
 	for (i = 0; i < q_data->fmt->num_planes; i++) {
-		if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
+		if (vb2_plane_size(vb, i) < q_data->sizeimage[i] &&
+			vb2_plane_size(vb, i) != PAGE_SIZE) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 				"data will not fit into plane %d (%lu < %d)\n",
 				i, vb2_plane_size(vb, i),
@@ -3083,116 +3737,9 @@
 		}
 	}
 
-	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;
@@ -3232,6 +3779,21 @@
 			}
 		}
 	}
+
+	if (flag & HDR10P_TYPE) {
+		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+			ctx->aux_infos.bufs[i].hdr10p_buf = vzalloc(HDR10P_BUF_SIZE);
+			if (ctx->aux_infos.bufs[i].hdr10p_buf) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+					"v4l2 alloc %dth hdr10p buffer:%px\n",
+					i, ctx->aux_infos.bufs[i].hdr10p_buf);
+			} else {
+				ctx->aux_infos.bufs[i].hdr10p_buf = NULL;
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+					"v4l2 alloc %dth hdr10p buffer fail\n", i);
+			}
+		}
+	}
 }
 
 void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag)
@@ -3265,6 +3827,18 @@
 			}
 		}
 	}
+
+	if (flag & HDR10P_TYPE) {
+		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
+			if (ctx->aux_infos.bufs[i].hdr10p_buf != NULL) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+					"v4l2 free %dth hdr10p buffer:%px\n",
+					i, ctx->aux_infos.bufs[i].hdr10p_buf);
+				vfree(ctx->aux_infos.bufs[i].hdr10p_buf);
+				ctx->aux_infos.bufs[i].hdr10p_buf = NULL;
+			}
+		}
+	}
 }
 
 void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx)
@@ -3337,15 +3911,119 @@
 	}
 }
 
+void aml_bind_hdr10p_buffer(struct aml_vcodec_ctx *ctx, char **addr)
+{
+	int index = ctx->aux_infos.hdr10p_index;
+
+	if (ctx->aux_infos.bufs[index].hdr10p_buf != NULL) {
+		*addr = ctx->aux_infos.bufs[index].hdr10p_buf;
+		ctx->aux_infos.hdr10p_index = (index + 1) % V4L_CAP_BUFF_MAX;
+	}
+}
+
+static void aml_canvas_cache_free(struct canvas_cache *cache)
+{
+	int i = -1;
+
+	for (i = 0; i < ARRAY_SIZE(cache->res); i++) {
+		if (cache->res[i].cid > 0) {
+			v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+				"canvas-free, name:%s, canvas id:%d\n",
+				cache->res[i].name,
+				cache->res[i].cid);
+
+			canvas_pool_map_free_canvas(cache->res[i].cid);
+
+			cache->res[i].cid = 0;
+		}
+	}
+}
+
+void aml_canvas_cache_put(struct aml_vcodec_dev *dev)
+{
+	struct canvas_cache *cache = &dev->cache;
+
+	mutex_lock(&cache->lock);
+
+	v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+		"canvas-put, ref:%d\n", cache->ref);
+
+	cache->ref--;
+
+	if (cache->ref == 0) {
+		aml_canvas_cache_free(cache);
+	}
+
+	mutex_unlock(&cache->lock);
+}
+
+int aml_canvas_cache_get(struct aml_vcodec_dev *dev, char *usr)
+{
+	struct canvas_cache *cache = &dev->cache;
+	int i;
+
+	mutex_lock(&cache->lock);
+
+	cache->ref++;
+
+	for (i = 0; i < ARRAY_SIZE(cache->res); i++) {
+		if (cache->res[i].cid <= 0) {
+			snprintf(cache->res[i].name, 32, "%s-%d", usr, i);
+			cache->res[i].cid =
+				canvas_pool_map_alloc_canvas(cache->res[i].name);
+		}
+
+		v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+			"canvas-alloc, name:%s, canvas id:%d\n",
+			cache->res[i].name,
+			cache->res[i].cid);
+
+		if (cache->res[i].cid <= 0) {
+			v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+				"canvas-fail, name:%s, canvas id:%d.\n",
+				cache->res[i].name,
+				cache->res[i].cid);
+
+			mutex_unlock(&cache->lock);
+			goto err;
+		}
+	}
+
+	v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+		"canvas-get, ref:%d\n", cache->ref);
+
+	mutex_unlock(&cache->lock);
+	return 0;
+err:
+	aml_canvas_cache_put(dev);
+	return -1;
+}
+
+int aml_canvas_cache_init(struct aml_vcodec_dev *dev)
+{
+	dev->cache.ref = 0;
+	mutex_init(&dev->cache.lock);
+
+	v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+		"canvas-init, ref:%d\n", dev->cache.ref);
+
+	return 0;
+}
+
 void aml_v4l_vpp_release_early(struct aml_vcodec_ctx * ctx)
 {
-	if (ctx->vpp && !(ctx->vpp_cfg.enable_nr &&
-		atomic_read(&ctx->vpp->local_buf_out))) {
+	struct aml_vpp_cfg_infos *vpp_cfg = &ctx->vpp_cfg;
+
+	if (ctx->vpp == NULL)
+		return;
+
+	if (vpp_cfg->early_release_flag ||
+		!(vpp_cfg->enable_nr && atomic_read(&ctx->vpp->local_buf_out))) {
 		aml_v4l2_vpp_destroy(ctx->vpp);
 		atomic_dec(&ctx->dev->vpp_count);
 		ctx->vpp = NULL;
 
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 			"vpp destroy inst count:%d.\n",
 			atomic_read(&ctx->dev->vpp_count));
 	}
@@ -3358,116 +4036,54 @@
 	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);
+		atomic_dec(&ctx->dev->vpp_count);
 		ctx->vpp = NULL;
 
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"vpp destory inst count:%d.\n",
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+			"vpp destroy 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");
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+			"ge2d destroy.\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);
+	ctx->aux_infos.free_buffer(ctx, SEI_TYPE | DV_TYPE | HDR10P_TYPE);
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 		"v4ldec has been destroyed.\n");
 
 	if (ctx->sync) {
 		vdec_clean_all_fence(ctx->sync);
 	}
 
+	vdec_trace_clean(&ctx->vtr);
+
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+	if (ctx->dv_id >= 0) {
+		dv_inst_unmap(ctx->dv_id);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"%s: dv_inst_unmap ctx %p, dv_id %d\n", __func__, ctx, ctx->dv_id);
+	}
+#endif
+
+	if (ctx->stream_mode) {
+		ctx->set_ext_buf_flg = false;
+		ptsserver_ins_release(ctx->ptsserver_id);
+	}
+
+	aml_es_mgr_release(ctx);
+
 	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 =
@@ -3480,177 +4096,13 @@
 		__func__, ubuf->index, ubuf->dbuf,
 		file_inode(ubuf->dbuf->file)->i_ino);
 
+	aml_buf_detach(&ctx->bm, (ulong)ubuf->dbuf);
+
 	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 aml_uvm_buff_attach(struct vb2_buffer * vb)
 {
 	int ret = 0;
 	struct dma_buf *dbuf = vb->planes[0].dbuf;
@@ -3658,6 +4110,10 @@
 	struct aml_vcodec_ctx *ctx =
 		vb2_get_drv_priv(vb->vb2_queue);
 	struct aml_uvm_buff_ref *ubuf = NULL;
+	struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+	struct aml_v4l2_buf *buf =
+		container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+	struct aml_buf *am_buf = buf->aml_buf;
 
 	if (vb->memory != VB2_MEMORY_DMABUF || !dmabuf_is_uvm(dbuf))
 		return 0;
@@ -3667,9 +4123,10 @@
 		return -ENOMEM;
 
 	ubuf->index	= vb->index;
-	ubuf->addr	= vb2_dma_contig_plane_dma_addr(vb, 0);
+	ubuf->addr	= get_addr(vb, 0);
 	ubuf->dbuf	= dbuf;
 	ubuf->ref	= &ctx->ctx_ref;
+	am_buf->uvm_buf = (void *)ubuf;
 
 	u_info.type	= VF_PROCESS_DECODER;
 	u_info.arg	= (void *)ubuf;
@@ -3692,156 +4149,203 @@
 	return ret;
 }
 
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
-					    struct vb2_buffer *vb)
+static ulong prepare_get_addr(struct dma_buf *dbuf, struct device	 *dev)
 {
-	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;
+	struct dma_buf_attachment *dba;
+	struct sg_table *sgt;
+	ulong addr;
 
-	uhmod = uvm_get_hook_mod(dbuf, u_type);
-	if (IS_ERR_OR_NULL(uhmod))
-		return NULL;
+	/* create attachment for the dmabuf with the user device */
+	dba = dma_buf_attach(dbuf, dev);
+	if (IS_ERR(dba)) {
+		pr_err("failed to attach dmabuf\n");
+		return 0;
+	}
 
-	ibuf = !is_v4lvideo ? (struct internal_comp_buf *) uhmod->arg :
-		container_of(uhmod->arg, struct internal_comp_buf, priv_data);
+	/* get the associated scatterlist for this buffer */
+	sgt = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
+	if (IS_ERR(sgt)) {
+		pr_err("Error getting dmabuf scatterlist\n");
+		return 0;
+	}
 
-	uvm_put_hook_mod(dbuf, u_type);
+	addr = sg_dma_address(sgt->sgl);
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"%s, vb2: (%d, %px) --> comp: (%d, %px)\n",
-		__func__, vb->index, dbuf, ibuf->index, ibuf);
+	/* unmap attachment and detach dbuf */
+	dma_buf_unmap_attachment(dba, sgt, DMA_BIDIRECTIONAL);
+	dma_buf_detach(dbuf, dba);
 
-	return ibuf;
+	return addr;
 }
 
 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 aml_v4l2_buf *buf =
+		container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
 	struct aml_vcodec_mem src_mem;
+	struct aml_buf_config config;
+	u32 dw = DM_YUV_ONLY;
+	u32 tw = DM_INVALID;
 
 	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);
+		"%s, type: %d, vb: %lx, idx: %d, state: %d, used: %d, ts: %llu, uvm dbuf: %px\n",
+		__func__, vb->vb2_queue->type, (ulong) vb,
+		vb->index, vb->state, buf->used, vb->timestamp, vb->planes[0].dbuf);
 
 	/*
 	 * 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;
+		struct aml_buf *aml_buf = buf->aml_buf;
+		struct vframe_s *vf;
 
-		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
-			return;
+		if (aml_buf->vb != vb) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"vb2 (old idx: %d new idx: %d) update\n",
+				aml_buf->vb->index, vb->index);
+			aml_buf_replace(&ctx->bm, aml_buf, vb);
 
 		}
 
-		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));
+		if (aml_buf->pair == BUF_MASTER)
+			aml_buf->queued_mask = 1 << BUF_MASTER;
 
-			/* 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;
-			}
+		if (aml_buf->pair == BUF_SUB0) {
+			aml_buf = aml_buf->master_buf;
+			aml_buf->queued_mask = 1 << BUF_SUB0;
+		}
+		if (aml_buf->pair == BUF_SUB1) {
+			aml_buf = aml_buf->master_buf;
+			aml_buf->queued_mask = 1 << BUF_SUB1;
+		}
 
-			/* DI hook must be detached if the dmabuff be reused. */
-			if (ctx->vpp_cfg.enable_local_buf) {
+		vf = &aml_buf->vframe;
+
+		/* DI hook must be detached if the dmabuff be reused. */
+		if (ctx->vpp_cfg.enable_local_buf) {
+			if (!buf->attached) {
 				struct dma_buf *dma = vb->planes[0].dbuf;
 
-				if (dmabuf_is_uvm(dma) &&
-					uvm_detach_hook_mod(dma, VF_PROCESS_DI) < 0) {
+				if (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);
-
-			/* check dpb ready */
-			aml_check_dpb_ready(ctx);
-		} else {
-			struct vframe_s *vf = fb->vframe;
-			struct task_chain_s *task = fb->task;
-
-			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);
+				buf->attached = true;
+			} else
+				aml_v4l2_vpp_recycle(ctx->vpp, buf);
 		}
 
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
+			"IN__BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+			"dma addr: %llx Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
+			ctx->ada_ctx->frm_name,
+			aml_buf->state,
+			ctx->in_buff_cnt,
+			vb->index, vb,
+			vf ? vf->index & 0xff : -1, vf,
+			vf ? vf->timestamp : 0,
+			(u64)get_addr(vb, 0),
+			aml_buf->planes[0].addr, aml_buf->planes[0].length,
+			aml_buf->planes[1].addr, aml_buf->planes[1].length,
+			aml_buf->planes[2].addr, aml_buf->planes[2].length);
+
+		ctx->in_buff_cnt++;
+
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_10,
+			CTX_BUF_TOTAL(ctx) + ctx->out_buff_cnt - ctx->in_buff_cnt);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_PIC_4, vb->index);
+
+		aml_buf_fill(&ctx->bm, aml_buf, BUF_USER_VSINK);
+
+		vdec_thread_wakeup(ctx->ada_ctx);
+
 		wake_up_interruptible(&ctx->cap_wq);
 		return;
+	} else if (ctx->output_dma_mode) {
+		struct dma_buf *dbuf = vb->planes[0].dbuf;
+		struct device *dev = vb->vb2_queue->alloc_devs[0] ? :
+							vb->vb2_queue->dev;
+
+		if (dbuf && dev) {
+			buf->addr = prepare_get_addr(dbuf, dev);
+			if (buf->addr &&
+				buf->addr != sg_dma_address(buf->out_sgt->sgl)) {
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+					"vb2 dma addr update(0x%llx --> 0x%lx)\n",
+					(u64)sg_dma_address(buf->out_sgt->sgl), buf->addr);
+			}
+		} else
+			v4l_dbg(ctx, 0,
+					"dbuf %px dev %px\n", dbuf, dev);
 	}
 
+	if (ctx->stream_mode &&
+		!(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+		struct dmabuf_dmx_sec_es_data *es_data;
+
+		if (dmabuf_manage_get_type(vb->planes[0].dbuf) != DMA_BUF_TYPE_DMX_ES) {
+			pr_err("not DMA_BUF_TYPE_DMX_ES\n");
+			return;
+		}
+		es_data = (struct dmabuf_dmx_sec_es_data *)dmabuf_manage_get_info(vb->planes[0].dbuf, DMA_BUF_TYPE_DMX_ES);
+		buf->dma_buf = (void *)es_data;
+	}
 	v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
 
 	if (ctx->state != AML_STATE_INIT) {
 		return;
 	}
 
-	buf->used = true;
 	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
-	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+	buf = container_of(vb2_v4l2, struct aml_v4l2_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;
 	}
 
+	if (ctx->stream_mode &&
+		!(ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G ||
+		ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)) {
+		struct dmabuf_dmx_sec_es_data *es_data = (struct dmabuf_dmx_sec_es_data *)buf->dma_buf;
+		int offset = vb->planes[0].data_offset;
+		if (ctx->set_ext_buf_flg == false) {
+			v4l2_set_ext_buf_addr(ctx->ada_ctx, es_data, offset);
+			ctx->es_free = aml_es_input_free;
+			ctx->set_ext_buf_flg = true;
+		}
+
+		src_mem.addr = es_data->data_start + offset;
+		src_mem.size = vb->planes[0].bytesused - offset;
+		src_mem.dbuf = vb->planes[0].dbuf;
+
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT, "update wp 0x%lx + sz 0x%x offset 0x%x ori start 0x%x pts %llu\n",
+			src_mem.addr, src_mem.size, offset, es_data->data_start, vb->timestamp);
+
+	} else {
+		src_mem.addr	= buf->addr ? buf->addr :
+				sg_dma_address(buf->out_sgt->sgl);
+		src_mem.size	= vb->planes[0].bytesused;
+	}
 	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.size	= vb->planes[0].bytesused;
+	if (!ctx->is_drm_mode)
+		src_mem.vaddr = vb2_plane_vaddr(vb, 0);
+
 	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 {
+		/* frame mode and non-dbuf mode. */
+		if (ctx->stream_mode || !ctx->output_dma_mode) {
 			v4l2_buff_done(to_vb2_v4l2_buffer(vb),
 				VB2_BUF_STATE_DONE);
 		}
@@ -3853,13 +4357,10 @@
 	 * 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);
-	} else if (ctx->param_sets_from_ucode) {
+	/* frame mode and non-dbuf mode. */
+	if (ctx->stream_mode || !ctx->output_dma_mode) {
 		v4l2_buff_done(to_vb2_v4l2_buffer(vb),
 			VB2_BUF_STATE_DONE);
 	}
@@ -3870,12 +4371,40 @@
 		return;
 	}
 
+	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+		return;
+
+	}
+
+	if (vdec_if_get_param(ctx, GET_PARAM_TW_MODE, &tw)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid tw_mode\n");
+		return;
+
+	}
+
 	if (!ctx->picinfo.dpb_frames)
 		return;
 
 	v4l_buf_size_decision(ctx);
 	ctx->last_decoded_picinfo = ctx->picinfo;
 
+	config.enable_extbuf	= true;
+	config.enable_fbc	= ((dw != DM_YUV_ONLY) || tw) ? true : false;
+	config.enable_secure	= ctx->is_drm_mode;
+	config.memory_mode	= vb->vb2_queue->memory;
+	config.planes		= V4L2_TYPE_IS_MULTIPLANAR(vb->vb2_queue->type) ? 2 : 1;
+	config.luma_length	= ctx->picinfo.y_len_sz;
+	config.chroma_length	= ctx->picinfo.c_len_sz;
+	config.luma_length_tw	= ctx->picinfo.y_len_sz_tw;
+	config.chroma_length_tw	= ctx->picinfo.c_len_sz_tw;
+	config.dw_mode		= dw;
+	config.tw_mode		= tw;
+
+	if (ctx->enable_di_post)
+		ctx->bm.vpp_work_mode	= VPP_WORK_MODE_DI_POST;
+	aml_buf_configure(&ctx->bm, &config);
+
 	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,
@@ -3887,7 +4416,7 @@
 	mutex_lock(&ctx->state_lock);
 	if (ctx->state == AML_STATE_INIT) {
 		ctx->state = AML_STATE_PROBE;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_PROBE)\n");
 	}
@@ -3898,20 +4427,20 @@
 {
 	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;
+	struct aml_v4l2_buf *buf = NULL;
 
 	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);
-	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+	buf = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
 
 	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);
+		vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_ABORT)\n");
 	}
@@ -3922,17 +4451,19 @@
 	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_v4l2_buf *buf = container_of(vb2_v4l2,
+					struct aml_v4l2_buf, vb);
 	u32 size, phy_addr = 0;
 	int i;
+	int ret;
 
 	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)) {
 		buf->lastframe = false;
+	} else {
+		buf->attached = false;
 	}
 
 	/* codec_mm buffers count */
@@ -3941,21 +4472,21 @@
 			char *owner = __getname();
 
 			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';
+			strncpy(buf->mem_owner, owner, sizeof(buf->mem_owner));
+			buf->mem_owner[sizeof(buf->mem_owner) - 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,
+				buf->mem[i] = v4l_reqbufs_from_codec_mm(buf->mem_owner,
 						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;
+			unsigned int dw_mode = DM_YUV_ONLY;
 
 			for (i = 0; i < vb->num_planes; i++) {
 				struct dma_buf * dma;
@@ -3965,7 +4496,7 @@
 					return -EINVAL;
 				}
 				/* None-DW mode means single layer */
-				if (dw_mode == VDEC_DW_AFBC_ONLY && i > 0) {
+				if (dw_mode == DM_AVBC_ONLY && i > 0) {
 					v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 							"only support single plane in dw mode 0\n");
 					return -EINVAL;
@@ -3974,45 +4505,26 @@
 				dma = vb->planes[i].dbuf;
 
 				if (!dmabuf_is_uvm(dma))
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "non-uvm dmabuf\n");
+					v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "non-uvm dmabuf\n");
 			}
 		}
 	}
 
 	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;
+		ulong key;
+		if (vb->memory == VB2_MEMORY_DMABUF)
+			key = (ulong)vb->planes[0].dbuf;
+		if (vb->memory == VB2_MEMORY_MMAP)
+			key = vb2_dma_contig_plane_dma_addr(vb, 0);
 
-		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);
+		ret = aml_buf_attach(&ctx->bm, key,
+			vb2_dma_contig_plane_dma_addr(vb, 0), vb);
+		if (ret) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+				"aml_buf_attach fail!\n");
+			return ret;
+		}
+		aml_uvm_buf_delay_alloc(ctx, vb2_v4l2);
 	}
 
 	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
@@ -4037,9 +4549,8 @@
 	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_v4l2_buf *buf = container_of(vb2_v4l2,
+					struct aml_v4l2_buf, vb);
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
 		__func__, vb->vb2_queue->type, vb->index);
@@ -4053,16 +4564,10 @@
 					"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]);
+				v4l_freebufs_back_to_codec_mm(buf->mem_owner, buf->mem[i]);
 				buf->mem[i] = NULL;
 			}
-		}
-		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);
-			}
+			aml_buf_detach(&ctx->bm, vb2_dma_contig_plane_dma_addr(vb, 0));
 		}
 	}
 }
@@ -4075,10 +4580,14 @@
 	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_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
 
 	v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
 
+	ctx->dst_queue_streaming = true;
+
+	vdec_thread_wakeup(ctx->ada_ctx);
+
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, type: %d\n", __func__, q->type);
 
@@ -4087,7 +4596,7 @@
 
 static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
 {
-	struct aml_video_dec_buf *buf = NULL;
+	struct aml_v4l2_buf *buf = NULL;
 	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
 	int i;
@@ -4096,19 +4605,27 @@
 		"%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))
+	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
 		ctx->is_out_stream_off = true;
-	else
+	} else {
 		ctx->is_stream_off = true;
+		ctx->dst_queue_streaming = false;
+		ctx->out_buff_cnt = 0;
+		ctx->in_buff_cnt = 0;
+		ctx->write_frames = 0;
+	}
 
 	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
 		struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
-		unsigned long flags;
+		ulong flags;
 
-		cancel_work_sync(&ctx->dmabuff_recycle_work);
-		spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
+		spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+		ctx->es_wkr_stop = true;
+		spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+
+		cancel_work_sync(&ctx->es_wkr_in);
+		cancel_work_sync(&ctx->es_wkr_out);
 		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);
@@ -4126,11 +4643,10 @@
 		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);
+			vdec_tracing(&ctx->vtr, VTRACE_V4L_ST_0, ctx->state);
 			ctx->v4l_resolution_change = false;
 			ctx->reset_flag = V4L_RESET_MODE_NORMAL;
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 				"force reset to drop es frames.\n");
 			wake_up_interruptible(&ctx->cap_wq);
 			aml_vdec_reset(ctx);
@@ -4142,23 +4658,21 @@
 			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);
-
 		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 = container_of(vb2_v4l2, struct aml_v4l2_buf, vb);
+			if (buf->aml_buf) {
+				buf->aml_buf->state	= FB_ST_FREE;
+				memset(&buf->aml_buf->vframe,
+					0, sizeof(struct vframe_s));
+			}
+			buf->attached		= false;
+			buf->used		= false;
+			buf->vb.flags		= 0;
 
 			if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
 				v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
@@ -4167,15 +4681,23 @@
 				q->bufs[i]->index, q->bufs[i]->state);*/
 		}
 
-		fb_map_table_clean(ctx);
-
-		fb_token_clean(ctx);
-
+		aml_buf_reset(&ctx->bm);
+		aml_codec_connect(ctx->ada_ctx); /* for resolution change */
+		aml_compressed_info_show(ctx);
+		memset(&ctx->compressed_buf_info, 0, sizeof(ctx->compressed_buf_info));
 		ctx->buf_used_count = 0;
-		ctx->cap_pool.in = 0;
-		ctx->cap_pool.out = 0;
-		ctx->cap_pool.dec = 0;
-		ctx->cap_pool.vpp = 0;
+	}
+	if (ctx->is_out_stream_off && ctx->is_stream_off) {
+		ctx->v4l_resolution_change = false;
+		ctx->reset_flag = V4L_RESET_MODE_NORMAL;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+			"seek force reset to drop es frames.\n");
+		aml_vdec_reset(ctx);
+	}
+
+	if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+		atomic_set(&ctx->vpp_cache_num, 0);
+		atomic_set(&ctx->ge2d_cache_num, 0);
 	}
 }
 
@@ -4183,26 +4705,33 @@
 {
 	struct aml_vcodec_ctx *ctx = priv;
 	struct aml_vcodec_dev *dev = ctx->dev;
+	ulong flags;
 
-	if (ctx->output_thread_ready)
-		queue_work(dev->decode_workqueue, &ctx->decode_work);
+	spin_lock_irqsave(&ctx->es_wkr_slock, flags);
+	if (ctx->es_wkr_stop) {
+		spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
+		return;
+	}
+
+	queue_work(dev->decode_workqueue, &ctx->es_wkr_in);
+
+	spin_unlock_irqrestore(&ctx->es_wkr_slock, flags);
 }
 
 static int m2mops_vdec_job_ready(void *m2m_priv)
 {
 	struct aml_vcodec_ctx *ctx = m2m_priv;
 
-	if (ctx->state < AML_STATE_PROBE ||
-		ctx->state > AML_STATE_FLUSHED)
-		return 0;
-
-	return 1;
+	return (ctx->es_wkr_stop ||
+		!is_input_ready(ctx->ada_ctx) ||
+		vdec_input_full(ctx->ada_ctx)) ? 0 : 1;
 }
 
 static void m2mops_vdec_job_abort(void *priv)
 {
 	struct aml_vcodec_ctx *ctx = priv;
 
+	v4l2_m2m_job_finish(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
 }
 
@@ -4234,6 +4763,22 @@
 	case AML_V4L2_GET_FILMGRAIN_INFO:
 		ctrl->val = ctx->film_grain_present;
 		break;
+	case AML_V4L2_GET_DECODER_INFO:
+		memcpy(ctrl->p_new.p, &ctx->decoder_status_info,
+			sizeof(struct aml_decoder_status_info));
+		ctx->decoder_status_info.error_type = 0;
+		break;
+	case AML_V4L2_GET_BITDEPTH:
+		ctrl->val = ctx->picinfo.bitdepth;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+			"bitdepth: %d\n", ctrl->val);
+		break;
+	case AML_V4L2_DEC_PARMS_CONFIG:
+		vidioc_vdec_g_parm_ext(ctrl, ctx);
+		break;
+	case AML_V4L2_GET_INST_ID:
+		ctrl->val = ctx->id;
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -4244,19 +4789,45 @@
 {
 	struct aml_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s id %d val %d\n", __func__, ctrl->id, ctrl->val);
 
 	if (ctrl->id == AML_V4L2_SET_DRMMODE) {
 		ctx->is_drm_mode = ctrl->val;
 		ctx->param_sets_from_ucode = true;
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"set stream mode: %x\n", ctrl->val);
+			"set DRM 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,
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 			"set duration: %x\n", ctrl->val);
-	}
+	} else if (ctrl->id == AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE) {
+		ctx->cache_input_buffer_num = ctrl->val;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+			"cache_input_buffer_num: %d\n", ctrl->val);
+	} else if (ctrl->id == AML_V4L2_DEC_PARMS_CONFIG) {
+		vidioc_vdec_s_parm_ext(ctrl, ctx);
+	} else if (ctrl->id == AML_V4L2_SET_STREAM_MODE) {
+		u32 ret;
+		ctx->stream_mode = ctrl->val;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "set streambase: %x\n", ctrl->val);
 
+		if (ctx->stream_mode == true) {
+			ptsserver_ins *pIns = NULL;
+			ret = ptsserver_ins_alloc(&ctx->ptsserver_id, &pIns, NULL);
+			if (ret < 0) {
+				v4l_dbg(ctx, 0, "%s Alloc pts server fail!\n", __func__);
+			}
+			ptsserver_set_mode(ctx->ptsserver_id, true);
+			ctx->pts_serves_ops = get_pts_server_ops();
+			if (ctx->pts_serves_ops == NULL) {
+				v4l_dbg(ctx, 0, "%s pts_serves_ops is NULL!\n", __func__);
+			}
+		}
+	} else if (ctrl->id == AML_V4L2_SET_ES_DMABUF_TYPE) {
+		ctx->output_dma_mode = ctrl->val;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+			"set dma buf mode: %x\n", ctrl->val);
+	}
 	return 0;
 }
 
@@ -4277,6 +4848,18 @@
 	.def	= 0,
 };
 
+static const struct v4l2_ctrl_config ctrl_set_dma_buf_mode = {
+	.name	= "dma buf mode",
+	.id	= AML_V4L2_SET_ES_DMABUF_TYPE,
+	.ops	= &aml_vcodec_dec_ctrl_ops,
+	.type	= V4L2_CTRL_TYPE_BOOLEAN,
+	.flags	= V4L2_CTRL_FLAG_WRITE_ONLY,
+	.min	= 0,
+	.max	= 1,
+	.step	= 1,
+	.def	= 0,
+};
+
 static const struct v4l2_ctrl_config ctrl_gt_input_buffer_number = {
 	.name	= "input buffer number",
 	.id	= AML_V4L2_GET_INPUT_BUFFER_NUM,
@@ -4289,6 +4872,17 @@
 	.def	= 0,
 };
 
+static const struct v4l2_ctrl_config ctrl_set_input_buffer_number_cache = {
+	.name	= "input buffer number cache",
+	.id	= AML_V4L2_SET_INPUT_BUFFER_NUM_CACHE,
+	.ops	= &aml_vcodec_dec_ctrl_ops,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.min	= 0,
+	.max	= 128,
+	.step	= 1,
+	.def	= 0,
+};
+
 static const struct v4l2_ctrl_config ctrl_st_duration = {
 	.name	= "duration",
 	.id	= AML_V4L2_SET_DURATION,
@@ -4301,6 +4895,18 @@
 	.def	= 0,
 };
 
+static const struct v4l2_ctrl_config ctrl_stream_mode = {
+	.name	= "stream mode",
+	.id	= AML_V4L2_SET_STREAM_MODE,
+	.ops	= &aml_vcodec_dec_ctrl_ops,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.flags	= V4L2_CTRL_FLAG_WRITE_ONLY,
+	.min	= 0,
+	.max	= 1,
+	.step	= 1,
+	.def	= 0,
+};
+
 static const struct v4l2_ctrl_config ctrl_gt_filmgrain_info = {
 	.name	= "filmgrain info",
 	.id	= AML_V4L2_GET_FILMGRAIN_INFO,
@@ -4313,6 +4919,56 @@
 	.def	= 0,
 };
 
+static const struct v4l2_ctrl_config ctrl_gt_bit_depth = {
+	.name	= "bitdepth",
+	.id	= AML_V4L2_GET_BITDEPTH,
+	.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_sgt_streamparm = {
+	.name	= "streamparm",
+	.id	= AML_V4L2_DEC_PARMS_CONFIG,
+	.ops	= &aml_vcodec_dec_ctrl_ops,
+	.type	= V4L2_CTRL_COMPOUND_TYPES,
+	.flags	= V4L2_CTRL_FLAG_VOLATILE,
+	.dims = { sizeof(struct aml_dec_params) },
+	.min	= 0,
+	.max	= 0xff,
+	.step	= 1,
+	.def	= 0,
+};
+
+static const struct v4l2_ctrl_config ctrl_get_inst_id = {
+	.name	= "Get instance id",
+	.id	= AML_V4L2_GET_INST_ID,
+	.ops	= &aml_vcodec_dec_ctrl_ops,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.flags	= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE,
+	.min	= 0,
+	.max	= 0x7fffffff,
+	.step	= 1,
+	.def	= 0,
+};
+
+static const struct v4l2_ctrl_config ctrl_gt_decoder_info = {
+	.name		= "decoder information",
+	.id		= AML_V4L2_GET_DECODER_INFO,
+	.ops		= &aml_vcodec_dec_ctrl_ops,
+	.type		= V4L2_CTRL_COMPOUND_TYPES,
+	.flags		= V4L2_CTRL_FLAG_VOLATILE,
+	.min		= 0,
+	.max		= sizeof(struct aml_decoder_status_info),
+	.step		= 1,
+	.elem_size	= 1,
+	.dims		= { sizeof(struct aml_decoder_status_info) },
+};
+
 int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
 {
 	int ret;
@@ -4345,24 +5001,66 @@
 		goto err;
 	}
 
+	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_set_dma_buf_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_set_input_buffer_number_cache, 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_stream_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_filmgrain_info, 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_decoder_info, 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_bit_depth, NULL);
+	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+		ret = ctx->ctrl_hdl.error;
+		goto err;
+	}
+
+	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_sgt_streamparm, NULL);
+	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+		ret = ctx->ctrl_hdl.error;
+		goto err;
+	}
+
+	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_get_inst_id, NULL);
+	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+		ret = ctx->ctrl_hdl.error;
+		goto err;
+	}
+
 	v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
 
 	return 0;
@@ -4404,31 +5102,89 @@
 	return 0;
 }
 
-static int check_dec_cfginfo(struct aml_vdec_cfg_infos *cfg)
+static void vidioc_vdec_g_parm_ext(struct v4l2_ctrl *ctrl,
+	struct aml_vcodec_ctx *ctx)
 {
-	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);
+	struct v4l2_streamparm parm = {0};
+
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	memcpy(&parm.parm.raw_data, ctrl->p_new.p, sizeof(parm.parm.raw_data));
+	vidioc_vdec_g_parm(NULL, &ctx->fh, &parm);
+	memcpy(ctrl->p_new.p, &parm.parm.raw_data, sizeof(parm.parm.raw_data));
+
+}
+
+static int vidioc_vdec_g_pixelaspect(struct file *file, void *fh,
+	int buf_type, struct v4l2_fract *aspect)
+{
+	struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
+	u32 height_aspect_ratio, width_aspect_ratio;
+
+	if ((aspect == NULL) || (ctx == NULL)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"GET_PARAM_PIXEL_ASPECT_INFO err\n");
+		return -EFAULT;
+	}
+
+	height_aspect_ratio = ctx->height_aspect_ratio;
+	width_aspect_ratio = ctx->width_aspect_ratio;
+
+	if ((height_aspect_ratio != 0) && (width_aspect_ratio != 0)) {
+		aspect->numerator = height_aspect_ratio;
+		aspect->denominator = width_aspect_ratio;
+	}
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s: numerator is %d, denominator is %d\n",
+		__func__, aspect->numerator, aspect->denominator);
+
+	return 0;
+}
+
+static int check_dec_cfginfo(struct aml_vcodec_ctx *ctx, struct aml_vdec_cfg_infos *cfg)
+{
+	if (cfg->double_write_mode != DM_AVBC_ONLY &&
+		cfg->double_write_mode != DM_YUV_1_1_AVBC &&
+		cfg->double_write_mode != DM_YUV_1_4_AVBC_A &&
+		cfg->double_write_mode != DM_YUV_1_4_AVBC_B &&
+		cfg->double_write_mode != DM_YUV_1_2_AVBC &&
+		cfg->double_write_mode != DM_YUV_ONLY &&
+		cfg->double_write_mode != DM_AVBC_1_1 &&
+		cfg->double_write_mode != DM_YUV_AUTO_1_2_AVBC &&
+		cfg->double_write_mode != DM_YUV_AUTO_1_4_AVBC &&
+		cfg->double_write_mode != DM_YUV_AUTO_14_12_AVBC &&
+		cfg->double_write_mode != DM_YUV_1_1_10BIT_AVBC &&
+		cfg->double_write_mode != DM_YUV_1_4_10BIT_AVBC &&
+		cfg->double_write_mode != DM_YUV_1_2_10BIT_AVBC &&
+		cfg->double_write_mode != DM_YUV_1_8_10BIT_AVBC &&
+		cfg->double_write_mode != DM_YUV_14_11_10BIT_AVBC) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid DW:0x%x\n", cfg->double_write_mode);
 		return -1;
 	}
+
+	if (cfg->triple_write_mode != DM_INVALID &&
+		cfg->triple_write_mode != DM_YUV_1_1_AVBC &&
+		cfg->triple_write_mode != DM_YUV_1_4_AVBC_A &&
+		cfg->triple_write_mode != DM_YUV_1_4_AVBC_B &&
+		cfg->triple_write_mode != DM_YUV_1_2_AVBC &&
+		cfg->triple_write_mode != DM_YUV_1_1_10BIT_AVBC &&
+		cfg->triple_write_mode != DM_YUV_1_4_10BIT_AVBC &&
+		cfg->triple_write_mode != DM_YUV_1_2_10BIT_AVBC &&
+		cfg->triple_write_mode != DM_YUV_1_8_10BIT_AVBC &&
+		cfg->triple_write_mode != DM_YUV_14_11_10BIT_AVBC) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid TW:0x%x\n", cfg->triple_write_mode);
+		return -1;
+	}
+
 	if (cfg->ref_buf_margin > 20) {
-		pr_err("invalid margin %d\n", cfg->ref_buf_margin);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "Invalid margin %d\n", cfg->ref_buf_margin);
 		return -1;
 	}
 
-	if (mandatory_dw_mmu) {
-		cfg->double_write_mode = 0x21;
-	}
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "DW:%x, TW:%x, Margin:%d\n",
+		cfg->double_write_mode,
+		cfg->triple_write_mode,
+		cfg->ref_buf_margin);
 
-	pr_info("double write mode %d margin %d\n",
-		cfg->double_write_mode, cfg->ref_buf_margin);
 	return 0;
 }
 
@@ -4459,10 +5215,17 @@
 		ctx->config.type = V4L2_CONFIG_PARM_DECODE;
 
 		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
-			if (check_dec_cfginfo(&in->cfg))
+			if (check_dec_cfginfo(ctx, &in->cfg))
 				return -EINVAL;
 			dec->cfg = in->cfg;
 		}
+
+		if (!vdec_if_set_param(ctx, SET_PARAM_CFG_INFO, &dec->cfg) &&
+			!vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
+			update_ctx_dimension(ctx, dst_vq->type);
+			aml_buf_configure_update(ctx);
+		}
+
 		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
 			dec->ps = in->ps;
 		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -4475,16 +5238,46 @@
 		/* 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;
+		if (force_enable_nr) {
+			if (force_enable_nr & 0x1)
+				ctx->vpp_cfg.enable_nr = true;
+			if (force_enable_nr & 0x2)
+				ctx->vpp_cfg.enable_nr = false;
+		}
 
 		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;
+		if (force_enable_di_local_buffer) {
+			if (force_enable_di_local_buffer & 0x1)
+				ctx->vpp_cfg.enable_local_buf = true;
+			if (force_enable_di_local_buffer & 0x2)
+				ctx->vpp_cfg.enable_local_buf = false;
+		}
+		ctx->vpp_cfg.dynamic_bypass_vpp =
+			dec->cfg.metadata_config_flag & (1 << 10);
+
+		ctx->vpp_cfg.early_release_flag = dec->cfg.metadata_config_flag & (1 << 18);
+
+		ctx->ge2d_cfg.bypass =
+			(dec->cfg.metadata_config_flag & (1 << 9));
+		ctx->vpp_cfg.bypass =
+			(dec->cfg.metadata_config_flag & (1 << 8));
+
+		if (ctx->ge2d_cfg.bypass || ctx->vpp_cfg.bypass)
+			v4l_buf_size_decision(ctx);
 
 		ctx->internal_dw_scale = dec->cfg.metadata_config_flag & (1 << 13);
 		ctx->second_field_pts_mode = dec->cfg.metadata_config_flag & (1 << 12);
+		ctx->force_di_permission = dec->cfg.metadata_config_flag & (1 << 17);
+		ctx->no_fbc_output = dec->cfg.metadata_config_flag & (1 << 19);
+		if (force_di_permission)
+			ctx->force_di_permission = true;
+
+		ctx->enable_di_post = dec->cfg.metadata_config_flag & (1 << 20);
+		if (enable_di_post) {
+			ctx->enable_di_post = true;
+		}
+		ctx->alloc_type = dec->cfg.metadata_config_flag & (1 << 21);
 
 		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);
@@ -4497,6 +5290,21 @@
 	return 0;
 }
 
+static void vidioc_vdec_s_parm_ext(struct v4l2_ctrl *ctrl,
+	struct aml_vcodec_ctx *ctx)
+{
+	struct v4l2_streamparm parm = {0};
+	struct vb2_queue *dst_vq;
+	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+	if (dst_vq->is_multiplanar == 1)
+		parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	else
+		parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	memcpy(&parm.parm.raw_data, ctrl->p_new.p, sizeof(parm.parm.raw_data));
+	vidioc_vdec_s_parm(NULL, &ctx->fh, &parm);
+}
 
 const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
 	.device_run	= m2mops_vdec_device_run,
@@ -4562,6 +5370,8 @@
 
 	.vidioc_g_parm			= vidioc_vdec_g_parm,
 	.vidioc_s_parm			= vidioc_vdec_s_parm,
+
+	.vidioc_g_pixelaspect		= vidioc_vdec_g_pixelaspect,
 };
 
 int aml_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
@@ -4575,11 +5385,11 @@
 	src_vq->type		= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	src_vq->drv_priv	= ctx;
-	src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
+	src_vq->buf_struct_size = sizeof(struct aml_v4l2_buf);
 	src_vq->ops		= &aml_vdec_vb2_ops;
 	src_vq->mem_ops		= &vb2_dma_sg_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->lock		= &ctx->dev->dev_mutex;
+	src_vq->lock		= &ctx->v4l_intf_lock;
 	ret = vb2_queue_init(src_vq);
 	if (ret) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -4591,11 +5401,11 @@
 					V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	dst_vq->io_modes	= VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	dst_vq->drv_priv	= ctx;
-	dst_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
+	dst_vq->buf_struct_size = sizeof(struct aml_v4l2_buf);
 	dst_vq->ops		= &aml_vdec_vb2_ops;
 	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->lock		= &ctx->v4l_intf_lock;
 	dst_vq->min_buffers_needed = 1;
 	ret = vb2_queue_init(dst_vq);
 	if (ret) {
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index 649c977..318d404 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -1,22 +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:
-*/
+ * 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_DEC_H_
 #define _AML_VCODEC_DEC_H_
 
@@ -25,9 +25,39 @@
 #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 <linux/amlogic/media/video_sink/v4lvideo_ext.h>
 #include "aml_vcodec_util.h"
 #include "aml_task_chain.h"
+#include "aml_buf_mgr.h"
+
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
+#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+#else
+struct metadata {
+	char *p_md;
+	char *p_comp;
+};
+
+struct file_private_data {
+	struct vframe_s vf;
+	struct vframe_s *vf_p;
+	bool is_keep;
+	int keep_id;
+	int keep_head_id;
+	struct file *file;
+	ulong vb_handle;
+	ulong v4l_dec_ctx;
+	u32 v4l_inst_id;
+	struct vframe_s vf_ext;
+	struct vframe_s *vf_ext_p;
+	u32 flag;
+	struct metadata md;
+	void *private;
+	struct file *cnt_file;
+};
+
+#endif
 
 #define VCODEC_CAPABILITY_4K_DISABLED	0x10
 #define VCODEC_DEC_4K_CODED_WIDTH	4096U
@@ -41,16 +71,20 @@
 #define VDEC_GATHER_MEMORY_TYPE		0
 #define VDEC_SCATTER_MEMORY_TYPE	1
 
-#define META_DATA_SIZE			(256)
+#define VDEC_META_DATA_SIZE			(256)
+#ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
 #define MD_BUF_SIZE			(1024)
 #define COMP_BUF_SIZE			(8196)
+#endif
 #define SEI_BUF_SIZE			(2 * 12 * 1024)
+#define HDR10P_BUF_SIZE			(128)
+
 #define SEI_TYPE	(1)
 #define DV_TYPE		(2)
-
+#define HDR10P_TYPE	(4)
 
 /*
- * struct vdec_v4l2_buffer - decoder frame buffer
+ * struct aml_buf - decoder frame buffer
  * @mem_type	: gather or scatter memory.
  * @num_planes	: used number of the plane
  * @mem[4]	: array mem for used planes,
@@ -61,8 +95,8 @@
  * @vframe	: store the vframe that get from caller.
  * @task	: the context of task chain manager.
  */
-
-struct vdec_v4l2_buffer {
+/*
+struct aml_buf {
 	int	mem_type;
 	int	num_planes;
 	union {
@@ -74,46 +108,70 @@
 	void	*vframe;
 
 	struct task_chain_s *task;
-};
+};*///todo
 
 /**
- * struct aml_video_dec_buf - Private data related to each VB2 buffer.
+ * struct aml_v4l2_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
  * @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
+ * @aml_buf:	Decode status, and buffer information of Capture buffer
  *
  * Note : These status information help us track and debug buffer state
  */
-struct aml_video_dec_buf {
+struct aml_v4l2_buf {
 	struct vb2_v4l2_buffer vb;
 	struct list_head list;
 
-	struct vdec_v4l2_buffer frame_buffer;
+	struct aml_buf *aml_buf;
 	struct file_private_data privdata;
 	struct codec_mm_s *mem[2];
-	char mem_onwer[32];
+	char mem_owner[32];
 	bool used;
-	bool que_in_m2m;
+	bool attached;
 	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];
-
+	char meta_data[VDEC_META_DATA_SIZE + 4];
+	void *dma_buf;
 	struct sg_table *out_sgt;
-	struct sg_table *cap_sgt;
+	ulong addr;
 };
 
+#define AML_ES_REF_MAX (1024)
+
+struct aml_es_mgr {
+	DECLARE_KFIFO_PTR(ref_q, typeof(struct aml_es_ref_elem*));
+	DECLARE_KFIFO_PTR(free_q, typeof(struct aml_es_ref_elem*));
+	void *elems;
+
+	/* The start position of unconsumed. */
+	ulong cursor_Wp;
+
+	ulong buf_start;
+	u32 buf_size;
+
+	struct aml_vcodec_ctx *ctx;
+	atomic_t buf_cache;
+};
+
+struct aml_es_ref_elem {
+	struct dma_buf *dbuf;
+	ulong buf_start;
+	u32 buf_size;
+	ulong au_addr;
+	u32 au_size;
+	u64 timestamp;
+};
+
+
 extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops aml_vdec_m2m_ops;
 
@@ -137,13 +195,40 @@
 void aml_v4l_vpp_release_early(struct aml_vcodec_ctx * ctx);
 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);
+ssize_t aml_buffer_status(struct aml_vcodec_ctx *ctx, char *buf);
+void aml_compressed_info_show(struct aml_vcodec_ctx *ctx);
+void cal_compress_buff_info(ulong used_page_num, struct aml_vcodec_ctx *ctx);
+
+ssize_t aml_vdec_basic_information(struct aml_vcodec_ctx *ctx, char *buf);
+void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
+		       struct aml_buf *aml_buf,
+		       u32 requester);
 
 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);
+void aml_bind_hdr10p_buffer(struct aml_vcodec_ctx *v4l, char **addr);
+
+int aml_canvas_cache_init(struct aml_vcodec_dev *dev);
+void aml_canvas_cache_put(struct aml_vcodec_dev *dev);
+int aml_canvas_cache_get(struct aml_vcodec_dev *dev, char *usr);
+int aml_uvm_buff_attach(struct vb2_buffer * vb);
+
+int aml_es_mgr_init(struct aml_vcodec_ctx *ctx);
+void aml_es_mgr_release(struct aml_vcodec_ctx *ctx);
+
+int aml_es_write(struct aml_vcodec_ctx *ctx, struct dma_buf *dbuf,
+			ulong addr, u32 size, u64 timestamp);
+
+void fbc_transcode_and_set_vf(struct aml_vcodec_ctx *ctx,
+						  struct aml_buf *aml_buf,
+						  struct vframe_s *vf);
+ssize_t dump_cma_and_sys_memsize(struct aml_vcodec_ctx *ctx, char *buf);
+
+ulong get_addr(struct vb2_buffer *vb, int i);
+
+
 
 #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 f92f4a8..cb78b57 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -1,23 +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:
-*/
-
+ * 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/slab.h>
 #include <linux/interrupt.h>
@@ -30,10 +29,15 @@
 #include <media/videobuf2-dma-contig.h>
 #include <linux/kthread.h>
 #include <linux/compat.h>
+#include <linux/version.h>
+#include <media/v4l2-dev.h>
+
 #include "aml_vcodec_drv.h"
 #include "aml_vcodec_dec.h"
 #include "aml_vcodec_util.h"
 #include "aml_vcodec_vpp.h"
+#include "../frame_provider/decoder/utils/decoder_report.h"
+
 #include <linux/file.h>
 #include <linux/anon_inodes.h>
 
@@ -51,35 +55,36 @@
 bool param_sets_from_ucode = 1;
 bool enable_drm_mode;
 extern void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx);
+char dump_path[32] = "/data";
 
 static int fops_vcodec_open(struct file *file)
 {
 	struct aml_vcodec_dev *dev = video_drvdata(file);
 	struct aml_vcodec_ctx *ctx = NULL;
-	struct aml_video_dec_buf *aml_buf = NULL;
-	int ret = 0;
+	struct aml_v4l2_buf *aml_vb = NULL;
 	struct vb2_queue *src_vq;
+	int ret = 0;
 
 	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) {
+	aml_vb = kzalloc(sizeof(*aml_vb), GFP_KERNEL);
+	if (!aml_vb) {
 		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(aml_vb);
 		kfree(ctx);
 		return -ENOMEM;
 	}
 
 	mutex_lock(&dev->dev_mutex);
-	ctx->empty_flush_buf = aml_buf;
+	ctx->empty_flush_buf = aml_vb;
 	ctx->id = dev->id_counter++;
 	v4l2_fh_init(&ctx->fh, video_devdata(file));
 	file->private_data = &ctx->fh;
@@ -94,19 +99,27 @@
 	mutex_init(&ctx->buff_done_lock);
 	mutex_init(&ctx->state_lock);
 	mutex_init(&ctx->comp_lock);
+	mutex_init(&ctx->compressed_buf_info_lock);
 	spin_lock_init(&ctx->slock);
 	spin_lock_init(&ctx->tsplock);
-	spin_lock_init(&ctx->dmabuff_recycle_lock);
+	spin_lock_init(&ctx->es_wkr_slock);
 	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_WORK(&ctx->es_wkr_out, dmabuff_recycle_worker);
 	INIT_KFIFO(ctx->dmabuff_recycle);
 	INIT_KFIFO(ctx->capture_buffer);
+	atomic_set(&ctx->vpp_cache_num, 0);
+	atomic_set(&ctx->ge2d_cache_num, 0);
+	mutex_init(&ctx->v4l_intf_lock);
 
 	ctx->post_to_upper_done = true;
 	ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0;
+	ctx->cache_input_buffer_num = 60;
+	ctx->write_frames = 0;
+
+	aml_es_mgr_init(ctx);
 
 	if (enable_drm_mode) {
 		ctx->is_drm_mode = true;
@@ -134,9 +147,11 @@
 	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;
+	ctx->cal_compress_buff_info = cal_compress_buff_info;
+	ctx->fbc_transcode_and_set_vf = fbc_transcode_and_set_vf;
 	aml_vcodec_dec_set_default_params(ctx);
 	ctx->is_stream_off = true;
-
+	ctx->set_ext_buf_flg = false;
 	ctx->aux_infos.dv_index = 0;
 	ctx->aux_infos.sei_index = 0;
 	ctx->aux_infos.alloc_buffer = aml_alloc_buffer;
@@ -144,6 +159,14 @@
 	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;
+	ctx->aux_infos.bind_hdr10p_buffer = aml_bind_hdr10p_buffer;
+
+	ret = aml_buf_mgr_init(&ctx->bm, "v4ldec-m2m", ctx->id, ctx);
+	if (ret) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"Failed to init buffer manager.\n");
+		goto err_buffer_manager;
+	}
 
 	ret = aml_thread_start(ctx, aml_thread_capture_worker, AML_THREAD_CAPTURE, "cap");
 	if (ret) {
@@ -154,8 +177,10 @@
 
 	list_add(&ctx->list, &dev->ctx_list);
 
+	ctx->dv_id = -1;
+
 	mutex_unlock(&dev->dev_mutex);
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n",
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "%s decoder %lx\n",
 		dev_name(&dev->plat_dev->dev), (ulong)ctx);
 
 	return 0;
@@ -163,6 +188,8 @@
 	/* Deinit when failure occurred */
 err_creat_thread:
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
+err_buffer_manager:
+	aml_buf_mgr_release(&ctx->bm);
 err_m2m_ctx_init:
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 err_ctrls_setup:
@@ -181,9 +208,8 @@
 	struct aml_vcodec_dev *dev = video_drvdata(file);
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR, "release decoder %lx\n", (ulong) ctx);
 	mutex_lock(&dev->dev_mutex);
-
 	aml_thread_stop(ctx);
 	wait_vcodec_ending(ctx);
 	vb2_queue_release(&ctx->m2m_ctx->cap_q_ctx.q);
@@ -197,6 +223,7 @@
 	list_del_init(&ctx->list);
 
 	kfree(ctx->empty_flush_buf);
+	aml_buf_mgr_release(&ctx->bm);
 	aml_v4l_vpp_release_early(ctx);
 	kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
 	mutex_unlock(&dev->dev_mutex);
@@ -241,7 +268,7 @@
 		kzalloc(sizeof(struct file_private_data), GFP_KERNEL);
 	if (!file->private_data) {
 		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"alloc priv data faild.\n");
+			"alloc priv data failed.\n");
 		return -ENOMEM;
 	}
 
@@ -464,10 +491,11 @@
 
 	list_for_each_entry(ctx, &dev->ctx_list, list) {
 		/* basic information. */
-		aml_vdec_basic_information(ctx);
+		pbuf += aml_vdec_basic_information(ctx, pbuf);
 
 		/* buffers status. */
-		aml_buffer_status(ctx);
+		pbuf += aml_buffer_status(ctx, pbuf);
+		pbuf += dump_cma_and_sys_memsize(ctx, pbuf);
 	}
 out:
 	mutex_unlock(&dev->dev_mutex);
@@ -475,10 +503,64 @@
 	return pbuf - buf;
 }
 
+ssize_t show_v4ldec_state(struct aml_vcodec_dev *dev, char *buf) {
+	return status_show(&dev->v4ldec_class, NULL, buf);
+}
+EXPORT_SYMBOL(show_v4ldec_state);
+
+static ssize_t mmu_mem_info_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) {
+		aml_compressed_info_show(ctx);
+	}
+out:
+	mutex_unlock(&dev->dev_mutex);
+
+	return pbuf - buf;
+}
+
+static ssize_t dump_path_show(struct class *class,
+		struct class_attribute *attr, char *buf)
+{
+	return snprintf(buf, sizeof(dump_path), "%s\n", dump_path);
+}
+
+static ssize_t dump_path_store(struct class *class,
+		struct class_attribute *attr,
+		const char *buf, size_t size)
+{
+	ssize_t n;
+	if (size > sizeof(dump_path))
+		pr_err("path too long\n");
+	n = snprintf(dump_path, sizeof(dump_path), "%s", buf);
+	if (n > 0 && dump_path[n-1] == '\n') {
+		dump_path[n-1] = 0;
+		pr_info("dump path changed to %s\n", dump_path);
+	}
+	return size;
+}
+
 static CLASS_ATTR_RO(status);
+static CLASS_ATTR_RO(mmu_mem_info);
+static CLASS_ATTR_RW(dump_path);
 
 static struct attribute *v4ldec_class_attrs[] = {
 	&class_attr_status.attr,
+	&class_attr_dump_path.attr,
+	&class_attr_mmu_mem_info.attr,
 	NULL
 };
 
@@ -543,7 +625,7 @@
 	}
 
 	dev->decode_workqueue =
-		alloc_ordered_workqueue("output-worker",
+		alloc_ordered_workqueue("dec-worker",
 			__WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
 	if (!dev->decode_workqueue) {
 		dev_err(&pdev->dev, "Failed to create decode workqueue\n");
@@ -553,7 +635,11 @@
 
 	//dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
 	ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26);
+#else
+	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 26);
+#endif
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register video device\n");
 		goto err_dec_reg;
@@ -569,18 +655,26 @@
 		goto err_reg_class;
 	}
 
+	ret = aml_canvas_cache_init(dev);
+	if (ret) {
+		dev_err(&pdev->dev, "v4l dec alloc canvas fail.\n");
+		goto err_alloc_canvas;
+	}
+	register_dump_v4ldec_state_func(dev, show_v4ldec_state);
 	dev_info(&pdev->dev, "v4ldec registered as /dev/video%d\n", vfd_dec->num);
 
 	return 0;
 
-err_reg_class:
+err_alloc_canvas:
 	class_unregister(&dev->v4ldec_class);
+err_reg_class:
+	video_unregister_device(vfd_dec);
 err_dec_reg:
 	destroy_workqueue(dev->decode_workqueue);
 err_event_workq:
 	v4l2_m2m_release(dev->m2m_dev_dec);
 err_dec_mem_init:
-	video_unregister_device(vfd_dec);
+	video_device_release(vfd_dec);
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
@@ -605,6 +699,8 @@
 
 	v4l2_device_unregister(&dev->v4l2_dev);
 
+	aml_canvas_cache_put(dev);
+
 	dev_info(&pdev->dev, "v4ldec removed.\n");
 
 	return 0;
@@ -628,7 +724,8 @@
 
 static int __init amvdec_ports_init(void)
 {
-	pr_info("v4l dec module init\n");
+	v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+		"v4l dec module init\n");
 
 	if (platform_driver_register(&aml_vcodec_dec_driver)) {
 		pr_err("failed to register v4l dec driver\n");
@@ -652,9 +749,13 @@
 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);
+int t3x_tw_output;
+EXPORT_SYMBOL(t3x_tw_output);
+module_param(t3x_tw_output, int, 0644);
+
+u32 disable_vpp_dw_mmu;
+EXPORT_SYMBOL(disable_vpp_dw_mmu);
+module_param(disable_vpp_dw_mmu, uint, 0644);
 
 bool aml_set_vfm_enable;
 EXPORT_SYMBOL(aml_set_vfm_enable);
@@ -726,6 +827,10 @@
 EXPORT_SYMBOL(bypass_progressive);
 module_param(bypass_progressive, int, 0644);
 
+int force_di_permission;
+EXPORT_SYMBOL(force_di_permission);
+module_param(force_di_permission, int, 0644);
+
 bool support_mjpeg;
 EXPORT_SYMBOL(support_mjpeg);
 module_param(support_mjpeg, bool, 0644);
@@ -742,6 +847,14 @@
 EXPORT_SYMBOL(force_enable_di_local_buffer);
 module_param(force_enable_di_local_buffer, int, 0644);
 
+int es_node_expand = 1;
+EXPORT_SYMBOL(es_node_expand);
+module_param(es_node_expand, int, 0644);
+
+int dump_es_output_frame;
+EXPORT_SYMBOL(dump_es_output_frame);
+module_param(dump_es_output_frame, int, 0644);
+
 int vpp_bypass_frames;
 EXPORT_SYMBOL(vpp_bypass_frames);
 module_param(vpp_bypass_frames, int, 0644);
@@ -750,6 +863,14 @@
 EXPORT_SYMBOL(bypass_nr_flag);
 module_param(bypass_nr_flag, int, 0644);
 
+u32 trace_config = 0xffffffff;
+EXPORT_SYMBOL(trace_config);
+module_param(trace_config, uint, 0644);
+
+int enable_di_post;
+EXPORT_SYMBOL(enable_di_post);
+module_param(enable_di_post, 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..32a3c2b 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -1,22 +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:
-*/
+ * 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_DRV_H_
 #define _AML_VCODEC_DRV_H_
 
@@ -30,9 +30,13 @@
 #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 <media/v4l2-mem2mem.h>
+//#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
+
+#include "utils/aml_dec_trace.h"
 #include "aml_vcodec_util.h"
 #include "aml_vcodec_dec.h"
+#include "aml_vcodec_ts.h"
 
 #define AML_VCODEC_DRV_NAME	"aml_vcodec_drv"
 #define AML_VCODEC_DEC_NAME	"aml-vcodec-dec"
@@ -62,6 +66,9 @@
 /* exception handing */
 #define V4L2_EVENT_REQUEST_RESET	(1 << 8)
 #define V4L2_EVENT_REQUEST_EXIT		(1 << 9)
+#define V4L2_EVENT_SEND_ERROR		(1 << 10)
+#define V4L2_EVENT_REPORT_ERROR_FRAME	(1 << 11)
+
 
 /* eos event */
 #define V4L2_EVENT_SEND_EOS		(1 << 16)
@@ -87,6 +94,10 @@
 #define TRANS_ABORT		(1 << 2)
 
 #define CTX_BUF_TOTAL(ctx) (ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size)
+
+#define MAX_AVBC_BUFFER_SIZE	16
+
+#define MAX_VPP_BUFFER_CACHE_NUM 16
 /**
  * enum aml_hw_reg_idx - AML hw register base index
  */
@@ -197,6 +208,10 @@
 	enum v4l2_field	field;
 	u32	bytesperline[AML_VCODEC_MAX_PLANES];
 	u32	sizeimage[AML_VCODEC_MAX_PLANES];
+
+	u32	bytesperline_tw[AML_VCODEC_MAX_PLANES];
+	u32	sizeimage_tw[AML_VCODEC_MAX_PLANES];
+
 	struct aml_video_fmt	*fmt;
 	bool resolution_changed;
 };
@@ -241,7 +256,7 @@
  * @visible_width: picture width
  * @visible_height: picture height
  * @coded_width: picture buffer width (64 aligned up from pic_w)
- * @coded_height: picture buffer heiht (64 aligned up from pic_h)
+ * @coded_height: picture buffer height (64 aligned up from pic_h)
  * @y_bs_sz: Y bitstream size
  * @c_bs_sz: CbCr bitstream size
  * @y_len_sz: additional size required to store decompress information for y
@@ -265,17 +280,20 @@
 	u32 c_bs_sz;
 	u32 y_len_sz;
 	u32 c_len_sz;
+	u32 y_len_sz_tw;
+	u32 c_len_sz_tw;
 	int profile_idc;
 	enum v4l2_field field;
 	u32 dpb_frames;
 	u32 dpb_margin;
 	u32 vpp_margin;
+	u32 bitdepth;
 };
 
 /**
  * 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
+ * @header_size: continuous size for the compressed header
  * @frame_buffer_size: SG page number to store the frame
  */
 struct vdec_comp_buf_info {
@@ -294,18 +312,28 @@
 	u32 low_latency_mode;
 	u32 uvm_hook_type;
 	/*
+	 * bit 21	: buffer alloc flag. 0: dma heap, 1: ion heap.
+	 * bit 20	: di post flag.
+	 * bit 19	: no-surface flag.
+	 * bit 18	: release vpp early. 0:false, 1:true
+	 * bit 17	: force di permission.
 	 * 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 11	: disable error policy.
+	 * bit 10	: dynamic bypass vpp.
+	 * bit 9	: disable ge2d wrapper.
+	 * bit 8	: disable vpp wrapper.
 	 * 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];
+	u32 triple_write_mode;
+	u32 dv_profile;
+	u32 data[2];
 };
 
 struct aml_vdec_hdr_infos {
@@ -342,7 +370,8 @@
 	u32 dpb_frames;
 	u32 dpb_margin;
 	u32 field;
-	u32 data[3];
+	u32 bitdepth;
+	u32 data[2];
 };
 
 struct aml_vdec_cnt_infos {
@@ -382,6 +411,15 @@
 	u32 dec, vpp, ge2d;
 };
 
+struct v4l_compressed_buffer_info {
+	u64	used_page_sum;
+	u32	recycle_num;
+	u32	used_page_distributed_array[MAX_AVBC_BUFFER_SIZE];
+	u32	used_page_in_group[V4L_CAP_BUFF_MAX];
+	u32	max_avg_val_by_group;
+	u32	used_page_by_group;
+};
+
 enum aml_thread_type {
 	AML_THREAD_OUTPUT,
 	AML_THREAD_CAPTURE,
@@ -427,10 +465,14 @@
 	ulong	header_dw_addr;
 	void	*mmu_box_dw;
 	void	*bmmu_box_dw;
+#ifdef NEW_FB_CODE
+	void	*mmu_box_1;
+	void	*mmu_box_dw_1;
+#endif
 };
 
 /*
- * struct aml_uvm_buff_ref - uvm buff is used reseve ctx ref count.
+ * struct aml_uvm_buff_ref - uvm buff is used reserve ctx ref count.
  * @index	: index of video buffer.
  * @addr	: physic address of video buffer.
  * @ref		: reference of v4ldec context.
@@ -444,7 +486,7 @@
 };
 
 /*
- * enum aml_fb_requester - indicate which module request fb buffers.
+ * enum aml_fb_requester - indicate which module request aml_buf buffers.
  */
 enum aml_fb_requester {
 	AML_FB_REQ_DEC,
@@ -454,12 +496,12 @@
 };
 
 /*
- * @query: try to achieved fb token.
- * @alloc: used for allocte fb buffer.
+ * @query: try to achieved aml_buf token.
+ * @alloc: used for allocte aml_buf buffer.
  */
 struct aml_fb_ops {
 	bool		(*query)(struct aml_fb_ops *, ulong *);
-	int		(*alloc)(struct aml_fb_ops *, ulong, struct vdec_v4l2_buffer **, u32);
+	int		(*alloc)(struct aml_fb_ops *, ulong, struct aml_buf **, u32);
 };
 
 /*
@@ -492,12 +534,14 @@
 	int		sei_state;
 	char*		comp_buf;
 	char*		md_buf;
+	char*		hdr10p_buf;
 };
 
 /*
  * struct aux_info - record aux data infos
  * @sei_index:		sei data index.
  * @dv_index:		dv data index.
+ * @hdr10p_index:	hdr10p data index.
  * @sei_need_free:	sei buffer need to free.
  * @bufs:		stores aux data.
  * @alloc_buffer:	alloc aux buffer functions.
@@ -505,10 +549,12 @@
  * @free_one_sei_buffer:free sei buffer with index functions.
  * @bind_sei_buffer:	bind sei buffer functions.
  * @bind_dv_buffer:	bind dv buffer functions.
+ * @bind_hdr10p_buffer:	bind hdr10p buffer functions.
  */
 struct aux_info {
 	int	sei_index;
-	int 	dv_index;
+	int	dv_index;
+	int	hdr10p_index;
 	bool    sei_need_free;
 	struct aux_data bufs[V4L_CAP_BUFF_MAX];
 	void 	(*alloc_buffer)(struct aml_vcodec_ctx *ctx, int flag);
@@ -516,14 +562,15 @@
 	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);
+	void	(*bind_hdr10p_buffer)(struct aml_vcodec_ctx *ctx, char **addr);
 };
 
 /*
  * struct meta_data - record meta data.
- * @buf[META_DATA_SIZE]: meta data information.
+ * @buf[VDEC_META_DATA_SIZE]: meta data information.
  */
 struct meta_data {
-	char buf[META_DATA_SIZE];
+	char buf[VDEC_META_DATA_SIZE];
 };
 
 /*
@@ -560,12 +607,45 @@
 	bool	enable_local_buf;
 	bool	res_chg;
 	bool	is_vpp_reset;
+	bool	dynamic_bypass_vpp;
+	bool	early_release_flag;
+	bool	bypass;
 };
 
 struct aml_ge2d_cfg_infos {
 	u32	mode;
 	u32	buf_size;
 	bool	is_drm;
+	bool	bypass;
+};
+
+struct canvas_res {
+	int			cid;
+	u8			name[32];
+};
+
+struct canvas_cache {
+	int			ref;
+	struct canvas_res	res[8];
+	struct mutex		lock;
+};
+
+struct aml_decoder_status_info {
+	u32 error_type;
+	u32 frame_width;
+	u32 frame_height;
+	u32 decoder_count;
+	u32 decoder_error_count;
+};
+
+struct cma_sys_size_info {
+	int max_total_size;
+	int cma_part;
+	int sys_part;
+	int max_cma_size;
+	int max_sys_size;
+	int cur_cma_size;
+	int cur_sys_size;
 };
 
 /*
@@ -589,7 +669,7 @@
  * @queue: waitqueue that can be used to wait for this context to finish.
  * @state_lock: protect the codec status.
  * @state: state of the context.
- * @decode_work: decoder work be used to output buffer.
+
  * @output_thread_ready: indicate the output thread ready.
  * @cap_pool: capture buffers are remark in the pool.
  * @vdec_thread_list: vdec thread be used to capture.
@@ -598,7 +678,8 @@
  * @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.
- # @v4l_resolution_change: indicate resolution change happend.
+ * @dst_queue_streaming: the state of the destination queue.
+ * @v4l_resolution_change: indicate resolution change happened.
  * @comp: comp be used for sync picture information with decoder.
  * @config: used to set or get parms for application.
  * @picinfo: store picture info after header parsing.
@@ -619,8 +700,10 @@
  * @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.
+ * @es_wkr_in: Used to write es buffer from v4l2 core to decoder.
+ * @es_wkr_out: Used to recover the es buffer consumed by the decoder.
+ * @es_wkr_slock: Ensure the data access security of the es buffer work queue.
+ * @es_wkr_stop: Indicates that the es work queue stops working.
  * @dmabuff_recycle: kfifo used for store vb buff.
  * @capture_buffer: kfifo used for store capture vb buff.
  * @mmu_box: mmu_box of context.
@@ -636,6 +719,9 @@
  * @vpp_is_need: the instance is need vpp.
  * @task_chain_pool: used to store task chain inst.
  * @index_disp: the number of frames output.
+ * @buffer manager context.
+ * @force_report_interlace: the flag for conversion field.
+ * @force_tw_output: The flag for T3X output TW YUV.
  */
 struct aml_vcodec_ctx {
 	int				id;
@@ -651,14 +737,13 @@
 	struct v4l2_ctrl_handler	ctrl_hdl;
 	spinlock_t			slock;
 	spinlock_t			tsplock;
-	struct aml_video_dec_buf	*empty_flush_buf;
+	struct aml_v4l2_buf		*empty_flush_buf;
 	struct list_head		list;
 
 	struct aml_q_data		q_data[2];
 	wait_queue_head_t		queue;
 	struct mutex			state_lock;
 	enum aml_instance_state		state;
-	struct work_struct		decode_work;
 	bool				output_thread_ready;
 	struct v4l_buff_pool		cap_pool;
 	struct list_head		vdec_thread_list;
@@ -668,6 +753,7 @@
 	int				ge2d_size;
 	bool				param_sets_from_ucode;
 	bool				v4l_codec_dpb_ready;
+	bool				dst_queue_streaming;
 	bool				v4l_resolution_change;
 	struct completion		comp;
 	struct v4l2_config_parm		config;
@@ -691,9 +777,13 @@
 	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;
+
+	struct work_struct		es_wkr_in;
+	struct work_struct		es_wkr_out;
+	spinlock_t			es_wkr_slock;
+	bool				es_wkr_stop;
+
 	DECLARE_KFIFO(dmabuff_recycle, struct vb2_v4l2_buffer *, 32);
 	DECLARE_KFIFO(capture_buffer, struct vb2_v4l2_buffer *, 32);
 
@@ -724,12 +814,59 @@
 	bool				ge2d_is_need;
 
 	bool 				second_field_pts_mode;
+	bool				force_di_permission;
 	struct aux_info			aux_infos;
+	u32				capture_memory_mode;
+	u32				height_aspect_ratio;
+	u32				width_aspect_ratio;
 	u32				index_disp;
 	bool				post_to_upper_done;
 	bool			film_grain_present;
 	void			*bmmu_box_dw;
 	void			*mmu_box_dw;
+
+	void (*cal_compress_buff_info)(ulong, struct aml_vcodec_ctx *ctx);
+	struct mutex			compressed_buf_info_lock;
+	struct v4l_compressed_buffer_info	compressed_buf_info;
+
+	u32				stream_mode;
+	bool				set_ext_buf_flg;
+	s32				ptsserver_id;
+	struct pts_server_ops			*pts_serves_ops;
+
+	struct aml_buf_mgr_s		bm;
+	void (*vdec_recycle_dec_resource)(void *, struct aml_buf *);
+
+	atomic_t		vpp_cache_num;
+	atomic_t		ge2d_cache_num;
+	int 			cache_input_buffer_num;
+	int			in_buff_cnt;
+	int			out_buff_cnt;
+	int                     write_frames;
+	u64			current_timestamp;
+	bool			force_recycle;
+
+	struct vdec_trace		vtr;
+	int dv_id;
+	struct aml_es_mgr	es_mgr;
+	void (*es_free)(struct aml_vcodec_ctx *, ulong);
+	bool			v4l_reqbuff_flag;
+#ifdef NEW_FB_CODE
+	int 			front_back_mode;
+	void			*mmu_box_1;
+	void			*mmu_box_dw_1;
+#endif
+	struct mutex		v4l_intf_lock;
+	void (*fbc_transcode_and_set_vf)(struct aml_vcodec_ctx *,  struct aml_buf *,
+						  struct vframe_s *);
+	bool			no_fbc_output;
+	bool			force_report_interlace;
+	struct cma_sys_size_info mem_size_info;
+	struct aml_decoder_status_info	decoder_status_info;
+	struct aml_buf		*master_buf;
+	bool			enable_di_post;
+	u32			alloc_type;
+	bool			force_tw_output;
 };
 
 /**
@@ -748,7 +885,8 @@
  * @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.
+ * @v4ldec_class	: creat class sysfs used to show some information.
+ * @cache		: canvas pool specific used for v4ldec context.
  */
 struct aml_vcodec_dev {
 	struct v4l2_device		v4l2_dev;
@@ -767,6 +905,7 @@
 	wait_queue_head_t		queue;
 	atomic_t			vpp_count;
 	struct class			v4ldec_class;
+	struct canvas_cache		cache;
 };
 
 static inline struct aml_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
@@ -784,5 +923,31 @@
 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 aml_vdec_recycle_dec_resource(struct aml_vcodec_ctx * ctx,
+					struct aml_buf *aml_buf);
+typedef ssize_t (*dump_v4ldec_state_func)(struct aml_vcodec_dev *dev, char *);
+
+/*
+ * v4l2_m2m_job_pause() - paused the schedule of data which from the job queue.
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+void v4l2_m2m_job_pause(struct v4l2_m2m_dev *m2m_dev,
+			struct v4l2_m2m_ctx *m2m_ctx);
+
+ /*
+  * v4l2_m2m_job_resume() - resumed the schedule of data which from the job que.
+  *
+  * @m2m_dev: opaque pointer to the internal data to handle M2M context
+  * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+  */
+void v4l2_m2m_job_resume(struct v4l2_m2m_dev *m2m_dev,
+			 struct v4l2_m2m_ctx *m2m_ctx);
+
+#define V4L2_PIX_FMT_AV1      v4l2_fourcc('A', 'V', '1', '0') /* av1 */
+#define V4L2_PIX_FMT_AVS      v4l2_fourcc('A', 'V', 'S', '0') /* avs */
+#define V4L2_PIX_FMT_AVS2     v4l2_fourcc('A', 'V', 'S', '2') /* avs2 */
+#define V4L2_PIX_FMT_AVS3     v4l2_fourcc('A', 'V', 'S', '3') /* avs3 */
 
 #endif /* _AML_VCODEC_DRV_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.c b/drivers/amvdec_ports/aml_vcodec_ge2d.c
index 2d331ed..8a5a6d3 100644
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.c
+++ b/drivers/amvdec_ports/aml_vcodec_ge2d.c
@@ -1,23 +1,22 @@
 /*
-* 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:
-*/
-
+ * 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/delay.h>
 #include <linux/videodev2.h>
@@ -27,20 +26,22 @@
 #include <linux/amlogic/media/ge2d/ge2d.h>
 #include <linux/amlogic/media/canvas/canvas_mgr.h>
 
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
 #include "../common/chips/decoder_cpu_ver_info.h"
 #include "aml_vcodec_ge2d.h"
 #include "aml_vcodec_adapt.h"
 #include "vdec_drv_if.h"
+#include "utils/common.h"
+#include "../common/media_utils/media_utils.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_vb->vb.vb2_buf.index)
 
-#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;
+extern char dump_path[32];
 
 enum GE2D_FLAG {
 	GE2D_FLAG_P		= 0x1,
@@ -100,11 +101,11 @@
 static int get_input_format(struct vframe_s *vf)
 {
 	int format = GE2D_FORMAT_M24_YUV420;
-	enum videocom_source_type soure_type;
+	enum videocom_source_type source_type;
 
-	soure_type = get_source_type(vf);
+	source_type = get_source_type(vf);
 
-	switch (soure_type) {
+	switch (source_type) {
 	case DECODER_8BIT_NORMAL:
 		if (vf->type & VIDTYPE_VIU_422)
 			format = GE2D_FORMAT_S16_YUV422;
@@ -189,10 +190,16 @@
 	return format;
 }
 
+static void update_ge2d_num_cache(struct aml_v4l2_ge2d *ge2d)
+{
+	atomic_set(&ge2d->ctx->ge2d_cache_num,
+		GE2D_FRAME_SIZE - kfifo_len(&ge2d->input));
+}
+
 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;
+	struct aml_buf *aml_buf = NULL;
 	bool eos = false;
 
 	if (!ge2d || !ge2d->ctx) {
@@ -202,12 +209,19 @@
 		return -1;
 	}
 
-	fb 	= &buf->aml_buf->frame_buffer;
+	if (ge2d->ctx->is_stream_off) {
+		v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_EXINFO,
+			"ge2d discard recycle frame %s %d ge2d:%p\n",
+			__func__, __LINE__, ge2d);
+		return -1;
+	}
+
+	aml_buf 	= buf->aml_vb->aml_buf;
 	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",
+		"in:%d, out:%d, vf:%d, in done:%d, out done:%d, ge2d_cache_num:%d\n",
 		buf->vf,
 		buf->vf->index,
 		buf->vf->flag,
@@ -218,13 +232,16 @@
 		kfifo_len(&ge2d->output),
 		kfifo_len(&ge2d->frame),
 		kfifo_len(&ge2d->in_done_q),
-		kfifo_len(&ge2d->out_done_q));
+		kfifo_len(&ge2d->out_done_q),
+		atomic_read(&ge2d->ctx->ge2d_cache_num));
 
-	fb->task->recycle(fb->task, TASK_TYPE_GE2D);
+	aml_buf_fill(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D);
 
 	kfifo_put(&ge2d->input, buf);
+	update_ge2d_num_cache(ge2d);
 
-	ATRACE_COUNTER("VC_IN_GE2D-1.recycle", fb->buf_idx);
+	vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_6, atomic_read(&ge2d->ctx->ge2d_cache_num));
+	vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_1, aml_buf->index);
 
 	return 0;
 }
@@ -232,7 +249,7 @@
 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;
+	struct aml_buf *aml_buf = NULL;
 	bool bypass = false;
 	bool eos = false;
 
@@ -243,15 +260,30 @@
 		return -1;
 	}
 
-	fb	= &buf->aml_buf->frame_buffer;
+	if (ge2d->ctx->is_stream_off) {
+		v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_EXINFO,
+			"ge2d discard submit frame %s %d ge2d:%p\n",
+			__func__, __LINE__, ge2d);
+		return -1;
+	}
+
+	aml_buf	= buf->aml_vb->aml_buf;
 	eos	= (buf->flag & GE2D_FLAG_EOS);
 	bypass	= (buf->flag & GE2D_FLAG_BUF_BY_PASS);
 
-	/* recovery fb handle. */
-	buf->vf->v4l_mem_handle = (ulong)fb;
+	/* recovery aml_buf handle. */
+	buf->vf->v4l_mem_handle = (ulong)aml_buf;
 
 	kfifo_put(&ge2d->out_done_q, buf);
 
+	if (aml_buf->ge2d_buf == NULL) {
+		aml_buf->ge2d_buf = vzalloc(sizeof(struct aml_v4l2_ge2d_buf));
+	}
+
+	if (aml_buf->ge2d_buf)
+		memcpy((struct aml_v4l2_ge2d_buf *)(aml_buf->ge2d_buf), buf,
+			sizeof(struct aml_v4l2_ge2d_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",
@@ -268,20 +300,20 @@
 		kfifo_len(&ge2d->out_done_q),
 		buf->vf->width, buf->vf->height);
 
-	ATRACE_COUNTER("VC_OUT_GE2D-2.submit", fb->buf_idx);
+	vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_4, aml_buf->index);
 
-	fb->task->submit(fb->task, TASK_TYPE_GE2D);
+	aml_buf_done(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D);
 
 	ge2d->out_num[OUTPUT_PORT]++;
 
 	return 0;
 }
 
-static void ge2d_vf_get(void *caller, struct vframe_s **vf_out)
+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 aml_buf *aml_buf = NULL;
 	struct vframe_s *vf = NULL;
 	bool bypass = false;
 	bool eos = false;
@@ -294,7 +326,7 @@
 	}
 
 	if (kfifo_get(&ge2d->out_done_q, &buf)) {
-		fb	= &buf->aml_buf->frame_buffer;
+		aml_buf	= buf->aml_vb->aml_buf;
 		eos	= (buf->flag & GE2D_FLAG_EOS);
 		bypass	= (buf->flag & GE2D_FLAG_BUF_BY_PASS);
 		vf	= buf->vf;
@@ -307,9 +339,36 @@
 			vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
 		}
 
-		*vf_out = vf;
+		if (ge2d->ctx->enable_di_post) {
+			if (is_cpu_t7()) {
+				if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
+					if ((ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
+						(ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
+						(ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
+						(ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
+						(ge2d->ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
+						vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+					}
+					else {
+						if (aml_buf->state == 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;
+			}
+		}
 
-		ATRACE_COUNTER("VC_OUT_GE2D-3.vf_get", fb->buf_idx);
+		memcpy(vf_out, vf, sizeof(struct vframe_s));
+
+		mutex_lock(&ge2d->output_lock);
+		kfifo_put(&ge2d->frame, vf);
+		kfifo_put(&ge2d->output, buf);
+		mutex_unlock(&ge2d->output_lock);
+		up(&ge2d->sem_out);
+
+		vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_5, aml_buf->index);
 
 		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",
@@ -323,34 +382,7 @@
 
 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)
@@ -367,7 +399,7 @@
 		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;
+		struct aml_buf *aml_buf;
 
 		if (down_interruptible(&ge2d->sem_in))
 			goto exit;
@@ -389,37 +421,28 @@
 		}
 		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;
+		aml_buf = aml_buf_get(&ctx->bm, BUF_USER_GE2D, false);
+		if (!aml_buf) {
+			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_vb =
+			container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
+		#if 0
+		memcpy(&out_buf->aml_vb->ge2d_buf, out_buf,
+					sizeof(struct aml_v4l2_ge2d_buf));
+		#endif
+		v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
+			"ge2d bind buf:%d to ge2d_buf:%px\n",
+			GE2D_BUF_GET_IDX(out_buf), out_buf);
+
+		aml_buf->planes[0].bytes_used = aml_buf->planes[0].length;
+		aml_buf->planes[1].bytes_used = aml_buf->planes[1].length;
+
 		/* safe to pop in_buf */
 		if (!kfifo_get(&ge2d->in_done_q, &in_buf)) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -436,8 +459,8 @@
 		}
 		mutex_unlock(&ge2d->output_lock);
 
-		fb = &out_buf->aml_buf->frame_buffer;
-		fb->status = FB_ST_GE2D;
+		aml_buf->state = FB_ST_GE2D;
+
 
 		/* fill output vframe information. */
 		memcpy(vf_out, in_buf->vf, sizeof(*vf_out));
@@ -445,18 +468,18 @@
 			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[0].phy_addr = aml_buf->planes[0].addr;
+		if (aml_buf->num_planes == 1) {
 			vf_out->canvas0_config[1].phy_addr =
-				fb->m.mem[0].addr + fb->m.mem[0].offset;
+				aml_buf->planes[0].addr + aml_buf->planes[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);
+				aml_buf->planes[0].addr + aml_buf->planes[0].offset
+				+ (aml_buf->planes[0].offset >> 2);
 		} else {
 			vf_out->canvas0_config[1].phy_addr =
-				fb->m.mem[1].addr;
+				aml_buf->planes[1].addr;
 			vf_out->canvas0_config[2].phy_addr =
-				fb->m.mem[2].addr;
+				aml_buf->planes[2].addr;
 		}
 
 		/* fill outbuf parms. */
@@ -470,10 +493,19 @@
 		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;
+			src_fmt |= (is_cpu_t7c() ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X)) ?
+						GE2D_LITTLE_ENDIAN : GE2D_BIG_ENDIAN;
 		else
-			src_fmt |= GE2D_LITTLE_ENDIAN;
+			src_fmt |= (is_cpu_t7c() ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+						(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X)) ?
+						GE2D_BIG_ENDIAN : GE2D_LITTLE_ENDIAN;
 
 		/* negotiate format of destination */
 		dst_fmt = get_input_format(in_buf->vf);
@@ -504,17 +536,20 @@
 			vf_out->canvas0_config[2].endian = 7;
 		}
 
+		vf_out->mem_sec = ctx->is_drm_mode ? 1 : 0;
 		start_time = local_clock();
+
+		mutex_lock(&ctx->dev->cache.lock);
 		/* 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]);
+			canvas_config_config(ctx->dev->cache.res[0].cid, &in_buf->vf->canvas0_config[0]);
+			canvas_config_config(ctx->dev->cache.res[1].cid, &in_buf->vf->canvas0_config[1]);
+			canvas_config_config(ctx->dev->cache.res[2].cid, &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;
+				ctx->dev->cache.res[0].cid |
+				ctx->dev->cache.res[1].cid << 8 |
+				ctx->dev->cache.res[2].cid << 16;
 
 			ge2d_config.src_planes[0].addr =
 				in_buf->vf->canvas0_config[0].phy_addr;
@@ -553,20 +588,20 @@
 			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]);
+		canvas_config_config(ctx->dev->cache.res[3].cid, &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]);
+		canvas_config_config(ctx->dev->cache.res[4].cid, &vf_out->canvas0_config[1]);
+		canvas_config_config(ctx->dev->cache.res[5].cid, &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);
+			ctx->dev->cache.res[3].cid |
+			ctx->dev->cache.res[4].cid << 8;
+		canvas_read(ctx->dev->cache.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->dst_canvas_id[1], &cd);
+		canvas_read(ctx->dev->cache.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;
@@ -592,9 +627,10 @@
 		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	= ctx->is_drm_mode ? 1 : 0;
 
-		ATRACE_COUNTER("VC_OUT_GE2D-1.handle_start",
-			in_buf->aml_buf->frame_buffer.buf_idx);
+		vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_3,
+			in_buf->aml_vb->aml_buf->index);
 
 		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), "
@@ -620,6 +656,7 @@
 		if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 				"ge2d_context_config_ex error.\n");
+			mutex_unlock(&ctx->dev->cache.lock);
 			goto exit;
 		}
 
@@ -634,6 +671,7 @@
 					0, 0, in_buf->vf->width, in_buf->vf->height);
 			}
 		}
+		mutex_unlock(&ctx->dev->cache.lock);
 
 		//pr_info("consume time %d us\n", div64_u64(local_clock() - start_time, 1000));
 
@@ -658,6 +696,19 @@
 	return 4;
 }
 
+void static inline aml_v4l2_ge2d_set_workmode(struct aml_vcodec_ctx *ctx,
+		struct aml_ge2d_cfg_infos *cfg)
+{
+	if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
+		(ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
+		cfg->mode |= GE2D_MODE_CONVERT_NV12;
+	else if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
+		(ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
+		cfg->mode |= GE2D_MODE_CONVERT_NV21;
+	else
+		cfg->mode |= GE2D_MODE_CONVERT_NV21;
+}
+
 int aml_v4l2_ge2d_init(
 		struct aml_vcodec_ctx *ctx,
 		struct aml_ge2d_cfg_infos *cfg,
@@ -665,7 +716,6 @@
 {
 	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;
 
@@ -676,7 +726,8 @@
 	if (!ge2d)
 		return -ENOMEM;
 
-	ge2d->work_mode = work_mode;
+	aml_v4l2_ge2d_set_workmode(ctx, cfg);
+	ge2d->work_mode = cfg->mode;
 
 	/* default convert little endian. */
 	if (!ge2d->work_mode) {
@@ -760,26 +811,15 @@
 		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)) {
+	if (aml_canvas_cache_get(ctx->dev, "v4ldec-ge2d") < 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]);
+			ctx->dev->cache.res[0].cid,
+			ctx->dev->cache.res[1].cid,
+			ctx->dev->cache.res[2].cid,
+			ctx->dev->cache.res[3].cid,
+			ctx->dev->cache.res[4].cid,
+			ctx->dev->cache.res[5].cid);
 		goto error8;
 	}
 
@@ -798,7 +838,7 @@
 
 	*ge2d_handle = ge2d;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"GE2D_CFG bsize:%d, wkm:%x, bm:%x, drm:%d\n",
 		ge2d->buf_size,
 		ge2d->work_mode,
@@ -808,18 +848,7 @@
 	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]);
+	aml_canvas_cache_put(ctx->dev);
 error8:
 	vfree(ge2d->ivbpool);
 error7:
@@ -846,11 +875,12 @@
 	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);
-
+	if (ge2d->running) {
+		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 */
 
@@ -862,12 +892,7 @@
 	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]);
+	aml_canvas_cache_put(ge2d->ctx->dev);
 
 	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
 		"ge2d destroy done\n");
@@ -878,10 +903,28 @@
 }
 EXPORT_SYMBOL(aml_v4l2_ge2d_destroy);
 
+int aml_v4l2_ge2d_thread_stop(struct aml_v4l2_ge2d* ge2d)
+{
+	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
+		"ge2d thread stop begin\n");
+
+	if (ge2d->running) {
+		ge2d->running = false;
+		up(&ge2d->sem_in);
+		up(&ge2d->sem_out);
+		kthread_stop(ge2d->task);
+	}
+	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
+		"ge2d thread stop done\n");
+
+	return 0;
+}
+EXPORT_SYMBOL(aml_v4l2_ge2d_thread_stop);
+
 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;
+	struct aml_buf *aml_buf = NULL;
 
 	if (!ge2d)
 		return -EINVAL;
@@ -899,13 +942,14 @@
 		"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);
+	aml_buf = (struct aml_buf *)vf->v4l_mem_handle;
+	in_buf->aml_vb = container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
 	in_buf->vf = vf;
 
 	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
+		unsigned int dw_mode = DM_YUV_ONLY;
 		struct file *fp;
+		char file_name[64] = {0};
 
 		if (!dump_ge2d_input || ge2d->ctx->is_drm_mode)
 			break;
@@ -913,26 +957,44 @@
 		if (vdec_if_get_param(ge2d->ctx, GET_PARAM_DW_MODE, &dw_mode))
 			break;
 
-		if (dw_mode == VDEC_DW_AFBC_ONLY)
+		if (dw_mode == DM_AVBC_ONLY)
 			break;
 
-		fp = filp_open("/data/dec_dump_before.raw",
-				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+		snprintf(file_name, 64, "%s/dec_dump_ge2d_input_%ux%u.raw", dump_path, vf->width, vf->height);
+		fp = media_open(file_name, O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
 		if (!IS_ERR(fp)) {
-			struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
+			struct vb2_buffer *vb = &in_buf->aml_vb->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 y data
+			u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+				vf->width, vf->height, 64);
+
+			// dump uv data
+			if (vb->num_planes == 1) {
+				aml_yuv_dump(fp, yuv_data_addr, vf->width,
+					vf->height / 2, 64);
+			} else {
+				aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+					vf->width, vf->height / 2, 64);
+			}
+
+			pr_info("dump idx: %d %dx%d num_planes %d\n",
+				dump_ge2d_input,
+				vf->width,
+				vf->height,
+				vb->num_planes);
+
 			dump_ge2d_input--;
-			filp_close(fp, NULL);
+			media_close(fp, NULL);
 		}
 	} while(0);
 
-	ATRACE_COUNTER("VC_OUT_GE2D-0.receive", fb->buf_idx);
+	vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_2, aml_buf->index);
 
 	kfifo_put(&ge2d->in_done_q, in_buf);
+	update_ge2d_num_cache(ge2d);
+	vdec_tracing(&ge2d->ctx->vtr, VTRACE_GE2D_PIC_6, atomic_read(&ge2d->ctx->ge2d_cache_num));
+	aml_buf_update_holder(&ge2d->ctx->bm, aml_buf, BUF_USER_GE2D, BUF_GET);
 	up(&ge2d->sem_in);
 
 	return 0;
@@ -942,11 +1004,11 @@
 {
 	struct aml_vcodec_ctx *ctx =
 		(struct aml_vcodec_ctx *)v4l_ctx;
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)fb_ctx;
+	struct aml_buf *aml_buf =
+		(struct aml_buf *)fb_ctx;
 	int ret = -1;
 
-	ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, fb->vframe);
+	ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, &aml_buf->vframe);
 	if (ret < 0) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"ge2d push vframe err, ret: %d\n", ret);
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.h b/drivers/amvdec_ports/aml_vcodec_ge2d.h
index a12931d..e495945 100644
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.h
+++ b/drivers/amvdec_ports/aml_vcodec_ge2d.h
@@ -1,22 +1,22 @@
 /*
-* 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:
-*/
+ * 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_GE2D_H_
 #define _AML_VCODEC_GE2D_H_
 
@@ -38,7 +38,7 @@
 	u32			flag;
 	struct vframe_s		*vf;
 	void			*caller_data;
-	struct aml_video_dec_buf *aml_buf;
+	struct aml_v4l2_buf	*aml_vb;
 };
 
 struct aml_v4l2_ge2d {
@@ -72,9 +72,6 @@
 	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);
@@ -85,5 +82,7 @@
 		struct aml_v4l2_ge2d** ge2d_handle);
 
 int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d);
+int aml_v4l2_ge2d_thread_stop(struct aml_v4l2_ge2d* ge2d);
+
 
 #endif
diff --git a/drivers/amvdec_ports/aml_vcodec_ts.c b/drivers/amvdec_ports/aml_vcodec_ts.c
new file mode 100644
index 0000000..3a9abe0
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_ts.c
@@ -0,0 +1,123 @@
+/*
+* 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 "aml_vcodec_drv.h"
+
+#include <linux/sched/clock.h>
+#include "aml_vcodec_ts.h"
+
+int aml_vcodec_pts_checkout(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts)
+{
+	checkout_pts_offset mCheckOutPtsOffset = {0};
+	int ret;
+
+	mCheckOutPtsOffset.offset = offset;
+	ret = ptsserver_checkout_pts_offset(ptsserver_id,&mCheckOutPtsOffset);
+	if (ret) {
+		pr_err("aml_vcodec_pts_checkout ret = %d\n", ret);
+		return ret;
+	}
+
+	*pts = mCheckOutPtsOffset;
+
+	pr_debug("%s duration: %lld offset: 0x%llx pts: 0x%x pts64: %llu\n",
+		__func__, (offset >> 32) & 0xffffffff,
+		offset & 0xffffffff, pts->pts, pts->pts_64);
+
+	return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_pts_checkout);
+
+int aml_vcodec_pts_offset(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts)
+{
+	checkout_pts_offset mCheckOutPtsOffset = {0};
+	int ret;
+	mCheckOutPtsOffset.offset = offset;
+
+	ret = ptsserver_peek_pts_offset(ptsserver_id, &mCheckOutPtsOffset);
+	if (ret) {
+		pr_err("aml_vcodec_pts_offset ret = %d\n", ret);
+		return ret;
+	}
+
+	*pts = mCheckOutPtsOffset;
+
+	pr_debug("%s duration: %lld offset: 0x%llx pts: 0x%x pts64: %llu\n",
+		__func__, (offset >> 32) & 0xffffffff,
+		offset & 0xffffffff, pts->pts, pts->pts_64);
+
+	return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_pts_offset);
+
+int aml_vcodec_pts_checkin(s32 ptsserver_id, u32 pkt_size, u64 pts_val)
+{
+	checkin_pts_size mCheckinPtsSize;
+
+	mCheckinPtsSize.size =pkt_size;
+	mCheckinPtsSize.pts = (u32)div64_u64(pts_val * 9, 100);
+	mCheckinPtsSize.pts_64 = pts_val;
+	ptsserver_checkin_pts_size(ptsserver_id,&mCheckinPtsSize);
+
+	pr_debug("%s pkt_size:%d chekin pts: %d, pts64: %llu\n",
+		__func__, pkt_size, mCheckinPtsSize.pts, pts_val);
+
+	return 0;
+}
+
+int aml_vcodec_pts_first_checkin(u32 format, s32 ptsserver_id, u32 wp, u32 buf_start)
+{
+	uint32_t mBaseffset = 0;
+	uint32_t mAlignmentOffset = 0;
+	start_offset mSartOffset;
+
+	if ((format == V4L2_PIX_FMT_HEVC) || (format == V4L2_PIX_FMT_VP9) || (format == V4L2_PIX_FMT_AV1)) {
+		mAlignmentOffset  = wp % 0x80;
+		mBaseffset = 0;
+	} else {
+		mBaseffset = wp - buf_start;
+	}
+
+	mSartOffset.mBaseOffset = mBaseffset;
+	mSartOffset.mAlignmentOffset = mAlignmentOffset;
+	ptsserver_set_first_checkin_offset(ptsserver_id,&mSartOffset);
+
+	pr_debug("%s format:%d mBaseffset: 0x%d mAlignmentOffset: %d\n",
+		__func__, format, mBaseffset, mAlignmentOffset);
+
+	return 0;
+}
+
+static struct pts_server_ops pts_server_ops = {
+	.checkout	= aml_vcodec_pts_checkout,
+	.cal_offset = aml_vcodec_pts_offset,
+	.checkin	= aml_vcodec_pts_checkin,
+	.first_checkin	= aml_vcodec_pts_first_checkin,
+};
+
+struct pts_server_ops *get_pts_server_ops(void)
+{
+	return &pts_server_ops;
+}
+EXPORT_SYMBOL(get_pts_server_ops);
diff --git a/drivers/amvdec_ports/aml_vcodec_ts.h b/drivers/amvdec_ports/aml_vcodec_ts.h
new file mode 100644
index 0000000..26924b3
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_ts.h
@@ -0,0 +1,39 @@
+/*
+* 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_TS_H_
+#define _AML_VCODEC_TS_H_
+
+#include "../media_sync/pts_server/pts_server_core.h"
+
+int aml_vcodec_pts_checkout(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+int aml_vcodec_pts_offset(s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+int aml_vcodec_pts_checkin(s32 ptsserver_id, u32 pkt_size, u64 pts_val);
+int aml_vcodec_pts_first_checkin(u32 format, s32 ptsserver_id, u32 wp, u32 buf_start);
+
+struct pts_server_ops {
+	int (*checkout) (s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+	int (*cal_offset) (s32 ptsserver_id, u64 offset, struct checkoutptsoffset *pts);
+	int (*checkin) (s32 ptsserver_id, u32 pkt_size, u64 pts_val);
+	int (*first_checkin) (u32 format, s32 ptsserver_id, u32 wp, u32 buf_start);
+};
+struct pts_server_ops *get_pts_server_ops(void);
+
+#endif
+
diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c
index 54b0d06..ad90fd1 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.c
+++ b/drivers/amvdec_ports/aml_vcodec_util.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 
 #include "aml_vcodec_drv.h"
@@ -44,3 +44,54 @@
 	return ctx;
 }
 EXPORT_SYMBOL(aml_vcodec_get_curr_ctx);
+
+int user_to_task(enum buf_core_user user)
+{
+	enum task_type_e t;
+
+	switch (user) {
+	case BUF_USER_DEC:
+		t = TASK_TYPE_DEC;
+		break;
+	case BUF_USER_VPP:
+		t = TASK_TYPE_VPP;
+		break;
+	case BUF_USER_GE2D:
+		t = TASK_TYPE_GE2D;
+		break;
+	case BUF_USER_VSINK:
+		t = TASK_TYPE_V4L_SINK;
+		break;
+	default:
+		t = TASK_TYPE_MAX;
+	}
+
+	return t;
+}
+EXPORT_SYMBOL(user_to_task);
+
+int task_to_user(enum task_type_e task)
+{
+	enum buf_core_user t;
+
+	switch (task) {
+	case TASK_TYPE_DEC:
+		t = BUF_USER_DEC;
+		break;
+	case TASK_TYPE_VPP:
+		t = BUF_USER_VPP;
+		break;
+	case TASK_TYPE_GE2D:
+		t = BUF_USER_GE2D;
+		break;
+	case TASK_TYPE_V4L_SINK:
+		t = BUF_USER_VSINK;
+		break;
+	default:
+		t = BUF_USER_MAX;
+	}
+
+	return t;
+}
+EXPORT_SYMBOL(task_to_user);
+
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h
index 96c5453..cc4286f 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.h
+++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -1,28 +1,37 @@
 /*
-* 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:
-*/
+ * 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_UTIL_H_
 #define _AML_VCODEC_UTIL_H_
 
 #include <linux/types.h>
-#include <linux/dma-direction.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
+#ifdef __KERNEL__
+#include <uapi/linux/videodev2.h>
+#else
+#include <uapi/linux/time.h>
+#endif
+#include <linux/version.h>
+
+#include "aml_buf_core.h"
+#include "aml_task_chain.h"
+
 /*
 typedef unsigned long long	u64;
 typedef signed long long	s64;
@@ -54,7 +63,8 @@
 struct aml_vcodec_dev;
 
 extern u32 debug_mode;
-extern u32 mandatory_dw_mmu;
+extern u32 disable_vpp_dw_mmu;
+extern int t3x_tw_output;
 
 #ifdef v4l_dbg
 #undef v4l_dbg
@@ -99,8 +109,42 @@
 		}								\
 	} while (0)
 
+#define v4l_dbg_ext(id, flags, fmt, args...)						\
+	do {									\
+		if ((flags == V4L_DEBUG_CODEC_ERROR) ||				\
+			(flags == V4L_DEBUG_CODEC_PRINFO) ||			\
+			(debug_mode & flags)) {					\
+			if (flags == V4L_DEBUG_CODEC_ERROR) {			\
+				__v4l_dbg(1, id, "[ERR]: " fmt, ##args);	\
+			} else	{						\
+				__v4l_dbg(1, id, fmt, ##args);			\
+			}							\
+		}								\
+	} while (0)
+
 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);
 
+/*
+ * todo
+ */
+int user_to_task(enum buf_core_user user);
+
+/*
+ * todo
+ */
+int task_to_user(enum task_type_e task);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 15, 0)
+#ifdef __KERNEL__
+static inline __u64 timeval_to_ns(const struct __kernel_v4l2_timeval *tv)
+#else
+static inline __u64 timeval_to_ns(const struct timeval *tv)
+#endif
+{
+	return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
+}
+#endif
+
 #endif /* _AML_VCODEC_UTIL_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.c b/drivers/amvdec_ports/aml_vcodec_vpp.c
index 5a86c1f..716928d 100644
--- a/drivers/amvdec_ports/aml_vcodec_vpp.c
+++ b/drivers/amvdec_ports/aml_vcodec_vpp.c
@@ -1,23 +1,22 @@
 /*
-* 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:
-*/
-
+ * 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/delay.h>
 #include <linux/videodev2.h>
@@ -28,18 +27,27 @@
 #include "aml_vcodec_adapt.h"
 #include "vdec_drv_if.h"
 #include "../common/chips/decoder_cpu_ver_info.h"
+#include "../frame_provider/decoder/utils/aml_buf_helper.h"
+#include "utils/common.h"
+#include "../common/media_utils/media_utils.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 VPP_BUF_GET_IDX(vpp_buf) (vpp_buf->aml_vb->vb.vb2_buf.index)
 #define INPUT_PORT 0
 #define OUTPUT_PORT 1
 
 extern int dump_vpp_input;
 extern int vpp_bypass_frames;
+extern char dump_path[32];
 
-static void di_release_keep_buf_wrap(void *arg)
+struct di_buffer_wrap {
+	struct vframe_s vf_cp;
+	struct di_buffer *buf;
+};
+
+static void di_release_keep_buf_wrap1(void *arg)
 {
 	struct di_buffer *buf = (struct di_buffer *)arg;
 
@@ -50,6 +58,40 @@
 
 	di_release_keep_buf(buf);
 
+	ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_release", buf->mng.index);
+}
+
+static void di_release_keep_buf_wrap2(void *arg)
+{
+	struct di_buffer_wrap *buf_wrap = (struct di_buffer_wrap *)arg;
+	struct di_buffer *buf = NULL;
+	struct vframe_s *vf_cp = NULL;
+	s32 cur_di_ins_id = -1, last_di_ins_id = -1;
+
+	if (buf_wrap) {
+		buf = buf_wrap->buf;
+		vf_cp = &buf_wrap->vf_cp;
+		if (buf && buf->vf)
+			cur_di_ins_id = buf->vf->di_instance_id;
+		last_di_ins_id = vf_cp->di_instance_id;
+	}
+
+	v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,
+		"%s release di local buffer %px, vf:%px, cur_id: %d vf_cp:%px, vf-ext:%px, vf_cp-ext:%px, last_id: %d comm:%s, pid:%d,buf->flag=%d\n",
+		__func__ , buf, buf->vf, cur_di_ins_id, vf_cp, buf->vf ? buf->vf->vf_ext : NULL, vf_cp->vf_ext, last_di_ins_id,
+		current->comm, current->pid, buf->flag);
+
+	/* just release di bufffer when same id or interlace video or post write mode */
+	if ((cur_di_ins_id == last_di_ins_id && cur_di_ins_id > 0) ||
+		(buf->flag & DI_FLAG_I) ||
+	    !(vf_cp->di_flag & DI_FLAG_DI_PVPPLINK))
+		di_release_keep_buf(buf);
+	else
+		v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,"%s release warning\n",__func__);
+
+	if (buf_wrap)
+		vfree(buf_wrap);
+
 	ATRACE_COUNTER("VC_OUT_VPP_LC-2.lc_release", buf->mng.index);
 }
 
@@ -57,15 +99,16 @@
 {
 	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 aml_v4l2_buf *aml_vb = NULL;
 	struct uvm_hook_mod_info u_info;
+	struct di_buffer_wrap *buf_wrap = NULL;
 	int ret;
 
-	aml_buf = vpp_buf->aml_buf;
-	if (!aml_buf)
+	aml_vb = vpp_buf->aml_vb;
+	if (!aml_vb)
 		return -EINVAL;
 
-	dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
+	dma = aml_vb->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");
@@ -81,20 +124,33 @@
 	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");
+			"attach_DI_buffer exist hook, dbuf:%px\n", dma);
 		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;
+	buf_wrap = vzalloc(sizeof(struct di_buffer_wrap));
+	if (buf_wrap) {
+		buf_wrap->buf = vpp_buf->di_local_buf;
+		u_info.type = VF_PROCESS_DI;
+		u_info.arg = (void *)buf_wrap;
+		u_info.free = di_release_keep_buf_wrap2;
 
-	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");
+		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");
+			vfree(buf_wrap);
+		} else if (vpp_buf->di_buf.vf->vf_ext) {
+			v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+				"%s swap di_buf %px.vf->vf_ext:%px to buf_wrap->vf_cp:%px\n",
+				__func__, vpp_buf->di_buf.vf, vpp_buf->di_buf.vf->vf_ext, &buf_wrap->vf_cp);
+			memcpy(&buf_wrap->vf_cp,
+				vpp_buf->di_buf.vf->vf_ext,
+				sizeof(struct vframe_s));
+			vpp_buf->di_buf.vf->vf_ext = &buf_wrap->vf_cp;
+		}
 	}
 
-	ATRACE_COUNTER("VC_OUT_VPP_LC-0.lc_attach", vpp_buf->di_local_buf->mng.index);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_12, vpp_buf->di_local_buf->mng.index);
 
 	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
 		"%s attach di local buffer %px, dbuf:%px\n",
@@ -107,15 +163,14 @@
 {
 	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 aml_v4l2_buf *aml_vb = NULL;
 	int ret;
 
-	aml_buf = vpp_buf->aml_buf;
-	if (!aml_buf)
+	aml_vb = vpp_buf->aml_vb;
+	if (!aml_vb)
 		return -EINVAL;
-
-	dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
-	if (!dma || !dmabuf_is_uvm(dma)) {
+	dma = aml_vb->vb.vb2_buf.planes[0].dbuf;
+	if (IS_ERR_OR_NULL(dma) || !dmabuf_is_uvm(dma)) {
 		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
 			"detach_DI_buffer err\n");
 		return -EINVAL;
@@ -127,7 +182,7 @@
 		return 0;
 	}
 
-	ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_detach", vpp_buf->di_local_buf->mng.index);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_13, vpp_buf->di_local_buf->mng.index);
 
 	ret = uvm_detach_hook_mod(dma, VF_PROCESS_DI);
 	if (ret < 0) {
@@ -156,6 +211,12 @@
 	}
 }
 
+static void update_vpp_num_cache(struct aml_v4l2_vpp *vpp)
+{
+	if (!vpp->ctx->is_stream_off)
+		atomic_set(&vpp->ctx->vpp_cache_num, VPP_FRAME_SIZE - kfifo_len(&vpp->input));
+}
+
 static int is_di_input_buff_full(struct aml_v4l2_vpp *vpp)
 {
 	return ((vpp->in_num[INPUT_PORT] - vpp->in_num[OUTPUT_PORT])
@@ -173,14 +234,15 @@
 {
 	struct aml_v4l2_vpp *vpp = buf->caller_data;
 	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
+	struct aml_buf *aml_buf = NULL;
 	bool bypass = false;
 	bool eos = false;
+	struct vframe_s *tmp;
 
 	if (!vpp || !vpp->ctx) {
 		pr_err("fatal %s %d vpp:%p\n",
 			__func__, __LINE__, vpp);
-		di_release_keep_buf_wrap(buf);
+		di_release_keep_buf_wrap1(buf);
 		return DI_ERR_UNDEFINED;
 	}
 
@@ -188,7 +250,7 @@
 		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);
+		di_release_keep_buf_wrap1(buf);
 		return DI_ERR_UNDEFINED;
 	}
 
@@ -196,11 +258,11 @@
 		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);
+		di_release_keep_buf_wrap1(buf);
 		return DI_ERR_UNDEFINED;
 	}
 
-	fb	= &vpp_buf->aml_buf->frame_buffer;
+	aml_buf	= vpp_buf->aml_vb->aml_buf;
 	eos	= (buf->flag & DI_FLAG_EOS);
 	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
 
@@ -208,7 +270,7 @@
 	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;
+	vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)aml_buf;
 
 	if (!eos && !bypass) {
 		vpp_buf->di_local_buf = buf;
@@ -219,18 +281,34 @@
 
 	kfifo_put(&vpp->out_done_q, vpp_buf);
 
-	if (vpp->is_prog)
+	if (vpp->is_prog) {
 		kfifo_put(&vpp->input, vpp_buf->inbuf);
+		update_vpp_num_cache(vpp);
+		vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+	}
 
+	if (aml_buf->vpp_buf == NULL) {
+		aml_buf->vpp_buf = vzalloc(sizeof(struct aml_v4l2_vpp_buf));
+	}
+
+	if (aml_buf->vpp_buf)
+		memcpy((struct aml_v4l2_vpp_buf *)(aml_buf->vpp_buf), vpp_buf,
+			sizeof(struct aml_v4l2_vpp_buf));
+
+	tmp = (struct vframe_s *)(buf->vf ? buf->vf->vf_ext : NULL);
 	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, "
+		"vpp_output local done: idx:%d, vf:%px, afbc:0x%lx ext vf:%px, idx:%d, flag(vf:%x di:%x) (buf->vf:%px vf_ext:%px, afbc:0x%lx) %s %s, ts:%lld, "
 		"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-		fb->buf_idx,
+		aml_buf->index,
 		vpp_buf->di_buf.vf,
+		vpp_buf->di_buf.vf->compHeadAddr,
 		vpp_buf->di_buf.vf->vf_ext,
 		vpp_buf->di_buf.vf->index,
 		vpp_buf->di_buf.vf->flag,
 		buf->flag,
+		buf->vf,
+		buf->vf ? buf->vf->vf_ext : NULL,
+		tmp ? tmp->compHeadAddr : 0,
 		vpp->is_prog ? "P" : "I",
 		eos ? "eos" : "",
 		vpp_buf->di_buf.vf->timestamp,
@@ -240,9 +318,9 @@
 		kfifo_len(&vpp->in_done_q),
 		kfifo_len(&vpp->out_done_q));
 
-	ATRACE_COUNTER("VC_OUT_VPP-2.lc_submit", fb->buf_idx);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_10, aml_buf->index);
 
-	fb->task->submit(fb->task, TASK_TYPE_VPP);
+	aml_buf_done(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
 
 	vpp->out_num[OUTPUT_PORT]++;
 	vpp->in_num[OUTPUT_PORT]++;
@@ -255,7 +333,7 @@
 {
 	struct aml_v4l2_vpp *vpp = buf->caller_data;
 	struct aml_v4l2_vpp_buf *vpp_buf;
-	struct vdec_v4l2_buffer *fb = NULL;
+	struct aml_buf *aml_buf = NULL;
 	bool eos = false;
 
 	if (!vpp || !vpp->ctx) {
@@ -273,13 +351,13 @@
 	}
 
 	vpp_buf	= container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
-	fb 	= &vpp_buf->aml_buf->frame_buffer;
+	aml_buf 	= vpp_buf->aml_vb->aml_buf;
 	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,
+		aml_buf->index,
 		buf->vf,
 		buf->vf->index,
 		buf->vf->flag,
@@ -295,15 +373,23 @@
 
 	if (!vpp->is_prog) {
 		/* recycle vf only in non-bypass mode */
-		fb->task->recycle(fb->task, TASK_TYPE_VPP);
+		aml_buf_fill(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
 
 		kfifo_put(&vpp->input, vpp_buf);
+		update_vpp_num_cache(vpp);
+		vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+	}
+
+	if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+		kfifo_put(&vpp->input, vpp_buf);
+		update_vpp_num_cache(vpp);
+		vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
 	}
 
 	if (vpp->buffer_mode != BUFFER_MODE_ALLOC_BUF)
 		vpp->in_num[OUTPUT_PORT]++;
 
-	ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_1, aml_buf->index);
 
 	return DI_ERR_NONE;
 }
@@ -313,7 +399,7 @@
 {
 	struct aml_v4l2_vpp *vpp = buf->caller_data;
 	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
+	struct aml_buf *aml_buf = NULL;
 	bool bypass = false;
 	bool eos = false;
 
@@ -332,19 +418,27 @@
 	}
 
 	vpp_buf	= container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
-	fb	= &vpp_buf->aml_buf->frame_buffer;
+	aml_buf	= vpp_buf->aml_vb->aml_buf;
 	eos	= (buf->flag & DI_FLAG_EOS);
 	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
 
-	/* recovery fb handle. */
-	buf->vf->v4l_mem_handle = (ulong)fb;
+	/* recovery aml_buf handle. */
+	buf->vf->v4l_mem_handle = (ulong)aml_buf;
 
 	kfifo_put(&vpp->out_done_q, vpp_buf);
 
+	if (aml_buf->vpp_buf == NULL) {
+		aml_buf->vpp_buf = vzalloc(sizeof(struct aml_v4l2_vpp_buf));
+	}
+
+	if (aml_buf->vpp_buf)
+		memcpy((struct aml_v4l2_vpp_buf *)(aml_buf->vpp_buf), vpp_buf,
+			sizeof(struct aml_v4l2_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,
+		aml_buf->index,
 		buf->vf,
 		buf->vf->index,
 		buf->vf->flag,
@@ -358,9 +452,9 @@
 		kfifo_len(&vpp->in_done_q),
 		kfifo_len(&vpp->out_done_q));
 
-	ATRACE_COUNTER("VC_OUT_VPP-2.submit", fb->buf_idx);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_9, aml_buf->index);
 
-	fb->task->submit(fb->task, TASK_TYPE_VPP);
+	aml_buf_done(&vpp->ctx->bm, aml_buf, BUF_USER_VPP);
 
 	vpp->out_num[OUTPUT_PORT]++;
 
@@ -371,11 +465,109 @@
 	return DI_ERR_NONE;
 }
 
-static void vpp_vf_get(void *caller, struct vframe_s **vf_out)
+static enum DI_ERRORTYPE
+	v4l_vpp_fill_output_done_dw_mmu(struct di_buffer *buf)
+{
+	struct aml_v4l2_vpp *vpp = buf->caller_data;
+	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
+	struct aml_buf *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;
+	}
+
+	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_wrap1(buf);
+		return DI_ERR_UNDEFINED;
+	}
+
+	fb	= vpp_buf->aml_vb->aml_buf;
+	eos	= (buf->flag & DI_FLAG_EOS);
+	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
+
+	vpp_buf->di_buf.flag		|= buf->flag;
+	vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)fb;
+
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+		"%s dec_vf_type:0x%x di_out_vf_type:0x%x\n",
+		__func__, vpp_buf->di_buf.vf->type, buf->vf->type);
+
+	/*di pw*/
+	if (buf->vf->type & 0x40000000) {
+		vpp_buf->di_buf.vf->type	|= (buf->vf->type & 0xfffffff);
+
+		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+			"di pw enable, vf_type:0x%x\n", vpp_buf->di_buf.vf->type);
+	}
+
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+		"%s dec_vf(w x h):(%d x %d) di_out_vf(w x h):(%d x %d)\n",
+		__func__, vpp_buf->di_buf.vf->width, vpp_buf->di_buf.vf->height,
+		buf->vf->width, buf->vf->height);
+
+	if (buf->vf->width != 0 &&
+		buf->vf->height != 0) {
+		vpp_buf->di_buf.vf->width	= buf->vf->width;
+		vpp_buf->di_buf.vf->height	= buf->vf->height;
+	}
+
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+		"vpp out buff canvas:phy:%lx/%lx %dx%d",
+		buf->vf->canvas0_config[0].phy_addr,
+		buf->vf->canvas0_config[1].phy_addr,
+		buf->vf->canvas0_config[0].width,
+		buf->vf->canvas0_config[0].height);
+
+	kfifo_put(&vpp->out_done_q, vpp_buf);
+
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
+		"vpp_output_dw 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->index,
+		vpp_buf->di_buf.vf,
+		vpp_buf->di_buf.vf->index,
+		vpp_buf->di_buf.vf->flag,
+		vpp_buf->di_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));
+
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_9, fb->index);
+
+	fb->task->submit(fb->task, TASK_TYPE_VPP);
+
+	vpp->out_num[OUTPUT_PORT]++;
+
+	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 aml_buf *aml_buf = NULL;
 	struct di_buffer *buf = NULL;
 	struct vframe_s *vf = NULL;
 	bool bypass = false;
@@ -389,7 +581,7 @@
 	}
 
 	if (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
-		fb	= &vpp_buf->aml_buf->frame_buffer;
+		aml_buf	= vpp_buf->aml_vb->aml_buf;
 		buf	= &vpp_buf->di_buf;
 		eos	= (buf->flag & DI_FLAG_EOS);
 		bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
@@ -409,9 +601,16 @@
 			}
 		}
 
-		*vf_out = vf;
+		memcpy(vf_out, vf, sizeof(struct vframe_s));
 
-		ATRACE_COUNTER("VC_OUT_VPP-3.vf_get", fb->buf_idx);
+		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);
+
+		vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_11, aml_buf->index);
 
 		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
 			"%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
@@ -425,19 +624,19 @@
 
 static void vpp_vf_put(void *caller, struct vframe_s *vf)
 {
+	#if 0
 	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_buf *aml_buf = NULL;
+	struct aml_v4l2_buf *aml_vb = 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);
+	aml_buf	= (struct aml_buf *) vf->v4l_mem_handle;
+	aml_vb	= container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
 
-
-	vpp_buf	= (struct aml_v4l2_vpp_buf *) aml_buf->vpp_buf_handle;
+	vpp_buf	= (struct aml_v4l2_vpp_buf *) aml_vb->vpp_buf_handle;
 	buf	= &vpp_buf->di_buf;
 	eos	= (buf->flag & DI_FLAG_EOS);
 	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
@@ -450,12 +649,7 @@
 		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);
-	}
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_0, aml_buf->index);
 
 	if (!eos && !bypass) {
 		if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
@@ -463,24 +657,84 @@
 		}
 	}
 
-	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);
+	kfifo_put(&vpp->pre_output, vpp_buf);
+
+	queue_work(vpp->ctx->dev->decode_workqueue, &vpp->worker);
+	#endif
+}
+
+void vpp_wrapper_worker(struct work_struct *work)
+{
+	struct aml_v4l2_vpp *vpp =
+		container_of(work, struct aml_v4l2_vpp, worker);
+	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
+
+	while (vpp->running &&
+		!kfifo_is_empty(&vpp->pre_output)) {
+		if (!kfifo_get(&vpp->pre_output, &vpp_buf)) {
+			v4l_dbg(vpp->ctx, 0, "vpp can not get pre output\n");
+			return;
+		}
+
+		if (vpp->is_prog) {
+			ATRACE_COUNTER("VC_IN_VPP-1.recycle", vpp_buf->aml_vb->aml_buf->index);
+			aml_buf_fill(&vpp->ctx->bm, vpp_buf->aml_vb->aml_buf, BUF_USER_VPP);
+		}
+
+		mutex_lock(&vpp->output_lock);
+		kfifo_put(&vpp->output, vpp_buf);
+		mutex_unlock(&vpp->output_lock);
+
+		up(&vpp->sem_out);
+	}
+}
+
+void aml_v4l2_vpp_recycle(struct aml_v4l2_vpp *vpp, struct aml_v4l2_buf *aml_vb)
+{
+	struct aml_v4l2_vpp_buf *vpp_buf;
+	struct di_buffer *buf = NULL;
+	struct vframe_s *vf = NULL;
+	bool bypass = false;
+	bool eos = false;
+
+	if (aml_vb->aml_buf->vpp_buf == NULL)
+		return;
+
+	vpp_buf = (struct aml_v4l2_vpp_buf *)aml_vb->aml_buf->vpp_buf;
+	buf	= &vpp_buf->di_buf;
+	eos	= (buf->flag & DI_FLAG_EOS);
+	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
+	vf      = vpp_buf->di_buf.vf;
+
+	ATRACE_COUNTER("VC_IN_VPP-0.vf_put", aml_vb->aml_buf->index);
+
+	if (!eos && !bypass) {
+		if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
+			/*vpp_buf->di_buf.caller_data might point to the vpp that had been destroyed*/
+			if (vpp != vpp_buf->di_buf.caller_data)
+				vpp_buf->di_buf.caller_data = vpp;
+			detach_DI_buffer(vpp_buf);
+		}
+	}
 }
 
 static int aml_v4l2_vpp_thread(void* param)
 {
 	struct aml_v4l2_vpp* vpp = param;
 	struct aml_vcodec_ctx *ctx = vpp->ctx;
+	bool dynamic_bypass_vpp_flag = ctx->vpp_cfg.dynamic_bypass_vpp;
 
 	v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "enter vpp thread\n");
+
+	if (dynamic_bypass_vpp_flag) {
+		v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "dynamic bypass vpp\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;
+		struct aml_buf *aml_buf;
 
 		if (down_interruptible(&vpp->sem_in))
 			goto exit;
@@ -488,6 +742,12 @@
 		if (!vpp->running)
 			break;
 
+		if (dynamic_bypass_vpp_flag != ctx->vpp_cfg.dynamic_bypass_vpp) {
+			dynamic_bypass_vpp_flag = ctx->vpp_cfg.dynamic_bypass_vpp;
+			di_s_bypass_ch(vpp->di_handle, dynamic_bypass_vpp_flag);
+			v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "dynamic bypass vpp:%s\n",
+				dynamic_bypass_vpp_flag ? "enable" : "disable");
+		}
 		if (kfifo_is_empty(&vpp->output)) {
 			if (down_interruptible(&vpp->sem_out))
 				goto exit;
@@ -496,6 +756,7 @@
 
 		if ((vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) &&
 			(is_di_input_buff_full(vpp) || is_di_output_buff_full(vpp))) {
+			v4l_dbg(ctx, 0, "di input/output full!\n");
 			usleep_range(500, 550);
 			goto retry;
 		}
@@ -509,34 +770,28 @@
 		mutex_unlock(&vpp->output_lock);
 
 		/* bind v4l2 buffers */
-		if (!vpp->is_prog && !out_buf->aml_buf) {
-			struct vdec_v4l2_buffer *out;
+		if (!vpp->is_prog) {
+			struct aml_buf *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)) {
+			out = aml_buf_get(&ctx->bm, BUF_USER_VPP, false);
+			if (!out) {
 				usleep_range(5000, 5500);
 				mutex_lock(&vpp->output_lock);
 				kfifo_put(&vpp->output, out_buf);
 				mutex_unlock(&vpp->output_lock);
+				v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "vpp no frame buffers!\n");
 				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;
+			out_buf->aml_vb =
+				container_of(to_vb2_v4l2_buffer(out->vb), struct aml_v4l2_buf, vb);
+
 			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;
+			out->planes[0].bytes_used = out->planes[0].length;
+			out->planes[1].bytes_used = out->planes[1].length;
 		}
 
 		/* safe to pop in_buf */
@@ -557,35 +812,32 @@
 
 		if (!vpp->is_prog) {
 			/* submit I to DI. */
-			fb = &out_buf->aml_buf->frame_buffer;
-			fb->status = FB_ST_VPP;
+			aml_buf = out_buf->aml_vb->aml_buf;
+			aml_buf->state = 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[0].phy_addr = aml_buf->planes[0].addr;
+			if (aml_buf->num_planes == 1)
 				vf_out->canvas0_config[1].phy_addr =
-					fb->m.mem[0].addr + fb->m.mem[0].offset;
+					aml_buf->planes[0].addr + aml_buf->planes[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));
+					aml_buf->planes[1].addr;
 
 			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;
+			out_buf->aml_vb = in_buf->aml_vb;
 
 			memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
 		}
 
+		vf_out->mem_sec = ctx->is_drm_mode ? 1 : 0;
 		/* fill outbuf parms. */
 		out_buf->di_buf.vf	= vf_out;
 		out_buf->di_buf.flag	= 0;
@@ -612,11 +864,13 @@
 		}
 
 		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,
+			"vpp_handle start: idx:(%d, %d), dec vf:%px/%d afbc:0x%lx, 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, fgs_valid:%d",
+			in_buf->aml_vb->aml_buf->index,
+			out_buf->aml_vb->aml_buf->index,
+			in_buf->di_buf.vf,
+			in_buf->di_buf.vf->index,
+			in_buf->di_buf.vf->compHeadAddr,
 			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,
@@ -632,36 +886,50 @@
 			kfifo_len(&vpp->output),
 			kfifo_len(&vpp->frame),
 			kfifo_len(&vpp->in_done_q),
-			kfifo_len(&vpp->out_done_q));
+			kfifo_len(&vpp->out_done_q),
+			in_buf->di_buf.vf->fgs_valid);
 
-		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;
+		if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+			vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_7,
+				out_buf->aml_vb->aml_buf->index);
 
-			v4l_vpp_fill_output_done(&out_buf->di_buf);
-			v4l_vpp_empty_input_done(&in_buf->di_buf);
+			kfifo_put(&vpp->processing, in_buf);
+
+			di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
+			vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_8,
+				in_buf->aml_vb->aml_buf->index);
+			di_empty_input_buffer(vpp->di_handle, &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);
+			if (vpp->is_bypass_p) {
+				vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_6,
+					in_buf->aml_vb->aml_buf->index);
+				out_buf->di_buf.flag = in_buf->di_buf.flag;
+				out_buf->di_buf.vf->vf_ext = in_buf->di_buf.vf;
 
-				di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+				v4l_vpp_fill_output_done(&out_buf->di_buf);
+				v4l_vpp_empty_input_done(&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);
+				if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
+					/*
+					 * the flow of DI local buffer:
+					 * empty input -> output done cb -> fetch processing fifo.
+					 */
+					vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_5,
+						in_buf->aml_vb->aml_buf->index);
 
-				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);
+					out_buf->inbuf = in_buf;
+					kfifo_put(&vpp->processing, out_buf);
+
+					di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+				} else {
+					vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_3,
+						out_buf->aml_vb->aml_buf->index);
+					di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
+
+					vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_4,
+						in_buf->aml_vb->aml_buf->index);
+					di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
+				}
 			}
 		}
 		vpp->in_num[INPUT_PORT]++;
@@ -694,13 +962,17 @@
 	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);
+	if (vpp->running) {
+		vpp->running = false;
+		cancel_work_sync(&vpp->worker);
+		up(&vpp->sem_in);
+		up(&vpp->sem_out);
+		kthread_stop(vpp->task);
+	}
 
 	kfifo_reset(&vpp->input);
 	kfifo_reset(&vpp->output);
+	kfifo_reset(&vpp->pre_output);
 	kfifo_reset(&vpp->frame);
 	kfifo_reset(&vpp->out_done_q);
 	kfifo_reset(&vpp->in_done_q);
@@ -737,7 +1009,7 @@
 
 	sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, &param);
 
-	v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PRINFO, "vpp wrapper reset.\n");
+	v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PROT, "vpp wrapper reset.\n");
 
 	return 0;
 
@@ -773,17 +1045,28 @@
 	else
 		vpp->buffer_mode = BUFFER_MODE_USE_BUF;
 
-	init.work_mode			= WORK_MODE_PRE_POST;
+	if (vpp->work_mode == VPP_MODE_S4_DW_MMU)
+		init.work_mode			= WORK_MODE_S4_DCOPY;
+	else
+		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;
 
+	v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL,
+		"%s work_mode:0x%x buffer_mode:%d\n",__func__, vpp->work_mode, vpp->buffer_mode);
+
 	if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
 		init.ops.fill_output_done =
 			v4l_vpp_fill_output_done_alloc_buffer;
 	}
 
+	if (vpp->work_mode == VPP_MODE_S4_DW_MMU) {
+		init.ops.fill_output_done =
+			v4l_vpp_fill_output_done_dw_mmu;
+	}
+
 	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) &&
@@ -792,7 +1075,7 @@
 	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 */
+	else /* AFBC decoder case, NV12 as default */
 		init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
 
 	if (cfg->is_drm)
@@ -808,6 +1091,7 @@
 
 	INIT_KFIFO(vpp->input);
 	INIT_KFIFO(vpp->output);
+	INIT_KFIFO(vpp->pre_output);
 	INIT_KFIFO(vpp->frame);
 	INIT_KFIFO(vpp->out_done_q);
 	INIT_KFIFO(vpp->in_done_q);
@@ -816,11 +1100,20 @@
 	vpp->ctx = ctx;
 	vpp->is_prog = cfg->is_prog;
 	vpp->is_bypass_p = cfg->is_bypass_p;
+	INIT_WORK(&vpp->worker, vpp_wrapper_worker);
 
 	buf_size = vpp->is_prog ? 16 : cfg->buf_size;
 	vpp->buf_size = buf_size;
 
 	/* setup output fifo */
+	ret = kfifo_alloc(&vpp->pre_output, buf_size, GFP_KERNEL);
+	if (ret) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"alloc pre_output fifo fail.\n");
+		ret = -ENOMEM;
+		goto error1;
+	}
+
 	ret = kfifo_alloc(&vpp->output, buf_size, GFP_KERNEL);
 	if (ret) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
@@ -907,7 +1200,7 @@
 
 	*vpp_handle = vpp;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"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,
@@ -938,6 +1231,8 @@
 error3:
 	kfifo_free(&vpp->output);
 error2:
+	kfifo_free(&vpp->pre_output);
+error1:
 	di_destroy_instance(vpp->di_handle);
 error:
 	kfree(vpp);
@@ -950,11 +1245,13 @@
 	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
 		"vpp destroy begin\n");
 	atomic_set(&vpp->local_buf_out, 0);
-	vpp->running = false;
-	up(&vpp->sem_in);
-	up(&vpp->sem_out);
-	kthread_stop(vpp->task);
-
+	if (vpp->running) {
+		vpp->running = false;
+		cancel_work_sync(&vpp->worker);
+		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 */
 
@@ -964,6 +1261,7 @@
 	kfifo_free(&vpp->processing);
 	kfifo_free(&vpp->frame);
 	vfree(vpp->vfpool);
+	kfifo_free(&vpp->pre_output);
 	kfifo_free(&vpp->output);
 	vfree(vpp->ovbpool);
 	kfifo_free(&vpp->input);
@@ -977,17 +1275,36 @@
 }
 EXPORT_SYMBOL(aml_v4l2_vpp_destroy);
 
+int aml_v4l2_vpp_thread_stop(struct aml_v4l2_vpp* vpp)
+{
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+		"vpp thread stop begin\n");
+
+	if (vpp->running) {
+		vpp->running = false;
+		up(&vpp->sem_in);
+		up(&vpp->sem_out);
+		kthread_stop(vpp->task);
+	}
+
+	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
+		"vpp thread stop done\n");
+
+	return 0;
+}
+EXPORT_SYMBOL(aml_v4l2_vpp_thread_stop);
+
 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;
+	struct aml_buf *aml_buf = 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");
+			"can not get free input buffer.\n");
 		return -1;
 	}
 
@@ -997,29 +1314,28 @@
 	if (vpp->in_num[INPUT_PORT] == 2)
 		vf->type |= VIDTYPE_V4L_EOS;
 #endif
-
-	in_buf->di_buf.vf = vf;
+	in_buf->di_buf.vf = &in_buf->vf;
 	in_buf->di_buf.flag = 0;
 	if (vf->type & VIDTYPE_V4L_EOS) {
-		u32 dw_mode = VDEC_DW_NO_AFBC;
+		u32 dw_mode = DM_YUV_ONLY;
 
 		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;
+		vf->type |= vpp->ctx->last_decoded_picinfo.field == V4L2_FIELD_INTERLACED ?
+						VIDTYPE_INTERLACE :
+						VIDTYPE_PROGRESSIVE;
 
-		if (dw_mode != VDEC_DW_NO_AFBC)
+		if (dw_mode != DM_YUV_ONLY)
 			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);
+	aml_buf = (struct aml_buf *)vf->v4l_mem_handle;
+	in_buf->aml_vb = container_of(to_vb2_v4l2_buffer(aml_buf->vb), struct aml_v4l2_buf, vb);
 
-	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
+	if (is_cpu_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) &&
@@ -1029,7 +1345,7 @@
 				vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
 			}
 			else {
-				if (fb->status == FB_ST_GE2D)
+				if (aml_buf->state == FB_ST_GE2D)
 					vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
 			}
 		}
@@ -1037,41 +1353,62 @@
 		if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
 			vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
 	}
+	memcpy(&in_buf->vf, vf, sizeof(struct vframe_s));
 
 	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);
+		"vpp_push_vframe: idx:%d, vf:%px, idx:%d, type:%x, ts:%lld flag:%x\n",
+		aml_buf->index, vf, vf->index, vf->type, vf->timestamp, vf->flag);
 
 	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
+		unsigned int dw_mode = DM_YUV_ONLY;
 		struct file *fp;
-
+		char file_name[64] = {0};
 		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)
+		if (dw_mode == DM_AVBC_ONLY)
 			break;
 
-		fp = filp_open("/data/dec_dump_before.raw",
-				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+		snprintf(file_name, 64, "%s/dec_dump_vpp_input_%ux%u.raw", dump_path, vf->width, vf->height);
+		fp = media_open(file_name, O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
 		if (!IS_ERR(fp)) {
-			struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
+			struct vb2_buffer *vb = &in_buf->aml_vb->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 y data
+			u8 *yuv_data_addr = aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 0),
+				vf->width, vf->height, 64);
+
+			// dump uv data
+			if (vb->num_planes == 1) {
+				aml_yuv_dump(fp, yuv_data_addr, vf->width,
+					vf->height / 2, 64);
+			} else {
+				aml_yuv_dump(fp, (u8 *)vb2_plane_vaddr(vb, 1),
+					vf->width, vf->height / 2, 64);
+			}
+
+			pr_info("dump idx: %d %dx%d num_planes %d\n",
+				dump_vpp_input,
+				vf->width,
+				vf->height,
+				vb->num_planes);
+
 			dump_vpp_input--;
-			filp_close(fp, NULL);
+			media_close(fp, NULL);
 		}
 	} while(0);
 
-	ATRACE_COUNTER("VC_OUT_VPP-0.receive", fb->buf_idx);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_2, aml_buf->index);
 
 	kfifo_put(&vpp->in_done_q, in_buf);
 	up(&vpp->sem_in);
 
+	update_vpp_num_cache(vpp);
+	vdec_tracing(&vpp->ctx->vtr, VTRACE_VPP_PIC_15, atomic_read(&vpp->ctx->vpp_cache_num));
+
+	aml_buf_update_holder(&vpp->ctx->bm, aml_buf, BUF_USER_VPP, BUF_GET);
+
 	return 0;
 }
 
@@ -1079,11 +1416,10 @@
 {
 	struct aml_vcodec_ctx *ctx =
 		(struct aml_vcodec_ctx *)v4l_ctx;
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)fb_ctx;
+	struct aml_buf *aml_buf =
+		(struct aml_buf *)fb_ctx;
 	int ret = -1;
-
-	ret = aml_v4l2_vpp_push_vframe(ctx->vpp, fb->vframe);
+	ret = aml_v4l2_vpp_push_vframe(ctx->vpp, &aml_buf->vframe);
 	if (ret < 0) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"vpp push vframe err, ret: %d\n", ret);
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.h b/drivers/amvdec_ports/aml_vcodec_vpp.h
index 27ffbe6..e53676f 100644
--- a/drivers/amvdec_ports/aml_vcodec_vpp.h
+++ b/drivers/amvdec_ports/aml_vcodec_vpp.h
@@ -1,22 +1,22 @@
 /*
-* 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:
-*/
+ * 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_VPP_H_
 #define _AML_VCODEC_VPP_H_
 
@@ -36,6 +36,7 @@
 	VPP_MODE_DI_LOCAL = 0x81,
 	VPP_MODE_COLOR_CONV_LOCAL = 0x82,
 	VPP_MODE_NOISE_REDUC_LOCAL = 0x83,
+	VPP_MODE_S4_DW_MMU = 0x91,
 	VPP_MODE_MAX = 0xff
 };
 
@@ -46,8 +47,9 @@
 	struct di_buffer di_buf;
 	struct di_buffer *di_local_buf;
 #endif
-	struct aml_video_dec_buf *aml_buf;
+	struct aml_v4l2_buf *aml_vb;
 	struct aml_v4l2_vpp_buf *inbuf;
+	struct vframe_s vf;
 };
 
 struct aml_v4l2_vpp {
@@ -59,6 +61,7 @@
 
 	DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_vpp_buf*));
 	DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_vpp_buf*));
+	DECLARE_KFIFO_PTR(pre_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);
@@ -70,6 +73,7 @@
 	struct task_struct *task;
 	bool running;
 	struct semaphore sem_in, sem_out;
+	struct work_struct worker;
 
 	/* In p to i transition, output/frame can be multi writer */
 	struct mutex output_lock;
@@ -101,6 +105,8 @@
 		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);
+void aml_v4l2_vpp_recycle(struct aml_v4l2_vpp *vpp, struct aml_v4l2_buf *aml_vb);
+int aml_v4l2_vpp_thread_stop(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(
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
index d0d0198..085b84d 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_h264_parser.h b/drivers/amvdec_ports/decoder/aml_h264_parser.h
index def00dd..00cff32 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amvdec_ports/decoder/aml_h264_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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_H264_PARSER_H
 #define AML_H264_PARSER_H
 
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
index 24977a8..96154e6 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..5b8b9b6 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amvdec_ports/decoder/aml_hevc_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,9 +11,12 @@
  * 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_HEVC_PARSER_H
 #define AML_HEVC_PARSER_H
 
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
index c582ab0..b86b6b1 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..c207b44 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.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 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..23bfb93 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..e35947c 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.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 AML_MPEG12_PARSER_H
 #define AML_MPEG12_PARSER_H
 
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
index 9c47c08..47075b2 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>
@@ -1072,7 +1091,7 @@
 
 	// If we have not switched to studio profile than we also did not switch bps
 	// that means something else (like a previous instance) outside set bps which
-	// would be inconsistant with the currect state, thus reset it
+	// would be inconsistent with the correct state, thus reset it
 	if (!s->studio_profile && bits_per_raw_sample != 8)
 		bits_per_raw_sample = 0;
 
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
index f9b71cf..16c78f5 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.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 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..c228abb 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/aml_vp9_parser.h b/drivers/amvdec_ports/decoder/aml_vp9_parser.h
index ddeddec..6b8cf92 100644
--- a/drivers/amvdec_ports/decoder/aml_vp9_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amvdec_ports/decoder/aml_vp9_parser.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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_VP9_PARSER_H
 #define AML_VP9_PARSER_H
 
diff --git a/drivers/amvdec_ports/decoder/utils.h b/drivers/amvdec_ports/decoder/utils.h
index 26b1552..45268ee 100644
--- a/drivers/amvdec_ports/decoder/utils.h
+++ b/drivers/amvdec_ports/decoder/utils.h
@@ -1,6 +1,4 @@
 /*
- * drivers/amlogic/media_modules/amvdec_ports/decoder/utils.h
- *
  * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -13,8 +11,12 @@
  * 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_H
 #define _UTILS_H
 
diff --git a/drivers/amvdec_ports/decoder/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c
index c28ca10..3a006b5 100644
--- a/drivers/amvdec_ports/decoder/vdec_av1_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -60,7 +60,7 @@
 /**
  * struct vdec_av1_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -205,8 +205,7 @@
 };
 
 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);
+	u8 *buf, u32 size, u64 ts, chunk_free free);
 
 static void get_pic_info(struct vdec_av1_inst *inst,
 			 struct vdec_pic_info *pic)
@@ -277,6 +276,8 @@
 			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_triple_write_mode:%d;",
+			ctx->config.parm.dec.cfg.triple_write_mode);
 		pbuf += sprintf(pbuf, "av1_buf_width:1920;");
 		pbuf += sprintf(pbuf, "av1_buf_height:1088;");
 		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -321,7 +322,7 @@
 		pbuf += sprintf(pbuf, "mW.y:%d;",
 			ctx->config.parm.dec.hdr.color_parms.white_point[1]);
 		pbuf += sprintf(pbuf, "mMaxDL:%d;",
-			ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+			ctx->config.parm.dec.hdr.color_parms.luminance[0]);
 		pbuf += sprintf(pbuf, "mMinDL:%d;",
 			ctx->config.parm.dec.hdr.color_parms.luminance[1]);
 		pbuf += sprintf(pbuf, "mMaxCLL:%d;",
@@ -360,8 +361,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable av1 hw.*/
+	/* to enable av1 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_HEVC;
 
 	/* probe info from the stream */
@@ -391,7 +394,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"av1 Instance >> %lx\n", (ulong) inst);
 
 	return 0;
@@ -412,7 +415,8 @@
 {
 	int ret = 0;
 
-	ret = vdec_write_nalu(inst, buf, size, timestamp);
+	ret = vdec_write_nalu(inst, buf, size, timestamp,
+			vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write data failed. size: %d, err: %d\n", size, ret);
@@ -450,7 +454,7 @@
 static int parse_stream_cpu(struct vdec_av1_inst *inst, u8 *buf, u32 size)
 {
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
-		"can not suppport parse stream by cpu.\n");
+		"can not support parse stream by cpu.\n");
 
 	return -1;
 }
@@ -464,7 +468,7 @@
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -915,7 +919,7 @@
 					&& ((p[1] == 0x00) && (p[2] == 0x3b)) /* terminal_provider_code */
 					&& ((p[3] == 0x00) && (p[4] == 0x00) && (p[5] == 0x08) && (p[6] == 0x00))) { /* terminal_provider_oriented_code */
 					v4l_dbg(0, V4L_DEBUG_CODEC_PARSER,
-						"dolbyvison rpu\n");
+						"dolbyvision_std rpu\n");
 					meta_buf[0] = meta_buf[1] = meta_buf[2] = 0;
 					meta_buf[3] = 0x01;
 					meta_buf[4] = 0x19;
@@ -980,7 +984,7 @@
 }
 
 static int vdec_write_nalu(struct vdec_av1_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -1000,13 +1004,14 @@
 		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,
+					0, free);
 		else
 			ret = -1;
 
 		vfree(data);
 	} else {
-		ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+		ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
 	}
 
 	return ret;
@@ -1051,7 +1056,7 @@
 		return -EAGAIN;
 	}
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -1070,7 +1075,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -1084,7 +1090,8 @@
 			(*res_chg = monitor_res_change(inst, buf, size)))
 			return 0;
 
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+					vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -1094,9 +1101,6 @@
 	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_PSINFO)
@@ -1112,6 +1116,11 @@
 		"parms status: %u\n", parms->parms_status);
  }
 
+static void get_cfg_info(struct vdec_av1_inst *inst, struct aml_vdec_cfg_infos *cfg)
+{
+	memcpy(cfg, &inst->ctx->config.parm.dec.cfg, sizeof(struct aml_vdec_cfg_infos));
+}
+
 static void get_param_comp_buf_info(struct vdec_av1_inst *inst,
 		struct vdec_comp_buf_info *params)
 {
@@ -1147,16 +1156,24 @@
 		get_param_config_info(inst, out);
 		break;
 
+	case GET_PARAM_CFG_INFO:
+		get_cfg_info(inst, out);
+		break;
+
 	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_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);
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			inst->parms.cfg.triple_write_mode;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
 		break;
 	}
+
 	case GET_PARAM_COMP_BUF_INFO:
 		get_param_comp_buf_info(inst, out);
 		break;
@@ -1175,62 +1192,6 @@
 	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)
 {
@@ -1238,6 +1199,7 @@
 	struct vdec_av1_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
 	int dw = inst->parms.cfg.double_write_mode;
+	int tw = inst->parms.cfg.triple_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -1253,8 +1215,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);
+	/* Only avbc, but DI will use YUV420 (w/4 x h/4) output. */
+	if (dw == DM_AVBC_1_1)
+		dw = DM_YUV_1_4_AVBC_B;
+
+	pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
 	/* calc DPB size */
@@ -1263,6 +1228,12 @@
 	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
+	pic->bitdepth		= ps->bitdepth;
+
+	if (tw) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
@@ -1272,9 +1243,11 @@
 	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, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
 		ps->visible_width, ps->visible_height,
-		ps->coded_width, ps->coded_height);
+		ps->coded_width, ps->coded_height, ps->bitdepth,
+		inst->parms.cfg.double_write_mode,
+		inst->parms.cfg.triple_write_mode);
 }
 
 static void set_param_comp_buf_info(struct vdec_av1_inst *inst,
@@ -1300,7 +1273,7 @@
 static void set_param_post_event(struct vdec_av1_inst *inst, u32 *event)
 {
 		aml_vdec_dispatch_event(inst->ctx, *event);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 			"av1 post event: %d\n", *event);
 }
 
@@ -1310,6 +1283,42 @@
 	inst->vsi->pic = *pic;
 }
 
+static void set_cfg_info(struct vdec_av1_inst *inst,
+	struct aml_vdec_cfg_infos *new_cfg)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+	u32 tw_new = new_cfg->triple_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode,
+		old_cfg->triple_write_mode,
+		new_cfg->triple_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		/* Only avbc, but DI will use YUV420 (w/4 x h/4) output. */
+		if (dw_new == DM_AVBC_1_1)
+			dw_new = DM_YUV_1_4_AVBC_B;
+
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	if (old_cfg->triple_write_mode != tw_new) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	*old_cfg = *new_cfg;
+}
+
 static int vdec_av1_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -1347,6 +1356,10 @@
 		set_pic_info(inst, in);
 		break;
 
+	case SET_PARAM_CFG_INFO:
+		set_cfg_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_avs2_if.c b/drivers/amvdec_ports/decoder/vdec_avs2_if.c
new file mode 100644
index 0000000..1b8a27a
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs2_if.c
@@ -0,0 +1,795 @@
+/*
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE	(16)
+
+#define HEADER_BUFFER_SIZE			(32 * 1024)
+#define SYNC_CODE				(0x498342)
+
+/**
+ * struct avs2_fb - avs2 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct avs2_fb {
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	int32_t poc;
+	uint32_t reserved;
+};
+
+/**
+ * struct vdec_avs2_dec_info - decode information
+ * @dpb_sz		: decoding picture buffer size
+ * @resolution_changed  : resolution change happen
+ * @reserved		: for 8 bytes alignment
+ * @bs_dma		: Input bit-stream buffer dma address
+ * @y_fb_dma		: Y frame buffer dma address
+ * @c_fb_dma		: C frame buffer dma address
+ * @vdec_fb_va		: VDEC frame buffer struct virtual address
+ */
+struct vdec_avs2_dec_info {
+	uint32_t dpb_sz;
+	uint32_t resolution_changed;
+	uint32_t reserved;
+	uint64_t bs_dma;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs2_vsi - shared memory for decode information exchange
+ *                        between VPU and Host.
+ *                        The memory is allocated by VPU then mapping to Host
+ *                        in vpu_dec_init() and freed in vpu_dec_deinit()
+ *                        by VPU.
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
+ * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
+ * @dec          : decode information (AP-R, VPU-W)
+ * @pic          : picture information (AP-R, VPU-W)
+ * @crop         : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs2_vsi {
+	char *header_buf;
+	int sps_size;
+	int pps_size;
+	int sei_size;
+	int head_offset;
+	struct vdec_avs2_dec_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_pic_info cur_pic;
+	struct v4l2_rect crop;
+	bool is_combine;
+	int nalu_pos;
+};
+
+/**
+ * struct vdec_avs2_inst - avs2 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx      : point to aml_vcodec_ctx
+ * @vsi      : VPU shared information
+ */
+struct vdec_avs2_inst {
+	unsigned int num_nalu;
+	struct aml_vcodec_ctx *ctx;
+	struct aml_vdec_adapt vdec;
+	struct vdec_avs2_vsi *vsi;
+	struct aml_dec_params parms;
+	struct completion comp;
+	struct vdec_comp_buf_info comp_info;
+};
+
+
+static int vdec_write_nalu(struct vdec_avs2_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free);
+
+static void get_pic_info(struct vdec_avs2_inst *inst,
+			 struct vdec_pic_info *pic)
+{
+	*pic = inst->vsi->pic;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"pic(%d, %d), buf(%d, %d)\n",
+		 pic->visible_width, pic->visible_height,
+		 pic->coded_width, pic->coded_height);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"Y(%d, %d), C(%d, %d)\n",
+		pic->y_bs_sz, pic->y_len_sz,
+		pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_crop_info(struct vdec_avs2_inst *inst, struct v4l2_rect *cr)
+{
+	cr->left = inst->vsi->crop.left;
+	cr->top = inst->vsi->crop.top;
+	cr->width = inst->vsi->crop.width;
+	cr->height = inst->vsi->crop.height;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"l=%d, t=%d, w=%d, h=%d\n",
+		 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_dpb_size(struct vdec_avs2_inst *inst, unsigned int *dpb_sz)
+{
+	*dpb_sz = inst->vsi->dec.dpb_sz;
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+	u8 *pbuf = parm;
+
+	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
+	pbuf += sprintf(pbuf, "avs2_double_write_mode:3;");
+	pbuf += sprintf(pbuf, "avs2_buf_width:1920;");
+	pbuf += sprintf(pbuf, "avs2_buf_height:1088;");
+	pbuf += sprintf(pbuf, "avs2_max_pic_w:8192;");
+	pbuf += sprintf(pbuf, "avs2_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;");
+	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
+
+	return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs2_inst *inst)
+{
+	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;
+
+		pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+			ctx->config.parm.dec.cfg.ref_buf_margin);
+		pbuf += sprintf(pbuf, "avs2_double_write_mode:%d;",
+			ctx->config.parm.dec.cfg.double_write_mode);
+		pbuf += sprintf(pbuf, "avs2_triple_write_mode:%d;",
+			ctx->config.parm.dec.cfg.triple_write_mode);
+		pbuf += sprintf(pbuf, "avs2_buf_width:1920;");
+		pbuf += sprintf(pbuf, "avs2_buf_height:1088;");
+		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+		pbuf += sprintf(pbuf, "no_head:0;");
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+			ctx->config.parm.dec.cfg.canvas_mem_mode);
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
+			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 = 3;
+		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) {
+		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;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+		pbuf += sprintf(pbuf, "mB.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+		pbuf += sprintf(pbuf, "mB.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+		pbuf += sprintf(pbuf, "mR.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+		pbuf += sprintf(pbuf, "mR.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+		pbuf += sprintf(pbuf, "mW.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+		pbuf += sprintf(pbuf, "mW.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+		pbuf += sprintf(pbuf, "mMaxDL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+		pbuf += sprintf(pbuf, "mMinDL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+		pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+		pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+		ctx->config.length	= pbuf - ctx->config.buf;
+		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;
+	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs2_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+	struct vdec_avs2_inst *inst = NULL;
+	int ret = -1;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->vdec.frm_name	= "AVS2";
+	inst->vdec.video_type	= VFORMAT_AVS2;
+	inst->vdec.filp		= ctx->dev->filp;
+	inst->vdec.ctx		= ctx;
+	inst->ctx		= ctx;
+
+	vdec_parser_parms(inst);
+
+	/* set play mode.*/
+	if (ctx->is_drm_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+	/* to enable avs2 hw.*/
+	inst->vdec.port.type	= PORT_TYPE_HEVC;
+
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_avs2_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 = 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;
+
+	/* init decoder. */
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_avs2 init err=%d\n", ret);
+		goto err;
+	}
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"avs2 Instance >> %lx\n", (ulong) inst);
+
+	return 0;
+err:
+	if (inst && inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+	if (inst && inst->vsi)
+		kfree(inst->vsi);
+	if (inst)
+		kfree(inst);
+	*h_vdec = 0;
+
+	return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs2_inst *inst,
+			      u8 *buf, u32 size, u64 timestamp)
+{
+	int ret = 0;
+
+	ret = vdec_write_nalu(inst, buf, size, timestamp,
+			vdec_vframe_input_free);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write data failed. size: %d, err: %d\n", size, ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_avs2_inst *inst,
+	ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+		vdec_vframe_input_free, inst->ctx);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write frame data failed. err: %d\n", ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs2_inst *inst, u8 *buf, u32 size)
+{
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		"can not support parse stream by cpu.\n");
+
+	return -1;
+}
+
+static int vdec_avs2_probe(unsigned long h_vdec,
+	struct aml_vcodec_mem *bs, void *out)
+{
+	struct vdec_avs2_inst *inst =
+		(struct vdec_avs2_inst *)h_vdec;
+	u8 *buf = (u8 *)bs->vaddr;
+	u32 size = bs->size;
+	int ret = 0;
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if ((s->magic != AML_VIDEO_MAGIC) &&
+				(s->type != V4L_STREAM_TYPE_MATEDATA))
+				return -1;
+
+			if (inst->ctx->param_sets_from_ucode) {
+				ret = parse_stream_ucode(inst, s->data,
+					s->len, bs->timestamp);
+			} else {
+				ret = parse_stream_cpu(inst, s->data, s->len);
+			}
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = parse_stream_ucode_dma(inst, bs->addr, size,
+				bs->timestamp, BUFF_IDX(bs, bs->index));
+		}
+	} else {
+		if (inst->ctx->param_sets_from_ucode) {
+			ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+		} else {
+			ret = parse_stream_cpu(inst, buf, size);
+		}
+	}
+
+	inst->vsi->cur_pic = inst->vsi->pic;
+
+	return ret;
+}
+
+static void vdec_avs2_deinit(unsigned long h_vdec)
+{
+	struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	video_decoder_release(&inst->vdec);
+
+	if (inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+
+	if (inst->vsi)
+		kfree(inst->vsi);
+
+	kfree(inst);
+
+	ctx->drv_handle = 0;
+}
+
+static int vdec_write_nalu(struct vdec_avs2_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+	return ret;
+}
+
+static bool monitor_res_change(struct vdec_avs2_inst *inst, u8 *buf, u32 size)
+{
+	int ret = -1;
+	u8 *p = buf;
+	int len = size;
+	u32 synccode =
+		((p[17] << 16) | (p[18] << 8) | p[19]);
+
+	if (synccode == SYNC_CODE) {
+		ret = parse_stream_cpu(inst, p, len);
+		if (!ret && (inst->vsi->cur_pic.coded_width !=
+			inst->vsi->pic.coded_width ||
+			inst->vsi->cur_pic.coded_height !=
+			inst->vsi->pic.coded_height)) {
+			inst->vsi->cur_pic = inst->vsi->pic;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int vdec_avs2_decode(unsigned long h_vdec,
+			   struct aml_vcodec_mem *bs, bool *res_chg)
+{
+	struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+	u8 *buf = (u8 *) bs->vaddr;
+	u32 size = bs->size;
+	int ret = -1;
+
+	if (bs == NULL)
+		return -1;
+
+	if (vdec_input_full(vdec)) {
+		return -EAGAIN;
+	}
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if (s->magic != AML_VIDEO_MAGIC)
+				return -1;
+
+			if (!inst->ctx->param_sets_from_ucode &&
+				(s->type == V4L_STREAM_TYPE_MATEDATA)) {
+				if ((*res_chg = monitor_res_change(inst,
+					s->data, s->len)))
+				return 0;
+			}
+
+			ret = vdec_vframe_write(vdec,
+				s->data,
+				s->len,
+				bs->timestamp,
+				0,
+				vdec_vframe_input_free);
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = vdec_vframe_write_with_dma(vdec,
+				bs->addr, size, bs->timestamp,
+				BUFF_IDX(bs, bs->index),
+				vdec_vframe_input_free, inst->ctx);
+		}
+	} else {
+		/*checked whether the resolution changes.*/
+		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,
+				vdec_vframe_input_free);
+	}
+
+	return ret;
+}
+
+ static void get_param_config_info(struct vdec_avs2_inst *inst,
+	struct aml_dec_params *parms)
+ {
+	 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)
+		 parms->hdr = inst->parms.hdr;
+	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+		 parms->cnt = inst->parms.cnt;
+
+	 parms->parms_status |= inst->parms.parms_status;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"parms status: %u\n", parms->parms_status);
+ }
+
+static void get_param_comp_buf_info(struct vdec_avs2_inst *inst,
+		struct vdec_comp_buf_info *params)
+{
+	memcpy(params, &inst->comp_info, sizeof(*params));
+}
+
+static int vdec_avs2_get_param(unsigned long h_vdec,
+			       enum vdec_get_param_type type, void *out)
+{
+	int ret = 0;
+	struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs2 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		get_pic_info(inst, out);
+		break;
+
+	case GET_PARAM_DPB_SIZE:
+		get_dpb_size(inst, out);
+		break;
+
+	case GET_PARAM_CROP_INFO:
+		get_crop_info(inst, out);
+		break;
+
+	case GET_PARAM_CONFIG_INFO:
+		get_param_config_info(inst, out);
+		break;
+
+	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_MODE:
+	{
+		u32 *mode = out;
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			inst->parms.cfg.triple_write_mode;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
+		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);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs2_inst *inst)
+{
+	complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs2_inst *inst,
+	struct aml_vdec_ps_infos *ps)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct vdec_avs2_dec_info *dec = &inst->vsi->dec;
+	struct v4l2_rect *rect = &inst->vsi->crop;
+	int dw = inst->parms.cfg.double_write_mode;
+	int tw = inst->parms.cfg.triple_write_mode;
+
+	/* fill visible area size that be used for EGL. */
+	pic->visible_width	= ps->visible_width;
+	pic->visible_height	= ps->visible_height;
+
+	/* calc visible ares. */
+	rect->left		= 0;
+	rect->top		= 0;
+	rect->width		= pic->visible_width;
+	rect->height		= pic->visible_height;
+
+	/* config canvas size that be used for decoder. */
+	pic->coded_width	= ps->coded_width;
+	pic->coded_height	= ps->coded_height;
+
+	pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
+	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;
+	pic->bitdepth		= ps->bitdepth;
+
+	if (tw) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	inst->parms.ps 	= *ps;
+	inst->parms.parms_status |=
+		V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+	/*wake up*/
+	complete(&inst->comp);
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		"Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
+		pic->visible_width, pic->visible_height,
+		pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
+}
+
+static void set_param_comp_buf_info(struct vdec_avs2_inst *inst,
+		struct vdec_comp_buf_info *info)
+{
+	memcpy(&inst->comp_info, info, sizeof(*info));
+}
+
+static void set_param_hdr_info(struct vdec_avs2_inst *inst,
+	struct aml_vdec_hdr_infos *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_EXINFO,
+			"avs2 set HDR infos\n");
+	}
+}
+
+static void set_param_post_event(struct vdec_avs2_inst *inst, u32 *event)
+{
+		aml_vdec_dispatch_event(inst->ctx, *event);
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+			"avs2 post event: %d\n", *event);
+}
+
+static void set_pic_info(struct vdec_avs2_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	inst->vsi->pic = *pic;
+}
+
+static void set_cfg_info(struct vdec_avs2_inst *inst,
+	struct aml_vdec_cfg_infos *new_cfg)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+	u32 tw_new = new_cfg->triple_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode,
+		old_cfg->triple_write_mode,
+		new_cfg->triple_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	if (old_cfg->triple_write_mode != tw_new) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	*old_cfg = *new_cfg;
+}
+
+static int vdec_avs2_set_param(unsigned long h_vdec,
+	enum vdec_set_param_type type, void *in)
+{
+	int ret = 0;
+	struct vdec_avs2_inst *inst = (struct vdec_avs2_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs2 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	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_COMP_BUF_INFO:
+		set_param_comp_buf_info(inst, in);
+		break;
+
+	case SET_PARAM_HDR_INFO:
+		set_param_hdr_info(inst, in);
+		break;
+
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(inst, in);
+		break;
+
+	case SET_PARAM_PIC_INFO:
+		set_pic_info(inst, in);
+		break;
+
+	case SET_PARAM_CFG_INFO:
+		set_cfg_info(inst, in);
+		break;
+
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid set parameter type=%d\n", type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct vdec_common_if vdec_avs2_if = {
+	.init		= vdec_avs2_init,
+	.probe		= vdec_avs2_probe,
+	.decode		= vdec_avs2_decode,
+	.get_param	= vdec_avs2_get_param,
+	.set_param	= vdec_avs2_set_param,
+	.deinit		= vdec_avs2_deinit,
+};
+
+struct vdec_common_if *get_avs2_dec_comm_if(void)
+{
+	return &vdec_avs2_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_avs3_if.c b/drivers/amvdec_ports/decoder/vdec_avs3_if.c
new file mode 100644
index 0000000..e4de1a2
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs3_if.c
@@ -0,0 +1,795 @@
+/*
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE	(16)
+
+#define HEADER_BUFFER_SIZE			(32 * 1024)
+#define SYNC_CODE				(0x498342)
+
+/**
+ * struct avs3_fb - avs3 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct avs3_fb {
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	int32_t poc;
+	uint32_t reserved;
+};
+
+/**
+ * struct vdec_avs3_dec_info - decode information
+ * @dpb_sz		: decoding picture buffer size
+ * @resolution_changed  : resolution change happen
+ * @reserved		: for 8 bytes alignment
+ * @bs_dma		: Input bit-stream buffer dma address
+ * @y_fb_dma		: Y frame buffer dma address
+ * @c_fb_dma		: C frame buffer dma address
+ * @vdec_fb_va		: VDEC frame buffer struct virtual address
+ */
+struct vdec_avs3_dec_info {
+	uint32_t dpb_sz;
+	uint32_t resolution_changed;
+	uint32_t reserved;
+	uint64_t bs_dma;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs3_vsi - shared memory for decode information exchange
+ *                        between VPU and Host.
+ *                        The memory is allocated by VPU then mapping to Host
+ *                        in vpu_dec_init() and freed in vpu_dec_deinit()
+ *                        by VPU.
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
+ * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
+ * @dec          : decode information (AP-R, VPU-W)
+ * @pic          : picture information (AP-R, VPU-W)
+ * @crop         : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs3_vsi {
+	char *header_buf;
+	int sps_size;
+	int pps_size;
+	int sei_size;
+	int head_offset;
+	struct vdec_avs3_dec_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_pic_info cur_pic;
+	struct v4l2_rect crop;
+	bool is_combine;
+	int nalu_pos;
+};
+
+/**
+ * struct vdec_avs3_inst - avs3 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx      : point to aml_vcodec_ctx
+ * @vsi      : VPU shared information
+ */
+struct vdec_avs3_inst {
+	unsigned int num_nalu;
+	struct aml_vcodec_ctx *ctx;
+	struct aml_vdec_adapt vdec;
+	struct vdec_avs3_vsi *vsi;
+	struct aml_dec_params parms;
+	struct completion comp;
+	struct vdec_comp_buf_info comp_info;
+};
+
+
+static int vdec_write_nalu(struct vdec_avs3_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free);
+
+static void get_pic_info(struct vdec_avs3_inst *inst,
+			 struct vdec_pic_info *pic)
+{
+	*pic = inst->vsi->pic;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"pic(%d, %d), buf(%d, %d)\n",
+		 pic->visible_width, pic->visible_height,
+		 pic->coded_width, pic->coded_height);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"Y(%d, %d), C(%d, %d)\n",
+		pic->y_bs_sz, pic->y_len_sz,
+		pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_crop_info(struct vdec_avs3_inst *inst, struct v4l2_rect *cr)
+{
+	cr->left = inst->vsi->crop.left;
+	cr->top = inst->vsi->crop.top;
+	cr->width = inst->vsi->crop.width;
+	cr->height = inst->vsi->crop.height;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"l=%d, t=%d, w=%d, h=%d\n",
+		 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_dpb_size(struct vdec_avs3_inst *inst, unsigned int *dpb_sz)
+{
+	*dpb_sz = inst->vsi->dec.dpb_sz;
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+	u8 *pbuf = parm;
+
+	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
+	pbuf += sprintf(pbuf, "avs3_double_write_mode:3;");
+	pbuf += sprintf(pbuf, "avs3_buf_width:1920;");
+	pbuf += sprintf(pbuf, "avs3_buf_height:1088;");
+	pbuf += sprintf(pbuf, "avs3_max_pic_w:8192;");
+	pbuf += sprintf(pbuf, "avs3_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;");
+	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
+
+	return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs3_inst *inst)
+{
+	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;
+
+		pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+			ctx->config.parm.dec.cfg.ref_buf_margin);
+		pbuf += sprintf(pbuf, "avs3_double_write_mode:%d;",
+			ctx->config.parm.dec.cfg.double_write_mode);
+		pbuf += sprintf(pbuf, "avs3_triple_write_mode:%d;",
+			ctx->config.parm.dec.cfg.triple_write_mode);
+		pbuf += sprintf(pbuf, "avs3_buf_width:1920;");
+		pbuf += sprintf(pbuf, "avs3_buf_height:1088;");
+		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
+		pbuf += sprintf(pbuf, "no_head:0;");
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+			ctx->config.parm.dec.cfg.canvas_mem_mode);
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
+			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 = 3;
+		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) {
+		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;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+		pbuf += sprintf(pbuf, "mB.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+		pbuf += sprintf(pbuf, "mB.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+		pbuf += sprintf(pbuf, "mR.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+		pbuf += sprintf(pbuf, "mR.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+		pbuf += sprintf(pbuf, "mW.x:%d;",
+			ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+		pbuf += sprintf(pbuf, "mW.y:%d;",
+			ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+		pbuf += sprintf(pbuf, "mMaxDL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.luminance[0] * 1000);
+		pbuf += sprintf(pbuf, "mMinDL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+		pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+		pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+		ctx->config.length	= pbuf - ctx->config.buf;
+		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;
+	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs3_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+	struct vdec_avs3_inst *inst = NULL;
+	int ret = -1;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->vdec.frm_name	= "AVS3";
+	inst->vdec.video_type	= VFORMAT_AVS3;
+	inst->vdec.filp		= ctx->dev->filp;
+	inst->vdec.ctx		= ctx;
+	inst->ctx		= ctx;
+
+	vdec_parser_parms(inst);
+
+	/* set play mode.*/
+	if (ctx->is_drm_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+	/* to enable avs3 hw.*/
+	inst->vdec.port.type	= PORT_TYPE_HEVC;
+
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_avs3_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 = 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;
+
+	/* init decoder. */
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_avs3 init err=%d\n", ret);
+		goto err;
+	}
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"avs3 Instance >> %lx\n", (ulong) inst);
+
+	return 0;
+err:
+	if (inst && inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+	if (inst && inst->vsi)
+		kfree(inst->vsi);
+	if (inst)
+		kfree(inst);
+	*h_vdec = 0;
+
+	return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs3_inst *inst,
+			      u8 *buf, u32 size, u64 timestamp)
+{
+	int ret = 0;
+
+	ret = vdec_write_nalu(inst, buf, size, timestamp,
+			vdec_vframe_input_free);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write data failed. size: %d, err: %d\n", size, ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_avs3_inst *inst,
+	ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+		vdec_vframe_input_free, inst->ctx);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write frame data failed. err: %d\n", ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs3_inst *inst, u8 *buf, u32 size)
+{
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		"can not support parse stream by cpu.\n");
+
+	return -1;
+}
+
+static int vdec_avs3_probe(unsigned long h_vdec,
+	struct aml_vcodec_mem *bs, void *out)
+{
+	struct vdec_avs3_inst *inst =
+		(struct vdec_avs3_inst *)h_vdec;
+	u8 *buf = (u8 *)bs->vaddr;
+	u32 size = bs->size;
+	int ret = 0;
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if ((s->magic != AML_VIDEO_MAGIC) &&
+				(s->type != V4L_STREAM_TYPE_MATEDATA))
+				return -1;
+
+			if (inst->ctx->param_sets_from_ucode) {
+				ret = parse_stream_ucode(inst, s->data,
+					s->len, bs->timestamp);
+			} else {
+				ret = parse_stream_cpu(inst, s->data, s->len);
+			}
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = parse_stream_ucode_dma(inst, bs->addr, size,
+				bs->timestamp, BUFF_IDX(bs, bs->index));
+		}
+	} else {
+		if (inst->ctx->param_sets_from_ucode) {
+			ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+		} else {
+			ret = parse_stream_cpu(inst, buf, size);
+		}
+	}
+
+	inst->vsi->cur_pic = inst->vsi->pic;
+
+	return ret;
+}
+
+static void vdec_avs3_deinit(unsigned long h_vdec)
+{
+	struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	video_decoder_release(&inst->vdec);
+
+	if (inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+
+	if (inst->vsi)
+		kfree(inst->vsi);
+
+	kfree(inst);
+
+	ctx->drv_handle = 0;
+}
+
+static int vdec_write_nalu(struct vdec_avs3_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+	return ret;
+}
+
+static bool monitor_res_change(struct vdec_avs3_inst *inst, u8 *buf, u32 size)
+{
+	int ret = -1;
+	u8 *p = buf;
+	int len = size;
+	u32 synccode =
+		((p[17] << 16) | (p[18] << 8) | p[19]);
+
+	if (synccode == SYNC_CODE) {
+		ret = parse_stream_cpu(inst, p, len);
+		if (!ret && (inst->vsi->cur_pic.coded_width !=
+			inst->vsi->pic.coded_width ||
+			inst->vsi->cur_pic.coded_height !=
+			inst->vsi->pic.coded_height)) {
+			inst->vsi->cur_pic = inst->vsi->pic;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int vdec_avs3_decode(unsigned long h_vdec,
+			   struct aml_vcodec_mem *bs, bool *res_chg)
+{
+	struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+	u8 *buf = (u8 *) bs->vaddr;
+	u32 size = bs->size;
+	int ret = -1;
+
+	if (bs == NULL)
+		return -1;
+
+	if (vdec_input_full(vdec)) {
+		return -EAGAIN;
+	}
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if (s->magic != AML_VIDEO_MAGIC)
+				return -1;
+
+			if (!inst->ctx->param_sets_from_ucode &&
+				(s->type == V4L_STREAM_TYPE_MATEDATA)) {
+				if ((*res_chg = monitor_res_change(inst,
+					s->data, s->len)))
+				return 0;
+			}
+
+			ret = vdec_vframe_write(vdec,
+				s->data,
+				s->len,
+				bs->timestamp,
+				0,
+				vdec_vframe_input_free);
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = vdec_vframe_write_with_dma(vdec,
+				bs->addr, size, bs->timestamp,
+				BUFF_IDX(bs, bs->index),
+				vdec_vframe_input_free, inst->ctx);
+		}
+	} else {
+		/*checked whether the resolution changes.*/
+		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,
+				vdec_vframe_input_free);
+	}
+
+	return ret;
+}
+
+ static void get_param_config_info(struct vdec_avs3_inst *inst,
+	struct aml_dec_params *parms)
+ {
+	 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)
+		 parms->hdr = inst->parms.hdr;
+	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+		 parms->cnt = inst->parms.cnt;
+
+	 parms->parms_status |= inst->parms.parms_status;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"parms status: %u\n", parms->parms_status);
+ }
+
+static void get_param_comp_buf_info(struct vdec_avs3_inst *inst,
+		struct vdec_comp_buf_info *params)
+{
+	memcpy(params, &inst->comp_info, sizeof(*params));
+}
+
+static int vdec_avs3_get_param(unsigned long h_vdec,
+			       enum vdec_get_param_type type, void *out)
+{
+	int ret = 0;
+	struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs3 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		get_pic_info(inst, out);
+		break;
+
+	case GET_PARAM_DPB_SIZE:
+		get_dpb_size(inst, out);
+		break;
+
+	case GET_PARAM_CROP_INFO:
+		get_crop_info(inst, out);
+		break;
+
+	case GET_PARAM_CONFIG_INFO:
+		get_param_config_info(inst, out);
+		break;
+
+	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_MODE:
+	{
+		u32 *mode = out;
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			inst->parms.cfg.triple_write_mode;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
+		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);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs3_inst *inst)
+{
+	complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs3_inst *inst,
+	struct aml_vdec_ps_infos *ps)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct vdec_avs3_dec_info *dec = &inst->vsi->dec;
+	struct v4l2_rect *rect = &inst->vsi->crop;
+	int dw = inst->parms.cfg.double_write_mode;
+	int tw = inst->parms.cfg.triple_write_mode;
+
+	/* fill visible area size that be used for EGL. */
+	pic->visible_width	= ps->visible_width;
+	pic->visible_height	= ps->visible_height;
+
+	/* calc visible ares. */
+	rect->left		= 0;
+	rect->top		= 0;
+	rect->width		= pic->visible_width;
+	rect->height		= pic->visible_height;
+
+	/* config canvas size that be used for decoder. */
+	pic->coded_width	= ps->coded_width;
+	pic->coded_height	= ps->coded_height;
+
+	pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
+	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;
+	pic->bitdepth		= ps->bitdepth;
+
+	if (tw) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	inst->parms.ps 	= *ps;
+	inst->parms.parms_status |=
+		V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+	/*wake up*/
+	complete(&inst->comp);
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		"Parse from ucode, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
+		pic->visible_width, pic->visible_height,
+		pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
+}
+
+static void set_param_comp_buf_info(struct vdec_avs3_inst *inst,
+		struct vdec_comp_buf_info *info)
+{
+	memcpy(&inst->comp_info, info, sizeof(*info));
+}
+
+static void set_param_hdr_info(struct vdec_avs3_inst *inst,
+	struct aml_vdec_hdr_infos *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_EXINFO,
+			"avs3 set HDR infos\n");
+	}
+}
+
+static void set_param_post_event(struct vdec_avs3_inst *inst, u32 *event)
+{
+		aml_vdec_dispatch_event(inst->ctx, *event);
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+			"avs3 post event: %d\n", *event);
+}
+
+static void set_pic_info(struct vdec_avs3_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	inst->vsi->pic = *pic;
+}
+
+static void set_cfg_info(struct vdec_avs3_inst *inst,
+	struct aml_vdec_cfg_infos *new_cfg)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+	u32 tw_new = new_cfg->triple_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode,
+		old_cfg->triple_write_mode,
+		new_cfg->triple_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	if (old_cfg->triple_write_mode != tw_new) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	*old_cfg = *new_cfg;
+}
+
+static int vdec_avs3_set_param(unsigned long h_vdec,
+	enum vdec_set_param_type type, void *in)
+{
+	int ret = 0;
+	struct vdec_avs3_inst *inst = (struct vdec_avs3_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs3 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	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_COMP_BUF_INFO:
+		set_param_comp_buf_info(inst, in);
+		break;
+
+	case SET_PARAM_HDR_INFO:
+		set_param_hdr_info(inst, in);
+		break;
+
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(inst, in);
+		break;
+
+	case SET_PARAM_PIC_INFO:
+		set_pic_info(inst, in);
+		break;
+
+	case SET_PARAM_CFG_INFO:
+		set_cfg_info(inst, in);
+		break;
+
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid set parameter type=%d\n", type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static struct vdec_common_if vdec_avs3_if = {
+	.init		= vdec_avs3_init,
+	.probe		= vdec_avs3_probe,
+	.decode		= vdec_avs3_decode,
+	.get_param	= vdec_avs3_get_param,
+	.set_param	= vdec_avs3_set_param,
+	.deinit		= vdec_avs3_deinit,
+};
+
+struct vdec_common_if *get_avs3_dec_comm_if(void)
+{
+	return &vdec_avs3_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_avs_if.c b/drivers/amvdec_ports/decoder/vdec_avs_if.c
new file mode 100644
index 0000000..dbc90b7
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_avs_if.c
@@ -0,0 +1,587 @@
+/*
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_drv.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
+#include <trace/events/meson_atrace.h>
+
+#define PREFIX_SIZE	(16)
+
+#define HEADER_BUFFER_SIZE			(32 * 1024)
+#define SYNC_CODE				(0x498342)
+
+/**
+ * struct vdec_avs_dec_info - decode information
+ * @dpb_sz		: decoding picture buffer size
+ * @resolution_changed  : resolution change happen
+ * @reserved		: for 8 bytes alignment
+ * @bs_dma		: Input bit-stream buffer dma address
+ * @y_fb_dma		: Y frame buffer dma address
+ * @c_fb_dma		: C frame buffer dma address
+ * @vdec_fb_va		: VDEC frame buffer struct virtual address
+ */
+struct vdec_avs_dec_info {
+	uint32_t dpb_sz;
+	uint32_t resolution_changed;
+	uint32_t reserved;
+	uint64_t bs_dma;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_avs_vsi - shared memory for decode information exchange
+ *                        between VPU and Host.
+ *                        The memory is allocated by VPU then mapping to Host
+ *                        in vpu_dec_init() and freed in vpu_dec_deinit()
+ *                        by VPU.
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
+ * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
+ * @dec          : decode information (AP-R, VPU-W)
+ * @pic          : picture information (AP-R, VPU-W)
+ * @crop         : crop information (AP-R, VPU-W)
+ */
+struct vdec_avs_vsi {
+	char *header_buf;
+	int sps_size;
+	int pps_size;
+	int sei_size;
+	int head_offset;
+	struct vdec_avs_dec_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_pic_info cur_pic;
+	struct v4l2_rect crop;
+	bool is_combine;
+	int nalu_pos;
+};
+
+/**
+ * struct vdec_avs_inst - avs decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx      : point to aml_vcodec_ctx
+ * @vsi      : VPU shared information
+ */
+struct vdec_avs_inst {
+	unsigned int num_nalu;
+	struct aml_vcodec_ctx *ctx;
+	struct aml_vdec_adapt vdec;
+	struct vdec_avs_vsi *vsi;
+	struct aml_dec_params parms;
+	struct completion comp;
+	struct vdec_comp_buf_info comp_info;
+};
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+	u8 *pbuf = parm;
+
+	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;");
+
+	return parm - pbuf;
+}
+
+static void vdec_parser_parms(struct vdec_avs_inst *inst)
+{
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	if (ctx->config.parm.dec.parms_status &
+		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+		u8 *pbuf = ctx->config.buf;
+
+		pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+			ctx->config.parm.dec.cfg.canvas_mem_mode);
+		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
+			ctx->config.parm.dec.cfg.ref_buf_margin);
+		ctx->config.length = pbuf - ctx->config.buf;
+	} else {
+		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
+	}
+
+	inst->vdec.config	= ctx->config;
+	inst->parms.cfg		= ctx->config.parm.dec.cfg;
+	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_avs_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+	struct vdec_avs_inst *inst = NULL;
+	int ret = -1;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->vdec.frm_name	= "AVS";
+	inst->vdec.video_type	= VFORMAT_AVS;
+	inst->vdec.filp		= ctx->dev->filp;
+	inst->vdec.ctx		= ctx;
+	inst->ctx		= ctx;
+
+	vdec_parser_parms(inst);
+
+	/* set play mode.*/
+	if (ctx->is_drm_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+	/* to enable avs hw.*/
+	inst->vdec.port.type	= PORT_TYPE_VIDEO;
+
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_avs_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 = 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;
+
+	/* init decoder. */
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_avs init err=%d\n", ret);
+		goto err;
+	}
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"avs Instance >> %lx\n", (ulong) inst);
+
+	return 0;
+err:
+	if (inst && inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+	if (inst && inst->vsi)
+		kfree(inst->vsi);
+	if (inst)
+		kfree(inst);
+	*h_vdec = 0;
+
+	return ret;
+}
+
+static int vdec_write_nalu(struct vdec_avs_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+	return ret;
+}
+
+static int parse_stream_ucode(struct vdec_avs_inst *inst,
+			      u8 *buf, u32 size, u64 timestamp)
+{
+	int ret = 0;
+
+	ret = vdec_write_nalu(inst, buf, size, timestamp,
+			vdec_vframe_input_free);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write data failed. size: %d, err: %d\n", size, ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+static int parse_stream_ucode_dma(struct vdec_avs_inst *inst,
+	ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+		vdec_vframe_input_free, inst->ctx);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write frame data failed. err: %d\n", ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_avs_inst *inst, u8 *buf, u32 size)
+{
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		"can not support parse stream by cpu.\n");
+
+	return -1;
+}
+
+static int vdec_avs_probe(unsigned long h_vdec,
+	struct aml_vcodec_mem *bs, void *out)
+{
+	struct vdec_avs_inst *inst =
+		(struct vdec_avs_inst *)h_vdec;
+	u8 *buf = (u8 *)bs->vaddr;
+	u32 size = bs->size;
+	int ret = 0;
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if ((s->magic != AML_VIDEO_MAGIC) &&
+				(s->type != V4L_STREAM_TYPE_MATEDATA))
+				return -1;
+
+			if (inst->ctx->param_sets_from_ucode) {
+				ret = parse_stream_ucode(inst, s->data,
+					s->len, bs->timestamp);
+			} else {
+				ret = parse_stream_cpu(inst, s->data, s->len);
+			}
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = parse_stream_ucode_dma(inst, bs->addr, size,
+				bs->timestamp, BUFF_IDX(bs, bs->index));
+		}
+	} else {
+		if (inst->ctx->param_sets_from_ucode) {
+			ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+		} else {
+			ret = parse_stream_cpu(inst, buf, size);
+		}
+	}
+
+	inst->vsi->cur_pic = inst->vsi->pic;
+
+	return ret;
+}
+
+static int vdec_avs_decode(unsigned long h_vdec,
+			      struct aml_vcodec_mem *bs, bool *res_chg)
+{
+	struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+	u8 *buf = (u8 *) bs->vaddr;
+	u32 size = bs->size;
+	int ret = -1;
+
+	if (vdec_input_full(vdec))
+		return -EAGAIN;
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if (s->magic != AML_VIDEO_MAGIC)
+				return -1;
+
+			ret = vdec_vframe_write(vdec,
+				s->data,
+				s->len,
+				bs->timestamp,
+				0,
+				vdec_vframe_input_free);
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = vdec_vframe_write_with_dma(vdec,
+				bs->addr, size, bs->timestamp,
+				BUFF_IDX(bs, bs->index),
+				vdec_vframe_input_free, inst->ctx);
+		}
+	} else {
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+					vdec_vframe_input_free);
+	}
+
+	return ret;
+}
+
+static void get_pic_info(struct vdec_avs_inst *inst,
+			 struct vdec_pic_info *pic)
+{
+	*pic = inst->vsi->pic;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"pic(%d, %d), buf(%d, %d)\n",
+		 pic->visible_width, pic->visible_height,
+		 pic->coded_width, pic->coded_height);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"Y(%d, %d), C(%d, %d)\n",
+		pic->y_bs_sz, pic->y_len_sz,
+		pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void get_dpb_size(struct vdec_avs_inst *inst, unsigned int *dpb_sz)
+{
+	*dpb_sz = inst->vsi->dec.dpb_sz;
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO, "sz=%d\n", *dpb_sz);
+}
+
+static void get_crop_info(struct vdec_avs_inst *inst, struct v4l2_rect *cr)
+{
+	cr->left = inst->vsi->crop.left;
+	cr->top = inst->vsi->crop.top;
+	cr->width = inst->vsi->crop.width;
+	cr->height = inst->vsi->crop.height;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"l=%d, t=%d, w=%d, h=%d\n",
+		 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_param_config_info(struct vdec_avs_inst *inst,
+   struct aml_dec_params *parms)
+{
+	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)
+		parms->hdr = inst->parms.hdr;
+	if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CNTINFO)
+		parms->cnt = inst->parms.cnt;
+
+	parms->parms_status |= inst->parms.parms_status;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"parms status: %u\n", parms->parms_status);
+}
+
+static int vdec_avs_get_param(unsigned long h_vdec,
+			       enum vdec_get_param_type type, void *out)
+{
+	int ret = 0;
+	struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		get_pic_info(inst, out);
+		break;
+
+	case GET_PARAM_DPB_SIZE:
+		get_dpb_size(inst, out);
+		break;
+
+	case GET_PARAM_CROP_INFO:
+		get_crop_info(inst, out);
+		break;
+
+	case GET_PARAM_CONFIG_INFO:
+		get_param_config_info(inst, out);
+		break;
+
+	case GET_PARAM_DW_MODE:
+	{
+		u32 *mode = out;
+		*mode = DM_YUV_ONLY;
+		break;
+	}
+
+	case GET_PARAM_TW_MODE:
+	{
+		unsigned int* mode = out;
+		*mode = DM_INVALID;
+		break;
+	}
+
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid get parameter type=%d\n", type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void set_param_write_sync(struct vdec_avs_inst *inst)
+{
+	complete(&inst->comp);
+}
+
+static void set_param_ps_info(struct vdec_avs_inst *inst,
+	struct aml_vdec_ps_infos *ps)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct vdec_avs_dec_info *dec = &inst->vsi->dec;
+	struct v4l2_rect *rect = &inst->vsi->crop;
+
+	/* fill visible area size that be used for EGL. */
+	pic->visible_width	= ps->visible_width;
+	pic->visible_height	= ps->visible_height;
+
+	/* calc visible ares. */
+	rect->left		= 0;
+	rect->top		= 0;
+	rect->width		= pic->visible_width;
+	rect->height		= pic->visible_height;
+
+	/* config canvas size that be used for decoder. */
+	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;
+
+	/* 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 |=
+		V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+	/*wake up*/
+	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",
+		ps->visible_width, ps->visible_height,
+		ps->coded_width, ps->coded_height,
+		pic->field == V4L2_FIELD_NONE ? "P" : "I");
+}
+
+static void set_pic_info(struct vdec_avs_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	inst->vsi->pic = *pic;
+}
+
+static void set_param_post_event(struct vdec_avs_inst *inst, u32 *event)
+{
+		aml_vdec_dispatch_event(inst->ctx, *event);
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+			"avs post event: %d\n", *event);
+}
+
+static int vdec_avs_set_param(unsigned long h_vdec,
+	enum vdec_set_param_type type, void *in)
+{
+	int ret = 0;
+	struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the avs inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	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;
+
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(inst, in);
+		break;
+
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid set parameter type=%d\n", type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void vdec_avs_deinit(unsigned long h_vdec)
+{
+	struct vdec_avs_inst *inst = (struct vdec_avs_inst *)h_vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	video_decoder_release(&inst->vdec);
+
+	if (inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+
+	if (inst->vsi)
+		kfree(inst->vsi);
+
+	kfree(inst);
+
+	ctx->drv_handle = 0;
+}
+
+static struct vdec_common_if vdec_avs_if = {
+	.init		= vdec_avs_init,
+	.probe		= vdec_avs_probe,
+	.decode		= vdec_avs_decode,
+	.get_param	= vdec_avs_get_param,
+	.set_param	= vdec_avs_set_param,
+	.deinit		= vdec_avs_deinit,
+};
+
+struct vdec_common_if *get_avs_dec_comm_if(void)
+{
+	return &vdec_avs_if;
+}
+
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 911c91d..d770115 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -32,6 +32,7 @@
 #include "../vdec_drv_base.h"
 #include "aml_h264_parser.h"
 #include "../utils/common.h"
+#include "../aml_vcodec_ts.h"
 
 /* h264 NALU type */
 #define NAL_NON_IDR_SLICE			0x01
@@ -73,7 +74,7 @@
 
 /**
  * struct h264_ring_fb_list - ring frame buffer list
- * @fb_list   : frame buffer arrary
+ * @fb_list   : frame buffer array
  * @read_idx  : read index
  * @write_idx : write index
  * @count     : buffer count in list
@@ -151,6 +152,7 @@
 	struct vdec_h264_vsi *vsi;
 	struct aml_dec_params parms;
 	struct completion comp;
+	struct vdec_comp_buf_info comp_info;
 };
 
 #if 0
@@ -176,7 +178,7 @@
 
 void dump_init(void)
 {
-	filp = filp_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
+	filp = media_open(DUMP_FILE_NAME, O_CREAT | O_RDWR, 0644);
 	if (IS_ERR(filp)) {
 		pr_err("open dump file failed\n");
 		filp = NULL;
@@ -186,7 +188,7 @@
 void dump_deinit(void)
 {
 	if (filp) {
-		filp_close(filp, current->files);
+		media_close(filp, current->files);
 		filp = NULL;
 		file_pos = 0;
 	}
@@ -218,6 +220,11 @@
 		 pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
 }
 
+static void get_cfg_info(struct vdec_h264_inst *inst, struct aml_vdec_cfg_infos *cfg)
+{
+	memcpy(cfg, &inst->ctx->config.parm.dec.cfg, sizeof(struct aml_vdec_cfg_infos));
+}
+
 static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
 {
 	cr->left = inst->vsi->crop.left;
@@ -315,6 +322,8 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
 	/* probe info from the stream */
 	inst->vsi = vzalloc(sizeof(struct vdec_h264_vsi));
@@ -342,7 +351,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"H264 Instance >> %lx", (ulong) inst);
 
 	return 0;
@@ -530,6 +539,33 @@
 	return combine;
 }
 
+static bool cloud_game_check_frame_combine(u8 *buf, u32 size)
+{
+	bool combine = false;
+	int i = 0, j = 0, cnt = 0;
+	u32 nal_type = 0;
+	u8 *p = buf;
+
+	for (i = 4; i < size; i++) {
+		j = find_start_code(p, 7);
+		if (j > 0) {
+			if (++cnt > 1) {
+				combine = true;
+				break;
+			}
+
+			nal_type = AVC_NAL_TYPE(p[j]);
+			if (nal_type != NAL_H264_AUD &&
+				(nal_type > NAL_H264_PPS || nal_type < NAL_H264_SEI))
+				break;
+			p += j;
+			i += j;
+		}
+		p++;
+	}
+	return combine;
+}
+
 static int vdec_search_startcode(u8 *buf, u32 range)
 {
 	int pos = -1;
@@ -554,7 +590,8 @@
 	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, 0,
+			vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -628,13 +665,20 @@
 static int vdec_h264_probe(unsigned long h_vdec,
 	struct aml_vcodec_mem *bs, void *out)
 {
-	struct vdec_h264_inst *inst =
-		(struct vdec_h264_inst *)h_vdec;
+	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
+	struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
 	u8 *buf = (u8 *) bs->vaddr;
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+		return 0;
+	}
+
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -688,7 +732,7 @@
 }
 
 static int vdec_write_nalu(struct vdec_h264_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	int ret = -1;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -703,7 +747,7 @@
 		goto err;
 
 	nal_type = AVC_NAL_TYPE(buf[nalu_pos]);
-	//v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "NALU type: %d, size: %u\n", nal_type, size);
+	//v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "NALU type: %d, size: %u\n", nal_type, size);
 
 	if (nal_type == NAL_H264_SPS && !is_combine) {
 		if (inst->vsi->head_offset + size > HEADER_BUFFER_SIZE) {
@@ -734,7 +778,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, 0, free);
 	} else {
 		char *write_buf = vmalloc(inst->vsi->head_offset + size);
 		if (!write_buf) {
@@ -746,7 +790,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, 0, free);
 
 		memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
 		inst->vsi->head_offset = 0;
@@ -795,7 +839,7 @@
 		inst->vsi->pic.coded_height) ||
 		(inst->vsi->pic.profile_idc !=
 		inst->vsi->cur_pic.profile_idc))) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n");
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "res change\n");
 		inst->vsi->cur_pic = inst->vsi->pic;
 		return true;
 	}
@@ -808,17 +852,27 @@
 {
 	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;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+	u8 *buf;
+	u32 size;
 	int ret = -1;
 
 	if (bs == NULL)
 		return -1;
 
+	buf = (u8 *) bs->vaddr;
+	size = bs->size;
+
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(vdec, (u32)bs->addr, size);
+		return size;
+	}
+
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -837,7 +891,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -848,8 +903,12 @@
 	} else {
 		if (inst->ctx->param_sets_from_ucode) {
 			int nal_idx = 0;
+			bool enable_fence = (inst->parms.cfg.low_latency_mode & 2) ? 1 : 0;
 			/* if the st compose from csd + slice that is the combine data. */
-			inst->vsi->is_combine = check_frame_combine(buf, size, &nal_idx);
+			if (enable_fence)
+				inst->vsi->is_combine = cloud_game_check_frame_combine(buf, size);
+			else
+				inst->vsi->is_combine = check_frame_combine(buf, size, &nal_idx);
 			/*if (nal_idx < 0)
 				return -1;*/
 		} else {
@@ -858,7 +917,8 @@
 				return 0;
 			}
 		}
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -878,8 +938,14 @@
 
 	parms->parms_status |= inst->parms.parms_status;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"parms status: %u\n", parms->parms_status);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"v4l config parms status: %u\n", parms->parms_status);
+}
+
+static void get_param_comp_buf_info(struct vdec_h264_inst *inst,
+	struct vdec_comp_buf_info *params)
+{
+	memcpy(params, &inst->comp_info, sizeof(*params));
 }
 
 static int vdec_h264_get_param(unsigned long h_vdec,
@@ -911,10 +977,25 @@
 		get_param_config_info(inst, out);
 		break;
 
+	case GET_PARAM_COMP_BUF_INFO:
+		get_param_comp_buf_info(inst, out);
+		break;
+
+	case GET_PARAM_CFG_INFO:
+		get_cfg_info(inst, out);
+		break;
+
 	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_MODE:
 	{
 		unsigned int* mode = out;
-		*mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			DM_INVALID;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
 		break;
 	}
 
@@ -932,6 +1013,30 @@
 	complete(&inst->comp);
 }
 
+static void set_cfg_info(struct vdec_h264_inst *inst,
+	struct aml_vdec_cfg_infos *new_cfg)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	*old_cfg = *new_cfg;
+}
+
 static void set_param_ps_info(struct vdec_h264_inst *inst,
 	struct aml_vdec_ps_infos *ps)
 {
@@ -951,9 +1056,10 @@
 	rect->height		= pic->visible_height;
 
 	/* config canvas size that be used for decoder. */
-	pic->coded_width	= ps->coded_width;
-	pic->coded_height	= ps->coded_height;
-	pic->y_len_sz		= pic->coded_width * pic->coded_height;
+	pic->coded_width 	= ps->coded_width;
+	pic->coded_height 	= ps->coded_height;
+
+	pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 	pic->profile_idc	= ps->profile;
 	pic->field		= ps->field;
@@ -961,21 +1067,22 @@
 	pic->dpb_margin		= ps->dpb_margin;
 	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
+	pic->bitdepth		= ps->bitdepth;
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
 		V4L2_CONFIG_PARM_DECODE_PSINFO;
 
-	vdec_config_dw_mode(pic, dw);
-
 	/*wake up*/
 	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), "
+		"scan:%s, bitdepth(%d), dw(%x)\n",
 		ps->visible_width, ps->visible_height,
 		ps->coded_width, ps->coded_height,
-		ps->field == V4L2_FIELD_NONE ? "P" : "I");
+		ps->field == V4L2_FIELD_NONE ? "P" : "I",
+		ps->bitdepth, dw);
 }
 
 static void set_param_hdr_info(struct vdec_h264_inst *inst,
@@ -989,7 +1096,7 @@
 			V4L2_CONFIG_PARM_DECODE_HDRINFO;
 		aml_vdec_dispatch_event(inst->ctx,
 			V4L2_EVENT_SRC_CH_HDRINFO);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"H264 set HDR infos\n");
 	}
 }
@@ -1003,9 +1110,14 @@
 static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
 {
 	aml_vdec_dispatch_event(inst->ctx, *event);
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"H264 post event: %d\n", *event);
 }
+static void set_param_comp_buf_info(struct vdec_h264_inst *inst,
+		struct vdec_comp_buf_info *info)
+{
+	memcpy(&inst->comp_info, info, sizeof(*info));
+}
 
 static int vdec_h264_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
@@ -1039,7 +1151,12 @@
 	case SET_PARAM_PIC_INFO:
 		set_pic_info(inst, in);
 		break;
-
+	case SET_PARAM_COMP_BUF_INFO:
+		set_param_comp_buf_info(inst, in);
+		break;
+	case SET_PARAM_CFG_INFO:
+		set_cfg_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..85242da 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -30,8 +30,9 @@
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
 #include "aml_hevc_parser.h"
+#include "../aml_vcodec_ts.h"
 
-#define HEVC_NAL_TYPE(value)				((value >> 1) & 0x3F)
+#define HEVC_NAL_TYPE(value)			((value >> 1) & 0x3F)
 #define HEADER_BUFFER_SIZE			(32 * 1024)
 
 /**
@@ -53,7 +54,7 @@
 /**
  * struct vdec_hevc_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -177,6 +178,8 @@
 			ctx->config.parm.dec.cfg.ref_buf_margin);
 		pbuf += sprintf(pbuf, "hevc_double_write_mode:%d;",
 			ctx->config.parm.dec.cfg.double_write_mode);
+		pbuf += sprintf(pbuf, "hevc_triple_write_mode:%d;",
+			ctx->config.parm.dec.cfg.triple_write_mode);
 		pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
 		pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
 		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -190,6 +193,8 @@
 			ctx->config.parm.dec.cfg.metadata_config_flag);
 		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
 			ctx->config.parm.dec.cfg.duration);
+		pbuf += sprintf(pbuf, "dv_profile:%d;",
+			ctx->config.parm.dec.cfg.dv_profile);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
 		ctx->config.parm.dec.cfg.double_write_mode = 1;
@@ -222,8 +227,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable hevc hw.*/
+	/* to enable hevc hw.*/
 	inst->vdec.port.type = PORT_TYPE_HEVC;
 
 	/* probe info from the stream */
@@ -252,7 +259,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"hevc Instance >> %lx\n", (ulong) inst);
 
 	return 0;
@@ -268,145 +275,14 @@
 	return ret;
 }
 
-
-static int refer_buffer_num(struct h265_SPS_t *sps)
-{
-	int used_buf_num = 0;
-	int sps_pic_buf_diff = 0;
-
-	if ((!sps->temporal_layer[0].num_reorder_pics) &&
-		(sps->temporal_layer[0].max_dec_pic_buffering)) {
-		/* the range of sps_num_reorder_pics_0 is in
-		[0, sps_max_dec_pic_buffering_minus1_0] */
-		used_buf_num = sps->temporal_layer[0].max_dec_pic_buffering;
-	} else
-		used_buf_num = sps->temporal_layer[0].num_reorder_pics;
-
-	sps_pic_buf_diff = sps->temporal_layer[0].max_dec_pic_buffering -
-		sps->temporal_layer[0].num_reorder_pics - 1;
-
-	if (sps_pic_buf_diff >= 4)
-		used_buf_num += 1;
-
-	/*need one more for multi instance, as
-	apply_ref_pic_set() has no chanch to run to
-	to clear referenced flag in some case */
-	used_buf_num++;
-
-	/* for eos add more buffer to flush.*/
-	used_buf_num++;
-
-	return used_buf_num;
-}
-
-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;
-	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_hevc_inst *inst, int length, int dw_mode)
-{
-	int ret = 64;
-
-	switch (vdec_get_dw_mode(inst, dw_mode)) {
-	case 0x0: /* 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 fill_vdec_params(struct vdec_hevc_inst *inst, struct h265_SPS_t *sps)
-{
-	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;
-	int margin = inst->parms.cfg.ref_buf_margin;
-
-	/* fill visible area size that be used for EGL. */
-	pic->visible_width = sps->width - (sps->output_window.left_offset +
-		sps->output_window.right_offset);
-	pic->visible_height = sps->height - (sps->output_window.top_offset +
-		sps->output_window.bottom_offset);
-	pic->visible_width = vdec_pic_scale(inst, pic->visible_width, dw);
-	pic->visible_height = vdec_pic_scale(inst, pic->visible_height, dw);
-
-	/* calc visible ares. */
-	rect->left		= 0;
-	rect->top		= 0;
-	rect->width		= pic->visible_width;
-	rect->height		= pic->visible_height;
-
-	/* config canvas size that be used for decoder. */
-	pic->coded_width	= vdec_pic_scale(inst, ALIGN(sps->width, 32), dw);
-	pic->coded_height	= vdec_pic_scale(inst, ALIGN(sps->height, 32), dw);
-
-	pic->y_len_sz		= pic->coded_width * pic->coded_height;
-	pic->c_len_sz		= pic->y_len_sz >> 1;
-
-	/* calc DPB size */
-	dec->dpb_sz		= refer_buffer_num(sps) + margin;
-
-	inst->parms.ps.visible_width	= pic->visible_width;
-	inst->parms.ps.visible_height	= pic->visible_height;
-	inst->parms.ps.coded_width	= pic->coded_width;
-	inst->parms.ps.coded_height	= pic->coded_height;
-	inst->parms.ps.dpb_size		= dec->dpb_sz;
-	inst->parms.parms_status	|= V4L2_CONFIG_PARM_DECODE_PSINFO;
-
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
-		dw, pic->coded_width, pic->coded_height,
-		pic->visible_width, pic->visible_height,
-		dec->dpb_sz - margin, margin);
-}
-
 static int parse_stream_ucode(struct vdec_hevc_inst *inst,
 			      u8 *buf, u32 size, u64 timestamp)
 {
 	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, 0,
+				vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -458,7 +334,7 @@
 	}
 
 	if (ps->sps_parsed)
-		fill_vdec_params(inst, &ps->sps);
+		//fill_vdec_params(inst, &ps->sps);
 
 	ret = ps->sps_parsed ? 0 : -1;
 out:
@@ -475,8 +351,16 @@
 	u8 *buf = (u8 *)bs->vaddr;
 	u32 size = bs->size;
 	int ret = 0;
+	struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
 
-	if (inst->ctx->is_drm_mode) {
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+		return 0;
+	}
+
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -528,12 +412,12 @@
 }
 
 static int vdec_write_nalu(struct vdec_hevc_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	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, 0, free);
 
 	return ret;
 }
@@ -580,6 +464,7 @@
 {
 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
 	u8 *buf = (u8 *) bs->vaddr;
 	u32 size = bs->size;
 	int ret = -1;
@@ -587,10 +472,16 @@
 	if (bs == NULL)
 		return -1;
 
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(vdec, (u32)bs->addr, size);
+		return size;
+	}
+
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -609,7 +500,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -623,7 +515,8 @@
 			if ((*res_chg = monitor_res_change(inst, buf, size)))
 				return 0;
 		}
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -643,7 +536,7 @@
 
 	 parms->parms_status |= inst->parms.parms_status;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"parms status: %u\n", parms->parms_status);
  }
 
@@ -683,15 +576,19 @@
 		break;
 
 	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_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);
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			inst->parms.cfg.triple_write_mode;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
 		break;
 	}
+
 	case GET_PARAM_COMP_BUF_INFO:
 		get_param_comp_buf_info(inst, out);
 		break;
@@ -717,6 +614,7 @@
 	struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
 	int dw = inst->parms.cfg.double_write_mode;
+	int tw = inst->parms.cfg.triple_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -733,8 +631,7 @@
 	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		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
 	pic->dpb_frames		= ps->dpb_frames;
@@ -742,6 +639,12 @@
 	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
+	pic->bitdepth		= ps->bitdepth;
+
+	if (tw) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
 
 	inst->parms.ps		= *ps;
 	inst->parms.parms_status |=
@@ -751,19 +654,44 @@
 	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), "
+		"scan:%s, bitdepth(%d), DW/TW(%x, %x)\n",
 		pic->visible_width, pic->visible_height,
 		pic->coded_width, pic->coded_height,
-		pic->field == V4L2_FIELD_NONE ? "P" : "I");
+		pic->field == V4L2_FIELD_NONE ? "P" : "I",
+		ps->bitdepth, dw, tw);
 }
 
 static void set_cfg_info(struct vdec_hevc_inst *inst,
-	struct aml_vdec_cfg_infos *cfg)
+	struct aml_vdec_cfg_infos *new_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));
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+	u32 tw_new = new_cfg->triple_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode,
+		old_cfg->triple_write_mode,
+		new_cfg->triple_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	if (old_cfg->triple_write_mode != tw_new) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	*old_cfg = *new_cfg;
 }
 
 static void set_param_comp_buf_info(struct vdec_hevc_inst *inst,
@@ -782,7 +710,7 @@
 			V4L2_CONFIG_PARM_DECODE_HDRINFO;
 		aml_vdec_dispatch_event(inst->ctx,
 			V4L2_EVENT_SRC_CH_HDRINFO);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 			"H265 set HDR infos\n");
 	}
 }
@@ -790,7 +718,7 @@
 static void set_param_post_event(struct vdec_hevc_inst *inst, u32 *event)
 {
 	aml_vdec_dispatch_event(inst->ctx, *event);
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"H265 post event: %d\n", *event);
 }
 
@@ -858,8 +786,6 @@
 	.deinit		= vdec_hevc_deinit,
 };
 
-struct vdec_common_if *get_hevc_dec_comm_if(void);
-
 struct vdec_common_if *get_hevc_dec_comm_if(void)
 {
 	return &vdec_hevc_if;
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 8332956..98d04b5 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -53,7 +53,7 @@
 /**
  * struct vdec_mjpeg_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -209,8 +209,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable mjpeg hw.*/
+	/* to enable mjpeg hw.*/
 	inst->vdec.port.type = PORT_TYPE_VIDEO;
 
 	/* probe info from the stream */
@@ -238,7 +240,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"mjpeg Instance >> %lx\n", (ulong) inst);
 
 	return 0;
@@ -302,7 +304,8 @@
 	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, 0,
+				vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -372,7 +375,7 @@
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -424,12 +427,12 @@
 }
 
 static int vdec_write_nalu(struct vdec_mjpeg_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	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, 0, free);
 
 	return ret;
 }
@@ -446,7 +449,7 @@
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -458,7 +461,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -467,7 +471,8 @@
 				vdec_vframe_input_free, inst->ctx);
 		}
 	} else {
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -501,7 +506,14 @@
 	case GET_PARAM_DW_MODE:
 	{
 		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
+		*mode = DM_YUV_ONLY;
+		break;
+	}
+
+	case GET_PARAM_TW_MODE:
+	{
+		unsigned int* mode = out;
+		*mode = DM_INVALID;
 		break;
 	}
 
@@ -521,7 +533,7 @@
 	struct vdec_mjpeg_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "%s in\n", __func__);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "%s in\n", __func__);
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
 	pic->visible_height	= ps->visible_height;
@@ -569,6 +581,13 @@
 	inst->vsi->pic = *pic;
 }
 
+static void set_param_post_event(struct vdec_mjpeg_inst *inst, u32 *event)
+{
+	aml_vdec_dispatch_event(inst->ctx, *event);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"mjpeg post event: %d\n", *event);
+}
+
 static int vdec_mjpeg_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -594,6 +613,10 @@
 		set_pic_info(inst, in);
 		break;
 
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(inst, in);
+		break;
+
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
@@ -612,8 +635,6 @@
 	.deinit		= vdec_mjpeg_deinit,
 };
 
-struct vdec_common_if *get_mjpeg_dec_comm_if(void);
-
 struct vdec_common_if *get_mjpeg_dec_comm_if(void)
 {
 	return &vdec_mjpeg_if;
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
index 2472ac1..7697dbd 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -29,6 +29,7 @@
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
 #include "aml_mpeg12_parser.h"
+#include "../aml_vcodec_ts.h"
 
 #define NAL_TYPE(value)				((value) & 0x1F)
 #define HEADER_BUFFER_SIZE			(32 * 1024)
@@ -52,7 +53,7 @@
 /**
  * struct vdec_mpeg12_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -206,8 +207,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable mpeg12 hw.*/
+	/* to enable mpeg12 hw.*/
 	inst->vdec.port.type = PORT_TYPE_VIDEO;
 
 	/* probe info from the stream */
@@ -235,7 +238,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"mpeg12 Instance >> %lx\n", (ulong) inst);
 
 	return 0;
@@ -291,7 +294,8 @@
 	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, 0,
+				vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -361,7 +365,16 @@
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(adapt_vdec, (u32)bs->addr, size);
+		return 0;
+	}
+
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -413,12 +426,12 @@
 }
 
 static int vdec_write_nalu(struct vdec_mpeg12_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	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, 0, free);
 
 	return ret;
 }
@@ -428,14 +441,21 @@
 {
 	struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
 	u8 *buf = (u8 *) bs->vaddr;
 	u32 size = bs->size;
 	int ret = -1;
 
+	if (ctx->stream_mode) {
+		aml_es_write(ctx, bs->dbuf, bs->addr, size, bs->timestamp);
+		vdec_write_stream_data(vdec, (u32)bs->addr, size);
+		return size;
+	}
+
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -447,7 +467,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -456,7 +477,8 @@
 				vdec_vframe_input_free, inst->ctx);
 		}
 	} else {
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -471,7 +493,7 @@
 
 	parms->parms_status |= inst->parms.parms_status;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"parms status: %u\n", parms->parms_status);
 }
 
@@ -507,7 +529,14 @@
 	case GET_PARAM_DW_MODE:
 	{
 		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
+		*mode = DM_YUV_ONLY;
+		break;
+	}
+
+	case GET_PARAM_TW_MODE:
+	{
+		unsigned int* mode = out;
+		*mode = DM_INVALID;
 		break;
 	}
 
@@ -585,11 +614,18 @@
 			V4L2_CONFIG_PARM_DECODE_HDRINFO;
 		aml_vdec_dispatch_event(inst->ctx,
 			V4L2_EVENT_SRC_CH_HDRINFO);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 			"mpeg12 set HDR infos\n");
 	}
 }
 
+static void set_param_post_event(struct vdec_mpeg12_inst *inst, u32 *event)
+{
+	aml_vdec_dispatch_event(inst->ctx, *event);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"mpeg2 post event: %d\n", *event);
+}
+
 static int vdec_mpeg12_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -619,6 +655,10 @@
 		set_pic_info(inst, in);
 		break;
 
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(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..6f2abbf 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -52,7 +52,7 @@
 /**
  * struct vdec_mpeg4_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -205,8 +205,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable mpeg4 hw.*/
+	/* to enable mpeg4 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_VIDEO;
 
 	/* probe info from the stream */
@@ -234,7 +236,7 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"mpeg4 Instance >> %lx\n", (ulong) inst);
 
 	return 0;
@@ -298,7 +300,8 @@
 	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, 0,
+				vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -368,7 +371,7 @@
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -420,12 +423,12 @@
 }
 
 static int vdec_write_nalu(struct vdec_mpeg4_inst *inst,
-	u8 *buf, u32 size, u64 ts)
+	u8 *buf, u32 size, u64 ts, chunk_free free)
 {
 	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, 0, free);
 
 	return ret;
 }
@@ -442,7 +445,7 @@
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -454,7 +457,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -463,7 +467,8 @@
 				vdec_vframe_input_free, inst->ctx);
 		}
 	} else {
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -496,12 +501,19 @@
 	case GET_PARAM_DW_MODE:
 	{
 		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
+		*mode = DM_YUV_ONLY;
+		break;
+	}
+
+	case GET_PARAM_TW_MODE:
+	{
+		unsigned int* mode = out;
+		*mode = DM_INVALID;
 		break;
 	}
 
 	default:
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
 		ret = -EINVAL;
 	}
@@ -516,7 +528,7 @@
 	struct vdec_mpeg4_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "%s in\n", __func__);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT, "%s in\n", __func__);
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
 	pic->visible_height	= ps->visible_height;
@@ -564,6 +576,14 @@
 	inst->vsi->pic = *pic;
 }
 
+static void set_param_post_event(struct vdec_mpeg4_inst *inst, u32 *event)
+{
+	aml_vdec_dispatch_event(inst->ctx, *event);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"mpeg4 post event: %d\n", *event);
+}
+
+
 static int vdec_mpeg4_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -589,6 +609,10 @@
 		set_pic_info(inst, in);
 		break;
 
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(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_vc1_if.c b/drivers/amvdec_ports/decoder/vdec_vc1_if.c
new file mode 100644
index 0000000..44e05be
--- /dev/null
+++ b/drivers/amvdec_ports/decoder/vdec_vc1_if.c
@@ -0,0 +1,625 @@
+/*
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <uapi/linux/swab.h>
+#include "../vdec_drv_if.h"
+#include "../aml_vcodec_util.h"
+#include "../aml_vcodec_dec.h"
+#include "../aml_vcodec_adapt.h"
+#include "../vdec_drv_base.h"
+#include "../utils/common.h"
+#include "../../frame_provider/decoder/utils/decoder_dma_alloc.h"
+#include "../../frame_provider/decoder/utils/vdec.h"
+
+#define NAL_TYPE(value)				((value) & 0x1F)
+#define HEADER_BUFFER_SIZE			(32 * 1024)
+#define VC1_TS_POOL_SIZE			64
+
+/**
+ * struct vdec_vc1_dec_info - decode information
+ * @dpb_sz		: decoding picture buffer size
+ * @resolution_changed  : resolution change happen
+ * @reserved		: for 8 bytes alignment
+ * @bs_dma		: Input bit-stream buffer dma address
+ * @y_fb_dma		: Y frame buffer dma address
+ * @c_fb_dma		: C frame buffer dma address
+ * @vdec_fb_va		: VDEC frame buffer struct virtual address
+ */
+struct vdec_vc1_dec_info {
+	uint32_t dpb_sz;
+	uint32_t resolution_changed;
+	uint32_t reserved;
+	uint64_t bs_dma;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+};
+
+/**
+ * struct vdec_vc1_vsi - shared memory for decode information exchange
+ *                        between VPU and Host.
+ *                        The memory is allocated by VPU then mapping to Host
+ *                        in vpu_dec_init() and freed in vpu_dec_deinit()
+ *                        by VPU.
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
+ * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
+ * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
+ * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
+ * @dec          : decode information (AP-R, VPU-W)
+ * @pic          : picture information (AP-R, VPU-W)
+ * @crop         : crop information (AP-R, VPU-W)
+ */
+struct vdec_vc1_vsi {
+	char *header_buf;
+	int sps_size;
+	int pps_size;
+	int sei_size;
+	int head_offset;
+	struct vdec_vc1_dec_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_pic_info cur_pic;
+	struct v4l2_rect crop;
+	bool is_combine;
+	int nalu_pos;
+};
+
+/**
+ * struct vdec_vc1_inst - vc1 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx      : point to aml_vcodec_ctx
+ * @vsi      : VPU shared information
+ */
+struct vdec_vc1_inst {
+	DECLARE_KFIFO_PTR(vc1_ts_q, u64);
+	unsigned int num_nalu;
+	struct aml_vcodec_ctx *ctx;
+	struct aml_vdec_adapt vdec;
+	struct vdec_vc1_vsi *vsi;
+	struct aml_dec_params parms;
+	struct completion comp;
+};
+
+static u32 vdec_config_default_parms(u8 *parm)
+{
+	u8 *pbuf = parm;
+
+	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;");
+
+	return pbuf - parm;
+}
+
+static void vdec_parser_parms(struct vdec_vc1_inst *inst)
+{
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	if (ctx->config.parm.dec.parms_status &
+		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
+		u8 *pbuf = ctx->config.buf;
+
+		pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
+		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
+			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);
+	}
+
+	inst->vdec.config	= ctx->config;
+	inst->parms.cfg		= ctx->config.parm.dec.cfg;
+	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
+}
+
+static int vdec_vc1_init(struct aml_vcodec_ctx *ctx, unsigned long *h_vdec)
+{
+	struct vdec_vc1_inst *inst = NULL;
+	int ret = -1;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	/* init ts fifo */
+	INIT_KFIFO(inst->vc1_ts_q);
+
+	ret = kfifo_alloc(&inst->vc1_ts_q, VC1_TS_POOL_SIZE, GFP_KERNEL);
+	if (ret) {
+		v4l_dbg(inst->ctx, 0, "Alloc vc1_ts_q fifo fail.\n");
+		return -ENOMEM;
+	}
+
+	inst->vdec.frm_name	= "VC1";
+	inst->vdec.video_type	= VFORMAT_VC1;
+	inst->vdec.filp		= ctx->dev->filp;
+	inst->vdec.ctx		= ctx;
+	inst->ctx		= ctx;
+
+	if (ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_G)
+		inst->vdec.format = VIDEO_DEC_FORMAT_WVC1;
+	else if (ctx->output_pix_fmt == V4L2_PIX_FMT_VC1_ANNEX_L)
+		inst->vdec.format = VIDEO_DEC_FORMAT_WMV3;
+
+	vdec_parser_parms(inst);
+
+	/* set play mode.*/
+	if (ctx->is_drm_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
+
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_vc1_inst), 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 = 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_vc1 init err=%d\n", ret);
+		goto err;
+	}
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"vc1 Instance >> %lx\n", (ulong) inst);
+
+	return 0;
+
+err:
+	if (inst && inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+	if (inst && inst->vsi)
+		kfree(inst->vsi);
+	if (inst)
+		kfree(inst);
+	*h_vdec = 0;
+
+	return ret;
+}
+
+static int parse_stream_ucode(struct vdec_vc1_inst *inst,
+			      u8 *buf, u32 size, u64 timestamp)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0,
+				vdec_vframe_input_free);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write frame data failed. err: %d\n", ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_ucode_dma(struct vdec_vc1_inst *inst,
+	ulong buf, u32 size, u64 timestamp, u32 handle)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write_with_dma(vdec, buf, size, timestamp, handle,
+		vdec_vframe_input_free, inst->ctx);
+	if (ret < 0) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"write frame data failed. err: %d\n", ret);
+		return ret;
+	}
+
+	/* wait ucode parse ending. */
+	wait_for_completion_timeout(&inst->comp,
+		msecs_to_jiffies(1000));
+
+	return inst->vsi->pic.dpb_frames ? 0 : -1;
+}
+
+static int parse_stream_cpu(struct vdec_vc1_inst *inst, u8 *buf, u32 size)
+{
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		"can not support parse stream by cpu.\n");
+
+	return -1;
+}
+
+static int vdec_vc1_probe(unsigned long h_vdec,
+	struct aml_vcodec_mem *bs, void *out)
+{
+	struct vdec_vc1_inst *inst =
+		(struct vdec_vc1_inst *)h_vdec;
+	u8 *buf = (u8 *)bs->vaddr;
+	u32 size = bs->size;
+	int ret = 0;
+
+	struct aml_vdec_adapt *adapt_vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+
+	if (ctx->stream_mode) {
+		kfifo_put(&inst->vc1_ts_q, bs->timestamp);
+		vdec_write_stream_data_inner(adapt_vdec, (char *)bs->addr, size, bs->timestamp);
+
+		return 0;
+	}
+
+	/*
+	 * Keep it for the frame mode later
+	 */
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if ((s->magic != AML_VIDEO_MAGIC) &&
+				(s->type != V4L_STREAM_TYPE_MATEDATA))
+				return -1;
+
+			if (inst->ctx->param_sets_from_ucode) {
+				ret = parse_stream_ucode(inst, s->data,
+					s->len, bs->timestamp);
+			} else {
+				ret = parse_stream_cpu(inst, s->data, s->len);
+			}
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = parse_stream_ucode_dma(inst, bs->addr, size,
+				bs->timestamp, BUFF_IDX(bs, bs->index));
+		}
+	} else {
+		if (inst->ctx->param_sets_from_ucode) {
+			ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
+		} else {
+			ret = parse_stream_cpu(inst, buf, size);
+		}
+	}
+
+	inst->vsi->cur_pic = inst->vsi->pic;
+
+	return ret;
+}
+
+static void vdec_vc1_deinit(unsigned long h_vdec)
+{
+	struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+	if (!inst)
+		return;
+
+	video_decoder_release(&inst->vdec);
+
+	if (inst->vsi && inst->vsi->header_buf)
+		vfree(inst->vsi->header_buf);
+
+	if (inst->vsi)
+		kfree(inst->vsi);
+
+	kfifo_free(&inst->vc1_ts_q);
+
+	kfree(inst);
+}
+
+static int vdec_write_nalu(struct vdec_vc1_inst *inst,
+	u8 *buf, u32 size, u64 ts, chunk_free free)
+{
+	int ret = 0;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+
+	ret = vdec_vframe_write(vdec, buf, size, ts, 0, free);
+
+	return ret;
+}
+
+static int vdec_vc1_decode(unsigned long h_vdec,
+			      struct aml_vcodec_mem *bs, bool *res_chg)
+{
+	struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+	struct aml_vdec_adapt *vdec = &inst->vdec;
+	struct aml_vcodec_ctx *ctx = inst->ctx;
+	struct stream_buf_s *stbuf;
+	u8 *buf = (u8 *) bs->vaddr;
+	u32 size = bs->size;
+	int ret = -1;
+	u32 free_space = 0;
+
+	if (ctx->stream_mode) {
+		if (kfifo_is_full(&inst->vc1_ts_q))
+			return -EAGAIN;
+
+		stbuf = &vdec->vdec->vbuf;
+		/* calculate the free size of stbuf */
+		free_space = (stbuf->buf_wp >= stbuf->buf_rp) ?
+			(stbuf->buf_size - (stbuf->buf_wp - stbuf->buf_rp)) :
+			(stbuf->buf_rp - stbuf->buf_wp);
+		if (free_space < size) {
+			v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_INPUT,
+				"%s require %d but stbuf free space(%d) is not enough. \n",
+				__func__, size, free_space);
+			return -EAGAIN;
+		} else {
+			kfifo_put(&inst->vc1_ts_q, bs->timestamp);
+			vdec_write_stream_data_inner(vdec, (char *)bs->addr, size, bs->timestamp);
+			return size;
+		}
+	}
+
+	/*
+	 * Keep it for the frame mode later
+	 */
+	if (vdec_input_full(vdec))
+		return -EAGAIN;
+
+	if (inst->ctx->output_dma_mode) {
+		if (bs->model == VB2_MEMORY_MMAP) {
+			struct aml_video_stream *s =
+				(struct aml_video_stream *) buf;
+
+			if (s->magic != AML_VIDEO_MAGIC)
+				return -1;
+
+			ret = vdec_vframe_write(vdec,
+				s->data,
+				s->len,
+				bs->timestamp,
+				0,
+				vdec_vframe_input_free);
+		} else if (bs->model == VB2_MEMORY_DMABUF ||
+			bs->model == VB2_MEMORY_USERPTR) {
+			ret = vdec_vframe_write_with_dma(vdec,
+				bs->addr, size, bs->timestamp,
+				BUFF_IDX(bs, bs->index),
+				vdec_vframe_input_free, inst->ctx);
+		}
+	} else {
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp,
+				vdec_vframe_input_free);
+	}
+
+	return ret;
+}
+
+static void get_pic_info(struct vdec_vc1_inst *inst,
+			 struct vdec_pic_info *pic)
+{
+	*pic = inst->vsi->pic;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"pic(%d, %d), buf(%d, %d)\n",
+		 pic->visible_width, pic->visible_height,
+		 pic->coded_width, pic->coded_height);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		"Y(%d, %d), C(%d, %d)\n",
+		pic->y_bs_sz, pic->y_len_sz,
+		pic->c_bs_sz, pic->c_len_sz);
+}
+
+static void vdec_vc1_get_pts(struct vdec_vc1_inst *inst,
+	u64 *pts)
+{
+	u64 timestamp = 0;
+
+	if (kfifo_get(&inst->vc1_ts_q, &timestamp)) {
+		*pts = timestamp;
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+			"%s get pts: timestamp %lld\n", __func__,
+			timestamp);
+	}
+}
+
+static int vdec_vc1_get_param(unsigned long h_vdec,
+			       enum vdec_get_param_type type, void *out)
+{
+	int ret = 0;
+	struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vc1 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		get_pic_info(inst, out);
+		break;
+
+	case GET_PARAM_DW_MODE:
+	{
+		u32 *mode = out;
+		*mode = DM_YUV_ONLY;
+		break;
+	}
+
+	case GET_PARAM_TW_MODE:
+	{
+		unsigned int* mode = out;
+		*mode = DM_INVALID;
+		break;
+	}
+
+	case GET_PARAM_TIME_STAMP:
+	{
+		u64 *pts = out;
+		vdec_vc1_get_pts(inst, pts);
+		break;
+	}
+
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid get parameter type=%d\n", type);
+		ret = -EINVAL; // for test
+	}
+
+	return ret;
+}
+
+static void set_param_write_sync(struct vdec_vc1_inst *inst)
+{
+	complete(&inst->comp);
+}
+
+static void set_pic_info(struct vdec_vc1_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	inst->vsi->pic = *pic;
+}
+
+static void set_param_post_event(struct vdec_vc1_inst *inst, u32 *event)
+{
+	aml_vdec_dispatch_event(inst->ctx, *event);
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"vc1 post event: %d\n", *event);
+}
+
+static void set_param_ps_info(struct vdec_vc1_inst *inst,
+	struct aml_vdec_ps_infos *ps)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct vdec_vc1_dec_info *dec = &inst->vsi->dec;
+	struct v4l2_rect *rect = &inst->vsi->crop;
+
+	/* fill visible area size that be used for EGL. */
+	pic->visible_width	= ps->visible_width;
+	pic->visible_height	= ps->visible_height;
+
+	/* calc visible ares. */
+	rect->left		= 0;
+	rect->top		= 0;
+	rect->width		= pic->visible_width;
+	rect->height		= pic->visible_height;
+
+	/* config canvas size that be used for decoder. */
+	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->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 |=
+		V4L2_CONFIG_PARM_DECODE_PSINFO;
+
+	/*wake up*/
+	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",
+		ps->visible_width, ps->visible_height,
+		ps->coded_width, ps->coded_height,
+		pic->field == V4L2_FIELD_NONE ? "P" : "I");
+}
+
+static void set_param_reset_event(struct vdec_vc1_inst *inst)
+{
+	/* reset fifo */
+	kfifo_reset(&inst->vc1_ts_q);
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
+		"vc1 instance reset. \n");
+}
+
+static int vdec_vc1_set_param(unsigned long h_vdec,
+	enum vdec_set_param_type type, void *in)
+{
+	int ret = 0;
+	struct vdec_vc1_inst *inst = (struct vdec_vc1_inst *)h_vdec;
+
+	if (!inst) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vc1 inst of dec is invalid.\n");
+		return -1;
+	}
+
+	switch (type) {
+	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;
+
+	case SET_PARAM_POST_EVENT:
+		set_param_post_event(inst, in);
+		break;
+
+	case SET_PARAM_INST_RESET:
+		set_param_reset_event(inst);
+		break;
+	default:
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"invalid set parameter type=%d\n", type);
+		ret = type;
+	}
+
+	return ret;
+}
+
+static struct vdec_common_if vdec_vc1_if = {
+	.init		= vdec_vc1_init,
+	.probe		= vdec_vc1_probe,
+	.decode		= vdec_vc1_decode,
+	.get_param	= vdec_vc1_get_param,
+	.set_param	= vdec_vc1_set_param,
+	.deinit		= vdec_vc1_deinit,
+};
+
+struct vdec_common_if *get_vc1_dec_comm_if(void);
+
+struct vdec_common_if *get_vc1_dec_comm_if(void)
+{
+	return &vdec_vc1_if;
+}
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index fe81ddd..1db31de 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -1,22 +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:
-*/
+ * 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/module.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -31,6 +31,7 @@
 #include "../vdec_drv_base.h"
 #include "aml_vp9_parser.h"
 #include "vdec_vp9_trigger.h"
+#include "../utils/common.h"
 
 #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
 #include <trace/events/meson_atrace.h>
@@ -64,7 +65,7 @@
 /**
  * struct vdec_vp9_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
- * @resolution_changed  : resoltion change happen
+ * @resolution_changed  : resolution change happen
  * @reserved		: for 8 bytes alignment
  * @bs_dma		: Input bit-stream buffer dma address
  * @y_fb_dma		: Y frame buffer dma address
@@ -128,7 +129,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, ulong meta_ptr, chunk_free free);
 
 static void get_pic_info(struct vdec_vp9_inst *inst,
 			 struct vdec_pic_info *pic)
@@ -139,10 +140,6 @@
 		"pic(%d, %d), buf(%d, %d)\n",
 		 pic->visible_width, pic->visible_height,
 		 pic->coded_width, pic->coded_height);
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
-		"Y(%d, %d), C(%d, %d)\n",
-		pic->y_bs_sz, pic->y_len_sz,
-		pic->c_bs_sz, pic->c_len_sz);
 }
 
 static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
@@ -187,9 +184,9 @@
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"%s:parms_status = 0x%x, present_flag = %d\n",
+		"%s:parms_status = 0x%x, present_flag = %d, hdr.signal_type 0x%x\n",
 		__func__, ctx->config.parm.dec.parms_status,
-		ctx->config.parm.dec.hdr.color_parms.present_flag);
+		ctx->config.parm.dec.hdr.color_parms.present_flag, ctx->config.parm.dec.hdr.signal_type);
 	if (ctx->config.parm.dec.parms_status &
 		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
 		u8 *pbuf = ctx->config.buf;
@@ -199,6 +196,8 @@
 			ctx->config.parm.dec.cfg.ref_buf_margin);
 		pbuf += sprintf(pbuf, "vp9_double_write_mode:%d;",
 			ctx->config.parm.dec.cfg.double_write_mode);
+		pbuf += sprintf(pbuf, "vp9_triple_write_mode:%d;",
+			ctx->config.parm.dec.cfg.triple_write_mode);
 		pbuf += sprintf(pbuf, "vp9_buf_width:%d;",
 			ctx->config.parm.dec.cfg.init_width);
 		pbuf += sprintf(pbuf, "vp9_buf_height:%d;",
@@ -220,47 +219,51 @@
 		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) {
+	if (ctx->config.parm.dec.parms_status &
+		V4L2_CONFIG_PARM_DECODE_HDRINFO) {
 		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;",
-			ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
-		pbuf += sprintf(pbuf, "mB.x:%d;",
-			ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
-		pbuf += sprintf(pbuf, "mB.y:%d;",
-			ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
-		pbuf += sprintf(pbuf, "mR.x:%d;",
-			ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
-		pbuf += sprintf(pbuf, "mR.y:%d;",
-			ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
-		pbuf += sprintf(pbuf, "mW.x:%d;",
-			ctx->config.parm.dec.hdr.color_parms.white_point[0]);
-		pbuf += sprintf(pbuf, "mW.y:%d;",
-			ctx->config.parm.dec.hdr.color_parms.white_point[1]);
-		pbuf += sprintf(pbuf, "mMaxDL:%d;",
-			ctx->config.parm.dec.hdr.color_parms.luminance[0] * 10000);
-		pbuf += sprintf(pbuf, "mMinDL:%d;",
-			ctx->config.parm.dec.hdr.color_parms.luminance[1]);
-		pbuf += sprintf(pbuf, "mMaxCLL:%d;",
-			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
-		pbuf += sprintf(pbuf, "mMaxFALL:%d;",
-			ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
-		ctx->config.length	= pbuf - ctx->config.buf;
-		inst->parms.hdr		= ctx->config.parm.dec.hdr;
-		inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
+		if (ctx->config.parm.dec.hdr.color_parms.present_flag) {
+			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;",
+				ctx->config.parm.dec.hdr.color_parms.primaries[0][1]);
+			pbuf += sprintf(pbuf, "mB.x:%d;",
+				ctx->config.parm.dec.hdr.color_parms.primaries[1][0]);
+			pbuf += sprintf(pbuf, "mB.y:%d;",
+				ctx->config.parm.dec.hdr.color_parms.primaries[1][1]);
+			pbuf += sprintf(pbuf, "mR.x:%d;",
+				ctx->config.parm.dec.hdr.color_parms.primaries[2][0]);
+			pbuf += sprintf(pbuf, "mR.y:%d;",
+				ctx->config.parm.dec.hdr.color_parms.primaries[2][1]);
+			pbuf += sprintf(pbuf, "mW.x:%d;",
+				ctx->config.parm.dec.hdr.color_parms.white_point[0]);
+			pbuf += sprintf(pbuf, "mW.y:%d;",
+				ctx->config.parm.dec.hdr.color_parms.white_point[1]);
+			pbuf += sprintf(pbuf, "mMaxDL:%d;",
+				ctx->config.parm.dec.hdr.color_parms.luminance[0] * 10000);
+			pbuf += sprintf(pbuf, "mMinDL:%d;",
+				ctx->config.parm.dec.hdr.color_parms.luminance[1]);
+			pbuf += sprintf(pbuf, "mMaxCLL:%d;",
+				ctx->config.parm.dec.hdr.color_parms.content_light_level.max_content);
+			pbuf += sprintf(pbuf, "mMaxFALL:%d;",
+				ctx->config.parm.dec.hdr.color_parms.content_light_level.max_pic_average);
+		}else {
+			pbuf += sprintf(pbuf, "signal_type:%d;",
+				ctx->config.parm.dec.hdr.signal_type);
+		}
+			ctx->config.length	= pbuf - ctx->config.buf;
+			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);
+		"config.buf = %s, ctx->config.length %d\n", ctx->config.buf, ctx->config.length);
 
 	inst->vdec.config	= ctx->config;
 	inst->parms.cfg		= ctx->config.parm.dec.cfg;
+
 	inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_CFGINFO;
 }
 
@@ -284,8 +287,10 @@
 	/* set play mode.*/
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
+	if (ctx->output_dma_mode)
+		inst->vdec.port.flag |= PORT_FLAG_DMABUF;
 
-	/* to eable vp9 hw.*/
+	/* to enable vp9 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_HEVC;
 
 	/* probe info from the stream */
@@ -304,7 +309,7 @@
 
 	init_completion(&inst->comp);
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 		"vp9 Instance >> %lx\n", (ulong) inst);
 
 	ctx->ada_ctx	= &inst->vdec;
@@ -339,110 +344,13 @@
 }
 #endif
 
-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;
-	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_vp9_inst *inst, int length, int dw_mode)
-{
-	int ret = 64;
-
-	switch (vdec_get_dw_mode(inst, dw_mode)) {
-	case 0x0: /* 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 fill_vdec_params(struct vdec_vp9_inst *inst,
-	struct VP9Context *vp9_ctx)
-{
-	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;
-	int margin = inst->parms.cfg.ref_buf_margin;
-
-	/* fill visible area size that be used for EGL. */
-	pic->visible_width	= vdec_pic_scale(inst, vp9_ctx->render_width, dw);
-	pic->visible_height	= vdec_pic_scale(inst, vp9_ctx->render_height, dw);
-
-	/* calc visible ares. */
-	rect->left		= 0;
-	rect->top		= 0;
-	rect->width		= pic->visible_width;
-	rect->height		= pic->visible_height;
-
-	/* config canvas size that be used for decoder. */
-	pic->coded_width	= vdec_pic_scale(inst, ALIGN(vp9_ctx->width, 32), dw);
-	pic->coded_height	= vdec_pic_scale(inst, ALIGN(vp9_ctx->height, 32), dw);
-
-	pic->y_len_sz		= pic->coded_width * pic->coded_height;
-	pic->c_len_sz		= pic->y_len_sz >> 1;
-
-	/* calc DPB size */
-	dec->dpb_sz = 5 + margin;//refer_buffer_num(sps->level_idc, poc_cnt, mb_w, mb_h);
-
-	inst->parms.ps.visible_width	= pic->visible_width;
-	inst->parms.ps.visible_height	= pic->visible_height;
-	inst->parms.ps.coded_width	= pic->coded_width;
-	inst->parms.ps.coded_height	= pic->coded_height;
-	inst->parms.ps.dpb_size		= dec->dpb_sz;
-	inst->parms.parms_status	|= V4L2_CONFIG_PARM_DECODE_PSINFO;
-
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"The stream infos, dw: %d, coded:(%d x %d), visible:(%d x %d), DPB: %d, margin: %d\n",
-		dw, pic->coded_width, pic->coded_height,
-		pic->visible_width, pic->visible_height,
-		dec->dpb_sz - margin, margin);
-}
-
-static int parse_stream_ucode(struct vdec_vp9_inst *inst,
-			      u8 *buf, u32 size, u64 timestamp, ulong meta_ptr)
+static int parse_stream_ucode(struct vdec_vp9_inst *inst, u8 *buf,
+		u32 size, u64 timestamp, ulong meta_ptr)
 {
 	int ret = 0;
 
-	ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr);
+	ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr,
+				vdec_vframe_input_free);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -494,7 +402,7 @@
 	}
 
 	if (ps->head_parsed)
-		fill_vdec_params(inst, &ps->ctx);
+		//fill_vdec_params(inst, &ps->ctx);
 
 	ret = ps->head_parsed ? 0 : -1;
 out:
@@ -512,7 +420,7 @@
 	u32 size = bs->size;
 	int ret = 0;
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -707,7 +615,7 @@
 }
 #endif
 
-static void trigger_decoder(struct aml_vdec_adapt *vdec)
+static void trigger_decoder(struct aml_vdec_adapt *vdec, chunk_free free)
 {
 	int i, ret;
 	u32 frame_size = 0;
@@ -716,7 +624,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, 0, free);
 		v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write trigger frame %d\n", ret);
 		p += frame_size;
@@ -724,7 +632,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, ulong meta_ptr, chunk_free free)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -737,7 +645,7 @@
 
 	/*trigger.*/
 	if (0 && !need_trigger) {
-		trigger_decoder(vdec);
+		trigger_decoder(vdec, free);
 		need_trigger = true;
 	}
 
@@ -754,10 +662,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, 0, free);
 		vfree(data);
 	} else {
-		ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr);
+		ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr, free);
 	}
 
 	return ret;
@@ -802,7 +710,7 @@
 		return -EAGAIN;
 	}
 
-	if (inst->ctx->is_drm_mode) {
+	if (inst->ctx->output_dma_mode) {
 		if (bs->model == VB2_MEMORY_MMAP) {
 			struct aml_video_stream *s =
 				(struct aml_video_stream *) buf;
@@ -821,7 +729,8 @@
 				s->data,
 				s->len,
 				bs->timestamp,
-				0);
+				0,
+				vdec_vframe_input_free);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -834,7 +743,8 @@
 		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,
+				bs->meta_ptr, vdec_vframe_input_free);
 	}
 
 	return ret;
@@ -894,15 +804,19 @@
 		break;
 
 	case GET_PARAM_DW_MODE:
+	case GET_PARAM_TW_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);
+		u32 m = (type == GET_PARAM_DW_MODE) ?
+			inst->parms.cfg.double_write_mode :
+			inst->parms.cfg.triple_write_mode;
+		int w = inst->vsi->pic.coded_width;
+		int h = inst->vsi->pic.coded_height;
+
+		*mode = vdec_get_dec_mode(w, h, m);
 		break;
 	}
+
 	case GET_PARAM_COMP_BUF_INFO:
 		get_param_comp_buf_info(inst, out);
 		break;
@@ -928,6 +842,7 @@
 	struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
 	int dw = inst->parms.cfg.double_write_mode;
+	int tw = inst->parms.cfg.triple_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -943,8 +858,7 @@
 	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		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw, 64);
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
 	/* calc DPB size */
@@ -953,6 +867,12 @@
 	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
+	pic->bitdepth		= ps->bitdepth;
+
+	if (tw) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
@@ -962,9 +882,9 @@
 	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, visible(%d x %d), coded(%d x %d), bitdepth(%d), DW/TW(%x, %x)\n",
 		pic->visible_width, pic->visible_height,
-		pic->coded_width, pic->coded_height);
+		pic->coded_width, pic->coded_height, ps->bitdepth, dw, tw);
 }
 
 static void set_param_comp_buf_info(struct vdec_vp9_inst *inst,
@@ -983,7 +903,7 @@
 			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_PROT,
 			"VP9 set HDR infos\n");
 	}
 }
@@ -991,7 +911,7 @@
 static void set_param_post_event(struct vdec_vp9_inst *inst, u32 *event)
 {
 		aml_vdec_dispatch_event(inst->ctx, *event);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PROT,
 			"VP9 post event: %d\n", *event);
 }
 
@@ -1001,6 +921,38 @@
 	inst->vsi->pic = *pic;
 }
 
+static void set_cfg_info(struct vdec_vp9_inst *inst,
+	struct aml_vdec_cfg_infos *new_cfg)
+{
+	struct vdec_pic_info *pic = &inst->vsi->pic;
+	struct aml_vdec_cfg_infos *old_cfg = &inst->parms.cfg;
+	u32 dw_new = new_cfg->double_write_mode;
+	u32 tw_new = new_cfg->triple_write_mode;
+
+	if (!memcmp(old_cfg, new_cfg, sizeof(*old_cfg)))
+		return;
+
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"%s, DW:(%x -> %x), TW:(%x -> %x)\n",
+		__func__,
+		old_cfg->double_write_mode,
+		new_cfg->double_write_mode,
+		old_cfg->triple_write_mode,
+		new_cfg->triple_write_mode);
+
+	if (old_cfg->double_write_mode != dw_new) {
+		pic->y_len_sz		= vdec_get_plane_size(pic->coded_width, pic->coded_height, dw_new, 64);
+		pic->c_len_sz		= pic->y_len_sz >> 1;
+	}
+
+	if (old_cfg->triple_write_mode != tw_new) {
+		pic->y_len_sz_tw	= vdec_get_plane_size(pic->coded_width, pic->coded_height, tw_new, 64);
+		pic->c_len_sz_tw	= pic->y_len_sz_tw >> 1;
+	}
+
+	*old_cfg = *new_cfg;
+}
+
 static int vdec_vp9_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -1038,6 +990,10 @@
 		set_pic_info(inst, in);
 		break;
 
+	case SET_PARAM_CFG_INFO:
+		set_cfg_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_trigger.h b/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
index 0097690..82fb3f4 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amvdec_ports/decoder/vdec_vp9_trigger.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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 _VDEC_VP9_TRIG_
 #define _VDEC_VP9_TRIG_
 
diff --git a/drivers/amvdec_ports/test/Android.mk b/drivers/amvdec_ports/test/Android.mk
deleted file mode 100644
index d9652fb..0000000
--- a/drivers/amvdec_ports/test/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE		:= vcode_m2m
-LOCAL_MODULE_TAGS	:= optional
-LOCAL_SRC_FILES		:= vcodec_m2m_test.c
-LOCAL_ARM_MODE		:= arm
-
-LOCAL_C_INCLUDES := \
-	$(JNI_H_INCLUDE) \
-	$(BOARD_AML_VENDOR_PATH)/vendor/amlogic/external/ffmpeg
-
-LOCAL_SHARED_LIBRARIES := \
-	libamffmpeg
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_LIBS:= \
-#        libavcodec:ffmpeg/lib/libavcodec.so \
-
-include $(BUILD_MULTI_PREBUILT)
diff --git a/drivers/amvdec_ports/test/vcodec_m2m_test.c b/drivers/amvdec_ports/test/vcodec_m2m_test.c
deleted file mode 100644
index bec040b..0000000
--- a/drivers/amvdec_ports/test/vcodec_m2m_test.c
+++ /dev/null
@@ -1,343 +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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <pthread.h>
-
-#define INBUF_SIZE	(4096)
-#define DUMP_DIR	"/data/video_frames"
-static int dump;
-
-typedef struct VcodecCtx {
-	AVFormatContext *fmt_ctx;
-	AVStream *stream;
-	int nb_streams;
-	int vst_idx;
-	char *filename;
-	pthread_t tid;
-	pthread_mutex_t pthread_mutex;
-	pthread_cond_t pthread_cond;
-} VcodecCtx;
-
-static void dump_yuv(AVFrame *frame, char *filename)
-{
-	FILE *f;
-
-	printf("name: %s, resolution: %dx%d, size: %d\n",
-		filename, frame->width, frame->height,
-		frame->buf[0]->size + frame->buf[1]->size);
-
-	f = fopen(filename,"w+");
-
-	fwrite(frame->buf[0]->data, 1, frame->buf[0]->size, f);
-	fwrite(frame->buf[1]->data, 1, frame->buf[1]->size, f);
-
-	fclose(f);
-}
-
-static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
-                   const char *filename)
-{
-	char buf[1024];
-	int ret;
-
-	ret = avcodec_send_packet(dec_ctx, pkt);
-	if (ret < 0) {
-		fprintf(stderr, "Error sending a packet for decoding\n");
-		return;
-	}
-
-	while (ret >= 0) {
-		ret = avcodec_receive_frame(dec_ctx, frame);
-		if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
-			return;
-		else if (ret < 0) {
-			fprintf(stderr, "Error during decoding, ret: %s\n", av_err2str(ret));
-			break;
-		}
-
-		//fprintf(stderr, "saving frame %3d\n", dec_ctx->frame_number);
-		fflush(stdout);
-
-		/* the picture is allocated by the decoder. no need to free it */
-		snprintf(buf, sizeof(buf), "%s/frame-%d", filename, dec_ctx->frame_number);
-
-		if (dump)
-			dump_yuv(frame, buf);
-	}
-}
-
-static void* read_thread(void *arg)
-{
-	int ret, err;
-	AVFormatContext *ic = NULL;
-	AVCodecContext *dec_ctx = NULL;
-	AVStream *stream = NULL;
-	AVCodec *codec = NULL;
-	AVPacket pkt1, *pkt = &pkt1;
-	AVFrame *frame = NULL;
-	int vst_idx = 0;
-	int has_video = 0;
-	unsigned int st_idx = 0;
-	VcodecCtx *vctx = arg;
-	const char *forced_codec_name = NULL;
-
-	printf("entry read thread, tid: %ld.\n", vctx->tid);
-
-	ic = avformat_alloc_context();
-	if (!ic) {
-		fprintf(stderr, "Could not allocate avformat context.\n");
-		goto out;
-	}
-
-	err = avformat_open_input(&ic, vctx->filename, NULL, NULL);
-	if (err < 0) {
-		fprintf(stderr, "Could not open avformat input.\n");
-		goto out;
-	}
-
-	err = avformat_find_stream_info(ic, NULL);
-	if (err < 0) {
-		fprintf(stderr, "find stream info err.\n");
-		goto out;
-	}
-
-	for (st_idx = 0; st_idx < ic->nb_streams; st_idx++) {
-		AVStream *st = ic->streams[st_idx];
-
-		enum AVMediaType type = st->codecpar->codec_type;
-		st->discard = AVDISCARD_ALL;
-
-		if (type == AVMEDIA_TYPE_VIDEO) {
-			st->discard = AVDISCARD_NONE;
-			vctx->vst_idx = st_idx;
-			has_video = 1;
-			break;
-		}
-	}
-
-	if (!has_video) {
-		fprintf(stderr, "no video stream.\n");
-		goto out;
-	}
-
-	stream = ic->streams[vctx->vst_idx];
-
-	//codec = avcodec_find_decoder(stream->codecpar->codec_id);
-	switch (stream->codecpar->codec_id) {
-		case AV_CODEC_ID_H264:
-			forced_codec_name = "h264_v4l2m2m";
-			break;
-		case AV_CODEC_ID_HEVC:
-			forced_codec_name = "hevc_v4l2m2m";
-			break;
-		case AV_CODEC_ID_VP9:
-			forced_codec_name = "vp9_v4l2m2m";
-			break;
-		case AV_CODEC_ID_MPEG1VIDEO:
-			forced_codec_name = "mpeg1_v4l2m2m";
-			break;
-		case AV_CODEC_ID_MPEG2VIDEO:
-			forced_codec_name = "mpeg2_v4l2m2m";
-			break;
-		case AV_CODEC_ID_VC1:
-			forced_codec_name = "vc1_v4l2m2m";
-			break;
-		case AV_CODEC_ID_H263:
-			forced_codec_name = "h263_v4l2m2m";
-			break;
-		case AV_CODEC_ID_MPEG4:
-			forced_codec_name = "mpeg4_v4l2m2m";
-			break;
-		case AV_CODEC_ID_MJPEG:
-			forced_codec_name = "mjpeg_v4l2m2m";
-			break;
-	}
-
-	codec = avcodec_find_decoder_by_name(forced_codec_name);
-	if (!codec) {
-		fprintf(stderr, "Unsupported codec with id %d for input stream %d\n",
-			stream->codecpar->codec_id, stream->index);
-		goto out;
-	}
-
-	dec_ctx = avcodec_alloc_context3(codec);
-	if (!dec_ctx) {
-		fprintf(stderr, "Could not allocate video codec context\n");
-		goto out;
-	}
-
-	err = avcodec_parameters_to_context(dec_ctx, stream->codecpar);
-	if (err < 0) {
-		fprintf(stderr, "Could not set paras to context\n");
-		goto out;
-	}
-
-	av_codec_set_pkt_timebase(dec_ctx, stream->time_base);
-	dec_ctx->framerate = stream->avg_frame_rate;
-
-	if (avcodec_open2(dec_ctx, codec, NULL) < 0) {
-		fprintf(stderr, "Could not open codec for input stream %d\n",
-			stream->index);
-		goto out;
-	}
-
-	printf("fmt ctx: %p, stream: %p, video st idx: %d, num: %d\n",
-		ic, stream, vst_idx, ic->nb_streams);
-        printf("format: %s\n",ic->iformat->name);
-
-	ic->flags |= AVFMT_FLAG_GENPTS;
-	ic->debug = 0xff;
-
-	//if (ic->pb)
-	//    ic->pb->eof_reached = 0;
-
-	frame = av_frame_alloc();
-	if (!frame) {
-		fprintf(stderr, "Could not allocate video frame\n");
-		goto out;
-	}
-
-	for (;;) {
-		ret = av_read_frame(ic, pkt);
-		if (ret < 0) {
-			if (ret == AVERROR_EOF || avio_feof(ic->pb)) {
-				printf("read data end, ret: %d.\n", ret);
-				break;
-			}
-
-			if (ic->pb && ic->pb->error)
-			    break;
-
-			printf("read data fail, ret: %d.\n", ret);
-			continue;
-		}
-
-		if (pkt->stream_index == vctx->vst_idx) {
-			//packet_queue_put(&is->audioq, pkt);
-			//printf("read video data size: %d.\n", pkt->size);
-			if (pkt->size)
-				decode(dec_ctx, frame, pkt, DUMP_DIR);
-		}
-
-		av_packet_unref(pkt);
-
-		usleep(8 * 1000);
-	}
-
-	/* flush the decoder */
-	decode(dec_ctx, frame, NULL, DUMP_DIR);
-out:
-	if (dec_ctx)
-		avcodec_free_context(&dec_ctx);
-
-	if (frame)
-		av_frame_free(&frame);
-
-	if (ic) {
-	    avformat_close_input(&ic);
-	    avformat_free_context(ic);
-	}
-
-	printf("read thread exit.\n");
-
-	pthread_mutex_lock(&vctx->pthread_mutex);
-	pthread_cond_signal(&vctx->pthread_cond);
-	pthread_mutex_unlock(&vctx->pthread_mutex);
-
-	return NULL;
-}
-
-static int open_input_file(const char *filename)
-{
-	int ret;
-	VcodecCtx *vctx;
-	pthread_t pid = pthread_self();
-
-	vctx = av_mallocz(sizeof(VcodecCtx));
-	if (!vctx)
-	    return -1;
-
-	vctx->filename = av_strdup(filename);
-	if (!vctx->filename) {
-	    av_free(vctx);
-	    return -1;
-	}
-
-	pthread_mutex_init(&vctx->pthread_mutex, NULL);
-	pthread_cond_init(&vctx->pthread_cond, NULL);
-
-	ret = pthread_create(&vctx->tid, NULL, read_thread, (void *)vctx);
-	if (ret == 0) {
-		pthread_setname_np(pid, "read_thread");
-
-		pthread_mutex_lock(&vctx->pthread_mutex);
-		pthread_cond_wait(&vctx->pthread_cond, &vctx->pthread_mutex);
-		pthread_join(vctx->tid, NULL);
-		pthread_mutex_unlock(&vctx->pthread_mutex);
-	}
-
-	av_free(vctx->filename);
-	av_free(vctx);
-
-	printf("creat the read thread, ret: %d.\n", ret);
-
-	return 0;
-}
-
-int main(int argc, char **argv)
-{
-	int ret;
-	const char *filename;
-	int log_level = 0;
-
-	if (argc < 2) {
-		fprintf(stderr, "Usage: %s <input file>\n ==> %s/frame-123\n", argv[0], DUMP_DIR);
-		exit(0);
-	}
-
-	filename = argv[1];
-	if (argv[2]) {
-		if (!strcmp(argv[2], "dump"))
-			dump = 1;
-		else
-			log_level = atoi(argv[2]);
-	}
-
-	mkdir(DUMP_DIR, 0664);
-
-	/*set debug level*/
-	av_log_set_level(log_level); //AV_LOG_DEBUG
-
-	/* register all the codecs */
-	avcodec_register_all();
-
-	ret = open_input_file(filename);
-	if (ret < 0)
-		fprintf(stderr, "open input file fail.\n");
-
-	return 0;
-}
diff --git a/drivers/amvdec_ports/utils/aml_dec_trace.c b/drivers/amvdec_ports/utils/aml_dec_trace.c
new file mode 100644
index 0000000..0d85b3f
--- /dev/null
+++ b/drivers/amvdec_ports/utils/aml_dec_trace.c
@@ -0,0 +1,135 @@
+/*
+ * 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_dec_trace.h"
+
+extern u32 trace_config;
+
+static const struct vdec_trace_map trace_map[] = {
+	/* trace mapping for v4ldec context. */
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_0,   "V4L", "ES-que" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_1,   "V4L", "ES-que_again" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_2,   "V4L", "ES-write" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_3,   "V4L", "ES-write_secure" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_4,   "V4L", "ES-receive" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_5,   "V4L", "ES-submit" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_6,   "V4L", "ES-deque" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_7,   "V4L", "ES-deque_again" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_8,   "V4L", "ES-write_end" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_9,   "V4L", "ES-write_secure_end" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_10,  "V4L", "ES-write_error" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_11,  "V4L", "ES-write_again" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ES_12,  "V4L", "ES-in_pts" },
+
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_0,  "V4L", "PIC-que" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_1,  "V4L", "PIC-que_again" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_2,  "V4L", "PIC-storage" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_3,  "V4L", "PIC-require" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_4,  "V4L", "PIC-recycle" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_5,  "V4L", "PIC-receive" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_6,  "V4L", "PIC-submit" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_7,  "V4L", "PIC-deque" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_8,  "V4L", "PIC-deque_again" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_9,  "V4L", "PIC-out_pts" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_PIC_10,  "V4L", "PIC-cache" },
+
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ST_0,   "V4L", "ST-state" },
+	{ VTRACE_GROUP_V4L_DEC,  VTRACE_V4L_ST_1,   "V4L", "ST-input_buffering" },
+
+	/* trace mapping for ge2d wrapper. */
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_0, "GE2D", "PIC-vf_put" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_1, "GE2D", "PIC-recycle" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_2, "GE2D", "PIC-receive" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_3, "GE2D", "PIC-handle_start" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_4, "GE2D", "PIC-submit" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_5, "GE2D", "PIC-vf_get" },
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_PIC_6, "GE2D", "PIC-cache" },
+
+	{ VTRACE_GROUP_V4L_GE2D, VTRACE_GE2D_ST_0,  "GE2D", "reserver" },
+
+	/* trace mapping for vpp wrapper. */
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_0,  "VPP", "PIC-vf_put" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_1,  "VPP", "PIC-recycle" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_2,  "VPP", "PIC-receive" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_3,  "VPP", "PIC-fill_output_start" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_4,  "VPP", "PIC-empty_input_start" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_5,  "VPP", "PIC-lc_handle_start" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_6,  "VPP", "PIC-direct_handle_start" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_7,  "VPP", "PIC-fill_output_start_dw" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_8,  "VPP", "PIC-empty_input_start_dw" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_9,  "VPP", "PIC-submit" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_10, "VPP", "PIC-lc_submit" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_11, "VPP", "PIC-vf_get" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_12, "VPP", "PIC-lc_attach" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_13, "VPP", "PIC-lc_detach" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_14, "VPP", "PIC-lc_release" },
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_PIC_15, "VPP", "PIC-cache" },
+
+	{ VTRACE_GROUP_V4L_VPP,  VTRACE_VPP_ST_0,   "VPP", "reserver" },
+
+	/* trace mapping for decode core. */
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_PIC_0, "DEC", "PIC-submit" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_PIC_1, "DEC", "PIC-reserver" },
+
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_0,  "DEC", "ST-chunk_size" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_1,  "DEC", "ST-free_buffer_count" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_2,  "DEC", "ST-dec_state" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_3,  "DEC", "ST-work_state" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_4,  "DEC", "ST-eos" },
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_5,  "DEC", "ST-wait_more_buf" },
+
+	{ VTRACE_GROUP_DEC_CORE,  VTRACE_DEC_ST_6,  "DEC", "ST-reserver" },
+
+	{ 0, VTRACE_MAX, "unknown", "unknown" },
+};
+
+void vdec_trace_init(struct vdec_trace *vtr, int ch, int vdec_id)
+{
+	int i, size = ARRAY_SIZE(trace_map);
+
+	for (i = 0; i < size; i++) {
+		if (!(trace_config & trace_map[i].group)) {
+			vtr->item[i].enable = false;
+			continue;
+		}
+
+		vtr->item[i].channel	= ch;
+		vtr->item[i].enable	= true;
+		vtr->item[i].group	= trace_map[i].group;
+		vtr->item[i].type	= trace_map[i].type;
+
+		snprintf(vtr->item[i].name, 64,
+			"[%d,%d] %s_%s",
+			ch, vdec_id,
+			trace_map[i].gname,
+			trace_map[i].description);
+	}
+}
+
+void vdec_trace_clean(struct vdec_trace *vtr)
+{
+	int i, size = ARRAY_SIZE(trace_map);
+
+	for (i = 0; i < size; i++) {
+		if (vtr->item[i].value)
+			vdec_tracing(vtr, vtr->item[i].type, 0);
+	}
+}
+
diff --git a/drivers/amvdec_ports/utils/aml_dec_trace.h b/drivers/amvdec_ports/utils/aml_dec_trace.h
new file mode 100644
index 0000000..4c0fcb0
--- /dev/null
+++ b/drivers/amvdec_ports/utils/aml_dec_trace.h
@@ -0,0 +1,168 @@
+/*
+ * 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_DEC_TRACE_H_
+#define _AML_DEC_TRACE_H_
+
+#include <trace/events/meson_atrace.h>
+
+#define VTRACE_GROUP_V4L_DEC	(1)
+#define VTRACE_GROUP_V4L_GE2D	(2)
+#define VTRACE_GROUP_V4L_VPP	(4)
+#define VTRACE_GROUP_DVB_DEC	(8)
+#define VTRACE_GROUP_DVB_VTP	(0x10)
+#define VTRACE_GROUP_DVB_VDO	(0x20)
+#define VTRACE_GROUP_DVB_VOUT	(0x40)
+#define VTRACE_GROUP_WRP	(0x80)
+#define VTRACE_GROUP_WRP_GE2D	(0x100)
+#define VTRACE_GROUP_WRP_VPP	(0x200)
+#define VTRACE_GROUP_WRP_SINK	(0x200)
+#define VTRACE_GROUP_DEC_CORE	(0x400)
+
+enum vdec_trace_type_list {
+	/* v4l wrapper. */
+	VTRACE_V4L_ES_0,	/* que.                  */
+	VTRACE_V4L_ES_1,	/* que_again.            */
+	VTRACE_V4L_ES_2,	/* write.                */
+	VTRACE_V4L_ES_3,	/* write_secure.         */
+	VTRACE_V4L_ES_4,	/* receive.              */
+	VTRACE_V4L_ES_5,	/* submit.               */
+	VTRACE_V4L_ES_6,	/* deque.                */
+	VTRACE_V4L_ES_7,	/* deque_again.          */
+	VTRACE_V4L_ES_8,	/* write_end.            */
+	VTRACE_V4L_ES_9,	/* write_secure_end.     */
+	VTRACE_V4L_ES_10,	/* write_error.          */
+	VTRACE_V4L_ES_11,	/* write_again.          */
+	VTRACE_V4L_ES_12,	/* in PTS.	 	 */
+
+	VTRACE_V4L_PIC_0,	/* que.                  */
+	VTRACE_V4L_PIC_1,	/* que_again.            */
+	VTRACE_V4L_PIC_2,	/* storage.              */
+	VTRACE_V4L_PIC_3,	/* require.              */
+	VTRACE_V4L_PIC_4,	/* recycle.              */
+	VTRACE_V4L_PIC_5,	/* receive.              */
+	VTRACE_V4L_PIC_6,	/* submit.               */
+	VTRACE_V4L_PIC_7,	/* deque.                */
+	VTRACE_V4L_PIC_8,	/* deque_again.          */
+	VTRACE_V4L_PIC_9,	/* out PTS.		 */
+	VTRACE_V4L_PIC_10,	/* vsink_cache_num.		 */
+
+	VTRACE_V4L_ST_0,	/* state.                */
+	VTRACE_V4L_ST_1,	/* input_buffering.      */
+
+	/* ge2d wrapper. */
+	VTRACE_GE2D_PIC_0,	/* vf_put.               */
+	VTRACE_GE2D_PIC_1,	/* recycle.              */
+	VTRACE_GE2D_PIC_2,	/* receive.              */
+	VTRACE_GE2D_PIC_3,	/* handle_start.         */
+	VTRACE_GE2D_PIC_4,	/* submit.               */
+	VTRACE_GE2D_PIC_5,	/* vf_get.               */
+	VTRACE_GE2D_PIC_6,	/* ge2d_cache_num.              */
+
+	VTRACE_GE2D_ST_0,	/* reserver.             */
+
+	/* vpp wrapper. */
+	VTRACE_VPP_PIC_0,	/* vf_put.               */
+	VTRACE_VPP_PIC_1,	/* recycle.              */
+	VTRACE_VPP_PIC_2,	/* receive.              */
+	VTRACE_VPP_PIC_3,	/* fill_output_start.    */
+	VTRACE_VPP_PIC_4,	/* empty_input_start.    */
+	VTRACE_VPP_PIC_5,	/* lc_handle_start.      */
+	VTRACE_VPP_PIC_6,	/* direct_handle_start.  */
+	VTRACE_VPP_PIC_7,	/* fill_output_start_dw. */
+	VTRACE_VPP_PIC_8,	/* empty_input_start_dw. */
+	VTRACE_VPP_PIC_9,	/* submit.               */
+	VTRACE_VPP_PIC_10,	/* lc_submit.            */
+	VTRACE_VPP_PIC_11,	/* vf_get.               */
+	VTRACE_VPP_PIC_12,	/* lc_attach.            */
+	VTRACE_VPP_PIC_13,	/* lc_detach.            */
+	VTRACE_VPP_PIC_14,	/* lc_release.           */
+	VTRACE_VPP_PIC_15,	/* vpp_cache_num.           */
+
+	VTRACE_VPP_ST_0,	/* reserver.		 */
+
+	/* dec core */
+	VTRACE_DEC_PIC_0,	/* submit.		 */
+	VTRACE_DEC_PIC_1,	/* reserver.		 */
+
+	VTRACE_DEC_ST_0,	/* chunk_size.           */
+	VTRACE_DEC_ST_1,	/* free_buffer_count.    */
+	VTRACE_DEC_ST_2,	/* dec_state.		 */
+	VTRACE_DEC_ST_3,	/* work_state.           */
+	VTRACE_DEC_ST_4,	/* eos.		         */
+	VTRACE_DEC_ST_5,	/* wait_more_buf.        */
+	VTRACE_DEC_ST_6,	/* reserver.		 */
+
+	VTRACE_MAX
+};
+
+struct vdec_trace_map {
+	u32	group;
+	int	type;
+	u8	*gname;
+	u8	*description;
+};
+
+struct vdec_trace_item {
+	int	channel;
+	bool	enable;
+	u32	group;
+	int	type;
+	ulong	value;
+	u8	name[64];
+};
+
+struct vdec_trace {
+	struct vdec_trace_item item[VTRACE_MAX + 1];
+};
+
+void vdec_trace_init(struct vdec_trace *vtr, int ch, int vdec_id);
+
+void vdec_trace_clean(struct vdec_trace *vtr);
+
+static inline void vdec_tracing(struct vdec_trace *vtr, int type, ulong val)
+{
+	if (vtr->item[type].enable) {
+		meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+			vtr->item[type].name,
+			(1 << KERNEL_ATRACE_COUNTER), val);
+		vtr->item[type].value = val;
+	}
+}
+
+static inline void vdec_tracing_begin(struct vdec_trace *vtr, int type)
+{
+	if (vtr->item[type].enable) {
+		meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+			vtr->item[type].name,
+			(1 << KERNEL_ATRACE_BEGIN), 0);
+	}
+}
+
+static inline void vdec_tracing_end(struct vdec_trace *vtr, int type)
+{
+	if (vtr->item[type].enable) {
+		meson_atrace(KERNEL_ATRACE_TAG_V4L2,
+			vtr->item[type].name,
+			(1 << KERNEL_ATRACE_END), 1);
+	}
+}
+
+#endif //_AML_DEC_TRACE_H_
+
diff --git a/drivers/amvdec_ports/utils/common.c b/drivers/amvdec_ports/utils/common.c
index 67cf93b..34efa3e 100644
--- a/drivers/amvdec_ports/utils/common.c
+++ b/drivers/amvdec_ports/utils/common.c
@@ -1,8 +1,28 @@
+/*
+ * 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>
 #include <linux/mm.h>
 #include <linux/string.h>
+#include "../../common/media_utils/media_utils.h"
 
 #include "common.h"
 #ifdef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
@@ -229,4 +249,121 @@
 	return false;
 }
 
+u8 *aml_yuv_dump(struct file *fp, u8 *start_addr, u32 real_width, u32 real_height, u32 align)
+{
+	u32 index;
+	u32 coded_width = ALIGN(real_width, align);
+	u32 coded_height = ALIGN(real_height, align);
+	u8 *yuv_data_addr = start_addr;
+
+	if (real_width != coded_width) {
+		for (index = 0; index < real_height; index++) {
+			media_write(fp, yuv_data_addr, real_width, 0);
+			yuv_data_addr += coded_width;
+		}
+	} else {
+		media_write(fp, yuv_data_addr, real_width * real_height, 0);
+	}
+
+	return (start_addr + coded_width * coded_height);
+}
+
+bool is_output_p010(u32 dec_mode)
+{
+	return !!(dec_mode & VDEC_MODE_10BIT_MASK);
+}
+
+int vdec_get_size_ratio(int dec_mode)
+{
+	int ratio = 1;
+
+	u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+	switch (dm) {
+	case DM_YUV_1_4_AVBC_A:
+	case DM_YUV_1_4_AVBC_B:
+		ratio = 4;
+		break;
+	case DM_YUV_1_2_AVBC:
+		ratio = 2;
+		break;
+	case DM_YUV_1_8_AVBC:
+		ratio = 8;
+		break;
+	default:
+		break;
+	}
+
+	return ratio;
+}
+
+int vdec_get_dec_mode(u32 w, u32 h, int dec_mode)
+{
+	u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+	switch (dm) {
+	case DM_YUV_AUTO_1_2_AVBC:
+		if (is_over_size(w, h, 1920 * 1088))
+			dm = 0x4; /*1:2*/
+		break;
+	case DM_YUV_AUTO_1_4_AVBC:
+		if (is_over_size(w, h, 1920 * 1088))
+			dm = 0x2; /*1:4*/
+		break;
+	case DM_YUV_AUTO_1_2_AVBC_B:
+		if (is_over_size(w, h, 1280 * 768))
+			dm = 0x4; /*1:2*/
+		break;
+	case DM_YUV_AUTO_14_12_AVBC:
+		if (is_over_size(w, h, 1920 * 1088))
+			dm = 0x3; /*1:4*/
+		else if (is_over_size(w, h, 960 * 576))
+			dm = 0x4; /*1:2*/
+		break;
+	default:
+		break;
+	}
+
+	return (dec_mode & VDEC_MODE_10BIT_MASK) | dm;
+}
+
+static int vdec_size_scale(int length, int dec_mode)
+{
+	int ret = 64;
+	u32 dm = dec_mode & VDEC_MODE_DW_MASK;
+
+	switch (dm) {
+	case DM_AVBC_ONLY: /* only afbc, output afbc */
+		ret = 64;
+		break;
+	case DM_YUV_1_1_AVBC: /* afbc and (w x h), output YUV420 */
+		ret = length;
+		break;
+	case DM_YUV_1_4_AVBC_A: /* afbc and (w/4 x h/4), output YUV420 */
+	case DM_YUV_1_4_AVBC_B: /* 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 0x8: /* afbc and (w/8 x h/8), output YUV420 */
+		ret = length >> 3;
+		break;
+	case 0x10: /* (w x h), output YUV420-8bit) */
+	default:
+		ret = length;
+		break;
+	}
+
+	return ret;
+}
+
+u32 vdec_get_plane_size(u32 w, u32 h, int dec_mode, int align)
+{
+	u32 dm = vdec_get_dec_mode(w, h, dec_mode);
+	u32 len = ALIGN(vdec_size_scale(w, dm), align) *
+		ALIGN(vdec_size_scale(h, dm), align);
+
+	return len << is_output_p010(dec_mode);
+}
 
diff --git a/drivers/amvdec_ports/utils/common.h b/drivers/amvdec_ports/utils/common.h
index 89ae50b..bbb2df4 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,
@@ -134,6 +153,35 @@
 };
 #endif
 
+#define VDEC_MODE_MMU_DW_MASK	(0x20)
+#define VDEC_MODE_10BIT_MASK	(0x10000)
+#define VDEC_MODE_DW_MASK	(0xffff)
+
+enum vdec_dec_mode {
+	DM_INVALID		= 0,
+	DM_AVBC_ONLY		= 0,
+	DM_YUV_1_1_AVBC		= 1,
+	DM_YUV_1_4_AVBC_A	= 2,
+	DM_YUV_1_4_AVBC_B	= 3,
+	DM_YUV_1_2_AVBC		= 4,
+	DM_YUV_1_8_AVBC		= 8,
+	DM_YUV_ONLY		= 0x10,
+	DM_AVBC_1_1		= 0x21,
+	DM_AVBC_1_4		= 0x22,
+	DM_AVBC_1_2		= 0x24,
+	DM_YUV_AUTO_1_2_AVBC	= 0x100,
+	DM_YUV_AUTO_1_4_AVBC	= 0x200,
+	DM_YUV_AUTO_1_2_AVBC_B	= 0x300,
+	/* (0~540] 1/1, (540~1080] 1/4, (1080~4K] 1/16 */
+	DM_YUV_AUTO_14_12_AVBC	= 0x400,
+	DM_YUV_1_1_10BIT_AVBC	= 0x10001,
+	DM_YUV_1_4_10BIT_AVBC	= 0x10003,
+	DM_YUV_1_2_10BIT_AVBC	= 0x10004,
+	DM_YUV_1_8_10BIT_AVBC	= 0x10008,
+	/* (0~1080] 1/1, (1080~4K] 1/16 */
+	DM_YUV_14_11_10BIT_AVBC	= 0x10200,
+};
+
 //fmt
 const char *av_color_space_name(enum AVColorSpace space);
 const char *av_color_primaries_name(enum AVColorPrimaries primaries);
@@ -152,4 +200,13 @@
 
 bool is_over_size(int w, int h, int size);
 
+u8 *aml_yuv_dump(struct file *fp, u8 *start_addr, u32 real_width, u32 real_height, u32 align);
+
+bool is_output_p010(u32 dec_mode);
+
+int vdec_get_size_ratio(int dec_mode);
+
+int vdec_get_dec_mode(u32 w, u32 h, int dec_mode);
+
+u32 vdec_get_plane_size(u32 w, u32 h, int dec_mode, int align);
 #endif
\ No newline at end of file
diff --git a/drivers/amvdec_ports/utils/get_bits.h b/drivers/amvdec_ports/utils/get_bits.h
index bb98ebd..5d9f168 100644
--- a/drivers/amvdec_ports/utils/get_bits.h
+++ b/drivers/amvdec_ports/utils/get_bits.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 AVCODEC_GET_BITS_H
 #define AVCODEC_GET_BITS_H
 
diff --git a/drivers/amvdec_ports/utils/golomb.c b/drivers/amvdec_ports/utils/golomb.c
index 21fcb6a..2033962 100644
--- a/drivers/amvdec_ports/utils/golomb.c
+++ b/drivers/amvdec_ports/utils/golomb.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>
 
diff --git a/drivers/amvdec_ports/utils/golomb.h b/drivers/amvdec_ports/utils/golomb.h
index d66c182..631dab7 100644
--- a/drivers/amvdec_ports/utils/golomb.h
+++ b/drivers/amvdec_ports/utils/golomb.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 AVCODEC_GOLOMB_H
 #define AVCODEC_GOLOMB_H
 
diff --git a/drivers/amvdec_ports/utils/pixfmt.h b/drivers/amvdec_ports/utils/pixfmt.h
index f13411e..1a0e833 100644
--- a/drivers/amvdec_ports/utils/pixfmt.h
+++ b/drivers/amvdec_ports/utils/pixfmt.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 AVUTIL_PIXFMT_H
 #define AVUTIL_PIXFMT_H
 
@@ -16,7 +35,7 @@
  * then the chroma plane resolution must be rounded up.
  *
  * @par
- * When the pixel format is palettized RGB32 (AV_PIX_FMT_PAL8), the palettized
+ * When the pixel format is palette RGB32 (AV_PIX_FMT_PAL8), the palette
  * image data is stored in AVFrame.data[0]. The palette is transported in
  * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is
  * formatted the same as in AV_PIX_FMT_RGB32 described above (i.e., it is
diff --git a/drivers/amvdec_ports/utils/put_bits.h b/drivers/amvdec_ports/utils/put_bits.h
index 8b2aa15..11a6c94 100644
--- a/drivers/amvdec_ports/utils/put_bits.h
+++ b/drivers/amvdec_ports/utils/put_bits.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 AVCODEC_PUT_BITS_H
 #define AVCODEC_PUT_BITS_H
 
diff --git a/drivers/amvdec_ports/vdec_drv_base.h b/drivers/amvdec_ports/vdec_drv_base.h
index 990d406..ef0667e 100644
--- a/drivers/amvdec_ports/vdec_drv_base.h
+++ b/drivers/amvdec_ports/vdec_drv_base.h
@@ -1,22 +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:
-*/
+ * 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 _VDEC_DRV_BASE_
 #define _VDEC_DRV_BASE_
 
diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c
index 01510c5..ac48e41 100644
--- a/drivers/amvdec_ports/vdec_drv_if.c
+++ b/drivers/amvdec_ports/vdec_drv_if.c
@@ -1,22 +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:
-*/
+ * 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/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -24,6 +24,7 @@
 #include "vdec_drv_if.h"
 #include "aml_vcodec_dec.h"
 #include "vdec_drv_base.h"
+#include "../frame_provider/decoder/utils/vdec_v4l2_buffer_ops.h"
 
 const struct vdec_common_if *get_h264_dec_comm_if(void);
 const struct vdec_common_if *get_hevc_dec_comm_if(void);
@@ -32,6 +33,10 @@
 const struct vdec_common_if *get_mpeg4_dec_comm_if(void);
 const struct vdec_common_if *get_mjpeg_dec_comm_if(void);
 const struct vdec_common_if *get_av1_dec_comm_if(void);
+const struct vdec_common_if *get_avs_dec_comm_if(void);
+const struct vdec_common_if *get_avs2_dec_comm_if(void);
+const struct vdec_common_if *get_avs3_dec_comm_if(void);
+const struct vdec_common_if *get_vc1_dec_comm_if(void);
 
 int vdec_if_init(struct aml_vcodec_ctx *ctx, unsigned int fourcc)
 {
@@ -61,6 +66,19 @@
 	case V4L2_PIX_FMT_AV1:
 		ctx->dec_if = get_av1_dec_comm_if();
 		break;
+	case V4L2_PIX_FMT_AVS:
+		ctx->dec_if = get_avs_dec_comm_if();
+		break;
+	case V4L2_PIX_FMT_AVS2:
+		ctx->dec_if = get_avs2_dec_comm_if();
+		break;
+	case V4L2_PIX_FMT_AVS3:
+		ctx->dec_if = get_avs3_dec_comm_if();
+		break;
+	case V4L2_PIX_FMT_VC1_ANNEX_L:
+	case V4L2_PIX_FMT_VC1_ANNEX_G:
+		ctx->dec_if = get_vc1_dec_comm_if();
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -85,7 +103,7 @@
 {
 	int ret = 0;
 
-	if (bs) {
+	if (bs && (!ctx->stream_mode)) {
 		if ((bs->addr & 63) != 0) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 				"bs dma_addr should 64 byte align\n");
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index 29911f8..e837902 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -1,22 +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:
-*/
+ * 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 _VDEC_DRV_IF_H_
 #define _VDEC_DRV_IF_H_
 
@@ -65,17 +65,6 @@
 	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,
-};
-
 /*
  * the caller does not own the returned buffer. The buffer will not be
  *				released before vdec_if_deinit.
@@ -91,7 +80,10 @@
 	GET_PARAM_DPB_SIZE,
 	GET_PARAM_CONFIG_INFO,
 	GET_PARAM_DW_MODE,
-	GET_PARAM_COMP_BUF_INFO
+	GET_PARAM_COMP_BUF_INFO,
+	GET_PARAM_CFG_INFO,
+	GET_PARAM_TW_MODE,
+	GET_PARAM_TIME_STAMP
 };
 
 /*
@@ -104,7 +96,8 @@
 	SET_PARAM_HDR_INFO,
 	SET_PARAM_POST_EVENT,
 	SET_PARAM_PIC_INFO,
-	SET_PARAM_CFG_INFO
+	SET_PARAM_CFG_INFO,
+	SET_PARAM_INST_RESET
 };
 
 /**
diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c
index 158e32c..fa1cba0 100644
--- a/drivers/common/chips/chips.c
+++ b/drivers/common/chips/chips.c
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/chips/chips.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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>
@@ -30,7 +32,6 @@
 #include "../../frame_provider/decoder/utils/vdec.h"
 #include "chips.h"
 #include <linux/amlogic/media/utils/log.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
 #include "decoder_cpu_ver_info.h"
 
 #define VIDEO_FIRMWARE_FATHER_NAME "video"
@@ -86,6 +87,12 @@
 	{AM_MESON_CPU_MAJOR_ID_P1, "p1"},
 	{AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
 	{AM_MESON_CPU_MAJOR_ID_T5W, "t5w"},
+	{AM_MESON_CPU_MAJOR_ID_S5, "s5"},
+	{AM_MESON_CPU_MAJOR_ID_GXLX3, "gxlx3"},
+	{AM_MESON_CPU_MAJOR_ID_T5M, "t5m"},
+	{AM_MESON_CPU_MAJOR_ID_T3X, "t3x"},
+	{AM_MESON_CPU_MAJOR_ID_TXHD2, "txhd2"},
+	{AM_MESON_CPU_MAJOR_ID_S1A, "s1a"},
 	{0, NULL},
 };
 
@@ -134,7 +141,9 @@
  *	VFORMAT_H264_ENC,
  *	VFORMAT_JPEG_ENC,
  *	VFORMAT_VP9,
-*	VFORMAT_AVS2,
+ *	VFORMAT_AVS2,
+ *	VFORMAT_AV1,
+ *	VFORMAT_AVS3,
  *	VFORMAT_MAX
  *};
  */
@@ -156,6 +165,7 @@
 	{VFORMAT_VP9, "vp9"},
 	{VFORMAT_AVS2, "avs2"},
 	{VFORMAT_AV1, "av1"},
+	{VFORMAT_AVS3, "avs3"},
 	{VFORMAT_YUV, "yuv"},
 	{0, NULL},
 };
diff --git a/drivers/common/chips/chips.h b/drivers/common/chips/chips.h
index 003e9d2..dd6b3a2 100644
--- a/drivers/common/chips/chips.h
+++ b/drivers/common/chips/chips.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/chips/chips.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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 UCODE_MANAGER_HEADER
 #define UCODE_MANAGER_HEADER
 #include "../media_clock/clk/clk_priv.h"
diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c
index af162b8..13acb1e 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.c
+++ b/drivers/common/chips/decoder_cpu_ver_info.c
@@ -1,22 +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:
-*/
+ * 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/kernel.h>
 #include <linux/module.h>
@@ -26,215 +26,683 @@
 #include <linux/of_device.h>
 #include <linux/amlogic/media/registers/cpu_version.h>
 #include "decoder_cpu_ver_info.h"
+#include "../register/register.h"
 
-#define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
-#define AM_SUCESS 0
+#define AM_SUCCESS 0
 #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]=
-{
-	AM_MESON_CPU_MAJOR_ID_M6,
-	AM_MESON_CPU_MAJOR_ID_M6TV,
-	AM_MESON_CPU_MAJOR_ID_M6TVL,
-	AM_MESON_CPU_MAJOR_ID_M8,
-	AM_MESON_CPU_MAJOR_ID_MTVD,
-	AM_MESON_CPU_MAJOR_ID_M8B,
-	AM_MESON_CPU_MAJOR_ID_MG9TV,
-	AM_MESON_CPU_MAJOR_ID_M8M2,
-	AM_MESON_CPU_MAJOR_ID_UNUSE,
-	AM_MESON_CPU_MAJOR_ID_GXBB,
-	AM_MESON_CPU_MAJOR_ID_GXTVBB,
-	AM_MESON_CPU_MAJOR_ID_GXL,
-	AM_MESON_CPU_MAJOR_ID_GXM,
-	AM_MESON_CPU_MAJOR_ID_TXL,
-	AM_MESON_CPU_MAJOR_ID_TXLX,
-	AM_MESON_CPU_MAJOR_ID_AXG,
-	AM_MESON_CPU_MAJOR_ID_GXLX,
-	AM_MESON_CPU_MAJOR_ID_TXHD,
-	AM_MESON_CPU_MAJOR_ID_G12A,
-	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_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_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 bool codec_dos_dev = 0;		//to compat old dts
+
+static struct dos_of_dev_s *platform_dos_dev = NULL;
+
+static struct dos_of_dev_s dos_dev_data[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START] = {
+	[AM_MESON_CPU_MAJOR_ID_M8B - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_M8B,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = false,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_1080P,
+		.hevc_max_resolution = RESOLUTION_1080P,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_GXL,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_G12A,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,	//hevcb clk must be same with hevcf in g12a
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_G12B - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_G12B,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag	= false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu	= true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_GXLX2 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_GXLX2,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag	= false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu	= true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_SM1,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,  //support 8kp24
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_TL1,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K, //support 8kp24
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_TM2,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_C1,
+		.reg_compat = NULL,
+		.is_vdec_canvas_support = true,
+		.fmt_support_flags = FMT_JPEG_ENC,
+	},
+
+
+	[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_SC2,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T5,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K, //unsupport vp9 & av1
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_AVS2,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T5D,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 667,
+		.max_hevcb_clock = 667,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_1080P,
+		.hevc_max_resolution = RESOLUTION_1080P,	//unsupport 4k and avs2
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T7,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.is_support_axi_ctrl = true,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_S4,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T3,
+		.reg_compat = t3_mm_registers_compat,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.is_support_rdma     = true,
+		.is_support_mmu_copy = true,
+		.is_support_axi_ctrl = true,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,	//8kp30, rdma, mmu copy
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_S4D,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T5W,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_S5,
+		.reg_compat = s5_mm_registers_compat,	//register compact
+		.max_vdec_clock        = 800,
+		.max_hevcf_clock       = 800,
+		.max_hevcb_clock       = 800,
+		.hevc_clk_combine_flag = true,
+		.is_hw_parser_support  = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu   = true,
+		.is_support_dual_core  = true,
+		.is_support_axi_ctrl = true,
+		.hevc_stream_extra_shift = 8,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T5M,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.is_support_axi_ctrl = true,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_4K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_T3X,
+		.reg_compat = s5_mm_registers_compat,	//register compact
+		.max_vdec_clock        = 800,
+		.max_hevcf_clock       = 800,
+		.max_hevcb_clock       = 800,
+		.hevc_clk_combine_flag = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.is_support_rdma     = true,
+		.is_support_axi_ctrl = true,
+		.hevc_stream_extra_shift = 8,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1_AVS3,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_TXHD2,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 500,
+		.max_hevcb_clock = 500,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_1080P,
+		.hevc_max_resolution = RESOLUTION_4K,	//unsupport avs2,av1
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC | FMT_VP9,
+	},
+
+	[AM_MESON_CPU_MAJOR_ID_S1A - MAJOR_ID_START] = {
+		.chip_id = AM_MESON_CPU_MAJOR_ID_S1A,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 500,
+		.max_hevcb_clock = 500,
+		.hevc_clk_combine_flag  = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = false,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_1080P,
+		.hevc_max_resolution = RESOLUTION_1080P,
+		.fmt_support_flags = FMT_HEVC | FMT_H264 | FMT_MPEG2 | FMT_MPEG4 | FMT_VC1,
+	},
 };
 
+/* sub id features */
+static struct dos_of_dev_s dos_dev_sub_table[] = {
+	{	/* g12b revb */
+		.chip_id = AM_MESON_CPU_MINOR_ID_REVB_G12B,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 667,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,	//g12b revb hevc clk support 800mhz
+		.hevc_clk_combine_flag	= true,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu	= true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2,
+	},
+
+	{	/* tm2 revb */
+		.chip_id = AM_MESON_CPU_MINOR_ID_REVB_TM2,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = true,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	{
+		.chip_id = AM_MESON_CPU_MINOR_ID_S4_S805X2,
+		.reg_compat = NULL,
+		.max_vdec_clock        = 500,
+		.max_hevcf_clock       = 500,
+		.max_hevcb_clock       = 500,
+		.hevc_clk_combine_flag = true,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = false,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.vdec_max_resolution = RESOLUTION_1080P,
+		.hevc_max_resolution = RESOLUTION_1080P,
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	},
+
+	{
+		.chip_id = AM_MESON_CPU_MINOR_ID_T7C,
+		.reg_compat = NULL,
+		.max_vdec_clock  = 800,
+		.max_hevcf_clock = 800,
+		.max_hevcb_clock = 800,
+		.hevc_clk_combine_flag  = false,
+		.is_hw_parser_support   = false,
+		.is_vdec_canvas_support = true,
+		.is_support_h264_mmu    = true,
+		.is_support_dual_core = false,
+		.is_support_axi_ctrl = true,
+		.vdec_max_resolution = RESOLUTION_4K,
+		.hevc_max_resolution = RESOLUTION_8K,  //fixed endian issue
+		.fmt_support_flags = FMT_VDEC_ALL | FMT_HEVC_VP9_AVS2_AV1,
+	}
+};
+
+/* dos device match table */
 static const struct of_device_id cpu_ver_of_match[] = {
 	{
 		.compatible = "amlogic, cpu-major-id-axg",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_AXG - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_AXG - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-g12a",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_G12A - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-gxl",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXL - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-gxm",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_GXM - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_GXM - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-txl",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TXL - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXL - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-txlx",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TXLX - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXLX - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-sm1",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_SM1 - MAJOR_ID_START],
 	},
 
 	{
 		.compatible = "amlogic, cpu-major-id-tl1",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TL1 - MAJOR_ID_START],
 	},
 	{
 		.compatible = "amlogic, cpu-major-id-tm2",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TM2 - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-c1",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_C1 - MAJOR_ID_START],
 	},
 	{
 		.compatible = "amlogic, cpu-major-id-sc2",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[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],
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-s5",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S5 - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-t5m",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T5M - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-t3x",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_T3X - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-txhd2",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_TXHD2 - MAJOR_ID_START],
+	},
+	{
+		.compatible = "amlogic, cpu-major-id-s1a",
+		.data = &dos_dev_data[AM_MESON_CPU_MAJOR_ID_S1A - 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],
+		.data = &dos_dev_sub_table[0],
 	},
 	{
 		.compatible = "amlogic, cpu-major-id-tm2-b",
-		.data = &cpu_sub_info[1],
+		.data = &dos_dev_sub_table[1],
 	},
 	{
 		.compatible = "amlogic, cpu-major-id-s4-805x2",
-		.data = &cpu_sub_info[2],
+		.data = &dos_dev_sub_table[2],
 	},
+	{
+		.compatible = "amlogic, cpu-major-id-t7c",
+		.data = &dos_dev_sub_table[3],
+	},
+	{}
 };
 
-static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pid_type, int *sub_id)
+static struct platform_device *get_dos_dev_from_dtb(void)
 {
 	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) {
-		pr_err("No find node.\n");
-		return -EINVAL;
+	pnode = of_find_node_by_name(NULL, CODEC_DOS_DEV_ID_NODE_NAME);
+	if (pnode == NULL) {
+		codec_dos_dev = false;
+		pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+		if (pnode == NULL) {
+			pr_err("No find node.\n");
+			return NULL;
+		}
+	} else {
+		codec_dos_dev = true;
 	}
 
-	pdev =  of_find_device_by_node(pnode);
-	if (NULL == pdev)
-		return -EINVAL;
+	return of_find_device_by_node(pnode);
+}
+
+static struct dos_of_dev_s * get_dos_of_dev_data(struct platform_device *pdev)
+{
+	const struct of_device_id *pmatch = NULL;
+
+	if (pdev == NULL)
+		return NULL;
 
 	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;
+			return NULL;
 		}
 	}
 
-	*pid_type = (enum AM_MESON_CPU_MAJOR_ID)(*(int *)pmatch->data) & (MAJOY_ID_MASK);
-
-	*sub_id = ((*(int *)pmatch->data) & (SUB_ID_MASK)) >> 8;
-
-	return AM_SUCESS;
+	return (struct dos_of_dev_s *)pmatch->data;
 }
 
-static void initial_cpu_id(void)
+/* dos to get platform data */
+static int dos_device_search_data(int id, int sub_id)
 {
-	enum AM_MESON_CPU_MAJOR_ID id_type = AM_MESON_CPU_MAJOR_ID_MAX;
-	int sub_id = 0;
+	int i, j;
+	int sub_dev_id;
 
-	if (AM_SUCESS == get_cpu_id_from_dtb(&id_type, &sub_id)) {
-		cpu_ver_id = id_type;
-		cpu_sub_id = sub_id;
+	for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
+		if (id == dos_dev_data[i].chip_id) {
+			platform_dos_dev = &dos_dev_data[i];
+			pr_info("%s, get major %d dos dev data success\n", __func__, i);
+
+			if (sub_id) {
+				for (j = 0; j < ARRAY_SIZE(dos_dev_sub_table); j++) {
+					if (id == (dos_dev_sub_table[j].chip_id & MAJOR_ID_MASK)) {
+						sub_dev_id = (dos_dev_sub_table[j].chip_id & SUB_ID_MASK) >> 8;
+						if (sub_id == sub_dev_id) {
+							platform_dos_dev = &dos_dev_sub_table[j];
+							pr_info("%s, get sub %d dos dev data success\n", __func__, j);
+						}
+					}
+				}
+			}
+		}
+	}
+	if (platform_dos_dev)
+		return 0;
+	else
+		return -ENODEV;
+}
+
+struct platform_device *initial_dos_device(void)
+{
+	struct platform_device *pdev = NULL;
+	struct dos_of_dev_s *of_dev_data;
+
+	pdev = get_dos_dev_from_dtb();
+
+	of_dev_data = get_dos_of_dev_data(pdev);
+
+	if (of_dev_data) {
+		cpu_ver_id = of_dev_data->chip_id & MAJOY_ID_MASK;
+		cpu_sub_id = (of_dev_data->chip_id & SUB_ID_MASK) >> 8;
+		platform_dos_dev = of_dev_data;
 	} else {
 		cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type();
-		cpu_sub_id = (is_meson_rev_b()) ? CHIP_REVB : CHIP_REVA;
-	}
+		cpu_sub_id = is_meson_rev_b() ? CHIP_REVB :
+					(is_meson_rev_c() ? CHIP_REVC : CHIP_REVA);
 
-	if ((AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) && (CHIP_REVB == cpu_sub_id))
+		pr_info("get dos dev failed, id %d(%d), try to search\n",
+			cpu_ver_id, cpu_sub_id);
+
+		if (dos_device_search_data(cpu_ver_id, cpu_sub_id) < 0) {
+			pr_err("get dos device failed, dos maybe out of work\n");
+			//return NULL;
+		}
+	}
+	if ((cpu_ver_id == AM_MESON_CPU_MAJOR_ID_G12B) &&
+		(cpu_sub_id == CHIP_REVB))
 		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 (pdev && of_dev_data)
+		dos_register_probe(pdev, of_dev_data->reg_compat);
+
+	pr_info("initial_dos_device end, chip %d(%d)\n",
+		cpu_ver_id, cpu_sub_id);
+
+	return pdev;
 }
+EXPORT_SYMBOL(initial_dos_device);
 
 enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void)
 {
 	if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
-		initial_cpu_id();
+		initial_dos_device();
 
 	return cpu_ver_id;
 }
@@ -249,7 +717,7 @@
 bool is_cpu_meson_revb(void)
 {
 	if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
-		initial_cpu_id();
+		initial_dos_device();
 
 	return (cpu_sub_id == CHIP_REVB);
 }
@@ -269,3 +737,260 @@
 }
 EXPORT_SYMBOL(is_cpu_s4_s805x2);
 
+bool is_cpu_t7(void)
+{
+	return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
+		&& (get_cpu_sub_id() != CHIP_REVC));
+}
+EXPORT_SYMBOL(is_cpu_t7);
+
+bool is_cpu_t7c(void)
+{
+	return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7)
+		&& (get_cpu_sub_id() == CHIP_REVC));
+}
+EXPORT_SYMBOL(is_cpu_t7c);
+
+/*
+	feature from dos dev functions
+*/
+/*
+bit0: force support no_parser;
+bit1: force support all video format;
+*/
+#define FORCE_VDEC_NO_PARSER     BIT(0)
+#define FORCE_VDEC_SUPPORT_FMT   BIT(1)
+static u32 force_dos_support;
+
+inline bool is_hevc_align32(int blkmod)
+{
+	if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S1A) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(is_hevc_align32);
+
+inline bool is_support_new_dos_dev(void)
+{
+	return codec_dos_dev;
+}
+EXPORT_SYMBOL(is_support_new_dos_dev);
+
+inline struct dos_of_dev_s *dos_dev_get(void)
+{
+	return platform_dos_dev;
+}
+EXPORT_SYMBOL(dos_dev_get);
+
+
+/* vdec & hevc clock */
+inline u32 vdec_max_clk_get(void)
+{
+	return platform_dos_dev->max_vdec_clock;
+}
+EXPORT_SYMBOL(vdec_max_clk_get);
+
+inline u32 hevcf_max_clk_get(void)
+{
+	return platform_dos_dev->max_hevcf_clock;
+}
+EXPORT_SYMBOL(hevcf_max_clk_get);
+
+inline u32 hevcb_max_clk_get(void)
+{
+	return platform_dos_dev->max_hevcb_clock;
+}
+EXPORT_SYMBOL(hevcb_max_clk_get);
+
+inline bool is_hevc_clk_combined(void)
+{
+	return (platform_dos_dev->hevc_clk_combine_flag);
+}
+EXPORT_SYMBOL(is_hevc_clk_combined);
+
+/* ressolution */
+inline int vdec_is_support_4k(void)
+{
+	if (platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P)
+		return true;
+	else
+		return false;
+}
+EXPORT_SYMBOL(vdec_is_support_4k);
+
+inline int hevc_is_support_4k(void)
+{
+	if (platform_dos_dev->hevc_max_resolution > RESOLUTION_1080P)
+		return true;
+	else
+		return false;
+}
+EXPORT_SYMBOL(hevc_is_support_4k);
+
+inline int hevc_is_support_8k(void)
+{
+	if (platform_dos_dev->hevc_max_resolution > RESOLUTION_4K)
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(hevc_is_support_8k);
+
+inline bool is_oversize_vdec(int w, int h)
+{
+	if (w < 0 || h < 0)
+		return true;
+
+	if (h != 0 && (w > platform_dos_dev->vdec_max_resolution / h))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(is_oversize_vdec);
+
+inline bool is_oversize_hevc(int w, int h)
+{
+	if (w < 0 || h < 0)
+		return true;
+
+	if (h != 0 && (w > platform_dos_dev->hevc_max_resolution / h))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(is_oversize_hevc);
+
+inline bool is_support_no_parser(void)
+{
+	return ((force_dos_support & FORCE_VDEC_NO_PARSER) ||
+		(!platform_dos_dev->is_hw_parser_support));
+}
+EXPORT_SYMBOL(is_support_no_parser);
+
+/* vdec intra canvas feature */
+inline bool is_support_vdec_canvas(void)
+{
+	return (platform_dos_dev->is_vdec_canvas_support);
+}
+EXPORT_SYMBOL(is_support_vdec_canvas);
+
+inline bool is_support_dual_core(void)
+{
+	return (platform_dos_dev->is_support_dual_core);
+}
+EXPORT_SYMBOL(is_support_dual_core);
+
+inline bool is_support_p010_mode(void)
+{
+	return (platform_dos_dev->is_support_p010);
+}
+EXPORT_SYMBOL(is_support_p010_mode);
+
+inline bool is_support_triple_write(void)
+{
+	return (platform_dos_dev->is_support_triple_write);
+}
+EXPORT_SYMBOL(is_support_triple_write);
+
+inline bool is_support_rdma(void)
+{
+	return (platform_dos_dev->is_support_rdma);
+}
+EXPORT_SYMBOL(is_support_rdma);
+
+inline bool is_support_mmu_copy(void)
+{
+	return (platform_dos_dev->is_support_mmu_copy);
+}
+EXPORT_SYMBOL(is_support_mmu_copy);
+
+inline bool is_support_axi_ctrl(void)
+{
+	return platform_dos_dev->is_support_axi_ctrl;
+}
+EXPORT_SYMBOL(is_support_axi_ctrl);
+
+inline bool is_support_format(int format)
+{
+	if ((platform_dos_dev->fmt_support_flags == 0) ||
+		(force_dos_support & FORCE_VDEC_SUPPORT_FMT))
+		return true;
+
+	return ((1 << format) &
+		platform_dos_dev->fmt_support_flags);
+}
+EXPORT_SYMBOL(is_support_format);
+
+inline int get_hevc_stream_extra_shift_bytes(void)
+{
+	return platform_dos_dev->hevc_stream_extra_shift;
+}
+EXPORT_SYMBOL(get_hevc_stream_extra_shift_bytes);
+
+void pr_dos_infos(void)
+{
+	pr_info("dos device info:\n");
+	pr_info("chip id: 0x%x(0x%x)\n", cpu_ver_id, cpu_sub_id);
+
+	pr_info("max vdec  clock: %03d MHz\n", vdec_max_clk_get());
+	pr_info("max hevcf clock: %03d MHz\n", hevcf_max_clk_get());
+	if (!is_hevc_clk_combined()) {
+		pr_info("max hevcb clock: %03d MHz\n", hevcb_max_clk_get());
+	}
+
+	pr_info("max vdec resolution : %s\n",
+		platform_dos_dev->vdec_max_resolution > RESOLUTION_1080P ? "4K":"1080P");
+	pr_info("max hevc resolution : %s\n",
+		platform_dos_dev->hevc_max_resolution < RESOLUTION_4K ? "1080P" :
+		(platform_dos_dev->hevc_max_resolution > RESOLUTION_4K ? "8K":"4K"));
+
+	pr_info("support no parser   : %d\n", is_support_no_parser());
+	pr_info("support vdec canvas : %d\n", is_support_vdec_canvas());
+	pr_info("support dual core   : %d\n", is_support_dual_core());
+	pr_info("support p010 mode   : %d\n", is_support_p010_mode());
+	pr_info("support triple write: %d\n", is_support_triple_write());
+	pr_info("support rdma        : %d\n", is_support_rdma());
+	pr_info("support mmu copy    : %d\n", is_support_mmu_copy());
+	pr_info("support dos axi ctrl: %d\n", is_support_axi_ctrl());
+	pr_info("support format      : 0x%x\n", platform_dos_dev->fmt_support_flags);
+	pr_info("hevc_stream_extra_shift_bytes: %d\n", get_hevc_stream_extra_shift_bytes());
+}
+EXPORT_SYMBOL(pr_dos_infos);
+
+void dos_info_debug(void)
+{
+	int i;
+	struct dos_of_dev_s *save = platform_dos_dev;
+	int save_major_id = cpu_ver_id;
+	int save_sub_id = cpu_sub_id;
+
+	for (i = 0; i < ARRAY_SIZE(dos_dev_data); i++) {
+		platform_dos_dev = &dos_dev_data[i];
+		if (platform_dos_dev->chip_id) {
+			cpu_ver_id = platform_dos_dev->chip_id;
+			pr_dos_infos();
+			pr_info("\n");
+		}
+	}
+	for (i = 0; i < ARRAY_SIZE(dos_dev_sub_table); i++) {
+		platform_dos_dev = &dos_dev_sub_table[i];
+		if (platform_dos_dev->chip_id) {
+			cpu_ver_id = platform_dos_dev->chip_id & MAJOR_ID_MASK;
+			cpu_sub_id = (platform_dos_dev->chip_id & SUB_ID_MASK) >> 8;
+			pr_dos_infos();
+			pr_info("\n");
+		}
+	}
+
+	platform_dos_dev = save;
+	cpu_ver_id = save_major_id;
+	cpu_sub_id = save_sub_id;
+}
+EXPORT_SYMBOL(dos_info_debug);
+
+
+module_param(force_dos_support, uint, 0664);
+
diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h
index 6129244..eaf58c9 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.h
+++ b/drivers/common/chips/decoder_cpu_ver_info.h
@@ -1,28 +1,35 @@
 /*
-* 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:
-*/
+ * 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 DECODER_CPU_VER_INFO_H
 #define DECODER_CPU_VER_INFO_H
+#include <linux/platform_device.h>
 #include <linux/amlogic/media/registers/cpu_version.h>
+#include "../register/register.h"
+#include <linux/amlogic/media/utils/vformat.h>
+
 /* majoy chip id define */
 #define MAJOY_ID_MASK (0x000000ff)
 
+#define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
+#define CODEC_DOS_DEV_ID_NODE_NAME  "vcodec_dos_dev"
+
 enum AM_MESON_CPU_MAJOR_ID {
 	AM_MESON_CPU_MAJOR_ID_M6	= 0x16,
 	AM_MESON_CPU_MAJOR_ID_M6TV	= 0x17,
@@ -62,6 +69,14 @@
 	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_C3	= 0x3c,
+	AM_MESON_CPU_MAJOR_ID_S5	= 0x3e,
+	AM_MESON_CPU_MAJOR_ID_GXLX3	= 0x3f,
+	AM_MESON_CPU_MAJOR_ID_T5M	= 0x41,
+	AM_MESON_CPU_MAJOR_ID_T3X	= 0x42,
+	AM_MESON_CPU_MAJOR_ID_RES_0x43,
+	AM_MESON_CPU_MAJOR_ID_TXHD2	= 0x44,
+	AM_MESON_CPU_MAJOR_ID_S1A	= 0x45,
 	AM_MESON_CPU_MAJOR_ID_MAX,
 };
 
@@ -75,13 +90,88 @@
 #define REVC_MASK (CHIP_REVC << 8)
 #define REVX_MASK (CHIP_REVX << 8)
 
+#define MAJOR_ID_MASK 0xFF
 #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_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)
+#define AM_MESON_CPU_MINOR_ID_T7C        (REVC_MASK | AM_MESON_CPU_MAJOR_ID_T7)
+
+/* for dos_of_dev_s max resolution define */
+#define RESOLUTION_1080P  (1920 * 1088)
+#define RESOLUTION_4K     (4302 * 2176)  //4k
+#define RESOLUTION_8K     (8192 * 4352)  //8k
+
+/* fmt_support */
+//vdec
+#define FMT_MPEG2    BIT(VFORMAT_MPEG12)
+#define FMT_MPEG4    BIT(VFORMAT_MPEG4)
+#define FMT_H264     BIT(VFORMAT_H264)
+#define FMT_MJPEG    BIT(VFORMAT_MJPEG)
+#define FMT_VC1      BIT(VFORMAT_VC1)
+#define FMT_AVS      BIT(VFORMAT_AVS)
+#define FMT_MVC      BIT(VFORMAT_H264MVC)
+//hevc
+#define FMT_HEVC     BIT(VFORMAT_HEVC)
+#define FMT_VP9      BIT(VFORMAT_VP9)
+#define FMT_AVS2     BIT(VFORMAT_AVS2)
+#define FMT_AV1      BIT(VFORMAT_AV1)
+#define FMT_AVS3     BIT(VFORMAT_AVS3)
+//hcodec
+#define FMT_H264_ENC BIT(VFORMAT_H264_ENC)
+#define FMT_JPEG_ENC BIT(VFORMAT_JPEG_ENC)
+
+//frequently-used combination
+#define FMT_VDEC_ALL               (FMT_MPEG2 | FMT_MPEG4 | FMT_H264 | FMT_MJPEG | FMT_VC1 | FMT_MVC | FMT_AVS)
+#define FMT_VDEC_NO_AVS            (FMT_MPEG2 | FMT_MPEG4 | FMT_H264 | FMT_MJPEG | FMT_VC1 | FMT_MVC)
+
+#define FMT_HEVC_VP9_AV1           (FMT_HEVC | FMT_VP9 | FMT_AV1)
+#define FMT_HEVC_VP9_AVS2          (FMT_HEVC | FMT_VP9 | FMT_AVS2)
+#define FMT_HEVC_VP9_AVS2_AV1      (FMT_AV1  | FMT_HEVC_VP9_AVS2)
+#define FMT_HEVC_VP9_AVS2_AV1_AVS3 (FMT_AVS3 | FMT_HEVC_VP9_AVS2_AV1)
+
+/* dos hardware feature define. */
+struct dos_of_dev_s {
+	enum AM_MESON_CPU_MAJOR_ID chip_id;
+
+	/* register*/
+	reg_compat_func reg_compat;
+
+	/* clock, Mhz. necessary!! */
+	u32 max_vdec_clock;
+	u32 max_hevcf_clock;
+	u32 max_hevcb_clock;
+	bool hevc_clk_combine_flag;
+
+	/* resolution. necessary!! */
+	u32 vdec_max_resolution;	//just for h264
+	u32 hevc_max_resolution;
+
+	/* esparser */
+	bool is_hw_parser_support;
+
+	/* vdec */
+	bool is_vdec_canvas_support;
+	bool is_support_h264_mmu;
+
+	/* hevc */
+	bool is_support_dual_core;
+	bool is_support_p010;
+	bool is_support_triple_write;
+	bool is_support_rdma;
+	bool is_support_mmu_copy;
+	int hevc_stream_extra_shift;
+
+	bool is_support_axi_ctrl;  /*dos pipeline ctrl by dos or dmc */
+
+	u32 fmt_support_flags;
+};
+
 
 /* export functions */
+struct platform_device *initial_dos_device(void);
+
 enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void);
 
 bool is_cpu_meson_revb(void);
@@ -92,4 +182,58 @@
 
 bool is_cpu_s4_s805x2(void);
 
+bool is_cpu_t7(void);
+bool is_cpu_t7c(void);
+
+inline bool is_support_new_dos_dev(void);
+
+struct dos_of_dev_s *dos_dev_get(void);
+
+inline bool is_hevc_align32(int blkmod);
+
+/* clk get */
+inline u32 vdec_max_clk_get(void);
+
+inline u32 hevcf_max_clk_get(void);
+
+inline u32 hevcb_max_clk_get(void);
+
+inline bool is_hevc_clk_combined(void);
+
+/* resolution check */
+inline int vdec_is_support_4k(void);
+
+inline int hevc_is_support_4k(void);
+
+inline int hevc_is_support_8k(void);
+
+inline bool is_oversize_vdec(int w, int h);
+
+inline bool is_oversize_hevc(int w, int h);
+
+/* hardware features */
+inline bool is_support_no_parser(void);
+
+inline bool is_support_vdec_canvas(void);
+
+inline bool is_support_dual_core(void);
+
+inline bool is_support_p010_mode(void);
+
+inline bool is_support_triple_write(void);
+
+inline bool is_support_rdma(void);
+
+inline bool is_support_mmu_copy(void);
+
+inline bool is_support_axi_ctrl(void);
+
+inline bool is_support_format(int format);
+
+inline int get_hevc_stream_extra_shift_bytes(void);
+
+void pr_dos_infos(void);
+
+void dos_info_debug(void);
+
 #endif
diff --git a/drivers/common/firmware/Makefile b/drivers/common/firmware/Makefile
index 748039c..8b7ef6b 100644
--- a/drivers/common/firmware/Makefile
+++ b/drivers/common/firmware/Makefile
@@ -1,3 +1,14 @@
-obj-m	+=	firmware.o
-firmware-objs	+=	firmware_drv.o
-firmware-objs	+=	firmware_type.o
+MODULE_NAME = firmware
+obj-m = $(MODULE_NAME).o
+$(MODULE_NAME)-y += firmware_drv.o
+$(MODULE_NAME)-y += firmware_type.o
+ifeq (${VERSION},5)
+ifeq (${PATCHLEVEL},15)
+	$(MODULE_NAME)-y += ../media_utils/media_utils_dummy.o
+else
+	$(MODULE_NAME)-y += ../media_utils/media_utils.o
+endif
+endif
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)= \"[$(PR_FMT)]: \" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/common/firmware/firmware_cfg.h b/drivers/common/firmware/firmware_cfg.h
index e23ac2a..342a3a2 100644
--- a/drivers/common/firmware/firmware_cfg.h
+++ b/drivers/common/firmware/firmware_cfg.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/firmware/firmware_cfg.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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:
  */
-
 /*all firmwares in one bin.*/
 {VIDEO_MISC,	VIDEO_PACKAGE,	"video_ucode.bin"},
 
diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c
index 9422198..4ec161c 100644
--- a/drivers/common/firmware/firmware_drv.c
+++ b/drivers/common/firmware/firmware_drv.c
@@ -1,7 +1,5 @@
-/*
- * drivers/amlogic/media/common/firmware/firmware.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ /*
+ * 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
@@ -13,6 +11,11 @@
  * 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>
@@ -23,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 
 #include <linux/amlogic/media/utils/vformat.h>
 #include <linux/amlogic/media/registers/cpu_version.h>
@@ -33,20 +37,30 @@
 #include <linux/string.h>
 #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 <linux/version.h>
+#if LINUX_VERSION_CODE == KERNEL_VERSION(5, 4, 0)
 #include <uapi/linux/major.h>
+#else
+#include <linux/amlogic/major.h> //if kernel is 4.9 then use this one
+#endif
 #include <linux/cdev.h>
 #include <linux/crc32.h>
 #include "../chips/decoder_cpu_ver_info.h"
 
+#if !IS_ENABLED(CONFIG_AMLOGIC_TEE) && \
+	!IS_ENABLED(CONFIG_AMLOGIC_TEE_MODULE)
+static inline bool tee_enabled(void) { return false; }
+#else
+#include <linux/amlogic/tee.h>
+#endif
+
 /* major.minor */
-#define PACK_VERS "v0.3"
+#define PACK_VERS "v0.4"
 
 #define CLASS_NAME	"firmware_codec"
 #define DEV_NAME	"firmware_vdec"
 #define DIR		"video"
-#define FRIMWARE_SIZE	(64 * 1024) /*64k*/
+#define FIRMWARE_SIZE	(64 * 1024) /*64k*/
 #define BUFF_SIZE	(1024 * 1024 * 2)
 
 #define FW_LOAD_FORCE	(0x1)
@@ -59,6 +73,7 @@
 
 #define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K')
 #define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E')
+#define NEWP ('N' << 24 | 'E' << 16 | 'W' << 8 | 'P')
 
 #ifndef FIRMWARE_MAJOR
 #define FIRMWARE_MAJOR AMSTREAM_MAJOR
@@ -80,6 +95,39 @@
 
 static u32 debug;
 static u32 detail;
+static bool new_package = false;
+
+bool fw_tee_enabled(void)
+{
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S1A)
+		return false;
+
+	return tee_enabled();
+}
+EXPORT_SYMBOL(fw_tee_enabled);
+
+extern unsigned long long g_fw_mask;
+void fw_get_format_from_dtb(void)
+{
+	struct device_node *pnode = NULL;
+	u32 ret;
+
+	pnode = of_find_node_by_name(NULL, CODEC_DOS_DEV_ID_NODE_NAME);
+	if (!pnode) {
+		pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+		if (!pnode) {
+			pr_err("not find node\n");
+			return;
+		}
+	}
+	ret = of_property_read_u64(pnode, "ucode_format", &g_fw_mask);
+	if (ret) {
+		pr_info("read format in dts failed, ret = %d\n", ret);
+		return;
+	}
+
+	return;
+}
 
 int get_firmware_data(unsigned int format, char *buf)
 {
@@ -87,11 +135,12 @@
 	struct fw_mgr_s *mgr = g_mgr;
 	struct fw_info_s *info;
 
-	pr_info("[%s], the fw (%s) will be loaded...\n",
-		tee_enabled() ? "TEE" : "LOCAL",
-		get_fw_format_name(format));
+	if (debug)
+		pr_info("[%s], the fw (%s) will be loaded...\n",
+			fw_tee_enabled() ? "TEE" : "LOCAL",
+			get_fw_format_name(format));
 
-	if (tee_enabled())
+	if (fw_tee_enabled())
 		return 0;
 
 	mutex_lock(&mutex);
@@ -177,7 +226,7 @@
 	const struct firmware *fw;
 	int magic, offset = 0;
 
-	pr_info("Try to load %s  ...\n", file_name);
+	pr_debug("Try to load %s  ...\n", file_name);
 
 	ret = request_firmware(&fw, file_name, g_dev->dev);
 	if (ret < 0) {
@@ -192,7 +241,7 @@
 	}
 
 	magic = fw_probe((char *)fw->data);
-	if (magic != PACK && magic != CODE) {
+	if (magic != PACK && magic != CODE && magic != NEWP) {
 		if (fw->size < SEC_OFFSET) {
 			pr_info("This is an invalid firmware file.\n");
 			goto release;
@@ -209,7 +258,7 @@
 
 	memcpy(buf, (char *)fw->data + offset, fw->size - offset);
 
-	pr_info("load firmware size : %zd, Name : %s.\n",
+	pr_debug("load firmware size : %zd, Name : %s.\n",
 		fw->size, file_name);
 	ret = fw->size;
 release:
@@ -248,6 +297,22 @@
 }
 EXPORT_SYMBOL(get_decoder_firmware_data);
 
+int get_decoder_firmware_version(void)
+{
+	int version;
+
+	version = (package_head.version & 0xff);
+
+	return version;
+}
+EXPORT_SYMBOL(get_decoder_firmware_version);
+
+int get_decoder_firmware_submit_count(void)
+{
+	return package_head.submit_count;
+}
+EXPORT_SYMBOL(get_decoder_firmware_submit_count);
+
 static unsigned long fw_mgr_lock(struct fw_mgr_s *mgr)
 {
 	unsigned long flags;
@@ -368,7 +433,6 @@
 		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);
-		
 	}
 
 	list_for_each_entry(info, &mgr->fw_head, node) {
@@ -460,6 +524,8 @@
 
 	__putname(path);
 
+	fw_get_format_from_dtb();
+
 	if (debug)
 		fw_files_info_walk();
 
@@ -494,6 +560,12 @@
 	if (fw_info->format == FIRMWARE_MAX)
 		return 0;
 
+	if (!fw_check_need_load(fw->head.format)) {
+		kfree(fw_info);
+		kfree(fw);
+		return 1;
+	}
+
 	list_for_each_entry_safe(info, tmp, &mgr->fw_head, node) {
 		if (info->format != fw_info->format)
 			continue;
@@ -656,7 +728,7 @@
 			goto out;
 		}
 
-		data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
+		data = kzalloc(FIRMWARE_SIZE, GFP_KERNEL);
 		if (data == NULL) {
 			kfree(info);
 			ret = -ENOMEM;
@@ -678,7 +750,7 @@
 		pack_data += (pack_info->head.length + info_len);
 		pack_info = (struct package_info_s *)pack_data;
 
-		if (!data->head.duplicate &&
+		if (!data->head.duplicate && (new_package == false) &&
 			!fw_data_check_sum(data)) {
 			pr_info("check sum fail !\n");
 			kfree(data);
@@ -715,7 +787,7 @@
 	if (info == NULL)
 		return -ENOMEM;
 
-	info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
+	info->data = kzalloc(FIRMWARE_SIZE, GFP_KERNEL);
 	if (info->data == NULL) {
 		kfree(info);
 		return -ENOMEM;
@@ -780,12 +852,16 @@
 		if (files->file_type == VIDEO_PACKAGE && magic == PACK) {
 			if (!fw_check_pack_version(buf))
 				ret = fw_package_parse(files, buf, size);
+		} else if (files->file_type == VIDEO_PACKAGE && magic == NEWP) {
+			new_package = true;
+			if (!fw_check_pack_version(buf))
+				ret = fw_package_parse(files, buf, size);
 		} else if (files->file_type == VIDEO_FW_FILE && magic == CODE) {
 			ret = fw_code_parse(files, buf, size);
 		} else {
 			list_del(&files->node);
 			kfree(files);
-			pr_info("invaild file type.\n");
+			pr_info("invalid file type.\n");
 		}
 
 		memset(buf, 0, BUFF_SIZE);
@@ -858,7 +934,7 @@
 	int ret = 0;
 	struct fw_mgr_s *mgr = g_mgr;
 
-	if (tee_enabled())
+	if (fw_tee_enabled())
 		return 0;
 
 	mutex_lock(&mutex);
@@ -1002,7 +1078,7 @@
 		goto err;
 	}
 
-	pr_info("Registered firmware driver success.\n");
+	pr_debug("Registered firmware driver success.\n");
 err:
 	return ret;
 }
diff --git a/drivers/common/firmware/firmware_priv.h b/drivers/common/firmware/firmware_priv.h
index d901f9d..371949f 100644
--- a/drivers/common/firmware/firmware_priv.h
+++ b/drivers/common/firmware/firmware_priv.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/firmware/firmware.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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 __VIDEO_FIRMWARE_PRIV_HEAD_
 #define __VIDEO_FIRMWARE_PRIV_HEAD_
 #include <linux/types.h>
diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c
index 8d95c12..0f506b9 100644
--- a/drivers/common/firmware/firmware_type.c
+++ b/drivers/common/firmware/firmware_type.c
@@ -1,66 +1,82 @@
 /*
-* 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:
-*/
+ * 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/bits.h>
 #include "firmware_type.h"
 #include "../chips/decoder_cpu_ver_info.h"
 
 static const struct format_name_s format_name[] = {
-	{VIDEO_DEC_MPEG12,		"mpeg12"},
-	{VIDEO_DEC_MPEG12_MULTI,	"mpeg12_multi"},
-	{VIDEO_DEC_MPEG4_3,		"mpeg4_3"},
-	{VIDEO_DEC_MPEG4_4,		"mpeg4_4"},
-	{VIDEO_DEC_MPEG4_4_MULTI,	"mpeg4_4_multi"},
-	{VIDEO_DEC_MPEG4_5,		"xvid"},
-	{VIDEO_DEC_MPEG4_5_MULTI,	"xvid_multi"},
-	{VIDEO_DEC_H263,		"h263"},
-	{VIDEO_DEC_H263_MULTI,		"h263_multi"},
-	{VIDEO_DEC_MJPEG,		"mjpeg"},
-	{VIDEO_DEC_MJPEG_MULTI,		"mjpeg_multi"},
-	{VIDEO_DEC_REAL_V8,		"real_v8"},
-	{VIDEO_DEC_REAL_V9,		"real_v9"},
-	{VIDEO_DEC_VC1,			"vc1"},
-	{VIDEO_DEC_VC1_G12A,		"vc1_g12a"},
-	{VIDEO_DEC_AVS,			"avs"},
-	{VIDEO_DEC_AVS_GXM,		"avs_gxm"},
-	{VIDEO_DEC_AVS_NOCABAC,		"avs_no_cabac"},
-	{VIDEO_DEC_AVS_MULTI,		"avs_multi"},
-	{VIDEO_DEC_H264,		"h264"},
-	{VIDEO_DEC_H264_MVC,		"h264_mvc"},
-	{VIDEO_DEC_H264_MVC_GXM,	"h264_mvc_gxm"},
-	{VIDEO_DEC_H264_MULTI,		"h264_multi"},
-	{VIDEO_DEC_H264_MULTI_MMU,	"h264_multi_mmu"},
-	{VIDEO_DEC_H264_MULTI_GXM,	"h264_multi_gxm"},
-	{VIDEO_DEC_HEVC,		"hevc"},
-	{VIDEO_DEC_HEVC_MMU,		"hevc_mmu"},
-	{VIDEO_DEC_HEVC_MMU_SWAP,	"hevc_mmu_swap"},
-	{VIDEO_DEC_HEVC_G12A,		"hevc_g12a"},
-	{VIDEO_DEC_VP9,			"vp9"},
-	{VIDEO_DEC_VP9_MMU,		"vp9_mmu"},
-	{VIDEO_DEC_VP9_G12A,		"vp9_g12a"},
-	{VIDEO_DEC_AVS2,		"avs2"},
-	{VIDEO_DEC_AVS2_MMU,		"avs2_mmu"},
-	{VIDEO_DEC_AV1_MMU,		"av1_mmu"},
-	{VIDEO_ENC_H264,		"h264_enc"},
-	{VIDEO_ENC_JPEG,		"jpeg_enc"},
+	{VIDEO_DEC_MPEG12,		"mpeg12",		BIT_ULL(0)},
+	{VIDEO_DEC_MPEG12_MULTI,	"mpeg12_multi",		BIT_ULL(1)},
+	{VIDEO_DEC_MPEG4_3,		"mpeg4_3",		BIT_ULL(2)},
+	{VIDEO_DEC_MPEG4_4,		"mpeg4_4",		BIT_ULL(3)},
+	{VIDEO_DEC_MPEG4_4_MULTI,	"mpeg4_4_multi",	BIT_ULL(4)},
+	{VIDEO_DEC_MPEG4_5,		"xvid",			BIT_ULL(5)},
+	{VIDEO_DEC_MPEG4_5_MULTI,	"xvid_multi",		BIT_ULL(6)},
+	{VIDEO_DEC_H263,		"h263",			BIT_ULL(7)},
+	{VIDEO_DEC_H263_MULTI,		"h263_multi",		BIT_ULL(8)},
+	{VIDEO_DEC_MJPEG,		"mjpeg",		BIT_ULL(9)},
+	{VIDEO_DEC_MJPEG_MULTI,		"mjpeg_multi",		BIT_ULL(10)},
+	{VIDEO_DEC_REAL_V8,		"real_v8",		BIT_ULL(11)},
+	{VIDEO_DEC_REAL_V9,		"real_v9",		BIT_ULL(12)},
+	{VIDEO_DEC_VC1,			"vc1",			BIT_ULL(13)},
+	{VIDEO_DEC_VC1_G12A,		"vc1_g12a",		BIT_ULL(14)},
+	{VIDEO_DEC_AVS,			"avs",			BIT_ULL(15)},
+	{VIDEO_DEC_AVS_GXM,		"avs_gxm",		BIT_ULL(16)},
+	{VIDEO_DEC_AVS_NOCABAC,		"avs_no_cabac",		BIT_ULL(17)},
+	{VIDEO_DEC_AVS_MULTI,		"avs_multi",		BIT_ULL(18)},
+	{VIDEO_DEC_H264,		"h264",			BIT_ULL(19)},
+	{VIDEO_DEC_H264_MVC,		"h264_mvc",		BIT_ULL(20)},
+	{VIDEO_DEC_H264_MVC_GXM,	"h264_mvc_gxm",		BIT_ULL(21)},
+	{VIDEO_DEC_H264_MULTI,		"h264_multi",		BIT_ULL(22)},
+	{VIDEO_DEC_H264_MULTI_MMU,	"h264_multi_mmu",	BIT_ULL(23)},
+	{VIDEO_DEC_H264_MULTI_GXM,	"h264_multi_gxm",	BIT_ULL(24)},
+	{VIDEO_DEC_HEVC,		"hevc",			BIT_ULL(25)},
+	{VIDEO_DEC_HEVC_MMU,		"hevc_mmu",		BIT_ULL(26)},
+	{VIDEO_DEC_HEVC_MMU_SWAP,	"hevc_mmu_swap",	BIT_ULL(27)},
+	{VIDEO_DEC_HEVC_G12A,		"hevc_g12a",		BIT_ULL(28)},
+	{VIDEO_DEC_VP9,			"vp9",			BIT_ULL(29)},
+	{VIDEO_DEC_VP9_MMU,		"vp9_mmu",		BIT_ULL(30)},
+	{VIDEO_DEC_VP9_G12A,		"vp9_g12a",		BIT_ULL(31)},
+	{VIDEO_DEC_AVS2,		"avs2",			BIT_ULL(32)},
+	{VIDEO_DEC_AVS2_MMU,		"avs2_mmu",		BIT_ULL(33)},
+	{VIDEO_DEC_AV1_MMU,		"av1_mmu",		BIT_ULL(34)},
+	{VIDEO_DEC_AVS3,		"avs3_mmu",		BIT_ULL(35)},
+	/* front/back ucode */
+	{VIDEO_DEC_HEVC_FRONT,		"hevc_front",		BIT_ULL(36)},
+	{VIDEO_DEC_HEVC_BACK,		"hevc_back",		BIT_ULL(37)},
+	{VIDEO_DEC_VP9_FRONT,		"vp9_front",		BIT_ULL(38)},
+	{VIDEO_DEC_VP9_BACK,		"vp9_back",		BIT_ULL(39)},
+	{VIDEO_DEC_AV1_FRONT,		"av1_front",		BIT_ULL(40)},
+	{VIDEO_DEC_AV1_BACK,		"av1_back",		BIT_ULL(41)},
+	{VIDEO_DEC_AVS2_FRONT,		"avs2_front",		BIT_ULL(42)},
+	{VIDEO_DEC_AVS2_BACK,		"avs2_back",		BIT_ULL(43)},
+	{VIDEO_DEC_AVS3_FRONT,		"avs3_front",		BIT_ULL(44)},
+	{VIDEO_DEC_AVS3_BACK,		"avs3_back",		BIT_ULL(45)},
+
+	{VIDEO_ENC_H264,		"h264_enc",		BIT_ULL(46)},
+	{VIDEO_ENC_JPEG,		"jpeg_enc",		BIT_ULL(47)},
 	{FIRMWARE_MAX,			"unknown"},
 };
 
+unsigned long long g_fw_mask = (~0ULL);
+
 static const struct cpu_type_s cpu_type[] = {
 	{AM_MESON_CPU_MAJOR_ID_GXL,	"gxl"},
 	{AM_MESON_CPU_MAJOR_ID_GXM,	"gxm"},
@@ -75,7 +91,9 @@
 	{AM_MESON_CPU_MAJOR_ID_SM1,	"sm1"},
 	{AM_MESON_CPU_MAJOR_ID_TL1,	"tl1"},
 	{AM_MESON_CPU_MAJOR_ID_TM2,	"tm2"},
+	{AM_MESON_CPU_MAJOR_ID_C1,	"c1"},
 	{AM_MESON_CPU_MAJOR_ID_SC2,	"sc2"},
+	{AM_MESON_CPU_MAJOR_ID_C2,	"c2"},
 	{AM_MESON_CPU_MAJOR_ID_T5,	"t5"},
 	{AM_MESON_CPU_MAJOR_ID_T5D,	"t5d"},
 	{AM_MESON_CPU_MAJOR_ID_T7,	"t7"},
@@ -83,6 +101,12 @@
 	{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_S5,	"s5"},
+	{AM_MESON_CPU_MAJOR_ID_GXLX3,	"gxlx3"},
+	{AM_MESON_CPU_MAJOR_ID_T5M,	"t5m"},
+	{AM_MESON_CPU_MAJOR_ID_T3X,	"t3x"},
+	{AM_MESON_CPU_MAJOR_ID_TXHD2,	"txhd2"},
+	{AM_MESON_CPU_MAJOR_ID_S1A,	"s1a"},
 };
 
 const char *get_fw_format_name(unsigned int format)
@@ -127,3 +151,21 @@
 }
 EXPORT_SYMBOL(fw_get_cpu);
 
+int fw_check_need_load(const char *name)
+{
+	int idx, size = ARRAY_SIZE(format_name);
+
+	for (idx = 0; idx < size; idx++) {
+		if (!strcmp(name, format_name[idx].name)) {
+			if (g_fw_mask & format_name[idx].format_mask)
+				return true;
+			else
+				return false;
+		}
+	}
+
+	pr_info("no %s load info, load it\n", name);
+	return -1;
+}
+EXPORT_SYMBOL(fw_check_need_load);
+
diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h
index 4615baf..6907e4c 100644
--- a/drivers/common/firmware/firmware_type.h
+++ b/drivers/common/firmware/firmware_type.h
@@ -1,22 +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:
-*/
+ * 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 __VIDEO_FIRMWARE_FORMAT_
 #define __VIDEO_FIRMWARE_FORMAT_
 
@@ -49,6 +49,7 @@
 #define VIDEO_DEC_VP9_MMU		(19)
 #define VIDEO_ENC_H264			(20)
 #define VIDEO_ENC_JPEG			(21)
+#define VIDEO_ENC_H264_CABAC	(22)
 #define VIDEO_DEC_H264_MULTI_MMU	(23)
 #define VIDEO_DEC_HEVC_G12A		(24)
 #define VIDEO_DEC_VP9_G12A		(25)
@@ -66,6 +67,17 @@
 #define VIDEO_DEC_HEVC_MMU_SWAP		TAG('2', '6', '5', 'S')
 #define VIDEO_DEC_AVS_MULTI		TAG('A', 'V', 'S', 'M')
 #define VIDEO_DEC_AV1_MMU		TAG('A', 'V', '1', 'M')
+#define VIDEO_DEC_HEVC_FRONT  TAG('2', '6', '5', 'F')
+#define VIDEO_DEC_HEVC_BACK   TAG('2', '6', '5', 'B')
+#define VIDEO_DEC_VP9_FRONT  TAG('V', 'P', '9', 'F')
+#define VIDEO_DEC_VP9_BACK   TAG('V', 'P', '9', 'B')
+#define VIDEO_DEC_AV1_FRONT  TAG('A', 'V', '1', 'F')
+#define VIDEO_DEC_AV1_BACK   TAG('A', 'V', '1', 'B')
+#define VIDEO_DEC_AVS2_FRONT  TAG('A', 'S', '2', 'F')
+#define VIDEO_DEC_AVS2_BACK   TAG('A', 'S', '2', 'B')
+#define VIDEO_DEC_AVS3			TAG('A', 'V', 'S', '3')
+#define VIDEO_DEC_AVS3_FRONT  TAG('A', 'S', '3', 'F')
+#define VIDEO_DEC_AVS3_BACK   TAG('A', 'S', '3', 'B')
 
 /* ... */
 #define FIRMWARE_MAX			(UINT_MAX)
@@ -81,10 +93,12 @@
 #define OPTEE_VDEC			(1)
 #define OPTEE_VDEC_HEVC			(2)
 #define OPTEE_VDEC_HCDEC			(3)
+#define OPTEE_VDEC_HEVCB			(4)
 
 struct format_name_s {
 	unsigned int format;
 	const char *name;
+	unsigned long long format_mask;
 };
 
 struct cpu_type_s {
@@ -95,5 +109,8 @@
 const char *get_fw_format_name(unsigned int format);
 unsigned int get_fw_format(const char *name);
 int fw_get_cpu(const char *name);
+int get_decoder_firmware_version(void);
+int get_decoder_firmware_submit_count(void);
+int fw_check_need_load(const char *name);
 
 #endif
diff --git a/drivers/common/media_clock/Makefile b/drivers/common/media_clock/Makefile
index 975b5e5..cd6eb27 100644
--- a/drivers/common/media_clock/Makefile
+++ b/drivers/common/media_clock/Makefile
@@ -1,6 +1,12 @@
-obj-m	+=	media_clock.o
-media_clock-objs += ../chips/chips.o
-media_clock-objs += clk/clkg12.o
-media_clock-objs += clk/clk.o
-media_clock-objs += switch/amports_gate.o
-media_clock-objs += ../chips/decoder_cpu_ver_info.o
+MODULE_NAME = media_clock
+obj-m = $(MODULE_NAME).o
+$(MODULE_NAME)-y += ../chips/chips.o
+$(MODULE_NAME)-y += clk/clkg12.o
+$(MODULE_NAME)-y += clk/clk.o
+$(MODULE_NAME)-y += switch/amports_gate.o
+$(MODULE_NAME)-y += ../chips/decoder_cpu_ver_info.o
+$(MODULE_NAME)-y += ../register/register.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)= \"[$(PR_FMT)]: \" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c
index 6340c1a..9304fd1 100644
--- a/drivers/common/media_clock/clk/clk.c
+++ b/drivers/common/media_clock/clk/clk.c
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/clk/clk.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,13 @@
  * 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:
+ * drivers/amlogic/media/common/arch/clk/clk.c
  */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -311,21 +314,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);
@@ -350,11 +338,12 @@
 
 	if (format == VFORMAT_HEVC || format == VFORMAT_VP9
 		|| format == VFORMAT_AVS2
-		|| format == VFORMAT_AV1) {
+		|| format == VFORMAT_AV1
+		|| format == VFORMAT_AVS3) {
 		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()) {
+			!is_hevc_clk_combined()) {
 			ret_clk = hevc_back_clock_set(clk);
 			clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps;
 		}
@@ -444,19 +433,19 @@
 		return -ENOMEM;
 	memcpy(p_setting, setting, size);
 
-	pr_info("register clk_set_setting cpu[%d]\n", cputype);
+	pr_debug("register clk_set_setting cpu[%d]\n", cputype);
 
 	get_current_vdec_chip()->clk_setting_array = p_setting;
 	return 0;
 }
 
 int register_vdec_clk_setting(int cputype[],
-	struct clk_set_setting *p_seting, int size)
+	struct clk_set_setting *p_setting, int size)
 {
 	int i = 0;
 
 	while (cputype[i] > 0) {
-		register_vdec_clk_setting_per_cpu(cputype[i], p_seting, size);
+		register_vdec_clk_setting_per_cpu(cputype[i], p_setting, size);
 		i++;
 	}
 	return 0;
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h
index bbc3bee..2d22e29 100644
--- a/drivers/common/media_clock/clk/clk.h
+++ b/drivers/common/media_clock/clk/clk.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/clk/clk.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,13 +11,19 @@
  * 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:
+ * drivers/amlogic/media/common/arch/clk/clk.h
  */
-
 #ifndef VDEC_CHIP_CLK_HEADER
 #define VDEC_CHIP_CLK_HEADER
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/clk/clk-conf.h>
 #include "clk_priv.h"
 #include <linux/amlogic/media/clk/gp_pll.h>
 
@@ -52,8 +56,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);
 
@@ -74,7 +76,7 @@
 int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type);
 
 int register_vdec_clk_setting(int cputype[],
-	struct clk_set_setting *p_seting, int size);
+	struct clk_set_setting *p_setting, int size);
 
 int unregister_vdec_clk_setting(void);
 
@@ -124,8 +126,18 @@
 
 static int __init vdec_init_clk(void)
 {
+	struct platform_device *pdev;
 	int cpus[] = CLK_FOR_CPU;
 
+	pdev = initial_dos_device();
+
+	if (is_support_new_dos_dev()) {
+		/* set clock parent as dos dev node */
+		of_clk_set_defaults(pdev->dev.of_node, false);
+
+		amports_clock_gate_init(&pdev->dev);
+	}
+
 	register_vdec_clk_mgr(cpus, VDEC_1, &vdec_clk_mgr);
 #ifdef VDEC_HAS_VDEC2
 	register_vdec_clk_mgr(cpus, VDEC_2, &vdec2_clk_mgr);
diff --git a/drivers/common/media_clock/clk/clk_priv.h b/drivers/common/media_clock/clk/clk_priv.h
index 60b7be0..3949e48 100644
--- a/drivers/common/media_clock/clk/clk_priv.h
+++ b/drivers/common/media_clock/clk/clk_priv.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/clk/clk_priv.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,10 +11,16 @@
  * 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:
+ * drivers/amlogic/media/common/arch/clk/clk_priv.h
  */
-
 #ifndef AMPORTS_CLK_PRIV_HEADER
 #define AMPORTS_CLK_PRIV_HEADER
+#include "../../../frame_provider/decoder/utils/vdec.h"
 
 struct clk_set {
 	u32 wh_X_fps;		/* [x*y*fps */
diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c
index c49d150..94b77da 100644
--- a/drivers/common/media_clock/clk/clkg12.c
+++ b/drivers/common/media_clock/clk/clkg12.c
@@ -1,7 +1,5 @@
-/*
- * drivers/amlogic/media/common/arch/clk/clkgx.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ /*
+ * 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
@@ -13,6 +11,12 @@
  * 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:
+ * drivers/amlogic/media/common/arch/clk/clkgx.c
  */
 #define DEBUG
 #include <linux/init.h>
@@ -21,7 +25,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/amlogic/media/clk/gp_pll.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
 #include <linux/amlogic/media/utils/amports_config.h>
 #include "../../../frame_provider/decoder/utils/vdec.h"
 #include <linux/amlogic/media/registers/register.h>
@@ -289,6 +292,9 @@
  *	VFORMAT_H264_ENC,
  *	VFORMAT_JPEG_ENC,
  *	VFORMAT_VP9,
+ *	VFORMAT_AVS2,
+ *	VFORMAT_AV1,
+ *	VFORMAT_AVS3,
  *	VFORMAT_MAX
  *};
  *sample:
@@ -408,7 +414,11 @@
 		{1920*1080*60, 166}, {4096*2048*30, 333},
 		{4096*2048*60, 630}, {INT_MAX, 630},}
 	},
-
+	{/*VFORMAT_AVS3*/
+		{{1280*720*30, 100}, {1920*1080*30, 100},
+		{1920*1080*60, 166}, {4096*2048*30, 333},
+		{4096*2048*60, 630}, {INT_MAX, 630},}
+	},
 };
 
 void set_clock_gate(struct gate_switch_node *nodes, int num)
@@ -418,7 +428,11 @@
 
 	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))
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2))
 		hevc_mux_str = "clk_hevc_mux";
 	else
 		hevc_mux_str = "clk_hevcf_mux";
@@ -426,16 +440,23 @@
 	do {
 		node = &nodes[num - 1];
 		if (IS_ERR_OR_NULL(node) || (IS_ERR_OR_NULL(node->clk)))
-			pr_info("get mux clk err.\n");
-
-		if (!strcmp(node->name, "clk_vdec_mux"))
+			continue;
+		if (!strcmp(node->name, "clk_vdec_mux")) {
 			gclk.vdec_mux_node = node;
-		else if (!strcmp(node->name, "clk_hcodec_mux"))
+			pr_debug("%s get vdec mux\n", __func__);
+		}
+		else if (!strcmp(node->name, "clk_hcodec_mux")) {
 			gclk.hcodec_mux_node = node;
-		else if (!strcmp(node->name, hevc_mux_str))
-				gclk.hevc_mux_node = node;
-		else if (!strcmp(node->name, "clk_hevcb_mux"))
+			pr_debug("%s get hcodec mux\n", __func__);
+		}
+		else if (!strcmp(node->name, hevc_mux_str)) {
+			gclk.hevc_mux_node = node;
+			pr_debug("%s get hevc_mux_str\n", __func__);
+		}
+		else if (!strcmp(node->name, "clk_hevcb_mux")) {
 			gclk.hevc_back_mux_node = node;
+			pr_debug("%s get hevcb mux\n", __func__);
+		}
 	} while(--num);
 }
 EXPORT_SYMBOL(set_clock_gate);
@@ -489,7 +510,7 @@
 		break;
 
 	default:
-		pr_info("invaild vdec type.\n");
+		pr_info("invalid vdec type.\n");
 	}
 
 	if (IS_ERR_OR_NULL(clk)) {
@@ -732,14 +753,7 @@
 		clk = 667;
 	}
 
-	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)
-		clk = 800;
-
-	if (is_cpu_s4_s805x2())
-		clk = 500;
+	clk = vdec_max_clk_get();
 
 	if (set_frq_enable && vdec_frq) {
 		pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
@@ -787,10 +801,8 @@
 	if ((clk > 500 && clk != 667)) {
 		if (clock_real_clk[VDEC_HEVCB] == 648)
 		return 648;
-		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
-			clk = TL1_HEVC_MAX_CLK;
-		else
-			clk = 667;
+
+		clk = hevcb_max_clk_get();
 	}
 
 	if (set_frq_enable && hevcb_frq) {
@@ -836,15 +848,8 @@
 	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))
-			clk = TL1_HEVC_MAX_CLK;
-		else
-			clk = 667;
 
-		if (is_cpu_s4_s805x2())
-			clk = 500;
+		clk = hevcf_max_clk_get();
 	}
 
 	if (set_frq_enable && hevc_frq) {
@@ -1050,6 +1055,12 @@
 	AM_MESON_CPU_MAJOR_ID_P1,\
 	AM_MESON_CPU_MAJOR_ID_S4D,\
 	AM_MESON_CPU_MAJOR_ID_T5W,\
+	AM_MESON_CPU_MAJOR_ID_S5,\
+	AM_MESON_CPU_MAJOR_ID_GXLX3,\
+	AM_MESON_CPU_MAJOR_ID_T5M,\
+	AM_MESON_CPU_MAJOR_ID_T3X,\
+	AM_MESON_CPU_MAJOR_ID_TXHD2,\
+	AM_MESON_CPU_MAJOR_ID_S1A,\
 	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..9009894 100644
--- a/drivers/common/media_clock/switch/amports_gate.c
+++ b/drivers/common/media_clock/switch/amports_gate.c
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/switch/amports_gate.c
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,13 @@
  * 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
+//#define DEBUG
 #include <linux/compiler.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
@@ -22,7 +25,6 @@
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 #include "amports_gate.h"
-#include <linux/amlogic/media/utils/vdec_reg.h>
 #include "../../../stream_input/amports/amports_priv.h"
 #include "../../../frame_provider/decoder/utils/vdec.h"
 #include "../clk/clk.h"
@@ -99,11 +101,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_debug("get gate %s control failed %px\n",
 				gates[i].name,
 				gates[i].clk);
 		} else {
-			pr_info("get gate %s control ok %px\n",
+			pr_debug("get gate %s control ok %px\n",
 				gates[i].name,
 				gates[i].clk);
 		}
@@ -156,6 +158,8 @@
 
 			if (gates[i].clk)
 				amports_gate_clk(&gates[i], enable);
+			else
+				return -ENODEV;
 		}
 	}
 	return 0;
diff --git a/drivers/common/media_clock/switch/amports_gate.h b/drivers/common/media_clock/switch/amports_gate.h
index 58abc92..6dd8049 100644
--- a/drivers/common/media_clock/switch/amports_gate.h
+++ b/drivers/common/media_clock/switch/amports_gate.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/media/common/arch/switch/amports_gate.h
- *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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 AMPORT_GATE_H
 #define AMPORT_GATE_H
 #include <linux/device.h>
diff --git a/drivers/common/media_utils/media_utils.c b/drivers/common/media_utils/media_utils.c
new file mode 100644
index 0000000..d2a6337
--- /dev/null
+++ b/drivers/common/media_utils/media_utils.c
@@ -0,0 +1,50 @@
+/*
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/fs.h>
+
+ssize_t media_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+{
+	return kernel_write(file, buf, count, pos);
+}
+EXPORT_SYMBOL(media_write);
+
+ssize_t media_read(struct file *file, void *bufs, size_t count, loff_t *pos)
+{
+	return kernel_read(file, bufs, count, pos);
+}
+EXPORT_SYMBOL(media_read);
+
+struct file *media_open(const char *filename, int flags, umode_t mode)
+{
+	return filp_open(filename, flags, mode);
+}
+EXPORT_SYMBOL(media_open);
+
+int media_close(struct file *filp, fl_owner_t id)
+{
+	return filp_close(filp, id);
+}
+EXPORT_SYMBOL(media_close);
+
diff --git a/drivers/common/media_utils/media_utils.h b/drivers/common/media_utils/media_utils.h
new file mode 100644
index 0000000..09e8638
--- /dev/null
+++ b/drivers/common/media_utils/media_utils.h
@@ -0,0 +1,26 @@
+/*
+ * 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 _MEDIA_FILE_H_
+#define _MEDIA_FILE_H_
+ssize_t media_write(struct file *, const void *, size_t, loff_t *);
+ssize_t media_read(struct file *, void *, size_t, loff_t *);
+struct file *media_open(const char *, int, umode_t);
+int media_close(struct file *, fl_owner_t);
+#endif
diff --git a/drivers/common/media_utils/media_utils_dummy.c b/drivers/common/media_utils/media_utils_dummy.c
new file mode 100644
index 0000000..4d75a55
--- /dev/null
+++ b/drivers/common/media_utils/media_utils_dummy.c
@@ -0,0 +1,50 @@
+/*
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/fs.h>
+
+ssize_t media_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+{
+	return 0;
+}
+EXPORT_SYMBOL(media_write);
+
+ssize_t media_read(struct file *file, void *bufs, size_t count, loff_t *pos)
+{
+	return 0;
+}
+EXPORT_SYMBOL(media_read);
+
+struct file *media_open(const char *filename, int flags, umode_t mode)
+{
+	return NULL;
+}
+EXPORT_SYMBOL(media_open);
+
+int media_close(struct file *filp, fl_owner_t id)
+{
+	return 0;
+}
+EXPORT_SYMBOL(media_close);
+
diff --git a/drivers/common/media_utils/media_utils_dummy.h b/drivers/common/media_utils/media_utils_dummy.h
new file mode 100644
index 0000000..09e8638
--- /dev/null
+++ b/drivers/common/media_utils/media_utils_dummy.h
@@ -0,0 +1,26 @@
+/*
+ * 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 _MEDIA_FILE_H_
+#define _MEDIA_FILE_H_
+ssize_t media_write(struct file *, const void *, size_t, loff_t *);
+ssize_t media_read(struct file *, void *, size_t, loff_t *);
+struct file *media_open(const char *, int, umode_t);
+int media_close(struct file *, fl_owner_t);
+#endif
diff --git a/drivers/common/register/register.c b/drivers/common/register/register.c
new file mode 100644
index 0000000..859ae92
--- /dev/null
+++ b/drivers/common/register/register.c
@@ -0,0 +1,242 @@
+/*
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include "../chips/decoder_cpu_ver_info.h"
+#include "register.h"
+
+static void __iomem *reg_base[MAX_REG_BUS];
+struct bus_reg_desc *reg_desc[MAX_REG_BUS];
+
+#define CODEC_REG_READ_DEBUG  0x01
+#define CODEC_REG_WRITE_DEBUG 0x02
+#define CODEC_REG_MAP_DEBUG   0x08
+
+static u32 register_debug;
+module_param(register_debug, uint, 0664);
+
+void registers_offset_config(struct bus_reg_desc *offset_from, s32 val, u32 size)
+{
+	u32 i;
+
+	for (i = 0; i < size; i++) {
+		offset_from[i].reg_compat_offset = val;
+	}
+}
+EXPORT_SYMBOL(registers_offset_config);
+
+
+void s5_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs)
+{
+	if (bs == DOS_BUS) {
+		printk("s5 dos register compat\n");
+		registers_offset_config(&desc[HEVC_ASSIST_AMR1_INT0],
+			-(0x0025 - 0x0015),
+			(HEVC_ASSIST_MBX_SSEL - HEVC_ASSIST_AMR1_INT0 + 1));
+
+		registers_offset_config(&desc[HEVC_ASSIST_TIMER0_LO],
+			-(0x0060 - 0x0036),
+			(HEVC_ASSIST_DMA_INT_MSK2 - HEVC_ASSIST_TIMER0_LO + 1));
+
+		registers_offset_config(&desc[HEVC_ASSIST_MBOX0_IRQ_REG],
+			-(0x0070 - 0x0040),
+			(HEVC_ASSIST_AXI_STATUS2_LO - HEVC_ASSIST_MBOX0_IRQ_REG + 1));
+
+		registers_offset_config(&desc[HEVC_ASSIST_SCRATCH_0],
+			-(0x00c0 - 0x00b0),
+			(HEVC_ASSIST_SCRATCH_N - HEVC_ASSIST_SCRATCH_0) + 1);
+
+		registers_offset_config(&desc[AV1D_IPP_DIR_CFG], -(0x0490 - 0x0419), 1);
+	}
+}
+
+void t3_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs)
+{
+	registers_offset_config(&desc[AV1D_IPP_DIR_CFG], -(0x0490 - 0x0419), 1);
+}
+
+
+//###############################################################################
+ulong dos_reg_compat_convert(ulong addr)
+{
+		s32 reg_compat_offset;
+		struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+
+		if (addr & NEW_REG_CHECK_MASK) {
+			addr &= (~NEW_REG_CHECK_MASK);
+			reg_compat_offset = 0;
+		} else {
+			reg_compat_offset = dos_desc[addr].reg_compat_offset;
+		}
+
+		return (addr + reg_compat_offset);
+	}
+EXPORT_SYMBOL(dos_reg_compat_convert);
+
+void write_dos_reg(ulong addr, int val)
+{
+	void __iomem * reg_adr;
+	s32 reg_compat_offset;
+	struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+
+	if (addr & NEW_REG_CHECK_MASK) {
+		addr &= (~NEW_REG_CHECK_MASK);
+		reg_compat_offset = 0;
+	} else {
+		reg_compat_offset = dos_desc[addr].reg_compat_offset;
+	}
+
+	if ((reg_compat_offset + addr) < 0) {
+		pr_err("write dos reg out of range, name %s, addr %lx, offset %d\n",
+			dos_desc[addr].reg_name, addr, reg_compat_offset);
+		return;
+	}
+
+	reg_adr = reg_base[DOS_BUS] + ((reg_compat_offset + addr) << 2);
+
+	if (register_debug) {
+		if (register_debug & CODEC_REG_WRITE_DEBUG) {
+			pr_info("write_reg(%lx, %x)\n", (reg_compat_offset + addr), val);
+		}
+		if (register_debug & CODEC_REG_MAP_DEBUG) {
+			pr_info("%s %px, name %s, addr %lx, offset %d\n",
+				__func__, reg_adr, dos_desc[addr].reg_name, addr, reg_compat_offset);
+		}
+	}
+
+	writel(val, reg_adr);
+}
+EXPORT_SYMBOL(write_dos_reg);
+
+int read_dos_reg(ulong addr)
+{
+	void __iomem * reg_adr;
+	int value;
+	struct bus_reg_desc *dos_desc = reg_desc[DOS_BUS];
+	s32 reg_compat_offset;
+
+	if (addr & NEW_REG_CHECK_MASK) {
+		addr &= (~NEW_REG_CHECK_MASK);
+		reg_compat_offset = 0;
+	} else {
+		reg_compat_offset = dos_desc[addr].reg_compat_offset;
+	}
+
+	if ((reg_compat_offset + addr) < 0) {
+		pr_err("read dos reg out of range, name %s, addr %lx, offset %d\n",
+			dos_desc[addr].reg_name, addr, reg_compat_offset);
+		return -ENXIO;
+	}
+
+	reg_adr = reg_base[DOS_BUS] + ((reg_compat_offset + addr) << 2);
+
+	value = readl(reg_adr);
+
+	if (register_debug) {
+		if (register_debug & CODEC_REG_READ_DEBUG) {
+			pr_info("read_reg(%lx) = %x\n", (reg_compat_offset + addr), value);
+		}
+		if (register_debug & CODEC_REG_MAP_DEBUG) {
+			pr_info("%s %px, name %s, addr %lx, offset %d\n",
+				__func__, reg_adr, dos_desc[addr].reg_name, addr, reg_compat_offset);
+		}
+	}
+	return value;
+}
+EXPORT_SYMBOL(read_dos_reg);
+
+int read_dos_reg_comp(ulong addr)
+{
+	if (is_support_new_dos_dev())
+		return read_dos_reg(addr);
+	else
+		return aml_read_dosbus((uint)addr);
+}
+EXPORT_SYMBOL(read_dos_reg_comp);
+
+void write_dos_reg_comp(ulong addr, int val)
+{
+	if (is_support_new_dos_dev())
+		write_dos_reg(addr, val);
+	else
+		aml_write_dosbus((uint)addr, (uint)val);
+}
+EXPORT_SYMBOL(write_dos_reg_comp);
+
+
+void dos_reg_write_bits(unsigned int reg, u32 val, int start, int len)
+{
+	u32 to_val = read_dos_reg_comp(reg);
+	u32 mask = (((1L << (len)) - 1) << (start));
+
+	to_val &= ~mask;
+	to_val |= (val << start) & mask;
+	write_dos_reg_comp(reg, to_val);
+}
+EXPORT_SYMBOL(dos_reg_write_bits);
+
+int dos_register_probe(struct platform_device *pdev, reg_compat_func reg_compat_fn)
+{
+	u32 i;
+	struct resource res;
+	u32 res_size;
+
+	if (pdev == NULL) {
+		pr_info("no dev found, dos_register can not map\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < MAX_REG_BUS; i++) {
+		if (of_address_to_resource(pdev->dev.of_node, i, &res)) {
+			pr_err("of_address_to_resource failed\n");
+			return -EINVAL;
+		}
+
+		res_size = resource_size(&res);
+		reg_base[i] = ioremap(res.start, res_size);
+
+		pr_info("%s, res start %llx, end %llx, iomap: %px\n",
+			__func__, (unsigned long long)res.start,
+			(unsigned long long)res.end, reg_base[i]);
+
+		reg_desc[i] = (struct bus_reg_desc *)kzalloc(res_size *
+			sizeof(struct bus_reg_desc), GFP_KERNEL);
+		if (!reg_desc[i])
+			pr_err("Warn: dos regs offset table alloc failed\n");
+
+		if (reg_compat_fn)
+			reg_compat_fn(reg_desc[i], i);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(dos_register_probe);
+
+
diff --git a/drivers/common/register/register.h b/drivers/common/register/register.h
new file mode 100644
index 0000000..8ed948b
--- /dev/null
+++ b/drivers/common/register/register.h
@@ -0,0 +1,82 @@
+/*
+ * 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 _DOS_REGISTER_H_
+#define _DOS_REGISTER_H_
+
+#include <linux/platform_device.h>
+#include "../../include/regs/dos_registers.h"
+#include <linux/amlogic/media/utils/vdec_reg.h>
+
+
+typedef enum {
+	DOS_BUS,
+	MAX_REG_BUS
+} MM_BUS_ENUM;
+
+struct bus_reg_desc {
+	char const *reg_name;
+	s32 reg_compat_offset;
+};
+
+
+#define WRITE_VREG(addr, val) write_dos_reg_comp(addr, val)
+
+#define READ_VREG(addr) read_dos_reg_comp(addr)
+
+
+int read_dos_reg(ulong addr);
+void write_dos_reg(ulong addr, int val);
+void dos_reg_write_bits(unsigned int reg, u32 val, int start, int len);
+
+int read_dos_reg_comp(ulong addr);
+void write_dos_reg_comp(ulong addr, int val);
+
+
+#define WRITE_VREG_BITS(r, val, start, len) dos_reg_write_bits(r, val, start, len)
+#define CLEAR_VREG_MASK(r, mask)   write_dos_reg_comp(r, read_dos_reg_comp(r) & ~(mask))
+#define SET_VREG_MASK(r, mask)     write_dos_reg_comp(r, read_dos_reg_comp(r) | (mask))
+
+
+#define READ_HREG(r) read_dos_reg_comp((r) | 0x1000)
+#define WRITE_HREG(r, val) write_dos_reg_comp((r) | 0x1000, val)
+#define WRITE_HREG_BITS(r, val, start, len) \
+	dos_reg_write_bits((r) | 0x1000, val, start, len)
+//#define SET_HREG_MASK(r, mask) codec_set_dosbus_mask((r) | 0x1000, mask)
+//#define CLEAR_HREG_MASK(r, mask) codec_clear_dosbus_mask((r) | 0x1000, mask)
+
+//##############################################################
+
+typedef void (*reg_compat_func)(struct bus_reg_desc *, MM_BUS_ENUM bus);
+
+void t3_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs);
+void s5_mm_registers_compat(struct bus_reg_desc *desc, MM_BUS_ENUM bs);
+
+
+ulong dos_reg_compat_convert(ulong addr);
+
+void write_dos_reg(ulong addr, int val);
+
+int read_dos_reg(ulong addr);
+
+
+int dos_register_probe(struct platform_device *pdev, reg_compat_func reg_compat_fn);
+
+
+#endif
diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile
index f30c4f1..3346cef 100644
--- a/drivers/frame_provider/Makefile
+++ b/drivers/frame_provider/Makefile
@@ -1,2 +1,2 @@
 obj-y	+=	decoder/
-obj-y	+=	decoder_v4l/
+obj-${CONFIG_AMLOGIC_MEDIA_V4L_DEC}	+=	decoder_v4l/
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile
index bb0079e..0268802 100644
--- a/drivers/frame_provider/decoder/Makefile
+++ b/drivers/frame_provider/decoder/Makefile
@@ -2,12 +2,16 @@
 obj-y	+=	mpeg12/
 obj-y	+=	mpeg4/
 obj-y	+=	vc1/
-obj-y	+=	h264/
+obj-y	+=	h264_mvc/
 obj-y	+=	h264_multi/
 obj-y	+=	h265/
 obj-y	+=	vp9/
 obj-y	+=	mjpeg/
-obj-y	+=	avs/
 obj-y	+=	avs2/
 obj-y	+=	avs_multi/
 obj-y	+=	vav1/
+obj-y	+=	avs3/
+obj-y	+=	vp9_fb/
+obj-y	+=	h265_fb/
+obj-y	+=	vav1_fb/
+obj-y	+=	avs2_fb/
diff --git a/drivers/frame_provider/decoder/avs/Makefile b/drivers/frame_provider/decoder/avs/Makefile
deleted file mode 100644
index 1d56236..0000000
--- a/drivers/frame_provider/decoder/avs/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS) += amvdec_avs.o
-amvdec_avs-objs += avs.o avsp_trans.o
diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c
deleted file mode 100644
index 5869eac..0000000
--- a/drivers/frame_provider/decoder/avs/avs.c
+++ /dev/null
@@ -1,1988 +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.
- *
- */
-#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/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 "../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.h"
-#include <linux/amlogic/media/codec_mm/configs.h>
-#include "../utils/decoder_mmu_box.h"
-#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>
-
-#define DRIVER_NAME "amvdec_avs"
-#define MODULE_NAME "amvdec_avs"
-
-
-#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 I_PICTURE   0
-#define P_PICTURE   1
-#define B_PICTURE   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 VF_POOL_SIZE        32
-#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
-
-
-#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_flag;
-
-/********************************
-firmware_sel
-    0: use avsp_trans long cabac ucode;
-    1: not use avsp_trans long cabac ucode
-********************************/
-static int firmware_sel;
-static int disable_longcabac_trans = 1;
-
-static int support_user_data = 1;
-
-int avs_get_debug_flag(void)
-{
-	return debug_flag;
-}
-
-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_event_cb(int type, void *data, void *private_data);
-static int vavs_vf_states(struct vframe_states *states, void *);
-
-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
-#define WORKSPACE_SIZE		(4 * SZ_1M)
-
-#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
-
-static u32 vf_buf_num = 8;
-static u32 vf_buf_num_used;
-static u32 canvas_base = 128;
-#ifdef NV21
-	int	canvas_num = 2; /*NV21*/
-#else
-	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;
-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;
-static u32 buf_size = 32 * 1024 * 1024;
-static u32 buf_offset;
-static u32 avi_flag;
-static u32 vavs_ratio;
-static u32 pic_type;
-static u32 pts_by_offset = 1;
-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
-
-static u32 radr, rval;
-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;
-
-static struct vdec_s *vdec = NULL;
-
-#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
-
-
-static void *user_data_buffer;
-static dma_addr_t user_data_buffer_phys;
-
-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 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
-};
-
-static void set_frame_info(struct vframe_s *vf, unsigned int *duration)
-{
-	int ar = 0;
-
-	unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO);
-#ifndef USE_AVS_SEQ_INFO
-	if (vavs_amstream_dec_info.width > 0
-		&& vavs_amstream_dec_info.height > 0) {
-		vf->width = vavs_amstream_dec_info.width;
-		vf->height = vavs_amstream_dec_info.height;
-	} else
-#endif
-	{
-		vf->width = READ_VREG(AVS_PIC_WIDTH);
-		vf->height = READ_VREG(AVS_PIC_HEIGHT);
-		frame_width = vf->width;
-		frame_height = vf->height;
-		/* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/
-	}
-
-#ifndef USE_AVS_SEQ_INFO
-	if (vavs_amstream_dec_info.rate > 0)
-		*duration = 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); */
-		frame_dur = *duration;
-		schedule_work(&notify_work);
-	}
-
-	if (vavs_ratio == 0) {
-		/* always stretch to 16:9 */
-		vf->ratio_control |= (0x90 <<
-				DISP_RATIO_ASPECT_RATIO_BIT);
-	} else {
-		switch (pixel_ratio) {
-		case 1:
-			ar = (vf->height * vavs_ratio) / vf->width;
-			break;
-		case 2:
-			ar = (vf->height * 3 * vavs_ratio) / (vf->width * 4);
-			break;
-		case 3:
-			ar = (vf->height * 9 * vavs_ratio) / (vf->width * 16);
-			break;
-		case 4:
-			ar = (vf->height * 100 * vavs_ratio) / (vf->width *
-					221);
-			break;
-		default:
-			ar = (vf->height * 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;
-}
-
-
-static struct work_struct userdata_push_work;
-/*
-#define DUMP_LAST_REPORTED_USER_DATA
-*/
-static void userdata_push_do_work(struct work_struct *work)
-{
-	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(),
-			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 *)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 *)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 *)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)user_data_buffer,
-				USER_DATA_SIZE, user_data_length);
-*/
-}
-
-static void UserDataHandler(void)
-{
-	unsigned int user_data_flags;
-
-	user_data_flags = READ_VREG(AV_SCRATCH_N);
-	if (user_data_flags & (1 << 15)) {	/* data ready */
-		schedule_work(&userdata_push_work);
-	}
-}
-
-
-#ifdef HANDLE_AVS_IRQ
-static irqreturn_t vavs_isr(int irq, void *dev_id)
-#else
-static void vavs_isr(void)
-#endif
-{
-	u32 reg;
-	struct vframe_s *vf;
-	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;
-	if (debug_flag & 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);
-		}
-	}
-#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
-
-
-	UserDataHandler();
-
-	reg = READ_VREG(AVS_BUFFEROUT);
-
-	if (reg) {
-		if (debug_flag & AVS_DEBUG_PRINT)
-			pr_info("AVS_BUFFEROUT=%x\n", reg);
-		if (pts_by_offset) {
-			offset = READ_VREG(AVS_OFFSET_REG);
-			if (debug_flag & AVS_DEBUG_PRINT)
-				pr_info("AVS OFFSET=%x\n", offset);
-			if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
-				&frame_size,
-				0, &pts_us64) == 0) {
-				pts_valid = 1;
-#ifdef DEBUG_PTS
-				pts_hit++;
-#endif
-			} else {
-#ifdef DEBUG_PTS
-				pts_missed++;
-#endif
-			}
-		}
-
-		repeat_count = READ_VREG(AVS_REPEAT_COUNT);
-		if (firmware_sel == 0)
-			buffer_index =
-				((reg & 0x7) +
-				(((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
-		else
-			buffer_index =
-				((reg & 0x7) - 1) & 7;
-
-		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)
-				pts_i_missed++;
-			else
-				pts_i_hit++;
-		}
-#endif
-
-		if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
-			&& frame_width == 1920 && frame_height == 1080) {
-			force_interlaced_frame = true;
-		}
-
-		if (throw_pb_flag && picture_type != I_PICTURE) {
-
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("picture type %d throwed\n",
-					   picture_type);
-			}
-			WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index));
-		} else if (reg & INTERLACE_FLAG || force_interlaced_frame) {	/* interlace */
-			throw_pb_flag = 0;
-
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("interlace, picture type %d\n",
-					   picture_type);
-			}
-
-			if (kfifo_get(&newframe_q, &vf) == 0) {
-				pr_info
-				("fatal error, no available buffer slot.");
-				return IRQ_HANDLED;
-			}
-			set_frame_info(vf, &dur);
-			vf->bufWidth = 1920;
-			pic_type = 2;
-			if ((picture_type == I_PICTURE) && pts_valid) {
-				vf->pts = pts;
-				vf->pts_us64 = pts_us64;
-				if ((repeat_count > 1) && avi_flag) {
-					/* next_pts = pts +
-					 *   (vavs_amstream_dec_info.rate *
-					 *   repeat_count >> 1)*15/16;
-					 */
-					next_pts =
-						pts +
-						(dur * repeat_count >> 1) *
-						15 / 16;
-				} else
-					next_pts = 0;
-			} else {
-				vf->pts = next_pts;
-				if (vf->pts == 0) {
-					vf->pts_us64 = 0;
-				}
-				if ((repeat_count > 1) && avi_flag) {
-					/* vf->duration =
-					 *   vavs_amstream_dec_info.rate *
-					 *   repeat_count >> 1;
-					 */
-					vf->duration = dur * repeat_count >> 1;
-					if (next_pts != 0) {
-						next_pts +=
-							((vf->duration) -
-							 ((vf->duration) >> 4));
-					}
-				} else {
-					/* vf->duration =
-					 *   vavs_amstream_dec_info.rate >> 1;
-					 */
-					vf->duration = dur >> 1;
-					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
-			vf->canvas0Addr = vf->canvas1Addr =
-				index2canvas(buffer_index);
-			vf->type_original = vf->type;
-
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("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;
-			*/
-			vfbuf_use[buffer_index]++;
-			vf->mem_handle =
-				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);
-			ATRACE_COUNTER(MODULE_NAME, vf->pts);
-			vf_notify_receiver(PROVIDER_NAME,
-					VFRAME_EVENT_PROVIDER_VFRAME_READY,
-					NULL);
-
-			if (kfifo_get(&newframe_q, &vf) == 0) {
-				pr_info("fatal error, no available buffer slot.");
-				return IRQ_HANDLED;
-						}
-			set_frame_info(vf, &dur);
-			vf->bufWidth = 1920;
-			if (force_interlaced_frame)
-				vf->pts = 0;
-			else
-			vf->pts = next_pts;
-			if (vf->pts == 0) {
-				vf->pts_us64 = 0;
-			}
-			if ((repeat_count > 1) && avi_flag) {
-				/* vf->duration = vavs_amstream_dec_info.rate *
-				 *   repeat_count >> 1;
-				 */
-				vf->duration = dur * repeat_count >> 1;
-				if (next_pts != 0) {
-					next_pts +=
-						((vf->duration) -
-						 ((vf->duration) >> 4));
-				}
-			} else {
-				/* vf->duration = vavs_amstream_dec_info.rate
-				 *   >> 1;
-				 */
-				vf->duration = dur >> 1;
-				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
-			vf->canvas0Addr = vf->canvas1Addr =
-				index2canvas(buffer_index);
-			vf->type_original = vf->type;
-			vf->pts_us64 = 0;
-			vfbuf_use[buffer_index]++;
-			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);
-			total_frame++;
-		} else {	/* progressive */
-			throw_pb_flag = 0;
-
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("progressive picture type %d\n",
-					   picture_type);
-			}
-			if (kfifo_get(&newframe_q, &vf) == 0) {
-				pr_info
-				("fatal error, no available buffer slot.");
-				return IRQ_HANDLED;
-			}
-			set_frame_info(vf, &dur);
-			vf->bufWidth = 1920;
-			pic_type = 1;
-
-			if ((picture_type == I_PICTURE) && pts_valid) {
-				vf->pts = pts;
-				if ((repeat_count > 1) && avi_flag) {
-					/* next_pts = pts +
-					 *   (vavs_amstream_dec_info.rate *
-					 *   repeat_count)*15/16;
-					 */
-					next_pts =
-						pts +
-						(dur * repeat_count) * 15 / 16;
-				} else
-					next_pts = 0;
-			} else {
-				vf->pts = next_pts;
-				if (vf->pts == 0) {
-					vf->pts_us64 = 0;
-				}
-				if ((repeat_count > 1) && avi_flag) {
-					/* vf->duration =
-					 *   vavs_amstream_dec_info.rate *
-					 *   repeat_count;
-					 */
-					vf->duration = dur * repeat_count;
-					if (next_pts != 0) {
-						next_pts +=
-							((vf->duration) -
-							 ((vf->duration) >> 4));
-					}
-				} else {
-					/* vf->duration =
-					 *   vavs_amstream_dec_info.rate;
-					 */
-					vf->duration = dur;
-					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
-			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;
-			*/
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("buffer_index %d, canvas addr %x\n",
-					   buffer_index, vf->canvas0Addr
-					   );
-			 pr_info("PicType = %d, PTS = 0x%x\n",
-				picture_type, vf->pts);
-			}
-
-			vfbuf_use[buffer_index]++;
-			vf->mem_handle =
-				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);
-			ATRACE_COUNTER(MODULE_NAME, vf->pts);
-			vf_notify_receiver(PROVIDER_NAME,
-					VFRAME_EVENT_PROVIDER_VFRAME_READY,
-					NULL);
-			total_frame++;
-		}
-
-		/*count info*/
-		gvs->frame_dur = frame_dur;
-		vdec_count_info(gvs, 0, offset);
-
-		/* pr_info("PicType = %d, PTS = 0x%x\n",
-		 *   picture_type, vf->pts);
-		 */
-		WRITE_VREG(AVS_BUFFEROUT, 0);
-	}
-	WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
-
-#ifdef HANDLE_AVS_IRQ
-	return IRQ_HANDLED;
-#else
-	return;
-#endif
-}
-/*
- *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;
-
-	if (recover_flag)
-		return NULL;
-
-	if (kfifo_peek(&display_q, &vf))
-		return vf;
-
-	return NULL;
-
-}
-
-static struct vframe_s *vavs_vf_get(void *op_arg)
-{
-	struct vframe_s *vf;
-
-	if (recover_flag)
-		return NULL;
-
-	if (kfifo_get(&display_q, &vf))
-		return vf;
-
-	return NULL;
-
-}
-
-static void vavs_vf_put(struct vframe_s *vf, void *op_arg)
-{
-	int i;
-
-	if (recover_flag)
-		return;
-
-	for (i = 0; i < VF_POOL_SIZE; i++) {
-		if (vf == &cur_vfpool[i])
-			break;
-	}
-	if (i < VF_POOL_SIZE)
-		kfifo_put(&recycle_q, (const struct vframe_s *)vf);
-
-}
-
-static int vavs_event_cb(int type, void *data, void *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 && vdec)
-			req->req_result[0] = vdec_secure(vdec);
-		else
-			req->req_result[0] = 0xffffffff;
-	}
-
-	return 0;
-}
-
-int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
-{
-	if (!(stat & STAT_VDEC_RUN))
-		return -1;
-
-	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 = READ_VREG(AV_SCRATCH_C);
-	vstatus->status = stat;
-	vstatus->bit_rate = gvs->bit_rate;
-	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;
-}
-
-int vavs_set_isreset(struct vdec_s *vdec, int isreset)
-{
-	is_reset = isreset;
-	return 0;
-}
-
-static int vavs_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;
-}
-/****************************************/
-static int vavs_canvas_init(void)
-{
-	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;
-	u32 endian;
-
-	vf_buf_num_used = vf_buf_num;
-	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 = vf_buf_num_used + 2;
-#else
-	need_alloc_buf_num = 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(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)
-				buf_offset = buf_start -
-					RV_AI_BUFF_START_ADDR;
-			else
-				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 (vdec->canvas_mode == CANVAS_BLKMODE_LINEAR)
-			endian = 7;
-		else
-			endian = 0;
-#ifdef NV21
-			config_cav_lut_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,
-					buf_start +
-					decbuf_y_size, canvas_width,
-					canvas_height / 2,
-					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
-#else
-			config_cav_lut_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,
-					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,
-					buf_start +
-					decbuf_y_size + decbuf_uv_size,
-					canvas_width / 2, canvas_height / 2,
-					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
-#endif
-			if (debug_flag & AVS_DEBUG_PRINT) {
-				pr_info("canvas config %d, addr %p\n", i,
-					   (void *)buf_start);
-			}
-
-	}
-	return 0;
-}
-
-void vavs_recover(void)
-{
-	vavs_canvas_init();
-
-	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);
-	WRITE_VREG(AV_SCRATCH_H, 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);
-		WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode
-	}
-
-
-	if (firmware_sel == 0) {
-		/* fixed canvas index */
-		WRITE_VREG(AV_SCRATCH_0, canvas_base);
-		WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used);
-	} else {
-		int ii;
-
-		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)
-			);
-		}
-	}
-
-	/* notify ucode the buffer offset */
-	WRITE_VREG(AV_SCRATCH_F, buf_offset);
-
-	/* disable PSCALE for hardware sharing */
-	WRITE_VREG(PSCALE_CTRL, 0);
-
-	WRITE_VREG(AVS_SOS_COUNT, 0);
-	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 1				/* def DEBUG_UCODE */
-	WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
-	SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
-
-#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_N, (u32)(user_data_buffer_phys - buf_offset));
-	pr_info("support_user_data = %d\n", support_user_data);
-	if (support_user_data)
-		WRITE_VREG(AV_SCRATCH_M, 1);
-	else
-		WRITE_VREG(AV_SCRATCH_M, 0);
-
-	WRITE_VREG(AV_SCRATCH_5, 0);
-
-}
-
-static int vavs_prot_init(void)
-{
-	int r;
-#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
-
-	/***************** 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);
-	/*************************************************************/
-
-	r = vavs_canvas_init();
-	WRITE_VREG(AV_SCRATCH_H, 0);
-#ifdef NV21
-		if (firmware_sel == 0) {
-			/* fixed canvas index */
-			WRITE_VREG(AV_SCRATCH_0, canvas_base);
-			WRITE_VREG(AV_SCRATCH_1, vf_buf_num_used);
-		} else {
-			int ii;
-
-			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)
-				);
-			}
-			WRITE_VREG(AV_SCRATCH_H, 1); // 8 buf flag to ucode
-		}
-#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 */
-	WRITE_VREG(AV_SCRATCH_F, buf_offset);
-
-	/* disable PSCALE for hardware sharing */
-	WRITE_VREG(PSCALE_CTRL, 0);
-
-	WRITE_VREG(AVS_SOS_COUNT, 0);
-	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 1				/* def DEBUG_UCODE */
-	WRITE_VREG(AV_SCRATCH_D, 0);
-#endif
-
-#ifdef NV21
-	SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
-#endif
-
-#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_N, (u32)(user_data_buffer_phys - buf_offset));
-	pr_info("support_user_data = %d\n", support_user_data);
-	if (support_user_data)
-		WRITE_VREG(AV_SCRATCH_M, 1);
-	else
-		WRITE_VREG(AV_SCRATCH_M, 0);
-
-	return r;
-}
-
-#ifdef AVSP_LONG_CABAC
-static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE]  __aligned(64);
-#endif
-static void vavs_local_init(bool is_reset)
-{
-	int i;
-
-	is_reset = 0;
-	vavs_ratio = vavs_amstream_dec_info.ratio;
-
-	avi_flag = (unsigned long) vavs_amstream_dec_info.param;
-
-	frame_width = frame_height = frame_dur = frame_prog = 0;
-
-	throw_pb_flag = 1;
-
-	total_frame = 0;
-	saved_resolution = 0;
-	next_pts = 0;
-
-#ifdef DEBUG_PTS
-	pts_hit = pts_missed = pts_i_hit = pts_i_missed = 0;
-#endif
-
-	if (!is_reset) {
-		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;
-			vfpool[i].bufWidth = 1920;
-			kfifo_put(&newframe_q, vf);
-		}
-
-		for (i = 0; i < vf_buf_num; i++)
-			vfbuf_use[i] = 0;
-	}
-
-	cur_vfpool = vfpool;
-
-	if (recover_flag == 1)
-		return;
-
-	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);
-
-}
-
-static int vavs_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;
-}
-
-#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(true);
-
-	pr_info("vavs: vf_ppmgr_reset\n");
-}
-#endif
-
-static void vavs_local_reset(void)
-{
-	mutex_lock(&vavs_mutex);
-	//recover_flag = 1;
-	pr_info("error, local reset\n");
-	amvdec_stop();
-	msleep(100);
-	vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL);
-	vavs_local_init(true);
-	vavs_recover();
-
-
-	reset_userdata_fifo(1);
-
-
-	amvdec_start();
-	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);
-}
-
-static struct work_struct fatal_error_wd_work;
-static struct work_struct notify_work;
-static atomic_t error_handler_run = ATOMIC_INIT(0);
-static void vavs_fatal_error_handler(struct work_struct *work)
-{
-	if (debug_flag & 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(true);
-		vf_reg_provider(&vavs_vf_prov);
-#endif
-		vavs_recover();
-		amvdec_start();
-		mutex_unlock(&vavs_mutex);
-	} else {
-		pr_info("avs fatal_error_handler\n");
-		vavs_local_reset();
-	}
-	atomic_set(&error_handler_run, 0);
-}
-
-static void vavs_notify_work(struct work_struct *work)
-{
-	if (fr_hint_status == VDEC_NEED_HINT) {
-		vf_notify_receiver(PROVIDER_NAME ,
-			VFRAME_EVENT_PROVIDER_FR_HINT ,
-			(void *)((unsigned long)frame_dur));
-		fr_hint_status = VDEC_HINTED;
-	}
-	return;
-}
-
-static void avs_set_clk(struct work_struct *work)
-{
-		int fps = 96000 / frame_dur;
-
-		saved_resolution = frame_width * frame_height * fps;
-		if (firmware_sel == 0 &&
-			(debug_flag & AVS_DEBUG_USE_FULL_SPEED)) {
-			vdec_source_changed(VFORMAT_AVS,
-				4096, 2048, 60);
-		} else {
-			vdec_source_changed(VFORMAT_AVS,
-			frame_width, frame_height, fps);
-		}
-}
-
-static void vavs_put_timer_func(struct timer_list *timer)
-{
-#ifndef HANDLE_AVS_IRQ
-	vavs_isr();
-#endif
-
-	if (READ_VREG(AVS_SOS_COUNT)) {
-		if (!error_recovery_mode) {
-#if 0
-			if (debug_flag & 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(true);
-				vf_reg_provider(&vavs_vf_prov);
-#endif
-				vavs_recover();
-				amvdec_start();
-				mutex_unlock(&vavs_mutex);
-			} else {
-				vavs_local_reset();
-			}
-#else
-			if (!atomic_read(&error_handler_run)) {
-				atomic_set(&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(&fatal_error_wd_work);
-			}
-#endif
-		}
-	}
-#if 0
-	if (long_cabac_busy == 0 &&
-		error_watchdog_threshold > 0 &&
-		kfifo_len(&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(&newframe_q),
-			kfifo_len(&display_q),
-			kfifo_len(&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 (!kfifo_is_empty(&recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) {
-		struct vframe_s *vf;
-
-		if (kfifo_get(&recycle_q, &vf)) {
-			if ((vf->index < vf_buf_num) &&
-			 (--vfbuf_use[vf->index] == 0)) {
-				WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index));
-				vf->index = vf_buf_num;
-			}
-				kfifo_put(&newframe_q,
-						  (const struct vframe_s *)vf);
-		}
-	}
-
-	if (frame_dur > 0 && saved_resolution !=
-		frame_width * frame_height * (96000 / frame_dur))
-		schedule_work(&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;
-#ifdef PERFORMANCE_DEBUG
-	pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n",
-		__func__,
-		kfifo_len(&newframe_q),
-		kfifo_len(&display_q),
-		kfifo_len(&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(&newframe_q),
-		kfifo_len(&display_q),
-		kfifo_len(&recycle_q)
-		);
-#endif
-	if (status < 0) {
-		pr_info("transcoding error, local reset\r\n");
-		vavs_local_reset();
-	}
-
-}
-#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(void)
-{
-	int ret, size = -1;
-	char *buf = vmalloc(0x1000 * 16);
-
-	if (IS_ERR_OR_NULL(buf))
-		return -ENOMEM;
-
-	pr_info("vavs_init\n");
-
-	stat |= STAT_TIMER_INIT;
-
-	amvdec_enable();
-	vavs_local_init(false);
-
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
-		size = get_firmware_data(VIDEO_DEC_AVS, buf);
-	else {
-		if (firmware_sel == 1)
-			size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, buf);
-#ifdef AVSP_LONG_CABAC
-		else {
-			init_avsp_long_cabac_buf();
-			size = get_firmware_data(VIDEO_DEC_AVS, buf);
-		}
-#endif
-	}
-
-	if (size < 0) {
-		amvdec_disable();
-		pr_err("get firmware fail.");
-		vfree(buf);
-		return -1;
-	}
-
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM)
-		ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf);
-	else if (firmware_sel == 1)
-		ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", buf);
-	else
-		ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf);
-
-	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);
-
-	stat |= STAT_MC_LOAD;
-
-	/* enable AMRISC side protocol */
-	ret = vavs_prot_init();
-	if (ret < 0)
-		return ret;
-
-#ifdef HANDLE_AVS_IRQ
-	if (vdec_request_irq(VDEC_IRQ_1, vavs_isr,
-			"vavs-irq", (void *)vavs_dec_id)) {
-		amvdec_disable();
-		pr_info("vavs irq register error.\n");
-		return -ENOENT;
-	}
-#endif
-
-	stat |= STAT_ISR_REG;
-
-#ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
-	vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL);
-	vf_reg_provider(&vavs_vf_prov);
-	vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
-#else
-	vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, NULL);
-	vf_reg_provider(&vavs_vf_prov);
-#endif
-
-	if (vavs_amstream_dec_info.rate != 0) {
-		if (!is_reset) {
-			vf_notify_receiver(PROVIDER_NAME,
-					VFRAME_EVENT_PROVIDER_FR_HINT,
-					(void *)((unsigned long)
-					vavs_amstream_dec_info.rate));
-			fr_hint_status = VDEC_HINTED;
-		}
-	} else
-		fr_hint_status = VDEC_NEED_HINT;
-
-	stat |= STAT_VF_HOOK;
-
-	timer_setup(&recycle_timer, vavs_put_timer_func, 0);
-	recycle_timer.expires = jiffies + PUT_INTERVAL;
-	add_timer(&recycle_timer);
-
-	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);
-	amvdec_start();
-
-	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;
-
-	if (pdata == NULL) {
-		pr_info("amvdec_avs memory resource undefined.\n");
-		return -EFAULT;
-	}
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
-		firmware_sel = 1;
-
-	if (firmware_sel == 1) {
-		vf_buf_num = 8;
-		canvas_base = 0;
-		canvas_num = 2;
-	} else {
-
-		canvas_base = 128;
-		canvas_num = 2; /*NV21*/
-	}
-
-
-	if (pdata->sys_info)
-		vavs_amstream_dec_info = *pdata->sys_info;
-
-	pr_info("%s (%d,%d) %d\n", __func__, vavs_amstream_dec_info.width,
-		   vavs_amstream_dec_info.height, vavs_amstream_dec_info.rate);
-
-	pdata->dec_status = vavs_dec_status;
-	pdata->set_isreset = vavs_set_isreset;
-	is_reset = 0;
-
-	pdata->user_data_read = NULL;
-	pdata->reset_userdata_fifo = NULL;
-
-	vavs_vdec_info_init();
-
-
-	if (NULL == user_data_buffer) {
-		user_data_buffer =
-			dma_alloc_coherent(amports_get_dma_device(),
-				USER_DATA_SIZE,
-				&user_data_buffer_phys, GFP_KERNEL);
-		if (!user_data_buffer) {
-			pr_info("%s: Can not allocate user_data_buffer\n",
-				   __func__);
-			return -ENOMEM;
-		}
-		pr_debug("user_data_buffer = 0x%p, user_data_buffer_phys = 0x%x\n",
-			user_data_buffer, (u32)user_data_buffer_phys);
-	}
-
-	INIT_WORK(&set_clk_work, avs_set_clk);
-	vdec = pdata;
-
-	INIT_WORK(&fatal_error_wd_work, vavs_fatal_error_handler);
-	atomic_set(&error_handler_run, 0);
-
-	INIT_WORK(&userdata_push_work, userdata_push_do_work);
-	INIT_WORK(&notify_work, vavs_notify_work);
-
-	if (vavs_init() < 0) {
-		pr_info("amvdec_avs init failed.\n");
-		kfree(gvs);
-		gvs = NULL;
-		pdata->dec_status = NULL;
-		return -ENODEV;
-	}
-	return 0;
-}
-
-static int amvdec_avs_remove(struct platform_device *pdev)
-{
-	if (stat & STAT_TIMER_ARM) {
-		del_timer_sync(&recycle_timer);
-		stat &= ~STAT_TIMER_ARM;
-	}
-	cancel_work_sync(&fatal_error_wd_work);
-	atomic_set(&error_handler_run, 0);
-
-	cancel_work_sync(&userdata_push_work);
-
-	cancel_work_sync(&notify_work);
-	if (stat & STAT_VDEC_RUN) {
-		amvdec_stop();
-		stat &= ~STAT_VDEC_RUN;
-	}
-
-	if (stat & STAT_ISR_REG) {
-		vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id);
-		stat &= ~STAT_ISR_REG;
-	}
-
-#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 (stat & STAT_VF_HOOK) {
-		if (fr_hint_status == VDEC_HINTED)
-			vf_notify_receiver(PROVIDER_NAME,
-				VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL);
-		fr_hint_status = VDEC_NO_NEED_HINT;
-		vf_unreg_provider(&vavs_vf_prov);
-		stat &= ~STAT_VF_HOOK;
-	}
-
-
-	if (user_data_buffer != NULL) {
-		dma_free_coherent(
-			amports_get_dma_device(),
-			USER_DATA_SIZE,
-			user_data_buffer,
-			user_data_buffer_phys);
-		user_data_buffer = NULL;
-		user_data_buffer_phys = 0;
-	}
-
-
-	amvdec_disable();
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TM2)
-		vdec_reset_core(NULL);
-	pic_type = 0;
-	if (mm_blk_handle) {
-		decoder_bmmu_box_free(mm_blk_handle);
-		mm_blk_handle = NULL;
-	}
-#ifdef DEBUG_PTS
-	pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", pts_hit,
-		   pts_missed, pts_i_hit, pts_i_missed);
-	pr_debug("total frame %d, avi_flag %d, rate %d\n", total_frame, avi_flag,
-		   vavs_amstream_dec_info.rate);
-#endif
-	kfree(gvs);
-	gvs = NULL;
-	vdec = NULL;
-
-	cancel_work_sync(&set_clk_work);
-	return 0;
-}
-
-/****************************************/
-#ifdef CONFIG_PM
-static int avs_suspend(struct device *dev)
-{
-	amvdec_suspend(to_platform_device(dev), dev->power.power_state);
-	return 0;
-}
-
-static int avs_resume(struct device *dev)
-{
-	amvdec_resume(to_platform_device(dev));
-	return 0;
-}
-
-static const struct dev_pm_ops avs_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(avs_suspend, avs_resume)
-};
-#endif
-
-static struct platform_driver amvdec_avs_driver = {
-	.probe = amvdec_avs_probe,
-	.remove = amvdec_avs_remove,
-	.driver = {
-		.name = DRIVER_NAME,
-#ifdef CONFIG_PM
-		.pm = &avs_pm_ops,
-#endif
-	}
-};
-
-static struct codec_profile_t amvdec_avs_profile = {
-	.name = "avs",
-	.profile = ""
-};
-
-static struct mconfig avs_configs[] = {
-	MC_PU32("stat", &stat),
-	MC_PU32("debug_flag", &debug_flag),
-	MC_PU32("error_recovery_mode", &error_recovery_mode),
-	MC_PU32("pic_type", &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 avs_node;
-
-
-static int __init amvdec_avs_driver_init_module(void)
-{
-	pr_debug("amvdec_avs module init\n");
-
-	if (platform_driver_register(&amvdec_avs_driver)) {
-		pr_info("failed to register amvdec_avs driver\n");
-		return -ENODEV;
-	}
-
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB)
-		amvdec_avs_profile.profile = "avs+";
-
-	vcodec_profile_register(&amvdec_avs_profile);
-	INIT_REG_NODE_CONFIGS("media.decoder", &avs_node,
-		"avs", avs_configs, CONFIG_FOR_RW);
-	return 0;
-}
-
-static void __exit amvdec_avs_driver_remove_module(void)
-{
-	pr_debug("amvdec_avs module remove.\n");
-
-	platform_driver_unregister(&amvdec_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(debug_flag, uint, 0664);
-MODULE_PARM_DESC(debug_flag, "\n debug_flag\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(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(support_user_data, uint, 0664);
-MODULE_PARM_DESC(support_user_data, "\n support_user_data\n");
-
-module_init(amvdec_avs_driver_init_module);
-module_exit(amvdec_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/avs/avs.h b/drivers/frame_provider/decoder/avs/avs.h
deleted file mode 100644
index 8277d20..0000000
--- a/drivers/frame_provider/decoder/avs/avs.h
+++ /dev/null
@@ -1,91 +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_UCODE         0x02
-#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/avs/avsp_trans.c b/drivers/frame_provider/decoder/avs/avsp_trans.c
deleted file mode 100644
index a92dbb9..0000000
--- a/drivers/frame_provider/decoder/avs/avsp_trans.c
+++ /dev/null
@@ -1,5065 +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/types.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timer.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.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/dma-mapping.h>
-#include <linux/amlogic/media/codec_mm/codec_mm.h>
-#include <linux/slab.h>
-/* #include <mach/am_regs.h> */
-#include <linux/module.h>
-#include <linux/amlogic/media/utils/vdec_reg.h>
-#include "../../../stream_input/amports/streambuf_reg.h"
-#include "../utils/amvdec.h"
-#include <linux/amlogic/media/registers/register.h>
-#include "../../../stream_input/amports/amports_priv.h"
-
-#include "avs.h"
-#ifdef AVSP_LONG_CABAC
-
-#define DECODING_SANITY_CHECK
-
-#define TRACE 0
-#define LIWR_FIX 0
-#define pow2(a, b) (1<<b)
-#define io_printf pr_info
-
-static unsigned char *local_heap_adr;
-static int local_heap_size;
-static int local_heap_pos;
-static int transcoding_error_flag;
-
-unsigned char *local_alloc(int num, int size)
-{
-	unsigned char *ret_buf = NULL;
-	int alloc_size = num * size;
-
-	if ((local_heap_pos + alloc_size) <= local_heap_size) {
-		ret_buf = local_heap_adr + local_heap_pos;
-		local_heap_pos += alloc_size;
-	} else {
-		pr_info(
-				"!!!local_alloc(%d) error, local_heap (size %d) is not enough\r\n",
-				alloc_size, local_heap_size);
-	}
-	return ret_buf;
-}
-
-int local_heap_init(int size)
-{
-	/*local_heap_adr = &local_heap[0];*/
-	local_heap_adr = (unsigned char *)(avsp_heap_adr +
-	MAX_CODED_FRAME_SIZE);
-	memset(local_heap_adr, 0, LOCAL_HEAP_SIZE);
-
-	local_heap_size = LOCAL_HEAP_SIZE;
-	local_heap_pos = 0;
-	return 0;
-}
-
-void local_heap_uninit(void)
-{
-	local_heap_adr = NULL;
-	local_heap_size = 0;
-	local_heap_pos = 0;
-}
-
-#define CODE2D_ESCAPE_SYMBOL 59
-
-const int vlc_golomb_order[3][7][2] =
-
-{{{2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{3, 9}, {2, 9}, {
-		2, 9}, {2, 9}, {2, 9}, {2, 9}, {2, 9}, }, {{2, 9}, {0, 9},
-		{1, 9}, {1, 9}, {0, 9}, {-1, -1}, {-1, -1}, }, };
-
-const int MaxRun[3][7] = {{22, 14, 9, 6, 4, 2, 1}, {25, 18, 13, 9, 6, 4, 3}, {
-		24, 19, 10, 7, 4, -1, -1} };
-
-const int refabslevel[19][26] = {{4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-		2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1}, {7, 4, 4, 3, 3, 3, 3, 3, 2,
-		2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
-		10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4, 3, 2, 2, -1, -1,
-		-1 - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1}, {18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {22, 7, 3, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1}, {27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {4,
-		3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-		2, 2, 2, 2}, {5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-		2, 2, -1, -1, -1, -1, -1, -1, -1}, {7, 5, 4, 4, 3, 3, 3, 2, 2,
-		2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
-		{10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1}, {13, 7, 5, 4,
-				3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1}, {17, 8, 4,
-				3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
-				22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1}, {5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-				2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1}, {6, 4, 3,
-				3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-				2, -1, -1, -1, -1, -1, -1}, {10, 6, 4, 4, 3, 3,
-				2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1}, {14, 7, 4, 3, 3, 2,
-				2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1}, {20, 7, 3, 2,
-				2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} };
-
-static const int incvlc_intra[7] = {0, 1, 2, 4, 7, 10, 3000};
-static const int incvlc_chroma[5] = {0, 1, 2, 4, 3000};
-
-const int AVS_2DVLC_INTRA[7][26][27] = {{{0, 22, 38, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1}, {2, 32, -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}, {4, 44, -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}, {6, 50, -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}, {8, 54, -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}, {10, -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}, {12, -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}, {14, -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}, {16, -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}, {18, -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}, {20, -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}, {24, -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}, {26, -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}, {28, -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}, {30, -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}, {34, -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}, {36, -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}, {40, -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}, {42, -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}, {46, -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}, {48, -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}, {52, -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}, {56, -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, -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}, }, {{8, 0, 4, 15, 27, 41,
-		55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1}, {-1, 2, 17, 35, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
-		{-1, 6, 25, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
-				-1, 9, 33, -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, 11, 39, -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, 13, 45, -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, 19, 49, -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, 21, 51, -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, 23, -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, 29, -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, 31, -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, 37, -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, 43, -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, 47, -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, 57, -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, -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, -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, -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, -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, -1, -1}, }, {{8, 0, 2, 6,
-		13, 17, 27, 35, 45, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1}, {-1, 4, 11, 21, 33, 49, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1}, {-1, 9, 23, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 15,
-		29, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 19, 39, -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, 25, 43, -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, 31, 53, -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, 41,
-		-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, 47, -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, 57, -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, -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, -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, -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, -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, -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, -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, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1}, }, {{8, 0, 2, 4, 9, 11, 17, 21, 25, 33, 39, 45, 55, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 6, 13, 19,
-		29, 35, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1}, {-1, 15, 27, 41, 57, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1}, {-1, 23, 37, 53, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
-		-1, 31, 51, -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, 43, -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, 49, -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, -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, -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, -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, -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, -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, -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, -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, -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}, }, {{6, 0, 2, 4, 7, 9, 11, 15, 17,
-		21, 23, 29, 33, 35, 43, 47, 49, 57, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1}, {-1, 13, 19, 27, 31, 37, 45, 55, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
-		25, 41, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1, 39, -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, 53, -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, -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, -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,
-		-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, -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, -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, -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, -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, -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, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, }, {{0,
-		1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 27, 31, 33, 37, 41,
-		45, 49, 51, 55, -1, -1, -1, -1, -1}, {-1, 21, 29, 35, 43, 47,
-		53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1}, {-1, 39, 57, -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, -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, -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,
-		-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, -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, -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, -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, -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, -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, -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,
-		-1, -1, -1, -1, -1}, }, {{0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19,
-		21, 23, 25, 27, 29, 31, 35, 37, 39, 41, 43, 47, 49, 51, 53, 57},
-		{-1, 33, 45, 55, -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, -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,
-				-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, -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, -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}, {-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, -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, -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, -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, -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, -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} } };
-
-const int AVS_2DVLC_CHROMA[5][26][27] = {{{0, 14, 32, 56, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1}, {2, 48, -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}, {4, -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}, {6, -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}, {8, -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}, {10,
-		-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}, {12, -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}, {16, -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}, {18, -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}, {20,
-		-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}, {22, -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}, {24, -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}, {26, -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}, {28,
-		-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}, {30, -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}, {34, -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}, {36, -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}, {38,
-		-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}, {40, -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}, {42, -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}, {44, -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}, {46,
-		-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}, {50, -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}, {52, -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}, {54, -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}, }, {{0, 1, 5, 15, 29,
-		43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1}, {-1, 3, 21, 45, -1, -1, -1, -1, -1, -1,
-		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-		-1}, {-1, 7, 37, -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, 9, 41, -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, 11, 53, -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, 13, -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, 17, -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, 19, -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, 23, -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, 25, -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, 27, -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, 31, -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, 33, -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, 35, -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, 39, -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, 47, -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, 49, -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, 51, -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, 55, -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, 57, -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,
-		-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, -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}, },
-		{{2, 0, 3, 7, 11, 17, 27, 33, 47, 53, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {
-				-1, 5, 13, 21, 37, 55, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1}, {-1, 9, 23, 41, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1}, {-1, 15, 31, 57, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, {-1,
-				19, 43, -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, 25, 45, -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, 29, -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,
-				35, -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, 39, -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, 49, -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,
-				51, -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, -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, -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, -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, -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, -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, -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}, }, {{0, 1, 3, 5, 7, 11, 15, 19, 23, 29,
-				35, 43, 47, 53, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1}, {-1, 9, 13, 21, 31, 39, 51,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1}, {-1, 17, 27,
-				37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
-				{-1, 25, 41, -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, 33, 55, -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, 45, -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, 49, -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, 57, -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,
-						-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, -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, -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, -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, -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, -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, -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}, },
-		{{0, 1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 23, 27, 29, 33, 37, 41,
-				43, 51, 55, -1, -1, -1, -1, -1, -1, -1}, {-1,
-				17, 25, 31, 39, 45, 53, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1}, {-1, 35, 49, -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, 47, -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,
-				57, -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, -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, -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, -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, -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, -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, -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, -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, -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, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1}, } };
-
-const int UE[64][2] = {{1, 1}, {2, 3}, {3, 3}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {
-		8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15,
-		7}, {16, 9}, {17, 9}, {18, 9}, {19, 9}, {20, 9}, {21, 9},
-		{22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {
-				29, 9}, {30, 9}, {31, 9}, {32, 11}, {33, 11}, {
-				34, 11}, {35, 11}, {36, 11}, {37, 11}, {38, 11},
-		{39, 11}, {40, 11}, {41, 11}, {42, 11}, {43, 11}, {44, 11}, {45,
-				11}, {46, 11}, {47, 11}, {48, 11}, {49, 11}, {
-				50, 11}, {51, 11}, {52, 11}, {53, 11}, {54, 11},
-		{55, 11}, {56, 11}, {57, 11}, {58, 11}, {59, 11}, {60, 11}, {61,
-				11}, {62, 11}, {63, 11}, {64, 13} };
-
-unsigned int src_start;
-unsigned int des_start;
-
-#ifdef AVSP_LONG_CABAC
-
-unsigned char *es_buf;
-unsigned int es_buf_ptr;
-unsigned int es_buf_is_overflow;
-
-#else
-FILE *f_es;
-#endif
-unsigned int es_ptr;
-unsigned int es_res;
-unsigned int es_res_ptr;
-unsigned int previous_es;
-
-void init_es(void)
-{
-
-#ifdef AVSP_LONG_CABAC
-	es_buf_is_overflow = 0;
-
-	es_buf[0] = 0x00;
-	es_buf[1] = 0x00;
-	es_buf[2] = 0x01;
-	es_buf_ptr = 3;
-	es_ptr = 3;
-#else
-	f_es = fopen("es.out", "wb");
-	if (f_es == NULL)
-		io_printf(" ERROR : Can not open es.out for write\n");
-	putc(0x00, f_es);
-	putc(0x00, f_es);
-	putc(0x01, f_es);
-
-	es_ptr = 3;
-#endif
-	es_res = 0;
-	es_res_ptr = 0;
-	previous_es = 0xff;
-
-}
-
-void push_es(int value, int num)
-{
-	unsigned char wr_es_data;
-	int push_num;
-	int push_value;
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & ES_DUMP)
-		io_printf(" push_es : value : 0x%x, num : %d\n", value, num);
-#endif
-	while (num > 0) {
-		if (num >= 8)
-			push_num = 8;
-		else
-			push_num = num;
-
-		num = num - push_num;
-		push_value = (value >> num);
-
-		es_res = (es_res << push_num) | push_value;
-		es_res_ptr = es_res_ptr + push_num;
-
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & ES_DUMP)
-			io_printf(" #### es_res : 0x%X, es_res_ptr : %d\n",
-				es_res, es_res_ptr);
-#endif
-
-		while (es_res_ptr >= 8) {
-			es_res_ptr = es_res_ptr & 7;
-			wr_es_data = (es_res >> es_res_ptr) & 0xff;
-			if ((previous_es == 0) & (wr_es_data < 4)) {
-				io_printf(
-						" Insert 2'b10 for emu at position : %d\n",
-						es_ptr);
-
-				es_res_ptr = es_res_ptr + 2;
-				wr_es_data = 2;
-			}
-#ifdef AVSP_LONG_CABAC
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & ES_DUMP)
-				pr_info("es_buf[%d] = 0x%02x\r\n",
-					es_buf_ptr, wr_es_data);
-#endif
-			if (!es_buf_is_overflow) {
-				es_buf[es_buf_ptr++] = wr_es_data;
-				if (es_buf_ptr >= MAX_CODED_FRAME_SIZE)
-					es_buf_is_overflow = 1;
-			}
-#else
-			putc(wr_es_data, f_es);
-#endif
-			es_ptr++;
-			previous_es = ((previous_es << 8) | wr_es_data)
-					& 0xffff;
-		}
-
-	}
-}
-
-#ifdef BLOCK_SIZE
-#undef BLOCK_SIZE
-#endif
-
-#define MIN_QP          0
-#define MAX_QP          63
-
-#define BLOCK_SIZE      4
-#define B8_SIZE         8
-#define MB_BLOCK_SIZE   16
-
-#define BLOCK_MULTIPLE      (MB_BLOCK_SIZE/(BLOCK_SIZE*2))
-
-#define DECODE_COPY_MB  0
-#define DECODE_MB       1
-
-#define NO_INTRA_PMODE  5
-#define INTRA_PMODE_4x4   10
-#define NO_INTRA_PMODE_4x4	19
-/* 8x8 intra prediction modes */
-#define VERT_PRED             0
-#define HOR_PRED              1
-#define DC_PRED               2
-#define DOWN_LEFT_PRED   3
-#define DOWN_RIGHT_PRED  4
-
-#define VERT_PRED_4x4   0
-#define HOR_PRED_4x4	1
-#define DC_PRED_4x4		2
-#define DOWN_LEFT_PRED_4x4	3
-#define DOWN_RIGHT_PRED_4x4	4
-
-#define HOR_DOWN_PRED_4x4		5
-#define VERT_LEFT_PRED_4x4	6
-#define HOR_UP_PRED_4x4	   7
-#define VERT_RIGHT_PRED_4x4	8
-
-#define DC_PRED_8       0
-#define HOR_PRED_8      1
-#define VERT_PRED_8     2
-#define PLANE_8         3
-
-#define LUMA_16DC       0
-#define LUMA_16AC       1
-#define LUMA_8x8        2
-#define LUMA_8x4        3
-#define LUMA_4x8        4
-#define LUMA_4x4        5
-#define CHROMA_DC       6
-#define CHROMA_AC       7
-#define NUM_BLOCK_TYPES 8
-
-#define I_PICTURE_START_CODE    0xB3
-#define PB_PICTURE_START_CODE   0xB6
-#define SLICE_START_CODE_MIN    0x00
-#define SLICE_START_CODE_MAX    0xAF
-#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 EOS             1
-#define SOP             2
-#define SOS             3
-#define P8x8    8
-#define I8MB    9
-#define I4MB   10
-#define IBLOCK  11
-#define SI4MB   12
-#define MAXMODE 13
-
-#define IS_INTRA(MB)    ((MB)->mb_type == I8MB  || (MB)->mb_type == I4MB)
-#define IS_NEWINTRA(MB) ((MB)->mb_type == I4MB)
-#define IS_OLDINTRA(MB) ((MB)->mb_type == I8MB)
-#define IS_INTER(MB)    ((MB)->mb_type != I8MB  && (MB)->mb_type != I4MB)
-#define IS_INTERMV(MB)  ((MB)->mb_type != I8MB  && (MB)->mb_type != I4MB\
-	&& (MB)->mb_type != 0)
-
-#define IS_DIRECT(MB)   ((MB)->mb_type == 0     && (img->type == B_IMG))
-#define IS_COPY(MB)     ((MB)->mb_type == 0     && (img->type == P_IMG))
-#define IS_P8x8(MB)     ((MB)->mb_type == P8x8)
-
-#define P_IMG     0
-#define B_IMG     1
-#define I_IMG     2
-
-#define FIELD     0
-#define FRAME     1
-
-#define SE_CABP    21
-struct decoding_environment_s {
-	unsigned int dbuffer;
-	int dbits_to_go;
-	unsigned char *dcodestrm;
-	int *dcodestrm_len;
-};
-
-struct bi_context_type_s {
-	unsigned char MPS;
-	unsigned int LG_PMPS;
-	unsigned char cycno;
-};
-
-
-/**********************************************************************
- * C O N T E X T S   F O R   R M   S Y N T A X   E L E M E N T S
- **********************************************************************
- */
-
-#define NUM_MB_TYPE_CTX  11
-#define NUM_B8_TYPE_CTX  9
-#define NUM_MV_RES_CTX   10
-#define NUM_REF_NO_CTX   6
-#define NUM_DELTA_QP_CTX 4
-#define NUM_MB_AFF_CTX 4
-
-struct motion_info_contexts_s {
-	struct bi_context_type_s mb_type_contexts[4][NUM_MB_TYPE_CTX];
-	struct bi_context_type_s b8_type_contexts[2][NUM_B8_TYPE_CTX];
-	struct bi_context_type_s mv_res_contexts[2][NUM_MV_RES_CTX];
-	struct bi_context_type_s ref_no_contexts[2][NUM_REF_NO_CTX];
-	struct bi_context_type_s delta_qp_contexts[NUM_DELTA_QP_CTX];
-	struct bi_context_type_s mb_aff_contexts[NUM_MB_AFF_CTX];
-#ifdef TEST_WEIGHTING_AEC
-struct bi_context_type_s mb_weighting_pred;
-#endif
-};
-
-#define NUM_IPR_CTX    2
-#define NUM_CIPR_CTX   4
-#define NUM_CBP_CTX    4
-#define NUM_BCBP_CTX   4
-#define NUM_MAP_CTX   16
-#define NUM_LAST_CTX  16
-
-#define NUM_ONE_CTX    5
-#define NUM_ABS_CTX    5
-
-struct texture_info_contexts {
-	struct bi_context_type_s ipr_contexts[NUM_IPR_CTX];
-	struct bi_context_type_s cipr_contexts[NUM_CIPR_CTX];
-	struct bi_context_type_s cbp_contexts[3][NUM_CBP_CTX];
-	struct bi_context_type_s bcbp_contexts[NUM_BLOCK_TYPES][NUM_BCBP_CTX];
-	struct bi_context_type_s one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX];
-	struct bi_context_type_s abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX];
-	struct bi_context_type_s fld_map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
-	struct bi_context_type_s fld_last_contexts
-	[NUM_BLOCK_TYPES][NUM_LAST_CTX];
-	struct bi_context_type_s map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
-	struct bi_context_type_s last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
-};
-struct img_par;
-
-struct syntaxelement {
-	int type;
-	int value1;
-	int value2;
-	int len;
-	int inf;
-	unsigned int bitpattern;
-	int context;
-	int k;
-	int golomb_grad;
-	int golomb_maxlevels;
-#if TRACE
-#define       TRACESTRING_SIZE 100
-	char tracestring[TRACESTRING_SIZE];
-#endif
-
-	void (*mapping)(int len, int info, int *value1, int *value2);
-
-	void (*reading)(struct syntaxelement *, struct img_par *,
-			struct decoding_environment_s *);
-
-};
-
-struct bitstream_s {
-
-	int read_len;
-	int code_len;
-
-	int frame_bitoffset;
-	int bitstream_length;
-
-	unsigned char *stream_buffer;
-};
-
-struct datapartition {
-
-	struct bitstream_s *bitstream;
-	struct decoding_environment_s de_aec;
-
-	int (*read_syntax_element)(struct syntaxelement *, struct img_par *,
-			struct datapartition *);
-/*!< virtual function;
- * actual method depends on chosen data partition and
- * entropy coding method
- */
-};
-
-struct slice_s {
-	int picture_id;
-	int qp;
-	int picture_type;
-	int start_mb_nr;
-	int max_part_nr;
-	int num_mb;
-
-	struct datapartition *part_arr;
-	struct motion_info_contexts_s *mot_ctx;
-	struct texture_info_contexts *tex_ctx;
-	int field_ctx[3][2];
-};
-
-struct img_par {
-	int number;
-	int current_mb_nr;
-	int max_mb_nr;
-	int current_slice_nr;
-	int tr;
-	int qp;
-	int type;
-
-	int typeb;
-
-	int width;
-	int height;
-	int width_cr;
-	int height_cr;
-	int source_bitdepth;
-	int mb_y;
-	int mb_x;
-	int block_y;
-	int pix_y;
-	int pix_x;
-	int pix_c_y;
-	int block_x;
-	int pix_c_x;
-
-	int ***mv;
-	int mpr[16][16];
-
-	int m7[16][16];
-	int m8[/*2*/4][8][8];
-	int cof[4][/*6*/8][4][4];
-	int cofu[4];
-	int **ipredmode;
-	int quad[256];
-	int cod_counter;
-
-	int ***dfmv;
-	int ***dbmv;
-	int **fw_reffrarr;
-	int **bw_reffrarr;
-
-	int ***mv_frm;
-	int **fw_reffrarr_frm;
-	int **bw_reffrarr_frm;
-	int imgtr_next_p;
-	int imgtr_last_p;
-	int tr_frm;
-	int tr_fld;
-	int imgtr_last_prev_p;
-
-	int no_forward_reference;
-	int seq_header_indicate;
-	int b_discard_flag;
-
-	int ***fw_mv;
-	int ***bw_mv;
-	int subblock_x;
-	int subblock_y;
-
-	int buf_cycle;
-
-	int direct_type;
-
-	int ***mv_top;
-	int ***mv_bot;
-	int **fw_reffrarr_top;
-	int **bw_reffrarr_top;
-	int **fw_reffrarr_bot;
-	int **bw_reffrarr_bot;
-
-	int **ipredmode_top;
-	int **ipredmode_bot;
-	int ***fw_mv_top;
-	int ***fw_mv_bot;
-	int ***bw_mv_top;
-	int ***bw_mv_bot;
-	int ***dfmv_top;
-	int ***dbmv_top;
-	int ***dfmv_bot;
-	int ***dbm_bot;
-
-	int toppoc;
-	int bottompoc;
-	int framepoc;
-	unsigned int frame_num;
-
-	unsigned int pic_distance;
-	int delta_pic_order_cnt_bottom;
-
-	signed int pic_distance_msb;
-	unsigned int prev_pic_distance_lsb;
-	signed int curr_pic_distance_msb;
-	unsigned int this_poc;
-
-	int pic_width_inmbs;
-	int pic_height_inmbs;
-	int pic_size_inmbs;
-
-	int block8_x, block8_y;
-	int structure;
-	int pn;
-	int buf_used;
-	int buf_size;
-	int picture_structure;
-	int advanced_pred_mode_disable;
-	int types;
-	int current_mb_nr_fld;
-
-	int p_field_enhanced;
-	int b_field_enhanced;
-
-	int slice_weighting_flag;
-	int lum_scale[4];
-	int lum_shift[4];
-	int chroma_scale[4];
-	int chroma_shift[4];
-	int mb_weighting_flag;
-	int weighting_prediction;
-	int mpr_weight[16][16];
-	int top_bot;
-	int bframe_number;
-
-	int auto_crop_right;
-	int auto_crop_bottom;
-
-	struct slice_s *current_slice;
-	int is_v_block;
-	int is_intra_block;
-
-	int new_seq_header_flag;
-	int new_sequence_flag;
-	int last_pic_bbv_delay;
-
-	int sequence_end_flag;
-	int is_top_field;
-
-	int abt_flag;
-	int qp_shift;
-
-#ifdef EIGHTH
-int eighth_subpixel_flag;
-int subpixel_precision;
-int unit_length;
-int subpixel_mask;
-
-int max_mvd;
-int min_mvd;
-#endif
-
-};
-
-struct macroblock {
-	int qp;
-	int slice_nr;
-	int delta_quant;
-	struct macroblock *mb_available[3][3];
-	/*!< pointer to neighboring MBs in a 3x3 window of current MB,
-	 *which is located at [1][1]
-	 * NULL pointer identifies neighboring MBs which are unavailable
-	 */
-
-	int mb_type;
-	int mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];
-	int cbp, cbp_blk, cbp01;
-	unsigned long cbp_bits;
-
-	int b8mode[4];
-	int b8pdir[4];
-	int mb_type_2;
-	int c_ipred_mode_2;
-	int dct_mode;
-
-	int c_ipred_mode;
-	int lf_disable;
-	int lf_alpha_c0_offset;
-	int lf_beta_offset;
-
-	int CABT[4];
-	int CABP[4];
-	int cbp_4x4[4];
-
-	int skip_flag;
-
-	struct macroblock *mb_available_up;
-	struct macroblock *mb_available_left;
-	unsigned int mbaddr_a, mbaddr_b, mbaddr_c, mbaddr_d;
-	unsigned int mbavail_a, mbavail_b, mbavail_c, mbavail_d;
-
-};
-
-struct macroblock *mb_data;
-
-struct img_par *img;
-
-struct bitstream_s *curr_stream;
-
-struct datapartition *alloc_partition(int n);
-
-unsigned int vld_mem_start_addr;
-unsigned int vld_mem_end_addr;
-
-int marker_bit;
-
-int progressive_sequence;
-int horizontal_size;
-int vertical_size;
-
-int second_ifield;
-int pre_img_type;
-
-/* slice_header() */
-int slice_vertical_position;
-int slice_vertical_position_extension;
-int fixed_picture_qp;
-int fixed_slice_qp;
-int slice_qp;
-
-/*
- *************************************************************************
- * Function:ue_v, reads an u(v) syntax element, the length in bits is stored in
- the global UsedBits variable
- * Input:
- tracestring
- the string for the trace file
- bitstream
- the stream to be read from
- * Output:
- * Return: the value of the coded syntax element
- * Attention:
- *************************************************************************
- */
-/*!
- *  definition of AVS syntaxelements
- *  order of elements follow dependencies for picture reconstruction
- */
-/*!
- * \brief   Assignment of old TYPE partition elements to new
- *          elements
- *
- *  old element     | new elements
- *  TYPE_HEADER     | SE_HEADER, SE_PTYPE
- *  TYPE_MBHEADER    | SE_MBTYPE, SE_REFFRAME, SE_INTRAPREDMODE
- *  TYPE_MVD        | SE_MVD
- *  TYPE_CBP        | SE_CBP_INTRA, SE_CBP_INTER * SE_DELTA_QUANT_INTER
- *  SE_DELTA_QUANT_INTRA
- *  TYPE_COEFF_Y    | SE_LUM_DC_INTRA, SE_LUM_AC_INTRA,
-    SE_LUM_DC_INTER, SE_LUM_AC_INTER
- *  TYPE_2x2DC      | SE_CHR_DC_INTRA, SE_CHR_DC_INTER
- *  TYPE_COEFF_C    | SE_CHR_AC_INTRA, SE_CHR_AC_INTER
- *  TYPE_EOS        | SE_EOS
- */
-
-#define SE_HEADER           0
-#define SE_PTYPE            1
-#define SE_MBTYPE           2
-#define SE_REFFRAME         3
-#define SE_INTRAPREDMODE    4
-#define SE_MVD              5
-#define SE_CBP_INTRA        6
-#define SE_LUM_DC_INTRA     7
-#define SE_CHR_DC_INTRA     8
-#define SE_LUM_AC_INTRA     9
-#define SE_CHR_AC_INTRA     10
-#define SE_CBP_INTER        11
-#define SE_LUM_DC_INTER     12
-#define SE_CHR_DC_INTER     13
-#define SE_LUM_AC_INTER     14
-#define SE_CHR_AC_INTER     15
-#define SE_DELTA_QUANT_INTER      16
-#define SE_DELTA_QUANT_INTRA      17
-#define SE_BFRAME           18
-#define SE_EOS              19
-#define SE_MAX_ELEMENTS     20
-#define SE_CBP01            21
-int chroma_format;
-/*
- *************************************************************************
- * Function:Reads bits from the bitstream buffer
- * Input:
- byte buffer[]
- containing VLC-coded data bits
- int totbitoffset
- bit offset from start of partition
- int bytecount
- total bytes in bitstream
- int numbits
- number of bits to read
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-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;
-}
-
-/*
- *************************************************************************
- * Function:read FLC codeword from UVLC-partition
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int read_syntaxelement_flc(struct syntaxelement *sym)
-{
-	int frame_bitoffset = curr_stream->frame_bitoffset;
-	unsigned char *buf = curr_stream->stream_buffer;
-	int bitstreamlengthinbytes = curr_stream->bitstream_length;
-
-	if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
-			sym->len)) < 0)
-		return -1;
-
-	curr_stream->frame_bitoffset += sym->len;
-	sym->value1 = sym->inf;
-
-#if TRACE
-	tracebits2(sym->tracestring, sym->len, sym->inf);
-#endif
-
-	return 1;
-}
-
-/*
- *************************************************************************
- * Function:ue_v, reads an u(1) syntax element, the length in bits is stored in
- the global UsedBits variable
- * Input:
- tracestring
- the string for the trace file
- bitstream
- the stream to be read from
- * Output:
- * Return: the value of the coded syntax element
- * Attention:
- *************************************************************************
- */
-int u_1(char *tracestring)
-{
-	return u_v(1, tracestring);
-}
-
-/*
- *************************************************************************
- * Function:mapping rule for ue(v) syntax elements
- * Input:length and info
- * Output:number in the code table
- * Return:
- * Attention:
- *************************************************************************
- */
-void linfo_ue(int len, int info, int *value1, int *dummy)
-{
-	*value1 = (int)pow2(2, (len / 2)) + info - 1;
-}
-
-int u_v(int leninbits, char *tracestring)
-{
-	struct syntaxelement symbol, *sym = &symbol;
-
-#ifdef AVSP_LONG_CABAC
-#else
-	assert(curr_stream->stream_buffer != NULL);
-#endif
-	sym->type = SE_HEADER;
-	sym->mapping = linfo_ue;
-	sym->len = leninbits;
-	read_syntaxelement_flc(sym);
-
-	return sym->inf;
-}
-
-/*
- *************************************************************************
- * Function:mapping rule for se(v) syntax elements
- * Input:length and info
- * Output:signed mvd
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void linfo_se(int len, int info, int *value1, int *dummy)
-{
-	int n;
-
-	n = (int)pow2(2, (len / 2)) + info - 1;
-	*value1 = (n + 1) / 2;
-	if ((n & 0x01) == 0)
-		*value1 = -*value1;
-
-}
-
-/*
- *************************************************************************
- * Function:length and info
- * Input:
- * Output:cbp (intra)
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void linfo_cbp_intra(int len, int info, int *cbp, int *dummy)
-{
-}
-
-const int NCBP[64][2] = {{4, 0}, {16, 19}, {17, 16}, {19, 15}, {14, 18},
-		{9, 11}, {22, 31}, {8, 13}, {11, 17}, {21, 30}, {10, 12},
-		{7, 9}, {12, 10}, {6, 7}, {5, 8}, {1, 1}, {35, 4}, {47, 42}, {
-				48, 38}, {38, 27}, {46, 39}, {36, 33}, {50, 59},
-		{26, 26}, {45, 40}, {52, 58}, {41, 35}, {28, 25}, {37, 29}, {23,
-				24}, {31, 28}, {2, 3}, {43, 5}, {51, 51}, {56,
-				52}, {39, 37}, {55, 50}, {33, 43}, {62, 63}, {
-				27, 44}, {54, 53}, {60, 62}, {40, 48}, {32, 47},
-		{42, 34}, {24, 45}, {29, 49}, {3, 6}, {49, 14}, {53, 55}, {57,
-				56}, {25, 36}, {58, 54}, {30, 41}, {59, 60}, {
-				15, 21}, {61, 57}, {63, 61}, {44, 46}, {18, 22},
-		{34, 32}, {13, 20}, {20, 23}, {0, 2} };
-
-unsigned int s1, t1, value_s, value_t;
-unsigned char dec_bypass, dec_final;
-
-#define get_byte() {                                         \
-	dbuffer = dcodestrm[(*dcodestrm_len)++];\
-	dbits_to_go = 7;                        \
-}
-
-#define dbuffer         (dep->dbuffer)
-#define dbits_to_go     (dep->dbits_to_go)
-#define dcodestrm       (dep->dcodestrm)
-#define dcodestrm_len   (dep->dcodestrm_len)
-
-#define B_BITS	10
-
-#define LG_PMPS_SHIFTNO 2
-
-#define HALF      (1 << (B_BITS-1))
-#define QUARTER   (1 << (B_BITS-2))
-
-unsigned int biari_decode_symbol(struct decoding_environment_s *dep,
-		struct bi_context_type_s *bi_ct)
-{
-	register unsigned char bit;
-	register unsigned char s_flag;
-	register unsigned char is_lps = 0;
-	register unsigned char cwr;
-	register unsigned char cycno = bi_ct->cycno;
-	register unsigned int lg_pmps = bi_ct->LG_PMPS;
-	register unsigned int t_rlps;
-	register unsigned int s2, t2;
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & AEC_DUMP)
-		io_printf("LG_PMPS : %03X, MPS : %d, cycno : %d -- %p\n",
-			bi_ct->LG_PMPS, bi_ct->MPS, bi_ct->cycno, bi_ct);
-#endif
-
-	bit = bi_ct->MPS;
-
-	cwr = (cycno <= 1) ? 3 : (cycno == 2) ? 4 : 5;
-
-	if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
-		s2 = s1;
-		t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
-		s_flag = 0;
-	} else {
-		s2 = s1 + 1;
-		t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
-		s_flag = 1;
-	}
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & AEC_DUMP)
-		io_printf(" s2 : %d, t2 : %03X\n", s2, t2);
-#endif
-
-	if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
-		is_lps = 1;
-		bit = !bit;
-
-		t_rlps = (s_flag == 0) ?
-				(lg_pmps >> LG_PMPS_SHIFTNO) :
-				(t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
-
-		if (s2 == value_s)
-			value_t = (value_t - t2);
-		else {
-			if (--dbits_to_go < 0)
-				get_byte();
-
-			value_t = (value_t << 1)
-					| ((dbuffer >> dbits_to_go) & 0x01);
-			value_t = 256 + value_t - t2;
-
-		}
-
-		while (t_rlps < QUARTER) {
-			t_rlps = t_rlps << 1;
-			if (--dbits_to_go < 0)
-				get_byte();
-
-			value_t = (value_t << 1)
-					| ((dbuffer >> dbits_to_go) & 0x01);
-		}
-
-		s1 = 0;
-		t1 = t_rlps & 0xff;
-
-		value_s = 0;
-		while (value_t < QUARTER) {
-			int j;
-
-			if (--dbits_to_go < 0)
-				get_byte();
-			j = (dbuffer >> dbits_to_go) & 0x01;
-
-			value_t = (value_t << 1) | j;
-			value_s++;
-		}
-		value_t = value_t & 0xff;
-	} else {
-
-		s1 = s2;
-		t1 = t2;
-	}
-
-	if (dec_bypass)
-		return bit;
-
-	if (is_lps)
-		cycno = (cycno <= 2) ? (cycno + 1) : 3;
-	else if (cycno == 0)
-		cycno = 1;
-	bi_ct->cycno = cycno;
-
-	if (is_lps) {
-		switch (cwr) {
-		case 3:
-			lg_pmps = lg_pmps + 197;
-			break;
-		case 4:
-			lg_pmps = lg_pmps + 95;
-			break;
-		default:
-			lg_pmps = lg_pmps + 46;
-		}
-
-		if (lg_pmps >= (256 << LG_PMPS_SHIFTNO)) {
-			lg_pmps = (512 << LG_PMPS_SHIFTNO) - 1 - lg_pmps;
-			bi_ct->MPS = !(bi_ct->MPS);
-		}
-	} else {
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & AEC_DUMP)
-			io_printf(" - lg_pmps_MPS : %X (%X - %X - %X)\n",
-					lg_pmps - (unsigned int)(lg_pmps>>cwr)
-					- (unsigned int)(lg_pmps>>(cwr+2)),
-					lg_pmps,
-					(unsigned int)(lg_pmps>>cwr),
-					(unsigned int)(lg_pmps>>(cwr+2))
-			);
-#endif
-		lg_pmps = lg_pmps - (unsigned int)(lg_pmps >> cwr)
-				- (unsigned int)(lg_pmps >> (cwr + 2));
-	}
-
-	bi_ct->LG_PMPS = lg_pmps;
-
-	return bit;
-}
-
-unsigned int biari_decode_symbolw(struct decoding_environment_s *dep,
-		struct bi_context_type_s *bi_ct1,
-		struct bi_context_type_s *bi_ct2)
-{
-	register unsigned char bit1, bit2;
-	register unsigned char pred_mps, bit;
-	register unsigned int lg_pmps;
-	register unsigned char cwr1, cycno1 = bi_ct1->cycno;
-	register unsigned char cwr2, cycno2 = bi_ct2->cycno;
-	register unsigned int lg_pmps1 = bi_ct1->LG_PMPS;
-	register unsigned int lg_pmps2 =
-			bi_ct2->LG_PMPS;
-	register unsigned int t_rlps;
-	register unsigned char s_flag, is_lps = 0;
-	register unsigned int s2, t2;
-
-
-	bit1 = bi_ct1->MPS;
-	bit2 = bi_ct2->MPS;
-
-	cwr1 = (cycno1 <= 1) ? 3 : (cycno1 == 2) ? 4 : 5;
-	cwr2 = (cycno2 <= 1) ? 3 : (cycno2 == 2) ? 4 : 5;
-
-	if (bit1 == bit2) {
-		pred_mps = bit1;
-		lg_pmps = (lg_pmps1 + lg_pmps2) / 2;
-	} else {
-		if (lg_pmps1 < lg_pmps2) {
-			pred_mps = bit1;
-			lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
-					- ((lg_pmps2 - lg_pmps1) >> 1);
-		} else {
-			pred_mps = bit2;
-			lg_pmps = (256 << LG_PMPS_SHIFTNO) - 1
-					- ((lg_pmps1 - lg_pmps2) >> 1);
-		}
-	}
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & AEC_DUMP)
-		io_printf(" - Begin - LG_PMPS : %03X, MPS : %d\n",
-			lg_pmps, pred_mps);
-#endif
-	if (t1 >= (lg_pmps >> LG_PMPS_SHIFTNO)) {
-		s2 = s1;
-		t2 = t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
-		s_flag = 0;
-	} else {
-		s2 = s1 + 1;
-		t2 = 256 + t1 - (lg_pmps >> LG_PMPS_SHIFTNO);
-		s_flag = 1;
-	}
-
-	bit = pred_mps;
-	if (s2 > value_s || (s2 == value_s && value_t >= t2)) {
-		is_lps = 1;
-		bit = !bit;
-		t_rlps = (s_flag == 0) ?
-				(lg_pmps >> LG_PMPS_SHIFTNO) :
-				(t1 + (lg_pmps >> LG_PMPS_SHIFTNO));
-
-		if (s2 == value_s)
-			value_t = (value_t - t2);
-		else {
-			if (--dbits_to_go < 0)
-				get_byte();
-
-			value_t = (value_t << 1)
-					| ((dbuffer >> dbits_to_go) & 0x01);
-			value_t = 256 + value_t - t2;
-		}
-
-		while (t_rlps < QUARTER) {
-			t_rlps = t_rlps << 1;
-			if (--dbits_to_go < 0)
-				get_byte();
-
-			value_t = (value_t << 1)
-					| ((dbuffer >> dbits_to_go) & 0x01);
-		}
-		s1 = 0;
-		t1 = t_rlps & 0xff;
-
-		value_s = 0;
-		while (value_t < QUARTER) {
-			int j;
-
-			if (--dbits_to_go < 0)
-				get_byte();
-			j = (dbuffer >> dbits_to_go) & 0x01;
-
-			value_t = (value_t << 1) | j;
-			value_s++;
-		}
-		value_t = value_t & 0xff;
-	} else {
-		s1 = s2;
-		t1 = t2;
-	}
-
-	if (bit != bit1) {
-		cycno1 = (cycno1 <= 2) ? (cycno1 + 1) : 3;
-	} else {
-		if (cycno1 == 0)
-			cycno1 = 1;
-	}
-
-	if (bit != bit2) {
-		cycno2 = (cycno2 <= 2) ? (cycno2 + 1) : 3;
-	} else {
-		if (cycno2 == 0)
-			cycno2 = 1;
-	}
-	bi_ct1->cycno = cycno1;
-	bi_ct2->cycno = cycno2;
-
-	{
-
-		if (bit == bit1) {
-			lg_pmps1 =
-					lg_pmps1
-				- (unsigned int)(lg_pmps1
-					>> cwr1)
-				- (unsigned int)(lg_pmps1
-					>> (cwr1
-					+ 2));
-		} else {
-			switch (cwr1) {
-			case 3:
-				lg_pmps1 = lg_pmps1 + 197;
-				break;
-			case 4:
-				lg_pmps1 = lg_pmps1 + 95;
-				break;
-			default:
-				lg_pmps1 = lg_pmps1 + 46;
-			}
-
-			if (lg_pmps1 >= (256 << LG_PMPS_SHIFTNO)) {
-				lg_pmps1 = (512 << LG_PMPS_SHIFTNO) - 1
-						- lg_pmps1;
-				bi_ct1->MPS = !(bi_ct1->MPS);
-			}
-		}
-		bi_ct1->LG_PMPS = lg_pmps1;
-
-		if (bit == bit2) {
-			lg_pmps2 =
-					lg_pmps2
-				- (unsigned int)(lg_pmps2
-				>> cwr2)
-				- (unsigned int)(lg_pmps2
-				>> (cwr2
-				+ 2));
-		} else {
-			switch (cwr2) {
-			case 3:
-				lg_pmps2 = lg_pmps2 + 197;
-				break;
-			case 4:
-				lg_pmps2 = lg_pmps2 + 95;
-				break;
-			default:
-				lg_pmps2 = lg_pmps2 + 46;
-			}
-
-			if (lg_pmps2 >= (256 << LG_PMPS_SHIFTNO)) {
-				lg_pmps2 = (512 << LG_PMPS_SHIFTNO) - 1
-						- lg_pmps2;
-				bi_ct2->MPS = !(bi_ct2->MPS);
-			}
-		}
-		bi_ct2->LG_PMPS = lg_pmps2;
-	}
-
-
-	return bit;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    biari_decode_symbol_eq_prob():
- * \return
- *    the decoded symbol
- ************************************************************************
- */
-unsigned int biari_decode_symbol_eq_prob(struct decoding_environment_s *dep)
-{
-	unsigned char bit;
-	struct bi_context_type_s octx;
-	struct bi_context_type_s *ctx = &octx;
-
-	ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
-	ctx->MPS = 0;
-	ctx->cycno = 0xfe;
-	dec_bypass = 1;
-	bit = biari_decode_symbol(dep, ctx);
-	dec_bypass = 0;
-	return bit;
-}
-
-unsigned int biari_decode_final(struct decoding_environment_s *dep)
-{
-	unsigned char bit;
-	struct bi_context_type_s octx;
-	struct bi_context_type_s *ctx = &octx;
-
-	ctx->LG_PMPS = 1 << LG_PMPS_SHIFTNO;
-	ctx->MPS = 0;
-	ctx->cycno = 0xff;
-	dec_final = 1;
-	bit = biari_decode_symbol(dep, ctx);
-	dec_final = 0;
-	return bit;
-}
-
-int i_8(char *tracestring)
-{
-	int frame_bitoffset = curr_stream->frame_bitoffset;
-	unsigned char *buf = curr_stream->stream_buffer;
-	int bitstreamlengthinbytes = curr_stream->bitstream_length;
-	struct syntaxelement symbol, *sym = &symbol;
-#ifdef AVSP_LONG_CABAC
-#else
-	assert(curr_stream->stream_buffer != NULL);
-#endif
-
-	sym->len = 8;
-	sym->type = SE_HEADER;
-	sym->mapping = linfo_ue;
-
-	if ((get_bits(buf, frame_bitoffset, &(sym->inf), bitstreamlengthinbytes,
-			sym->len)) < 0)
-		return -1;
-	curr_stream->frame_bitoffset += sym->len;
-	sym->value1 = sym->inf;
-	if (sym->inf & 0x80)
-		sym->inf = -(~((int)0xffffff00 | sym->inf) + 1);
-#if TRACE
-	tracebits2(sym->tracestring, sym->len, sym->inf);
-#endif
-	return sym->inf;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    arideco_bits_read
- ************************************************************************
- */
-int arideco_bits_read(struct decoding_environment_s *dep)
-{
-
-	return 8 * ((*dcodestrm_len) - 1) + (8 - dbits_to_go);
-}
-
-/*!
- ************************************************************************
- * \brief
- *    arithmetic decoding
- ************************************************************************
- */
-int read_syntaxelement_aec(struct syntaxelement *se, struct img_par *img,
-		struct datapartition *this_data_part)
-{
-	int curr_len;
-	struct decoding_environment_s *dep_dp = &(this_data_part->de_aec);
-
-	curr_len = arideco_bits_read(dep_dp);
-
-	se->reading(se, img, dep_dp);
-
-	se->len = (arideco_bits_read(dep_dp) - curr_len);
-	return se->len;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    This function is used to arithmetically decode the
- *    run length info of the skip mb
- ************************************************************************
- */
-void readrunlenghtfrombuffer_aec(struct syntaxelement *se, struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	struct bi_context_type_s *pctx;
-	int ctx, symbol;
-
-	pctx = img->current_slice->tex_ctx->one_contexts[0];
-	symbol = 0;
-	ctx = 0;
-	while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
-		symbol += 1;
-		ctx++;
-		if (ctx >= 3)
-			ctx = 3;
-	}
-	se->value1 = symbol;
-#if TRACE
-	fprintf(p_trace, "@%d%s\t\t\t%d\n",
-		symbol_count++, se->tracestring, se->value1);
-	fflush(p_trace);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- *    This function is used to arithmetically decode a pair of
- *    intra prediction modes of a given MB.
- ************************************************************************
- */
-int mapd_intrap[5] = {0, 2, 3, 4, 1};
-void read_intrapredmode_aec(struct syntaxelement *se, struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	struct bi_context_type_s *pctx;
-	int ctx, symbol;
-
-	pctx = img->current_slice->tex_ctx->one_contexts[1];
-	symbol = 0;
-	ctx = 0;
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & AEC_DUMP)
-		io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
-#endif
-	while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
-		symbol += 1;
-		ctx++;
-		if (ctx >= 3)
-			ctx = 3;
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & AEC_DUMP)
-			io_printf(" -- read_intrapredmode_aec ctx : %d\n", ctx);
-#endif
-		if (symbol == 4)
-			break;
-		}
-	se->value1 = mapd_intrap[symbol] - 1;
-
-#if TRACE
-	fprintf(p_trace, "@%d %s\t\t\t%d\n",
-		symbol_count++, se->tracestring, se->value1);
-	fflush(p_trace);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- *    decoding of unary binarization using one or 2 distinct
- *    models for the first and all remaining bins; no terminating
- *    "0" for max_symbol
- ***********************************************************************
- */
-unsigned int unary_bin_max_decode(struct decoding_environment_s *dep_dp,
-		struct bi_context_type_s *ctx,
-		int ctx_offset, unsigned int max_symbol)
-{
-	unsigned int l;
-	unsigned int symbol;
-	struct bi_context_type_s *ictx;
-
-	symbol = biari_decode_symbol(dep_dp, ctx);
-
-	if (symbol == 0)
-		return 0;
-
-	if (max_symbol == 1)
-		return symbol;
-	symbol = 0;
-	ictx = ctx + ctx_offset;
-	do {
-		l = biari_decode_symbol(dep_dp, ictx);
-		symbol++;
-	} while ((l != 0) && (symbol < max_symbol - 1));
-	if ((l != 0) && (symbol == max_symbol - 1))
-		symbol++;
-	return symbol;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    decoding of unary binarization using one or 2 distinct
- *    models for the first and all remaining bins
- ***********************************************************************
- */
-unsigned int unary_bin_decode(struct decoding_environment_s *dep_dp,
-		struct bi_context_type_s *ctx, int ctx_offset)
-{
-	unsigned int l;
-	unsigned int symbol;
-	struct bi_context_type_s *ictx;
-
-	symbol = 1 - biari_decode_symbol(dep_dp, ctx);
-
-	if (symbol == 0)
-		return 0;
-	symbol = 0;
-	ictx = ctx + ctx_offset;
-	do {
-		l = 1 - biari_decode_symbol(dep_dp, ictx);
-		symbol++;
-	} while (l != 0);
-	return symbol;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    This function is used to arithmetically decode the chroma
- *    intra prediction mode of a given MB.
- ************************************************************************
- */
-void read_cipredmode_aec(struct syntaxelement *se,
-	struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
-	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-	int act_ctx, a, b;
-	int act_sym = se->value1;
-
-	if (curr_mb->mb_available_up == NULL)
-		b = 0;
-	else {
-		/*if ( (curr_mb->mb_available_up)->mb_type==IPCM)
-		 * b=0;
-		 * else
-		 */
-		b = (((curr_mb->mb_available_up)->c_ipred_mode != 0) ? 1 : 0);
-	}
-
-	if (curr_mb->mb_available_left == NULL)
-		a = 0;
-	else {
-		/* if ( (curr_mb->mb_available_left)->mb_type==IPCM)
-		 * a=0;
-		 * else
-		 */
-		a = (((curr_mb->mb_available_left)->c_ipred_mode != 0) ? 1 : 0);
-	}
-
-	act_ctx = a + b;
-
-
-	act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx);
-
-	if (act_sym != 0)
-		act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3,
-				0, 2) + 1;
-
-	se->value1 = act_sym;
-
-#if TRACE
-	fprintf(p_trace, "@%d %s\t\t%d\n",
-		symbol_count++, se->tracestring, se->value1);
-	fflush(p_trace);
-#endif
-
-}
-
-int slice_header(char *buf, int startcodepos, int length)
-{
-	int i;
-
-	int weight_para_num = 0;
-	int mb_row;
-	int mb_column;
-	int mb_index;
-	int mb_width, mb_height;
-
-	mb_column = 0;
-
-	memcpy(curr_stream->stream_buffer, buf, length);
-	curr_stream->code_len = curr_stream->bitstream_length = length;
-
-	curr_stream->read_len =
-	curr_stream->frame_bitoffset = (startcodepos) * 8;
-	slice_vertical_position = u_v(8, "slice vertical position");
-
-	push_es(slice_vertical_position, 8);
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & SLICE_INFO_DUMP)
-		io_printf(" * 8-bits slice_vertical_position : %d\n",
-			slice_vertical_position);
-#endif
-
-	if (vertical_size > 2800) {
-		slice_vertical_position_extension = u_v(3,
-				"slice vertical position extension");
-		push_es(slice_vertical_position_extension, 3);
-
-	}
-
-	if (vertical_size > 2800)
-		mb_row = (slice_vertical_position_extension << 7)
-				+ slice_vertical_position;
-	else
-		mb_row = slice_vertical_position;
-
-	mb_width = (horizontal_size + 15) / 16;
-	if (!progressive_sequence)
-		mb_height = 2 * ((vertical_size + 31) / 32);
-	else
-		mb_height = (vertical_size + 15) / 16;
-
-
-	mb_index = mb_row * mb_width + mb_column;
-
-	if (!img->picture_structure && img->type == I_IMG
-			&& (mb_index >= mb_width * mb_height / 2)) {
-		second_ifield = 1;
-		img->type = P_IMG;
-		pre_img_type = P_IMG;
-	}
-
-	{
-		if (!fixed_picture_qp) {
-			fixed_slice_qp = u_v(1, "fixed_slice_qp");
-			push_es(fixed_slice_qp, 1);
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & SLICE_INFO_DUMP)
-				io_printf(" * 1-bit fixed_slice_qp : %d\n",
-					fixed_slice_qp);
-#endif
-			slice_qp = u_v(6, "slice_qp");
-			push_es(slice_qp, 6);
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & SLICE_INFO_DUMP)
-				io_printf(" * 6-bits slice_qp : %d\n",
-					slice_qp);
-#endif
-
-			img->qp = slice_qp;
-		}
-
-		if (img->type != I_IMG) {
-			img->slice_weighting_flag = u_v(1,
-					"slice weighting flag");
-
-			if (img->slice_weighting_flag) {
-
-				if (second_ifield && !img->picture_structure)
-					weight_para_num = 1;
-				else if (img->type == P_IMG
-						&& img->picture_structure)
-					weight_para_num = 2;
-				else if (img->type == P_IMG
-						&& !img->picture_structure)
-					weight_para_num = 4;
-				else if (img->type == B_IMG
-						&& img->picture_structure)
-					weight_para_num = 2;
-				else if (img->type == B_IMG
-						&& !img->picture_structure)
-					weight_para_num = 4;
-
-#ifdef DUMP_DEBUG
-				if (avs_get_debug_flag() & SLICE_INFO_DUMP)
-					io_printf(" - weight_para_num : %d\n",
-						weight_para_num);
-#endif
-				for (i = 0; i < weight_para_num; i++) {
-					img->lum_scale[i] = u_v(8,
-							"luma scale");
-
-					img->lum_shift[i] = i_8("luma shift");
-
-					marker_bit = u_1("insert bit");
-
-
-					{
-						img->chroma_scale[i] = u_v(8,
-								"chroma scale");
-
-						img->chroma_shift[i] = i_8(
-								"chroma shift");
-
-						marker_bit = u_1("insert bit");
-
-					}
-				}
-				img->mb_weighting_flag = u_v(1,
-						"MB weighting flag");
-
-			}
-		}
-	}
-
-
-#if 1
-	return mb_index;
-#endif
-}
-
-void no_mem_exit(char *where)
-{
-	io_printf("%s\r\n", where);
-}
-
-unsigned char bit[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-
-struct inputstream_s {
-	/*FILE *f;*/
-	unsigned char buf[SVA_STREAM_BUF_SIZE];
-	unsigned int uclear_bits;
-	unsigned int upre_3bytes;
-	int ibyte_position;
-	int ibuf_bytesnum;
-	int iclear_bitsnum;
-	int istuff_bitsnum;
-	int ibits_count;
-};
-
-struct inputstream_s IRABS;
-struct inputstream_s *p_irabs = &IRABS;
-
-struct stat_bits {
-	int curr_frame_bits;
-	int prev_frame_bits;
-	int emulate_bits;
-	int prev_emulate_bits;
-	int last_unit_bits;
-	int bitrate;
-	int total_bitrate[1000];
-	int coded_pic_num;
-	int time_s;
-};
-
-struct stat_bits *stat_bits_ptr;
-
-unsigned char *temp_slice_buf;
-int start_codeposition;
-int first_slice_length;
-int first_slice_startpos;
-
-int bitstream_buf_used;
-int startcode_offset;
-
-int bitstream_read_ptr;
-
-int demulate_enable;
-
-int last_dquant;
-
-int total_mb_count;
-
-int current_mb_skip;
-
-int skip_mode_flag;
-
-int current_mb_intra;
-
-/*
- *************************************************************************
- * Function: Check start code's type
- * Input:
- * Output:
- * Return:
- * Author: XZHENG, 20080515
- *************************************************************************
- */
-void check_type(int startcode)
-{
-	startcode = startcode & 0x000000ff;
-	switch (startcode) {
-	case 0xb0:
-	case 0xb2:
-	case 0xb5:
-		demulate_enable = 0;
-		break;
-	default:
-		demulate_enable = 1;
-		break;
-	}
-
-}
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:  0 : OK
- -1 : arrive at stream end
- -2 : meet another start code
- * Attention:
- *************************************************************************
- */
-int clear_nextbyte(struct inputstream_s *p)
-{
-	int i, k, j;
-	unsigned char temp[3];
-
-	i = p->ibyte_position;
-	k = p->ibuf_bytesnum - i;
-	if (k < 3) {
-		for (j = 0; j < k; j++)
-			temp[j] = p->buf[i + j];
-
-		p->ibuf_bytesnum = read_bitstream(p->buf + k,
-				SVA_STREAM_BUF_SIZE - k);
-		bitstream_buf_used++;
-		if (p->ibuf_bytesnum == 0) {
-			if (k > 0) {
-				while (k > 0) {
-					p->upre_3bytes = ((p->upre_3bytes << 8)
-							| p->buf[i])
-							& 0x00ffffff;
-					if (p->upre_3bytes < 4
-							&& demulate_enable) {
-						p->uclear_bits =
-						(p->uclear_bits
-						<< 6)
-						| (p->buf[i]
-						>> 2);
-						p->iclear_bitsnum += 6;
-						stat_bits_ptr->emulate_bits
-						+= 2;
-					} else {
-						p->uclear_bits = (p->uclear_bits
-						<< 8)
-						| p->buf[i];
-						p->iclear_bitsnum += 8;
-					}
-					p->ibyte_position++;
-					k--;
-					i++;
-				}
-				return 0;
-			} else {
-				return -1;
-			}
-		} else {
-			for (j = 0; j < k; j++)
-				p->buf[j] = temp[j];
-			p->ibuf_bytesnum += k;
-			i = p->ibyte_position = 0;
-		}
-	}
-	if (p->buf[i] == 0 && p->buf[i + 1] == 0 && p->buf[i + 2] == 1)
-		return -2;
-	p->upre_3bytes = ((p->upre_3bytes << 8) | p->buf[i]) & 0x00ffffff;
-	if (p->upre_3bytes < 4 && demulate_enable) {
-		p->uclear_bits = (p->uclear_bits << 6) | (p->buf[i] >> 2);
-		p->iclear_bitsnum += 6;
-		stat_bits_ptr->emulate_bits += 2;
-	} else {
-		p->uclear_bits = (p->uclear_bits << 8) | p->buf[i];
-		p->iclear_bitsnum += 8;
-	}
-	p->ibyte_position++;
-	return 0;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:  0 : OK
- -1 : arrive at stream end
- -2 : meet another start code
- * Attention:
- *************************************************************************
- */
-int read_n_bit(struct inputstream_s *p, int n, int *v)
-{
-	int r;
-	unsigned int t;
-
-	while (n > p->iclear_bitsnum) {
-		r = clear_nextbyte(p);
-		if (r) {
-			if (r == -1) {
-				if (p->ibuf_bytesnum - p->ibyte_position > 0)
-					break;
-			}
-			return r;
-		}
-	}
-	t = p->uclear_bits;
-	r = 32 - p->iclear_bitsnum;
-	*v = (t << r) >> (32 - n);
-	p->iclear_bitsnum -= n;
-	return 0;
-}
-
-#ifdef AVSP_LONG_CABAC
-unsigned char TMP_BUF[2 * SVA_STREAM_BUF_SIZE];
-int tmp_buf_wr_ptr;
-int tmp_buf_rd_ptr;
-int tmp_buf_count;
-#endif
-void open_irabs(struct inputstream_s *p)
-{
-	p->uclear_bits = 0xffffffff;
-	p->ibyte_position = 0;
-	p->ibuf_bytesnum = 0;
-	p->iclear_bitsnum = 0;
-	p->istuff_bitsnum = 0;
-	p->ibits_count = 0;
-	p->upre_3bytes = 0;
-
-	bitstream_buf_used = 0;
-	bitstream_read_ptr = (src_start - 16) & 0xfffffff0;
-
-#ifdef AVSP_LONG_CABAC
-	tmp_buf_count = 0;
-	tmp_buf_wr_ptr = 0;
-	tmp_buf_rd_ptr = 0;
-#endif
-
-}
-
-void move_bitstream(unsigned int move_from_addr, unsigned int move_to_addr,
-		int move_size)
-{
-	int move_bytes_left = move_size;
-	unsigned int move_read_addr;
-	unsigned int move_write_addr = move_to_addr;
-
-	int move_byte;
-	unsigned int data32;
-
-	while (move_from_addr > vld_mem_end_addr) {
-		move_from_addr = move_from_addr + vld_mem_start_addr
-				- vld_mem_end_addr - 8;
-	}
-	move_read_addr = move_from_addr;
-	while (move_bytes_left > 0) {
-		move_byte = move_bytes_left;
-		if (move_byte > 512)
-			move_byte = 512;
-		if ((move_read_addr + move_byte) > vld_mem_end_addr)
-			move_byte = (vld_mem_end_addr + 8) - move_read_addr;
-
-		WRITE_VREG(LMEM_DMA_ADR, move_read_addr);
-		WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
-		WRITE_VREG(LMEM_DMA_CTRL, 0xc200);
-
-		data32 = 0x8000;
-		while (data32 & 0x8000)
-			data32 = READ_VREG(LMEM_DMA_CTRL);
-
-		WRITE_VREG(LMEM_DMA_ADR, move_write_addr);
-		WRITE_VREG(LMEM_DMA_COUNT, move_byte / 2);
-		WRITE_VREG(LMEM_DMA_CTRL, 0x8200);
-
-		data32 = 0x8000;
-		while (data32 & 0x8000)
-			data32 = READ_VREG(LMEM_DMA_CTRL);
-
-		data32 = 0x0fff;
-		while (data32 & 0x0fff)
-			data32 = READ_VREG(WRRSP_LMEM);
-
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & STREAM_INFO_DUMP)
-			io_printf("  2 MOVE %d Bytes from 0x%x to 0x%x\n",
-				move_byte, move_read_addr, move_write_addr);
-#endif
-
-		move_read_addr = move_read_addr + move_byte;
-		if (move_read_addr > vld_mem_end_addr)
-			move_read_addr = vld_mem_start_addr;
-		move_write_addr = move_write_addr + move_byte;
-		move_bytes_left = move_bytes_left - move_byte;
-	}
-
-}
-
-int read_bitstream(unsigned char *buf, int size)
-{
-	int i;
-
-#ifdef AVSP_LONG_CABAC
-
-	unsigned int *TMP_BUF_32 = (unsigned int *)bitstream_read_tmp;
-
-	if (tmp_buf_count < size) {
-		dma_sync_single_for_cpu(amports_get_dma_device(),
-				bitstream_read_tmp_phy, SVA_STREAM_BUF_SIZE,
-				DMA_FROM_DEVICE);
-
-		move_bitstream(bitstream_read_ptr, bitstream_read_tmp_phy,
-				SVA_STREAM_BUF_SIZE);
-
-		for (i = 0; i < SVA_STREAM_BUF_SIZE / 8; i++) {
-			TMP_BUF[tmp_buf_wr_ptr++] =
-					(TMP_BUF_32[2 * i + 1] >> 24) & 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] =
-					(TMP_BUF_32[2 * i + 1] >> 16) & 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 8)
-					& 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 1] >> 0)
-					& 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] =
-					(TMP_BUF_32[2 * i + 0] >> 24) & 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] =
-					(TMP_BUF_32[2 * i + 0] >> 16) & 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 8)
-					& 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-			TMP_BUF[tmp_buf_wr_ptr++] = (TMP_BUF_32[2 * i + 0] >> 0)
-					& 0xff;
-			if (tmp_buf_wr_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-				tmp_buf_wr_ptr = 0;
-		}
-		tmp_buf_count = tmp_buf_count + SVA_STREAM_BUF_SIZE;
-		bitstream_read_ptr = bitstream_read_ptr + SVA_STREAM_BUF_SIZE;
-	}
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & STREAM_INFO_DUMP)
-		io_printf(" Read %d bytes from %d, size left : %d\n",
-			size, tmp_buf_rd_ptr, tmp_buf_count);
-#endif
-	for (i = 0; i < size; i++) {
-		buf[i] = TMP_BUF[tmp_buf_rd_ptr++];
-		if (tmp_buf_rd_ptr >= (2 * SVA_STREAM_BUF_SIZE))
-			tmp_buf_rd_ptr = 0;
-	}
-	tmp_buf_count = tmp_buf_count - size;
-
-#else
-	for (i = 0; i < size; i++)
-		buf[i] = tmp_stream[bitstream_read_ptr + i];
-	bitstream_read_ptr = bitstream_read_ptr + size;
-#endif
-
-	return size;
-}
-
-int next_startcode(struct inputstream_s *p)
-{
-	int i, m;
-	unsigned char a = 0, b = 0;
-
-	m = 0;
-
-	while (1) {
-		if (p->ibyte_position >= p->ibuf_bytesnum - 2) {
-			m = p->ibuf_bytesnum - p->ibyte_position;
-			if (m < 0)
-				return -2;
-			if (m == 1)
-				b = p->buf[p->ibyte_position + 1];
-			if (m == 2) {
-				b = p->buf[p->ibyte_position + 1];
-				a = p->buf[p->ibyte_position];
-			}
-			p->ibuf_bytesnum = read_bitstream(p->buf,
-					SVA_STREAM_BUF_SIZE);
-			p->ibyte_position = 0;
-			bitstream_buf_used++;
-		}
-
-		if (p->ibuf_bytesnum + m < 3)
-			return -1;
-
-		if (m == 1 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
-			p->ibyte_position = 2;
-			p->iclear_bitsnum = 0;
-			p->istuff_bitsnum = 0;
-			p->ibits_count += 24;
-			p->upre_3bytes = 1;
-			return 0;
-		}
-
-		if (m == 2 && b == 0 && a == 0 && p->buf[0] == 1) {
-			p->ibyte_position = 1;
-			p->iclear_bitsnum = 0;
-			p->istuff_bitsnum = 0;
-			p->ibits_count += 24;
-			p->upre_3bytes = 1;
-			return 0;
-		}
-
-		if (m == 2 && b == 0 && p->buf[0] == 0 && p->buf[1] == 1) {
-			p->ibyte_position = 2;
-			p->iclear_bitsnum = 0;
-			p->istuff_bitsnum = 0;
-			p->ibits_count += 24;
-			p->upre_3bytes = 1;
-			return 0;
-		}
-
-		for (i = p->ibyte_position; i < p->ibuf_bytesnum - 2; i++) {
-			if (p->buf[i] == 0 && p->buf[i + 1] == 0
-					&& p->buf[i + 2] == 1) {
-				p->ibyte_position = i + 3;
-				p->iclear_bitsnum = 0;
-				p->istuff_bitsnum = 0;
-				p->ibits_count += 24;
-				p->upre_3bytes = 1;
-				return 0;
-			}
-			p->ibits_count += 8;
-		}
-		p->ibyte_position = i;
-	}
-}
-
-int get_oneunit(char *buf, int *startcodepos, int *length)
-{
-	int i, j, k;
-
-	i = next_startcode(p_irabs);
-
-	if (i != 0) {
-		if (i == -1)
-			io_printf(
-					"\narrive at stream end and start code is not found!");
-		if (i == -2)
-			io_printf("\np->ibyte_position error!");
-
-	}
-	startcode_offset =
-			p_irabs->ibyte_position
-					- 3 + (bitstream_buf_used-1)
-					* SVA_STREAM_BUF_SIZE;
-	buf[0] = 0;
-	buf[1] = 0;
-	buf[2] = 1;
-	*startcodepos = 3;
-	i = read_n_bit(p_irabs, 8, &j);
-	buf[3] = (char)j;
-
-	check_type(buf[3]);
-	if (buf[3] == SEQUENCE_END_CODE) {
-		*length = 4;
-		return -1;
-	}
-	k = 4;
-	while (1) {
-		i = read_n_bit(p_irabs, 8, &j);
-		if (i < 0)
-			break;
-		buf[k++] = (char)j;
-		if (k >= (MAX_CODED_FRAME_SIZE - 1))
-			break;
-	}
-	if (p_irabs->iclear_bitsnum > 0) {
-		int shift;
-
-		shift = 8 - p_irabs->iclear_bitsnum;
-		i = read_n_bit(p_irabs, p_irabs->iclear_bitsnum, &j);
-
-		if (j != 0)
-			buf[k++] = (char)(j << shift);
-		stat_bits_ptr->last_unit_bits += shift;
-	}
-	*length = k;
-	return k;
-}
-
-/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __attribute__ ((aligned(64)));*/
-/*unsigned char tmp_buf[MAX_CODED_FRAME_SIZE] __aligned(64);*/
-int header(void)
-{
-	unsigned char *buf;
-	int startcodepos, length;
-
-	unsigned char *tmp_buf;
-
-	tmp_buf = (unsigned char *)avsp_heap_adr;
-
-	buf = &tmp_buf[0];
-	while (1) {
-		start_codeposition = get_oneunit(buf, &startcodepos, &length);
-
-		switch (buf[startcodepos]) {
-		case SEQUENCE_HEADER_CODE:
-			io_printf(
-					"# SEQUENCE_HEADER_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case EXTENSION_START_CODE:
-			io_printf(
-					"# EXTENSION_START_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case USER_DATA_START_CODE:
-			io_printf(
-					"# USER_DATA_START_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case VIDEO_EDIT_CODE:
-			io_printf(
-					"# VIDEO_EDIT_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case I_PICTURE_START_CODE:
-			io_printf(
-					"# I_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case PB_PICTURE_START_CODE:
-			io_printf(
-					"# PB_PICTURE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		case SEQUENCE_END_CODE:
-			io_printf(
-					"# SEQUENCE_END_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-			break;
-		default:
-			io_printf(
-					"# SLICE_START_CODE (0x%02x) found at offset %d (0x%x)\n",
-					buf[startcodepos], startcode_offset,
-					startcode_offset);
-#if 0
-			io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
-					READ_VREG(VLD_MEM_VIFIFO_START_PTR));
-			io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
-					READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
-			io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
-					READ_VREG(VLD_MEM_VIFIFO_END_PTR));
-			io_printf("VLD_MEM_VIFIFO_WP %x\r\n"
-					READ_VREG(VLD_MEM_VIFIFO_WP));
-			io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
-					READ_VREG(VLD_MEM_VIFIFO_RP));
-			io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n"
-					READ_VREG(VLD_MEM_VBUF_RD_PTR));
-			io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
-					READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
-			io_printf("PARSER_VIDEO_HOLE %x\r\n",
-					READ_MPEG_REG(PARSER_VIDEO_HOLE));
-#endif
-			if ((buf[startcodepos] >= SLICE_START_CODE_MIN
-				&& buf[startcodepos]
-				<= SLICE_START_CODE_MAX)
-				&& ((!img->seq_header_indicate)
-				|| (img->type == B_IMG
-				&& img->b_discard_flag
-				== 1
-				&& !img->no_forward_reference))) {
-				break;
-			} else if (buf[startcodepos] >= SLICE_START_CODE_MIN) {
-
-				first_slice_length = length;
-				first_slice_startpos = startcodepos;
-
-				temp_slice_buf = &tmp_buf[0];
-				return SOP;
-			} else {
-				io_printf("Can't find start code");
-				return -EOS;
-			}
-		}
-	}
-
-}
-
-/*
- *************************************************************************
- * Function:Allocates a Bitstream
- * Input:
- * Output:allocated Bitstream point
- * Return:
- * Attention:
- *************************************************************************
- */
-struct bitstream_s *alloc_bitstream(void)
-{
-	struct bitstream_s *bitstream;
-
-	bitstream = (struct bitstream_s *)local_alloc(1,
-		sizeof(struct bitstream_s));
-	if (bitstream == NULL) {
-		io_printf(
-			"AllocBitstream: Memory allocation for Bitstream failed");
-		return NULL;
-	}
-	bitstream->stream_buffer = (unsigned char *)local_alloc(
-			MAX_CODED_FRAME_SIZE,
-			sizeof(unsigned char));
-	if (bitstream->stream_buffer == NULL) {
-		io_printf(
-				"AllocBitstream: Memory allocation for streamBuffer failed");
-		return NULL;
-	}
-
-	return bitstream;
-}
-
-void biari_init_context_logac(struct bi_context_type_s *ctx)
-{
-	ctx->LG_PMPS = (QUARTER << LG_PMPS_SHIFTNO) - 1;
-	ctx->MPS = 0;
-	ctx->cycno = 0;
-}
-
-#define BIARI_CTX_INIT1_LOG(jj, ctx)\
-{\
-	for (j = 0; j < jj; j++)\
-		biari_init_context_logac(&(ctx[j]));\
-}
-
-#define BIARI_CTX_INIT2_LOG(ii, jj, ctx)\
-{\
-	for (i = 0; i < ii; i++)\
-		for (j = 0; j < jj; j++)\
-			biari_init_context_logac(&(ctx[i][j]));\
-}
-
-#define BIARI_CTX_INIT3_LOG(ii, jj, kk, ctx)\
-{\
-	for (i = 0; i < ii; i++)\
-		for (j = 0; j < jj; j++)\
-			for (k = 0; k < kk; k++)\
-				biari_init_context_logac(&(ctx[i][j][k]));\
-}
-
-#define BIARI_CTX_INIT4_LOG(ii, jj, kk, ll, ctx)\
-{\
-	for (i = 0; i < ii; i++)\
-		for (j = 0; j < jj; j++)\
-			for (k = 0; k < kk; k++)\
-				for (l = 0; l < ll; l++)\
-					biari_init_context_logac\
-					(&(ctx[i][j][k][l]));\
-}
-
-void init_contexts(struct img_par *img)
-{
-	struct motion_info_contexts_s *mc = img->current_slice->mot_ctx;
-	struct texture_info_contexts *tc = img->current_slice->tex_ctx;
-	int i, j;
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & SLICE_INFO_DUMP)
-		io_printf(" ---- init_contexts ----\n");
-#endif
-
-	BIARI_CTX_INIT2_LOG(3, NUM_MB_TYPE_CTX, mc->mb_type_contexts);
-	BIARI_CTX_INIT2_LOG(2, NUM_B8_TYPE_CTX, mc->b8_type_contexts);
-	BIARI_CTX_INIT2_LOG(2, NUM_MV_RES_CTX, mc->mv_res_contexts);
-	BIARI_CTX_INIT2_LOG(2, NUM_REF_NO_CTX, mc->ref_no_contexts);
-	BIARI_CTX_INIT1_LOG(NUM_DELTA_QP_CTX, mc->delta_qp_contexts);
-	BIARI_CTX_INIT1_LOG(NUM_MB_AFF_CTX, mc->mb_aff_contexts);
-
-	BIARI_CTX_INIT1_LOG(NUM_IPR_CTX, tc->ipr_contexts);
-	BIARI_CTX_INIT1_LOG(NUM_CIPR_CTX, tc->cipr_contexts);
-	BIARI_CTX_INIT2_LOG(3, NUM_CBP_CTX, tc->cbp_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_BCBP_CTX, tc->bcbp_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ONE_CTX, tc->one_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_ABS_CTX, tc->abs_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->fld_map_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX,
-			tc->fld_last_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_MAP_CTX, tc->map_contexts);
-	BIARI_CTX_INIT2_LOG(NUM_BLOCK_TYPES, NUM_LAST_CTX, tc->last_contexts);
-#ifdef TEST_WEIGHTING_AEC
-	biari_init_context_logac(&mc->mb_weighting_pred);
-#endif
-}
-
-/*!
- ************************************************************************
- * \brief
- *    Allocation of contexts models for the motion info
- *    used for arithmetic decoding
- *
- ************************************************************************
- */
-struct motion_info_contexts_s *create_contexts_motioninfo(void)
-{
-	struct motion_info_contexts_s *deco_ctx;
-
-	deco_ctx = (struct motion_info_contexts_s *)local_alloc(1,
-			sizeof(struct motion_info_contexts_s));
-	if (deco_ctx == NULL)
-		no_mem_exit("create_contexts_motioninfo: deco_ctx");
-
-	return deco_ctx;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    Allocates of contexts models for the texture info
- *    used for arithmetic decoding
- ************************************************************************
- */
-struct texture_info_contexts *create_contexts_textureinfo(void)
-{
-	struct texture_info_contexts *deco_ctx;
-
-	deco_ctx = (struct texture_info_contexts *)local_alloc(1,
-			sizeof(struct texture_info_contexts));
-	if (deco_ctx == NULL)
-		no_mem_exit("create_contexts_textureinfo: deco_ctx");
-
-	return deco_ctx;
-}
-
-struct datapartition *alloc_partition(int n)
-{
-	struct datapartition *part_arr, *datapart;
-	int i;
-
-	part_arr =
-	(struct datapartition *)local_alloc(n, sizeof(struct datapartition));
-	if (part_arr == NULL) {
-		no_mem_exit(
-				"alloc_partition: Memory allocation for Data Partition failed");
-		return NULL;
-	}
-
-#if LIWR_FIX
-	part_arr[0].bitstream = NULL;
-#else
-	for (i = 0; i < n; i++) {
-		datapart = &(part_arr[i]);
-		datapart->bitstream = (struct bitstream_s *)local_alloc(1,
-				sizeof(struct bitstream_s));
-		if (datapart->bitstream == NULL) {
-			no_mem_exit(
-					"alloc_partition: Memory allocation for Bitstream failed");
-			return NULL;
-		}
-	}
-#endif
-	return part_arr;
-}
-
-int malloc_slice(struct img_par *img)
-{
-	struct slice_s *currslice;
-
-	img->current_slice =
-	(struct slice_s *)local_alloc(1, sizeof(struct slice_s));
-	currslice = img->current_slice;
-	if (currslice == NULL) {
-		no_mem_exit(
-			"Memory allocation for struct slice_s datastruct Failed"
-			);
-		return 0;
-	}
-	if (1) {
-
-		currslice->mot_ctx = create_contexts_motioninfo();
-		if (currslice->mot_ctx == NULL)
-			return 0;
-
-		currslice->tex_ctx = create_contexts_textureinfo();
-		if (currslice->tex_ctx == NULL)
-			return 0;
-	}
-#if LIWR_FIX
-	currslice->max_part_nr = 1;
-#else
-	currslice->max_part_nr = 3;
-#endif
-	currslice->part_arr = alloc_partition(currslice->max_part_nr);
-	if (currslice->part_arr == NULL)
-		return 0;
-	return 1;
-}
-
-void init(struct img_par *img)
-{
-	int i;
-
-	for (i = 0; i < 256; i++)
-		img->quad[i] = i * i;
-}
-
-/*
- *************************************************************************
- * Function:Allocate 2D memory array -> int array2D[rows][columns]
- * Input:
- * Output: memory size in bytes
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int get_mem2Dint(int ***array2D, int rows, int columns)
-{
-	int i;
-
-	*array2D = (int **)local_alloc(rows, sizeof(int *));
-	if (*array2D == NULL) {
-		no_mem_exit("get_mem2Dint: array2D");
-		return -1;
-	}
-	(*array2D)[0] = (int *)local_alloc(rows * columns, sizeof(int));
-	if ((*array2D)[0] == NULL) {
-		no_mem_exit("get_mem2Dint: array2D");
-		return -1;
-	}
-
-	for (i = 1; i < rows; i++)
-		(*array2D)[i] = (*array2D)[i - 1] + columns;
-
-	return rows * columns * sizeof(int);
-}
-
-int initial_decode(void)
-{
-	int i, j;
-	int ret;
-	int img_height = (vertical_size + img->auto_crop_bottom);
-	int memory_size = 0;
-
-	ret = malloc_slice(img);
-	if (ret == 0)
-		return 0;
-
-	mb_data = (struct macroblock *)local_alloc(
-			(img->width / MB_BLOCK_SIZE)
-			* (img_height /*vertical_size*/
-			/ MB_BLOCK_SIZE), sizeof(struct macroblock));
-	if (mb_data == NULL) {
-		no_mem_exit("init_global_buffers: mb_data");
-		return 0;
-	}
-
-	if (progressive_sequence) {
-		int size;
-		size = get_mem2Dint(&(img->ipredmode),
-				img->width / B8_SIZE * 2 + 4,
-				vertical_size / B8_SIZE * 2 + 4);
-		if (size == -1)
-			return 0;
-
-		memory_size += size;
-	} else {
-		int size;
-		size = get_mem2Dint(&(img->ipredmode),
-				img->width / B8_SIZE * 2 + 4,
-				(vertical_size + 32) / (2 * B8_SIZE) * 4 + 4);
-		if (size == -1)
-			return 0;
-
-		memory_size += size;
-	}
-
-	for (i = 0; i < img->width / (B8_SIZE) * 2 + 4; i++) {
-		for (j = 0; j < img->height / (B8_SIZE) * 2 + 4; j++)
-			img->ipredmode[i][j] = -1;
-	}
-
-	init(img);
-	img->number = 0;
-	img->type = I_IMG;
-	img->imgtr_last_p = 0;
-	img->imgtr_next_p = 0;
-
-	img->new_seq_header_flag = 1;
-	img->new_sequence_flag = 1;
-
-	return 1;
-}
-
-void aec_new_slice(void)
-{
-	last_dquant = 0;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    Initializes the DecodingEnvironment for the arithmetic coder
- ************************************************************************
- */
-
-void arideco_start_decoding(struct decoding_environment_s *dep,
-	unsigned char *cpixcode,
-		int firstbyte, int *cpixcode_len, int slice_type)
-{
-
-	dcodestrm = cpixcode;
-	dcodestrm_len = cpixcode_len;
-	*dcodestrm_len = firstbyte;
-
-	s1 = 0;
-	t1 = QUARTER - 1;
-	value_s = 0;
-
-	value_t = 0;
-
-	{
-		int i;
-
-		dbits_to_go = 0;
-		for (i = 0; i < B_BITS - 1; i++) {
-			if (--dbits_to_go < 0)
-				get_byte();
-
-			value_t = (value_t << 1)
-					| ((dbuffer >> dbits_to_go) & 0x01);
-		}
-	}
-
-	while (value_t < QUARTER) {
-		if (--dbits_to_go < 0)
-			get_byte();
-
-		value_t = (value_t << 1) | ((dbuffer >> dbits_to_go) & 0x01);
-		value_s++;
-	}
-	value_t = value_t & 0xff;
-
-	dec_final = dec_bypass = 0;
-
-
-
-}
-
-/*
- *************************************************************************
- * Function:Checks the availability of neighboring macroblocks of
- the current macroblock for prediction and context determination;
- marks the unavailable MBs for intra prediction in the
- ipredmode-array by -1. Only neighboring MBs in the causal
- past of the current MB are checked.
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void checkavailabilityofneighbors(struct img_par *img)
-{
-	int i, j;
-	const int mb_width = img->width / MB_BLOCK_SIZE;
-	const int mb_nr = img->current_mb_nr;
-	struct macroblock *curr_mb = &mb_data[mb_nr];
-	int check_value;
-	int remove_prediction;
-
-	curr_mb->mb_available_up = NULL;
-	curr_mb->mb_available_left = NULL;
-
-	for (i = 0; i < 3; i++)
-		for (j = 0; j < 3; j++)
-			mb_data[mb_nr].mb_available[i][j] = NULL;
-
-	mb_data[mb_nr].mb_available[1][1] = curr_mb;
-
-	if (img->pix_x >= MB_BLOCK_SIZE) {
-		remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - 1].slice_nr;
-
-		if (remove_prediction)
-
-		{
-
-			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
-					+ 1) * 2] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
-					+ 1) * 2 + 1] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
-					+ 2) * 2] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 - 1][(img->block_y
-					+ 2) * 2 + 1] = -1;
-		}
-		if (!remove_prediction)
-			curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
-
-	}
-
-	check_value = (img->pix_y >= MB_BLOCK_SIZE);
-	if (check_value) {
-		remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - mb_width].slice_nr;
-
-		if (remove_prediction) {
-			img->ipredmode
-			[(img->block_x + 1) * 2][(img->block_y + 1)
-					* 2 - 1] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 + 1][(img->block_y
-					+ 1) * 2 - 1] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 + 2][(img->block_y
-					+ 1) * 2 - 1] = -1;
-			img->ipredmode[(img->block_x + 1) * 2 + 3][(img->block_y
-					+ 1) * 2 - 1] = -1;
-		}
-
-		if (!remove_prediction) {
-			curr_mb->mb_available[0][1] =
-					&(mb_data[mb_nr - mb_width]);
-		}
-	}
-
-	if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
-		remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - mb_width - 1].slice_nr;
-
-		if (remove_prediction) {
-			img->ipredmode[img->block_x * 2 + 1][img->block_y * 2
-					+ 1] = -1;
-		}
-		if (!remove_prediction) {
-			curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
-					- 1]);
-		}
-	}
-
-	if (img->pix_y >= MB_BLOCK_SIZE
-			&& img->pix_x < (img->width - MB_BLOCK_SIZE)) {
-		if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
-			curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
-					+ 1]);
-	}
-
-	if (1) {
-		curr_mb->mbaddr_a = mb_nr - 1;
-		curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
-		curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
-		curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
-
-		curr_mb->mbavail_a =
-		(curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
-		curr_mb->mbavail_b =
-		(curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
-		curr_mb->mbavail_c =
-		(curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
-		curr_mb->mbavail_d =
-		(curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
-
-	}
-
-}
-
-void checkavailabilityofneighborsaec(void)
-{
-
-	int i, j;
-	const int mb_width = img->width / MB_BLOCK_SIZE;
-	const int mb_nr = img->current_mb_nr;
-	struct macroblock *curr_mb = &(mb_data[mb_nr]);
-	int check_value;
-
-	for (i = 0; i < 3; i++)
-		for (j = 0; j < 3; j++)
-			mb_data[mb_nr].mb_available[i][j] = NULL;
-	mb_data[mb_nr].mb_available[1][1] = &(mb_data[mb_nr]);
-
-	if (img->pix_x >= MB_BLOCK_SIZE) {
-		int remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - 1].slice_nr;
-		if (!remove_prediction)
-			curr_mb->mb_available[1][0] = &(mb_data[mb_nr - 1]);
-	}
-
-	check_value = (img->pix_y >= MB_BLOCK_SIZE);
-	if (check_value) {
-		int remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - mb_width].slice_nr;
-
-		if (!remove_prediction) {
-			curr_mb->mb_available[0][1] =
-					&(mb_data[mb_nr - mb_width]);
-		}
-	}
-
-	if (img->pix_y >= MB_BLOCK_SIZE && img->pix_x >= MB_BLOCK_SIZE) {
-		int remove_prediction = curr_mb->slice_nr
-				!= mb_data[mb_nr - mb_width - 1].slice_nr;
-		if (!remove_prediction) {
-			curr_mb->mb_available[0][0] = &(mb_data[mb_nr - mb_width
-					- 1]);
-		}
-	}
-
-	if (img->pix_y >= MB_BLOCK_SIZE
-			&& img->pix_x < (img->width - MB_BLOCK_SIZE)) {
-		if (curr_mb->slice_nr == mb_data[mb_nr - mb_width + 1].slice_nr)
-			curr_mb->mb_available[0][2] = &(mb_data[mb_nr - mb_width
-					+ 1]);
-	}
-	curr_mb->mb_available_left = curr_mb->mb_available[1][0];
-	curr_mb->mb_available_up = curr_mb->mb_available[0][1];
-	curr_mb->mbaddr_a = mb_nr - 1;
-	curr_mb->mbaddr_b = mb_nr - img->pic_width_inmbs;
-	curr_mb->mbaddr_c = mb_nr - img->pic_width_inmbs + 1;
-	curr_mb->mbaddr_d = mb_nr - img->pic_width_inmbs - 1;
-
-	curr_mb->mbavail_a = (curr_mb->mb_available[1][0] != NULL) ? 1 : 0;
-	curr_mb->mbavail_b = (curr_mb->mb_available[0][1] != NULL) ? 1 : 0;
-	curr_mb->mbavail_c = (curr_mb->mb_available[0][2] != NULL) ? 1 : 0;
-	curr_mb->mbavail_d = (curr_mb->mb_available[0][0] != NULL) ? 1 : 0;
-}
-
-/*
- *************************************************************************
- * Function:initializes the current macroblock
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void start_macroblock(struct img_par *img)
-{
-	int i, j, k, l;
-	struct macroblock *curr_mb;
-
-#ifdef AVSP_LONG_CABAC
-#else
-
-#endif
-
-	curr_mb = &mb_data[img->current_mb_nr];
-
-	/* Update coordinates of the current macroblock */
-	img->mb_x = (img->current_mb_nr) % (img->width / MB_BLOCK_SIZE);
-	img->mb_y = (img->current_mb_nr) / (img->width / MB_BLOCK_SIZE);
-
-#ifdef DUMP_DEBUG
-	if (avs_get_debug_flag() & MB_NUM_DUMP)
-		io_printf(" #Begin MB : %d, (%x, %x) es_ptr %d\n",
-			img->current_mb_nr, img->mb_x, img->mb_y, es_ptr);
-#endif
-
-
-	total_mb_count = total_mb_count + 1;
-
-	/* Define vertical positions */
-	img->block_y = img->mb_y * BLOCK_SIZE / 2; /* luma block position */
-	img->block8_y = img->mb_y * BLOCK_SIZE / 2;
-	img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
-	if (chroma_format == 2)
-		img->pix_c_y = img->mb_y *
-		MB_BLOCK_SIZE; /* chroma macroblock position */
-	else
-		img->pix_c_y = img->mb_y *
-		MB_BLOCK_SIZE / 2; /* chroma macroblock position */
-
-	/* Define horizontal positions */
-	img->block_x = img->mb_x * BLOCK_SIZE / 2; /* luma block position */
-	img->block8_x = img->mb_x * BLOCK_SIZE / 2;
-	img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
-	img->pix_c_x = img->mb_x *
-	MB_BLOCK_SIZE / 2; /* chroma pixel position */
-
-	checkavailabilityofneighbors(img);
-
-	/*<!*******EDIT START BY lzhang ******************/
-
-	if (1)
-		checkavailabilityofneighborsaec();
-	/*<!*******EDIT end BY lzhang ******************/
-
-	curr_mb->qp = img->qp;
-	curr_mb->mb_type = 0;
-	curr_mb->delta_quant = 0;
-	curr_mb->cbp = 0;
-	curr_mb->cbp_blk = 0;
-	curr_mb->c_ipred_mode = DC_PRED_8;
-	curr_mb->c_ipred_mode_2 = DC_PRED_8;
-
-	for (l = 0; l < 2; l++)
-		for (j = 0; j < BLOCK_MULTIPLE; j++)
-			for (i = 0; i < BLOCK_MULTIPLE; i++)
-				for (k = 0; k < 2; k++)
-					curr_mb->mvd[l][j][i][k] = 0;
-
-	curr_mb->cbp_bits = 0;
-
-	for (j = 0; j < MB_BLOCK_SIZE; j++)
-		for (i = 0; i < MB_BLOCK_SIZE; i++)
-			img->m7[i][j] = 0;
-
-	for (j = 0; j < 2 * BLOCK_SIZE; j++)
-		for (i = 0; i < 2 * BLOCK_SIZE; i++) {
-			img->m8[0][i][j] = 0;
-			img->m8[1][i][j] = 0;
-			img->m8[2][i][j] = 0;
-			img->m8[3][i][j] = 0;
-		}
-
-	curr_mb->lf_disable = 1;
-
-	img->weighting_prediction = 0;
-}
-
-/*
- *************************************************************************
- * Function:init macroblock I and P frames
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void init_macroblock(struct img_par *img)
-{
-	int i, j;
-
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < 4; j++) {
-			img->ipredmode[img->block_x * 2 + i + 2][img->block_y
-					* 2 + j + 2] = -1;
-		}
-	}
-
-}
-
-/*
- *************************************************************************
- * Function:Interpret the mb mode for I-Frames
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void interpret_mb_mode_i(struct img_par *img)
-{
-	int i;
-
-	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-	int num = 4;
-
-	curr_mb->mb_type = I8MB;
-
-
-	current_mb_intra = 1;
-
-	for (i = 0; i < 4; i++) {
-		curr_mb->b8mode[i] = IBLOCK;
-		curr_mb->b8pdir[i] = -1;
-	}
-
-	for (i = num; i < 4; i++) {
-		curr_mb->b8mode[i] =
-				curr_mb->mb_type_2 == P8x8 ?
-						4 : curr_mb->mb_type_2;
-		curr_mb->b8pdir[i] = 0;
-	}
-}
-
-const int pred_4x4[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1,
-		1, 1}, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 0, 0, 3, 3, 3, 3, 3, 3},
-		{0, 1, 4, 4, 4, 4, 4, 4, 4}, {0, 1, 5, 5, 5, 5, 5, 5, 5}, {0, 0,
-				0, 0, 0, 0, 6, 0, 0},
-		{0, 1, 7, 7, 7, 7, 7, 7, 7}, {0, 0, 0, 0, 4, 5, 6, 7, 8}
-
-};
-
-const int pred_4x4to8x8[9] = {0, 1, 2, 3, 4, 1, 0, 1, 0
-
-};
-
-const int pred_8x8to4x4[5] = {0, 1, 2, 3, 4};
-
-void read_ipred_block_modes(struct img_par *img, int b8)
-{
-	int bi, bj, dec;
-	struct syntaxelement curr_se;
-	struct macroblock *curr_mb;
-	int j2;
-	int mostprobableintrapredmode;
-	int upintrapredmode;
-	int uprightintrapredmode;
-	int leftintrapredmode;
-	int leftdownintrapredmode;
-	int intrachromapredmodeflag;
-
-	struct slice_s *currslice = img->current_slice;
-	struct datapartition *dp;
-
-	curr_mb = mb_data + img->current_mb_nr;
-	intrachromapredmodeflag = IS_INTRA(curr_mb);
-
-	curr_se.type = SE_INTRAPREDMODE;
-#if TRACE
-	strncpy(curr_se.tracestring, "Ipred Mode", TRACESTRING_SIZE);
-#endif
-
-	if (b8 < 4) {
-		if (curr_mb->b8mode[b8] == IBLOCK) {
-			intrachromapredmodeflag = 1;
-
-			if (1) {
-				dp = &(currslice->part_arr[0]);
-				curr_se.reading = read_intrapredmode_aec;
-				dp->read_syntax_element(&curr_se, img, dp);
-
-				if (curr_se.value1 == -1)
-					push_es(1, 1);
-				else
-					push_es(curr_se.value1, 3);
-
-
-			}
-			bi = img->block_x + (b8 & 1);
-			bj = img->block_y + (b8 / 2);
-
-			upintrapredmode = img->ipredmode[(bi + 1) * 2][(bj) * 2
-					+ 1];
-			uprightintrapredmode =
-					img->ipredmode[(bi + 1) * 2 + 1][(bj)
-							* 2 + 1];
-			leftintrapredmode =
-					img->ipredmode[(bi) * 2 + 1][(bj + 1)
-							* 2];
-			leftdownintrapredmode = img->ipredmode[(bi) * 2 + 1][(bj
-					+ 1) * 2 + 1];
-
-			if ((upintrapredmode < 0) || (leftintrapredmode < 0)) {
-				mostprobableintrapredmode = DC_PRED;
-			} else if ((upintrapredmode < NO_INTRA_PMODE)
-					&& (leftintrapredmode <
-						NO_INTRA_PMODE)) {
-				mostprobableintrapredmode =
-					upintrapredmode
-					< leftintrapredmode ?
-					upintrapredmode :
-					leftintrapredmode;
-			} else if (upintrapredmode < NO_INTRA_PMODE) {
-				mostprobableintrapredmode = upintrapredmode;
-			} else if (leftintrapredmode < NO_INTRA_PMODE) {
-				mostprobableintrapredmode = leftintrapredmode;
-			} else {
-				mostprobableintrapredmode =
-					pred_4x4[leftintrapredmode
-					- INTRA_PMODE_4x4][upintrapredmode
-					- INTRA_PMODE_4x4];
-				mostprobableintrapredmode =
-				pred_4x4to8x8[mostprobableintrapredmode];
-			}
-
-
-
-			dec =
-					(curr_se.value1 == -1) ?
-					mostprobableintrapredmode :
-					curr_se.value1
-					+ (curr_se.value1
-					>= mostprobableintrapredmode);
-
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & MB_INFO_DUMP)
-				io_printf(" - ipredmode[%d] : %d\n", b8, dec);
-#endif
-
-			img->ipredmode[(1 + bi) * 2][(1 + bj) * 2] = dec;
-			img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2] = dec;
-			img->ipredmode[(1 + bi) * 2][(1 + bj) * 2 + 1] = dec;
-			img->ipredmode[(1 + bi) * 2 + 1][(1 + bj) * 2 + 1] =
-					dec;
-
-			j2 = bj;
-		}
-	} else if (b8 == 4 && curr_mb->b8mode[b8 - 3] == IBLOCK) {
-
-		curr_se.type = SE_INTRAPREDMODE;
-#if TRACE
-		strncpy(curr_se.tracestring,
-			"Chroma intra pred mode", TRACESTRING_SIZE);
-#endif
-
-		if (1) {
-			dp = &(currslice->part_arr[0]);
-			curr_se.reading = read_cipredmode_aec;
-			dp->read_syntax_element(&curr_se, img, dp);
-		} else
-
-		{
-		}
-		curr_mb->c_ipred_mode = curr_se.value1;
-
-		push_es(UE[curr_se.value1][0], UE[curr_se.value1][1]);
-
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & MB_INFO_DUMP)
-			io_printf(" * UE c_ipred_mode read : %d\n",
-				curr_mb->c_ipred_mode);
-#endif
-
-		if (curr_se.value1 < DC_PRED_8 || curr_se.value1 > PLANE_8) {
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & MB_INFO_DUMP)
-				io_printf("%d\n", img->current_mb_nr);
-#endif
-			pr_info("illegal chroma intra pred mode!\n");
-		}
-	}
-}
-
-/*!
- ************************************************************************
- * \brief
- *    This function is used to arithmetically decode the coded
- *    block pattern of a given MB.
- ************************************************************************
- */
-void readcp_aec(struct syntaxelement *se, struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	struct texture_info_contexts *ctx = img->current_slice->tex_ctx;
-	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-
-	int mb_x, mb_y;
-	int a, b;
-	int curr_cbp_ctx, curr_cbp_idx;
-	int cbp = 0;
-	int cbp_bit;
-	int mask;
-
-	for (mb_y = 0; mb_y < 4; mb_y += 2) {
-		for (mb_x = 0; mb_x < 4; mb_x += 2) {
-			if (curr_mb->b8mode[mb_y + (mb_x / 2)] == IBLOCK)
-				curr_cbp_idx = 0;
-			else
-				curr_cbp_idx = 1;
-
-			if (mb_y == 0) {
-				if (curr_mb->mb_available_up == NULL)
-					b = 0;
-				else {
-					b = ((((curr_mb->mb_available_up)->cbp
-							& (1 << (2 + mb_x / 2)))
-							== 0) ? 1 : 0);
-				}
-
-			} else
-				b = (((cbp & (1 << (mb_x / 2))) == 0) ? 1 : 0);
-
-			if (mb_x == 0) {
-				if (curr_mb->mb_available_left == NULL)
-					a = 0;
-				else {
-					a =
-					((((curr_mb->mb_available_left)->cbp
-					& (1
-					<< (2
-					* (mb_y
-					/ 2)
-					+ 1)))
-					== 0) ?
-					1 : 0);
-				}
-			} else
-				a = (((cbp & (1 << mb_y)) == 0) ? 1 : 0);
-			curr_cbp_ctx = a + 2 * b;
-			mask = (1 << (mb_y + mb_x / 2));
-			cbp_bit = biari_decode_symbol(dep_dp,
-					ctx->cbp_contexts[0] + curr_cbp_ctx);
-
-			if (cbp_bit)
-				cbp += mask;
-		}
-	}
-	curr_cbp_ctx = 0;
-	cbp_bit = biari_decode_symbol(dep_dp,
-			ctx->cbp_contexts[1] + curr_cbp_ctx);
-
-	if (cbp_bit) {
-		curr_cbp_ctx = 1;
-		cbp_bit = biari_decode_symbol(dep_dp,
-				ctx->cbp_contexts[1] + curr_cbp_ctx);
-		if (cbp_bit) {
-			cbp += 48;
-
-		} else {
-			curr_cbp_ctx = 1;
-			cbp_bit = biari_decode_symbol(dep_dp,
-					ctx->cbp_contexts[1] + curr_cbp_ctx);
-			cbp += (cbp_bit == 1) ? 32 : 16;
-
-		}
-	}
-
-	se->value1 = cbp;
-	if (!cbp)
-		last_dquant = 0;
-
-
-
-}
-
-/*!
- ************************************************************************
- * \brief
- *    This function is used to arithmetically decode the delta qp
- *     of a given MB.
- ************************************************************************
- */
-void readdquant_aec(struct syntaxelement *se, struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	struct motion_info_contexts_s *ctx = img->current_slice->mot_ctx;
-
-	int act_ctx;
-	int act_sym;
-	int dquant;
-
-
-	act_ctx = ((last_dquant != 0) ? 1 : 0);
-
-	act_sym = 1
-			- biari_decode_symbol(dep_dp,
-					ctx->delta_qp_contexts + act_ctx);
-	if (act_sym != 0) {
-		act_ctx = 2;
-		act_sym = unary_bin_decode(dep_dp,
-				ctx->delta_qp_contexts + act_ctx, 1);
-		act_sym++;
-	}
-	act_sym &= 0x3f;
-	push_es(UE[act_sym][0], UE[act_sym][1]);
-
-	dquant = (act_sym + 1) / 2;
-	if ((act_sym & 0x01) == 0)
-		dquant = -dquant;
-	se->value1 = dquant;
-
-	last_dquant = dquant;
-
-}
-
-int csyntax;
-
-#define CHECKDELTAQP {\
-	if (img->qp+curr_mb->delta_quant > 63\
-			|| img->qp+curr_mb->delta_quant < 0) {\
-		csyntax = 0;\
-		transcoding_error_flag = 1;\
-		io_printf("error(0) (%3d|%3d) @ MB%d\n",\
-			curr_mb->delta_quant,\
-			img->qp+curr_mb->delta_quant,\
-			img->picture_structure == 0 \
-			? img->current_mb_nr_fld : img->current_mb_nr);\
-		} }
-
-int dct_level[65];
-int dct_run[65];
-int pair_pos;
-int dct_pairs = -1;
-const int t_chr[5] = {0, 1, 2, 4, 3000};
-
-void readrunlevel_aec_ref(struct syntaxelement *se, struct img_par *img,
-		struct decoding_environment_s *dep_dp)
-{
-	int pairs, rank, pos;
-	int run, level, abslevel, symbol;
-	int sign;
-
-	if (dct_pairs < 0) {
-		struct bi_context_type_s (*primary)[NUM_MAP_CTX];
-		struct bi_context_type_s *pctx;
-		struct bi_context_type_s *pCTX2;
-		int ctx, ctx2, offset;
-
-		if (se->context == LUMA_8x8) {
-			if (img->picture_structure == 0) {
-				primary =
-				img->current_slice->tex_ctx->fld_map_contexts;
-			} else {
-				primary =
-				img->current_slice->tex_ctx->map_contexts;
-			}
-		} else {
-			if (img->picture_structure == 0) {
-				primary =
-				img->current_slice->tex_ctx->fld_last_contexts;
-			} else {
-				primary =
-				img->current_slice->tex_ctx->last_contexts;
-			}
-		}
-
-		rank = 0;
-		pos = 0;
-		for (pairs = 0; pairs < 65; pairs++) {
-#ifdef DECODING_SANITY_CHECK
-			/*max index is NUM_BLOCK_TYPES - 1*/
-			pctx = primary[rank & 0x7];
-#else
-			pctx = primary[rank];
-#endif
-			if (rank > 0) {
-#ifdef DECODING_SANITY_CHECK
-				/*max index is NUM_BLOCK_TYPES - 1*/
-				pCTX2 = primary[(5 + (pos >> 5)) & 0x7];
-#else
-				pCTX2 = primary[5 + (pos >> 5)];
-#endif
-				ctx2 = (pos >> 1) & 0x0f;
-				ctx = 0;
-
-
-				if (biari_decode_symbolw(dep_dp, pctx + ctx,
-						pCTX2 + ctx2)) {
-					break;
-				}
-			}
-
-			ctx = 1;
-			symbol = 0;
-			while (biari_decode_symbol(dep_dp, pctx + ctx) == 0) {
-				symbol += 1;
-				ctx++;
-				if (ctx >= 2)
-					ctx = 2;
-			}
-			abslevel = symbol + 1;
-
-			if (biari_decode_symbol_eq_prob(dep_dp)) {
-				level = -abslevel;
-				sign = 1;
-			} else {
-				level = abslevel;
-				sign = 0;
-			}
-#if TRACE
-			tracebits2("level", 1, level);
-#endif
-
-			if (abslevel == 1)
-				offset = 4;
-			else
-				offset = 6;
-			symbol = 0;
-			ctx = 0;
-			while (biari_decode_symbol(dep_dp, pctx + ctx + offset)
-					== 0) {
-				symbol += 1;
-				ctx++;
-				if (ctx >= 1)
-					ctx = 1;
-			}
-			run = symbol;
-
-#if TRACE
-			tracebits2("run", 1, run);
-#endif
-			dct_level[pairs] = level;
-			dct_run[pairs] = run;
-			if (abslevel > t_chr[rank]) {
-				if (abslevel <= 2)
-					rank = abslevel;
-				else if (abslevel <= 4)
-					rank = 3;
-				else
-					rank = 4;
-			}
-			pos += (run + 1);
-			if (pos >= 64)
-				pos = 63;
-		}
-		dct_pairs = pairs;
-		pair_pos = dct_pairs;
-	}
-
-	if (dct_pairs > 0) {
-		se->value1 = dct_level[pair_pos - 1];
-		se->value2 = dct_run[pair_pos - 1];
-		pair_pos--;
-	} else {
-
-		se->value1 = se->value2 = 0;
-	}
-
-	if ((dct_pairs--) == 0)
-		pair_pos = 0;
-}
-
-int b8_ctr;
-#if 0
-int curr_residual_chroma[4][16][16];
-int curr_residual_luma[16][16];
-#endif
-
-const int SCAN[2][64][2] = {{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {0, 3}, {0, 4}, {1,
-		1}, {1, 2}, {0, 5}, {0, 6}, {1, 3}, {2, 0}, {2, 1}, {0, 7}, {1,
-		4}, {2, 2}, {3, 0}, {1, 5}, {1, 6}, {2, 3}, {3, 1}, {3, 2}, {4,
-		0}, {1, 7}, {2, 4}, {4, 1}, {2, 5}, {3, 3}, {4, 2}, {2, 6}, {3,
-		4}, {4, 3}, {5, 0}, {5, 1}, {2, 7}, {3, 5}, {4, 4}, {5, 2}, {6,
-		0}, {5, 3}, {3, 6}, {4, 5}, {6, 1}, {6, 2}, {5, 4}, {3, 7}, {4,
-		6}, {6, 3}, {5, 5}, {4, 7}, {6, 4}, {5, 6}, {6, 5}, {5, 7}, {6,
-		6}, {7, 0}, {6, 7}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7,
-		6}, {7, 7} }, {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {
-		3, 0}, {2, 1}, {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, {
-		4, 0}, {5, 0}, {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, {
-		1, 5}, {2, 4}, {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, {
-		5, 2}, {4, 3}, {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, {
-		3, 5}, {4, 4}, {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, {
-		4, 5}, {3, 6}, {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, {
-		7, 4}, {6, 5}, {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, {
-		6, 7}, {7, 7} } };
-
-const int SCAN_4x4[16][2] = {{0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3,
-		0}, {2, 1}, {1, 2}, {0, 3}, {1, 3}, {2, 2}, {3, 1}, {3, 2}, {2,
-		3}, {3, 3} };
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void encode_golomb_word(unsigned int symbol, unsigned int grad0,
-		unsigned int max_levels, unsigned int *res_bits,
-		unsigned int *res_len)
-{
-	unsigned int level, res, numbits;
-
-	res = 1UL << grad0;
-	level = 1UL;
-	numbits = 1UL + grad0;
-
-	while (symbol >= res && level < max_levels) {
-		symbol -= res;
-		res = res << 1;
-		level++;
-		numbits += 2UL;
-	}
-
-	if (level >= max_levels) {
-		if (symbol >= res)
-			symbol = res - 1UL;
-	}
-
-	*res_bits = res | symbol;
-	*res_len = numbits;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void encode_multilayer_golomb_word(unsigned int symbol,
-		const unsigned int *grad, const unsigned int *max_levels,
-		unsigned int *res_bits, unsigned int *res_len)
-{
-	unsigned int accbits, acclen, bits, len, tmp;
-
-	accbits = acclen = 0UL;
-
-	while (1) {
-		encode_golomb_word(symbol, *grad, *max_levels, &bits, &len);
-		accbits = (accbits << len) | bits;
-		acclen += len;
-#ifdef AVSP_LONG_CABAC
-#else
-		assert(acclen <= 32UL);
-#endif
-		tmp = *max_levels - 1UL;
-
-		if (!((len == (tmp << 1) + (*grad))
-				&& (bits == (1UL << (tmp + *grad)) - 1UL)))
-			break;
-
-		tmp = *max_levels;
-		symbol -= (((1UL << tmp) - 1UL) << (*grad)) - 1UL;
-		grad++;
-		max_levels++;
-	}
-	*res_bits = accbits;
-	*res_len = acclen;
-}
-
-/*
- *************************************************************************
- * Function:
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int writesyntaxelement_golomb(struct syntaxelement *se, int write_to_stream)
-{
-	unsigned int bits, len, i;
-	unsigned int grad[4], max_lev[4];
-
-	if (!(se->golomb_maxlevels & ~0xFF))
-		encode_golomb_word(se->value1, se->golomb_grad,
-				se->golomb_maxlevels, &bits, &len);
-	else {
-		for (i = 0UL; i < 4UL; i++) {
-			grad[i] = (se->golomb_grad >> (i << 3)) & 0xFFUL;
-			max_lev[i] = (se->golomb_maxlevels >> (i << 3))
-					& 0xFFUL;
-		}
-		encode_multilayer_golomb_word(se->value1, grad, max_lev, &bits,
-				&len);
-	}
-
-	se->len = len;
-	se->bitpattern = bits;
-
-	if (write_to_stream)
-		push_es(bits, len);
-	return se->len;
-}
-
-/*
- *************************************************************************
- * Function:Get coded block pattern and coefficients (run/level)
- from the bitstream
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-void read_cbpandcoeffsfrom_nal(struct img_par *img)
-{
-
-	int tablenum;
-	int inumblk;
-	int inumcoeff;
-	int symbol2D;
-	int escape_level_diff;
-	const int (*AVS_2DVLC_table_intra)[26][27];
-	const int (*AVS_2DVLC_table_chroma)[26][27];
-	int write_to_stream;
-	struct syntaxelement currse_enc;
-	struct syntaxelement *e_currse = &currse_enc;
-
-	int coeff_save[65][2];
-	int coeff_ptr;
-
-	int ii, jj;
-	int mb_nr = img->current_mb_nr;
-
-	int m2, jg2;
-	struct macroblock *curr_mb = &mb_data[mb_nr];
-
-	int block8x8;
-
-	int block_x, block_y;
-
-	struct slice_s *currslice = img->current_slice;
-	int level, run, coef_ctr, len, k, i0, j0, uv, qp;
-
-	int boff_x, boff_y, start_scan;
-	struct syntaxelement curr_se;
-	struct datapartition *dp;
-
-	AVS_2DVLC_table_intra = AVS_2DVLC_INTRA;
-	AVS_2DVLC_table_chroma = AVS_2DVLC_CHROMA;
-	write_to_stream = 1;
-
-	dct_pairs = -1;
-
-	curr_mb->qp = img->qp;
-	qp = curr_mb->qp;
-
-
-	for (block_y = 0; block_y < 4; block_y += 2) {/* all modes */
-	for (block_x = 0; block_x < 4; block_x += 2) {
-		block8x8 = 2 * (block_y / 2) + block_x / 2;
-		if (curr_mb->cbp & (1 << block8x8)) {
-			tablenum = 0;
-			inumblk = 1;
-			inumcoeff = 65;
-			coeff_save[0][0] = 0;
-			coeff_save[0][1] = 0;
-			coeff_ptr = 1;
-
-			b8_ctr = block8x8;
-
-			boff_x = (block8x8 % 2) << 3;
-			boff_y = (block8x8 / 2) << 3;
-
-			img->subblock_x = boff_x >> 2;
-			img->subblock_y = boff_y >> 2;
-
-			start_scan = 0;
-			coef_ctr = start_scan - 1;
-			level = 1;
-			img->is_v_block = 0;
-			img->is_intra_block = IS_INTRA(curr_mb);
-			for (k = start_scan;
-				(k < 65) && (level != 0);
-				k++) {
-
-				curr_se.context = LUMA_8x8;
-				curr_se.type =
-				(IS_INTRA(curr_mb)) ?
-					SE_LUM_AC_INTRA :
-					SE_LUM_AC_INTER;
-
-				dp = &(currslice->part_arr[0]);
-				curr_se.reading =
-					readrunlevel_aec_ref;
-				dp->
-				read_syntax_element(&curr_se,
-					img, dp);
-				level = curr_se.value1;
-				run = curr_se.value2;
-				len = curr_se.len;
-
-				if (level != 0) {
-					coeff_save[coeff_ptr][0] =
-					run;
-					coeff_save[coeff_ptr][1] =
-					level;
-					coeff_ptr++;
-				}
-
-
-
-				if (level != 0) {/* leave if len = 1 */
-					coef_ctr += run + 1;
-					if ((img->picture_structure
-						== FRAME)) {
-						ii =
-						SCAN[img->picture_structure]
-						[coef_ctr][0];
-						jj =
-						SCAN[img->picture_structure]
-						[coef_ctr][1];
-					} else {
-						ii =
-						SCAN[img->picture_structure]
-						[coef_ctr][0];
-						jj =
-						SCAN[img->picture_structure]
-						[coef_ctr][1];
-					}
-
-				}
-			}
-
-			while (coeff_ptr > 0) {
-				run =
-						coeff_save[coeff_ptr
-								- 1][0];
-				level =
-						coeff_save[coeff_ptr
-								- 1][1];
-
-				coeff_ptr--;
-
-				symbol2D = CODE2D_ESCAPE_SYMBOL;
-				if (level > -27 && level < 27
-					&& run < 26) {
-					if (tablenum == 0)
-
-						symbol2D =
-						AVS_2DVLC_table_intra
-						[tablenum]
-						[run][abs(
-						level)
-						- 1];
-					else
-
-						symbol2D =
-						AVS_2DVLC_table_intra
-						[tablenum]
-						[run][abs(
-					level)];
-					if (symbol2D >= 0
-							&& level
-									< 0)
-						symbol2D++;
-					if (symbol2D < 0)
-
-						symbol2D =
-						(CODE2D_ESCAPE_SYMBOL
-						+ (run
-						<< 1)
-						+ ((level
-						> 0) ?
-						1 :
-						0));
-				}
-
-				else {
-
-					symbol2D =
-						(CODE2D_ESCAPE_SYMBOL
-						+ (run
-						<< 1)
-						+ ((level
-						> 0) ?
-						1 :
-						0));
-				}
-
-
-
-				e_currse->type = SE_LUM_AC_INTER;
-				e_currse->value1 = symbol2D;
-				e_currse->value2 = 0;
-
-				e_currse->golomb_grad =
-						vlc_golomb_order
-						[0][tablenum][0];
-				e_currse->golomb_maxlevels =
-						vlc_golomb_order
-						[0][tablenum][1];
-
-				writesyntaxelement_golomb(
-						e_currse,
-						write_to_stream);
-
-				if (symbol2D
-						>= CODE2D_ESCAPE_SYMBOL) {
-
-					e_currse->type =
-							SE_LUM_AC_INTER;
-					e_currse->golomb_grad =
-							1;
-					e_currse->golomb_maxlevels =
-							11;
-					escape_level_diff =
-						abs(
-						level)
-						- ((run
-						> MaxRun[0][tablenum]) ?
-						1 :
-						refabslevel[tablenum][run]);
-					e_currse->value1 =
-							escape_level_diff;
-
-					writesyntaxelement_golomb(
-							e_currse,
-							write_to_stream);
-
-				}
-
-				if (abs(level)
-					> incvlc_intra[tablenum]) {
-					if (abs(level) <= 2)
-						tablenum =
-						abs(
-						level);
-					else if (abs(level) <= 4)
-						tablenum = 3;
-					else if (abs(level) <= 7)
-						tablenum = 4;
-					else if (abs(level)
-							<= 10)
-						tablenum = 5;
-					else
-						tablenum = 6;
-				}
-			}
-
-
-		}
-		}
-	}
-
-
-
-	m2 = img->mb_x * 2;
-	jg2 = img->mb_y * 2;
-
-
-	uv = -1;
-	block_y = 4;
-#if 0
-	qp = QP_SCALE_CR[curr_mb->qp];
-#endif
-	for (block_x = 0; block_x < 4; block_x += 2) {
-
-		uv++;
-
-
-		b8_ctr = (uv + 4);
-		if ((curr_mb->cbp >> (uv + 4)) & 0x1) {
-
-			tablenum = 0;
-			inumblk = 1;
-			inumcoeff = 65;
-			coeff_save[0][0] = 0;
-			coeff_save[0][1] = 0;
-			coeff_ptr = 1;
-
-			coef_ctr = -1;
-			level = 1;
-			img->subblock_x = 0;
-			img->subblock_y = 0;
-			curr_se.context = CHROMA_AC;
-			curr_se.type = (IS_INTRA(curr_mb) ?
-					SE_CHR_AC_INTRA :
-					SE_CHR_AC_INTER);
-			dp = &(currslice->part_arr[0]);
-			curr_se.reading = readrunlevel_aec_ref;
-			img->is_v_block = uv;
-			img->is_intra_block = IS_INTRA(curr_mb);
-			for (k = 0; (k < 65) && (level != 0); k++) {
-
-				dp->read_syntax_element
-				(&curr_se, img, dp);
-				level = curr_se.value1;
-				run = curr_se.value2;
-				len = curr_se.len;
-
-				if (level != 0) {
-					coeff_save[coeff_ptr][0] = run;
-					coeff_save[coeff_ptr][1] =
-							level;
-					coeff_ptr++;
-				}
-
-
-				if (level != 0) {
-					coef_ctr = coef_ctr + run + 1;
-					if ((img->picture_structure
-						== FRAME)
-						/*&& (!curr_mb->mb_field)*/) {
-						i0 =
-						SCAN[img->picture_structure]
-						[coef_ctr][0];
-						j0 =
-						SCAN[img->picture_structure]
-						[coef_ctr][1];
-					} else {
-						i0 =
-						SCAN[img->picture_structure]
-						[coef_ctr][0];
-						j0 =
-						SCAN[img->picture_structure]
-						[coef_ctr][1];
-					}
-
-				}
-			}
-
-			while (coeff_ptr > 0) {
-
-				run = coeff_save[coeff_ptr - 1][0];
-				level = coeff_save[coeff_ptr - 1][1];
-
-				coeff_ptr--;
-
-				symbol2D = CODE2D_ESCAPE_SYMBOL;
-				if (level > -27 && level < 27
-						&& run < 26) {
-					if (tablenum == 0)
-
-						symbol2D =
-						AVS_2DVLC_table_chroma
-						[tablenum][run][abs(
-						level)
-						- 1];
-					else
-						symbol2D =
-							AVS_2DVLC_table_chroma
-							[tablenum][run][abs(
-							level)];
-					if (symbol2D >= 0
-						&& level < 0)
-						symbol2D++;
-					if (symbol2D < 0)
-						symbol2D =
-						(CODE2D_ESCAPE_SYMBOL
-						+ (run
-						<< 1)
-						+ ((level
-						> 0) ?
-						1 :
-						0));
-				}
-
-				else {
-					symbol2D =
-					(CODE2D_ESCAPE_SYMBOL
-					+ (run
-					<< 1)
-					+ ((level
-					> 0) ?
-					1 :
-					0));
-				}
-
-				e_currse->type = SE_LUM_AC_INTER;
-				e_currse->value1 = symbol2D;
-				e_currse->value2 = 0;
-				e_currse->golomb_grad =
-						vlc_golomb_order[2]
-						[tablenum][0];
-				e_currse->golomb_maxlevels =
-						vlc_golomb_order[2]
-						[tablenum][1];
-
-				writesyntaxelement_golomb(e_currse,
-						write_to_stream);
-
-				/*
-				 * if (write_to_stream)
-				 * {
-				 * bitCount[BITS_COEFF_UV_MB]+=e_currse->len;
-				 * e_currse++;
-				 * curr_mb->currSEnr++;
-				 * }
-				 * no_bits+=e_currse->len;
-
-
-				 * if (icoef == 0) break;
-				 */
-
-				if (symbol2D >= CODE2D_ESCAPE_SYMBOL) {
-
-					e_currse->type = SE_LUM_AC_INTER;
-					e_currse->golomb_grad = 0;
-					e_currse->golomb_maxlevels = 11;
-					escape_level_diff =
-						abs(level)
-						- ((run
-						> MaxRun[2][tablenum]) ?
-						1 :
-						refabslevel[tablenum
-						+ 14][run]);
-					e_currse->value1 =
-							escape_level_diff;
-
-					writesyntaxelement_golomb(
-							e_currse,
-							write_to_stream);
-
-				}
-
-				if (abs(level)
-				> incvlc_chroma[tablenum]) {
-					if (abs(level) <= 2)
-						tablenum = abs(level);
-					else if (abs(level) <= 4)
-						tablenum = 3;
-					else
-						tablenum = 4;
-				}
-			}
-
-		}
-	}
-}
-
-/*
- *************************************************************************
- * Function:Get the syntax elements from the NAL
- * Input:
- * Output:
- * Return:
- * Attention:
- *************************************************************************
- */
-
-int read_one_macroblock(struct img_par *img)
-{
-	int i, j;
-
-	struct syntaxelement curr_se;
-	struct macroblock *curr_mb = &mb_data[img->current_mb_nr];
-
-	int cabp_flag;
-
-	int tempcbp;
-	int fixqp;
-
-	struct slice_s *currslice = img->current_slice;
-	struct datapartition *dp;
-
-	fixqp = (fixed_picture_qp || fixed_slice_qp);
-
-	for (i = 0; i < 8; i++)
-		for (j = 0; j < 8; j++) {
-			img->m8[0][i][j] = 0;
-			img->m8[1][i][j] = 0;
-			img->m8[2][i][j] = 0;
-			img->m8[3][i][j] = 0;
-		}
-
-	current_mb_skip = 0;
-
-	curr_mb->qp = img->qp;
-	curr_se.type = SE_MBTYPE;
-	curr_se.mapping = linfo_ue;
-
-	curr_mb->mb_type_2 = 0;
-
-	if (img->type == I_IMG)
-		curr_mb->mb_type = 0;
-
-	interpret_mb_mode_i(img);
-
-	init_macroblock(img);
-
-	if ((IS_INTRA(curr_mb)) && (img->abt_flag)) {
-
-#if TRACE
-		strncpy(curr_se.tracestring, "cabp_flag", TRACESTRING_SIZE);
-#endif
-
-		curr_se.len = 1;
-		curr_se.type = SE_CABP;
-		read_syntaxelement_flc(&curr_se);
-		cabp_flag = curr_se.value1;
-		if (cabp_flag == 0) {
-			curr_mb->CABP[0] = 0;
-			curr_mb->CABP[1] = 0;
-			curr_mb->CABP[2] = 0;
-			curr_mb->CABP[3] = 0;
-		} else {
-			for (i = 0; i < 4; i++) {
-				curr_se.len = 1;
-				curr_se.type = SE_CABP;
-				read_syntaxelement_flc(&curr_se);
-				curr_mb->CABP[i] = curr_se.value1;
-			}
-		}
-
-	} else {
-		curr_mb->CABP[0] = 0;
-		curr_mb->CABP[1] = 0;
-		curr_mb->CABP[2] = 0;
-		curr_mb->CABP[3] = 0;
-
-	}
-
-	if (IS_INTRA(curr_mb)) {
-		for (i = 0; i < /*5*/(chroma_format + 4); i++)
-
-			read_ipred_block_modes(img, i);
-	}
-
-	curr_se.type = SE_CBP_INTRA;
-	curr_se.mapping = linfo_cbp_intra;
-
-#if TRACE
-	snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP");
-#endif
-
-	if (img->type == I_IMG || IS_INTER(curr_mb)) {
-		curr_se.golomb_maxlevels = 0;
-
-		if (1) {
-			dp = &(currslice->part_arr[0]);
-			curr_se.reading = readcp_aec;
-			dp->read_syntax_element(&curr_se, img, dp);
-		}
-
-
-		curr_mb->cbp = curr_se.value1;
-		push_es(UE[NCBP[curr_se.value1][0]][0],
-				UE[NCBP[curr_se.value1][0]][1]);
-
-	}
-
-# if 1
-	if (curr_mb->cbp != 0)
-		tempcbp = 1;
-	else
-		tempcbp = 0;
-#else
-
-	if (chroma_format == 2)	{
-#if TRACE
-		snprintf(curr_se.tracestring, TRACESTRING_SIZE, "CBP422");
-#endif
-		curr_se.mapping = /*linfo_se*/linfo_ue;
-		curr_se.type = SE_CBP_INTRA;
-		readsyntaxelement_uvlc(&curr_se, inp);
-		curr_mb->cbp01 = curr_se.value1;
-		io_printf(" * UE cbp01 read : 0x%02X\n", curr_mb->cbp01);
-	}
-
-	if (chroma_format == 2)	{
-		if (curr_mb->cbp != 0 || curr_mb->cbp01 != 0)
-			tempcbp = 1;
-		else
-			tempcbp = 0;
-
-	} else {
-		if (curr_mb->cbp != 0)
-			tempcbp = 1;
-		else
-			tempcbp = 0;
-	}
-
-#endif
-
-	if (IS_INTRA(curr_mb) && (img->abt_flag) && (curr_mb->cbp & (0xF))) {
-		curr_mb->CABT[0] = curr_mb->CABP[0];
-		curr_mb->CABT[1] = curr_mb->CABP[1];
-		curr_mb->CABT[2] = curr_mb->CABP[2];
-		curr_mb->CABT[3] = curr_mb->CABP[3];
-	} else {
-
-		curr_mb->CABT[0] = 0;
-		curr_mb->CABT[1] = 0;
-		curr_mb->CABT[2] = 0;
-		curr_mb->CABT[3] = 0;
-
-		if (!fixqp && (tempcbp)) {
-			if (IS_INTER(curr_mb))
-				curr_se.type = SE_DELTA_QUANT_INTER;
-			else
-				curr_se.type = SE_DELTA_QUANT_INTRA;
-
-#if TRACE
-			snprintf(curr_se.tracestring,
-				TRACESTRING_SIZE, "Delta quant ");
-#endif
-
-			if (1) {
-				dp = &(currslice->part_arr[0]);
-				curr_se.reading = readdquant_aec;
-				dp->read_syntax_element(&curr_se, img, dp);
-			}
-
-			curr_mb->delta_quant = curr_se.value1;
-#ifdef DUMP_DEBUG
-			if (avs_get_debug_flag() & MB_INFO_DUMP) {
-				io_printf(" * SE delta_quant read : %d\n",
-					curr_mb->delta_quant);
-			}
-#endif
-			CHECKDELTAQP
-
-			if (transcoding_error_flag)
-				return -1;
-
-			img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
-					+ (MAX_QP - MIN_QP + 1))
-					% (MAX_QP - MIN_QP + 1) + MIN_QP;
-		}
-
-		if (fixqp) {
-			curr_mb->delta_quant = 0;
-			img->qp = (img->qp - MIN_QP + curr_mb->delta_quant
-					+ (MAX_QP - MIN_QP + 1))
-					% (MAX_QP - MIN_QP + 1) + MIN_QP;
-
-		}
-#ifdef DUMP_DEBUG
-		if (avs_get_debug_flag() & MB_INFO_DUMP)
-			io_printf(" - img->qp : %d\n", img->qp);
-#endif
-	}
-
-	read_cbpandcoeffsfrom_nal(img);
-	return DECODE_MB;
-}
-
-/*!
- ************************************************************************
- * \brief
- *    finding end of a slice in case this is not the end of a frame
- *
- * Unsure whether the "correction" below actually solves an off-by-one
- * problem or whether it introduces one in some cases :-(  Anyway,
- * with this change the bit stream format works with AEC again.
- * StW, 8.7.02
- ************************************************************************
- */
-int aec_startcode_follows(struct img_par *img, int eos_bit)
-{
-	struct slice_s *currslice = img->current_slice;
-	struct datapartition *dp;
-	unsigned int bit;
-	struct decoding_environment_s *dep_dp;
-
-	dp = &(currslice->part_arr[0]);
-	dep_dp = &(dp->de_aec);
-
-	if (eos_bit)
-		bit = biari_decode_final(dep_dp);
-	else
-		bit = 0;
-
-	return bit == 1 ? 1 : 0;
-}
-
-#ifdef AVSP_LONG_CABAC
-int process_long_cabac(void)
-#else
-void main(void)
-#endif
-{
-	int data32;
-	int current_header;
-	int i;
-	int tmp;
-	int ret;
-
-	int byte_startposition;
-	int aec_mb_stuffing_bit;
-	struct slice_s *currslice;
-#ifdef PERFORMANCE_DEBUG
-	pr_info("enter %s\r\n", __func__);
-#endif
-	transcoding_error_flag = 0;
-	ret = 0;
-	es_buf = es_write_addr_virt;
-
-	if (local_heap_init(MAX_CODED_FRAME_SIZE * 4) < 0) {
-		ret = -1;
-		goto End;
-	}
-
-	img = (struct img_par *)local_alloc(1, sizeof(struct img_par));
-	if (img	== NULL) {
-		no_mem_exit("main: img");
-		ret = -1;
-		goto End;
-	}
-	stat_bits_ptr = (struct stat_bits *)local_alloc(1,
-			sizeof(struct stat_bits));
-	if (stat_bits_ptr == NULL) {
-		no_mem_exit("main: stat_bits");
-		ret = -1;
-		goto End;
-	}
-
-	curr_stream = alloc_bitstream();
-	if (curr_stream == NULL) {
-		io_printf("alloc bitstream failed\n");
-		ret = -1;
-		goto End;
-	}
-
-	chroma_format = 1;
-	demulate_enable = 0;
-	img->seq_header_indicate = 1;
-
-#ifdef AVSP_LONG_CABAC
-	data32 = READ_VREG(LONG_CABAC_REQ);
-	progressive_sequence = (data32 >> 1) & 1;
-	fixed_picture_qp = (data32 >> 2) & 1;
-	img->picture_structure = (data32 >> 3) & 1;
-	img->type = (data32 >> 4) & 3;
-	skip_mode_flag = (data32 >> 6) & 1;
-
-	src_start = READ_VREG(LONG_CABAC_SRC_ADDR);
-	des_start = READ_VREG(LONG_CABAC_DES_ADDR);
-
-	data32 = READ_VREG(LONG_CABAC_PIC_SIZE);
-	horizontal_size = (data32 >> 0) & 0xffff;
-	vertical_size = (data32 >> 16) & 0xffff;
-	if (horizontal_size * vertical_size > 1920 * 1080) {
-		io_printf("pic size check failed: width = %d, height = %d\n",
-			horizontal_size, vertical_size);
-		ret = -1;
-		goto End;
-	}
-
-	vld_mem_start_addr = READ_VREG(VLD_MEM_VIFIFO_START_PTR);
-	vld_mem_end_addr = READ_VREG(VLD_MEM_VIFIFO_END_PTR);
-
-#else
-	progressive_sequence = 0;
-	fixed_picture_qp = 0;
-	img->picture_structure = 0;
-	img->type = I_IMG;
-	skip_mode_flag = 1;
-	horizontal_size = 1920;
-	vertical_size = 1080;
-
-	src_start = 0;
-#endif
-
-	if (horizontal_size % 16 != 0)
-		img->auto_crop_right = 16 - (horizontal_size % 16);
-	else
-		img->auto_crop_right = 0;
-
-	if (!progressive_sequence) {
-		if (vertical_size % 32 != 0)
-			img->auto_crop_bottom = 32 - (vertical_size % 32);
-		else
-			img->auto_crop_bottom = 0;
-	} else {
-		if (vertical_size % 16 != 0)
-			img->auto_crop_bottom = 16 - (vertical_size % 16);
-		else
-			img->auto_crop_bottom = 0;
-	}
-
-	img->width = (horizontal_size + img->auto_crop_right);
-	if (img->picture_structure)
-		img->height = (vertical_size + img->auto_crop_bottom);
-	else
-		img->height = (vertical_size + img->auto_crop_bottom) / 2;
-	img->width_cr = (img->width >> 1);
-
-	img->pic_width_inmbs = img->width / MB_BLOCK_SIZE;
-	img->pic_height_inmbs = img->height / MB_BLOCK_SIZE;
-	img->pic_size_inmbs = img->pic_width_inmbs * img->pic_height_inmbs;
-
-	io_printf(
-			"[LONG CABAC] Start Transcoding from 0x%x to 0x%x Size : %d x %d\r\n",
-			src_start, des_start, horizontal_size, vertical_size);
-#if 0
-	io_printf("VLD_MEM_VIFIFO_START_PTR %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_START_PTR));
-	io_printf("VLD_MEM_VIFIFO_CURR_PTR %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_CURR_PTR));
-	io_printf("VLD_MEM_VIFIFO_END_PTR %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_END_PTR));
-	io_printf("VLD_MEM_VIFIFO_WP %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_WP));
-	io_printf("VLD_MEM_VIFIFO_RP %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_RP));
-	io_printf("VLD_MEM_VBUF_RD_PTR %x\r\n",
-			READ_VREG(VLD_MEM_VBUF_RD_PTR));
-	io_printf("VLD_MEM_VIFIFO_BUF_CNTL %x\r\n",
-			READ_VREG(VLD_MEM_VIFIFO_BUF_CNTL));
-#endif
-	io_printf(
-			"[LONG CABAC] progressive_sequence : %d, fixed_picture_qp : %d, skip_mode_flag : %d\r\n",
-			progressive_sequence, fixed_picture_qp, skip_mode_flag);
-	io_printf("[LONG CABAC] picture_structure : %d, picture_type : %d\r\n",
-			img->picture_structure, img->type);
-
-	open_irabs(p_irabs);
-
-
-	if (initial_decode() == 0) {
-		io_printf("initial_decode failed\n");
-		ret = -1;
-		goto End;
-	}
-
-	init_es();
-
-	current_header = header();
-	io_printf("[LONG CABAC] header Return : %d\n", current_header);
-
-	tmp = slice_header(temp_slice_buf, first_slice_startpos,
-			first_slice_length);
-
-	init_contexts(img);
-	aec_new_slice();
-	byte_startposition = (curr_stream->frame_bitoffset) / 8;
-
-	currslice = img->current_slice;
-
-	if (1) {
-		for (i = 0; i < 1; i++) {
-			img->current_slice->part_arr[i].read_syntax_element =
-					read_syntaxelement_aec;
-			img->current_slice->part_arr[i].bitstream = curr_stream;
-		}
-		curr_stream = currslice->part_arr[0].bitstream;
-	}
-	if ((curr_stream->frame_bitoffset) % 8 != 0)
-		byte_startposition++;
-
-	arideco_start_decoding(&img->current_slice->part_arr[0].de_aec,
-			curr_stream->stream_buffer, (byte_startposition),
-			&(curr_stream->read_len), img->type);
-
-	img->current_mb_nr = 0;
-	total_mb_count = 0;
-	while (img->current_mb_nr < img->pic_size_inmbs)
-
-	{
-		start_macroblock(img);
-		if (-1 == read_one_macroblock(img)) {
-			ret = -1;
-			pr_info("macroblock trans failed, exit\n");
-			goto End;
-		}
-		if (img->cod_counter <= 0)
-			aec_mb_stuffing_bit = aec_startcode_follows(img, 1);
-		img->current_mb_nr++;
-	}
-
-	push_es(0xff, 8);
-	io_printf(" Total ES_LENGTH : %d\n", es_ptr);
-
-#ifdef AVSP_LONG_CABAC
-	push_es(0xff, 64);
-	if (es_buf_is_overflow) {
-		io_printf("fatal error: es_buf_is_overflow\n");
-		ret = -1;
-		goto End;
-	}
-
-	if (transcoding_error_flag == 0) {
-#if 1
-		dma_sync_single_for_device(amports_get_dma_device(),
-			es_write_addr_phy,
-			es_ptr, DMA_TO_DEVICE);
-
-		wmb(); /**/
-#endif
-	}
-#else
-	fclose(f_es);
-#endif
-
-End:
-#ifdef AVSP_LONG_CABAC
-	WRITE_VREG(LONG_CABAC_REQ, 0);
-#endif
-	local_heap_uninit();
-#ifdef PERFORMANCE_DEBUG
-	pr_info("exit %s\r\n", __func__);
-#endif
-	return ret;
-}
-#endif
diff --git a/drivers/frame_provider/decoder/avs2/Makefile b/drivers/frame_provider/decoder/avs2/Makefile
index 5fe8566..04c7767 100644
--- a/drivers/frame_provider/decoder/avs2/Makefile
+++ b/drivers/frame_provider/decoder/avs2/Makefile
@@ -1,2 +1,7 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += amvdec_avs2.o
-amvdec_avs2-objs += vavs2.o avs2_bufmgr.o
+MODULE_NAME = amvdec_avs2
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs2.o avs2_bufmgr.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
index de9a3d2..143acdc 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
+++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
@@ -1,22 +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:
-*/
+ * 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>
@@ -36,24 +36,21 @@
 #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 <linux/sched/clock.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
 #include "../utils/decoder_mmu_box.h"
 #include "../utils/decoder_bmmu_box.h"
-#include "avs2_global.h"
-
-#include <linux/amlogic/media/utils/vdec_reg.h>
 #include "../utils/vdec.h"
 #include "../utils/amvdec.h"
+#include "avs2_global.h"
 
 #undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
 
 #define assert(chk_cond) {\
 	if (!(chk_cond))\
@@ -83,13 +80,11 @@
 		for (pos = 0; pos < numCoeff; pos++) {
 			if (Alfp->componentID == ALF_Cb)
 				Alfp->coeffmulti[0][pos] =
-					get_param(
-					rpm_param->alf.alf_cb_coeffmulti[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],
+					get_param(rpm_param->alf.alf_cr_coeffmulti[pos],
 					"Chroma ALF coefficients");
 #if Check_Bitstream
 			if (pos <= 7)
@@ -119,8 +114,7 @@
 		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
+					symbol = get_param(rpm_param->alf.region_distance
 						[region_distance_idx++],
 						"Region distance");
 				} else {
@@ -132,30 +126,21 @@
 
 			for (pos = 0; pos < numCoeff; pos++) {
 				Alfp->coeffmulti[f][pos] =
-				get_param(
-					rpm_param->alf.alf_y_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);
+					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);
+					assert(Alfp->coeffmulti[f][pos] >= -1088 &&
+						Alfp->coeffmulti[f][pos] <= 1071);
 #endif
-
 			}
 		}
 
 #if Check_Bitstream
 		assert(pre_symbole >= 0 && pre_symbole <= 15);
-
 #endif
 	}
 	break;
@@ -175,16 +160,13 @@
 	int32_t compIdx;
 	if (input->alf_enable) {
 		img->pic_alf_on[0] =
-			get_param(
-			rpm_param->alf.picture_alf_enable_Y,
+			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,
+			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,
+			get_param(rpm_param->alf.picture_alf_enable_Cr,
 			"alf_pic_flag_Cr");
 
 		avs2_dec->m_alfPictureParam[ALF_Y].alf_flag
@@ -219,24 +201,16 @@
 	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,
+		get_param(rpm_param->p.progressive_sequence,
 			"progressive_sequence");
 #if INTERLACE_CODING
 	hd->is_field_sequence           =
-		get_param(
-			rpm_param->p.is_field_sequence,
+		get_param(rpm_param->p.is_field_sequence,
 			"field_coded_sequence");
 #endif
 #if HALF_PIXEL_COMPENSATION || HALF_PIXEL_CHROMA
@@ -255,102 +229,84 @@
 		input->output_bit_depth =
 			get_param(rpm_param->p.sample_precision,
 			"sample_precision");
-		input->output_bit_depth =
-			6 + (input->output_bit_depth) * 2;
+		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;
+		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");
+			"sample_precision");
 	}
 	hd->aspect_ratio_information    =
 		get_param(rpm_param->p.aspect_ratio_information,
-			"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*/
+		"temporal_id exist flag"); /*get
+		Extension 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);
-
+		"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;
+		"mhpskip enabled") & 0x1;
 	hd->dhp_enabled             =
 		get_param(rpm_param->p.avs2_seq_flags >> DHP_ENABLED_BIT,
-			"dhp enabled") & 0x1;
+		"dhp enabled") & 0x1;
 	hd->wsm_enabled             =
 		get_param(rpm_param->p.avs2_seq_flags >> WSM_ENABLED_BIT,
-			"wsm enabled") & 0x1;
+		"wsm enabled") & 0x1;
 
 	img->inter_amp_enable       =
 		get_param(rpm_param->p.avs2_seq_flags >> INTER_AMP_ENABLE_BIT,
-			"Asymmetric Motion Partitions") & 0x1;
+		"Asymmetric Motion Partitions") & 0x1;
 	input->useNSQT              =
 		get_param(rpm_param->p.avs2_seq_flags >> USENSQT_BIT,
-			"useNSQT") & 0x1;
+		"useNSQT") & 0x1;
 	input->useSDIP              =
 		get_param(rpm_param->p.avs2_seq_flags >> USESDIP_BIT,
-			"useNSIP") & 0x1;
+		"useNSIP") & 0x1;
 
 	hd->b_secT_enabled          =
 		get_param(rpm_param->p.avs2_seq_flags >> B_SECT_ENABLED_BIT,
-			"secT enabled") & 0x1;
+		"secT enabled") & 0x1;
 
 	input->sao_enable           =
 		get_param(rpm_param->p.avs2_seq_flags >> SAO_ENABLE_BIT,
-			"SAO Enable Flag") & 0x1;
+		"SAO Enable Flag") & 0x1;
 	input->alf_enable           =
 		get_param(rpm_param->p.avs2_seq_flags >> ALF_ENABLE_BIT,
-			"ALF Enable Flag") & 0x1;
+		"ALF Enable Flag") & 0x1;
 	hd->b_pmvr_enabled          =
 		get_param(rpm_param->p.avs2_seq_flags >> B_PMVR_ENABLED_BIT,
-			"pmvr enabled") & 0x1;
-
+		"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  =
@@ -359,23 +315,19 @@
 	}
 
 	input->crossSliceLoopFilter    =
-		get_param(rpm_param->p.avs2_seq_flags
-			>> CROSSSLICELOOPFILTER_BIT,
-			"Cross Loop Filter Flag") & 0x1;
+		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");
+		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;
@@ -383,26 +335,22 @@
 	img->width_cr       = (img->width >> 1);
 
 	if (input->chroma_format == 1) {
-		img->height_cr
-		= (img->height >> 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);
+	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 = 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;
@@ -416,13 +364,11 @@
 #endif
 
 	hd->time_code_flag       =
-		get_param(rpm_param->p.time_code_flag,
-		"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");
+			get_param(rpm_param->p.time_code, "time_code");
 	}
 	if (hd->background_picture_enable) {
 		hd->background_picture_flag =
@@ -430,16 +376,14 @@
 			"background_picture_flag");
 
 		if (hd->background_picture_flag) {
-			img->typeb =
-				BACKGROUND_IMG;
+			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,
+				get_param(rpm_param->p.background_picture_output_flag,
 				"background_picture_output_flag");
 		}
 	}
@@ -447,10 +391,7 @@
 
 	{
 		img->coding_order         =
-			get_param(rpm_param->p.coding_order,
-			"coding_order");
-
-
+			get_param(rpm_param->p.coding_order, "coding_order");
 
 #if M3480_TEMPORAL_SCALABLE
 		if (hd->temporal_id_exist_flag == 1) {
@@ -478,19 +419,12 @@
 			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 = get_param(rpm_param->p.predict, "use RCS in SPS");
+			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.referred_by_others =
+				get_param(rpm_param->p.referred_by_others_cur, "referred by others");
 			hd->curr_RPS.num_of_ref =
 				get_param(rpm_param->p.num_of_ref_cur,
 				"num of reference picture");
@@ -516,51 +450,34 @@
 					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,
+		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,
+			img->picture_structure   = get_param(rpm_param->p.picture_structure,
 				"picture_structure");
 		} else {
-			img->picture_structure
-				= 1;
+			img->picture_structure = 1;
 		}
 
-		hd->top_field_first =
-			get_param(rpm_param->p.top_field_first,
+		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,
+		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,
+			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;
-
 }
 
 /*
@@ -577,9 +494,6 @@
 	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");
@@ -589,8 +503,7 @@
 			hd->picture_coding_type == 3)) {
 		if (hd->picture_coding_type == 1) {
 			hd->background_pred_flag       =
-				get_param(
-				rpm_param->p.background_pred_flag,
+				get_param(rpm_param->p.background_pred_flag,
 				"background_pred_flag");
 		} else {
 			hd->background_pred_flag = 0;
@@ -598,11 +511,8 @@
 		if (hd->background_pred_flag == 0) {
 
 			hd->background_reference_enable =
-				get_param(
-				rpm_param->
-				p.background_reference_enable,
+				get_param(rpm_param->p.background_reference_enable,
 				"background_reference_enable");
-
 		} else {
 #if RD170_FIX_BG
 			hd->background_reference_enable = 1;
@@ -616,20 +526,14 @@
 		hd->background_reference_enable = 0;
 	}
 
-
-
 	if (hd->picture_coding_type == 1) {
-		img->type =
-			P_IMG;
+		img->type = P_IMG;
 	} else if (hd->picture_coding_type == 3) {
-		img->type =
-			F_IMG;
+		img->type = F_IMG;
 	} else {
-		img->type =
-			B_IMG;
+		img->type = B_IMG;
 	}
 
-
 	if (hd->picture_coding_type == 1 &&
 		hd->background_pred_flag) {
 		img->typeb = BP_IMG;
@@ -637,60 +541,45 @@
 		img->typeb = 0;
 	}
 
-
 	{
 		img->coding_order         =
-			get_param(
-			rpm_param->p.coding_order,
-			"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");
+			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");
+				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");
+		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");
+			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.referred_by_others =
+				get_param(rpm_param->p.referred_by_others_cur,
+				"referred by others");
 			hd->curr_RPS.num_of_ref =
-				get_param(
-				rpm_param->p.num_of_ref_cur,
+				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],
+					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,
+				get_param(rpm_param->p.num_to_remove_cur,
 				"num of removed picture");
 #ifdef SANITY_CHECK
 			if (hd->curr_RPS.num_to_remove > MAXREF)	{
@@ -706,75 +595,52 @@
 					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,
+		get_param(rpm_param->p.progressive_frame,
 		"progressive_frame");
 
 	if (!hd->progressive_frame) {
 		img->picture_structure  =
-		get_param(rpm_param->p.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,
+		get_param(rpm_param->p.top_field_first,
 		"top_field_first");
 	hd->repeat_first_field      =
-	get_param(rpm_param->p.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,
+			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,
+		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)
-
-	{
+	if (img->coding_order  <  img->PrevPicDistanceLsb) {
 		int32_t i, j;
 
 		hc->total_frames++;
@@ -810,8 +676,7 @@
 		img->tr = img->coding_order +
 		hd->displaydelay - hd->picture_reorder_delay;
 	} else {
-		img->tr =
-		img->coding_order;
+		img->tr = img->coding_order;
 	}
 
 #if REMOVE_UNUSED
@@ -820,7 +685,6 @@
 	img->pic_distance = img->tr % 256;
 #endif
 	hc->picture_distance = img->pic_distance;
-
 }
 
 int32_t avs2_init_global_buffers(struct avs2_decoder *avs2_dec)
@@ -832,9 +696,7 @@
 	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;
@@ -844,15 +706,13 @@
 	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;
+		avs2_dec->fref[refnum]->referred_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;
@@ -862,13 +722,13 @@
 	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->referred_by_others = -1;
 	avs2_dec->m_bg->imgtr_fwRefDistance = -256;
 	init_frame_t(avs2_dec->m_bg);
 	avs2_dec->m_bg->index = refnum;
@@ -880,9 +740,6 @@
 		((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;
 }
@@ -910,12 +767,11 @@
 #endif
 		if (is_avs2_print_bufmgr_detail())
 			pr_info("%s[t] avs2_dec->fref[%d]@0x%p\n",
-			__func__, refnum, avs2_dec->fref[refnum]);
+				__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;
+		avs2_dec->fref[refnum]->referred_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));
 	}
@@ -923,10 +779,10 @@
 
 	if (is_avs2_print_bufmgr_detail())
 		pr_info("%s[t] avs2_dec->m_bg@0x%p\n",
-		__func__, avs2_dec->m_bg);
+			__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->referred_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));
@@ -937,9 +793,6 @@
 		((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
@@ -949,7 +802,7 @@
 	memset(currfref, 0, sizeof(struct avs2_frame_s));
 	currfref->imgcoi_ref          = -257;
 	currfref->is_output           = -1;
-	currfref->refered_by_others   = -1;
+	currfref->referred_by_others   = -1;
 	currfref->imgtr_fwRefDistance = -256;
 	memset(currfref->ref_poc, 0, sizeof(currfref->ref_poc));
 }
@@ -961,8 +814,6 @@
 
 	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, "[");
@@ -970,9 +821,7 @@
 #if RD1510_FIX_BG
 			if (img->type == B_IMG) {
 				sprintf(str_tmp, "%4d    ",
-					hc->f_rec->
-					ref_poc[
-					img->num_of_references - 1 - i]);
+					hc->f_rec->ref_poc[img->num_of_references - 1 - i]);
 			} else {
 				sprintf(str_tmp, "%4d    ",
 					hc->f_rec->ref_poc[i]);
@@ -981,7 +830,6 @@
 			sprintf(str_tmp, "%4d     ",
 				avs2_dec->fref[i]->imgtr_fwRefDistance);
 #endif
-
 			str_tmp[5] = '\0';
 			strcat(str, str_tmp);
 		}
@@ -991,7 +839,7 @@
 	}
 }
 
-void prepare_RefInfo(struct avs2_decoder *avs2_dec)
+int prepare_RefInfo(struct avs2_decoder *avs2_dec)
 {
 	struct ImageParameters_s    *img = &avs2_dec->img;
 	struct Video_Com_data_s *hc = &avs2_dec->hc;
@@ -999,7 +847,9 @@
 
 	int32_t i, j;
 	int32_t ii;
+	int32_t tmp_ref;
 	struct avs2_frame_s *tmp_fref;
+	int32_t error_mark = 0;
 
 	/*update IDR frame*/
 	if (img->tr > hd->next_IDRtr && hd->curr_IDRtr != hd->next_IDRtr) {
@@ -1009,7 +859,6 @@
 	/* 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",
@@ -1026,7 +875,6 @@
 			avs2_dec->fref[ii]->imgtr_fwRefDistance);
 	}
 	}
-#endif
 
 	for (i = 0; i < hd->curr_RPS.num_of_ref; i++) {
 		/*int32_t accumulate = 0;*/
@@ -1036,8 +884,7 @@
 #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 -
+			if (avs2_dec->fref[j]->imgcoi_ref == img->coding_order -
 				hd->curr_RPS.ref_pic[i]) {
 				break;
 			}
@@ -1056,15 +903,12 @@
 				}
 			}
 			if (k == avs2_dec->ref_maxbuffer) {
-				tmp_tr =
-				-1-1;
+				tmp_tr = -1-1;
 			} else {
-				tmp_tr =
-					avs2_dec->fref[k]->imgtr_fwRefDistance;
+				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;
+				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] ==
@@ -1089,28 +933,46 @@
 			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);
+				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 &&
+	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[1]->imgtr_fwRefDistance >= img->tr
+		|| avs2_dec->fref[1]->imgtr_fwRefDistance == -256))) {
+		if (get_error_policy(avs2_dec) & 0x2) {
+			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 (avs2_dec->fref[1]->imgtr_fwRefDistance != -256) {
+				avs2_dec->bufmgr_error_flag = 1;
+			}
+			return -1;
+		} else {
+			error_mark = 1;
+		}
+	}
+	if (img->type == P_IMG) {
+		for (ii = 0; ii < img->num_of_references;ii++) {
+			tmp_ref = img->coding_order - hd->curr_RPS.ref_pic[ii];
+			if ((avs2_dec->fref[ii]->imgcoi_ref != tmp_ref) &&
+				(avs2_dec->fref[ii]->imgcoi_ref != (tmp_ref - 256))) {
+				if (get_error_policy(avs2_dec) & 0x2) {
+					pr_info("wrong reference configuration for P frame\n");
+					pr_info("fref[%d] imgcoi_ref %d, ref_pic[%d] %d\n",
+						ii,avs2_dec->fref[ii]->imgcoi_ref,
+						ii,hd->curr_RPS.ref_pic[ii]);
+					return -1;
+				} else {
+					error_mark = 1;
+				}
+			}
+		}
 	}
 
 #if !FIX_PROFILE_LEVEL_DPB_RPS_1
@@ -1131,8 +993,7 @@
 			avs2_dec->fref[j]->temporal_id = -1;
 #endif
 			if (avs2_dec->fref[j]->is_output == -1) {
-				avs2_dec->fref[j]->
-				imgtr_fwRefDistance = -256;
+				avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
 			}
 		}
 	}
@@ -1143,23 +1004,19 @@
 	/*   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)
+			|| 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--;
+		pr_info("%s, warning, no enough buf\n", __func__);
+		return -2;
 	}
 
 	hc->f_rec        = avs2_dec->fref[i];
@@ -1171,28 +1028,24 @@
 #endif
 	hc->f_rec->is_output = 1;
 #ifdef AML
-	hc->f_rec->error_mark = 0;
+	hc->f_rec->error_mark = error_mark;
 	hc->f_rec->decoded_lcu = 0;
 	hc->f_rec->slice_type = img->type;
+	hc->f_rec->time = div64_u64(local_clock(), 1000) - avs2_dec->start_time;
 #endif
-	hc->f_rec->refered_by_others = hd->curr_RPS.referd_by_others;
+	hc->f_rec->referred_by_others = hd->curr_RPS.referred_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);
+		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;
+			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;
+		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
@@ -1206,8 +1059,7 @@
 	if (img->type == INTRA_IMG) {
 		int32_t l;
 		for (l = 0; l < 4; l++) {
-			hc->f_rec->ref_poc[l]
-			= img->tr;
+			hc->f_rec->ref_poc[l] = img->tr;
 		}
 	}
 
@@ -1223,19 +1075,19 @@
 		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;
+				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",
+			"fref[%d]: index %d imgcoi_ref %d imgtr_fwRefDistance %d referred %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]->referred_by_others,
 			avs2_dec->fref[ii]->is_output,
 			avs2_dec->fref[ii]->bg_flag,
 			avs2_dec->fref[ii]->vf_ref,
@@ -1245,11 +1097,10 @@
 			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]
-		);
+			avs2_dec->fref[ii]->ref_poc[6]);
+		}
 	}
-	}
-#endif
+	return 0;
 }
 
 int32_t init_frame(struct avs2_decoder *avs2_dec)
@@ -1276,18 +1127,17 @@
 		hc->cur_pic = avs2_dec->m_bg;
 #endif
 	} else {
-		prepare_RefInfo(avs2_dec);
+		if (prepare_RefInfo(avs2_dec) < 0)
+			return -1;
 #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;
+		avs2_dec->bk_img_is_top_field = img->is_top_field;
 	}
 #endif
 	return 0;
@@ -1296,10 +1146,8 @@
 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];
+	for (i = pos; i < data->buffer_num - 1; i++) {
+		data->stdoutdata[i] = data->stdoutdata[i + 1];
 	}
 	data->buffer_num--;
 }
@@ -1331,9 +1179,8 @@
 			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) {
+				avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag
+				== 0) {
 				/*write_GB_frame(hd->p_out_background);*/
 			} else {
 				write_frame(avs2_dec,
@@ -1349,36 +1196,11 @@
 		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;
+		avs2_dec->fref[j]->referred_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;
@@ -1402,22 +1224,14 @@
 	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;
+	p_outdata->background_picture_output_flag = hd->background_picture_output_flag;
 		/*Longfei.Wang@mediatek.com*/
 #endif
 
@@ -1441,10 +1255,6 @@
 			== (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 {
@@ -1464,8 +1274,7 @@
 		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)
+				+ avs2_dec->outprint.stdoutdata[i].picture_reorder_delay)
 				<= (int32_t)img->coding_order)) {
 				pos = i;
 				tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
@@ -1483,18 +1292,12 @@
 		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) {
-				/**/
-				/**/
+				avs2_dec->outprint.stdoutdata[pos].background_picture_output_flag == 0) {
 			} else {
-				write_frame(avs2_dec,
-				avs2_dec->outprint.stdoutdata[pos].tr);
+				write_frame(avs2_dec, avs2_dec->outprint.stdoutdata[pos].tr);
 			}
-#endif
 			delete_trbuffer(&avs2_dec->outprint, pos);
 		}
 
@@ -1508,16 +1311,14 @@
 		int32_t tmp_min, pos = -1;
 		tmp_min = 1 << 20;
 
-		for (i = 0; i <
-			avs2_dec->outprint.buffer_num; i++) {
+		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;
+				tmp_min = avs2_dec->outprint.stdoutdata[i].tr;
 			}
 		}
 
@@ -1532,24 +1333,20 @@
 #else
 				if (avs2_dec->outprint.stdoutdata[pos].typeb
 					== BACKGROUND_IMG &&
-					hd->background_picture_output_flag
-					== 0) {
+					hd->background_picture_output_flag == 0) {
 #endif
-					write_GB_frame(
-						hd->p_out_background);
+					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)
@@ -1565,18 +1362,15 @@
 			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;
+			if (avs2_dec->fref[j]->referred_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);
+					pr_info("%s, fref index %d\n", __func__, j);
 			}
 			break;
 		}
@@ -1594,25 +1388,10 @@
 	int8_t *Frmfld;
 	int8_t Frm[] = "FRM";
 	int8_t Fld[] = "FLD";
-	struct STDOUT_DATA_s *p_stdoutdata
-	= &data->stdoutdata[pos];
+	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) {
+	if (p_stdoutdata->picture_structure) {
 		Frmfld = Frm;
 	} else {
 		Frmfld = Fld;
@@ -1624,11 +1403,8 @@
 #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)
@@ -1638,8 +1414,6 @@
 #endif
 		{
 			hd->vec_flag = 0;
-			/*fprintf(stdout, "Video Edit
-			  Code\n");*/
 		}
 	}
 
@@ -1659,22 +1433,9 @@
 #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++;
 }
 
@@ -1698,11 +1459,6 @@
 			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;
@@ -1711,13 +1467,10 @@
 				memcpy(seq_checker_buf, Buf, length);
 #endif
 			}
-
-
 		}
 #endif
 #if RD170_FIX_BG
-		if (input->alf_enable
-			&& alfParAllcoated == 1) {
+		if (input->alf_enable && alfParAllcoated == 1) {
 			ReleaseAlfGlobalBuffer();
 			alfParAllcoated = 0;
 		}
@@ -1726,13 +1479,10 @@
 #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
@@ -1749,13 +1499,9 @@
 #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");
+				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);
@@ -1778,9 +1524,6 @@
 		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;
@@ -1794,22 +1537,6 @@
 		/* 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;
 		}
 
@@ -1819,9 +1546,6 @@
 		}
 		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;
 		}
 
@@ -1844,7 +1568,6 @@
 	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
@@ -1881,7 +1604,6 @@
 	int32_t lcu_y_num_div;
 
 	int32_t N8_SizeScale;
-	/*pr_info("%s\n", __func__);*/
 	{
 		N8_SizeScale = 1;
 
@@ -1922,20 +1644,10 @@
 		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);
+		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;
 	}
@@ -1944,27 +1656,13 @@
 		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);
+	if (init_frame(avs2_dec) < 0) {
+		pr_info("%s, warning, init_frame error!\n", __func__);
+		return -1;
+	}
 
 	img->types = img->type;   /* jlzheng 7.15*/
 
@@ -2031,7 +1729,6 @@
 	/* 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
@@ -2039,8 +1736,7 @@
 	{
 		int32_t i, j;
 		if (is_avs2_print_bufmgr_detail()) {
-			pr_info(
-				"%s, coding_order %d to remove %d buf: ",
+			pr_info("%s, coding_order %d to remove %d buf: ",
 				__func__,
 				img->coding_order,
 				hd->curr_RPS.num_to_remove);
@@ -2060,12 +1756,11 @@
 			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;
+				avs2_dec->fref[j]->referred_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]->imgtr_fwRefDistance = -256;
 					avs2_dec->fref[j]->imgcoi_ref = -257;
 					avs2_dec->fref[j]->temporal_id = -1;
 
@@ -2076,8 +1771,7 @@
 				avs2_dec->fref[j]->temporal_id = -1;
 #endif
 				if (avs2_dec->fref[j]->is_output == -1) {
-					avs2_dec->fref[j]->imgtr_fwRefDistance
-						= -256;
+					avs2_dec->fref[j]->imgtr_fwRefDistance = -256;
 				}
 #endif
 			}
@@ -2085,7 +1779,6 @@
 	}
 #endif
 
-
 	/*! TO 19.11.2001 Known Problem: for init_frame
 	 * we have to know the picture type of the
 	 * actual frame*/
@@ -2143,8 +1836,7 @@
 		}
 		for (j = 0; j < 16; j++) {
 			for (k = 0; k < 9; k++) {
-				avs2_dec->
-				m_alfPictureParam[i].coeffmulti[j][k] = 0;
+				avs2_dec->m_alfPictureParam[i].coeffmulti[j][k] = 0;
 				/*16*9*/
 			}
 		}
@@ -2159,15 +1851,6 @@
 		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;
@@ -2184,7 +1867,6 @@
 
 	img->imgcoi_next_ref = 0;
 
-
 	img->num_of_references = 0;
 	hc->seq_header = 0;
 
@@ -2200,6 +1882,5 @@
 
 	/* time for total decoding session*/
 	hc->tot_time = 0;
-
 }
 
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h
index be35a5e..b3b0feb 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_global.h
+++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -1,47 +1,22 @@
-/* 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.
+ * 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 _GLOBAL_H_
 #define _GLOBAL_H_
 
@@ -141,7 +116,7 @@
   /* 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_M1_FUNCTION 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 */
@@ -172,7 +147,7 @@
 #define AVS2_HDR_Tec                       1
 #if AVS2_HDR_Tec
 #define HDR_CHROMA_DELTA_QP                1 /* M3905 */
-#define HDR_ADPTIVE_UV_DELTA                  1
+#define HDR_ADAPTIVE_UV_DELTA                  1
 #endif
 /*
  *************************************
@@ -601,7 +576,7 @@
 	int32_t copyright_number;
 };
 
-struct CameraParamters_s {
+struct CameraParameters_s {
 	int32_t reserved;
 	int32_t camera_id;
 	int32_t height_of_image_device;
@@ -746,7 +721,7 @@
 	byte ***ref;
 
 	int32_t imgtr_fwRefDistance;
-	int32_t refered_by_others;
+	int32_t referred_by_others;
 	int32_t is_output;
 	int32_t to_prepare_disp;
 #if M3480_TEMPORAL_SCALABLE
@@ -789,7 +764,7 @@
 	int BUF_index;
 	int pic_w;
 	int pic_h;
-	int stream_offset;
+	u32 stream_offset;
 	u32 pts;
 	u64 pts64;
 	/**/
@@ -804,7 +779,7 @@
 	int mv_buf_index;
 #endif
 
-	/* picture qos infomation*/
+	/* picture qos information*/
 	int max_qp;
 	int avg_qp;
 	int min_qp;
@@ -820,6 +795,9 @@
 
 	char *cuva_data_buf;
 	int  cuva_data_size;
+#ifdef AML
+	u64 time;
+#endif
 };
 
 
@@ -858,7 +836,7 @@
 
 	int32_t **predBlock;             /* !< current best prediction mode */
 	int32_t **predBlockTmp;
-	/* !< the diff pixel values between orginal image and prediction */
+	/* !< the diff pixel values between original image and prediction */
 	int32_t **resiY;
 	/* !< Array containing square values,used for snr computation */
 	int32_t *quad;
@@ -1093,7 +1071,7 @@
 /*#include "commonVariables.h"*/
 
 /*
-extern struct CameraParamters_s *camera;
+extern struct CameraParameters_s *camera;
 extern struct SNRParameters_s *snr;
 extern struct ImageParameters_s *img;
  */
@@ -1181,7 +1159,7 @@
 	int32_t poc;
 	int32_t qp_offset;
 	int32_t num_of_ref;
-	int32_t referd_by_others;
+	int32_t referred_by_others;
 	int32_t ref_pic[MAXREF];
 	int32_t predict;
 	int32_t deltaRPS;
@@ -1333,8 +1311,8 @@
 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 slice_horizontal_position;       /* added by mz, 2008.04 */
+int32_t slice_horizontal_position_extension;
 
 int32_t StartCodePosition;
 int32_t background_pred_flag;
@@ -1588,7 +1566,7 @@
 		uint16_t displaydelay; /*???*/
 		uint16_t predict;     /*???*/
 		uint16_t RPS_idx;      /*???*/
-		uint16_t referd_by_others_cur;
+		uint16_t referred_by_others_cur;
 		uint16_t num_of_ref_cur;
 		uint16_t ref_pic_cur[8];
 		uint16_t num_to_remove_cur;
@@ -1667,6 +1645,9 @@
 	int32_t to_prepare_disp_count;
 	int8_t bufmgr_error_flag;
 #endif
+#ifdef AML
+	u64 start_time;
+#endif
 };
 
 
@@ -1686,5 +1667,6 @@
 
 extern bool is_avs2_print_param(void);
 extern bool is_avs2_print_bufmgr_detail(void);
+extern int get_error_policy(struct avs2_decoder *avs2_dec);
 #endif
 
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c
index e21dc55..ba0a363 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.c
+++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -1,7 +1,5 @@
- /*
- * drivers/amlogic/amports/avs2.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+/*
+ * 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
@@ -13,7 +11,12 @@
  * 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>
@@ -34,30 +37,37 @@
 #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 "../utils/decoder_mmu_box.h"
-#include "../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 "../utils/vdec.h"
-#include "../utils/amvdec.h"
-
 #include <linux/amlogic/media/video_sink/video.h>
 #include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+
+#include <linux/slab.h>
+#include <linux/sched/clock.h>
+#include <uapi/linux/tee.h>
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../include/regs/dos_registers.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
 #include "../utils/config_parser.h"
 #include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
 #include "../utils/vdec_feature.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "avs2_global.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+
+#define MEM_NAME "codec_avs2"
 
 #define I_ONLY_SUPPORT
 #define MIX_STREAM_SUPPORT
@@ -68,7 +78,6 @@
 #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
@@ -96,8 +105,6 @@
 
 #define HEVC_SAO_CTRL9                             0x362d
 
-
-
 /*
  * AVS2_DEC_STATUS define
 */
@@ -141,11 +148,10 @@
 #define AVS2_ACTION_DONE                     0xff
 /*AVS2_DEC_STATUS end*/
 
-
 #define VF_POOL_SIZE        32
 
 #undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
 
 #define DECODE_MODE_SINGLE				(0 | (0x80 << 24))
 #define DECODE_MODE_MULTI_STREAMBASE	(1 | (0x80 << 24))
@@ -155,7 +161,6 @@
 #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"
@@ -170,43 +175,43 @@
 #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
+	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] = {
@@ -227,13 +232,9 @@
 	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
@@ -288,12 +289,17 @@
 static u32 double_write_mode;
 static u32 without_display_mode;
 
+/*
+bit0: if dpb abnormal, check dpb buffer status and flush dpb.
+bit1: 0:show error frame.
+*/
+static unsigned int error_proc_policy = 0x3;
+
 static u32 mv_buf_dynamic_alloc;
 
 #define DRIVER_NAME "amvdec_avs2"
 #define DRIVER_HEADER_NAME "amvdec_avs2_header"
 
-
 #define PUT_INTERVAL        (HZ/100)
 #define ERROR_SYSTEM_RESET_COUNT   200
 
@@ -301,7 +307,7 @@
 #define PTS_NONE_REF_USE_DURATION 1
 
 #define PTS_MODE_SWITCHING_THRESHOLD           3
-#define PTS_MODE_SWITCHING_RECOVERY_THREASHOLD 3
+#define PTS_MODE_SWITCHING_RECOVERY_THRESHOLD 3
 
 #define DUR2PTS(x) ((x)*90/96)
 
@@ -360,9 +366,6 @@
 
 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);
@@ -397,22 +400,12 @@
 	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
@@ -442,7 +435,7 @@
 #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_QOS_INFO                 0x8000
 #define AVS2_DBG_DIS_LOC_ERROR_PROC       0x10000
 #define AVS2_DBG_DIS_SYS_ERROR_PROC   0x20000
 #define AVS2_DBG_DUMP_PIC_LIST       0x40000
@@ -558,19 +551,11 @@
 #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
 #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;
@@ -625,6 +610,13 @@
 #define DEC_RESULT_EOS              9
 #define DEC_RESULT_FORCE_EXIT       10
 
+#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
+
 static void avs2_work(struct work_struct *work);
 struct loop_filter_info_n;
 struct loopfilter;
@@ -636,7 +628,7 @@
 	spinlock_t buffer_lock;
 	struct device *cma_dev;
 	struct platform_device *platform_dev;
-	void (*vdec_cb)(struct vdec_s *, void *);
+	void (*vdec_cb)(struct vdec_s *, void *, int);
 	void *vdec_cb_arg;
 	struct vframe_chunk_s *chunk;
 	int dec_result;
@@ -668,12 +660,6 @@
 	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;
 
@@ -764,9 +750,7 @@
 	uint8_t skip_PB_before_I;
 	int PB_skip_mode;
 	int PB_skip_count_after_decoding;
-	/*hw*/
 
-	/**/
 	struct vdec_info *gvs;
 
 
@@ -815,6 +799,14 @@
 	dma_addr_t rdma_phy_adr;
 	unsigned *rdma_adr;
 	int hdr_flag;
+	bool high_bandwidth_flag;
+	ulong rpm_mem_handle;
+	ulong lmem_phy_handle;
+	ulong frame_mmu_map_handle;
+	ulong frame_dw_mmu_map_handle;
+	ulong rdma_mem_handle;
+	ulong cuva_handle;
+	u32 error_proc_policy;
 };
 
 static int  compute_losless_comp_body_size(
@@ -861,7 +853,6 @@
 #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)
@@ -878,10 +869,13 @@
 
 static int get_compress_header_size(struct AVS2Decoder_s *dec)
 {
+	int w = ALIGN(dec->init_pic_w, 64);
+	int h = ALIGN(dec->init_pic_h, 64);
+
 	if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
-		(IS_8K_SIZE(dec->init_pic_w, dec->init_pic_h)))
+		(IS_8K_SIZE(w, h)))
 		return MMU_COMPRESS_HEADER_SIZE_8K;
-	else if (IS_4K_SIZE(dec->init_pic_w, dec->init_pic_h))
+	else if (IS_4K_SIZE(w, h))
 		return MMU_COMPRESS_HEADER_SIZE_4K;
 	return MMU_COMPRESS_HEADER_SIZE_1080P;
 }
@@ -909,15 +903,18 @@
 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;
+	struct avs2_frame_s *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;
+	avs2_print(dec, 0, "%s decoder timeout\n", __func__);
+
+	if (pic && (pic->error_mark == 0) &&
+		(pic->decoded_lcu == 0)) {
+		update_decoded_pic(dec);
+		pic->error_mark = 1;
+	}
+
 	dec->dec_result = DEC_RESULT_DONE;
-	update_decoded_pic(dec);
 	reset_process_time(dec);
 	vdec_schedule_work(&dec->work);
 }
@@ -926,10 +923,8 @@
 {
 	u32 dw_mode;
 
-	dw_mode = (dec->m_ins_flag &&
-		((double_write_mode & 0x80000000) == 0)) ?
-		dec->double_write_mode :
-		(double_write_mode & 0x7fffffff);
+	dw_mode = (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))
@@ -947,15 +942,15 @@
 	u32 dw = 0x1; /*1:1*/
 	switch (valid_dw_mode) {
 	case 0x100:
-		if (w > 1920 && h > 1088)
+		if (w * h > 1920 * 1088)
 			dw = 0x4; /*1:2*/
 		break;
 	case 0x200:
-		if (w > 1920 && h > 1088)
+		if (w * h > 1920 * 1088)
 			dw = 0x2; /*1:4*/
 		break;
 	case 0x300:
-		if (w > 1280 && h > 720)
+		if (w * h > 1280 * 768)
 			dw = 0x4; /*1:2*/
 		break;
 	default:
@@ -984,7 +979,7 @@
 			dw = 0x2; /*1:4*/
 		break;
 	case 0x300:
-		if (w > 1280 && h > 720)
+		if (w > 1280 && h > 768)
 			dw = 0x4; /*1:2*/
 		break;
 	default:
@@ -994,7 +989,6 @@
 	return dw;
 }
 
-//#define	MAX_4K_NUM		0x1200
 #ifdef AVS2_10B_MMU
 int avs2_alloc_mmu(
 	struct AVS2Decoder_s *dec,
@@ -1009,8 +1003,7 @@
 	int cur_mmu_4k_number, max_frame_num;
 
 	picture_size = compute_losless_comp_body_size(
-		dec, pic_width, pic_height,
-		bit_depth_10);
+		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;
@@ -1043,8 +1036,7 @@
 	int cur_mmu_4k_number, max_frame_num;
 
 	picture_size = compute_losless_comp_body_size(
-		dec, pic_width, pic_height,
-		bit_depth_10);
+		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;
@@ -1069,18 +1061,11 @@
 	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
-				) {
+		if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+			&& avs2_dec->fref[i]->is_output == -1
+			&& avs2_dec->fref[i]->bg_flag == 0
+			&& avs2_dec->fref[i]->vf_ref == 0
+			&& avs2_dec->fref[i]->to_prepare_disp == 0) {
 			count++;
 		}
 	}
@@ -1088,6 +1073,13 @@
 	return count;
 }
 
+int get_error_policy(struct avs2_decoder *avs2_dec)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec, struct AVS2Decoder_s, avs2_dec);
+
+	return dec->error_proc_policy;
+}
+
 #ifdef CONSTRAIN_MAX_BUF_NUM
 static int get_vf_ref_only_buf_count(struct AVS2Decoder_s *dec)
 {
@@ -1095,18 +1087,11 @@
 	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
-				) {
+		if ((avs2_dec->fref[i]->imgcoi_ref < -256)
+			&& avs2_dec->fref[i]->is_output == -1
+			&& avs2_dec->fref[i]->bg_flag == 0
+			&& avs2_dec->fref[i]->vf_ref > 0
+			&& avs2_dec->fref[i]->to_prepare_disp == 0) {
 			count++;
 		}
 	}
@@ -1120,18 +1105,11 @@
 	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
-				) {
+		if ((avs2_dec->fref[i]->imgcoi_ref >= -256)
+			|| avs2_dec->fref[i]->is_output != -1
+			|| avs2_dec->fref[i]->bg_flag != 0
+			|| avs2_dec->fref[i]->vf_ref != 0
+			|| avs2_dec->fref[i]->to_prepare_disp != 0) {
 			count++;
 		}
 	}
@@ -1149,7 +1127,6 @@
 	dec->cur_fb_idx_mmu = INVALID_IDX;
 #endif
 
-
 	/* private init */
 	dec->work_space_buf = buf_spec_i;
 #ifndef AVS2_10B_MMU
@@ -1161,8 +1138,7 @@
 	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;
@@ -1193,8 +1169,6 @@
 
 #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;
@@ -1265,7 +1239,6 @@
 static u32 buffer_mode = 1;
 /* buffer_mode_dbg: debug only*/
 static u32 buffer_mode_dbg = 0xffff0000;
-/**/
 
 /*
 bit 0, 1: only display I picture;
@@ -1273,7 +1246,6 @@
 */
 static u32 i_only_flag;
 
-
 static u32 max_decoding_time;
 /*
 error handling
@@ -1293,7 +1265,6 @@
 	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);
 
@@ -1307,22 +1278,16 @@
 #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 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
 #define LMEM_DUMP_ADR             HEVC_ASSIST_SCRATCH_9
@@ -1454,14 +1419,6 @@
 		.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*/
@@ -1549,14 +1506,6 @@
 		.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*/
@@ -1639,12 +1588,6 @@
 		.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,
@@ -1664,310 +1607,94 @@
 	},
 	{
 		/* 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 = 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 = 0x3d00, //0x3c80,
-		},
-		.dblk_data = {
-			.buf_size = 0x62800,
-		},
-		.dblk_data2 = {
-			.buf_size = 0x62800,
-		},
+		.max_width		= 1920, //2048
+		.max_height		= 1088, //1152
+		.ipp			= {.buf_size = 0x1e00}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+		.short_term_rps		= {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, // RCS STORE AREA - Max 32 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+		.sao_up			= {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.swap_buf		= {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+		.scalelut		= {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.dblk_para		= {.buf_size = 0x4100}, //(ctu_numb_x+1) * 128 = (2048/16+1)*128= 0x4080
+		.dblk_data		= {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+		.dblk_data2		= {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
 #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
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_1080P}, /*2*16*(more than 2304)/4, 4K*/
 #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)
-		},
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_1080P}, //2*16*2304/4, 4K
 #endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x1e00, /* 2 * size of hevc*/
-		},
+		.mpred_above		= {.buf_size = 0x2000}, // 2 * size of hevc: (pic_width/64)*16*16 byte = 2048/64*16*16=0x2000
 #ifdef MV_USE_FIXED_BUF
-		.mpred_mv = {/* 1080p, 0x40000 per buffer */
-			.buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS,
-		},
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS}, // 1080p, 0x40000 per buffer
 #endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
+		.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,
-		},
+		.max_width		= 4096,
+		.max_height		= 2304,
+		.ipp			= {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+		.short_term_rps		= {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, // RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,total 0x2000 bytes
+		.sao_up			= {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.swap_buf		= {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+		.scalelut		= {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.dblk_para		= {.buf_size = 0x8100}, //(ctu_numb_x+1) * 128 = (4096/16+1)*128 = 0x8080
+		.dblk_data		= {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+		.dblk_data2		= {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
 #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
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_4K},/*2*16*(more than 2304)/4, 4K*/
 #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)
-		},
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_4K}, //2*16*2304/4, 4K
 #endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x4000, /* 2 * size of hevc*/
-		},
+		.mpred_above		= {.buf_size = 0x4000}, //(pic_width/64)*16*16 byte = 4096/64*16*16=0x4000
 #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,
-		},
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS}, //.buf_size = 0x100000*16, 4k2k => 0x100000 per buffer  4096x2304 => 0x120000 per buffer
 #endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
+		.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,
-		},
+		.max_width		= 4096 * 2,
+		.max_height		= 2304 * 2,
+		.ipp			= {.buf_size = 0x4000 * 2}, //IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+		.short_term_rps		= {.buf_size = 0x800}, //SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, //RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, //SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, //PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytess
+		.sao_up			= {.buf_size = 0}, //SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.swap_buf		= {.buf_size = 0x800}, //256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+		.scalelut		= {.buf_size = 0}, //support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.dblk_para		= {.buf_size = 0x10100}, //0x10080, //(ctu_numb_x+1) * 128 = (8192/16+1) * 128 = 0x10080
+		.dblk_data		= {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+		.dblk_data2		= {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
 #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
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_8K}, /*2*16*2304/4, 4K*/
 #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)
-		},
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_8K}, //2*16*2304/4, 4K
 #endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x8000,
-		},
+		.mpred_above		= {.buf_size = 0x8000}, //(pic_width/64)*16*16 byte = 8192/64*16*16=0x8000
 #ifdef MV_USE_FIXED_BUF
-		.mpred_mv = {
-			/*4k2k , 0x100000 per buffer*/
-			.buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS,
-		},
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS}, //4k2k , 0x100000 per buffer
 #endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
+		.rpm			= {.buf_size = RPM_BUF_SIZE},
+		.lmem			= {.buf_size = 0x400 * 2},
 	}
 };
 
@@ -2316,15 +2043,14 @@
 #endif
 
 static int config_pic(struct AVS2Decoder_s *dec,
-				struct avs2_frame_s *pic, int32_t lcu_size_log2)
+				struct avs2_frame_s *pic)
 {
 	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;
+
+	int32_t lcu_size = dec->avs2_dec.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) ?
@@ -2374,7 +2100,6 @@
 	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(
@@ -2403,44 +2128,39 @@
 			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;
+		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;
+			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
-				);
+				buf_size);
 			return ret;
 		}
 
-		if (pic->cma_alloc_addr)
+		if (pic->cma_alloc_addr) {
 			y_adr = pic->cma_alloc_addr;
-		else {
+			if (!vdec_secure(hw_to_vdec(dec)))
+				codec_mm_memset(y_adr, 0, buf_size);
+		} else {
 			avs2_print(dec, 0,
 				"decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
 				VF_BUFFER_IDX(i),
-				buf_size
-				);
+				buf_size);
 			return -1;
 		}
 	}
@@ -2484,31 +2204,29 @@
 #endif
 		}
 #ifdef MV_USE_FIXED_BUF
-		pic->mpred_mv_wr_start_addr =
-			dec->work_space_buf->mpred_mv.buf_start +
+		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;
+			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);
+				"%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);
+				"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);
+				"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,
@@ -2520,8 +2238,7 @@
 	return ret;
 }
 
-static void init_pic_list(struct AVS2Decoder_s *dec,
-	int32_t lcu_size_log2)
+static void init_pic_list(struct AVS2Decoder_s *dec)
 {
 	int i;
 	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
@@ -2546,6 +2263,8 @@
 				dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
 				return;
 			}
+			if (!vdec_secure(hw_to_vdec(dec)))
+				codec_mm_memset(buf_addr, 0, header_size);
 		}
 	}
 #endif
@@ -2560,11 +2279,9 @@
 		pic->index = i;
 		pic->BUF_index = -1;
 		pic->mv_buf_index = -1;
-		if (config_pic(dec, pic, lcu_size_log2) < 0) {
+		if (config_pic(dec, pic) < 0) {
 			if (debug)
-				avs2_print(dec, 0,
-					"Config_pic %d fail\n",
-					pic->index);
+				avs2_print(dec, 0, "Config_pic %d fail\n", pic->index);
 			pic->index = -1;
 			break;
 		}
@@ -2592,16 +2309,7 @@
 	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;
@@ -2610,9 +2318,6 @@
 		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));
 
@@ -2626,36 +2331,26 @@
 #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);
+	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);
+	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);
+	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);
+	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,
@@ -2675,13 +2370,13 @@
 	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",
+		"fref[%d]: index %d decode_id %d mvbuf %d imgcoi_ref %d imgtr_fwRefDistance %d referred %d, pre %d is_out %d, bg %d, vf_ref %d error %d lcu %d ref_pos(%d,%d,%d,%d,%d,%d,%d), time %lld\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]->referred_by_others,
 		avs2_dec->fref[ii]->to_prepare_disp,
 		avs2_dec->fref[ii]->is_output,
 		avs2_dec->fref[ii]->bg_flag,
@@ -2694,8 +2389,8 @@
 		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]
-		);
+		avs2_dec->fref[ii]->ref_poc[6],
+		avs2_dec->fref[ii]->time);
 	}
 	return;
 }
@@ -2707,25 +2402,20 @@
 	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,
@@ -2738,6 +2428,9 @@
 		return 0;
 
 	if (avs2_dec->img.type == P_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+
 		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
 			"config_mc_buffer for P_IMG, img type %d\n",
 			avs2_dec->img.type);
@@ -2746,28 +2439,9 @@
 			(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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
 			WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
 				(pic->mc_canvas_u_v << 16) |
 				(pic->mc_canvas_u_v << 8) |
@@ -2781,6 +2455,39 @@
 				i, pic->mc_canvas_u_v, pic->mc_canvas_y,
 				pic->error_mark);
 		}
+
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
+	} else if (avs2_dec->img.type == F_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+
+		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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
+			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);
+		}
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
 		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
 			(16 << 8) | (0<<1) | 1);
 		for (i = 0; i < avs2_dec->img.num_of_references; i++) {
@@ -2831,145 +2538,6 @@
 	}
 	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)
 {
@@ -2984,13 +2552,7 @@
 		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 */
@@ -3008,8 +2570,7 @@
 		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 = READ_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
 			rdata32_2 = rdata32_2 & 0xffff;
 			rdata32_2 = rdata32_2 | (rdata32_2 << 16);
 		}
@@ -3061,26 +2622,22 @@
 		col_isIntra = 0;
 	}
 
-	mpred_mv_rd_start_addr =
-		col_pic->mpred_mv_wr_start_addr;
+	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);
+		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);
+	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,
@@ -3120,8 +2677,7 @@
 		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_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);
@@ -3206,15 +2762,14 @@
 	[ 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);
+	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,
@@ -3230,8 +2785,7 @@
 		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");
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgDBLK: .done.\n");
 }
 
 static void config_sao_hw(struct AVS2Decoder_s *dec)
@@ -3241,10 +2795,8 @@
 	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*/
+	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);
@@ -3280,10 +2832,8 @@
 		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);*/
+
 	WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
 
 	data32 = (mc_buffer_size_u_v_h << 16);
@@ -3294,13 +2844,13 @@
 	data32 = READ_VREG(HEVC_SAO_CTRL1);
 	data32 &= (~0x3000);
 	/*[13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32*/
-	data32 |= (MEM_MAP_MODE << 12);
+	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
+	*  [31:24] ar_fifo1_axi_thread
+	*  [23:16] ar_fifo0_axi_thread
 	*  [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
@@ -3323,14 +2873,14 @@
 	ata32 = 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);
 	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 |= (mem_map_mode << 12);
 	data32 &= (~0xff0);
 	/*data32 |= 0x670;*/ /*Big-Endian per 64-bit*/
 	data32 |= 0x880;  /*.Big-Endian per 64-bit */
@@ -3357,7 +2907,7 @@
 	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 |= 0x8; /*Big-Endian per 64-bit*/
 
@@ -3368,9 +2918,12 @@
 #else
 	data32 = READ_VREG(HEVC_SAO_CTRL1);
 	data32 &= (~(3 << 14));
-	data32 |= (2 << 14);	/* line align with 64*/
+	if (is_hevc_align32(mem_map_mode))
+		data32 |= (1 << 14);
+	else
+		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
@@ -3380,25 +2933,15 @@
 	data32 |= ((dec->endian >> 8) & 0xfff);	/* data32 |= 0x670; Big-Endian per 64-bit */
 #endif
 	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
+	*  [31:24] ar_fifo1_axi_thread
+	*  [23:16] ar_fifo0_axi_thread
 	*  [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
@@ -3447,7 +2990,6 @@
 	* [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 */
@@ -3456,7 +2998,10 @@
 	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 */
+	if (is_hevc_align32(mem_map_mode))
+		data32 |= (1 << 8);
+	else
+		data32 |= (2 << 8);		/* line align with 64 for dw only */
 	WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
 #endif
 #ifndef AVS2_10B_NV21
@@ -3469,7 +3014,6 @@
 	}
 #endif
 #endif
-
 }
 
 static void reconstructCoefficients(struct AVS2Decoder_s *dec,
@@ -3480,18 +3024,11 @@
 		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]);*/
+			dec->m_filterCoeffSym[g][i] = alfParam->coeffmulti[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]);*/
+		dec->m_filterCoeffSym[g][alfParam->num_coeff - 1] = coeffPred +
+			alfParam->coeffmulti[g][alfParam->num_coeff - 1];
 	}
 }
 
@@ -3687,8 +3224,7 @@
 			dec->m_filterCoeffSym[i][7],
 			dec->m_filterCoeffSym[i][8]);
 	}
-	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
-		"[c] cfgALF .done.\n");
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "[c] cfgALF .done.\n");
 }
 
 static void config_other_hw(struct AVS2Decoder_s *dec)
@@ -3737,7 +3273,7 @@
 }
 
 static u32 init_cuva_size;
-static int cuva_data_is_avaible(struct AVS2Decoder_s *dec)
+static int cuva_data_is_available(struct AVS2Decoder_s *dec)
 {
 	u32 reg_val;
 
@@ -3767,10 +3303,10 @@
 	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)) {
+	if (pic == NULL || 0 == cuva_data_is_available(dec)) {
 		avs2_print(dec, AVS2_DBG_HDR_INFO,
-		"%s:pic 0x%p or data not avaible\n",
-		__func__, pic);
+			"%s:pic 0x%p or data not available\n",
+			__func__, pic);
 		return;
 	}
 
@@ -3780,8 +3316,8 @@
 	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);
+		"%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;
@@ -3808,9 +3344,8 @@
 			}
 
 			avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
-				"cuva: (size %d)\n",
-				pic->cuva_data_size);
-			if (get_dbg_flag(dec) & AVS2_DBG_HDR_DATA) {
+				"cuva: (size %d)\n", pic->cuva_data_size);
+			if (get_dbg_flag(dec) & AVS2_DBG_HDR_INFO) {
 				for (i = 0; i < pic->cuva_data_size; i++) {
 					pr_info("%02x ", pic->cuva_data_buf[i]);
 					if (((i + 1) & 0xf) == 0)
@@ -3880,7 +3415,6 @@
 	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
@@ -3888,12 +3422,10 @@
 #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);
 
 	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
 		if (buf_spec->max_width <= 4096 && buf_spec->max_height <= 2304)
@@ -3913,14 +3445,8 @@
 
 #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*/
@@ -3932,8 +3458,6 @@
 
 	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);
@@ -3944,21 +3468,16 @@
 
 #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);*/
+	WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR, buf_spec->mmu_vbh.buf_start + VBH_BUF_SIZE(buf_spec));
 
 	/* 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);
 
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
 #endif
 
 #ifdef AVS2_10B_MMU_DW
@@ -4019,30 +3538,29 @@
 	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 |
+
+	data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+	/* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+	data32 &= ~(7 << 29);
+	data32 |= (3 << 29);
+
+	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*/
-		;
+		(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
+		(0 << 1) |/*emulation_check_off VP9
 		do not have emulation*/
-	(1 << 0)/*startcode_check_on*/
-	;
+		(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)*/
@@ -4054,21 +3572,15 @@
 		(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*/
-		);
+		(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*/
-	);
+		(1 << 29));     /*data_protect_fill_ff_enable*/
 
-	WRITE_VREG(HEVC_PARSER_CORE_CONTROL,
-		(1 << 0)/* hevc_parser_core_clk_en*/
-	);
+	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);
 
@@ -4149,14 +3661,6 @@
 	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*/
 
@@ -4177,17 +3681,12 @@
 
 	WRITE_VREG(HEVCD_IPP_TOP_CNTL,
 		(0 << 1) | /*enable ipp*/
-		(1 << 0)   /*software reset ipp and mpp*/
-	);
+		(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
+		(0 << 0));   /*software reset ipp and mpp*/
+
 	/* Init dblk*/
 	data32 = READ_VREG(HEVC_DBLK_CFGB);
 	data32 |= (2 << 0);
@@ -4268,14 +3767,14 @@
 	dec->rpm_ptr = NULL;
 	dec->lmem_ptr = NULL;
 	if (dec->rpm_addr) {
-		dma_free_coherent(amports_get_dma_device(),
+		decoder_dma_free_coherent(dec->rpm_mem_handle,
 						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(),
+		decoder_dma_free_coherent(dec->cuva_handle,
 				dec->cuva_size, dec->cuva_addr,
 					dec->cuva_phy_addr);
 		dec->cuva_addr = NULL;
@@ -4283,7 +3782,7 @@
 
 	if (dec->lmem_addr) {
 			if (dec->lmem_phy_addr)
-				dma_free_coherent(amports_get_dma_device(),
+				decoder_dma_free_coherent(dec->lmem_phy_handle,
 						LMEM_BUF_SIZE, dec->lmem_addr,
 						dec->lmem_phy_addr);
 		dec->lmem_addr = NULL;
@@ -4292,7 +3791,7 @@
 #ifdef AVS2_10B_MMU
 	if (dec->frame_mmu_map_addr) {
 		if (dec->frame_mmu_map_phy_addr)
-			dma_free_coherent(amports_get_dma_device(),
+			decoder_dma_free_coherent(dec->frame_mmu_map_handle,
 				get_frame_mmu_map_size(dec), dec->frame_mmu_map_addr,
 					dec->frame_mmu_map_phy_addr);
 		dec->frame_mmu_map_addr = NULL;
@@ -4302,7 +3801,7 @@
 #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(),
+			decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
 				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;
@@ -4360,8 +3859,7 @@
 #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_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) {
@@ -4401,15 +3899,14 @@
 		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(),
+		dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
 			RPM_BUF_SIZE,
-			&dec->rpm_phy_addr, GFP_KERNEL);
+			&dec->rpm_phy_addr, "AVS2_RPM_BUF");
 		if (dec->rpm_addr == NULL) {
 			pr_err("%s: failed to alloc rpm buffer\n", __func__);
 			return -1;
@@ -4422,8 +3919,8 @@
 	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);
+		dec->cuva_addr = decoder_dma_alloc_coherent(&dec->cuva_handle,
+				dec->cuva_size, &dec->cuva_phy_addr, "AVS2_CUVA_BUF");
 	        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);
@@ -4433,9 +3930,9 @@
 		}
 	}
 
-	dec->lmem_addr = dma_alloc_coherent(amports_get_dma_device(),
+	dec->lmem_addr = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
 			LMEM_BUF_SIZE,
-			&dec->lmem_phy_addr, GFP_KERNEL);
+			&dec->lmem_phy_addr, "AVS2_LMEM_BUF");
 	if (dec->lmem_addr == NULL) {
 		pr_err("%s: failed to alloc lmem buffer\n", __func__);
 		return -1;
@@ -4447,9 +3944,9 @@
 
 #ifdef AVS2_10B_MMU
 	if (dec->mmu_enable) {
-		dec->frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
+		dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
 					get_frame_mmu_map_size(dec),
-					&dec->frame_mmu_map_phy_addr, GFP_KERNEL);
+					&dec->frame_mmu_map_phy_addr, "AVS2_MMU_BUF");
 		if (dec->frame_mmu_map_addr == NULL) {
 			pr_err("%s: failed to alloc count_buffer\n", __func__);
 			return -1;
@@ -4460,9 +3957,9 @@
 
 #ifdef AVS2_10B_MMU_DW
 	if (dec->dw_mmu_enable) {
-		dec->dw_frame_mmu_map_addr = dma_alloc_coherent(amports_get_dma_device(),
+		dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
 					get_frame_mmu_map_size(dec),
-					&dec->dw_frame_mmu_map_phy_addr, GFP_KERNEL);
+					&dec->dw_frame_mmu_map_phy_addr, "AVS2_DWMMU_BUF");
 		if (dec->dw_frame_mmu_map_addr == NULL) {
 			pr_err("%s: failed to alloc count_buffer\n", __func__);
 			return -1;
@@ -4482,7 +3979,6 @@
 #define CMD_FRAME_DISPLAY          3
 #define CMD_DEBUG                  10
 
-
 #define DECODE_BUFFER_NUM_MAX    32
 #define DISPLAY_BUFFER_NUM       6
 
@@ -4509,7 +4005,10 @@
 		canvas_h = pic->pic_h /
 			get_double_write_ratio(pic->double_write_mode);
 		/*sao_crtl1 aligned with 64*/
-		canvas_w = ALIGN(canvas_w, 64);
+		if (is_hevc_align32(blkmode))
+			canvas_w = ALIGN(canvas_w, 32);
+		else
+			canvas_w = ALIGN(canvas_w, 64);
 		canvas_h = ALIGN(canvas_h, 32);
 
 		if (vdec->parallel_dec == 1) {
@@ -4624,6 +4123,7 @@
 
 	vf->sidebind_type = dec->sidebind_type;
 	vf->sidebind_channel_id = dec->sidebind_channel_id;
+	vf->codec_vfmt = VFORMAT_AVS2;
 
 	return;
 }
@@ -4656,7 +4156,7 @@
 
 	if (kfifo_len(&dec->display_q) > VF_POOL_SIZE) {
 		avs2_print(dec, AVS2_DBG_BUFMGR,
-			"kfifo len:%d invaild, peek error\n",
+			"kfifo len:%d invalid, peek error\n",
 			kfifo_len(&dec->display_q));
 		return NULL;
 	}
@@ -4676,8 +4176,8 @@
 		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];
+			if (dec->avs2_dec.frm_pool[i].index == index)
+				pic = &dec->avs2_dec.frm_pool[i];
 		}
 	}
 	return pic;
@@ -4713,6 +4213,8 @@
 
 	if (kfifo_get(&dec->display_q, &vf)) {
 		uint8_t index = vf->index & 0xff;
+		struct vdec_s *vdec = hw_to_vdec(dec);
+
 		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);
@@ -4720,8 +4222,8 @@
 				(debug & AVS2_DBG_PIC_LEAK)) {
 				int i;
 				avs2_print(dec, 0,
-				"%s error index 0x%x pic not exist\n",
-				__func__, index);
+					"%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);
@@ -4732,17 +4234,30 @@
 				debug |= AVS2_DBG_PIC_LEAK_WAIT;
 			return NULL;
 		}
+
+		vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+		vf->vf_ud_param.ud_param.buf_len = 0;
+		vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+		vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+		vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+		vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS2 << 3);
+		vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+		if (vf->pts)
+			vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+		vf->omx_index = dec->vf_get_count;
 		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);
+				"%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;
 		}
 	}
@@ -4752,7 +4267,11 @@
 static void vavs2_vf_put(struct vframe_s *vf, void *op_arg)
 {
 	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+	struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
 	uint8_t index;
+	unsigned long flags = 0;
 
 	if (vf == (&dec->vframe_dummy))
 		return;
@@ -4760,6 +4279,7 @@
 	if (!vf)
 		return;
 
+	lock_buffer(dec, flags);
 	index = vf->index & 0xff;
 
 	kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
@@ -4771,11 +4291,8 @@
 		dec->vf_put_count);
 
 	if (index < dec->used_buf_num) {
-		unsigned long flags;
-		struct avs2_frame_s *pic;
+		struct avs2_frame_s *pic = get_pic_by_index(dec, index);
 
-		lock_buffer(dec, flags);
-		pic = get_pic_by_index(dec, index);
 		if (pic && pic->vf_ref > 0)
 			pic->vf_ref--;
 		else {
@@ -4793,9 +4310,12 @@
 						0x1);
 		dec->last_put_idx = index;
 		dec->new_frame_displayed++;
-		unlock_buffer(dec, flags);
 	}
+	unlock_buffer(dec, flags);
 
+#ifdef MULTI_INSTANCE_SUPPORT
+	vdec_up(vdec);
+#endif
 }
 
 static int vavs2_event_cb(int type, void *data, void *private_data)
@@ -4814,7 +4334,7 @@
 			(struct provider_aux_req_s *)data;
 		unsigned char index;
 		unsigned long flags;
-		struct avs2_frame_s *pic;
+		struct avs2_frame_s *pic = NULL;
 
 		if (!req->vf) {
 			req->aux_size = dec->vf_put_count;
@@ -4833,8 +4353,8 @@
 		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);
+			"%s pic 0x%p index %d =>size %d\n",
+			__func__, pic, index, req->aux_size);
 	}
 
 	return 0;
@@ -4859,11 +4379,8 @@
 		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)
 {
@@ -4871,13 +4388,12 @@
 
 	if (pic->slice_type == I_IMG)
 		vframe_qos->type = 1;
-	else if (pic->slice_type == P_IMG)
+	else if ((pic->slice_type == P_IMG) ||
+		(pic->slice_type == F_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
@@ -4887,15 +4403,14 @@
 	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);
+		vframe_qos->max_mv,
+		vframe_qos->avg_mv,
+		vframe_qos->min_mv);
 #endif
 
 	vframe_qos->max_qp = pic->max_qp;
@@ -4903,9 +4418,9 @@
 	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);
+		vframe_qos->max_qp,
+		vframe_qos->avg_qp,
+		vframe_qos->min_qp);
 #endif
 
 	vframe_qos->max_skip = pic->max_skip;
@@ -4913,9 +4428,9 @@
 	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);
+		vframe_qos->max_skip,
+		vframe_qos->avg_skip,
+		vframe_qos->min_skip);
 #endif
 
 	vframe_qos->num++;
@@ -4926,11 +4441,11 @@
 	struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy)
 {
 	unsigned long flags;
-	int stream_offset;
+	u32 stream_offset = pic->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,
@@ -4948,9 +4463,7 @@
 			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 (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
 				if (pts_lookup_offset_us64
 					(PTS_TYPE_VIDEO, stream_offset,
 					&vf->pts, &frame_size, 0,
@@ -4982,14 +4495,12 @@
 
 				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");
+					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;
+				int p = PTS_MODE_SWITCHING_RECOVERY_THRESHOLD;
 				dec->pts_mode_recovery_count++;
 				if (dec->pts_mode_recovery_count > p) {
 					dec->pts_mode_switching_count = 0;
@@ -4998,8 +4509,7 @@
 			}
 		}
 
-		pts_discontinue =
-			(abs(dec->last_pts  - vf->pts) >=
+		pts_discontinue = (abs(dec->last_pts  - vf->pts) >=
 			 tsync_vpts_discontinuity_margin());
 
 		if (vf->pts != 0)
@@ -5017,15 +4527,11 @@
 		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 +
+			vf->pts_us64 = dec->last_pts_us64 +
 				(DUR2PTS(dec->frame_dur) * 100 / 9);
 		}
 
 		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;
@@ -5052,7 +4558,6 @@
 				}
 			}
 #endif
-
 #else
 			vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
 			vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
@@ -5060,8 +4565,7 @@
 		}
 		if (pic->double_write_mode &&
 			((pic->double_write_mode & 0x20) == 0)) {
-			vf->type = VIDTYPE_PROGRESSIVE |
-				VIDTYPE_VIU_FIELD;
+			vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
 			vf->type |= VIDTYPE_VIU_NV21;
 			if (pic->double_write_mode == 3) {
 				vf->type |= VIDTYPE_COMPRESS;
@@ -5073,15 +4577,11 @@
 			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->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];
+					vf->canvas1_config[0] = pic->canvas_config[0];
+					vf->canvas1_config[1] = pic->canvas_config[1];
 
 			} else
 #endif
@@ -5111,17 +4611,17 @@
 			break;
 		}
 		if ((vf->type & VIDTYPE_COMPRESS) == 0)
-			vf->bitdepth =
-				BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
+			vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
 		if (pic->bit_depth == AVS2_BITS_8)
 			vf->bitdepth |= BITDEPTH_SAVING_MODE;
 
+		vf->type_original = vf->type;
 		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); */
+
+		if (dec->high_bandwidth_flag) {
+			vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH;
+		}
+
 		vf->width = pic->pic_w /
 			get_double_write_ratio(pic->double_write_mode);
 		vf->height = pic->pic_h /
@@ -5134,11 +4634,9 @@
 			((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);
+				get_double_write_ratio(pic->double_write_mode & 0xf);
 			vf->compHeight = pic->pic_h /
-				get_double_write_ratio(
-					pic->double_write_mode & 0xf);
+				get_double_write_ratio(pic->double_write_mode & 0xf);
 		} else {
 			vf->compWidth = pic->pic_w;
 			vf->compHeight = pic->pic_h;
@@ -5155,12 +4653,10 @@
 #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);
+				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));
+				decoder_bmmu_box_get_mem_handle(dec->bmmu_box,
+				HEADER_BUFFER_IDX(pic->BUF_index));
 			vf->mem_dw_handle = NULL;
 		} else
 #endif
@@ -5171,6 +4667,13 @@
 			vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
 				dec->bmmu_box,
 				HEADER_BUFFER_IDX(pic->index));
+			if (dec->double_write_mode == 3)
+				vf->mem_dw_handle =
+					decoder_bmmu_box_get_mem_handle(
+						dec->bmmu_box,
+						VF_BUFFER_IDX(pic->BUF_index));
+			else
+				vf->mem_dw_handle = NULL;
 		}
 		} else {
 			vf->mem_handle = decoder_bmmu_box_get_mem_handle(
@@ -5185,10 +4688,44 @@
 			dec->bmmu_box,
 			VF_BUFFER_IDX(pic->index));
 #endif
-	if (!vdec->vbuf.use_ptsserv && vdec_stream_based(vdec)) {
-		vf->pts_us64 = stream_offset;
+
+	if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+		/* offset for tsplayer pts lookup */
+		u64 frame_type = 0;
+		if (pic->slice_type == I_IMG)
+			frame_type = KEYFRAME_FLAG;
+		else if ((pic->slice_type == P_IMG) ||
+			(pic->slice_type == F_IMG))
+			frame_type = PFRAME_FLAG;
+		else
+			frame_type = BFRAME_FLAG;
+		vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
 		vf->pts = 0;
+	} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+		/* lookup by decoder */
+		checkout_pts_offset pts_info;
+		u64 frame_type = 0;
+		if (pic->slice_type == I_IMG)
+			frame_type = KEYFRAME_FLAG;
+		else if (pic->slice_type == P_IMG)
+			frame_type = PFRAME_FLAG;
+		else
+			frame_type = BFRAME_FLAG;
+		pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
+		if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+			vf->pts = pts_info.pts;
+			vf->pts_us64 = pts_info.pts_64;
+		} else {
+			vf->pts = 0;
+			vf->pts_us64 = 0;
+		}
 	}
+	avs2_print(dec, AVS2_DBG_OUT_PTS,
+		"avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld(0x%llx) slice_type %d, duration %d\n",
+		vf->pts, vf->pts_us64, vf->pts_us64, pic->slice_type, vf->duration);
+
 	if (!dummy) {
 		lock_buffer(dec, flags);
 		pic->vf_ref = 1;
@@ -5232,9 +4769,7 @@
 		}
 
 		if (pic->error_mark) {
-			avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
-				"!!!error pic, skip\n",
-				0);
+			avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "!!!error pic, skip\n", 0);
 			continue;
 		}
 
@@ -5242,8 +4777,7 @@
 			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);
+					"!!!slice type %d (not I) skip\n", 0, pic->slice_type);
 				continue;
 			}
 			dec->skip_PB_before_I = 0;
@@ -5256,7 +4790,7 @@
 
 		if (vf) {
 			struct vdec_info tmp4x;
-			int stream_offset = pic->stream_offset;
+			u32 stream_offset = pic->stream_offset;
 			set_vframe(dec, vf, pic, 0);
 			decoder_do_frame_check(pvdec, vf);
 			vdec_vframe_ready(pvdec, vf);
@@ -5267,16 +4801,7 @@
 
 			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++;
-			}
-		}
+			vdec_count_info(dec->gvs, 2, stream_offset);
 			memcpy(&tmp4x, dec->gvs, sizeof(struct vdec_info));
 			tmp4x.bit_depth_luma = bit_depth_luma;
 			tmp4x.bit_depth_chroma = bit_depth_chroma;
@@ -5304,10 +4829,8 @@
 	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)
@@ -5362,35 +4885,23 @@
 	if (dec->process_state ==
 		PROC_STATE_DECODING) {
 		dec->process_state =
-		PROC_STATE_DECODE_AGAIN;
+			PROC_STATE_DECODE_AGAIN;
 	} else if (dec->process_state ==
 		PROC_STATE_HEAD_DONE) {
 		dec->process_state =
-		PROC_STATE_HEAD_AGAIN;
+			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 == NULL)
+		return ;
+
 	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",
@@ -5457,7 +4968,6 @@
 		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;
 }
 
@@ -5484,10 +4994,6 @@
 		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;
@@ -5546,7 +5052,6 @@
 		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;
@@ -5591,7 +5096,6 @@
 #ifdef DEBUG_QOS
 		int pic_number = 0;
 #endif
-
 		picture->max_mv = 0;
 		picture->avg_mv = 0;
 		picture->min_mv = 0;
@@ -5603,9 +5107,6 @@
 		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,
@@ -5709,21 +5210,21 @@
 	    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);
+			pic_number, (rdata32>>0) & 0xff);
 #endif
-		picture->min_qp = (rdata32>>0)&0xff;
+		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);
+			pic_number, (rdata32>>8) & 0xff);
 #endif
-		picture->max_qp = (rdata32>>8)&0xff;
+		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);
+			pic_number, (rdata32>>16) & 0xff);
 	    avs2_print(dec, 0, "[Picture %d Quality] C QP max : %d\n",
-			pic_number, (rdata32>>24)&0xff);
+			pic_number, (rdata32>>24) & 0xff);
 #endif
 
 		/* blk22_mv_count */
@@ -5845,7 +5346,6 @@
 	    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;
@@ -5853,7 +5353,6 @@
 	    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;
@@ -5863,7 +5362,6 @@
 	    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;
@@ -5871,7 +5369,6 @@
 	    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;
@@ -5907,10 +5404,6 @@
 	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,
@@ -5943,54 +5436,16 @@
 		if (dec->m_ins_flag) {
 			set_cuva_data(dec);
 			update_decoded_pic(dec);
+			check_pic_error(dec, dec->avs2_dec.hc.cur_pic);
 			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");
@@ -6017,13 +5472,17 @@
 		start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
 
 	if (dec->process_state ==
-			PROC_STATE_HEAD_AGAIN
-			) {
+		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);
+			if (dec->m_ins_flag) {
+				dec->dec_result = DEC_RESULT_DONE;
+				amhevc_stop();
+				vdec_schedule_work(&dec->work);
+			}
 			goto irq_handled_exit;
 		} else {
 			avs2_print(dec, AVS2_DBG_BUFMGR,
@@ -6031,10 +5490,12 @@
 				start_code);
 			dec->process_state = PROC_STATE_HEAD_DONE;
 			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+			if (dec->m_ins_flag)
+				start_process_time(dec);
 			goto irq_handled_exit;
 		}
 	} else if (dec->process_state ==
-			PROC_STATE_DECODE_AGAIN) {
+		PROC_STATE_DECODE_AGAIN) {
 		if ((start_code == I_PICTURE_START_CODE)
 		|| (start_code == PB_PICTURE_START_CODE)) {
 			avs2_print(dec, AVS2_DBG_BUFMGR,
@@ -6046,6 +5507,8 @@
 				"PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
 				start_code);
 			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+			if (dec->m_ins_flag)
+				start_process_time(dec);
 			goto irq_handled_exit;
 		}
 	}
@@ -6061,7 +5524,6 @@
 #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)
@@ -6077,11 +5539,10 @@
 					pic->is_output == -1 &&
 					pic->mmu_alloc_flag &&
 					pic->vf_ref == 0) {
-					if (pic->refered_by_others == 0) {
+					if (pic->referred_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);
 #endif
@@ -6128,36 +5589,29 @@
 		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)) {
+		if (dec->avs2_dec.param.p.video_signal_type & (1<<14)) {
 			union param_u *pPara;
 
-			avs2_print(dec, 0,
-					"avs2 HDR meta data present\n");
+			avs2_print(dec, AVS2_DBG_HDR_INFO, "avs2 HDR meta data present\n");
 			pPara = &dec->avs2_dec.param;
 
 			/*clean this flag*/
-			pPara->p.video_signal_type
-				&= ~(1<<30);
+			pPara->p.video_signal_type &= ~(1<<14);
 
 			dec->vf_dp.present_flag = 1;
 
-			dec->vf_dp.white_point[0]
-				= pPara->p.white_point_x;
+			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;
+			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];
+				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,
@@ -6165,31 +5619,26 @@
 			}
 
 			for (i = 0; i < 3; i++) {
-				dec->vf_dp.primaries[i][1]
-					= pPara->p.display_primaries_y[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;
+			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;
+			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;
+			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);
@@ -6201,8 +5650,6 @@
 				"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)
@@ -6218,7 +5665,7 @@
 					" %s %s\n",
 					video_format_names[(v >> 10) & 7],
 					((v >> 9) & 1) ?
-						"full_range" : "limited");
+					"full_range" : "limited");
 				if (v & 0x100) {
 					u32 transfer;
 					u32 maxtrix;
@@ -6226,14 +5673,11 @@
 					avs2_print(dec, AVS2_DBG_HDR_INFO,
 						"color_description present:\n");
 					avs2_print(dec, AVS2_DBG_HDR_INFO,
-						"color_primarie = %d\n",
-						v & 0xff);
+						"color_primarie = %d\n", v & 0xff);
 					avs2_print(dec, AVS2_DBG_HDR_INFO,
-						"transfer_characteristic = %d\n",
-						(c >> 8) & 0xff);
+						"transfer_characteristic = %d\n", (c >> 8) & 0xff);
 					avs2_print(dec, AVS2_DBG_HDR_INFO,
-						"  matrix_coefficient = %d\n",
-						c & 0xff);
+						"  matrix_coefficient = %d\n", c & 0xff);
 
 					transfer = (c >> 8) & 0xFF;
 					if (transfer >= 15)
@@ -6266,30 +5710,15 @@
 			}
 
 			if (enable_force_video_signal_type)
-				dec->video_signal_type
-					= 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;
+				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);
 
@@ -6301,24 +5730,23 @@
 			dec->start_decoding_flag |= 0x1;
 		dec->process_state = PROC_STATE_HEAD_DONE;
 		WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+		if (dec->m_ins_flag)
+			start_process_time(dec);
 	} 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(dec);
 			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
+		if (dec->m_ins_flag && ret > 0
 			&& dec->avs2_dec.hc.cur_pic->cuva_data_buf != NULL)
 			release_cuva_data(dec->avs2_dec.hc.cur_pic);
 
@@ -6377,63 +5805,93 @@
 				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)
+			&buf_addr) < 0) {
 				ret = -1;
-			else
-				dec->avs2_dec.hc.cur_pic->
-				mpred_mv_wr_start_addr
-				= buf_addr;
+			} else {
+				dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr = buf_addr;
+				if (!vdec_secure(hw_to_vdec(dec)))
+					codec_mm_memset(dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr,
+						0, mv_buf_size);
+			}
 		}
 #endif
 		if (ret < 0) {
 			avs2_print(dec, AVS2_DBG_BUFMGR,
-				"avs2_bufmgr_process=> %d, AVS2_10B_DISCARD_NAL\r\n",
-			 ret);
+				"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
 			if (dec->mmu_enable)
 				avs2_recycle_mmu_buf(dec);
 	#endif
 			if (dec->m_ins_flag) {
-				dec->dec_result = DEC_RESULT_DONE;
+				int slice_type = 0;
+				struct avs2_frame_s *cur_pic = dec->avs2_dec.hc.cur_pic;
+
+				if (cur_pic != NULL) {
+					slice_type = cur_pic->slice_type;
+				} else {
+					slice_type = dec->avs2_dec.img.type;
+				}
+
+				dec->gvs->frame_count++;
+				dec->gvs->drop_frame_count++;
+				dec->gvs->error_frame_count++;
+
+				if (slice_type == I_IMG) {
+					dec->gvs->i_lost_frames++;
+					dec->gvs->i_concealed_frames++;
+					dec->gvs->i_decoded_frames++;
+				} else if ((slice_type == P_IMG) ||
+					(slice_type == F_IMG)) {
+					dec->gvs->p_lost_frames++;
+					dec->gvs->p_concealed_frames++;
+					dec->gvs->p_decoded_frames++;
+				} else if (slice_type == B_IMG) {
+					dec->gvs->b_lost_frames++;
+					dec->gvs->b_concealed_frames++;
+					dec->gvs->b_decoded_frames++;
+				}
+
+				dec->dec_result = DEC_RESULT_ERROR;
 				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;
-			*/
+			struct avs2_frame_s *cur_pic = dec->avs2_dec.hc.cur_pic;
+
+			if (cur_pic != NULL) {
+				dec->gvs->frame_count++;
+				if (cur_pic->slice_type == I_IMG) {
+					dec->gvs->i_decoded_frames++;
+				} else if ((cur_pic->slice_type == P_IMG) ||
+					(cur_pic->slice_type == F_IMG)) {
+					dec->gvs->p_decoded_frames++;
+				} else if (cur_pic->slice_type == B_IMG) {
+					dec->gvs->b_decoded_frames++;
+				}
+			}
+
+			cur_pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
 			if (!dec->m_ins_flag) {
 				dec->frame_count++;
-				decode_frame_count[dec->index]
-					= 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;
+				cur_pic->pts = dec->chunk->pts;
+				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);
+			cur_pic->bit_depth = dec->avs2_dec.input.sample_bit_depth;
+			cur_pic->double_write_mode = get_double_write_mode(dec);
 decode_slice:
 			PRINT_LINE();
 
@@ -6449,14 +5907,13 @@
 				"=>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);
+				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_INIT) {
 				dec->process_state = PROC_STATE_DECODING;
 				dec_again_process(dec);
 				goto irq_handled_exit;
@@ -6505,8 +5962,7 @@
 			READ_VREG(HEVC_STREAM_END_ADDR),
 			READ_VREG(HEVC_STREAM_LEVEL),
 			READ_VREG(HEVC_STREAM_WR_PTR),
-			READ_VREG(HEVC_STREAM_RD_PTR)
-		);
+			READ_VREG(HEVC_STREAM_RD_PTR));
 
 	debug_tag = READ_HREG(DEBUG_REG1);
 	if (debug_tag & 0x10000) {
@@ -6522,8 +5978,7 @@
 			if ((i & 0xf) == 0)
 				pr_info("%03x: ", i);
 			for (ii = 0; ii < 4; ii++) {
-				pr_info("%04x ",
-					   dec->lmem_ptr[i + 3 - ii]);
+				pr_info("%04x ", dec->lmem_ptr[i + 3 - ii]);
 			}
 			if (((i + ii) & 0xf) == 0)
 				pr_info("\n");
@@ -6544,8 +5999,7 @@
 		else
 			WRITE_HREG(DEBUG_REG1, 0);
 	} else if (debug_tag != 0) {
-		pr_info(
-			"dbg%x: %x lcu %x\n", READ_HREG(DEBUG_REG1),
+		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)
@@ -6577,10 +6031,6 @@
 
 		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)
@@ -6601,7 +6051,7 @@
 	uint8_t empty_flag;
 	unsigned int buf_level;
 
-	enum receviver_start_e state = RECEIVER_INACTIVE;
+	enum receiver_start_e state = RECEIVER_INACTIVE;
 	if (dec->m_ins_flag) {
 		if (hw_to_vdec(dec)->next_status
 			== VDEC_STATUS_DISCONNECTED) {
@@ -6641,32 +6091,17 @@
 				/* 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);
+					 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;
+			((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--;
@@ -6701,8 +6136,7 @@
 			__func__,
 			dec->chunk->size,
 			dec->chunk->offset,
-			get_data_check_sum(dec, dec->chunk->size)
-			);
+			get_data_check_sum(dec, dec->chunk->size));
 		dump_data(dec, dec->chunk->size);
 	}
 	if (debug & AVS2_DBG_DUMP_PIC_LIST) {
@@ -6747,8 +6181,6 @@
 		}
 		debug &= ~AVS2_DBG_DUMP_LMEM_BUF;
 	}
-	/*if (debug & AVS2_DBG_HW_RESET) {
-	}*/
 
 	if (radr != 0) {
 		if (rval != 0) {
@@ -6799,13 +6231,11 @@
 	/*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)) {
+		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;
+			dec->saved_resolution = frame_width * frame_height * fps;
 	}
 
 	timer->expires = jiffies + PUT_INTERVAL;
@@ -6850,8 +6280,7 @@
 	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);
+	snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), "%s", DRIVER_NAME);
 	return 0;
 }
 
@@ -6871,48 +6300,16 @@
 
 	avs2_init_decoder_hw(dec);
 
-#if 1
-	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
-		"%s\n", __func__);
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s\n", __func__);
 	data32 = READ_VREG(HEVC_STREAM_CONTROL);
-	data32 = data32 |
-		(1 << 0)/*stream_fetch_enable*/
-		;
+	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);
 
@@ -6971,25 +6368,21 @@
 	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;
+	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);
+		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)
+	else if ((unsigned long) dec->vavs2_amstream_dec_info.param & 0x08)
 		dec->i_only = 0x7;
 	else
 		dec->i_only = 0x0;
@@ -7004,7 +6397,6 @@
 		kfifo_put(&dec->newframe_q, vf);
 	}
 
-
 	ret = avs2_local_init(dec);
 
 	return ret;
@@ -7017,6 +6409,7 @@
 	int fw_size = 0x1000 * 16;
 	struct firmware_s *fw = NULL;
 	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
 
 	timer_setup(&dec->timer, vavs2_put_timer_func, 0);
 
@@ -7024,6 +6417,7 @@
 	if (vavs2_local_init(dec) < 0)
 		return -EBUSY;
 
+	avs2_dec->start_time = div64_u64(local_clock(), 1000);
 	vdec_set_vframe_comm(vdec, DRIVER_NAME);
 
 	fw = vmalloc(sizeof(struct firmware_s) + fw_size);
@@ -7042,11 +6436,6 @@
 	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;
 
@@ -7060,7 +6449,7 @@
 		amhevc_disable();
 		vfree(fw);
 		pr_err("AVS2: the %s fw loading failed, err: %x\n",
-			tee_enabled() ? "TEE" : "local", ret);
+			fw_tee_enabled() ? "TEE" : "local", ret);
 		return -EBUSY;
 	}
 
@@ -7072,10 +6461,10 @@
 	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)) {
+		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;
@@ -7102,7 +6491,6 @@
 
 	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",
@@ -7196,8 +6584,7 @@
 		dec->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
 			dec->index, FRAME_BUFFERS,
 			dec->need_cache_size,
-			tvp_flag
-			);
+			tvp_flag);
 		if (!dec->mmu_box) {
 			pr_err("avs2 alloc mmu box failed!!\n");
 			return -1;
@@ -7209,8 +6596,7 @@
 		dec->dw_mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME,
 			dec->index, FRAME_BUFFERS,
 			dec->need_cache_size,
-			tvp_flag
-			);
+			tvp_flag);
 		if (!dec->dw_mmu_box) {
 			pr_err("avs2 alloc dw mmu box failed!!\n");
 			dec->dw_mmu_enable = 0;
@@ -7224,7 +6610,8 @@
 			4 + PAGE_SHIFT,
 			CODEC_MM_FLAGS_CMA_CLEAR |
 			CODEC_MM_FLAGS_FOR_VDECODER |
-			tvp_flag);
+			tvp_flag,
+			BMMU_ALLOC_FLAGS_WAITCLEAR);
 	if (!dec->bmmu_box) {
 		pr_err("avs2 alloc bmmu box failed!!\n");
 		return -1;
@@ -7235,7 +6622,6 @@
 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 AVS2Decoder_s *dec = &gAVS2Decoder;
 	int ret;
 	pr_info("%s\n", __func__);
@@ -7281,7 +6667,7 @@
 	}
 
 	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
-			work_buf_size, DRIVER_NAME, &pdata->mem_start);
+		work_buf_size, DRIVER_NAME, &pdata->mem_start);
 	if (ret < 0) {
 		uninit_mmu_buffers(dec);
 		mutex_unlock(&vavs2_mutex);
@@ -7291,11 +6677,10 @@
 
 	dec->buf_start = pdata->mem_start;
 
-
 	if (debug) {
 		avs2_print(dec, 0,
 			"===AVS2 decoder mem resource 0x%lx size 0x%x\n",
-			   pdata->mem_start, dec->buf_size);
+			pdata->mem_start, dec->buf_size);
 	}
 
 	if (pdata->sys_info) {
@@ -7317,7 +6702,7 @@
 
 	pdata->private = dec;
 	pdata->dec_status = vavs2_dec_status;
-	/*pdata->set_isreset = vavs2_set_isreset;*/
+
 	is_reset = 0;
 	if (vavs2_init(pdata) < 0) {
 		pr_info("\namvdec_avs2 init failed.\n");
@@ -7328,8 +6713,7 @@
 		return -ENODEV;
 	}
 	/*set the max clk for smooth playing...*/
-	hevc_source_changed(VFORMAT_AVS2,
-			4096, 2048, 60);
+	hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
 	mutex_unlock(&vavs2_mutex);
 
 	return 0;
@@ -7345,13 +6729,11 @@
 
 	vavs2_stop(dec);
 
-
 	hevc_source_changed(VFORMAT_AVS2, 0, 0, 0);
 
-
 #ifdef DEBUG_PTS
 	pr_info("pts missed %ld, pts hit %ld, duration %d\n",
-		   dec->pts_missed, dec->pts_hit, dec->frame_dur);
+		dec->pts_missed, dec->pts_hit, dec->frame_dur);
 #endif
 
 	mutex_unlock(&vavs2_mutex);
@@ -7418,33 +6800,36 @@
 
 	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);
+		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]);
+			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");
 	}
-	avs2_print(dec,
-	 0,
-		"\n");
+	avs2_print(dec, 0, "\n");
 
 	if (!dec->chunk->block->is_mapped)
 		codec_mm_unmap_phyaddr(data);
 }
 
+void wait_hevc_search_done(struct AVS2Decoder_s *dec)
+{
+	int count = 0;
+	WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+	while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+		usleep_range(100, 101);
+		count++;
+		if (count > 100) {
+			avs2_print(dec, 0, "%s timeout\n", __func__);
+			break;
+		}
+	}
+}
+
 static void avs2_work(struct work_struct *work)
 {
 	struct AVS2Decoder_s *dec = container_of(work,
@@ -7463,8 +6848,7 @@
 
 	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)) {
+		&& (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);
@@ -7502,8 +6886,7 @@
 				"%s: chunk size 0x%x sum 0x%x\n",
 				__func__, r,
 				(debug & PRINT_FLAG_VDEC_STATUS) ?
-				get_data_check_sum(dec, r) : 0
-				);
+				get_data_check_sum(dec, r) : 0);
 			if (debug & PRINT_FLAG_VDEC_DATA)
 				dump_data(dec, dec->chunk->size);
 
@@ -7528,9 +6911,10 @@
 			vdec_schedule_work(&dec->work);
 		}
 		return;
-	} else if (dec->dec_result == DEC_RESULT_DONE) {
-		/* if (!dec->ctx_valid)
-			dec->ctx_valid = 1; */
+	} else if ((dec->dec_result == DEC_RESULT_DONE)
+		|| (dec->dec_result == DEC_RESULT_ERROR)) {
+		struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
 		dec->slice_idx++;
 		dec->frame_count++;
 		dec->process_state = PROC_STATE_INIT;
@@ -7540,6 +6924,20 @@
 		if (dec->mmu_enable)
 			dec->used_4k_num = (READ_VREG(HEVC_SAO_MMU_STATUS) >> 16);
 #endif
+
+		if ((pic != NULL) && (pic->error_mark) &&
+			(dec->dec_result == DEC_RESULT_DONE)) {
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == I_IMG) {
+				dec->gvs->i_concealed_frames++;
+			} else if ((pic->slice_type == P_IMG) ||
+				(pic->slice_type == F_IMG)) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == B_IMG) {
+				dec->gvs->b_concealed_frames++;
+			}
+		}
+
 		avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
 			"%s (===> %d) dec_result %d %x %x %x shiftbytes 0x%x decbytes 0x%x\n",
 			__func__,
@@ -7549,9 +6947,7 @@
 			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
-			);
+			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) {
 		/*
@@ -7564,20 +6960,15 @@
 			return;
 		}
 	} else if (dec->dec_result == DEC_RESULT_EOS) {
-		avs2_print(dec, 0,
-			"%s: end of stream\n",
-			__func__);
+		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__);
+		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;
@@ -7595,6 +6986,20 @@
 		del_timer_sync(&dec->timer);
 		dec->stat &= ~STAT_TIMER_ARM;
 	}
+
+	wait_hevc_search_done(dec);
+
+	if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+		avs2_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+			__func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+		avs2_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+		avs2_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+		avs2_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+	}
+
 	/* mark itself has all HW resource released and input released */
 	if (vdec->parallel_dec ==1)
 		vdec_core_finish_run(vdec, CORE_MASK_HEVC);
@@ -7602,7 +7007,7 @@
 		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);
+		dec->vdec_cb(hw_to_vdec(dec), dec->vdec_cb_arg, CORE_MASK_HEVC);
 }
 
 static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec)
@@ -7631,38 +7036,21 @@
 		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);
+			(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);
+		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);
+			PRINT_FLAG_VDEC_DETAIL, "%s buf level:%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) >=
@@ -7672,8 +7060,7 @@
 	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
-			)
+			run_ready_max_vf_only_num)
 			ret = 0;
 		if (run_ready_display_q_num > 0 &&
 			kfifo_len(&dec->display_q) >=
@@ -7702,7 +7089,7 @@
 }
 
 static void run(struct vdec_s *vdec, unsigned long mask,
-	void (*callback)(struct vdec_s *, void *), void *arg)
+	void (*callback)(struct vdec_s *, void *, int), void *arg)
 {
 	struct AVS2Decoder_s *dec =
 		(struct AVS2Decoder_s *)vdec->private;
@@ -7711,7 +7098,7 @@
 	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)) {
@@ -7747,12 +7134,12 @@
 			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);
+			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)
@@ -7762,11 +7149,9 @@
 				data = ((u8 *)dec->chunk->block->start_virt) +
 					dec->chunk->offset;
 
-			avs2_print_cont(dec, 0, "data adr %p:",
-				data);
+			avs2_print_cont(dec, 0, "data adr %p:", data);
 			for (ii = 0; ii < 8; ii++)
-				avs2_print_cont(dec, 0, "%02x ",
-					data[ii]);
+				avs2_print_cont(dec, 0, "%02x ", data[ii]);
 			if (!dec->chunk->block->is_mapped)
 				codec_mm_unmap_phyaddr(data);
 		}
@@ -7780,8 +7165,7 @@
 	} 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__);
+		avs2_print(dec, 0, "%s: Error amvdec_loadmc fail\n", __func__);
 		dec->dec_result = DEC_RESULT_FORCE_EXIT;
 		vdec_schedule_work(&dec->work);
 		return;
@@ -7790,7 +7174,6 @@
 		vdec->mc_type = VFORMAT_AVS2;
 	}
 
-
 	if (avs2_hw_ctx_restore(dec) < 0) {
 		vdec_schedule_work(&dec->work);
 		return;
@@ -7834,13 +7217,11 @@
 
 static void reset(struct vdec_s *vdec)
 {
-
 	struct AVS2Decoder_s *dec =
 		(struct AVS2Decoder_s *)vdec->private;
 
 	avs2_print(dec,
 		PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
-
 }
 
 static irqreturn_t avs2_irq_cb(struct vdec_s *vdec, int irq)
@@ -7868,8 +7249,7 @@
 		"width/height (%d/%d), used_buf_num %d\n",
 		dec->avs2_dec.img.width,
 		dec->avs2_dec.img.height,
-		dec->used_buf_num
-		);
+		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",
@@ -7880,11 +7260,10 @@
 		display_frame_count[dec->index],
 		run_count[dec->index],
 		not_run_ready[dec->index],
-		input_empty[dec->index]
-		);
+		input_empty[dec->index]);
 
 	if (vf_get_receiver(vdec->vf_provider_name)) {
-		enum receviver_start_e state =
+		enum receiver_start_e state =
 		vf_notify_receiver(vdec->vf_provider_name,
 			VFRAME_EVENT_PROVIDER_QUREY_STATE,
 			NULL);
@@ -7895,18 +7274,17 @@
 	}
 
 	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
-	);
+		"%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);
 
@@ -7963,8 +7341,7 @@
 		STBUF_READ(&vdec->vbuf, get_wp));
 
 	if (input_frame_based(vdec) &&
-		(debug & PRINT_FLAG_VDEC_DATA)
-		) {
+		(debug & PRINT_FLAG_VDEC_DATA)) {
 		int jj;
 		if (dec->chunk && dec->chunk->block &&
 			dec->chunk->size > 0) {
@@ -7980,20 +7357,16 @@
 				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]);
+					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");
+					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)
@@ -8004,11 +7377,12 @@
 	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;
+	static struct vframe_operations_s vf_tmp_ops;
 
 	pr_info("%s\n", __func__);
-	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) {
+	if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2)) {
 		pr_info("%s, chip id %d is not support avs2\n",
 			__func__, get_cpu_major_id());
 		return -1;
@@ -8017,8 +7391,7 @@
 		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 = vzalloc(sizeof(struct AVS2Decoder_s));
 	if (dec == NULL) {
@@ -8044,16 +7417,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);
-	 */
-
 	dec->index = pdev->id;
 	dec->m_ins_flag = 1;
+	dec->error_proc_policy = error_proc_policy;
 	if (is_rdma_enable()) {
-		dec->rdma_adr = dma_alloc_coherent(amports_get_dma_device(), RDMA_SIZE, &dec->rdma_phy_adr, GFP_KERNEL);
+		dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle,
+				RDMA_SIZE, &dec->rdma_phy_adr, "AVS2_RDMA_BUF");
 		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;
@@ -8082,8 +7451,12 @@
 		snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
 			MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
 
+	memcpy(&vf_tmp_ops, &vavs2_vf_provider, sizeof(struct vframe_operations_s));
+	if (without_display_mode == 1) {
+		vf_tmp_ops.get = NULL;
+	}
 	vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
-		&vavs2_vf_provider, dec);
+		&vf_tmp_ops, dec);
 
 	dec->provider_name = pdata->vf_provider_name;
 	platform_set_drvdata(pdev, pdata);
@@ -8095,7 +7468,7 @@
 		dec->stat |= VP9_TRIGGER_FRAME_ENABLE;
 
 	if ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
-		/*use ptr config for doubel_write_mode, etc*/
+		/*use ptr config for double_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)
@@ -8117,6 +7490,14 @@
 				&config_val) == 0)
 			dec->sidebind_channel_id = config_val;
 
+		if (get_config_int(pdata->config,
+			"parm_metadata_config_flag",
+			&config_val) == 0) {
+			dec->high_bandwidth_flag = config_val & VDEC_CFG_FLAG_HIGH_BANDWIDTH;
+			if (dec->high_bandwidth_flag)
+				avs2_print(dec, 0, "high bandwidth\n");
+		}
+
 		if (get_config_int(pdata->config, "HDRStaticInfo",
 				&vf_dp.present_flag) == 0
 				&& vf_dp.present_flag == 1) {
@@ -8156,9 +7537,6 @@
 		}
 		dec->vf_dp = vf_dp;
 	} else {
-		/*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;
 	}
@@ -8181,7 +7559,6 @@
 #endif
 	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;
 	}
@@ -8191,10 +7568,12 @@
 			&dec->cma_alloc_addr);
 	if (ret < 0) {
 		uninit_mmu_buffers(dec);
-		/* devm_kfree(&pdev->dev, (void *)dec); */
 		vfree((void *)dec);
 		return ret;
 	}
+	if (!vdec_secure(pdata))
+		codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
 	dec->buf_start = dec->cma_alloc_addr;
 	dec->buf_size = work_buf_size;
 
@@ -8230,14 +7609,12 @@
 		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);
+	hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
 	if (pdata->parallel_dec == 1)
 		vdec_core_request(pdata, CORE_MASK_HEVC);
 	else {
@@ -8283,14 +7660,14 @@
 		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); */
+		decoder_dma_free_coherent(dec->rdma_mem_handle,
+			RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
+
 	vfree((void *)dec);
 	return 0;
 }
@@ -8347,7 +7724,6 @@
 
 static int __init amvdec_avs2_driver_init_module(void)
 {
-
 #ifdef AVS2_10B_MMU
 	struct BuffInfo_s *p_buf_info;
 
@@ -8392,9 +7768,11 @@
 	}
 
 	if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_G12A) ||
-		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D)) {
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D) ||
+		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TXHD2)) {
 		amvdec_avs2_profile.name = "avs2_unsupport";
-	} else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+	} else if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) ||
+				(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5M)) {
 		if (vdec_is_support_4k())
 			amvdec_avs2_profile.profile =
 				"4k, 10bit, dwrite, compressed";
@@ -8427,7 +7805,6 @@
 }
 
 /****************************************/
-
 module_param(bit_depth_luma, uint, 0664);
 MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\n");
 
@@ -8546,7 +7923,6 @@
 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");
@@ -8583,10 +7959,10 @@
 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_PARM_DESC(force_bufspec, "\n amvdec_avs2 force_bufspec\n");
 
 module_param(udebug_flag, uint, 0664);
-MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n");
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs2 udebug_flag\n");
 
 module_param(udebug_pause_pos, uint, 0664);
 MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
@@ -8604,10 +7980,9 @@
 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");
+	"\n amvdec_avs2 force_disp_pic_index\n");
 
 module_param(without_display_mode, uint, 0664);
 MODULE_PARM_DESC(without_display_mode, "\n without_display_mode\n");
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.h b/drivers/frame_provider/decoder/avs2/vavs2.h
index 071bfb3..6bba092 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.h
+++ b/drivers/frame_provider/decoder/avs2/vavs2.h
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/amports/vavs2.h
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,8 +11,12 @@
  * 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 VAVS2_H
 #define VAVS2_H
 
diff --git a/drivers/frame_provider/decoder/avs2_fb/Makefile b/drivers/frame_provider/decoder/avs2_fb/Makefile
new file mode 100644
index 0000000..d18ff35
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/Makefile
@@ -0,0 +1,7 @@
+MODULE_NAME = amvdec_avs2_fb
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS2_FB) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs2_fb.o avs2_bufmgr.o
+
+PR_FMT = $(subst amvdec_,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c
new file mode 100644
index 0000000..a7edcac
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_bufmgr.c
@@ -0,0 +1,1898 @@
+/*
+ * 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/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/sched/clock.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+#include "avs2_global.h"
+
+#undef pr_info
+#define pr_info pr_cont
+
+#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;*/
+
+	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");
+	/*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");
+
+	/*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);
+
+	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 (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");
+	}
+#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");
+			RPS_idx = get_param(rpm_param->p.RPS_idx,
+				"predict for RCS");
+			/*gop size16*/
+			hd->curr_RPS.referred_by_others =
+				get_param(rpm_param->p.referred_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");
+			}
+		}
+		/*xyji 12.23*/
+
+		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;
+
+	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.referred_by_others =
+				get_param(rpm_param->p.referred_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");
+			}
+		}
+	}
+
+	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->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;
+
+	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].frame_num -= 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;
+
+	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];
+
+		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]->referred_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];
+
+	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->referred_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);
+#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
+#ifdef NEW_FRONT_BACK_CODE
+		if (avs2_dec->fref[refnum]->backend_ref > 0)
+		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]->referred_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->referred_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);
+#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->referred_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;
+
+	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';
+	}
+}
+
+int 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;
+	int32_t tmp_ref;
+	struct avs2_frame_s *tmp_fref;
+	int32_t error_mark = 0;
+
+	/*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;
+
+	/*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);
+	}
+	}
+
+	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
+		|| avs2_dec->fref[1]->imgtr_fwRefDistance == -256))) {
+		if (get_error_policy(avs2_dec) & 0x2) {
+			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);
+			if (avs2_dec->fref[1]->imgtr_fwRefDistance != -256) {
+				avs2_dec->bufmgr_error_flag = 1;
+			}
+			return -1;
+		} else {
+			error_mark = 1;
+		}
+	}
+	if (img->type == P_IMG) {
+		for (ii = 0; ii < img->num_of_references;ii++) {
+			tmp_ref = img->coding_order - hd->curr_RPS.ref_pic[ii];
+			if ((avs2_dec->fref[ii]->imgcoi_ref != tmp_ref) &&
+				(avs2_dec->fref[ii]->imgcoi_ref != (tmp_ref - 256))) {
+				if (get_error_policy(avs2_dec) & 0x2) {
+					pr_info("wrong reference configuration for P frame\n");
+					pr_info("fref[%d] imgcoi_ref %d, ref_pic[%d] %d\n",
+						ii,avs2_dec->fref[ii]->imgcoi_ref,
+						ii,hd->curr_RPS.ref_pic[ii]);
+					return -1;
+				} else {
+					error_mark = 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
+#ifdef NEW_FRONT_BACK_CODE
+				&& avs2_dec->fref[i]->backend_ref == 0
+#endif
+				&& avs2_dec->fref[i]->vf_ref == 0
+				&& avs2_dec->fref[i]->to_prepare_disp == 0
+				) {
+			break;
+		}
+	}
+
+	if (i == avs2_dec->ref_maxbuffer) {
+		pr_info("%s, warning, no enough buf\n", __func__);
+		return -2;
+	}
+
+	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->poc = img->tr;
+	hc->f_rec->error_mark = error_mark;
+	hc->f_rec->decoded_lcu = 0;
+	hc->f_rec->back_done_mark = 1;
+	hc->f_rec->slice_type = img->type;
+	hc->f_rec->time = div64_u64(local_clock(), 1000) - avs2_dec->start_time;
+#endif
+	hc->f_rec->referred_by_others = hd->curr_RPS.referred_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;
+		}
+	}
+
+	/*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, backend_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]->referred_by_others,
+			avs2_dec->fref[ii]->is_output,
+			avs2_dec->fref[ii]->bg_flag,
+			avs2_dec->fref[ii]->vf_ref,
+#ifdef NEW_FRONT_BACK_CODE
+		avs2_dec->fref[ii]->backend_ref,
+#else
+		0,
+#endif
+			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 0;
+}
+
+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 {
+		if (prepare_RefInfo(avs2_dec) < 0)
+			return -1;
+#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]->referred_by_others = 0;
+	}
+}
+#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->frame_num = img->tr;
+	p_outdata->tr = img->tr;
+
+	p_outdata->qp = 0;
+
+	p_outdata->tmp_time = hd->tmp_time;
+	p_outdata->picture_structure = img->picture_structure;
+
+#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);
+			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 (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);
+			}
+			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]->referred_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 (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*/
+		{
+			img->sequence_end_flag = 0;
+		}
+	}
+	if ((p_stdoutdata->tr + hc->total_frames * 256)
+		== hd->next_IDRtr) {
+#if !RD170_FIX_BG
+		if (hd->vec_flag) /**/
+#endif
+		{
+			hd->vec_flag = 0;
+		}
+	}
+
+	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 (is_avs2_print_bufmgr_detail())
+		pr_info(" %s\n", p_stdoutdata->str_reference_list);
+
+	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);
+#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) {
+			if (is_avs2_print_bufmgr_detail())
+				pr_info("vec_flag is 1, flushDPB and reinit bugmgr\n");
+
+			flushDPB(avs2_dec);
+
+			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) {
+			if (is_avs2_print_bufmgr_detail())
+				pr_info("new_sequence_flag after sequence_end_flag, flushDPB and reinit bugmgr\n");
+			flushDPB(avs2_dec);
+
+#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;
+			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;
+			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) {
+			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");
+		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;
+	{
+		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) {
+		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;
+	}
+
+	img->current_mb_nr = 0;
+
+	if (init_frame(avs2_dec) < 0) {
+		pr_info("%s, warning, init_frame error!\n", __func__);
+		return -1;
+	}
+
+	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);
+
+	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]->referred_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;
+	}
+
+	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/avs2_fb/avs2_fb_hw.c b/drivers/frame_provider/decoder/avs2_fb/avs2_fb_hw.c
new file mode 100644
index 0000000..911b65b
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_fb_hw.c
@@ -0,0 +1,2840 @@
+#include "../../../include/regs/dos_registers.h"
+
+#define LPF_SPCC_ENABLE
+
+/* to do */
+//#define DOUBLE_WRITE_VH0_TEMP    0
+//#define DOUBLE_WRITE_VH1_TEMP    0
+//#define DOUBLE_WRITE_VH0_HALF    0
+//#define DOUBLE_WRITE_VH1_HALF    0
+//#define DOS_BASE_ADR  0
+
+//#define HEVCD_MPP_DECOMP_AXIURG_CTL 0
+
+/**/
+#ifdef FOR_S5
+ulong dos_reg_compat_convert(ulong adr);
+#endif
+#define print_scratch_error(a)
+//#define MEM_MAP_MODE    0
+
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec);
+
+//typedef union param_u param_t;
+static void WRITE_BACK_RET(struct avs2_decoder *avs2_dec)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0xcc00000;   //ret
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"WRITE_BACK_RET()\ninstruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0;           //nop
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+}
+
+static void WRITE_BACK_8(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint8_t data)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x20<<22) | ((spr_addr&0xfff)<<8) | (data&0xff);   //mtspi data, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data,
+		avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void WRITE_BACK_16(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint8_t rd_addr, uint16_t data)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6) | (rd_addr&0x3f);       // movi rd_addr, data[15:0]
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x,%x)\ninstruction[%3d] = %8x, data= %x\n",
+		__func__, spr_addr, rd_addr, data,
+		avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], data&0xffff);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f);  // mtsp rd_addr, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void WRITE_BACK_32(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint32_t data)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6);   // movi COMMON_REG_0, data
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data,
+		avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	data = (data & 0xffff0000)>>16;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1b<<22) | (data<<6);                // mvihi COMMON_REG_0, data[31:16]
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8);    // mtsp COMMON_REG_0, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void READ_INS_WRITE(struct avs2_decoder *avs2_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t position, uint8_t size)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+	//spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+	spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x,%x,%x,%x)\n",
+		__func__, spr_addr0, spr_addr1, rd_addr, position, size);
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f);    //mtsp rd_addr, src_addr1
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+//Caution:  pc offset fixed to 4, the data of cmp_addr need ready before call this function
+void READ_CMP_WRITE(struct avs2_decoder *avs2_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t cmp_addr, uint8_t position, uint8_t size)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+	//spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+	spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x,%x,%x,%x,%x)\n",
+		__func__, spr_addr0, spr_addr1, rd_addr, cmp_addr, position, size);
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+		avs2_dec->instruction[avs2_dec->ins_offset] = (0x29<<22) | (4<<12) | ((rd_addr&0x3f)<<6) | cmp_addr;     //cbne current_pc+4, rd_addr, cmp_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+		avs2_dec->instruction[avs2_dec->ins_offset] = 0;                                                       //nop
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f);    //mtsp rd_addr, src_addr1
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void READ_WRITE_DATA16(struct avs2_decoder *avs2_dec, uint32_t spr_addr, uint16_t data, uint8_t position, uint8_t size)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		struct AVS2Decoder_s, avs2_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8);    //mfsp COMON_REG_0, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"%s(%x,%x,%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data, position, size,
+		avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | (data<<6) | 1;        //movi COMMON_REG_1, data
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | (0<<6) | 1;  //ins COMMON_REG_0, COMMON_REG_1, position, size
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8);    //mtsp COMMON_REG_0, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs2_dec->ins_offset < 256 && (avs2_dec->ins_offset + 16) >= 256) {
+		WRITE_BACK_RET(avs2_dec);
+		avs2_dec->ins_offset = 256;
+	}
+#endif
+}
+
+#if 0
+void READ_BACK_32(struct AVS2Decoder_s *dec, uint32_t spr_addr, uint8_t rd_addr)
+{
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f);  //mfsp rd_addr, spr_addr
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n", avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+}
+#endif
+
+static int32_t config_mc_buffer_fb(struct AVS2Decoder_s *dec)
+{
+	int32_t i,j;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+	struct avs2_frame_s *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_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (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_BACK_32(avs2_dec, 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_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (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);
+		WRITE_BACK_32(avs2_dec, 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 (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+		for (j = 0; j < MAXREF; j++) {
+			if (avs2_dec->f_bg == cur_pic->ref_pic[j])
+				break;
+			if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = avs2_dec->f_bg;
+				break;
+			}
+		}
+#endif
+	}
+
+	if (avs2_dec->img.type == I_IMG)
+		return 0;
+
+	if (avs2_dec->img.type == P_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+		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);
+		WRITE_BACK_8(avs2_dec, 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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
+			///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+			///    (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+			WRITE_BACK_32(avs2_dec, 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\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+					break;
+				if (cur_pic->ref_pic[j] == NULL) {
+					cur_pic->ref_pic[j] = pic;
+					break;
+				}
+			}
+#endif
+
+		}
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
+	} else if (avs2_dec->img.type == F_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+		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);
+		WRITE_BACK_8(avs2_dec, 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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
+			///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+			///    (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+			WRITE_BACK_32(avs2_dec, 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\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+					break;
+				if (cur_pic->ref_pic[j] == NULL) {
+					cur_pic->ref_pic[j] = pic;
+					break;
+				}
+			}
+#endif
+		}
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+		WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (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);
+		WRITE_BACK_32(avs2_dec, 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_BACK_8(avs2_dec, 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);
+		WRITE_BACK_32(avs2_dec, 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\n", 1, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+		for (j = 0; j < MAXREF; j++) {
+			if (pic == cur_pic->ref_pic[j])
+				break;
+			if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+			}
+		}
+#endif
+
+		pic = avs2_dec->fref[0];
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+		WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (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);
+		WRITE_BACK_32(avs2_dec, 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\n", 0, pic->mc_canvas_u_v, pic->mc_canvas_y);
+#if (defined NEW_FRONT_BACK_CODE) && (!defined FB_BUF_DEBUG_NO_PIPLINE)
+		for (j = 0; j < MAXREF; j++) {
+			if (pic == cur_pic->ref_pic[j])
+				break;
+			if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+			}
+		}
+#endif
+	}
+	return 0;
+}
+
+#ifdef NEW_FRONT_BACK_CODE
+/*copy from simulation code*/
+
+#define FB_LMEM_SIZE_LOG2           6
+#define FB_LMEM_SIZE             (1 << FB_LMEM_SIZE_LOG2)
+#define FB_VCPU_IMEM_SIZE         0x400
+#define FB_SYSTEM_IMEM_SIZE       0x400
+#define FB_SCALELUT_LMEM_SIZE     0x400
+
+#if 0
+#define FB_PARSER_SAO0_BLOCK_SIZE       (4*1024*4)*64
+#define FB_PARSER_SAO1_BLOCK_SIZE       (4*1024*4)*64
+#define FB_MPRED_IMP0_BLOCK_SIZE        (4*1024*4)*256
+#define FB_MPRED_IMP1_BLOCK_SIZE        (4*1024*4)*256
+#else
+#define FB_PARSER_SAO0_BLOCK_SIZE       (4*1024*4)
+#define FB_PARSER_SAO1_BLOCK_SIZE       (4*1024*4)
+#define FB_MPRED_IMP0_BLOCK_SIZE        (4*1024*4)
+#define FB_MPRED_IMP1_BLOCK_SIZE        (4*1024*4)
+#endif
+/**/
+#define BUF_BLOCK_NUM 256
+
+#define FB_IFBUF_SCALELUT_BLOCK_SIZE       FB_SCALELUT_LMEM_SIZE
+#define FB_IFBUF_VCPU_IMEM_BLOCK_SIZE FB_VCPU_IMEM_SIZE
+#define FB_IFBUF_SYS_IMEM_BLOCK_SIZE FB_SYSTEM_IMEM_SIZE
+#define FB_IFBUF_LMEM0_BLOCK_SIZE   FB_LMEM_SIZE
+#define FB_IFBUF_LMEM1_BLOCK_SIZE   FB_LMEM_SIZE
+
+#define IFBUF_SCALELUT_SIZE                  (FB_IFBUF_SCALELUT_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_VCPU_IMEM_SIZE        (FB_IFBUF_VCPU_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_SYS_IMEM_SIZE        (FB_IFBUF_SYS_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM0_SIZE                  (FB_IFBUF_LMEM0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM1_SIZE                  (FB_IFBUF_LMEM1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO0_SIZE      (FB_PARSER_SAO0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO1_SIZE      (FB_PARSER_SAO1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP0_SIZE      (FB_MPRED_IMP0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP1_SIZE      (FB_MPRED_IMP1_BLOCK_SIZE * BUF_BLOCK_NUM)
+
+static void copy_loopbufs_ptr(buff_ptr_t* trg, buff_ptr_t* src)
+{
+	trg->mmu0_ptr = src->mmu0_ptr;
+	trg->mmu1_ptr = src->mmu1_ptr;
+	trg->scalelut_ptr = src->scalelut_ptr;
+	trg->vcpu_imem_ptr = src->vcpu_imem_ptr;
+	trg->sys_imem_ptr = src->sys_imem_ptr;
+	trg->sys_imem_ptr_v = src->sys_imem_ptr_v;
+	trg->lmem0_ptr = src->lmem0_ptr;
+	trg->lmem1_ptr = src->lmem1_ptr;
+	trg->parser_sao0_ptr = src->parser_sao0_ptr;
+	trg->parser_sao1_ptr = src->parser_sao1_ptr;
+	trg->mpred_imp0_ptr = src->mpred_imp0_ptr;
+	trg->mpred_imp1_ptr = src->mpred_imp1_ptr;
+	//
+	trg->scalelut_ptr_pre = src->scalelut_ptr_pre;
+	trg->scalelut_ptr_changed = src->scalelut_ptr_changed;
+}
+
+static void print_loopbufs_ptr(struct AVS2Decoder_s *dec, char* mark, buff_ptr_t* ptr)
+{
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s:mmu0_ptr 0x%x, mmu1_ptr 0x%x, scalelut_ptr 0x%x (changed %d) pre_ptr 0x%x, vcpu_imem_ptr 0x%x, sys_imem_ptr 0x%x (vir 0x%x), lmem0_ptr 0x%x, lmem1_ptr 0x%x, parser_sao0_ptr 0x%x, parser_sao1_ptr 0x%x, mpred_imp0_ptr 0x%x, mpred_imp1_ptr 0x%x\n",
+		mark,
+		ptr->mmu0_ptr,
+		ptr->mmu1_ptr,
+		ptr->scalelut_ptr,
+		ptr->scalelut_ptr_changed,
+		ptr->scalelut_ptr_pre,
+		ptr->vcpu_imem_ptr,
+		ptr->sys_imem_ptr,
+		ptr->sys_imem_ptr_v,
+		ptr->lmem0_ptr,
+		ptr->lmem1_ptr,
+		ptr->parser_sao0_ptr,
+		ptr->parser_sao1_ptr,
+		ptr->mpred_imp0_ptr,
+		ptr->mpred_imp1_ptr);
+}
+
+static int init_mmu_fb_bufstate(struct AVS2Decoder_s *dec, int mmu_fb_4k_number)
+{
+	int ret;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	dma_addr_t tmp_phy_adr;
+	int mmu_map_size = ((mmu_fb_4k_number * 4) >> 6) << 6;
+
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s: mmu_fb_4k_number %d\n", __func__, mmu_fb_4k_number);
+
+	if (mmu_fb_4k_number < 0)
+		return -1;
+
+	dec->mmu_box_fb = decoder_mmu_box_alloc_box(DRIVER_NAME,
+		dec->index, 2, (mmu_fb_4k_number << 12) * 2, 0);
+
+	dec->fb_buf_mmu0_addr = dma_alloc_coherent(amports_get_dma_device(),
+		mmu_map_size, &tmp_phy_adr, GFP_KERNEL);
+	avs2_dec->fb_buf_mmu0.buf_start = tmp_phy_adr;
+	if (dec->fb_buf_mmu0_addr == NULL) {
+		avs2_print(dec, 0, "%s: failed to alloc fb_mmu0_map\n", __func__);
+		return -1;
+	}
+	memset(dec->fb_buf_mmu0_addr, 0, mmu_map_size);
+	avs2_dec->fb_buf_mmu0.buf_size = mmu_map_size;
+	avs2_dec->fb_buf_mmu0.buf_end = avs2_dec->fb_buf_mmu0.buf_start + mmu_map_size;
+
+	dec->fb_buf_mmu1_addr = dma_alloc_coherent(amports_get_dma_device(),
+		mmu_map_size, &tmp_phy_adr, GFP_KERNEL);
+	avs2_dec->fb_buf_mmu1.buf_start = tmp_phy_adr;
+	if (dec->fb_buf_mmu1_addr == NULL) {
+		avs2_print(dec, 0, "%s: failed to alloc fb_mmu1_map\n", __func__);
+		return -1;
+	}
+	memset(dec->fb_buf_mmu1_addr, 0, mmu_map_size);
+	avs2_dec->fb_buf_mmu1.buf_size = mmu_map_size;
+	avs2_dec->fb_buf_mmu1.buf_end = avs2_dec->fb_buf_mmu1.buf_start + mmu_map_size;
+
+	ret = decoder_mmu_box_alloc_idx(dec->mmu_box_fb,
+		0, mmu_fb_4k_number, dec->fb_buf_mmu0_addr);
+	if (ret != 0) {
+		avs2_print(dec, 0, "%s: failed to alloc fb_mmu0 pages");
+		return -1;
+	}
+
+	ret = decoder_mmu_box_alloc_idx(dec->mmu_box_fb,
+		1, mmu_fb_4k_number, dec->fb_buf_mmu1_addr);
+	if (ret != 0) {
+		avs2_print(dec, 0, "%s: failed to alloc fb_mmu1 pages");
+		return -1;
+	}
+
+	dec->mmu_fb_4k_number = mmu_fb_4k_number;
+	avs2_dec->fr.mmu0_ptr = avs2_dec->fb_buf_mmu0.buf_start;
+	avs2_dec->bk.mmu0_ptr = avs2_dec->fb_buf_mmu0.buf_start;
+	avs2_dec->fr.mmu1_ptr = avs2_dec->fb_buf_mmu1.buf_start;
+	avs2_dec->bk.mmu1_ptr = avs2_dec->fb_buf_mmu1.buf_start;
+
+	return 0;
+}
+
+static void init_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+/*simulation code: change to use linux APIs; also need write uninit_fb_bufstate()*/
+	int ret;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	dma_addr_t tmp_phy_adr;
+	unsigned long tmp_adr;
+	int mmu_fb_4k_number = dec->fb_ifbuf_num * avs2_mmu_page_num(dec,
+		dec->init_pic_w, dec->init_pic_h, 1);
+
+	ret = init_mmu_fb_bufstate(dec, mmu_fb_4k_number);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc mmu fb buffer\n", __func__);
+		return ;
+	}
+
+	avs2_dec->fb_buf_scalelut.buf_size = IFBUF_SCALELUT_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_SCALELUT_ID, avs2_dec->fb_buf_scalelut.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_scalelut.buf_size);
+	}
+
+	avs2_dec->fb_buf_scalelut.buf_start = tmp_adr;
+	avs2_dec->fb_buf_scalelut.buf_end = avs2_dec->fb_buf_scalelut.buf_start + avs2_dec->fb_buf_scalelut.buf_size;
+
+	avs2_dec->fb_buf_vcpu_imem.buf_size = IFBUF_VCPU_IMEM_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_VCPU_IMEM_ID, avs2_dec->fb_buf_vcpu_imem.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_vcpu_imem.buf_size);
+	}
+
+	avs2_dec->fb_buf_vcpu_imem.buf_start = tmp_adr;
+	avs2_dec->fb_buf_vcpu_imem.buf_end = avs2_dec->fb_buf_vcpu_imem.buf_start + avs2_dec->fb_buf_vcpu_imem.buf_size;
+
+	avs2_dec->fb_buf_sys_imem.buf_size = IFBUF_SYS_IMEM_SIZE * dec->fb_ifbuf_num;
+	avs2_dec->fb_buf_sys_imem_addr = dma_alloc_coherent(amports_get_dma_device(),
+		avs2_dec->fb_buf_sys_imem.buf_size, &tmp_phy_adr, GFP_KERNEL);
+	avs2_dec->fb_buf_sys_imem.buf_start = tmp_phy_adr;
+	if (avs2_dec->fb_buf_sys_imem_addr == NULL) {
+		pr_err("%s: failed to alloc fb_buf_sys_imem\n", __func__);
+		return;
+	}
+	avs2_dec->fb_buf_sys_imem.buf_end = avs2_dec->fb_buf_sys_imem.buf_start + avs2_dec->fb_buf_sys_imem.buf_size;
+
+	avs2_dec->fb_buf_lmem0.buf_size = IFBUF_LMEM0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_LMEM0_ID, avs2_dec->fb_buf_lmem0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_lmem0.buf_size);
+	}
+
+	avs2_dec->fb_buf_lmem0.buf_start = tmp_adr;
+	avs2_dec->fb_buf_lmem0.buf_end = avs2_dec->fb_buf_lmem0.buf_start + avs2_dec->fb_buf_lmem0.buf_size;
+
+	avs2_dec->fb_buf_lmem1.buf_size = IFBUF_LMEM1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_LMEM1_ID, avs2_dec->fb_buf_lmem1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_lmem1.buf_size);
+	}
+
+	avs2_dec->fb_buf_lmem1.buf_start = tmp_adr;
+	avs2_dec->fb_buf_lmem1.buf_end = avs2_dec->fb_buf_lmem1.buf_start + avs2_dec->fb_buf_lmem1.buf_size;
+
+	avs2_dec->fb_buf_parser_sao0.buf_size = IFBUF_PARSER_SAO0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_PARSER_SAO0_ID, avs2_dec->fb_buf_parser_sao0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_parser_sao0.buf_size);
+	}
+
+	avs2_dec->fb_buf_parser_sao0.buf_start = tmp_adr;
+	avs2_dec->fb_buf_parser_sao0.buf_end = avs2_dec->fb_buf_parser_sao0.buf_start + avs2_dec->fb_buf_parser_sao0.buf_size;
+
+	avs2_dec->fb_buf_parser_sao1.buf_size = IFBUF_PARSER_SAO1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_PARSER_SAO1_ID, avs2_dec->fb_buf_parser_sao1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_parser_sao1.buf_size);
+	}
+
+	avs2_dec->fb_buf_parser_sao1.buf_start = tmp_adr;
+	avs2_dec->fb_buf_parser_sao1.buf_end = avs2_dec->fb_buf_parser_sao1.buf_start + avs2_dec->fb_buf_parser_sao1.buf_size;
+
+	avs2_dec->fb_buf_mpred_imp0.buf_size = IFBUF_MPRED_IMP0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUFF_MPRED_IMP0_ID, avs2_dec->fb_buf_mpred_imp0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_mpred_imp0.buf_size);
+	}
+
+	avs2_dec->fb_buf_mpred_imp0.buf_start = tmp_adr;
+	avs2_dec->fb_buf_mpred_imp0.buf_end = avs2_dec->fb_buf_mpred_imp0.buf_start + avs2_dec->fb_buf_mpred_imp0.buf_size;
+
+	avs2_dec->fb_buf_mpred_imp1.buf_size = IFBUF_MPRED_IMP1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUFF_MPRED_IMP1_ID, avs2_dec->fb_buf_mpred_imp1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	if (ret) {
+		avs2_print(dec, 0, "%s: failed to alloc buffer, %d\n", __func__, __LINE__);
+	} else {
+		if (!vdec_secure(hw_to_vdec(dec)))
+			codec_mm_memset(tmp_adr, 0, avs2_dec->fb_buf_mpred_imp1.buf_size);
+	}
+
+	avs2_dec->fb_buf_mpred_imp1.buf_start = tmp_adr;
+	avs2_dec->fb_buf_mpred_imp1.buf_end = avs2_dec->fb_buf_mpred_imp1.buf_start + avs2_dec->fb_buf_mpred_imp1.buf_size;
+
+	avs2_dec->fr.scalelut_ptr = avs2_dec->fb_buf_scalelut.buf_start;
+	avs2_dec->bk.scalelut_ptr = avs2_dec->fb_buf_scalelut.buf_start;
+	avs2_dec->fr.vcpu_imem_ptr = avs2_dec->fb_buf_vcpu_imem.buf_start;
+	avs2_dec->bk.vcpu_imem_ptr = avs2_dec->fb_buf_vcpu_imem.buf_start;
+	avs2_dec->fr.sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+	avs2_dec->bk.sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+	avs2_dec->fr.lmem0_ptr = avs2_dec->fb_buf_lmem0.buf_start;
+	avs2_dec->bk.lmem0_ptr = avs2_dec->fb_buf_lmem0.buf_start;
+	avs2_dec->fr.lmem1_ptr = avs2_dec->fb_buf_lmem1.buf_start;
+	avs2_dec->bk.lmem1_ptr = avs2_dec->fb_buf_lmem1.buf_start;
+	avs2_dec->fr.parser_sao0_ptr = avs2_dec->fb_buf_parser_sao0.buf_start;
+	avs2_dec->bk.parser_sao0_ptr = avs2_dec->fb_buf_parser_sao0.buf_start;
+	avs2_dec->fr.parser_sao1_ptr = avs2_dec->fb_buf_parser_sao1.buf_start;
+	avs2_dec->bk.parser_sao1_ptr = avs2_dec->fb_buf_parser_sao1.buf_start;
+	avs2_dec->fr.mpred_imp0_ptr = avs2_dec->fb_buf_mpred_imp0.buf_start;
+	avs2_dec->bk.mpred_imp0_ptr = avs2_dec->fb_buf_mpred_imp0.buf_start;
+	avs2_dec->fr.mpred_imp1_ptr = avs2_dec->fb_buf_mpred_imp1.buf_start;
+	avs2_dec->bk.mpred_imp1_ptr = avs2_dec->fb_buf_mpred_imp1.buf_start;
+	avs2_dec->fr.scalelut_ptr_pre = 0;
+	avs2_dec->bk.scalelut_ptr_pre = 0;
+	avs2_dec->fr.scalelut_ptr_changed = 0;
+	avs2_dec->bk.scalelut_ptr_changed = 0;
+
+	avs2_dec->fr.sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr; //for linux
+
+	print_loopbufs_ptr(dec, "init", &avs2_dec->fr);
+}
+
+static void uninit_mmu_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	if (dec->fb_buf_mmu0_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs2_dec->fb_buf_mmu0.buf_size, dec->fb_buf_mmu0_addr,
+			avs2_dec->fb_buf_mmu0.buf_start);
+		dec->fb_buf_mmu0_addr = NULL;
+	}
+	if (dec->fb_buf_mmu1_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs2_dec->fb_buf_mmu1.buf_size, dec->fb_buf_mmu1_addr,
+			avs2_dec->fb_buf_mmu1.buf_start);
+		dec->fb_buf_mmu1_addr = NULL;
+	}
+	if (dec->mmu_box_fb) {
+		decoder_mmu_box_free(dec->mmu_box_fb);
+		dec->mmu_box_fb = NULL;
+	}
+	dec->mmu_fb_4k_number = 0;
+}
+
+static void uninit_fb_bufstate(struct AVS2Decoder_s *dec)
+{
+	int i;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	for (i = 0; i < FB_LOOP_BUF_COUNT; i++) {
+		if (i != BMMU_IFBUF_SYS_IMEM_ID)
+		decoder_bmmu_box_free_idx(dec->bmmu_box, i);
+	}
+
+	if (avs2_dec->fb_buf_sys_imem_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs2_dec->fb_buf_sys_imem.buf_size, avs2_dec->fb_buf_sys_imem_addr,
+			avs2_dec->fb_buf_sys_imem.buf_start);
+		avs2_dec->fb_buf_sys_imem_addr = NULL;
+	}
+
+	uninit_mmu_fb_bufstate(dec);
+}
+
+static void config_bufstate_front_hw(struct avs2_decoder *avs2_dec)
+{
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_START, avs2_dec->fb_buf_mmu0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_END, avs2_dec->fb_buf_mmu0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0, avs2_dec->fr.mmu0_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_START, avs2_dec->fb_buf_mmu1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_END, avs2_dec->fb_buf_mmu1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1, avs2_dec->fr.mmu1_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_parser_sao0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_parser_sao0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_parser_sao1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_parser_sao1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//    config mpred_imp_if data write buffer start address
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_mpred_imp0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_mpred_imp0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_mpred_imp1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_mpred_imp1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config other buffers
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_scalelut.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_scalelut.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.scalelut_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.scalelut_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, avs2_dec->fr.scalelut_ptr_pre);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_vcpu_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_vcpu_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_sys_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_sys_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//config lmem buffers
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_lmem0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_lmem0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM0_BLOCK_SIZE);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs2_dec->fb_buf_lmem1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs2_dec->fb_buf_lmem1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs2_dec->fr.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs2_dec->bk.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM1_BLOCK_SIZE);
+}
+
+static void config_bufstate_back_hw(struct avs2_decoder *avs2_dec)
+{
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_START, avs2_dec->fb_buf_mmu0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_END, avs2_dec->fb_buf_mmu0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0, avs2_dec->bk.mmu0_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_START, avs2_dec->fb_buf_mmu1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_END, avs2_dec->fb_buf_mmu1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1, avs2_dec->bk.mmu1_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_parser_sao0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_parser_sao0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 1);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_parser_sao1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_parser_sao1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+//    config mpred_imp_if data write buffer start address
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 2);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_mpred_imp0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_mpred_imp0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 3);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_mpred_imp1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_mpred_imp1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config other buffers
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 4);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_scalelut.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_scalelut.buf_end);
+//    if (avs2_dec->bk.scalelut_ptr_changed)
+//        WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr);
+//    else
+//        WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr_pre);
+//    WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, avs2_dec->bk.scalelut_ptr_pre);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.scalelut_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 7);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_vcpu_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_vcpu_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 8);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_sys_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_sys_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config lmem buffers
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 5);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_lmem0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_lmem0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 6);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs2_dec->fb_buf_lmem1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs2_dec->fb_buf_lmem1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs2_dec->bk.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+}
+
+static void read_bufstate_front(struct avs2_decoder *avs2_dec)
+{
+	//struct AVS2Decoder_s *dec = container_of(avs2_dec,
+		//struct AVS2Decoder_s, avs2_dec);
+	//uint32_t tmp;
+	avs2_dec->fr.mmu0_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0);
+	avs2_dec->fr.mmu1_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+	//tmp = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	//if (avs2_dec->fr.scalelut_ptr == tmp)
+	//    avs2_dec->fr.scalelut_ptr_changed = 0;
+	//else
+	//    avs2_dec->fr.scalelut_ptr_changed = 1;
+	//avs2_dec->fr.scalelut_ptr = tmp;
+	avs2_dec->fr.scalelut_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	//avs2_dec->fr.scalelut_ptr_pre = READ_VREG(HEVC_ASSIST_RING_F_THRESHOLD);
+	//avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		//"pic_end_ptr = %x; pic_start_ptr = %x\n", avs2_dec->fr.scalelut_ptr, avs2_dec->fr.scalelut_ptr_pre);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+	avs2_dec->fr.vcpu_imem_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+	avs2_dec->fr.lmem0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+	avs2_dec->fr.lmem1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+	avs2_dec->fr.parser_sao0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+	avs2_dec->fr.parser_sao1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+	avs2_dec->fr.mpred_imp0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+	avs2_dec->fr.mpred_imp1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+
+	avs2_dec->fr.sys_imem_ptr = avs2_dec->sys_imem_ptr;
+	avs2_dec->fr.sys_imem_ptr_v = avs2_dec->sys_imem_ptr_v;
+}
+
+/*hw config*/
+
+/**/
+static int  compute_losless_comp_body_size(struct AVS2Decoder_s *dec,
+	int width, int height,
+	uint8_t is_bit_depth_10);
+static  int  compute_losless_comp_header_size(struct AVS2Decoder_s *dec,
+	int width, int height);
+
+static void config_work_space_hw(struct AVS2Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	struct BuffInfo_s* buf_spec = &dec->work_space_buf_store;
+	int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+	/*
+	int losless_comp_body_size;
+	cur_pic = dec->avs2_dec.hc.cur_pic;
+	losless_comp_body_size =
+		compute_losless_comp_body_size(
+		dec, cur_pic->pic_w,
+		cur_pic->pic_h, (dec->avs2_dec.hc.cur_pic->bit_depth == AVS2_BITS_10));
+	*/
+	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, is_bit_depth_10);
+	int losless_comp_body_size_dw = losless_comp_body_size;
+	int losless_comp_header_size_dw = losless_comp_header_size;
+
+	if (front_flag) {
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s front %x %x %x %x %x %x %x %x\n", __func__,
+		buf_spec->start_adr,
+		buf_spec->rpm.buf_start,
+		buf_spec->short_term_rps.buf_start,
+		buf_spec->rcs.buf_start,
+		buf_spec->sps.buf_start,
+				buf_spec->pps.buf_start,
+				buf_spec->swap_buf.buf_start,
+		buf_spec->swap_buf2.buf_start,
+		buf_spec->scalelut.buf_start);
+	WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+	//WRITE_VREG(HEVC_RPM_BUFFER, buf_spec->rpm.buf_start);
+	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_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);
+	}
+
+	if (back_flag) {
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s back %x %x %x %x %x %x %x\n", __func__,
+		buf_spec->ipp.buf_start,
+		buf_spec->ipp1.buf_start,
+				buf_spec->sao_up.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);
+	WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2,buf_spec->ipp1.buf_start);
+	WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE_DBE1,buf_spec->ipp1.buf_start);
+	WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2_DBE1,buf_spec->ipp.buf_start);
+	//WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+#ifdef AVS2_10B_MMU
+	//WRITE_VREG(H265_MMU_MAP_BUFFER, FRAME_MMU_MAP_ADDR);
+	WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, dec->frame_mmu_map_phy_addr);
+	WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR_DBE1, dec->frame_mmu_map_phy_addr_1); //new dual
+#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);
+		WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, dec->dw_frame_mmu_map_phy_addr_1); //new dual
+		//printk("WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2, 0x%x\n", FRAME_MMU_MAP_ADDR_DW_0);
+		//printk("WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, 0x%x\n", FRAME_MMU_MAP_ADDR_DW_1);
+	}
+#endif
+	//WRITE_VREG(HEVC_SCALELUT, buf_spec->scalelut.buf_start);
+
+		WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);
+		WRITE_VREG(HEVC_DBLK_CFG4_DBE1, buf_spec->dblk_para.buf_start);
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFG4: 0x%x\n", buf_spec->dblk_para.buf_start);
+		WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start);
+		WRITE_VREG(HEVC_DBLK_CFG5_DBE1, buf_spec->dblk_data.buf_start);
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFG5: 0x%x\n", buf_spec->dblk_data.buf_start);
+		WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start);
+		WRITE_VREG(HEVC_DBLK_CFGE_DBE1, buf_spec->dblk_data2.buf_start);
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFGE: 0x%x\n", 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);
+
+	data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+#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_DBE1, data32);
+
+#ifdef AVS2_10B_MMU
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,0x0);
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,(0x1<< 4)); // bit[4] : paged_mem_mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,0x0);
+#else
+	// WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe
+#if 1
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1, (0<<3)); // bit[3] smem mode
+#else
+	if (params->p.bit_depth != 0x00) WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+	else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe
+#endif
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,(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);
+	WRITE_VREG(HEVC_CM_BODY_LENGTH_DBE1,losless_comp_body_size);
+	WRITE_VREG(HEVC_CM_HEADER_OFFSET_DBE1,losless_comp_body_size);
+	WRITE_VREG(HEVC_CM_HEADER_LENGTH_DBE1,losless_comp_header_size);
+#else // LOSLESS_COMPRESS_MODE
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31);
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,0x1 << 31);
+#endif
+#ifdef AVS2_10B_MMU
+	#if 1
+		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/4);
+		WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start  + buf_spec->mmu_vbh.buf_size/2);
+		WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2 + buf_spec->mmu_vbh.buf_size/4);
+	#else
+		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);
+		WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start);
+		WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2);
+	#endif
+
+	/* use HEVC_CM_HEADER_START_ADDR */
+	data32 = READ_VREG(HEVC_SAO_CTRL5);
+	data32 |= (1<<10);
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+	data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+	data32 |= (1<<10);
+	WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#endif
+#ifdef AVS2_10B_MMU_DW
+if (dec->dw_mmu_enable) {
+		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_CM_BODY_LENGTH2_DBE1,losless_comp_body_size_dw);
+		WRITE_VREG(HEVC_CM_HEADER_OFFSET2_DBE1,losless_comp_body_size_dw);
+		WRITE_VREG(HEVC_CM_HEADER_LENGTH2_DBE1,losless_comp_header_size_dw);
+
+	#if 1
+		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 + buf_spec->mmu_vbh_dw.buf_size/4);
+		WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+		WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2 + buf_spec->mmu_vbh_dw.buf_size/4);
+	#else
+		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 + buf_spec->mmu_vbh_dw.buf_size/2);
+		WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start);
+		WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+	#endif
+
+	#ifdef AVS2_10B_MMU_DW
+	#if 1
+	#ifndef FOR_S5
+		WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+		WRITE_VREG(HEVC_DW_VH0_ADDDR_DBE1, DOUBLE_WRITE_VH0_HALF);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR_DBE1, DOUBLE_WRITE_VH1_HALF);
+	#endif
+	#else
+		//WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+		//WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+		WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+	#endif
+	#endif
+
+	/* use HEVC_CM_HEADER_START_ADDR */
+	data32 = READ_VREG(HEVC_SAO_CTRL5);
+	data32 |= (1<<15);
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+	data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+	data32 |= (1<<15);
+	WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+}
+#endif
+
+	} // back_flag
+	if (front_flag) {
+	WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+#ifdef CO_MV_COMPRESS
+	data32 = READ_VREG(HEVC_MPRED_CTRL4);
+	data32 |=  (1<<1);
+	WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+#endif
+	} // front_flag
+
+}
+
+static void hevc_init_decoder_hw(struct AVS2Decoder_s *dec,
+	uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	int32_t i;
+
+int32_t g_WqMDefault4x4[16] = {
+	64,     64,     64,     68,
+	64,     64,     68,     72,
+	64,     68,     76,     80,
+	72,     76,     84,     96
+};
+
+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
+};
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Entering hevc_init_decoder_hw\n");
+#if 0
+	printk("[test.c] Test Parser Register Read/Write\n");
+	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; }
+
+	// test Parser Reset
+	WRITE_VREG(DOS_SW_RESET1, (1<<3)); // reset_whole parser
+	WRITE_VREG(DOS_SW_RESET1, 0); // reset_whole parser
+	data32 = READ_VREG(HEVC_PARSER_VERSION);
+	if (data32 != 0x00010001) { print_scratch_error(27); return; }
+#endif
+
+#if 0 // JT
+	printk("[test.c] Enable BitStream Fetch\n");
+	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);
+#endif // JT
+
+#if 0 //def AVS2_10B_HED_FB
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Init AVS2_10B_HED_FB\n");
+	data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+	data32 = data32 |
+		(1 << 3) | // fb_read_avs2_enable0
+		(1 << 6) | // fb_read_avs2_enable1
+		(1 << 1) | // fb_avs2_enable
+		(0 << 13) | // fb_read_avs3_enable0
+		(0 << 14) | // fb_read_avs3_enable1
+		(0 << 9) | // fb_avs3_enable
+		(3 << 7)  //core0_en, core1_en,hed_fb_en
+		;
+	WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+//    data32 = READ_VREG(P_HEVC_ASSIST_FB_W_CTL);
+//    data32 = data32 |
+//             (1 << 0)    // hed_fb_wr_en
+		;
+//    WRITE_VREG(P_HEVC_ASSIST_FB_W_CTL, data32);
+
+//#ifdef H265_10B_HED_SAME_FB
+//    printk("[test.c] Init H265_10B_HED_SAME_FB\n");
+//    data32 = READ_VREG(P_HEVC_ASSIST_FB_R_CTL);
+//    data32 = data32 |
+//             (1 << 0)    // hed_fb_rd_en
+//             ;
+//    WRITE_VREG(P_HEVC_ASSIST_FB_R_CTL, data32);
+//#endif
+
+#endif
+#if 1 //move to ucode
+	if (!efficiency_mode && front_flag) {
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable HEVC Parser Interrupt\n");
+	data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+	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);
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable HEVC Parser Shift\n");
+
+	data32 = READ_VREG(HEVC_SHIFT_STATUS);
+#ifdef AVS2
+	data32 = data32 |
+		(0 << 1) |  // emulation_check_on // AVS2 emulation on/off will be controlled in microcode according to startcode type
+		(1 << 0)    // startcode_check_on
+		;
+#else
+	data32 = data32 |
+		(1 << 1) |  // emulation_check_on
+		(1 << 0)    // startcode_check_on
+		;
+#endif
+	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);
+
+	}
+#endif
+
+	if (!efficiency_mode && back_flag) {
+#if 0 // Dual Core : back Microcode will always initial SCALELUT
+	// Initial IQIT_SCALELUT memory -- just to avoid X in simulation
+	printk("[test.c] Initial IQIT_SCALELUT memory -- just to avoid X in simulation...\n");
+	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_DBE1, 0); // cfg_p_addr
+	for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, 0);
+#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
+		}
+		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR_DBE1, (0 << 8) | (0<<1) | 1);
+		for (i=0; i<32; i++) {
+			WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#ifdef DUAL_CORE_64
+			WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#endif
+		}
+	}
+
+	if (!efficiency_mode && front_flag) {
+#ifdef ENABLE_SWAP_TEST
+		WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+#else
+		WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+#endif
+
+	//WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
+	//WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, decode_pic_num);
+#if 0
+	// Send parser_cmd
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] SEND Parser Command ...\n");
+	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);
+#endif
+#if 1 //move to ucode
+
+	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
+		);
+#endif
+	}
+
+#if 0
+//def MULTI_INSTANCE_SUPPORT
+	// Begin of Multi-instance
+	WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+	WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+	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);
+
+	// End of Multi-instance
+#endif
+	// Changed to Start MPRED in microcode
+	/*
+	printk("[test.c] Start MPRED\n");
+	WRITE_VREG(HEVC_MPRED_INT_STATUS,
+		(1<<31)
+		);
+	*/
+
+	// AVS2 default seq_wq_matrix config
+	if (!efficiency_mode && back_flag) {
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+			"[test.c] Config AVS2 default seq_wq_matrix ...\n");
+		// 4x4
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+		for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+		// 8x8
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+		for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+		// 4x4
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+		for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+		// 8x8
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+		for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+			"[test.c] Reset IPP\n");
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+			(0 << 1) | // enable ipp
+			(4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(1 << 0)   // software reset ipp and mpp
+			);
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+			(1 << 1) | // enable ipp
+			(4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(0 << 0)   // software reset ipp and mpp
+			);
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+			(0 << 1) | // enable ipp
+			(4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(1 << 0)   // software reset ipp and mpp
+			);
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+			(1 << 1) | // enable ipp
+			(4 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(0 << 0)   // software reset ipp and mpp
+			);
+
+		// Init dblk
+#define LPF_LINEBUF_MODE_CTU_BASED
+	//must be defined for DUAL_CORE
+
+		data32 = READ_VREG(HEVC_DBLK_CFGB);
+		data32 |= (2 << 0);
+		WRITE_VREG(HEVC_DBLK_CFGB, data32); // [3:0] cfg_video_type -> AVS2
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+		WRITE_VREG(HEVC_DBLK_CFG0, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+		WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+
+		data32 = READ_VREG(HEVC_DBLK_CFGB_DBE1);
+		data32 |= (2 << 0);
+		WRITE_VREG(HEVC_DBLK_CFGB_DBE1, data32); // [3:0] cfg_video_type -> AVS2
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+		WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+		WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+
+		avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+			"[test.c] Bitstream level Init for DBLK .Done.\n");
+
+		// Initialize mcrcc and decomp perf counters
+#if 0
+		mcrcc_perfcount_reset();
+		decomp_perfcount_reset();
+#endif
+	}//back_flag end
+	if (back_flag) {
+#if 0
+		//to do: move to config_sao_hw_fb
+		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);
+	#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 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+
+		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);
+		WRITE_VREG(HEVC_SAO_CTRL1_DBE1, 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);
+		WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+		} else {
+		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7) {
+			WRITE_VREG(HEVC_SAO_CTRL26, 0);
+			WRITE_VREG(HEVC_SAO_CTRL26_DBE1, 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) {
+			data32 |= (0xff<<16);
+			WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
+			WRITE_VREG(HEVC_SAO_CTRL26_DBE1, 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)
+			data32 |= (0x33<<16);
+		WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+		}
+#endif
+		if (dec->mmu_enable) {
+		data32 = READ_VREG(HEVC_SAO_CTRL9);
+		data32 |= 0x1;
+		WRITE_VREG(HEVC_SAO_CTRL9, data32);
+		WRITE_VREG(HEVC_SAO_CTRL9_DBE1, data32);
+		}
+	#ifdef AVS2_10B_MMU_DW
+		if (dec->dw_mmu_enable) {
+		data32 = READ_VREG(HEVC_SAO_CTRL9);
+		data32 |= (1 << 10);
+		WRITE_VREG(HEVC_SAO_CTRL9, data32);
+		WRITE_VREG(HEVC_SAO_CTRL9_DBE1, data32);
+		}
+	#endif
+	}
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Leaving hevc_init_decoder_hw\n");
+	return;
+}
+
+extern void config_cuva_buf(struct AVS2Decoder_s *dec);
+static int32_t avs2_hw_init(struct AVS2Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	uint32_t tmp = 0;
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s front_flag %d back_flag %d\n", __func__, front_flag, back_flag);
+	if (dec->front_back_mode != 1) {
+		if (front_flag)
+		avs2_hw_ctx_restore(dec);
+		if (back_flag) {
+		/* clear mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+		/* enable mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+
+		}
+		return 0;
+	}
+
+	if (front_flag) {
+		data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+		data32 = data32 | (3 << 7) | (1 << 1);
+		tmp = (1 << 0) | (1 << 9) | (1 << 10);
+		data32 &= ~tmp;
+		WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+	}
+
+	if (back_flag) {
+		data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+		data32 = data32 | (3 << 7) | (1 << 3) | (1 << 6);
+		tmp = (1 << 2) | (1 << 13) | (1 << 11) | (1 << 5) | (1 << 14) | (1 << 12);
+		data32 &= ~tmp;
+		WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+	}
+
+	config_work_space_hw(dec, front_flag, back_flag);
+
+	if (!efficiency_mode && front_flag && dec->pic_list_init_flag)
+		init_pic_list_hw_fb(dec);
+
+	hevc_init_decoder_hw(dec, front_flag, back_flag);
+
+//Start JT
+#if 1 //move to ucode
+	if (!efficiency_mode && front_flag) {
+#if 0
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable BitStream Fetch\n");
+
+	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 -1; }
+	/*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 -1; }
+	data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+	if (data32 != 0x9abcdef0) { print_scratch_error(32); return -1; }
+#endif
+	WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+	WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000); // 0x000000 - 0x000003 emulate code for AVS2
+	}
+#endif
+// End JT
+
+	if (!efficiency_mode && back_flag) {
+// 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);
+		WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL_DBE1, data32);
+
+		// Set IPP MULTICORE CFG
+		WRITE_VREG(HEVCD_IPP_MULTICORE_CFG, 1);
+		WRITE_VREG(HEVCD_IPP_MULTICORE_CFG_DBE1, 1);
+
+#ifdef DYN_CACHE
+		if (dec->front_back_mode == 1) {
+			WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+			WRITE_VREG(HEVCD_IPP_DYN_CACHE_DBE1,0x2b);//enable new mcrcc
+			avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+		}
+#endif
+	}
+
+if (front_flag) {
+	unsigned int decode_mode;
+
+	WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+
+#if 1 // JT
+
+#if 0 //def SIMULATION
+	if (decode_pic_begin == 0)
+		WRITE_VREG(HEVC_WAIT_FLAG, 1);
+	else
+		WRITE_VREG(HEVC_WAIT_FLAG, 0);
+#else
+	WRITE_VREG(HEVC_WAIT_FLAG, 1);
+#endif
+
+	/* disable PSCALE for hardware sharing */
+#ifdef DOS_PROJECT
+#else
+#ifndef FOR_S5
+	WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+#endif
+#endif
+	/* clear mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+	/* enable mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+	//WRITE_VREG(DEBUG_REG1, 0x0);  //no debug
+	WRITE_VREG(NAL_SEARCH_CTL, 0x8); //check SEQUENCE/I_PICTURE_START in ucode
+	WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+#ifdef MULTI_INSTANCE_SUPPORT
+	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(DECODE_MODE, 1); //DECODE_MODE_MULTI_STREAMBASE
+	WRITE_VREG(HEVC_DECODE_SIZE, 0xffffffff);
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"decode_mode 0x%x\n", decode_mode);
+	config_cuva_buf(dec);
+#endif
+
+	//WRITE_VREG(XIF_DOS_SCRATCH31, 0x0);
+	//WRITE_VREG(HEVC_MPSR, 1);
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[test.c] P_HEVC_MPSR!\n");
+#endif
+	}
+	if (back_flag) {
+		/* clear mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+		/* enable mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+	}
+
+	return 0;
+}
+
+static void release_free_mmu_buffers(struct AVS2Decoder_s *dec)
+{
+	int ii;
+
+	if (!(dec->error_proc_policy & 0x2))
+		return ;
+
+	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 &&
+#ifdef NEW_FRONT_BACK_CODE
+			pic->backend_ref == 0 &&
+#endif
+		pic->vf_ref == 0) {
+		if (pic->referred_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);
+			if (dec->front_back_mode)
+			decoder_mmu_box_free_idx(dec->mmu_box_1,
+				pic->index);
+#endif
+#ifdef AVS2_10B_MMU_DW
+			if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+			decoder_mmu_box_free_idx(dec->dw_mmu_box,
+				pic->index);
+			if (dec->front_back_mode && dec->dw_mmu_box_1)
+				decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+				pic->index);
+			}
+
+#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
+		}
+		}
+	}
+
+}
+
+static int BackEnd_StartDecoding(struct AVS2Decoder_s *dec)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+	int cur_mmu_4k_number;
+	int i = 0;
+
+	avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+		"Start BackEnd Decoding %d (wr pos %d, rd pos %d) poc %d\n",
+		avs2_dec->backend_decoded_count, avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos, pic->poc);
+	if (dec->front_back_mode != 1 &&
+		dec->front_back_mode != 3) {
+		copy_loopbufs_ptr(&avs2_dec->bk, &avs2_dec->next_bk[avs2_dec->fb_rd_pos]);
+		print_loopbufs_ptr(dec, "bk", &avs2_dec->bk);
+		avs2_hw_init(dec, 0, 1);
+
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+		return 0;
+	}
+#if 0
+#ifdef AVS2_10B_MMU
+	alloc_mmu(&avs2_mmumgr_0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+	alloc_mmu(&avs2_mmumgr_1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#ifdef AVS2_10B_MMU_DW
+	alloc_mmu(&avs2_mmumgr_dw0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+	alloc_mmu(&avs2_mmumgr_dw1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#endif
+	pic->mmu_alloc_flag = 1;
+#endif
+#else
+
+	mutex_lock(&dec->fb_mutex);
+	for (i = 0; (i < MAXREF) && (pic->error_mark == 0); i++) {
+		if ((pic->ref_pic[i]) && (pic->ref_pic[i]->error_mark)) {
+			avs2_print(dec, AVS2_DBG_BUFMGR,
+				"%s ref pic(%d) has error_mark, skip\n", __func__, i);
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == I_IMG) {
+				dec->gvs->i_concealed_frames++;
+			} else if ((pic->slice_type == P_IMG) ||
+				(pic->slice_type == F_IMG)) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == B_IMG) {
+				dec->gvs->b_concealed_frames++;
+			}
+			pic->error_mark = 1;
+			break;
+		}
+	}
+	mutex_unlock(&dec->fb_mutex);
+
+	if ((dec->error_proc_policy & 0x2) && pic->error_mark) {
+		mutex_lock(&dec->fb_mutex);
+		dec->gvs->drop_frame_count++;
+		if (pic->slice_type == I_IMG) {
+			dec->gvs->i_lost_frames++;
+		} else if ((pic->slice_type == P_IMG) ||
+			(pic->slice_type == F_IMG)) {
+			dec->gvs->p_lost_frames++;
+		} else if (pic->slice_type == B_IMG) {
+			dec->gvs->b_lost_frames++;
+		}
+		mutex_unlock(&dec->fb_mutex);
+
+		avs2_print(dec, AVS2_DBG_BUFMGR, "%s pic has error_mark, skip\n", __func__);
+		pic_backend_ref_operation(dec, 0);
+		return 1;
+	}
+
+	cur_mmu_4k_number = avs2_mmu_page_num(dec,
+		pic->width, pic->height / 2 + 32 + 8, pic->depth == 10);
+
+	if (cur_mmu_4k_number < 0)
+		return -1;
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"%s:pic->index %d, mmu_4k_number %d\n", __func__, pic->index, cur_mmu_4k_number);
+
+	if (dec->mmu_enable) {
+		decoder_mmu_box_alloc_idx(
+			dec->mmu_box,
+			pic->index,
+			cur_mmu_4k_number,
+			dec->frame_mmu_map_addr);
+
+		decoder_mmu_box_alloc_idx(
+			dec->mmu_box_1,
+			pic->index,
+			cur_mmu_4k_number,
+			dec->frame_mmu_map_addr_1);
+		if (dec->dw_mmu_enable) {
+			decoder_mmu_box_alloc_idx(
+				dec->dw_mmu_box,
+				pic->index,
+				cur_mmu_4k_number,
+				dec->dw_frame_mmu_map_addr);
+
+			decoder_mmu_box_alloc_idx(
+				dec->dw_mmu_box_1,
+				pic->index,
+				cur_mmu_4k_number,
+				dec->dw_frame_mmu_map_addr_1);
+		}
+	}
+	pic->mmu_alloc_flag = 1;
+#endif
+	copy_loopbufs_ptr(&avs2_dec->bk, &avs2_dec->next_bk[avs2_dec->fb_rd_pos]);
+	print_loopbufs_ptr(dec, "bk", &avs2_dec->bk);
+
+	if (dec->front_back_mode == 1)
+		amhevc_reset_b();
+
+	if (efficiency_mode)
+		WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 1);
+	else
+		WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 0);
+	avs2_hw_init(dec, 0, 1);
+	if (dec->front_back_mode == 3) {
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+	} else {
+		config_bufstate_back_hw(avs2_dec);
+		WRITE_VREG(PIC_DECODE_COUNT_DBE, avs2_dec->backend_decoded_count);
+		WRITE_VREG(HEVC_DEC_STATUS_DBE, HEVC_BE_DECODE_DATA);
+		WRITE_VREG(HEVC_SAO_CRC, 0);
+		amhevc_start_b();
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC_BACK);
+	}
+
+	return 0;
+}
+
+#if 1
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec)
+{
+	int i;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic;
+
+	dec->avs2_dec.ins_offset = 0;
+	/*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
+	WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+
+	for (i = 0; i < dec->used_buf_num; i++) {
+#if 0
+		if (i == (dec->used_buf_num - 1))
+		pic = avs2_dec->m_bg;
+		else
+		pic = avs2_dec->fref[i];
+#else
+		pic = avs2_dec->init_fref[i];
+#endif
+		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_BACK_16(avs2_dec, 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_BACK_16(avs2_dec, HEVC2_MPP_ANC2AXI_TBL_CONF_ADDR,
+		(0x1 << 1) | (pic->index << 8));
+	else
+		WRITE_BACK_16(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+		(0x1 << 1) | (pic->index << 8));
+#endif
+	WRITE_BACK_32(avs2_dec, 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_BACK_32(avs2_dec, 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_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+#ifdef DUAL_CORE_64
+#ifdef AVS2_10B_MMU
+	WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+		pic->header_adr >> 5);
+#else
+	WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+		pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+	WRITE_BACK_32(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_DATA,
+		pic->mc_u_v_adr >> 5);
+#endif
+/*DUAL_CORE_64*/
+#endif
+	}
+	WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#ifdef DUAL_CORE_64
+	WRITE_BACK_8(avs2_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+		0x1);
+#endif
+#if 0
+	/*Zero out canvas registers in IPP -- avoid simulation X*/
+	WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+		(0 << 8) | (0 << 1) | 1);
+	for (i = 0; i < 32; i++) {
+		WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#ifdef DUAL_CORE_64
+		WRITE_BACK_8(avs2_dec, HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+#endif
+	}
+#endif
+}
+
+#else
+static void init_pic_list_hw_fb(struct AVS2Decoder_s *dec)
+{
+	int i;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic;
+	dec->avs2_dec.ins_offset = 0;
+
+	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_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+		(0x1 << 1) | (pic->index << 8));
+
+	WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->header_adr >> 5);
+#else
+	WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+	WRITE_BACK_32(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+	}
+	WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+#if 0
+	/*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);
+	}
+#endif
+}
+#endif
+
+static void config_mpred_hw_fb(struct AVS2Decoder_s *dec)
+{
+	//int32_t i;
+	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     AMVP_MAX_NUM_CANDS_MEM=3;
+	//int32_t     AMVP_MAX_NUM_CANDS=2;
+	//int32_t     NUM_CHROMA_MODE=5;
+	//int32_t     DM_CHROMA_IDX=36;
+	//int32_t     above_ptr_ctrl =0;
+	//int32_t     buffer_linear =1;
+	//int32_t     cu_size_log2 =3;
+	int32_t     mpred_mv_rd_start_addr ;
+	//int32_t     mpred_curr_lcu_x;
+	//int32_t     mpred_curr_lcu_y;
+	//int32_t     mpred_above_buf_start ;
+	//int32_t     mpred_mv_rd_ptr ;
+	//int32_t     mpred_mv_rd_ptr_p1 ;
+	int32_t     mpred_mv_rd_end_addr;
+	int32_t     MV_MEM_UNIT_l;
+	//int32_t     mpred_mv_wr_ptr ;
+
+	int32_t     above_en;
+	int32_t     mv_wr_en;
+	int32_t     mv_rd_en;
+	int32_t     col_isIntra;
+	//if (dec->slice_type!=2)
+	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_l=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_l);
+
+	//mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"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);
+
+#if 0
+	data32 = ((dec->lcu_x_num - dec->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  =   (
+		dec->slice_type |
+		dec->new_pic<<2 |
+		dec->new_tile<<3|
+		dec->isNextSliceSegment<<4|
+		dec->TMVPFlag<<5|
+		dec->LDCFlag<<6|
+		dec->ColFromL0Flag<<7|
+		above_ptr_ctrl<<8 |
+		above_en<<9|
+		mv_wr_en<<10|
+		mv_rd_en<<11|
+		col_isIntra<<12|
+		buffer_linear<<13|
+		dec->LongTerm_Curr<<14|
+		dec->LongTerm_Col<<15|
+		avs2_dec->lcu_size_log2<<16|
+		cu_size_log2<<20|
+		dec->plevel<<24
+		);
+	WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+
+	data32 = READ_VREG(HEVC_MPRED_CTRL1);
+	data32  =   (
+#ifdef DOS_PROJECT
+//no set in m8baby test1902
+	(data32 & (0x1<<24)) |  // Don't override clk_forced_on ,
+#endif
+		dec->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  =   (
+		dec->pic_w|
+		dec->pic_h<<16
+		);
+	WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+	data32  =   (
+		(dec->lcu_x_num-1)   |
+		(dec->lcu_y_num-1)<<16
+		);
+	WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU,data32);
+
+	data32  =   (
+		dec->tile_start_lcu_x   |
+		dec->tile_start_lcu_y<<16
+		);
+	WRITE_VREG(HEVC_MPRED_TILE_START,data32);
+
+	data32  =   (
+		dec->tile_width_lcu   |
+		dec->tile_height_lcu<<16
+		);
+	WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU,data32);
+
+	data32  =   (
+		dec->RefNum_L0   |
+		dec->RefNum_L1<<8|
+		0
+		//col_RefNum_L0<<16|
+		//col_RefNum_L1<<24
+		);
+	WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+	data32  =   (
+		dec->LongTerm_Ref
+		);
+	WRITE_VREG(HEVC_MPRED_LT_REF,data32);
+
+	data32=0;
+	for (i=0;i<dec->RefNum_L0;i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+	data32=0;
+	for (i=0;i<dec->RefNum_L1;i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+	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]);
+
+#if 0
+	if (dec->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 (!dec->isNextSliceSegment)
+	{
+		//WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1);
+		WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+	}
+#endif
+	WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dw_fb(struct AVS2Decoder_s *dec, struct avs2_frame_s *pic,
+		u32 mc_buffer_size_u_v_h)
+{
+
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	int dw_mode = get_double_write_mode(dec);
+	uint32_t data = 0, data32;
+	if ((dw_mode & 0x10) == 0) {
+		WRITE_BACK_8(avs2_dec, HEVC_SAO_CTRL26, 0);
+
+		//data32 = READ_VREG(HEVC_SAO_CTRL5);
+		//data32 &= (~(0xff << 16));
+		if (((dw_mode & 0xf) == 8) ||
+		((dw_mode & 0xf) == 9)) {
+		data = 0xff; //data32 |= (0xff << 16);
+		//WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		WRITE_BACK_8(avs2_dec, HEVC_SAO_CTRL26, 0xf);
+		} else {
+		if ((dw_mode & 0xf) == 2 ||
+			(dw_mode & 0xf) == 3)
+			data = 0xff; //data32 |= (0xff<<16);
+		else if ((dw_mode & 0xf) == 4 ||
+			(dw_mode & 0xf) == 5)
+			data = 0x33; //data32 |= (0x33<<16);
+
+		/*if (dec->mem_saving_mode == 1)
+			READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 1, 9, 1); //data32 |= (1 << 9);
+		else*/
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 0, 9, 1); //data32 &= ~(1 << 9);
+		/*if (workaround_enable & 1)
+			READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 1, 7, 1); //data32 |= (1 << 7);*/
+		//WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		}
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, data, 16, 8);
+	}
+
+		/* m8baby test1902 */
+		//data32 = READ_VREG(HEVC_SAO_CTRL1);
+		//data32 &= (~0x3000);
+		/* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+		//data32 |= (dec->mem_map_mode << 12);
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, MEM_MAP_MODE, 12, 2);
+		//data32 &= (~0xff0);
+#ifdef AVS2_10B_MMU_DW
+		if (dec->dw_mmu_enable == 0)
+		data = ((dec->endian >> 8) & 0xfff); //endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf)
+#else
+		data = ((dec->endian >> 8) & 0xfff);    /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, data, 0, 12);
+
+		//data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+		if (dw_mode == 0)
+		data = 0x2; //data32 |= 0x2; /*disable double write*/
+		else if (dw_mode & 0x10)
+		data = 0x1; //data32 |= 0x1; /*disable cm*/
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, data, 0, 2);
+
+		//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
+	 */
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL1, 2, 14, 2);
+		//WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+#if 0
+		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 (dec->init_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)
+			data |= (0x1 << 8); /*enable first write*/
+			else if (dw_mode & 0x10)
+			data |= (0x1 << 9); /*double write only*/
+			else
+			data |= ((0x1 << 8)  |(0x1 << 9));
+			WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGB, data);
+			//WRITE_VREG(HEVC_DBLK_CFGB, data);
+		}
+#else
+		//data32 &= (~0x300); /*[8]:first write enable (compress)
+		//                [9]:double write enable (uncompress)*/
+		if (dw_mode == 0)
+		data = 1; //data32 |= (0x1 << 8); /*enable first write*/
+		else if (dw_mode == 0x10)
+		data = 2; //data32 |= (0x1 << 9); /*double write only*/
+		else
+		data = 3; //data32 |= ((0x1 << 8) | (0x1 << 9));
+		//WRITE_VREG(HEVC_DBLK_CFGB, data32);
+		READ_WRITE_DATA16(avs2_dec, HEVC_DBLK_CFGB, data, 8, 2);
+#endif
+		if (dw_mode & 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);
+		READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL5, 0, 16, 8);
+		}
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+	data32 = pic->mc_y_adr;
+	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	if ((dw_mode & 0x10) == 0)
+		WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, data32);
+
+	if (dec->mmu_enable)
+		WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS2_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0);
+		WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+	}
+#endif
+#else
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+	data32 = (mc_buffer_size_u_v_h << 16) << 1;
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_LENGTH, data32);
+
+	data32 = (mc_buffer_size_u_v_h << 16);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_C_LENGTH, data32);
+
+}
+
+static void config_sao_hw_fb(struct AVS2Decoder_s *dec)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic = avs2_dec->hc.cur_pic;
+	//union param_u* params = &avs2_dec->param;
+	//uint32_t data32; // data32_2;
+	int32_t pic_width = avs2_dec->img.width;
+	int32_t pic_height = avs2_dec->img.height;
+	int32_t lcu_size_log2 = avs2_dec->lcu_size_log2;
+	int32_t lcu_size = 1<<lcu_size_log2;
+	int32_t pic_width_lcu  = ( pic_width % lcu_size  ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+	int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+	int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+	int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+	int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+	config_dw_fb(dec, pic, mc_buffer_size_u_v_h);
+#if 0 // no dual mode
+	data32 = READ_VREG(HEVC_SAO_CTRL0);
+	data32 &= (~0xf);
+	data32 |= avs2_dec->lcu_size_log2;
+	WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#else
+	READ_WRITE_DATA16(avs2_dec, HEVC_SAO_CTRL0, avs2_dec->lcu_size_log2, 0, 4);
+#endif
+
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_BACK_32(avs2_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+	if ((get_double_write_mode(dec) & 0x20) == 0) {
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+	if (dec->dw_mmu_enable) {
+		WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, 0);
+		WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR, 0);
+	}
+
+#ifdef AVS2_10B_MMU
+	///WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs2_dec->cm_header_start + (pic->index * MMU_COMPRESS_HEADER_SIZE));
+	//WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR, avs2_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS2_10B_MMU_DW
+	//if (dec->dw_mmu_enable) {
+		///WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+	//   WRITE_BACK_32(avs2_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+	//}
+#endif
+
+#else
+	///WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+	data32 = (mc_buffer_size_u_v_h<<16)<<1;
+	//WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_LENGTH ,data32);
+
+	///WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+	//WRITE_BACK_32(avs2_dec, HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+	data32 = (mc_buffer_size_u_v_h<<16);
+	///WRITE_VREG(HEVC_SAO_C_LENGTH  ,data32);
+	WRITE_BACK_32(avs2_dec, HEVC_SAO_C_LENGTH  ,data32);
+	///WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+	//WRITE_BACK_32(avs2_dec, HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+	///WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+	//WRITE_BACK_32(avs2_dec, HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+#ifdef AVS2_10B_NV21
+	SHOULD NOT DEFINED !!
+	data32 = READ_VREG(HEVC_SAO_CTRL1);
+	data32 &= (~0x3000);
+	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);
+
+	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 H265_NV21 (no down-scale)
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+	data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+	data32 &= (~0x30);
+	data32 |= (MEM_MAP_MODE << 4); // [5:4]    -- address_format 00:linear 01:32x32 10:64x32
+	WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"[c] cfgSAO .done.\n");
+}
+
+static void config_dblk_hw_fb(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;
+
+#if 0 // NOT Dual Mode
+	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
+#ifdef LPF_SPCC_ENABLE
+		//data32 |= (dec->pic_w <= 64)?(1<<20):0; // if pic width isn't more than one CTU, disable pipeline
+		data32 |= (0x3<<20); // SPCC_ENABLE
+#endif
+	WRITE_VREG(HEVC_DBLK_CFG1, data32);
+#else
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0x6450101;                                          //mfsp COMMON_REG_1, HEVC_DBLK_CFG1
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((((avs2_dec->input.sample_bit_depth == 10) ? 0xa:0x0)&0xffff)<<6);   // movi COMMON_REG_0, data
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x, bit_depth %x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], avs2_dec->input.sample_bit_depth);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0x9604040;                                          //ins  COMMON_REG_1, COMMON_REG_0, 16, 4
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | ((((rpm_param->p.lcu_size == 6) ? 0:(rpm_param->p.lcu_size == 5) ? 1:2))<<6);   // movi COMMON_REG_0, data
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x, rpm_param->p.lcu_size %x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset], rpm_param->p.lcu_size);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0x9402040;                                          //ins  COMMON_REG_1, COMMON_REG_0, 0, 2
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#ifdef LPF_SPCC_ENABLE
+	avs2_dec->instruction[avs2_dec->ins_offset] = (0x1a<<22) | (3<<6);   // movi COMMON_REG_0, data
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0x9682040;                                          //ins  COMMON_REG_1, COMMON_REG_0, 20, 2
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#endif
+
+	avs2_dec->instruction[avs2_dec->ins_offset] = 0x6050101;                                          //mtsp COMMON_REG_1, HEVC_DBLK_CFG1
+	avs2_print(dec, AVS2_DBG_BUFMGR_DETAIL,
+		"instruction[%3d] = %8x\n",  avs2_dec->ins_offset, avs2_dec->instruction[avs2_dec->ins_offset]);
+	avs2_dec->ins_offset++;
+#endif
+
+	data32 = (avs2_dec->img.height<<16) | avs2_dec->img.width;
+	//WRITE_VREG(HEVC_DBLK_CFG2, data32);
+	WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFG2, data32);
+
+	data32 = ((avs2_dec->input.crossSliceLoopFilter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+		((rpm_param->p.loop_filter_disable & 0x1)<<26) |               // [26 +: 1]: loop_filter_disable
+		((avs2_dec->input.useNSQT & 0x1)<<25) |                        // [25 +: 1]: useNSQT
+		((avs2_dec->img.type & 0x7)<<22) |                             // [22 +: 3]: imgtype
+		((rpm_param->p.alpha_c_offset&0x1f) <<17) |                    // [17 +: 5]: alpha_c_offset (-8~8)
+		((rpm_param->p.beta_offset&0x1f) <<12) |                       // [12 +: 5]: beta_offset (-8~8)
+		((rpm_param->p.chroma_quant_param_delta_cb&0x3f)<<6) |         // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+		((rpm_param->p.chroma_quant_param_delta_cr&0x3f)<<0);          // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+	///WRITE_VREG(HEVC_DBLK_CFG9, data32);
+	WRITE_BACK_32(avs2_dec, 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 reconstructCoefInfo(struct AVS2Decoder_s *dec,
+	int32_t compIdx, struct ALFParam_s *alfParam);
+static void config_alf_hw_fb(struct AVS2Decoder_s *dec)
+{
+	/*
+	* Picture level ALF parameter configuration here
+	*/
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	uint32_t data32;
+	int32_t i,j;
+	int32_t m_filters_per_group;
+	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);
+	WRITE_BACK_32(avs2_dec, 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);
+	WRITE_BACK_32(avs2_dec, 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);
+	WRITE_BACK_32(avs2_dec, 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);
+	WRITE_BACK_32(avs2_dec, 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);
+	WRITE_BACK_32(avs2_dec, 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);
+	WRITE_BACK_32(avs2_dec, 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);
+		WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+		data32 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+			((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);
+		WRITE_BACK_32(avs2_dec, HEVC_DBLK_CFGD, data32);
+	}
+	if (debug & AVS2_DBG_BUFMGR_DETAIL) {
+		for (i=0;i<m_filters_per_group;i++)
+			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_mcrcc_axi_hw_fb(struct AVS2Decoder_s *dec)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	//uint32_t rdata32;
+	//uint32_t rdata32_2;
+
+	///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+	WRITE_BACK_8(avs2_dec, HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+
+	if (avs2_dec->img.type  == I_IMG) { // I-PIC
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+		WRITE_BACK_8(avs2_dec, HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+		return;
+	}
+
+#if 0
+	mcrcc_get_hitrate();
+	decomp_get_hitrate();
+	decomp_get_comprate();
+#endif
+
+	if ((avs2_dec->img.type  == B_IMG) || (avs2_dec->img.type  == F_IMG)) {  // B-PIC or F_PIC
+		// Programme canvas0
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+		WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+	READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+		// Programme canvas1
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (1<<1) | 0);
+		WRITE_BACK_16(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1, (16 << 8) | (1<<1) | 0);
+		///rdata32_2 = READ_VREG_V(P_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_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///    rdata32_2 = rdata32_2 & 0xffff;
+		///    rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+		///}
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32_2);
+		READ_CMP_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 1, 0, 16, 16);
+	} else { // P-PIC
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+		WRITE_BACK_8(avs2_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+	READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+		// Programme canvas1
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32);
+	READ_INS_WRITE(avs2_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 0, 16, 16);
+	}
+
+	///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+	WRITE_BACK_16(avs2_dec, HEVCD_MCRCC_CTL1, 0, 0xff0); // enable mcrcc progressive-mode
+	return;
+}
+
+static void config_other_hw_fb(struct AVS2Decoder_s *dec)
+{
+
+}
+
+#endif
diff --git a/drivers/frame_provider/decoder/avs2_fb/avs2_global.h b/drivers/frame_provider/decoder/avs2_fb/avs2_global.h
new file mode 100644
index 0000000..5c395ed
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/avs2_global.h
@@ -0,0 +1,1718 @@
+/*
+ * 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 _GLOBAL_H_
+#define _GLOBAL_H_
+
+#include <linux/amlogic/media/utils/amstream.h>
+
+#define NEW_FB_CODE
+#define NEW_FRONT_BACK_CODE
+/* #include <stdio.h>                              //!< for FILE */
+/* #include <stdlib.h> */
+
+#define AML
+#define SANITY_CHECK
+#undef NO_DISPLAY
+
+#define P010_ENABLE
+
+#define OW_TRIPLE_WRITE
+
+/* #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 */
+
+#define LARGE_INSTRUCTION_SPACE_SUPORT
+
+/* 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_FUNCTION 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 CameraParameters_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 referred_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;
+	/*AVS2_10B_MMU_DW*/
+	unsigned long dw_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;
+	u32 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 information*/
+	struct vframe_qos_s vqos;
+
+	u32 hw_decode_time;
+	u32 frame_size; // For frame base mode
+
+	char *cuva_data_buf;
+	int  cuva_data_size;
+#ifdef NEW_FB_CODE
+	unsigned char back_done_mark;
+	//unsigned char flush_mark;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+	int backend_ref;
+	int width;
+	int height;
+	int depth;
+	struct avs2_frame_s *ref_pic[MAXREF];
+#endif
+#ifdef OW_TRIPLE_WRITE
+	unsigned int tw_y_adr;
+	unsigned int tw_u_v_adr;
+
+	//int tw_y_canvas_index;
+	//int tw_uv_canvas_index;
+	struct canvas_config_s tw_canvas_config[2];
+
+	u32 triple_write_mode;
+#endif
+#ifdef AML
+	u64 time;
+	s32 poc;
+	u32 hw_front_decode_time;
+	u32 stream_size; // For stream base mode
+#endif
+};
+
+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 original 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   frame_num;
+	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 CameraParameters_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 referred_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
+#define RPM_VALID_END                                          0x236
+
+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 referred_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 buff_s {
+	u32 buf_start;
+	u32 buf_size;
+	u32 buf_end;
+};
+#ifdef NEW_FB_CODE
+#define MAX_FB_IFBUF_NUM             16
+
+typedef struct buff_s buff_t;
+typedef struct hevc_state_s hevc_stru_t;
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+//new dual
+typedef struct {
+	uint32_t mmu0_ptr;
+	uint32_t mmu1_ptr;
+	uint32_t scalelut_ptr;
+	uint32_t vcpu_imem_ptr;
+	uint32_t sys_imem_ptr;
+	uint32_t lmem0_ptr;
+	uint32_t lmem1_ptr;
+	uint32_t parser_sao0_ptr;
+	uint32_t parser_sao1_ptr;
+	uint32_t mpred_imp0_ptr;
+	uint32_t mpred_imp1_ptr;
+	//
+	uint32_t scalelut_ptr_pre;
+	uint8_t scalelut_ptr_changed;
+	//for linux
+	void *sys_imem_ptr_v;
+} buff_ptr_t;
+#endif
+
+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];
+	struct avs2_frame_s *init_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
+#ifdef NEW_FRONT_BACK_CODE
+	//avs2_frame_t *cur_pic;
+
+	uint8_t wait_working_buf;
+	uint8_t front_pause_flag; /*multi pictures in one packe*/
+	/*FB mgr*/
+	uint8_t fb_wr_pos;
+	uint8_t fb_rd_pos;
+	buff_t fb_buf_mmu0;
+	buff_t fb_buf_mmu1;
+	buff_t fb_buf_scalelut;
+	buff_t fb_buf_vcpu_imem;
+	buff_t fb_buf_sys_imem;
+	buff_t fb_buf_lmem0;
+	buff_t fb_buf_lmem1;
+	buff_t fb_buf_parser_sao0;
+	buff_t fb_buf_parser_sao1;
+	buff_t fb_buf_mpred_imp0;
+	buff_t fb_buf_mpred_imp1;
+	uint32_t frontend_decoded_count;
+	uint32_t backend_decoded_count;
+	buff_ptr_t fr;
+	buff_ptr_t bk;
+	buff_ptr_t next_bk[MAX_FB_IFBUF_NUM];
+	struct avs2_frame_s *next_be_decode_pic[MAX_FB_IFBUF_NUM];
+	/**/
+	/*for WRITE_BACK_RET*/
+	//uint32_t  instruction[256];
+	uint32_t sys_imem_ptr;
+	void *sys_imem_ptr_v;
+	void *fb_buf_sys_imem_addr;
+	uint32_t  instruction[256*4]; //avoid code crash, but only 256 used
+	uint32_t  ins_offset;
+#endif
+#ifdef AML
+	u64 start_time;
+#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);
+extern int get_error_policy(struct avs2_decoder *avs2_dec);
+#endif
+
diff --git a/drivers/frame_provider/decoder/avs2_fb/vavs2.h b/drivers/frame_provider/decoder/avs2_fb/vavs2.h
new file mode 100644
index 0000000..6bba092
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/vavs2.h
@@ -0,0 +1,28 @@
+/*
+ * 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 VAVS2_H
+#define VAVS2_H
+
+#define AVS2_10B_MMU
+#define AVS2_10B_MMU_DW
+
+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/avs2_fb/vavs2_fb.c b/drivers/frame_provider/decoder/avs2_fb/vavs2_fb.c
new file mode 100644
index 0000000..e8aa769
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs2_fb/vavs2_fb.c
@@ -0,0 +1,10311 @@
+/*
+ * 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/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/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+#include <linux/slab.h>
+#include <linux/sched/clock.h>
+#include <uapi/linux/tee.h>
+
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../include/regs/dos_registers.h"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+#include "../utils/config_parser.h"
+#include "../utils/firmware.h"
+#include "../utils/vdec_feature.h"
+#include "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "avs2_global.h"
+#include "../../../common/media_utils/media_utils.h"
+#include "../../decoder/utils/vdec_profile.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+#define MEM_NAME "codec_avs2"
+
+#define FOR_S5
+
+#define I_ONLY_SUPPORT
+#define MIX_STREAM_SUPPORT
+#define CONSTRAIN_MAX_BUF_NUM
+//#ifdef S5
+#define DYN_CACHE  //!!!enable it on S5
+//#endif
+#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
+*/
+/*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 HEVC_BE_DECODE_DATA        0xa0
+#define HEVC_BE_DECODE_DATA_DONE   0xb0
+#define HEVC_BE_DECODE_TIMEOUT     0xc0
+
+#define VF_POOL_SIZE        32
+
+#undef pr_info
+#define pr_info pr_cont
+
+#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 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
+#if 0
+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
+};
+#endif
+
+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
+};
+/* to remove, fix build error */
+
+#define MULTI_INSTANCE_SUPPORT
+
+#ifndef STAT_KTHREAD
+#define STAT_KTHREAD 0x40
+#endif
+
+#ifdef MULTI_INSTANCE_SUPPORT
+#define MAX_DECODE_INSTANCE_NUM     12
+#define MULTI_DRIVER_NAME "ammvdec_avs2_fb"
+
+#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];
+#ifdef NEW_FB_CODE
+static unsigned int max_process_time_back[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count_back[MAX_DECODE_INSTANCE_NUM];
+#endif
+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;
+#endif
+static int start_decode_buf_level = 0x8000;
+
+static u32 work_buf_size;
+
+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;
+ * 0x10000, double write p010 enable
+ */
+static u32 double_write_mode = 0x80000003;
+
+/* triple_write_mode:
+ * 0, no triple 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
+ * 0x10000, triple write p010 enable
+ */
+static u32 triple_write_mode;
+
+static u32 without_display_mode;
+static u32 dump_yuv_frame = 0;
+static u32 paral_alloc_buffer_mode = 1;
+
+/*
+bit0: if dpb abnormal, check dpb buffer status and flush dpb.
+bit1: 0:show error frame.
+*/
+static unsigned int error_proc_policy = 0x3;
+
+static u32 mv_buf_dynamic_alloc;
+
+#define DRIVER_NAME "amvdec_avs2_fb"
+#define DRIVER_HEADER_NAME "amvdec_avs2_header_fb"
+
+#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_THRESHOLD 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 void fill_frame_info(struct AVS2Decoder_s *dec,
+	struct avs2_frame_s *pic, unsigned int framesize, unsigned int pts);
+static int vavs2_stop(struct AVS2Decoder_s *dec);
+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 struct avs2_frame_s *get_pic_by_index(
+	struct AVS2Decoder_s *dec, int index);
+static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec);
+static void avs2_work_implement(struct AVS2Decoder_s *dec);
+
+#ifdef NEW_FB_CODE
+static unsigned int decode_timeout_val_back = 200;
+static unsigned int efficiency_mode = 1;
+static unsigned int back_timer_check_count = 3;
+
+static void avs2_work_back(struct work_struct *work);
+static void avs2_work_back_implement(struct AVS2Decoder_s *dec,
+	struct vdec_s *vdec,int from);
+static void avs2_timeout_work_back(struct work_struct *work);
+#endif
+
+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)
+{
+#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 */
+};
+
+enum alloc_buffer_status_t {
+	BUFFER_INIT  =  0,
+	BUFFER_ALLOCATING = 1,
+	BUFFER_ALLOCATE_DONE = 2,
+};
+
+/*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 */;
+
+#define WR_PTR_INC_NUM 128
+
+#define SIMULATION
+#define DOS_PROJECT
+#undef MEMORY_MAP_IN_REAL_CHIP
+
+#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 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_QOS_INFO                 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_BE_SIMULATE_IRQ   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 fbdebug_flag;
+
+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;
+}
+
+inline 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 (adr != 0)
+		WRITE_VREG(adr, val);
+
+	if (debug & AVS2_DBG_REG) {
+		adr = dos_reg_compat_convert(adr);
+		pr_info("%s(%x, %x)\n", __func__, adr, val);
+	}
+}
+
+#undef WRITE_VREG
+#define WRITE_VREG WRITE_VREG_DBG2
+#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*/
+
+#ifdef NEW_FB_CODE
+#define	BMMU_IFBUF_SCALELUT_ID		(0)
+#define	BMMU_IFBUF_VCPU_IMEM_ID 	(BMMU_IFBUF_SCALELUT_ID + 1)
+#define	BMMU_IFBUF_SYS_IMEM_ID		(BMMU_IFBUF_VCPU_IMEM_ID + 1)
+#define	BMMU_IFBUF_LMEM0_ID			(BMMU_IFBUF_SYS_IMEM_ID + 1)
+#define	BMMU_IFBUF_LMEM1_ID			(BMMU_IFBUF_LMEM0_ID + 1)
+#define	BMMU_IFBUF_PARSER_SAO0_ID	(BMMU_IFBUF_LMEM1_ID + 1)
+#define	BMMU_IFBUF_PARSER_SAO1_ID	(BMMU_IFBUF_PARSER_SAO0_ID + 1)
+#define	BMMU_IFBUFF_MPRED_IMP0_ID	(BMMU_IFBUF_PARSER_SAO1_ID + 1)
+#define	BMMU_IFBUFF_MPRED_IMP1_ID	(BMMU_IFBUFF_MPRED_IMP0_ID + 1)
+#define FB_LOOP_BUF_COUNT	(BMMU_IFBUFF_MPRED_IMP1_ID + 1)
+#else
+#define FB_LOOP_BUF_COUNT	0
+#endif
+
+#define MV_USE_FIXED_BUF
+#ifdef MV_USE_FIXED_BUF
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1)
+#else
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + ((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define MV_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + (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
+#define CO_MV_BUF_SIZE_4K     0x120000
+#define CO_MV_BUF_SIZE_8K     0x480000
+
+#ifdef NEW_FB_CODE
+static u32 fb_ifbuf_num = 3;
+/*
+	0: single core mode
+	1: front_back_mode
+	2: front_back_test_mode
+*/
+static u32 front_back_mode = 1;
+#endif
+
+struct BuffInfo_s {
+	u32 max_width;
+	u32 max_height;
+	u32 start_adr;
+	u32 end_adr;
+	struct buff_s ipp;
+#ifdef NEW_FRONT_BACK_CODE
+	struct buff_s ipp1;
+#endif
+	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
+#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;
+#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
+#define DEC_RESULT_WAIT_BUFFER      11
+
+#ifdef NEW_FB_CODE
+#define DEC_BACK_RESULT_NONE             0
+#define DEC_BACK_RESULT_DONE             1
+#define DEC_BACK_RESULT_TIMEOUT          2
+#define DEC_BACK_RESULT_FORCE_EXIT       10
+#endif
+
+#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
+
+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;
+	int pic_list_wait_alloc_done_flag;
+	unsigned char index;
+	spinlock_t buffer_lock;
+	struct device *cma_dev;
+	struct platform_device *platform_dev;
+	void (*vdec_cb)(struct vdec_s *, void *, int);
+	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;
+	u32 vavs2_ratio;
+	int fatal_error;
+	uint8_t init_flag;
+	uint8_t first_sc_checked;
+	uint8_t process_busy;
+	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;
+
+#ifdef AVS2_10B_MMU
+	bool mmu_enable;
+
+	u32 cuva_size;
+	void *cuva_addr;
+	dma_addr_t cuva_phy_addr;
+
+	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];
+	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];
+	u32 vf_pre_count;
+	u32 vf_get_count;
+	u32 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;
+
+	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;
+	dma_addr_t rdma_phy_adr;
+	unsigned *rdma_adr;
+	int hdr_flag;
+	bool high_bandwidth_flag;
+	ulong rpm_mem_handle;
+	ulong lmem_phy_handle;
+	ulong frame_mmu_map_handle;
+	ulong frame_dw_mmu_map_handle;
+	ulong rdma_mem_handle;
+	ulong cuva_handle;
+#ifdef NEW_FB_CODE
+	u32 front_back_mode;
+	int fb_ifbuf_num;
+	//int pic_wr_count;
+	//int pic_rd_count;
+	//struct PIC_s *decoded_PIC[MAX_REF_PIC_NUM];
+	//u32 flush_count;
+
+	/*init_fb_bufstate() for linux APIs*/
+	struct work_struct work_back;
+	struct work_struct timeout_work_back;
+
+	void *frame_mmu_map_addr_1;
+	dma_addr_t frame_mmu_map_phy_addr_1;
+	void *mmu_box_1;
+
+	void *dw_mmu_box_1;
+	void *dw_frame_mmu_map_addr_1;
+	dma_addr_t dw_frame_mmu_map_phy_addr_1;
+
+	void *mmu_box_fb;
+	void *fb_buf_mmu0_addr;
+	void *fb_buf_mmu1_addr;
+	/**/
+	void (*vdec_back_cb)(struct vdec_s *, void *, int);
+	void *vdec_back_cb_arg;
+	struct firmware_s *fw_back;
+	struct timer_list timer_back;
+	unsigned long int start_process_time_back;
+	unsigned int decode_timeout_count_back;
+	unsigned int timeout_num_back;
+
+	int dec_back_result;
+	u32 dec_status_back;
+	struct mutex fb_mutex;
+	int mmu_fb_4k_number;
+	ulong frame_mmu_map_handle_1;
+	ulong frame_dw_mmu_map_handle_1;
+#endif
+	uint32_t ASSIST_MBOX0_IRQ_REG;
+	uint32_t ASSIST_MBOX0_CLR_REG;
+	uint32_t ASSIST_MBOX0_MASK;
+	uint32_t backend_ASSIST_MBOX0_IRQ_REG;
+	uint32_t backend_ASSIST_MBOX0_CLR_REG;
+	uint32_t backend_ASSIST_MBOX0_MASK;
+
+	unsigned char print_buf[1024*16+16];
+	int print_buf_len;
+	struct trace_decoder_name trace;
+	u32 last_stbuf_level;
+	u32 again_count;
+	u32 error_proc_policy;
+#ifdef OW_TRIPLE_WRITE
+	int triple_write_mode;
+#endif
+	struct mutex slice_header_lock;
+	u32 last_monitor_data;
+	u32 back_timer_check_count;
+};
+
+static int  compute_losless_comp_body_size(
+		struct AVS2Decoder_s *dec, int width, int height,
+		uint8_t is_bit_depth_10);
+
+static int avs2_mmu_page_num(struct AVS2Decoder_s *dec,
+	int w, int h, int bit_depth_10);
+
+static int avs2_debug(struct AVS2Decoder_s *dec,
+	int flag, const char *fmt, ...)
+{
+#define HEVC_PRINT_BUF		512
+	unsigned char buf[HEVC_PRINT_BUF];
+	int len = 0;
+	if (dec && dec->print_buf_len>0) {
+		dec->print_buf_len = 0;
+		pr_info("%s", dec->print_buf);
+	}
+	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;
+}
+
+#define avs2_print(dec, flag, fmt, args...)					\
+	do {									\
+		if (dec == NULL ||    \
+			(flag == 0) || \
+			((debug_mask & \
+			(1 << dec->index)) \
+		&& (debug & flag))) { \
+			avs2_debug(dec, flag, fmt, ##args);	\
+			} \
+	} while (0)
+
+static void avs2_print_flush(struct AVS2Decoder_s *dec)
+{
+	if (dec->print_buf_len>0) {
+		dec->print_buf_len = 0;
+		pr_info("%s", dec->print_buf);
+	}
+}
+
+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_mask &
+		(1 << dec->index))
+		&& (debug & flag))) {
+		va_list args;
+
+		va_start(args, fmt);
+#if 0
+		vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+		pr_info("%s", buf);
+#else
+		if (dec->print_buf_len<1024*16)
+			dec->print_buf_len += vsnprintf(dec->print_buf+dec->print_buf_len,
+				1024*16-dec->print_buf_len, fmt, args);
+		else
+			pr_info("print_buf is full\n");
+#endif
+		va_end(args);
+	}
+	return 0;
+}
+
+#define PROB_SIZE    (496 * 2 * 4)
+#define PROB_BUF_SIZE    (0x5000)
+#define COUNT_BUF_SIZE   (0x300 * 4 * 4)
+#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(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 get_compress_header_size(struct AVS2Decoder_s *dec)
+{
+	int w = ALIGN(dec->init_pic_w, 64);
+	int h = ALIGN(dec->init_pic_h, 64);
+
+	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;
+	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_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+	dec->timeout_num++;
+	avs2_print(dec, 0, "%s decoder timeout\n", __func__);
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1) {
+		amhevc_stop_f();
+	} else
+#endif
+	amhevc_stop();
+
+	if (pic && (pic->error_mark == 0) &&
+		(pic->decoded_lcu == 0)) {
+		update_decoded_pic(dec);
+		pic->error_mark = 1;
+	}
+
+	dec->dec_result = DEC_RESULT_DONE;
+	reset_process_time(dec);
+	vdec_schedule_work(&dec->work);
+}
+
+#ifdef NEW_FB_CODE
+static void reset_process_time_back(struct AVS2Decoder_s *dec)
+{
+	if (dec->start_process_time_back) {
+		unsigned int process_time =
+			1000 * (jiffies - dec->start_process_time_back) / HZ;
+		dec->start_process_time_back = 0;
+		if (process_time > max_process_time_back[dec->index])
+			max_process_time_back[dec->index] = process_time;
+	}
+}
+
+static void start_process_time_back(struct AVS2Decoder_s *dec)
+{
+	dec->start_process_time_back = jiffies;
+	dec->decode_timeout_count_back = 2;
+	dec->back_timer_check_count = back_timer_check_count;
+}
+
+/*
+static void restart_process_time_back(struct AVS2Decoder_s *dec)
+{
+	dec->start_process_time_back = jiffies;
+	dec->decode_timeout_count_back = 2;
+}
+*/
+static void timeout_process_back(struct AVS2Decoder_s *dec)
+{
+	/*
+	 * 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(&dec->work_back) ||
+		work_busy(&dec->work_back) ||
+		work_busy(&dec->timeout_work_back) ||
+		work_pending(&dec->timeout_work_back)) {
+		pr_err("%s avs2[%d] work back pending, do nothing.\n",__func__, dec->index);
+		return;
+	}
+
+	/* disable interrupt before timeout */
+	WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 0);
+
+	avs2_print(dec,
+		0, "%s decoder timeout\n", __func__);
+	dec->timeout_num_back++;
+#if 0
+	amhevc_stop();
+	read_decode_info(dec);
+	hevc_print(dec,
+		0, "%s decoder timeout\n", __func__);
+	check_pic_decoded_error(dec,
+				dec->pic_decoded_lcu_idx);
+	/*The current decoded frame is marked
+		error when the decode timeout*/
+	if (dec->cur_pic != NULL)
+		dec->cur_pic->error_mark = 1;
+	dec->decoded_poc = dec->curr_POC;
+	dec->decoding_pic = NULL;
+	dec->dec_result = DEC_RESULT_DONE;
+#endif
+	reset_process_time_back(dec);
+
+	if (work_pending(&dec->work_back))
+		return;
+	dec->dec_back_result = DEC_BACK_RESULT_TIMEOUT;
+	vdec_schedule_work(&dec->timeout_work_back);
+}
+#endif
+
+static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec)
+{
+	u32 dw_mode;
+
+	dw_mode = (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)
+{
+	u32 valid_dw_mode = get_valid_double_write_mode(dec) & 0xffff;
+	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 * h > 1920 * 1088)
+			dw = 0x4; /*1:2*/
+		break;
+	case 0x200:
+		if (w * h > 1920 * 1088)
+			dw = 0x2; /*1:4*/
+		break;
+	case 0x300:
+		if (w * h > 1280 * 768)
+			dw = 0x4; /*1:2*/
+		break;
+	default:
+		dw = valid_dw_mode;
+		break;
+	}
+	return dw;
+}
+
+#ifdef OW_TRIPLE_WRITE
+static int get_triple_write_mode(struct AVS2Decoder_s *dec)
+{
+	int tw = ((triple_write_mode & 0x80000000) == 0) ?
+		dec->triple_write_mode : (triple_write_mode & 0x7fffffff);
+
+	return (tw & 0xffff);
+}
+#endif
+
+#ifdef P010_ENABLE
+static __inline__ bool is_dw_p010(struct AVS2Decoder_s *dec)
+{
+	int a = (double_write_mode & 0x80000000) ? (double_write_mode & 0x10000) : 0;
+
+	return ((dec->double_write_mode & 0x10000) || a);
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+	int a = (triple_write_mode & 0x80000000) ? (triple_write_mode & 0x10000) : 0;
+
+	return ((dec->triple_write_mode & 0x10000) || a);
+}
+
+#else
+
+static __inline__ bool is_dw_p010(struct AVS2Decoder_s *dec)
+{
+	return 0;
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+	return 0;
+}
+#endif
+
+/* 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 > 768)
+			dw = 0x4; /*1:2*/
+		break;
+	default:
+		dw = valid_dw_mode;
+		break;
+	}
+	return dw;
+}
+
+#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 cur_mmu_4k_number;
+	int ret;
+
+	cur_mmu_4k_number = avs2_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+	if (cur_mmu_4k_number < 0)
+		return -1;
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"%s:mmu_4k_number %d\n", __func__, cur_mmu_4k_number);
+
+	ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+	ret = decoder_mmu_box_alloc_idx(
+		dec->mmu_box,
+		cur_buf_idx,
+		cur_mmu_4k_number,
+		mmu_index_adr);
+	ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+
+	return ret;
+}
+#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)
+{
+	int bit_depth_10 = (bit_depth == AVS2_BITS_10);
+	int cur_mmu_4k_number;
+	int ret;
+
+	cur_mmu_4k_number = avs2_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+
+	if (cur_mmu_4k_number < 0)
+		return -1;
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"%s:mmu_4k_number %d\n", __func__, cur_mmu_4k_number);
+
+	ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+	ret = decoder_mmu_box_alloc_idx(
+		dec->dw_mmu_box,
+		cur_buf_idx,
+		cur_mmu_4k_number,
+		mmu_index_adr);
+	ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+
+	return ret;
+}
+#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)
+			&& avs2_dec->fref[i]->is_output == -1
+			&& avs2_dec->fref[i]->bg_flag == 0
+#ifdef NEW_FRONT_BACK_CODE
+		&& avs2_dec->fref[i]->backend_ref == 0
+#endif
+			&& avs2_dec->fref[i]->vf_ref == 0
+			&& avs2_dec->fref[i]->to_prepare_disp == 0
+			) {
+
+			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)
+			&& avs2_dec->fref[i]->is_output == -1
+			&& avs2_dec->fref[i]->bg_flag == 0
+			&& avs2_dec->fref[i]->vf_ref > 0
+			&& avs2_dec->fref[i]->to_prepare_disp == 0) {
+			count++;
+		}
+	}
+
+	return count;
+}
+
+int get_error_policy(struct avs2_decoder *avs2_dec)
+{
+	struct AVS2Decoder_s *dec = container_of(avs2_dec, struct AVS2Decoder_s, avs2_dec);
+
+	return dec->error_proc_policy;
+}
+
+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)
+			|| avs2_dec->fref[i]->is_output != -1
+			|| avs2_dec->fref[i]->bg_flag != 0
+			|| avs2_dec->fref[i]->vf_ref != 0
+			|| avs2_dec->fref[i]->to_prepare_disp != 0) {
+			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
+	spin_lock_init(&dec->buffer_lock);
+
+	/* 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;
+
+	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;
+#ifdef NEW_FB_CODE
+	dec->start_process_time_back = 0;
+	dec->decode_timeout_count_back = 0;
+	dec->timeout_num_back = 0;
+	dec->decode_timeout_count_back = 0;
+#endif
+	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
+
+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 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)
+#define HEVC_CONFIG_P010_LE        (0x77007)
+
+#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 = 4;
+#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 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
+#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 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_EFFICIENCY_MODE      HEVC_ASSIST_SCRATCH_L
+/*!!!*/
+#define HEVC_DECODE_COUNT       HEVC_ASSIST_SCRATCH_M
+#define HEVC_DECODE_SIZE		HEVC_ASSIST_SCRATCH_N
+//#define HEVC_DECODE_SIZE		HEVC_ASSIST_SCRATCH_6
+#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
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE             HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE            HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE                  HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE                  HEVC_ASSIST_SCRATCH_Z
+#define HEVC_EFFICIENCY_MODE_BACK       HEVC_ASSIST_SCRATCH_10
+
+#define EE_ASSIST_MBOX0_IRQ_REG    0x3f70
+#define EE_ASSIST_MBOX0_CLR_REG    0x3f71
+#define EE_ASSIST_MBOX0_MASK       0x3f72
+#endif
+
+#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,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x4000,
+		},
+#endif
+		.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*/
+		},
+#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,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x4000,
+		},
+#endif
+		.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*/
+		},
+#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,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x4000 * 2,
+		},
+#endif
+		.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*/
+		},
+#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, //2048
+		.max_height		= 1088, //1152
+		.ipp			= {.buf_size = 0x1e00}, //IPP work space calculation :4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1			= {.buf_size = 0x1e00}, //IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+		.short_term_rps		= {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, // RCS STORE AREA - Max 32 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+		.sao_up			= {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.swap_buf		= {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+		.scalelut		= {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.dblk_para		= {.buf_size = 0x4100}, //(ctu_numb_x+1) * 128 = (2048/16+1)*128= 0x4080
+		.dblk_data		= {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+		.dblk_data2		= {.buf_size = 0x80800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(2048/16+1)*2048=0x80800
+#ifdef AVS2_10B_MMU
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_1080P}, /*2*16*(more than 2304)/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_1080P}, //2*16*2304/4, 4K
+#endif
+		.mpred_above		= {.buf_size = 0x2000}, // 2 * size of hevc: (pic_width/64)*16*16 byte = 2048/64*16*16=0x2000
+#ifdef MV_USE_FIXED_BUF
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_1080P * FRAME_BUFFERS}, // 1080p, 0x40000 per buffer
+#endif
+		.rpm			= {.buf_size = RPM_BUF_SIZE},
+		.lmem			= {.buf_size = 0x400 * 2},
+	},
+	{
+		.max_width		= 4096,
+		.max_height		= 2304,
+		.ipp			= {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1			= {.buf_size = 0x4000}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+		.short_term_rps		= {.buf_size = 0x800}, // SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, // RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, // SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, // PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,total 0x2000 bytes
+		.sao_up			= {.buf_size = 0}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.swap_buf		= {.buf_size = 0x800}, // 256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+		.scalelut		= {.buf_size = 0}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.dblk_para		= {.buf_size = 0x8100}, //(ctu_numb_x+1) * 128 = (4096/16+1) * 128 = 0x8080
+		.dblk_data		= {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+		.dblk_data2		= {.buf_size = 0xc0800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(4096/16+1)*2048=0xc0800
+#ifdef AVS2_10B_MMU
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_4K},/*2*16*(more than 2304)/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_4K}, //2*16*2304/4, 4K
+#endif
+		.mpred_above		= {.buf_size = 0x4000}, //(pic_width/64)*16*16 byte = 4096/64*16*16=0x4000
+#ifdef MV_USE_FIXED_BUF
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_4K * FRAME_BUFFERS}, //.buf_size = 0x100000*16, 4k2k => 0x100000 per buffer  4096x2304 => 0x120000 per buffer
+#endif
+		.rpm			= {.buf_size = RPM_BUF_SIZE},
+		.lmem			= {.buf_size = 0x400 * 2},
+	},
+	{
+		.max_width		= 4096 * 2,
+		.max_height		= 2304 * 2,
+		.ipp			= {.buf_size = 0x4000 * 2}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1			= {.buf_size = 0x4000 * 2}, // IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+#endif
+#ifdef USE_SIM_BUFSPEC
+		.sao_abv		= {.buf_size = 0x30000 * 2},
+		.sao_vb			= {.buf_size = 0x30000 * 2},
+#else
+		.sao_abv		= {.buf_size = 0},
+		.sao_vb			= {.buf_size = 0},
+#endif
+		.short_term_rps		= {.buf_size = 0x800}, //SHORT_TERM_RPS - Max 64 set, 16 entry every set, total 64x16x2 = 2048 bytes (0x800)
+		.rcs			= {.buf_size = 0x400}, //RCS STORE AREA - Max 16 RCS, each has 32 bytes, total 0x0400 bytes
+		.sps			= {.buf_size = 0x800}, //SPS STORE AREA - Max 16 SPS, each has 0x80 bytes, total 0x0800 bytes
+		.pps			= {.buf_size = 0x2000}, //PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total 0x2000 bytes
+#ifdef USE_SIM_BUFSPEC
+		.sao_up			= {.buf_size = 0x2800 * 2}, // SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+#else
+		.sao_up			= {.buf_size = 0}, //SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+#endif
+		.swap_buf		= {.buf_size = 0x800}, //256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)
+		.swap_buf2		= {.buf_size = 0x800},
+#ifdef USE_SIM_BUFSPEC
+		.scalelut		= {.buf_size = 0x8000 * 2}, // support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+#else
+		.scalelut		= {.buf_size = 0}, //support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+#endif
+#ifdef FOR_S5
+		.dblk_para		= { .buf_size = 0x40000 * 2},
+		.dblk_data		= { .buf_size = 0x80000 * 2},
+		.dblk_data2		= { .buf_size = 0x80000 * 2},
+#else
+		.dblk_para		= {.buf_size = 0x10100}, //(ctu_numb_x+1) * 128 = (8192/16+1)*128 = 0x10080
+		.dblk_data		= {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+		.dblk_data2		= {.buf_size = 0x140800}, //addr_offset_lft(64)*4096 + (ctu_numb_y+1)*2048 = 64*4096+(8192/16+1)*2048=0x140800
+#endif
+#ifdef USE_SIM_BUFSPEC
+#ifdef AVS2_10B_MMU
+		.mmu_vbh		= {.buf_size = 0x5000 * 2}, //2*16*2304/4, 4K
+		.cm_header		= {.buf_size = MMU_COMPRESS_HEADER_SIZE * AVS2_BUFFER_NUM}, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+#endif
+#ifdef AVS2_10B_MMU_DW
+		.mmu_vbh_dw		= {.buf_size = 0x5000 * 2}, //2*16*2304/4, 4K
+		.cm_header_dw		= {.buf_size = MMU_COMPRESS_HEADER_SIZE_DW * AVS2_BUFFER_NUM}, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
+#endif
+#else
+#ifdef AVS2_10B_MMU
+		.mmu_vbh		= {.buf_size = VBH_BUF_SIZE_8K}, /*2*16*2304/4, 4K*/
+#endif
+#ifdef AVS2_10B_MMU_DW
+		.mmu_vbh_dw		= {.buf_size = DW_VBH_BUF_SIZE_8K}, //2*16*2304/4, 4K
+#endif
+#endif
+#ifdef FOR_S5
+		.mpred_above		= {.buf_size = 0x8000 * 2},
+#else
+		.mpred_above		= {.buf_size = 0x8000}, //(pic_width/64)*16*16 byte = 8192/64*16*16=0x8000
+#endif
+#ifdef MV_USE_FIXED_BUF
+		.mpred_mv		= {.buf_size = CO_MV_BUF_SIZE_8K * FRAME_BUFFERS}, //4k2k , 0x100000 per buffer
+#endif
+		.rpm			= {.buf_size = RPM_BUF_SIZE},
+#ifdef FOR_S5
+		.lmem			= {.buf_size = 0x600 * 2},
+#else
+		.lmem			= {.buf_size = 0x400 * 2},
+#endif
+	}
+};
+
+#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
+
+static void config_hevc_irq_num(struct AVS2Decoder_s *dec)
+{
+	PRINT_LINE();
+#ifdef NEW_FB_CODE
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+		dec->ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+		dec->ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+		dec->ASSIST_MBOX0_MASK    = EE_ASSIST_MBOX0_MASK;
+		dec->backend_ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+		dec->backend_ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+		dec->backend_ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+	} else {
+		dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+		dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+		dec->ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+		dec->backend_ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+		dec->backend_ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+		dec->backend_ASSIST_MBOX0_MASK    = EE_ASSIST_MBOX0_MASK;
+	}
+#else
+	dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+	dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+	dec->ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+#endif
+}
+
+#ifdef NEW_FB_CODE
+
+void pic_backend_ref_operation(struct AVS2Decoder_s *dec, bool add_flag)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic = NULL;
+	int i = 0;
+
+	mutex_lock(&dec->fb_mutex);
+	if (add_flag) {
+		pic = dec->avs2_dec.hc.cur_pic;
+		pic->backend_ref = 1;
+		pic->back_done_mark = 0;
+	} else {
+		pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+		pic->backend_ref--;
+		if (pic->backend_ref < 0) {
+			pic->backend_ref = 0;
+			avs2_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:pic(%px) backend_ref error\n",
+				__func__, pic);
+		}
+		pic->back_done_mark = 1;
+	}
+
+	for (i = 0; (i < MAXREF) && (pic->ref_pic[i] != NULL); i++) {
+		if (add_flag) {
+			pic->ref_pic[i]->backend_ref++;
+		} else {
+			pic->ref_pic[i]->backend_ref--;
+			if (pic->ref_pic[i]->backend_ref < 0) {
+				pic->ref_pic[i]->backend_ref = 0;
+				avs2_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:ref_pic(%px) backend_ref error\n",
+					__func__, pic->ref_pic[i]);
+			}
+		}
+	}
+
+	mutex_unlock(&dec->fb_mutex);
+}
+
+#include "avs2_fb_hw.c"
+
+/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+static int front_decpic_done_update(struct AVS2Decoder_s *dec, uint8_t reset_flag)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	pic_backend_ref_operation(dec, 1);
+	if (dec->front_back_mode == 1) {
+		read_bufstate_front(avs2_dec);
+		print_loopbufs_ptr(dec, "fr", &avs2_dec->fr);
+
+		WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 1);
+
+#if 0 //def RESET_FRONT_PER_PICTURE
+		if (reset_flag) {
+			/*not multi pictures in one packe*/
+			amhevc_stop_f();
+			//save_stream_context(dec->work_space_buf->swap_buf.buf_start);
+		}
+#endif
+	} else {
+		if (reset_flag) /*not multi pictures in one packe*/
+			amhevc_stop();
+	}
+
+	avs2_dec->frontend_decoded_count++;
+	avs2_dec->next_be_decode_pic[avs2_dec->fb_wr_pos] = avs2_dec->hc.cur_pic;
+
+	mutex_lock(&dec->fb_mutex);
+	avs2_dec->fb_wr_pos++;
+	if (avs2_dec->fb_wr_pos >= dec->fb_ifbuf_num)
+		avs2_dec->fb_wr_pos = 0;
+
+	if (avs2_dec->fb_wr_pos == avs2_dec->fb_rd_pos) {
+		avs2_dec->wait_working_buf = 1;
+		avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"fb_wr_pos %d fb_rd_pos %d, set wait_working_buf = 1\n", avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos);
+	} else {
+		avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"fb_wr_pos %d fb_rd_pos %d\n", avs2_dec->fb_wr_pos, avs2_dec->fb_rd_pos);
+	}
+	mutex_unlock(&dec->fb_mutex);
+
+	return 0;
+}
+
+#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);
+#ifdef NEW_FRONT_BACK_CODE
+	buf_spec->ipp1.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+	buf_spec->sao_abv.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp1.buf_start + buf_spec->ipp1.buf_size);
+#else
+	buf_spec->sao_abv.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+#endif
+	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);
+	#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->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);
+	#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 */
+#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);
+#ifdef NEW_FRONT_BACK_CODE
+			pr_info("ipp1.buf_start             :%x\n",
+				   buf_spec->ipp1.buf_start);
+#endif
+			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
+	#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
+			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)
+{
+#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;
+	}
+#endif
+	decoder_mmu_box_free(dec->mmu_box);
+	dec->mmu_box = NULL;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (dec->mmu_box_1)
+			decoder_mmu_box_free(dec->mmu_box_1);
+		dec->mmu_box_1 = NULL;
+		if (dec->dw_mmu_enable && dec->dw_mmu_box_1) {
+			decoder_mmu_box_free(dec->dw_mmu_box_1);
+			dec->dw_mmu_box_1 = NULL;
+		}
+	}
+	if (dec->front_back_mode) {
+		uninit_fb_bufstate(dec);
+	}
+#endif
+	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;
+
+	if (IS_8K_SIZE(dec->vavs2_amstream_dec_info.width, dec->vavs2_amstream_dec_info.height))
+		dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin;
+	else
+		dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin - 4;
+
+	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;
+
+		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);
+	}
+	dec->buf_num = i;
+}
+#endif
+
+static u32 calc_buffer_u_v_h_size(u32 w, u32 h, u32 ratio, u32 lcu_size)
+{
+	int pic_width_dw = w / ratio;
+	int pic_height_dw = h / ratio;
+
+	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) >> 1;	// div 2
+
+	return ((mc_buffer_size_u_v + 0xffff) >> 16);
+}
+
+static int config_pic(struct AVS2Decoder_s *dec,
+				struct avs2_frame_s *pic)
+{
+	int ret = -1;
+	int i;
+	int pic_width = dec->init_pic_w;
+	int pic_height = dec->init_pic_h;
+
+	int32_t lcu_size = dec->avs2_dec.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;
+	int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+
+	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, is_bit_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_uv_size;
+	int dw_mode = get_double_write_mode_init(dec);
+#ifdef OW_TRIPLE_WRITE
+	int tw_mode = get_triple_write_mode(dec);
+#endif
+
+	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+		mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+			pic_height, get_double_write_ratio(dw_mode & 0xf), lcu_size);
+		/*64k alignment*/
+		buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
+		buf_size = ((buf_size + 0xffff) >> 16) << 16;
+#ifdef P010_ENABLE
+		if (is_dw_p010(dec)) {	//double size mem for p010 mode
+			buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		}
+#endif
+	}
+#ifdef OW_TRIPLE_WRITE
+	if (tw_mode) {
+		mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+			pic_height, get_double_write_ratio(tw_mode), lcu_size);
+
+		buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		if (is_tw_p010(dec)) {
+			buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		}
+	}
+#endif
+
+	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
+	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 (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;
+			if (!vdec_secure(hw_to_vdec(dec)))
+				codec_mm_memset(y_adr, 0, buf_size);
+		} 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*/
+		dw_uv_size = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+
+		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 + (dw_uv_size << 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 + (dw_uv_size << 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 + (dw_uv_size << 1);
+#endif
+		}
+		if (tw_mode) {
+			if (dw_mode) {
+				pic->tw_y_adr = pic->dw_u_v_adr + dw_uv_size;  //base dw buf addr
+			} else {
+				pic->tw_y_adr = y_adr;  //base no dw buf addr
+			}
+			pic->tw_u_v_adr = pic->tw_y_adr + (mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1));
+		}
+
+#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 ",
+				pic->mpred_mv_wr_start_addr);
+			avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+				"dw_y_adr %d, pic->dw_u_v_adr =%d ",
+				pic->dw_y_adr,
+				pic->dw_u_v_adr);
+			avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+				"tw y_addr %x, uv_addr %x\n",
+				pic->tw_y_adr, pic->tw_u_v_adr);
+		}
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static void init_pic_list(struct AVS2Decoder_s *dec)
+{
+	int i;
+	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;
+			}
+			if (!vdec_secure(hw_to_vdec(dec)))
+				codec_mm_memset(buf_addr, 0, header_size);
+		}
+	}
+#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];
+		avs2_dec->init_fref[i] = pic;
+		pic->index = i;
+		pic->BUF_index = -1;
+		pic->mv_buf_index = -1;
+		if (config_pic(dec, pic) < 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_wait_alloc_done_flag = BUFFER_ALLOCATE_DONE;
+}
+
+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;
+
+	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_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_DATA, pic->mc_y_adr >> 5);
+#endif
+#ifndef LOSLESS_COMPRESS_MODE
+	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) backend_ref %d, back done %d, time %lld\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]->referred_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],
+		avs2_dec->fref[ii]->backend_ref,
+		avs2_dec->fref[ii]->back_done_mark,
+		avs2_dec->fref[ii]->time
+		);
+	}
+	return;
+}
+
+static int config_mc_buffer(struct AVS2Decoder_s *dec)
+{
+	int32_t i;
+#ifdef NEW_FRONT_BACK_CODE
+	int32_t j;
+#endif
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct avs2_frame_s *pic;
+	struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+	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,
+			(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,
+			(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);
+
+#ifdef NEW_FRONT_BACK_CODE
+		if (dec->front_back_mode) {
+			for (j = 0; j < MAXREF; j++) {
+			if (avs2_dec->f_bg == cur_pic->ref_pic[j])
+				break;
+			if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = avs2_dec->f_bg;
+				break;
+			}
+			}
+		}
+#endif
+	}
+
+	if (avs2_dec->img.type == I_IMG)
+		return 0;
+
+	if (avs2_dec->img.type == P_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+		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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
+			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);
+#ifdef NEW_FRONT_BACK_CODE
+		if (dec->front_back_mode) {
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+				break;
+				if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+				}
+			}
+			}
+#endif
+		}
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
+	} else if (avs2_dec->img.type == F_IMG) {
+		int valid_ref_cnt;
+		valid_ref_cnt = 0;
+		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];
+			if (pic->referred_by_others != 1)
+				continue;
+			valid_ref_cnt++;
+			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);
+#ifdef NEW_FRONT_BACK_CODE
+		if (dec->front_back_mode) {
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+				break;
+				if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+				}
+			}
+			}
+#endif
+		}
+		if (valid_ref_cnt != avs2_dec->img.num_of_references)
+			cur_pic->error_mark = 1;
+		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);
+#ifdef NEW_FRONT_BACK_CODE
+		if (dec->front_back_mode) {
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+				break;
+				if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+				}
+			}
+			}
+#endif
+
+		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);
+#ifdef NEW_FRONT_BACK_CODE
+		if (dec->front_back_mode) {
+			for (j = 0; j < MAXREF; j++) {
+				if (pic == cur_pic->ref_pic[j])
+				break;
+				if (cur_pic->ref_pic[j] == NULL) {
+				cur_pic->ref_pic[j] = pic;
+				break;
+				}
+			}
+			}
+#endif
+	}
+	return 0;
+}
+
+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 ((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*/
+	int dw_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+	int tw_mode = get_triple_write_mode(dec);
+#endif
+
+	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 ((dw_mode & 0x10) == 0)
+		WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr);
+#endif
+	if ((dw_mode & 0x20) == 0) {
+		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 OW_TRIPLE_WRITE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+		if (tw_mode) {
+			WRITE_VREG(HEVC_SAO_Y_START_ADDR3, cur_pic->tw_y_adr);
+			WRITE_VREG(HEVC_SAO_C_START_ADDR3, cur_pic->tw_u_v_adr);
+		} else {
+			WRITE_VREG(HEVC_SAO_Y_START_ADDR3, 0xffffffff);
+			WRITE_VREG(HEVC_SAO_C_START_ADDR3, 0xffffffff);
+		}
+	}
+#endif
+
+#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 + is_dw_p010(dec) + 1);
+	WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
+	data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+	WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
+
+	if (tw_mode) {
+		data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1);
+		WRITE_VREG(HEVC_SAO_Y_LENGTH3, data32);
+		data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec));
+		WRITE_VREG(HEVC_SAO_C_LENGTH3, data32);
+
+		if (debug & AVS2_DBG_REG) {
+			avs2_print(dec, 0, "triple write SAO_Y_ADDR3 %x, SAO_Y_LENGTH3 %x, SAO_C_ADDR3 %x, SAO_C_LENGTH3 %x\n",
+			READ_VREG(HEVC_SAO_Y_START_ADDR3), READ_VREG(HEVC_SAO_Y_LENGTH3),
+			READ_VREG(HEVC_SAO_C_START_ADDR3), READ_VREG(HEVC_SAO_C_LENGTH3));
+		}
+	}
+
+#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);
+#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 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+
+	if (dw_mode == 0)
+		data32 |= 0x2; /*disable double write*/
+	else if (dw_mode & 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 (dw_mode & 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 ((dw_mode & 0xf) == 8 || (dw_mode & 0xf) == 9) {
+			data32 |= (0xff<<16);
+			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)
+			data32 |= (0x33<<16);
+		WRITE_VREG(HEVC_SAO_CTRL5, data32);
+	}
+#ifdef P010_ENABLE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+		data32 = READ_VREG(HEVC_SAO_CTRL3);
+		if (is_dw_p010(dec)) {
+			data32 |= (1 << 1);
+			WRITE_VREG(HEVC_SAO_CTRL3, data32);
+		} else {
+			data32 &= ~(1 << 1);
+			WRITE_VREG(HEVC_SAO_CTRL3, data32);
+		}
+	}
+#endif
+#ifdef OW_TRIPLE_WRITE
+	if (tw_mode) {
+		data32 = READ_VREG(HEVC_SAO_CTRL31);
+		data32 &= ~0xfff;
+		if ((tw_mode == 2) || (tw_mode == 3)) {
+			data32 |= ((0xf << 6) | 0xf);	//1:4
+		} else if ((tw_mode == 4) || (tw_mode == 5)) {
+			data32 |= ((0x3 << 6) | 0x3);	//1:2
+		} else if ((tw_mode == 8) || (tw_mode == 9)) {
+			data32 |= ((0x3f << 6) | 0x3f);
+		}
+		WRITE_VREG(HEVC_SAO_CTRL31, data32);
+
+		data32 = READ_VREG(HEVC_SAO_CTRL32);
+		data32 &= (~0xfff); /* clr endian, blkmod and align */
+		data32 |= ((dec->endian >> 12) & 0xff);
+		data32 |= ((mem_map_mode & 0x3) << 8);
+		/* Linear_LineAlignment 00:16byte 01:32byte 10:64byte */
+		data32 |= (2 << 10);
+		WRITE_VREG(HEVC_SAO_CTRL32, data32);
+
+		data32 = READ_VREG(HEVC_SAO_CTRL3);
+		data32 |= (1 << 2); /* enable triple write */
+#ifdef P010_ENABLE
+		if (is_tw_p010(dec)) {
+			data32 |= (1 << 3);  /* enable triple write p010  */
+		} else {
+			data32 &= ~(1 << 3);
+		}
+#endif
+		WRITE_VREG(HEVC_SAO_CTRL3, data32);
+
+		if (debug & AVS2_DBG_REG) {
+			pr_info("%s, HEVC_SAO_CTRL3 %x, HEVC_SAO_CTRL31 %x, HEVC_SAO_CTRL32 %x\n",
+				__func__, READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL31), READ_VREG(HEVC_SAO_CTRL32));
+		}
+	}
+#endif
+
+	/*
+	* [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
+#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,
+	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];
+		}
+		coeffPred = (1 << ALF_NUM_BIT_SHIFT) - sum;
+		dec->m_filterCoeffSym[g][alfParam->num_coeff - 1] = coeffPred +
+			alfParam->coeffmulti[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);
+	}
+	if (debug & AVS2_DBG_BUFMGR_DETAIL) {
+		for (i = 0; i < m_filters_per_group; i++)
+			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
+#ifdef P010_ENABLE
+	if (get_double_write_mode(dec) & 0x10) {
+		if (is_dw_p010(dec)) {
+			/* Enable P010 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+				(0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+		} else {
+			/* Enable NV21 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+		}
+	}
+#endif
+#endif
+}
+
+static u32 init_cuva_size;
+static int cuva_data_is_available(struct AVS2Decoder_s *dec, u32 reg_val)
+{
+
+	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;
+}
+
+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_available(dec, size_reg_val)) {
+		avs2_print(dec, AVS2_DBG_HDR_INFO,
+			"%s:pic 0x%p or data not available\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, "%s: cuva: (size %d)\n", __func__, pic->cuva_data_size);
+			if (get_dbg_flag(dec) & AVS2_DBG_HDR_INFO) {
+				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;
+	int is_bit_depth_10 = (dec->avs2_dec.input.sample_bit_depth == 8) ? 0 : 1;
+#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, is_bit_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);
+#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
+#ifdef AVS2_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		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);
+
+	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);
+	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));
+	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
+/*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
+#ifdef P010_ENABLE
+	if (get_double_write_mode(dec) & 0x10) {
+		if (is_dw_p010(dec)) {
+			/* Enable P010 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+				(0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+		} else {
+			/* Enable NV21 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+		}
+	}
+#endif
+#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));
+
+	/* use HEVC_CM_HEADER_START_ADDR */
+	data32 = READ_VREG(HEVC_SAO_CTRL5);
+	data32 |= (1<<10);
+#if 0
+	if (debug & AVS2_DBG_FORCE_UNCOMPRESS)
+		data32 |= 0x80;
+#endif
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+#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);
+
+	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
+}
+
+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;
+
+	data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+	/* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+	data32 &= ~(7 << 29);
+	data32 |= (3 << 29);
+
+	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);
+#ifdef DYN_CACHE
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+			avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "HEVC DYN MCRCC\n");
+		WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+	}
+#endif
+#if 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);
+#endif
+	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
+
+	/*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*/
+
+	/* 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 struct AVS2Decoder_s gAVS2Decoder;
+
+static void avs2_local_uninit(struct AVS2Decoder_s *dec)
+{
+	dec->rpm_ptr = NULL;
+	dec->lmem_ptr = NULL;
+	if (dec->rpm_addr) {
+		decoder_dma_free_coherent(dec->rpm_mem_handle,
+						RPM_BUF_SIZE, dec->rpm_addr,
+						dec->rpm_phy_addr);
+		dec->rpm_addr = NULL;
+	}
+
+	if (dec->cuva_addr) {
+		decoder_dma_free_coherent(dec->cuva_handle,
+				dec->cuva_size, dec->cuva_addr,
+					dec->cuva_phy_addr);
+		dec->cuva_addr = NULL;
+	}
+
+	if (dec->lmem_addr) {
+			if (dec->lmem_phy_addr)
+				decoder_dma_free_coherent(dec->lmem_phy_handle,
+						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)
+			decoder_dma_free_coherent(dec->frame_mmu_map_handle,
+				get_frame_mmu_map_size(), dec->frame_mmu_map_addr,
+					dec->frame_mmu_map_phy_addr);
+		dec->frame_mmu_map_addr = NULL;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (dec->frame_mmu_map_phy_addr_1)
+			decoder_dma_free_coherent(dec->frame_mmu_map_handle_1,
+				get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+					dec->frame_mmu_map_phy_addr_1);
+
+		dec->frame_mmu_map_addr_1 = NULL;
+	}
+#endif
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+	if (dec->dw_frame_mmu_map_addr) {
+		if (dec->dw_frame_mmu_map_phy_addr)
+			decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
+				get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr,
+					dec->dw_frame_mmu_map_phy_addr);
+		dec->dw_frame_mmu_map_addr = NULL;
+	}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode && dec->dw_frame_mmu_map_addr_1) {
+			if (dec->dw_frame_mmu_map_phy_addr_1)
+				decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle_1,
+					get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+						dec->dw_frame_mmu_map_phy_addr_1);
+
+			dec->dw_frame_mmu_map_addr_1 = NULL;
+		}
+#endif
+#endif
+
+	if (dec->gvs)
+		vfree(dec->gvs);
+	dec->gvs = NULL;
+}
+
+static int avs2_local_init(struct AVS2Decoder_s *dec)
+{
+	int ret = -1;
+	int bufspec_index = 0;
+	/*int losless_comp_header_size, losless_comp_body_size;*/
+
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	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));
+		bufspec_index = force_bufspec & 0xf;
+		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)
+					bufspec_index = 2;
+					//memcpy(cur_buf_info, &amvavs2_workbuff_spec[2],	/* 8k */
+					//sizeof(struct BuffInfo_s));
+				else
+					bufspec_index = 1;
+					//memcpy(cur_buf_info, &amvavs2_workbuff_spec[1],	/* 4k */
+					//sizeof(struct BuffInfo_s));
+			} else
+				bufspec_index = 0;
+				//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()) {
+				bufspec_index = 5;
+				//memcpy(cur_buf_info, &amvavs2_workbuff_spec[5],	/* 8k */
+				//sizeof(struct BuffInfo_s));
+			} else
+				bufspec_index = 3;
+				//memcpy(cur_buf_info, &amvavs2_workbuff_spec[3],/* 1080p */
+				//sizeof(struct BuffInfo_s));
+		}
+	}
+	memcpy(cur_buf_info, &amvavs2_workbuff_spec[bufspec_index],
+	sizeof(struct BuffInfo_s));
+	pr_info("buffer spec %d\n", bufspec_index);
+
+	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 ((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;
+		}
+	}
+	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);
+
+#ifndef AVS2_10B_MMU
+	init_buf_list(dec);
+#else
+	if (IS_8K_SIZE(dec->vavs2_amstream_dec_info.width, dec->vavs2_amstream_dec_info.height))
+		dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin;
+	else
+		dec->used_buf_num = max_buf_num + dec->dynamic_buf_margin - 4;
+
+	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;
+
+	pts_unstable = ((unsigned long)(dec->vavs2_amstream_dec_info.param)
+			& 0x40) >> 6;
+
+	if ((debug & AVS2_DBG_SEND_PARAM_WITH_REG) == 0) {
+		dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
+			RPM_BUF_SIZE,
+			&dec->rpm_phy_addr, "AVS2_RPM_BUF");
+		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 = decoder_dma_alloc_coherent(&dec->cuva_handle,
+				dec->cuva_size, &dec->cuva_phy_addr, "AVS2_CUVA_BUF");
+			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 = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
+			LMEM_BUF_SIZE,
+			&dec->lmem_phy_addr, "AVS2_LMEM_BUF");
+	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_ptr = dec->lmem_addr;
+
+#ifdef AVS2_10B_MMU
+	if (dec->mmu_enable) {
+		dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
+					get_frame_mmu_map_size(),
+					&dec->frame_mmu_map_phy_addr, "AVS2_MMU_BUF");
+		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());
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode && dec->frame_mmu_map_addr_1 == NULL) {
+			dec->frame_mmu_map_addr_1 = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle_1,
+					get_frame_mmu_map_size(),
+					&dec->frame_mmu_map_phy_addr_1, "AVS2_MMU_BUF_1");
+			if (dec->frame_mmu_map_addr_1 == NULL) {
+				pr_err("%s: failed to alloc count_buffer\n", __func__);
+				return -1;
+			}
+			memset(dec->frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+		}
+#endif
+	}
+#endif
+
+#ifdef AVS2_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
+					get_frame_mmu_map_size(),
+					&dec->dw_frame_mmu_map_phy_addr, "AVS2_DWMMU_BUF");
+		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());
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->dw_frame_mmu_map_addr_1 = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle_1,
+					get_frame_mmu_map_size(),
+					&dec->dw_frame_mmu_map_phy_addr_1, "AVS2_DWMMU_BUF_1");
+			if (dec->dw_frame_mmu_map_addr_1 == NULL) {
+				pr_err("%s: failed to alloc count_buffer\n", __func__);
+				return -1;
+			}
+			memset(dec->dw_frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+		}
+#endif
+	}
+#endif
+#ifdef NEW_FB_CODE
+	avs2_dec->wait_working_buf = 0;
+	avs2_dec->front_pause_flag = 0; /*multi pictures in one packe*/
+	if (dec->front_back_mode) {
+		avs2_dec->frontend_decoded_count = 0;
+		avs2_dec->backend_decoded_count = 0;
+		avs2_dec->fb_wr_pos = 0;
+		avs2_dec->fb_rd_pos = 0;
+		init_fb_bufstate(dec);
+		copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+	}
+#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[0].bit_depth = is_dw_p010(dec);
+
+		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;
+		pic->canvas_config[1].bit_depth = is_dw_p010(dec);
+
+		ATRACE_COUNTER(dec->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr);
+#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);
+
+		ATRACE_COUNTER(dec->trace.set_canvas0_addr, spec2canvas(pic));
+	#endif
+	}
+
+#ifdef OW_TRIPLE_WRITE
+	if (pic->triple_write_mode) {
+		canvas_w = pic->pic_w /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);	//same ratio with double write
+		canvas_h = pic->pic_h /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);
+
+		canvas_w = ALIGN(canvas_w, 64);
+		canvas_h = ALIGN(canvas_h, 32);
+
+#if 0
+		if (vdec->parallel_dec == 1) {
+			if (pic->tw_y_canvas_index == -1)
+				pic->tw_y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+			if (pic->tw_uv_canvas_index == -1)
+				pic->tw_uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+		} else {
+			pic->tw_y_canvas_index = 128 + pic->index * 2;
+			pic->tw_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, 7, VDEC_HEVC);
+		config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
+			canvas_w, canvas_h,
+			CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+#endif
+		pic->tw_canvas_config[0].phy_addr   = pic->tw_y_adr;
+		pic->tw_canvas_config[0].width      = canvas_w;
+		pic->tw_canvas_config[0].height     = canvas_h;
+		pic->tw_canvas_config[0].block_mode = blkmode;
+		pic->tw_canvas_config[0].endian     = 7;
+		pic->tw_canvas_config[0].bit_depth  = is_tw_p010(dec);
+
+		pic->tw_canvas_config[1].phy_addr   = pic->tw_u_v_adr;
+		pic->tw_canvas_config[1].width      = canvas_w;
+		pic->tw_canvas_config[1].height     = canvas_h;
+		pic->tw_canvas_config[1].block_mode = blkmode;
+		pic->tw_canvas_config[1].endian     = 7;
+		pic->tw_canvas_config[1].bit_depth  = is_tw_p010(dec);
+	}
+#endif
+}
+
+static void set_frame_info(struct AVS2Decoder_s *dec, struct vframe_s *vf)
+{
+	unsigned int ar = 0;
+	unsigned int pixel_ratio = 0;;
+
+	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_type 0x%x \n",
+			vf->signal_type);
+
+	pixel_ratio = dec->vavs2_amstream_dec_info.ratio;
+
+	if (dec->vavs2_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 * dec->vavs2_ratio) / vf->width;
+				break;
+			case 2:
+				vf->sar_width = 4;
+				vf->sar_height = 3;
+				ar = (vf->height * 3 * dec->vavs2_ratio) / (vf->width * 4);
+				break;
+			case 3:
+				vf->sar_width = 16;
+				vf->sar_height = 9;
+				ar = (vf->height * 9 * dec->vavs2_ratio) / (vf->width * 16);
+				break;
+			case 4:
+				vf->sar_width = 221;
+				vf->sar_height = 100;
+				ar = (vf->height * 100 * dec->vavs2_ratio) / (vf->width *
+						221);
+				break;
+			default:
+				vf->sar_width = 1;
+				vf->sar_height = 1;
+				ar = (vf->height * dec->vavs2_ratio) / vf->width;
+				break;
+			}
+		}
+
+	ar = min_t(u32, 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;
+	vf->codec_vfmt = VFORMAT_AVS2;
+
+	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_len(&dec->display_q) > VF_POOL_SIZE) {
+		avs2_print(dec, AVS2_DBG_BUFMGR,
+			"kfifo len:%d invalid, peek error\n",
+			kfifo_len(&dec->display_q));
+		return NULL;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		struct vframe_s *vf_tmp;
+		if (kfifo_peek(&dec->display_q, &vf_tmp) && vf_tmp) {
+				uint8_t index = vf_tmp->index & 0xff;
+				struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+				if (!pic->back_done_mark)
+					return NULL;
+		} else
+			return NULL;
+	}
+#endif
+
+	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.frm_pool[i].index == index)
+				pic = &dec->avs2_dec.frm_pool[i];
+		}
+	}
+	return pic;
+}
+
+static void update_vf_memhandle(struct AVS2Decoder_s *dec,
+	struct vframe_s *vf, struct avs2_frame_s *pic)
+{
+	vf->mem_handle = NULL;
+	vf->mem_handle_1 = NULL;
+	vf->mem_head_handle = NULL;
+	vf->mem_dw_handle = NULL;
+
+#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);
+			if (dec->front_back_mode)
+				vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->dw_mmu_box_1, 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);
+			if (dec->front_back_mode)
+				vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->mmu_box_1, pic->index);
+			vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+				dec->bmmu_box,
+				HEADER_BUFFER_IDX(pic->index));
+			if (dec->double_write_mode == 3)
+				vf->mem_dw_handle =
+					decoder_bmmu_box_get_mem_handle(
+						dec->bmmu_box,
+						VF_BUFFER_IDX(pic->BUF_index));
+			else
+				vf->mem_dw_handle = NULL;
+		}
+	} 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
+}
+
+static struct vframe_s *vavs2_vf_get(void *op_arg)
+{
+	struct vframe_s *vf;
+	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+	unsigned long flags = 0;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	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;
+	}
+
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (kfifo_peek(&dec->display_q, &vf) && vf) {
+				uint8_t index = vf->index & 0xff;
+				if (index < dec->used_buf_num) {
+					struct avs2_frame_s *pic = get_pic_by_index(dec, index);
+					if (!pic->back_done_mark)
+						return NULL;
+				} else
+					return NULL;
+		} else
+			return NULL;
+	}
+#endif
+
+	lock_buffer(dec, flags);
+	if (kfifo_get(&dec->display_q, &vf)) {
+		uint8_t index = vf->index & 0xff;
+
+
+		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;
+				unlock_buffer(dec, flags);
+				return NULL;
+			}
+
+			if ((dec->error_proc_policy & 0x2) &&
+				pic && pic->error_mark) {
+				kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+				dec->vf_pre_count--;
+				if (pic->vf_ref > 0)
+					pic->vf_ref--;
+				avs2_print(dec, AVS2_DBG_BUFMGR, "%s pic has error_mark, get err\n", __func__);
+#ifdef MULTI_INSTANCE_SUPPORT
+				vdec_up(vdec);
+#endif
+				unlock_buffer(dec, flags);
+				return NULL;
+			}
+
+			ATRACE_COUNTER(dec->trace.vf_get_name, (long)vf);
+			ATRACE_COUNTER(dec->trace.disp_q_name, kfifo_len(&dec->display_q));
+#ifdef MULTI_INSTANCE_SUPPORT
+			ATRACE_COUNTER(dec->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr);
+#else
+			ATRACE_COUNTER(dec->trace.get_canvas0_addr, vf->canvas0Addr);
+#endif
+
+			vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+			vf->vf_ud_param.ud_param.buf_len = 0;
+			vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+			vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+			vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+			vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS2 << 3);
+			vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+			if (vf->pts)
+				vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+			vf->omx_index = dec->vf_get_count;
+			dec->vf_get_count++;
+			if (pic) {
+				if (dec->front_back_mode == 1) {
+					update_vf_memhandle(dec, vf, pic);
+					decoder_do_frame_check(hw_to_vdec(dec), vf);
+#ifdef NEW_FB_CODE
+					fill_frame_info(dec, pic, pic->stream_size, vf->pts);
+					vdec_fill_vdec_frame(vdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#endif
+				}
+				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);
+			}
+			unlock_buffer(dec, flags);
+			return vf;
+		}
+	}
+	unlock_buffer(dec, flags);
+	return NULL;
+}
+
+static void vavs2_vf_put(struct vframe_s *vf, void *op_arg)
+{
+	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+	struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
+	uint8_t index;
+	unsigned long flags = 0;
+
+	if (vf == (&dec->vframe_dummy))
+		return;
+
+	if (!vf)
+		return;
+
+	ATRACE_COUNTER(dec->trace.vf_put_name, (long)vf);
+#ifdef MULTI_INSTANCE_SUPPORT
+	ATRACE_COUNTER(dec->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr);
+#else
+	ATRACE_COUNTER(dec->trace.put_canvas0_addr, vf->canvas0Addr);
+#endif
+
+	lock_buffer(dec, flags);
+	index = vf->index & 0xff;
+	kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+	ATRACE_COUNTER(dec->trace.new_q_name, kfifo_len(&dec->newframe_q));
+	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) {
+		struct avs2_frame_s *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(dec->ASSIST_MBOX0_IRQ_REG,
+						0x1);
+		dec->last_put_idx = index;
+		dec->new_frame_displayed++;
+	}
+	unlock_buffer(dec, flags);
+
+#ifdef MULTI_INSTANCE_SUPPORT
+	vdec_up(vdec);
+#endif
+
+}
+
+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 = NULL;
+
+		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;
+}
+
+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 vdec_s *vdec = hw_to_vdec(dec);
+
+	if (pic->slice_type == I_IMG)
+		pic->vqos.type = 1;
+	else if ((pic->slice_type == P_IMG) ||
+		(pic->slice_type == F_IMG))
+		pic->vqos.type = 2;
+	else if (pic->slice_type == B_IMG)
+		pic->vqos.type = 3;
+
+	if (input_frame_based(hw_to_vdec(dec)))
+		pic->vqos.size = pic->frame_size;
+	else {
+		if (!((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv))
+			&& vdec_stream_based(vdec))
+			pic->vqos.size = pic->stream_size;
+		else if (framesize == 0)
+			pic->vqos.size = pic->stream_size;
+		else
+			pic->vqos.size = framesize;
+	}
+
+	if (pic->error_mark)
+		pic->vqos.decode_buffer = 3;
+	else
+		pic->vqos.decode_buffer = 0;
+
+	pic->vqos.pts = pts;
+	pic->vqos.num++;
+
+	if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+		avs2_print(dec, 0, "slice:%d, poc:%d, size %d, decode_buffer:%d, time:%dus\n",
+			pic->vqos.type, pic->poc, pic->vqos.size, pic->vqos.decode_buffer, pic->hw_decode_time);
+
+		avs2_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_mv, pic->vqos.avg_mv, pic->vqos.min_mv);
+
+		avs2_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_qp, pic->vqos.avg_qp, pic->vqos.min_qp);
+
+		avs2_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_skip, pic->vqos.avg_skip, pic->vqos.min_skip);
+	}
+
+	return ;
+}
+
+static void set_vframe(struct AVS2Decoder_s *dec,
+	struct vframe_s *vf, struct avs2_frame_s *pic, u8 dummy)
+{
+	unsigned long flags;
+	u32 stream_offset = pic->stream_offset;
+	unsigned int frame_size = 0;
+	int pts_discontinue;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	avs2_print(dec, AVS2_DBG_BUFMGR,
+		"%s index = %d pos = %d\r\n",
+		__func__, pic->index,
+		pic->imgtr_fwRefDistance);
+#ifdef OW_TRIPLE_WRITE
+	if ((pic->triple_write_mode) ||
+		(pic->double_write_mode && (pic->double_write_mode & 0x20) == 0))
+#else
+	if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0)
+#endif
+		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.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
+				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;
+
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode == 0)
+#endif
+		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_THRESHOLD;
+				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 ((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);
+		dec->last_pts = vf->pts;
+
+		if (vf->pts_us64 != 0)
+			dec->last_lookup_pts_us64 = vf->pts_us64;
+
+		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);
+		}
+
+		dec->last_pts_us64 = 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;
+#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
+#else
+		vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+		vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
+#endif
+	}
+	if (pic->double_write_mode &&
+		((pic->double_write_mode & 0x20) == 0)) {
+		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 (dec->high_bandwidth_flag) {
+		vf->flag |= VFRAME_FLAG_HIGH_BANDWIDTH;
+	}
+
+	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;
+	}
+	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;
+	}
+
+#ifdef OW_TRIPLE_WRITE
+	if (!pic->double_write_mode && pic->triple_write_mode) {
+		vf->type |= VIDTYPE_VIU_NV21;		//nv12 flag
+		vf->canvas0_config[0] = pic->tw_canvas_config[0];
+		vf->canvas0_config[1] = pic->tw_canvas_config[1];
+		vf->canvas1_config[0] = pic->tw_canvas_config[0];
+		vf->canvas1_config[1] = pic->tw_canvas_config[1];
+		vf->width = pic->pic_w /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);	//tw same ratio defined with dw
+		vf->height = pic->pic_h /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);
+		avs2_print(dec, 0, "output triple write w %d, h %d, bitdepth %s\n",
+				vf->width, vf->height, vf->canvas0_config[0].bit_depth?"10":"8");
+	}
+#endif
+
+	if (force_fps & 0x100) {
+		u32 rate = force_fps & 0xff;
+		if (rate)
+			vf->duration = 96000/rate;
+		else
+			vf->duration = 0;
+	}
+	if (dec->front_back_mode != 1)
+		update_vf_memhandle(dec, vf, pic);
+
+	if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+		/* offset for tsplayer pts lookup */
+		u64 frame_type = 0;
+		if (pic->slice_type == I_IMG)
+			frame_type = KEYFRAME_FLAG;
+		else if ((pic->slice_type == P_IMG) ||
+			(pic->slice_type == F_IMG))
+			frame_type = PFRAME_FLAG;
+		else
+			frame_type = BFRAME_FLAG;
+		vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
+		vf->pts = 0;
+	} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+		/* lookup by decoder */
+		checkout_pts_offset pts_info;
+		u64 frame_type = 0;
+		if (pic->slice_type == I_IMG)
+			frame_type = KEYFRAME_FLAG;
+		else if (pic->slice_type == P_IMG)
+			frame_type = PFRAME_FLAG;
+		else
+			frame_type = BFRAME_FLAG;
+		pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
+		if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+			vf->pts = pts_info.pts;
+			vf->pts_us64 = pts_info.pts_64;
+		} else {
+			vf->pts = 0;
+			vf->pts_us64 = 0;
+		}
+	}
+	avs2_print(dec, AVS2_DBG_OUT_PTS,
+		"avs2 dec out pts: vf->pts=%d, vf->pts_us64 = %lld(0x%llx) slice_type %d, duration %d\n",
+		vf->pts, vf->pts_us64, vf->pts_us64, pic->slice_type, vf->duration);
+
+	lock_buffer(dec, flags);
+	if (!dummy) {
+		pic->vf_ref = 1;
+	}
+
+	dec->vf_pre_count++;
+	unlock_buffer(dec, flags);
+}
+
+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 ((dec->error_proc_policy & 0x2) &&
+			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) {
+			set_vframe(dec, vf, pic, 0);
+			if (dec->front_back_mode != 1)
+				decoder_do_frame_check(pvdec, vf);
+			vdec_vframe_ready(pvdec, vf);
+			kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
+			ATRACE_COUNTER(dec->trace.pts_name, vf->pts);
+			ATRACE_COUNTER(dec->trace.new_q_name, kfifo_len(&dec->newframe_q));
+			ATRACE_COUNTER(dec->trace.disp_q_name, kfifo_len(&dec->display_q));
+
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode == 0) {
+#endif
+			dec_update_gvs(dec);
+			/*count info*/
+			vdec_count_info(dec->gvs, 2, pic->stream_offset);
+			dec->gvs->bit_depth_luma = pic->depth;
+			dec->gvs->bit_depth_chroma = pic->depth;
+			dec->gvs->double_write_mode = pic->double_write_mode;
+			vdec_fill_vdec_frame(pvdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#ifdef NEW_FB_CODE
+			}
+#endif
+
+			pvdec->vdec_fps_detec(pvdec->id);
+			if (without_display_mode == 0) {
+				if (dec->front_back_mode != 1)
+					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);
+		} while ((data32 & 0x10000) == 0);
+		params->l.data[i] = data32&0xffff;
+		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;
+	//avs2_print(dec, 0, "avs3_param: (%d)\n", dec->avs2_dec.img.number);
+	pr_info("avs2_param: (%d)\n", dec->avs2_dec.img.number);
+	for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
+		avs2_print_cont(dec, 0, "%04x ", dec->avs2_dec.param.l.data[i]);
+		if (((i + 1) & 0xf) == 0) {
+			avs2_print_cont(dec, 0, "\n");
+			avs2_print_flush(dec);
+		}
+	}
+	avs2_print(dec, 0, "\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);
+			avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "pic index %d page_start %d\n",
+				dec->cur_fb_idx_mmu, dec->used_4k_num);
+			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)
+{
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1)
+		amhevc_stop_f();
+	else
+#endif
+	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 void check_pic_error(struct AVS2Decoder_s *dec,
+	struct avs2_frame_s *pic)
+{
+	if (pic == NULL)
+		return ;
+
+	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;
+	return 0;
+}
+
+#define HEVC_MV_INFO   0x310d
+#define HEVC_QP_INFO   0x3137
+#define HEVC_SKIP_INFO 0x3136
+
+static void get_qos_info(struct AVS2Decoder_s *dec, struct vframe_qos_s* vqos, int poc, int core_num)
+{
+	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 = poc;
+	uint64_t ctrl_reg = HEVC_PIC_QUALITY_CTRL;
+	uint64_t data_reg = HEVC_PIC_QUALITY_DATA;
+
+#ifdef NEW_FB_CODE
+	if (core_num == 1) {
+		ctrl_reg = HEVC_PIC_QUALITY_CTRL_DBE1;
+		data_reg = HEVC_PIC_QUALITY_DATA_DBE1;
+	}
+#endif
+
+	/* set rd_idx to 0 */
+	WRITE_VREG(ctrl_reg, 0);
+
+	blk88_y_count = READ_VREG(data_reg);
+	if (blk88_y_count == 0) {
+		avs2_print(dec, AVS2_DBG_QOS_INFO,
+			"[Picture %d Quality] NO Data yet.\n",
+			pic_number);
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (1 << 8));
+		return;
+	}
+
+	/* qp_y_sum */
+	rdata32 = READ_VREG(data_reg);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] Y QP AVG : %d (%d/%d)\n",
+		pic_number, rdata32 / blk88_y_count, rdata32, blk88_y_count);
+
+	vqos->avg_qp = rdata32 * 10 / blk88_y_count;
+	/* intra_y_count */
+	rdata32 = READ_VREG(data_reg);
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] Y skipped rate : %d%c (%d)\n",
+		pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+
+	vqos->avg_skip = rdata32 * 1000 / blk88_y_count;
+	/* coeff_non_zero_y_count */
+	rdata32 = READ_VREG(data_reg);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] Y ZERO_Coeff rate : %d%c (%d)\n",
+		pic_number, (100 - rdata32 * 100 /blk88_y_count), '%', rdata32);
+
+	/* blk66_c_count */
+	blk88_c_count = READ_VREG(data_reg);
+	if (blk88_c_count == 0) {
+		avs2_print(dec, AVS2_DBG_QOS_INFO,
+			"[Picture %d Quality] NO Data yet.\n",
+			pic_number);
+
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (1 << 8));
+		return;
+	}
+
+	/* qp_c_sum */
+	rdata32 = READ_VREG(data_reg);
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] C ZERO_Coeff rate : %d%c (%d)\n",
+		pic_number, (100 - rdata32 * 100 / blk88_c_count), '%', 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(data_reg);
+
+	vqos->min_qp = (rdata32 >> 0) & 0xff;
+	vqos->max_qp = (rdata32>>8) & 0xff;
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] Y QP max: %d min: %d\n",
+		pic_number, (rdata32>>8) & 0xff, (rdata32>>0) & 0xff);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] C QP min: %d, max: %d\n",
+		pic_number, (rdata32 >> 16) & 0xff, (rdata32 >> 24) & 0xff);
+
+	/* blk22_mv_count */
+	blk22_mv_count = READ_VREG(data_reg);
+	if (blk22_mv_count == 0) {
+		avs2_print(dec, AVS2_DBG_QOS_INFO,
+			"[Picture %d Quality] NO MV Data yet.\n",
+			pic_number);
+
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (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(data_reg);
+	/* should all be 0x00 or 0xff */
+
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	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 * 10, blk22_mv_count);
+	vqos->avg_mv = value;
+
+	value = div_s64(value, 10);
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L0 AVG : %d (%lld/%d)\n",
+		pic_number, (int)value, value, blk22_mv_count);
+
+	/* mvy_L0_count[31:0] */
+	rdata32_l = READ_VREG(data_reg);
+	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;
+
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	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;
+
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	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;
+
+	avs2_print(dec, AVS2_DBG_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(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	vqos->max_mv = mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	vqos->min_mv = mv_lo;
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L0 MAX: %d MIN: %d\n",
+		pic_number, mv_hi, mv_lo);
+
+	/* {mvy_L0_max, mvy_L0_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] MVY_L0 MIN: %d MAX: %d\n",
+		pic_number, mv_lo, mv_hi);
+
+	/* {mvx_L1_max, mvx_L1_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L1 MAX: %d MIN: %d\n",
+		pic_number, mv_hi, mv_lo);
+
+	/* {mvy_L1_max, mvy_L1_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] MVY_L1 MAX:%d MIN: %d\n",
+		pic_number, mv_hi, mv_lo);
+
+	rdata32 = READ_VREG(ctrl_reg);
+
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"[Picture %d Quality] After Read : VDEC_PIC_QUALITY_CTRL : 0x%x\n",
+		pic_number, rdata32);
+	/* reset all counts */
+	WRITE_VREG(ctrl_reg, (1 << 8));
+}
+
+/* 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, bool back_flag)
+{
+	struct avs2_frame_s *picture = NULL;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	struct vframe_qos_s vqos_0, vqos_1;
+
+	if (back_flag) {
+#ifdef NEW_FB_CODE
+		picture = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+#endif
+	} else {
+		picture = dec->avs2_dec.hc.cur_pic;
+	}
+
+	if (!picture) {
+		avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+			"%s decode picture is none exist\n", __func__);
+		return;
+	}
+
+	if (vdec->mvfrm) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode == 1) {
+			if (back_flag) {
+				picture->hw_decode_time =
+					local_clock() - vdec->hw_back_decode_start;
+				if (picture->hw_decode_time < picture->hw_front_decode_time)
+					picture->hw_decode_time = picture->hw_front_decode_time;
+
+			} else {
+				picture->hw_front_decode_time =
+					local_clock() - vdec->hw_front_decode_start;
+				return ;
+			}
+		} else
+#endif
+			picture->hw_decode_time =
+				local_clock() - vdec->mvfrm->hw_decode_start;
+	}
+
+	avs2_print(dec, AVS2_DBG_QOS_INFO,
+		"slice_type:%d, poc:%d, hw_decode_time:%d\n",
+		picture->slice_type, picture->imgtr_fwRefDistance, picture->hw_decode_time);
+
+	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->vqos.max_mv = a[2];
+		picture->vqos.avg_mv = a[1];
+		picture->vqos.min_mv = a[0];
+
+		avs2_print(dec, AVS2_DBG_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;
+				}
+			}
+		picture->vqos.max_qp = a[2];
+		picture->vqos.avg_qp = a[1];
+		picture->vqos.min_qp = a[0];
+		avs2_print(dec, AVS2_DBG_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;
+				}
+			}
+		picture->vqos.max_skip = a[2];
+		picture->vqos.avg_skip = a[1];
+		picture->vqos.min_skip = a[0];
+
+		avs2_print(dec, AVS2_DBG_QOS_INFO,
+			"skip data %x  a[0]= %x a[1]= %x a[2]= %x\n",
+			data, a[0], a[1], a[2]);
+	} else {
+		picture->vqos.max_mv = 0;
+		picture->vqos.avg_mv = 0;
+		picture->vqos.min_mv = 0;
+
+		picture->vqos.max_skip = 0;
+		picture->vqos.avg_skip = 0;
+		picture->vqos.min_skip = 0;
+
+		picture->vqos.max_qp = 0;
+		picture->vqos.avg_qp = 0;
+		picture->vqos.min_qp = 0;
+
+		get_qos_info(dec, &vqos_0, picture->poc, 0);
+
+		if (back_flag) {
+#ifdef NEW_FB_CODE
+			get_qos_info(dec, &vqos_1, picture->poc, 1);
+
+			vqos_0.max_mv = max(vqos_0.max_mv, vqos_1.max_mv);
+			vqos_0.min_mv = min(vqos_0.min_mv, vqos_1.min_mv);
+			vqos_0.max_qp = max(vqos_0.max_qp, vqos_1.max_qp);
+			vqos_0.min_qp = min(vqos_0.min_qp, vqos_1.min_qp);
+
+			vqos_0.avg_qp = (vqos_0.avg_qp + vqos_1.avg_qp) / 20;
+			vqos_0.avg_skip = (vqos_0.avg_skip + vqos_1.avg_skip) / 20;
+			vqos_0.avg_mv = (vqos_0.avg_mv + vqos_1.avg_mv) / 20;
+#endif
+		} else {
+			vqos_0.avg_qp = vqos_0.avg_qp / 10;
+			vqos_0.avg_skip = vqos_0.avg_skip / 10;
+			vqos_0.avg_mv = vqos_0.avg_mv / 10;
+		}
+
+		picture->vqos = vqos_0;
+	}
+}
+
+static int avs2_mmu_page_num(struct AVS2Decoder_s *dec,
+		int w, int h, int bit_depth_10)
+{
+	int picture_size;
+	int cur_mmu_4k_number, max_frame_num;
+
+	picture_size = compute_losless_comp_body_size(dec, w, h, bit_depth_10);
+	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;
+}
+
+#ifdef NEW_FB_CODE
+irqreturn_t avs2_back_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+
+	dec->dec_status_back = READ_VREG(HEVC_DEC_STATUS_DBE);
+	if (dec->dec_status_back == HEVC_BE_DECODE_DATA_DONE) {
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC_BACK);
+	}
+		/*BackEnd_Handle()*/
+	if (dec->front_back_mode != 1) {
+		avs2_print(dec, AVS2_DBG_IRQ_EVENT,
+			"[BE] %s\n", __func__);
+		if (dec->front_back_mode == 3)
+			dec->dec_status_back = HEVC_BE_DECODE_DATA_DONE;
+		return IRQ_WAKE_THREAD;
+	}
+
+	if (debug & AVS2_DBG_IRQ_EVENT)
+		avs2_print(dec, 0,
+			"[BE] avs2 back isr dec_status_back  = 0x%x\n",
+			dec->dec_status_back
+		);
+
+	if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) && READ_VREG(DEBUG_REG1_DBE)) {
+		pr_info("[BE] dbg%x: %x, HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+		READ_VREG(DEBUG_REG1_DBE),
+		READ_VREG(DEBUG_REG2_DBE),
+		READ_VREG(HEVC_SAO_CRC),
+		READ_VREG(HEVC_SAO_CRC_DBE1));
+		WRITE_VREG(DEBUG_REG1_DBE, 0);
+	}
+	if (debug & AVS2_DBG_IRQ_EVENT) {
+		pr_info("[BE] HEVC_CM_BODY_START_ADDR done= %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR));
+		pr_info("[BE] HEVC_CM_HEADER_START_ADDR done= %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR));
+		pr_info("[BE] HEVC_SAO_Y_START_ADDR done= %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR));
+		pr_info("[BE] HEVC_SAO_Y_LENGTH done= %x\n", READ_VREG(HEVC_SAO_Y_LENGTH));
+		pr_info("[BE] HEVC_SAO_C_START_ADDR done= %x\n", READ_VREG(HEVC_SAO_C_START_ADDR));
+		pr_info("[BE] HEVC_SAO_C_LENGTH done= %x\n", READ_VREG(HEVC_SAO_C_LENGTH));
+		pr_info("[BE] HEVC_SAO_Y_WPTR done= %x\n", READ_VREG(HEVC_SAO_Y_WPTR));
+		pr_info("[BE] HEVC_SAO_C_WPTR done= %x\n", READ_VREG(HEVC_SAO_C_WPTR));
+		pr_info("[BE] HEVC_SAO_CTRL0 done= %x\n", READ_VREG(HEVC_SAO_CTRL0));
+		pr_info("[BE] HEVC_SAO_CTRL1 done= %x\n", READ_VREG(HEVC_SAO_CTRL1));
+		pr_info("[BE] HEVC_SAO_CTRL2 done= %x\n", READ_VREG(HEVC_SAO_CTRL2));
+		pr_info("[BE] HEVC_SAO_CTRL3 done= %x\n", READ_VREG(HEVC_SAO_CTRL3));
+		pr_info("[BE] HEVC_SAO_CTRL4 done= %x\n", READ_VREG(HEVC_SAO_CTRL4));
+		pr_info("[BE] HEVC_SAO_CTRL5 done= %x\n", READ_VREG(HEVC_SAO_CTRL5));
+
+		pr_info("[BE] HEVC_CM_BODY_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR_DBE1));
+		pr_info("[BE] HEVC_CM_HEADER_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR_DBE1));
+		pr_info("[BE] HEVC_SAO_Y_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR_DBE1));
+		pr_info("[BE] HEVC_SAO_Y_LENGTH_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_LENGTH_DBE1));
+		pr_info("[BE] HEVC_SAO_C_START_ADDR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_START_ADDR_DBE1));
+		pr_info("[BE] HEVC_SAO_C_LENGTH_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_LENGTH_DBE1));
+		pr_info("[BE] HEVC_SAO_Y_WPTR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_Y_WPTR_DBE1));
+		pr_info("[BE] HEVC_SAO_C_WPTR_DBE1 done= %x\n", READ_VREG(HEVC_SAO_C_WPTR_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL0_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL0_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL1_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL1_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL2_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL2_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL3_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL3_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL4_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL4_DBE1));
+		pr_info("[BE] HEVC_SAO_CTRL5_DBE1 done= %x\n", READ_VREG(HEVC_SAO_CTRL5_DBE1));
+	}
+
+	if (dec->dec_status_back == AVS2_DEC_IDLE) {
+		return IRQ_HANDLED;
+	}
+	/**/
+	return IRQ_WAKE_THREAD;
+}
+
+static int file_write(struct file* fp, char *wdata, unsigned int size)
+{
+	int ret = 0, cnt = 0;
+
+	if (fp == NULL)
+		return 0;
+
+	while (ret < size) {
+		ret += media_write(fp, wdata + ret, size - ret, &fp->f_pos);
+		if (++cnt > 2)
+			break;
+	}
+
+	return ret;
+}
+
+static void pic_yuv_dump(struct avs2_frame_s* pic)
+{
+	u8 *vaddr_y, *vaddr_uv;
+	struct file *fp_yuv = NULL;
+	char file_name[64] = {0};
+	u32 i;
+
+	ulong phy_y = pic->dw_y_adr;
+	ulong phy_uv = pic->dw_u_v_adr;
+	u32 w = pic->pic_w / get_double_write_ratio(pic->double_write_mode);
+	u32 h = pic->pic_h / get_double_write_ratio(pic->double_write_mode);
+	u32 buf_w = ALIGN(w, 64);
+	u32 buf_h = ALIGN(h, 32);
+
+	if (!dump_yuv_frame)
+		return;
+
+	pr_info("%s, buf w %d, h %d, pic w %d, h %d\n", __func__, buf_w, buf_h, w, h);
+
+	snprintf(file_name, 64, "/data/tmp/dec_dump_%ux%u.raw", w, h);
+
+	fp_yuv = media_open(file_name,
+		O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
+
+	if (IS_ERR(fp_yuv)) {
+		return;
+	}
+
+	for (i = 0; i < h; i++) {
+		vaddr_y = codec_mm_vmap(phy_y, buf_w);
+		if (vaddr_y) {
+			codec_mm_dma_flush(vaddr_y, buf_w, DMA_FROM_DEVICE);
+			file_write(fp_yuv, vaddr_y, w);
+			codec_mm_unmap_phyaddr(vaddr_y);
+		}
+		phy_y += buf_w;
+	}
+
+	for (i = 0; i < h / 2; i++) {
+		vaddr_uv = codec_mm_vmap(phy_uv, buf_w);
+		if (vaddr_uv) {
+			codec_mm_dma_flush(vaddr_uv, buf_w, DMA_FROM_DEVICE);
+			file_write(fp_yuv, vaddr_uv, w);
+			codec_mm_unmap_phyaddr(vaddr_uv);
+		}
+		phy_uv += buf_w;
+	}
+	pr_info("dump idx: %d %dx%d\n", dump_yuv_frame, buf_w, buf_h);
+	dump_yuv_frame--;
+	media_close(fp_yuv, NULL);
+}
+
+irqreturn_t avs2_back_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+	unsigned int dec_status = dec->dec_status_back;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	/*simulation code: if (READ_VREG(HEVC_DEC_STATUS_DBE)==HEVC_BE_DECODE_DATA_DONE)*/
+	if (dec_status == HEVC_BE_DECODE_DATA_DONE || dec->front_back_mode == 2) {
+		struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+
+		get_picture_qos_info(dec, true);
+
+		dec_update_gvs(dec);
+		/*count info*/
+		vdec_count_info(dec->gvs, 2, pic->stream_offset);
+		dec->gvs->bit_depth_luma = pic->depth;
+		dec->gvs->bit_depth_chroma = pic->depth;
+		dec->gvs->double_write_mode = pic->double_write_mode;
+
+		reset_process_time_back(dec);
+		vdec->back_pic_done = true;
+		avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"BackEnd data done %d, fb_rd_pos %d, poc %d HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+			avs2_dec->backend_decoded_count, avs2_dec->fb_rd_pos, pic->poc,
+			(get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+					READ_VREG(HEVC_SAO_CRC) : 0,
+			(get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+					READ_VREG(HEVC_SAO_CRC_DBE1) : 0);
+
+		if (dec->front_back_mode == 1) {
+			avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"MMU0 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0));
+			avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"MMU1 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1));
+			pic_yuv_dump(pic);
+			WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS2_DEC_IDLE);
+			WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 2);
+		}
+
+		pic_backend_ref_operation(dec, 0);
+
+		if (without_display_mode == 0) {
+			struct vframe_s *vf = NULL;
+			if (kfifo_peek(&dec->display_q, &vf) && vf) {
+				struct avs2_frame_s *peek_pic =
+					&dec->avs2_dec.frm_pool[vf->index & 0xff];
+				if (peek_pic == pic)
+					vf_notify_receiver(dec->provider_name,
+						VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+			}
+		} else
+			vavs2_vf_put(vavs2_vf_get(dec), dec);
+
+		if (dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3) {
+			unsigned used_4k_num0;
+			unsigned used_4k_num1;
+			used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+			if (dec->front_back_mode == 3)
+				used_4k_num1 = used_4k_num0;
+			else
+				used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS_DBE1) >> 16;
+			avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+				"decoder_mmu_box_free_idx_tail index %d core0 %d core1 %d\n",
+				pic->index, used_4k_num0, used_4k_num1);
+			decoder_mmu_box_free_idx_tail(
+					dec->mmu_box,
+					pic->index,
+					used_4k_num0);
+			decoder_mmu_box_free_idx_tail(
+					dec->mmu_box_1,
+					pic->index,
+					used_4k_num1);
+			if (dec->dw_mmu_enable) {
+				used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+				if (dec->front_back_mode == 3)
+					used_4k_num1 = used_4k_num0;
+				else
+					used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS2_DBE1) >> 16;
+				avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+					"DW decoder_mmu_box_free_idx_tail core0 %d core1 %d\n",
+					used_4k_num0, used_4k_num1);
+				decoder_mmu_box_free_idx_tail(
+						dec->dw_mmu_box,
+						pic->index,
+						used_4k_num0);
+				decoder_mmu_box_free_idx_tail(
+						dec->dw_mmu_box_1,
+						pic->index,
+						used_4k_num1);
+			}
+		}
+
+#if 1 //def RESET_BACK_PER_PICTURE
+		if (dec->front_back_mode == 1)
+			amhevc_stop_b();
+#endif
+		/*if (dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3)
+		release_free_mmu_buffers(dec);*/
+
+		if (avs2_dec->front_pause_flag) {
+			/*multi pictures in one packe*/
+			WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG,
+						0x1);
+		}
+#ifdef NEW_FB_CODE
+		dec->dec_back_result = DEC_BACK_RESULT_DONE;
+		avs2_work_back_implement(dec, vdec, 0);
+#endif
+	}
+
+	return IRQ_HANDLED;
+}
+#endif
+
+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;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+#ifdef NEW_FB_CODE
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+#endif
+
+	if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+		(dec_status == AVS2_HEAD_PIC_PB_READY)) {
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START);
+	} else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
+	}
+
+	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);
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 1)
+					amhevc_stop_f();
+				else
+#endif
+				amhevc_stop();
+				vdec_schedule_work(&dec->work);
+			}
+		}
+		goto irq_handled_exit;
+	} else if ((dec_status == HEVC_DECPIC_DATA_DONE)
+		|| (dec_status == HEVC_DECPIC_DATA_ERROR)) {
+		struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+		mutex_lock(&dec->slice_header_lock);
+		mutex_unlock(&dec->slice_header_lock);
+		PRINT_LINE();
+		vdec->front_pic_done = true;
+
+		if ((pic != NULL) && (vdec_stream_based(hw_to_vdec(dec)))
+			&& (dec_status == HEVC_DECPIC_DATA_DONE))
+			pic->stream_size = vdec_get_stream_size(hw_to_vdec(dec));
+
+		if ((dec->front_back_mode == 0) &&
+			get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+			avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+				"HEVC_DECPIC_DATA_DONE: decode_idx %d shiftcnt=0x%x, HEVC_SAO_CRC %x\n",
+				dec->frame_count,
+				READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+				READ_VREG(HEVC_SAO_CRC));
+		} else {
+			if (pic != NULL)
+				avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+					"FrontEnd data done %d, fb_rd_pos %d, pic index %d, poc %d stream crc %x shiftbyte %x\n",
+					avs2_dec->frontend_decoded_count, avs2_dec->fb_rd_pos, dec->avs2_dec.hc.cur_pic->index,
+					pic->poc, READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+			else
+				avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+					"FrontEnd data done %d, fb_rd_pos %d, stream crc %x shiftbyte %x\n",
+					avs2_dec->frontend_decoded_count, avs2_dec->fb_rd_pos,
+					READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+		}
+#ifdef AVS2_10B_MMU
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode != 1)
+#endif
+		avs2_recycle_mmu_buf_tail(dec);
+#endif
+
+		dec->start_decoding_flag |= 0x3;
+		if (dec->m_ins_flag) {
+			if (dec_status == HEVC_DECPIC_DATA_ERROR &&
+				(pic != NULL))
+				pic->error_mark = 1;
+			set_cuva_data(dec);
+			update_decoded_pic(dec);
+			check_pic_error(dec, pic);
+			get_picture_qos_info(dec, 0);
+			reset_process_time(dec);
+			dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode) {
+				/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+				if (pic != NULL)
+					front_decpic_done_update(dec, 1); /*not multi pictures in one packe*/
+			} else
+#endif
+			amhevc_stop();
+			ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_EDN);
+			avs2_work_implement(dec);
+		}
+		goto irq_handled_exit;
+	}
+	PRINT_LINE();
+	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);
+			if (dec->m_ins_flag) {
+				dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 1)
+					amhevc_stop_f();
+				else
+#endif
+					amhevc_stop();
+				vdec_schedule_work(&dec->work);
+			}
+			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);
+			if (dec->m_ins_flag)
+				start_process_time(dec);
+			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);
+			if ((dec->front_back_mode == 1) && (dec->pic_list_init_flag == 0) &&
+				(dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATE_DONE)) {
+				dec->pic_list_init_flag = 1;
+				goto alloc_buffer_done;
+			}
+			else
+				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);
+			if (dec->m_ins_flag)
+				start_process_time(dec);
+			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) {
+#ifndef NEW_FB_CODE
+			int32_t ii;
+#endif
+			avs2_post_process(&dec->avs2_dec);
+
+			if (debug & AVS2_DBG_PRINT_PIC_LIST)
+				dump_pic_list(dec);
+
+			if (dec->front_back_mode != 1 || !efficiency_mode)
+				avs2_prepare_display_buf(dec);
+			dec->avs2_dec.hc.cur_pic = NULL;
+#ifdef NEW_FB_CODE
+			//release_free_mmu_buffers(dec);
+#else
+			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) {
+					ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+					if (pic->referred_by_others == 0) {
+#ifdef AVS2_10B_MMU
+						pic->mmu_alloc_flag = 0;
+
+						decoder_mmu_box_free_idx(dec->mmu_box,
+							pic->index);
+#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
+					}
+					ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+				}
+			}
+#endif
+		}
+	}
+
+	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 {
+			ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START);
+			for (i = 0; i < (RPM_VALID_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];
+			}
+			ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END);
+		}
+#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 (dec->avs2_dec.param.p.video_signal_type & (1<<14)) {
+			union param_u *pPara;
+
+			avs2_print(dec, AVS2_DBG_HDR_INFO, "avs2 HDR meta data present\n");
+			pPara = &dec->avs2_dec.param;
+
+			/*clean this flag*/
+			pPara->p.video_signal_type &= ~(1<<14);
+
+			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];
+				dec->vf_dp.primaries[i][1] = pPara->p.display_primaries_y[i];
+
+				if (debug & AVS2_DBG_HDR_INFO) {
+					avs2_print(dec, AVS2_DBG_HDR_INFO,
+							"primaries[%d][0]:0x%x\n",
+							i,
+							dec->vf_dp.primaries[i][0]);
+					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);
+		}
+
+		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;
+		}
+		dec->frame_width = dec->avs2_dec.param.p.horizontal_size;
+		dec->frame_height = dec->avs2_dec.param.p.vertical_size;
+	}
+	PRINT_LINE();
+	avs2_prepare_header(&dec->avs2_dec, start_code);
+
+	mutex_lock(&dec->slice_header_lock);
+	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);
+		if (dec->m_ins_flag)
+			start_process_time(dec);
+	} else if (start_code == I_PICTURE_START_CODE ||
+		start_code == PB_PICTURE_START_CODE) {
+		ret = 0;
+
+#ifdef NEW_FB_CODE
+		if (dec->m_ins_flag) {
+			u32 width = dec->avs2_dec.param.p.horizontal_size;
+			u32 height = dec->avs2_dec.param.p.vertical_size;
+			u8 bit_depth = AVS2_BITS_8;
+			int cur_mmu_fb_4k_number = 0;
+
+			if (dec->avs2_dec.param.p.profile_id == BASELINE10_PROFILE) {
+				bit_depth = dec->avs2_dec.param.p.encoding_precision;
+				bit_depth = 6 + bit_depth * 2;
+			}
+			cur_mmu_fb_4k_number = dec->fb_ifbuf_num * avs2_mmu_page_num(dec,
+				width, height, (bit_depth == 10));
+
+			if ((dec->front_back_mode == 1) &&
+				(start_code == I_PICTURE_START_CODE) &&
+				(dec->mmu_fb_4k_number < cur_mmu_fb_4k_number) &&
+				(cur_mmu_fb_4k_number > 0)) {
+				dec->init_pic_h = dec->avs2_dec.param.p.vertical_size;
+				dec->init_pic_w = dec->avs2_dec.param.p.horizontal_size;
+
+				amhevc_stop_f();
+				avs2_print(dec, AVS2_DBG_BUFMGR,
+					"%s: need realloc cur_mmu_fb_4k_number %d, mmu_4k_number %d\n",
+					__func__, cur_mmu_fb_4k_number, dec->mmu_fb_4k_number);
+				uninit_mmu_fb_bufstate(dec);
+				init_mmu_fb_bufstate(dec, cur_mmu_fb_4k_number);
+				dec_again_process(dec);
+				mutex_unlock(&dec->slice_header_lock);
+				goto irq_handled_exit;
+			}
+		}
+#endif
+
+		//dec->avs2_dec.ins_offset = 0; //move to init_pic_list_hw_fb
+		if (dec->pic_list_init_flag == 0) {
+			avs2_init_global_buffers(&dec->avs2_dec);
+				/*avs2_dec->m_bg->index is
+				set to dec->used_buf_num - 1*/
+			if ((dec->front_back_mode == 1) && (paral_alloc_buffer_mode & 1)) {
+				if ((dec->pic_list_wait_alloc_done_flag == BUFFER_INIT)) {
+					dec->dec_result = DEC_RESULT_WAIT_BUFFER;
+					avs2_print(dec, AVS2_DBG_BUFMGR, "alloc buffer\n");
+					ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+					vdec_schedule_work(&dec->work);
+					mutex_unlock(&dec->slice_header_lock);
+					goto irq_handled_exit;
+				}
+			} else
+				init_pic_list(dec);
+#ifdef NEW_FB_CODE
+			if ((dec->front_back_mode == 1) ||
+				(dec->front_back_mode == 3))
+				init_pic_list_hw_fb(dec);
+			else
+#endif
+			init_pic_list_hw(dec);
+			dec->pic_list_init_flag = 1;
+		}
+
+alloc_buffer_done:
+
+		ret = avs2_process_header(&dec->avs2_dec);
+		if (!dec->m_ins_flag)
+			dec->slice_idx++;
+
+		if (dec->m_ins_flag && ret > 0
+			&& 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
+#ifdef NEW_FB_CODE
+				&& (dec->front_back_mode != 1)
+#endif
+				) {
+				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
+#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
+		}
+
+#ifndef MV_USE_FIXED_BUF
+		ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START);
+
+		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 (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;
+				if (!vdec_secure(hw_to_vdec(dec)))
+					codec_mm_memset(dec->avs2_dec.hc.cur_pic->mpred_mv_wr_start_addr,
+						0, mv_buf_size);
+			}
+		}
+
+		ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END);
+#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
+			if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+				&& (dec->front_back_mode != 1)
+#endif
+				)
+				avs2_recycle_mmu_buf(dec);
+	#endif
+			if (dec->m_ins_flag) {
+				int slice_type = 0;
+				struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+#ifdef NEW_FB_CODE
+				mutex_lock(&dec->fb_mutex);
+#endif
+				if (cur_pic != NULL) {
+					slice_type = cur_pic->slice_type;
+				} else {
+					slice_type = dec->avs2_dec.img.type;
+				}
+
+				dec->gvs->frame_count++;
+				dec->gvs->drop_frame_count++;
+				dec->gvs->error_frame_count++;
+
+				if (slice_type == I_IMG) {
+					dec->gvs->i_lost_frames++;
+					dec->gvs->i_concealed_frames++;
+					dec->gvs->i_decoded_frames++;
+				} else if ((slice_type == P_IMG) ||
+					(slice_type == F_IMG)) {
+					dec->gvs->p_lost_frames++;
+					dec->gvs->p_concealed_frames++;
+					dec->gvs->p_decoded_frames++;
+				} else if (slice_type == B_IMG) {
+					dec->gvs->b_lost_frames++;
+					dec->gvs->b_concealed_frames++;
+					dec->gvs->b_decoded_frames++;
+				}
+#ifdef NEW_FB_CODE
+				mutex_unlock(&dec->fb_mutex);
+#endif
+
+				dec->dec_result = DEC_RESULT_ERROR;
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 1)
+					amhevc_stop_f();
+				else
+#endif
+				amhevc_stop();
+				vdec_schedule_work(&dec->work);
+			}
+			mutex_unlock(&dec->slice_header_lock);
+			goto irq_handled_exit;
+		} else {
+			struct avs2_frame_s *cur_pic = avs2_dec->hc.cur_pic;
+
+#ifdef NEW_FRONT_BACK_CODE
+			if (dec->front_back_mode) {
+				cur_pic->width = avs2_dec->img.width;
+				cur_pic->height = avs2_dec->img.height;
+				cur_pic->depth = avs2_dec->input.sample_bit_depth;
+				for (i = 0; i < MAXREF; i++)
+					cur_pic->ref_pic[i] = NULL;
+			}
+#endif
+
+			if (cur_pic != NULL) {
+				dec->gvs->frame_count++;
+				if (cur_pic->slice_type == I_IMG) {
+					dec->gvs->i_decoded_frames++;
+				} else if ((cur_pic->slice_type == P_IMG) ||
+					(cur_pic->slice_type == F_IMG)) {
+					dec->gvs->p_decoded_frames++;
+				} else if (cur_pic->slice_type == B_IMG) {
+					dec->gvs->b_decoded_frames++;
+				}
+			}
+
+			cur_pic->stream_offset = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+
+			if (!dec->m_ins_flag) {
+				dec->frame_count++;
+				decode_frame_count[dec->index] = dec->frame_count;
+			}
+			/*MULTI_INSTANCE_SUPPORT*/
+			if (dec->chunk) {
+				cur_pic->pts = dec->chunk->pts;
+				cur_pic->pts64 = dec->chunk->pts64;
+			}
+
+			cur_pic->bit_depth = dec->avs2_dec.input.sample_bit_depth;
+			cur_pic->double_write_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+			cur_pic->triple_write_mode = get_triple_write_mode(dec);
+#endif
+
+			if (vdec->mvfrm)
+				cur_pic->frame_size = vdec->mvfrm->frame_size;
+decode_slice:
+			PRINT_LINE();
+
+		ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START);
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+			if (!efficiency_mode) {
+				config_mc_buffer_fb(dec);
+				config_mcrcc_axi_hw_fb(dec);
+			}
+			config_mpred_hw_fb(dec);
+			if (!efficiency_mode) {
+				config_dblk_hw_fb(dec);
+				config_sao_hw_fb(dec);
+				config_alf_hw_fb(dec);
+			}
+			config_other_hw_fb(dec);
+		} else {
+#endif
+			config_mc_buffer(dec);
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode == 0)
+#endif
+				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);
+#ifdef NEW_FB_CODE
+			}
+#endif
+		ATRACE_COUNTER(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END);
+
+			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);
+				mutex_unlock(&dec->slice_header_lock);
+				goto irq_handled_exit;
+			}
+
+			dec->process_state = PROC_STATE_DECODING;
+#ifdef NEW_FRONT_BACK_CODE
+		if ((!efficiency_mode) && (dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3)) {
+
+			WRITE_BACK_RET(avs2_dec);
+			avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"write system instruction, ins_offset = %d, addr = 0x%x\n",
+				avs2_dec->ins_offset, avs2_dec->fr.sys_imem_ptr);
+			avs2_dec->sys_imem_ptr = avs2_dec->fr.sys_imem_ptr;
+			avs2_dec->sys_imem_ptr_v = avs2_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+			if (avs2_dec->ins_offset > 512) {
+				avs2_print(dec, 0, "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs2_dec->ins_offset);
+				avs2_dec->ins_offset = 512;
+			} else if (avs2_dec->ins_offset < 256) {
+				avs2_dec->ins_offset = 256;
+				WRITE_BACK_RET(avs2_dec);
+			}
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+			avs2_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs2_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+
+			if (avs2_dec->ins_offset > 256) {
+				avs2_print(dec, 0,
+					"!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs2_dec->ins_offset);
+				avs2_dec->ins_offset = 256;
+			}
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+			avs2_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs2_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+
+			if (avs2_dec->sys_imem_ptr >= avs2_dec->fb_buf_sys_imem.buf_end) {
+				avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+					"sys_imem_ptr is 0x%x, wrap around\n", avs2_dec->sys_imem_ptr);
+				avs2_dec->sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+				avs2_dec->sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr;
+			}
+			if (dec->front_back_mode == 1) {
+				//WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+				//WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+				//imem_count++;
+				WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+			}
+			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+		}
+		else
+#endif
+			{
+			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+			}
+		}
+
+		if (dec->m_ins_flag)
+			start_process_time(dec);
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC);
+	}
+
+	if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+		(dec_status == AVS2_HEAD_PIC_PB_READY)) {
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END);
+	}
+
+	if ((dec->front_back_mode == 1) && efficiency_mode) {
+		if (dec->pic_list_init_flag == 2) {
+#ifdef NEW_FB_CODE
+			if ((dec->front_back_mode == 1) ||
+				(dec->front_back_mode == 3))
+				init_pic_list_hw_fb(dec);
+			else
+#endif
+				init_pic_list_hw(dec);
+		}
+
+		if ((dec->front_back_mode == 1 || dec->front_back_mode == 3) &&
+			(start_code == I_PICTURE_START_CODE ||
+			start_code == PB_PICTURE_START_CODE)) {
+
+			int32_t g_WqMDefault4x4[16] = {
+				64, 	64, 	64, 	68,
+				64, 	64, 	68, 	72,
+				64, 	68, 	76, 	80,
+				72, 	76, 	84, 	96
+			};
+			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
+			};
+			config_mc_buffer_fb(dec);
+			config_mcrcc_axi_hw_fb(dec);
+			config_dblk_hw_fb(dec);
+			config_sao_hw_fb(dec);
+			config_alf_hw_fb(dec);
+
+			// 4x4
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+			for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+			// 8x8
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+			for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+			// 4x4
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+			for (i=0; i<16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+			// 8x8
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+			for (i=0; i<64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+			WRITE_BACK_RET(avs2_dec);
+			avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"write system instruction, ins_offset = %d, addr = 0x%x\n",
+				avs2_dec->ins_offset, avs2_dec->fr.sys_imem_ptr);
+			avs2_dec->sys_imem_ptr = avs2_dec->fr.sys_imem_ptr;
+			avs2_dec->sys_imem_ptr_v = avs2_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+			if (avs2_dec->ins_offset > 512) {
+				avs2_print(dec, 0, "!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs2_dec->ins_offset);
+				avs2_dec->ins_offset = 512;
+			} else if (avs2_dec->ins_offset < 256) {
+				avs2_dec->ins_offset = 256;
+				WRITE_BACK_RET(avs2_dec);
+			}
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+			avs2_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs2_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+
+			if (avs2_dec->ins_offset > 256) {
+				avs2_print(dec, 0,
+					"!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs2_dec->ins_offset);
+				avs2_dec->ins_offset = 256;
+			}
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			memcpy(avs2_dec->sys_imem_ptr_v, (void*)(&avs2_dec->instruction[0]), avs2_dec->ins_offset*4);
+			avs2_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs2_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+
+			if (avs2_dec->sys_imem_ptr >= avs2_dec->fb_buf_sys_imem.buf_end) {
+				avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+					"sys_imem_ptr is 0x%x, wrap around\n", avs2_dec->sys_imem_ptr);
+				avs2_dec->sys_imem_ptr = avs2_dec->fb_buf_sys_imem.buf_start;
+				avs2_dec->sys_imem_ptr_v = avs2_dec->fb_buf_sys_imem_addr;
+			}
+			if (dec->front_back_mode == 1) {
+				//WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+				//WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+				//imem_count++;
+				WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+			}
+		}
+		if ((start_code == I_PICTURE_START_CODE)
+				|| (start_code == PB_PICTURE_START_CODE)
+				|| (start_code == SEQUENCE_END_CODE)
+				|| (start_code == VIDEO_EDIT_CODE)) {
+
+			avs2_prepare_display_buf(dec);
+		}
+	}
+	PRINT_LINE();
+	mutex_unlock(&dec->slice_header_lock);
+
+irq_handled_exit:
+	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 = 0;
+
+	dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
+	if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC);
+	}
+
+	WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+	if ((debug & AVS2_DBG_BE_SIMULATE_IRQ)
+		&&(READ_VREG(DEBUG_REG1_DBE) ||
+			READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+	}
+
+	if ((dec_status == AVS2_HEAD_PIC_I_READY) ||
+		(dec_status == AVS2_HEAD_PIC_PB_READY)) {
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_HEAD_DONE);
+	} else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_PIC_DONE);
+	}
+
+	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) {
+		if (dec->front_back_mode != 1)
+			avs2_print(dec, 0,
+				"avs2 isr dec status  = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_SAO_CRC %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),
+				(get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+					READ_VREG(HEVC_SAO_CRC) : 0
+				);
+		else
+			avs2_print(dec, 0,
+				"avs2 isr dec status  = 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_DECODE_SIZE %x [BE] pc %x psr %x DEC_STATUS %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),
+				READ_VREG(HEVC_DECODE_SIZE),
+				READ_VREG(HEVC_MPC_E_DBE),
+			READ_VREG(HEVC_MPSR_DBE),
+			READ_VREG(HEVC_DEC_STATUS_DBE)
+				);
+	}
+	if (udebug_flag)
+		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 stream crc %x, shiftbytes 0x%x decbytes 0x%x\n",
+			READ_HREG(DEBUG_REG1), READ_HREG(DEBUG_REG2), READ_VREG(HEVC_PARSER_LCU_START),
+			READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+			(u32)(READ_VREG(HEVC_SHIFT_BYTE_COUNT) - dec->start_shift_bytes));
+
+		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) {
+			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;
+		}
+	}
+	ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_ISR_END);
+	return IRQ_WAKE_THREAD;
+}
+
+#ifdef NEW_FB_CODE
+static void avs2_check_timer_back_func(struct timer_list *timer)
+{
+	struct AVS2Decoder_s *dec = container_of(timer,
+			struct AVS2Decoder_s, timer_back);
+
+	if (dec->init_flag == 0) {
+		if (dec->stat & STAT_TIMER_BACK_ARM) {
+			mod_timer(&dec->timer_back, jiffies + PUT_INTERVAL);
+		}
+		return;
+	}
+
+	if (
+		(decode_timeout_val_back > 0) &&
+		(dec->start_process_time_back > 0) &&
+		((1000 * (jiffies - dec->start_process_time_back) / HZ)
+			> decode_timeout_val_back)
+	) {
+		if (dec->decode_timeout_count_back > 0)
+			dec->decode_timeout_count_back--;
+		if (dec->decode_timeout_count_back == 0)
+			timeout_process_back(dec);
+	}
+
+	if (debug & AVS2_DBG_BE_SIMULATE_IRQ) {
+		//struct vdec_s *vdec = hw_to_vdec(dec);
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+		//if (avs3_back_irq_cb(vdec, 0) == IRQ_WAKE_THREAD)
+		//	avs3_back_threaded_irq_cb(vdec, 0);
+	}
+
+	if ((dec->back_timer_check_count != 0) &&
+		!(dec->error_proc_policy & 0x2) &&
+		(decode_timeout_val_back > 0)) {
+		int current_monitor_data = 0;
+
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (READ_VREG(HEVC_PATH_MONITOR_CTRL) & 0xfffffe0f) | 0x91);
+		current_monitor_data = READ_VREG(HEVC_PATH_MONITOR_DATA);
+		if (dec->last_monitor_data == current_monitor_data) {
+			if (dec->back_timer_check_count > 0)
+				dec->back_timer_check_count--;
+			if (dec->back_timer_check_count == 0) {
+				timeout_process_back(dec);
+			}
+		} else {
+			dec->back_timer_check_count = back_timer_check_count;
+		}
+		dec->last_monitor_data = current_monitor_data;
+		mod_timer(timer, jiffies + 1);
+	} else
+		mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+#endif
+
+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 receiver_start_e state = RECEIVER_INACTIVE;
+
+	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(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+				}
+			}
+		}
+	} 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(dec->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 (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)
+{
+	avs2_config_work_space_hw(dec);
+	if (dec->pic_list_init_flag)
+		init_pic_list_hw(dec);
+
+	avs2_init_decoder_hw(dec);
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE, "%s\n", __func__);
+#if 0
+	data32 = READ_VREG(HEVC_STREAM_CONTROL);
+	data32 = data32 | (1 << 0); /*stream_fetch_enable*/
+	WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+	WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+	WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
+
+	WRITE_VREG(HEVC_WAIT_FLAG, 1);
+
+	/* clear mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+	/* enable mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+	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);
+
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+		WRITE_VREG(HEVC_SAO_CRC, 0);
+		if (dec->front_back_mode == 1)
+			WRITE_VREG(HEVC_SAO_CRC_DBE1, 0);
+	}
+
+}
+
+#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->vavs2_ratio = dec->vavs2_amstream_dec_info.ratio;
+
+	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;
+
+	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;
+#ifdef NEW_FB_CODE
+	struct firmware_s *fw_back = NULL;
+#endif
+	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)vdec->private;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	timer_setup(&dec->timer, vavs2_put_timer_func, 0);
+#ifdef NEW_FB_CODE
+	timer_setup(&dec->timer_back, avs2_check_timer_back_func, 0);
+	dec->stat |= STAT_TIMER_BACK_INIT;
+#endif
+
+	dec->stat |= STAT_TIMER_INIT;
+	if (vavs2_local_init(dec) < 0)
+		return -EBUSY;
+
+	avs2_dec->start_time = div64_u64(local_clock(), 1000);
+	vdec_set_vframe_comm(vdec, DRIVER_NAME);
+
+	fw = vmalloc(sizeof(struct firmware_s) + fw_size);
+	if (IS_ERR_OR_NULL(fw))
+		return -ENOMEM;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+		fw_back = vzalloc(sizeof(struct firmware_s) + fw_size);
+		if (IS_ERR_OR_NULL(fw_back))
+			return -ENOMEM;
+
+		size = get_firmware_data(VIDEO_DEC_AVS2_FRONT, fw->data);
+
+		fw_back->len = get_firmware_data(VIDEO_DEC_AVS2_BACK, fw_back->data);
+		if (fw_back->len < 0) {
+			pr_err("get back firmware fail.\n");
+			vfree(fw_back);
+			return -1;
+		}
+	} else
+#endif
+	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;
+
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->timer_back.expires = jiffies + PUT_INTERVAL;
+			dec->fw_back = fw_back;
+		}
+#endif
+
+		INIT_WORK(&dec->work, avs2_work);
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			INIT_WORK(&dec->work_back, avs2_work_back);
+			INIT_WORK(&dec->timeout_work_back, avs2_timeout_work_back);
+			mutex_init(&dec->fb_mutex);
+		}
+#endif
+		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",
+			fw_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->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;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+#endif
+	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);
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		cancel_work_sync(&dec->work_back);
+		vfree(dec->fw_back);
+		dec->fw_back = NULL;
+	}
+#endif
+	uninit_mmu_buffers(dec);
+	if (dec->fw) {
+		vfree(dec->fw);
+		dec->fw = NULL;
+	}
+
+	return 0;
+}
+
+static int vavs2_stop(struct AVS2Decoder_s *dec)
+{
+
+	dec->init_flag = 0;
+	dec->first_sc_checked = 0;
+	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(dec->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;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+#endif
+
+	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);
+
+	if (dec->m_ins_flag) {
+		cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			cancel_work_sync(&dec->work_back);
+			vfree(dec->fw_back);
+			dec->fw_back = NULL;
+		}
+#endif
+	} else
+		amhevc_disable();
+	uninit_mmu_buffers(dec);
+
+	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;
+
+	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;
+		}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+				dec->index, FRAME_BUFFERS,
+				dec->need_cache_size,
+				tvp_flag
+				);
+			if (!dec->mmu_box_1) {
+				pr_err("avs2 alloc mmu box1 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;
+		}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->dw_mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+				dec->index, FRAME_BUFFERS,
+				dec->need_cache_size,
+				tvp_flag
+				);
+			if (!dec->dw_mmu_box_1) {
+				pr_err("avs2 alloc dw mmu box1 failed!!\n");
+				dec->dw_mmu_enable = 0;
+			}
+		}
+#endif
+	}
+#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,
+			BMMU_ALLOC_FLAGS_WAITCLEAR);
+	if (!dec->bmmu_box) {
+		pr_err("avs2 alloc bmmu box failed!!\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int amvdec_avs2_probe(struct platform_device *pdev)
+{
+	struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+	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);
+
+	dec->init_flag = 0;
+	dec->first_sc_checked = 0;
+	dec->eos = 0;
+	dec->start_process_time = 0;
+	dec->timeout_num = 0;
+	dec->fatal_error = 0;
+	dec->show_frame_num = 0;
+	if (pdata == NULL) {
+		avs2_print(dec, 0,
+			"\namvdec_avs2 memory resource undefined.\n");
+		mutex_unlock(&vavs2_mutex);
+		return -EFAULT;
+	}
+	dec->m_ins_flag = 0;
+	dec->platform_dev = pdev;
+	platform_set_drvdata(pdev, pdata);
+
+#ifdef NEW_FB_CODE
+	dec->front_back_mode = 0;
+#endif
+	config_hevc_irq_num(dec);
+
+#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");
+		return -1;
+	}
+
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+		work_buf_size, DRIVER_NAME, &pdata->mem_start);
+	if (ret < 0) {
+		uninit_mmu_buffers(dec);
+		mutex_unlock(&vavs2_mutex);
+		return ret;
+	}
+	dec->buf_size = work_buf_size;
+
+	dec->buf_start = pdata->mem_start;
+
+	if (debug) {
+		avs2_print(dec, 0,
+			"===AVS2 decoder mem resource 0x%lx size 0x%x\n",
+			pdata->mem_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->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;
+
+	is_reset = 0;
+	if (vavs2_init(pdata) < 0) {
+		pr_info("\namvdec_avs2 init failed.\n");
+		avs2_local_uninit(dec);
+		uninit_mmu_buffers(dec);
+		pdata->dec_status = NULL;
+		mutex_unlock(&vavs2_mutex);
+		return -ENODEV;
+	}
+	/*set the max clk for smooth playing...*/
+	hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
+	mutex_unlock(&vavs2_mutex);
+
+	return 0;
+}
+
+static int amvdec_avs2_remove(struct platform_device *pdev)
+{
+	struct AVS2Decoder_s *dec = &gAVS2Decoder;
+	if (debug)
+		pr_info("amvdec_avs2_remove\n");
+
+	mutex_lock(&vavs2_mutex);
+
+	vavs2_stop(dec);
+
+	hevc_source_changed(VFORMAT_AVS2, 0, 0, 0);
+
+#ifdef DEBUG_PTS
+	pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+		dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+
+	mutex_unlock(&vavs2_mutex);
+
+	return 0;
+}
+
+/****************************************/
+
+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,
+	}
+};
+static struct codec_profile_t amvdec_avs2_profile = {
+	.name = "avs2_fb",
+	.profile = ""
+};
+static struct codec_profile_t amvdec_avs2_profile_mult;
+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 0
+//DEBUG only
+	for (jj = size-1; jj>=(size-16); jj--) {
+		if (data[jj])
+			break;
+	}
+	if (jj<(size-16)) {
+		for (jj = size-1; jj>=(size-16); jj--)
+			data[jj] = 0xff;
+	}
+#endif
+
+	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_flush(dec);
+		}
+	}
+	avs2_print(dec, 0, "\n");
+
+	if (!dec->chunk->block->is_mapped)
+		codec_mm_unmap_phyaddr(data);
+}
+
+static bool is_stbuf_stagnant_full(struct AVS2Decoder_s *dec)
+{
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	u32 cur_level, last_level, reset_level;
+
+	ulong wp = STBUF_READ(&vdec->vbuf, get_wp);
+	ulong rp = STBUF_READ(&vdec->vbuf, get_rp);
+
+	if (wp >= rp)
+		cur_level = wp - rp;
+	else
+		cur_level = rp + vdec->vbuf.buf_size - wp;
+
+	last_level = dec->last_stbuf_level;
+	dec->last_stbuf_level = cur_level;
+	reset_level = (vdec->vbuf.buf_size > (SZ_1M * 10)) ? (SZ_1M * 10) : (vdec->vbuf.buf_size >> 1);
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"cur level %x, last level %x, reset lvl %x\n", cur_level, last_level, reset_level);
+	if ((cur_level == last_level) && (cur_level >= reset_level))
+		return true;
+
+	return false;
+}
+
+void wait_hevc_search_done(struct AVS2Decoder_s *dec)
+{
+	int count = 0;
+	WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+	while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+		usleep_range(100, 101);
+		count++;
+		if (count > 100) {
+			avs2_print(dec, 0, "%s timeout\n", __func__);
+			break;
+		}
+	}
+}
+
+static int avs2_wait_alloc_buf(void *args)
+{
+	struct AVS2Decoder_s *dec = (struct AVS2Decoder_s *)args;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	init_pic_list(dec);
+
+	vdec_up(vdec);
+
+	return 0;
+}
+
+static void avs2_work_implement(struct AVS2Decoder_s *dec)
+{
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	if (dec->dec_result == DEC_RESULT_DONE || dec->dec_result == DEC_RESULT_WAIT_BUFFER)
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_START);
+	else if (dec->dec_result == DEC_RESULT_AGAIN)
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_AGAIN);
+
+	/* 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 (efficiency_mode && dec->pic_list_init_flag == 1)
+			dec->pic_list_init_flag =2;
+
+	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_avs2: 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_avs2: Insufficient data\n");
+
+			vdec_schedule_work(&dec->work);
+		}
+		return;
+	} else if ((dec->dec_result == DEC_RESULT_DONE)
+		|| (dec->dec_result == DEC_RESULT_ERROR)) {
+		struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+
+		dec->slice_idx++;
+		dec->frame_count++;
+		dec->process_state = PROC_STATE_INIT;
+		decode_frame_count[dec->index] = dec->frame_count;
+
+		if ((pic != NULL) && (pic->error_mark) &&
+			(dec->dec_result == DEC_RESULT_DONE)) {
+#ifdef NEW_FB_CODE
+			mutex_lock(&dec->fb_mutex);
+#endif
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == I_IMG) {
+				dec->gvs->i_concealed_frames++;
+			} else if ((pic->slice_type == P_IMG) ||
+				(pic->slice_type == F_IMG)) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == B_IMG) {
+				dec->gvs->b_concealed_frames++;
+			}
+
+			if (pic->backend_ref == 0) {
+				dec->gvs->drop_frame_count++;
+				if (pic->slice_type == I_IMG) {
+					dec->gvs->i_lost_frames++;
+				} else if ((pic->slice_type == P_IMG) ||
+					(pic->slice_type == F_IMG)) {
+					dec->gvs->p_lost_frames++;
+				} else if (pic->slice_type == B_IMG) {
+					dec->gvs->b_lost_frames++;
+				}
+			}
+#ifdef NEW_FB_CODE
+			mutex_unlock(&dec->fb_mutex);
+#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;
+		}
+
+		if (vdec_stream_based(vdec) && !dec->start_decoding_flag) {
+			if (is_stbuf_stagnant_full(dec)) {
+				if (++dec->again_count > 0x100) {
+					vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+					dec->again_count = 0;
+					dec->last_stbuf_level = 0;
+					pr_info("avs2 have not found pic to start\n");
+				}
+			}
+		}
+	} 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) {
+			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(dec->ASSIST_MBOX0_MASK, 0);
+			vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+			dec->stat &= ~STAT_ISR_REG;
+		}
+	} else if (dec->dec_result == DEC_RESULT_WAIT_BUFFER) {
+		pr_err("DEC_RESULT_WAIT_BUFFER in\n");
+		vdec_post_task(avs2_wait_alloc_buf, dec);
+		dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATING;
+		dec->process_state =
+			PROC_STATE_DECODE_AGAIN;
+	}
+
+	if (dec->stat & STAT_TIMER_ARM) {
+		del_timer_sync(&dec->timer);
+		dec->stat &= ~STAT_TIMER_ARM;
+	}
+
+#ifdef NEW_FRONT_BACK_CODE
+	if (!vdec->front_pic_done && (dec->front_back_mode == 1)) {
+		fb_hw_status_clear(true);
+		avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"%s, clear front, status 0x%x, status_back 0x%x\n",
+			__func__, dec->dec_status, dec->dec_status_back);
+	}
+#endif
+	wait_hevc_search_done(dec);
+
+	if (dec->dec_result == DEC_RESULT_DONE || dec->dec_result == DEC_RESULT_WAIT_BUFFER)
+		ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_WORKER_END);
+
+	if (get_dbg_flag(dec) & AVS2_DBG_QOS_INFO) {
+		avs2_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+			__func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+		avs2_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+		avs2_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+		avs2_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+	}
+
+	/* 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, CORE_MASK_HEVC);
+}
+
+static void avs2_work(struct work_struct *work)
+{
+	struct AVS2Decoder_s *dec = container_of(work,
+		struct AVS2Decoder_s, work);
+
+	avs2_work_implement(dec);
+}
+
+#ifdef NEW_FB_CODE
+static void avs2_work_back_implement(struct AVS2Decoder_s *dec,
+	struct vdec_s *vdec,int from)
+{
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"[BE] %s result %d\n", __func__, dec->dec_back_result);
+
+	if (dec->dec_back_result == DEC_BACK_RESULT_TIMEOUT) {
+		struct avs2_frame_s *pic = avs2_dec->next_be_decode_pic[avs2_dec->fb_rd_pos];
+
+		mutex_lock(&dec->fb_mutex);
+		if (pic->error_mark == 0) {
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == I_IMG) {
+				dec->gvs->i_concealed_frames++;
+			} else if ((pic->slice_type == P_IMG) ||
+				(pic->slice_type == F_IMG)) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == B_IMG) {
+				dec->gvs->b_concealed_frames++;
+			}
+		}
+		mutex_unlock(&dec->fb_mutex);
+
+		pic ->error_mark = 1;
+		pic_backend_ref_operation(dec, 0);
+
+		if (dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3)
+			release_free_mmu_buffers(dec);
+	}
+
+	avs2_dec->backend_decoded_count++;
+
+	mutex_lock(&dec->fb_mutex);
+	avs2_dec->fb_rd_pos++;
+	if (avs2_dec->fb_rd_pos >= dec->fb_ifbuf_num)
+		avs2_dec->fb_rd_pos = 0;
+
+	avs2_dec->wait_working_buf = 0;
+	mutex_unlock(&dec->fb_mutex);
+	WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS2_DEC_IDLE);
+	amhevc_stop_b();
+
+	if (!vdec->back_pic_done && (dec->front_back_mode == 1)) {
+		fb_hw_status_clear(false);
+		avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"%s, clear back, status 0x%x, status_back 0x%x\n",
+			__func__, dec->dec_status, dec->dec_status_back);
+	}
+
+	if (dec->stat & STAT_TIMER_BACK_ARM) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+
+	vdec_core_finish_run(vdec, CORE_MASK_HEVC_BACK);
+
+	if (dec->vdec_back_cb)
+		dec->vdec_back_cb(hw_to_vdec(dec), dec->vdec_back_cb_arg, CORE_MASK_HEVC_BACK);
+
+}
+
+static void avs2_work_back(struct work_struct *work)
+{
+	struct AVS2Decoder_s *dec = container_of(work,
+			struct AVS2Decoder_s, work_back);
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	avs2_work_back_implement(dec, vdec, 0);
+
+}
+
+static void avs2_timeout_work_back(struct work_struct *work)
+{
+	struct AVS2Decoder_s *dec = container_of(work,
+		struct AVS2Decoder_s, timeout_work_back);
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	if (work_pending(&dec->work_back))
+		return;
+	avs2_work_back_implement(dec, vdec, 1);
+}
+#endif
+
+static int avs2_hw_ctx_restore(struct AVS2Decoder_s *dec)
+{
+	/* new to do ... */
+	vavs2_prot_init(dec);
+	return 0;
+}
+
+#ifdef NEW_FB_CODE
+	/*run_ready_back*/
+static unsigned long check_input_data(struct vdec_s *vdec, unsigned long mask)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+
+	if (fbdebug_flag & 0x1)
+		return 0;
+
+	if (((avs2_dec->fb_wr_pos != avs2_dec->fb_rd_pos) || avs2_dec->wait_working_buf) &&
+		(dec->front_back_mode))
+		return mask;
+	else
+		return 0;
+}
+#endif
+
+static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	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_BE_SIMULATE_IRQ)
+		&&(READ_VREG(DEBUG_REG1_DBE) ||
+			READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+	}
+
+	if (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATING)
+			return 0;
+
+	if ((fbdebug_flag & 0x2) &&
+		dec->front_back_mode &&
+		(dec->avs2_dec.hc.cur_pic != NULL) &&
+		(dec->avs2_dec.hc.cur_pic->back_done_mark == 0))
+		return 0;
+
+	if (debug & AVS2_DBG_PIC_LEAK_WAIT)
+		return ret;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && avs2_dec->wait_working_buf)
+		return 0xffffffff;
+#endif
+
+	if (dec->eos)
+		return ret;
+	if (!dec->first_sc_checked) {
+		int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp);
+#ifdef NEW_FB_CODE
+/* to do:
+		for dec->mmu_box_1
+*/
+#endif
+		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 ((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)
+#ifdef NEW_FB_CODE
+		return ret ? mask : mask & ~(CORE_MASK_HEVC);
+#else
+		return ret ? CORE_MASK_HEVC : 0;
+#endif
+	else
+		return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
+}
+
+#ifdef NEW_FB_CODE
+static void run_back(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+	int loadr = 0;
+	int ret = 0;
+
+	if (vdec->mc_back_loaded || dec->front_back_mode != 1) {
+		/*firmware have load before,
+			and not changes to another.
+			ignore reload.
+		*/
+	} else {
+		loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS2, vdec,
+				"avs2_back", dec->fw_back->data);
+
+		if (loadr < 0) {
+			amhevc_disable();
+			avs2_print(dec, 0, "AVS2: the %s back fw loading failed, err: %x\n",
+				fw_tee_enabled() ? "TEE" : "local", loadr);
+			dec->dec_back_result = DEC_BACK_RESULT_FORCE_EXIT;
+			vdec_schedule_work(&dec->work_back);
+			return;
+		}
+
+		//vdec->mc_back_loaded = 1;
+		vdec->mc_back_type = VFORMAT_HEVC;
+	}
+
+	mod_timer(&dec->timer_back, jiffies);
+	dec->stat |= STAT_TIMER_BACK_ARM;
+
+	vdec->back_pic_done = false;
+	run_count_back[dec->index]++;
+	dec->vdec_back_cb_arg = arg;
+	dec->vdec_back_cb = callback;
+	//pr_err("run h265_HEVC_back_test\n");
+	//vdec_post_task(h265_HEVC_back_test, hevc);
+	ret = BackEnd_StartDecoding(dec);
+
+	if (ret == 1) {
+		dec->dec_back_result = DEC_BACK_RESULT_DONE;
+		vdec_schedule_work(&dec->work_back);
+	} else {
+		start_process_time_back(dec);
+	}
+
+	vdec->hw_back_decode_start = local_clock();
+}
+
+#if 0
+static void start_front_end_multi_pic_decoding(struct AVS2Decoder_s *dec)
+{ /*multi pictures in one packe*/
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	printk("Start FrontEnd Decoding %d\n", avs2_dec->frontend_decoded_count);
+	printk("copy loopbuf to next_bk[%d]\n",avs2_dec->fb_wr_pos);
+	copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+
+	if (dec->front_back_mode == 1)
+		config_bufstate_front_hw(avs2_dec);
+	WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE);
+}
+#endif
+#endif
+
+static void run(struct vdec_s *vdec, unsigned long mask,
+	void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+	int r;
+
+#ifdef NEW_FB_CODE
+	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+	/*simulation code: if (dec_status == AVS2_DEC_IDLE)*/
+	//pr_err("mask = 0x%lx\n", mask);
+	if (dec->front_back_mode == 0 || (mask & CORE_MASK_HEVC)) {
+#endif
+	run_count[dec->index]++;
+	dec->vdec_cb_arg = arg;
+	dec->vdec_cb = callback;
+
+	ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_RUN_START);
+#ifdef NEW_FRONT_BACK_CODE
+	if (debug & PRINT_FLAG_VDEC_STATUS)
+		WRITE_VREG(HEVC_STREAM_CRC, 0);
+	vdec->front_pic_done = false;
+
+	/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+	if (dec->front_back_mode) {
+		avs2_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"Start FrontEnd Decoding %d\n", avs2_dec->frontend_decoded_count);
+		avs2_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"copy loopbuf to next_bk[%d]\n",avs2_dec->fb_wr_pos);
+		copy_loopbufs_ptr(&avs2_dec->next_bk[avs2_dec->fb_wr_pos], &avs2_dec->fr);
+
+		//if (avs2_dec->frontend_decoded_count>0) {
+		if (dec->front_back_mode == 1)
+			amhevc_reset_f();
+		else
+			hevc_reset_core(vdec);
+		//}
+	} else
+#endif
+	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_avs2: Insufficient data\n");
+
+		vdec_schedule_work(&dec->work);
+		return;
+	}
+	input_empty[dec->index] = 0;
+	dec->dec_result = DEC_RESULT_NONE;
+	if (debug)
+		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");
+	}
+
+	ATRACE_COUNTER(dec->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 NEW_FB_CODE
+		int loadr = 0;
+		if (dec->front_back_mode == 1 || dec->front_back_mode == 3)
+			loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS2, vdec,
+					"avs2_front", dec->fw->data);
+		else
+#endif
+		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;
+		}
+		//vdec->mc_loaded = 1;
+		vdec->mc_type = VFORMAT_AVS2;
+	}
+	ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END);
+
+	ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START);
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (efficiency_mode)
+			WRITE_VREG(HEVC_EFFICIENCY_MODE, 1);
+		else
+			WRITE_VREG(HEVC_EFFICIENCY_MODE, 0);
+		avs2_hw_init(dec, 1, 0);
+			//config_decode_mode(dec);
+		if (dec->front_back_mode == 1)
+			config_bufstate_front_hw(avs2_dec);
+		WRITE_VREG(HEVC_DEC_STATUS_REG, AVS2_ACTION_DONE); //?? to remove
+	} else
+#endif
+
+	if (avs2_hw_ctx_restore(dec) < 0) {
+		vdec_schedule_work(&dec->work);
+		return;
+	}
+	ATRACE_COUNTER(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END);
+
+	if (vdec_frame_based(vdec))
+		WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
+
+	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);
+
+		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) HEVC_DECODE_SIZE %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(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();
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1) {
+		vdec->hw_front_decode_start = local_clock();
+		amhevc_start_f();
+	} else
+#endif
+	amhevc_start();
+	dec->stat |= STAT_VDEC_RUN;
+	ATRACE_COUNTER(dec->trace.decode_time_name, DECODER_RUN_END);
+#ifdef NEW_FB_CODE
+	}
+	if (dec->front_back_mode &&
+		(mask & CORE_MASK_HEVC_BACK)) {
+		run_back(vdec, callback, arg);
+	}
+#endif
+}
+
+static void reset(struct vdec_s *vdec)
+{
+	struct AVS2Decoder_s *dec =
+		(struct AVS2Decoder_s *)vdec->private;
+
+	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;
+
+	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;
+		return;
+	}
+
+	avs2_print(dec, 0, "====== %s\n", __func__);
+
+	avs2_print(dec, 0,
+		"width/height (%d/%d), used_buf_num %d, ref_maxbuffer %d\n",
+		dec->avs2_dec.img.width,
+		dec->avs2_dec.img.height,
+		dec->used_buf_num,
+		dec->avs2_dec.ref_maxbuffer);
+
+	avs2_print(dec, 0,
+		"front_back_mode (%d), 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",
+		dec->front_back_mode,
+		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 receiver_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), used_cont %d\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,
+		get_used_buf_count(dec));
+
+	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);
+		}
+	}
+	if (dec->front_back_mode == 1) {
+		struct avs2_decoder *avs2_dec = &dec->avs2_dec;
+		avs2_print(dec, 0,
+			"[BE] dec_back_result 0x%x, frontend_decoded_count %d, backend_decoded_count %d, fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+			dec->dec_back_result,
+			avs2_dec->frontend_decoded_count,
+			avs2_dec->backend_decoded_count,
+			avs2_dec->fb_wr_pos,
+			avs2_dec->fb_rd_pos,
+			avs2_dec->wait_working_buf
+		);
+
+		avs2_print(dec, 0,
+			"[BE] HEVC_DEC_STATUS_DBE=0x%x\n",
+			READ_VREG(HEVC_DEC_STATUS_DBE));
+		avs2_print(dec, 0,
+			"[BE] HEVC_MPC_E_DBE=0x%x\n",
+			READ_VREG(HEVC_MPC_E_DBE));
+		avs2_print(dec, 0,
+			"[BE] HEVC_MPSR_DBE=0x%x\n",
+			READ_VREG(HEVC_MPSR_DBE));
+		avs2_print(dec, 0,
+			"[BE] DEBUG_REG1_DBE=0x%x\n",
+			READ_VREG(DEBUG_REG1_DBE));
+		avs2_print(dec, 0,
+			"[BE] DEBUG_REG2_DBE=0x%x\n",
+			READ_VREG(DEBUG_REG2_DBE));
+	}
+
+}
+
+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 AVS2Decoder_s *dec = NULL;
+	static struct vframe_operations_s vf_tmp_ops;
+
+	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;
+	}
+
+	memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
+
+	dec = vzalloc(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;
+#ifdef NEW_FB_CODE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) {
+		dec->front_back_mode = front_back_mode;
+	} else {
+		dec->front_back_mode = 0;
+	}
+	dec->fb_ifbuf_num = fb_ifbuf_num;
+	if (dec->fb_ifbuf_num > MAX_FB_IFBUF_NUM)
+		dec->fb_ifbuf_num = MAX_FB_IFBUF_NUM;
+	pdata->check_input_data = NULL;
+	if (dec->front_back_mode) {
+		pdata->check_input_data = check_input_data;
+		pdata->reset = NULL;
+		pdata->back_irq_handler = avs2_back_irq_cb;
+		pdata->back_threaded_irq_handler = avs2_back_threaded_irq_cb;
+	} else
+#endif
+	pdata->reset = reset;
+	pdata->irq_handler = avs2_irq_cb;
+	pdata->threaded_irq_handler = avs2_threaded_irq_cb;
+	pdata->dump_state = avs2_dump_state;
+
+	dec->index = pdev->id;
+	dec->m_ins_flag = 1;
+	dec->error_proc_policy = error_proc_policy;
+	config_hevc_irq_num(dec);
+
+	if (is_rdma_enable()) {
+		dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle,
+				RDMA_SIZE, &dec->rdma_phy_adr, "AVS2_RDMA_BUF");
+		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->trace.vdec_name, sizeof(dec->trace.vdec_name),
+		"avs2-%d", dec->index);
+	snprintf(dec->trace.pts_name, sizeof(dec->trace.pts_name),
+		"%s-pts", dec->trace.vdec_name);
+	snprintf(dec->trace.vf_get_name, sizeof(dec->trace.vf_get_name),
+		"%s-vf_get", dec->trace.vdec_name);
+	snprintf(dec->trace.vf_put_name, sizeof(dec->trace.vf_put_name),
+		"%s-vf_put", dec->trace.vdec_name);
+	snprintf(dec->trace.set_canvas0_addr, sizeof(dec->trace.set_canvas0_addr),
+		"%s-set_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.get_canvas0_addr, sizeof(dec->trace.get_canvas0_addr),
+		"%s-get_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.put_canvas0_addr, sizeof(dec->trace.put_canvas0_addr),
+		"%s-put_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.new_q_name, sizeof(dec->trace.new_q_name),
+		"%s-newframe_q", dec->trace.vdec_name);
+	snprintf(dec->trace.disp_q_name, sizeof(dec->trace.disp_q_name),
+		"%s-dispframe_q", dec->trace.vdec_name);
+	snprintf(dec->trace.decode_time_name, sizeof(dec->trace.decode_time_name),
+		"decoder_time%d", pdev->id);
+	snprintf(dec->trace.decode_run_time_name, sizeof(dec->trace.decode_run_time_name),
+		"decoder_run_time%d", pdev->id);
+	snprintf(dec->trace.decode_header_memory_time_name, sizeof(dec->trace.decode_header_memory_time_name),
+		"decoder_header_time%d", pdev->id);
+	snprintf(dec->trace.decode_work_time_name, sizeof(dec->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);
+		dec->frameinfo_enable = 1;
+	} else
+		snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE,
+			MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff);
+
+	memcpy(&vf_tmp_ops, &vavs2_vf_provider, sizeof(struct vframe_operations_s));
+	if (without_display_mode == 1) {
+		vf_tmp_ops.get = NULL;
+	}
+	vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+		&vf_tmp_ops, 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 ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
+		/*use ptr config for double_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;
+#ifdef OW_TRIPLE_WRITE
+		if (get_config_int(pdata->config, "avs2_triple_write_mode",
+			&config_val) == 0)
+			dec->triple_write_mode = config_val;
+		else
+			dec->triple_write_mode = triple_write_mode;
+#endif
+		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,
+			"parm_metadata_config_flag",
+			&config_val) == 0) {
+			dec->high_bandwidth_flag = config_val & VDEC_CFG_FLAG_HIGH_BANDWIDTH;
+			if (dec->high_bandwidth_flag)
+				avs2_print(dec, 0, "high bandwidth\n");
+		}
+
+		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 {
+		dec->double_write_mode = double_write_mode;
+		dec->dynamic_buf_margin = dynamic_buf_num_margin;
+	}
+	video_signal_type = dec->video_signal_type;
+
+	if (double_write_mode) {
+		dec->double_write_mode = get_double_write_mode(dec);
+	}
+
+	if (!dec->dynamic_buf_margin && dynamic_buf_num_margin)
+		dec->dynamic_buf_margin = dynamic_buf_num_margin;
+	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
+#ifdef OW_TRIPLE_WRITE
+	if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3X) {
+		if ((dec->triple_write_mode) || (triple_write_mode) ||
+			(dec->double_write_mode & 0x10000) || (double_write_mode & 0x10000)) {
+			double_write_mode &= ~(1 <<16);
+			dec->double_write_mode &= ~(1 <<16);
+			triple_write_mode = 0;
+			dec->triple_write_mode = 0;
+			pr_err("%s warn: unsupport triple write or p010 mode, force disabled\n", __func__);
+		}
+	}
+#endif
+
+	if (amvdec_avs2_mmu_init(dec) < 0) {
+		pr_err("avs2 alloc bmmu box failed!!\n");
+		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);
+		vfree((void *)dec);
+		return ret;
+	}
+	if (!vdec_secure(pdata))
+		codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
+	dec->buf_start = dec->cma_alloc_addr;
+	dec->buf_size = work_buf_size;
+
+	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 (is_support_vdec_canvas())
+		dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+	if (is_dw_p010(dec) || is_tw_p010(dec))
+		dec->endian = HEVC_CONFIG_P010_LE;
+	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);
+		vfree((void *)dec);
+		pdata->dec_status = NULL;
+		return -ENODEV;
+	}
+	mutex_init(&dec->slice_header_lock);
+	vdec_set_prepare_level(pdata, start_decode_buf_level);
+	hevc_source_changed(VFORMAT_AVS2, 4096, 2048, 60);
+	if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode)
+			vdec_core_request(pdata, CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+		else
+#endif
+		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) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode)
+			vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+		else
+#endif
+		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())
+		decoder_dma_free_coherent(dec->rdma_mem_handle,
+			RDMA_SIZE, dec->rdma_adr, dec->rdma_phy_adr);
+
+	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");
+
+	if (platform_driver_register(&amvdec_avs2_driver)) {
+		pr_err("failed to register amvdec_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_fb_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);
+	amvdec_avs2_profile_mult = amvdec_avs2_profile;
+	amvdec_avs2_profile_mult.name = "mavs2_fb";
+	vcodec_profile_register(&amvdec_avs2_profile_mult);
+
+	INIT_REG_NODE_CONFIGS("media.decoder", &avs2_node,
+		"avs2_fb", avs2_configs, CONFIG_FOR_RW);
+	vcodec_feature_register(VFORMAT_AVS2, 0);
+	return 0;
+}
+
+static void __exit amvdec_avs2_driver_remove_module(void)
+{
+	pr_debug("amvdec_avs2 module remove.\n");
+	platform_driver_unregister(&ammvdec_avs2_driver);
+	platform_driver_unregister(&amvdec_avs2_driver);
+}
+
+/****************************************/
+module_param(bit_depth_luma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs2 bit_depth_luma\n");
+
+module_param(error_proc_policy, uint, 0664);
+MODULE_PARM_DESC(error_proc_policy, "\n amvdec_avs2 error_proc_policy\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");
+
+#ifdef OW_TRIPLE_WRITE
+module_param(triple_write_mode, uint, 0664);
+MODULE_PARM_DESC(triple_write_mode, "\n triple_write_mode\n");
+#endif
+
+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_avs2 force_bufspec\n");
+
+module_param(fbdebug_flag, uint, 0664);
+MODULE_PARM_DESC(fbdebug_flag, "\n amvdec_avs2 fbdebug_flag\n");
+
+module_param(udebug_flag, uint, 0664);
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs2 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_avs2 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_param(paral_alloc_buffer_mode, uint, 0664);
+MODULE_PARM_DESC(paral_alloc_buffer_mode, "\n  paral_alloc_buffer_mode\n");
+
+#ifdef NEW_FB_CODE
+module_param(front_back_mode, uint, 0664);
+MODULE_PARM_DESC(front_back_mode, "\n amvdec_avs2 front_back_mode\n");
+
+module_param(fb_ifbuf_num, uint, 0664);
+MODULE_PARM_DESC(fb_ifbuf_num, "\n amvdec_avs2 fb_ifbuf_num\n");
+
+module_param(decode_timeout_val_back, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val_back,
+	"\n avs2 decode_timeout_val_back\n");
+
+module_param(back_timer_check_count, uint, 0664);
+MODULE_PARM_DESC(back_timer_check_count,
+	"\n avs2 back_timer_check_count\n");
+
+module_param(dump_yuv_frame, uint, 0664);
+MODULE_PARM_DESC(dump_yuv_frame, "\n amvdec_avs2 dump_yuv_frame\n");
+
+module_param_array(max_process_time_back, uint,
+	&max_decode_instance_num, 0664);
+
+module_param(efficiency_mode, uint, 0664);
+MODULE_PARM_DESC(efficiency_mode, "\n  efficiency_mode\n");
+
+#endif
+
+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/avs3/Makefile b/drivers/frame_provider/decoder/avs3/Makefile
new file mode 100644
index 0000000..cc45a95
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/Makefile
@@ -0,0 +1,7 @@
+MODULE_NAME = amvdec_avs3
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS3) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += vavs3.o avs3_bufmgr.o dec_eco.o com_picman.o
+
+PR_FMT = $(subst amvdec_,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c b/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c
new file mode 100644
index 0000000..d331169
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_bufmgr.c
@@ -0,0 +1,1124 @@
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+#define CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+#endif
+#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/sched/clock.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+//#define printf printk
+#endif
+#include "avs3_global.h"
+#define CONV_LOG2(v)                    (com_tbl_log2[v])
+
+void set_livcdata_dec(DEC id_lib, LibVCData *libvc_data)
+{
+	DEC_CTX      * tmp_ctx = (DEC_CTX *)id_lib;
+	tmp_ctx->dpm.libvc_data = libvc_data;
+}
+
+void init_libvcdata(LibVCData *libvc_data)
+{
+	int i, j;
+	libvc_data->bits_dependencyFile = 0;
+	libvc_data->bits_libpic = 0;
+
+	libvc_data->library_picture_enable_flag = 0;
+#if IPPPCRR
+#if LIB_PIC_UPDATE
+	libvc_data->lib_pic_update = 0;
+	libvc_data->update = 0;
+	libvc_data->countRL = 0;
+	libvc_data->encode_skip = 0;
+	libvc_data->end_of_intra_period = 0;
+#else
+	libvc_data->first_pic_as_libpic = 0;
+#endif
+#endif
+#if CRR_ENC_OPT_CFG
+	libvc_data->lib_in_l0 = 2;
+	libvc_data->lib_in_l1 = 0;
+	libvc_data->pb_ref_lib = 0;
+	libvc_data->rl_ref_lib = 2;
+	libvc_data->max_list_refnum = 2;
+	libvc_data->libpic_idx = -1;
+#endif
+	libvc_data->is_libpic_processing = 0;
+	libvc_data->is_libpic_prepared = 0;
+
+	libvc_data->num_candidate_pic = 0;
+	libvc_data->num_lib_pic = 0;
+	libvc_data->num_RLpic = 0;
+
+	libvc_data->num_libpic_outside = 0;
+
+	for (i = 0; i < MAX_CANDIDATE_PIC; i++)
+	{
+		libvc_data->list_poc_of_candidate_pic[i] = -1;
+		libvc_data->list_candidate_pic[i] = NULL;
+
+		libvc_data->list_hist_feature_of_candidate_pic[i].num_component = 0;
+		libvc_data->list_hist_feature_of_candidate_pic[i].num_of_hist_interval = 0;
+		libvc_data->list_hist_feature_of_candidate_pic[i].length_of_interval = 0;
+		for (j = 0; j < MAX_NUM_COMPONENT; j++)
+		{
+		libvc_data->list_hist_feature_of_candidate_pic[i].list_hist_feature[j] = NULL;
+		}
+
+		libvc_data->list_poc_of_RLpic[i] = -1;
+		libvc_data->list_libidx_for_RLpic[i] = -1;
+
+	}
+	for (i = 0; i < MAX_NUM_LIBPIC; i++)
+	{
+		libvc_data->list_poc_of_libpic[i] = -1;
+		libvc_data->list_libpic_outside[i] = NULL;
+		libvc_data->list_library_index_outside[i] = -1;
+	}
+}
+
+static const s8 com_tbl_log2[257] =
+{
+	/* 0, 1 */
+	-1, -1,
+		/* 2, 3 */
+		1, -1,
+		/* 4 ~ 7 */
+		2, -1, -1, -1,
+		/* 8 ~ 15 */
+		3, -1, -1, -1, -1, -1, -1, -1,
+		/* 16 ~ 31 */
+		4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+		/* 31 ~ 63 */
+		5, -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,
+		/* 64 ~ 127 */
+		6, -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,
+		/* 128 ~ 255 */
+		7, -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, -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,
+		/* 256 */
+		8
+	};
+
+COM_PIC *dec_pull_frm(DEC_CTX *ctx, int state)
+{
+	int ret;
+	COM_PIC *pic = NULL;
+	int library_picture_index;
+	//*imgb = NULL;
+#if LIBVC_ON
+	// output lib pic and corresponding library_picture_index
+	if (ctx->info.sqh.library_stream_flag)
+	{
+		pic = ctx->pic;
+		library_picture_index = ctx->info.pic_header.library_picture_index;
+
+		//output to the buffer outside the decoder
+		ret = com_picman_out_libpic(pic, library_picture_index, &ctx->dpm);
+		if (pic)
+		{
+		printf("%s output index %d\n", __func__, pic->buf_cfg.index);
+		//com_assert_rv(pic->imgb != NULL, COM_ERR);
+		//pic->imgb->addref(pic->imgb);
+		//*imgb = pic->imgb;
+		}
+		//Don't output the reconstructed libpics to yuv. Because lib pic should not display.
+
+		return pic;
+	}
+	else
+#endif
+	{
+		pic = com_picman_out_pic( &ctx->dpm, &ret, ctx->info.pic_header.decode_order_index, state ); //MX: doi is not increase mono, but in the range of [0,255]
+		if (pic)
+		{
+		printf("%s output index %d\n", __func__, pic->buf_cfg.index);
+		//com_assert_rv(pic->imgb != NULL, COM_ERR);
+		/* increase reference count */
+		//pic->imgb->addref(pic->imgb);
+		//*imgb = pic->imgb;
+		}
+		return pic;
+	}
+}
+
+static void make_stat(DEC_CTX * ctx, int btype, DEC_STAT * stat)
+{
+	int i, j;
+	stat->read = 0;
+	stat->ctype = btype;
+	stat->stype = 0;
+	stat->fnum = -1;
+#if LIBVC_ON
+	stat->is_RLpic_flag = ctx->info.pic_header.is_RLpic_flag;
+#endif
+	if (ctx)
+	{
+		//stat->read = COM_BSR_GET_READ_BYTE(&ctx->bs);
+		if (btype == COM_CT_SLICE)
+		{
+		stat->fnum = ctx->pic_cnt;
+		stat->stype = ctx->info.pic_header.slice_type;
+		/* increase decoded picture count */
+		ctx->pic_cnt++;
+		stat->poc = ctx->ptr;
+		for (i = 0; i < 2; i++)
+		{
+			stat->refpic_num[i] = ctx->dpm.num_refp[i];
+			for (j = 0; j < stat->refpic_num[i]; j++)
+			{
+#if LIBVC_ON
+			stat->refpic[i][j] = ctx->refp[j][i].pic->ptr;
+#else
+			stat->refpic[i][j] = ctx->refp[j][i].ptr;
+#endif
+			}
+		}
+		}
+		else if (btype == COM_CT_PICTURE)
+		{
+		stat->fnum = -1;
+		stat->stype = ctx->info.pic_header.slice_type;
+		stat->poc = ctx->info.pic_header.dtr;
+		for (i = 0; i < 2; i++)
+		{
+			stat->refpic_num[i] = ctx->dpm.num_refp[i];
+			for (j = 0; j < stat->refpic_num[i]; j++)
+			{
+#if LIBVC_ON
+			stat->refpic[i][j] = ctx->refp[j][i].pic->ptr;
+#else
+			stat->refpic[i][j] = ctx->refp[j][i].ptr;
+#endif
+			}
+		}
+		}
+	}
+
+#if PRINT_SQH_PARAM_DEC
+#if PHASE_2_PROFILE
+	stat->profile_id = ctx->info.sqh.profile_id;
+#endif
+	stat->internal_bit_depth = ctx->info.sqh.encoding_precision == 2 ? 10 : 8;;
+#if ENHANCE_TSPCM
+	stat->intra_tools = (ctx->info.sqh.tscpm_enable_flag << 0) + (ctx->info.sqh.enhance_tscpm_enable_flag << 1) +
+		(ctx->info.sqh.ipf_enable_flag << 2) + (ctx->info.sqh.dt_intra_enable_flag << 3) + (ctx->info.sqh.ipcm_enable_flag << 4);
+#if MIPF
+	stat->intra_tools += (ctx->info.sqh.mipf_enable_flag << 5);
+#endif
+#else
+	stat->intra_tools = (ctx->info.sqh.tscpm_enable_flag << 0) + (ctx->info.sqh.ipf_enable_flag << 1) + (ctx->info.sqh.dt_intra_enable_flag << 2) + (ctx->info.sqh.ipcm_enable_flag << 3);
+#if MIPF
+	stat->intra_tools += (ctx->info.sqh.mipf_enable_flag << 4);
+#endif
+#endif
+
+#if PMC
+	stat->intra_tools += (ctx->info.sqh.pmc_enable_flag << 6);
+#endif
+
+#if IPF_CHROMA
+	stat->intra_tools += (ctx->info.sqh.chroma_ipf_enable_flag << 7);
+#endif
+#if IIP
+	stat->intra_tools += (ctx->info.sqh.iip_enable_flag << 8);
+#endif
+	stat->inter_tools = (ctx->info.sqh.affine_enable_flag << 0) + (ctx->info.sqh.amvr_enable_flag << 1) + (ctx->info.sqh.umve_enable_flag << 2) + (ctx->info.sqh.emvr_enable_flag << 3);
+	stat->inter_tools+= (ctx->info.sqh.smvd_enable_flag << 4) + (ctx->info.sqh.num_of_hmvp_cand << 10);
+#if AWP
+	stat->inter_tools += ctx->info.sqh.awp_enable_flag << 5;
+#endif
+	stat->trans_tools = (ctx->info.sqh.secondary_transform_enable_flag << 0) + (ctx->info.sqh.position_based_transform_enable_flag << 1);
+
+	stat->filte_tools = (ctx->info.sqh.sample_adaptive_offset_enable_flag << 0) + (ctx->info.sqh.adaptive_leveling_filter_enable_flag << 1);
+
+	stat->scc_tools   = 0;
+#if FIMC
+	stat->scc_tools  += (ctx->info.sqh.fimc_enable_flag << 0);
+#endif
+#if IBC_BVP
+	stat->scc_tools += (ctx->info.sqh.num_of_hbvp_cand << 1);
+#endif
+#endif
+}
+
+static void sequence_deinit(DEC_CTX * ctx)
+{
+	com_picman_deinit(&ctx->dpm);
+}
+
+static int sequence_init(DEC_CTX * ctx, COM_SQH * sqh, int max_pb_size)
+{
+	int size;
+	int ret;
+
+	ctx->info.bit_depth_internal = (sqh->encoding_precision == 2) ? 10 : 8;
+	assert(sqh->sample_precision == 1 || sqh->sample_precision == 2);
+	ctx->info.bit_depth_input = (sqh->sample_precision == 1) ? 8 : 10;
+	ctx->info.qp_offset_bit_depth = (8 * (ctx->info.bit_depth_internal - 8));
+
+	sequence_deinit(ctx);
+	ctx->info.pic_width  = ((sqh->horizontal_size + MINI_SIZE - 1) / MINI_SIZE) * MINI_SIZE;
+	ctx->info.pic_height = ((sqh->vertical_size   + MINI_SIZE - 1) / MINI_SIZE) * MINI_SIZE;
+	ctx->info.max_cuwh = 1 << sqh->log2_max_cu_width_height;
+	ctx->info.log2_max_cuwh = CONV_LOG2(ctx->info.max_cuwh);
+
+	size = ctx->info.max_cuwh;
+	ctx->info.pic_width_in_lcu = (ctx->info.pic_width + (size - 1)) / size;
+	ctx->info.pic_height_in_lcu = (ctx->info.pic_height + (size - 1)) / size;
+	ctx->info.f_lcu = ctx->info.pic_width_in_lcu * ctx->info.pic_height_in_lcu;
+	ctx->info.pic_width_in_scu = (ctx->info.pic_width + ((1 << MIN_CU_LOG2) - 1)) >> MIN_CU_LOG2;
+	ctx->info.pic_height_in_scu = (ctx->info.pic_height + ((1 << MIN_CU_LOG2) - 1)) >> MIN_CU_LOG2;
+	ctx->info.f_scu = ctx->info.pic_width_in_scu * ctx->info.pic_height_in_scu;
+#if ASP
+	ctx->info.skip_me_asp = FALSE;
+	ctx->info.skip_umve_asp = FALSE;
+#endif
+
+	ctx->pa.width = ctx->info.pic_width;
+	ctx->pa.height = ctx->info.pic_height;
+	ctx->pa.pad_l = PIC_PAD_SIZE_L;
+	ctx->pa.pad_c = PIC_PAD_SIZE_C;
+	ret = com_picman_init(&ctx->dpm, max_pb_size, MAX_NUM_REF_PICS, &ctx->pa);
+	com_assert_g(COM_SUCCEEDED(ret), ERR);
+
+	/*
+	...
+	*/
+
+	ctx->info.pic_header.tool_alf_on = ctx->info.sqh.adaptive_leveling_filter_enable_flag;
+#if ALF_SHAPE || ALF_IMP
+	ctx->info.pic_header.tool_alf_shape_on = ctx->info.sqh.adaptive_filter_shape_enable_flag;
+#endif
+	create_alf_global_buffer(ctx);
+	ctx->info.pic_header.pic_alf_on = ctx->pic_alf_on;
+
+	return COM_OK;
+ERR:
+	sequence_deinit(ctx);
+	ctx->init_flag = 0;
+	return ret;
+}
+
+int dec_cnk(DEC_CTX * ctx, DEC_STAT * stat, unsigned char start_code,
+	union param_u *param, int max_pb_size)
+{
+	COM_PIC_HEADER   *pic_header;
+	COM_SQH * sqh;
+	COM_SH_EXT *shext;
+	COM_CNKH *cnkh;
+	int        ret = COM_OK;
+	int i;
+	PRINT_LINE();
+	if (stat)
+	{
+		com_mset(stat, 0, sizeof(DEC_STAT));
+	}
+	sqh = &ctx->info.sqh;
+	pic_header = &ctx->info.pic_header;
+	shext = &ctx->info.shext;
+	cnkh = &ctx->info.cnkh;
+
+	/* set error status */
+#ifdef TRACE_RDO_EXCLUDE_I
+#if TRACE_RDO_EXCLUDE_I
+	if (pic_header->slice_type != SLICE_I)
+	{
+#endif
+#endif
+		COM_TRACE_SET(1);
+#ifdef TRACE_RDO_EXCLUDE_I
+#if TRACE_RDO_EXCLUDE_I
+	}
+	else
+	{
+		COM_TRACE_SET(0);
+	}
+#endif
+#endif
+	/* bitstream reader initialization */
+	//com_bsr_init(bs, bitb->addr, bitb->ssize, NULL);
+	//SET_SBAC_DEC(bs, &ctx->sbac_dec);
+
+	//start_store_param("", bs->cur[3]);
+	if (start_code == 0xB0)
+	{
+		cnkh->ctype = COM_CT_SQH;
+		ret = dec_eco_sqh(param, sqh);
+		PRINT_LINE();
+		com_assert_rv(COM_SUCCEEDED(ret), ret);
+		PRINT_LINE();
+#if LIBVC_ON
+		ctx->dpm.libvc_data->is_libpic_processing = sqh->library_stream_flag;
+		ctx->dpm.libvc_data->library_picture_enable_flag = sqh->library_picture_enable_flag;
+		/*
+		if (ctx->dpm.libvc_data->library_picture_enable_flag && !ctx->dpm.libvc_data->is_libpic_prepared)
+		{
+		ret = COM_ERR_UNEXPECTED;
+		printf("\nError: when decode seq.bin with library picture enable, you need to input libpic.bin at the same time by using param: --input_libpics.");
+		com_assert_rv(ctx->dpm.libvc_data->library_picture_enable_flag == ctx->dpm.libvc_data->is_libpic_prepared, ret);
+		}
+	 */
+#endif
+		PRINT_LINE();
+
+#if EXTENSION_USER_DATA
+		//extension_and_user_data(ctx, param, 0, sqh, pic_header);
+#endif
+		if ( !ctx->init_flag )
+		{
+		PRINT_LINE();
+		ret = sequence_init(ctx, sqh, max_pb_size);
+		PRINT_LINE();
+		com_assert_rv(COM_SUCCEEDED(ret), ret);
+		//g_DOIPrev = g_CountDOICyCleTime = 0;
+		PRINT_LINE();
+		ctx->init_flag = 1;
+		}
+	}
+	else if ( start_code == 0xB1 )
+	{
+		ctx->init_flag = 0;
+		cnkh->ctype = COM_CT_SEQ_END;
+	}
+	else if (start_code == 0xB3 || start_code == 0xB6)
+	{
+		int need_minus_256 = 0;
+		PRINT_LINE();
+		cnkh->ctype = COM_CT_PICTURE;
+		if (ctx->init_flag != 1)
+			return COM_ERR_MALFORMED_BITSTREAM;
+		/* decode slice header */
+		pic_header->low_delay = sqh->low_delay;
+		ret = dec_eco_pic_header(param, pic_header, sqh, &need_minus_256, start_code);
+		if (need_minus_256)
+		{
+		com_picman_dpbpic_doi_minus_cycle_length( &ctx->dpm );
+		}
+
+		ctx->wq[0] = pic_header->wq_4x4_matrix;
+		ctx->wq[1] = pic_header->wq_8x8_matrix;
+
+		if (!sqh->library_stream_flag)
+		{
+		com_picman_check_repeat_doi(&ctx->dpm, pic_header);
+		}
+
+#if EXTENSION_USER_DATA && WRITE_MD5_IN_USER_DATA
+		//extension_and_user_data(ctx, param, 1, sqh, pic_header);
+#endif
+		com_construct_ref_list_doi(pic_header);
+
+		//add by Yuqun Fan, init rpl list at ph instead of sh
+#if HLS_RPL
+#if LIBVC_ON
+		if (!sqh->library_stream_flag)
+#endif
+		{
+		ret = com_picman_refpic_marking_decoder(&ctx->dpm, pic_header);
+		if (avs3_get_error_policy() & 0x4)
+			com_assert_rv(ret == COM_OK, ret);
+		}
+		com_cleanup_useless_pic_buffer_in_pm(&ctx->dpm);
+
+		/* reference picture lists construction */
+		ret = com_picman_refp_rpl_based_init_decoder(&ctx->dpm, pic_header, ctx->refp);
+
+#if AWP
+		if (ctx->info.pic_header.slice_type == SLICE_P || ctx->info.pic_header.slice_type == SLICE_B)
+		{
+		for (i = 0; i < ctx->dpm.num_refp[REFP_0]; i++)
+		{
+			ctx->info.pic_header.ph_poc[REFP_0][i] = ctx->refp[i][REFP_0].ptr;
+		}
+		}
+
+		if (ctx->info.pic_header.slice_type == SLICE_B)
+		{
+		for (i = 0; i < ctx->dpm.num_refp[REFP_1]; i++)
+		{
+			ctx->info.pic_header.ph_poc[REFP_1][i] = ctx->refp[i][REFP_1].ptr;
+		}
+		}
+#endif
+#else
+		/* initialize reference pictures */
+		//ret = com_picman_refp_init(&ctx->dpm, ctx->info.sqh.num_ref_pics_act, sh->slice_type, ctx->ptr, ctx->info.sh.temporal_id, ctx->last_intra_ptr, ctx->refp);
+#endif
+		if (avs3_get_error_policy() & 0x4) {
+			com_assert_rv(COM_SUCCEEDED(ret), ret);
+		} else if (ret != 0) {
+			ret = 0;
+			goto NEW_PICTURE;
+		}
+#ifdef ORI_CODE
+	}
+	else if (start_code >= 0x00 && start_code <= 0x8E)
+	{
+#endif
+		cnkh->ctype = COM_CT_SLICE;
+		ret = dec_eco_patch_header(param, sqh, pic_header, shext, ctx->patch);
+		/* initialize slice */
+#ifdef ORI_CODE
+		ret = slice_init(ctx, ctx->core, pic_header);
+#else
+		ctx->dtr_prev_low = pic_header->dtr;
+		ctx->dtr = pic_header->dtr;
+		ctx->ptr = pic_header->dtr; /* PTR */
+#endif
+		com_assert_rv(COM_SUCCEEDED(ret), ret);
+#if 1
+		if (is_avs3_print_bufmgr_detail())
+			com_picman_print_state(&ctx->dpm);
+		if (pic_header->rpl_l0.ref_pic_active_num > 0) {
+		char tmpbuf[128];
+		int pos = 0;
+		for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++)
+			pos += sprintf(&tmpbuf[pos], "%d ", ctx->refp[i][REFP_0].ptr);
+		printf("rpl_l0 num %d: %s\n", pic_header->rpl_l0.ref_pic_active_num, tmpbuf);
+		}
+		if (pic_header->rpl_l1.ref_pic_active_num > 0) {
+		char tmpbuf[128];
+		int pos = 0;
+		for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++)
+			pos += sprintf(&tmpbuf[pos], "%d ", ctx->refp[i][REFP_1].ptr);
+		printf("rpl_l1 num %d: %s\n", pic_header->rpl_l1.ref_pic_active_num, tmpbuf);
+		}
+#endif
+NEW_PICTURE:
+		/* get available frame buffer for decoded image */
+		ctx->pic = com_picman_get_empty_pic(&ctx->dpm, &ret);
+		com_assert_rv(ctx->pic, ret);
+		/* get available frame buffer for decoded image */
+		ctx->map.map_refi = ctx->pic->map_refi;
+		ctx->map.map_mv = ctx->pic->map_mv;
+		/* decode slice layer */
+
+		//ret = dec_pic(ctx, ctx->core, sqh, pic_header, shext);
+
+#if 0
+/*AML*/
+/*put to post_process*/
+		/* put decoded picture to DPB */
+#if LIBVC_ON
+		if (sqh->library_stream_flag)
+		{
+		ret = com_picman_put_libpic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index, ctx->info.pic_header.temporal_id, 1, ctx->refp, pic_header);
+		}
+		else
+#endif
+		{
+		ret = com_picman_put_pic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index,
+				         pic_header->picture_output_delay, ctx->info.pic_header.temporal_id, 1, ctx->refp);
+		assert((&ctx->dpm)->cur_pb_size <= sqh->max_dpb_size);
+		}
+#endif
+	}
+	else
+	{
+		//stop_store_param();
+		return COM_ERR_MALFORMED_BITSTREAM;
+	}
+		PRINT_LINE();
+	make_stat(ctx, cnkh->ctype, stat);
+		PRINT_LINE();
+	//stop_store_param();
+	return ret;
+}
+
+void allocate_alf_param(ALF_PARAM **alf_param, int comp_idx
+#if ALF_SHAPE
+			, int num_coef
+#endif
+)
+{
+	//*alf_param = (ALF_PARAM *)malloc(sizeof(ALF_PARAM));
+	(*alf_param)->alf_flag = 0;
+#if ALF_SHAPE
+	(*alf_param)->num_coeff = num_coef;
+#else
+	(*alf_param)->num_coeff = ALF_MAX_NUM_COEF;
+#endif
+	(*alf_param)->filters_per_group = 1;
+#if ALF_IMP
+	(*alf_param)->dir_index = 0;
+	(*alf_param)->max_filter_num = (comp_idx == Y_C) ? NO_VAR_BINS : 1;
+#endif
+	(*alf_param)->component_id = comp_idx;
+
+#ifdef ORI_CODE
+	(*alf_param)->coeff_multi = NULL;
+	(*alf_param)->filter_pattern = NULL;
+	switch (comp_idx)
+	{
+	case Y_C:
+#if ALF_SHAPE
+		get_mem_2D_int(&((*alf_param)->coeff_multi), NO_VAR_BINS, num_coef);
+#else
+		get_mem_2D_int(&((*alf_param)->coeff_multi), NO_VAR_BINS, ALF_MAX_NUM_COEF);
+#endif
+		get_mem_1D_int(&((*alf_param)->filter_pattern), NO_VAR_BINS);
+		break;
+	case U_C:
+	case V_C:
+#if ALF_SHAPE
+		get_mem_2D_int(&((*alf_param)->coeff_multi), 1, num_coef);
+#else
+		get_mem_2D_int(&((*alf_param)->coeff_multi), 1, ALF_MAX_NUM_COEF);
+#endif
+		break;
+	default:
+		printf("Not a legal component ID\n");
+		assert(0);
+		exit(-1);
+	}
+#endif
+}
+
+void create_alf_global_buffer(DEC_CTX *ctx)
+{
+	int i;
+#if ALF_SHAPE
+	int num_coef = (ctx->info.sqh.adaptive_filter_shape_enable_flag) ? ALF_MAX_NUM_COEF_SHAPE2 : ALF_MAX_NUM_COEF;
+#endif
+	for (i = 0; i < N_C; i++)
+	{
+		allocate_alf_param(&ctx->info.pic_header.alf_picture_param[i], i
+#if ALF_SHAPE
+				, num_coef
+#endif
+		);
+	}
+}
+
+void avs3_bufmgr_init(struct avs3_decoder *hw)
+{
+	int i;
+	//DEC_CTX *ctx = &hw->ctx;
+	hw->ctx.dpm.hw = hw;
+	for (i = 0; i < NUM_ALF_COMPONENT; i++)
+		hw->p_alfPictureParam[i] = &hw->m_alfPictureParam[i];
+	hw->ctx.info.pic_header.alf_picture_param = &hw->p_alfPictureParam[0];
+
+	init_pic_pool(hw);
+
+	init_libvcdata(&hw->libvc_data);
+	set_livcdata_dec(&hw->ctx, &hw->libvc_data);
+}
+
+int avs3_param_error_check(union param_u *param)
+{
+	if (param->p.sqh_max_dpb_size > MAX_PB_SIZE) {
+		pr_err("%s, param->p.sqh_max_dpb_size %d error\n", __func__, param->p.sqh_max_dpb_size);
+		return COM_ERR;
+	}
+
+	if ((param->p.pic_header_rpl_l0_ref_pic_num > MAX_NUM_REF_PICS) ||
+		(param->p.pic_header_rpl_l1_ref_pic_num > MAX_NUM_REF_PICS)) {
+		pr_info("%s, rpl_ref_pic_num %d, %d error\n", __func__,
+		param->p.pic_header_rpl_l0_ref_pic_num,
+		param->p.pic_header_rpl_l1_ref_pic_num);
+		return COM_ERR;
+	}
+
+	return COM_OK;
+}
+
+int avs3_bufmgr_process(struct avs3_decoder *hw, int start_code)
+{
+	int ret;
+	COM_PIC *pic;
+	DEC_CTX *ctx = &hw->ctx;
+	int i;
+	printf("%s start_code 0x%x\n", __func__, start_code);
+
+	if (avs3_param_error_check(&hw->param))
+		return COM_ERR;
+
+	ret = dec_cnk(&hw->ctx, &hw->stat, start_code, &hw->param,
+		hw->max_pb_size);
+	if (start_code == SEQUENCE_HEADER_CODE) {
+		hw->lcu_size = hw->ctx.info.max_cuwh;
+		hw->lcu_size_log2 = hw->ctx.info.log2_max_cuwh;
+		hw->lcu_x_num = hw->ctx.info.pic_width_in_lcu;
+		hw->lcu_y_num = hw->ctx.info.pic_height_in_lcu;
+		hw->lcu_total = hw->ctx.info.f_lcu;
+		printf("lcu_size %d lcu_size_log2 %d lcu_total %d\n", hw->lcu_size, hw->lcu_size_log2, hw->lcu_total);
+	} else if (start_code == I_PICTURE_START_CODE || start_code == PB_PICTURE_START_CODE) {
+		//hw->input.sample_bit_depth = hw->ctx.info.bit_depth_input;
+		hw->input.sample_bit_depth = hw->ctx.info.bit_depth_internal;
+		hw->input.alf_enable = ctx->info.sqh.adaptive_leveling_filter_enable_flag;
+		for (i = 0; i < NUM_ALF_COMPONENT; i++)
+		hw->img.pic_alf_on[i] = hw->ctx.pic_alf_on[i];
+		hw->img.width = hw->ctx.pa.width;
+		hw->img.height = hw->ctx.pa.height;
+		hw->slice_type = hw->ctx.info.pic_header.slice_type;
+		pic = ctx->pic;
+		if (pic && (!ret)) {
+		hw->cur_pic = &pic->buf_cfg;
+			printf("set refpic before cur_pic index %d, pic %p L0 num:%d, L1 num:%d\n",
+				hw->cur_pic->index, hw->cur_pic, hw->cur_pic->list0_num_refp, hw->cur_pic->list1_num_refp);
+		hw->cur_pic->list0_num_refp = hw->ctx.dpm.num_refp[REFP_0];
+		for (i = 0; i < hw->ctx.dpm.num_refp[REFP_0]; i++)
+			hw->cur_pic->list0_ptr[i] = hw->ctx.refp[i][REFP_0].ptr;
+#ifdef NEW_FRONT_BACK_CODE
+		for (i = 0; i < hw->cur_pic->list0_num_refp; i++)
+			hw->cur_pic->list0_index[i] = hw->ctx.refp[i][REFP_0].pic->buf_cfg.index;
+
+		hw->cur_pic->list1_num_refp = hw->ctx.dpm.num_refp[REFP_1];
+		for (i = 0; i < hw->cur_pic->list1_num_refp; i++)
+			hw->cur_pic->list1_index[i] = hw->ctx.refp[i][REFP_1].pic->buf_cfg.index;
+#endif
+			printf("set refpic after cur_pic index %d, pic %p L0 num:%d, L1 num:%d\n",
+				hw->cur_pic->index, hw->cur_pic, hw->cur_pic->list0_num_refp, hw->cur_pic->list1_num_refp);
+		}
+		//Read_ALF_param(hw);
+	}
+	return ret;
+}
+
+int check_poc_in_dpb(struct avs3_decoder *hw, int poc)
+{
+	COM_PIC * pic;
+	int i = 0;
+
+	for (i = 0; i < hw->max_pb_size; i++) {
+		pic = &hw->pic_pool[i];
+		if ((pic != NULL) && (pic->buf_cfg.used) &&
+			(poc == pic->ptr) && (!(avs3_get_error_policy() & 0x8))) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+int avs3_bufmgr_post_process(struct avs3_decoder *hw)
+{
+	DEC_CTX *ctx = &hw->ctx;
+	DEC_STAT *stat = &hw->stat;
+	COM_SQH *sqh =  &ctx->info.sqh;
+	COM_PIC_HEADER   *pic_header = &ctx->info.pic_header;
+	COM_CNKH *cnkh = &ctx->info.cnkh;
+	//COM_IMGB *imgb;
+	int        ret = COM_OK;
+
+	if ((ctx->pic != NULL) && !((ctx->pic->buf_cfg.in_dpb == 0)
+		&& (ctx->pic->buf_cfg.used == 1)))
+		return ret;
+
+	if (check_poc_in_dpb(hw, ctx->ptr)) {
+		ctx->pic->buf_cfg.used = 0;
+		return 2;
+	}
+
+	ctx->pic->buf_cfg.in_dpb = true;
+	if (stat)
+	{
+		com_mset(stat, 0, sizeof(DEC_STAT));
+	}
+
+	/* put decoded picture to DPB */
+#if LIBVC_ON
+	if (sqh->library_stream_flag)
+	{
+		ret = com_picman_put_libpic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index, ctx->info.pic_header.temporal_id, 1, ctx->refp, pic_header);
+	}
+	else
+#endif
+	{
+		ret = com_picman_put_pic(&ctx->dpm, ctx->pic, ctx->info.pic_header.slice_type, ctx->ptr, pic_header->decode_order_index,
+				     pic_header->picture_output_delay, ctx->info.pic_header.temporal_id, 1, ctx->refp);
+#ifdef NEW_FRONT_BACK_CODE
+		if ((&ctx->dpm)->cur_pb_size > sqh->max_dpb_size)
+		printf("!!! (&ctx->dpm)->cur_pb_size %d > sqh->max_dpb_size %d\n",
+			(&ctx->dpm)->cur_pb_size, sqh->max_dpb_size);
+#else
+		assert((& ctx->dpm)->cur_pb_size <= sqh->max_dpb_size);
+#endif
+	}
+	cnkh->ctype = COM_CT_SLICE;
+
+	make_stat(ctx, cnkh->ctype, stat);
+	printf("### pic_cnt %d cur_num_ref_pics %d\n", ctx->pic_cnt, ctx->dpm.cur_num_ref_pics);
+#if 0
+	if (hw->stat.fnum >= 0)
+	{
+		//if (aml_print_header_info) printf(" # fnum : %d state : %d\n", stat.fnum, state);
+		COM_PIC *pic = dec_pull_frm(&hw->ctx, &imgb, 0);
+		/*
+		if (ret == COM_ERR_UNEXPECTED)
+		{
+		//v1print("bumping process completed\n");
+		//printf("COM_ERR_UNEXPECTED\n");
+		//ret = -1;
+		}
+		else if (COM_FAILED(ret))
+		{
+		//v0print("failed to pull the decoded image\n");
+		printf("failed to pull the decoded image\n");
+		ret = -1;
+		}*/
+	}
+	else
+	{
+		imgb = NULL;
+	}
+#endif
+#if 0
+	if (imgb)
+	{
+		width = imgb->width[0];
+		height = imgb->height[0];
+		if (op_flag[OP_FLAG_FNAME_OUT])
+		{
+		write_dec_img(id, op_fname_out, imgb, ((DEC_CTX *)id)->info.bit_depth_internal);
+		}
+		imgb->release(imgb);
+		pic_cnt++;
+	}
+#endif
+	return ret;
+
+}
+
+void avs3_cleanup_useless_pic_buffer_in_pm(struct avs3_decoder *hw)
+{
+	com_cleanup_useless_pic_buffer_in_pm(&hw->ctx.dpm);
+}
+
+COM_PIC * com_pic_alloc(struct avs3_decoder *hw, PICBUF_ALLOCATOR * pa, int * ret)
+{
+	COM_PIC * pic = NULL;
+	int i;
+	for (i = 0; i < hw->max_pb_size; i++) {
+		if (hw->pic_pool[i].buf_cfg.used == 0) {
+		break;
+		}
+	}
+	if (i < hw->max_pb_size) {
+		avs3_frame_t pic_cfg;
+		pic = &hw->pic_pool[i];
+		memcpy(&pic_cfg, &pic->buf_cfg, sizeof(avs3_frame_t));
+		memset(pic, 0, sizeof(COM_PIC));
+		pic->width_luma = pa->width;
+		pic->height_luma = pa->height;
+		memcpy(&pic->buf_cfg, &pic_cfg, sizeof(avs3_frame_t));
+		pic->buf_cfg.used = 1;
+		pic->buf_cfg.slice_type = hw->ctx.info.pic_header.slice_type;
+#ifdef AML
+		pic->buf_cfg.error_mark = 0;
+		pic->buf_cfg.vf_ref = 0;
+		pic->buf_cfg.backend_ref = 0;
+		pic->buf_cfg.in_dpb = false;
+		pic->buf_cfg.time = div64_u64(local_clock(), 1000) - hw->start_time;
+		pic->buf_cfg.decoded_lcu = 0;
+#ifdef NEW_FB_CODE
+		pic->buf_cfg.back_done_mark = 1;
+#endif
+#endif
+
+	}
+	if (pic)
+		printf("%s: pic index %d\n", __func__, pic->buf_cfg.index);
+	else
+		printf("%s: ret NULL\n", __func__);
+	return pic;
+	//return com_picbuf_alloc(pa->width, pa->height, pa->pad_l, pa->pad_c, ret);
+}
+
+void com_pic_free(struct avs3_decoder *hw, PICBUF_ALLOCATOR *pa, COM_PIC *pic)
+{
+	pic->buf_cfg.used = 0;
+	pic->buf_cfg.in_dpb = 0;
+	printf("%s: pic index %d\n", __func__, pic->buf_cfg.index);
+}
+
+void init_pic_pool(struct avs3_decoder *hw)
+{
+	int i;
+	COM_PIC * pic;
+	for (i = 0; i < MAX_PB_SIZE; i++) {
+		pic = &hw->pic_pool[i];
+		memset(pic, 0, sizeof (COM_PIC));
+		if (i < hw->max_pb_size) {
+		pic->buf_cfg.used = 0;
+		pic->buf_cfg.index = i;
+		} else {
+		pic->buf_cfg.used = -1;
+		pic->buf_cfg.index = -1;
+		}
+	}
+
+}
+
+#if 0
+void readAlfCoeff(struct avs3_decoder *avs3_dec, ALFParam *Alfp)
+{
+	int32_t pos;
+	union param_u *rpm_param = &avs3_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] = rpm_param->alf.alf_cb_coeffmulti[pos];
+		else
+			Alfp->coeffmulti[0][pos] = rpm_param->alf.alf_cr_coeffmulti[pos];
+#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 = rpm_param->alf.alf_filters_num_m_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 = rpm_param->alf.region_distance[region_distance_idx++];
+			} else {
+			symbol = 1;
+			}
+			Alfp->filterPattern[symbol + pre_symbole] = 1;
+			pre_symbole = symbol + pre_symbole;
+		}
+
+		for (pos = 0; pos < numCoeff; pos++) {
+			Alfp->coeffmulti[f][pos] = rpm_param->alf.alf_y_coeffmulti[f][pos];
+#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: {
+		printf("Not a legal component ID\n");
+		assert(0);
+		exit(-1);
+	}
+	}
+}
+
+void Read_ALF_param(struct avs3_decoder *avs3_dec)
+{
+	struct inp_par    *input = &avs3_dec->input;
+	ImageParameters    *img = &avs3_dec->img;
+	union param_u *rpm_param = &avs3_dec->param;
+	int32_t compIdx;
+	int32_t j,k;
+	if (input->alf_enable) {
+		img->pic_alf_on[0] = rpm_param->alf.picture_alf_enable_Y;
+		img->pic_alf_on[1] = rpm_param->alf.picture_alf_enable_Cb;
+		img->pic_alf_on[2] = rpm_param->alf.picture_alf_enable_Cr;
+
+		avs3_dec->m_alfPictureParam[ALF_Y].alf_flag  = img->pic_alf_on[ALF_Y];
+		avs3_dec->m_alfPictureParam[ALF_Cb].alf_flag = img->pic_alf_on[ALF_Cb];
+		avs3_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(avs3_dec, &avs3_dec->m_alfPictureParam[compIdx]);
+			}
+		}
+		}
+	}
+
+}
+#endif
+
+void print_param(union param_u * param)
+{
+
+	printk("sqh->profile_id = %d (0x%x)\n", param->p.sqh_profile_id, param->p.sqh_profile_id);
+	printk("sqh->level_id = %d (0x%x)\n", param->p.sqh_level_id, param->p.sqh_level_id);
+	printk("sqh->progressive_sequence = %d (0x%x)\n", param->p.sqh_progressive_sequence, param->p.sqh_progressive_sequence);
+	printk("sqh->field_coded_sequence = %d (0x%x)\n", param->p.sqh_field_coded_sequence, param->p.sqh_field_coded_sequence);
+	printk("sqh->library_stream_flag = %d (0x%x)\n", param->p.sqh_library_stream_flag, param->p.sqh_library_stream_flag);
+	printk("sqh->library_picture_enable_flag = %d (0x%x)\n", param->p.sqh_library_picture_enable_flag, param->p.sqh_library_picture_enable_flag);
+	printk("sqh->horizontal_size = %d (0x%x)\n", param->p.sqh_horizontal_size, param->p.sqh_horizontal_size);
+	printk("sqh->vertical_size = %d (0x%x)\n", param->p.sqh_vertical_size, param->p.sqh_vertical_size);
+	printk("sqh->sample_precision = %d (0x%x)\n", param->p.sqh_sample_precision, param->p.sqh_sample_precision);
+	printk("sqh->encoding_precision = %d (0x%x)\n", param->p.sqh_encoding_precision, param->p.sqh_encoding_precision);
+	printk("sqh->aspect_ratio = %d (0x%x)\n", param->p.sqh_aspect_ratio, param->p.sqh_aspect_ratio);
+	printk("sqh->frame_rate_code = %d (0x%x)\n", param->p.sqh_frame_rate_code, param->p.sqh_frame_rate_code);
+	printk("sqh->low_delay = %d (0x%x)\n", param->p.sqh_low_delay, param->p.sqh_low_delay);
+	printk("sqh->temporal_id_enable_flag = %d (0x%x)\n", param->p.sqh_temporal_id_enable_flag, param->p.sqh_temporal_id_enable_flag);
+	printk("sqh->max_dpb_size = %d (0x%x)\n", param->p.sqh_max_dpb_size, param->p.sqh_max_dpb_size);
+	printk("sqh->log2_max_cu_width_height = %d (0x%x)\n", param->p.sqh_log2_max_cu_width_height, param->p.sqh_log2_max_cu_width_height);
+	printk("sqh->adaptive_leveling_filter_enable_flag = %d (0x%x)\n", param->p.sqh_adaptive_leveling_filter_enable_flag, param->p.sqh_adaptive_leveling_filter_enable_flag);
+	printk("sqh->num_of_hmvp_cand = %d (0x%x)\n", param->p.sqh_num_of_hmvp_cand, param->p.sqh_num_of_hmvp_cand);
+	printk("sqh->output_reorder_delay = %d (0x%x)\n", param->p.sqh_output_reorder_delay, param->p.sqh_output_reorder_delay);
+	printk("sqh->cross_patch_loop_filter = %d (0x%x)\n", param->p.sqh_cross_patch_loop_filter, param->p.sqh_cross_patch_loop_filter);
+	printk("pic_header->decode_order_index = %d (0x%x)\n", param->p.pic_header_decode_order_index, param->p.pic_header_decode_order_index);
+	printk("pic_header->picture_output_delay = %d (0x%x)\n", param->p.pic_header_picture_output_delay, param->p.pic_header_picture_output_delay);
+	printk("pic_header->progressive_frame = %d (0x%x)\n", param->p.pic_header_progressive_frame, param->p.pic_header_progressive_frame);
+	printk("pic_header->top_field_first = %d (0x%x)\n", param->p.pic_header_top_field_first, param->p.pic_header_top_field_first);
+	printk("pic_header->repeat_first_field = %d (0x%x)\n", param->p.pic_header_repeat_first_field, param->p.pic_header_repeat_first_field);
+	printk("pic_header->rpl_l0_idx = %d (0x%x)\n", param->p.pic_header_rpl_l0_idx, param->p.pic_header_rpl_l0_idx);
+	printk("pic_header->rpl_l1_idx = %d (0x%x)\n", param->p.pic_header_rpl_l1_idx, param->p.pic_header_rpl_l1_idx);
+	printk("pic_header->rpl_l0.ref_pic_num = %d (0x%x)\n", param->p.pic_header_rpl_l0_ref_pic_num, param->p.pic_header_rpl_l0_ref_pic_num);
+	printk("pic_header->rpl_l1.ref_pic_num = %d (0x%x)\n", param->p.pic_header_rpl_l1_ref_pic_num, param->p.pic_header_rpl_l1_ref_pic_num);
+	printk("pic_header->rpl_l0.reference_to_library_enable_flag = %d (0x%x)\n", param->p.pic_header_rpl_l0_reference_to_library_enable_flag, param->p.pic_header_rpl_l0_reference_to_library_enable_flag);
+	printk("pic_header->rpl_l1.reference_to_library_enable_flag = %d (0x%x)\n", param->p.pic_header_rpl_l1_reference_to_library_enable_flag, param->p.pic_header_rpl_l1_reference_to_library_enable_flag);
+	printk("pic_header->loop_filter_disable_flag = %d (0x%x)\n", param->p.pic_header_loop_filter_disable_flag, param->p.pic_header_loop_filter_disable_flag);
+	printk("pic_header->random_access_decodable_flag = %d (0x%x)\n", param->p.pic_header_random_access_decodable_flag, param->p.pic_header_random_access_decodable_flag);
+	printk("pic_header->slice_type = %d (0x%x)\n", param->p.pic_header_slice_type, param->p.pic_header_slice_type);
+	printk("pic_header->num_ref_idx_active_override_flag = %d (0x%x)\n", param->p.pic_header_num_ref_idx_active_override_flag, param->p.pic_header_num_ref_idx_active_override_flag);
+	printk("pic_header->rpl_l0.ref_pic_active_num = %d (0x%x)\n", param->p.pic_header_rpl_l0_ref_pic_active_num, param->p.pic_header_rpl_l0_ref_pic_active_num);
+	printk("pic_header->rpl_l1.ref_pic_active_num = %d (0x%x)\n", param->p.pic_header_rpl_l1_ref_pic_active_num, param->p.pic_header_rpl_l1_ref_pic_active_num);
+	printk("sqh->adaptive_filter_shape_enable_flag = %d (0x%x)\n", param->p.sqh_adaptive_filter_shape_enable_flag, param->p.sqh_adaptive_filter_shape_enable_flag);
+	printk("pic->header_library_picture_index = %d (0x%x)\n", param->p.pic_header_library_picture_index, param->p.pic_header_library_picture_index);
+	printk("pic->header_top_field_picture_flag = %d (0x%x)\n", param->p.pic_header_top_field_picture_flag, param->p.pic_header_top_field_picture_flag);
+	printk("pic->header->alpha_c_offset = %d (0x%x)\n", param->p.pic_header_alpha_c_offset, param->p.pic_header_alpha_c_offset);
+	printk("pic->header->beta_offset = %d (0x%x)\n", param->p.pic_header_beta_offset, param->p.pic_header_beta_offset);
+	printk("pic->header->chroma_quant_param_delta_cb = %d (0x%x)\n", param->p.pic_header_chroma_quant_param_delta_cb, param->p.pic_header_chroma_quant_param_delta_cb);
+	printk("pic->header->chroma_quant_param_delta_cr = %d (0x%x)\n", param->p.pic_header_chroma_quant_param_delta_cr, param->p.pic_header_chroma_quant_param_delta_cr);
+};
+
+void print_alf_param(union param_u * param)
+{
+	int i, ii;
+	int pos = 0;
+	char tmpbuf[128];
+	printk("picture_alf_enable_Y %d picture_alf_enable_Cb %d picture_alf_enable_Cr %d\n", param->alf.picture_alf_enable_Y, param->alf.picture_alf_enable_Cb, param->alf.picture_alf_enable_Cr);
+	printk("alf_filters_num_m_1 %d dir_index %d\n", param->alf.alf_filters_num_m_1, param->alf.dir_index);
+	for (i = 0; i < 16; i++)
+		pos += sprintf(&tmpbuf[pos], "%d ", param->alf.region_distance[i]);
+	printk("region_distance: %s\n", tmpbuf);
+
+	pos = 0;
+	for (i = 0; i < 9; i++)
+		pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_cb_coeffmulti[i]);
+	printk("alf_cb_coeffmulti: %s\n", tmpbuf);
+
+	pos = 0;
+	for (i = 0; i < 9; i++)
+		pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_cr_coeffmulti[i]);
+	printk("alf_cr_coeffmulti: %s\n", tmpbuf);
+
+	for (ii = 0; ii < 16; ii++) {
+		pos = 0;
+		for (i = 0; i < 9; i++)
+		pos += sprintf(&tmpbuf[pos], "%d ", (int16_t)param->alf.alf_y_coeffmulti[ii][i]);
+		printk("alf_y_coeffmulti[%d][]: %s\n", ii, tmpbuf);
+	}
+}
+
+void print_pic_pool(struct avs3_decoder *hw, char *mark)
+{
+	COM_PIC * pic;
+	int i;
+	int used_count = 0;
+	char tmpbuf[128];
+	COM_PM *pm = &hw->ctx.dpm;
+	int pm_count = 0, pm_ref_count = 0;
+	for (i = 0; i < hw->max_pb_size; i++) {
+		pic = &hw->pic_pool[i];
+		if (pic->buf_cfg.used)
+		used_count++;
+	}
+
+	for (i = 0; i < pm->max_pb_size; i++)
+	{
+		if (pm->pic[i] != NULL) {
+			pm_ref_count++;
+		} else {
+			break;
+		}
+	}
+
+	for (i = 0; i < pm->max_pb_size; i++)
+	{
+		if (pm->pic[i] != NULL) {
+			pm_count++;
+		}
+	}
+
+	printk("%s----pic_pool (used %d, total %d) cur_num_ref_pics %d pm count %d, pm_ref_count %d diff %d\n", mark, used_count, hw->max_pb_size,
+		hw->ctx.dpm.cur_num_ref_pics, pm_count, pm_ref_count,  used_count - pm_count);
+
+	for (i = 0; i < hw->max_pb_size; i++) {
+		pic = &hw->pic_pool[i];
+		if (pic->buf_cfg.used) {
+#ifdef NEW_FRONT_BACK_CODE
+		int pos = 0, j;
+		pos += sprintf(&tmpbuf[pos], "(");
+		for (j = 0; j < pic->buf_cfg.list0_num_refp; j++)
+			pos += sprintf(&tmpbuf[pos], "%d ", pic->buf_cfg.list0_index[j]);
+		pos += sprintf(&tmpbuf[pos], ")");
+		pos += sprintf(&tmpbuf[pos], "(");
+		for (j = 0; j < pic->buf_cfg.list1_num_refp; j++)
+			pos += sprintf(&tmpbuf[pos], "%d ", pic->buf_cfg.list1_index[j]);
+		pos += sprintf(&tmpbuf[pos], ")");
+#else
+		tmpbuf[0] = 0;
+#endif
+		printk("%d (%p): buf_cfg index %d depth %d dtr %d ptr %d is_ref %d need_for_out %d, backend_ref %d, vf_ref %d, output_delay %d, w/h(%d,%d) id %d slicetype %d error_mark %d ref index:%s in_dpb %d time %lld\n",
+			i, pic, pic->buf_cfg.index, pic->buf_cfg.depth,
+			pic->dtr, pic->ptr, pic->is_ref,
+			pic->need_for_out,
+			pic->buf_cfg.backend_ref, pic->buf_cfg.vf_ref,
+			pic->picture_output_delay,
+			pic->width_luma, pic->height_luma, pic->temporal_id,
+			pic->buf_cfg.slice_type,
+			pic->buf_cfg.error_mark,
+			tmpbuf,
+			pic->buf_cfg.in_dpb,
+			pic->buf_cfg.time
+			);
+		}
+	}
+
+	for (i = 0; i < pm->max_pb_size; i++)
+	{
+		if (pm->pic[i] != NULL) {
+			printk("pm pic %p index %d\n", pm->pic[i], i);
+		}
+	}
+}
\ No newline at end of file
diff --git a/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c b/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c
new file mode 100644
index 0000000..13539e5
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_fb_hw.c
@@ -0,0 +1,3233 @@
+#include "../../../include/regs/dos_registers.h"
+#include "../../../common/media_utils/media_utils.h"
+
+#ifdef FOR_S5
+ulong dos_reg_compat_convert(ulong adr);
+#endif
+
+/* to do */
+#define DOUBLE_WRITE_VH0_TEMP    0
+#define DOUBLE_WRITE_VH1_TEMP    0
+#define DOUBLE_WRITE_VH0_HALF    0
+#define DOUBLE_WRITE_VH1_HALF    0
+//#define DOS_BASE_ADR  0xd0050000
+#if 0
+//#define HEVC_SAO_MMU_VH0_ADDR_DBE1 0
+//#define HEVC_SAO_MMU_VH1_ADDR_DBE1 0
+#define HEVCD_MPP_DECOMP_AXIURG_CTL 0
+
+#define HEVC_MPRED_POC24_CTRL0 0
+#define HEVC_MPRED_POC24_CTRL1 0
+
+#define HEVCD_MCRCC_PERFMON_CTL_DBE1 0
+#define HEVCD_MCRCC_PERFMON_DATA_DBE1 0
+#define HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1 0
+#define HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1 0
+#endif
+//#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
+//#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+/**/
+#define DOS_BASE_ADR  0x0
+
+#define print_scratch_error(a)
+//#define MEM_MAP_MODE    0
+
+//typedef union param_u param_t;
+
+#define PRINT_HEVC_DATA_PATH_MONITOR
+//static   unsigned   mcrcc_hit_rate;
+static   unsigned   mcrcc_hit_rate_0;
+static   unsigned   mcrcc_hit_rate_1;
+//static   unsigned   mcrcc_bypass_rate;
+static   unsigned   mcrcc_bypass_rate_0;
+static   unsigned   mcrcc_bypass_rate_1;
+
+static void init_pic_list_hw_fb(struct AVS3Decoder_s *dec);
+
+static void C_Reg_Rd(unsigned adr, unsigned *pval)
+{
+	*pval = READ_VREG(adr);
+}
+
+static void    mcrcc_perfcount_reset_dual(struct AVS3Decoder_s *dec)
+{
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[cache_util.c] Entered mcrcc_perfcount_reset_dual...\n");
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x1);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)0x0);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)0x1);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)0x0);
+	return;
+}
+
+static void    mcrcc_get_hitrate_dual(int pic_num)
+{
+	unsigned   tmp;
+	unsigned   raw_mcr_cnt;
+	unsigned   hit_mcr_cnt;
+	unsigned   byp_mcr_cnt_nchoutwin;
+	unsigned   byp_mcr_cnt_nchcanv;
+	unsigned   hit_mcr_0_cnt;
+	unsigned   hit_mcr_1_cnt;
+	unsigned   hitrate;
+	printk("[cache_util.c] Entered mcrcc_get_hitrate_dual...\n");
+
+	printk("[MCRCC CORE ] Picture : %d\n",pic_num);
+
+	// CORE 0
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x0<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x1<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x2<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchoutwin);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x3<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &byp_mcr_cnt_nchcanv);
+
+	printk("[MCRCC CORE0] raw_mcr_cnt: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE0] hit_mcr_cnt: %d\n",hit_mcr_cnt);
+	printk("[MCRCC CORE0] byp_mcr_cnt_nchoutwin: %d\n",byp_mcr_cnt_nchoutwin);
+	printk("[MCRCC CORE0] byp_mcr_cnt_nchcanv: %d\n",byp_mcr_cnt_nchcanv);
+
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x4<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
+	printk("[MCRCC CORE0] miss_mcr_0_cnt: %d\n",tmp);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x5<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &tmp);
+	printk("[MCRCC CORE0] miss_mcr_1_cnt: %d\n",tmp);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x6<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_0_cnt);
+	printk("[MCRCC CORE0] hit_mcr_0_cnt: %d\n",hit_mcr_0_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL, (unsigned int)(0x7<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA, &hit_mcr_1_cnt);
+	printk("[MCRCC CORE0] hit_mcr_1_cnt: %d\n",hit_mcr_1_cnt);
+
+	if ( raw_mcr_cnt != 0 ) {
+		hitrate = (hit_mcr_0_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE0] CANV0_HIT_RATE : %d\n", hitrate);
+		hitrate = (hit_mcr_1_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE0] CANV1_HIT_RATE : %d\n", hitrate);
+		hitrate = (byp_mcr_cnt_nchcanv *100 / raw_mcr_cnt);
+		printk("[MCRCC CORE0] NONCACH_CANV_BYP_RATE : %d\n", hitrate);
+		hitrate = (byp_mcr_cnt_nchoutwin *100 / raw_mcr_cnt);
+		printk("[MCRCC CORE0] CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
+	}
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+		printk("[P%d MCRCC CORE0] MCRCC_HIT_RATE : %d\n", pic_num, hitrate);
+		hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 / raw_mcr_cnt);
+		printk("[P%d MCRCC CORE0] MCRCC_BYP_RATE : %d\n", pic_num, hitrate);
+	} else
+	{
+		printk("[P%d MCRCC CORE0] MCRCC_HIT_RATE : na\n", pic_num);
+		printk("[P%d MCRCC CORE0] MCRCC_BYP_RATE : na\n", pic_num);
+	}
+
+	mcrcc_hit_rate_0 = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+	mcrcc_bypass_rate_0 = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+
+	// CORE 0
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x0<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x1<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x2<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &byp_mcr_cnt_nchoutwin);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x3<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &byp_mcr_cnt_nchcanv);
+
+	printk("[MCRCC CORE1] raw_mcr_cnt: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE1] hit_mcr_cnt: %d\n",hit_mcr_cnt);
+	printk("[MCRCC CORE1] byp_mcr_cnt_nchoutwin: %d\n",byp_mcr_cnt_nchoutwin);
+	printk("[MCRCC CORE1] byp_mcr_cnt_nchcanv: %d\n",byp_mcr_cnt_nchcanv);
+
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x4<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &tmp);
+	printk("[MCRCC CORE1] miss_mcr_0_cnt: %d\n",tmp);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x5<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &tmp);
+	printk("[MCRCC CORE1] miss_mcr_1_cnt: %d\n",tmp);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x6<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_0_cnt);
+	printk("[MCRCC CORE1] hit_mcr_0_cnt: %d\n",hit_mcr_0_cnt);
+	WRITE_VREG(HEVCD_MCRCC_PERFMON_CTL_DBE1, (unsigned int)(0x7<<1));
+	C_Reg_Rd(HEVCD_MCRCC_PERFMON_DATA_DBE1, &hit_mcr_1_cnt);
+	printk("[MCRCC CORE1] hit_mcr_1_cnt: %d\n",hit_mcr_1_cnt);
+
+	if ( raw_mcr_cnt != 0 ) {
+		hitrate = (hit_mcr_0_cnt * 100 /raw_mcr_cnt);
+		printk("[MCRCC CORE1] CANV0_HIT_RATE : %d\n", hitrate);
+		hitrate = (hit_mcr_1_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE1] CANV1_HIT_RATE : %d\n", hitrate);
+		hitrate = (byp_mcr_cnt_nchcanv * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE1] NONCACH_CANV_BYP_RATE : %d\n", hitrate);
+		hitrate = (byp_mcr_cnt_nchoutwin * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE1] CACHE_OUTWIN_BYP_RATE : %d\n", hitrate);
+	}
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+		printk("[P%d MCRCC CORE1] MCRCC_HIT_RATE : %d\n", pic_num, hitrate);
+		hitrate = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+		printk("[P%d MCRCC CORE1] MCRCC_BYP_RATE : %d\n", pic_num, hitrate);
+	} else
+	{
+		printk("[P%d MCRCC CORE1] MCRCC_HIT_RATE : na\n", pic_num);
+		printk("[P%d MCRCC CORE1] MCRCC_BYP_RATE : na\n", pic_num);
+	}
+
+	mcrcc_hit_rate_1 = (hit_mcr_cnt * 100 /raw_mcr_cnt);
+	mcrcc_bypass_rate_1 = ((byp_mcr_cnt_nchoutwin + byp_mcr_cnt_nchcanv) * 100 /raw_mcr_cnt);
+
+	return;
+}
+
+static void    decomp_perfcount_reset_dual(struct AVS3Decoder_s *dec)
+{
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[cache_util.c] Entered decomp_perfcount_reset_dual...\n");
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x1);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)0x0);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)0x1);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)0x0);
+	return;
+}
+
+static void    decomp_get_hitrate_dual(int pic_num)
+{
+	unsigned   raw_mcr_cnt;
+	unsigned   hit_mcr_cnt;
+	unsigned      hitrate;
+	printk("[cache_util.c] Entered decomp_get_hitrate_dual...\n");
+
+	// CORE0
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x0<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x1<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
+
+	printk("[MCRCC CORE0] hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE0] hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 /raw_mcr_cnt);
+		printk("[MCRCC CORE0] DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+	} else
+	{
+		printk("[MCRCC CORE0] DECOMP_HCACHE_HIT_RATE : na\n");
+	}
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x2<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x3<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &hit_mcr_cnt);
+
+	printk("[MCRCC CORE0] dcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE0] dcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE0] DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+
+		hitrate = (mcrcc_hit_rate_0 + (mcrcc_bypass_rate_0 * hit_mcr_cnt / raw_mcr_cnt ));
+		printk("[MCRCC CORE0] MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate);
+
+	} else
+	{
+		printk("[MCRCC CORE0] DECOMP_DCACHE_HIT_RATE : na\n");
+	}
+
+	// CORE1
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x0<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x1<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+
+	printk("[MCRCC CORE1] hcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE1] hcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE1] DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+	} else
+	{
+		printk("[MCRCC CORE1] DECOMP_HCACHE_HIT_RATE : na\n");
+	}
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x2<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_mcr_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x3<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &hit_mcr_cnt);
+
+	printk("[MCRCC CORE1] dcache_raw_cnt_total: %d\n",raw_mcr_cnt);
+	printk("[MCRCC CORE1] dcache_hit_cnt_total: %d\n",hit_mcr_cnt);
+
+	if ( raw_mcr_cnt != 0 )
+	{
+		hitrate = (hit_mcr_cnt * 100 / raw_mcr_cnt);
+		printk("[MCRCC CORE1] DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+
+		hitrate = (mcrcc_hit_rate_1 + (mcrcc_bypass_rate_1 * hit_mcr_cnt / raw_mcr_cnt));
+		printk("[MCRCC CORE1] MCRCC_DECOMP_DCACHE_EFFECTIVE_HIT_RATE : %d\n", hitrate);
+
+	} else
+	{
+		printk("[MCRCC CORE1] DECOMP_DCACHE_HIT_RATE : na\n");
+	}
+
+	return;
+}
+
+static void    decomp_get_comprate_dual(int pic_num)
+{
+	unsigned   raw_ucomp_cnt;
+	unsigned   fast_comp_cnt;
+	unsigned   slow_comp_cnt;
+	unsigned      comprate;
+
+	printk("[cache_util.c] Entered decomp_get_comprate_dual...\n");
+
+	// CORE0
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x4<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &fast_comp_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x5<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &slow_comp_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL, (unsigned int)(0x6<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA, &raw_ucomp_cnt);
+
+	printk("[MCRCC CORE0] decomp_fast_comp_total: %d\n",fast_comp_cnt);
+	printk("[MCRCC CORE0] decomp_slow_comp_total: %d\n",slow_comp_cnt);
+	printk("[MCRCC CORE0] 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);
+		printk("[MCRCC CORE0] DECOMP_COMP_RATIO : %d\n", comprate);
+	} else
+	{
+		printk("[MCRCC CORE0] DECOMP_COMP_RATIO : na\n");
+	}
+
+	// CORE1
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x4<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &fast_comp_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x5<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &slow_comp_cnt);
+	WRITE_VREG(HEVCD_MPP_DECOMP_PERFMON_CTL_DBE1, (unsigned int)(0x6<<1));
+	C_Reg_Rd(HEVCD_MPP_DECOMP_PERFMON_DATA_DBE1, &raw_ucomp_cnt);
+
+	printk("[MCRCC CORE1] decomp_fast_comp_total: %d\n",fast_comp_cnt);
+	printk("[MCRCC CORE1] decomp_slow_comp_total: %d\n",slow_comp_cnt);
+	printk("[MCRCC CORE1] 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);
+		printk("[MCRCC CORE1] DECOMP_COMP_RATIO : %d\n", comprate);
+	} else
+	{
+		printk("[MCRCC CORE1] DECOMP_COMP_RATIO : na\n");
+	}
+
+	return;
+}
+
+static void print_mcrcc_hit_info(int pic_num) {
+	//printk("before call mcrcc_get_hitrate\r\n");
+	mcrcc_get_hitrate_dual(pic_num);
+	decomp_get_hitrate_dual(pic_num);
+	decomp_get_comprate_dual(pic_num);
+}
+
+static void WRITE_BACK_RET(struct avs3_decoder *avs3_dec)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0xcc00000;   //ret
+	avs3_print(dec, AVS3_DBG_REG,
+		"WRITE_BACK_RET()\ninstruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0;           //nop
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+}
+
+static void WRITE_BACK_8(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint8_t data)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x20<<22) | ((spr_addr&0xfff)<<8) | (data&0xff);   //mtspi data, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data,
+		avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void WRITE_BACK_16(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint8_t rd_addr, uint16_t data)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6) | (rd_addr&0x3f);       // movi rd_addr, data[15:0]
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x,%x)\ninstruction[%3d] = %8x, data= %x\n",
+		__func__, spr_addr, rd_addr, data,
+		avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset], data&0xffff);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f);  // mtsp rd_addr, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void WRITE_BACK_32(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint32_t data)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((data&0xffff)<<6);   // movi COMMON_REG_0, data
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data,
+		avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	data = (data & 0xffff0000)>>16;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1b<<22) | (data<<6);                // mvihi COMMON_REG_0, data[31:16]
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8);    // mtsp COMMON_REG_0, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void READ_INS_WRITE(struct avs3_decoder *avs3_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t position, uint8_t size)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+	//spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+	spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x,%x,%x,%x)\n",
+		__func__, spr_addr0, spr_addr1, rd_addr, position, size);
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f);    //mtsp rd_addr, src_addr1
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+//Caution:  pc offset fixed to 4, the data of cmp_addr need ready before call this function
+void READ_CMP_WRITE(struct avs3_decoder *avs3_dec, uint32_t spr_addr0, uint32_t spr_addr1, uint8_t rd_addr, uint8_t cmp_addr, uint8_t position, uint8_t size)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr0 = ((spr_addr0 - DOS_BASE_ADR) >> 0) & 0xfff;
+	//spr_addr1 = ((spr_addr1 - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr0 = (dos_reg_compat_convert(spr_addr0) & 0xfff);
+	spr_addr1 = (dos_reg_compat_convert(spr_addr1) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x,%x,%x,%x,%x)\n",
+		__func__, spr_addr0, spr_addr1, rd_addr, cmp_addr, position, size);
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+		avs3_dec->instruction[avs3_dec->ins_offset] = (0x29<<22) | (4<<12) | ((rd_addr&0x3f)<<6) | cmp_addr;     //cbne current_pc+4, rd_addr, cmp_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+		avs3_dec->instruction[avs3_dec->ins_offset] = 0;                                                       //nop
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr0&0xfff)<<8) | (rd_addr&0x3f);    //mfsp rd_addr, src_addr0
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | ((rd_addr&0x3f)<<6) | (rd_addr&0x3f);   //ins rd_addr, rd_addr, position, size
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr1&0xfff)<<8) | (rd_addr&0x3f);    //mtsp rd_addr, src_addr1
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+static void READ_WRITE_DATA16(struct avs3_decoder *avs3_dec, uint32_t spr_addr, uint16_t data, uint8_t position, uint8_t size)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	//spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	spr_addr = (dos_reg_compat_convert(spr_addr) & 0xfff);
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8);    //mfsp COMON_REG_0, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"%s(%x,%x,%x,%x)\ninstruction[%3d] = %8x\n",
+		__func__, spr_addr, data, position, size,
+		avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | (data<<6) | 1;        //movi COMMON_REG_1, data
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x25<<22) | ((position&0x1f)<<17) | ((size&0x1f)<<12) | (0<<6) | 1;  //ins COMMON_REG_0, COMMON_REG_1, position, size
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x18<<22) | ((spr_addr&0xfff)<<8);    //mtsp COMMON_REG_0, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+	if (avs3_dec->ins_offset < 256 && (avs3_dec->ins_offset+16) >= 256) {
+		WRITE_BACK_RET(avs3_dec);
+		avs3_dec->ins_offset = 256;
+	}
+#endif
+}
+
+#if 0
+void READ_BACK_32(struct AVS3Decoder_s *dec, uint32_t spr_addr, uint8_t rd_addr)
+{
+	struct AVS3Decoder_s *dec = container_of(avs3_dec,
+		struct AVS3Decoder_s, avs3_dec);
+	spr_addr = ((spr_addr - DOS_BASE_ADR) >> 0) & 0xfff;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x19<<22) | ((spr_addr&0xfff)<<8) | (rd_addr&0x3f);  //mfsp rd_addr, spr_addr
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+}
+#endif
+
+static int32_t config_mc_buffer_fb(struct AVS3Decoder_s *dec)
+{
+	int32_t i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	//avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+	avs3_frame_t *pic;
+	//uint32_t rdata32;
+	//uint32_t rdata32_2;
+	//if (avs3_dec->img.type == I_IMG)
+	//    return 0;
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"Entered config_mc_buffer....\n");
+	if (avs3_dec->f_bg != NULL) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+		avs3_dec->f_bg->mc_canvas_y, avs3_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_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (15 << 8) | (0<<1) | 1);   // L0:BG
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		///    (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+		WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		(avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_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_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (31 << 8) | (0<<1) | 1);  // L1:BG
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		///    (avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+		WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		(avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+	}
+	if (avs3_dec->slice_type == SLICE_I)
+		return 0;
+	if (avs3_dec->slice_type == SLICE_P || avs3_dec->slice_type == SLICE_B) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"config_mc_buffer for REF_0, img type %d\n", avs3_dec->slice_type);
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+		WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_0]; i++) {
+		pic = &avs3_dec->ctx.refp[i][REFP_0].pic->buf_cfg;
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		///    (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+		WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+				(pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"L0 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+		}
+	}
+	if (avs3_dec->slice_type == SLICE_B) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"config_mc_buffer for REF_1\n");
+
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+		WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 0, (16 << 8) | (0<<1) | 1);
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+		pic = &avs3_dec->ctx.refp[i][REFP_1].pic->buf_cfg;
+		///WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+		///    (pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+		WRITE_BACK_32(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR,
+				(pic->mc_canvas_u_v<<16)|(pic->mc_canvas_u_v<<8)|pic->mc_canvas_y);
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"L1 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+		}
+	}
+	return 0;
+}
+
+#ifdef NEW_FRONT_BACK_CODE
+/*copy from simulation code*/
+
+#define FB_LMEM_SIZE_LOG2           6
+#define FB_LMEM_SIZE             (1 << FB_LMEM_SIZE_LOG2)
+#define FB_VCPU_IMEM_SIZE         0x400
+#define FB_SYSTEM_IMEM_SIZE       0x400
+#define FB_SCALELUT_LMEM_SIZE     0x400
+
+#if 0
+#define FB_PARSER_SAO0_BLOCK_SIZE       (4*1024*4)*64
+#define FB_PARSER_SAO1_BLOCK_SIZE       (4*1024*4)*64
+#define FB_MPRED_IMP0_BLOCK_SIZE        (4*1024*4)*256
+#define FB_MPRED_IMP1_BLOCK_SIZE        (4*1024*4)*256
+#else
+#define FB_PARSER_SAO0_BLOCK_SIZE       (4*1024*4)
+#define FB_PARSER_SAO1_BLOCK_SIZE       (4*1024*4)
+#define FB_MPRED_IMP0_BLOCK_SIZE        (4*1024*4)
+#define FB_MPRED_IMP1_BLOCK_SIZE        (4*1024*4)
+#endif
+/**/
+#define BUF_BLOCK_NUM 256
+
+#define FB_IFBUF_SCALELUT_BLOCK_SIZE       FB_SCALELUT_LMEM_SIZE
+#define FB_IFBUF_VCPU_IMEM_BLOCK_SIZE FB_VCPU_IMEM_SIZE
+#define FB_IFBUF_SYS_IMEM_BLOCK_SIZE FB_SYSTEM_IMEM_SIZE
+#define FB_IFBUF_LMEM0_BLOCK_SIZE   FB_LMEM_SIZE
+#define FB_IFBUF_LMEM1_BLOCK_SIZE   FB_LMEM_SIZE
+
+#define IFBUF_SCALELUT_SIZE                  (FB_IFBUF_SCALELUT_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_VCPU_IMEM_SIZE        (FB_IFBUF_VCPU_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_SYS_IMEM_SIZE        (FB_IFBUF_SYS_IMEM_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM0_SIZE                  (FB_IFBUF_LMEM0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_LMEM1_SIZE                  (FB_IFBUF_LMEM1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO0_SIZE      (FB_PARSER_SAO0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_PARSER_SAO1_SIZE      (FB_PARSER_SAO1_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP0_SIZE      (FB_MPRED_IMP0_BLOCK_SIZE * BUF_BLOCK_NUM)
+#define IFBUF_MPRED_IMP1_SIZE      (FB_MPRED_IMP1_BLOCK_SIZE * BUF_BLOCK_NUM)
+
+static void copy_loopbufs_ptr(buff_ptr_t* trg, buff_ptr_t* src)
+{
+	trg->mmu0_ptr = src->mmu0_ptr;
+	trg->mmu1_ptr = src->mmu1_ptr;
+	trg->scalelut_ptr = src->scalelut_ptr;
+	trg->vcpu_imem_ptr = src->vcpu_imem_ptr;
+	trg->sys_imem_ptr = src->sys_imem_ptr;
+	trg->sys_imem_ptr_v = src->sys_imem_ptr_v;
+	trg->lmem0_ptr = src->lmem0_ptr;
+	trg->lmem1_ptr = src->lmem1_ptr;
+	trg->parser_sao0_ptr = src->parser_sao0_ptr;
+	trg->parser_sao1_ptr = src->parser_sao1_ptr;
+	trg->mpred_imp0_ptr = src->mpred_imp0_ptr;
+	trg->mpred_imp1_ptr = src->mpred_imp1_ptr;
+	//
+	trg->scalelut_ptr_pre = src->scalelut_ptr_pre;
+}
+
+static void print_loopbufs_ptr(struct AVS3Decoder_s *dec, char* mark, buff_ptr_t* ptr)
+{
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "==%s==:\n", mark);
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"mmu0_ptr %x, mmu1_ptr %x\nscalelut_ptr %x pre_ptr %x\nvcpu_imem_ptr %x\nsys_imem_ptr %x (vir 0x%x: %02x %02x %02x %02x)\nlmem0_ptr %x, lmem1_ptr %x\nparser_sao0_ptr %x, parser_sao1_ptr %x\nmpred_imp0_ptr %x, mpred_imp1_ptr %x\n",
+		ptr->mmu0_ptr,
+		ptr->mmu1_ptr,
+		ptr->scalelut_ptr,
+		ptr->scalelut_ptr_pre,
+		ptr->vcpu_imem_ptr,
+		ptr->sys_imem_ptr,
+		ptr->sys_imem_ptr_v,
+		((u8 *)(ptr->sys_imem_ptr_v))[0], ((u8 *)(ptr->sys_imem_ptr_v))[1],
+		((u8 *)(ptr->sys_imem_ptr_v))[2], ((u8 *)(ptr->sys_imem_ptr_v))[3],
+		ptr->lmem0_ptr,
+		ptr->lmem1_ptr,
+		ptr->parser_sao0_ptr,
+		ptr->parser_sao1_ptr,
+		ptr->mpred_imp0_ptr,
+		ptr->mpred_imp1_ptr);
+}
+
+static void print_loopbufs_ptr2(struct AVS3Decoder_s *dec, char* mark, buff_ptr_t* p_ptr, buff_ptr_t* ptr)
+{
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "==%s==:\n", mark);
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"mmu0_ptr (%x=>%x%s) mmu1_ptr (%x=>%x%s)\nscalelut_ptr (%x=>%x%s) pre_ptr (%x=>%x%s)\nvcpu_imem_ptr (%x=>%x%s)\nsys_imem_ptr (%x=>%x%s) (vir 0x%x: %02x %02x %02x %02x)\nlmem0_ptr (%x=>%x%s), lmem1_ptr (%x=>%x%s)\nparser_sao0_ptr (%x=>%x%s), parser_sao1_ptr (%x=>%x%s)\nmpred_imp0_ptr (%x=>%x%s), mpred_imp1_ptr (%x=>%x%s)\n",
+		p_ptr->mmu0_ptr, ptr->mmu0_ptr, (ptr->mmu0_ptr<p_ptr->mmu0_ptr)?" wrap":"",
+		p_ptr->mmu1_ptr, ptr->mmu1_ptr, (ptr->mmu1_ptr<p_ptr->mmu1_ptr)?" wrap":"",
+		p_ptr->scalelut_ptr, ptr->scalelut_ptr, (ptr->scalelut_ptr<p_ptr->scalelut_ptr)?" wrap":"",
+		p_ptr->scalelut_ptr_pre, ptr->scalelut_ptr_pre, (ptr->scalelut_ptr_pre<p_ptr->scalelut_ptr_pre)?" wrap":"",
+		p_ptr->vcpu_imem_ptr, ptr->vcpu_imem_ptr, (ptr->vcpu_imem_ptr<p_ptr->vcpu_imem_ptr)?" wrap":"",
+		p_ptr->sys_imem_ptr, ptr->sys_imem_ptr, (ptr->sys_imem_ptr<p_ptr->sys_imem_ptr)?" wrap":"",
+		p_ptr->sys_imem_ptr_v,
+		((u8 *)(ptr->sys_imem_ptr_v))[0], ((u8 *)(ptr->sys_imem_ptr_v))[1],
+		((u8 *)(ptr->sys_imem_ptr_v))[2], ((u8 *)(ptr->sys_imem_ptr_v))[3],
+		p_ptr->lmem0_ptr, ptr->lmem0_ptr, (ptr->lmem0_ptr<p_ptr->lmem0_ptr)?" wrap":"",
+		p_ptr->lmem1_ptr, ptr->lmem1_ptr, (ptr->lmem1_ptr<p_ptr->lmem1_ptr)?" wrap":"",
+		p_ptr->parser_sao0_ptr, ptr->parser_sao0_ptr, (ptr->parser_sao0_ptr<p_ptr->parser_sao0_ptr)?" wrap":"",
+		p_ptr->parser_sao1_ptr, ptr->parser_sao1_ptr, (ptr->parser_sao1_ptr<p_ptr->parser_sao1_ptr)?" wrap":"",
+		p_ptr->mpred_imp0_ptr, ptr->mpred_imp0_ptr, (ptr->mpred_imp0_ptr<p_ptr->mpred_imp0_ptr)?" wrap":"",
+		p_ptr->mpred_imp1_ptr, ptr->mpred_imp1_ptr, (ptr->mpred_imp1_ptr<p_ptr->mpred_imp1_ptr)?" wrap":"");
+}
+
+static void print_loopbufs_adr_size(struct AVS3Decoder_s *dec)
+{
+	int i;
+	uint32_t adr, size;
+	char *name[9] = {"parser_sao0", "parser_sao1", "mpred_imp0", "mpred_imp1", "scalelut", "lmem0", "lmem1", "vcpu_imem", "sys_imem"};
+
+	avs3_print_cont(dec, 0, "loopbuf memory:\n");
+	for (i=0; i<9; i++) {
+		WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+		adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+		size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+		avs3_print_cont(dec, 0, "%s start 0x%x size 0x%x\n", name[i], adr, size);
+	}
+	avs3_print_flush(dec);
+}
+
+static u32 dump_fb_mmu_buffer(struct AVS3Decoder_s *dec, void *mmu_map_adr, u32 mmu_map_size, u8 *file)
+{
+	int i;
+	u8 *adr = (u8 *)mmu_map_adr;
+	u32 page_phy_adr;
+	loff_t off = 0;
+	int mode = O_CREAT | O_WRONLY | O_TRUNC;
+	struct file *fp = NULL;
+
+	u32 total_check_sum = 0;
+	if (file) {
+		fp = media_open(file, mode, 0666);
+	}
+
+	for (i = 0; i < mmu_map_size; i += 4) {
+		page_phy_adr = (adr[i] | (adr[i+1]<<8) | (adr[i+2]<<16) | (adr[i+3]<<24)) << 12;
+		if (page_phy_adr)
+		d_dump(dec, page_phy_adr, 1024*4, fp, &off, &total_check_sum, 0);
+		else
+		avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "!!%s mmu_map 0x%p, page count %d, page %d is zero\n",
+			__func__, mmu_map_adr, mmu_map_size/4, i/4);
+	}
+	if (fp) {
+		media_close(fp, current->files);
+	}
+	return total_check_sum;
+}
+
+static void fb_mmu_buffer_fill_zero(struct AVS3Decoder_s *dec, void *mmu_map_adr, u32 mmu_map_size)
+{
+	int i;
+	u32 page_phy_adr;
+	u8 *adr = (u8 *)mmu_map_adr;
+	for (i = 0; i < mmu_map_size; i += 4) {
+		page_phy_adr = (adr[i] | (adr[i+1]<<8) | (adr[i+2]<<16) | (adr[i+3]<<24)) << 12;
+		if (page_phy_adr)
+		d_dump(dec, page_phy_adr, 1024*4, NULL, NULL, NULL, 0);
+		else
+		avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "!!%s mmu_map 0x%p, page count %d, page %d is zero\n",
+			__func__, mmu_map_adr, mmu_map_size/4, i/4);
+	}
+}
+
+static void dump_loop_buffer(struct AVS3Decoder_s *dec, int count, u8 save_file)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int i;
+	u32 total_check_sum;
+	uint32_t adr, size;
+	char *name[9] = {"parser_sao0", "parser_sao1", "mpred_imp0", "mpred_imp1", "scalelut", "lmem0", "lmem1", "vcpu_imem", "sys_imem"};
+	char file[64];
+	char mark[16];
+	for (i=0; i<9; i++) {
+		WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+		adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+		size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+		if (save_file) {
+		if (count >= 0)
+			sprintf(&file[0], "/data/tmp/%s_%d", name[i], count);
+		else
+			sprintf(&file[0], "/data/tmp/%s", name[i]);
+		}
+		sprintf(&mark[0], "%s %d", name[i], count);
+		dump_or_fill_phy_buffer(dec, adr, size, save_file?file:NULL, 0, mark);
+	}
+	//dump mmu0
+	if (save_file) {
+		if (count >= 0)
+		sprintf(&file[0], "/data/tmp/%s_%d", "mmu0", count);
+		else
+		sprintf(&file[0], "/data/tmp/%s", "mmu0");
+	}
+	total_check_sum = dump_fb_mmu_buffer(dec, dec->fb_buf_mmu0_addr, avs3_dec->fb_buf_mmu0.buf_size, save_file?file:NULL);
+	avs3_print(dec, 0, "dump mmu0 %d (pages 0x%x) check_sum %x %s\n", count, avs3_dec->fb_buf_mmu0.buf_size/4, total_check_sum, save_file? file:"");
+
+	//dump mmu1
+	if (save_file) {
+		if (count >= 0)
+		sprintf(&file[0], "/data/tmp/%s_%d", "mmu1", count);
+		else
+		sprintf(&file[0], "/data/tmp/%s", "mmu1");
+	}
+	total_check_sum = dump_fb_mmu_buffer(dec, dec->fb_buf_mmu1_addr, avs3_dec->fb_buf_mmu1.buf_size, save_file?file:NULL);
+	avs3_print(dec, 0, "dump mmu1 %d (pages 0x%x) check_sum %x %s\n", count, avs3_dec->fb_buf_mmu1.buf_size/4, total_check_sum, save_file? file:"");
+
+	//dump bufspec
+	if (save_file) {
+		if (count >= 0)
+		sprintf(&file[0], "/data/tmp/%s_%d", "bufspec", count);
+		else
+		sprintf(&file[0], "/data/tmp/%s", "bufspec");
+	}
+	sprintf(&mark[0], "%s %d", "bufspec", count);
+	dump_or_fill_phy_buffer(dec, dec->buf_start, dec->buf_size, save_file?file:NULL, 0, mark);
+}
+
+static void loop_buffer_fill_zero(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int i;
+	uint32_t adr, size;
+	for (i=0; i<9; i++) {
+		WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, i);
+		adr = READ_VREG(HEVC_ASSIST_RING_F_START);
+		size = READ_VREG(HEVC_ASSIST_RING_F_END) - adr;
+		dump_or_fill_phy_buffer(dec, adr, size, NULL, 1, NULL);
+	}
+	fb_mmu_buffer_fill_zero(dec, dec->fb_buf_mmu0_addr, avs3_dec->fb_buf_mmu0.buf_size);
+	fb_mmu_buffer_fill_zero(dec, dec->fb_buf_mmu1_addr, avs3_dec->fb_buf_mmu1.buf_size);
+
+	dump_or_fill_phy_buffer(dec, dec->buf_start, dec->buf_size, NULL, 1, NULL);
+}
+
+static int init_mmu_fb_bufstate(struct AVS3Decoder_s *dec, int mmu_fb_4k_number)
+{
+	int ret;
+	dma_addr_t tmp_phy_adr;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int mmu_map_size = ((mmu_fb_4k_number * 4) >> 6) << 6;
+	int tvp_flag = vdec_secure(hw_to_vdec(dec)) ? CODEC_MM_FLAGS_TVP : 0;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR,
+		"%s mmu_fb_4k_number = %d\n", __func__, mmu_fb_4k_number);
+
+	if (mmu_fb_4k_number < 0)
+		return -1;
+
+	dec->mmu_box_fb = decoder_mmu_box_alloc_box(DRIVER_NAME,
+		dec->index, 2,
+		(mmu_fb_4k_number << 12) * 2,
+		tvp_flag
+		);
+
+	dec->fb_buf_mmu0_addr =
+		dma_alloc_coherent(amports_get_dma_device(),
+		mmu_map_size,
+		&tmp_phy_adr, GFP_KERNEL);
+	avs3_dec->fb_buf_mmu0.buf_start = tmp_phy_adr;
+	if (dec->fb_buf_mmu0_addr == NULL) {
+		pr_err("%s: failed to alloc fb_mmu0_map\n", __func__);
+		return -1;
+	}
+	memset(dec->fb_buf_mmu0_addr, 0, mmu_map_size);
+	avs3_dec->fb_buf_mmu0.buf_size = mmu_map_size;
+	avs3_dec->fb_buf_mmu0.buf_end = avs3_dec->fb_buf_mmu0.buf_start + mmu_map_size;
+
+	dec->fb_buf_mmu1_addr =
+		dma_alloc_coherent(amports_get_dma_device(),
+		mmu_map_size,
+		&tmp_phy_adr, GFP_KERNEL);
+	avs3_dec->fb_buf_mmu1.buf_start = tmp_phy_adr;
+	if (dec->fb_buf_mmu1_addr == NULL) {
+		pr_err("%s: failed to alloc fb_mmu1_map\n", __func__);
+		return -1;
+	}
+	memset(dec->fb_buf_mmu1_addr, 0, mmu_map_size);
+	avs3_dec->fb_buf_mmu1.buf_size = mmu_map_size;
+	avs3_dec->fb_buf_mmu1.buf_end = avs3_dec->fb_buf_mmu1.buf_start + mmu_map_size;
+
+	ret = decoder_mmu_box_alloc_idx(
+		dec->mmu_box_fb,
+		0,
+		mmu_fb_4k_number,
+		dec->fb_buf_mmu0_addr);
+	if (ret != 0) {
+		pr_err("%s: failed to alloc fb_mmu0 pages\n", __func__);
+		return -1;
+	}
+
+	ret = decoder_mmu_box_alloc_idx(
+		dec->mmu_box_fb,
+		1,
+		mmu_fb_4k_number,
+		dec->fb_buf_mmu1_addr);
+	if (ret != 0) {
+		pr_err("%s: failed to alloc fb_mmu1 pages\n", __func__);
+		return -1;
+	}
+
+	dec->mmu_fb_4k_number = mmu_fb_4k_number;
+	avs3_dec->fr.mmu0_ptr = avs3_dec->fb_buf_mmu0.buf_start;
+	avs3_dec->bk.mmu0_ptr = avs3_dec->fb_buf_mmu0.buf_start;
+	avs3_dec->fr.mmu1_ptr = avs3_dec->fb_buf_mmu1.buf_start;
+	avs3_dec->bk.mmu1_ptr = avs3_dec->fb_buf_mmu1.buf_start;
+
+	return 0;
+}
+
+static void init_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+/*simulation code: change to use linux APIs; also need write uninit_fb_bufstate()*/
+	int ret;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	dma_addr_t tmp_phy_adr;
+	unsigned long tmp_adr;
+	int mmu_4k_number = dec->fb_ifbuf_num * avs3_mmu_page_num(dec, dec->init_pic_w, dec->init_pic_h, 1);
+
+	ret = init_mmu_fb_bufstate(dec, mmu_4k_number);
+	if (ret < 0) {
+		avs3_print(dec, 0, "%s: failed to alloc mmu fb buffer\n", __func__);
+		return ;
+	}
+
+	avs3_dec->fb_buf_scalelut.buf_size = IFBUF_SCALELUT_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_SCALELUT_ID, avs3_dec->fb_buf_scalelut.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_scalelut.buf_start = tmp_adr;
+	avs3_dec->fb_buf_scalelut.buf_end = avs3_dec->fb_buf_scalelut.buf_start + avs3_dec->fb_buf_scalelut.buf_size;
+
+	avs3_dec->fb_buf_vcpu_imem.buf_size = IFBUF_VCPU_IMEM_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_VCPU_IMEM_ID, avs3_dec->fb_buf_vcpu_imem.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_vcpu_imem.buf_start = tmp_adr;
+	avs3_dec->fb_buf_vcpu_imem.buf_end = avs3_dec->fb_buf_vcpu_imem.buf_start + avs3_dec->fb_buf_vcpu_imem.buf_size;
+
+	avs3_dec->fb_buf_sys_imem.buf_size = IFBUF_SYS_IMEM_SIZE * dec->fb_ifbuf_num;
+	avs3_dec->fb_buf_sys_imem_addr = dma_alloc_coherent(amports_get_dma_device(),
+		avs3_dec->fb_buf_sys_imem.buf_size, &tmp_phy_adr, GFP_KERNEL);
+	avs3_dec->fb_buf_sys_imem.buf_start = tmp_phy_adr;
+	if (avs3_dec->fb_buf_sys_imem_addr == NULL) {
+		pr_err("%s: failed to alloc fb_buf_sys_imem\n", __func__);
+		return;
+	}
+	avs3_dec->fb_buf_sys_imem.buf_end = avs3_dec->fb_buf_sys_imem.buf_start + avs3_dec->fb_buf_sys_imem.buf_size;
+
+	avs3_dec->fb_buf_lmem0.buf_size = IFBUF_LMEM0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_LMEM0_ID, avs3_dec->fb_buf_lmem0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_lmem0.buf_start = tmp_adr;
+	avs3_dec->fb_buf_lmem0.buf_end = avs3_dec->fb_buf_lmem0.buf_start + avs3_dec->fb_buf_lmem0.buf_size;
+
+	avs3_dec->fb_buf_lmem1.buf_size = IFBUF_LMEM1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_LMEM1_ID, avs3_dec->fb_buf_lmem1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_lmem1.buf_start = tmp_adr;
+	avs3_dec->fb_buf_lmem1.buf_end = avs3_dec->fb_buf_lmem1.buf_start + avs3_dec->fb_buf_lmem1.buf_size;
+
+	avs3_dec->fb_buf_parser_sao0.buf_size = IFBUF_PARSER_SAO0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_PARSER_SAO0_ID, avs3_dec->fb_buf_parser_sao0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_parser_sao0.buf_start = tmp_adr;
+	avs3_dec->fb_buf_parser_sao0.buf_end = avs3_dec->fb_buf_parser_sao0.buf_start + avs3_dec->fb_buf_parser_sao0.buf_size;
+
+	avs3_dec->fb_buf_parser_sao1.buf_size = IFBUF_PARSER_SAO1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUF_PARSER_SAO1_ID, avs3_dec->fb_buf_parser_sao1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_parser_sao1.buf_start = tmp_adr;
+	avs3_dec->fb_buf_parser_sao1.buf_end = avs3_dec->fb_buf_parser_sao1.buf_start + avs3_dec->fb_buf_parser_sao1.buf_size;
+
+	avs3_dec->fb_buf_mpred_imp0.buf_size = IFBUF_MPRED_IMP0_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUFF_MPRED_IMP0_ID, avs3_dec->fb_buf_mpred_imp0.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_mpred_imp0.buf_start = tmp_adr;
+	avs3_dec->fb_buf_mpred_imp0.buf_end = avs3_dec->fb_buf_mpred_imp0.buf_start + avs3_dec->fb_buf_mpred_imp0.buf_size;
+
+	avs3_dec->fb_buf_mpred_imp1.buf_size = IFBUF_MPRED_IMP1_SIZE * dec->fb_ifbuf_num;
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+		BMMU_IFBUFF_MPRED_IMP1_ID, avs3_dec->fb_buf_mpred_imp1.buf_size,
+		DRIVER_NAME, &tmp_adr);
+	avs3_dec->fb_buf_mpred_imp1.buf_start = tmp_adr;
+	avs3_dec->fb_buf_mpred_imp1.buf_end = avs3_dec->fb_buf_mpred_imp1.buf_start + avs3_dec->fb_buf_mpred_imp1.buf_size;
+
+	avs3_dec->fr.scalelut_ptr = avs3_dec->fb_buf_scalelut.buf_start;
+	avs3_dec->bk.scalelut_ptr = avs3_dec->fb_buf_scalelut.buf_start;
+	avs3_dec->fr.vcpu_imem_ptr = avs3_dec->fb_buf_vcpu_imem.buf_start;
+	avs3_dec->bk.vcpu_imem_ptr = avs3_dec->fb_buf_vcpu_imem.buf_start;
+	avs3_dec->fr.sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+	avs3_dec->bk.sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+	avs3_dec->fr.lmem0_ptr = avs3_dec->fb_buf_lmem0.buf_start;
+	avs3_dec->bk.lmem0_ptr = avs3_dec->fb_buf_lmem0.buf_start;
+	avs3_dec->fr.lmem1_ptr = avs3_dec->fb_buf_lmem1.buf_start;
+	avs3_dec->bk.lmem1_ptr = avs3_dec->fb_buf_lmem1.buf_start;
+	avs3_dec->fr.parser_sao0_ptr = avs3_dec->fb_buf_parser_sao0.buf_start;
+	avs3_dec->bk.parser_sao0_ptr = avs3_dec->fb_buf_parser_sao0.buf_start;
+	avs3_dec->fr.parser_sao1_ptr = avs3_dec->fb_buf_parser_sao1.buf_start;
+	avs3_dec->bk.parser_sao1_ptr = avs3_dec->fb_buf_parser_sao1.buf_start;
+	avs3_dec->fr.mpred_imp0_ptr = avs3_dec->fb_buf_mpred_imp0.buf_start;
+	avs3_dec->bk.mpred_imp0_ptr = avs3_dec->fb_buf_mpred_imp0.buf_start;
+	avs3_dec->fr.mpred_imp1_ptr = avs3_dec->fb_buf_mpred_imp1.buf_start;
+	avs3_dec->bk.mpred_imp1_ptr = avs3_dec->fb_buf_mpred_imp1.buf_start;
+	if (fbdebug_flag & 0x4) {
+		avs3_dec->fr.scalelut_ptr_pre = avs3_dec->fr.scalelut_ptr;
+		avs3_dec->bk.scalelut_ptr_pre = avs3_dec->bk.scalelut_ptr;
+	} else {
+		avs3_dec->fr.scalelut_ptr_pre = 0;
+		avs3_dec->bk.scalelut_ptr_pre = 0;
+	}
+
+	avs3_dec->fr.sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr; //for linux
+
+	print_loopbufs_ptr(dec, "init", &avs3_dec->fr);
+}
+
+static void uninit_mmu_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+	if (dec->fb_buf_mmu0_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs3_dec->fb_buf_mmu0.buf_size, dec->fb_buf_mmu0_addr,
+			avs3_dec->fb_buf_mmu0.buf_start);
+		dec->fb_buf_mmu0_addr = NULL;
+	}
+	if (dec->fb_buf_mmu1_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs3_dec->fb_buf_mmu1.buf_size, dec->fb_buf_mmu1_addr,
+			avs3_dec->fb_buf_mmu1.buf_start);
+		dec->fb_buf_mmu1_addr = NULL;
+	}
+
+	if (dec->mmu_box_fb) {
+		decoder_mmu_box_free(dec->mmu_box_fb);
+		dec->mmu_box_fb = NULL;
+	}
+}
+
+static void uninit_fb_bufstate(struct AVS3Decoder_s *dec)
+{
+	int i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	for (i = 0; i < FB_LOOP_BUF_COUNT; i++) {
+		if (i != BMMU_IFBUF_SYS_IMEM_ID)
+		decoder_bmmu_box_free_idx(dec->bmmu_box, i);
+	}
+
+	if (avs3_dec->fb_buf_sys_imem_addr) {
+		dma_free_coherent(amports_get_dma_device(),
+			avs3_dec->fb_buf_sys_imem.buf_size, avs3_dec->fb_buf_sys_imem_addr,
+			avs3_dec->fb_buf_sys_imem.buf_start);
+		avs3_dec->fb_buf_sys_imem_addr = NULL;
+	}
+	uninit_mmu_fb_bufstate(dec);
+}
+
+static void config_bufstate_front_hw(struct avs3_decoder *avs3_dec)
+{
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_START, avs3_dec->fb_buf_mmu0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0_END, avs3_dec->fb_buf_mmu0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0, avs3_dec->fr.mmu0_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_START, avs3_dec->fb_buf_mmu1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1_END, avs3_dec->fb_buf_mmu1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1, avs3_dec->fr.mmu1_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_parser_sao0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_parser_sao0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_parser_sao1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_parser_sao1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//    config mpred_imp_if data write buffer start address
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_mpred_imp0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_mpred_imp0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_mpred_imp1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_mpred_imp1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+// config other buffers
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_scalelut.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_scalelut.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.scalelut_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.scalelut_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, avs3_dec->fr.scalelut_ptr_pre);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_vcpu_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_vcpu_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_sys_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_sys_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, 0);
+
+//config lmem buffers
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_lmem0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_lmem0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM0_BLOCK_SIZE);
+
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+	WRITE_VREG(HEVC_ASSIST_RING_F_START, avs3_dec->fb_buf_lmem1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_F_END, avs3_dec->fb_buf_lmem1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, avs3_dec->fr.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_RPTR, avs3_dec->bk.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_F_THRESHOLD, FB_IFBUF_LMEM1_BLOCK_SIZE);
+}
+
+static void config_bufstate_back_hw(struct avs3_decoder *avs3_dec)
+{
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_START, avs3_dec->fb_buf_mmu0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0_END, avs3_dec->fb_buf_mmu0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0, avs3_dec->bk.mmu0_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_START, avs3_dec->fb_buf_mmu1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1_END, avs3_dec->fb_buf_mmu1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1, avs3_dec->bk.mmu1_ptr);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_parser_sao0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_parser_sao0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.parser_sao0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 1);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_parser_sao1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_parser_sao1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.parser_sao1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+//    config mpred_imp_if data write buffer start address
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 2);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_mpred_imp0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_mpred_imp0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.mpred_imp0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 3);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_mpred_imp1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_mpred_imp1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.mpred_imp1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config other buffers
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 4);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_scalelut.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_scalelut.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.scalelut_ptr);
+	WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, avs3_dec->bk.scalelut_ptr_pre);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 7);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_vcpu_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_vcpu_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.vcpu_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 8);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_sys_imem.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_sys_imem.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.sys_imem_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+// config lmem buffers
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 5);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_lmem0.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_lmem0.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.lmem0_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+	WRITE_VREG(HEVC_ASSIST_RING_B_INDEX, 6);
+	WRITE_VREG(HEVC_ASSIST_RING_B_START, avs3_dec->fb_buf_lmem1.buf_start);
+	WRITE_VREG(HEVC_ASSIST_RING_B_END, avs3_dec->fb_buf_lmem1.buf_end);
+	WRITE_VREG(HEVC_ASSIST_RING_B_RPTR, avs3_dec->bk.lmem1_ptr);
+	//WRITE_VREG(HEVC_ASSIST_RING_B_THRESHOLD, 0);
+
+}
+
+static void read_bufstate_front(struct avs3_decoder *avs3_dec)
+{
+	//uint32_t tmp;
+	avs3_dec->fr.mmu0_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR0);
+	avs3_dec->fr.mmu1_ptr = READ_VREG(HEVC_ASSIST_FB_MMU_MAP_ADDR1);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 4);
+	avs3_dec->fr.scalelut_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	//avs3_dec->fr.scalelut_ptr_pre = READ_VREG(HEVC_ASSIST_RING_F_THRESHOLD);
+	//printk("pic_end_ptr = %x; pic_start_ptr = %x\n", avs3_dec->fr.scalelut_ptr, avs3_dec->fr.scalelut_ptr_pre);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 7);
+	avs3_dec->fr.vcpu_imem_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 5);
+	avs3_dec->fr.lmem0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 6);
+	avs3_dec->fr.lmem1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 0);
+	avs3_dec->fr.parser_sao0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 1);
+	avs3_dec->fr.parser_sao1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 2);
+	avs3_dec->fr.mpred_imp0_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+	WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 3);
+	avs3_dec->fr.mpred_imp1_ptr = READ_VREG(HEVC_ASSIST_RING_F_WPTR);
+
+	avs3_dec->fr.sys_imem_ptr = avs3_dec->sys_imem_ptr;
+	avs3_dec->fr.sys_imem_ptr_v = avs3_dec->sys_imem_ptr_v;
+}
+
+/*hw config*/
+
+/**/
+static int  compute_losless_comp_body_size(struct AVS3Decoder_s *dec,
+	int width, int height,
+	uint8_t is_bit_depth_10);
+static  int  compute_losless_comp_header_size(struct AVS3Decoder_s *dec,
+	int width, int height);
+
+static void config_work_space_hw(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	DEC_CTX * ctx = &dec->avs3_dec.ctx;
+	struct BuffInfo_s *buf_spec = dec->work_space_buf;
+	u32 width = dec->avs3_dec.img.width ? dec->avs3_dec.img.width : dec->init_pic_w;
+	u32 height = dec->avs3_dec.img.height ? dec->avs3_dec.img.height : dec->init_pic_h;
+	u8 is_bit_depth_10 = (ctx->info.bit_depth_internal == 8) ? 0 : 1;
+	int losless_comp_header_size =
+		compute_losless_comp_header_size(
+		dec, width,
+		height);
+	int losless_comp_body_size =
+		compute_losless_comp_body_size(dec,
+		width,
+		height, is_bit_depth_10);
+	int losless_comp_body_size_dw = losless_comp_body_size;
+	int losless_comp_header_size_dw = losless_comp_header_size;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", __func__,
+		buf_spec->ipp.buf_start,
+		buf_spec->ipp1.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->sbac_top.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);
+	if (back_flag) {
+		WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE,buf_spec->ipp.buf_start);
+		WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2,buf_spec->ipp1.buf_start);
+		WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE_DBE1,buf_spec->ipp1.buf_start);
+		WRITE_VREG(HEVCD_IPP_LINEBUFF_BASE2_DBE1,buf_spec->ipp.buf_start);
+	}
+	if (front_flag) {
+		//WRITE_VREG(HEVC_RPM_BUFFER, buf_spec->rpm.buf_start);
+		if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+		WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+		}
+
+		WRITE_VREG(AVS3_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(AVS3_SBAC_TOP_BUFFER, buf_spec->sbac_top.buf_start);
+	}
+	if (back_flag) {
+		WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+		WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR, dec->frame_mmu_map_phy_addr);
+		WRITE_VREG(HEVC_ASSIST_MMU_MAP_ADDR_DBE1, dec->frame_mmu_map_phy_addr_1); //new dual
+	}
+
+	if (back_flag) {
+#ifdef AVS3_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);
+		WRITE_VREG(HEVC_SAO_MMU_DMA_CTRL2_DBE1, dec->dw_frame_mmu_map_phy_addr_1); //new dual
+	}
+#endif
+	WRITE_VREG(HEVC_STREAM_SWAP_BUFFER2, buf_spec->swap_buf2.buf_start);
+
+	WRITE_VREG(HEVC_DBLK_CFG4, buf_spec->dblk_para.buf_start);  // cfg_cpi_addr
+	WRITE_VREG(HEVC_DBLK_CFG4_DBE1, buf_spec->dblk_para.buf_start);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFG4: 0x%x\n", buf_spec->dblk_para.buf_start);
+	WRITE_VREG(HEVC_DBLK_CFG5, buf_spec->dblk_data.buf_start); // cfg_xio_addr
+	WRITE_VREG(HEVC_DBLK_CFG5_DBE1, buf_spec->dblk_data.buf_start);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFG5: 0x%x\n", buf_spec->dblk_data.buf_start);
+	WRITE_VREG(HEVC_DBLK_CFGE, buf_spec->dblk_data2.buf_start); // cfg_adp_addr
+	WRITE_VREG(HEVC_DBLK_CFGE_DBE1, buf_spec->dblk_data2.buf_start);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		" [DBLK DBG] CFGE: 0x%x\n", 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);
+
+	data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+#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_DBE1, data32);
+
+#ifdef AVS3_10B_MMU
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,(0x1<< 4)); // bit[4] : paged_mem_mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,0x0);
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,(0x1<< 4)); // bit[4] : paged_mem_mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,0x0);
+#else
+	// WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mdoe
+#if 1
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1, (0<<3)); // bit[3] smem mode
+#else
+	if (params->p.bit_depth != 0x00) WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (0<<3)); // bit[3] smem mode
+	else WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, (1<<3)); // bit[3] smem mdoe
+#endif
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2,(losless_comp_body_size >> 5));
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL2_DBE1,(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);
+	WRITE_VREG(HEVC_CM_BODY_LENGTH_DBE1,losless_comp_body_size);
+	WRITE_VREG(HEVC_CM_HEADER_OFFSET_DBE1,losless_comp_body_size);
+	WRITE_VREG(HEVC_CM_HEADER_LENGTH_DBE1,losless_comp_header_size);
+#else
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,0x1 << 31);
+	WRITE_VREG(HEVCD_MPP_DECOMP_CTL1_DBE1,0x1 << 31);
+#endif
+#ifdef AVS3_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 + buf_spec->mmu_vbh.buf_size/4);
+	WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR_DBE1, buf_spec->mmu_vbh.buf_start  + buf_spec->mmu_vbh.buf_size/2);
+	WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR_DBE1, buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size/2 + buf_spec->mmu_vbh.buf_size/4);
+
+	/* use HEVC_CM_HEADER_START_ADDR */
+	data32 = READ_VREG(HEVC_SAO_CTRL5);
+	data32 |= (1<<10);
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+	data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+	data32 |= (1<<10);
+	WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+
+#endif
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		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_CM_BODY_LENGTH2_DBE1,losless_comp_body_size_dw);
+		WRITE_VREG(HEVC_CM_HEADER_OFFSET2_DBE1,losless_comp_body_size_dw);
+		WRITE_VREG(HEVC_CM_HEADER_LENGTH2_DBE1,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 + buf_spec->mmu_vbh_dw.buf_size/4);
+		WRITE_VREG(HEVC_SAO_MMU_VH0_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2);
+		WRITE_VREG(HEVC_SAO_MMU_VH1_ADDR2_DBE1, buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size/2 + buf_spec->mmu_vbh_dw.buf_size/4);
+
+	#ifndef AVS3_10B_NV21
+	#ifdef AVS3_10B_MMU_DW
+		WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+		WRITE_VREG(HEVC_DW_VH0_ADDDR_DBE1, DOUBLE_WRITE_VH0_HALF);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR_DBE1, DOUBLE_WRITE_VH1_HALF);
+	#endif
+	#endif
+
+		/* use HEVC_CM_HEADER_START_ADDR */
+		data32 = READ_VREG(HEVC_SAO_CTRL5);
+		data32 |= (1<<15);
+		WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		data32 = READ_VREG(HEVC_SAO_CTRL5_DBE1);
+		data32 |= (1<<15);
+		WRITE_VREG(HEVC_SAO_CTRL5_DBE1, data32);
+	}
+#endif
+	} //back_flag end
+	if (front_flag) {
+		WRITE_VREG(HEVC_MPRED_ABV_START_ADDR, buf_spec->mpred_above.buf_start);
+	#ifdef CO_MV_COMPRESS
+		data32 = READ_VREG(HEVC_MPRED_CTRL4);
+		data32 |=  (1<<1 | 1<<26);
+		WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+	#else
+		data32 = READ_VREG(HEVC_MPRED_CTRL4);
+		data32 |=  (1<<26); //enable AVS3 mode
+		WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+	#endif
+	}
+}
+
+static void hevc_init_decoder_hw(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	int32_t i;
+
+int32_t g_WqMDefault4x4[16] = {
+	64,     64,     64,     68,
+	64,     64,     68,     72,
+	64,     68,     76,     80,
+	72,     76,     84,     96
+};
+
+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
+};
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] Entering hevc_init_decoder_hw\n");
+#if 0
+	printk("[test.c] Test Parser Register Read/Write\n");
+	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; }
+
+	// test Parser Reset
+	WRITE_VREG(DOS_SW_RESET1, (1<<3)); // reset_whole parser
+	WRITE_VREG(DOS_SW_RESET1, 0); // reset_whole parser
+	data32 = READ_VREG(HEVC_PARSER_VERSION);
+	if (data32 != 0x00010001) { print_scratch_error(27); return; }
+#endif
+
+#if 0 // JT
+	printk("[test.c] Enable BitStream Fetch\n");
+	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);
+#endif // JT
+
+#if 0 //def AVS3_10B_HED_FB
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] Init AVS3_10B_HED_FB\n");
+	data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+	data32 = data32 |
+		(1 << 3) | // fb_read_avs2_enable0
+		(1 << 6) | // fb_read_avs2_enable1
+		(1 << 1) | // fb_avs2_enable
+		(1 << 13) | // fb_read_avs3_enable0
+		(1 << 14) | // fb_read_avs3_enable1
+		(1 << 9) | // fb_avs3_enable
+		(3 << 7)  //core0_en, core1_en,hed_fb_en
+		;
+	WRITE_VREG(HEVC_ASSIST_FB_CTL, data32); // new dual
+//    data32 = READ_VREG(HEVC_ASSIST_FB_W_CTL);
+//    data32 = data32 |
+//             (1 << 0)    // hed_fb_wr_en
+		;
+//    WRITE_VREG(HEVC_ASSIST_FB_W_CTL, data32);
+
+//#ifdef H265_10B_HED_SAME_FB
+//    printk("[test.c] Init H265_10B_HED_SAME_FB\n");
+//    data32 = READ_VREG(HEVC_ASSIST_FB_R_CTL);
+//    data32 = data32 |
+//             (1 << 0)    // hed_fb_rd_en
+//             ;
+//    WRITE_VREG(HEVC_ASSIST_FB_R_CTL, data32);
+//#endif
+
+#endif
+	if (!efficiency_mode && front_flag) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable HEVC Parser Interrupt\n");
+		data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+		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);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable HEVC Parser Shift\n");
+
+		data32 = READ_VREG(HEVC_SHIFT_STATUS);
+	#ifdef AVS3
+		data32 = data32 |
+			(0 << 1) |  // emulation_check_on // AVS3 emulation on/off will be controlled in microcode according to startcode type
+			(1 << 0)    // startcode_check_on
+			;
+	#else
+		data32 = data32 |
+			(1 << 1) |  // emulation_check_on
+			(1 << 0)    // startcode_check_on
+			;
+	#endif
+		WRITE_VREG(HEVC_SHIFT_STATUS, data32);
+
+		WRITE_VREG(HEVC_SHIFT_CONTROL,
+		(6 << 20) |  // emu_push_bits  (6-bits for AVS3)
+		(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);
+	}
+
+	if (!efficiency_mode && back_flag) {
+#if 0 // Dual Core : back Microcode will always initial SCALELUT
+	// Initial IQIT_SCALELUT memory -- just to avoid X in simulation
+	printk("[test.c] Initial IQIT_SCALELUT memory -- just to avoid X in simulation...\n");
+	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_DBE1, 0); // cfg_p_addr
+	for (i=0; i<1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, 0);
+#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
+		}
+		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR_DBE1, (0 << 8) | (0<<1) | 1);
+		for (i=0; i<32; i++) {
+			WRITE_VREG(HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#ifdef DUAL_CORE_64
+			WRITE_VREG(HEVC2_HEVCD_MPP_ANC_CANVAS_DATA_ADDR_DBE1, 0);
+#endif
+		}
+	}
+
+	if (front_flag) {
+#if 0
+	#ifdef ENABLE_SWAP_TEST
+		WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100);
+	#else
+		WRITE_VREG(HEVC_STREAM_SWAP_TEST, 0);
+	#endif
+#endif
+		//WRITE_VREG(HEVC_DECODE_PIC_BEGIN_REG, 0);
+		//WRITE_VREG(HEVC_DECODE_PIC_NUM_REG, decode_pic_num);
+#if 0
+		// Send parser_cmd
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] SEND Parser Command ...\n");
+		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);
+#endif
+
+		if (!efficiency_mode) {
+		WRITE_VREG(HEVC_PARSER_IF_CONTROL,
+			(1 << 12) | // alf_on_sao
+			//  (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
+			);
+		}
+	}
+#if 0
+//def MULTI_INSTANCE_SUPPORT
+	// Begin of Multi-instance
+	WRITE_VREG(HEVC_MPRED_INT_STATUS, (1<<31));
+
+	WRITE_VREG(HEVC_PARSER_RESULT_3, 0xffffffff);
+
+	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);
+
+	// End of Multi-instance
+#endif
+	// Changed to Start MPRED in microcode
+	/*
+	printk("[test.c] Start MPRED\n");
+	WRITE_VREG(HEVC_MPRED_INT_STATUS,
+		(1<<31)
+		);
+	*/
+
+	// AVS3 default seq_wq_matrix config
+	if (!efficiency_mode && back_flag) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "[test.c] Config AVS3 default seq_wq_matrix ...\n");
+		// 4x4
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+		for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+		// 8x8
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+		for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+		// 4x4
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+		for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+		// 8x8
+		WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+		for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"[test.c] Reset IPP\n");
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+			(0 << 1) | // enable ipp
+			(1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(1 << 0)   // software reset ipp and mpp
+			);
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL,
+			(1 << 1) | // enable ipp
+			(1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(0 << 0)   // software reset ipp and mpp
+			);
+
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+			(0 << 1) | // enable ipp
+			(1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(1 << 0)   // software reset ipp and mpp
+			);
+		WRITE_VREG(HEVCD_IPP_TOP_CNTL_DBE1,
+			(1 << 1) | // enable ipp
+			(1 << 3) | // bit[5:3] 000:HEVC, 010:VP9 , 100:avs2, 110:av1 001:avs3
+			(0 << 0)   // software reset ipp and mpp
+			);
+
+		// Init dblk
+		data32 = READ_VREG(HEVC_DBLK_CFGB);
+		data32 |= (5 << 0);
+		WRITE_VREG(HEVC_DBLK_CFGB, data32); // [3:0] cfg_video_type -> AVS3
+#define LPF_LINEBUF_MODE_CTU_BASED
+	//must be defined for DUAL_CORE
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+		WRITE_VREG(HEVC_DBLK_CFG0, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+		WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"[test.c] Bitstream level Init for DBLK .Done.\n");
+
+		data32 = READ_VREG(HEVC_DBLK_CFGB_DBE1);
+		data32 |= (5 << 0);
+		WRITE_VREG(HEVC_DBLK_CFGB_DBE1, data32); // [3:0] cfg_video_type -> AVS3
+#ifdef LPF_LINEBUF_MODE_CTU_BASED
+		WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (0<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#else
+		WRITE_VREG(HEVC_DBLK_CFG0_DBE1, (1<<18) | (1 << 0)); // [18]tile based line buffer storage mode [0] rst_sync(will be self cleared)
+#endif
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"[test.c] Bitstream level Init for DBLK_DBE1 .Done.\n");
+
+		// Initialize mcrcc and decomp perf counters
+#if 1
+		if (dec->front_back_mode == 1) {
+			mcrcc_perfcount_reset_dual(dec);
+			decomp_perfcount_reset_dual(dec);
+		}
+#endif
+	}//back_flag end
+	//printk("[test.c] Leaving hevc_init_decoder_hw\n");
+	return;
+}
+
+extern void config_cuva_buf(struct AVS3Decoder_s *dec);
+static int32_t avs3_hw_init(struct AVS3Decoder_s *dec, uint8_t front_flag, uint8_t back_flag)
+{
+	uint32_t data32;
+	unsigned int decode_mode;
+	uint32_t tmp = 0;
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s front_flag %d back_flag %d\n", __func__, front_flag, back_flag);
+	if (dec->front_back_mode != 1) {
+		if (front_flag)
+		avs3_hw_ctx_restore(dec);
+		if (back_flag) {
+		/* clear mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+		/* enable mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+
+		}
+		return 0;
+	}
+
+	if (front_flag) {
+		data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+		data32 = data32 | (3 << 7) | (1 << 9) | (1 << 1);
+		tmp = (1 << 0) | (1 << 10);
+		data32 &= ~tmp;
+		WRITE_VREG(HEVC_ASSIST_FB_CTL, data32);
+	}
+
+	if (back_flag) {
+		data32 = READ_VREG(HEVC_ASSIST_FB_CTL);
+		data32 = data32 | (3 << 7) | (1 << 3) | (1 << 13) | (1 << 6) | (1 << 14);
+		tmp = (1 << 2) |  (1 << 11) | (1 << 5) | (1 << 12);
+		data32 &= ~tmp;
+		WRITE_VREG(HEVC_ASSIST_FB_CTL, data32);
+	}
+
+	config_work_space_hw(dec, front_flag, back_flag);
+
+	if (!efficiency_mode && dec->pic_list_init_flag && front_flag)
+	init_pic_list_hw_fb(dec);
+
+	hevc_init_decoder_hw(dec, front_flag, back_flag);
+//Start JT
+	if (!efficiency_mode) {
+	if (front_flag) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[test.c] Enable BitStream Fetch\n");
+#if 0
+		data32 = READ_VREG(HEVC_STREAM_CONTROL);
+		data32 = data32 |
+			(1 << 0) // stream_fetch_enable
+			;
+		WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+#if 0
+		data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+		if (data32 != 0x00000100) { print_scratch_error(29); return -1; }
+		/*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 -1; }
+		data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+		if (data32 != 0x9abcdef0) { print_scratch_error(32); return -1; }
+#endif
+		WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+		WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000); // 0x000000 - 0x000003 emulate code for AVS3
+	}
+	}
+// End JT
+
+	if (!efficiency_mode && back_flag) {
+	// 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);
+		WRITE_VREG(HEVCD_MPP_DECOMP_AXIURG_CTL_DBE1, data32);
+
+	// Set IPP MULTICORE CFG
+		WRITE_VREG(HEVCD_IPP_MULTICORE_CFG, 1);
+		WRITE_VREG(HEVCD_IPP_MULTICORE_CFG_DBE1, 1);
+
+#ifdef DYN_CACHE
+		if (dec->front_back_mode == 1) {
+		WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+		WRITE_VREG(HEVCD_IPP_DYN_CACHE_DBE1,0x2b);//enable new mcrcc
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"HEVC DYN MCRCC\n");
+		}
+#endif
+	}
+	if (front_flag) {
+		WRITE_VREG(LMEM_DUMP_ADR, (u32)dec->lmem_phy_addr);
+	#if 1 // JT
+
+	#if 0 //def SIMULATION
+		if (decode_pic_begin == 0)
+		WRITE_VREG(HEVC_WAIT_FLAG, 1);
+		else
+		WRITE_VREG(HEVC_WAIT_FLAG, 0);
+	#else
+		WRITE_VREG(HEVC_WAIT_FLAG, 1);
+	#endif
+		/* clear mailbox interrupt */
+		WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+		/* enable mailbox interrupt */
+		WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+
+		/* disable PSCALE for hardware sharing */
+	#ifdef DOS_PROJECT
+	#else
+		WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+	#endif
+
+		//WRITE_VREG(DEBUG_REG1, 0x0);  //no debug
+		WRITE_VREG(NAL_SEARCH_CTL, 0x8); //check SEQUENCE/I_PICTURE_START in ucode
+		WRITE_VREG(DECODE_STOP_POS, udebug_flag);
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+		WRITE_VREG(HEVC_DBG_LOG_ADR, dec->ucode_log_phy_addr);
+#endif
+	#ifdef MULTI_INSTANCE_SUPPORT
+	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;
+#ifdef FOR_S5
+		/*to do..*/
+		dec->start_decoding_flag = 3;
+		decode_mode |= (dec->start_decoding_flag << 16);
+#endif
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s set decode_mode 0x%x\n", __func__, decode_mode);
+		WRITE_VREG(DECODE_MODE, decode_mode); //DECODE_MODE_MULTI_STREAMBASE
+		config_cuva_buf(dec);
+
+	#endif
+
+		//WRITE_VREG(XIF_DOS_SCRATCH31, 0x0);
+		//WRITE_VREG(HEVC_MPSR, 1);
+		//printk("[test.c] HEVC_MPSR!\n");
+	#endif
+	}
+	if (back_flag) {
+		/* clear mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_CLR_REG, 1);
+
+		/* enable mailbox interrupt */
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 1);
+	}
+
+	return 0;
+}
+
+static void release_free_mmu_buffers(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int ii;
+	for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+		struct avs3_frame_s *pic =
+		&avs3_dec->pic_pool[ii].buf_cfg;
+		if (pic->used == 0 &&
+		pic->vf_ref == 0 &&
+#ifdef NEW_FRONT_BACK_CODE
+		pic->backend_ref == 0 && /*?? why need it in case0763,
+				                                    used is supposed to be 1 if backend_ref is not 0*/
+#endif
+		pic->mmu_alloc_flag) {
+		pic->mmu_alloc_flag = 0;
+		decoder_mmu_box_free_idx(dec->mmu_box,
+			pic->index);
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s decoder_mmu_box_free_idx index=%d\n",
+			__func__, pic->index);
+		if (dec->front_back_mode)
+			decoder_mmu_box_free_idx(dec->mmu_box_1,
+			pic->index);
+
+#ifdef AVS3_10B_MMU_DW
+		if (dec->dw_mmu_enable && dec->dw_mmu_box) {
+			decoder_mmu_box_free_idx(dec->dw_mmu_box,
+			pic->index);
+			avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s DW decoder_mmu_box_free_idx index=%d\n",
+			__func__, pic->index);
+			if (dec->front_back_mode && dec->dw_mmu_box_1)
+			decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+				pic->index);
+		}
+#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
+		}
+	}
+}
+
+static void print_hevc_b_data_path_monitor(int frame_count)
+{
+		uint32_t total_clk_count;
+		uint32_t path_transfer_count;
+		uint32_t path_wait_count;
+		uint32_t path_status;
+	unsigned path_wait_ratio;
+
+		printk("\n[WAITING DATA/CMD] Parser/IQIT/IPP/DBLK/OW/DDR/MPRED_IPP_CMD/IPP_DBLK_CMD\n");
+
+	//---------------------- CORE 0 -------------------------------
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL, 0); // Disable monitor and set rd_idx to 0
+		total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA);
+
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (1<<4)); // Disable monitor and set rd_idx to 1
+
+	// 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;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk("[P%d HEVC CORE0 PATH] WAITING Ratio : %d",
+		frame_count,
+		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;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", 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;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", 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;
+	else path_wait_ratio = path_wait_count *100 / path_transfer_count;
+		printk(" %d", 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;
+	else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// IMP
+		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;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// path status
+	path_status = READ_VREG(HEVC_PATH_MONITOR_DATA);
+
+	// 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;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+#if 0
+		WRITE_VREG(HEVC_PARSER_IF_MONITOR_CTRL, (2<<4)); // Disable monitor and set rd_idx to 2
+
+	// Parser-Mpred CMD
+		path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+		path_wait_count = READ_VREG(HEVC_PARSER_IF_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);
+
+	// Parser-SAO CMD
+		path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA);
+		path_wait_count = READ_VREG(HEVC_PARSER_IF_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);
+	}
+#else
+	printk("\n");
+#endif
+	//---------------------- CORE 1 -------------------------------
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL_DBE1, 0); // Disable monitor and set rd_idx to 0
+		total_clk_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL_DBE1, (1<<4)); // Disable monitor and set rd_idx to 1
+
+	// parser --> iqit
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+		printk("[P%d HEVC CORE1 PATH] WAITING Ratio : %d",
+		frame_count,
+		path_wait_ratio);
+
+	// iqit --> ipp
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// dblk <-- ipp
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 /path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// dblk --> ow
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// <--> DDR
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// IMP
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+	// path status
+	path_status = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+
+	// CMD
+		path_transfer_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PATH_MONITOR_DATA_DBE1);
+	if (path_transfer_count == 0) path_wait_ratio = 0;
+	else path_wait_ratio = path_wait_count * 100 / path_transfer_count;
+		printk(" %d", path_wait_ratio);
+
+# if 0
+		WRITE_VREG(HEVC_PARSER_IF_MONITOR_CTRL, (2<<4)); // Disable monitor and set rd_idx to 2
+
+	// Parser-Mpred CMD
+		path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+	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);
+
+	// Parser-SAO CMD
+		path_transfer_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+		path_wait_count = READ_VREG(HEVC_PARSER_IF_MONITOR_DATA_DBE1);
+	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);
+	}
+#else
+	printk("\n");
+#endif
+}
+
+static int BackEnd_StartDecoding(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+	int picture_size;
+	int cur_mmu_4k_number, max_frame_num;
+	int i = 0;
+	struct avs3_frame_s *ref_pic = NULL;
+
+	avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+		"Start BackEnd Decoding %d (wr pos %d, rd pos %d) pic index %d\n",
+		avs3_dec->backend_decoded_count, avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, pic->index);
+
+#if 0
+#ifdef AVS3_10B_MMU
+	alloc_mmu(&avs3_mmumgr_0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+	alloc_mmu(&avs3_mmumgr_1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#ifdef AVS3_10B_MMU_DW
+	alloc_mmu(&avs3_mmumgr_dw0, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+	alloc_mmu(&avs3_mmumgr_dw1, pic->index, pic->width, pic->height/2+32+8, ((pic->depth == 0) ? 0 : DEPTH_BITS_10));
+#endif
+	pic->mmu_alloc_flag = 1;
+#endif
+#else
+
+	mutex_lock(&dec->fb_mutex);
+	for (i = 0; (i < pic->list0_num_refp) && (pic->error_mark == 0); i++) {
+		ref_pic = &avs3_dec->pic_pool[pic->list0_index[i]].buf_cfg;
+		if (ref_pic->error_mark) {
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == SLICE_I) {
+				dec->gvs->i_concealed_frames++;
+			} else if (pic->slice_type == SLICE_P) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == SLICE_B) {
+				dec->gvs->b_concealed_frames++;
+			}
+			pic->error_mark = 1;
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 ref_pic %d pic error\n",
+				__func__, pic->list0_index[i]);
+		}
+	}
+
+	for (i = 0; (i < pic->list1_num_refp) && (pic->error_mark == 0); i++) {
+		ref_pic = &avs3_dec->pic_pool[pic->list1_index[i]].buf_cfg;
+		if (ref_pic->error_mark) {
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == SLICE_I) {
+				dec->gvs->i_concealed_frames++;
+			} else if (pic->slice_type == SLICE_P) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == SLICE_B) {
+				dec->gvs->b_concealed_frames++;
+			}
+			pic->error_mark = 1;
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 ref_pic %d pic error\n",
+				__func__, pic->list1_index[i]);
+		}
+	}
+	mutex_unlock(&dec->fb_mutex);
+
+	if (pic->error_mark && (error_handle_policy & 0x4)) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"%s: error pic, skip\n", __func__);
+
+		mutex_lock(&dec->fb_mutex);
+		dec->gvs->drop_frame_count++;
+		if (pic->slice_type == SLICE_I) {
+			dec->gvs->i_lost_frames++;
+		} else if (pic->slice_type == SLICE_P) {
+			dec->gvs->p_lost_frames++;
+		} else if (pic->slice_type == SLICE_B) {
+			dec->gvs->b_lost_frames++;
+		}
+		mutex_unlock(&dec->fb_mutex);
+
+		pic_backend_ref_operation(dec, pic, 0);
+
+		return 1;
+	}
+
+	picture_size = compute_losless_comp_body_size(
+		dec, pic->width, pic->height/2 + 32 + 8,
+		pic->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 2;
+	}
+	avs3_print(dec, AVS3_DBG_BUFMGR,
+		"%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+		__func__, pic->index, cur_mmu_4k_number);
+
+	decoder_mmu_box_alloc_idx(
+		dec->mmu_box,
+		pic->index,
+		cur_mmu_4k_number,
+		dec->frame_mmu_map_addr);
+
+	decoder_mmu_box_alloc_idx(
+		dec->mmu_box_1,
+		pic->index,
+		cur_mmu_4k_number,
+		dec->frame_mmu_map_addr_1);
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+		__func__, pic->index, cur_mmu_4k_number);
+
+	if (dec->dw_mmu_enable) {
+		decoder_mmu_box_alloc_idx(
+		dec->dw_mmu_box,
+		pic->index,
+		cur_mmu_4k_number,
+		dec->dw_frame_mmu_map_addr);
+
+		decoder_mmu_box_alloc_idx(
+		dec->dw_mmu_box_1,
+		pic->index,
+		cur_mmu_4k_number,
+		dec->dw_frame_mmu_map_addr_1);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s DW decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+		__func__, pic->index, cur_mmu_4k_number);
+	}
+	pic->mmu_alloc_flag = 1;
+#endif
+	ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_ALLOC_MMU_END);
+
+	ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_START);
+
+	copy_loopbufs_ptr(&avs3_dec->bk, &avs3_dec->next_bk[avs3_dec->fb_rd_pos]);
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"update loopbuf bk from next_bk[fb_rd_pos=%d]\n", avs3_dec->fb_rd_pos);
+	print_loopbufs_ptr(dec, "bk", &avs3_dec->bk);
+#ifdef NEW_FRONT_BACK_CODE
+#ifdef PRINT_HEVC_DATA_PATH_MONITOR
+	if (dec->front_back_mode == 1) {
+		if (avs3_dec->backend_decoded_count > 0 &&
+			(debug & AVS3_DBG_CACHE)) {
+			print_hevc_b_data_path_monitor(avs3_dec->backend_decoded_count-1);
+			print_mcrcc_hit_info(avs3_dec->backend_decoded_count-1);
+		}
+	}
+#endif
+#endif
+	if (dec->front_back_mode == 1)
+		amhevc_reset_b();
+	if (efficiency_mode)
+		WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 1 << 1);
+	else
+		WRITE_VREG(HEVC_EFFICIENCY_MODE_BACK, 0 << 1);
+	avs3_hw_init(dec, 0, 1);
+	if (dec->front_back_mode == 3) {
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+		ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_END);
+	} else {
+		config_bufstate_back_hw(avs3_dec);
+		WRITE_VREG(PIC_DECODE_COUNT_DBE, avs3_dec->backend_decoded_count);
+		WRITE_VREG(HEVC_DEC_STATUS_DBE, HEVC_BE_DECODE_DATA);
+		WRITE_VREG(HEVC_SAO_CRC, 0);
+		ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_CONFIGURE_REGISTER_END);
+
+		ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_FW_START);
+		amhevc_start_b();
+		ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_FW_END);
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC_BACK);
+	}
+
+	return 0;
+}
+
+static unsigned HEVC_MPRED_L0_REF_POC_ADR[] = {
+	HEVC_MPRED_L0_REF00_POC,
+	HEVC_MPRED_L0_REF01_POC,
+	HEVC_MPRED_L0_REF02_POC,
+	HEVC_MPRED_L0_REF03_POC,
+	HEVC_MPRED_L0_REF04_POC,
+	HEVC_MPRED_L0_REF05_POC,
+	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,
+	HEVC_MPRED_L0_REF12_POC,
+	HEVC_MPRED_L0_REF13_POC,
+	HEVC_MPRED_L0_REF14_POC,
+	HEVC_MPRED_L0_REF15_POC,
+	HEVC_MPRED_POC24_CTRL0
+};
+
+static unsigned HEVC_MPRED_L1_REF_POC_ADR[] = {
+	HEVC_MPRED_L1_REF00_POC,
+	HEVC_MPRED_L1_REF01_POC,
+	HEVC_MPRED_L1_REF02_POC,
+	HEVC_MPRED_L1_REF03_POC,
+	HEVC_MPRED_L1_REF04_POC,
+	HEVC_MPRED_L1_REF05_POC,
+	HEVC_MPRED_L1_REF06_POC,
+	HEVC_MPRED_L1_REF07_POC,
+	HEVC_MPRED_L1_REF08_POC,
+	HEVC_MPRED_L1_REF09_POC,
+	HEVC_MPRED_L1_REF10_POC,
+	HEVC_MPRED_L1_REF11_POC,
+	HEVC_MPRED_L1_REF12_POC,
+	HEVC_MPRED_L1_REF13_POC,
+	HEVC_MPRED_L1_REF14_POC,
+	HEVC_MPRED_L1_REF15_POC,
+	HEVC_MPRED_POC24_CTRL1
+};
+
+static void init_pic_list_hw_fb(struct AVS3Decoder_s *dec)
+{
+	int i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *pic;
+	/*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x0);*/
+	avs3_dec->ins_offset = 0;
+#if 1
+	WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+
+#ifdef DUAL_CORE_64
+	WRITE_BACK_8(avs3_dec, HEVC2_HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, (0x1 << 1) | (0x1 << 2));
+#endif
+#endif
+	for (i = 0; i < dec->avs3_dec.max_pb_size; i++) {
+		pic = &avs3_dec->pic_pool[i].buf_cfg;
+		if (pic->index < 0)
+		break;
+#ifdef AVS3_10B_MMU
+	/*WRITE_VREG(HEVCD_MPP_ANC2AXI_TBL_CMD_ADDR,
+		pic->header_adr
+		| (pic->mc_canvas_y << 8)|0x1);*/
+		//WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR,
+		//    (0x1 << 1) | (pic->index << 8));
+
+	WRITE_BACK_32(avs3_dec, 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_BACK_32(avs3_dec, 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_BACK_32(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_DATA, pic->mc_u_v_adr >> 5);
+#endif
+	}
+	WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC2AXI_TBL_CONF_ADDR, 0x1);
+
+	/*Zero out canvas registers in IPP -- avoid simulation X*/
+	WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR,
+		(0 << 8) | (0 << 1) | 1);
+	for (i = 0; i < 32; i++) {
+		WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, 0);
+	}
+}
+
+static void config_mpred_hw_fb(struct AVS3Decoder_s *dec)
+{
+	int32_t i;
+	uint32_t data32;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+	avs3_frame_t *col_pic;
+	//COM_PIC *colPic;
+
+	//int32_t     AMVP_MAX_NUM_CANDS_MEM=3;
+	//int32_t     AMVP_MAX_NUM_CANDS=2;
+	//int32_t     NUM_CHROMA_MODE=5;
+	//int32_t     DM_CHROMA_IDX=36;
+	int32_t     above_ptr_ctrl =0;
+	//int32_t     buffer_linear =1;
+	//int32_t     cu_size_log2 =3;
+	int32_t     mpred_mv_rd_start_addr ;
+	//int32_t     mpred_curr_lcu_x;
+	//int32_t     mpred_curr_lcu_y;
+	//int32_t     mpred_above_buf_start ;
+	//int32_t     mpred_mv_rd_ptr ;
+	//int32_t     mpred_mv_rd_ptr_p1 ;
+	int32_t     mpred_mv_rd_end_addr;
+	int32_t     MV_MEM_UNIT_l;
+	//int32_t     mpred_mv_wr_ptr ;
+
+	int32_t     above_en;
+	int32_t     mv_wr_en;
+	int32_t     mv_rd_en;
+	int32_t     col_isIntra;
+	int32_t     col_ptr;
+	//if (hevc->slice_type!=2)
+
+	if (avs3_dec->slice_type == SLICE_P) {
+		if (avs3_dec->ctx.refp[0][REFP_0].pic != NULL)
+			col_pic = &avs3_dec->ctx.refp[0][REFP_0].pic->buf_cfg;
+		else
+			col_pic = cur_pic;
+	} else if (avs3_dec->slice_type == SLICE_B) {
+		if (avs3_dec->ctx.refp[0][REFP_1].pic != NULL)
+			col_pic = &avs3_dec->ctx.refp[0][REFP_1].pic->buf_cfg;
+		else
+			col_pic = cur_pic;
+	} else {
+		col_pic = cur_pic;
+	}
+
+	if (avs3_dec->slice_type != SLICE_I)
+	{
+		above_en=1;
+		mv_wr_en=1;
+		if (col_pic->slice_type != SLICE_I)
+			mv_rd_en=1;
+		else
+			mv_rd_en=0;
+		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_l=get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+	mpred_mv_rd_end_addr=mpred_mv_rd_start_addr + ((avs3_dec->lcu_x_num*avs3_dec->lcu_y_num)*MV_MEM_UNIT_l);
+
+	//mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"cur pic index %d  slicetype %d col pic index %d slicetype %d\n",
+		cur_pic->index, cur_pic->slice_type,
+		col_pic->index, col_pic->slice_type);
+
+	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);
+	avs3_print(dec, AVS3_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 =
+	((avs3_dec->bk_img_is_top_field) << 13) |
+	((avs3_dec->hd.background_picture_enable & 1) << 12) |
+		((avs3_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+		((avs3_dec->hd.b_pmvr_enabled & 1) << 6) |
+		((avs3_dec->img.is_top_field & 1) << 5)  |
+		((avs3_dec->img.is_field_sequence & 1) << 4) |
+		((avs3_dec->img.typeb & 7) << 1) |
+		(avs3_dec->hd.background_reference_enable & 0x1);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+	"HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n", data32, avs3_dec->hd.curr_RPS.num_of_ref);
+	WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+	*/
+#if 1
+	/*
+	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 &= (~(0x3 | (0xf << 8) | (0xf << 16)));
+	data32  =   (
+		avs3_dec->slice_type |
+		/*hevc->new_pic<<2 |
+		hevc->new_tile<<3|
+		hevc->isNextSliceSegment<<4|
+		hevc->TMVPFlag<<5|
+		hevc->LDCFlag<<6|
+		hevc->ColFromL0Flag<<7|
+	 */
+		above_ptr_ctrl<<8 |
+		above_en<<9|
+		mv_wr_en<<10|
+		mv_rd_en<<11|
+		avs3_dec->lcu_size_log2<<16
+		/*|cu_size_log2<<20*/
+		);
+	WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"HEVC_MPRED_CTRL0=0x%x\n",
+		READ_VREG(HEVC_MPRED_CTRL0));
+
+	data32 = READ_VREG(HEVC_MPRED_CTRL1);
+	data32 &= (~0xf);
+	data32 |= avs3_dec->ctx.info.sqh.num_of_hmvp_cand;
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"write HEVC_MPRED_CTRL1=0x%x, avs3_dec->ctx.info.sqh.num_of_hmvp_cand=%d\n",
+		data32, avs3_dec->ctx.info.sqh.num_of_hmvp_cand);
+	WRITE_VREG(HEVC_MPRED_CTRL1,data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"HEVC_MPRED_CTRL1=0x%x\n",
+		READ_VREG(HEVC_MPRED_CTRL1));
+
+	data32  =   (
+		avs3_dec->img.width|
+		avs3_dec->img.height<<16
+		);
+	WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+	data32  =   (
+		(avs3_dec->lcu_x_num-1)   |
+		(avs3_dec->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  =   (
+		avs3_dec->ctx.dpm.num_refp[REFP_0]   |
+		avs3_dec->ctx.dpm.num_refp[REFP_1]<<8|
+		0
+		//col_RefNum_L0<<16|
+		//col_RefNum_L1<<24
+		);
+	WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+	data32=0;
+	for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_0];i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+	data32=0;
+	for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_1];i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+
+	WRITE_VREG(HEVC_MPRED_CUR_POC, avs3_dec->ctx.ptr & 0xffff);
+	if (avs3_dec->slice_type == SLICE_P) {
+		col_ptr = avs3_dec->ctx.refp[0][REFP_0].ptr;
+		//colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+	}
+	else if (avs3_dec->slice_type == SLICE_B) {
+		col_ptr = avs3_dec->ctx.refp[0][REFP_1].ptr;
+		//colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+	}
+	else {
+		col_ptr = avs3_dec->ctx.pic->ptr;
+		//colPic = avs3_dec->ctx.pic;
+	}
+	WRITE_VREG(HEVC_MPRED_COL_POC, col_ptr & 0xffff);
+	//below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> Ref_POC_xx_L1 in pair write order!!!
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"HEVC_MPRED_CUR_POC=0x%x, HEVC_MPRED_COL_POC=0x%x\n",
+		READ_VREG(HEVC_MPRED_CUR_POC), READ_VREG(HEVC_MPRED_COL_POC));
+
+	for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+		data32 = 0;
+		if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+		if (i < cur_pic->list0_num_refp) {
+			data32 |= cur_pic->list0_ptr[i] & 0xffff;
+		}
+		if (i < col_pic->list0_num_refp) {
+			data32 |= ((col_pic->list0_ptr[i] & 0xffff) << 16);
+		}
+		}
+		WRITE_VREG(HEVC_MPRED_L0_REF_POC_ADR[i], data32);
+	}
+	if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+		for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+			if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+				if (i < cur_pic->list0_num_refp) {
+					avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"[%d] ", cur_pic->list0_ptr[i]);
+				}
+				if (i < col_pic->list0_num_refp) {
+					avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"<%d> ", col_pic->list0_ptr[i]);
+				}
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"HEVC_MPRED_L0_REF=0x%x (readback 0x%x)\n", i,
+					data32, READ_VREG(HEVC_MPRED_L0_REF_POC_ADR[i]));
+			}
+		}
+	}
+	for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+		WRITE_VREG(HEVC_MPRED_L1_REF_POC_ADR[i], avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff);
+	}
+	if (debug) {
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"HEVC_MPRED_L1_REF%02d_POC=0x%x (readback 0x%x)\n", i, avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff, READ_VREG(HEVC_MPRED_L1_REF_POC_ADR[i]));
+		}
+	}
+
+#if 0
+	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);
+	}
+#endif
+	WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dw_fb(struct AVS3Decoder_s *dec, struct avs3_frame_s *pic,
+		u32 mc_buffer_size_u_v_h)
+{
+
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int dw_mode = get_double_write_mode(dec);
+	uint32_t data, data32;
+	if ((dw_mode & 0x10) == 0) {
+		WRITE_BACK_8(avs3_dec, HEVC_SAO_CTRL26, 0);
+
+		//data32 = READ_VREG(HEVC_SAO_CTRL5);
+		//data32 &= (~(0xff << 16));
+		if (((dw_mode & 0xf) == 8) ||
+		((dw_mode & 0xf) == 9)) {
+		data = 0xff; //data32 |= (0xff << 16);
+		//WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		WRITE_BACK_8(avs3_dec, HEVC_SAO_CTRL26, 0xf);
+		} else {
+		if ((dw_mode & 0xf) == 2 ||
+			(dw_mode & 0xf) == 3)
+			data = 0xff; //data32 |= (0xff<<16);
+		else if ((dw_mode & 0xf) == 4 ||
+			(dw_mode & 0xf) == 5)
+			data = 0x33; //data32 |= (0x33<<16);
+
+		/*if (dec->mem_saving_mode == 1)
+			READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 1, 9, 1); //data32 |= (1 << 9);
+		else*/
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 0, 9, 1); //data32 &= ~(1 << 9);
+		/*if (workaround_enable & 1)
+			READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 1, 7, 1); //data32 |= (1 << 7);*/
+		//WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		}
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, data, 16, 8);
+	}
+
+		/* m8baby test1902 */
+		//data32 = READ_VREG(HEVC_SAO_CTRL1);
+		//data32 &= (~0x3000);
+		/* [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32 */
+		//data32 |= (dec->mem_map_mode << 12);
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, MEM_MAP_MODE, 12, 2);
+		//data32 &= (~0xff0);
+#ifdef AVS3_10B_MMU_DW
+		if (dec->dw_mmu_enable == 0)
+		data = ((dec->endian >> 8) & 0xfff); //endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf)
+#else
+		data = ((dec->endian >> 8) & 0xfff);    /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, data, 0, 12);
+
+		//data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+		if (dw_mode == 0)
+		data = 0x2; //data32 |= 0x2; /*disable double write*/
+		else if (dw_mode & 0x10)
+		data = 0x1; //data32 |= 0x1; /*disable cm*/
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, data, 0, 2);
+
+		//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
+	 */
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL1, 2, 14, 2);
+		//WRITE_VREG(HEVC_SAO_CTRL1, data32);
+
+		//data32 &= (~0x300); /*[8]:first write enable (compress)
+		//                [9]:double write enable (uncompress)*/
+		if (dw_mode == 0)
+		data = 1; //data32 |= (0x1 << 8); /*enable first write*/
+		else if (dw_mode == 0x10)
+		data = 2; //data32 |= (0x1 << 9); /*double write only*/
+		else
+		data = 3; //data32 |= ((0x1 << 8) | (0x1 << 9));
+		//WRITE_VREG(HEVC_DBLK_CFGB, data32);
+		READ_WRITE_DATA16(avs3_dec, HEVC_DBLK_CFGB, data, 8, 2);
+
+		if (dw_mode & 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);
+		READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL5, 0, 16, 8);
+		}
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+	data32 = pic->mc_y_adr;
+	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	if ((dw_mode & 0x10) == 0)
+		WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, data32);
+
+	if (dec->mmu_enable)
+		WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0);
+		WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+	}
+#endif
+#else
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+	data32 = (mc_buffer_size_u_v_h << 16) << 1;
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_LENGTH, data32);
+
+	data32 = (mc_buffer_size_u_v_h << 16);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_C_LENGTH, data32);
+
+}
+
+static void config_sao_hw_fb(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_frame_t *pic = avs3_dec->cur_pic;
+	//union param_u* params = &avs3_dec->param;
+	//uint32_t data32;
+	int32_t pic_width = avs3_dec->img.width;
+	int32_t pic_height = avs3_dec->img.height;
+	int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+	int32_t lcu_size = 1<<lcu_size_log2;
+	int32_t pic_width_lcu  = ( pic_width % lcu_size  ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+	int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+	int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+	int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+	int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+	config_dw_fb(dec, pic, mc_buffer_size_u_v_h);
+#if 0 // no dual mode
+	data32 = READ_VREG(HEVC_SAO_CTRL0);
+	data32 &= (~0xf);
+	data32 |= avs3_dec->lcu_size_log2;
+	WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#else
+	READ_WRITE_DATA16(avs3_dec, HEVC_SAO_CTRL0, avs3_dec->lcu_size_log2, 0, 4);
+#endif
+
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+	if ((get_double_write_mode(dec) & 0x20) == 0) {
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+	if (dec->dw_mmu_enable) {
+		WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, 0);
+		WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR, 0);
+	}
+
+	///WRITE_VREG(HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+	//WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+	///WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+	//WRITE_BACK_32(avs3_dec, HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+#ifdef AVS3_10B_MMU
+	///WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * MMU_COMPRESS_HEADER_SIZE));
+	//WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS3_10B_MMU_DW
+	//if (dec->dw_mmu_enable) {
+		///WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+	//    WRITE_BACK_32(avs3_dec, HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+	//}
+#endif
+
+#else
+	///WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+	data32 = (mc_buffer_size_u_v_h<<16)<<1;
+	///WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_LENGTH ,data32);
+
+	///WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+	//WRITE_BACK_32(avs3_dec, HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+	data32 = (mc_buffer_size_u_v_h<<16);
+	///WRITE_VREG(HEVC_SAO_C_LENGTH  ,data32);
+	WRITE_BACK_32(avs3_dec, HEVC_SAO_C_LENGTH  ,data32);
+	///WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+	//WRITE_BACK_32(avs3_dec, HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+	///WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+	//WRITE_BACK_32(avs3_dec, HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+
+#ifdef AVS3_10B_NV21
+	SHOULD NOT DEFINED !!
+	data32 = READ_VREG( HEVC_SAO_CTRL1);
+	data32 &= (~0x3000);
+	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);
+
+	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 H265_NV21 (no down-scale)
+	WRITE_VREG( HEVC_SAO_CTRL5, data32);
+
+	data32 = READ_VREG( HEVCD_IPP_AXIIF_CONFIG);
+	data32 &= (~0x30);
+	data32 |= (MEM_MAP_MODE << 4); // [5:4]    -- address_format 00:linear 01:32x32 10:64x32
+	WRITE_VREG( HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgSAO .done.\n");
+}
+
+static void config_dblk_hw_fb(struct AVS3Decoder_s *dec)
+{
+	/*
+	* Picture level de-block parameter configuration here
+	*/
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	union param_u *rpm_param = &avs3_dec->param;
+	uint32_t data32;
+	DEC_CTX * ctx = &avs3_dec->ctx;
+	int32_t alpha_c_offset = rpm_param->p.pic_header_alpha_c_offset;
+	int32_t beta_offset = rpm_param->p.pic_header_beta_offset;
+
+	alpha_c_offset = (alpha_c_offset >=16) ? 15 : ((alpha_c_offset < -16) ? -16 : alpha_c_offset);
+	beta_offset = (beta_offset >=16) ? 15 : ((beta_offset < -16) ? -16 : beta_offset);
+
+#if 0 // NOT Dual Mode
+	data32 = READ_VREG(HEVC_DBLK_CFG1);
+	data32 = (((data32>>20)&0xfff)<<20) |
+		(((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)<<16) |             // [16 +: 4]: {luma_bd[1:0],chroma_bd[1:0]}
+		(((data32>>2)&0x3fff)<<2) |
+		(((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)<<0);// [ 0 +: 2]: lcu_size
+	WRITE_VREG(HEVC_DBLK_CFG1, data32);
+#else
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0x6450101;                                          //mfsp COMMON_REG_1, HEVC_DBLK_CFG1
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)&0xffff)<<6);   // movi COMMON_REG_0, data
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0x9604040;                                          //ins  COMMON_REG_1, COMMON_REG_0, 16, 4
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = (0x1a<<22) | ((((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)&0xffff)<<6);   // movi COMMON_REG_0, data
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0x9402040;                                          //ins  COMMON_REG_1, COMMON_REG_0, 0, 2
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+	avs3_dec->instruction[avs3_dec->ins_offset] = 0x6050101;                                          //mtsp COMMON_REG_1, HEVC_DBLK_CFG1
+	avs3_print(dec, AVS3_DBG_REG,
+		"instruction[%3d] = %8x\n", avs3_dec->ins_offset, avs3_dec->instruction[avs3_dec->ins_offset]);
+	avs3_dec->ins_offset++;
+#endif
+
+	data32 = (avs3_dec->img.height<<16) | avs3_dec->img.width;
+	///WRITE_VREG(HEVC_DBLK_CFG2, data32);
+	WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFG2, data32);
+
+	data32 = ((rpm_param->p.sqh_cross_patch_loop_filter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+		((rpm_param->p.pic_header_loop_filter_disable_flag & 0x1)<<26) |               // [26 +: 1]: loop_filter_disable
+		((alpha_c_offset&0x1f) <<17) |                    // [17 +: 5]: alpha_c_offset (-8~8)
+		((beta_offset&0x1f) <<12) |                       // [12 +: 5]: beta_offset (-8~8)
+		((rpm_param->p.pic_header_chroma_quant_param_delta_cb&0x3f)<<6) |         // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+		((rpm_param->p.pic_header_chroma_quant_param_delta_cr&0x3f)<<0);          // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+	///WRITE_VREG(HEVC_DBLK_CFG9, data32);
+	WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFG9, data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d,%d),log2_lcuSize(%d)\n",
+			rpm_param->p.sqh_cross_patch_loop_filter,rpm_param->p.pic_header_loop_filter_disable_flag,
+			ctx->info.bit_depth_input,ctx->info.bit_depth_internal,ctx->info.log2_max_cuwh);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: alphaCOffset(%d crop to %d),betaOffset(%d crop to %d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+			rpm_param->p.pic_header_alpha_c_offset, alpha_c_offset, rpm_param->p.pic_header_beta_offset, beta_offset,
+			rpm_param->p.pic_header_chroma_quant_param_delta_cb,rpm_param->p.pic_header_chroma_quant_param_delta_cr);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: .done.\n");
+
+}
+
+static void reconstructCoefficients(struct AVS3Decoder_s *dec, ALFParam *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->coeff_multi[g][i]);
+		dec->m_filterCoeffSym[g][i] = alfParam->coeff_multi[g][i];
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"[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->coeff_multi[g][alfParam->num_coeff - 1];
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[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 AVS3Decoder_s *dec, int32_t compIdx, ALFParam *alfParam)
+{
+	int32_t i;
+	if (compIdx == ALF_Y) {
+		if (alfParam->filters_per_group > 1) {
+		for (i = 1; i < NO_VAR_BINS; ++i) {
+			if (alfParam->filter_pattern[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_fb(struct AVS3Decoder_s *dec)
+{
+	/*
+	* Picture level ALF parameter configuration here
+	*/
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	uint32_t data32;
+	int32_t i,j;
+	int32_t m_filters_per_group;
+#ifdef USE_FORCED_ALF_PARAM
+	ALFParam forced_alf_cr;
+	forced_alf_cr.alf_flag = 1;
+	forced_alf_cr.num_coeff = 9;
+	forced_alf_cr.filters_per_group = 1;
+	forced_alf_cr.component_id = 2;
+	forced_alf_cr.coeff_multi[0][0] = -3;
+	forced_alf_cr.coeff_multi[0][1] = -3;
+	forced_alf_cr.coeff_multi[0][2] = 4;
+	forced_alf_cr.coeff_multi[0][3] = 7;
+	forced_alf_cr.coeff_multi[0][4] = 6;
+	forced_alf_cr.coeff_multi[0][5] = -1;
+	forced_alf_cr.coeff_multi[0][6] = 3;
+	forced_alf_cr.coeff_multi[0][7] = 6;
+	forced_alf_cr.coeff_multi[0][8] = 0;
+#endif
+
+	ALFParam *m_alfPictureParam_y = &avs3_dec->m_alfPictureParam[0];
+	ALFParam *m_alfPictureParam_cb = &avs3_dec->m_alfPictureParam[1];
+#ifdef USE_FORCED_ALF_PARAM
+	ALFParam *m_alfPictureParam_cr = &forced_alf_cr; // &avs3_dec->m_alfPictureParam[2];
+#else
+	ALFParam *m_alfPictureParam_cr = &avs3_dec->m_alfPictureParam[2];
+#endif
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filter_pattern[0]=0x%x,[15]=0x%x\n",
+			m_alfPictureParam_y->component_id,
+			m_alfPictureParam_y->alf_flag,
+			m_alfPictureParam_y->filters_per_group,
+			m_alfPictureParam_y->filter_pattern[0],m_alfPictureParam_y->filter_pattern[15]);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[t]alfy,num_coeff(%d),coeff_multi[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->coeff_multi[0][0],
+			m_alfPictureParam_y->coeff_multi[0][1],
+			m_alfPictureParam_y->coeff_multi[1][0],
+			m_alfPictureParam_y->coeff_multi[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);
+	WRITE_BACK_32(avs3_dec, 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);
+	WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+	avs3_print(dec, AVS3_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);
+	WRITE_BACK_32(avs3_dec, 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);
+	WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+	avs3_print(dec, AVS3_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);
+	WRITE_BACK_32(avs3_dec, 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);
+	WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+	avs3_print(dec, AVS3_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);
+		WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+		data32 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+			((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);
+		WRITE_BACK_32(avs3_dec, HEVC_DBLK_CFGD, data32);
+		avs3_print(dec, AVS3_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]);
+	}
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgALF .done.\n");
+}
+
+static void  config_mcrcc_axi_hw_fb(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	//uint32_t rdata32;
+	//uint32_t rdata32_2;
+
+	///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+	WRITE_BACK_8(avs3_dec, HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+	if (avs3_dec->slice_type == SLICE_I) {
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+		WRITE_BACK_8(avs3_dec, HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+		return;
+	}
+
+#if 0
+	mcrcc_get_hitrate();
+	decomp_get_hitrate();
+	decomp_get_comprate();
+#endif
+	if ((avs3_dec->slice_type == SLICE_B) || (avs3_dec->slice_type == SLICE_P)) {
+		// Programme canvas0
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+		WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 0);
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+	READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+		// Programme canvas1
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (1<<1) | 0);
+		WRITE_BACK_16(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, 1, (16 << 8) | (1<<1) | 0);
+		///rdata32_2 = READ_VREG_V(P_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_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///    rdata32_2 = rdata32_2 & 0xffff;
+		///    rdata32_2 = rdata32_2 | ( rdata32_2 << 16);
+		///}
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32_2);
+	READ_CMP_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 1, 0, 16, 16);
+	} else { // P-PIC
+		///WRITE_VREG_V(P_HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+		WRITE_BACK_8(avs3_dec, HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (1<<1) | 0);
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL2, rdata32);
+	READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL2, 0, 16, 16);
+
+		// Programme canvas1
+		///rdata32 = READ_VREG_V(P_HEVCD_MPP_ANC_CANVAS_DATA_ADDR);
+		///rdata32 = rdata32 & 0xffff;
+		///rdata32 = rdata32 | ( rdata32 << 16);
+		///WRITE_VREG_V(P_HEVCD_MCRCC_CTL3, rdata32);
+	READ_INS_WRITE(avs3_dec, HEVCD_MPP_ANC_CANVAS_DATA_ADDR, HEVCD_MCRCC_CTL3, 0, 16, 16);
+	}
+
+	///WRITE_VREG_V(P_HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+	WRITE_BACK_16(avs3_dec, HEVCD_MCRCC_CTL1, 0, 0xff0); // enable mcrcc progressive-mode
+	return;
+}
+
+#endif
diff --git a/drivers/frame_provider/decoder/avs3/avs3_global.h b/drivers/frame_provider/decoder/avs3/avs3_global.h
new file mode 100644
index 0000000..e3d6087
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/avs3_global.h
@@ -0,0 +1,561 @@
+#ifndef AVS3_GLOBAL_H_
+#define AVS3_GLOBAL_H_
+
+//#define DEBUG_AMRISC
+
+#define LINUX
+#define NEW_FB_CODE
+#define NEW_FRONT_BACK_CODE
+#define LARGE_INSTRUCTION_SPACE_SUPORT
+#define BUFMGR_SANITY_CHECK
+
+#define P010_ENABLE
+
+#define OW_TRIPLE_WRITE
+
+#include "com_def.h"
+
+#ifdef SIMULATION
+#ifdef SYSTEM_TEST
+#define printf st_printf
+#define printk st_printf
+#else
+#define printf io_printf
+#define printk io_printf
+#endif
+#endif
+
+#define WITH_OLD_CODE
+
+#define RPM_BEGIN                                              0x080  //0x100
+#define ALF_BEGIN                                              0x100  //0x180
+#define RPM_END                                                0x200  //0x280
+#define RPM_VALID_END                                          0x1b8
+
+
+typedef union param_u {
+	struct {
+		unsigned short data[RPM_END - RPM_BEGIN];
+	} l;
+	struct {
+
+		/*sequence head*/
+		unsigned short sqh_profile_id;
+		unsigned short sqh_level_id;
+		unsigned short sqh_progressive_sequence;
+		unsigned short sqh_field_coded_sequence;
+		unsigned short sqh_library_stream_flag;
+		unsigned short sqh_library_picture_enable_flag;
+		unsigned short sqh_horizontal_size;
+		unsigned short sqh_vertical_size;
+		unsigned short sqh_sample_precision;
+		unsigned short sqh_encoding_precision;
+		unsigned short sqh_aspect_ratio;
+		unsigned short sqh_frame_rate_code;
+		unsigned short sqh_low_delay;
+		unsigned short sqh_temporal_id_enable_flag;
+		unsigned short sqh_max_dpb_size;
+		unsigned short sqh_num_ref_default_active_minus1[2];
+		unsigned short sqh_log2_max_cu_width_height;
+		unsigned short sqh_adaptive_leveling_filter_enable_flag;
+		unsigned short sqh_num_of_hmvp_cand;
+		unsigned short sqh_output_reorder_delay;
+		unsigned short sqh_cross_patch_loop_filter;
+		/*picture head*/
+		unsigned short pic_header_decode_order_index;
+		unsigned short pic_header_picture_output_delay;
+		unsigned short pic_header_progressive_frame;
+		unsigned short pic_header_top_field_first;
+		unsigned short pic_header_repeat_first_field;
+		unsigned short pic_header_ref_pic_list_sps_flag[2];
+		unsigned short pic_header_rpl_l0_idx;
+		unsigned short pic_header_rpl_l1_idx;
+		unsigned short pic_header_rpl_l0_ref_pic_num;
+		unsigned short pic_header_rpl_l0_ref_pics_ddoi[17];
+		unsigned short pic_header_rpl_l1_ref_pic_num;
+		unsigned short pic_header_rpl_l1_ref_pics_ddoi[17];
+		unsigned short pic_header_rpl_l0_reference_to_library_enable_flag;
+		unsigned short pic_header_rpl_l0_library_index_flag[17];
+		unsigned short pic_header_rpl_l1_reference_to_library_enable_flag;
+		unsigned short pic_header_rpl_l1_library_index_flag[17];
+		unsigned short pic_header_loop_filter_disable_flag;
+		unsigned short pic_header_random_access_decodable_flag;
+		unsigned short pic_header_slice_type;
+		unsigned short pic_header_num_ref_idx_active_override_flag;
+		unsigned short pic_header_rpl_l0_ref_pic_active_num;
+		unsigned short pic_header_rpl_l1_ref_pic_active_num;
+		/*patch head*/
+		/**/
+		unsigned short sqh_adaptive_filter_shape_enable_flag;
+		unsigned short pic_header_library_picture_index;
+		unsigned short pic_header_top_field_picture_flag;
+		unsigned short pic_header_alpha_c_offset;
+		unsigned short pic_header_beta_offset;
+		unsigned short pic_header_chroma_quant_param_delta_cb;
+		unsigned short pic_header_chroma_quant_param_delta_cr;
+//HDR10
+		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 dir_index;
+		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;
+}param_t;
+
+/******************************************************************************
+ * CONTEXT used for decoding process.
+ *
+ * All have to be stored are in this structure.
+ *****************************************************************************/
+typedef struct _DEC_CTX DEC_CTX;
+struct _DEC_CTX
+{
+	COM_INFO              info;
+	/* magic code */
+	u32                   magic;
+	/* DEC identifier */
+	DEC                   id;
+	/* CORE information used for fast operation */
+	//DEC_CORE             *core;
+	/* current decoding bitstream */
+	//COM_BSR               bs;
+
+	/* decoded picture buffer management */
+	COM_PM                dpm;
+	/* create descriptor */
+	DEC_CDSC              cdsc;
+
+	/* current decoded (decoding) picture buffer */
+	COM_PIC              *pic;
+#if EVS_UBVS_MODE
+	pel                   dpb_evs[N_C][MAX_SRB_PRED_SIZE];
+#endif
+	/* SBAC */
+	//DEC_SBAC              sbac_dec;
+	u8                    init_flag;
+
+	COM_MAP               map;
+#if CHROMA_NOT_SPLIT
+	u8                    tree_status;
+#endif
+#if MODE_CONS
+	u8                    cons_pred_mode;
+#endif
+
+	/* total count of remained LCU for decoding one picture. if a picture is
+	decoded properly, this value should reach to zero */
+	int                   lcu_cnt;
+
+	int                 **edge_filter[LOOPFILTER_DIR_TYPE];
+
+	COM_PIC              *pic_sao;
+	SAO_STAT_DATA        ***sao_stat_data; //[SMB][comp][types]
+	SAO_BLK_PARAM         **sao_blk_params; //[SMB][comp]
+	SAO_BLK_PARAM         **rec_sao_blk_params;//[SMB][comp]
+
+#if ESAO
+	COM_PIC              *pic_esao;  //rec buff after deblock filter
+	ESAO_BLK_PARAM          pic_esao_params[N_C];//comp]
+	ESAO_FUNC_POINTER       func_esao_block_filter;
+#endif
+
+#if CCSAO
+#if CCSAO_ENHANCEMENT
+	COM_PIC              *pic_ccsao[2];
+#else
+	COM_PIC              *pic_ccsao;
+#endif
+#if !CCSAO_PH_SYNTAX
+	CCSAO_BLK_PARAM       pic_ccsao_params[N_C-1];
+#endif
+	CCSAO_FUNC_POINTER    ccsao_func_ptr;
+#endif
+
+	COM_PIC              *pic_alf_Dec;
+	COM_PIC              *pic_alf_Rec;
+	int                   pic_alf_on[N_C];
+	int                ***coeff_all_to_write_alf;
+	//DEC_ALF_VAR            *dec_alf;
+
+	u8                    ctx_flags[NUM_CNID];
+
+	/**************************************************************************/
+	/* current slice number, which is increased whenever decoding a slice.
+	when receiving a slice for new picture, this value is set to zero.
+	this value can be used for distinguishing b/w slices */
+	u16                   slice_num;
+	/* last coded intra picture's presentation temporal reference */
+	int                   last_intra_ptr;
+	/* current picture's decoding temporal reference */
+	int                   dtr;
+	/* previous picture's decoding temporal reference low part */
+	int                   dtr_prev_low;
+	/* previous picture's decoding temporal reference high part */
+	int                   dtr_prev_high;
+	/* current picture's presentation temporal reference */
+	int                   ptr;
+	/* the number of currently decoded pictures */
+	int                   pic_cnt;
+	/* picture buffer allocator */
+	PICBUF_ALLOCATOR      pa;
+	/* bitstream has an error? */
+	u8                    bs_err;
+	/* reference picture (0: forward, 1: backward) */
+	COM_REFP              refp[MAX_NUM_REF_PICS][REFP_NUM];
+	/* flag for picture signature enabling */
+	u8                    use_pic_sign;
+	/* picture signature (MD5 digest 128bits) */
+	u8                    pic_sign[16];
+	/* flag to indicate picture signature existing or not */
+	u8                    pic_sign_exist;
+	//AmlDbg*               amldbg;
+
+#if PATCH
+	int                   patch_column_width[64];
+	int                   patch_row_height[128];
+	PATCH_INFO           *patch;
+#endif
+
+	u8                   *wq[2];
+#if CUDQP
+	COM_CU_QP_GROUP       cu_qp_group;
+#endif
+};
+
+#ifdef WITH_OLD_CODE
+#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
+
+enum ALFComponentID {
+	ALF_Y = 0,
+	ALF_Cb,
+	ALF_Cr,
+	NUM_ALF_COMPONENT
+};
+
+#if 0
+typedef struct {
+	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;
+} ALFParam;
+#endif
+
+typedef ALF_PARAM ALFParam;
+
+#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
+
+typedef struct {
+	//int32_t typeb;
+	//int32_t type;
+	//int32_t tr;                                     //<! temporal reference, 8 bit,
+	int32_t width;                   //!< Number of pels
+	int32_t height;                  //!< Number of lines
+	int32_t num_of_references;
+	int32_t            pic_alf_on[NUM_ALF_COMPONENT];
+	//int32_t is_field_sequence;
+	//int32_t is_top_field;
+	int number;
+} ImageParameters;
+
+struct inp_par {
+	u32 sample_bit_depth;
+	u32 alf_enable;
+};
+#else
+#define PIC_POOL_SIZE 32
+#endif
+
+//new dual
+struct buff_s {
+	u32 buf_start;
+	u32 buf_size;
+	u32 buf_end;
+};
+typedef struct buff_s buff_t;
+
+#ifdef NEW_FRONT_BACK_CODE
+#define MAX_FB_IFBUF_NUM             16
+typedef struct {
+	uint32_t mmu0_ptr;
+	uint32_t mmu1_ptr;
+	uint32_t scalelut_ptr;
+	uint32_t vcpu_imem_ptr;
+	uint32_t sys_imem_ptr;
+	uint32_t lmem0_ptr;
+	uint32_t lmem1_ptr;
+	uint32_t parser_sao0_ptr;
+	uint32_t parser_sao1_ptr;
+	uint32_t mpred_imp0_ptr;
+	uint32_t mpred_imp1_ptr;
+	//
+	uint32_t scalelut_ptr_pre;
+	//for linux
+	void *sys_imem_ptr_v;
+} buff_ptr_t;
+#endif
+
+typedef struct avs3_decoder {
+#ifdef WITH_OLD_CODE
+	uint8_t init_hw_flag;
+	struct inp_par   input;
+	ImageParameters  img;
+	//Video_Com_data  hc;
+	//Video_Dec_data  hd;
+	//union param_u param;
+	//avs3_frame_t *fref[REF_MAXBUFFER];
+#ifdef AML
+	/*used for background
+	when background_picture_output_flag is 0*/
+	//avs3_frame_t *m_bg;
+	/*current background picture, ether m_bg or fref[..]*/
+	avs3_frame_t *f_bg;
+#endif
+	//outdata outprint;
+	uint32_t cm_header_start;
+	ALF_PARAM m_alfPictureParam[N_C];
+	ALF_PARAM *p_alfPictureParam[N_C];
+/*#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;
+#endif
+/*WITH_OLD_CODE*/
+#endif
+	union param_u param;
+	DEC_CTX ctx;
+	DEC_STAT stat;
+	COM_PIC  pic_pool[MAX_PB_SIZE];
+	LibVCData libvc_data;
+	unsigned int dec_status;
+	avs3_frame_t *cur_pic;
+	avs3_frame_t *col_pic;
+	u8 slice_type;
+	u8 seq_change_flag;
+	int decode_id;
+/**/
+#ifdef NEW_FRONT_BACK_CODE
+	uint8_t wait_working_buf;
+	uint8_t front_pause_flag; /*multi pictures in one packe*/
+	/*FB mgr*/
+	uint8_t fb_wr_pos;
+	uint8_t fb_rd_pos;
+	buff_t fb_buf_mmu0;
+	buff_t fb_buf_mmu1;
+	buff_t fb_buf_scalelut;
+	buff_t fb_buf_vcpu_imem;
+	buff_t fb_buf_sys_imem;
+	buff_t fb_buf_lmem0;
+	buff_t fb_buf_lmem1;
+	buff_t fb_buf_parser_sao0;
+	buff_t fb_buf_parser_sao1;
+	buff_t fb_buf_mpred_imp0;
+	buff_t fb_buf_mpred_imp1;
+	uint32_t frontend_decoded_count;
+	uint32_t backend_decoded_count;
+	buff_ptr_t fr;
+	buff_ptr_t bk;
+	buff_ptr_t init_fr;
+	buff_ptr_t p_fr;
+	buff_ptr_t next_bk[MAX_FB_IFBUF_NUM];
+	avs3_frame_t* next_be_decode_pic[MAX_FB_IFBUF_NUM];
+	/**/
+	/*for WRITE_BACK_RET*/
+	uint32_t sys_imem_ptr;
+	void *sys_imem_ptr_v;
+	void *fb_buf_sys_imem_addr;
+	uint32_t  instruction[256*4]; //avoid code crash, but only 256 used
+	uint32_t  ins_offset;
+#endif
+#ifdef AML
+	int max_pb_size;
+	int8_t bufmgr_error_flag;
+	u64 start_time;
+	//int32_t ref_maxbuffer;
+#endif
+} avs3_decoder_t;
+
+void avs3_bufmgr_init(struct avs3_decoder *hw);
+
+int com_picman_out_libpic(COM_PIC * pic, int library_picture_index, COM_PM * pm);
+COM_PIC * com_picman_out_pic(COM_PM * pm, int * err, int cur_pic_doi, int state);
+int com_picman_deinit(COM_PM * pm);
+int com_picman_init(COM_PM * pm, int max_pb_size, int max_num_ref_pics, PICBUF_ALLOCATOR * pa);
+int com_picman_dpbpic_doi_minus_cycle_length( COM_PM *pm );
+int com_picman_check_repeat_doi(COM_PM * pm, COM_PIC_HEADER * pic_header);
+int com_construct_ref_list_doi( COM_PIC_HEADER *pic_header );
+int com_picman_refpic_marking_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header);
+int com_cleanup_useless_pic_buffer_in_pm( COM_PM *pm );
+int com_picman_refp_rpl_based_init_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM]);
+void com_picman_print_state(COM_PM * pm);
+COM_PIC * com_picman_get_empty_pic(COM_PM * pm, int * err);
+int com_picman_put_libpic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM], COM_PIC_HEADER * pic_header);
+int com_picman_put_pic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr,
+	u32 picture_output_delay, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM]);
+void com_pic_free(struct avs3_decoder *hw, PICBUF_ALLOCATOR *pa, COM_PIC *pic);
+COM_PIC * com_pic_alloc(struct avs3_decoder *hw, PICBUF_ALLOCATOR * pa, int * ret);
+
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code);
+int dec_eco_patch_header(union param_u *param, COM_SQH *sqh, COM_PIC_HEADER * ph, COM_SH_EXT * sh,PATCH_INFO *patch);
+int dec_eco_sqh(union param_u *param, COM_SQH * sqh);
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code);
+int dec_eco_alf_coeff(union param_u *rpm_param, ALF_PARAM *alf_param);
+int dec_eco_alf_param(union param_u *rpm_param, COM_PIC_HEADER *sh
+#if ALF_SHAPE
+				, int num_coef
+#endif
+#if ALF_IMP
+	, int max_filter_num
+#endif
+);
+
+#define AVS3_DBG_BUFMGR                   0x01
+#define AVS3_DBG_IRQ_EVENT                0x02
+#define AVS3_DBG_BUFMGR_MORE              0x04
+#define AVS3_DBG_BUFMGR_DETAIL            0x08
+#define AVS3_DBG_PRINT_PARAM              0x10
+#define AVS3_DBG_PRINT_PIC_LIST           0x20
+#define AVS3_DBG_OUT_PTS                  0x40
+#define AVS3_DBG_PRINT_SOURCE_LINE        0x80
+#define AVS3_DBG_SEND_PARAM_WITH_REG      0x100
+#define AVS3_DBG_MERGE                    0x200
+#define AVS3_DBG_NOT_RECYCLE_MMU_TAIL     0x400
+#define AVS3_DBG_REG                      0x800
+#define AVS3_DBG_PIC_LEAK                 0x1000
+#define AVS3_DBG_PIC_LEAK_WAIT            0x2000
+#define AVS3_DBG_HDR_INFO                 0x4000
+#define AVS3_DBG_QOS_INFO                 0x8000
+#define AVS3_DBG_DIS_LOC_ERROR_PROC       0x10000
+#define AVS3_DBG_DIS_SYS_ERROR_PROC   0x20000
+#define AVS3_DBG_DUMP_PIC_LIST       0x40000
+#define AVS3_DBG_TRIG_SLICE_SEGMENT_PROC 0x80000
+#define AVS3_DBG_DISABLE_IQIT_SCALELUT_INIT  0x100000
+//#define AVS3_DBG_BE_SIMULATE_IRQ       0x200000
+#define AVS3_DBG_SAO_CRC                0x200000
+#define AVS3_DBG_FORCE_SEND_AGAIN       0x400000
+#define AVS3_DBG_DUMP_DATA              0x800000
+#define AVS3_DBG_DUMP_LMEM_BUF         0x1000000
+#define AVS3_DBG_DUMP_RPM_BUF          0x2000000
+#define AVS3_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
+
+u32 avs3_get_debug_flag(void);
+
+bool is_avs3_print_bufmgr_detail(void);
+
+struct AVS3Decoder_s;
+
+extern u32 debug_mask;
+extern	int avs3_debug(struct AVS3Decoder_s *dec,
+		int flag, const char *fmt, ...);
+
+
+#define avs3_print(dec, flag, fmt, args...)					\
+	do {									\
+		if (dec == NULL ||    \
+			(flag == 0) || \
+			((debug_mask & \
+			(1 << dec->index)) \
+		&& (debug & flag))) { \
+			avs3_debug(dec, flag, fmt, ##args);	\
+			} \
+	} while (0)
+
+//int avs3_print(struct AVS3Decoder_s *dec,
+//	int flag, const char *fmt, ...);
+#define assert(x)
+#ifdef DEBUG_AMRISC
+#ifndef DEBUG_RELEASE_MODE
+#define printf(...) do {\
+	if (is_avs3_print_bufmgr_detail()) \
+	avs3_debug(NULL, 0, __VA_ARGS__); \
+} while (0)
+
+#define PRINT_LINE() \
+	do { \
+	if (avs3_get_debug_flag() & AVS3_DBG_PRINT_SOURCE_LINE)\
+	avs3_debug(NULL, 0, "%s line %d\n", __func__, __LINE__);\
+	} while (0)
+#else
+#define printf(...) do {\
+		; \
+	} while (0)
+
+#define PRINT_LINE() \
+		do { \
+		; \
+		} while (0)
+#endif
+#else
+
+#define printf(...) do {\
+	if (is_avs3_print_bufmgr_detail()) \
+	printk(__VA_ARGS__); \
+} while (0)
+
+#define PRINT_LINE() \
+	do { \
+	if (avs3_get_debug_flag() & AVS3_DBG_PRINT_SOURCE_LINE)\
+	pr_info("%s line %d\n", __func__, __LINE__);\
+	} while (0)
+
+#endif
+
+void create_alf_global_buffer(DEC_CTX *ctx);
+//void init_pic_list(struct avs3_decoder *hw);
+COM_PIC *dec_pull_frm(DEC_CTX *ctx, int state);
+void print_pic_pool(struct avs3_decoder *hw, char *mark);
+void init_pic_pool(struct avs3_decoder *hw);
+int avs3_bufmgr_process(struct avs3_decoder *hw, int start_code);
+int avs3_bufmgr_post_process(struct avs3_decoder *hw);
+void avs3_cleanup_useless_pic_buffer_in_pm(struct avs3_decoder *hw);
+void print_alf_param(union param_u * param);
+void print_param(union param_u * param);
+int avs3_get_error_policy(void);
+
+#endif
+
diff --git a/drivers/frame_provider/decoder/avs3/com_def.h b/drivers/frame_provider/decoder/avs3/com_def.h
new file mode 100644
index 0000000..b91b377
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_def.h
@@ -0,0 +1,2736 @@
+/* ====================================================================================================================
+
+	The copyright in this software is being made available under the 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) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+	Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+	Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+	Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted only for
+	the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+	promoting such standards. The following conditions are required to be 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.
+	* The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be 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.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_DEF_H_
+#define _COM_DEF_H_
+#define AML
+
+#include "com_typedef.h"
+#include "com_port.h"
+#include <linux/amlogic/media/utils/amstream.h>
+
+#if TSCPM
+#define MAX_INT                     2147483647  ///< max. value of signed 32-bit integer
+#endif
+
+/* profile & level */
+#if PHASE_2_PROFILE
+#define PROFILE_ID 0x32
+#else
+#define PROFILE_ID 0x22
+#endif
+#define LEVEL_ID 0x6A
+
+/* MCABAC (START) */
+#define PROB_BITS                         11 // LPS_PROB(10-bit) + MPS(1-bit)
+#define PROB_MASK                         ((1 << PROB_BITS) - 1) // mask for LPS_PROB + MPS
+#define MAX_PROB                          ((1 << PROB_BITS) - 1) // equal to PROB_LPS + PROB_MPS, 0x7FF
+#define HALF_PROB                         (MAX_PROB >> 1)
+#define QUAR_HALF_PROB                    (1 << (PROB_BITS-3))
+#define LG_PMPS_SHIFTNO                   2
+#if CABAC_MULTI_PROB
+#define PROB_INIT                         (HALF_PROB << 1) + (HALF_PROB << PROB_BITS)
+#else
+#define PROB_INIT                         (HALF_PROB << 1) /* 1/2 of initialization = (HALF_PROB << 1)+ MPS(0) */
+#endif
+#define READ_BITS_INIT                    16
+#define DEC_RANGE_SHIFT                   (READ_BITS_INIT-(PROB_BITS-2))
+
+#define COM_BSR_IS_BYTE_ALIGN(bs)         !((bs)->leftbits & 0x7)
+
+#if CABAC_MULTI_PROB
+#define MAX_WINSIZE                        9
+#define MIN_WINSIZE                        2
+#define MCABAC_SHIFT_I                     5
+#define MCABAC_SHIFT_B                     5
+#define MCABAC_SHIFT_P                     5
+#define CYCNO_SHIFT_BITS                   21   // PROB_BITS
+#define MCABAC_PROB_BITS                   10
+#define MCABAC_PROB_MASK                   ((1 << MCABAC_PROB_BITS) - 1)
+#define COUNTER_THR_I                      8
+#define COUNTER_THR_B                      16
+#define COUNTER_THR_P                      16
+#endif
+
+/* MCABAC (END) */
+
+/* Multiple Reference (START) */
+#define MAX_NUM_ACTIVE_REF_FRAME_B         2  /* Maximum number of active reference frames for RA condition */
+#define MAX_NUM_ACTIVE_REF_FRAME_LDB       4  /* Maximum number of active reference frames for LDB condition */
+#define MV_SCALE_PREC                      14 /* Scaling precision for motion vector prediction (2^MVP_SCALING_PRECISION) */
+/* Multiple Reference (END) */
+
+/* Max. and min. Quantization parameter */
+#define MIN_QUANT                          0
+#define MAX_QUANT_BASE                     63
+
+/* BIO (START) */
+#if BIO
+#define BIO_MAX_SIZE                      128
+#define BIO_CLUSTER_SIZE                  4
+#define BIO_WINDOW_SIZE                   0
+#define BIO_AVG_WIN_SIZE                  (BIO_CLUSTER_SIZE + (BIO_WINDOW_SIZE << 1))
+#define LIMITBIO                          768
+#define DENOMBIO                          2
+#endif
+/* BIO (END) */
+
+/* IST (START)*/
+#if IST
+#define IST_MAX_COEF_SIZE                  16
+#endif
+/* IST (END)*/
+
+/* SBT (START) */
+#if SBT
+#define get_sbt_idx(s)                     (s & 0xf)
+#define get_sbt_pos(s)                     ((s>>4) & 0xf)
+#define get_sbt_info(idx, pos)             (idx + (pos << 4))
+#define is_sbt_horizontal(idx)             (idx == 2 || idx == 4)
+#define is_sbt_quad_size(idx)              (idx == 3 || idx == 4)
+//encoder only
+#define SBT_FAST                           1 // early skip fast algorithm
+#define SBT_SAVELOAD                       1 // save & load
+#endif
+/* SBT (END) */
+
+/* AMVR (START) */
+#define MAX_NUM_MVR                        5  /* 0 (1/4-pel) ~ 4 (4-pel) */
+#if BD_AFFINE_AMVR
+#define MAX_NUM_AFFINE_MVR                 3
+#endif
+#define FAST_MVR_IDX                       2
+#define SKIP_MVR_IDX                       1
+#if BIO
+#define BIO_MAX_MVR                        1
+#endif
+/* AMVR (END)  */
+
+/* ABVR (START) */
+#if IBC_ABVR
+#define MAX_NUM_BVR                        2 /* 1/4-pel */
+#endif
+/* ABVR (END) */
+
+/* DB_AVS2 (START) */
+#define EDGE_TYPE_LUMA                     1
+#define EDGE_TYPE_ALL                      2
+#define LOOPFILTER_DIR_TYPE                2
+#define LOOPFILTER_SIZE_IN_BIT             2
+#define LOOPFILTER_SIZE                    (1 << LOOPFILTER_SIZE_IN_BIT)
+#define LOOPFILTER_GRID                    8
+#define DB_CROSS_SLICE                     1
+/* DB_AVS2 (END) */
+
+/* SAO_AVS2 (START) */
+#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 NUM_SAO_EO_TYPES_LOG2              2
+#define NUM_SAO_BO_CLASSES                 (1<<NUM_SAO_BO_CLASSES_LOG2)
+#define SAO_SHIFT_PIX_NUM                  4
+/* SAO_AVS2 (END) */
+
+/* ESAO_AVS3 (START) */
+#if ESAO
+#define ESAO_LUMA_TYPES                    2  // 1 : only 17 classes; 2: both 17 and 9 classes are applied
+#define NUM_ESAO_LUMA_TYPE0                17   //
+#define NUM_ESAO_LUMA_TYPE1                9
+
+//Y
+#define ESAO_LABEL_NUM_Y                   16   //
+#define ESAO_LABEL_NUM_IN_BIT_Y            4 //bits
+#define ESAO_LABEL_CLASSES_Y               272  //16*17
+//U
+#define ESAO_LABEL_NUM_U                   96
+#define ESAO_LABEL_NUM_IN_BIT_U            7
+#define ESAO_LABEL_CLASSES_U               272
+//V
+#define ESAO_LABEL_NUM_V                   96
+#define ESAO_LABEL_NUM_IN_BIT_V            7
+#define ESAO_LABEL_CLASSES_V               272
+
+//maximum value among  Y, U and V
+#define ESAO_LABEL_NUM_MAX                 96
+#define ESAO_LABEL_NUM_IN_BIT_MAX          7
+#define ESAO_LABEL_CLASSES_MAX             272
+#endif
+/* ESAO_AVS3 (END) */
+
+#if CCSAO
+/* CCSAO_AVS3 (START) */
+#if CCSAO_ENHANCEMENT
+#define CCSAO_SET_NUM                      4
+#define CCSAO_SET_NUM_BIT                  2
+#endif
+
+#define CCSAO_TYPE_NUM                     9
+#define CCSAO_TYPE_NUM_BIT                 4
+
+#define CCSAO_BAND_NUM                     16
+#define CCSAO_BAND_NUM_BIT                 4
+
+#if CCSAO_ENHANCEMENT
+#define CCSAO_BAND_NUM_C                   2
+#define CCSAO_BAND_NUM_BIT_C               1
+#define CCSAO_CLASS_NUM                    (CCSAO_BAND_NUM * CCSAO_BAND_NUM_C)
+#else
+#define CCSAO_CLASS_NUM                    CCSAO_BAND_NUM
+#endif
+/* CCSAO_AVS3 (END) */
+#endif
+
+/* ALF_AVS2 (START) */
+#if ALF_SHAPE
+#define ALF_MAX_NUM_COEF_SHAPE2            15
+#endif
+#define ALF_MAX_NUM_COEF                   9
+#if ALF_IMP
+#define ITER_NUM                            4
+#define INTERVAL_NUM_X 8
+#define INTERVAL_NUM_Y 8
+#define NO_VAR_BINS                        INTERVAL_NUM_X*INTERVAL_NUM_Y
+#define NO_VAR_BINS_16                     16
+#else
+#define NO_VAR_BINS                        16
+#endif
+#define ALF_REDESIGN_ITERATION             3
+#define LOG2_VAR_SIZE_H                    2
+#define LOG2_VAR_SIZE_W                    2
+#define ALF_FOOTPRINT_SIZE                 7
+#define DF_CHANGED_SIZE                    3
+#define ALF_NUM_BIT_SHIFT                  6
+/* ALF_AVS2 (END) */
+
+/* DMVR_AVS2 (START) */
+#if DMVR
+#define DMVR_IMPLIFICATION_SUBCU_SIZE      16
+#define DMVR_ITER_COUNT                    2
+#define REF_PRED_POINTS_NUM                9
+#define REF_PRED_EXTENTION_PEL_COUNT       1
+#define REF_PRED_POINTS_PER_LINE_NUM       3
+#define REF_PRED_POINTS_LINES_NUM          3
+#define DMVR_NEW_VERSION_ITER_COUNT        8
+#endif
+/* DMVR_AVS2 (END) */
+
+/* INTERPF_AVS2 (START) */
+#if INTERPF
+#define NUM_RDO_INTER_FILTER               6  //number of additional RDO
+#endif
+/* INTERPF_AVS2 (END) */
+
+/* IBC (START) */
+#if USE_IBC
+#define IBC_SEARCH_RANGE                     64
+#define IBC_NUM_CANDIDATES                   64
+#define IBC_FAST_METHOD_BUFFERBV             0X01
+#define IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE 0X02
+#define IBC_BITSTREAM_FLAG_RESTRIC_LOG2      6 // restrict coded flag size
+#define IBC_MAX_CU_LOG2                      4 /* max block size for ibc search in unit of log2 */
+#define IBC_MAX_CAND_SIZE                    (1 << IBC_MAX_CU_LOG2)
+#if BVD_CODING
+#define BVD_EXG_ORDER                        2
+#endif
+#endif
+/* IBC (END) */
+
+/* BVP (START) */
+#if IBC_BVP
+#define ALLOWED_HBVP_NUM                   12
+#define MAX_NUM_BVP                        7
+#define CBVP_TH_SIZE                       32
+#define CBVP_TH_CNT                        2
+#endif
+/* BVP (END) */
+
+/* SP (START) */
+#if USE_SP
+#if SP_SVP
+#define SP_SEARCH_RANGE                     64
+#endif
+#define SP_STRING_INFO_NO                  1024//  1 << ( MAX_CU_LOG2 + MAX_CU_LOG2 - 4)//64*64 / 4 = 1024 //number of max sp string_copy_info in a CU
+#define SP_MAX_SPS_CANDS                   256
+#define SP_RECENT_CANDS                    12
+#define SP_EXG_ORDER                       3
+#if EVS_UBVS_MODE
+#define MAX_CU_SIZE_IN_BIT                 6
+#define MAX_SRB_SIZE                       15
+#define MAX_SSRB_SIZE                      17
+#define MAX_SRB_PRED_SIZE                  28
+#define UV_WEIGHT                          0.25
+#define EVS_PV_MAX                         10
+#endif
+#define GET_TRAV_X(trav_idx, cu_width)                  ((trav_idx) & ((cu_width)-1))
+#define GET_TRAV_Y(trav_idx, cu_width_log2)             ((trav_idx) >> (cu_width_log2))
+#define IS_VALID_SP_CU_SIZE(cu_width, cu_height)        (((cu_width) < 4 || (cu_height) < 4 || (cu_width) > 32 || (cu_height) > 32) ? 0 : 1)
+#if EVS_UBVS_MODE
+#define IS_VALID_CS2_CU_SIZE(cu_width, cu_height)       (((cu_width) < 8 || (cu_height) < 8 || (cu_width) > 32 || (cu_height) > 32) ? 0 : 1)
+#endif
+#endif
+/* SP (END) */
+
+/* MVAP (START) */
+#if MVAP
+#define MIN_SUB_BLOCK_SIZE                 8
+typedef enum _MVAP_ANGULAR_PRED_MODE
+{
+	HORIZONTAL,                    ///< horizontal
+	VERTICAL,                      ///< vertical
+	HORIZONTAL_UP,                 ///< horizontal up
+	HORIZONTAL_DOWN,               ///< horizontal down
+	VERTICAL_RIGHT,                ///< vertical right
+	ALLOWED_MVAP_NUM = 5           ///< allowed mvap number
+} MVAP_ANGULAR_PRED_MODE;
+#endif
+/* MVAP (END) */
+
+/* ETMVP (START) */
+#if ETMVP
+#define MIN_ETMVP_SIZE                 8
+#define MIN_ETMVP_MC_SIZE              8
+#define MAX_ETMVP_NUM                  5
+#endif
+/* ETMVP (END) */
+
+/* Common stuff (START) */
+#if defined(_MSC_VER)
+#define ALIGNED_(x) __declspec(align(x))
+#define FORCE_INLINE __forceinline
+//#define INLINE __inline
+#else
+#if defined(__GNUC__)
+#define ALIGNED_(x) __attribute__ ((aligned(x)))
+#define FORCE_INLINE __attribute__((always_inline))
+//#define INLINE __inline__
+#endif
+#endif
+#if 0
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+typedef int BOOL;
+#define TRUE  1
+#define FALSE 0
+
+/* AFFINE (START) */
+#define VER_NUM                             4
+#define AFFINE_MAX_NUM_LT                   3 ///< max number of motion candidates in top-left corner
+#define AFFINE_MAX_NUM_RT                   2 ///< max number of motion candidates in top-right corner
+#define AFFINE_MAX_NUM_LB                   2 ///< max number of motion candidates in left-bottom corner
+#define AFFINE_MAX_NUM_RB                   1 ///< max number of motion candidates in right-bottom corner
+#define AFFINE_MIN_BLOCK_SIZE               4 ///< Minimum affine MC block size
+
+#define AFF_MAX_NUM_MRG                     5 // maximum affine merge candidates
+#define AFF_MODEL_CAND                      2 // maximum affine model based candidate
+
+#define MAX_MEMORY_ACCESS_BI                ((8 + 7) * (8 + 7) / 64)
+#define MAX_MEMORY_ACCESS_UNI               ((8 + 7) * (4 + 7) / 32)
+
+// AFFINE ME configuration (non-normative)
+#define AF_ITER_UNI                         7 // uni search iteration time
+#define AF_ITER_BI                          5 // bi search iteration time
+#define AFFINE_BI_ITER                      1
+
+#define AFF_SIZE                            16
+/* AFFINE (END) */
+
+/* MIPF (START) */
+#if MIPF
+#define MIPF_TH_SIZE                       64
+#define MIPF_TH_SIZE_CHROMA                32
+#define MIPF_TH_DIST                       1
+#define MIPF_TH_DIST_CHROMA                2
+#endif
+/* MIPF (END) */
+
+/* IPF (START) */
+#define NUM_IPF_CTX                         1 ///< number of context models for MPI Idx coding
+#if DT_PARTITION
+#define DT_INTRA_BOUNDARY_FILTER_OFF        1 ///< turn off boundary filter if intra DT is ON
+#endif
+/* IPF (END) */
+
+/* For debugging (START) */
+#define ENC_DEC_TRACE                       0
+#if ENC_DEC_TRACE
+#define MVF_TRACE                           0 ///< use for tracing MVF
+#define TRACE_REC                           0 ///< trace reconstructed pixels
+#define TRACE_RDO                           0 //!< Trace only encode stream (0), only RDO (1) or all of them (2)
+#define TRACE_BIN                           1 //!< trace each bin
+#if TRACE_RDO
+#define TRACE_RDO_EXCLUDE_I                 0 //!< Exclude I frames
+#endif
+extern FILE *fp_trace;
+extern int fp_trace_print;
+extern int fp_trace_counter;
+#if TRACE_RDO == 1
+#define COM_TRACE_SET(A) fp_trace_print=!A
+#elif TRACE_RDO == 2
+#define COM_TRACE_SET(A)
+#else
+#define COM_TRACE_SET(A) fp_trace_print=A
+#endif
+#define COM_TRACE_STR(STR) if (fp_trace_print) { fprintf(fp_trace, STR); fflush(fp_trace); }
+#define COM_TRACE_INT(INT) if (fp_trace_print) { fprintf(fp_trace, "%d ", INT); fflush(fp_trace); }
+#define COM_TRACE_COUNTER  COM_TRACE_INT(fp_trace_counter++); COM_TRACE_STR("\t")
+#define COM_TRACE_MV(X, Y) if (fp_trace_print) { fprintf(fp_trace, "(%d, %d) ", X, Y); fflush(fp_trace); }
+#define COM_TRACE_FLUSH    if (fp_trace_print) fflush(fp_trace)
+#else
+#define COM_TRACE_SET(A)
+#define COM_TRACE_STR(str)
+#define COM_TRACE_INT(INT)
+#define COM_TRACE_COUNTER
+#define COM_TRACE_MV(X, Y)
+#define COM_TRACE_FLUSH
+#endif
+/* For debugging (END) */
+
+#define STRIDE_IMGB2PIC(s_imgb)          ((s_imgb)>>1)
+
+#define Y_C                                0  /* Y luma */
+#define U_C                                1  /* Cb Chroma */
+#define V_C                                2  /* Cr Chroma */
+#define N_C                                3  /* number of color component */
+
+#define REFP_0                             0
+#define REFP_1                             1
+#define REFP_NUM                           2
+
+#if ST_CHROMA
+#define CHANNEL_LUMA                       0  /* Y Luma */
+#define CHANNEL_CHROMA                     1  /* Cb and Cr Chroma */
+#define MAX_NUM_CHANNEL                    2  /* number of color channel */
+#endif
+/* X direction motion vector indicator */
+#define MV_X                               0
+/* Y direction motion vector indicator */
+#define MV_Y                               1
+/* Maximum count (dimension) of motion */
+#define MV_D                               2
+
+#define N_REF                              2  /* left, up, right */
+
+#define NUM_NEIB                           1  //since SUCO is not implemented
+
+#define MINI_SIZE_LOG2                     3
+#define MINI_SIZE                          (1 << MINI_SIZE_LOG2)
+#define MAX_CU_LOG2                        7
+#define MIN_CU_LOG2                        2
+#define MAX_CU_SIZE                       (1 << MAX_CU_LOG2)
+#define MIN_CU_SIZE                       (1 << MIN_CU_LOG2)
+#define MAX_CU_DIM                        (MAX_CU_SIZE * MAX_CU_SIZE)
+#define MIN_CU_DIM                        (MIN_CU_SIZE * MIN_CU_SIZE)
+#define MAX_CU_DEPTH                       6  /* 128x128 ~ 4x4 */
+#if AWP
+#define AWP_ANGLE_NUM                     (8)
+#define AWP_RWFERENCE_SET_NUM             (7)
+#define AWP_MODE_NUM                      (AWP_ANGLE_NUM * AWP_RWFERENCE_SET_NUM)
+#define AWP_MV_LIST_LENGTH                 5
+#define MIN_AWP_SIZE_LOG2                  3 /*  8 */
+#define MAX_AWP_SIZE_LOG2                  6 /* 64 */
+#define MIN_AWP_SIZE                      (1 << MIN_AWP_SIZE_LOG2)
+#define MAX_AWP_SIZE                      (1 << MAX_AWP_SIZE_LOG2)
+#define MAX_AWP_DIM                       (MAX_AWP_SIZE * MAX_AWP_SIZE)
+
+// encoder para
+#define AWP_RDO_NUM                        7
+#define CANDIDATES_PER_PARTITION            2
+#endif
+#if AWP_MVR
+#define NUM_PARTITION_FOR_AWP_MVR_RD      42
+#endif
+#define MAX_TR_LOG2                        6  /* 64x64 */
+#define MIN_TR_LOG2                        1  /* 2x2 */
+#define MAX_TR_SIZE                        (1 << MAX_TR_LOG2)
+#define MIN_TR_SIZE                        (1 << MIN_TR_LOG2)
+#define MAX_TR_DIM                         (MAX_TR_SIZE * MAX_TR_SIZE)
+#define MIN_TR_DIM                         (MIN_TR_SIZE * MIN_TR_SIZE)
+
+#if TB_SPLIT_EXT
+#define MAX_NUM_PB                         4
+#define MAX_NUM_TB                         4
+#define PB0                                0  // default PB idx
+#define TB0                                0  // default TB idx
+#define TBUV0                              0  // default TB idx for chroma
+
+#define NUM_SL_INTER                       10
+#define NUM_SL_INTRA                       8
+#endif
+
+/* maximum CB count in a LCB */
+#define MAX_CU_CNT_IN_LCU                  (MAX_CU_DIM/MIN_CU_DIM)
+/* pixel position to SCB position */
+#define PEL2SCU(pel)                       ((pel) >> MIN_CU_LOG2)
+
+#define PIC_PAD_SIZE_L                     (MAX_CU_SIZE + 16)
+#define PIC_PAD_SIZE_C                     (PIC_PAD_SIZE_L >> 1)
+
+#define NUM_AVS2_SPATIAL_MV                3
+#define NUM_SKIP_SPATIAL_MV                6
+#define MVPRED_L                           0
+#define MVPRED_U                           1
+#define MVPRED_UR                          2
+#define MVPRED_xy_MIN                      3
+
+/* for GOP 16 test, increase to 32 */
+/* maximum reference picture count. Originally, Max. 16 */
+/* for GOP 16 test, increase to 32 */
+#define MAX_NUM_REF_PICS                   17
+
+#define MAX_NUM_ACTIVE_REF_FRAME           4
+
+/* DPB Extra size */
+#define EXTRA_FRAME                        MAX_NUM_REF_PICS
+
+/* maximum picture buffer size */
+#ifdef AML
+#define MAX_PB_SIZE                       (32)
+#else
+#define MAX_PB_SIZE                       (MAX_NUM_REF_PICS + EXTRA_FRAME)
+#endif
+/* Neighboring block availability flag bits */
+#define AVAIL_BIT_UP                       0
+#define AVAIL_BIT_LE                       1
+#define AVAIL_BIT_UP_LE                    2
+
+/* Neighboring block availability flags */
+#define AVAIL_UP                          (1 << AVAIL_BIT_UP)
+#define AVAIL_LE                          (1 << AVAIL_BIT_LE)
+#define AVAIL_UP_LE                       (1 << AVAIL_BIT_UP_LE)
+
+/* MB availability check macro */
+#define IS_AVAIL(avail, pos)            (((avail)&(pos)) == (pos))
+/* MB availability set macro */
+#define SET_AVAIL(avail, pos)             (avail) |= (pos)
+/* MB availability remove macro */
+#define REM_AVAIL(avail, pos)             (avail) &= (~(pos))
+/* MB availability into bit flag */
+#define GET_AVAIL_FLAG(avail, bit)      (((avail)>>(bit)) & 0x1)
+
+/*****************************************************************************
+ * slice type
+ *****************************************************************************/
+#define SLICE_I                            COM_ST_I
+#define SLICE_P                            COM_ST_P
+#define SLICE_B                            COM_ST_B
+
+#define IS_INTRA_SLICE(slice_type)       ((slice_type) == SLICE_I))
+#define IS_INTER_SLICE(slice_type)      (((slice_type) == SLICE_P) || ((slice_type) == SLICE_B))
+
+/*****************************************************************************
+ * prediction mode
+ *****************************************************************************/
+#define MODE_INVALID                      -1
+#define MODE_INTRA                         0
+#define MODE_INTER                         1
+#define MODE_SKIP                          2
+#define MODE_DIR                           3
+#if USE_IBC
+#define MODE_IBC                           4
+#endif
+
+/*****************************************************************************
+ * prediction direction
+ *****************************************************************************/
+typedef enum _INTER_PRED_DIR
+{
+	PRED_L0 = 0,
+	PRED_L1 = 1,
+	PRED_BI = 2,
+	PRED_DIR_NUM = 3,
+} INTER_PRED_DIR;
+
+#if BD_AFFINE_AMVR
+#define Tab_Affine_AMVR(x)                 ((x == 0) ? 2 : ((x == 1) ? 4 : 0) )
+#endif
+
+/*****************************************************************************
+ * skip / direct mode
+ *****************************************************************************/
+#define TRADITIONAL_SKIP_NUM               (PRED_DIR_NUM + 1)
+#define ALLOWED_HMVP_NUM                   8
+#define MAX_SKIP_NUM                       (TRADITIONAL_SKIP_NUM + ALLOWED_HMVP_NUM)
+
+#define UMVE_BASE_NUM                      2
+#define UMVE_REFINE_STEP                   5
+#define UMVE_MAX_REFINE_NUM                (UMVE_REFINE_STEP * 4)
+#if UMVE_ENH
+#define UMVE_REFINE_STEP_SEC_SET           8
+#define UMVE_MAX_REFINE_NUM_SEC_SET        (UMVE_REFINE_STEP_SEC_SET * 4)
+#endif
+
+#if AFFINE_UMVE
+#define AFFINE_UMVE_BASE_NUM               AFF_MAX_NUM_MRG
+#define AFFINE_UMVE_REFINE_STEP            5
+#define AFFINE_UMVE_DIR                    4
+#define AFFINE_UMVE_MAX_REFINE_NUM         (AFFINE_UMVE_REFINE_STEP * AFFINE_UMVE_DIR)
+#endif
+
+#if AWP_MVR
+#define AWP_MVR_REFINE_STEP                5
+#define AWP_MVR_DIR                        4
+#define AWP_MVR_MAX_REFINE_NUM             (AWP_MVR_REFINE_STEP * AWP_MVR_DIR)
+#endif
+
+#if INTERPF
+#define MAX_INTER_SKIP_RDO                 (MAX_SKIP_NUM + NUM_RDO_INTER_FILTER)
+#else
+#define MAX_INTER_SKIP_RDO                 MAX_SKIP_NUM
+#endif
+
+#if EXT_AMVR_HMVP
+#define THRESHOLD_MVPS_CHECK               1.1
+#endif
+
+#if SUB_TMVP
+#define SBTMVP_MIN_SIZE                    16
+#define SBTMVP_NUM                         4
+#define SBTMVP_NUM_1D                      2
+#endif
+
+/*****************************************************************************
+ * intra prediction direction
+ *****************************************************************************/
+#define IPD_DC                             0
+#define IPD_PLN                            1  /* Luma, Planar */
+#define IPD_BI                             2  /* Luma, Bilinear */
+
+#define IPD_DM_C                           0  /* Chroma, DM*/
+#define IPD_DC_C                           1  /* Chroma, DC */
+#define IPD_HOR_C                          2  /* Chroma, Horizontal*/
+#define IPD_VER_C                          3  /* Chroma, Vertical */
+#define IPD_BI_C                           4  /* Chroma, Bilinear */
+#if TSCPM
+#define IPD_TSCPM_C                        5
+#if ENHANCE_TSPCM || PMC || EPMC
+#define IPD_TSCPM_L_C                      6
+#define IPD_TSCPM_T_C                      7
+#endif
+#endif
+
+#if PMC
+#define IPD_MCPM_C                         8
+#define IPD_MCPM_L_C                       9
+#define IPD_MCPM_T_C                       10
+#endif
+#if PMC && EPMC
+#define IPD_EMCPM_C                         11
+#define IPD_EMCPM_L_C                       12
+#define IPD_EMCPM_T_C                       13
+#define IPD_EMCPM2_C                        14
+#define IPD_EMCPM2_L_C                      15
+#define IPD_EMCPM2_T_C                      16
+#elif EPMC
+#define IPD_EMCPM_C                         8
+#define IPD_EMCPM_L_C                       9
+#define IPD_EMCPM_T_C                       10
+#define IPD_EMCPM2_C                        11
+#define IPD_EMCPM2_L_C                      12
+#define IPD_EMCPM2_T_C                      13
+#endif
+#define IPD_CHROMA_CNT                     5
+
+#define IPD_INVALID                       (-1)
+
+#define IPD_RDO_CNT                        5
+
+#define IPD_HOR                            24 /* Luma, Horizontal */
+#define IPD_VER                            12 /* Luma, Vertical */
+#if EIPM
+#define IPD_CNT                            66
+#define IPD_HOR_EXT                        58
+#define IPD_VER_EXT                        43
+#define IPD_DIA_R_EXT                      50
+#define IPD_DIA_L_EXT                      34
+#else
+#define IPD_CNT                            33
+#endif
+#if IPCM
+#define IPD_IPCM                           33
+#endif
+
+#define IPD_DIA_R                         18 /* Luma, Right diagonal */
+#define IPD_DIA_L                         3  /* Luma, Left diagonal */
+#define IPD_DIA_U                         32 /* Luma, up diagonal */
+
+#if FIMC
+#define NUM_MPM                                 2 // Fixed for anchor
+#define CNTMPM_INIT_NUM                   NUM_MPM //
+#if EIPM
+#define CNTMPM_TABLE_LENGTH               IPD_CNT // table length
+#else
+#define CNTMPM_TABLE_LENGTH    (IPD_CNT + !!IPCM) // table length
+#endif
+#define CNTMPM_BASE_VAL                        70 //
+#define CNTMPM_MAX_NUM        CNTMPM_TABLE_LENGTH // Fixed for anchor
+#endif
+
+/*****************************************************************************
+* Transform
+*****************************************************************************/
+
+/*****************************************************************************
+ * reference index
+ *****************************************************************************/
+#define REFI_INVALID                      (-1)
+#define REFI_IS_VALID(refi)               ((refi) >= 0)
+#define SET_REFI(refi, idx0, idx1)        (refi)[REFP_0] = (idx0); (refi)[REFP_1] = (idx1)
+
+/*****************************************************************************
+ * macros for CU map
+
+ - [ 0: 6] : slice number (0 ~ 128)
+ - [ 7:14] : reserved
+ - [15:15] : 1 -> intra CU, 0 -> inter CU
+ - [16:22] : QP
+ - [23:23] : skip mode flag
+ - [24:24] : luma cbf
+ - [25:25] : ibc flag
+ - [26:30] : reserved
+ - [31:31] : 0 -> no encoded/decoded CU, 1 -> encoded/decoded CU
+ *****************************************************************************/
+/* set intra CU flag to map */
+#define MCU_SET_INTRA_FLAG(m)           (m)=((m)|(1<<15))
+/* get intra CU flag from map */
+#define MCU_GET_INTRA_FLAG(m)           (int)(((m)>>15) & 1)
+/* clear intra CU flag in map */
+#define MCU_CLEAR_INTRA_FLAG(m)         (m)=((m) & 0xFFFF7FFF)
+
+/* set QP to map */
+#if CUDQP_PLATFORM_BUGFIX
+#define MCU_SET_QP(m, qp)               (m)=((m&0xFF80FFFF)|((qp)&0x7F)<<16)
+#else
+#define MCU_SET_QP(m, qp)               (m)=((m)|((qp)&0x7F)<<16)
+#endif
+/* get QP from map */
+#define MCU_GET_QP(m)                   (int)(((m)>>16)&0x7F)
+
+/* set skip mode flag */
+#define MCU_SET_SF(m)                   (m)=((m)|(1<<23))
+/* get skip mode flag */
+#define MCU_GET_SF(m)                   (int)(((m)>>23) & 1)
+/* clear skip mode flag */
+#define MCU_CLR_SF(m)                   (m)=((m) & (~(1<<23)))
+
+/* set cu cbf flag */
+#define MCU_SET_CBF(m)                  (m)=((m)|(1<<24))
+/* get cu cbf flag */
+#define MCU_GET_CBF(m)                  (int)(((m)>>24) & 1)
+/* clear cu cbf flag */
+#define MCU_CLR_CBF(m)                  (m)=((m) & (~(1<<24)))
+
+#if USE_IBC
+/* set ibc mode flag */
+#define MCU_SET_IBC(m)                  (m)=((m)|(1<<25))
+/* get ibc mode flag */
+#define MCU_GET_IBC(m)                  (int)(((m)>>25) & 1)
+/* clear ibc mode flag */
+#define MCU_CLR_IBC(m)                  (m)=((m) & (~(1<<25)))
+#endif
+
+/* set encoded/decoded flag of CU to map */
+#define MCU_SET_CODED_FLAG(m)           (m)=((m)|(1<<31))
+/* get encoded/decoded flag of CU from map */
+#define MCU_GET_CODED_FLAG(m)           (int)(((m)>>31) & 1)
+/* clear encoded/decoded CU flag to map */
+#define MCU_CLR_CODED_FLAG(m)           (m)=((m) & 0x7FFFFFFF)
+
+/* multi bit setting: intra flag, encoded/decoded flag, slice number */
+#define MCU_SET_IF_COD_SN_QP(m, i, sn, qp) \
+	(m) = (((m)&0xFF807F80)|((sn)&0x7F)|((qp)<<16)|((i)<<15)|(1<<31))
+
+#define MCU_IS_COD_NIF(m)               ((((m)>>15) & 0x10001) == 0x10000)
+
+#if BGC
+/*
+- [10:11] : bgc flag and bgc idx
+*/
+#define MCU_SET_BGC_FLAG(m)             (m)=((m)|(1<<10))
+#define MCU_GET_BGC_FLAG(m)             (int)(((m)>>10) & 1)
+#define MCU_CLR_BGC_FLAG(m)             (m)=((m) & (~(1<<10)))
+#define MCU_SET_BGC_IDX(m)              (m)=((m)|(1<<11))
+#define MCU_GET_BGC_IDX(m)              (int)(((m)>>11) & 1)
+#define MCU_CLR_BGC_IDX(m)              (m)=((m) & (~(1<<11)))
+#endif
+
+/*
+- [8:9] : affine vertex number, 00: 1(trans); 01: 2(affine); 10: 3(affine); 11: 4(affine)
+*/
+
+/* set affine CU mode to map */
+#define MCU_SET_AFF(m, v)               (m)=((m & 0xFFFFFCFF)|((v)&0x03)<<8)
+/* get affine CU mode from map */
+#define MCU_GET_AFF(m)                  (int)(((m)>>8)&0x03)
+/* clear affine CU mode to map */
+#define MCU_CLR_AFF(m)                  (m)=((m) & 0xFFFFFCFF)
+
+/* set x scu offset & y scu offset relative to top-left scu of CU to map */
+#define MCU_SET_X_SCU_OFF(m, v)         (m)=((m & 0xFFFF00FF)|((v)&0xFF)<<8)
+#define MCU_SET_Y_SCU_OFF(m, v)         (m)=((m & 0xFF00FFFF)|((v)&0xFF)<<16)
+/* get x scu offset & y scu offset relative to top-left scu of CU in map */
+#define MCU_GET_X_SCU_OFF(m)            (int)(((m)>>8)&0xFF)
+#define MCU_GET_Y_SCU_OFF(m)            (int)(((m)>>16)&0xFF)
+
+/* set cu_width_log2 & cu_height_log2 to map */
+#define MCU_SET_LOGW(m, v)              (m)=((m & 0xF0FFFFFF)|((v)&0x0F)<<24)
+#define MCU_SET_LOGH(m, v)              (m)=((m & 0x0FFFFFFF)|((v)&0x0F)<<28)
+/* get cu_width_log2 & cu_height_log2 to map */
+#define MCU_GET_LOGW(m)                 (int)(((m)>>24)&0x0F)
+#define MCU_GET_LOGH(m)                 (int)(((m)>>28)&0x0F)
+
+#if BET_SPLIT_DECISION
+/* save to map_cu_mode*/
+#define MCU_SET_QT_DEPTH(m, v)       (m)=((m & 0xFFFFFFF0)|((v)&0x0F)<<0)
+#define MCU_SET_BET_DEPTH(m, v)      (m)=((m & 0xFFFFFF0F)|((v)&0x0F)<<4)
+#define MCU_GET_QT_DEPTH(m)          (int)(((m)>>0)&0x0F)
+#define MCU_GET_BET_DEPTH(m)         (int)(((m)>>4)&0x0F)
+#endif
+
+#if TB_SPLIT_EXT
+//set
+#define MCU_SET_TB_PART_LUMA(m,v)       (m)=((m & 0xFFFFFF00)|((v)&0xFF)<<0 )
+//get
+#define MCU_GET_TB_PART_LUMA(m)         (int)(((m)>>0 )&0xFF)
+#endif
+
+#if SBT
+//set
+#define MCU_SET_SBT_INFO(m,v)           (m)=((m & 0xFFFF00FF)|((v)&0xFF)<<8 )
+//get
+#define MCU_GET_SBT_INFO(m)             (int)(((m)>>8 )&0xFF)
+#endif
+
+#if USE_SP
+#define MSP_SET_SP_INFO(m)              (m)=(m | 0x80)
+#define MSP_GET_SP_INFO(m)              (int)(((m)>>7) & 1)
+#define MSP_CLR_SP_INFO(m)              (m)=(m & 0x7F)
+#if EVS_UBVS_MODE
+#define MSP_SET_CS2_INFO(m)             (m)=((m)|0x40)
+#define MSP_GET_CS2_INFO(m)             (int)(((m)>>6) & 1)
+#define MSP_CLR_CS2_INFO(m)             (m)=(m & 0xBF)
+#endif
+#endif
+
+typedef u32 SBAC_CTX_MODEL;
+#define NUM_POSITION_CTX                   2
+#define NUM_SBAC_CTX_AFFINE_MVD_FLAG       2
+
+#if IIP
+#define NUM_IIP_CTX                        1
+#endif
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SKIP_FLAG             4
+#else
+#define NUM_SBAC_CTX_SKIP_FLAG             3
+#endif
+#if USE_IBC
+#define NUM_SBAC_CTX_IBC_FLAG              3
+#endif
+#if USE_SP
+#define NUM_SOIF_CTX                       1 ///< number of context models for SP or IBC flag coding
+#define NUM_GSF_CTX                        1 ///< number of context models for SP flag coding
+#define NUM_SP_CDF_CTX                     1 ///< number of context models for SP copy direction flag
+#define NUM_SP_IMF_CTX                     1 ///< number of context models for SP is matched flag
+#if SP_CODE_TEXT_BUGFIX
+#define NUM_SP_STRLEN_CTX                  4 ///< number of context models for SP matched length
+#else
+#define NUM_SP_STRLEN_CTX                  3 ///< number of context models for SP matched length
+#endif
+#define NUM_SP_ABO_CTX                     1 ///< number of context models for SP is above offset flag
+#define NUM_SP_OYZ_CTX                     1 ///< number of context models for SP is offset Y Zero flag
+#define NUM_SP_OXZ_CTX                     1 ///< number of context models for SP is offset X Zero flag
+#if !SP_CODE_TEXT_BUGFIX
+#define NUM_SP_SLF_CTX                     1 ///< number of context models for SP whether using special length buffer flag
+#endif
+#define NUM_SP_NRF_CTX                     1
+#define NUM_SP_NID_CTX                     (SP_RECENT_CANDS - 1)
+#define NUM_SP_PIMF_CTX                    1 ///< number of context models for SP pixel is matched flag
+#if EVS_UBVS_MODE
+#define NUM_CS2F_CTX                       1 ///< number of context models for CS2 flag coding
+#define NUM_SP_MODE_CTX                    1
+#define NUM_SP_STRING_TYPE_CTX             1
+#define NUM_SP_STRING_SCAN_MODE_CTX        1
+#define NUM_SP_LOREF_MAX_LENGTH_CTX        4
+#define NUM_SP_SRB_FLAG_CTX                1
+#define NUM_SP_SRB_LOREFFLAG_CTX           1
+#define NUM_SP_SRB_TOPRUN_CTX              3
+#define NUM_SP_SRB_LEFTRUN_CTX             5
+#endif
+#endif
+#define NUM_SBAC_CTX_SKIP_IDX              (MAX_SKIP_NUM - 1)
+
+#if ETMVP
+#define NUM_SBAC_CTX_ETMVP_IDX             (MAX_ETMVP_NUM - 1)
+#define NUM_SBAC_CTX_ETMVP_FLAG            1
+#endif
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_DIRECT_FLAG           2
+#else
+#define NUM_SBAC_CTX_DIRECT_FLAG           1
+#endif
+#if INTERPF
+#define NUM_SBAC_CTX_INTERPF               2
+#endif
+#define NUM_SBAC_CTX_UMVE_BASE_IDX         1
+#define NUM_SBAC_CTX_UMVE_STEP_IDX         1
+#define NUM_SBAC_CTX_UMVE_DIR_IDX          2
+
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SPLIT_FLAG            4
+#else
+#define NUM_SBAC_CTX_SPLIT_FLAG            3
+#endif
+#define NUM_SBAC_CTX_SPLIT_MODE            3
+#define NUM_SBAC_CTX_BT_SPLIT_FLAG         9
+#if SEP_CONTEXT
+#define NUM_SBAC_CTX_SPLIT_DIR             5
+#else
+#define NUM_SBAC_CTX_SPLIT_DIR             3
+#endif
+#define NUM_QT_CBF_CTX                     3       /* number of context models for QT CBF */
+#if SEP_CONTEXT
+#define NUM_CTP_ZERO_FLAG_CTX              2       /* number of context models for ctp_zero_flag */
+#define NUM_PRED_MODE_CTX                  6       /* number of context models for prediction mode */
+#else
+#define NUM_CTP_ZERO_FLAG_CTX              1       /* number of context models for ctp_zero_flag */
+#define NUM_PRED_MODE_CTX                  5       /* number of context models for prediction mode */
+#endif
+#if MODE_CONS
+#define NUM_CONS_MODE_CTX                  1       /* number of context models for constrained prediction mode */
+#endif
+#define NUM_TB_SPLIT_CTX                   1
+#if SBT
+#define NUM_SBAC_CTX_SBT_INFO              7
+#endif
+#if CUDQP
+#define NUM_SBAC_CTX_CU_QP_DELTA_ABS       4
+#endif
+
+#define NUM_SBAC_CTX_DELTA_QP              4
+
+#if SEP_CONTEXT
+#define NUM_INTER_DIR_CTX                  3       /* number of context models for inter prediction direction */
+#else
+#define NUM_INTER_DIR_CTX                  2       /* number of context models for inter prediction direction */
+#endif
+#define NUM_REFI_CTX                       3
+
+#define NUM_MVR_IDX_CTX                   (MAX_NUM_MVR - 1)
+#if IBC_ABVR
+#define NUM_BVR_IDX_CTX                   (MAX_NUM_BVR - 1)
+#endif
+#if IBC_BVP
+#define NUM_BVP_IDX_CTX                   (MAX_NUM_BVP - 1)
+#endif
+#if BVD_CODING
+#define NUM_BV_RES_CTX                     8       /* number of context models for block vector difference */
+#endif
+#if BD_AFFINE_AMVR
+#define NUM_AFFINE_MVR_IDX_CTX            (MAX_NUM_AFFINE_MVR - 1)
+#endif
+#if SIBC
+#define NUM_SIBC_IDX_CTX                   2
+#endif
+
+#if EXT_AMVR_HMVP
+#define NUM_EXTEND_AMVR_FLAG               1
+#endif
+#define NUM_MV_RES_CTX                     3       /* number of context models for motion vector difference */
+
+#if PMC && EPMC
+#define NUM_INTRA_DIR_CTX                  14
+#elif PMC || EPMC
+#define NUM_INTRA_DIR_CTX                  13
+#else
+#if EIPM
+#if TSCPM
+#if ENHANCE_TSPCM
+#define NUM_INTRA_DIR_CTX                  12
+#else
+#define NUM_INTRA_DIR_CTX                  11
+#endif
+#else
+#define NUM_INTRA_DIR_CTX                  10
+#endif
+#else
+#if TSCPM
+#if ENHANCE_TSPCM
+#define NUM_INTRA_DIR_CTX                  11
+#else
+#define NUM_INTRA_DIR_CTX                  10
+#endif
+#else
+#define NUM_INTRA_DIR_CTX                  9
+#endif
+#endif
+#endif
+
+#define NUM_SBAC_CTX_AFFINE_FLAG           1
+#define NUM_SBAC_CTX_AFFINE_MRG            AFF_MAX_NUM_MRG - 1
+
+#if AWP
+#define NUM_SBAC_CTX_AWP_FLAG              1
+#define NUM_SBAC_CTX_AWP_IDX               2
+#endif
+
+#if SMVD
+#define NUM_SBAC_CTX_SMVD_FLAG             1
+#endif
+
+#if DT_SYNTAX
+#define NUM_SBAC_CTX_PART_SIZE             6
+#endif
+
+#define NUM_SAO_MERGE_FLAG_CTX             3
+#define NUM_SAO_MODE_CTX                   1
+#define NUM_SAO_OFFSET_CTX                 1
+
+#define NUM_ALF_COEFF_CTX                  1
+#define NUM_ALF_LCU_CTX                    1
+
+#if ESAO
+#define NUM_ESAO_LCU_CTX                   1
+#define NUM_ESAO_OFFSET_CTX                1
+#define NUM_ESAO_UV_COUNT_CTX              1
+#endif
+
+#if CCSAO
+#define NUM_CCSAO_LCU_CTX                  1
+#define NUM_CCSAO_OFFSET_CTX               1
+#endif
+
+#if SRCC
+/* Scan-Region based coefficient coding (SRCC) (START) */
+#define LOG2_CG_SIZE                       4
+
+#define NUM_PREV_0VAL                      5
+#define NUM_PREV_12VAL                     5
+
+#define SCAN_REGION_GROUP                  14
+
+#define NUM_CTX_SCANR_LUMA                 25
+#define NUM_CTX_SCANR_CHROMA               3
+#define NUM_CTX_SCANR                      (NUM_CTX_SCANR_LUMA + NUM_CTX_SCANR_CHROMA)
+
+#define NUM_CTX_GT0_LUMA                   51
+#define NUM_CTX_GT0_LUMA_TU                17
+
+#define NUM_CTX_GT0_CHROMA                 9   /* number of context models for chroma gt0 flag */
+#define NUM_CTX_GT0                        (NUM_CTX_GT0_LUMA + NUM_CTX_GT0_CHROMA)  /* number of context models for gt0 flag */
+
+#define NUM_CTX_GT1_LUMA                   17
+#define NUM_CTX_GT1_CHROMA                 5
+#define NUM_CTX_GT1                        (NUM_CTX_GT1_LUMA + NUM_CTX_GT1_CHROMA)  /* number of context models for gt1/2 flag */
+
+/* Scan-Region based coefficient coding (SRCC) (END) */
+#endif
+
+#if ETS
+#define NUM_ETS_IDX_CTX                    1
+#endif
+
+#if EST
+#define NUM_EST_IDX_CTX                    1
+#endif
+
+#if ST_CHROMA
+#define NUM_ST_CHROMA_IDX_CTX              1
+#endif
+
+#define RANK_NUM 6
+#define NUM_SBAC_CTX_LEVEL                 (RANK_NUM * 4)
+#define NUM_SBAC_CTX_RUN                   (RANK_NUM * 4)
+
+#define NUM_SBAC_CTX_RUN_RDOQ              (RANK_NUM * 4)
+
+#define NUM_SBAC_CTX_LAST1                 RANK_NUM
+#define NUM_SBAC_CTX_LAST2                 12
+
+#define NUM_SBAC_CTX_LAST                  2
+
+/* context models for arithmetic coding */
+typedef struct _COM_SBAC_CTX
+{
+	SBAC_CTX_MODEL   skip_flag       [NUM_SBAC_CTX_SKIP_FLAG];
+#if USE_IBC
+	SBAC_CTX_MODEL   ibc_flag        [NUM_SBAC_CTX_IBC_FLAG];
+#endif
+#if USE_SP
+	SBAC_CTX_MODEL   sp_or_ibc_flag  [NUM_SOIF_CTX];
+	SBAC_CTX_MODEL   sp_flag         [NUM_GSF_CTX];
+	SBAC_CTX_MODEL   sp_copy_direct_flag[NUM_SP_CDF_CTX];
+	SBAC_CTX_MODEL   sp_is_matched_flag[NUM_SP_IMF_CTX];
+	SBAC_CTX_MODEL   sp_string_length[NUM_SP_STRLEN_CTX];
+	SBAC_CTX_MODEL   sp_above_offset [NUM_SP_ABO_CTX];
+	SBAC_CTX_MODEL   sp_offset_y_zero[NUM_SP_OYZ_CTX];
+	SBAC_CTX_MODEL   sp_offset_x_zero[NUM_SP_OXZ_CTX];
+#if !SP_CODE_TEXT_BUGFIX
+	SBAC_CTX_MODEL   sp_special_len_flag[NUM_SP_SLF_CTX];
+#endif
+	SBAC_CTX_MODEL   sp_n_recent_flag[NUM_SP_NRF_CTX];
+	SBAC_CTX_MODEL   sp_n_index      [NUM_SP_NID_CTX];
+#if SP_SLR
+	SBAC_CTX_MODEL   sp_pixel_is_matched_flag[NUM_SP_PIMF_CTX];
+#endif
+#if EVS_UBVS_MODE
+	SBAC_CTX_MODEL   sp_cs2_flag[NUM_CS2F_CTX];
+	SBAC_CTX_MODEL   sp_mode_context[NUM_SP_MODE_CTX];
+	SBAC_CTX_MODEL   sp_str_type_context[NUM_SP_STRING_TYPE_CTX];
+	SBAC_CTX_MODEL   sp_str_scanmode_context[NUM_SP_STRING_SCAN_MODE_CTX];
+	SBAC_CTX_MODEL   sp_lo_ref_maxlength_context[NUM_SP_LOREF_MAX_LENGTH_CTX];
+	//For SRB
+	SBAC_CTX_MODEL   sp_evs_present_flag_context[NUM_SP_SRB_FLAG_CTX];
+	SBAC_CTX_MODEL   sp_SRB_lo_ref_color_flag_context[NUM_SP_SRB_LOREFFLAG_CTX];
+	SBAC_CTX_MODEL   sp_SRB_copy_toprun_context[NUM_SP_SRB_TOPRUN_CTX];
+#endif
+#endif
+	SBAC_CTX_MODEL   skip_idx_ctx    [NUM_SBAC_CTX_SKIP_IDX];
+	SBAC_CTX_MODEL   direct_flag     [NUM_SBAC_CTX_DIRECT_FLAG];
+#if INTERPF
+	SBAC_CTX_MODEL   inter_filter_flag[NUM_SBAC_CTX_INTERPF];
+#endif
+#if BGC
+	SBAC_CTX_MODEL   bgc_flag;
+	SBAC_CTX_MODEL   bgc_idx;
+#endif
+#if AWP
+	SBAC_CTX_MODEL   umve_awp_flag;
+#else
+	SBAC_CTX_MODEL   umve_flag;
+#endif
+	SBAC_CTX_MODEL   umve_base_idx   [NUM_SBAC_CTX_UMVE_BASE_IDX];
+	SBAC_CTX_MODEL   umve_step_idx   [NUM_SBAC_CTX_UMVE_STEP_IDX];
+	SBAC_CTX_MODEL   umve_dir_idx    [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#if AFFINE_UMVE
+	SBAC_CTX_MODEL   affine_umve_flag;
+	SBAC_CTX_MODEL   affine_umve_step_idx   [NUM_SBAC_CTX_UMVE_STEP_IDX];
+	SBAC_CTX_MODEL   affine_umve_dir_idx    [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#endif
+	SBAC_CTX_MODEL   inter_dir       [NUM_INTER_DIR_CTX];
+	SBAC_CTX_MODEL   intra_dir       [NUM_INTRA_DIR_CTX];
+	SBAC_CTX_MODEL   pred_mode       [NUM_PRED_MODE_CTX];
+#if MODE_CONS
+	SBAC_CTX_MODEL   cons_mode       [NUM_CONS_MODE_CTX];
+#endif
+#if IIP
+	SBAC_CTX_MODEL   iip_flag        [NUM_IIP_CTX];
+#endif
+	SBAC_CTX_MODEL   ipf_flag        [NUM_IPF_CTX];
+	SBAC_CTX_MODEL   refi            [NUM_REFI_CTX];
+	SBAC_CTX_MODEL   mvr_idx         [NUM_MVR_IDX_CTX];
+#if IBC_ABVR
+	SBAC_CTX_MODEL   bvr_idx         [NUM_BVR_IDX_CTX];
+#endif
+#if BD_AFFINE_AMVR
+	SBAC_CTX_MODEL   affine_mvr_idx  [NUM_AFFINE_MVR_IDX_CTX];
+#endif
+#if EXT_AMVR_HMVP
+	SBAC_CTX_MODEL   mvp_from_hmvp_flag[NUM_EXTEND_AMVR_FLAG];
+#endif
+#if IBC_BVP
+	SBAC_CTX_MODEL   cbvp_idx[NUM_BVP_IDX_CTX];
+#endif
+#if SIBC
+	SBAC_CTX_MODEL   sibc_flag       [NUM_SIBC_IDX_CTX];
+#endif
+#if BVD_CODING
+	SBAC_CTX_MODEL   bvd             [2][NUM_BV_RES_CTX];
+#endif
+	SBAC_CTX_MODEL   mvd             [2][NUM_MV_RES_CTX];
+	SBAC_CTX_MODEL   ctp_zero_flag   [NUM_CTP_ZERO_FLAG_CTX];
+	SBAC_CTX_MODEL   cbf             [NUM_QT_CBF_CTX];
+#if CUDQP
+	SBAC_CTX_MODEL   cu_qp_delta_abs [NUM_SBAC_CTX_CU_QP_DELTA_ABS];
+#endif
+	SBAC_CTX_MODEL   tb_split        [NUM_TB_SPLIT_CTX];
+#if SBT
+	SBAC_CTX_MODEL   sbt_info        [NUM_SBAC_CTX_SBT_INFO];
+#endif
+#if SRCC
+	SBAC_CTX_MODEL   cc_gt0          [NUM_CTX_GT0];
+	SBAC_CTX_MODEL   cc_gt1          [NUM_CTX_GT1];
+	SBAC_CTX_MODEL   cc_scanr_x      [NUM_CTX_SCANR];
+	SBAC_CTX_MODEL   cc_scanr_y      [NUM_CTX_SCANR];
+#endif
+	SBAC_CTX_MODEL   run             [NUM_SBAC_CTX_RUN];
+	SBAC_CTX_MODEL   run_rdoq        [NUM_SBAC_CTX_RUN];
+	SBAC_CTX_MODEL   last1           [NUM_SBAC_CTX_LAST1 * 2];
+	SBAC_CTX_MODEL   last2           [NUM_SBAC_CTX_LAST2 * 2 - 2];
+	SBAC_CTX_MODEL   level           [NUM_SBAC_CTX_LEVEL];
+	SBAC_CTX_MODEL   split_flag      [NUM_SBAC_CTX_SPLIT_FLAG];
+	SBAC_CTX_MODEL   bt_split_flag   [NUM_SBAC_CTX_BT_SPLIT_FLAG];
+	SBAC_CTX_MODEL   split_dir       [NUM_SBAC_CTX_SPLIT_DIR];
+	SBAC_CTX_MODEL   split_mode      [NUM_SBAC_CTX_SPLIT_MODE];
+	SBAC_CTX_MODEL   affine_flag     [NUM_SBAC_CTX_AFFINE_FLAG];
+	SBAC_CTX_MODEL   affine_mrg_idx  [NUM_SBAC_CTX_AFFINE_MRG];
+#if ETMVP
+	SBAC_CTX_MODEL   etmvp_flag[NUM_SBAC_CTX_ETMVP_FLAG];
+	SBAC_CTX_MODEL   etmvp_idx[NUM_SBAC_CTX_ETMVP_IDX];
+#endif
+#if AWP
+	SBAC_CTX_MODEL   awp_flag        [NUM_SBAC_CTX_AWP_FLAG];
+	SBAC_CTX_MODEL   awp_idx         [NUM_SBAC_CTX_AWP_IDX];
+#endif
+#if AWP_MVR
+	SBAC_CTX_MODEL   awp_mvr_flag;
+	SBAC_CTX_MODEL   awp_mvr_step_idx[NUM_SBAC_CTX_UMVE_STEP_IDX];
+	SBAC_CTX_MODEL   awp_mvr_dir_idx [NUM_SBAC_CTX_UMVE_DIR_IDX];
+#endif
+#if SMVD
+	SBAC_CTX_MODEL   smvd_flag       [NUM_SBAC_CTX_SMVD_FLAG];
+#endif
+#if DT_SYNTAX
+	SBAC_CTX_MODEL   part_size       [NUM_SBAC_CTX_PART_SIZE];
+#endif
+#if ETS
+	SBAC_CTX_MODEL   ets_flag        [NUM_ETS_IDX_CTX];
+#endif
+#if EST
+	SBAC_CTX_MODEL   est_flag        [NUM_EST_IDX_CTX];
+#endif
+#if ST_CHROMA
+	SBAC_CTX_MODEL   st_chroma_flag[NUM_ST_CHROMA_IDX_CTX];
+#endif
+
+	SBAC_CTX_MODEL   sao_merge_flag  [NUM_SAO_MERGE_FLAG_CTX];
+	SBAC_CTX_MODEL   sao_mode        [NUM_SAO_MODE_CTX];
+	SBAC_CTX_MODEL   sao_offset      [NUM_SAO_OFFSET_CTX];
+	SBAC_CTX_MODEL   alf_lcu_enable  [NUM_ALF_LCU_CTX];
+	SBAC_CTX_MODEL   delta_qp        [NUM_SBAC_CTX_DELTA_QP];
+#if ESAO
+	SBAC_CTX_MODEL   esao_lcu_enable [NUM_ESAO_LCU_CTX];
+	SBAC_CTX_MODEL   esao_offset     [NUM_ESAO_OFFSET_CTX];
+	SBAC_CTX_MODEL   esao_chroma_mode_flag[NUM_ESAO_UV_COUNT_CTX];
+#endif
+#if CCSAO
+	SBAC_CTX_MODEL   ccsao_lcu_flag  [NUM_CCSAO_LCU_CTX];
+	SBAC_CTX_MODEL   ccsao_offset    [NUM_CCSAO_OFFSET_CTX];
+#endif
+} COM_SBAC_CTX;
+
+#define COEF_SCAN_ZIGZAG                    0
+#define COEF_SCAN_TYPE_NUM                  1
+
+/* Maximum transform dynamic range (excluding sign bit) */
+#define MAX_TX_DYNAMIC_RANGE               15
+#if SRCC
+#define MAX_TX_VAL                       ((1 << MAX_TX_DYNAMIC_RANGE) - 1)
+#define MIN_TX_VAL                      (-(1 << MAX_TX_DYNAMIC_RANGE))
+#endif
+
+#define QUANT_SHIFT                        14
+
+/* neighbor CUs
+	neighbor position:
+
+	D     B     C
+
+	A     X,<G>
+
+	E          <F>
+*/
+#define MAX_NEB                            5
+#define NEB_A                              0  /* left */
+#define NEB_B                              1  /* up */
+#define NEB_C                              2  /* up-right */
+#define NEB_D                              3  /* up-left */
+#define NEB_E                              4  /* low-left */
+
+#define NEB_F                              5  /* co-located of low-right */
+#define NEB_G                              6  /* co-located of X */
+#define NEB_X                              7  /* center (current block) */
+#define NEB_H                              8  /* right */
+#define NEB_I                              9  /* low-right */
+#define MAX_NEB2                           10
+
+/* SAO_AVS2(START) */
+typedef enum _SAO_MODE   //mode
+{
+	SAO_MODE_OFF = 0,
+	SAO_MODE_MERGE,
+	SAO_MODE_NEW,
+	NUM_SAO_MODES
+} SAO_MODE;
+
+typedef enum _SAO_MODE_MERGE_TYPE
+{
+	SAO_MERGE_LEFT = 0,
+	SAO_MERGE_ABOVE,
+	NUM_SAO_MERGE_TYPES
+} SAO_MODE_MERGE_TYPE;
+
+typedef enum _SAO_MODE_NEW_TYPE   //NEW: types
+{
+	SAO_TYPE_EO_0,
+	SAO_TYPE_EO_90,
+	SAO_TYPE_EO_135,
+	SAO_TYPE_EO_45,
+	SAO_TYPE_BO,
+	NUM_SAO_NEW_TYPES
+} SAO_MODE_NEW_TYPE;
+
+typedef enum _SAO_EO_CLASS   // 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
+} SAO_EO_CLASS;
+
+typedef struct _SAO_STAT_DATA
+{
+	long long int diff[MAX_NUM_SAO_CLASSES];
+	int count[MAX_NUM_SAO_CLASSES];
+} SAO_STAT_DATA;
+
+typedef struct _SAO_BLK_PARAM
+{
+	int mode_idc; //NEW, MERGE, OFF
+	int type_idc; //NEW: EO_0, EO_90, EO_135, EO_45, BO. MERGE: left, above
+	int start_band; //BO: starting band index
+	int start_band2;
+	int delta_band;
+	int offset[MAX_NUM_SAO_CLASSES];
+} SAO_BLK_PARAM;
+/* SAO_AVS2(END) */
+
+#if DBR
+typedef struct _DBR_PARAM
+{
+	int dbr_horizontal_enabled;
+	int thresh_horizontal_index;
+	int horizontal_offsets[6];
+	int dbr_vertical_enabled;
+	int thresh_vertical_index;
+	int vertical_offsets[6];
+} DBR_PARAM;
+#endif
+
+#if ESAO
+/* ESAO_AVS3(START) */
+typedef struct _ESAO_STAT_DATA
+{
+	long long diff[ESAO_LABEL_CLASSES_MAX];
+	int count[ESAO_LABEL_CLASSES_MAX];
+} ESAO_STAT_DATA;
+
+typedef struct _ESAO_BLK_PARAM
+{
+	int  offset[ESAO_LABEL_CLASSES_MAX];
+	int *lcu_flag;
+}ESAO_BLK_PARAM;
+
+typedef struct _ESAO_FUNC_POINTER
+{
+	void (*esao_on_block_for_luma)(pel* p_dst, int i_dst, pel * p_src, int i_src, int i_block_w, int i_block_h, int bit_depth, int bo_value, const int *esao_offset, int lcu_available_left, int lcu_available_right,
+		int lcu_available_up, int lcu_available_down, int lcu_available_upleft, int lcu_available_upright, int lcu_available_leftdown, int lcu_available_rightdwon, int luma_type);
+	void (*esao_on_block_for_chroma)(pel * p_dst, int i_dst, pel * p_src, int i_src, int i_block_w, int i_block_h, int bo_value, int shift_value, int bit_depth, const int *esao_offset);
+}ESAO_FUNC_POINTER;
+/* ESAO_AVS3(END) */
+#endif
+
+#if CCSAO
+/* CCSAO_AVS3(START) */
+typedef struct
+{
+	long long diff [CCSAO_CLASS_NUM];
+	int       count[CCSAO_CLASS_NUM];
+}CCSAO_STAT_DATA;
+
+#if CCSAO_ENHANCEMENT
+typedef struct
+{
+	long long diff [CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+	int       count[CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+}CCSAO_REFINE_DATA;
+
+typedef struct
+{
+	int       lcu_pos;
+	double    lcu_cost;
+}CCSAO_LCU_COST;
+
+typedef struct
+{
+	BOOL      en;
+	int       set;
+	int       cnt;
+}CCSAO_SET_CNT;
+
+typedef struct
+{
+	int       set_num;
+	int       type  [CCSAO_SET_NUM];
+	int       mode  [CCSAO_SET_NUM];
+	int       mode_c[CCSAO_SET_NUM];
+	int       offset[CCSAO_SET_NUM][CCSAO_CLASS_NUM];
+	int      *lcu_flag;
+}CCSAO_BLK_PARAM;
+#else
+typedef struct
+{
+	int       type;
+	int       mode;
+	int       offset[CCSAO_CLASS_NUM];
+	int      *lcu_flag;
+}CCSAO_BLK_PARAM;
+#endif
+
+typedef struct
+{
+	void(*ccsao_on_block_for_chroma)(pel *p_dst, int i_dst, pel *p_src, int i_src,
+#if CCSAO_ENHANCEMENT
+		pel *p_src2, int i_src2,
+#endif
+		int lcu_width_c, int lcu_height_c, int bit_depth, int type, int band_num,
+#if CCSAO_ENHANCEMENT
+		int band_num_c,
+#endif
+		const int *ccsao_offset,
+		int lcu_available_left, int lcu_available_right, int lcu_available_up, int lcu_available_down, int lcu_available_upleft, int lcu_available_upright, int lcu_available_leftdown, int lcu_available_rightdwon);
+}CCSAO_FUNC_POINTER;
+/* CCSAO_AVS3(END) */
+#endif
+
+/* ALF_AVS2(START) */
+typedef struct _ALF_PARAM
+{
+	int alf_flag;
+	int num_coeff;
+	int filters_per_group;
+#if ALF_IMP
+	int dir_index;
+	int max_filter_num;
+#endif
+	int component_id;
+#ifdef AML
+	int32_t filter_pattern[NO_VAR_BINS];
+	int32_t coeff_multi[NO_VAR_BINS][ALF_MAX_NUM_COEF];
+#else
+	int *filter_pattern;
+	int **coeff_multi;
+#endif
+} ALF_PARAM;
+
+typedef struct _ALF_CORR_DATA
+{
+	double ***E_corr; //!< auto-correlation matrix
+	double  **y_corr; //!< cross-correlation
+	double   *pix_acc;
+	int       component_id;
+} ALF_CORR_DATA;
+/* ALF_AVS2(END) */
+
+#ifdef AML
+typedef struct avs3_frame_s{
+#if 0
+	int32_t imgcoi_ref;
+	byte **referenceFrame[3];
+	int32_t **refbuf;
+	int32_t ** *mvbuf;
+	double saorate[NUM_SAO_COMPONENTS];
+	byte ** *ref;
+
+	int32_t imgtr_fwRefDistance;
+	int32_t refered_by_others;
+	int32_t is_output;
+#if M3480_TEMPORAL_SCALABLE
+	int32_t temporal_id;          //temporal level setted in configure file
+#endif
+	byte **oneForthRefY;
+#if FIX_MAX_REF
+	int32_t ref_poc[MAXREF];
+#else
+	int32_t ref_poc[4];
+#endif
+#endif
+	int index;
+	int used;
+	u32 mmu_alloc_flag;
+	u32 lcu_size_log2;
+	u32 header_adr;
+	u32 header_dw_adr;
+	u32 mc_y_adr;
+	u32 mc_u_v_adr;
+	u32 mc_canvas_y;
+	u32 mc_canvas_u_v;
+	u32 mpred_mv_wr_start_addr;
+	u8 bg_flag;
+	u32 refered_by_others;
+	u32 is_output;
+	int vf_ref;
+	u8 slice_type;
+	int list0_num_refp;
+	int list0_ptr[MAX_NUM_REF_PICS];
+	int backend_ref;
+#ifdef NEW_FB_CODE
+	unsigned char back_done_mark;
+	//unsigned char flush_mark;
+#endif
+#ifdef NEW_FRONT_BACK_CODE
+	int list0_index[MAX_NUM_REF_PICS];
+	int list1_num_refp;
+	int list1_index[MAX_NUM_REF_PICS];
+	int width;
+	int height;
+	int depth;
+#endif
+#ifdef AML
+	int error_mark;
+	int32_t decoded_lcu;
+
+	unsigned long cma_alloc_addr;
+	int buf_size;
+	int BUF_index;
+	int lcu_total;
+	int comp_body_size;
+	uint32_t dw_y_adr;
+	uint32_t dw_u_v_adr;
+	unsigned long dw_header_adr;
+	int y_canvas_index;
+	int uv_canvas_index;
+	struct canvas_config_s canvas_config[2];
+	int double_write_mode;
+
+	u32 stream_offset;
+	u32 pts;
+	u64 pts64;
+	/* picture qos information*/
+	struct vframe_qos_s vqos;
+
+	u32 hw_decode_time;
+	u32 frame_size; // For frame base mode
+	char *cuva_data_buf;
+	int  cuva_data_size;
+	bool in_dpb;
+	u64 time;
+	s32 poc;
+	u32 hw_front_decode_time;
+	struct vdec_info vinfo;
+	u32 stream_size; // For stream base mode
+#endif
+#ifdef OW_TRIPLE_WRITE
+	unsigned int tw_y_adr;
+	unsigned int tw_u_v_adr;
+
+	//int tw_y_canvas_index;
+	//int tw_uv_canvas_index;
+	struct canvas_config_s tw_canvas_config[2];
+
+	u32 triple_write_mode;
+#endif
+} avs3_frame_t;
+#endif
+/* picture store structure */
+typedef struct _COM_PIC
+{
+	/* Start address of Y component (except padding) */
+	pel             *y;
+	/* Start address of U component (except padding)  */
+	pel             *u;
+	/* Start address of V component (except padding)  */
+	pel             *v;
+#if EVS_UBVS_MODE
+	/* Start address of U component format 444 (except padding)  */
+	pel             *u444;
+	/* Start address of V component format 444 (except padding)  */
+	pel             *v444;
+#endif
+	/* Stride of luma picture */
+	int              stride_luma;
+	/* Stride of chroma picture */
+	int              stride_chroma;
+	/* Width of luma picture */
+	int              width_luma;
+	/* Height of luma picture */
+	int              height_luma;
+	/* Width of chroma picture */
+	int              width_chroma;
+	/* Height of chroma picture */
+	int              height_chroma;
+	/* padding size of luma */
+	int              padsize_luma;
+	/* padding size of chroma */
+	int              padsize_chroma;
+	/* image buffer */
+	COM_IMGB        *imgb;
+	/* decoding temporal reference of this picture */
+	int              dtr;
+	/* presentation temporal reference of this picture */
+	int              ptr;
+	int              picture_output_delay;
+	/* 0: not used for reference buffer, reference picture type */
+	u8               is_ref;
+	/* needed for output? */
+	u8               need_for_out;
+	/* scalable layer id */
+	u8               temporal_id;
+	s16            (*map_mv)[REFP_NUM][MV_D];
+	s8             (*map_refi)[REFP_NUM];
+#if ETMVP || SUB_TMVP || AWP
+	u32              list_ptr[REFP_NUM][MAX_NUM_REF_PICS];
+#else
+	u32              list_ptr[MAX_NUM_REF_PICS];
+#endif
+#ifdef AML
+	avs3_frame_t buf_cfg;
+#endif
+} COM_PIC;
+
+#if LIBVC_ON
+#define MAX_NUM_COMPONENT                   3
+#define MAX_NUM_LIBPIC                      16
+#define MAX_CANDIDATE_PIC                   256
+#define MAX_DIFFERENCE_OF_RLPIC_AND_LIBPIC  1.7e+308; ///< max. value of Double-type value
+
+typedef struct _PIC_HIST_FEATURE
+{
+	int num_component;
+	int num_of_hist_interval;
+	int length_of_interval;
+	int * list_hist_feature[MAX_NUM_COMPONENT];
+} PIC_HIST_FEATURE;
+
+// ====================================================================================================================
+// Information of libpic
+// ====================================================================================================================
+
+typedef struct _LibVCData
+{
+	int num_candidate_pic;
+	int list_poc_of_candidate_pic[MAX_CANDIDATE_PIC]; // for now, the candidate set contain only pictures from input sequence.
+	COM_IMGB * list_candidate_pic[MAX_CANDIDATE_PIC];
+	PIC_HIST_FEATURE list_hist_feature_of_candidate_pic[MAX_CANDIDATE_PIC];
+
+	int num_lib_pic;
+	int list_poc_of_libpic[MAX_NUM_LIBPIC];
+
+	COM_PIC * list_libpic_outside[MAX_NUM_LIBPIC];
+	int num_libpic_outside;
+	int list_library_index_outside[MAX_NUM_LIBPIC];
+
+	int num_RLpic;
+	int list_poc_of_RLpic[MAX_CANDIDATE_PIC];
+	int list_libidx_for_RLpic[MAX_CANDIDATE_PIC]; //the idx of library picture instead of poc of library picture in origin sequence is set as new poc.
+
+	int bits_dependencyFile;
+	int bits_libpic;
+
+	int library_picture_enable_flag;
+#if IPPPCRR
+#if LIB_PIC_UPDATE
+	int lib_pic_update;
+	int update;
+	int countRL;
+	int encode_skip;
+	int end_of_intra_period;
+#else
+	int first_pic_as_libpic;
+#endif
+#endif
+	int is_libpic_processing;
+	int is_libpic_prepared;
+#if CRR_ENC_OPT_CFG
+	int lib_in_l0, lib_in_l1, pb_ref_lib, rl_ref_lib, max_list_refnum;
+	int libpic_idx;
+#endif
+
+} LibVCData;
+#endif
+
+/*****************************************************************************
+ * picture buffer allocator
+ *****************************************************************************/
+typedef struct _PICBUF_ALLOCATOR
+{
+	/* width */
+	int              width;
+	/* height */
+	int              height;
+	/* pad size for luma */
+	int              pad_l;
+	/* pad size for chroma */
+	int              pad_c;
+	/* arbitrary data, if needs */
+	int              ndata[4];
+	/* arbitrary address, if needs */
+	void            *pdata[4];
+} PICBUF_ALLOCATOR;
+
+/*****************************************************************************
+ * picture manager for DPB in decoder and RPB in encoder
+ *****************************************************************************/
+typedef struct _COM_PM
+{
+	/* picture store (including reference and non-reference) */
+	COM_PIC          *pic[MAX_PB_SIZE];
+	/* address of reference pictures */
+	COM_PIC          *pic_ref[MAX_NUM_REF_PICS];
+	/* maximum reference picture count */
+	int               max_num_ref_pics;
+	/* current count of available reference pictures in PB */
+	int               cur_num_ref_pics;
+	/* number of reference pictures */
+	int               num_refp[REFP_NUM];
+	/* next output POC */
+	int               ptr_next_output;
+	/* POC increment */
+	int               ptr_increase;
+	/* max number of picture buffer */
+	int               max_pb_size;
+	/* current picture buffer size */
+	int               cur_pb_size;
+	/* address of leased picture for current decoding/encoding buffer */
+	COM_PIC          *pic_lease;
+	/* picture buffer allocator */
+	PICBUF_ALLOCATOR  pa;
+#if LIBVC_ON
+	/* information for LibVC */
+	LibVCData        *libvc_data;
+	int               is_library_buffer_empty;
+	COM_PIC          *pb_libpic; //buffer for libpic
+	int               cur_libpb_size;
+	int               pb_libpic_library_index;
+#endif
+/*AML*/
+	void              *hw;
+	spinlock_t        pm_lock;
+/**/
+} COM_PM;
+
+/* reference picture structure */
+typedef struct _COM_REFP
+{
+	/* address of reference picture */
+	COM_PIC         *pic;
+	/* PTR of reference picture */
+	int              ptr;
+	s16            (*map_mv)[REFP_NUM][MV_D];
+	s8             (*map_refi)[REFP_NUM];
+#if ETMVP || SUB_TMVP || AWP
+	u32            (*list_ptr)[MAX_NUM_REF_PICS];
+#else
+	u32             *list_ptr;
+#endif
+#if LIBVC_ON
+	int              is_library_picture;
+#endif
+} COM_REFP;
+
+typedef struct _COM_MOTION
+{
+	s16              mv[REFP_NUM][MV_D];
+	s8               ref_idx[REFP_NUM];
+} COM_MOTION;
+
+/*****************************************************************************
+ * chunk header
+ *****************************************************************************/
+typedef struct _COM_CNKH
+{
+	/* version: 3bit */
+	int              ver;
+	/* chunk type: 4bit */
+	int              ctype;
+	/* broken link flag: 1bit(should be zero) */
+	int              broken;
+} COM_CNKH;
+
+/*****************************************************************************
+ * sequence header
+ *****************************************************************************/
+typedef struct _COM_SQH
+{
+	u8               profile_id;                 /* 8 bits */
+	u8               level_id;                   /* 8 bits */
+	u8               progressive_sequence;       /* 1 bit  */
+	u8               field_coded_sequence;       /* 1 bit  */
+#if LIBVC_ON
+	u8               library_stream_flag;     /* 1 bit  */
+	u8               library_picture_enable_flag;     /* 1 bit  */
+	u8               duplicate_sequence_header_flag;     /* 1 bit  */
+#endif
+	u8               chroma_format;              /* 2 bits */
+	u8               encoding_precision;         /* 3 bits */
+	u8               output_reorder_delay;       /* 5 bits */
+	u8               sample_precision;           /* 3 bits */
+	u8               aspect_ratio;               /* 4 bits */
+	u8               frame_rate_code;            /* 4 bits */
+	u32              bit_rate_lower;             /* 18 bits */
+	u32              bit_rate_upper;             /* 18 bits */
+	u8               low_delay;                  /* 1 bit */
+	u8               temporal_id_enable_flag;    /* 1 bit */
+	u32              bbv_buffer_size;            /* 18 bits */
+	u8               max_dpb_size;               /* 4 bits */
+	int              horizontal_size;            /* 14 bits */
+	int              vertical_size;              /* 14 bits */
+	u8               log2_max_cu_width_height;   /* 3 bits */
+	u8               min_cu_size;
+	u8               max_part_ratio;
+	u8               max_split_times;
+	u8               min_qt_size;
+	u8               max_bt_size;
+	u8               max_eqt_size;
+	u8               max_dt_size;
+#if HLS_RPL
+	int              rpl1_index_exist_flag;
+	int              rpl1_same_as_rpl0_flag;
+	COM_RPL          rpls_l0[MAX_NUM_RPLS];
+	COM_RPL          rpls_l1[MAX_NUM_RPLS];
+	int              rpls_l0_num;
+	int              rpls_l1_num;
+	int              num_ref_default_active_minus1[2];
+#endif
+#if IPCM
+	int              ipcm_enable_flag;
+#endif
+	u8               amvr_enable_flag;
+#if IBC_ABVR
+	u8               abvr_enable_flag;
+#endif
+#if USE_SP
+	int              sp_enable_flag;
+#if EVS_UBVS_MODE
+	int              evs_ubvs_enable_flag;
+#endif
+#endif
+	int              umve_enable_flag;
+#if UMVE_ENH
+	int              umve_enh_enable_flag;
+#endif
+#if AWP
+	int              awp_enable_flag;
+#endif
+#if AWP_MVR
+	int              awp_mvr_enable_flag;
+#endif
+#if ETMVP
+	int              etmvp_enable_flag;
+#endif
+#if SUB_TMVP
+	int              sbtmvp_enable_flag;
+#endif
+#if MIPF
+	int              mipf_enable_flag;
+#endif
+#if DBK_SCC
+	int              loop_filter_type_enable_flag;
+#endif
+#if DBR
+	int              dbr_enable_flag;
+#endif
+	int              ipf_enable_flag;
+#if EXT_AMVR_HMVP
+	int              emvr_enable_flag;
+#endif
+	u8               affine_enable_flag;
+#if ASP
+	u8               asp_enable_flag;
+#endif
+#if AFFINE_UMVE
+	u8               affine_umve_enable_flag;
+#endif
+#if SMVD
+	u8               smvd_enable_flag;
+#endif
+#if BIO
+	u8               bio_enable_flag;
+#endif
+#if BGC
+	u8               bgc_enable_flag;
+#endif
+#if DMVR
+	u8               dmvr_enable_flag;
+#endif
+#if INTERPF
+	u8               interpf_enable_flag;
+#endif
+#if MVAP
+	u8               mvap_enable_flag;
+	u8               num_of_mvap_cand;
+#endif
+#if DT_PARTITION
+	u8               dt_intra_enable_flag;
+#endif
+	u8               num_of_hmvp_cand;
+#if IBC_BVP
+	u8               num_of_hbvp_cand;
+#endif
+#if SIBC
+	u8               sibc_enable_flag;
+#endif
+#if TSCPM
+	u8               tscpm_enable_flag;
+#if ENHANCE_TSPCM
+	u8               enhance_tscpm_enable_flag;
+#endif
+#if PMC
+	u8               pmc_enable_flag;
+#endif
+#endif
+#if IPF_CHROMA
+	u8               chroma_ipf_enable_flag;
+#endif
+#if IIP
+	u8               iip_enable_flag;
+#endif
+#if FIMC
+	u8               fimc_enable_flag;
+#endif
+#if IST
+	u8               ist_enable_flag;
+#endif
+#if ISTS
+	u8               ists_enable_flag;
+#endif
+#if TS_INTER
+	u8               ts_inter_enable_flag;
+#endif
+#if EST
+	u8               est_enable_flag;
+#endif
+#if ST_CHROMA
+	u8               st_chroma_enable_flag;
+#endif
+#if SRCC
+	u8               srcc_enable_flag;
+#endif
+#if CABAC_MULTI_PROB
+	u8               mcabac_enable_flag;
+#endif
+#if EIPM
+	u8               eipm_enable_flag;
+#endif
+	u8               sample_adaptive_offset_enable_flag;
+#if ESAO
+	u8               esao_enable_flag;
+#endif
+#if CCSAO
+	u8               ccsao_enable_flag;
+#endif
+#if ALF_SHAPE || ALF_IMP
+	u8               adaptive_filter_shape_enable_flag;
+#endif
+	u8               adaptive_leveling_filter_enable_flag;
+	u8               secondary_transform_enable_flag;
+	u8               position_based_transform_enable_flag;
+#if SBT
+	u8               sbt_enable_flag;
+#endif
+
+	u8               wq_enable;
+	u8               seq_wq_mode;
+	u8               wq_4x4_matrix[16];
+	u8               wq_8x8_matrix[64];
+#if PATCH
+	u8               patch_stable;
+	u8               cross_patch_loop_filter;
+	u8               patch_ref_colocated;
+	u8               patch_uniform;
+	u8               patch_width_minus1;
+	u8               patch_height_minus1;
+	u8               patch_columns;
+	u8               patch_rows;
+	int              column_width[64];
+	int              row_height[32];
+#endif
+#if USE_IBC
+	u8               ibc_flag;
+#endif
+#if ESAO
+	u8              pic_esao_on[3];
+	u8              esao_adaptive_param[3];
+	u8              esao_lcu_enable[3];
+#endif
+} COM_SQH;
+
+/*****************************************************************************
+ * picture header
+ *****************************************************************************/
+typedef struct _COM_PIC_HEADER
+{
+	/* info from sqh */
+	u8  low_delay;
+	/* decoding temporal reference */
+#if HLS_RPL
+	s32 poc;
+	int              rpl_l0_idx;         //-1 means this slice does not use RPL candidate in SPS for RPL0
+	int              rpl_l1_idx;         //-1 means this slice does not use RPL candidate in SPS for RPL1
+	COM_RPL          rpl_l0;
+	COM_RPL          rpl_l1;
+	u8               num_ref_idx_active_override_flag;
+	u8               ref_pic_list_sps_flag[2];
+#endif
+	u32              dtr;
+	u8               slice_type;
+	u8               temporal_id;
+	u8               loop_filter_disable_flag;
+	u32              bbv_delay;
+	u16              bbv_check_times;
+
+#if DBK_SCC
+	u8               loop_fitler_type;
+#endif
+	u8               loop_filter_parameter_flag;
+	int              alpha_c_offset;
+	int              beta_offset;
+
+	u8               chroma_quant_param_disable_flag;
+	s8               chroma_quant_param_delta_cb;
+	s8               chroma_quant_param_delta_cr;
+
+	/*Flag and coeff for ALF*/
+	int              tool_alf_on;
+#if ALF_SHAPE || ALF_IMP
+	int              tool_alf_shape_on;
+#endif
+	int             *pic_alf_on;
+	ALF_PARAM       **alf_picture_param;
+#if DBR
+	DBR_PARAM        ph_dbr_param;
+#endif
+
+	int              fixed_picture_qp_flag;
+#if CUDQP
+	u8               cu_delta_qp_flag;
+	u8               cu_qp_group_size;
+	int              cu_qp_group_area_size;
+#endif
+	int              random_access_decodable_flag;
+	int              time_code_flag;
+	int              time_code;
+	int              decode_order_index;
+	int              picture_output_delay;
+	int              progressive_frame;
+	int              picture_structure;
+	int              top_field_first;
+	int              repeat_first_field;
+	int              top_field_picture_flag;
+	int              picture_qp;
+	int              affine_subblock_size_idx;
+#if LIBVC_ON
+	int              is_RLpic_flag;  // only reference libpic
+	int              library_picture_index;
+#endif
+	int              pic_wq_enable;
+	int              pic_wq_data_idx;
+	int              wq_param;
+	int              wq_model;
+	int              wq_param_vector[6];
+	u8               wq_4x4_matrix[16];
+	u8               wq_8x8_matrix[64];
+#if USE_IBC
+	u8               ibc_flag;
+#endif
+#if USE_SP
+	u8               sp_pic_flag;
+#if EVS_UBVS_MODE
+	u8               evs_ubvs_pic_flag;
+#endif
+#endif
+#if FIMC
+	u8               fimc_pic_flag;
+#endif
+#if ISTS
+	u8               ph_ists_enable_flag;
+#endif
+#if TS_INTER
+	u8               ph_ts_inter_enable_flag;
+#endif
+#if AWP
+	u8               ph_awp_refine_flag;
+#endif
+#if AWP || FAST_LD
+	int              ph_poc[REFP_NUM][MAX_NUM_ACTIVE_REF_FRAME];
+#endif
+#if ENC_ME_IMP
+	BOOL             is_lowdelay;
+#endif
+#if FAST_LD
+	int              l1idx_to_l0idx[MAX_NUM_ACTIVE_REF_FRAME];
+#endif
+#if UMVE_ENH
+	u8               umve_set_flag;
+#endif
+#if EPMC
+	u8               ph_epmc_model_flag;
+#endif
+#if ESAO
+	u8               pic_esao_on[N_C];
+	u8               esao_adaptive_param[N_C];
+	u8               esao_luma_type;            //0:17 1 :9
+	u8               esao_lcu_enable[N_C];      //lcu mode control flag
+	int              esao_chroma_band_length[2];
+	int              esao_chroma_start_band[2];
+	int              esao_chroma_band_flag[2];
+#if ESAO_PH_SYNTAX
+	ESAO_BLK_PARAM   pic_esao_params[N_C];
+#endif
+#endif
+#if CCSAO
+	u8               pic_ccsao_on  [N_C-1];
+	u8               ccsao_lcu_ctrl[N_C-1];
+#if CCSAO_ENHANCEMENT
+	u8               ccsao_set_num   [N_C-1];
+	u8               ccsao_type      [N_C-1][CCSAO_SET_NUM];
+	u8               ccsao_band_num  [N_C-1][CCSAO_SET_NUM];
+	u8               ccsao_band_num_c[N_C-1][CCSAO_SET_NUM];
+#else
+	u8               ccsao_type    [N_C-1];
+	u8               ccsao_band_num[N_C-1];
+#endif
+#if CCSAO_PH_SYNTAX
+	CCSAO_BLK_PARAM  pic_ccsao_params[N_C-1];
+#endif
+#endif
+	int g_DOIPrev;
+	int g_CountDOICyCleTime;
+} COM_PIC_HEADER;
+
+typedef struct _COM_SH_EXT
+{
+	u8               slice_sao_enable[N_C];
+	u8               fixed_slice_qp_flag;
+	u8               slice_qp;
+} COM_SH_EXT;
+
+#if TB_SPLIT_EXT
+typedef struct _COM_PART_INFO
+{
+	u8 num_sub_part;
+	int sub_x[MAX_NUM_PB]; //sub part x, y, w and h
+	int sub_y[MAX_NUM_PB];
+	int sub_w[MAX_NUM_PB];
+	int sub_h[MAX_NUM_PB];
+	int sub_scup[MAX_NUM_PB];
+} COM_PART_INFO;
+#endif
+
+#if CUDQP
+typedef struct _COM_CU_QP_GROUP
+{
+	int num_delta_qp;
+	int cu_qp_group_x;
+	int cu_qp_group_y;
+	int pred_qp;
+	//encoder only
+	int target_qp_for_qp_group;
+	int qp_group_width;
+	int qp_group_height;
+} COM_CU_QP_GROUP;
+#endif
+
+typedef struct _COM_POS
+{
+	u8 a;    // 1/4 position
+	u8 b;    // 2/4 position
+	u8 c;    // 3/4 position
+} COM_POS;
+
+typedef struct _COM_POS_INFO
+{
+	COM_POS x;   // x dimension
+	COM_POS y;   // y dimension
+} COM_POS_INFO;
+/*****************************************************************************
+ * user data types
+ *****************************************************************************/
+#define COM_UD_PIC_SIGNATURE              0x10
+#define COM_UD_END                        0xFF
+
+#if USE_SP
+ /*****************************************************************************
+  * SP mode structure
+  *****************************************************************************/
+typedef struct _COM_SP_INFO
+{
+	u8  is_matched;
+	u16 length;
+	s16 offset_x;
+	s16 offset_y;
+#if SP_SLR
+	int match_dict[4];
+	pel pixel[4][N_C];
+#else
+	pel pixel[N_C];
+#endif
+#if !SP_CODE_TEXT_BUGFIX
+	u8  sp_length_type;
+#endif
+	u8  n_recent_flag;
+	s8  n_recent_idx;
+#if SP_SVP
+	s16 svp_x;
+	s16 svp_y;
+	s8  n_offset_num;
+#endif
+} COM_SP_INFO;
+#if EVS_UBVS_MODE
+typedef struct _COM_SP_PIX
+{
+	pel Y;
+	pel U;
+	pel V;
+}COM_SP_PIX;
+typedef struct _COM_SP_EVS_INFO
+{
+	u8  is_matched;
+	u16 length;
+	pel pixel[N_C];
+	u8  match_type;
+	u8  srb_index;
+	u16 srb_bits;
+	u16 srb_dist;
+	u8  esc_flag;
+	int pos;
+	s8  valid_flag;
+	u8  allcomp_adr_update_flag;
+}COM_SP_EVS_INFO;
+#endif
+#endif
+/*****************************************************************************
+ * for binary and triple tree structure
+ *****************************************************************************/
+typedef enum _SPLIT_MODE
+{
+	NO_SPLIT        = 0,
+	SPLIT_BI_VER    = 1,
+	SPLIT_BI_HOR    = 2,
+#if EQT
+	SPLIT_EQT_VER   = 3,
+	SPLIT_EQT_HOR   = 4,
+	SPLIT_QUAD      = 5,
+#else
+	SPLIT_QUAD      = 3,
+#endif
+	NUM_SPLIT_MODE
+} SPLIT_MODE;
+
+typedef enum _SPLIT_DIR
+{
+	SPLIT_VER = 0,
+	SPLIT_HOR = 1,
+	SPLIT_QT = 2,
+} SPLIT_DIR;
+
+#if MODE_CONS
+typedef enum _CONS_PRED_MODE
+{
+	NO_MODE_CONS = 0,
+	ONLY_INTER = 1,
+	ONLY_INTRA = 2,
+} CONS_PRED_MODE;
+#endif
+
+#if CHROMA_NOT_SPLIT
+typedef enum _TREE_STATUS
+{
+	TREE_LC = 0,
+	TREE_L  = 1,
+	TREE_C  = 2,
+} TREE_STATUS;
+#endif
+
+typedef enum _CHANNEL_TYPE
+{
+	CHANNEL_LC = 0,
+	CHANNEL_L  = 1,
+	CHANNEL_C  = 2,
+#if PMC || EPMC
+	CHANNEL_U  = 3,
+	CHANNEL_V  = 4,
+#endif
+} CHANNEL_TYPE;
+
+#if TB_SPLIT_EXT
+typedef enum _PART_SIZE
+{
+	SIZE_2Nx2N,           ///< symmetric partition,  2Nx2N
+	SIZE_2NxnU,           ///< asymmetric partition, 2Nx( N/2) + 2Nx(3N/2)
+	SIZE_2NxnD,           ///< asymmetric partition, 2Nx(3N/2) + 2Nx( N/2)
+	SIZE_nLx2N,           ///< asymmetric partition, ( N/2)x2N + (3N/2)x2N
+	SIZE_nRx2N,           ///< asymmetric partition, (3N/2)x2N + ( N/2)x2N
+	SIZE_NxN,             ///< symmetric partition, NxN
+	SIZE_2NxhN,           ///< symmetric partition, 2N x 0.5N
+	SIZE_hNx2N,           ///< symmetric partition, 0.5N x 2N
+	NUM_PART_SIZE
+} PART_SIZE;
+#endif
+
+typedef enum _BLOCK_SHAPE
+{
+	NON_SQUARE_18,
+	NON_SQUARE_14,
+	NON_SQUARE_12,
+	SQUARE,
+	NON_SQUARE_21,
+	NON_SQUARE_41,
+	NON_SQUARE_81,
+	NUM_BLOCK_SHAPE,
+} BLOCK_SHAPE;
+
+typedef enum _CTX_NEV_IDX
+{
+	CNID_SKIP_FLAG,
+	CNID_PRED_MODE,
+	CNID_AFFN_FLAG,
+	NUM_CNID,
+} CTX_NEV_IDX;
+
+#if AWP
+typedef enum _AWP_ANGLE_RATIO
+{
+	AWP_ANGLE_1,  // 1:1
+	AWP_ANGLE_2,  // 1:2 2:1
+	AWP_ANGLE_4,  // 1:4 4:1
+	AWP_ANGLE_8,  // 1:8 8:1
+	AWP_ANGLE_16,
+	AWP_ANGLE_32,
+	AWP_ANGLE_64,
+	AWP_ANGLE_HOR,
+	AWP_ANGLE_VER
+} AWP_ANGLE_RATIO;
+#endif
+
+#if DMVR
+#define DMVR_PAD_LENGTH                                        2
+#define EXTRA_PIXELS_FOR_FILTER                                7 // Maximum extraPixels required for final MC based on fiter size
+#define PAD_BUFFER_STRIDE                               ((MAX_CU_SIZE + EXTRA_PIXELS_FOR_FILTER + (DMVR_ITER_COUNT * 2)))
+static const int NTAPS_LUMA = 8; ///< Number of taps for luma
+static const int NTAPS_CHROMA = 4; ///< Number of taps for chroma
+#endif
+
+/*****************************************************************************
+* mode decision structure
+*****************************************************************************/
+typedef struct _COM_MODE
+{
+	/* CU position X in a frame in SCU unit */
+	int            x_scu;
+	/* CU position Y in a frame in SCU unit */
+	int            y_scu;
+
+	/* depth of current CU */
+	int            cud;
+
+	/* width of current CU */
+	int            cu_width;
+	/* height of current CU */
+	int            cu_height;
+	/* log2 of cu_width */
+	int             cu_width_log2;
+	/* log2 of cu_height */
+	int             cu_height_log2;
+	/* position of CU */
+	int            x_pos;
+	int            y_pos;
+	/* CU position in current frame in SCU unit */
+	int            scup;
+
+	int  cu_mode;
+#if TB_SPLIT_EXT
+	//note: DT can apply to intra CU and only use normal amvp for inter CU (no skip, direct, amvr, affine, hmvp)
+	int  pb_part;
+	int  tb_part;
+	COM_PART_INFO  pb_info;
+	COM_PART_INFO  tb_info;
+#endif
+#if SBT
+	u8   sbt_info;
+	int  sbt_hor_trans;
+	int  sbt_ver_trans;
+#endif
+
+	pel  rec[N_C][MAX_CU_DIM];
+	s16  coef[N_C][MAX_CU_DIM];
+	pel  pred[N_C][MAX_CU_DIM];
+
+#if TB_SPLIT_EXT
+	int  num_nz[MAX_NUM_TB][N_C];
+#else
+	int  num_nz[N_C];
+#endif
+
+	/* reference indices */
+	s8   refi[REFP_NUM];
+
+	/* MVR indices */
+	u8   mvr_idx;
+#if INTERPF
+	u8   inter_filter_flag;
+#endif
+#if BGC
+	u8   bgc_flag;
+	u8   bgc_idx;
+#if UMVE_ENH
+	s8   bgc_flag_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM_SEC_SET * UMVE_BASE_NUM];
+	s8   bgc_idx_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM_SEC_SET * UMVE_BASE_NUM];
+#else
+	s8   bgc_flag_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM * UMVE_BASE_NUM];
+	s8   bgc_idx_cands[MAX_SKIP_NUM + UMVE_MAX_REFINE_NUM * UMVE_BASE_NUM];
+#endif
+#endif
+	u8   umve_flag;
+	u8   umve_idx;
+	u8   skip_idx;
+#if EXT_AMVR_HMVP
+	u8   mvp_from_hmvp_flag;
+#endif
+#if IBC_BVP
+	u8   cbvp_idx;
+#if CBVP_LIST_SIMP
+	s8   cnt_hbvp_cands;
+#endif
+#endif
+
+#if SP_SVP
+	u8   svp_idx;
+#endif
+
+#if AFFINE_UMVE
+	u8   affine_umve_flag;
+	s8   affine_umve_idx[VER_NUM];
+	s8   best_affine_merge_index;
+#endif
+
+	/* mv difference */
+	s16  mvd[REFP_NUM][MV_D];
+	/* mv */
+	s16  mv[REFP_NUM][MV_D];
+
+	u8   affine_flag;
+	CPMV affine_mv[REFP_NUM][VER_NUM][MV_D];
+	s16  affine_mvd[REFP_NUM][VER_NUM][MV_D];
+
+#if AWP
+	/* awp flag*/
+	u8   awp_flag;
+	/* awp cand idx*/
+	u8   awp_idx0;
+	u8   awp_idx1;
+	/* awp mv & refidx*/
+	s16  awp_mv0[REFP_NUM][MV_D];
+	s16  awp_mv1[REFP_NUM][MV_D];
+	s8   awp_refi0[REFP_NUM];
+	s8   awp_refi1[REFP_NUM];
+#endif
+
+#if AWP_MVR
+	u8   awp_mvr_flag0;
+	u8   awp_mvr_idx0;
+	u8   awp_mvr_flag1;
+	u8   awp_mvr_idx1;
+#endif
+
+#if SMVD
+	u8   smvd_flag;
+#endif
+
+#if DMVR
+	pel  dmvr_template[MAX_CU_DIM];
+	pel  dmvr_ref_pred_interpolated[REFP_NUM][(MAX_CU_SIZE + (2*(DMVR_NEW_VERSION_ITER_COUNT + 1) * REF_PRED_EXTENTION_PEL_COUNT)) * (MAX_CU_SIZE + (2*(DMVR_NEW_VERSION_ITER_COUNT + 1) * REF_PRED_EXTENTION_PEL_COUNT))];
+	u8   dmvr_enable;
+	pel  dmvr_padding_buf[2][N_C][PAD_BUFFER_STRIDE * PAD_BUFFER_STRIDE];
+#endif
+
+#if ETMVP
+	u8   etmvp_flag;
+#endif
+
+	/* intra prediction mode */
+#if TB_SPLIT_EXT
+	u8   mpm[MAX_NUM_PB][2];
+	s8   ipm[MAX_NUM_PB][2];
+#else
+	u8   mpm[2];
+	s8   ipm[2];
+#endif
+#if USE_IBC
+	// ibc flag for MODE_IBC
+	u8   ibc_flag;
+#endif
+#if IBC_ABVR
+	u8   bvr_idx;
+#endif
+#if SIBC
+	u8   sibc_flag;
+#endif
+#if IIP
+	u8   iip_flag;
+#endif
+	u8   ipf_flag;
+	/* intra transform type */
+	u8   slice_type;
+#if IST
+	u8   ist_tu_flag;
+#endif
+#if ISTS
+	u8   ph_ists_enable_flag;
+#endif
+#if TS_INTER
+	u8   ph_ts_inter_enable_flag;
+#endif
+#if AWP
+	u8   ph_awp_refine_flag;
+#endif
+#if EST
+	u8   est_flag;
+#endif
+#if ST_CHROMA
+	u8   st_chroma_flag;
+#endif
+#if USE_SP
+	u8   sp_flag;
+	u8   sp_copy_direction;
+	u16  sub_string_no;
+	COM_SP_INFO string_copy_info[SP_STRING_INFO_NO];
+	double cur_bst_rdcost;
+	u8   is_sp_pix_completed;
+#endif
+#if EVS_UBVS_MODE
+	u8                   cs2_flag;
+	u8                   evs_copy_direction;
+	int                  evs_sub_string_no;
+	COM_SP_EVS_INFO*     evs_str_copy_info; //evs_str_copy_info[SP_STRING_INFO_NO];
+	int                  unpred_pix_num;
+	COM_SP_PIX*          unpred_pix_info;   //unpred_pix_info[SP_STRING_INFO_NO];
+	u8                   equal_val_str_present_flag;
+	u8                   unpredictable_pix_present_flag;
+	s16*                 p_SRB[N_C];
+	u8                   pvbuf_size;
+	u8*                  pvbuf_reused_flag;
+	u8                   all_comp_flag[MAX_SRB_SIZE];//1:LUMA AND CHROMA 0: ONLY LUMA
+	u8                   all_comp_pre_flag[MAX_SRB_PRED_SIZE];
+	u16                  temp_m_pvbuf[2][MAX_SRB_SIZE];
+	s16*                 p_SRB_prev[N_C];
+	u8                   pvbuf_size_prev;
+	u16                  m_pvbuf_prev[2][MAX_SRB_PRED_SIZE];
+	u16                  m_pvbuf[2][MAX_SRB_SIZE];
+	u16                  m_pvbuf_new[2][MAX_SRB_PRED_SIZE];
+	u8                   m_dpb_idx[MAX_SRB_SIZE];
+	u8                   m_dpb_idx_prev[MAX_SRB_PRED_SIZE];
+#endif
+} COM_MODE;
+
+/*****************************************************************************
+* map structure
+*****************************************************************************/
+typedef struct _COM_MAP
+{
+	/* SCU map for CU information */
+	u32                    *map_scu;
+	/* LCU split information */
+	s8                     (*map_split)[MAX_CU_DEPTH][NUM_BLOCK_SHAPE][MAX_CU_CNT_IN_LCU];
+	/* decoded motion vector for every blocks */
+	s16                    (*map_mv)[REFP_NUM][MV_D];
+	/* reference frame indices */
+	s8                     (*map_refi)[REFP_NUM];
+	/* intra prediction modes */
+	s8                     *map_ipm;
+	u32                    *map_cu_mode;
+#if TB_SPLIT_EXT
+	u32                    *map_pb_tb_part;
+#endif
+	s8                     *map_depth;
+	s8                     *map_delta_qp;
+	s8                     *map_patch_idx;
+#if USE_SP
+	u8                     *map_usp;
+#endif
+#if PATCH
+	u32                    *map_scu_temp;
+	u32                    *map_cu_mode_temp;
+	s16                    (*map_mv_temp)[REFP_NUM][MV_D];
+	s8                     (*map_refi_temp)[REFP_NUM];
+#if USE_SP
+	u8                     *map_usp_temp;
+#endif
+#endif
+} COM_MAP;
+
+/*****************************************************************************
+* common info
+*****************************************************************************/
+typedef struct _COM_INFO
+{
+	/* current chunk header */
+	COM_CNKH                cnkh;
+
+	/* current picture header */
+	COM_PIC_HEADER          pic_header;
+
+	/* current slice header */
+	COM_SH_EXT              shext;
+
+	/* sequence header */
+	COM_SQH                 sqh;
+
+	/* decoding picture width */
+	int                     pic_width;
+	/* decoding picture height */
+	int                     pic_height;
+	/* maximum CU width and height */
+	int                     max_cuwh;
+	/* log2 of maximum CU width and height */
+	int                     log2_max_cuwh;
+
+	/* picture width in LCU unit */
+	int                     pic_width_in_lcu;
+	/* picture height in LCU unit */
+	int                     pic_height_in_lcu;
+
+	/* picture size in LCU unit (= w_lcu * h_lcu) */
+	int                     f_lcu;
+	/* picture width in SCU unit */
+	int                     pic_width_in_scu;
+	/* picture height in SCU unit */
+	int                     pic_height_in_scu;
+	/* picture size in SCU unit (= pic_width_in_scu * h_scu) */
+	int                     f_scu;
+
+	int                     bit_depth_internal;
+	int                     bit_depth_input;
+	int                     qp_offset_bit_depth;
+#if ASP
+	BOOL                    skip_me_asp;
+	BOOL                    skip_umve_asp;
+#endif
+#if BGC
+	pel                    *pred_tmp;
+#endif
+} COM_INFO;
+
+typedef enum _MSL_IDX
+{
+	MSL_SKIP,  //skip
+	MSL_MERGE,  //merge or direct
+	MSL_LIS0,  //list 0
+	MSL_LIS1,  //list 1
+	MSL_BI,    //bi pred
+	NUM_MODE_SL,
+} MSL_IDX;
+/*****************************************************************************
+* patch info
+*****************************************************************************/
+#if PATCH
+typedef struct _PATCH_INFO
+{
+	int                     stable;
+	int                     cross_patch_loop_filter;
+	int                     ref_colocated;
+	int                     uniform;
+	int                     height;
+	int                     width;
+	int                     columns;
+	int                     rows;
+	int                     idx;
+	/*patch's location(up left) in pixel*/
+	int                     x_pel;
+	int                     y_pel;
+	/*all the cu in a patch are skip_mode*/
+	int                     skip_patch_flag;
+	/*pointer the width of each patch*/
+	int                    *width_in_lcu;
+	int                    *height_in_lcu;
+	/*count as the patch*/
+	int                     x_pat;
+	int                     y_pat;
+	/*define the boundary of a patch*/
+	int                     left_pel;
+	int                     right_pel;
+	int                     up_pel;
+	int                     down_pel;
+	/*patch_sao_enable_flag info of all patches*/
+	s8                     *patch_sao_enable;
+} PATCH_INFO;
+#endif
+typedef enum _TRANS_TYPE
+{
+	DCT2,
+	DCT8,
+	DST7,
+	NUM_TRANS_TYPE
+} TRANS_TYPE;
+
+#if FIMC
+typedef struct _COM_CNTMPM
+{
+	u32 freqT [CNTMPM_TABLE_LENGTH]; // freqT [ mode ]
+	u8  modeT [2];                   // modeT [ order]
+} COM_CNTMPM;
+#endif
+
+#if PMC || EPMC
+#define IS_RIGHT_CBF_U(cbf_u)               ((cbf_u) > 0)
+#define V_QP_OFFSET                         1
+#endif
+
+#if EPMC
+#define MOD_IDX                             2        //2 is -2
+#define MOD2_IDX                            1        //1 is -0.5
+#define TH_CBCR                             -0.10
+#endif
+
+#if IIP
+#define MAX_IIP_BLK                       4096 //the number is included
+#define MIN_IIP_BLK                       64 //the number is included
+#define STNUM                             5 // anchor is 3
+#else
+#define STNUM                             3 // anchor is 3
+#endif
+
+#if ASP
+#define ASP_SHIFT                          3
+#define DMV_BUF_SIZE                       8*8
+#endif
+#if 0
+#include "com_tbl.h"
+#include "com_util.h"
+#include "com_recon.h"
+#include "com_ipred.h"
+#include "com_tbl.h"
+#include "com_itdq.h"
+#include "com_picman.h"
+#include "com_mc.h"
+#include "com_img.h"
+#endif
+
+#endif /* _COM_DEF_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/com_picman.c b/drivers/frame_provider/decoder/avs3/com_picman.c
new file mode 100644
index 0000000..4da867a
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_picman.c
@@ -0,0 +1,1214 @@
+/* ====================================================================================================================
+
+	The copyright in this software is being made available under the 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) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+	Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+	Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+	Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted only for
+	the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+	promoting such standards. The following conditions are required to be 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.
+	* The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be 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.
+
+* ====================================================================================================================
+*/
+#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/slab.h>
+
+//#include "com_def.h"
+#include "avs3_global.h"
+
+#ifdef SIMULATION
+#ifdef SYSTEM_TEST
+#define printf st_printf
+#define printk st_printf
+#else
+#define printf io_printf
+#define printk io_printf
+#endif
+#endif
+
+/* macros for reference picture flag */
+#define IS_REF(pic)          (((pic)->is_ref) != 0)
+#define SET_REF_UNMARK(pic)  (((pic)->is_ref) = 0)
+#define SET_REF_MARK(pic)    (((pic)->is_ref) = 1)
+
+#define PRINT_DPB(pm)\
+	printf("%s: current num_ref = %d, dpb_size = %d\n", __FUNCTION__, \
+	pm->cur_num_ref_pics, picman_get_num_allocated_pics(pm));
+
+static unsigned long com_picman_lock(COM_PM * pm)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&pm->pm_lock, flags);
+
+	return flags;
+}
+
+void com_picman_unlock(COM_PM * pm, unsigned long flags)
+{
+	spin_unlock_irqrestore(&pm->pm_lock, flags);
+}
+
+static int picman_get_num_allocated_pics(COM_PM * pm)
+{
+	int i, cnt = 0;
+	for (i = 0; i < pm->max_pb_size; i++) /* this is coding order */
+	{
+		if (pm->pic[i])
+			cnt++;
+	}
+	return cnt;
+}
+
+static int picman_move_pic(COM_PM *pm, int from, int to)
+{
+	int i;
+	COM_PIC * pic;
+	int temp_cur_num_ref_pics = pm->cur_num_ref_pics;
+	BOOL found_empty_pos = 0;
+
+	pic = pm->pic[from];
+
+	for (i = from; i < temp_cur_num_ref_pics - 1; i++) {
+	pm->pic[i] = pm->pic[i + 1];// move the remaining ref pic to the front
+	}
+	pm->pic[temp_cur_num_ref_pics - 1] = NULL; // the new end fill with NULL.
+	temp_cur_num_ref_pics--;// update, since the ref-pic number decrease
+	for (i = to; i > temp_cur_num_ref_pics; i--) {
+		if (pm->pic[i] == NULL) {
+			pm->pic[i] = pic;// find the first NULL pos from end to front, and fill with the un-ref pic
+			found_empty_pos = 1;
+			break;
+		}
+	}
+
+	if (found_empty_pos != 1) {
+		pr_info("%s pic %p will be discarded\n", __func__, pic);
+	}
+	assert(found_empty_pos == 1);
+	return 0;
+}
+
+#if 0
+static void picman_flush_pb(COM_PM * pm)
+{
+	int i;
+	/* mark all frames unused */
+	for (i = 0; i < MAX_PB_SIZE; i++)
+	{
+		if (pm->pic[i]) SET_REF_UNMARK(pm->pic[i]);
+	}
+	pm->cur_num_ref_pics = 0;
+}
+#endif
+static void picman_update_pic_ref(COM_PM * pm)
+{
+	COM_PIC ** pic;
+	COM_PIC ** pic_ref;
+	COM_PIC  * pic_t;
+	int i, j, cnt;
+	ulong flags;
+
+	flags = com_picman_lock(pm);
+
+	pic = pm->pic;
+	pic_ref = pm->pic_ref;
+	for (i = 0, j = 0; i < pm->max_pb_size; i++) {
+		if (pic[i] && IS_REF(pic[i])) {
+#ifdef BUFMGR_SANITY_CHECK
+			if (j < MAX_NUM_REF_PICS)
+				pic_ref[j++] = pic[i];
+			else {
+				if (avs3_get_debug_flag())
+					pr_info("%s ref pic num(%d) is more than the MAX_NUM_REF_PICS\n",
+						__func__, j);
+			}
+#else
+			pic_ref[j++] = pic[i];
+#endif
+		}
+	}
+	cnt = j;
+	while (j < MAX_NUM_REF_PICS)
+		pic_ref[j++] = NULL;
+	/* descending order sort based on PTR */
+	for (i = 0; i < cnt - 1; i++) {
+		for (j = i + 1; j < cnt; j++) {
+#ifdef BUFMGR_SANITY_CHECK
+			if (i >= MAX_NUM_REF_PICS || j >= MAX_NUM_REF_PICS) {
+				if (avs3_get_debug_flag())
+					pr_info("%s pm pic num(%d,%d) is more than the MAX_NUM_REF_PICS\n",
+						__func__, i, j);
+				return;
+			}
+#endif
+			if (pic_ref[i]->ptr < pic_ref[j]->ptr) {
+				pic_t = pic_ref[i];
+				pic_ref[i] = pic_ref[j];
+				pic_ref[j] = pic_t;
+			}
+		}
+	}
+
+	com_picman_unlock(pm, flags);
+}
+
+static COM_PIC * picman_remove_pic_from_pb(COM_PM * pm, int pos)
+{
+	int         i;
+	COM_PIC  * pic_rem;
+	ulong flags;
+
+	flags = com_picman_lock(pm);
+
+	pic_rem = pm->pic[pos];
+	printf("%s: pic %p pos %d\n", __func__, pic_rem, pos);
+	pm->pic[pos] = NULL;
+	/* fill empty pic buffer */
+	for (i = pos; i < pm->max_pb_size - 1; i++) {
+		pm->pic[i] = pm->pic[i + 1];
+	}
+	pm->pic[pm->max_pb_size - 1] = NULL;
+	pm->cur_pb_size--;
+
+	com_picman_unlock(pm, flags);
+
+	return pic_rem;
+}
+
+static void picman_set_pic_to_pb(COM_PM * pm, COM_PIC * pic,
+				     COM_REFP(*refp)[REFP_NUM], int pos)
+{
+	int i;
+	printf("%s: pic %p pos %d\n", __func__, pic, pos);
+	for (i = 0; i < pm->num_refp[REFP_0]; i++) {
+#if ETMVP || SUB_TMVP || AWP
+		pic->list_ptr[REFP_0][i] = refp[i][REFP_0].ptr;
+#else
+		pic->list_ptr[i] = refp[i][REFP_0].ptr;
+#endif
+	}
+#if ETMVP || SUB_TMVP || AWP
+	for (i = 0; i < pm->num_refp[REFP_1]; i++) {
+		pic->list_ptr[REFP_1][i] = refp[i][REFP_1].ptr;
+	}
+#endif
+	if (pos >= 0) {
+		com_assert(pm->pic[pos] == NULL);
+		if (pm->pic[pos] != NULL) {
+			COM_PIC * pos_pic;
+			pos_pic = pm->pic[pos];
+
+			/* search empty pic buffer position */
+			for (i = (pm->max_pb_size - 1); i >= 0; i--)
+			{
+				if (pm->pic[i] == NULL)
+				{
+					pm->pic[i] = pos_pic;
+					break;
+				}
+			}
+
+			if (i < 0)
+			{
+				printf("pos pic will be discarded\n");
+			}
+		}
+		pm->pic[pos] = pic;
+	} else /* pos < 0 */
+	{
+		/* search empty pic buffer position */
+		for (i = (pm->max_pb_size - 1); i >= 0; i--) {
+			if (pm->pic[i] == NULL) {
+				pm->pic[i] = pic;
+				break;
+			}
+		}
+		if (i < 0) {
+			printf("i=%d\n", i);
+			com_assert(i >= 0);
+		}
+	}
+	pm->cur_pb_size++;
+}
+
+static int picman_get_empty_pic_from_list(COM_PM * pm)
+{
+	//COM_IMGB * imgb;
+	COM_PIC  * pic;
+	int i;
+	for (i = 0; i < pm->max_pb_size; i++) {
+		pic = pm->pic[i];
+		if (pic != NULL && !IS_REF(pic) && pic->need_for_out == 0
+#ifdef AML
+		&& pic->buf_cfg.vf_ref == 0
+		&& pic->buf_cfg.backend_ref == 0
+		&& pic->buf_cfg.in_dpb == 0
+#endif
+		) {
+#ifdef ORI_CODE
+			imgb = pic->imgb;
+			com_assert(imgb != NULL);
+			/* check reference count */
+			if (1 == imgb->getref(imgb)) {
+				return i; /* this is empty buffer */
+			}
+#else
+			printf("%s: pm index %d pic index %d\n",
+				__func__, i, pic->buf_cfg.index);
+			return i;
+#endif
+		}
+	}
+	return -1;
+}
+
+void set_refp(COM_REFP * refp, COM_PIC  * pic_ref)
+{
+	refp->pic      = pic_ref;
+	refp->ptr      = pic_ref->ptr;
+	refp->map_mv   = pic_ref->map_mv;
+	refp->map_refi = pic_ref->map_refi;
+	refp->list_ptr = pic_ref->list_ptr;
+#if LIBVC_ON
+	refp->is_library_picture = 0;
+#endif
+}
+
+void copy_refp(COM_REFP * refp_dst, COM_REFP * refp_src)
+{
+	refp_dst->pic      = refp_src->pic;
+	refp_dst->ptr      = refp_src->ptr;
+	refp_dst->map_mv   = refp_src->map_mv;
+	refp_dst->map_refi = refp_src->map_refi;
+	refp_dst->list_ptr = refp_src->list_ptr;
+#if LIBVC_ON
+	refp_dst->is_library_picture = refp_src->is_library_picture;
+#endif
+}
+
+int check_copy_refp(COM_REFP(*refp)[REFP_NUM], int cnt, int lidx, COM_REFP  * refp_src)
+{
+	int i;
+	for (i = 0; i < cnt; i++) {
+#if LIBVC_ON
+		if (refp[i][lidx].ptr == refp_src->ptr && refp[i][lidx].is_library_picture == refp_src->is_library_picture)
+#else
+		if (refp[i][lidx].ptr == refp_src->ptr)
+#endif
+		{
+			return -1;
+		}
+	}
+	copy_refp(&refp[cnt][lidx], refp_src);
+	return COM_OK;
+}
+
+#if HLS_RPL   //This is implementation of reference picture list construction based on RPL. This is meant to replace function int com_picman_refp_init(COM_PM *pm, int num_ref_pics_act, int slice_type, u32 ptr, u8 layer_id, int last_intra, COM_REFP(*refp)[REFP_NUM])
+int com_picman_refp_rpl_based_init(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM])
+{
+	//MX: IDR?
+	int i;
+	if ((pic_header->slice_type == SLICE_I) && (pic_header->poc == 0))
+	{
+		pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+		return COM_OK;
+	}
+
+	picman_update_pic_ref(pm);
+
+#if LIBVC_ON
+	if (!pm->libvc_data->library_picture_enable_flag && pic_header->slice_type != SLICE_I)
+#endif
+	{
+		com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+	}
+
+	for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+		refp[i][REFP_0].pic = refp[i][REFP_1].pic = NULL;
+	}
+
+	pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+
+	//Do the L0 first
+	for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++) {
+#if LIBVC_ON
+		if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l0.library_index_flag[i]) {
+			int ref_lib_index = pic_header->rpl_l0.ref_pics[i];
+			com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+
+		set_refp(&refp[i][REFP_0], pm->pb_libpic);
+		refp[i][REFP_0].ptr = pic_header->poc - 1;
+		refp[i][REFP_0].is_library_picture = 1;
+		pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+		}
+		else
+#endif
+		{
+		int refPicPoc = pic_header->poc - pic_header->rpl_l0.ref_pics[i];
+		//Find the ref pic in the DPB
+			int j = 0;
+			int diff;
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+				j++;
+
+			//If the ref pic is found, set it to RPL0
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+
+				set_refp(&refp[i][REFP_0], pm->pic_ref[j]);
+				pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+				//make sure delta doi of RPL0 correct,in case of last incomplete GOP
+				diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+				if (diff != pic_header->rpl_l0.ref_pics_ddoi[i]) {
+					pic_header->ref_pic_list_sps_flag[0] = 0;
+					pic_header->rpl_l0.ref_pics_ddoi[i] = diff;
+				}
+			} else {
+				printf("%s: The L0 Reference Picture(%d) is not find in dpb",
+					__func__, refPicPoc);
+				return COM_ERR;   //The refence picture must be available in the DPB, if not found then there is problem
+			}
+		}
+	}
+
+	//update inactive ref ddoi in L0,in case of last incomplete GOP
+	for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+#if LIBVC_ON
+		if (!pic_header->rpl_l0.library_index_flag[i] && pic_header->rpl_l0.ref_pics[i] > 0)
+#else
+		if (pic_header->rpl_l0.ref_pics[i] > 0)
+#endif
+		{
+			int refPicPoc = pic_header->poc - pic_header->rpl_l0.ref_pics[i];
+			//Find the ref pic in the DPB
+			int j = 0;
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+				j++;
+
+			//If the ref pic is found, set it to RPL0
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+				int diff = (pic_header->decode_order_index % DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+				if (diff != pic_header->rpl_l0.ref_pics_ddoi[i]) {
+					pic_header->ref_pic_list_sps_flag[0] = 0;
+					pic_header->rpl_l0.ref_pics_ddoi[i] = diff;
+				}
+			}
+		}
+	}
+	if (pic_header->slice_type == SLICE_P) return COM_OK;
+
+	//Do the L1 first
+	for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++) {
+#if LIBVC_ON
+		if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l1.library_index_flag[i]) {
+			int ref_lib_index = pic_header->rpl_l1.ref_pics[i];
+			com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+
+			set_refp(&refp[i][REFP_1], pm->pb_libpic);
+			refp[i][REFP_1].ptr = pic_header->poc - 1;
+			refp[i][REFP_1].is_library_picture = 1;
+			pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+		} else
+#endif
+		{
+			int refPicPoc = pic_header->poc - pic_header->rpl_l1.ref_pics[i];
+			//Find the ref pic in the DPB
+			int j = 0;
+			int diff;
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+				j++;
+
+			//If the ref pic is found, set it to RPL1
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+				set_refp(&refp[i][REFP_1], pm->pic_ref[j]);
+				pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+				//make sure delta doi of RPL0 correct
+				diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+				if (diff != pic_header->rpl_l1.ref_pics_ddoi[i]) {
+					pic_header->ref_pic_list_sps_flag[1] = 0;
+					pic_header->rpl_l1.ref_pics_ddoi[i] = diff;
+				}
+			} else {
+				printf("%s: The L1 Reference Picture(%d) is not find in dpb",
+					__func__, refPicPoc);
+				return COM_ERR;   //The refence picture must be available in the DPB, if not found then there is problem
+			}
+		}
+	}
+	//update inactive ref ddoi in L1
+	for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+#if LIBVC_ON
+		if (!pic_header->rpl_l1.library_index_flag[i] && pic_header->rpl_l1.ref_pics[i] > 0)
+#else
+		if (pic_header->rpl_l1.ref_pics[i] > 0)
+#endif
+		{
+			int refPicPoc = pic_header->poc - pic_header->rpl_l1.ref_pics[i];
+			//Find the ref pic in the DPB
+			int j = 0;
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr != refPicPoc)
+				j++;
+
+			//If the ref pic is found, set it to RPL0
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->ptr == refPicPoc) {
+				int diff = (pic_header->decode_order_index%DOI_CYCLE_LENGTH - pm->pic_ref[j]->dtr);//MX: doi is not increase mono, but in the range of [0,255]; the diff may be minus value.
+				if (diff != pic_header->rpl_l1.ref_pics_ddoi[i]) {
+					pic_header->ref_pic_list_sps_flag[1] = 0;
+					pic_header->rpl_l1.ref_pics_ddoi[i] = diff;
+				}
+			}
+		}
+	}
+	return COM_OK;  //RPL construction completed
+}
+
+int com_cleanup_useless_pic_buffer_in_pm( COM_PM *pm )
+{
+	//remove the pic if it is a unref pic, and has been output.
+	int i;
+	printf("%s\n", __func__);
+	for (i = 0; i < pm->max_pb_size; i++) {
+		if (pm->pic[i] != NULL)
+			printf("pm pic %p index %d\n", pm->pic[i], i);
+		if ( (pm->pic[i] != NULL) && (pm->pic[i]->need_for_out == 0)
+		&& (pm->pic[i]->is_ref == 0)
+#ifdef AML
+		&& (pm->pic[i]->buf_cfg.backend_ref == 0)
+		&& (pm->pic[i]->buf_cfg.vf_ref == 0)
+#endif
+		) {
+			com_pic_free(pm->hw, &pm->pa, pm->pic[i]);
+			pm->cur_pb_size--;
+			pm->pic[i] = NULL;
+		}
+	}
+	return COM_OK;
+}
+
+int com_picman_dpbpic_doi_minus_cycle_length( COM_PM *pm )
+{
+	COM_PIC * pic;
+	int i;
+	for (i = 0; i < pm->max_pb_size; i++) {
+		pic = pm->pic[i];
+		if ( pic != NULL )//MX: no matter whether is ref or unref(for output), need to minus 256.
+		{
+			pic->dtr = pic->dtr - DOI_CYCLE_LENGTH;
+			assert( pic->dtr >= (-256) );//MX:minus once at most.
+		}
+	}
+	return COM_OK;
+}
+
+//This is implementation of reference picture list construction based on RPL for decoder
+//in decoder, use DOI as pic reference instead of POC
+int com_picman_refp_rpl_based_init_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header, COM_REFP(*refp)[REFP_NUM])
+{
+	int i;
+	picman_update_pic_ref(pm);
+#ifdef BUFMGR_SANITY_CHECK
+	for (i = 0; i < pm->cur_num_ref_pics; i++) {
+		if (pm->pic_ref[i] == NULL) {
+			if (avs3_get_debug_flag())
+				pr_info("%s error, pm->cur_num_ref_pics = %d,  pm->pic_ref[%d] is NULL\n",
+					__func__, pm->cur_num_ref_pics, i);
+			return COM_ERR;
+		}
+	}
+#endif
+#if LIBVC_ON
+	if (!pm->libvc_data->library_picture_enable_flag && pic_header->slice_type != SLICE_I)
+#endif
+	{
+		com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+	}
+
+	for (i = 0; i < MAX_NUM_REF_PICS; i++)
+		refp[i][REFP_0].pic = refp[i][REFP_1].pic = NULL;
+	pm->num_refp[REFP_0] = pm->num_refp[REFP_1] = 0;
+
+	//Do the L0 first
+	for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++) {
+#if LIBVC_ON
+		if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l0.library_index_flag[i]) {
+			int ref_lib_index;
+			ref_lib_index = pic_header->rpl_l0.ref_pics_ddoi[i];
+			com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+#ifdef BUFMGR_SANITY_CHECK
+			if (pm->pb_libpic == NULL) {
+				if (avs3_get_debug_flag())
+					pr_info("%s error, pm->pb_libpic is NULL\n", __func__);
+				return COM_ERR;
+			}
+#endif
+			set_refp(&refp[i][REFP_0], pm->pb_libpic);
+			refp[i][REFP_0].ptr = pic_header->poc - 1;
+			refp[i][REFP_0].is_library_picture = 1;
+			pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+		} else
+#endif
+		{
+			int refPicDoi = pic_header->rpl_l0.ref_pics_doi[i];//MX: no need to fix the value in the range of 0~255. because DOI in the DPB can be a minus value, after minus 256.
+			//Find the ref pic in the DPB
+			int j = 0;
+			ulong flags;
+
+			flags = com_picman_lock(pm);
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr != refPicDoi)
+				j++;
+
+			//If the ref pic is found, set it to RPL0
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr == refPicDoi) {
+				set_refp(&refp[i][REFP_0], pm->pic_ref[j]);
+				pm->num_refp[REFP_0] = pm->num_refp[REFP_0] + 1;
+			} else {
+				com_picman_unlock(pm, flags);
+				printf("%s: The L0 Reference Picture(%d) is not find in dpb",
+					__func__, refPicDoi);
+				return COM_ERR;   //The refence picture must be available in the DPB, if not found then there is problem
+			}
+
+			com_picman_unlock(pm, flags);
+		}
+	}
+
+	if (pic_header->slice_type == SLICE_P)
+		return COM_OK;
+
+	//Do the L1 first
+	for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++) {
+#if LIBVC_ON
+		if (pm->libvc_data->library_picture_enable_flag && pic_header->rpl_l1.library_index_flag[i]) {
+			int ref_lib_index = pic_header->rpl_l1.ref_pics_ddoi[i];
+			com_assert_rv(ref_lib_index == pm->pb_libpic_library_index, COM_ERR_UNEXPECTED);
+#ifdef BUFMGR_SANITY_CHECK
+			if (pm->pb_libpic == NULL) {
+				if (avs3_get_debug_flag())
+					pr_info("%s error, pm->pb_libpic is NULL\n", __func__);
+				return COM_ERR;
+			}
+#endif
+			set_refp(&refp[i][REFP_1], pm->pb_libpic);
+			refp[i][REFP_1].ptr = pic_header->poc - 1;
+			refp[i][REFP_1].is_library_picture = 1;
+			pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+		} else
+#endif
+		{
+			int refPicDoi = pic_header->rpl_l1.ref_pics_doi[i];//MX: no need to fix the value in the range of 0~255. because DOI in the DPB can be a minus value, after minus 256.
+			//Find the ref pic in the DPB
+			int j = 0;
+#ifdef BUFMGR_SANITY_CHECK
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr != refPicDoi)
+#else
+			while (j < pm->cur_num_ref_pics && pm->pic_ref[j]->dtr != refPicDoi)
+#endif
+			{
+				j++;
+			}
+
+			//If the ref pic is found, set it to RPL1
+#ifdef BUFMGR_SANITY_CHECK
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j] && pm->pic_ref[j]->dtr == refPicDoi)
+#else
+			if (j < pm->cur_num_ref_pics && pm->pic_ref[j]->dtr == refPicDoi)
+#endif
+			{
+				set_refp(&refp[i][REFP_1], pm->pic_ref[j]);
+				pm->num_refp[REFP_1] = pm->num_refp[REFP_1] + 1;
+			} else {
+				printf("%s: The L1 Reference Picture(%d) is not find in dpb",
+					__func__, refPicDoi);
+				return COM_ERR;   //The refence picture must be available in the DPB, if not found then there is problem
+			}
+		}
+	}
+
+	return COM_OK;  //RPL construction completed
+}
+#endif
+
+COM_PIC * com_picman_get_empty_pic(COM_PM * pm, int * err)
+{
+	int ret;
+	COM_PIC * pic = NULL;
+#if LIBVC_ON
+	if (pm->libvc_data->is_libpic_processing) {
+		/* no need to find empty picture buffer in list */
+		ret = -1;
+	} else
+#endif
+	{
+		/* try to find empty picture buffer in list */
+		ret = picman_get_empty_pic_from_list(pm);
+	}
+	if (ret >= 0) {
+		pic = picman_remove_pic_from_pb(pm, ret);
+		goto END;
+	}
+	/* else if available, allocate picture buffer */
+	pm->cur_pb_size = picman_get_num_allocated_pics(pm);
+	printf("cur_pb_size %d, cur_libpb_size %d, max_pb_size %d\n",
+		pm->cur_pb_size, pm->cur_libpb_size, pm->max_pb_size);
+#if LIBVC_ON
+	if (pm->cur_pb_size + pm->cur_libpb_size < pm->max_pb_size)
+#else
+	if (pm->cur_pb_size < pm->max_pb_size)
+#endif
+	{
+		/* create picture buffer */
+		pic = com_pic_alloc(pm->hw, &pm->pa, &ret);
+		com_assert_gv(pic != NULL, ret, COM_ERR_OUT_OF_MEMORY, ERR);
+		goto END;
+	}
+	com_assert_gv(0, ret, COM_ERR_UNKNOWN, ERR);
+END:
+	pm->pic_lease = pic;
+	if (err) *err = COM_OK;
+	return pic;
+ERR:
+	if (err) *err = ret;
+	if (pic) com_pic_free(pm->hw, &pm->pa, pic);
+	return NULL;
+}
+#if HLS_RPL
+/*This is the implementation of reference picture marking based on RPL*/
+int com_picman_refpic_marking(COM_PM *pm, COM_PIC_HEADER *pic_header)
+{
+	int i;
+	COM_PIC * pic;
+	int count_library_picture = 0;
+	int referenced_library_picture_index = -1;
+	int numberOfPicsToCheck;
+
+	picman_update_pic_ref(pm);
+#if LIBVC_ON
+	if (!pic_header->rpl_l0.reference_to_library_enable_flag && !pic_header->rpl_l1.reference_to_library_enable_flag && pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#else
+	if (pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#endif
+		com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+
+	numberOfPicsToCheck = pm->cur_num_ref_pics;
+	for (i = 0; i < numberOfPicsToCheck; i++) {
+		pic = pm->pic[i];
+		if (pm->pic[i] && IS_REF(pm->pic[i])) {
+			//If the pic in the DPB is a reference picture, check if this pic is included in RPL0
+			int isIncludedInRPL = 0;
+			int j = 0;
+			while (!isIncludedInRPL && j < pic_header->rpl_l0.ref_pic_num) {
+#if LIBVC_ON
+				if ((pic->ptr == (pic_header->poc - pic_header->rpl_l0.ref_pics[j])) && !pic_header->rpl_l0.library_index_flag[j])  //NOTE: we need to put POC also in COM_PIC
+#else
+				if (pic->ptr == (pic_header->poc - pic_header->rpl_l0.ref_pics[j]))  //NOTE: we need to put POC also in COM_PIC
+#endif
+				{
+					isIncludedInRPL = 1;
+			}
+			j++;
+		}
+			//Check if the pic is included in RPL1. This while loop will be executed only if the ref pic is not included in RPL0
+			j = 0;
+			while (!isIncludedInRPL && j < pic_header->rpl_l1.ref_pic_num) {
+#if LIBVC_ON
+				if ((pic->ptr == (pic_header->poc - pic_header->rpl_l1.ref_pics[j])) && !pic_header->rpl_l1.library_index_flag[j])  //NOTE: we need to put POC also in COM_PIC
+#else
+				if (pic->ptr == (pic_header->poc - pic_header->rpl_l1.ref_pics[j]))
+#endif
+				{
+					isIncludedInRPL = 1;
+				}
+				j++;
+			}
+			//If the ref pic is not included in either RPL0 nor RPL1, then mark it as not used for reference. move it to the end of DPB.
+			if (!isIncludedInRPL) {
+				SET_REF_UNMARK(pic);
+				picman_move_pic(pm, i, pm->max_pb_size - 1);
+				pm->cur_num_ref_pics--;
+				i--;                                           //We need to decrement i here because it will be increment by i++ at for loop. We want to keep the same i here because after the move, the current ref pic at i position is the i+1 position which we still need to check.
+				numberOfPicsToCheck--;                         //We also need to decrement this variable to avoid checking the moved ref picture twice.
+		}
+		}
+	}
+#if LIBVC_ON
+	// count the libpic in rpl
+	for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+		if (pic_header->rpl_l0.library_index_flag[i]) {
+			if (count_library_picture == 0) {
+				referenced_library_picture_index = pic_header->rpl_l0.ref_pics[i];
+				count_library_picture++;
+			}
+
+			com_assert_rv(referenced_library_picture_index == pic_header->rpl_l0.ref_pics[i], COM_ERR_UNEXPECTED);
+		}
+	}
+	for (i = 0; i < pic_header->rpl_l1.ref_pic_num; i++) {
+		if (pic_header->rpl_l1.library_index_flag[i]) {
+			if (count_library_picture == 0) {
+				referenced_library_picture_index = pic_header->rpl_l1.ref_pics[i];
+				count_library_picture++;
+			}
+
+			com_assert_rv(referenced_library_picture_index == pic_header->rpl_l1.ref_pics[i], COM_ERR_UNEXPECTED);
+		}
+	}
+
+	if (count_library_picture > 0) {
+		// move out lib pic
+		if (!pm->is_library_buffer_empty && (referenced_library_picture_index != pm->pb_libpic_library_index)) {
+			//com_picbuf_free(pm->libvc_data->pb_libpic);
+			pm->pb_libpic = NULL;
+			pm->cur_libpb_size--;
+			pm->pb_libpic_library_index = -1;
+			pm->is_library_buffer_empty = 1;
+		}
+		// move in lib pic from the buffer outside the decoder
+		if (pm->is_library_buffer_empty) {
+			//send out referenced_library_picture_index
+			int  libpic_idx = -1;
+			int ii;
+			for (ii = 0; ii < pm->libvc_data->num_libpic_outside; ii++) {
+				if (referenced_library_picture_index == pm->libvc_data->list_library_index_outside[ii]) {
+					libpic_idx = ii;
+					break;
+				}
+		}
+		com_assert_rv(libpic_idx >= 0, COM_ERR_UNEXPECTED);
+
+		// move in lib pic from the buffer outside the decoder
+		pm->pb_libpic = pm->libvc_data->list_libpic_outside[libpic_idx];
+		pm->pb_libpic_library_index = referenced_library_picture_index;
+		pm->cur_libpb_size++;
+		pm->is_library_buffer_empty = 0;
+		}
+	}
+#endif
+	return COM_OK;
+}
+
+int com_construct_ref_list_doi( COM_PIC_HEADER *pic_header)
+{
+	int i;
+
+	if (pic_header == NULL)
+		return COM_ERR;
+
+	if ((pic_header->rpl_l0.ref_pic_num > MAX_NUM_REF_PICS) ||
+		(pic_header->rpl_l1.ref_pic_num > MAX_NUM_REF_PICS))
+		return COM_ERR;
+
+	for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+		pic_header->rpl_l0.ref_pics_doi[i] = pic_header->decode_order_index%DOI_CYCLE_LENGTH - pic_header->rpl_l0.ref_pics_ddoi[i];
+	}
+	if (is_avs3_print_bufmgr_detail()) {
+		printf("rpl_l0.ref_pics_doi[%d]=%d, pic_header->rpl_l0.ref_pics_ddoi[%d]=%d\n",
+			i, pic_header->rpl_l0.ref_pics_doi[i], i, pic_header->rpl_l0.ref_pics_ddoi[i]);
+	}
+	for ( i = 0; i < pic_header->rpl_l1.ref_pic_num; i++ )
+	{
+		pic_header->rpl_l1.ref_pics_doi[i] = pic_header->decode_order_index%DOI_CYCLE_LENGTH - pic_header->rpl_l1.ref_pics_ddoi[i];
+	}
+	if (is_avs3_print_bufmgr_detail()) {
+		printf("rpl_l1.ref_pics_doi[%d]=%d, pic_header->rpl_l1.ref_pics_ddoi[%d]=%d\n",
+			i, pic_header->rpl_l1.ref_pics_doi[i], i, pic_header->rpl_l1.ref_pics_ddoi[i]);
+	}
+	return COM_OK;
+}
+
+/*This is the implementation of reference picture marking based on RPL for decoder */
+/*In decoder side, use DOI as pic reference instead of POI */
+int com_picman_refpic_marking_decoder(COM_PM *pm, COM_PIC_HEADER *pic_header)
+{
+	int i;
+	COM_PIC * pic;
+	int numberOfPicsToCheck;
+	int count_library_picture = 0;
+	int referenced_library_picture_index = -1;
+
+	picman_update_pic_ref(pm);
+#if LIBVC_ON
+	if (!pic_header->rpl_l0.reference_to_library_enable_flag && !pic_header->rpl_l1.reference_to_library_enable_flag && pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#else
+	if (pic_header->slice_type != SLICE_I && pic_header->poc != 0)
+#endif
+		com_assert_rv(pm->cur_num_ref_pics > 0, COM_ERR_UNEXPECTED);
+
+	numberOfPicsToCheck = pm->cur_num_ref_pics;
+	for (i = 0; i < numberOfPicsToCheck; i++) {
+		pic = pm->pic[i];
+		if (pm->pic[i] && IS_REF(pm->pic[i])) {
+			//If the pic in the DPB is a reference picture, check if this pic is included in RPL0
+			int isIncludedInRPL = 0;
+			int j = 0;
+			while (!isIncludedInRPL && j < pic_header->rpl_l0.ref_pic_num) {
+#if LIBVC_ON
+				if (!pic_header->rpl_l0.library_index_flag[j] && pic->dtr == pic_header->rpl_l0.ref_pics_doi[j])
+#else
+				if ( pic->dtr == ((pic_header->decode_order_index - pic_header->rpl_l0.ref_pics_ddoi[j] + DOI_CYCLE_LENGTH) % DOI_CYCLE_LENGTH) )  //NOTE: we need to put POC also in COM_PIC
+#endif
+				{
+					isIncludedInRPL = 1;
+				}
+				j++;
+			}
+			//Check if the pic is included in RPL1. This while loop will be executed only if the ref pic is not included in RPL0
+			j = 0;
+			while (!isIncludedInRPL && j < pic_header->rpl_l1.ref_pic_num) {
+#if LIBVC_ON
+				if ( !pic_header->rpl_l1.library_index_flag[j] && pic->dtr == pic_header->rpl_l1.ref_pics_doi[j] )
+#else
+				if ( pic->dtr == ((pic_header->decode_order_index - pic_header->rpl_l1.ref_pics_ddoi[j] + DOI_CYCLE_LENGTH) % DOI_CYCLE_LENGTH) )
+#endif
+				{
+					isIncludedInRPL = 1;
+				}
+				j++;
+			}
+			//If the ref pic is not included in either RPL0 nor RPL1, then mark it as not used for reference. move it to the end of DPB.
+			if (!isIncludedInRPL) {
+				SET_REF_UNMARK(pic);
+				picman_move_pic(pm, i, pm->max_pb_size - 1);
+				pm->cur_num_ref_pics--;
+				i--;                                           //We need to decrement i here because it will be increment by i++ at for loop. We want to keep the same i here because after the move, the current ref pic at i position is the i+1 position which we still need to check.
+				numberOfPicsToCheck--;                         //We also need to decrement this variable to avoid checking the moved ref picture twice.
+			}
+		}
+	}
+#if LIBVC_ON
+	// count the libpic in rpl
+	for (i = 0; i < pic_header->rpl_l0.ref_pic_num; i++) {
+		if (pic_header->rpl_l0.library_index_flag[i]) {
+			if (count_library_picture == 0) {
+				referenced_library_picture_index = pic_header->rpl_l0.ref_pics_ddoi[i];
+				count_library_picture++;
+			}
+
+			com_assert_rv(referenced_library_picture_index == pic_header->rpl_l0.ref_pics_ddoi[i], COM_ERR_UNEXPECTED);
+		}
+	}
+	for (i = 0; i < pic_header->rpl_l1.ref_pic_num; i++) {
+		if (pic_header->rpl_l1.library_index_flag[i]) {
+			if (count_library_picture == 0) {
+				referenced_library_picture_index = pic_header->rpl_l1.ref_pics_ddoi[i];
+				count_library_picture++;
+			}
+
+			com_assert_rv(referenced_library_picture_index == pic_header->rpl_l1.ref_pics_ddoi[i], COM_ERR_UNEXPECTED);
+		}
+	}
+
+	if (count_library_picture > 0) {
+		// move out lib pic
+		if (!pm->is_library_buffer_empty && (referenced_library_picture_index != pm->pb_libpic_library_index)) {
+			//com_picbuf_free(pm->libvc_data->pb_libpic);
+			pm->pb_libpic = NULL;
+			pm->cur_libpb_size--;
+			pm->pb_libpic_library_index = -1;
+			pm->is_library_buffer_empty = 1;
+		}
+		// move in lib pic from the buffer outside the decoder
+		if (pm->is_library_buffer_empty) {
+			//send out referenced_library_picture_index
+			int  libpic_idx = -1;
+			int ii;
+			for (ii = 0; ii < pm->libvc_data->num_libpic_outside; ii++) {
+				if (referenced_library_picture_index == pm->libvc_data->list_library_index_outside[ii])
+				{
+					libpic_idx = ii;
+					break;
+				}
+			}
+			com_assert_rv(libpic_idx >= 0, COM_ERR_UNEXPECTED);
+
+			//move in the corresponding referenced library pic
+			pm->pb_libpic = pm->libvc_data->list_libpic_outside[libpic_idx];
+			pm->pb_libpic_library_index = referenced_library_picture_index;
+			pm->cur_libpb_size++;
+			pm->is_library_buffer_empty = 0;
+		}
+	}
+#endif
+	return COM_OK;
+}
+
+#endif
+
+#if LIBVC_ON
+int com_picman_put_libpic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM], COM_PIC_HEADER * pic_header)
+{
+	int i;
+	SET_REF_MARK(pic);
+	pic->temporal_id = temporal_id;
+	pic->ptr = ptr;
+	pic->dtr = dtr;
+	pic->need_for_out = (u8)need_for_output;
+
+	for (i = 0; i < pm->num_refp[REFP_0]; i++) {
+#if ETMVP || SUB_TMVP || AWP
+		pic->list_ptr[REFP_0][i] = refp[i][REFP_0].ptr;
+#else
+		pic->list_ptr[i] = refp[i][REFP_0].ptr;
+#endif
+	}
+#if ETMVP || SUB_TMVP || AWP
+	for (i = 0; i < pm->num_refp[REFP_1]; i++) {
+		pic->list_ptr[REFP_1][i] = refp[i][REFP_1].ptr;
+	}
+#endif
+
+	// move out
+	if (!pm->is_library_buffer_empty) {
+		//com_picbuf_free(pm->pb_libpic);
+		pm->pb_libpic = NULL;
+		pm->cur_libpb_size--;
+		pm->pb_libpic_library_index = -1;
+		pm->is_library_buffer_empty = 1;
+	}
+
+	// move in
+	pm->pb_libpic = pic;
+	pm->pb_libpic_library_index = pic_header->library_picture_index;
+	pm->cur_libpb_size++;
+	pm->is_library_buffer_empty = 0;
+
+	if (pm->pic_lease == pic) {
+		pm->pic_lease = NULL;
+	}
+
+	return COM_OK;
+}
+#endif
+
+int com_picman_put_pic(COM_PM * pm, COM_PIC * pic, int slice_type, u32 ptr, u32 dtr,
+	u32 picture_output_delay, u8 temporal_id, int need_for_output, COM_REFP(*refp)[REFP_NUM])
+{
+	/* manage RPB */
+	SET_REF_MARK(pic);
+	pic->temporal_id = temporal_id;
+	pic->ptr = ptr;
+	pic->dtr = dtr%DOI_CYCLE_LENGTH;//MX: range of 0~255
+	pic->picture_output_delay = picture_output_delay;
+	pic->need_for_out = (u8)need_for_output;
+	/* put picture into listed RPB */
+	if (IS_REF(pic)) {
+		picman_set_pic_to_pb(pm, pic, refp, pm->cur_num_ref_pics);
+		pm->cur_num_ref_pics++;
+#ifdef BUFMGR_SANITY_CHECK
+		if (pm->cur_num_ref_pics > MAX_NUM_REF_PICS) {
+			if (avs3_get_debug_flag())
+				pr_info("pm->cur_num_ref_pics (%d) is beyond limit, force it to %d\n",
+					pm->cur_num_ref_pics, MAX_NUM_REF_PICS);
+			pm->cur_num_ref_pics = MAX_NUM_REF_PICS;
+		}
+#endif
+	} else {
+		picman_set_pic_to_pb(pm, pic, refp, -1);
+	}
+	if (pm->pic_lease == pic) {
+		pm->pic_lease = NULL;
+	}
+	/*PRINT_DPB(pm);*/
+	return COM_OK;
+}
+#if LIBVC_ON
+int com_picman_out_libpic(COM_PIC * pic, int library_picture_index, COM_PM * pm)
+{
+	if (pic != NULL && pic->need_for_out)
+	{
+		//output to the buffer outside the decoder
+		int num_libpic_outside = pm->libvc_data->num_libpic_outside;
+		pm->libvc_data->list_libpic_outside[num_libpic_outside] = pic;
+		pm->libvc_data->list_library_index_outside[num_libpic_outside] = library_picture_index;
+		pm->libvc_data->num_libpic_outside++;
+		pic->need_for_out = 0;
+
+		return COM_OK;
+	} else {
+		return COM_ERR_UNEXPECTED;
+	}
+}
+#endif
+
+COM_PIC * com_picman_out_pic(COM_PM * pm, int * err, int cur_pic_doi, int state)
+{
+	COM_PIC ** ps;
+	int i, ret, any_need_for_out = 0;
+	BOOL exist_pic = 0;
+	int temp_smallest_poc = MAX_INT;
+	int temp_idx_for_smallest_poc = 0;
+	ps = pm->pic;
+
+	if (state != 1) {
+		for (i = 0; i < pm->max_pb_size; i++) {
+			if (ps[i] != NULL && ps[i]->need_for_out) {
+				any_need_for_out = 1;
+				if ((ps[i]->dtr + ps[i]->picture_output_delay <= cur_pic_doi)) {
+					exist_pic = 1;
+					if (temp_smallest_poc >= ps[i]->ptr)
+					{
+						temp_smallest_poc = ps[i]->ptr;
+						temp_idx_for_smallest_poc = i;
+					}
+				}
+			}
+		}
+		if (exist_pic) {
+			ps[temp_idx_for_smallest_poc]->need_for_out = 0;
+			if (err) *err = COM_OK;
+			return ps[temp_idx_for_smallest_poc];
+		}
+	} else {
+		//bumping state, bumping the pic in the DPB according to the POC number, from small to larger.
+		for (i = 0; i < pm->max_pb_size; i++) {
+			if (ps[i] != NULL && ps[i]->need_for_out) {
+				any_need_for_out = 1;
+				//Need to output the smallest poc
+				if ((ps[i]->ptr <= temp_smallest_poc)) {
+					exist_pic = 1;
+					temp_smallest_poc = ps[i]->ptr;
+					temp_idx_for_smallest_poc = i;
+				}
+			}
+		}
+		if (exist_pic) {
+			ps[temp_idx_for_smallest_poc]->need_for_out = 0;
+			if (err) *err = COM_OK;
+			return ps[temp_idx_for_smallest_poc];
+		}
+	}
+
+	if (any_need_for_out == 0) {
+		ret = COM_ERR_UNEXPECTED;
+	} else {
+		ret = COM_OK_FRM_DELAYED;
+	}
+	if (err) *err = ret;
+	return NULL;
+}
+
+int com_picman_deinit(COM_PM * pm)
+{
+	int i;
+	/* remove allocated picture and picture store buffer */
+	for (i = 0; i < pm->max_pb_size; i++) {
+		if (pm->pic[i]) {
+			com_pic_free(pm->hw, &pm->pa, pm->pic[i]);
+			pm->pic[i] = NULL;
+		}
+	}
+	if (pm->pic_lease) {
+		com_pic_free(pm->hw, &pm->pa, pm->pic_lease);
+		pm->pic_lease = NULL;
+	}
+
+	pm->cur_num_ref_pics = 0;
+
+#if LIBVC_ON
+	if (pm->pb_libpic) {
+		pm->pb_libpic = NULL;
+	}
+	pm->cur_libpb_size = 0;
+	pm->pb_libpic_library_index = -1;
+	pm->is_library_buffer_empty = 1;
+#endif
+	return COM_OK;
+}
+
+int com_picman_init(COM_PM * pm, int max_pb_size, int max_num_ref_pics, PICBUF_ALLOCATOR * pa)
+{
+	if (max_num_ref_pics > MAX_NUM_REF_PICS || max_pb_size > MAX_PB_SIZE) {
+		return COM_ERR_UNSUPPORTED;
+	}
+	spin_lock_init(&pm->pm_lock);
+	pm->max_num_ref_pics = max_num_ref_pics;
+	pm->max_pb_size = max_pb_size;
+	pm->ptr_increase = 1;
+	pm->pic_lease = NULL;
+	com_mcpy(&pm->pa, pa, sizeof(PICBUF_ALLOCATOR));
+#if LIBVC_ON
+	pm->pb_libpic = NULL;
+	pm->cur_libpb_size = 0;
+	pm->pb_libpic_library_index = -1;
+	pm->is_library_buffer_empty = 1;
+#endif
+	return COM_OK;
+}
+
+int com_picman_check_repeat_doi(COM_PM * pm, COM_PIC_HEADER * pic_header)
+{
+	COM_PIC * pic;
+	int i;
+	for (i = 0; i < pm->max_pb_size; i++) {
+		pic = pm->pic[i];
+		if (pic != NULL) {
+			assert(pic->dtr != pic_header->decode_order_index);//the DOI of current frame cannot be the same as the DOI of pic in DPB.
+		}
+	}
+	return COM_OK;
+}
+
+void com_picman_print_state(COM_PM * pm)
+{
+	COM_PIC * pic;
+	char tmpbuf[128];
+	int i, ii, j;
+	printf("pm->pic:\n");
+	for (i = 0; i < pm->max_pb_size; i++) {
+		pic = pm->pic[i];
+		if (pic != NULL) {
+			int pos = 0;
+			for (ii = 0; ii < 2; ii++) {
+				pos += sprintf(&tmpbuf[pos], "(");
+				for (j = 0; j < MAX_NUM_REF_PICS; j++)
+					pos += sprintf(&tmpbuf[pos], "%d ", pic->list_ptr[ii][j]);
+				pos += sprintf(&tmpbuf[pos], ")");
+			}
+
+			printf("%d: pic %p index %d dtr %d ptr %d is_ref %d need_for_out %d, backend_ref %d, vf_ref %d, output_delay %d, w/h(%d,%d) id %d, list_ptr %s\n",
+				i, pic, pic->buf_cfg.index, pic->dtr, pic->ptr, pic->is_ref,
+				pic->need_for_out, pic->buf_cfg.backend_ref, pic->buf_cfg.vf_ref,
+				pic->picture_output_delay,
+				pic->width_luma, pic->height_luma, pic->temporal_id,
+				tmpbuf);
+		}
+	}
+}
diff --git a/drivers/frame_provider/decoder/avs3/com_port.h b/drivers/frame_provider/decoder/avs3/com_port.h
new file mode 100644
index 0000000..a239d9c
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_port.h
@@ -0,0 +1,152 @@
+/* ====================================================================================================================
+
+	The copyright in this software is being made available under the 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) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+	Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+	Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+	Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted only for
+	the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+	promoting such standards. The following conditions are required to be 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.
+	* The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be 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.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_PORT_H_
+#define _COM_PORT_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+ * types
+ *****************************************************************************/
+typedef s16                        pel; /* pixel type */
+typedef s32                        double_pel; /* pixel type */
+
+#ifndef NULL
+#define NULL                      (void*)0
+#endif
+
+/*****************************************************************************
+ * limit constant
+ *****************************************************************************/
+#define COM_UINT16_MAX          ((u16)0xFFFF)
+#define COM_UINT16_MIN          ((u16)0x0)
+#define COM_INT16_MAX           ((s16)0x7FFF)
+#define COM_INT16_MIN           ((s16)0x8000)
+
+#define COM_UINT_MAX            ((u32)0xFFFFFFFF)
+#define COM_UINT_MIN            ((u32)0x0)
+#define COM_INT_MAX             ((int)0x7FFFFFFF)
+#define COM_INT_MIN             ((int)0x80000000)
+
+#define COM_UINT32_MAX          ((u32)0xFFFFFFFF)
+#define COM_UINT32_MIN          ((u32)0x0)
+#define COM_INT32_MAX           ((s32)0x7FFFFFFF)
+#define COM_INT32_MIN           ((s32)0x80000000)
+
+#define COM_UINT64_MAX          ((u64)0xFFFFFFFFFFFFFFFFL)
+#define COM_UINT64_MIN          ((u64)0x0L)
+#define COM_INT64_MAX           ((s64)0x7FFFFFFFFFFFFFFFL)
+#define COM_INT64_MIN           ((s64)0x8000000000000000L)
+
+#define COM_INT18_MAX           ((s32)(131071))
+#define COM_INT18_MIN           ((s32)(-131072))
+
+/*****************************************************************************
+ * memory operations
+ *****************************************************************************/
+#define com_malloc(size)          malloc((size))
+#define com_malloc_fast(size)     com_malloc((size))
+
+#define com_mfree(m)              if (m) {free(m);}
+#define com_mfree_fast(m)         if (m) {com_mfree(m);}
+
+#define com_mcpy(dst,src,size)    memcpy((dst), (src), (size))
+#define com_mset(dst,v,size)      memset((dst), (v), (size))
+#define com_mset_x64a(dst,v,size) memset((dst), (v), (size))
+#define com_mset_x128(dst,v,size) memset((dst), (v), (size))
+#define com_mcmp(dst,src,size)    memcmp((dst), (src), (size))
+static __inline void com_mset_16b(s16 * dst, s16 v, int cnt)
+{
+	int i;
+	for (i=0; i<cnt; i++)
+		dst[i] = v;
+}
+
+/*****************************************************************************
+ * trace and assert
+ *****************************************************************************/
+#ifndef COM_TRACE
+#define COM_TRACE               0
+#endif
+
+/* print function */
+#if defined(LINUX)
+#define com_print(args...) printf(args)
+#else
+#define com_print(args,...) printf(args,__VA_ARGS__)
+#endif
+
+/* trace function */
+#if COM_TRACE
+#define com_trace com_print("[%s:%d] ", __FILE__, __LINE__); com_print
+#else
+#if defined(LINUX)
+#define com_trace(args...) {}
+#else
+#define com_trace(...) {}
+#endif
+#endif
+
+/* assert function */
+//#include <assert.h>
+#define com_assert(x) \
+	{if (!(x)) {assert(x);}}
+#define com_assert_r(x) \
+	{if (!(x)) {assert(x); return;}}
+#define com_assert_rv(x,r) \
+	{if (!(x)) {assert(x); return (r);}}
+#define com_assert_g(x,g) \
+	{if (!(x)) {assert(x); goto g;}}
+#define com_assert_gv(x,r,v,g) \
+	{if (!(x)) {assert(x); (r)=(v); goto g;}}
+
+#ifdef X86_SSE
+#if defined(WIN32) || defined(WIN64)
+#include <emmintrin.h>
+#include <xmmintrin.h>
+#include <tmmintrin.h>
+#include <smmintrin.h>
+#else
+//#include <x86intrin.h>
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COM_PORT_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/com_typedef.h b/drivers/frame_provider/decoder/avs3/com_typedef.h
new file mode 100644
index 0000000..459a0f7
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/com_typedef.h
@@ -0,0 +1,713 @@
+/* ====================================================================================================================
+
+	The copyright in this software is being made available under the 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) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+	Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+	Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+	Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted only for
+	the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+	promoting such standards. The following conditions are required to be 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.
+	* The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be 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.
+
+* ====================================================================================================================
+*/
+
+#ifndef _COM_H_
+#define _COM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define HPM_VERSION "10.0"
+
+/* AVS3 phase-2 macros*/
+//intra
+#define EIPM                               1 // M4993: extended intra prediction mode
+#define MIPF                               1 // M5079: multiple intra prediction filter
+#define PMC                                1 // M5158: Prediction from Multiple Cross-components
+#define IPF_CHROMA                         1 // M5385 M5418: enable intrapf for chroma components
+#define IIP                                1 // M5826: Improved Intra Prediction
+//inter
+#define DMVR                               1 // M4813: decoder-side motion vector refinement
+#define BIO                                1 // M4762: Bi-directional Optical Flow
+#define BGC                                1 // M5398: Bi-directional Gradient Correction
+#define INTERPF                            1 // M4812: inter prediction filtering
+#define MVAP                               1 // M4926: motion vector angel prediction
+#define AFFINE_UMVE                        1 // M5095: Enhanced Affine Skip/Direct Mode
+#define AWP                                1 // M5142: angular weighted prediction & M5143: AWP list construction optimization
+#define ETMVP                              1 // M5330(CE2-1.1):Enhanced temporal motion vector prediction
+#define UMVE_ENH                           1 // M5379: enable the combination of interPF and UMVE modes; picture-level UMVE offset adaptation
+#define SUB_TMVP                           1 // M5396(CE2-2.1) + M5397: NxN subblock TMVP
+#define ASP                                1 // M5801 (CE2-3.2): affine secondary prediction
+//transform & quantization
+#define IST                                1 // M4772: implicit selection of transforms for intra residual
+#define SBT                                1 // M4876: sub-block transform for inter residual
+#define EST                                1 // M5159: Enhanced Secondary Transform
+#define ST_CHROMA                          1 // M5874: Secondary transform for intra chroma residual
+#define CUDQP                              1 // M5877: cu-level qp adjustment
+//residual coding & CABAC
+#define SRCC                               1 // M4763: scan region based coefficient coding
+#define CABAC_MULTI_PROB                   1 // M4867 M5139: counter-based multi-probability CABAC
+//scc tools (off for class A/B/C in CTC, and enabled for scc seqs)
+#define USE_IBC                            1 // M4859: intra block copy [cannot off now]
+#define FIMC                               1 // M4972: frequency-based intra mode coding
+#if IST
+#define ISTS                               1 // M5160: Implicit Selection of Transform Skip
+#endif
+#define USE_SP                             1 // M5226: String Prediction
+#if ISTS
+#define TS_INTER                           1 // M5601: Transform skip for inter-coded blocks
+#define ETS                                1 // M5954: Extended Transform Skip
+#endif
+// in-loop filter tools
+#define ESAO                               1 // M5374: Enhanced Sample Adaptive Offset
+#define DBR                                1 // M5587: deblocking refinement
+#define ALF_SHAPE                          1 // M5589: increased ALF coefficient
+#define ALF_IMP                            1 // M5964: ALF improvements
+#define CCSAO                              1 // M5800: Cross-component Sample Adaptive Offset
+#define DBK_SCC                            1 // M5221 + M5869: improved deblock filter
+
+//detailed change on each new coding tool
+#if DBK_SCC
+#define DBK_OPT                            1 // M5869(CE2-2.1): improve deblock filter
+#endif
+
+#if SBT
+#define ISBT                               1 // M5952: Implicit signaling for SBT
+#endif
+
+#if IIP
+#define IIP_BUGFIX                         1 // bug fix for iip codes, change the performance of HPM9.1
+#endif
+
+#if PMC
+#define EPMC                               1 // M5659: extended PMC
+#endif
+
+#if AWP
+#define AWP_MVR                            1 // M5380: angular weighted prediction with motion vector refinement
+#endif
+
+#if CUDQP
+#define CUDQP_QP_MAP                       1 // generate 16x16 QP map based on texture variance
+#define CUDQP_PLATFORM_BUGFIX              1 // [Note]: can be cleaned up in next HPM version
+#define ONLY_ONE_DQP                       1 // only one delta QP in one QG (useful as 0 for conformance test, since we support multiple QPs in one QG)
+#endif
+
+#if ESAO
+#define ESAO_PH_SYNTAX                     1
+#endif
+
+#if CCSAO
+#define CCSAO_PH_SYNTAX                    1
+#if CCSAO_PH_SYNTAX
+#define CCSAO_ENHANCEMENT                  1 // M6051: alternative set and chroma BO for CCSAO
+#endif
+#endif
+
+#if USE_IBC
+#define IBC_REF_POS_CONS                   1 // M4940: position constraint of reference block in IBC mode
+#define IBC_ABVR                           1 // M5070: IBC adaptive block vector resolution
+#define IBC_BVP                            1 // M5081: IBC block vector prediction
+#define CBVP_LIST_SIMP                     1 // M5810: simplification of CBVP list construction
+#define SIBC                               1 // M5976: symmetric intra block copy
+#define BVD_CODING                         1 // M5961: modification of BVD coding
+#endif
+
+#if USE_SP
+#define SP_SVP                             0 // M5613: SP string vector prediction
+#define SP_SLR                             1 // M5631: control of SP string length resolution
+#define SP_CU_BUGFIX                       1 // M5611: cu block string prediction Tree_L distortion miss shift right
+#define SP_CODE_TEXT_BUGFIX                1 // M5669: fix on the inconsistency between code and text for SP
+#define EVS_UBVS_MODE                      1 // M5822: add evs_ubvs (equal value string and unit basic vector string) SP sub-mode
+#define SP_REF_OVERLAP                     1 // M5994: allow the reference string above to overlap with current string
+#define SP_DEC_SV_CHECK                    1 // M5864: check if string vector valid within search range
+#endif
+
+//code optimization
+#if EST
+#define EST_BUGFIX                         1 // M5944:EST bugfix
+#endif
+
+#define ALF_DEC_OPT                        1 // M5589: Remove unnecessary judgments in the filtering process
+#define INTER_ME_MVLIB                     1 // M5527: improved EPZS motion estimation based on motion vector library
+#define ENC_ME_IMP                         1 // M5806: gradient-based motion estimation and affine CPMV library
+#define ETMVP_FLAG_BUG_FIX                 1 // M5886: add necessary condition for etmvp flag coding
+
+#define AFFINE_UMVE_OPT                    1 //M5812: speedup for affine umve
+
+#define AWP_MVR_ENCODER_OPT                1 // M5871: improve AWP_MVR idx cost estimation
+
+#if USE_IBC && USE_SP
+#define SCC_CROSSINFO_UTILIZE             1 // M5605: SCC cross info utilize
+#endif
+
+#if USE_SP
+#define SP_BUGFIX                          1 // M5679: SP encoder bugfix
+#define SP_ALIGN_SIGN_BUGFIX               1 // M5822: SP encoder bugfix
+#define SP_SV_ENCODE_BUGIFX                1 // M5934: SP encode bugfix
+#if SP_SLR
+#define SP_SLR_BUGFIX                      1 // M5783: SP SLR bugfix
+#endif
+#define SP_FLAG_BUGFIX                     1 // M5992: encoder bugfix related to SP flag
+#endif
+#define SCC_BUGFIX                         1 // M5821: SCC encoder bugfix
+#define SCC_BUGFIX2                        1 // M5882: SCC encoder bugfix
+#if SCC_BUGFIX2
+#define IBC_RDO_BUGFIX                     1
+#define SP_RDO_BUGFIX                      1
+#define CS_RDO_BUGFIX                      1
+#endif
+
+#define REUSE_CU_SPLIT_OPT                 1 // M5900: Adjust threshold for reusing cu results
+
+#define REFORMAT_HASH_RATIO                1 // fix issue 152: multiple calculation of hash ratio
+
+#define BITSTREAM_MERGE_BUGFIX             1 // M5867: bugfix for bitstream merge
+
+//high-level
+#define PHASE_2_PROFILE                    1 //
+/*end of AVS phase-2 macros*/
+
+/* ------------------------BELOW HERE is related to AVS3 phase 1 -----------------------*/
+/*non-normative bugfix for AVS3 phase-1 after HPM4.0.1 (if any, add here) */
+
+/*end of non-normative bugfix */
+
+/*normative bugfix for AVS3 phase-1 after HPM4.0.1 (if any, add here) */
+
+/*end of normative bugfix */
+
+//high level syntax
+#define WRITE_MD5_IN_USER_DATA             1 // write per-frame MD5 into user_data after picture header
+#define REPEAT_SEQ_HEADER                  1 // add sequence header before each I frame
+
+#define HLS_RPL                            1
+#if HLS_RPL
+#define DOI_CYCLE_LENGTH                 256 // the length of the DOI cycle.
+#endif
+
+#define PATCH                              1
+#if PATCH
+#define PATCH_M4839                        1
+#define PATCH_HEADER_PARAM_TEST            0 // different patches have different patch-header patch_sao_enable_flag parameters
+#endif
+
+//partition
+#define EQT                                1
+//debug
+#define SPLIT_DEBUG                        1  // some debug code to check the split
+#define PLATFORM_GENERAL_DEBUG             1  // some key check points at encoder for detecting potential bugs
+/*  ---------------------------   conformance test related, start   -------------------------------------*/
+#define PRINT_SQH_PARAM_DEC                1
+#define FIXED_SPLIT                        0  // fixed split pattern [must be OFF in formal test] <<<<<<<<<----------NOTE
+#if FIXED_SPLIT
+#define FS_ALL_COMBINATION                 0  // test split combination of 6 depth
+#if FS_ALL_COMBINATION
+#define START_QT_DEPTH                     0
+#define START_SPLIT_MODE                   0  // 0: not constrain; 1~5: constrain 1 split at start qt depth
+#define VERIFY_SPLIT                       0  // print target split combination for each CTU
+#define FS_SIMPLE_ORDER                    1  // simple order of split modes (from smallest mode value to the largest)
+#endif
+#define FS_SAME_SIZE_PER_X_CTU             1  // constrained size changed per X CTUs
+#if FS_SAME_SIZE_PER_X_CTU
+#define FS_SAME_SIZE_X_VAL                 1  // can be any value larger than 0
+#endif
+#endif
+/*  ---------------------------   conformance test related, end     -------------------------------------*/
+
+//coding mode constraint for region of 64 pixels
+#define MODE_CONS                          1  // [this macro cannot be off]
+//chroma no split for avoiding 2xN chroma blocks
+#define CHROMA_NOT_SPLIT                   1  // [this macro cannot be off]
+
+//for DT and PBT
+#define TB_SPLIT_EXT                       1  // extend the framework to support multiple luma prediction & transform blocks (support PBT and Intra DT) [this macro cannot be off]
+#if TB_SPLIT_EXT
+//fast algorithm (common)
+#define TR_SAVE_LOAD                       1  // fast algorithm for PBT
+#define TR_EARLY_TERMINATE                 1  // fast algorithm for PBT
+#endif
+#define DT_PARTITION                       1  // [this macro cannot be off] (DT can be turn off ONLY by configure)
+#if DT_PARTITION
+#define DT_SYNTAX                          1  // syntax change to support DT (must be 1)
+//DT_INTRA
+#define DT_INTRA_FAST_BY_RD                1  // fast algorithm: early skip based on RD cost comparison
+#define DT_SAVE_LOAD                       1  // fast algorithm: save & load best part_size
+#endif
+#define PRINT_CU                           0
+#define PRINT_CU_LEVEL_2                   0
+#define PRINT_HMVP_FIFO                    0
+#define PRINT_TRANSFORM_TABLE              0
+#define DEBUG_TEST_CHANGE_HORI_VERT_SIZE   0  //change horizontal_size and vertical_size to (8xN-1) in sqh coding
+#define PSNR_1020                          0  //use 1020 as peak value for 10-bit picture in PSNR calculation (for comparing PSNR with HM and VTM)
+//**************** This part needs clean-up later (End)
+
+//intra
+#define TSCPM                              1
+#if TSCPM
+#define ENHANCE_TSPCM                      1
+#endif
+#define IPCM                               1
+
+//inter
+#define BD_AFFINE_AMVR                     1  // M4565 combine Affine and AMVR
+
+#define EXT_AMVR_HMVP                      1
+
+#define SMVD                               1  // Symmetric MVD mode
+
+#define INTER_CU_CONSTRAINT                1
+
+#define SEP_CONTEXT                        1 // Separate context for useless bin
+
+//transform
+
+// filter
+#define DEBLOCK_M4647                      1
+
+// others
+#define USE_RDOQ                           1 // Use RDOQ
+#define RDO_DBK                            1 // include DBK changes to luma samples into distortion
+#if RDO_DBK
+#define RDO_DBK_LUMA_ONLY                  1 // M5315: DBK encoder speed up
+#endif
+
+#define AFFINE_MVF_VERIFY                  0 // for debugging, clean up later
+
+#define CPMV_BIT_DEPTH                     18
+#if CPMV_BIT_DEPTH == 18
+typedef int                                CPMV;
+#else
+typedef short                              CPMV;
+#endif
+#define COM_CPMV_MAX                       ((s32)((1<<(CPMV_BIT_DEPTH - 1)) - 1))
+#define COM_CPMV_MIN                       ((s32)(-(1<<(CPMV_BIT_DEPTH - 1))))
+
+#define LIBVC_ON                           1 // use Library Picture
+#if LIBVC_ON
+#define IPPPCRR                            1
+#if IPPPCRR
+#define PB_REF_LIB                         1
+#define LIB_PIC_UPDATE                     1 // M5422 adaptive library picture update
+#endif
+#define CRR_ENC_OPT_CFG                    1 // M5533 CRR encoding optimization about configuration
+#endif
+#define EXTENSION_USER_DATA                1
+#if EXTENSION_USER_DATA
+#define CRR_EXTENSION_DATA                 1 // M4822: cross random-access-point referencing extension
+#define HLS_12_6_7                         0 // write sequence display extension data into bitstream
+#define HLS_12_8                           0 // write CRR extension data into bitstream
+#endif
+
+#define WEIGHTED_SATD                      1 // M5382: Improved SATD based cost calculation
+
+//fast algorithm
+#define ENC_ECU_DEPTH                      4 // for early CU termination
+#define ENC_ECU_ADAPTIVE                   1 // for early CU termination
+#define MULTI_REF_ME_STEP                  1 // for ME speed-up
+#define FAST_LD                            1 // M5557: fast me for lowdelay case
+#define BET_SPLIT_DECISION                  1 // M5965: Test2, fast BET split decision based on QT split result
+
+//bbv
+#define BBV                                1 // for Bitstream Buffer verifies
+#if BBV
+#define BBV_DELAY_MAX                      0xFFFFFFFF
+#define BBV_CHECK_FRAMES_MAX               2000
+#define BBV_LIBVC                          1 // whether the bbv is with libvc
+#endif
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//                              SIMD Optimizations                            //
+//                                                                            //
+////////////////////////////////////////////////////////////////////////////////
+#define X86_SSE                            1
+#if X86_SSE
+#define SIMD_MC                            1
+#define SIMD_SAD                           1
+#define SIMD_SSD                           1
+#define SIMD_DIFF                          1
+#define SIMD_HAD_SAD                       1
+#define SIMD_AFFINE                        1
+#if ASP
+#define SIMD_ASP                           1
+#endif // ASP
+#if ENC_ME_IMP
+#define SIMD_GRAD_ME                       1
+#endif
+#else
+#define SIMD_MC                            0
+#define SIMD_SAD                           0
+#define SIMD_SSD                           0
+#define SIMD_DIFF                          0
+#define SIMD_HAD_SAD                       0
+#define SIMD_AFFINE                        0
+#if ASP
+#define SIMD_ASP                           0
+#endif // ASP
+#if ENC_ME_IMP
+#define SIMD_GRAD_ME                       0
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//                                                                            //
+//                         Certain Tools Parameters                           //
+//                                                                            //
+////////////////////////////////////////////////////////////////////////////////
+
+#define INC_QT_DEPTH(qtd, smode)           (smode == SPLIT_QUAD? (qtd + 1) : qtd)
+#define INC_BET_DEPTH(betd, smode)         (smode != SPLIT_QUAD? (betd + 1) : betd)
+
+#if EQT
+#define MAX_SPLIT_NUM                      6
+#define SPLIT_CHECK_NUM                    6
+#else
+#define MAX_SPLIT_NUM                      4
+#define SPLIT_CHECK_NUM                    4
+#endif
+
+/*****************************************************************************
+ * return values and error code
+ *****************************************************************************/
+/* no more frames, but it is OK */
+#define COM_OK_NO_MORE_FRM              (205)
+/* progress success, but output is not available temporarily */
+#define COM_OK_OUT_NOT_AVAILABLE        (204)
+/* frame dimension (width or height) has been changed */
+#define COM_OK_DIM_CHANGED              (203)
+/* decoding success, but output frame has been delayed */
+#define COM_OK_FRM_DELAYED              (202)
+#if IPPPCRR&&LIB_PIC_UPDATE
+#define RL_UPDATE_TO_LIBPIC             (2)
+#define COM_OK_SKIP                     (3)
+#endif
+#define COM_OK                          (0)
+#define END_OF_VIDEO_SEQUENCE           (206)
+#define NOT_END_OF_VIDEO_SEQUENCE       (207)
+
+#define COM_ERR                         (-1) /* generic error */
+#define COM_ERR_INVALID_ARGUMENT        (-101)
+#define COM_ERR_OUT_OF_MEMORY           (-102)
+#define COM_ERR_REACHED_MAX             (-103)
+#define COM_ERR_UNSUPPORTED             (-104)
+#define COM_ERR_UNEXPECTED              (-105)
+#define COM_ERR_BAD_CRC                 (-130) /* not matched CRC value */
+
+#define COM_ERR_UNSUPPORTED_COLORSPACE  (-201)
+#define COM_ERR_MALFORMED_BITSTREAM     (-202)
+
+#define COM_ERR_UNKNOWN                 (-32767) /* unknown error */
+
+/* return value checking *****************************************************/
+#define COM_SUCCEEDED(ret)              ((ret) >= 0)
+#define COM_FAILED(ret)                 ((ret) < 0)
+
+/* YUV planar ****************************************************************/
+#define COM_COLORSPACE_YUV400          300 /* Y 8bit */
+#define COM_COLORSPACE_YUV420          301 /* YUV420 8bit */
+#define COM_COLORSPACE_YUV422          302 /* YUV422 8bit narrow chroma*/
+#define COM_COLORSPACE_YUV444          303 /* YUV444 8bit */
+#define COM_COLORSPACE_YUV422N         COM_COLORSPACE_YUV422
+#define COM_COLORSPACE_YUV422W         310 /* YUV422 8bit wide chroma */
+
+#define COM_COLORSPACE_YUV400A8        400 /* Y+alpha 8bit */
+#define COM_COLORSPACE_YUV420A8        401 /* YUV420+alpha 8bit */
+#define COM_COLORSPACE_YUV422A8        402 /* YUV422+alpha 8bit narrow chroma*/
+#define COM_COLORSPACE_YUV444A8        403 /* YUV444+alpha 8bit */
+#define COM_COLORSPACE_YUV422NA8       COM_COLORSPACE_YUV422A8
+#define COM_COLORSPACE_YUV422WA8       414 /* YUV422+alpha 8bit wide chroma*/
+
+/* RGB pack ******************************************************************/
+
+/* RGB pack 8bit */
+#define COM_COLORSPACE_RGB888          2200
+#define COM_COLORSPACE_BGR888          2201
+
+#define COM_COLORSPACE_RGBA8888        2220
+#define COM_COLORSPACE_BGRA8888        2221
+#define COM_COLORSPACE_ARGB8888        2222
+#define COM_COLORSPACE_ABGR8888        2223
+
+/*****************************************************************************
+ * config types for decoder
+ *****************************************************************************/
+#define DEC_CFG_SET_USE_PIC_SIGNATURE  (301)
+
+/*****************************************************************************
+ * chunk type
+ *****************************************************************************/
+#define COM_CT_UNKNOWN                  (0)
+#define COM_CT_PICTURE                  (1) /* picture header */
+#define COM_CT_SQH                      (2) /* sequence header */
+#define COM_CT_SLICE                    (3) /* slice header */
+#define COM_CT_SIGN                     (6) /* picture signature */
+#define COM_CT_SEQ_END                  (7)
+
+/*****************************************************************************
+ * slice type
+ *****************************************************************************/
+#define COM_ST_UNKNOWN                  (0)
+#define COM_ST_I                        (1)
+#define COM_ST_P                        (2)
+#define COM_ST_B                        (3)
+
+/*****************************************************************************
+ * software version
+ *****************************************************************************/
+#define COM_VER_1                       (1)
+
+/*****************************************************************************
+ * type and macro for media time
+ *****************************************************************************/
+/* media time in 100-nanosec unit */
+typedef long long                    COM_MTIME;
+
+/*****************************************************************************
+ * image buffer format
+ *****************************************************************************
+ baddr
+	+---------------------------------------------------+ ---
+	|                                                   |  ^
+	|                                              |    |  |
+	|    a                                         v    |  |
+	|   --- +-----------------------------------+ ---   |  |
+	|    ^  |  (x, y)                           |  y    |  |
+	|    |  |   +---------------------------+   + ---   |  |
+	|    |  |   |                           |   |  ^    |  |
+	|    |  |   |                           |   |  |    |  |
+	|    |  |   |                           |   |  |    |  |
+	|    |  |   |                           |   |  |    |  |
+	|       |   |                           |   |       |
+	|    ah |   |                           |   |  h    |  e
+	|       |   |                           |   |       |
+	|    |  |   |                           |   |  |    |  |
+	|    |  |   |                           |   |  |    |  |
+	|    |  |   |                           |   |  v    |  |
+	|    |  |   +---------------------------+   | ---   |  |
+	|    v  |                                   |       |  |
+	|   --- +---+-------------------------------+       |  |
+	|     ->| x |<----------- w ----------->|           |  |
+	|       |<--------------- aw -------------->|       |  |
+	|                                                   |  v
+	+---------------------------------------------------+ ---
+
+	|<---------------------- stride-------------------->|
+
+ *****************************************************************************/
+
+#define COM_IMGB_MAX_PLANE              (4)
+
+typedef struct _COM_IMGB COM_IMGB;
+struct _COM_IMGB
+{
+	int                 cs; /* color space */
+	int                 np; /* number of plane */
+	int                 horizontal_size;
+	int                 vertical_size;
+	/* width (in unit of pixel) */
+	int                 width[COM_IMGB_MAX_PLANE];
+	/* height (in unit of pixel) */
+	int                 height[COM_IMGB_MAX_PLANE];
+	/* buffer stride (in unit of byte) */
+	int                 stride[COM_IMGB_MAX_PLANE];
+	/* address of each plane */
+	void              * addr_plane[COM_IMGB_MAX_PLANE];
+
+	/* time-stamps */
+	COM_MTIME          ts[4];
+
+	/* aligned width (in unit of pixel) */
+	int                 width_aligned[COM_IMGB_MAX_PLANE];
+	/* aligned height (in unit of pixel) */
+	int                 height_aligned[COM_IMGB_MAX_PLANE];
+
+	/* left padding size (in unit of pixel) */
+	int                 pad_left[COM_IMGB_MAX_PLANE];
+	/* right padding size (in unit of pixel) */
+	int                 pad_right[COM_IMGB_MAX_PLANE];
+	/* up padding size (in unit of pixel) */
+	int                 pad_up[COM_IMGB_MAX_PLANE];
+	/* bottom padding size (in unit of pixel) */
+	int                 pad_down[COM_IMGB_MAX_PLANE];
+
+	/* address of actual allocated buffer */
+	void              * buf_addr[COM_IMGB_MAX_PLANE];
+	/* actual allocated buffer size */
+	int                 buf_size[COM_IMGB_MAX_PLANE];
+
+	/* life cycle management */
+	int                 refcnt;
+	int                 (*addref)(COM_IMGB * imgb);
+	int                 (*getref)(COM_IMGB * imgb);
+	int                 (*release)(COM_IMGB * imgb);
+};
+
+/*****************************************************************************
+ * Bitstream buffer
+ *****************************************************************************/
+typedef struct _COM_BITB
+{
+	/* user space address indicating buffer */
+	void              * addr;
+	void              * addr2;
+	/* physical address indicating buffer, if any */
+	void              * pddr;
+	/* byte size of buffer memory */
+	int                 bsize;
+	/* byte size of bitstream in buffer */
+	int                 ssize;
+	/* bitstream has an error? */
+	int                 err;
+	/* arbitrary data, if needs */
+	int                 ndata[4];
+	/* arbitrary address, if needs */
+	void              * pdata[4];
+	/* time-stamps */
+	COM_MTIME          ts[4];
+
+} COM_BITB;
+
+/*****************************************************************************
+ * description for creating of decoder
+ *****************************************************************************/
+typedef struct _DEC_CDSC
+{
+	int            __na; /* nothing */
+} DEC_CDSC;
+
+/*****************************************************************************
+ * status after decoder operation
+ *****************************************************************************/
+typedef struct _DEC_STAT
+{
+	/* byte size of decoded bitstream (read size of bitstream) */
+	int            read;
+	/* chunk type */
+	int            ctype;
+	/* slice type */
+	int            stype;
+	/* frame number monotonically increased whenever decoding a frame.
+	note that it has negative value if the decoded data is not frame */
+	int            fnum;
+	/* picture order count */
+	int            poc;
+	/* number of reference pictures */
+	int            refpic_num[2];
+	/* list of reference pictures */
+	int            refpic[2][16];
+#if LIBVC_ON
+	/* is only ref libpic */
+	int            is_RLpic_flag;
+#if IPPPCRR
+	int            reflib[2][16];
+#endif
+#endif
+	/* for printing sqh parameter */
+#if PRINT_SQH_PARAM_DEC
+	/* framework param */
+#if PHASE_2_PROFILE
+	int            profile_id;
+#endif
+	int            internal_bit_depth;
+	/* tools */
+	int            intra_tools;
+	int            inter_tools;
+	int            trans_tools;
+	int            filte_tools;
+	int            scc_tools;
+#endif
+} DEC_STAT;
+
+/*****************************************************************************
+ * status after encoder operation
+ *****************************************************************************/
+typedef struct _ENC_STAT
+{
+	/* encoded bitstream byte size */
+	int            write;
+	/* picture number increased whenever encoding a frame */
+	unsigned long  fnum;
+	/* chunk type */
+	int            ctype;
+	/* slice type */
+	int            stype;
+	/* quantization parameter used for encoding */
+	int            qp;
+	/* picture order count */
+	int            poc;
+	/* number of reference pictures */
+	int            refpic_num[2];
+	/* list of reference pictures */
+	int            refpic[2][16];
+#if LIBVC_ON
+	/* is only ref libpic */
+	int            is_RLpic_flag;
+#if IPPPCRR
+	int            reflib[2][16];
+#endif
+#endif
+} ENC_STAT;
+
+#define MAX_NUM_REF_PICS                   17
+#define MAX_NUM_ACTIVE_REF_FRAME           4
+#define MAX_NUM_RPLS                       32
+
+//extern int g_CountDOICyCleTime;             // number to count the DOI cycle time.
+//extern int g_DOIPrev;                       // the doi of previous frm.
+
+#if HLS_RPL
+/* rpl structure */
+typedef struct _COM_RPL
+{
+	int slice_type;
+	int poc;
+	int tid;
+	int ref_pic_num;
+	int ref_pic_active_num;
+	int ref_pics[MAX_NUM_REF_PICS];
+	int ref_pics_ddoi[MAX_NUM_REF_PICS];
+	int ref_pics_doi[MAX_NUM_REF_PICS];//ref pic list, doi info
+#if LIBVC_ON
+	int reference_to_library_enable_flag;
+	int library_index_flag[MAX_NUM_REF_PICS];
+#endif
+} COM_RPL;
+#endif
+/*****************************************************************************
+ * API for decoder only
+ *****************************************************************************/
+/* instance identifier for decoder */
+typedef void  * DEC;
+
+DEC dec_create(DEC_CDSC * cdsc, int * err);
+void dec_delete(DEC id);
+int dec_decode(DEC id, COM_BITB * bitb, DEC_STAT * stat);
+int dec_config(DEC id, int cfg, void * buf, int * size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COM_H_ */
diff --git a/drivers/frame_provider/decoder/avs3/dec_eco.c b/drivers/frame_provider/decoder/avs3/dec_eco.c
new file mode 100644
index 0000000..9bb32a3
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/dec_eco.c
@@ -0,0 +1,1674 @@
+/* ====================================================================================================================
+
+	The copyright in this software is being made available under the 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) 2018, HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+	Copyright (c) 2018, SAMSUNG ELECTRONICS CO., LTD. All rights reserved.
+	Copyright (c) 2018, PEKING UNIVERSITY SHENZHEN GRADUATE SCHOOL. All rights reserved.
+	Copyright (c) 2018, PENGCHENG LABORATORY. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted only for
+	the purpose of developing standards within Audio and Video Coding Standard Workgroup of China (AVS) and for testing and
+	promoting such standards. The following conditions are required to be 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.
+	* The name of HUAWEI TECHNOLOGIES CO., LTD. or SAMSUNG ELECTRONICS CO., LTD. may not be 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.
+
+* ====================================================================================================================
+*/
+
+#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/slab.h>
+
+#include "avs3_global.h"
+//#define param_proc(mark, index, val) val
+int aml_print_header_info;
+
+#define AML
+#if HLS_RPL
+#if LIBVC_ON
+int dec_eco_rlp(union param_u *param, COM_RPL * rpl, COM_SQH * sqh)
+#else
+int dec_eco_rlp(union param_u *param, COM_RPL * rpl)
+#endif
+{
+#ifndef AML
+#if LIBVC_ON
+	int ddoi_base = 0;
+	int i;
+
+	rpl->reference_to_library_enable_flag = 0;
+	if (sqh->library_picture_enable_flag)
+	{
+		rpl->reference_to_library_enable_flag = param->p.rpl_reference_to_library_enable_flag;
+		if (aml_print_header_info) printf(" * 18-bits reference_to_library_enable_flag : %d\n", rpl->reference_to_library_enable_flag);
+	}
+	else {
+		if (aml_print_header_info) printf(" * set     reference_to_library_enable_flag : %d\n", rpl->reference_to_library_enable_flag);
+	}
+#endif
+
+	rpl->ref_pic_num = (u32)param->p.rpl_ref_pic_num;
+	if (aml_print_header_info) printf(" * UE      ref_pic_num : %d\n", rpl->ref_pic_num);
+	//note, here we store DOI of each ref pic instead of delta DOI
+	if (rpl->ref_pic_num > 0)
+	{
+#if LIBVC_ON
+		rpl->library_index_flag[0] = 0;
+		if (sqh->library_picture_enable_flag && rpl->reference_to_library_enable_flag)
+		{
+		rpl->library_index_flag[0] = param->p.rpl_library_index_flag[0];
+		if (aml_print_header_info) printf(" * 1-bit   library_index_flag[0] : %d\n", rpl->library_index_flag[0]);
+		}
+	else {
+		if (aml_print_header_info) printf(" * set     library_index_flag[0] : %d\n", rpl->library_index_flag[0]);
+	}
+		if (sqh->library_picture_enable_flag && rpl->library_index_flag[0])
+		{
+		rpl->ref_pics_ddoi[0] = (u32)param->p.rpl_ref_pics_ddoi[0];
+		if (aml_print_header_info) printf(" * UE      ref_pics_ddoi[0] : %d\n", rpl->ref_pics_ddoi[0]);
+		}
+		else
+#endif
+		{
+#ifdef ORI_CODE
+		rpl->ref_pics_ddoi[0] = (u32)com_bsr_read_ue(bs);
+		if (aml_print_header_info) printf(" * UE      abs_doi[0] : %d\n", rpl->ref_pics_ddoi[0]);
+		if (rpl->ref_pics_ddoi[0] != 0) rpl->ref_pics_ddoi[0] *= 1 - ((u32)com_bsr_read1(bs) << 1);
+		if (aml_print_header_info) printf(" * 1-bit   sign_doi[0] : %d --> ref_pics_ddoi[0] : %d\n", (rpl->ref_pics_ddoi[0] < 0), rpl->ref_pics_ddoi[0]);
+#if LIBVC_ON
+		ddoi_base = rpl->ref_pics_ddoi[0];
+#endif
+#endif
+				rpl->ref_pics_ddoi[0] = param->p.rpl_ref_pics_ddoi[0];
+		}
+
+	}
+#ifdef BUFMGR_SANITY_CHECK
+	for (i = 1; i < rpl->ref_pic_num && i < MAX_NUM_REF_PICS; ++i)
+#else
+	for (i = 1; i < rpl->ref_pic_num; ++i)
+#endif
+	{
+#if LIBVC_ON
+		rpl->library_index_flag[i] = 0;
+		if (sqh->library_picture_enable_flag && rpl->reference_to_library_enable_flag)
+		{
+		rpl->library_index_flag[i] = param->p.rpl_library_index_flag[i];
+		if (aml_print_header_info) printf(" * 1-bit   library_index_flag[%d] : %d\n", i, rpl->library_index_flag[i]);
+		}
+	else {
+		if (aml_print_header_info) printf(" * set     library_index_flag[%d] : %d\n", i, rpl->library_index_flag[i]);
+	}
+#ifdef ORI_CODE
+		if (sqh->library_picture_enable_flag && rpl->library_index_flag[i])
+		{
+		rpl->ref_pics_ddoi[i] = (u32)com_bsr_read_ue(bs);
+		if (aml_print_header_info) printf(" * UE      ref_pics_ddoi[%d] : %d\n", i, rpl->ref_pics_ddoi[i]);
+		}
+		else
+		{
+		int deltaRefPic = (u32)com_bsr_read_ue(bs);
+		if (aml_print_header_info) printf(" * UE      abs_delta_doi[%d] : %d\n", i, deltaRefPic);
+		if (deltaRefPic != 0) deltaRefPic *= 1 - ((u32)com_bsr_read1(bs) << 1);
+		if (aml_print_header_info) printf(" * 1-bit   sign_delta_doi[%d] : %d --> deltaRefPic : %d\n", i, (deltaRefPic < 0), deltaRefPic);
+#if LIBVC_ON
+		rpl->ref_pics_ddoi[i] = ddoi_base + deltaRefPic;
+		if (aml_print_header_info) printf(" - ref_pics_ddoi[%d] : %d\n", i, rpl->ref_pics_ddoi[i]);
+		ddoi_base = rpl->ref_pics_ddoi[i];
+#else
+		rpl->ref_pics_ddoi[i] = rpl->ref_pics_ddoi[i - 1] + deltaRefPic;
+#endif
+		}
+#endif
+/*ORI_CODE*/
+#endif
+			rpl->ref_pics_ddoi[i] = param->p.rpl_ref_pics_ddoi[i];
+
+	}
+/*!AML*/
+#endif
+	return COM_OK;
+}
+#endif
+
+int dec_eco_sqh(union param_u *param, COM_SQH * sqh)
+{
+	int i, j;
+	int max_cuwh;
+#ifdef ORI_CODE
+	//video_sequence_start_code
+	unsigned int ret = com_bsr_read(bs, 24);
+	assert(ret == 1);
+	unsigned int start_code;
+	start_code = com_bsr_read(bs, 8);
+	assert(start_code == 0xB0);
+#endif
+	sqh->profile_id = (u8)param->p.sqh_profile_id;
+	if (aml_print_header_info) {
+	printf(" * 8-bits  profile_id : 0x%02x ", sqh->profile_id);
+	if (sqh->profile_id == 0x00) printf(" -- Forbidden Profile\n");
+	else if (sqh->profile_id == 0x20) printf(" -- Main Profile\n");
+	else if (sqh->profile_id == 0x22) printf(" -- Main-10bit Profile\n");
+	else printf(" -- Reserved Profile\n");
+	}
+#if PHASE_2_PROFILE
+	if (sqh->profile_id != 0x22 && sqh->profile_id != 0x20
+	&& sqh->profile_id != 0x32 && sqh->profile_id != 0x30
+		)
+	{
+		printf("unknown profile id: 0x%x\n", sqh->profile_id);
+		assert(0);
+	}
+#endif
+	sqh->level_id = (u8)param->p.sqh_level_id;
+	if (aml_print_header_info) {
+	printf(" * 8-bits  level_id : 0x%02x ", sqh->level_id);
+	if (sqh->level_id == 0x10) printf(" -- Level 2.0.15\n");
+	else if (sqh->level_id == 0x12) printf(" -- Level 2.0.30\n");
+	else if (sqh->level_id == 0x14) printf(" -- Level 2.0.60\n");
+	else if (sqh->level_id == 0x20) printf(" -- Level 4.0.30\n");
+	else if (sqh->level_id == 0x22) printf(" -- Level 4.0.60\n");
+	else if (sqh->level_id == 0x40) printf(" -- Level 6.0.30\n");
+	else if (sqh->level_id == 0x42) printf(" -- Level 6.2.30\n");
+	else if (sqh->level_id == 0x44) printf(" -- Level 6.0.60\n");
+	else if (sqh->level_id == 0x46) printf(" -- Level 6.2.60\n");
+	else if (sqh->level_id == 0x48) printf(" -- Level 6.0.120\n");
+	else if (sqh->level_id == 0x4a) printf(" -- Level 6.2.120\n");
+	else if (sqh->level_id == 0x50) printf(" -- Level 8.0.30\n");
+	else if (sqh->level_id == 0x52) printf(" -- Level 8.2.30\n");
+	else if (sqh->level_id == 0x54) printf(" -- Level 8.0.60\n");
+	else if (sqh->level_id == 0x56) printf(" -- Level 8.2.60\n");
+	else if (sqh->level_id == 0x58) printf(" -- Level 8.0.120\n");
+	else if (sqh->level_id == 0x5a) printf(" -- Level 8.2.120\n");
+	else if (sqh->level_id == 0x60) printf(" -- Level 10.0.30\n");
+	else if (sqh->level_id == 0x62) printf(" -- Level 10.2.30\n");
+	else if (sqh->level_id == 0x64) printf(" -- Level 10.0.60\n");
+	else if (sqh->level_id == 0x66) printf(" -- Level 10.2.60\n");
+	else if (sqh->level_id == 0x68) printf(" -- Level 10.0.120\n");
+	else if (sqh->level_id == 0x6a) printf(" -- Level 10.2.120\n");
+	else printf(" -- Reserved Level\n");
+	}
+	sqh->progressive_sequence = (u8)param->p.sqh_progressive_sequence;
+	if (aml_print_header_info) printf(" * 1-bit   progressive_sequence : %d\n", sqh->progressive_sequence);
+	assert(sqh->progressive_sequence == 1);
+	sqh->field_coded_sequence = (u8)param->p.sqh_field_coded_sequence;
+	if (aml_print_header_info) printf(" * 1-bit   field_coded_sequence : %d\n", sqh->field_coded_sequence);
+#if LIBVC_ON
+	sqh->library_stream_flag = (u8)param->p.sqh_library_stream_flag;
+	if (aml_print_header_info) {
+	printf(" * 1-bit   library_stream_flag : %d\n", sqh->library_stream_flag);
+	}
+	sqh->library_picture_enable_flag = 0;
+	//sqh->duplicate_sequence_header_flag = 0;
+	if (!sqh->library_stream_flag)
+	{
+		sqh->library_picture_enable_flag = (u8)param->p.sqh_library_picture_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   library_picture_enable_flag : %d\n", sqh->library_picture_enable_flag);
+		if (sqh->library_picture_enable_flag)
+		{
+		//sqh->duplicate_sequence_header_flag = (u8)param->p.sqh_duplicate_sequence_header_flag;
+		if (aml_print_header_info) printf(" * 1-bit   duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+		}
+	else {
+		if (aml_print_header_info) printf(" - set     duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+	}
+	}
+	else {
+	if (aml_print_header_info) printf(" - set     library_picture_enable_flag : %d\n", sqh->library_picture_enable_flag);
+	if (aml_print_header_info) printf(" - set     duplicate_sequence_header_flag : %d\n", sqh->duplicate_sequence_header_flag);
+	}
+#endif
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	sqh->horizontal_size = param->p.sqh_horizontal_size;
+	if (aml_print_header_info) printf(" * 14-bits horizontal_size : %d\n", sqh->horizontal_size);
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	sqh->vertical_size = param->p.sqh_vertical_size;
+	if (aml_print_header_info) printf(" * 14-bits vertical_size : %d\n", sqh->vertical_size);
+	if (aml_print_header_info) printf("   - pic_frame_size : %d x %d\n", sqh->horizontal_size, sqh->vertical_size);
+	//sqh->chroma_format = (u8)param->p.sqh_chroma_format;
+	if (aml_print_header_info) {
+	printf(" * 2-bits  chroma_format : %d ", sqh->chroma_format);
+	if (sqh->chroma_format == 1) printf(" -- 4:2:0\n");
+	// else if (sqh->chroma_format == 2) printf(" -- 4:2:2\n");
+	else printf(" -- Reserved chroma_format\n");
+	}
+	sqh->sample_precision = (u8)param->p.sqh_sample_precision;
+	if (aml_print_header_info) printf(" * 3-bits  sample_precision : %d -- %d bits\n", sqh->sample_precision, sqh->sample_precision*2+6);
+
+#if PHASE_2_PROFILE
+	if (sqh->profile_id == 0x22 || sqh->profile_id == 0x32)
+#else
+	if (sqh->profile_id == 0x22)
+#endif
+	{
+		sqh->encoding_precision = (u8)param->p.sqh_encoding_precision;
+		if (aml_print_header_info) printf(" * 3-bits  encoding_precision : %d -- %d-bits\n", sqh->encoding_precision, sqh->encoding_precision*2+6);
+		//assert(sqh->encoding_precision == 2);
+	}
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	sqh->aspect_ratio = (u8)param->p.sqh_aspect_ratio;
+	if (aml_print_header_info) {
+	printf(" * 4-bits  aspect_ratio : %d ", sqh->aspect_ratio);
+	if (sqh->aspect_ratio == 1) printf(" -- SAR = 1.0\n");
+	else if (sqh->aspect_ratio == 2) printf(" -- DAR = 4:3\n");
+	else if (sqh->aspect_ratio == 3) printf(" -- DAR = 16:9\n");
+	else if (sqh->aspect_ratio == 4) printf(" -- DAR = 2.21:1\n");
+	else printf(" -- Reserved aspect_ratio_information\n");
+	}
+
+	sqh->frame_rate_code = (u8)param->p.sqh_frame_rate_code;
+	if (aml_print_header_info) {
+	printf(" * 4-bits  frame_rate_code : %d ", sqh->frame_rate_code);
+	if (sqh->frame_rate_code == 1) printf(" -- 23.976 fps\n");
+	else if (sqh->frame_rate_code == 2) printf(" -- 24 fps\n");
+	else if (sqh->frame_rate_code == 3) printf(" -- 25 fps\n");
+	else if (sqh->frame_rate_code == 4) printf(" -- 29.97 fps\n");
+	else if (sqh->frame_rate_code == 5) printf(" -- 30 fps\n");
+	else if (sqh->frame_rate_code == 6) printf(" -- 50 fps\n");
+	else if (sqh->frame_rate_code == 7) printf(" -- 59.94 fps\n");
+	else if (sqh->frame_rate_code == 8) printf(" -- 60 fps\n");
+	else if (sqh->frame_rate_code == 9) printf(" -- 100 fps\n");
+	else if (sqh->frame_rate_code == 10) printf(" -- 120 fps\n");
+	else if (sqh->frame_rate_code == 11) printf(" -- 200 fps\n");
+	else if (sqh->frame_rate_code == 12) printf(" -- 240 fps\n");
+	else if (sqh->frame_rate_code == 13) printf(" -- 300 fps\n");
+	else printf(" -- Reserved frame_rate_code\n");
+	}
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	//sqh->bit_rate_lower = param->p.sqh_bit_rate_lower;
+	if (aml_print_header_info) printf(" * 18-bits bit_rate_lower : %d\n", sqh->bit_rate_lower);
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	//sqh->bit_rate_upper = param->p.sqh_bit_rate_upper;
+	if (aml_print_header_info) printf(" * 12-bits bit_rate_upper : %d\n", sqh->bit_rate_upper);
+	printf(" -  BitRate = %d kbit/s \n", ((sqh->bit_rate_upper << 18) + sqh->bit_rate_lower) * 400 / 1024);
+	sqh->low_delay = (u8)param->p.sqh_low_delay;
+
+	sqh->temporal_id_enable_flag = (u8)param->p.sqh_temporal_id_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   temporal_id_enable_flag : %d\n", sqh->temporal_id_enable_flag);
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	//sqh->bbv_buffer_size = param->p.sqh_bbv_buffer_size;
+	if (aml_print_header_info) printf(" * 18-bits bbv_buffer_size : %d\n", sqh->bbv_buffer_size);
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	sqh->max_dpb_size = param->p.sqh_max_dpb_size;
+	if (aml_print_header_info) printf(" * 4-bits  max_dpb_size_minus1 : %d --> max_dpb_size : %d\n", sqh->max_dpb_size-1, sqh->max_dpb_size);
+
+#if HLS_RPL
+	if (aml_print_header_info) printf("--BEGIN HLS_RPL--------------------------------------------\n");
+	//sqh->rpl1_index_exist_flag = (u32)param->p.sqh_rpl1_index_exist_flag;
+	if (aml_print_header_info) printf(" * 1-bit   rpl1_index_exist_flag : %d\n", sqh->rpl1_index_exist_flag);
+	//sqh->rpl1_same_as_rpl0_flag = (u32)param->p.sqh_rpl1_same_as_rpl0_flag;
+	if (aml_print_header_info) printf(" * 1-bit   rpl1_same_as_rpl0_flag : %d\n", sqh->rpl1_same_as_rpl0_flag);
+	//assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	//sqh->rpls_l0_num = (u32)param->p.sqh_rpls_l0_num;
+	if (aml_print_header_info) printf(" * UE      rpls_l0_num : %d\n", sqh->rpls_l0_num);
+	for (i = 0; i < sqh->rpls_l0_num; ++i)
+	{
+#if LIBVC_ON
+	if (aml_print_header_info) printf(" ## dec_eco_rlp_l0[%d] ##\n", i);
+		dec_eco_rlp(param, &sqh->rpls_l0[i], sqh);
+#else
+		dec_eco_rlp(param, &sqh->rpls_l0[i]);
+#endif
+	}
+
+	if (!sqh->rpl1_same_as_rpl0_flag)
+	{
+		//sqh->rpls_l1_num = (u32)param->p.sqh_rpls_l1_num;
+		if (aml_print_header_info) printf(" * UE      rpls_l1_num : %d\n", sqh->rpls_l1_num);
+		for (i = 0; i < sqh->rpls_l1_num; ++i)
+		{
+#if LIBVC_ON
+	if (aml_print_header_info) printf(" ## dec_eco_rlp_l1[%d] ##\n", i);
+		dec_eco_rlp(param, &sqh->rpls_l1[i], sqh);
+#else
+		dec_eco_rlp(param, &sqh->rpls_l1[i]);
+#endif
+		}
+	}
+	else
+	{
+		//Basically copy everything from sqh->rpls_l0 to sqh->rpls_l1
+		//MX: LIBVC is not harmonization yet.
+		//sqh->rpls_l1_num = sqh->rpls_l0_num;
+		for (i = 0; i < sqh->rpls_l1_num; i++)
+		{
+#if LIBVC_ON
+		sqh->rpls_l1[i].reference_to_library_enable_flag = sqh->rpls_l0[i].reference_to_library_enable_flag;
+#endif
+		sqh->rpls_l1[i].ref_pic_num = sqh->rpls_l0[i].ref_pic_num;
+		for (j = 0; j < sqh->rpls_l1[i].ref_pic_num; j++)
+		{
+#if LIBVC_ON
+			sqh->rpls_l1[i].library_index_flag[j] = sqh->rpls_l0[i].library_index_flag[j];
+#endif
+			sqh->rpls_l1[i].ref_pics_ddoi[j] = sqh->rpls_l0[i].ref_pics_ddoi[j];
+		}
+		}
+	}
+	sqh->num_ref_default_active_minus1[0] = (u32)param->p.sqh_num_ref_default_active_minus1[0];
+	if (aml_print_header_info) printf("-----------------------------------------------------------\n");
+	if (aml_print_header_info) printf(" * UE      num_ref_default_active_minus1[0] : %d\n", sqh->num_ref_default_active_minus1[0]);
+	sqh->num_ref_default_active_minus1[1] = (u32)param->p.sqh_num_ref_default_active_minus1[1];
+	if (aml_print_header_info) printf(" * UE      num_ref_default_active_minus1[1] : %d\n", sqh->num_ref_default_active_minus1[1]);
+	if (aml_print_header_info) printf("--END HLS_RPL----------------------------------------------\n");
+#endif
+
+#ifdef ORI_CODE
+	if (aml_print_header_info) {
+	int temp_size_read;
+	temp_size_read = com_bsr_read(bs, 3); // log2_lcu_size_minus2
+	sqh->log2_max_cu_width_height = param->p.sqh_log2_max_cu_width_height;
+	printf(" * 3-bits  log2_lcu_size_minus2 : %d       --> lcu_size : %d x %d\n", temp_size_read, (1<< sqh->log2_max_cu_width_height), (1<< sqh->log2_max_cu_width_height));
+	temp_size_read = com_bsr_read(bs, 2);  // log2_min_cu_size_minus2
+	//sqh->min_cu_size = param->p.sqh_min_cu_size;
+	printf(" * 2-bits  log2_min_cu_size_minus2 : %d    --> min_cu_size : %d\n", temp_size_read, sqh->min_cu_size);
+	temp_size_read = com_bsr_read(bs, 2);  // log2_max_part_ratio_minus2
+	//sqh->max_part_ratio = param->p.sqh_max_part_ratio;
+	printf(" * 2-bits  log2_max_part_ratio_minus2 : %d --> max_part_ratio : %d\n", temp_size_read, sqh->max_part_ratio);
+	temp_size_read = com_bsr_read(bs, 3);  // max_split_times_minus6
+	//sqh->max_split_times = param->p.sqh_max_split_times;
+	printf(" * 3-bits  max_split_times_minus6 : %d     --> max_split_times : %d\n", temp_size_read, sqh->max_split_times);
+	temp_size_read = com_bsr_read(bs, 3);  // log2_min_qt_size_minus2
+	//sqh->min_qt_size = param->p.sqh_min_qt_size;
+	printf(" * 3-bits  log2_min_qt_size_minus2 : %d    --> min_qt_size : %d\n", temp_size_read, sqh->min_qt_size);
+	temp_size_read = com_bsr_read(bs, 3);  // log2_max_bt_size_minus2
+	//sqh->max_bt_size = param->p.sqh_max_bt_size;
+	printf(" * 3-bits  log2_max_bt_size_minus2 : %d    --> max_bt_size : %d\n", temp_size_read, sqh->max_bt_size);
+	temp_size_read = com_bsr_read(bs, 2);  // log2_max_eqt_size_minus3
+	//sqh->max_eqt_size = param->p.sqh_max_eqt_size;
+	printf(" * 2-bits  log2_max_eqt_size_minus3 : %d   --> max_eqt_size : %d\n", temp_size_read, sqh->max_eqt_size);
+	}
+	else
+#endif
+	{
+	sqh->log2_max_cu_width_height = param->p.sqh_log2_max_cu_width_height;
+	//sqh->min_cu_size = param->p.sqh_min_cu_size;
+	//sqh->max_part_ratio = param->p.sqh_max_part_ratio;
+	//sqh->max_split_times = param->p.sqh_max_split_times;
+	//sqh->min_qt_size = param->p.sqh_min_qt_size;
+		//sqh->max_bt_size = param->p.sqh_max_bt_size;
+		//sqh->max_eqt_size = param->p.sqh_max_eqt_size;
+	}
+
+#ifndef ORI_CODE
+	sqh->adaptive_leveling_filter_enable_flag = (u8)param->p.sqh_adaptive_leveling_filter_enable_flag;
+	sqh->num_of_hmvp_cand = (u8)param->p.sqh_num_of_hmvp_cand;
+	printf("sqh->num_of_hmvp_cand=%d\n", sqh->num_of_hmvp_cand);
+#if ALF_SHAPE || ALF_IMP
+	if (sqh->profile_id == 0x30 || sqh->profile_id == 0x32)
+	{
+		if (sqh->adaptive_leveling_filter_enable_flag)
+		{
+		sqh->adaptive_filter_shape_enable_flag = (u8)param->p.sqh_adaptive_filter_shape_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+		}
+		else
+		{
+		sqh->adaptive_filter_shape_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+		}
+	} else {
+		sqh->adaptive_filter_shape_enable_flag = 0;
+	}
+#endif
+#else
+	assert(com_bsr_read1(bs) == 1);                                //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+	//verify parameters allowed in Profile
+	assert(sqh->log2_max_cu_width_height >= 5 && sqh->log2_max_cu_width_height <= 7);
+	assert(sqh->min_cu_size == 4);
+	assert(sqh->max_part_ratio == 8);
+	assert(sqh->max_split_times == 6);
+	assert(sqh->min_qt_size == 4 || sqh->min_qt_size == 8 || sqh->min_qt_size == 16 || sqh->min_qt_size == 32 || sqh->min_qt_size == 64 || sqh->min_qt_size == 128);
+	assert(sqh->max_bt_size == 64 || sqh->max_bt_size == 128);
+	assert(sqh->max_eqt_size == 8 || sqh->max_eqt_size == 16 || sqh->max_eqt_size == 32 || sqh->max_eqt_size == 64);
+
+	//sqh->wq_enable = (u8)param->p.sqh_wq_enable;
+	if (aml_print_header_info) printf(" * 1-bit   wq_enable : %d\n", sqh->wq_enable);
+	if (sqh->wq_enable)
+	{
+		sqh->seq_wq_mode = param->p.sqh_seq_wq_mode;
+		if (aml_print_header_info) printf(" * 1-bit   seq_wq_mode : %d\n", sqh->seq_wq_mode);
+		if (sqh->seq_wq_mode)
+		{
+		read_wq_matrix(bs, sqh->wq_4x4_matrix, sqh->wq_8x8_matrix);  //weight_quant_matrix( )
+		}
+		else
+		{
+		memcpy(sqh->wq_4x4_matrix, tab_WqMDefault4x4, sizeof(tab_WqMDefault4x4));
+		memcpy(sqh->wq_8x8_matrix, tab_WqMDefault8x8, sizeof(tab_WqMDefault8x8));
+		}
+	}
+	//sqh->secondary_transform_enable_flag = (u8)param->p.sqh_secondary_transform_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   secondary_transform_enable_flag : %d\n", sqh->secondary_transform_enable_flag);
+	//sqh->sample_adaptive_offset_enable_flag = (u8)param->p.sqh_sample_adaptive_offset_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   sample_adaptive_offset_enable_flag : %d\n", sqh->sample_adaptive_offset_enable_flag);
+	sqh->adaptive_leveling_filter_enable_flag = (u8)param->p.sqh_adaptive_leveling_filter_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   adaptive_leveling_filter_enable_flag : %d\n", sqh->adaptive_leveling_filter_enable_flag);
+	//sqh->affine_enable_flag = (u8)param->p.sqh_affine_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   affine_enable_flag : %d\n", sqh->affine_enable_flag);
+#if SMVD
+	//sqh->smvd_enable_flag = (u8)param->p.sqh_smvd_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   smvd_enable_flag : %d\n", sqh->smvd_enable_flag);
+#endif
+#if IPCM
+	//sqh->ipcm_enable_flag = param->p.sqh_ipcm_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   ipcm_enable_flag : %d\n", sqh->ipcm_enable_flag);
+	assert(sqh->sample_precision == 1 || sqh->sample_precision == 2);
+#endif
+	//sqh->amvr_enable_flag = (u8)param->p.sqh_amvr_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   amvr_enable_flag : %d\n", sqh->amvr_enable_flag);
+	sqh->num_of_hmvp_cand = (u8)param->p.sqh_num_of_hmvp_cand;
+	if (aml_print_header_info) printf(" * 4-bits  num_of_hmvp_cand : %d\n", sqh->num_of_hmvp_cand);
+	//sqh->umve_enable_flag = (u8)param->p.sqh_umve_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   umve_enable_flag : %d\n", sqh->umve_enable_flag);
+#if EXT_AMVR_HMVP
+	if (sqh->amvr_enable_flag && sqh->num_of_hmvp_cand)
+	{
+		//sqh->emvr_enable_flag = (u8)param->p.sqh_emvr_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   emvr_enable_flag : %d\n", sqh->emvr_enable_flag);
+	}
+	else
+	{
+		//sqh->emvr_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     emvr_enable_flag : %d\n", sqh->emvr_enable_flag);
+	}
+#endif
+	//sqh->ipf_enable_flag = (u8)param->p.sqh_ipf_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   ipf_enable_flag : %d\n", sqh->ipf_enable_flag);
+#if TSCPM
+	//sqh->tscpm_enable_flag = (u8)param->p.sqh_tscpm_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   tscpm_enable_flag : %d\n", sqh->tscpm_enable_flag);
+#endif
+	//assert(com_bsr_read1(bs) == 1);              //marker_bit
+	if (aml_print_header_info) printf(" * 1-bit   marker_bit : %d\n", 1);
+#if DT_PARTITION
+	//sqh->dt_intra_enable_flag = (u8)param->p.sqh_dt_intra_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   dt_intra_enable_flag : %d\n", sqh->dt_intra_enable_flag);
+	if (sqh->dt_intra_enable_flag)
+	{
+		//u32 log2_max_dt_size_minus4 = com_bsr_read(bs, 2);
+		//assert(log2_max_dt_size_minus4 <= 2);
+		//sqh->max_dt_size = param->p.sqh_max_dt_size;
+		if (aml_print_header_info) printf(" * 2-bits  log2_max_dt_size_minus4 : %d --> max_dt_size : %d\n", log2_max_dt_size_minus4, sqh->max_dt_size);
+	}
+#endif
+	//sqh->position_based_transform_enable_flag = (u8)param->p.sqh_position_based_transform_enable_flag;
+	if (aml_print_header_info) printf(" * 1-bit   position_based_transform_enable_flag : %d\n", sqh->position_based_transform_enable_flag);
+
+#if PHASE_2_PROFILE
+	if (sqh->profile_id == 0x30 || sqh->profile_id == 0x32)
+	{
+#endif
+		// begin of phase-2 sqh
+#if ESAO
+		sqh->esao_enable_flag = (u8)param->p.sqh_esao_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   esao_enable_flag : %d\n", sqh->esao_enable_flag);
+#endif
+#if CCSAO
+		sqh->ccsao_enable_flag = (u8)param->p.sqh_ccsao_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   ccsao_enable_flag : %d\n", sqh->ccsao_enable_flag);
+#endif
+#if ALF_SHAPE || ALF_IMP
+		if (sqh->adaptive_leveling_filter_enable_flag)
+		{
+		sqh->adaptive_filter_shape_enable_flag = (u8)param->p.sqh_adaptive_filter_shape_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+		}
+		else
+		{
+		sqh->adaptive_filter_shape_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     adaptive_filter_shape_enable_flag : %d\n", sqh->adaptive_filter_shape_enable_flag);
+		}
+#endif
+#if UMVE_ENH
+		if (sqh->umve_enable_flag)
+		{
+		sqh->umve_enh_enable_flag = (u8)param->p.sqh_umve_enh_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   umve_enh_enable_flag : %d\n", sqh->umve_enh_enable_flag);
+		}
+#endif
+#if AWP
+		sqh->awp_enable_flag = (u8)param->p.sqh_awp_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   awp_enable_flag : %d\n", sqh->awp_enable_flag);
+#endif
+#if AWP_MVR
+		if (sqh->awp_enable_flag)
+		{
+		sqh->awp_mvr_enable_flag = (u8)param->p.sqh_awp_mvr_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   awp_mvr_enable_flag : %d\n", sqh->awp_mvr_enable_flag);
+		}
+		else
+		{
+		sqh->awp_mvr_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     awp_mvr_enable_flag : %d\n", sqh->awp_mvr_enable_flag);
+		}
+#endif
+#if BIO
+		sqh->bio_enable_flag = (u8)param->p.sqh_bio_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   bio_enable_flag : %d\n", sqh->bio_enable_flag);
+#endif
+#if BGC
+		sqh->bgc_enable_flag = (u8)param->p.sqh_bgc_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   bgc_enable_flag : %d\n", sqh->bgc_enable_flag);
+#endif
+#if DMVR
+		sqh->dmvr_enable_flag = (u8)param->p.sqh_dmvr_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   dmvr_enable_flag : %d\n", sqh->dmvr_enable_flag);
+#endif
+#if INTERPF
+		sqh->interpf_enable_flag = (u8)param->p.sqh_interpf_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   interpf_enable_flag : %d\n", sqh->interpf_enable_flag);
+#endif
+#if IBC_ABVR
+		sqh->abvr_enable_flag = (u8)param->p.sqh_abvr_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   abvr_enable_flag : %d\n", sqh->abvr_enable_flag);
+#endif
+#if USE_SP
+		sqh->sp_enable_flag = (u8)param->p.sqh_sp_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   sp_enable_flag : %d\n", sqh->sp_enable_flag);
+#if EVS_UBVS_MODE
+		if (sqh->sp_enable_flag)
+		{
+		sqh->evs_ubvs_enable_flag = (u8)param->p.sqh_evs_ubvs_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   evs_ubvs_enable_flag : %d\n", sqh->evs_ubvs_enable_flag);
+		}
+		else
+		{
+		sqh->evs_ubvs_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     evs_ubvs_enable_flag : %d\n", sqh->evs_ubvs_enable_flag);
+		}
+#endif
+#endif
+#if IBC_BVP
+		sqh->num_of_hbvp_cand = (u8)param->p.sqh_num_of_hbvp_cand;
+		if (aml_print_header_info) printf(" * 4-bits  num_of_hbvp_cand : %d\n", sqh->num_of_hbvp_cand);
+#endif
+#if ASP
+		if (sqh->affine_enable_flag)
+		{
+		sqh->asp_enable_flag = (u8)param->p.sqh_asp_enable_flag;
+		if (aml_print_header_info) printf(" * 1-bit   asp_enable_flag : %d\n", sqh->asp_enable_flag);
+		}
+		else
+		{
+		sqh->asp_enable_flag = 0;
+		if (aml_print_header_info) printf(" - set     asp_enable_flag : %d\n", sqh->asp_enable_flag);
+		}
+#endif
+#if AFFINE_UMVE
+		if (sqh->affine_enable_flag && sqh->umve_enable_flag)
+		{
+		sqh->affine_umve_enable_flag = (u8)param->p.sqh_affine_umve_enable_flag;
+		}
+		else
+		{
+		sqh->affine_umve_enable_flag = 0;
+		}
+#endif
+#if MIPF
+		sqh->mipf_enable_flag = (u8)param->p.sqh_mipf_enable_flag;
+#endif
+#if TSCPM && ENHANCE_TSPCM
+		if (sqh->tscpm_enable_flag)
+		{
+		sqh->enhance_tscpm_enable_flag = (u8)param->p.sqh_enhance_tscpm_enable_flag;
+		}
+		else
+		{
+		sqh->enhance_tscpm_enable_flag = 0;
+		}
+#endif
+#if IPF_CHROMA
+		if (sqh->ipf_enable_flag)
+		{
+		sqh->chroma_ipf_enable_flag = (u8)param->p.sqh_chroma_ipf_enable_flag;
+		}
+		else
+		{
+		sqh->chroma_ipf_enable_flag = 0;
+		}
+#endif
+#if IIP
+		sqh->iip_enable_flag = (u8)param->p.sqh_iip_enable_flag;
+#endif
+#if PMC
+		sqh->pmc_enable_flag = (u8)param->p.sqh_pmc_enable_flag;
+#endif
+#if FIMC
+		sqh->fimc_enable_flag = (u8)param->p.sqh_fimc_enable_flag;
+#endif
+#if USE_IBC
+		sqh->ibc_flag = (u8)param->p.sqh_ibc_flag;
+#endif
+#if SIBC
+		if (sqh->ibc_flag)
+		{
+		sqh->sibc_enable_flag = (u8)param->p.sqh_sibc_enable_flag;
+		}
+		else
+		{
+		sqh->sibc_enable_flag = 0;
+		}
+#endif
+#if SBT
+		sqh->sbt_enable_flag = (u8)param->p.sqh_sbt_enable_flag;
+#endif
+#if IST
+		sqh->ist_enable_flag = (u8)param->p.sqh_ist_enable_flag;
+#endif
+#if ISTS
+		sqh->ists_enable_flag = (u8)param->p.sqh_ists_enable_flag;
+#endif
+#if TS_INTER
+		sqh->ts_inter_enable_flag = (u8)param->p.sqh_ts_inter_enable_flag;
+#endif
+#if EST
+		if (sqh->secondary_transform_enable_flag)
+		{
+		sqh->est_enable_flag = (u8)param->p.sqh_est_enable_flag;
+		}
+#endif
+#if ST_CHROMA
+		if (sqh->secondary_transform_enable_flag)
+		{
+		sqh->st_chroma_enable_flag = (u8)param->p.sqh_st_chroma_enable_flag;
+		}
+		else
+		{
+		sqh->st_chroma_enable_flag = 0;
+		}
+#endif
+#if SRCC
+		sqh->srcc_enable_flag = (u8)param->p.sqh_srcc_enable_flag;
+#endif
+#if CABAC_MULTI_PROB
+		sqh->mcabac_enable_flag = (u8)param->p.sqh_mcabac_enable_flag;
+#endif
+#if EIPM
+		sqh->eipm_enable_flag = (u8)param->p.sqh_eipm_enable_flag;
+#endif
+#if ETMVP
+		sqh->etmvp_enable_flag = (u8)param->p.sqh_etmvp_enable_flag;
+#endif
+#if SUB_TMVP
+		sqh->sbtmvp_enable_flag = (u8)param->p.sqh_sbtmvp_enable_flag;
+#endif
+#if MVAP
+		sqh->mvap_enable_flag = (u8)param->p.sqh_mvap_enable_flag;
+		sqh->num_of_mvap_cand = sqh->mvap_enable_flag ? ALLOWED_MVAP_NUM : 0;
+#endif
+#if DBK_SCC
+		sqh->loop_filter_type_enable_flag = (u8)param->p.sqh_loop_filter_type_enable_flag;
+#endif
+#if DBR
+		sqh->dbr_enable_flag = (u8)param->p.sqh_dbr_enable_flag;
+#endif
+		// end of phase-2 sqh
+#if PHASE_2_PROFILE
+	}
+	else
+	{
+#if ESAO
+		sqh->esao_enable_flag = 0;
+#endif
+#if CCSAO
+		sqh->ccsao_enable_flag = 0;
+#endif
+#if ALF_SHAPE || ALF_IMP
+		sqh->adaptive_filter_shape_enable_flag = 0;
+#endif
+#if UMVE_ENH
+		sqh->umve_enh_enable_flag = 0;
+#endif
+#if AWP
+		sqh->awp_enable_flag = 0;
+#endif
+#if AWP_MVR
+		sqh->awp_mvr_enable_flag = 0;
+#endif
+#if BIO
+		sqh->bio_enable_flag = 0;
+#endif
+#if BGC
+		sqh->bgc_enable_flag = 0;
+#endif
+#if DMVR
+		sqh->dmvr_enable_flag = 0;
+#endif
+#if INTERPF
+		sqh->interpf_enable_flag = 0;
+#endif
+#if IBC_ABVR
+		sqh->abvr_enable_flag = 0;
+#endif
+#if USE_SP
+		sqh->sp_enable_flag = 0;
+#if EVS_UBVS_MODE
+		sqh->evs_ubvs_enable_flag = 0;
+#endif
+#endif
+#if IBC_BVP
+		sqh->num_of_hbvp_cand = 0;
+#endif
+#if ASP
+		sqh->asp_enable_flag = 0;
+#endif
+#if AFFINE_UMVE
+		sqh->affine_umve_enable_flag = 0;
+#endif
+#if MIPF
+		sqh->mipf_enable_flag = 0;
+#endif
+#if TSCPM && ENHANCE_TSPCM
+		sqh->enhance_tscpm_enable_flag = 0;
+#endif
+#if IPF_CHROMA
+		sqh->chroma_ipf_enable_flag = 0;
+#endif
+#if IIP
+		sqh->iip_enable_flag = 0;
+#endif
+#if PMC
+		sqh->pmc_enable_flag = 0;
+#endif
+#if FIMC
+		sqh->fimc_enable_flag = 0;
+#endif
+#if USE_IBC
+		sqh->ibc_flag = 0;
+#endif
+#if SIBC
+		sqh->sibc_enable_flag = 0;
+#endif
+#if SBT
+		sqh->sbt_enable_flag = 0;
+#endif
+#if IST
+		sqh->ist_enable_flag = 0;
+#endif
+#if ISTS
+		sqh->ists_enable_flag = 0;
+#endif
+#if TS_INTER
+		sqh->ts_inter_enable_flag = 0;
+#endif
+#if EST
+		sqh->est_enable_flag = 0;
+#endif
+#if ST_CHROMA
+		sqh->st_chroma_enable_flag = 0;
+#endif
+#if SRCC
+		sqh->srcc_enable_flag = 0;
+#endif
+#if CABAC_MULTI_PROB
+		sqh->mcabac_enable_flag = 0;
+#endif
+#if EIPM
+		sqh->eipm_enable_flag = 0;
+#endif
+#if ETMVP
+		sqh->etmvp_enable_flag = 0;
+#endif
+#if SUB_TMVP
+		sqh->sbtmvp_enable_flag = 0;
+#endif
+#if MVAP
+		sqh->mvap_enable_flag = 0;
+		sqh->num_of_mvap_cand = 0;
+#endif
+#if DBK_SCC
+		sqh->loop_filter_type_enable_flag = 0;
+#endif
+#if DBR
+		sqh->dbr_enable_flag = 0;
+#endif
+	}
+#endif // end of PHASE_2_PROFILE
+/*ORI_CODE*/
+#endif
+	if (sqh->low_delay == 0)
+	{
+		sqh->output_reorder_delay = (u8)param->p.sqh_output_reorder_delay;
+		if (aml_print_header_info) printf(" * 5-bits  output_reorder_delay : %d\n", sqh->output_reorder_delay);
+	}
+	else
+	{
+		sqh->output_reorder_delay = 0;
+		if (aml_print_header_info) printf(" - set     output_reorder_delay : %d\n", sqh->output_reorder_delay);
+	}
+#ifdef ORI_CODE
+#if PATCH
+	sqh->cross_patch_loop_filter = (u8)param->p.sqh_cross_patch_loop_filter;
+	if (aml_print_header_info) printf(" * 1-bit   cross_patch_loop_filter : %d\n", sqh->cross_patch_loop_filter);
+	//sqh->patch_ref_colocated = (u8)param->p.sqh_patch_ref_colocated;
+	if (aml_print_header_info) printf(" * 1-bit   patch_ref_colocated : %d\n", sqh->patch_ref_colocated);
+	//sqh->patch_stable = (u8)param->p.sqh_patch_stable;
+	if (aml_print_header_info) printf(" * 1-bit   patch_stable : %d\n", sqh->patch_stable);
+	if (sqh->patch_stable)
+	{
+		//sqh->patch_uniform = (u8)param->p.sqh_patch_uniform;
+		if (aml_print_header_info) printf(" * 1-bit   patch_uniform : %d\n", sqh->patch_uniform);
+		if (sqh->patch_uniform)
+		{
+		assert(com_bsr_read1(bs) == 1);                      //marker_bit
+		//sqh->patch_width_minus1 = (u8)param->p.sqh_patch_width_minus1;
+		if (aml_print_header_info) printf(" * UE      patch_width_minus1 : %d\n", sqh->patch_width_minus1);
+		//sqh->patch_height_minus1 = (u8)param->p.sqh_patch_height_minus1;
+		if (aml_print_header_info) printf(" * UE      patch_height_minus1 : %d\n", sqh->patch_height_minus1);
+		}
+	}
+#endif
+	com_bsr_read(bs, 2); //reserved_bits r(2)
+	if (aml_print_header_info) printf(" * 2-bits  reserved_bits dropped\n");
+
+	//next_start_code()
+	assert(com_bsr_read1(bs)==1); // stuffing_bit '1'
+	while (!COM_BSR_IS_BYTE_ALIGN(bs))
+	{
+		assert(com_bsr_read1(bs) == 0); // stuffing_bit '0'
+	}
+	while (com_bsr_next(bs, 24) != 0x1)
+	{
+		assert(com_bsr_read(bs, 8) == 0); // stuffing_byte '00000000'
+	};
+#endif
+	/* check values */
+	max_cuwh = 1 << sqh->log2_max_cu_width_height;
+	if (max_cuwh < MIN_CU_SIZE || max_cuwh > MAX_CU_SIZE)
+	{
+		printf("max_cuwh %d, MIN_CU_SIZE %d, MAX_CU_SIZE %d\n",
+		max_cuwh, MIN_CU_SIZE, MAX_CU_SIZE);
+		return COM_ERR_MALFORMED_BITSTREAM;
+	}
+	printf("%s return\n", __func__);
+	return COM_OK;
+}
+
+int dec_eco_pic_header(union param_u *param, COM_PIC_HEADER * pic_header, COM_SQH * sqh, int* need_minus_256, unsigned int start_code)
+{
+	int i, ii;
+#ifdef ORI_CODE
+	unsigned int ret = com_bsr_read(bs, 24);
+	assert(ret == 1);
+	unsigned int start_code = com_bsr_read(bs, 8);
+#endif
+	if (start_code == 0xB3)
+	{
+		pic_header->slice_type = SLICE_I;
+	}
+	assert(start_code == 0xB6 || start_code == 0xB3);
+	if (start_code != 0xB3)//MX: not SLICE_I
+	{
+	pic_header->random_access_decodable_flag = param->p.pic_header_random_access_decodable_flag;
+	}
+	//pic_header->bbv_delay = com_bsr_read(bs, 8) << 24 | com_bsr_read(bs, 8) << 16 | com_bsr_read(bs, 8) << 8 | com_bsr_read(bs, 8);
+		//pic_header->bbv_delay = (u32)param->p.pic_header_bbv_delay;
+	if (start_code == 0xB6)
+	{
+		//picture_coding_type
+		//u8 val = (u8)com_bsr_read(bs, 2);
+		//assert(val == 1 || val == 2);
+		pic_header->slice_type = (u8)param->p.pic_header_slice_type;
+	}
+	if (pic_header->slice_type == SLICE_I)
+	{
+		//pic_header->time_code_flag = param->p.pic_header_time_code_flag;
+		if (pic_header->time_code_flag == 1)
+		{
+		//pic_header->time_code = param->p.pic_header_time_code;
+		}
+	}
+
+	pic_header->decode_order_index = param->p.pic_header_decode_order_index;
+
+#if LIBVC_ON
+	pic_header->library_picture_index = -1;
+	if (pic_header->slice_type == SLICE_I)
+	{
+		if (sqh->library_stream_flag)
+		{
+		pic_header->library_picture_index = param->p.pic_header_library_picture_index;
+		}
+	}
+#endif
+
+	if (sqh->temporal_id_enable_flag == 1)
+	{
+		//pic_header->temporal_id = (u8)param->p.pic_header_temporal_id;
+	}
+	if (sqh->low_delay == 0)
+	{
+		pic_header->picture_output_delay = param->p.pic_header_picture_output_delay;
+		pic_header->bbv_check_times = 0;
+	}
+	else
+	{
+		pic_header->picture_output_delay = 0;
+		//pic_header->bbv_check_times = param->p.pic_header_bbv_check_times;
+	}
+
+	//the field information below is not used by decoder -- start
+	pic_header->progressive_frame = param->p.pic_header_progressive_frame;
+	assert(pic_header->progressive_frame == 1);
+	if (pic_header->progressive_frame == 0)
+	{
+		//pic_header->picture_structure = param->p.pic_header_picture_structure;
+	}
+	else
+	{
+		//pic_header->picture_structure = 1;
+	}
+	pic_header->top_field_first = param->p.pic_header_top_field_first;
+	pic_header->repeat_first_field = param->p.pic_header_repeat_first_field;
+	if (sqh->field_coded_sequence == 1)
+	{
+		pic_header->top_field_picture_flag = param->p.pic_header_top_field_picture_flag;
+		//com_bsr_read1(bs); // reserved_bits r(1)
+	}
+	// -- end
+
+#if LIBVC_ON
+	if (!sqh->library_stream_flag)
+	{
+#endif
+	if (pic_header->decode_order_index < pic_header->g_DOIPrev)
+	{
+	 *need_minus_256 = 1;
+		pic_header->g_CountDOICyCleTime++;                    // initialized the number .
+	}
+	pic_header->g_DOIPrev = pic_header->decode_order_index;
+	pic_header->dtr = pic_header->decode_order_index + (DOI_CYCLE_LENGTH*pic_header->g_CountDOICyCleTime) + pic_header->picture_output_delay - sqh->output_reorder_delay;//MX: in the decoder, the only usage of g_CountDOICyCleTime is to derive the POC/POC. here is the dtr
+#if LIBVC_ON
+	}
+	else
+	{
+		pic_header->dtr = pic_header->decode_order_index + (DOI_CYCLE_LENGTH*pic_header->g_CountDOICyCleTime) + pic_header->picture_output_delay - sqh->output_reorder_delay;
+	}
+#endif
+
+	//initialization
+	pic_header->rpl_l0_idx = pic_header->rpl_l1_idx = -1;
+	pic_header->ref_pic_list_sps_flag[0] = pic_header->ref_pic_list_sps_flag[1] = 0;
+	pic_header->rpl_l0.ref_pic_num = 0;
+	pic_header->rpl_l1.ref_pic_num = 0;
+	pic_header->rpl_l0.ref_pic_active_num = 0;
+	pic_header->rpl_l1.ref_pic_active_num = 0;
+	for (i = 0; i < MAX_NUM_REF_PICS; i++)
+	{
+		pic_header->rpl_l0.ref_pics[i] = 0;
+		pic_header->rpl_l1.ref_pics[i] = 0;
+		pic_header->rpl_l0.ref_pics_ddoi[i] = 0;
+		pic_header->rpl_l1.ref_pics_ddoi[i] = 0;
+		pic_header->rpl_l0.ref_pics_doi[i] = 0;
+		pic_header->rpl_l1.ref_pics_doi[i] = 0;
+#if LIBVC_ON
+		pic_header->rpl_l0.library_index_flag[i] = 0;
+		pic_header->rpl_l1.library_index_flag[i] = 0;
+#endif
+	}
+
+#if HLS_RPL
+	//TBD(@Chernyak) if (!IDR) condition to be added here
+	pic_header->poc = pic_header->dtr;
+	//pic_header->poc = com_bsr_read_ue(bs);  = param_proc???("", -1, );
+	// L0 candidates signaling
+	pic_header->ref_pic_list_sps_flag[0] = param->p.pic_header_ref_pic_list_sps_flag[0];
+	if (pic_header->ref_pic_list_sps_flag[0])
+	{
+		if (sqh->rpls_l0_num)
+		{
+		if (sqh->rpls_l0_num > 1)
+		{
+			pic_header->rpl_l0_idx = param->p.pic_header_rpl_l0_idx;
+		}
+		else//if sps only have 1 RPL, no need to signal the idx
+		{
+			pic_header->rpl_l0_idx = 0;
+		}
+#ifdef BUFMGR_SANITY_CHECK
+		if ((pic_header->rpl_l1_idx >= 0) &&
+			(pic_header->rpl_l1_idx < MAX_NUM_RPLS))
+#endif
+		memcpy(&pic_header->rpl_l0, &sqh->rpls_l0[pic_header->rpl_l0_idx], sizeof(pic_header->rpl_l0));
+		pic_header->rpl_l0.poc = pic_header->poc;
+		}
+	}
+	else
+	{
+#if LIBVC_ON
+		dec_eco_rlp(param, &pic_header->rpl_l0, sqh);
+#else
+		dec_eco_rlp(param, &pic_header->rpl_l0);
+#endif
+		pic_header->rpl_l0.poc = pic_header->poc;
+	}
+
+	//L1 candidates signaling
+		pic_header->ref_pic_list_sps_flag[1] = param->p.pic_header_ref_pic_list_sps_flag[1];
+	if (pic_header->ref_pic_list_sps_flag[1])
+	{
+		if (sqh->rpls_l1_num > 1 && sqh->rpl1_index_exist_flag)
+		{
+		pic_header->rpl_l1_idx = param->p.pic_header_rpl_l1_idx;
+		}
+		else if (!sqh->rpl1_index_exist_flag)
+		{
+		pic_header->rpl_l1_idx = pic_header->rpl_l0_idx;
+		}
+		else//if sps only have 1 RPL, no need to signal the idx
+		{
+		assert(sqh->rpls_l1_num == 1);
+		pic_header->rpl_l1_idx = 0;
+		}
+#ifdef BUFMGR_SANITY_CHECK
+		if ((pic_header->rpl_l1_idx >= 0) &&
+			(pic_header->rpl_l1_idx < MAX_NUM_RPLS))
+#endif
+		memcpy(&pic_header->rpl_l1, &sqh->rpls_l1[pic_header->rpl_l1_idx], sizeof(pic_header->rpl_l1));
+		pic_header->rpl_l1.poc = pic_header->poc;
+	}
+	else
+	{
+#if LIBVC_ON
+		dec_eco_rlp(param, &pic_header->rpl_l1, sqh);
+#else
+		dec_eco_rlp(param, &pic_header->rpl_l1);
+#endif
+		pic_header->rpl_l1.poc = pic_header->poc;
+	}
+#ifdef AML
+		pic_header->rpl_l0.ref_pic_num = param->p.pic_header_rpl_l0_ref_pic_num;
+	for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+			pic_header->rpl_l0.ref_pics_ddoi[ii] = param->p.pic_header_rpl_l0_ref_pics_ddoi[ii];
+	}
+		pic_header->rpl_l1.ref_pic_num = param->p.pic_header_rpl_l1_ref_pic_num;
+	for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+			pic_header->rpl_l1.ref_pics_ddoi[ii] = param->p.pic_header_rpl_l1_ref_pics_ddoi[ii];
+	}
+
+		pic_header->rpl_l0.reference_to_library_enable_flag = param->p.pic_header_rpl_l0_reference_to_library_enable_flag;
+	for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+			pic_header->rpl_l0.library_index_flag[ii] = param->p.pic_header_rpl_l0_library_index_flag[ii];
+	}
+		pic_header->rpl_l1.reference_to_library_enable_flag = param->p.pic_header_rpl_l1_reference_to_library_enable_flag;
+	for (ii=0; ii<MAX_NUM_REF_PICS; ii++) {
+			pic_header->rpl_l1.library_index_flag[ii] = param->p.pic_header_rpl_l1_library_index_flag[ii];
+	}
+
+#endif
+
+	if (pic_header->slice_type != SLICE_I)
+	{
+		pic_header->num_ref_idx_active_override_flag = param->p.pic_header_num_ref_idx_active_override_flag;
+		if (pic_header->num_ref_idx_active_override_flag)
+		{
+		pic_header->rpl_l0.ref_pic_active_num = (u32)param->p.pic_header_rpl_l0_ref_pic_active_num;
+#ifdef BUFMGR_SANITY_CHECK
+		if (pic_header->rpl_l0.ref_pic_active_num > MAX_NUM_REF_PICS) {
+			if (avs3_get_debug_flag())
+			pr_info("<1>pic_header->rpl_l0.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+			pic_header->rpl_l0.ref_pic_active_num, MAX_NUM_REF_PICS);
+			pic_header->rpl_l0.ref_pic_active_num = MAX_NUM_REF_PICS;
+		}
+#endif
+		if (pic_header->slice_type == SLICE_P)
+		{
+			pic_header->rpl_l1.ref_pic_active_num = 0;
+		}
+		else if (pic_header->slice_type == SLICE_B)
+		{
+			pic_header->rpl_l1.ref_pic_active_num = (u32)param->p.pic_header_rpl_l1_ref_pic_active_num;
+#ifdef BUFMGR_SANITY_CHECK
+			if (pic_header->rpl_l1.ref_pic_active_num > MAX_NUM_REF_PICS) {
+			if (avs3_get_debug_flag())
+				pr_info("<2>pic_header->rpl_l1.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+				pic_header->rpl_l1.ref_pic_active_num, MAX_NUM_REF_PICS);
+			pic_header->rpl_l1.ref_pic_active_num = MAX_NUM_REF_PICS;
+			}
+#endif
+		}
+		}
+		else
+		{
+		//Hendry -- @Roman: we need to signal the num_ref_idx_default_active_minus1[ i ]. This syntax element is in the PPS in the spec document
+		pic_header->rpl_l0.ref_pic_active_num = sqh->num_ref_default_active_minus1[0]+1;
+#ifdef BUFMGR_SANITY_CHECK
+		if (pic_header->rpl_l0.ref_pic_active_num > MAX_NUM_REF_PICS) {
+		if (avs3_get_debug_flag())
+			pr_info("<3>pic_header->rpl_l0.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+			pic_header->rpl_l0.ref_pic_active_num, MAX_NUM_REF_PICS);
+			pic_header->rpl_l0.ref_pic_active_num = MAX_NUM_REF_PICS;
+		}
+#endif
+		if (pic_header->slice_type == SLICE_P)
+		{
+		pic_header->rpl_l1.ref_pic_active_num = 0;
+		}
+		else
+		{
+		pic_header->rpl_l1.ref_pic_active_num = sqh->num_ref_default_active_minus1[1] + 1;
+#ifdef BUFMGR_SANITY_CHECK
+		if (pic_header->rpl_l1.ref_pic_active_num > MAX_NUM_REF_PICS) {
+			if (avs3_get_debug_flag())
+			pr_info("<4>pic_header->rpl_l1.ref_pic_active_num (%d) is beyond limit, force it to %d\n",
+				pic_header->rpl_l1.ref_pic_active_num, MAX_NUM_REF_PICS);
+			pic_header->rpl_l1.ref_pic_active_num = MAX_NUM_REF_PICS;
+		}
+#endif
+		}
+		}
+	}
+	if (pic_header->slice_type == SLICE_I)
+	{
+		pic_header->rpl_l0.ref_pic_active_num = 0;
+		pic_header->rpl_l1.ref_pic_active_num = 0;
+	}
+#if LIBVC_ON
+	pic_header->is_RLpic_flag = 0;
+	if (pic_header->slice_type != SLICE_I)
+	{
+		int only_ref_libpic_flag = 1;
+#ifdef BUFMGR_SANITY_CHECK
+		for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num && i < MAX_NUM_REF_PICS; i++)
+#else
+		for (i = 0; i < pic_header->rpl_l0.ref_pic_active_num; i++)
+#endif
+		{
+		if (!pic_header->rpl_l0.library_index_flag[i])
+		{
+			only_ref_libpic_flag = 0;
+			break;
+		}
+		}
+		if (only_ref_libpic_flag)
+		{
+#ifdef BUFMGR_SANITY_CHECK
+		for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num && i < MAX_NUM_REF_PICS; i++)
+#else
+		for (i = 0; i < pic_header->rpl_l1.ref_pic_active_num; i++)
+#endif
+		{
+			if (!pic_header->rpl_l1.library_index_flag[i])
+			{
+			only_ref_libpic_flag = 0;
+			break;
+			}
+		}
+		}
+		pic_header->is_RLpic_flag = only_ref_libpic_flag;
+	}
+#endif
+#endif
+
+#ifdef ORI_CODE
+
+	//pic_header->fixed_picture_qp_flag = param->p.pic_header_fixed_picture_qp_flag;
+	//pic_header->picture_qp = param->p.pic_header_picture_qp;
+#if CUDQP && PHASE_2_PROFILE
+	pic_header->cu_delta_qp_flag = pic_header->cu_qp_group_size = pic_header->cu_qp_group_area_size = 0;
+	if (!pic_header->fixed_picture_qp_flag && (sqh->profile_id == 0x32 || sqh->profile_id == 0x30))
+	{
+		pic_header->cu_delta_qp_flag = param->p.pic_header_cu_delta_qp_flag;
+		if (pic_header->cu_delta_qp_flag)
+		{
+		pic_header->cu_qp_group_size = param->p.pic_header_cu_qp_group_size;
+		pic_header->cu_qp_group_area_size = pic_header->cu_qp_group_size * pic_header->cu_qp_group_size;
+		}
+	}
+#endif
+#if CABAC_MULTI_PROB
+	if (pic_header->slice_type == SLICE_I)
+	{
+		mCabac_ws = MCABAC_SHIFT_I;
+		mCabac_offset = (1 << (mCabac_ws - 1));
+		counter_thr1 = 0;
+		counter_thr2 = COUNTER_THR_I;
+	}
+	else if (pic_header->slice_type == SLICE_B)
+	{
+		mCabac_ws = MCABAC_SHIFT_B;
+		mCabac_offset = (1 << (mCabac_ws - 1));
+		counter_thr1 = 3;
+		counter_thr2 = COUNTER_THR_B;
+	}
+	else
+	{
+		mCabac_ws = MCABAC_SHIFT_P;
+		mCabac_offset = (1 << (mCabac_ws - 1));
+		counter_thr1 = 3;
+		counter_thr2 = COUNTER_THR_P;
+	}
+	if (sqh->mcabac_enable_flag)
+	{
+		g_compatible_back = 0;
+	}
+	else
+	{
+		g_compatible_back = 1;
+	}
+#endif
+	//the reserved_bits only appears in inter_picture_header, so add the non-I-slice check
+	if ( pic_header->slice_type != SLICE_I && !(pic_header->slice_type == SLICE_B && pic_header->picture_structure == 1) )
+	{
+		com_bsr_read1( bs ); // reserved_bits r(1)
+	}
+	dec_eco_DB_param(bs, pic_header
+#if DBK_SCC || DBR
+		, sqh
+#endif
+	);
+
+	//pic_header->chroma_quant_param_disable_flag = (u8)param->p.pic_header_chroma_quant_param_disable_flag;
+	if (pic_header->chroma_quant_param_disable_flag == 0)
+	{
+		pic_header->chroma_quant_param_delta_cb = (u8)com_bsr_read_se(bs);
+		pic_header->chroma_quant_param_delta_cr = (u8)com_bsr_read_se(bs);
+	}
+	else
+	{
+		pic_header->chroma_quant_param_delta_cb = pic_header->chroma_quant_param_delta_cr = 0;
+	}
+
+	if (sqh->wq_enable)
+	{
+		pic_header->pic_wq_enable = param->p.pic_header_pic_wq_enable;
+		if (pic_header->pic_wq_enable)
+		{
+		pic_header->pic_wq_data_idx = param->p.pic_header_pic_wq_data_idx;
+		if (pic_header->pic_wq_data_idx == 0)
+		{
+			memcpy(pic_header->wq_4x4_matrix, sqh->wq_4x4_matrix, sizeof(sqh->wq_4x4_matrix));
+			memcpy(pic_header->wq_8x8_matrix, sqh->wq_8x8_matrix, sizeof(sqh->wq_8x8_matrix));
+		}
+		else if (pic_header->pic_wq_data_idx == 1)
+		{
+			int delta, i;
+			com_bsr_read1( bs ); //reserved_bits r(1)
+			pic_header->wq_param = param->p.pic_header_wq_param;
+			pic_header->wq_model = param->p.pic_header_wq_model;
+			if (pic_header->wq_param == 0)
+			{
+			memcpy(pic_header->wq_param_vector, tab_wq_param_default[1], sizeof(pic_header->wq_param_vector));
+			}
+			else if (pic_header->wq_param == 1)
+			{
+			for (i = 0; i < 6; i++)
+			{
+				delta = com_bsr_read_se(bs);
+				pic_header->wq_param_vector[i] = delta + tab_wq_param_default[0][i];
+			}
+			}
+			else
+			{
+			for (i = 0; i < 6; i++)
+			{
+				delta = com_bsr_read_se(bs);
+				pic_header->wq_param_vector[i] = delta + tab_wq_param_default[1][i];
+			}
+			}
+			set_pic_wq_matrix_by_param(pic_header->wq_param_vector, pic_header->wq_model, pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+		}
+		else
+		{
+			read_wq_matrix(bs, pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+		}
+		}
+		else
+		{
+		init_pic_wq_matrix(pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+		}
+	}
+	else
+	{
+		pic_header->pic_wq_enable = 0;
+		init_pic_wq_matrix(pic_header->wq_4x4_matrix, pic_header->wq_8x8_matrix);
+	}
+#if ESAO
+	if (sqh->esao_enable_flag)
+	{
+#if ESAO_PH_SYNTAX
+		dec_eco_esao_param(bs, pic_header);
+#else
+		dec_eco_esao_pic_header(bs, pic_header);
+#endif
+	}
+	else
+	{
+		memset(pic_header->pic_esao_on, 0, N_C * sizeof(int));
+	}
+#endif
+#if CCSAO
+	if (sqh->ccsao_enable_flag)
+	{
+		dec_eco_ccsao_pic_header(bs, pic_header);
+#if CCSAO_PH_SYNTAX
+		dec_eco_ccsao_param(pic_header, bs);
+#endif
+	}
+	else
+	{
+		memset(pic_header->pic_ccsao_on, 0, (N_C-1) * sizeof(int));
+	}
+#endif
+/*ORI_CODE*/
+#endif
+	if (pic_header->tool_alf_on)
+	{
+		/* decode ALF flag and ALF coeff */
+#if ALF_SHAPE
+		int num_coef = (sqh->adaptive_filter_shape_enable_flag) ? ALF_MAX_NUM_COEF_SHAPE2 : ALF_MAX_NUM_COEF;
+#endif
+
+#if ALF_IMP
+		int max_filter_num = (sqh->adaptive_filter_shape_enable_flag) ? NO_VAR_BINS:NO_VAR_BINS_16;
+#endif
+
+		dec_eco_alf_param(param, pic_header
+#if ALF_SHAPE
+				, num_coef
+#endif
+#if ALF_IMP
+		,max_filter_num
+#endif
+		);
+	}
+	else
+	{
+		memset( pic_header->pic_alf_on, 0, N_C * sizeof( int ) );
+	}
+#ifdef ORI_CODE
+	if (pic_header->slice_type != SLICE_I && sqh->affine_enable_flag)
+	{
+		//pic_header->affine_subblock_size_idx = param->p.pic_header_affine_subblock_size_idx;
+	}
+#if USE_IBC
+#if PHASE_2_PROFILE
+	if (sqh->ibc_flag)
+	{
+#endif
+		pic_header->ibc_flag = (u8)param->p.pic_header_ibc_flag;
+#if PHASE_2_PROFILE
+	}
+	else
+	{
+		pic_header->ibc_flag = 0;
+	}
+#endif
+#endif
+#if USE_SP
+#if PHASE_2_PROFILE
+	if (sqh->sp_enable_flag)
+	{
+#endif
+		pic_header->sp_pic_flag = (u8)param->p.pic_header_sp_pic_flag;
+#if PHASE_2_PROFILE
+	}
+	else
+	{
+		pic_header->sp_pic_flag = 0;
+	}
+#endif
+#if EVS_UBVS_MODE
+	pic_header->evs_ubvs_pic_flag = sqh->evs_ubvs_enable_flag;
+#endif
+#endif
+#if FIMC
+#if PHASE_2_PROFILE
+	if (sqh->fimc_enable_flag)
+	{
+#endif
+		pic_header->fimc_pic_flag = (u8)param->p.pic_header_fimc_pic_flag;
+#if PHASE_2_PROFILE
+	}
+	else
+	{
+		pic_header->fimc_pic_flag = 0;
+	}
+#endif
+#endif
+#if ISTS
+	if (sqh->ists_enable_flag)
+	{
+		pic_header->ph_ists_enable_flag = (u8)param->p.pic_header_ph_ists_enable_flag;
+	}
+#if PHASE_2_PROFILE
+	else
+	{
+		pic_header->ph_ists_enable_flag = 0;
+	}
+#endif
+#endif
+#if TS_INTER
+	if (sqh->ts_inter_enable_flag && pic_header->slice_type != SLICE_I)
+	{
+		pic_header->ph_ts_inter_enable_flag = (u8)param->p.pic_header_ph_ts_inter_enable_flag;
+	}
+#if PHASE_2_PROFILE
+	else
+	{
+		pic_header->ph_ts_inter_enable_flag = 0;
+	}
+#endif
+#endif
+#if AWP
+	if (sqh->awp_enable_flag)
+	{
+		pic_header->ph_awp_refine_flag = (u8)param->p.pic_header_ph_awp_refine_flag;
+	}
+#if PHASE_2_PROFILE
+	else
+	{
+		pic_header->ph_awp_refine_flag = 0;
+	}
+#endif
+#endif
+#if UMVE_ENH
+	if (sqh->umve_enh_enable_flag && pic_header->slice_type != SLICE_I)
+	{
+		pic_header->umve_set_flag = (u8)param->p.pic_header_umve_set_flag;
+	}
+	else
+	{
+		pic_header->umve_set_flag = 0;
+	}
+#endif
+#if EPMC
+	if (sqh->pmc_enable_flag)
+	{
+		pic_header->ph_epmc_model_flag = (u8)param->p.pic_header_ph_epmc_model_flag;
+
+	}
+	else
+	{
+		pic_header->ph_epmc_model_flag = 0;
+	}
+#endif
+	/* byte align */
+
+	ret = com_bsr_read1(bs);
+	assert(ret == 1);
+	while (!COM_BSR_IS_BYTE_ALIGN(bs))
+	{
+		assert(com_bsr_read1(bs) == 0);
+	}
+	while (com_bsr_next(bs, 24) != 0x1)
+	{
+		assert(com_bsr_read(bs, 8) == 0);
+	}
+/*ORI_CODE*/
+#endif
+	return COM_OK;
+}
+
+int dec_eco_patch_header(union param_u *param, COM_SQH *sqh, COM_PIC_HEADER * ph, COM_SH_EXT * sh,PATCH_INFO *patch)
+{
+	return COM_OK;
+}
+
+int dec_eco_alf_param(union param_u *rpm_param, COM_PIC_HEADER *sh
+#if ALF_SHAPE
+				, int num_coef
+#endif
+#if ALF_IMP
+	, int max_filter_num
+#endif
+)
+{
+	ALF_PARAM **alf_picture_param = sh->alf_picture_param;
+	int *pic_alf_on = sh->pic_alf_on;
+	int compIdx;
+	if (alf_picture_param == NULL) {
+		pr_err("%s, alf_picture_param null\n", __func__);
+		return COM_ERR;
+	}
+
+#if ALF_SHAPE
+	alf_picture_param[Y_C]->num_coeff = num_coef;
+	alf_picture_param[U_C]->num_coeff = num_coef;
+	alf_picture_param[V_C]->num_coeff = num_coef;
+#endif
+#if ALF_IMP
+	alf_picture_param[Y_C]->max_filter_num = max_filter_num;
+	alf_picture_param[U_C]->max_filter_num = 1;
+	alf_picture_param[V_C]->max_filter_num = 1;
+#endif
+	pic_alf_on[Y_C] = rpm_param->alf.picture_alf_enable_Y;
+	pic_alf_on[U_C] = rpm_param->alf.picture_alf_enable_Cb;
+	pic_alf_on[V_C] = rpm_param->alf.picture_alf_enable_Cr;
+
+	alf_picture_param[Y_C]->alf_flag = pic_alf_on[Y_C];
+	alf_picture_param[U_C]->alf_flag = pic_alf_on[U_C];
+	alf_picture_param[V_C]->alf_flag = pic_alf_on[V_C];
+	if (pic_alf_on[Y_C] || pic_alf_on[U_C] || pic_alf_on[V_C])
+	{
+		for (compIdx = 0; compIdx < N_C; compIdx++)
+		{
+		if (pic_alf_on[compIdx])
+		{
+			dec_eco_alf_coeff(rpm_param, alf_picture_param[compIdx]);
+		}
+		}
+	}
+	return COM_OK;
+}
+
+int dec_eco_alf_coeff(union param_u *rpm_param, ALF_PARAM *alf_param)
+{
+	int pos;
+	int f = 0, symbol, pre_symbole;
+	int32_t region_distance_idx = 0;
+#if ALF_SHAPE
+	const int num_coeff = alf_param->num_coeff;
+#else
+	const int num_coeff = (int)ALF_MAX_NUM_COEF;
+#endif
+
+	if (num_coeff > ALF_MAX_NUM_COEF)
+		return COM_ERR;
+
+	switch (alf_param->component_id)
+	{
+	case U_C:
+	case V_C:
+		for (pos = 0; pos < num_coeff; pos++)
+		{
+		if (alf_param->component_id == U_C)
+		alf_param->coeff_multi[0][pos] = (int16_t)rpm_param->alf.alf_cb_coeffmulti[pos];
+		else
+		alf_param->coeff_multi[0][pos] = (int16_t)rpm_param->alf.alf_cr_coeffmulti[pos];
+		}
+		break;
+	case Y_C:
+		alf_param->filters_per_group = rpm_param->alf.alf_filters_num_m_1;
+		alf_param->filters_per_group = alf_param->filters_per_group + 1;
+#if ALF_IMP
+		if (alf_param->max_filter_num == NO_VAR_BINS)
+		{
+		alf_param->dir_index = rpm_param->alf.dir_index;
+		}
+		else
+		{
+		assert(alf_param->max_filter_num == NO_VAR_BINS_16);
+		}
+#endif
+		memset(alf_param->filter_pattern, 0, NO_VAR_BINS * sizeof(int));
+		pre_symbole = 0;
+		symbol = 0;
+		for (f = 0; f < alf_param->filters_per_group; f++)
+		{
+		if (f > 0)
+		{
+#if ALF_IMP
+			if (alf_param->filters_per_group != alf_param->max_filter_num)
+#else
+			if (alf_param->filters_per_group != NO_VAR_BINS)
+#endif
+			{
+			symbol = rpm_param->alf.region_distance[region_distance_idx++];
+			}
+			else
+			{
+			symbol = 1;
+			}
+			alf_param->filter_pattern[symbol + pre_symbole] = 1;
+			pre_symbole = symbol + pre_symbole;
+		}
+		for (pos = 0; pos < num_coeff; pos++)
+		{
+			alf_param->coeff_multi[f][pos] = (int16_t)rpm_param->alf.alf_y_coeffmulti[f][pos]; //com_bsr_read_se(bs);
+		}
+		}
+		break;
+	default:
+		printf("Not a legal component ID\n");
+		assert(0);
+		//exit(-1);
+		return -1;
+	}
+	return COM_OK;
+}
diff --git a/drivers/frame_provider/decoder/avs3/vavs3.c b/drivers/frame_provider/decoder/avs3/vavs3.c
new file mode 100644
index 0000000..9a674bc
--- /dev/null
+++ b/drivers/frame_provider/decoder/avs3/vavs3.c
@@ -0,0 +1,11203 @@
+ /*
+ * drivers/amlogic/amports/avs3.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/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+#include <linux/dma-map-ops.h>
+#else
+#include <linux/dma-contiguous.h>
+#endif
+#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 "../utils/decoder_mmu_box.h"
+#include "../utils/decoder_bmmu_box.h"
+#include "avs3_global.h"
+#include "../../../common/media_utils/media_utils.h"
+//#define TMP_DEBUG
+
+//#define USE_FRONT_ISR_HANDLE_FOR_BACK
+
+#define FOR_S5
+#define PXP_DEBUG
+#define USE_SIM_BUFSPEC
+
+//#define DEBUG_CMD
+
+#define MEM_NAME "codec_avs3"
+#include "../utils/vdec.h"
+#include "../utils/amvdec.h"
+
+#include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include "../utils/config_parser.h"
+#include "../utils/firmware.h"
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../utils/vdec_feature.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "../utils/vdec_profile.h"
+#include "../../../media_sync/pts_server/pts_server_core.h"
+
+#define DYN_CACHE
+#define I_ONLY_SUPPORT
+#define MIX_STREAM_SUPPORT
+//#define CONSTRAIN_MAX_BUF_NUM
+
+#define CO_MV_COMPRESS
+
+#include "vavs3.h"
+#define HEVC_SHIFT_LENGTH_PROTECT                  0x313a
+#define HEVC_MPRED_CTRL4                           0x324c
+#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
+
+/*
+ * AVS3_DEC_STATUS define
+*/
+/*internal*/
+#define AVS3_DEC_IDLE                           0
+#define AVS3_SEQUENCE                           1
+#define AVS3_I_PICTURE                          2
+#define AVS3_PB_PICTURE                         3
+#define AVS3_DISCARD_STARTCODE                  4
+#define AVS3_DISCARD_NAL                        4
+
+#define AVS3_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 AVS3_HEAD_SEQ_READY                  0x21
+#define AVS3_HEAD_PIC_I_READY                0x22
+#define AVS3_HEAD_PIC_PB_READY               0x23
+#define AVS3_HEAD_SEQ_END_READY              0x24
+#define AVS3_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 AVS3_DECODE_BUFEMPTY        0x33
+#define AVS3_DECODE_TIMEOUT         0x34
+#define AVS3_DECODE_OVER_SIZE       0x35
+#define AVS3_EOS                    0x36
+
+/*cmd*/
+#define AVS3_10B_DISCARD_NAL                 0xf0
+#define AVS3_SEARCH_NEW_PIC                  0xf1
+#define AVS3_ACTION_ERROR                    0xfe
+#define HEVC_ACTION_ERROR                    0xfe
+#define AVS3_ACTION_DONE                     0xff
+/*AVS3_DEC_STATUS end*/
+
+//???
+#define HEVC_BE_DECODE_DATA        0xa0
+#define HEVC_BE_DECODE_DATA_DONE   0xb0
+#define HEVC_BE_DECODE_TIMEOUT     0xc0
+/*AVS3_BE_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_avs3"
+
+#define lock_buffer(dec, flags) \
+		spin_lock_irqsave(&dec->buffer_lock, flags)
+
+#define unlock_buffer(dec, flags) \
+		spin_unlock_irqrestore(&dec->buffer_lock, flags)
+
+#define lock_front_back(dec, flags) \
+		spin_lock_irqsave(&dec->front_back_lock, flags)
+
+#define unlock_front_back(dec, flags) \
+		spin_unlock_irqrestore(&dec->front_back_lock, flags)
+
+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];
+#ifdef NEW_FB_CODE
+static unsigned int max_process_time_back[MAX_DECODE_INSTANCE_NUM];
+static unsigned int run_count_back[MAX_DECODE_INSTANCE_NUM];
+#endif
+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 u32 over_decoder_shiftbytes = 0x80;
+#endif
+
+static int start_decode_buf_level = 0x8000;
+
+static u32 work_buf_size;
+
+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;
+ * 0x10000, double write p010 enable
+ */
+static u32 double_write_mode;
+
+/* triple_write_mode:
+ * 0, no triple 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
+ * 0x10000, triple write p010 enable
+ */
+static u32 triple_write_mode;
+
+static u32 without_display_mode;
+
+static u32 trace_debug_mode = 7;
+static u32 paral_alloc_buffer_mode = 1;
+
+static u32 mv_buf_dynamic_alloc;
+
+#define DRIVER_NAME "amvdec_avs3"
+#define DRIVER_HEADER_NAME "amvdec_avs3_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_THRESHOLD 3
+
+#define DUR2PTS(x) ((x)*90/96)
+
+struct AVS3Decoder_s;
+static int vavs3_vf_states(struct vframe_states *states, void *);
+static struct vframe_s *vavs3_vf_peek(void *);
+static struct vframe_s *vavs3_vf_get(void *);
+static void vavs3_vf_put(struct vframe_s *, void *);
+static int vavs3_event_cb(int type, void *data, void *private_data);
+static void set_vframe(struct AVS3Decoder_s *dec,
+	struct vframe_s *vf, struct avs3_frame_s *pic, u8 dummy);
+
+static int vavs3_stop(struct AVS3Decoder_s *dec);
+static s32 vavs3_init(struct vdec_s *vdec);
+static void vavs3_prot_init(struct AVS3Decoder_s *dec);
+static int vavs3_local_init(struct AVS3Decoder_s *dec);
+static void vavs3_put_timer_func(struct timer_list *timer);
+static void dump_data(struct AVS3Decoder_s *dec, int size);
+static unsigned char get_data_check_sum
+	(struct AVS3Decoder_s *dec, int size);
+static struct avs3_frame_s *get_pic_by_index(
+	struct AVS3Decoder_s *dec, int index);
+void pic_backend_ref_operation(struct AVS3Decoder_s *dec, avs3_frame_t *pic, bool add_flag);
+static int avs3_hw_ctx_restore(struct AVS3Decoder_s *dec);
+static void dump_or_fill_phy_buffer(struct AVS3Decoder_s *dec, u32 phy_adr, u32 size, char *file, u8 flag, char *mark);
+static void d_dump(struct AVS3Decoder_s *dec, unsigned int phy_adr, int size,
+	struct file *fp, loff_t *wr_off, u32 * total_check_sum, u8 print_flag);
+
+#ifdef NEW_FB_CODE
+static unsigned int decode_timeout_val_back = 200;
+static unsigned int fast_timer_check_count = 3;
+
+static unsigned int efficiency_mode = 1;
+
+static void avs3_work_back(struct work_struct *work);
+static void avs3_timeout_work_back(struct work_struct *work);
+static void avs3_work_back_implement(struct AVS3Decoder_s *dec,
+	struct vdec_s *vdec, int from);
+#endif
+
+static const char vavs3_dec_id[] = "vavs3-dev";
+
+#define PROVIDER_NAME   "decoder.avs3"
+#define MULTI_INSTANCE_PROVIDER_NAME    "vdec.avs3"
+
+static const struct vframe_operations_s vavs3_vf_provider = {
+	.peek = vavs3_vf_peek,
+	.get = vavs3_vf_get,
+	.put = vavs3_vf_put,
+	.event_cb = vavs3_event_cb,
+	.vf_states = vavs3_vf_states,
+};
+
+static struct vframe_provider_s vavs3_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 {
+	AVS3_BITS_8  =  8,  /**<  8 bits */
+	AVS3_BITS_10 = 10,  /**< 10 bits */
+	AVS3_BITS_12 = 12,  /**< 12 bits */
+};
+
+enum trace_debug_t {
+	TRACE_BASIC  =  1,
+	TRACE_BUFFER = 2,
+	TRACE_PERFORMANCE_DETAIL = 4,
+};
+
+enum alloc_buffer_status_t {
+	BUFFER_INIT  =  0,
+	BUFFER_ALLOCATING = 1,
+	BUFFER_ALLOCATE_DONE = 2,
+};
+
+/*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 AVS3_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 AVS3_10B_NV21
+#else
+#define LOSLESS_COMPRESS_MODE
+#endif
+
+#define DOUBLE_WRITE_YSTART_TEMP 0x02000000
+#define DOUBLE_WRITE_CSTART_TEMP 0x02900000
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+//#define UCODE_LOG_BUF_SIZE   (16 * 1024)
+#define UCODE_LOG_BUF_SIZE   (1024 * 1024)
+#endif
+
+#ifdef DEBUG_CMD
+static u32 debug_cmd_wait_count;
+static u32 debug_cmd_wait_type;
+#endif
+
+/* bit 0, disable backend
+	bit 1, start frontend only after last backend done (not pipeline front-back)
+	bit 2, do not loop buffer (use with bit[1] of 1)
+	bit 3, fill loop buffer 0 before starting front decoding
+	##
+	bit[31:28],1: dump loop buffer at frontend data done for specific frame to file
+			bit[27:16], frame num
+	bit[31:28],2: dump frame count of frames to file
+			bit[27:16], frame count
+	bit[31:28],3: dump every frame and print checksum
+	bit[31:28] 8: dump loop buffer to file in dump_state()
+*/
+static u32 fbdebug_flag;
+
+static u32 debug;
+
+static u32 debug_again;
+
+u32 avs3_get_debug_flag(void)
+{
+	return debug;
+}
+
+bool is_avs3_print_param(void)
+{
+	bool ret = false;
+	if (debug & AVS3_DBG_PRINT_PARAM)
+		ret = true;
+	return ret;
+}
+
+inline bool is_avs3_print_bufmgr_detail(void)
+{
+	bool ret = false;
+	if (debug & AVS3_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;
+
+static u32 dump_phy_adr;
+static u32 dump_phy_size;
+
+#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 & AVS3_DBG_REG) {
+		unsigned adr_conv = dos_reg_compat_convert(adr);
+		pr_info("%s(%x, %x)\n", __func__, adr_conv, val);
+	}
+	if (adr != 0)
+		WRITE_VREG(adr, val);
+
+	if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+		if (adr == HEVC_ASSIST_SCRATCH_0) // && val == AVS3_ACTION_DONE)
+			pr_info("!!write HEVC_ASSIST_SCRATCH_0 %x\n", val);
+	}
+}
+
+#undef WRITE_VREG
+#define WRITE_VREG WRITE_VREG_DBG2
+#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 (MAX_PB_SIZE)
+#define HEADER_FRAME_BUFFERS (FRAME_BUFFERS)
+
+#define FRAME_CONTEXTS_LOG2 2
+#define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
+/*buffer + header buffer + workspace*/
+
+#ifdef NEW_FB_CODE
+#define	BMMU_IFBUF_SCALELUT_ID		(0)
+#define	BMMU_IFBUF_VCPU_IMEM_ID 	(BMMU_IFBUF_SCALELUT_ID + 1)
+#define	BMMU_IFBUF_SYS_IMEM_ID		(BMMU_IFBUF_VCPU_IMEM_ID + 1)
+#define	BMMU_IFBUF_LMEM0_ID			(BMMU_IFBUF_SYS_IMEM_ID + 1)
+#define	BMMU_IFBUF_LMEM1_ID			(BMMU_IFBUF_LMEM0_ID + 1)
+#define	BMMU_IFBUF_PARSER_SAO0_ID	(BMMU_IFBUF_LMEM1_ID + 1)
+#define	BMMU_IFBUF_PARSER_SAO1_ID	(BMMU_IFBUF_PARSER_SAO0_ID + 1)
+#define	BMMU_IFBUFF_MPRED_IMP0_ID	(BMMU_IFBUF_PARSER_SAO1_ID + 1)
+#define	BMMU_IFBUFF_MPRED_IMP1_ID	(BMMU_IFBUFF_MPRED_IMP0_ID + 1)
+#define FB_LOOP_BUF_COUNT	(BMMU_IFBUFF_MPRED_IMP1_ID + 1)
+#else
+#define FB_LOOP_BUF_COUNT	0
+#endif
+
+#define MV_USE_FIXED_BUF
+#ifdef MV_USE_FIXED_BUF
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + HEADER_FRAME_BUFFERS+1)
+#else
+#define MAX_BMMU_BUFFER_NUM (FB_LOOP_BUF_COUNT + ((FRAME_BUFFERS*2)+HEADER_FRAME_BUFFERS+1)+1)
+#define VF_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + n)
+#define HEADER_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + FRAME_BUFFERS + n+1)
+#define MV_BUFFER_IDX(n) (FB_LOOP_BUF_COUNT + (FRAME_BUFFERS * 2) + n+1)
+#define WORK_SPACE_BUF_ID (FB_LOOP_BUF_COUNT + (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
+#define CO_MV_BUF_SIZE_4K     0x120000
+#define CO_MV_BUF_SIZE_8K     0x480000
+/*
+static void set_canvas(struct AVS3Decoder_s *dec,
+	struct avs3_frame_s *pic);
+int avs3_prepare_display_buf(struct AVS3Decoder_s *dec,
+					int pos);
+*/
+
+#ifdef NEW_FB_CODE
+static u32 fb_ifbuf_num = 3;
+/*
+	0: single core mode
+	1: front_back_mode
+	2: front_back_test_mode
+*/
+static u32 front_back_mode = 1;
+#endif
+
+struct BuffInfo_s {
+	u32 max_width;
+	u32 max_height;
+	u32 start_adr;
+	u32 end_adr;
+	struct buff_s ipp;
+#ifdef NEW_FRONT_BACK_CODE
+	struct buff_s ipp1;
+#endif
+	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 sbac_top;
+	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 AVS3_10B_MMU
+	struct buff_s mmu_vbh;
+	struct buff_s cm_header;
+#endif
+#ifdef AVS3_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;
+#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
+#define DEC_RESULT_WAIT_BUFFER      11
+#define DEC_RESULT_TIMEOUT          12
+
+#ifdef NEW_FB_CODE
+#define DEC_BACK_RESULT_NONE             0
+#define DEC_BACK_RESULT_DONE             1
+#define DEC_BACK_RESULT_TIMEOUT          2
+#define DEC_BACK_RESULT_FORCE_EXIT       10
+#endif
+
+static void avs3_work(struct work_struct *work);
+struct loop_filter_info_n;
+struct loopfilter;
+struct segmentation;
+
+struct AVS3Decoder_s {
+	int pic_list_init_flag;
+	int pic_list_wait_alloc_done_flag;
+	unsigned char index;
+	spinlock_t front_back_lock;
+	spinlock_t buffer_lock;
+	struct device *cma_dev;
+	struct platform_device *platform_dev;
+	void (*vdec_cb)(struct vdec_s *, void *, int);
+	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;
+	u32 vavs3_ratio;
+	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 AVS3_10B_MMU
+	struct buff_s mc_buf_spec;
+#endif
+	struct dec_sysinfo vavs3_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;
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+	void *ucode_log_addr;
+	dma_addr_t ucode_log_phy_addr;
+#endif
+
+#ifdef AVS3_10B_MMU
+	bool mmu_enable;
+
+	u32 cuva_size;
+	void *cuva_addr;
+	dma_addr_t cuva_phy_addr;
+
+	void *frame_mmu_map_addr;
+	dma_addr_t frame_mmu_map_phy_addr;
+#endif
+#ifdef AVS3_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;
+
+	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 vf_pre_count;
+	u32 vf_get_count;
+	u32 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 AVS3_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 AVS3_10B_MMU
+	int cur_fb_idx_mmu;
+#endif
+	struct avs3_decoder avs3_dec;
+	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;
+	u32 dynamic_buf_margin;
+	int sidebind_type;
+	int sidebind_channel_id;
+	u32 endian;
+	dma_addr_t rdma_phy_adr;
+	unsigned *rdma_adr;
+	int hdr_flag;
+
+	ulong rpm_mem_handle;
+	ulong lmem_phy_handle;
+	ulong frame_mmu_map_handle;
+	ulong frame_mmu_map_handle_1;
+	ulong frame_dw_mmu_map_handle;
+	ulong frame_dw_mmu_map_handle_1;
+	ulong ucode_log_handle;
+	ulong rdma_mem_handle;
+	ulong cuva_handle;
+#ifdef NEW_FB_CODE
+	u32 front_back_mode;
+	int fb_ifbuf_num;
+	//int pic_wr_count;
+	//int pic_rd_count;
+	//struct PIC_s *decoded_PIC[MAX_REF_PIC_NUM];
+	//u32 flush_count;
+
+	/*init_fb_bufstate() for linux APIs*/
+	struct work_struct work_back;
+	struct work_struct timeout_work_back;
+
+	void *frame_mmu_map_addr_1;
+	dma_addr_t frame_mmu_map_phy_addr_1;
+	void *mmu_box_1;
+
+	void *dw_mmu_box_1;
+	void *dw_frame_mmu_map_addr_1;
+	dma_addr_t dw_frame_mmu_map_phy_addr_1;
+
+	void *mmu_box_fb;
+	void *fb_buf_mmu0_addr;
+	void *fb_buf_mmu1_addr;
+	/**/
+	void (*vdec_back_cb)(struct vdec_s *, void *, int);
+	void *vdec_back_cb_arg;
+	struct firmware_s *fw_back;
+	struct timer_list timer_back;
+	unsigned long int start_process_time_back;
+	unsigned int decode_timeout_count_back;
+	unsigned int timeout_num_back;
+
+	int dec_back_result;
+	u32 dec_status_back;
+	struct mutex fb_mutex;
+	u32 mmu_fb_4k_number;
+#endif
+	uint32_t ASSIST_MBOX0_IRQ_REG;
+	uint32_t ASSIST_MBOX0_CLR_REG;
+	uint32_t ASSIST_MBOX0_MASK;
+	uint32_t backend_ASSIST_MBOX0_IRQ_REG;
+	uint32_t backend_ASSIST_MBOX0_CLR_REG;
+	uint32_t backend_ASSIST_MBOX0_MASK;
+
+	unsigned char print_buf[1024*16+16];
+	int print_buf_len;
+	struct trace_decoder_name trace;
+	int has_i_frame;
+	struct mutex slice_header_lock;
+#ifdef OW_TRIPLE_WRITE
+	int triple_write_mode;
+#endif
+	u32 last_monitor_data;
+};
+
+static int  compute_losless_comp_body_size(
+		struct AVS3Decoder_s *dec, int width, int height,
+		uint8_t is_bit_depth_10);
+
+static int avs3_mmu_page_num(struct AVS3Decoder_s *dec,
+	int pic_width, int pic_height, int is_bit_depth_10);
+
+static void avs3_work_implement(struct AVS3Decoder_s *dec);
+
+
+#undef pr_info
+#define pr_info printk
+int avs3_debug(struct AVS3Decoder_s *dec,
+	int flag, const char *fmt, ...)
+{
+#define HEVC_PRINT_BUF		512
+	unsigned char buf[HEVC_PRINT_BUF];
+	int len = 0;
+	if (dec && dec->print_buf_len>0) {
+		dec->print_buf_len = 0;
+		pr_info("%s", dec->print_buf);
+	}
+	if (dec == NULL ||
+		(flag == 0) ||
+		((debug_mask &
+		(1 << dec->index))
+		&& (debug & flag))) {
+		va_list args;
+
+		va_start(args, fmt);
+		if (dec)
+			len = sprintf(buf, "[%d]", dec->index);
+
+#ifdef DEBUG_AMRISC
+		if (dec && dec->front_back_mode == 1)
+			len += sprintf(buf+len, "<%x,%x,%x>", READ_VREG(HEVC_ASSIST_SCRATCH_0), READ_VREG(HEVC_MPC_E), READ_VREG(HEVC_MPC_E_DBE));
+		else
+			len += sprintf(buf+len, "<%x,%x>", READ_VREG(HEVC_ASSIST_SCRATCH_0), READ_VREG(HEVC_MPC_E));
+#endif
+		vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+		//pr_debug("%s", buf);
+		pr_info("%s", buf);
+		va_end(args);
+	}
+	return 0;
+}
+
+static void avs3_print_flush(struct AVS3Decoder_s *dec)
+{
+	if (dec->print_buf_len>0) {
+		dec->print_buf_len = 0;
+		pr_info("%s", dec->print_buf);
+	}
+}
+
+static int avs3_print_cont(struct AVS3Decoder_s *dec,
+	int flag, const char *fmt, ...)
+{
+	//unsigned char buf[HEVC_PRINT_BUF];
+	//int len = 0;
+	if (dec == NULL ||
+		(flag == 0) ||
+		((debug_mask &
+		(1 << dec->index))
+		&& (debug & flag))) {
+		va_list args;
+
+		va_start(args, fmt);
+#if 0
+		vsnprintf(buf + len, HEVC_PRINT_BUF - len, fmt, args);
+		pr_info("%s", buf);
+#else
+		if (dec->print_buf_len<1024*16)
+			dec->print_buf_len += vsnprintf(dec->print_buf+dec->print_buf_len,
+				1024*16-dec->print_buf_len, fmt, args);
+		else
+			pr_info("print_buf is full\n");
+#endif
+		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))
+
+/*
+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;
+bit 2:  1: not output error frame; 0: output error frame;
+bit 3:  1: same poc insert dpb;    0: same poc don't insert dpb;
+
+*/
+
+static u32 error_handle_policy = 5;
+
+int avs3_get_error_policy(void)
+{
+	return error_handle_policy;
+}
+
+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 get_compress_header_size(struct AVS3Decoder_s *dec)
+{
+	int32_t pic_width = dec->avs3_dec.img.width;
+	int32_t pic_height = dec->avs3_dec.img.height;
+
+	if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
+		(IS_8K_SIZE(pic_width, pic_height)))
+		return MMU_COMPRESS_HEADER_SIZE_8K;
+	else if (IS_4K_SIZE(pic_width, pic_height))
+		return MMU_COMPRESS_HEADER_SIZE_4K;
+	return MMU_COMPRESS_HEADER_SIZE_1080P;
+}
+
+static void reset_process_time(struct AVS3Decoder_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 AVS3Decoder_s *dec)
+{
+	dec->start_process_time = jiffies;
+	if ((dec->start_process_time != 0) &&
+		!(error_handle_policy & 0x4) &&
+		(decode_timeout_val > 0)) {
+		dec->decode_timeout_count = fast_timer_check_count;
+	} else
+		dec->decode_timeout_count = 0;
+	dec->last_lcu_idx = 0;
+}
+
+static void update_decoded_pic(struct AVS3Decoder_s *dec);
+
+static void timeout_process(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *cur_pic = avs3_dec->cur_pic;
+	dec->timeout_num++;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1) {
+		amhevc_stop_f();
+	} else
+#endif
+	amhevc_stop();
+	avs3_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);
+}
+
+#ifdef NEW_FB_CODE
+static void reset_process_time_back(struct AVS3Decoder_s *dec)
+{
+	if (dec->start_process_time_back) {
+		unsigned int process_time =
+			1000 * (jiffies - dec->start_process_time_back) / HZ;
+		dec->start_process_time_back = 0;
+		if (process_time > max_process_time_back[dec->index])
+			max_process_time_back[dec->index] = process_time;
+	}
+}
+
+static void start_process_time_back(struct AVS3Decoder_s *dec)
+{
+	dec->start_process_time_back = jiffies;
+	dec->decode_timeout_count_back = fast_timer_check_count;
+}
+
+/*
+static void restart_process_time_back(struct AVS3Decoder_s *dec)
+{
+	dec->start_process_time_back = jiffies;
+	dec->decode_timeout_count_back = 2;
+}
+*/
+static void timeout_process_back(struct AVS3Decoder_s *dec)
+{
+	/*
+	 * 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(&dec->work_back) ||
+		work_busy(&dec->work_back) ||
+		work_busy(&dec->timeout_work_back) ||
+		work_pending(&dec->timeout_work_back)) {
+		pr_err("%s avs3[%d] work back pending, do nothing.\n",__func__, dec->index);
+		return;
+	}
+
+	/* disable irq before handle timeout */
+	WRITE_VREG(dec->backend_ASSIST_MBOX0_MASK, 0);
+
+	avs3_print(dec,
+		0, "%s decoder timeout\n", __func__);
+	dec->timeout_num_back++;
+	reset_process_time_back(dec);
+
+	if (work_pending(&dec->work_back))
+		return;
+	dec->dec_back_result = DEC_BACK_RESULT_TIMEOUT;
+	vdec_schedule_work(&dec->timeout_work_back);
+}
+#endif
+
+static inline void decoder_trace(char *name, int value, int flag)
+{
+	if (trace_debug_mode & flag)
+		ATRACE_COUNTER(name, value);
+}
+
+static u32 get_valid_double_write_mode(struct AVS3Decoder_s *dec)
+{
+	u32 dw_mode;
+
+	dw_mode = (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 AVS3Decoder_s *dec)
+{
+	u32 valid_dw_mode = get_valid_double_write_mode(dec) & 0xffff;
+	int w = dec->avs3_dec.img.width;
+	int h = dec->avs3_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;
+}
+
+#ifdef OW_TRIPLE_WRITE
+static int get_triple_write_mode(struct AVS3Decoder_s *dec)
+{
+	int tw = ((triple_write_mode & 0x80000000) == 0) ?
+		dec->triple_write_mode : (triple_write_mode & 0x7fffffff);
+
+	return (tw & 0xffff);
+}
+#endif
+
+#ifdef P010_ENABLE
+static __inline__ bool is_dw_p010(struct AVS3Decoder_s *dec)
+{
+	int a = (double_write_mode & 0x80000000) ? (double_write_mode & 0x10000) : 0;
+
+	return ((dec->double_write_mode & 0x10000) || a);
+}
+
+static __inline__ bool is_tw_p010(struct AVS3Decoder_s *dec)
+{
+	int a = (triple_write_mode & 0x80000000) ? (triple_write_mode & 0x10000) : 0;
+
+	return ((dec->triple_write_mode & 0x10000) || a);
+}
+
+#else
+static __inline__ bool is_dw_p010(struct AVS3Decoder_s *dec)
+{
+	return 0;
+}
+
+static __inline__ bool is_tw_p010(struct AVS2Decoder_s *dec)
+{
+	return 0;
+}
+#endif
+
+/* for double write buf alloc */
+static int get_double_write_mode_init(struct AVS3Decoder_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 AVS3_10B_MMU
+int avs3_alloc_mmu(
+	struct AVS3Decoder_s *dec,
+	int cur_buf_idx,
+	int pic_width,
+	int pic_height,
+	unsigned short bit_depth,
+	unsigned int *mmu_index_adr)
+{
+	int cur_mmu_4k_number;
+	int bit_depth_10 = (bit_depth == AVS3_BITS_10);
+	int ret;
+
+	cur_mmu_4k_number = avs3_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+	if (cur_mmu_4k_number < 0) {
+		pr_err("%s: cur_mmu_4k_number 0x%x is error width %d height %d\n",
+			__func__, cur_mmu_4k_number, pic_width, pic_height);
+		return -1;
+	}
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+		__func__, cur_buf_idx, cur_mmu_4k_number);
+
+	decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+	ret = decoder_mmu_box_alloc_idx(
+		dec->mmu_box,
+		cur_buf_idx,
+		cur_mmu_4k_number,
+		mmu_index_adr);
+	decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+
+	return ret;
+}
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+int avs3_alloc_dw_mmu(
+	struct AVS3Decoder_s *dec,
+	int cur_buf_idx,
+	int pic_width,
+	int pic_height,
+	unsigned short bit_depth,
+	unsigned int *mmu_index_adr)
+{
+	int cur_mmu_4k_number;
+	int bit_depth_10 = (bit_depth == AVS3_BITS_10);
+	int ret;
+
+	cur_mmu_4k_number = avs3_mmu_page_num(dec, pic_width, pic_height, bit_depth_10);
+	if (cur_mmu_4k_number < 0) {
+		return -1;
+	}
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s decoder_mmu_box_alloc_idx index=%d mmu_4k_number %d\n",
+		__func__, cur_buf_idx, cur_mmu_4k_number);
+
+	decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+	ret = decoder_mmu_box_alloc_idx(
+		dec->dw_mmu_box,
+		cur_buf_idx,
+		cur_mmu_4k_number,
+		mmu_index_adr);
+	decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+
+	return ret;
+}
+#endif
+
+static int get_free_buf_count(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int ii;
+	int count = 0;
+	for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+		if (avs3_dec->pic_pool[ii].buf_cfg.used == 0)
+			count++;
+	}
+	return count;
+}
+
+#ifdef CONSTRAIN_MAX_BUF_NUM
+static int get_vf_ref_only_buf_count(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int ii;
+	int count = 0;
+	for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+		if (avs3_dec->pic_pool[ii].buf_cfg.used > 0 &&
+			avs3_dec->pic_pool[ii].buf_cfg.vf_ref > 0 &&
+#ifdef NEW_FRONT_BACK_CODE
+			avs3_dec->pic_pool[ii].buf_cfg.backend_ref == 0 && /*?? why need it in case0763,
+				                               used is supposed to be 1 if backend_ref is not 0*/
+#endif
+			avs3_dec->pic_pool[ii].is_ref == 0 &&
+			avs3_dec->pic_pool[ii].need_for_out == 0
+			) {
+			count++;
+		}
+	}
+	return count;
+}
+
+static int get_used_buf_count(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int ii;
+	int count = 0;
+	for (ii = 0; ii < avs3_dec->max_pb_size; ii++) {
+		if (avs3_dec->pic_pool[ii].buf_cfg.used > 0)
+			count++;
+	}
+	return count;
+}
+#endif
+int avs3_dec_init(struct AVS3Decoder_s *dec, struct BuffInfo_s *buf_spec_i,
+		struct buff_s *mc_buf_i) {
+
+	dec->frame_count = 0;
+#ifdef AVS3_10B_MMU
+	dec->cur_fb_idx_mmu = INVALID_IDX;
+#endif
+
+	/* private init */
+	dec->work_space_buf = buf_spec_i;
+#ifndef AVS3_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->has_i_frame = 0;
+	dec->bufmgr_error_count = 0;
+#ifdef NEW_FB_CODE
+	dec->start_process_time_back = 0;
+	dec->decode_timeout_count_back = 0;
+	dec->timeout_num_back = 0;
+	dec->decode_timeout_count_back = 0;
+#endif
+	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 avs3_version = 201602101;
+static u32 radr;
+static u32 rval;
+static u32 pop_shorts;
+	/*dbg_cmd[3:0]:
+		2, dump phy address of (dbg_cmd[31:4]<<4)
+	*/
+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)
+#define HEVC_CONFIG_P010_LE        (0x77007)
+
+#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: avs3_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;
+
+/*
+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 = (MAX_NUM_REF_PICS);
+
+static u32 run_ready_min_buf_num = 1;
+
+static DEFINE_MUTEX(vavs3_mutex);
+
+#define HEVC_DEC_STATUS_REG       HEVC_ASSIST_SCRATCH_0
+#define HEVC_RPM_BUFFER           HEVC_ASSIST_SCRATCH_1
+#define AVS3_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 AVS3_10B_MMU
+#define AVS3_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 AVS3_CUVA_ADR             HEVC_ASSIST_SCRATCH_A
+//#define AVS3_CUVA_DATA_SIZE       HEVC_ASSIST_SCRATCH_B
+/*same as simulation*/
+#define HEVC_DECODE_COUNT       HEVC_ASSIST_SCRATCH_A
+#define HEVC_DECODE_SIZE		HEVC_ASSIST_SCRATCH_B
+/**/
+
+#define AVS3_SBAC_TOP_BUFFER      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_9
+#define HEVC_STREAM_SWAP_TEST     HEVC_ASSIST_SCRATCH_L
+#define HEVC_EFFICIENCY_MODE      HEVC_ASSIST_SCRATCH_L
+/*!!!*/
+#define AVS3_CUVA_ADR       HEVC_ASSIST_SCRATCH_M
+#define AVS3_CUVA_DATA_SIZE		HEVC_ASSIST_SCRATCH_N
+#define HEVC_DECODE_PIC_BEGIN     HEVC_ASSIST_SCRATCH_M
+#define DEBUG_REG1              HEVC_ASSIST_SCRATCH_G
+#define DEBUG_REG2              HEVC_ASSIST_SCRATCH_H
+
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+#define HEVC_DBG_LOG_ADR       HEVC_ASSIST_SCRATCH_5
+#ifdef DEBUG_CMD
+#define HEVC_D_ADR               HEVC_ASSIST_SCRATCH_4
+#endif
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE             HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE            HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE                  HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE                  HEVC_ASSIST_SCRATCH_Z
+#define HEVC_EFFICIENCY_MODE_BACK       HEVC_ASSIST_SCRATCH_10
+#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
+	/*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
+
+#ifdef NEW_FRONT_BACK_CODE
+#define HEVC_DEC_STATUS_DBE             HEVC_ASSIST_SCRATCH_W
+#define PIC_DECODE_COUNT_DBE            HEVC_ASSIST_SCRATCH_X
+#define DEBUG_REG1_DBE                  HEVC_ASSIST_SCRATCH_Y
+#define DEBUG_REG2_DBE                  HEVC_ASSIST_SCRATCH_Z
+
+#define EE_ASSIST_MBOX0_IRQ_REG    0x3f70
+#define EE_ASSIST_MBOX0_CLR_REG    0x3f71
+#define EE_ASSIST_MBOX0_MASK       0x3f72
+#endif
+
+#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 amvavs3_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,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x1e00,
+		},
+#endif
+		.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,
+		},
+		.sbac_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 = 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 = 0x3d00, //0x3c80,
+		},
+		.dblk_data = {
+			.buf_size = 0x62800,
+		},
+		.dblk_data2 = {
+			.buf_size = 0x62800,
+		},
+#ifdef AVS3_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
+#ifdef AVS3_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*/
+		},
+#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 = 0x600 * 2,
+		}
+	},
+	{
+		.max_width = 4096,
+		.max_height = 2304,
+		.ipp = {
+			/* IPP work space calculation :
+				4096 * (Y+CbCr+Flags) = 12k, round to 16k */
+			.buf_size = 0x4000,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x4000,
+		},
+#endif
+		.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 */
+		// RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+		.buf_size = 0x1000,
+		},
+		.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,
+		},
+		.sbac_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 = 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 = 0x40000, },
+		.dblk_data  = { .buf_size = 0x80000, },
+		.dblk_data2 = { .buf_size = 0x80000, },
+#ifdef AVS3_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
+#ifdef AVS3_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 = 0x8000, /* 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 = 0x600 * 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,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+		.buf_size = 0x4000 * 2,
+		},
+#endif
+#ifdef USE_SIM_BUFSPEC
+		.sao_abv = {
+		.buf_size = 0x30000*2,
+		},
+		.sao_vb = {
+		.buf_size = 0x30000*2,
+		},
+
+#else
+		.sao_abv = {
+			.buf_size = 0,
+		},
+		.sao_vb = {
+			.buf_size = 0,
+		},
+#endif
+		.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*/
+		// RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+		.buf_size = 0x1000,
+		},
+		.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,
+		},
+		.sbac_top = {
+		// DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+		.buf_size = 0x2000 * 2,
+		},
+#ifdef USE_SIM_BUFSPEC
+		.sao_up = {
+		// SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+		.buf_size = 0x2800*2,
+		},
+#else
+		.sao_up = {
+		/*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
+				total 0x2800 bytes*/
+			.buf_size = 0,
+		},
+#endif
+		.swap_buf = {
+		/*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
+			.buf_size = 0x800,
+		},
+		.swap_buf2 = {
+			.buf_size = 0x800,
+		},
+#ifdef USE_SIM_BUFSPEC
+		.scalelut = {
+		// support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+		.buf_size = 0x8000*2,
+		},
+#else
+		.scalelut = {
+		/*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
+			.buf_size = 0,
+		},
+#endif
+		.dblk_para  = { .buf_size = 0x40000*2, },
+		.dblk_data  = { .buf_size = 0x80000*2, },
+		.dblk_data2 = { .buf_size = 0x80000*2, },
+#ifdef AVS3_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
+#ifdef AVS3_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*2,
+		},
+#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 = 0x600 * 2,
+		}
+	},
+
+	//large buf size for debugging only
+	{
+		.max_width = 4096 * 2,
+		.max_height = 2304 * 2,
+		.ipp = {
+		/*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
+		round to 16k*/
+			.buf_size = 0x4000 * 4,
+		},
+#ifdef NEW_FRONT_BACK_CODE
+		.ipp1 = {
+		// IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k, round to 16k
+			.buf_size = 0x4000 * 4,
+		},
+#endif
+#ifdef USE_SIM_BUFSPEC
+		.sao_abv = {
+			.buf_size = 0x30000*4,
+		},
+		.sao_vb = {
+			.buf_size = 0x30000*4,
+		},
+#else
+		.sao_abv = {
+			.buf_size = 0,
+		},
+		.sao_vb = {
+			.buf_size = 0,
+		},
+#endif
+		.short_term_rps = {
+		/*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
+			total 64x16x2 = 2048 bytes (0x800)*/
+			.buf_size = 0x800*4
+		},
+		.rcs = {
+		/*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
+		total 0x0400 bytes*/
+		// RLP STORE AREA - Max 64 L0 + 64 L1 RLP, each has 32 bytes, total 0x1000 bytes
+			.buf_size = 0x1000*4,
+		},
+		.sps = {
+		/*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
+			total 0x0800 bytes*/
+			.buf_size = 0x800*4,
+		},
+		.pps = {
+		/*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
+			0x2000 bytes*/
+			.buf_size = 0x2000*2,
+		},
+		.sbac_top = {
+			// DAALA TOP STORE AREA - 224 Bytes (use 256 Bytes for LPDDR4) per 128. Total 4096/128*256 = 0x2000
+			.buf_size = 0x2000 * 4,
+		},
+#ifdef USE_SIM_BUFSPEC
+		.sao_up = {
+			// SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes total 0x2800 bytes
+			.buf_size = 0x2800*4,
+		},
+#else
+		.sao_up = {
+		/*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
+				total 0x2800 bytes*/
+			.buf_size = 0,
+		},
+#endif
+		.swap_buf = {
+		/*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
+			.buf_size = 0x800*4,
+		},
+		.swap_buf2 = {
+			.buf_size = 0x800*4,
+		},
+#ifdef USE_SIM_BUFSPEC
+		.scalelut = {
+		// support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)
+			.buf_size = 0x8000*2,
+		},
+#else
+		.scalelut = {
+		/*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
+			.buf_size = 0,
+		},
+#endif
+		.dblk_para  = { .buf_size = 0x40000*4, },
+		.dblk_data  = { .buf_size = 0x80000*4, },
+		.dblk_data2 = { .buf_size = 0x80000*4, },
+#ifdef AVS3_10B_MMU
+		.mmu_vbh = {
+			.buf_size = VBH_BUF_SIZE_8K*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
+#ifdef AVS3_10B_MMU_DW
+		.mmu_vbh_dw = {
+			.buf_size = DW_VBH_BUF_SIZE_8K*2, //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*4,
+		},
+#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 = 0x600 * 2,
+		}
+	}
+
+};
+
+#define IS_8K_SIZE(w, h)  (((w) * (h)) > MAX_SIZE_4K)
+#define IS_4K_SIZE(w, h)  (((w) * (h)) > (1920*1088))
+
+static u32 get_mv_mem_unit(int lcu_size_log2)
+{
+	u32 mv_mem_unit;
+	//lcu_size_log2 == 6 ? 0x200 : lcu_size_log2 == 5 ? 0x80 : 0x20; //avs2
+	//mv_mem_unit = lcu_size_log2 == 7 ? 256 : lcu_size_log2 == 6 ? 64 : 16;
+	mv_mem_unit = lcu_size_log2 == 7 ? 512 : lcu_size_log2 == 6 ? 128 : 32;
+	return mv_mem_unit;
+}
+
+#ifndef MV_USE_FIXED_BUF
+
+static uint32_t get_mv_buf_size(struct AVS3Decoder_s *dec, int width, int height) {
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	uint32_t size;
+	if (mv_buf_dynamic_alloc == 1) {
+		int mv_mem_unit =
+			get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+			int32_t pic_width = avs3_dec->img.width;
+			int32_t pic_height = avs3_dec->img.height;
+		int32_t lcu_size = 1<<avs3_dec->lcu_size_log2;
+		int32_t pic_width_lcu  = ( pic_width %lcu_size  ) ? pic_width /lcu_size  + 1 : pic_width /lcu_size;
+		int32_t pic_height_lcu = ( pic_height %lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+		int32_t lcu_total       =pic_width_lcu*pic_height_lcu;
+		int new_size =  lcu_total * 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
+
+static void config_hevc_irq_num(struct AVS3Decoder_s *dec)
+{
+#ifdef NEW_FB_CODE
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+		dec->ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+		dec->ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+		dec->ASSIST_MBOX0_MASK    = EE_ASSIST_MBOX0_MASK;
+		dec->backend_ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+		dec->backend_ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+		dec->backend_ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+	} else {
+		dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+		dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+		dec->ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+		dec->backend_ASSIST_MBOX0_IRQ_REG = EE_ASSIST_MBOX0_IRQ_REG;
+		dec->backend_ASSIST_MBOX0_CLR_REG = EE_ASSIST_MBOX0_CLR_REG;
+		dec->backend_ASSIST_MBOX0_MASK    = EE_ASSIST_MBOX0_MASK;
+	}
+#else
+	dec->ASSIST_MBOX0_IRQ_REG = HEVC_ASSIST_MBOX0_IRQ_REG;
+	dec->ASSIST_MBOX0_CLR_REG = HEVC_ASSIST_MBOX0_CLR_REG;
+	dec->ASSIST_MBOX0_MASK    = HEVC_ASSIST_MBOX0_MASK;
+#endif
+}
+
+#ifdef NEW_FB_CODE
+#include "avs3_fb_hw.c"
+
+void pic_backend_ref_operation(struct AVS3Decoder_s *dec, avs3_frame_t *pic, bool add_flag)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_frame_t *ref_pic = NULL;
+	int i = 0;
+
+	mutex_lock(&dec->fb_mutex);
+	if (add_flag) {
+		pic->backend_ref = 1;
+		pic->back_done_mark = 0;
+	} else {
+		pic->backend_ref--;
+		if (pic->backend_ref < 0) {
+			pic->backend_ref = 0;
+			avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s:pic(%px) backend_ref error\n",
+				__func__, pic);
+		}
+		pic->back_done_mark = 1;
+	}
+
+	for (i = 0; i < pic->list0_num_refp; i++) {
+		ref_pic = &avs3_dec->pic_pool[pic->list0_index[i]].buf_cfg;
+		if (add_flag) {
+			ref_pic->backend_ref++;
+		} else {
+			ref_pic->backend_ref--;
+			if (ref_pic->backend_ref < 0) {
+				ref_pic->backend_ref = 0;
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 ref_pic %d backend_ref error\n",
+					__func__, pic->list0_index[i]);
+			}
+		}
+	}
+
+	for (i = 0; i < pic->list1_num_refp; i++) {
+		ref_pic = &avs3_dec->pic_pool[pic->list1_index[i]].buf_cfg;
+		if (add_flag) {
+			ref_pic->backend_ref++;
+		} else {
+			ref_pic->backend_ref--;
+			if (ref_pic->backend_ref < 0) {
+				ref_pic->backend_ref = 0;
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 ref_pic %d backend_ref error\n",
+					__func__, pic->list1_index[i]);
+			}
+		}
+	}
+
+	mutex_unlock(&dec->fb_mutex);
+}
+
+/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+static int front_decpic_done_update(struct AVS3Decoder_s *dec, uint8_t reset_flag)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+	int j;
+	if (debug & AVS3_DBG_PRINT_PIC_LIST) {
+		print_pic_pool(avs3_dec, "before inc backend_ref");
+
+		avs3_print_cont(dec, 0, "pic_cfg index %d, list0 index ", cur_pic->index);
+		for (j = 0; j < cur_pic->list0_num_refp; j++)
+			avs3_print_cont(dec, 0, "%d ", cur_pic->list0_index[j]);
+		avs3_print_cont(dec, 0, "list1 index ");
+		for (j = 0; j < cur_pic->list1_num_refp; j++)
+			avs3_print_cont(dec, 0, "%d ", cur_pic->list1_index[j]);
+		avs3_print_cont(dec, 0, "\n");
+	}
+
+	pic_backend_ref_operation(dec, cur_pic, 1);
+
+	if (debug & AVS3_DBG_PRINT_PIC_LIST)
+		print_pic_pool(avs3_dec, "after inc backend_ref");
+
+	if (dec->front_back_mode == 1) {
+		if (fbdebug_flag & 0x70000000) {
+			u8 cmd = (fbdebug_flag >> 28) & 0x7;
+			u32 dump_c = (fbdebug_flag >> 16) & 0xfff;
+			if ((cmd == 3) ||
+				(cmd == 1 && dump_c == avs3_dec->frontend_decoded_count) ||
+				(cmd == 2 && avs3_dec->frontend_decoded_count < dump_c))
+				dump_loop_buffer(dec, avs3_dec->frontend_decoded_count, cmd ==1 || cmd == 2);
+		}
+
+		if (fbdebug_flag & 0x4) {
+			copy_loopbufs_ptr(&avs3_dec->fr, &avs3_dec->init_fr);
+			print_loopbufs_ptr(dec, "fr", &avs3_dec->fr);
+		} else {
+			copy_loopbufs_ptr(&avs3_dec->p_fr, &avs3_dec->fr);
+			read_bufstate_front(avs3_dec);
+			avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"update fr from loop buf register\n");
+
+			print_loopbufs_ptr2(dec, "fr", &avs3_dec->p_fr, &avs3_dec->fr);
+		}
+
+		WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 1);
+
+		//WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_DEC_IDLE);
+	} else {
+		if (reset_flag) /*not multi pictures in one packe*/
+			amhevc_stop();
+	}
+
+	avs3_dec->frontend_decoded_count++;
+	avs3_dec->next_be_decode_pic[avs3_dec->fb_wr_pos] = avs3_dec->cur_pic;
+
+	mutex_lock(&dec->fb_mutex);
+	avs3_dec->fb_wr_pos++;
+	if (avs3_dec->fb_wr_pos >= dec->fb_ifbuf_num)
+		avs3_dec->fb_wr_pos = 0;
+
+	if (avs3_dec->fb_wr_pos == avs3_dec->fb_rd_pos)
+		avs3_dec->wait_working_buf = 1;
+
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+		avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, avs3_dec->wait_working_buf);
+
+	mutex_unlock(&dec->fb_mutex);
+
+	return 0;
+}
+
+#endif
+
+/*Losless compression body buffer size 4K per 64x32 (jt)*/
+static int  compute_losless_comp_body_size(struct AVS3Decoder_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;
+		bsize = (is_bit_depth_10 ? 4096 : 3200)
+		* width_x64 * height_x32;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"%s(%d,%d,%d)=>%d\n",
+		__func__, width, height,
+		is_bit_depth_10, bsize);
+
+	return  bsize;
+}
+
+static int avs3_mmu_page_num(struct AVS3Decoder_s *dec,
+	int pic_width, int pic_height, int is_bit_depth_10)
+{
+	int picture_size;
+	int cur_mmu_4k_number, max_frame_num;
+
+	picture_size =
+		compute_losless_comp_body_size(dec, pic_width, pic_height, is_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) {
+		avs3_print(dec, 0, "over max !! 0x%x width %d height %d\n",
+			max_frame_num, pic_width, pic_height);
+		return -1;
+	}
+	return cur_mmu_4k_number;
+}
+
+/* Losless compression header buffer size 32bytes per 128x64 (jt)*/
+static  int  compute_losless_comp_header_size(struct AVS3Decoder_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;
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"%s(%d,%d)=>%d\n",
+		__func__, width, height,
+		hsize);
+
+	return  hsize;
+}
+
+static void init_buff_spec(struct AVS3Decoder_s *dec,
+	struct BuffInfo_s *buf_spec)
+{
+	void *mem_start_virt;
+	buf_spec->ipp.buf_start =
+		WORKBUF_ALIGN(buf_spec->start_adr);
+#ifdef NEW_FRONT_BACK_CODE
+	buf_spec->ipp1.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+	buf_spec->sao_abv.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp1.buf_start + buf_spec->ipp1.buf_size);
+#else
+	buf_spec->sao_abv.buf_start =
+		WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+#endif
+	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->sbac_top.buf_start =
+		WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+	buf_spec->sao_up.buf_start =
+		WORKBUF_ALIGN(buf_spec->sbac_top.buf_start + buf_spec->sbac_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->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 AVS3_10B_MMU
+	buf_spec->mmu_vbh.buf_start  =
+		WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
+	#ifdef AVS3_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->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);
+	#endif
+#else /* AVS3_10B_MMU */
+	#ifdef AVS3_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 /* AVS3_10B_MMU */
+#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);
+#ifdef NEW_FRONT_BACK_CODE
+			pr_info("ipp1.buf_start             :%x\n",
+				   buf_spec->ipp1.buf_start);
+#endif
+			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 AVS3_10B_MMU
+			pr_info("mmu_vbh.buf_start     :%x\n",
+				buf_spec->mmu_vbh.buf_start);
+	#endif
+	#ifdef AVS3_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
+			pr_info("mpred_mv.buf_start        :%x\n",
+				   buf_spec->mpred_mv.buf_start);
+#endif
+			if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+				pr_info("rpm.buf_start             :%x\n",
+					   buf_spec->rpm.buf_start);
+			}
+		}
+	}
+
+}
+
+static void uninit_mmu_buffers(struct AVS3Decoder_s *dec)
+{
+#ifdef AVS3_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;
+	}
+#endif
+	decoder_mmu_box_free(dec->mmu_box);
+	dec->mmu_box = NULL;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (dec->mmu_box_1)
+			decoder_mmu_box_free(dec->mmu_box_1);
+		dec->mmu_box_1 = NULL;
+		if (dec->dw_mmu_enable && dec->dw_mmu_box_1) {
+			decoder_mmu_box_free(dec->dw_mmu_box_1);
+			dec->dw_mmu_box_1 = NULL;
+		}
+	}
+	if (dec->front_back_mode) {
+		uninit_fb_bufstate(dec);
+	}
+#endif
+	if (dec->bmmu_box)
+		decoder_bmmu_box_free(dec->bmmu_box);
+	dec->bmmu_box = NULL;
+}
+
+static u32 calc_buffer_u_v_h_size(u32 w, u32 h, u32 ratio, u32 lcu_size)
+{
+	int pic_width_dw = w / ratio;
+	int pic_height_dw = h / ratio;
+
+	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) >> 1; // div 2
+
+	return ((mc_buffer_size_u_v + 0xffff) >> 16);
+}
+
+static int config_pic(struct AVS3Decoder_s *dec,
+				struct avs3_frame_s *pic, int32_t lcu_size_log2)
+{
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	int ret = -1;
+	int i;
+	/* to do: init_pic_w, init_pic_h*/
+#if 0
+	int pic_width = dec->init_pic_w;
+	int pic_height = dec->init_pic_h;
+#else
+	//simulation
+	int32_t pic_width = dec->avs3_dec.img.width;
+	int32_t pic_height = dec->avs3_dec.img.height;
+#endif
+	/*struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;*/
+	int32_t lcu_size = 1 << dec->avs3_dec.lcu_size_log2;
+	int32_t pic_width_lcu  = ( pic_width %lcu_size  ) ? pic_width /lcu_size  + 1 : pic_width /lcu_size;
+	int32_t pic_height_lcu = ( pic_height %lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+	int32_t lcu_total       =pic_width_lcu*pic_height_lcu;
+
+	u32 y_adr = 0;
+	int buf_size = 0;
+	int losless_comp_body_size = compute_losless_comp_body_size(
+			dec, pic_width,
+			pic_height, buf_alloc_depth == 10);
+
+	//int mc_buffer_size_u_v = 0;
+	int mc_buffer_size_u_v_h = 0;
+	int dw_uv_size;
+	int dw_mode = get_double_write_mode_init(dec);
+#ifdef OW_TRIPLE_WRITE
+	int tw_mode = get_triple_write_mode(dec);
+#endif
+
+	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+		mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+			pic_height, get_double_write_ratio(dw_mode & 0xf), lcu_size);
+
+		/*64k alignment*/
+		buf_size = ((mc_buffer_size_u_v_h << 16) * 3);
+		buf_size = ((buf_size + 0xffff) >> 16) << 16;
+#ifdef P010_ENABLE
+		if (is_dw_p010(dec)) {	//double size mem for p010 mode
+			buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		}
+#endif
+	}
+#ifdef OW_TRIPLE_WRITE
+	if (tw_mode) {
+		mc_buffer_size_u_v_h = calc_buffer_u_v_h_size(pic_width,
+			pic_height, get_double_write_ratio(tw_mode), lcu_size);
+
+		buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		if (is_tw_p010(dec)) {
+			buf_size += ((mc_buffer_size_u_v_h << 16) * 3);
+		}
+	}
+#endif
+
+	if (dec->mmu_enable) {
+		pic->header_adr = decoder_bmmu_box_get_phy_addr(
+				dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
+
+#ifdef AVS3_10B_MMU_DW
+		if (dec->dw_mmu_enable) {
+			pic->dw_header_adr = pic->header_adr
+				+ get_compress_header_size(dec);
+		}
+#endif
+	}
+
+	i = pic->index;
+
+	/*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) {
+			avs3_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;
+			if (!vdec_secure(vdec))
+				codec_mm_memset(y_adr, 0, buf_size);
+
+			if (vdec->vdata == NULL ||
+				atomic_read(&vdec->vdata->use_flag) == 0) {
+				vdec->vdata = vdec_data_get();
+			}
+
+			if (vdec->vdata != NULL) {
+				int index = 0;
+				struct vdec_data_buf_s data_buf;
+				data_buf.alloc_policy = ALLOC_AUX_BUF;
+				data_buf.aux_buf_size = dec->cuva_size;
+
+				index = vdec_data_get_index((ulong)vdec->vdata, &data_buf);
+				if (index >= 0) {
+					pic->cuva_data_buf = vdec->vdata->data[index].aux_data_buf;
+					vdec_data_buffer_count_increase((ulong)vdec->vdata, index, i);
+					INIT_LIST_HEAD(&vdec->vdata->release_callback[i].node);
+					decoder_bmmu_box_add_callback_func(dec->bmmu_box, VF_BUFFER_IDX(i), (void *)&vdec->vdata->release_callback[i]);
+				} else {
+					avs3_print(dec, 0, "vdec data is full\n");
+				}
+			}
+		} else {
+			avs3_print(dec, 0,
+				"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*/
+	dw_uv_size = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+
+	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;
+	if (dw_mode) {
+		pic->dw_y_adr = y_adr;
+		pic->dw_u_v_adr = pic->dw_y_adr + (dw_uv_size << 1);
+
+		pic->mc_y_adr = pic->dw_y_adr;
+		pic->mc_u_v_adr = pic->dw_u_v_adr;
+	}
+	if (tw_mode) {
+		if (dw_mode) {
+			pic->tw_y_adr = pic->dw_u_v_adr + dw_uv_size;  //base dw buf addr
+		} else {
+			pic->tw_y_adr = y_adr;	//base no dw buf addr
+		}
+		pic->tw_u_v_adr = pic->tw_y_adr + (mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1));
+	}
+
+#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)) {
+		avs3_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 & AVS3_DBG_BUFMGR) {
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"%s index %d, head_size 0x%08x, MMU header_adr 0x%08x, dw_header_adr 0x%08x; ",
+			__func__, pic->index, get_compress_header_size(dec),
+			pic->header_adr, pic->dw_header_adr);
+
+		avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+			"dw_y_adr 0x%08x, dw_u_v_adr 0x%08x, ",
+			pic->dw_y_adr,
+			pic->dw_u_v_adr);
+
+		avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+			"comp_body_size %x comp_buf_size %x ;",
+			pic->comp_body_size,
+			pic->buf_size);
+		avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+			"mpred_mv_wr_start_adr %d ",
+			pic->mpred_mv_wr_start_addr);
+
+		avs3_print_cont(dec, AVS3_DBG_BUFMGR,
+			"tw y_addr %x, uv_addr %x\n", pic->tw_y_adr, pic->tw_u_v_adr);
+		avs3_print_flush(dec);
+	}
+
+	ret = 0;
+	return ret;
+}
+
+static void init_pic_list(struct AVS3Decoder_s *dec,
+	int32_t lcu_size_log2)
+{
+	int i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *pic;
+#ifdef AVS3_10B_MMU
+	if (dec->mmu_enable) {
+		for (i = 0; i < avs3_dec->max_pb_size; i++) {
+			unsigned long buf_addr;
+			u32 header_size = get_compress_header_size(dec);
+#ifdef AVS3_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) {
+				avs3_print(dec, 0,
+					"%s malloc compress header failed %d\n",
+					DRIVER_HEADER_NAME, i);
+				dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+				return;
+			}
+			if (!vdec_secure(hw_to_vdec(dec)))
+				codec_mm_memset(buf_addr, 0, header_size);
+		}
+	}
+#endif
+	dec->frame_height = avs3_dec->img.height;
+	dec->frame_width = avs3_dec->img.width;
+
+	for (i = 0; i < avs3_dec->max_pb_size; i++) {
+		pic = &avs3_dec->pic_pool[i].buf_cfg;
+		pic->index = i;
+		pic->BUF_index = -1;
+		//pic->mv_buf_index = -1;
+		if (config_pic(dec, pic, lcu_size_log2) < 0) {
+			//if (debug)
+				avs3_print(dec, 0,
+					"Config_pic %d fail\n",
+					pic->index);
+			pic->index = -1;
+			break;
+		}
+		pic->width = avs3_dec->img.width;
+		pic->height = avs3_dec->img.height;
+	}
+	for (; i < avs3_dec->max_pb_size; i++) {
+		pic = &avs3_dec->pic_pool[i].buf_cfg;
+		pic->index = -1;
+		pic->BUF_index = -1;
+		//pic->mv_buf_index = -1;
+	}
+	avs3_print(dec, AVS3_DBG_BUFMGR,
+		"%s ok, max_pb_size = %d\n",
+		__func__, avs3_dec->max_pb_size);
+	dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATE_DONE;
+}
+
+static void init_pic_list_hw(struct AVS3Decoder_s *dec)
+{
+	int i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_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 < avs3_dec->max_pb_size; i++) {
+		pic = &avs3_dec->pic_pool[i].buf_cfg;
+		if (pic->index < 0)
+			break;
+#ifdef AVS3_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 AVS3_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
+	}
+}
+
+#ifdef DEBUG_CMD
+#if 0
+static void d_fill_zero(struct AVS3Decoder_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;
+}
+#endif
+#if 0
+static void d_dump(struct AVS3Decoder_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)
+				avs3_print(hw, 0,
+					"%06x:", jj);
+			avs3_print_cont(hw, 0,
+				"%02x ", data[jj]);
+			if (((jj + 1) & 0xf) == 0)
+				avs3_print_cont(hw, 0,
+					"\n");
+		}
+		avs3_print(hw, 0, "\n");
+	}
+
+	WRITE_VREG(DEBUG_REG1, 0);
+	debug_cmd_wait_type = 0;
+
+}
+
+static void mv_buffer_fill_zero(struct AVS3Decoder_s *hw, struct PIC_BUFFER_CONFIG_s *pic_config)
+{
+	pr_info("fill dummy data pic index %d colocate addresses %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 AVS3Decoder_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 addresses %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
+#endif
+
+static int config_mc_buffer(struct AVS3Decoder_s *dec)
+{
+	int32_t i;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	//avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+	avs3_frame_t *pic;
+	//uint32_t rdata32;
+	//uint32_t rdata32_2;
+	//if (avs3_dec->img.type == I_IMG)
+	//    return 0;
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"Entered config_mc_buffer....\n");
+	if (avs3_dec->f_bg != NULL) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"config_mc_buffer for background (canvas_y %d, canvas_u_v %d)\n",
+		avs3_dec->f_bg->mc_canvas_y, avs3_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,
+		(avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_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,
+		(avs3_dec->f_bg->mc_canvas_u_v<<16)|(avs3_dec->f_bg->mc_canvas_u_v<<8)|avs3_dec->f_bg->mc_canvas_y);
+	}
+	if (avs3_dec->slice_type == SLICE_I)
+		return 0;
+	if (avs3_dec->slice_type == SLICE_P || avs3_dec->slice_type == SLICE_B) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"config_mc_buffer for REF_0, img type %d\n", avs3_dec->slice_type);
+		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (0 << 8) | (0<<1) | 1);
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_0]; i++) {
+		pic = &avs3_dec->ctx.refp[i][REFP_0].pic->buf_cfg;
+		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) {
+				avs3_dec->ctx.pic->buf_cfg.error_mark = 1;
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L0 refid %d pic error\n", __func__, i);
+			}
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"L0 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+		}
+	}
+	if (avs3_dec->slice_type == SLICE_B) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"config_mc_buffer for REF_1\n");
+
+		WRITE_VREG(HEVCD_MPP_ANC_CANVAS_ACCCONFIG_ADDR, (16 << 8) | (0<<1) | 1);
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+			pic = &avs3_dec->ctx.refp[i][REFP_1].pic->buf_cfg;
+			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) {
+				avs3_dec->ctx.pic->buf_cfg.error_mark = 1;
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "%s:L1 refid %d pic error\n", __func__, i);
+			}
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"L1 refid %x mc_canvas_u_v %x mc_canvas_y %x\n", i, pic->mc_canvas_u_v, pic->mc_canvas_y);
+		}
+	}
+	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 & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_DBG_CACHE)
+			pr_info("MCRCC_BYP_RATE : %d\n", hitrate);
+	} else if (debug & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_DBG_CACHE)
+			pr_info("DECOMP_HCACHE_HIT_RATE : %d\n", hitrate);
+	} else {
+		if (debug & AVS3_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 & AVS3_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 & AVS3_DBG_CACHE)
+			pr_info("DECOMP_DCACHE_HIT_RATE : %d\n", hitrate);
+	} else if (debug & AVS3_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 & AVS3_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 & AVS3_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 & AVS3_DBG_CACHE)
+			pr_info("DECOMP_COMP_RATIO : %d\n", comprate);
+	} else if (debug & AVS3_DBG_CACHE) {
+			pr_info("DECOMP_COMP_RATIO : na\n");
+	}
+	return;
+}
+#endif
+
+static void config_mcrcc_axi_hw(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	uint32_t rdata32;
+	uint32_t rdata32_2;
+
+	WRITE_VREG(HEVCD_MCRCC_CTL1, 0x2); // reset mcrcc
+	if (avs3_dec->slice_type == SLICE_I) {
+		WRITE_VREG(HEVCD_MCRCC_CTL1, 0x0); // remove reset -- disables clock
+		return;
+	}
+
+#if 0
+	mcrcc_get_hitrate();
+	decomp_get_hitrate();
+	decomp_get_comprate();
+#endif
+	if ((avs3_dec->slice_type == SLICE_B) || (avs3_dec->slice_type == SLICE_P)) {
+		// 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);
+	}
+
+	WRITE_VREG(HEVCD_MCRCC_CTL1, 0xff0); // enable mcrcc progressive-mode
+	return;
+}
+
+static void config_mpred_hw(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int32_t i;
+	uint32_t data32;
+	avs3_frame_t *cur_pic = avs3_dec->cur_pic;
+	avs3_frame_t *col_pic;
+	//COM_PIC *colPic;
+
+	//int32_t     AMVP_MAX_NUM_CANDS_MEM=3;
+	//int32_t     AMVP_MAX_NUM_CANDS=2;
+	//int32_t     NUM_CHROMA_MODE=5;
+	//int32_t     DM_CHROMA_IDX=36;
+	int32_t     above_ptr_ctrl =0;
+	//int32_t     buffer_linear =1;
+	//int32_t     cu_size_log2 =3;
+	int32_t     mpred_mv_rd_start_addr ;
+	//int32_t     mpred_curr_lcu_x;
+	//int32_t     mpred_curr_lcu_y;
+	//int32_t     mpred_above_buf_start ;
+	//int32_t     mpred_mv_rd_ptr ;
+	//int32_t     mpred_mv_rd_ptr_p1 ;
+	int32_t     mpred_mv_rd_end_addr;
+	int32_t     MV_MEM_UNIT_l;
+	//int32_t     mpred_mv_wr_ptr ;
+
+	int32_t     above_en;
+	int32_t     mv_wr_en;
+	int32_t     mv_rd_en;
+	int32_t     col_isIntra;
+	int32_t     col_ptr;
+
+	if (avs3_dec->slice_type == SLICE_P) {
+		col_pic = &avs3_dec->ctx.refp[0][REFP_0].pic->buf_cfg;
+	}
+	else if (avs3_dec->slice_type == SLICE_B) {
+		col_pic = &avs3_dec->ctx.refp[0][REFP_1].pic->buf_cfg;
+	}
+	else {
+		col_pic = cur_pic;
+	}
+
+	//if (dec->slice_type!=2)
+	if (avs3_dec->slice_type != SLICE_I)
+	{
+		above_en=1;
+		mv_wr_en=1;
+		if (col_pic->slice_type != SLICE_I)
+		mv_rd_en=1;
+		else
+		mv_rd_en=0;
+		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_l=get_mv_mem_unit(avs3_dec->lcu_size_log2);
+
+	mpred_mv_rd_end_addr=mpred_mv_rd_start_addr + ((avs3_dec->lcu_x_num*avs3_dec->lcu_y_num)*MV_MEM_UNIT_l);
+
+	//mpred_above_buf_start = buf_spec->mpred_above.buf_start;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"cur pic index %d  slicetype %d col pic index %d slicetype %d\n",
+		cur_pic->index, cur_pic->slice_type,
+		col_pic->index, col_pic->slice_type);
+
+	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);
+	avs3_print(dec, AVS3_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 =
+	((avs3_dec->bk_img_is_top_field) << 13) |
+	((avs3_dec->hd.background_picture_enable & 1) << 12) |
+		((avs3_dec->hd.curr_RPS.num_of_ref & 7) << 8) |
+		((avs3_dec->hd.b_pmvr_enabled & 1) << 6) |
+		((avs3_dec->img.is_top_field & 1) << 5)  |
+		((avs3_dec->img.is_field_sequence & 1) << 4) |
+		((avs3_dec->img.typeb & 7) << 1) |
+		(avs3_dec->hd.background_reference_enable & 0x1);
+	printk("HEVC_MPRED_CTRL9 <= 0x%x(num of ref %d)\n", data32, avs3_dec->hd.curr_RPS.num_of_ref);
+	WRITE_VREG(HEVC_MPRED_CTRL9, data32);
+	*/
+#if 1
+	/*
+	data32 = ((dec->lcu_x_num - dec->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 &= (~(0x3 | (0xf << 8) | (0xf << 16)));
+	data32  =   (
+		avs3_dec->slice_type |
+		/*dec->new_pic<<2 |
+		dec->new_tile<<3|
+		dec->isNextSliceSegment<<4|
+		dec->TMVPFlag<<5|
+		dec->LDCFlag<<6|
+		dec->ColFromL0Flag<<7|
+	 */
+		above_ptr_ctrl<<8 |
+		above_en<<9|
+		mv_wr_en<<10|
+		mv_rd_en<<11|
+		avs3_dec->lcu_size_log2<<16
+		/*|cu_size_log2<<20*/
+		);
+	WRITE_VREG(HEVC_MPRED_CTRL0,data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"P_HEVC_MPRED_CTRL0=0x%x\n",
+		READ_VREG(HEVC_MPRED_CTRL0));
+
+	data32 = READ_VREG(HEVC_MPRED_CTRL1);
+	data32 &= (~0xf);
+	data32 |= avs3_dec->ctx.info.sqh.num_of_hmvp_cand;
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"write P_HEVC_MPRED_CTRL1=0x%x, avs3_dec->ctx.info.sqh.num_of_hmvp_cand=%d\n",
+		data32, avs3_dec->ctx.info.sqh.num_of_hmvp_cand);
+	WRITE_VREG(HEVC_MPRED_CTRL1,data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"P_HEVC_MPRED_CTRL1=0x%x\n",
+		READ_VREG(HEVC_MPRED_CTRL1));
+
+	data32  =   (
+		avs3_dec->img.width|
+		avs3_dec->img.height<<16
+		);
+	WRITE_VREG(HEVC_MPRED_PIC_SIZE,data32);
+
+	data32  =   (
+		(avs3_dec->lcu_x_num-1)   |
+		(avs3_dec->lcu_y_num-1)<<16
+		);
+	WRITE_VREG(HEVC_MPRED_PIC_SIZE_LCU,data32);
+
+	/*data32  =   (
+		dec->tile_start_lcu_x   |
+		dec->tile_start_lcu_y<<16
+		);
+	WRITE_VREG(HEVC_MPRED_TILE_START,data32);
+	data32  =   (
+		dec->tile_width_lcu   |
+		dec->tile_height_lcu<<16
+		);
+	WRITE_VREG(HEVC_MPRED_TILE_SIZE_LCU,data32);
+	*/
+	data32  =   (
+		avs3_dec->ctx.dpm.num_refp[REFP_0]   |
+		avs3_dec->ctx.dpm.num_refp[REFP_1]<<8|
+		0
+		//col_RefNum_L0<<16|
+		//col_RefNum_L1<<24
+		);
+	WRITE_VREG(HEVC_MPRED_REF_NUM,data32);
+
+	data32=0;
+	for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_0];i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L0,data32);
+
+	data32=0;
+	for (i=0;i<avs3_dec->ctx.dpm.num_refp[REFP_1];i++)data32=data32|(1<<i);
+	WRITE_VREG(HEVC_MPRED_REF_EN_L1,data32);
+#endif
+
+	WRITE_VREG(HEVC_MPRED_CUR_POC, avs3_dec->ctx.ptr & 0xffff);
+	if (avs3_dec->slice_type == SLICE_P) {
+		col_ptr = avs3_dec->ctx.refp[0][REFP_0].ptr;
+		//colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+	}
+	else if (avs3_dec->slice_type == SLICE_B) {
+		col_ptr = avs3_dec->ctx.refp[0][REFP_1].ptr;
+		//colPic = avs3_dec->ctx.refp[0][REFP_0].pic;
+	}
+	else {
+		col_ptr = avs3_dec->ctx.pic->ptr;
+		//colPic = avs3_dec->ctx.pic;
+	}
+	WRITE_VREG(HEVC_MPRED_COL_POC, col_ptr & 0xffff);
+	//below MPRED Ref_POC_xx_Lx registers must follow Ref_POC_xx_L0 -> Ref_POC_xx_L1 in pair write order!!!
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"P_HEVC_MPRED_CUR_POC=0x%x, P_HEVC_MPRED_COL_POC=0x%x\n",
+		READ_VREG(HEVC_MPRED_CUR_POC), READ_VREG(HEVC_MPRED_COL_POC));
+
+	for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+		data32 = 0;
+		if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+		if (i < cur_pic->list0_num_refp) {
+			data32 |= cur_pic->list0_ptr[i] & 0xffff;
+		}
+		if (i < col_pic->list0_num_refp) {
+			data32 |= ((col_pic->list0_ptr[i] & 0xffff) << 16);
+		}
+		}
+		WRITE_VREG(HEVC_MPRED_L0_REF_POC_ADR[i], data32);
+	}
+	if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+		for (i = 0; i < MAX_NUM_REF_PICS; i++) {
+			if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+				if (i < cur_pic->list0_num_refp) {
+					avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+						"[%d] ", cur_pic->list0_ptr[i]);
+				}
+				if (i < col_pic->list0_num_refp) {
+					avs3_print_cont(dec, AVS3_DBG_BUFMGR_DETAIL,
+						"<%d> ", col_pic->list0_ptr[i]);
+				}
+			}
+			if (i < cur_pic->list0_num_refp || i < col_pic->list0_num_refp) {
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"P_HEVC_MPRED_L0_REF=0x%x (readback 0x%x)\n", i,
+					data32, READ_VREG(HEVC_MPRED_L0_REF_POC_ADR[i]));
+			}
+		}
+	}
+	for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+		WRITE_VREG(HEVC_MPRED_L1_REF_POC_ADR[i], avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff);
+	}
+	if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+		for (i = 0; i < avs3_dec->ctx.dpm.num_refp[REFP_1]; i++) {
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"P_HEVC_MPRED_L1_REF%02d_POC=0x%x (readback 0x%x)\n", i, avs3_dec->ctx.refp[i][REFP_1].ptr & 0xffff, READ_VREG(HEVC_MPRED_L1_REF_POC_ADR[i]));
+		}
+	}
+
+#if 0
+	if (dec->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 (!dec->isNextSliceSegment)
+	{
+		//WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr_p1);
+		WRITE_VREG(HEVC_MPRED_MV_RPTR,mpred_mv_rd_ptr);
+	}
+#endif
+	WRITE_VREG(HEVC_MPRED_MV_RD_END_ADDR,mpred_mv_rd_end_addr);
+}
+
+static void config_dblk_hw(struct AVS3Decoder_s *dec)
+{
+	/*
+	* Picture level de-block parameter configuration here
+	*/
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	union param_u *rpm_param = &avs3_dec->param;
+	uint32_t data32;
+	DEC_CTX * ctx = &avs3_dec->ctx;
+	int32_t alpha_c_offset = rpm_param->p.pic_header_alpha_c_offset;
+	int32_t beta_offset = rpm_param->p.pic_header_beta_offset;
+
+	alpha_c_offset = (alpha_c_offset >=16) ? 15 : ((alpha_c_offset < -16) ? -16 : alpha_c_offset);
+	beta_offset = (beta_offset >=16) ? 15 : ((beta_offset < -16) ? -16 : beta_offset);
+
+	data32 = READ_VREG(HEVC_DBLK_CFG1);
+	data32 = (((data32>>20)&0xfff)<<20) |
+		(((ctx->info.bit_depth_internal == 10) ? 0xa:0x0)<<16) |             // [16 +: 4]: {luma_bd[1:0],chroma_bd[1:0]}
+		(((data32>>2)&0x3fff)<<2) |
+		(((ctx->info.log2_max_cuwh == 6) ? 0:(ctx->info.log2_max_cuwh == 5) ? 1:(ctx->info.log2_max_cuwh == 4) ? 2:3)<<0);// [ 0 +: 2]: lcu_size
+	WRITE_VREG(HEVC_DBLK_CFG1, data32);
+
+	data32 = (avs3_dec->img.height<<16) | avs3_dec->img.width;
+	WRITE_VREG(HEVC_DBLK_CFG2, data32);
+
+	data32 = ((rpm_param->p.sqh_cross_patch_loop_filter & 0x1)<<27) |// [27 +: 1]: cross_slice_loopfilter_enable_flag
+		((rpm_param->p.pic_header_loop_filter_disable_flag & 0x1)<<26) |               // [26 +: 1]: loop_filter_disable
+		((alpha_c_offset&0x1f) <<17) |                    // [17 +: 5]: alpha_c_offset (-8~8)
+		((beta_offset&0x1f) <<12) |                       // [12 +: 5]: beta_offset (-8~8)
+		((rpm_param->p.pic_header_chroma_quant_param_delta_cb&0x3f)<<6) |         // [ 6 +: 6]: chroma_quant_param_delta_u (-16~16)
+		((rpm_param->p.pic_header_chroma_quant_param_delta_cr&0x3f)<<0);          // [ 0 +: 6]: chroma_quant_param_delta_v (-16~16)
+	WRITE_VREG(HEVC_DBLK_CFG9, data32);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: crossslice(%d),lfdisable(%d),bitDepth(%d,%d),log2_lcuSize(%d)\n",
+			rpm_param->p.sqh_cross_patch_loop_filter,rpm_param->p.pic_header_loop_filter_disable_flag,
+			ctx->info.bit_depth_input,ctx->info.bit_depth_internal,ctx->info.log2_max_cuwh);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: alphaCOffset(%d crop to %d),betaOffset(%d crop to %d),quantDeltaCb(%d),quantDeltaCr(%d)\n",
+			rpm_param->p.pic_header_alpha_c_offset, alpha_c_offset,rpm_param->p.pic_header_beta_offset, beta_offset,
+			rpm_param->p.pic_header_chroma_quant_param_delta_cb,rpm_param->p.pic_header_chroma_quant_param_delta_cr);
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgDBLK: .done.\n");
+
+}
+
+static void config_dw(struct AVS3Decoder_s *dec, struct avs3_frame_s *pic,
+		u32 mc_buffer_size_u_v_h)
+{
+
+	int dw_mode = get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+	int tw_mode = get_triple_write_mode(dec);
+#endif
+	uint32_t data32;
+
+	if ((dw_mode & 0x10) == 0) {
+		WRITE_VREG(HEVC_SAO_CTRL26, 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 (dec->mem_saving_mode == 1)
+				data32 |= (1 << 9);
+			else*/
+			data32 &= ~(1 << 9);
+			/*if (workaround_enable & 1)
+				data32 |= (1 << 7);*/
+			WRITE_VREG(HEVC_SAO_CTRL5, data32);
+		}
+	}
+
+	/* 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);
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_mmu_enable == 0)
+		data32 |= ((dec->endian >> 8) & 0xfff); /* endian: ((0x880 << 8) | 0x8) or ((0xff0 << 8) | 0xf) */
+#else
+	data32 |= ((dec->endian >> 8) & 0xfff); /* data32 |= 0x670; Big-Endian per 64-bit */
+#endif
+
+	data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
+	if (dw_mode == 0)
+		data32 |= 0x2; /*disable double write*/
+	else if (dw_mode & 0x10)
+		data32 |= 0x1; /*disable cm*/
+
+	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);
+
+	data32 = READ_VREG(HEVC_DBLK_CFGB);
+	data32 &= (~0x300); /*[8]:first write enable (compress)
+			[9]:double write enable (uncompress)*/
+	if (dw_mode == 0)
+		data32 |= (0x1 << 8); /*enable first write*/
+	else if (dw_mode == 0x10)
+		data32 |= (0x1 << 9); /*double write only*/
+	else
+		data32 |= ((0x1 << 8) | (0x1 << 9));
+	WRITE_VREG(HEVC_DBLK_CFGB, data32);
+
+	if (dw_mode & 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);
+	}
+
+#ifdef P010_ENABLE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+		data32 = READ_VREG(HEVC_SAO_CTRL3);
+		if (is_dw_p010(dec)) {
+			data32 |= (1 << 1);  /* enable double write p010 */
+		} else {
+			data32 &= ~(1 << 1);
+		}
+		WRITE_VREG(HEVC_SAO_CTRL3, data32);
+	}
+#endif
+#ifdef OW_TRIPLE_WRITE
+	if (tw_mode) {
+		data32 = READ_VREG(HEVC_SAO_CTRL31);
+		data32 &= ~0xfff;
+		if ((tw_mode == 2) || (tw_mode == 3)) {
+			data32 |= ((0xf << 6) | 0xf);	//1:4
+		} else if ((tw_mode == 4) || (tw_mode == 5)) {
+			data32 |= ((0x3 << 6) | 0x3);	//1:2
+		} else if ((tw_mode == 8) || (tw_mode == 9)) {
+			data32 |= ((0x3f << 6) | 0x3f);
+		}
+		WRITE_VREG(HEVC_SAO_CTRL31, data32);
+
+		data32 = READ_VREG(HEVC_SAO_CTRL32);
+		data32 &= (~0xfff); /* clr endian, blkmod and align */
+		data32 |= ((dec->endian >> 12) & 0xff);
+		data32 |= ((mem_map_mode & 0x3) << 8);
+		/* Linear_LineAlignment 00:16byte 01:32byte 10:64byte */
+		data32 |= (2 << 10);
+		WRITE_VREG(HEVC_SAO_CTRL32, data32);
+
+		data32 = READ_VREG(HEVC_SAO_CTRL3);
+		data32 |= (1 << 2);  /* enable triple write */
+#ifdef P010_ENABLE
+		if (is_tw_p010(dec)) {
+			data32 |= (1 << 3);  /* enable triple write p010 */
+		} else {
+			data32 &= ~(1 << 3);
+		}
+#endif
+		WRITE_VREG(HEVC_SAO_CTRL3, data32);
+
+		if (debug & AVS3_DBG_REG) {
+			avs3_print(dec, 0, "%s, HEVC_SAO_CTRL3 %x, HEVC_SAO_CTRL31 %x, HEVC_SAO_CTRL32 %x\n",
+				__func__, READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL31), READ_VREG(HEVC_SAO_CTRL32));
+		}
+	}
+#endif
+
+#ifdef LOSLESS_COMPRESS_MODE
+/*SUPPORT_10BIT*/
+
+	data32 = pic->mc_y_adr;
+	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+		WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_VREG(HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_VREG(HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	if ((dw_mode & 0x10) == 0)
+		WRITE_VREG(HEVC_CM_BODY_START_ADDR, data32);
+#ifdef OW_TRIPLE_WRITE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T3X) {
+		if (tw_mode) {
+			WRITE_VREG(HEVC_SAO_Y_START_ADDR3, pic->tw_y_adr);
+			WRITE_VREG(HEVC_SAO_C_START_ADDR3, pic->tw_u_v_adr);
+		} else {
+			WRITE_VREG(HEVC_SAO_Y_START_ADDR3, 0xffffffff);
+			WRITE_VREG(HEVC_SAO_C_START_ADDR3, 0xffffffff);
+		}
+	}
+#endif
+
+	if (dec->mmu_enable)
+		WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+#ifdef AVS3_10B_MMU_DW
+	if (dec->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, pic->dw_header_adr);
+	}
+#endif
+#else
+	WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+	WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->mc_u_v_adr);
+	WRITE_VREG(HEVC_SAO_Y_WPTR, pic->mc_y_adr);
+	WRITE_VREG(HEVC_SAO_C_WPTR, pic->mc_u_v_adr);
+#endif
+	data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec) + 1);
+	WRITE_VREG(HEVC_SAO_Y_LENGTH, data32);
+
+	data32 = mc_buffer_size_u_v_h << (16 + is_dw_p010(dec));
+	WRITE_VREG(HEVC_SAO_C_LENGTH, data32);
+
+	if (tw_mode) {
+		data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec) + 1);
+		WRITE_VREG(HEVC_SAO_Y_LENGTH3, data32);
+		data32 = mc_buffer_size_u_v_h << (16 + is_tw_p010(dec));
+		WRITE_VREG(HEVC_SAO_C_LENGTH3, data32);
+
+		if (debug & AVS3_DBG_REG) {
+			avs3_print(dec, 0, "triple write SAO_Y_ADDR3 %x, SAO_Y_LENGTH3 %x, SAO_C_ADDR3 %x, SAO_C_LENGTH3 %x\n",
+				READ_VREG(HEVC_SAO_Y_START_ADDR3), READ_VREG(HEVC_SAO_Y_LENGTH3),
+				READ_VREG(HEVC_SAO_C_START_ADDR3), READ_VREG(HEVC_SAO_C_LENGTH3));
+		}
+	}
+}
+
+static void config_sao_hw(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_frame_t *pic = avs3_dec->cur_pic;
+	//union param_u* params = &avs3_dec->param;
+	uint32_t data32;
+	int32_t pic_width = avs3_dec->img.width;
+	int32_t pic_height = avs3_dec->img.height;
+	int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+	int32_t lcu_size = 1<<lcu_size_log2;
+	int32_t pic_width_lcu  = ( pic_width % lcu_size  ) ? pic_width /lcu_size + 1 : pic_width /lcu_size;
+	int32_t pic_height_lcu = ( pic_height % lcu_size ) ? pic_height/lcu_size + 1 : pic_height/lcu_size;
+	int32_t lcu_total = pic_width_lcu*pic_height_lcu;
+	int32_t mc_buffer_size_u_v = lcu_total*lcu_size*lcu_size/2;
+	int32_t mc_buffer_size_u_v_h = (mc_buffer_size_u_v + 0xffff)>>16; //64k alignment
+
+	config_dw(dec, pic, mc_buffer_size_u_v_h);
+	data32 = READ_VREG(HEVC_SAO_CTRL0);
+	data32 &= (~0xf);
+	data32 |= avs3_dec->lcu_size_log2;
+	WRITE_VREG(HEVC_SAO_CTRL0, data32);
+#if 0
+#ifdef LOSLESS_COMPRESS_MODE
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+
+	if ((get_double_write_mode(dec) & 0x10) == 0)
+		WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+	if ((get_double_write_mode(dec) & 0x20) == 0) {
+		WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->dw_y_adr);
+		WRITE_VREG(HEVC_SAO_C_START_ADDR, pic->dw_u_v_adr);
+		WRITE_VREG(HEVC_SAO_Y_WPTR, pic->dw_y_adr);
+		WRITE_VREG(HEVC_SAO_C_WPTR, pic->dw_u_v_adr);
+	} else {
+		WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0xffffffff);
+		WRITE_VREG(HEVC_SAO_C_START_ADDR, 0xffffffff);
+	}
+	WRITE_VREG(HEVC_CM_HEADER_START_ADDR, pic->header_adr);
+	if (dec->dw_mmu_enable) {
+		WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->dw_header_adr);
+		WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
+		WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
+	}
+
+	//WRITE_VREG(HEVC_SAO_Y_START_ADDR, DOUBLE_WRITE_YSTART_TEMP);
+	//WRITE_VREG(HEVC_CM_BODY_START_ADDR, pic->mc_y_adr);
+#ifdef AVS3_10B_MMU
+	//WRITE_VREG(HEVC_CM_HEADER_START_ADDR, avs3_dec->cm_header_start + (pic->index * get_compress_header_size(dec)));
+#endif
+#ifdef AVS3_10B_MMU_DW
+	//if (dec->dw_mmu_enable) {
+	//    WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, pic->header_dw_adr);
+	//}
+#endif
+
+#else
+	WRITE_VREG(HEVC_SAO_Y_START_ADDR, pic->mc_y_adr);
+#endif
+
+	data32 = (mc_buffer_size_u_v_h<<16)<<1;
+	WRITE_VREG(HEVC_SAO_Y_LENGTH ,data32);
+
+	//WRITE_VREG(HEVC_SAO_C_START_ADDR,DOUBLE_WRITE_CSTART_TEMP);
+
+	data32 = (mc_buffer_size_u_v_h<<16);
+	WRITE_VREG(HEVC_SAO_C_LENGTH  ,data32);
+	//WRITE_VREG(HEVC_SAO_Y_WPTR ,DOUBLE_WRITE_YSTART_TEMP);
+	//WRITE_VREG(HEVC_SAO_C_WPTR ,DOUBLE_WRITE_CSTART_TEMP);
+#endif
+
+#ifdef AVS3_10B_NV21
+	data32 = READ_VREG(HEVC_SAO_CTRL1);
+	data32 &= (~0x3000);
+	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);
+
+	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 H265_NV21 (no down-scale)
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+	data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
+	data32 &= (~0x30);
+	data32 |= (MEM_MAP_MODE << 4); // [5:4]    -- address_format 00:linear 01:32x32 10:64x32
+	WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
+#endif
+
+#ifndef AVS3_10B_NV21
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		WRITE_VREG(HEVC_DW_VH0_ADDDR, DOUBLE_WRITE_VH0_TEMP);
+		WRITE_VREG(HEVC_DW_VH1_ADDDR, DOUBLE_WRITE_VH1_TEMP);
+	}
+#endif
+#endif
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgSAO .done.\n");
+}
+
+static void config_alf_hw(struct AVS3Decoder_s *dec)
+{
+	/*
+	* Picture level ALF parameter configuration here
+	*/
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	uint32_t data32;
+	int32_t i,j;
+	int32_t m_filters_per_group;
+#ifdef USE_FORCED_ALF_PARAM
+	ALFParam forced_alf_cr;
+	forced_alf_cr.alf_flag = 1;
+	forced_alf_cr.num_coeff = 9;
+	forced_alf_cr.filters_per_group = 1;
+	forced_alf_cr.component_id = 2;
+	forced_alf_cr.coeff_multi[0][0] = -3;
+	forced_alf_cr.coeff_multi[0][1] = -3;
+	forced_alf_cr.coeff_multi[0][2] = 4;
+	forced_alf_cr.coeff_multi[0][3] = 7;
+	forced_alf_cr.coeff_multi[0][4] = 6;
+	forced_alf_cr.coeff_multi[0][5] = -1;
+	forced_alf_cr.coeff_multi[0][6] = 3;
+	forced_alf_cr.coeff_multi[0][7] = 6;
+	forced_alf_cr.coeff_multi[0][8] = 0;
+#endif
+
+	ALFParam *m_alfPictureParam_y = &avs3_dec->m_alfPictureParam[0];
+	ALFParam *m_alfPictureParam_cb = &avs3_dec->m_alfPictureParam[1];
+#ifdef USE_FORCED_ALF_PARAM
+	ALFParam *m_alfPictureParam_cr = &forced_alf_cr; // &avs3_dec->m_alfPictureParam[2];
+#else
+	ALFParam *m_alfPictureParam_cr = &avs3_dec->m_alfPictureParam[2];
+#endif
+
+	printf("[t]alfy,cidx(%d),flag(%d),filters_per_group(%d),filter_pattern[0]=0x%x,[15]=0x%x\n",
+			m_alfPictureParam_y->component_id,
+			m_alfPictureParam_y->alf_flag,
+			m_alfPictureParam_y->filters_per_group,
+			m_alfPictureParam_y->filter_pattern[0],m_alfPictureParam_y->filter_pattern[15]);
+	printf("[t]alfy,num_coeff(%d),coeff_multi[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->coeff_multi[0][0],
+			m_alfPictureParam_y->coeff_multi[0][1],
+			m_alfPictureParam_y->coeff_multi[1][0],
+			m_alfPictureParam_y->coeff_multi[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);
+	avs3_print(dec, AVS3_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);
+	avs3_print(dec, AVS3_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);
+	avs3_print(dec, AVS3_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 = ((i == m_filters_per_group-1) << 31) | // [31] last indication
+			((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);
+		avs3_print(dec, AVS3_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]);
+	}
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"[c] cfgALF .done.\n");
+}
+
+static u32 init_cuva_size;
+
+static int cuva_data_is_available(struct AVS3Decoder_s *dec, u32 reg_val)
+{
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"%s:reg_val: %u \n",
+		__func__, reg_val);
+	if (reg_val != 0 && reg_val != init_cuva_size)
+		return 1;
+	else
+		return 0;
+}
+
+void config_cuva_buf(struct AVS3Decoder_s *dec)
+{
+	WRITE_VREG(AVS3_CUVA_ADR, dec->cuva_phy_addr);
+	init_cuva_size = (dec->cuva_size >> 4) << 16;
+	WRITE_VREG(AVS3_CUVA_DATA_SIZE, init_cuva_size);
+}
+
+static void set_cuva_data(struct AVS3Decoder_s *dec)
+{
+	int i;
+	unsigned short *cuva_adr;
+	unsigned int size_reg_val =
+		READ_VREG(AVS3_CUVA_DATA_SIZE);
+	unsigned int cuva_count = 0;
+	int cuva_size = 0;
+	struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+	if (pic == NULL || 0 == cuva_data_is_available(dec, size_reg_val)) {
+		avs3_print(dec, AVS3_DBG_HDR_INFO,
+		"%s:pic 0x%p or data not available\n",
+		__func__, pic);
+		return;
+	}
+
+	cuva_adr = (unsigned short *)dec->cuva_addr;
+	cuva_count = ((size_reg_val >> 16) << 4) >> 1;
+	cuva_size = dec->cuva_size;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"%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) {
+		if (pic->cuva_data_buf) {
+			unsigned char *p = pic->cuva_data_buf;
+			int len = 0;
+
+			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;
+			}
+
+			if (pic->cuva_data_buf[0] == 0x26
+				&& pic->cuva_data_buf[1] == 0x00
+				&& pic->cuva_data_buf[2] == 0x04
+				&& pic->cuva_data_buf[3] == 0x00
+				&& pic->cuva_data_buf[4] == 0x05) {
+				dec->hdr_flag |= HDR_CUVA_MASK;
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"cuva stream: (size %d)\n", pic->cuva_data_size);
+			} else {
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					" other hdr stream (size %d)\n", pic->cuva_data_size);
+			}
+
+			if (get_dbg_flag(dec) & AVS3_DBG_HDR_INFO) {
+				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 {
+			avs3_print(dec, 0, "cuva_data_buf NULL\n");
+		}
+	}
+}
+
+static void release_cuva_data(struct avs3_frame_s *pic)
+{
+	pic->cuva_data_size = 0;
+}
+
+static void avs3_config_work_space_hw(struct AVS3Decoder_s *dec)
+{
+	DEC_CTX * ctx = &dec->avs3_dec.ctx;
+	struct BuffInfo_s *buf_spec = dec->work_space_buf;
+	u32 width = dec->avs3_dec.img.width ? dec->avs3_dec.img.width : dec->init_pic_w;
+	u32 height = dec->avs3_dec.img.height ? dec->avs3_dec.img.height : dec->init_pic_h;
+	u8 is_bit_depth_10 = (ctx->info.bit_depth_internal == 8) ? 0 : 1;
+
+#ifdef LOSLESS_COMPRESS_MODE
+	int losless_comp_header_size = compute_losless_comp_header_size(
+		dec, width, height);
+	int losless_comp_body_size = compute_losless_comp_body_size(
+		dec, width, height, is_bit_depth_10);
+#endif
+#ifdef AVS3_10B_MMU
+	unsigned int data32;
+#endif
+	if (debug && dec->init_flag == 0)
+		avs3_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 & AVS3_DBG_SEND_PARAM_WITH_REG) == 0)
+		WRITE_VREG(HEVC_RPM_BUFFER, (u32)dec->rpm_phy_addr);
+	WRITE_VREG(AVS3_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(AVS3_SBAC_TOP_BUFFER, buf_spec->sbac_top.buf_start);
+	//WRITE_VREG(HEVC_SAO_UP, buf_spec->sao_up.buf_start);
+#ifdef AVS3_10B_MMU
+	WRITE_VREG(AVS3_MMU_MAP_BUFFER, dec->frame_mmu_map_phy_addr);
+#else
+	WRITE_VREG(HEVC_STREAM_SWAP_BUFFER, buf_spec->swap_buf.buf_start);
+#endif
+#ifdef AVS3_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);
+#ifndef FOR_S5
+	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]
+		avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+			"HEVC_DBLK_CFG3 = %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);
+
+#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 AVS3_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
+#ifdef P010_ENABLE
+	if (get_double_write_mode(dec) & 0x10) {
+		if (is_dw_p010(dec)) {
+			/* Enable P010 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1,
+				(0x1 << 31) | (1 << 24) | (((dec->endian >> 12) & 0xff) << 16));
+		} else {
+			/* Enable NV21 reference read mode for MC */
+			WRITE_VREG(HEVCD_MPP_DECOMP_CTL1, 0x1 << 31);
+		}
+	}
+#endif
+#endif
+
+#ifdef AVS3_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 0
+	if (debug & AVS3_DBG_FORCE_UNCOMPRESS)
+		data32 |= 0x80;
+#endif
+	WRITE_VREG(HEVC_SAO_CTRL5, data32);
+
+#endif
+
+#ifdef AVS3_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);
+
+	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
+	data32 = READ_VREG(HEVC_MPRED_CTRL4);
+	data32 |=  (1<<26); //enable AVS3 mode
+	WRITE_VREG(HEVC_MPRED_CTRL4, data32);
+}
+
+static void decomp_perfcount_reset(void)
+{
+	if (debug & AVS3_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 & AVS3_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;
+}
+
+#ifdef TMP_DEBUG
+
+static void avs2_init_decoder_hw(struct AVS3Decoder_s *dec)
+{
+	unsigned int data32;
+	unsigned int decode_mode;
+	int i;
+
+	data32 = READ_VREG(HEVC_PARSER_INT_CONTROL);
+
+	/* set bit 31~29 to 3 if HEVC_STREAM_FIFO_CTL[29] is 1 */
+	data32 &= ~(7 << 29);
+	data32 |= (3 << 29);
+
+	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;
+	dec->start_decoding_flag = 3;
+	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);
+#ifdef DYN_CACHE
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+		WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc
+	}
+#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 << 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
+
+	return;
+}
+
+#else
+static
+#endif
+void avs3_init_decoder_hw(struct AVS3Decoder_s *dec)
+{
+	unsigned int data32;
+	unsigned int decode_mode;
+	int i;
+	/*if (debug & AVS3_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 AVS3)*/
+		(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 {
+		if ((debug & AVS3_DBG_DISABLE_IQIT_SCALELUT_INIT) == 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);
+#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->avs3_dec.bufmgr_error_flag &&
+		(error_handle_policy & 0x1)) {
+		dec->bufmgr_error_count++;
+		dec->avs3_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 avs3_decoder *avs3_dec = &dec->avs3_dec;
+			dec->start_decoding_flag = 0;
+			//avs3_dec->hd.vec_flag = 1;
+			dec->skip_PB_before_I = 1;
+			avs3_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;
+		}
+	}
+#ifdef FOR_S5
+	/*to do..*/
+	dec->start_decoding_flag = 3;
+#endif
+	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);
+#ifdef DYN_CACHE
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL, "HEVC DYN MCRCC\n");
+		WRITE_VREG(HEVCD_IPP_DYN_CACHE,0x2b);//enable new mcrcc}
+	}
+#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 << 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*/
+	);
+
+#if 0 //def 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)
+	);
+	*/
+
+	/*AVS3 default seq_wq_matrix config*/
+
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"Config AVS3 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
+/*AVS3_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 |= (5 << 0);
+	/* [3:0] cfg_video_type -> AVS3*/
+#ifndef FOR_S5
+	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));
+#endif
+	WRITE_VREG(HEVC_DBLK_CFGB, data32);
+
+	WRITE_VREG(HEVC_DBLK_CFG0, (1<<18) | (1 << 0)); /* [0] rst_sync*/
+	avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+		"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_avs3_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 struct AVS3Decoder_s gAVS3Decoder;
+
+static void avs3_local_uninit(struct AVS3Decoder_s *dec)
+{
+	dec->rpm_ptr = NULL;
+	dec->lmem_ptr = NULL;
+	if (dec->rpm_addr) {
+		decoder_dma_free_coherent(dec->rpm_mem_handle,
+						RPM_BUF_SIZE, dec->rpm_addr,
+						dec->rpm_phy_addr);
+		dec->rpm_addr = NULL;
+	}
+
+	if (dec->cuva_addr) {
+		decoder_dma_free_coherent(dec->cuva_handle,
+				dec->cuva_size, dec->cuva_addr,
+					dec->cuva_phy_addr);
+		dec->cuva_addr = NULL;
+	}
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+	if (dec->ucode_log_addr) {
+		decoder_dma_free_coherent(dec->ucode_log_handle,
+				UCODE_LOG_BUF_SIZE, dec->ucode_log_addr,
+					dec->ucode_log_phy_addr);
+		dec->ucode_log_addr = NULL;
+	}
+#endif
+	if (dec->lmem_addr) {
+			if (dec->lmem_phy_addr)
+				decoder_dma_free_coherent(dec->lmem_phy_handle,
+						LMEM_BUF_SIZE, dec->lmem_addr,
+						dec->lmem_phy_addr);
+		dec->lmem_addr = NULL;
+	}
+
+#ifdef AVS3_10B_MMU
+	if (dec->frame_mmu_map_addr) {
+		if (dec->frame_mmu_map_phy_addr)
+			decoder_dma_free_coherent(dec->frame_mmu_map_handle,
+				get_frame_mmu_map_size(), dec->frame_mmu_map_addr,
+					dec->frame_mmu_map_phy_addr);
+		dec->frame_mmu_map_addr = NULL;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (dec->frame_mmu_map_phy_addr_1)
+			decoder_dma_free_coherent(dec->frame_mmu_map_handle_1,
+				get_frame_mmu_map_size(), dec->frame_mmu_map_addr_1,
+					dec->frame_mmu_map_phy_addr_1);
+
+		dec->frame_mmu_map_addr_1 = NULL;
+	}
+#endif
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_frame_mmu_map_addr) {
+		if (dec->dw_frame_mmu_map_phy_addr)
+			decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle,
+				get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr,
+					dec->dw_frame_mmu_map_phy_addr);
+		dec->dw_frame_mmu_map_addr = NULL;
+	}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode && dec->dw_frame_mmu_map_addr_1) {
+			if (dec->dw_frame_mmu_map_phy_addr_1)
+				decoder_dma_free_coherent(dec->frame_dw_mmu_map_handle_1,
+					get_frame_mmu_map_size(), dec->dw_frame_mmu_map_addr_1,
+						dec->dw_frame_mmu_map_phy_addr_1);
+
+			dec->dw_frame_mmu_map_addr_1 = NULL;
+		}
+#endif
+#endif
+
+	if (dec->gvs)
+		vfree(dec->gvs);
+	dec->gvs = NULL;
+}
+
+static int avs3_local_init(struct AVS3Decoder_s *dec)
+{
+	int ret = -1;
+	/*int losless_comp_header_size, losless_comp_body_size;*/
+
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct BuffInfo_s *cur_buf_info = NULL;
+	unsigned bufspec_index = 0;
+	cur_buf_info = &dec->work_space_buf_store;
+	if (force_bufspec) {
+		bufspec_index = force_bufspec & 0xf;
+		pr_info("force buffer spec %d\n", force_bufspec & 0xf);
+	} else {
+		if (vdec_is_support_4k()) {
+			bufspec_index = 2;	/* 8k */
+		} else
+			bufspec_index = 0;/* 1080p */
+	}
+	pr_info("buffer spec %d\n", bufspec_index);
+	memcpy(cur_buf_info, &amvavs3_workbuff_spec[bufspec_index],
+		sizeof(struct BuffInfo_s));
+
+	cur_buf_info->start_adr = dec->buf_start;
+#ifndef AVS3_10B_MMU
+	dec->mc_buf_spec.buf_end = dec->buf_start + dec->buf_size;
+#endif
+
+	init_buff_spec(dec, cur_buf_info);
+
+	avs3_bufmgr_init(&dec->avs3_dec);
+	//init_avs3_decoder(&dec->avs3_dec);
+
+#ifdef AVS3_10B_MMU
+	avs3_dec_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);
+	}
+	avs3_dec_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;
+		}
+	}
+
+	dec->init_pic_w = buf_alloc_width ? buf_alloc_width :
+		(dec->vavs3_amstream_dec_info.width ?
+		dec->vavs3_amstream_dec_info.width :
+		dec->work_space_buf->max_width);
+	dec->init_pic_h = buf_alloc_height ? buf_alloc_height :
+		(dec->vavs3_amstream_dec_info.height ?
+		dec->vavs3_amstream_dec_info.height :
+		dec->work_space_buf->max_height);
+
+	pr_info(
+		"init_pic_w %d init_pic_h %d\n", dec->init_pic_w, dec->init_pic_h);
+
+#ifndef AVS3_10B_MMU
+	init_buf_list(dec);
+#else
+	dec->avs3_dec.max_pb_size = max_buf_num + dec->dynamic_buf_margin;
+	if (dec->avs3_dec.max_pb_size > MAX_PB_SIZE)
+		dec->avs3_dec.max_pb_size = MAX_PB_SIZE;
+#endif
+	//dec->avs3_dec.ref_maxbuffer = MAX_PB_SIZE; //dec->used_buf_num - 1;
+	/*init_pic_list(dec);*/
+
+	pts_unstable = ((unsigned long)(dec->vavs3_amstream_dec_info.param)
+			& 0x40) >> 6;
+
+	if ((debug & AVS3_DBG_SEND_PARAM_WITH_REG) == 0) {
+		dec->rpm_addr = decoder_dma_alloc_coherent(&dec->rpm_mem_handle,
+			RPM_BUF_SIZE,
+			&dec->rpm_phy_addr, "AVS3_RPM_BUF");
+		if (dec->rpm_addr == NULL) {
+			pr_err("%s: failed to alloc rpm buffer\n", __func__);
+			return -1;
+		}
+		avs3_print(dec, AVS3_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 = decoder_dma_alloc_coherent(&dec->cuva_handle,
+				dec->cuva_size, &dec->cuva_phy_addr, "AVS3_CUVA_BUF");
+			avs3_print(dec, AVS3_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;
+		}
+	}
+#if (defined DEBUG_UCODE_LOG) || (defined DEBUG_CMD)
+	//if (udebug_flag & 0x8) {
+		dec->ucode_log_addr = decoder_dma_alloc_coherent(&dec->ucode_log_handle,
+				UCODE_LOG_BUF_SIZE, &dec->ucode_log_phy_addr, "AVS3_UCODE_LOG_BUF");
+		if (dec->ucode_log_addr == NULL) {
+			dec->ucode_log_phy_addr = 0;
+		}
+		pr_info("%s: alloc ucode log buffer %p\n",
+			__func__, dec->ucode_log_addr);
+	//}
+#endif
+	dec->lmem_addr = decoder_dma_alloc_coherent(&dec->lmem_phy_handle,
+			LMEM_BUF_SIZE,
+			&dec->lmem_phy_addr, "AVS3_LMEM_BUF");
+	if (dec->lmem_addr == NULL) {
+		pr_err("%s: failed to alloc lmem buffer\n", __func__);
+		return -1;
+	} else
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"%s, lmem_phy_addr %x\n",
+			__func__, (u32)dec->lmem_phy_addr);
+	dec->lmem_ptr = dec->lmem_addr;
+
+#ifdef AVS3_10B_MMU
+	if (dec->mmu_enable) {
+		dec->frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle,
+					get_frame_mmu_map_size(),
+					&dec->frame_mmu_map_phy_addr, "AVS3_MMU_BUF");
+		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());
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode && dec->frame_mmu_map_addr_1 == NULL) {
+			dec->frame_mmu_map_addr_1 =
+				decoder_dma_alloc_coherent(&dec->frame_mmu_map_handle_1,
+				get_frame_mmu_map_size(),
+				&dec->frame_mmu_map_phy_addr_1, "AVS3_MMU_1_BUF");
+			if (dec->frame_mmu_map_addr_1 == NULL) {
+				pr_err("%s: failed to alloc count_buffer\n", __func__);
+				return -1;
+			}
+			memset(dec->frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+		}
+#endif
+	}
+#endif
+
+#ifdef AVS3_10B_MMU_DW
+	if (dec->dw_mmu_enable) {
+		dec->dw_frame_mmu_map_addr = decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle,
+					get_frame_mmu_map_size(),
+					&dec->dw_frame_mmu_map_phy_addr, "AVS3_DWMMU_BUF");
+		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());
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->dw_frame_mmu_map_addr_1 =
+					decoder_dma_alloc_coherent(&dec->frame_dw_mmu_map_handle_1,
+					get_frame_mmu_map_size(),
+					&dec->dw_frame_mmu_map_phy_addr_1, "AVS3_DWMMU_1_BUF");
+			if (dec->dw_frame_mmu_map_addr_1 == NULL) {
+				pr_err("%s: failed to alloc count_buffer\n", __func__);
+				return -1;
+			}
+			memset(dec->dw_frame_mmu_map_addr_1, 0, get_frame_mmu_map_size());
+		}
+#endif
+	}
+#endif
+#ifdef NEW_FB_CODE
+	avs3_dec->wait_working_buf = 0;
+	avs3_dec->front_pause_flag = 0; /*multi pictures in one packe*/
+	if (dec->front_back_mode) {
+		avs3_dec->frontend_decoded_count = 0;
+		avs3_dec->backend_decoded_count = 0;
+		avs3_dec->fb_wr_pos = 0;
+		avs3_dec->fb_rd_pos = 0;
+		init_fb_bufstate(dec);
+		if (fbdebug_flag & 0x4) {
+			copy_loopbufs_ptr(&avs3_dec->init_fr, &avs3_dec->fr);
+		}
+		avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"copy loopbuf fr to next_bk[fb_wr_pos=%d]\n",avs3_dec->fb_wr_pos);
+		copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+	}
+#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 AVS3Decoder_s *dec,
+	struct avs3_frame_s *pic)
+{
+	int canvas_w = ALIGN(pic->width, 64)/4;
+	int canvas_h = ALIGN(pic->height, 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->width /
+			get_double_write_ratio(pic->double_write_mode);
+		canvas_h = pic->height /
+			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[0].bit_depth = is_dw_p010(dec);
+
+		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;
+		pic->canvas_config[1].bit_depth = is_dw_p010(dec);
+
+		decoder_trace(dec->trace.set_canvas0_addr, pic->canvas_config[0].phy_addr, TRACE_BUFFER);
+#endif
+	} else {
+	#ifndef AVS3_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);
+
+		decoder_trace(dec->trace.set_canvas0_addr, spec2canvas(pic), TRACE_BUFFER);
+	#endif
+	}
+
+#ifdef OW_TRIPLE_WRITE
+	if (pic->triple_write_mode) {
+		canvas_w = pic->width /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);	//same ratio with double write
+		canvas_h = pic->height /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);
+
+		canvas_w = ALIGN(canvas_w, 64);
+		canvas_h = ALIGN(canvas_h, 32);
+
+#if 0
+		if (vdec->parallel_dec == 1) {
+			if (pic->tw_y_canvas_index == -1)
+				pic->tw_y_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+			if (pic->tw_uv_canvas_index == -1)
+				pic->tw_uv_canvas_index = vdec->get_canvas_ex(CORE_MASK_HEVC, vdec->id);
+		} else {
+			pic->tw_y_canvas_index = 128 + pic->index * 2;
+			pic->tw_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, 7, VDEC_HEVC);
+		config_cav_lut_ex(pic->uv_canvas_index, pic->dw_u_v_adr,
+			canvas_w, canvas_h,
+			CANVAS_ADDR_NOWRAP, blkmode, 7, VDEC_HEVC);
+#endif
+		pic->tw_canvas_config[0].phy_addr = pic->tw_y_adr;
+		pic->tw_canvas_config[0].width = canvas_w;
+		pic->tw_canvas_config[0].height = canvas_h;
+		pic->tw_canvas_config[0].block_mode = blkmode;
+		pic->tw_canvas_config[0].endian = 7;
+		pic->tw_canvas_config[0].bit_depth = is_tw_p010(dec);
+
+		pic->tw_canvas_config[1].phy_addr = pic->tw_u_v_adr;
+		pic->tw_canvas_config[1].width = canvas_w;
+		pic->tw_canvas_config[1].height = canvas_h;
+		pic->tw_canvas_config[1].block_mode = blkmode;
+		pic->tw_canvas_config[1].endian = 7;
+		pic->tw_canvas_config[1].bit_depth = is_tw_p010(dec);
+	}
+#endif
+}
+
+static void set_frame_info(struct AVS3Decoder_s *dec, struct vframe_s *vf)
+{
+	unsigned int ar = 0;
+	unsigned int pixel_ratio = 0;;
+
+	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;
+
+	avs3_print(dec, AVS3_DBG_HDR_INFO,
+			"signal_type 0x%x \n",
+			vf->signal_type);
+
+	pixel_ratio = dec->vavs3_amstream_dec_info.ratio;
+
+	if (dec->vavs3_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 * dec->vavs3_ratio) / vf->width;
+				break;
+			case 2:
+				vf->sar_width = 4;
+				vf->sar_height = 3;
+				ar = (vf->height * 3 * dec->vavs3_ratio) / (vf->width * 4);
+				break;
+			case 3:
+				vf->sar_width = 16;
+				vf->sar_height = 9;
+				ar = (vf->height * 9 * dec->vavs3_ratio) / (vf->width * 16);
+				break;
+			case 4:
+				vf->sar_width = 221;
+				vf->sar_height = 100;
+				ar = (vf->height * 100 * dec->vavs3_ratio) / (vf->width *
+						221);
+				break;
+			default:
+				vf->sar_width = 1;
+				vf->sar_height = 1;
+				ar = (vf->height * dec->vavs3_ratio) / vf->width;
+				break;
+			}
+		}
+
+	ar = min_t(u32, 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;
+	vf->codec_vfmt = VFORMAT_AVS3;
+
+	return;
+}
+
+static int vavs3_vf_states(struct vframe_states *states, void *op_arg)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_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 *vavs3_vf_peek(void *op_arg)
+{
+	struct vframe_s *vf;
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_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_len(&dec->display_q) > VF_POOL_SIZE) {
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"kfifo len:%d invalid, peek error\n",
+			kfifo_len(&dec->display_q));
+		return NULL;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		struct vframe_s *vf_tmp;
+		if (kfifo_peek(&dec->display_q, &vf_tmp) && vf_tmp) {
+				uint8_t index = vf_tmp->index & 0xff;
+				struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+				if ((pic == NULL) || (!pic->back_done_mark)) {
+					return NULL;
+				}
+		} else
+			return NULL;
+	}
+#endif
+
+	if (kfifo_peek(&dec->display_q, &vf)) {
+		return vf;
+	}
+
+	return NULL;
+}
+
+static struct avs3_frame_s *get_pic_by_index(
+	struct AVS3Decoder_s *dec, int index)
+{
+	struct avs3_frame_s *pic = NULL;
+
+	if ((index >= 0) && (index < dec->avs3_dec.max_pb_size))
+		pic = &dec->avs3_dec.pic_pool[index].buf_cfg;
+	return pic;
+}
+
+static void update_vf_memhandle(struct AVS3Decoder_s *dec,
+	struct vframe_s *vf, struct avs3_frame_s *pic)
+{
+	vf->mem_handle = NULL;
+	vf->mem_handle_1 = NULL;
+	vf->mem_head_handle = NULL;
+	vf->mem_dw_handle = NULL;
+
+#ifdef AVS3_10B_MMU
+	if (vf->type & VIDTYPE_SCATTER) {
+#ifdef AVS3_10B_MMU_DW
+		if (pic->double_write_mode & 0x20) {
+			vf->mem_handle =
+				decoder_mmu_box_get_mem_handle(
+					dec->dw_mmu_box, pic->index);
+			if (dec->front_back_mode)
+				vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->dw_mmu_box_1, 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);
+			if (dec->front_back_mode)
+				vf->mem_handle_1 = decoder_mmu_box_get_mem_handle(dec->mmu_box_1, pic->index);
+			vf->mem_head_handle = decoder_bmmu_box_get_mem_handle(
+				dec->bmmu_box,
+				HEADER_BUFFER_IDX(pic->index));
+			if (dec->double_write_mode == 3)
+				vf->mem_dw_handle =
+					decoder_bmmu_box_get_mem_handle(
+						dec->bmmu_box,
+						VF_BUFFER_IDX(pic->BUF_index));
+			else
+				vf->mem_dw_handle = NULL;
+		}
+	} 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
+}
+
+static void fill_frame_info(struct AVS3Decoder_s *dec,
+	struct avs3_frame_s *pic, unsigned int framesize, unsigned int pts);
+
+static struct vframe_s *vavs3_vf_get(void *op_arg)
+{
+	struct vframe_s *vf;
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+	unsigned long flags = 0;
+
+	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 avs3_frame_s *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;
+	}
+
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (kfifo_peek(&dec->display_q, &vf) && vf) {
+				uint8_t index = vf->index & 0xff;
+				struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+				if ((pic == NULL) || (!pic->back_done_mark)) {
+					return NULL;
+				}
+		} else
+			return NULL;
+	}
+#endif
+
+	lock_buffer(dec, flags);
+	if (kfifo_get(&dec->display_q, &vf)) {
+		uint8_t index = vf->index & 0xff;
+		struct vdec_s *vdec = hw_to_vdec(dec);
+
+		decoder_trace(dec->trace.vf_get_name, (long)vf, TRACE_BUFFER);
+		decoder_trace(dec->trace.disp_q_name, kfifo_len(&dec->display_q), TRACE_BUFFER);
+#ifdef MULTI_INSTANCE_SUPPORT
+		decoder_trace(dec->trace.set_canvas0_addr, vf->canvas0_config[0].phy_addr, TRACE_BUFFER);
+#else
+		decoder_trace(dec->trace.get_canvas0_addr, vf->canvas0Addr, TRACE_BUFFER);
+#endif
+
+		if (index < dec->avs3_dec.max_pb_size) {
+			struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+			if (pic == NULL &&
+				(debug & AVS3_DBG_PIC_LEAK)) {
+				int i;
+				avs3_print(dec, 0,
+				"%s error index 0x%x pic not exist\n",
+				__func__, index);
+				print_pic_pool(&dec->avs3_dec, "");
+				for (i = 0; i < 10; i++) {
+					pic = get_pic_by_index(dec, index);
+					pr_info("pic = %p\n", pic);
+				}
+
+				if (debug & AVS3_DBG_PIC_LEAK)
+					debug |= AVS3_DBG_PIC_LEAK_WAIT;
+				unlock_buffer(dec, flags);
+				return NULL;
+			}
+
+			vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+			vf->vf_ud_param.ud_param.buf_len = 0;
+			vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+			vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+			vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+			vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS3 << 3);
+			vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+			if (vf->pts)
+				vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
+			vf->omx_index = dec->vf_get_count;
+			dec->vf_get_count++;
+			if (pic) {
+				if (dec->front_back_mode == 1) {
+					update_vf_memhandle(dec, vf, pic);
+					decoder_do_frame_check(hw_to_vdec(dec), vf);
+				}
+				avs3_print(dec, AVS3_DBG_BUFMGR,
+				"%s vf %p pic %p index 0x%x getcount %d type 0x%x w/h/depth %d/%d/0x%x, compHeadAddr 0x%08x, pts %d, %lld\n",
+				__func__, vf, pic, index,
+				//pic->imgtr_fwRefDistance_bak,
+				dec->vf_get_count,
+				vf->type,
+				vf->width, vf->height,
+				vf->bitdepth,
+				vf->compHeadAddr,
+				vf->pts,
+				vf->pts_us64);
+			}
+
+			if (pic && (!(pic->error_mark) || !(error_handle_policy & 0x4))) {
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 1) {
+					fill_frame_info(dec, pic, 0, vf->pts);
+					vdec_fill_vdec_frame(vdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+				}
+#endif
+				unlock_buffer(dec, flags);
+				return vf;
+			}
+
+			dec->vf_get_count--;
+			dec->vf_pre_count--;
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"%s:get error pic from fifo\n", __func__);
+			unlock_buffer(dec, flags);
+			vavs3_vf_put(vf, dec);
+			return NULL;
+		}
+	}
+	unlock_buffer(dec, flags);
+	return NULL;
+}
+
+static void vavs3_vf_put(struct vframe_s *vf, void *op_arg)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)op_arg;
+#ifdef MULTI_INSTANCE_SUPPORT
+	struct vdec_s *vdec = hw_to_vdec(dec);
+#endif
+	uint8_t index;
+	unsigned long flags = 0;
+
+	if (vf == (&dec->vframe_dummy))
+		return;
+
+	if (!vf)
+		return;
+
+	decoder_trace(dec->trace.vf_put_name, (long)vf, TRACE_BUFFER);
+#ifdef MULTI_INSTANCE_SUPPORT
+	decoder_trace(dec->trace.put_canvas0_addr, vf->canvas0_config[0].phy_addr, TRACE_BUFFER);
+#else
+	decoder_trace(dec->trace.put_canvas0_addr, vf->canvas0Addr, TRACE_BUFFER);
+#endif
+
+	lock_buffer(dec, flags);
+	index = vf->index & 0xff;
+	kfifo_put(&dec->newframe_q, (const struct vframe_s *)vf);
+	decoder_trace(dec->trace.new_q_name, kfifo_len(&dec->newframe_q), TRACE_BUFFER);
+
+	if (index < dec->avs3_dec.max_pb_size) {
+		struct avs3_frame_s *pic = get_pic_by_index(dec, index);
+
+		if (pic && pic->vf_ref > 0) {
+			pic->vf_ref--;
+		} else {
+			if (pic)
+				avs3_print(dec, 0,
+					"%s, error pic (index %d) vf_ref is %d\n",
+					__func__, index, pic->vf_ref);
+			else
+				avs3_print(dec, 0,
+					"%s, error pic (index %d) is NULL\n",
+					__func__, index);
+		}
+
+		if (pic && (!(pic->error_mark) || !(error_handle_policy & 0x4)))
+			dec->vf_put_count++;
+
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"%s vf %p pic %p index 0x%x putcount %d\n",
+			__func__, vf, pic, vf->index & 0xff, dec->vf_put_count);
+
+		if (dec->wait_buf)
+			WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+		dec->last_put_idx = index;
+		dec->new_frame_displayed++;
+	}
+	unlock_buffer(dec, flags);
+
+#ifdef MULTI_INSTANCE_SUPPORT
+	vdec_up(vdec);
+#endif
+}
+
+static int vavs3_event_cb(int type, void *data, void *private_data)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_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 avs3_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_AVS3;
+		if (index < dec->avs3_dec.max_pb_size) {
+			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);
+
+		avs3_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 avs3_frame_s *get_disp_pic(struct AVS3Decoder_s *dec)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *pic = NULL;
+	int32_t j;
+	int32_t pre_disp_count_min = 0x7fffffff;
+	for (j = 0; j < avs3_dec->ref_maxbuffer; j++) {
+		if (avs3_dec->fref[j]->to_prepare_disp &&
+			avs3_dec->fref[j]->to_prepare_disp <
+			pre_disp_count_min) {
+			pre_disp_count_min =
+				avs3_dec->fref[j]->to_prepare_disp;
+			pic = avs3_dec->fref[j];
+		}
+	}
+	if (pic)
+		pic->to_prepare_disp = 0;
+
+	return pic;
+
+}
+*/
+
+static void fill_frame_info(struct AVS3Decoder_s *dec,
+	struct avs3_frame_s *pic, unsigned int framesize, unsigned int pts)
+{
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	if (pic->slice_type == SLICE_I)
+		pic->vqos.type = 1;
+	else if (pic->slice_type == SLICE_P)
+		pic->vqos.type = 2;
+	else if (pic->slice_type == SLICE_B)
+		pic->vqos.type = 3;
+
+	if (input_frame_based(hw_to_vdec(dec)))
+		pic->vqos.size = pic->frame_size;
+	else {
+		if (!((vdec->vbuf.no_parser == 0) || (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP))
+			&& vdec_stream_based(vdec))
+			pic->vqos.size = pic->stream_size;
+		else if (framesize == 0)
+			pic->vqos.size = pic->stream_size;
+		else
+			pic->vqos.size = framesize;
+	}
+
+	if (pic->error_mark)
+		pic->vqos.decode_buffer = 3;
+	else
+		pic->vqos.decode_buffer = 0;
+
+	pic->vqos.num++;
+	pic->vqos.pts = pts;
+
+	if (get_dbg_flag(dec) & AVS3_DBG_QOS_INFO) {
+		avs3_print(dec, 0, "slice:%d, poc:%d, size %d, decode_buffer %d, time %dus\n",
+			pic->vqos.type, pic->poc, pic->vqos.size, pic->vqos.decode_buffer, pic->hw_decode_time);
+		avs3_print(dec, 0, "mv: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_mv,
+			pic->vqos.avg_mv,
+			pic->vqos.min_mv);
+
+		avs3_print(dec, 0, "qp: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_qp,
+			pic->vqos.avg_qp,
+			pic->vqos.min_qp);
+
+		avs3_print(dec, 0, "skip: max:%d, avg:%d, min:%d\n",
+			pic->vqos.max_skip,
+			pic->vqos.avg_skip,
+			pic->vqos.min_skip);
+	}
+
+	return ;
+}
+
+static void set_vframe(struct AVS3Decoder_s *dec,
+	struct vframe_s *vf, struct avs3_frame_s *pic, u8 dummy)
+{
+	u32 stream_offset = pic->stream_offset;
+	unsigned int frame_size = 0;
+	int pts_discontinue;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	ulong flags = 0;
+
+	avs3_print(dec, AVS3_DBG_BUFMGR,
+		"%s index = %d\r\n",
+		__func__, pic->index);
+
+#ifdef OW_TRIPLE_WRITE
+	if ((pic->triple_write_mode) ||
+		(pic->double_write_mode && (pic->double_write_mode & 0x20) == 0))
+#else
+	if (pic->double_write_mode && (pic->double_write_mode & 0x20) == 0)
+#endif
+		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.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
+			/* 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;
+
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode != 1)
+#endif
+		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_THRESHOLD;
+				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 ((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);
+		dec->last_pts = vf->pts;
+
+		if (vf->pts_us64 != 0)
+			dec->last_lookup_pts_us64 = vf->pts_us64;
+
+		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);
+		}
+
+		dec->last_pts_us64 = 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 AVS3_10B_MMU
+		vf->compBodyAddr = 0;
+		vf->compHeadAddr = pic->header_adr;
+#ifdef AVS3_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 & AVS3_DBG_OUT_PTS) == 0)) {
+				vf->compHeadAddr = pic->dw_header_adr;
+				pr_info("Use dw mmu for display\n");
+			}
+		}
+#endif
+
+#else
+		vf->compBodyAddr = pic->mc_y_adr; /*body adr*/
+		vf->compHeadAddr = pic->mc_y_adr + pic->comp_body_size;
+#endif
+	}
+	if (pic->double_write_mode &&
+		((pic->double_write_mode & 0x20) == 0)) {
+		vf->type = VIDTYPE_PROGRESSIVE |
+			VIDTYPE_VIU_FIELD;
+		vf->type |= VIDTYPE_VIU_NV21;
+		if (pic->double_write_mode == 3) {
+			vf->type |= VIDTYPE_COMPRESS;
+#ifdef AVS3_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 AVS3_10B_MMU
+		vf->type |= VIDTYPE_SCATTER;
+#endif
+	}
+
+	switch (pic->depth) {
+	case AVS3_BITS_8:
+		vf->bitdepth = BITDEPTH_Y8 |
+			BITDEPTH_U8 | BITDEPTH_V8;
+		break;
+	case AVS3_BITS_10:
+	case AVS3_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->depth == AVS3_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->width /
+		get_double_write_ratio(pic->double_write_mode);
+	vf->height = pic->height /
+		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;
+	}
+	if ((pic->double_write_mode & 0x20) &&
+		((pic->double_write_mode & 0xf) == 2 ||
+		(pic->double_write_mode & 0xf) == 4)) {
+		vf->compWidth = pic->width /
+			get_double_write_ratio(
+				pic->double_write_mode & 0xf);
+		vf->compHeight = pic->height /
+			get_double_write_ratio(
+				pic->double_write_mode & 0xf);
+	} else {
+		vf->compWidth = pic->width;
+		vf->compHeight = pic->height;
+	}
+
+#ifdef OW_TRIPLE_WRITE
+	if (!pic->double_write_mode && pic->triple_write_mode) {
+		vf->type |= VIDTYPE_VIU_NV21;		//nv12 flag
+		vf->canvas0_config[0] = pic->tw_canvas_config[0];
+		vf->canvas0_config[1] = pic->tw_canvas_config[1];
+		vf->canvas1_config[0] = pic->tw_canvas_config[0];
+		vf->canvas1_config[1] = pic->tw_canvas_config[1];
+		vf->width = pic->width /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);	//tw same ratio defined with dw
+		vf->height = pic->height /
+			get_double_write_ratio(pic->triple_write_mode & 0xf);
+		avs3_print(dec, 0, "output triple write w %d, h %d, bitdepth %s\n",
+				vf->width, vf->height, vf->canvas0_config[0].bit_depth?"10":"8");
+	}
+#endif
+
+	if (force_fps & 0x100) {
+		u32 rate = force_fps & 0xff;
+		if (rate)
+			vf->duration = 96000/rate;
+		else
+			vf->duration = 0;
+	}
+
+	if (dec->front_back_mode != 1)
+		update_vf_memhandle(dec, vf, pic);
+
+	if ((vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_UPPER_LOOKUP) && vdec_stream_based(vdec)) {
+		/* offset for tsplayer pts lookup */
+		u64 frame_type = 0;
+		if (pic->slice_type == SLICE_I)
+			frame_type = KEYFRAME_FLAG;
+		else if (pic->slice_type == SLICE_P)
+			frame_type = PFRAME_FLAG;
+		else if (pic->slice_type == SLICE_B)
+			frame_type = BFRAME_FLAG;
+		vf->pts_us64 = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
+		vf->pts = 0;
+	} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+		/* lookup by decoder */
+		checkout_pts_offset pts_info;
+		u64 frame_type = 0;
+		if (pic->slice_type == SLICE_I)
+			frame_type = KEYFRAME_FLAG;
+		else if (pic->slice_type == SLICE_P)
+			frame_type = PFRAME_FLAG;
+		else if (pic->slice_type == SLICE_B)
+			frame_type = BFRAME_FLAG;
+		pts_info.offset = (((u64)vf->duration << 32 | (frame_type << 62)) & 0xffffffff00000000)
+			| pic->stream_offset;
+		if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+			vf->pts = pts_info.pts;
+			vf->pts_us64 = pts_info.pts_64;
+		} else {
+			vf->pts = 0;
+			vf->pts_us64 = 0;
+		}
+	}
+	avs3_print(dec, AVS3_DBG_OUT_PTS,
+		"avs3 dec out pts: vf->pts=%d, vf->pts_us64 = %lld slice_type %d, duration %d\n",
+		vf->pts, vf->pts_us64, pic->slice_type, vf->duration);
+
+	lock_buffer(dec, flags);
+	if (!dummy) {
+		pic->vf_ref = 1;
+	}
+	dec->vf_pre_count++;
+	unlock_buffer(dec, flags);
+}
+
+static inline void dec_update_gvs(struct AVS3Decoder_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 avs3_prepare_display_buf(struct AVS3Decoder_s *dec)
+{
+#ifndef NO_DISPLAY
+	struct vframe_s *vf = NULL;
+	/*unsigned short slice_type;*/
+	struct avs3_frame_s *pic;
+	struct vdec_s *pvdec = hw_to_vdec(dec);
+
+	while (1) {
+		COM_PIC *com_pic = dec_pull_frm(&dec->avs3_dec.ctx, 0);
+
+		if (com_pic == NULL)
+			break;
+		pic = &com_pic->buf_cfg;
+		if (force_disp_pic_index & 0x100) {
+			/*recycle directly*/
+			continue;
+		}
+
+		if (pic->error_mark && (error_handle_policy & 0x4)) {
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"%s: error pic, skip\n", __func__);
+			continue;
+		}
+
+		if (dec->start_decoding_flag != 0) {
+			if (dec->skip_PB_before_I &&
+				pic->slice_type != I_IMG) {
+				avs3_print(dec, AVS3_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) {
+			set_vframe(dec, vf, pic, 0);
+			if (dec->front_back_mode != 1)
+				decoder_do_frame_check(pvdec, vf);
+			vdec_vframe_ready(pvdec, vf);
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"%s: pic %p stream_offset 0x%x\n",
+				__func__, com_pic, pic->stream_offset);
+
+			kfifo_put(&dec->display_q, (const struct vframe_s *)vf);
+			decoder_trace(dec->trace.pts_name, vf->pts, TRACE_BUFFER);
+			decoder_trace(dec->trace.new_q_name, kfifo_len(&dec->newframe_q), TRACE_BUFFER);
+			decoder_trace(dec->trace.disp_q_name, kfifo_len(&dec->display_q), TRACE_BUFFER);
+
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode == 0) {
+#endif
+			dec_update_gvs(dec);
+			/*count info*/
+			vdec_count_info(dec->gvs, 2, pic->stream_offset);
+
+			dec->gvs->bit_depth_luma = pic->depth;
+			dec->gvs->bit_depth_chroma = pic->depth;
+			dec->gvs->double_write_mode = pic->double_write_mode;
+			vdec_fill_vdec_frame(pvdec, &pic->vqos, dec->gvs, vf, pic->hw_decode_time);
+#ifdef NEW_FB_CODE
+			}
+#endif
+
+			pvdec->vdec_fps_detec(pvdec->id);
+			if (without_display_mode == 0) {
+				if (dec->front_back_mode != 1)
+					vf_notify_receiver(dec->provider_name,
+						VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+			} else
+				vavs3_vf_put(vavs3_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 & AVS3_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 & AVS3_DBG_BUFMGR)
+		pr_info("leave %s\r\n", __func__);
+}
+static void debug_buffer_mgr_more(struct AVS3Decoder_s *dec)
+{
+	int i;
+	if (!(debug & AVS3_DBG_BUFMGR_MORE))
+		return;
+
+	avs3_print(dec, 0, "avs3_param: (%d)\n", dec->avs3_dec.img.number);
+	for (i = 0; i < (RPM_END-RPM_BEGIN); i++) {
+		avs3_print_cont(dec, 0, "%04x ", dec->avs3_dec.param.l.data[i]);
+		if (((i + 1) & 0xf) == 0) {
+			avs3_print_cont(dec, 0, "\n");
+			avs3_print_flush(dec);
+		}
+	}
+	avs3_print(dec, 0, "\n");
+}
+
+#ifdef AVS3_10B_MMU
+static void avs3_recycle_mmu_buf_tail(struct AVS3Decoder_s *dec)
+{
+	if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+		u32 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, used_4k_num);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s decoder_mmu_box_free_idx_tail index=%d used_4k_num %d\n",
+		__func__, dec->cur_fb_idx_mmu, used_4k_num);
+
+		if (dec->dw_mmu_enable) {
+			used_4k_num = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+			avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s DW decoder_mmu_box_free_idx_tail index=%d used_4k_num %d\n",
+			__func__, dec->cur_fb_idx_mmu, used_4k_num);
+
+			decoder_mmu_box_free_idx_tail(
+					dec->dw_mmu_box,
+					dec->cur_fb_idx_mmu,
+					used_4k_num);
+		}
+
+		dec->cur_fb_idx_mmu = INVALID_IDX;
+	}
+}
+
+static void avs3_recycle_mmu_buf(struct AVS3Decoder_s *dec)
+{
+	if (dec->cur_fb_idx_mmu != INVALID_IDX) {
+		decoder_mmu_box_free_idx(dec->mmu_box,
+			dec->cur_fb_idx_mmu);
+
+		if (dec->front_back_mode)
+			decoder_mmu_box_free_idx(dec->mmu_box_1,
+			dec->cur_fb_idx_mmu);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s decoder_mmu_box_free_idx index=%d\n",
+		__func__, dec->cur_fb_idx_mmu);
+
+		if (dec->dw_mmu_enable) {
+			decoder_mmu_box_free_idx(dec->dw_mmu_box,
+				dec->cur_fb_idx_mmu);
+
+			if (dec->front_back_mode)
+				decoder_mmu_box_free_idx(dec->dw_mmu_box_1,
+				dec->cur_fb_idx_mmu);
+
+			avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s DW decoder_mmu_box_free_idx index=%d\n",
+			__func__, dec->cur_fb_idx_mmu);
+		}
+		dec->cur_fb_idx_mmu = INVALID_IDX;
+	}
+}
+#endif
+
+static void dec_again_process(struct AVS3Decoder_s *dec)
+{
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1)
+		amhevc_stop_f();
+	else
+#endif
+	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;
+
+	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 AVS3Decoder_s *dec,
+	struct avs3_frame_s *pic)
+{
+#ifndef PXP_DEBUG
+	if (dec->front_back_mode == 3 ||
+		(debug & AVS3_DBG_DIS_LOC_ERROR_PROC))
+		return;
+
+	if (pic->decoded_lcu != dec->avs3_dec.lcu_total) {
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"%s error pic(index %d) decoded lcu %d (total %d)\n",
+			__func__, pic->index,
+			pic->decoded_lcu, dec->avs3_dec.lcu_total);
+		pic->error_mark = 1;
+	} else {
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s pic(index %d) decoded lcu %d (total %d)\n",
+			__func__, pic->index,
+			pic->decoded_lcu, dec->avs3_dec.lcu_total);
+
+	}
+#endif
+}
+static void update_decoded_pic(struct AVS3Decoder_s *dec)
+{
+	struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+	if (pic) {
+		dec->avs3_dec.cur_pic->decoded_lcu =
+			(READ_VREG(HEVC_PARSER_LCU_START)
+					& 0xffffff) + 1;
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s pic(index %d) decoded lcu %d (total %d)\n",
+			__func__, pic->index,
+			pic->decoded_lcu, dec->avs3_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 AVS3Decoder_s *dec)
+{
+	int tmp = 0;
+
+	switch (params->p.sqh_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.sqh_progressive_sequence)
+		tmp = tmp / 2;
+	dec->frame_dur = div_u64(96000ULL, tmp);
+	dec->get_frame_dur = true;
+	avs3_print(dec, PRINT_FLAG_VDEC_STATUS, "avs3 frame_dur:%d,progressive:%d\n",
+		dec->frame_dur, params->p.sqh_progressive_sequence);
+	return 0;
+}
+
+#define HEVC_MV_INFO   0x310d
+#define HEVC_QP_INFO   0x3137
+#define HEVC_SKIP_INFO 0x3136
+
+static void get_qos_info(struct AVS3Decoder_s *dec, struct vframe_qos_s* vqos, int pic_number, int core_num)
+{
+	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;
+	uint64_t ctrl_reg = HEVC_PIC_QUALITY_CTRL;
+	uint64_t data_reg = HEVC_PIC_QUALITY_DATA;
+
+	if (core_num == 1) {
+		ctrl_reg = HEVC_PIC_QUALITY_CTRL_DBE1;
+		data_reg = HEVC_PIC_QUALITY_DATA_DBE1;
+	}
+
+	/* set rd_idx to 0 */
+	WRITE_VREG(ctrl_reg, 0);
+
+	blk88_y_count = READ_VREG(data_reg);
+	if (blk88_y_count == 0) {
+		avs3_print(dec, AVS3_DBG_QOS_INFO,
+			"[Picture %d Quality] NO Data yet.\n",
+			pic_number);
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (1 << 8));
+		return;
+	}
+
+	/* qp_y_sum */
+	rdata32 = READ_VREG(data_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] Y QP AVG:%d (%d/%d)\n",
+		pic_number, rdata32/blk88_y_count, rdata32, blk88_y_count);
+	vqos->avg_qp = rdata32 * 10 / blk88_y_count;
+
+	/* intra_y_count */
+	rdata32 = READ_VREG(data_reg);
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] Y skipped rate:%d%c (%d)\n",
+		pic_number, rdata32 * 100 / blk88_y_count, '%', rdata32);
+	vqos->avg_skip = rdata32 * 1000 / blk88_y_count;
+
+	/* coeff_non_zero_y_count */
+	rdata32 = READ_VREG(data_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] Y ZERO_Coeff rate:%d%c (%d)\n",
+		pic_number, (100 - rdata32 * 100 / blk88_y_count), '%', rdata32);
+
+	/* blk66_c_count */
+	blk88_c_count = READ_VREG(data_reg);
+	if (blk88_c_count == 0) {
+		avs3_print(dec, AVS3_DBG_QOS_INFO,
+			"[Picture %d Quality] NO Data yet.\n",
+			pic_number);
+
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (1 << 8));
+		return;
+	}
+
+	/* qp_c_sum */
+	rdata32 = READ_VREG(data_reg);
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] C ZERO_Coeff rate:%d%c (%d)\n",
+		pic_number, (100 - rdata32 * 100 / blk88_c_count), '%', 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(data_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] Y QP min:%d max:%d\n",
+		pic_number, (rdata32 >> 0) & 0xff, (rdata32 >> 8) & 0xff);
+
+	vqos->min_qp = (rdata32 >> 0) & 0xff;
+	vqos->max_qp = (rdata32 >> 8) & 0xff;
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] C QP min:%d max:%d\n",
+		pic_number, (rdata32 >> 16) & 0xff, (rdata32 >> 24) & 0xff);
+
+	/* blk22_mv_count */
+	blk22_mv_count = READ_VREG(data_reg);
+	if (blk22_mv_count == 0) {
+		avs3_print(dec, AVS3_DBG_QOS_INFO,
+			"[Picture %d Quality] NO MV Data yet.\n",
+			pic_number);
+
+		/* reset all counts */
+		WRITE_VREG(ctrl_reg, (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(data_reg);
+
+	/* should all be 0x00 or 0xff */
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	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 * 10, blk22_mv_count);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L0 AVG:%d (%lld/%d)\n",
+		pic_number, div_s64(value, 10), div_s64(value, 10), blk22_mv_count);
+
+	vqos->avg_mv = value;
+
+	/* mvy_L0_count[31:0] */
+	rdata32_l = READ_VREG(data_reg);
+	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;
+
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	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;
+
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	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;
+
+	avs3_print(dec, AVS3_DBG_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(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+	vqos->max_mv = mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+	vqos->min_mv = mv_lo;
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L0 MAX:%d MIN:%d\n",
+		pic_number, mv_hi, mv_lo);
+
+	/* {mvy_L0_max, mvy_L0_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] MVY_L0 MAX:%d MIN:%d\n",
+		pic_number, mv_hi, mv_lo);
+
+	/* {mvx_L1_max, mvx_L1_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] MVX_L1 MAX:%d MIN:%d\n",
+		pic_number, mv_hi, mv_lo);
+
+	/* {mvy_L1_max, mvy_L1_min} */
+	rdata32 = READ_VREG(data_reg);
+	mv_hi = (rdata32 >> 16) & 0xffff;
+	if (mv_hi & 0x8000)
+		mv_hi = 0x8000 - mv_hi;
+
+	mv_lo = (rdata32 >> 0) & 0xffff;
+	if (mv_lo & 0x8000)
+		mv_lo = 0x8000 - mv_lo;
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] MVY_L1 MAX:%d MIN:%d\n",
+		pic_number, mv_hi, mv_lo);
+
+	rdata32 = READ_VREG(ctrl_reg);
+	avs3_print(dec, AVS3_DBG_QOS_INFO,
+		"[Picture %d Quality] After Read:VDEC_PIC_QUALITY_CTRL: 0x%x\n",
+		pic_number, rdata32);
+
+	/* reset all counts */
+	WRITE_VREG(ctrl_reg, (1 << 8));
+
+}
+
+/* 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 AVS3Decoder_s *dec, bool back_flag)
+{
+	struct avs3_frame_s *picture = NULL;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct vframe_qos_s vqos_0, vqos_1;
+
+	if (back_flag) {
+#ifdef NEW_FB_CODE
+		picture = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+#endif
+	} else {
+		picture = dec->avs3_dec.cur_pic;
+	}
+
+	if (!picture) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			"%s decode picture is none exist\n");
+		return;
+	}
+
+	if (vdec->mvfrm) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode != 0) {
+			if (back_flag) {
+				picture->hw_decode_time =
+					local_clock() - vdec->hw_back_decode_start;
+				if (picture->hw_decode_time < picture->hw_front_decode_time)
+					picture->hw_decode_time = picture->hw_front_decode_time;
+
+			} else {
+				picture->hw_front_decode_time =
+					local_clock() - vdec->hw_front_decode_start;
+				return ;
+			}
+		} else
+#endif
+			picture->hw_decode_time =
+				local_clock() - vdec->mvfrm->hw_decode_start;
+	}
+
+	avs3_print(dec, AVS3_DBG_QOS_INFO, "slice_type:%d, poc:%d hw_decode_time:%d\n",
+		picture->slice_type, picture->poc, picture->hw_decode_time);
+
+	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 == SLICE_I)
+			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->vqos.max_mv = a[2];
+		picture->vqos.avg_mv = a[1];
+		picture->vqos.min_mv = a[0];
+		avs3_print(dec, AVS3_DBG_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;
+				}
+			}
+		picture->vqos.max_qp = a[2];
+		picture->vqos.avg_qp = a[1];
+		picture->vqos.min_qp = a[0];
+
+		avs3_print(dec, AVS3_DBG_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;
+				}
+			}
+		picture->vqos.max_skip = a[2];
+		picture->vqos.avg_skip = a[1];
+		picture->vqos.min_skip = a[0];
+
+		avs3_print(dec, AVS3_DBG_QOS_INFO,
+			"skip data %x  a[0]= %x a[1]= %x a[2]= %x\n",
+			data, a[0], a[1], a[2]);
+	} else {
+		picture->vqos.max_mv = 0;
+		picture->vqos.avg_mv = 0;
+		picture->vqos.min_mv = 0;
+
+		picture->vqos.max_skip = 0;
+		picture->vqos.avg_skip = 0;
+		picture->vqos.min_skip = 0;
+
+		picture->vqos.max_qp = 0;
+		picture->vqos.avg_qp = 0;
+		picture->vqos.min_qp = 0;
+
+		get_qos_info(dec, &vqos_0, picture->poc, 0);
+
+		if (back_flag) {
+#ifdef NEW_FB_CODE
+			get_qos_info(dec, &vqos_1, picture->poc, 1);
+
+			vqos_0.max_mv = max(vqos_0.max_mv, vqos_1.max_mv);
+			vqos_0.min_mv = min(vqos_0.min_mv, vqos_1.min_mv);
+			vqos_0.max_qp = max(vqos_0.max_qp, vqos_1.max_qp);
+			vqos_0.min_qp = min(vqos_0.min_qp, vqos_1.min_qp);
+
+			vqos_0.avg_qp = (vqos_0.avg_qp + vqos_1.avg_qp) / 20;
+			vqos_0.avg_skip = (vqos_0.avg_skip + vqos_1.avg_skip) / 20;
+			vqos_0.avg_mv = (vqos_0.avg_mv + vqos_1.avg_mv) / 20;
+#endif
+		} else {
+			vqos_0.avg_qp = vqos_0.avg_qp / 10;
+			vqos_0.avg_skip = vqos_0.avg_skip / 10;
+			vqos_0.avg_mv = vqos_0.avg_mv / 10;
+		}
+
+		picture->vqos = vqos_0;
+	}
+}
+
+#ifdef NEW_FB_CODE
+irqreturn_t avs3_back_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_PIC_DONE);
+	dec->dec_status_back = READ_VREG(HEVC_DEC_STATUS_DBE);
+	if (dec->dec_status_back == HEVC_BE_DECODE_DATA_DONE) {
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC_BACK);
+	}
+
+	/*BackEnd_Handle()*/
+	if (dec->front_back_mode != 1) {
+		avs3_print(dec, AVS3_DBG_IRQ_EVENT,
+			"[BE] %s\n", __func__);
+		if (dec->front_back_mode == 3)
+			dec->dec_status_back = HEVC_BE_DECODE_DATA_DONE;
+		return IRQ_WAKE_THREAD;
+	}
+
+#if 0
+	if (debug & AVS3_DBG_IRQ_EVENT)
+		avs3_print(dec, 0,
+			"[BE] avs3 back isr dec_status_back  = 0x%x\n",
+			dec->dec_status_back
+		);
+	if (READ_VREG(DEBUG_REG1_DBE)) {
+		pr_info("[BE] dbg%x: %x, HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n", READ_VREG(DEBUG_REG1_DBE),
+		READ_VREG(DEBUG_REG2_DBE),
+		READ_VREG(HEVC_SAO_CRC),
+		READ_VREG(HEVC_SAO_CRC_DBE1)
+		);
+		WRITE_VREG(DEBUG_REG1_DBE, 0);
+	}
+#else
+	if (READ_VREG(DEBUG_REG1_DBE)) {
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+		WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+		return IRQ_HANDLED;
+#else
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+		return IRQ_WAKE_THREAD;
+#endif
+	}
+#endif
+	if (dec->dec_status_back == AVS3_DEC_IDLE) {
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+		return IRQ_HANDLED;
+	}
+	/**/
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+	WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+	return IRQ_HANDLED;
+#else
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_END);
+	reset_process_time_back(dec);
+	return IRQ_WAKE_THREAD;
+#endif
+}
+
+irqreturn_t vavs3_back_isr_thread_fn(struct AVS3Decoder_s *dec)
+{
+	unsigned int dec_status = dec->dec_status_back;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	int j;
+	//unsigned long flags;
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_THREAD_PIC_DONE_START);
+
+	if (debug & AVS3_DBG_IRQ_EVENT)
+		avs3_print(dec, 0,
+			"[BE] avs3 back isr dec_status_back  = 0x%x\n",
+			dec->dec_status_back);
+	if (READ_VREG(DEBUG_REG1_DBE)) {
+		avs3_print(dec, 0, "[BE] dbg%x: %x\n",
+			READ_VREG(DEBUG_REG1_DBE), READ_VREG(DEBUG_REG2_DBE));
+		WRITE_VREG(DEBUG_REG1_DBE, 0);
+	}
+
+	/*simulation code: if (READ_VREG(HEVC_DEC_STATUS_DBE)==HEVC_BE_DECODE_DATA_DONE)*/
+	if (dec_status == HEVC_BE_DECODE_DATA_DONE || dec->front_back_mode == 2) {
+		struct avs3_frame_s *pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+
+		get_picture_qos_info(dec, true);
+
+		dec_update_gvs(dec);
+		/*count info*/
+		vdec_count_info(dec->gvs, 2, pic->stream_offset);
+		dec->gvs->bit_depth_luma = pic->depth;
+		dec->gvs->bit_depth_chroma = pic->depth;
+		dec->gvs->double_write_mode = pic->double_write_mode;
+
+		reset_process_time_back(dec);
+		vdec->back_pic_done = true;
+		avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"BackEnd data done %d, fb_rd_pos %d, pic index %d, poc %d HEVC_SAO_CRC %x HEVC_SAO_CRC_DBE1 %x\n",
+			avs3_dec->backend_decoded_count, avs3_dec->fb_rd_pos, pic->index, pic->poc,
+			READ_VREG(HEVC_SAO_CRC), READ_VREG(HEVC_SAO_CRC_DBE1));
+
+		if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+			avs3_print(dec, 0,
+				"CM_BODY_START_ADDR 0x%x CM_HEADER_START_ADDR 0x%x SAO_Y_START_ADDR 0x%x SAO_Y_LENGTH 0x%x\n",
+				READ_VREG(HEVC_CM_BODY_START_ADDR), READ_VREG(HEVC_CM_HEADER_START_ADDR),
+				READ_VREG(HEVC_SAO_Y_START_ADDR), READ_VREG(HEVC_SAO_Y_LENGTH));
+
+			avs3_print(dec, 0,
+				"SAO_C_START_ADDR 0x%x SAO_C_LENGTH 0x%x SAO_Y_WPTR 0x%x SAO_C_WPTR 0x%x\n",
+				READ_VREG(HEVC_SAO_C_START_ADDR), READ_VREG(HEVC_SAO_C_LENGTH),
+				READ_VREG(HEVC_SAO_Y_WPTR), READ_VREG(HEVC_SAO_C_WPTR));
+
+			avs3_print(dec, 0,
+				"SAO_CTRL0 0x%x SAO_CTRL1 0x%x SAO_CTRL2 0x%x SAO_CTRL3 0x%x SAO_CTRL4 0x%x SAO_CTRL5 0x%x\n",
+				READ_VREG(HEVC_SAO_CTRL0), READ_VREG(HEVC_SAO_CTRL1), READ_VREG(HEVC_SAO_CTRL2),
+				READ_VREG(HEVC_SAO_CTRL3), READ_VREG(HEVC_SAO_CTRL4), READ_VREG(HEVC_SAO_CTRL5));
+
+			avs3_print(dec, 0,
+				"CM_BODY_START_ADDR_DBE1 0x%x CM_HEADER_START_ADDR_DBE1 0x%x SAO_Y_START_ADDR_DBE1 0x%x SAO_Y_LENGTH_DBE1 0x%x\n",
+				READ_VREG(HEVC_CM_BODY_START_ADDR_DBE1), READ_VREG(HEVC_CM_HEADER_START_ADDR_DBE1),
+				READ_VREG(HEVC_SAO_Y_START_ADDR_DBE1), READ_VREG(HEVC_SAO_Y_LENGTH_DBE1));
+
+			avs3_print(dec, 0,
+				"SAO_C_START_ADDR_DBE1 0x%x SAO_C_LENGTH_DBE1 0x%x SAO_Y_WPTR_DBE1 0x%x SAO_C_WPTR_DBE1 0x%x\n",
+				READ_VREG(HEVC_SAO_C_START_ADDR_DBE1), READ_VREG(HEVC_SAO_C_LENGTH_DBE1),
+				READ_VREG(HEVC_SAO_Y_WPTR_DBE1), READ_VREG(HEVC_SAO_C_WPTR_DBE1));
+
+			avs3_print(dec, 0,
+				"SAO_CTRL0_DBE1 0x%x SAO_CTRL1_DBE1 0x%x SAO_CTRL2_DBE1 0x%x SAO_CTRL3_DBE1 0x%x SAO_CTRL4_DBE1 0x%x SAO_CTRL5_DBE1 0x%x\n",
+				READ_VREG(HEVC_SAO_CTRL0_DBE1), READ_VREG(HEVC_SAO_CTRL1_DBE1), READ_VREG(HEVC_SAO_CTRL2_DBE1),
+				READ_VREG(HEVC_SAO_CTRL3_DBE1), READ_VREG(HEVC_SAO_CTRL4_DBE1), READ_VREG(HEVC_SAO_CTRL5_DBE1));
+		}
+
+		if (fbdebug_flag & 0x70000000) {
+			u8 cmd = (fbdebug_flag >> 28) & 0x7;
+			u32 dump_c = (fbdebug_flag >> 16) & 0xfff;
+			if ((cmd == 3) ||
+				(cmd == 1 && dump_c == avs3_dec->backend_decoded_count) ||
+				(cmd == 2 && avs3_dec->backend_decoded_count < dump_c))
+				//10000, make log different from dump_loop_buffer after FrontEnd data done.
+				dump_loop_buffer(dec, 10000 + avs3_dec->backend_decoded_count, cmd ==1 || cmd == 2);
+		}
+
+		if (dec->front_back_mode == 1) {
+			avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"MMU0 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR0));
+			avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"MMU1 b cur addr : 0x%x\n", READ_VREG(HEVC_ASSIST_FBD_MMU_MAP_ADDR1));
+			WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS3_DEC_IDLE);
+			WRITE_VREG(HEVC_ASSIST_FB_PIC_CLR, 2);
+		}
+		if (debug & AVS3_DBG_PRINT_PIC_LIST) {
+			print_pic_pool(avs3_dec, "before dec backend_ref");
+			avs3_print_cont(dec, 0, "pic_cfg index %d, list0 index: ", pic->index);
+			for (j = 0; j < pic->list0_num_refp; j++)
+				avs3_print_cont(dec, 0, "%d ", pic->list0_index[j]);
+			avs3_print_cont(dec, 0, "list1 index: ");
+			for (j = 0; j < pic->list1_num_refp; j++)
+				avs3_print_cont(dec, 0, "%d ", pic->list1_index[j]);
+			avs3_print_cont(dec, 0, "\n");
+		}
+
+#if 0
+#ifdef AVS3_10B_MMU
+		release_unused_4k(&avs3_mmumgr_0, pic->index);
+		release_unused_4k(&avs3_mmumgr_1, pic->index);
+#endif
+#ifdef AVS3_10B_MMU_DW
+		release_unused_4k(&avs3_mmumgr_dw0, pic->index); // new dual
+		release_unused_4k(&avs3_mmumgr_dw1, pic->index); // new dual
+#endif
+#else
+		if ((dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3
+			)  && (debug & AVS3_DBG_NOT_RECYCLE_MMU_TAIL) == 0) {
+			/*if (dec->is_used_v4l) {
+				// to do
+			} else {*/
+				unsigned used_4k_num0;
+				unsigned used_4k_num1;
+				used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS) >> 16;
+				if (dec->front_back_mode == 3)
+					used_4k_num1 = used_4k_num0;
+				else
+					used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS_DBE1) >> 16;
+				avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+					"%s decoder_mmu_box_free_idx_tail index=%d, core0 %d core1 %d\n",
+					__func__, pic->index,
+					used_4k_num0, used_4k_num1);
+				decoder_mmu_box_free_idx_tail(
+						dec->mmu_box,
+						pic->index,
+						used_4k_num0);
+				decoder_mmu_box_free_idx_tail(
+						dec->mmu_box_1,
+						pic->index,
+						used_4k_num1);
+				if (dec->dw_mmu_enable) {
+					used_4k_num0 = READ_VREG(HEVC_SAO_MMU_STATUS2) >> 16;
+					if (dec->front_back_mode == 3)
+						used_4k_num1 = used_4k_num0;
+					else
+						used_4k_num1 = READ_VREG(HEVC_SAO_MMU_STATUS2_DBE1) >> 16;
+					avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+						"%s DW decoder_mmu_box_free_idx_tail index=%d, core0 %d core1 %d\n",
+						__func__, pic->index,
+						used_4k_num0, used_4k_num1);
+					decoder_mmu_box_free_idx_tail(
+							dec->dw_mmu_box,
+							pic->index,
+							used_4k_num0);
+					decoder_mmu_box_free_idx_tail(
+							dec->dw_mmu_box_1,
+							pic->index,
+							used_4k_num1);
+				}
+		}
+#endif
+
+		if (without_display_mode == 0) {
+			struct vframe_s *vf = NULL;
+			if (kfifo_peek(&dec->display_q, &vf) && vf) {
+				uint8_t index = vf->index & 0xff;
+				struct avs3_frame_s *peek_pic = get_pic_by_index(dec, index);
+
+				if (peek_pic == pic)
+					vf_notify_receiver(dec->provider_name,
+						VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+			}
+		} else
+			vavs3_vf_put(vavs3_vf_get(dec), dec);
+
+		pic_backend_ref_operation(dec, pic, 0);
+
+		if (debug & AVS3_DBG_PRINT_PIC_LIST)
+			print_pic_pool(avs3_dec, "after dec backend_ref");
+
+		if (dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3)
+		release_free_mmu_buffers(dec);
+
+		dec->dec_back_result = DEC_BACK_RESULT_DONE;
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_ISR_THREAD_EDN);
+		if (avs3_dec->front_pause_flag) {
+			/*multi pictures in one packe*/
+			WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG,
+						0x1);
+		}
+		avs3_work_back_implement(dec, vdec, 0);
+	}
+	//unlock_front_back(dec, flags);
+
+	return IRQ_HANDLED;
+}
+
+irqreturn_t avs3_back_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	irqreturn_t ret;
+	//unsigned long flags;
+	//lock_front_back(dec, flags);
+	ret = vavs3_back_isr_thread_fn(dec);
+	//unlock_front_back(dec, flags);
+	return ret;
+}
+
+#endif
+
+static void handle_ucode_dbg(struct AVS3Decoder_s *dec, uint debug_tag)
+{
+
+	int i;
+	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_VREG(DEBUG_REG1, 0);
+	} else if (debug_tag != 0) {
+		pr_info(
+			"dbg%x: %x lcu %x stream crc %x, shiftbytes 0x%x decbytes 0x%x\n", READ_HREG(DEBUG_REG1),
+				READ_HREG(DEBUG_REG2),
+				READ_VREG(HEVC_PARSER_LCU_START),
+			   READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+				READ_VREG(HEVC_SHIFT_BYTE_COUNT) -
+				dec->start_shift_bytes);
+		if ((debug & AVS3_DBG_SAO_CRC) &&
+			(get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5)) {
+			unsigned old_crc = READ_VREG(HEVC_SAO_CRC);
+			int count = 0;
+			while (1) {
+				unsigned crc;
+				crc = READ_VREG(HEVC_SAO_CRC);
+				if (crc == old_crc) {
+					pr_info("stable HEVC_SAO_CRC = %x, count=%d\n", crc, count);
+					break;
+				}
+				count++;
+				old_crc = crc;
+				if (count > 100) {
+					pr_info("read HEVC_SAO_CRC = %x\n", crc);
+					count = 0;
+				}
+			}
+		}
+
+		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_VREG(DEBUG_REG1, 0);
+		/*if (dec->dec_status) {
+			return IRQ_WAKE_THREAD;
+		} else*/ {
+			//dec->process_busy = 0;
+		}
+	}
+}
+
+static irqreturn_t vavs3_isr_thread_fn(int irq, void *data)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)data;
+	DEC_CTX *ctx = &dec->avs3_dec.ctx;
+	unsigned int dec_status = dec->dec_status;
+	int i, ret;
+	int32_t start_code = 0;
+#ifdef NEW_FB_CODE
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+#endif
+	unsigned char avs3_bi_mid_ptr;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+#if 0
+	avs3_print(dec, AVS3_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));
+#else
+	if (debug & AVS3_DBG_IRQ_EVENT) {
+		if (dec->front_back_mode != 1)
+			avs3_print(dec, 0,
+				"avs3 isr dec status  = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x)\n",
+				dec_status, READ_HREG(DEBUG_REG1), 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)
+			);
+		else
+			avs3_print(dec, 0,
+				"avs3 isr dec status  = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) [BE] pc %x psr %x DEC_STATUS %x\n",
+				dec_status, READ_HREG(DEBUG_REG1), 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),
+				READ_VREG(HEVC_MPC_E_DBE),
+			READ_VREG(HEVC_MPSR_DBE),
+			READ_VREG(HEVC_DEC_STATUS_DBE)
+			);
+	}
+
+	if (udebug_flag) {
+		uint debug_tag = READ_HREG(DEBUG_REG1);
+
+		if (debug_tag != 0) {
+			handle_ucode_dbg(dec, debug_tag);
+			//dec->process_busy = 0;
+			//return IRQ_HANDLED;
+		}
+	}
+
+#endif
+
+	if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+		(dec_status == AVS3_HEAD_PIC_PB_READY)) {
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_START, TRACE_BASIC);
+	} else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_PIC_DONE_START, TRACE_BASIC);
+	}
+
+#ifndef G12A_BRINGUP_DEBUG
+	if (dec->eos) {
+		goto irq_handled_exit;
+	}
+#endif
+	dec->wait_buf = 0;
+	if (dec_status == AVS3_DECODE_BUFEMPTY) {
+		if (dec->m_ins_flag) {
+			if (!vdec_frame_based(hw_to_vdec(dec)))
+				dec_again_process(dec);
+			else {
+				dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 1) {
+					amhevc_stop_f();
+				} else
+#endif
+				amhevc_stop();
+				vdec_schedule_work(&dec->work);
+			}
+		}
+		goto irq_handled_exit;
+	} else if ((dec_status == HEVC_DECPIC_DATA_DONE) ||
+		(dec_status == HEVC_DECPIC_DATA_ERROR)) {
+		struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+		u32 shiftbytes = 0;
+
+		if (pic != NULL)
+			pic->poc = ctx->info.pic_header.dtr;
+		mutex_lock(&dec->slice_header_lock);
+		mutex_unlock(&dec->slice_header_lock);
+		if (dec_status == HEVC_DECPIC_DATA_DONE)
+			vdec->front_pic_done = true;
+
+		if (pic && (vdec_stream_based(hw_to_vdec(dec)))
+			&& (dec_status == HEVC_DECPIC_DATA_DONE))
+			pic->stream_size = vdec_get_stream_size(hw_to_vdec(dec));
+
+		WRITE_VREG(HEVC_PARSER_DEBUG_IDX, 0xb);
+		shiftbytes = READ_VREG(HEVC_PARSER_DEBUG_DAT) & 0xffff;
+		if ((shiftbytes > over_decoder_shiftbytes) && (pic != NULL)) {
+			pic->error_mark = 1;
+			avs3_print(dec, PRINT_FLAG_VDEC_STATUS, "%s: over decoder(0x%x),set pic error\n",
+				__func__, shiftbytes);
+		}
+
+		if (dec->front_back_mode == 0) {
+			avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+				"HEVC_DECPIC_DATA_DONE: decode_idx %d stream crc %x shiftcnt=0x%x, HEVC_SAO_CRC %x HEVC_SAO_MMU_STATUS %x\n",
+				dec->frame_count,
+				READ_VREG(HEVC_STREAM_CRC),
+				READ_VREG(HEVC_SHIFT_BYTE_COUNT),
+				READ_VREG(HEVC_SAO_CRC),
+				READ_VREG(HEVC_SAO_MMU_STATUS));
+
+			if (debug & AVS3_DBG_BUFMGR_DETAIL) {
+				pr_info("HEVC_CM_BODY_START_ADDR = %x\n", READ_VREG(HEVC_CM_BODY_START_ADDR));
+				pr_info("HEVC_CM_HEADER_START_ADDR = %x\n", READ_VREG(HEVC_CM_HEADER_START_ADDR));
+				pr_info("HEVC_SAO_Y_START_ADDR = %x\n", READ_VREG(HEVC_SAO_Y_START_ADDR));
+				pr_info("HEVC_SAO_Y_LENGTH = %x\n", READ_VREG(HEVC_SAO_Y_LENGTH));
+				pr_info("HEVC_SAO_C_START_ADDR = %x\n", READ_VREG(HEVC_SAO_C_START_ADDR));
+				pr_info("HEVC_SAO_C_LENGTH = %x\n", READ_VREG(HEVC_SAO_C_LENGTH));
+				pr_info("HEVC_SAO_Y_WPTR = %x\n", READ_VREG(HEVC_SAO_Y_WPTR));
+				pr_info("HEVC_SAO_C_WPTR = %x\n", READ_VREG(HEVC_SAO_C_WPTR));
+
+				pr_info("HEVC_SAO_CTRL0 = %x\n", READ_VREG(HEVC_SAO_CTRL0));
+				pr_info("HEVC_SAO_CTRL1 = %x\n", READ_VREG(HEVC_SAO_CTRL1));
+				pr_info("HEVC_SAO_CTRL2 = %x\n", READ_VREG(HEVC_SAO_CTRL2));
+				pr_info("HEVC_SAO_CTRL3 = %x\n", READ_VREG(HEVC_SAO_CTRL3));
+				pr_info("HEVC_SAO_CTRL4 = %x\n", READ_VREG(HEVC_SAO_CTRL4));
+				pr_info("HEVC_SAO_CTRL5 = %x\n", READ_VREG(HEVC_SAO_CTRL5));
+
+			}
+			if ((debug & AVS3_DBG_NOT_RECYCLE_MMU_TAIL) == 0)
+				avs3_recycle_mmu_buf_tail(dec);
+		} else {
+			if (pic != NULL)
+				avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+					"FrontEnd data done %d, fb_rd_pos %d, pic index %d, poc %d stream crc %x shiftbyte %x, shiftstatus 0x%x\n",
+					avs3_dec->frontend_decoded_count, avs3_dec->fb_rd_pos, pic->index, pic->poc,
+					READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT), READ_VREG(HEVC_SHIFT_STATUS));
+			else
+				avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+					"FrontEnd data done %d, fb_rd_pos %d, stream crc %x shiftbyte %x\n",
+					avs3_dec->frontend_decoded_count, avs3_dec->fb_rd_pos,
+					READ_VREG(HEVC_STREAM_CRC), READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+		}
+
+		dec->start_decoding_flag |= 0x3;
+		if (dec->m_ins_flag) {
+			if (dec_status == HEVC_DECPIC_DATA_ERROR &&
+				(pic != NULL)) {
+				pic->error_mark = 1;
+			}
+
+			set_cuva_data(dec);
+			update_decoded_pic(dec);
+			check_pic_error(dec, pic);
+			get_picture_qos_info(dec, false);
+			dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode) {
+				/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+				if (pic != NULL)
+					front_decpic_done_update(dec, 1); /*not multi pictures in one packe*/
+			} else
+#endif
+			amhevc_stop();
+			decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_EDN, TRACE_BASIC);
+			avs3_work_implement(dec);
+		}
+
+		goto irq_handled_exit;
+	}
+#if 0
+	if (dec_status == AVS3_EOS) {
+		if (dec->m_ins_flag)
+			reset_process_time(dec);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"AVS3_EOS, flush buffer\r\n");
+
+		avs3_post_process(&dec->avs3_dec);
+		avs3_prepare_display_buf(dec);
+
+		avs3_print(dec, AVS3_DBG_BUFMGR,
+			"send AVS3_10B_DISCARD_NAL\r\n");
+		WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_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 == AVS3_DECODE_OVER_SIZE) {
+		avs3_print(dec, 0,
+			"avs3  decode oversize !!\n");
+		debug |= (AVS3_DBG_DIS_LOC_ERROR_PROC |
+			AVS3_DBG_DIS_SYS_ERROR_PROC);
+		dec->fatal_error |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
+		goto irq_handled_exit;
+	}
+
+	if (dec_status == AVS3_HEAD_SEQ_READY)
+		start_code = SEQUENCE_HEADER_CODE;
+	else if (dec_status == AVS3_HEAD_PIC_I_READY)
+		start_code = I_PICTURE_START_CODE;
+	else if (dec_status == AVS3_HEAD_PIC_PB_READY)
+		start_code = PB_PICTURE_START_CODE;
+	else if (dec_status == AVS3_HEAD_SEQ_END_READY)
+		start_code = SEQUENCE_END_CODE;
+	else if (dec_status == AVS3_STARTCODE_SEARCH_DONE)
+		/*VIDEO_EDIT_CODE*/
+		start_code = READ_VREG(CUR_NAL_UNIT_TYPE);
+	else
+		goto irq_handled_exit_and_start_timer;
+
+	if (dec->process_state ==
+			PROC_STATE_HEAD_AGAIN
+			) {
+		if ((start_code == I_PICTURE_START_CODE)
+		|| (start_code == PB_PICTURE_START_CODE)) {
+			avs3_print(dec, 0,
+				"PROC_STATE_HEAD_AGAIN error, start_code 0x%x!!!\r\n",
+				start_code);
+			goto irq_handled_exit_and_start_timer;
+		} else {
+			avs3_print(dec, AVS3_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, AVS3_ACTION_DONE);
+			goto irq_handled_exit_and_start_timer;
+		}
+	} else if (dec->process_state ==
+			PROC_STATE_DECODE_AGAIN) {
+		if ((start_code == I_PICTURE_START_CODE)
+		|| (start_code == PB_PICTURE_START_CODE)) {
+			avs3_print(dec, AVS3_DBG_BUFMGR,
+				"PROC_STATE_DECODE_AGAIN=> decode_slice, start_code 0x%x\r\n",
+				start_code);
+			if ((dec->front_back_mode == 1) && (dec->pic_list_init_flag == 0) && (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATE_DONE)) {
+				dec->pic_list_init_flag = 1;
+				goto alloc_buffer_done;
+			}
+			else
+				goto decode_slice;
+		} else {
+			avs3_print(dec, 0,
+				"PROC_STATE_DECODE_AGAIN, start_code 0x%x!!!\r\n",
+				start_code);
+			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+			goto irq_handled_exit_and_start_timer;
+		}
+	}
+
+	if ((start_code == I_PICTURE_START_CODE)
+		|| (start_code == PB_PICTURE_START_CODE)
+		|| (start_code == SEQUENCE_END_CODE)
+		|| (start_code == VIDEO_EDIT_CODE)) {
+
+		if (dec->avs3_dec.cur_pic != NULL) {
+#ifndef NEW_FB_CODE
+			int32_t ii;
+#endif
+			if (debug & AVS3_DBG_PRINT_PIC_LIST)
+				print_pic_pool(avs3_dec, "before post process");
+
+			ret = avs3_bufmgr_post_process(avs3_dec);
+
+			if (ret == 2) {
+				avs3_print(dec, AVS3_DBG_BUFMGR, "avs3 same poc %d\n",
+					avs3_dec->ctx.ptr);
+				pic_backend_ref_operation(dec, dec->avs3_dec.cur_pic, 0);
+			}
+
+			if (debug & AVS3_DBG_PRINT_PIC_LIST)
+				print_pic_pool(&dec->avs3_dec, "after post_process");
+
+			if ((dec->front_back_mode != 1) || !efficiency_mode)
+				avs3_prepare_display_buf(dec);
+			dec->avs3_dec.cur_pic = NULL;
+#ifdef NEW_FB_CODE
+			//release_free_mmu_buffers(dec);
+#else
+#endif
+		}
+	}
+
+	if ((dec_status == AVS3_HEAD_PIC_I_READY)
+		|| (dec_status == AVS3_HEAD_PIC_PB_READY)) {
+
+		if (debug & AVS3_DBG_SEND_PARAM_WITH_REG) {
+			get_rpm_param(
+				&dec->avs3_dec.param);
+		} else {
+			decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_START, TRACE_BASIC);
+			for (i = 0; i < (RPM_VALID_END - RPM_BEGIN); i += 4) {
+				int ii;
+				for (ii = 0; ii < 4; ii++)
+					dec->avs3_dec.param.l.data[i + ii] =
+						dec->rpm_ptr[i + 3 - ii];
+			}
+			decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_RPM_END, TRACE_BASIC);
+		}
+#if 0 //def SANITY_CHECK
+		if (dec->avs3_dec.param.p.num_of_ref_cur >
+			dec->avs3_dec.ref_maxbuffer) {
+			pr_info("Warning: Wrong num_of_ref_cur %d, force to %d\n",
+				dec->avs3_dec.param.p.num_of_ref_cur,
+				dec->avs3_dec.ref_maxbuffer);
+			dec->avs3_dec.param.p.num_of_ref_cur =
+				dec->avs3_dec.ref_maxbuffer;
+		}
+#endif
+
+		debug_buffer_mgr_more(dec);
+		get_frame_rate(&dec->avs3_dec.param, dec);
+
+		if (dec->avs3_dec.param.p.video_signal_type & (1<<14)) {
+			union param_u *pPara;
+
+			avs3_print(dec, AVS3_DBG_HDR_INFO, "avs3 HDR meta data present\n");
+			pPara = &dec->avs3_dec.param;
+
+			/*clean this flag*/
+			pPara->p.video_signal_type &= ~(1<<14);
+
+			dec->vf_dp.present_flag = 1;
+
+			dec->vf_dp.white_point[0]
+				= pPara->p.white_point_x;
+			avs3_print(dec, AVS3_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;
+			avs3_print(dec, AVS3_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];
+				avs3_print(dec, AVS3_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];
+				avs3_print(dec, AVS3_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;
+			avs3_print(dec, AVS3_DBG_HDR_INFO,
+				"luminance[0]:0x%x\n",
+				dec->vf_dp.luminance[0]);
+
+			dec->vf_dp.luminance[1]
+				= pPara->p.min_display_mastering_luminance;
+			avs3_print(dec, AVS3_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;
+			avs3_print(dec, AVS3_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;
+
+			avs3_print(dec, AVS3_DBG_HDR_INFO,
+				"max_pic_average:0x%x\n",
+				dec->vf_dp.content_light_level.max_pic_average);
+		}
+		if (dec->video_ori_signal_type !=
+			((dec->avs3_dec.param.p.video_signal_type << 16)
+			| dec->avs3_dec.param.p.color_description)) {
+			u32 v = dec->avs3_dec.param.p.video_signal_type;
+			u32 c = dec->avs3_dec.param.p.color_description;
+			u32 convert_c = c;
+
+			if (v & 0x2000) {
+				avs3_print(dec, AVS3_DBG_HDR_INFO,
+					"video_signal_type present:\n");
+				avs3_print(dec, AVS3_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;
+
+					avs3_print(dec, AVS3_DBG_HDR_INFO,
+						"color_description present:\n");
+					avs3_print(dec, AVS3_DBG_HDR_INFO,
+						"color_primarie = %d\n",
+						v & 0xff);
+					avs3_print(dec, AVS3_DBG_HDR_INFO,
+						"transfer_characteristic = %d\n",
+						(c >> 8) & 0xff);
+					avs3_print(dec, AVS3_DBG_HDR_INFO,
+						"  matrix_coefficient = %d\n",
+						c & 0xff);
+
+					transfer = (c >> 8) & 0xFF;
+					if (transfer >= 15)
+						avs3_print(dec, AVS3_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)
+						avs3_print(dec, AVS3_DBG_HDR_INFO,
+							"unsupport matrix_coefficient\n");
+					else if (maxtrix == 9)
+						maxtrix = 10;
+					else if (maxtrix == 8)
+						maxtrix = 9;
+
+					convert_c = (transfer << 8) | (maxtrix);
+
+					avs3_print(dec, AVS3_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
+
+	if (start_code == SEQUENCE_HEADER_CODE) {
+		avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+			" ## SEQUENCE_HEADER_CODE ##\n");
+		dec->avs3_dec.seq_change_flag = 1;
+		dec->avs3_dec.init_hw_flag = 0;
+	}
+
+	if (dec->has_i_frame == 0 &&
+		start_code == PB_PICTURE_START_CODE) {
+		dec->dec_result = DEC_RESULT_DONE;
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode == 1)
+			amhevc_stop_f();
+		else
+#endif
+		amhevc_stop();
+		avs3_print(dec, 0, "no i frame!!\n");
+		vdec_schedule_work(&dec->work);
+		goto irq_handled_exit;
+	}
+
+	mutex_lock(&dec->slice_header_lock);
+	if (start_code == SEQUENCE_END_CODE) {
+		avs3_bufmgr_process(&dec->avs3_dec, SEQUENCE_END_CODE);
+		WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+	} else if (start_code == SEQUENCE_HEADER_CODE ||
+		start_code == VIDEO_EDIT_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, AVS3_ACTION_DONE);
+	} else if (start_code == I_PICTURE_START_CODE ||
+		start_code == PB_PICTURE_START_CODE) {
+		avs3_frame_t *cur_pic;
+		ret = 0;
+#ifdef NEW_FB_CODE
+		if (dec->m_ins_flag) {
+			u32 width = avs3_dec->param.p.sqh_horizontal_size;
+			u32 height = avs3_dec->param.p.sqh_vertical_size;
+			u8 bit_depth = (u8)avs3_dec->param.p.sqh_encoding_precision;
+			int cur_mmu_fb_4k_number = 0;
+
+			width = ((width + MINI_SIZE - 1) >> MINI_SIZE_LOG2) << MINI_SIZE_LOG2;
+			height = ((height   + MINI_SIZE - 1) >> MINI_SIZE_LOG2) << MINI_SIZE_LOG2;
+			bit_depth = (bit_depth == 2) ? 10 : 8;
+			cur_mmu_fb_4k_number = dec->fb_ifbuf_num * avs3_mmu_page_num(dec,
+				width, height, (bit_depth == 10));
+
+			if ((dec->front_back_mode == 1) &&
+				(start_code == I_PICTURE_START_CODE) &&
+				(dec->mmu_fb_4k_number < cur_mmu_fb_4k_number) &&
+				(cur_mmu_fb_4k_number > 0)) {
+				amhevc_stop_f();
+				avs3_print(dec, AVS3_DBG_BUFMGR, "need realloc mmu fb\n");
+				uninit_mmu_fb_bufstate(dec);
+				init_mmu_fb_bufstate(dec, cur_mmu_fb_4k_number);
+				dec_again_process(dec);
+				mutex_unlock(&dec->slice_header_lock);
+				goto irq_handled_exit;
+			}
+		}
+#endif
+
+		avs3_print(dec, AVS3_DBG_BUFMGR, "========== Picture %d\n", avs3_dec->decode_id++);
+		//avs3_dec->ins_offset = 0; //move to init_pic_list_hw_fb
+		if (debug & AVS3_DBG_PRINT_PIC_LIST)
+			print_pic_pool(avs3_dec, "before bufmgr process");
+		if (is_avs3_print_param()) {
+			print_param(&avs3_dec->param);
+			print_alf_param(&avs3_dec->param);
+		}
+
+		decoder_trace(dec->trace.decode_header_memory_time_name, 9, TRACE_BASIC);
+
+		if (avs3_dec->seq_change_flag) {
+		avs3_bufmgr_process(avs3_dec, SEQUENCE_HEADER_CODE);
+		avs3_dec->seq_change_flag = 0;
+		}
+		ret = avs3_bufmgr_process(avs3_dec, start_code);
+		if (debug & AVS3_DBG_PRINT_PIC_LIST)
+			print_pic_pool(avs3_dec, "after bufmgr process");
+
+
+		if ((ret == 0) && (avs3_dec->cur_pic != NULL)) {
+			cur_pic = avs3_dec->cur_pic;
+#ifdef NEW_FRONT_BACK_CODE
+			cur_pic->width = avs3_dec->img.width;
+			cur_pic->height = avs3_dec->img.height;
+			cur_pic->depth = avs3_dec->input.sample_bit_depth;
+#endif
+
+			if (!dec->m_ins_flag)
+				dec->slice_idx++;
+			else
+				release_cuva_data(cur_pic);
+		}
+
+#if 0
+				if (avs3_dec->init_hw_flag == 0) {
+					//from simulation
+				init_pic_list_hw(avs3_dec, buf_spec, mc_buf_spec);
+				avs3_dec->init_hw_flag = 1;
+				}
+#else
+		if ((dec->pic_list_init_flag == 0) && (ctx->init_flag != 0)) {
+			int32_t lcu_size_log2 = avs3_dec->lcu_size_log2;
+
+			if ((dec->front_back_mode == 1) && (paral_alloc_buffer_mode & 1)) {
+				if ((dec->pic_list_wait_alloc_done_flag == BUFFER_INIT)) {
+					dec->dec_result = DEC_RESULT_WAIT_BUFFER;
+					avs3_print(dec, AVS3_DBG_BUFMGR, "alloc buffer\n");
+					vdec_schedule_work(&dec->work);
+					mutex_unlock(&dec->slice_header_lock);
+					goto irq_handled_exit;
+				}
+			} else
+				init_pic_list(dec, lcu_size_log2);
+
+#ifdef NEW_FB_CODE
+			if ((dec->front_back_mode == 1) ||
+				(dec->front_back_mode == 3))
+				init_pic_list_hw_fb(dec);
+			else
+#endif
+				init_pic_list_hw(dec);
+#endif
+			dec->pic_list_init_flag = 1;
+		}
+
+		decoder_trace(dec->trace.decode_header_memory_time_name, 10, TRACE_BASIC);
+alloc_buffer_done:
+
+#ifdef I_ONLY_SUPPORT
+		if ((start_code == PB_PICTURE_START_CODE) &&
+			(dec->i_only & 0x2))
+			ret = -2;
+#endif
+
+		if (ret == 0) {
+#ifdef AVS3_10B_MMU
+			if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+				&& (dec->front_back_mode != 1)
+#endif
+				) {
+#if 0
+//DDD
+				if (cur_pic->index == -1) {
+					pr_info("dec->avs3_dec.ctx.pic %p\n", dec->avs3_dec.ctx.pic);
+					print_pic_pool(avs3_dec, "error");
+				}
+#endif
+				ret = avs3_alloc_mmu(dec,
+					cur_pic->index,
+					cur_pic->width,
+					cur_pic->height,
+					cur_pic->depth,
+					dec->frame_mmu_map_addr);
+				if (ret >= 0) {
+					dec->cur_fb_idx_mmu =
+						cur_pic->index;
+					cur_pic->mmu_alloc_flag = 1;
+				} else
+					pr_err("can't alloc need mmu1,idx %d ret =%d\n",
+						cur_pic->index,
+						ret);
+			}
+#endif
+#ifdef AVS3_10B_MMU_DW
+			if (dec->dw_mmu_enable
+#ifdef NEW_FB_CODE
+				&& (dec->front_back_mode != 1)
+#endif
+				) {
+				ret = avs3_alloc_dw_mmu(dec,
+					cur_pic->index,
+					cur_pic->width,
+					cur_pic->height,
+					cur_pic->depth,
+					dec->dw_frame_mmu_map_addr);
+				if (ret >= 0) {
+					dec->cur_fb_idx_mmu =
+						cur_pic->index;
+					cur_pic->mmu_alloc_flag = 1;
+				} else
+					pr_err("can't alloc need dw mmu1,idx %d ret =%d\n",
+						dec->avs3_dec.cur_pic->index,
+						ret);
+			}
+#endif
+		}
+
+#ifndef MV_USE_FIXED_BUF
+		decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_START, TRACE_BASIC);
+
+		if (ret == 0 && cur_pic->
+			mpred_mv_wr_start_addr == 0
+#if 0 //def NEW_FB_CODE
+			&& (dec->front_back_mode != 1)
+#endif
+			) {
+			unsigned long buf_addr;
+			unsigned mv_buf_size = get_mv_buf_size(
+				dec,
+				cur_pic->width,
+				cur_pic->height);
+			int i = 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 {
+				cur_pic->mpred_mv_wr_start_addr = buf_addr;
+				if (!vdec_secure(hw_to_vdec(dec)))
+					codec_mm_memset(cur_pic->mpred_mv_wr_start_addr,
+						0, mv_buf_size);
+			}
+		}
+
+		decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_MEMORY_END, TRACE_BASIC);
+#endif
+		if (ret) {
+			avs3_print(dec, AVS3_DBG_BUFMGR,
+				"avs3_bufmgr_process=> %d, AVS3_10B_DISCARD_NAL\r\n",
+				ret);
+			WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_10B_DISCARD_NAL);
+	#ifdef AVS3_10B_MMU
+			if (dec->mmu_enable
+#ifdef NEW_FB_CODE
+				&& (dec->front_back_mode != 1)
+#endif
+				)
+				avs3_recycle_mmu_buf(dec);
+	#endif
+			if (dec->m_ins_flag) {
+				int slice_type = 0;
+
+#ifdef NEW_FB_CODE
+				mutex_lock(&dec->fb_mutex);
+#endif
+				if (avs3_dec->cur_pic != NULL) {
+					slice_type = avs3_dec->cur_pic->slice_type;
+				} else {
+					slice_type = dec->avs3_dec.param.p.pic_header_slice_type;
+				}
+
+				dec->gvs->frame_count++;
+				dec->gvs->drop_frame_count++;
+				dec->gvs->error_frame_count++;
+
+				if (slice_type == SLICE_I) {
+					dec->gvs->i_lost_frames++;
+					dec->gvs->i_concealed_frames++;
+					dec->gvs->i_decoded_frames++;
+				} else if (slice_type == SLICE_P) {
+					dec->gvs->p_lost_frames++;
+					dec->gvs->p_concealed_frames++;
+					dec->gvs->p_decoded_frames++;
+				} else if (slice_type == SLICE_B) {
+					dec->gvs->b_lost_frames++;
+					dec->gvs->b_concealed_frames++;
+					dec->gvs->b_decoded_frames++;
+				}
+
+#ifdef NEW_FB_CODE
+				mutex_unlock(&dec->fb_mutex);
+#endif
+
+				dec->dec_result = DEC_RESULT_ERROR;
+
+				vdec_schedule_work(&dec->work);
+			}
+			mutex_unlock(&dec->slice_header_lock);
+			goto irq_handled_exit;
+		} else {
+			if (avs3_dec->cur_pic != NULL) {
+				dec->gvs->frame_count++;
+				if (avs3_dec->cur_pic->slice_type == SLICE_I) {
+					dec->gvs->i_decoded_frames++;
+				} else if (avs3_dec->cur_pic->slice_type == SLICE_P) {
+					dec->gvs->p_decoded_frames++;
+				} else if (avs3_dec->cur_pic->slice_type == SLICE_B) {
+					dec->gvs->b_decoded_frames++;
+				}
+			}
+
+			dec->avs3_dec.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->avs3_dec.cur_pic->pts =
+				dec->chunk->pts;
+				dec->avs3_dec.cur_pic->pts64 =
+				dec->chunk->pts64;
+			}
+			if (vdec->mvfrm)
+				dec->avs3_dec.cur_pic->frame_size = vdec->mvfrm->frame_size;
+decode_slice:
+			dec->avs3_dec.cur_pic->double_write_mode
+				= get_double_write_mode(dec);
+#ifdef OW_TRIPLE_WRITE
+			dec->avs3_dec.cur_pic->triple_write_mode
+				= get_triple_write_mode(dec);
+#endif
+
+			decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_START, TRACE_BASIC);
+#ifdef NEW_FB_CODE
+			if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+				if (!efficiency_mode) {
+					config_mc_buffer_fb(dec);
+					config_mcrcc_axi_hw_fb(dec);
+				}
+
+				config_mpred_hw_fb(dec);
+
+				if (!efficiency_mode) {
+					config_dblk_hw_fb(dec);
+					config_sao_hw_fb(dec);
+					config_alf_hw_fb(dec);
+				}
+			} else {
+#endif
+				config_mc_buffer(dec);
+#ifdef NEW_FB_CODE
+				if (dec->front_back_mode == 0)
+#endif
+					config_mcrcc_axi_hw(dec);
+				config_mpred_hw(dec);
+				config_dblk_hw(dec);
+				config_sao_hw(dec);
+				config_alf_hw(dec);
+#ifdef NEW_FB_CODE
+			}
+#endif
+			decoder_trace(dec->trace.decode_header_memory_time_name, TRACE_HEADER_REGISTER_END, TRACE_BASIC);
+
+			// HEVC_PARSER_HEADER_INFO :
+			// bit[30]    --  avs3_bi_mid_ptr  // (ctx->ptr - ctx->refp[0][REFP_0].ptr == ctx->refp[0][REFP_1].ptr - ctx->ptr)
+			// bit[21:16] --  ctx->dpm.num_refp[REFP_1]
+			// bit[15:10] --  ctx->dpm.num_refp[REFP_0]
+			avs3_bi_mid_ptr = (ctx->ptr - ctx->refp[0][REFP_0].ptr == ctx->refp[0][REFP_1].ptr - ctx->ptr);
+			WRITE_VREG(HEVC_PARSER_HEADER_INFO, (ctx->dpm.num_refp[REFP_0]<<10) | (ctx->dpm.num_refp[REFP_1]<<16) | (avs3_bi_mid_ptr<<30));
+
+#ifdef BUFMGR_ONLY
+			WRITE_VREG(NAL_SEARCH_CTL, 0x1);
+#else
+			WRITE_VREG(NAL_SEARCH_CTL, 0);
+#endif
+
+#ifdef NEW_FRONT_BACK_CODE
+			if ((!efficiency_mode) && (dec->front_back_mode == 1 ||
+				dec->front_back_mode == 3)) {
+
+				WRITE_BACK_RET(avs3_dec);
+				avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+					"write system instruction, ins_offset = %d, addr = 0x%x\n",
+					avs3_dec->ins_offset, avs3_dec->fr.sys_imem_ptr);
+
+				avs3_dec->sys_imem_ptr = avs3_dec->fr.sys_imem_ptr;
+				avs3_dec->sys_imem_ptr_v = avs3_dec->fr.sys_imem_ptr_v;
+
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+				if (avs3_dec->ins_offset > 512) {
+					avs3_print(dec, 0,
+						"!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs3_dec->ins_offset);
+					avs3_dec->ins_offset = 512;
+				} else if (avs3_dec->ins_offset < 256) {
+					avs3_dec->ins_offset = 256;
+					WRITE_BACK_RET(avs3_dec);
+				}
+
+				memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+				//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+					avs3_dec->sys_imem_ptr_v,
+					((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+					((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+				avs3_dec->sys_imem_ptr += 2 * FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+				avs3_dec->sys_imem_ptr_v += 2 * FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+				if (avs3_dec->ins_offset > 256) {
+					avs3_print(dec, 0,
+						"!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs3_dec->ins_offset);
+					avs3_dec->ins_offset = 256;
+				}
+
+				memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+				//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+				avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+					"cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+					avs3_dec->sys_imem_ptr_v,
+					((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+					((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+				avs3_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+				avs3_dec->sys_imem_ptr_v +=FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+				if (avs3_dec->sys_imem_ptr >= avs3_dec->fb_buf_sys_imem.buf_end) {
+					avs3_print(dec, AVS3_DBG_BUFMGR,
+						"sys_imem_ptr is 0x%x, wrap around\n", avs3_dec->sys_imem_ptr);
+					avs3_dec->sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+					avs3_dec->sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr;
+				}
+				if (dec->front_back_mode == 1) {
+					//WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+					//WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+					//imem_count++;
+					WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+				}
+
+				WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+			} else {
+				WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+			}
+#endif
+
+			//WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+			//pr_info("!!write AVS3_ACTION_DONE %d\n", __LINE__);
+
+			if ((debug_again & 0x2) &&
+				dec->process_state ==
+				PROC_STATE_INIT) {
+				dec->process_state = PROC_STATE_DECODING;
+				dec_again_process(dec);
+				mutex_unlock(&dec->slice_header_lock);
+				goto irq_handled_exit;
+			}
+
+			dec->process_state = PROC_STATE_DECODING;
+
+		}
+		if (start_code == I_PICTURE_START_CODE)
+			dec->has_i_frame = 1;
+		if (dec->m_ins_flag)
+			start_process_time(dec);
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_START, CORE_MASK_HEVC);
+	}
+
+	if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+		(dec_status == AVS3_HEAD_PIC_PB_READY)) {
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_THREAD_HEAD_END, TRACE_PERFORMANCE_DETAIL);
+	}
+	if (efficiency_mode && (dec->front_back_mode == 1)) {
+		if (dec->pic_list_init_flag) {
+#ifdef NEW_FB_CODE
+			if ((dec->front_back_mode == 1) ||
+				(dec->front_back_mode == 3))
+				init_pic_list_hw_fb(dec);
+			else
+#endif
+				init_pic_list_hw(dec);
+		}
+
+		if ((dec->front_back_mode == 1 || dec->front_back_mode == 3) &&
+			(start_code == I_PICTURE_START_CODE ||
+			start_code == PB_PICTURE_START_CODE)) {
+
+			int32_t g_WqMDefault4x4[16] = {
+				64,     64,     64,     68,
+				64,     64,     68,     72,
+				64,     68,     76,     80,
+				72,     76,     84,     96
+			};
+
+			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
+			};
+			config_mc_buffer_fb(dec);
+			config_mcrcc_axi_hw_fb(dec);
+			config_dblk_hw_fb(dec);
+			config_sao_hw_fb(dec);
+			config_alf_hw_fb(dec);
+			// 4x4
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 64); // default seq_wq_matrix_4x4 begin address
+			for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault4x4[i]);
+
+			// 8x8
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0); // default seq_wq_matrix_8x8 begin address
+			for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, g_WqMDefault8x8[i]);
+
+			// 4x4
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 64); // default seq_wq_matrix_4x4 begin address
+			for (i = 0; i < 16; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault4x4[i]);
+
+			// 8x8
+			WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR_DBE1, 0); // default seq_wq_matrix_8x8 begin address
+			for (i = 0; i < 64; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA_DBE1, g_WqMDefault8x8[i]);
+
+			WRITE_BACK_RET(avs3_dec);
+			avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+				"write system instruction, ins_offset = %d, addr = 0x%x\n",
+				avs3_dec->ins_offset, avs3_dec->fr.sys_imem_ptr);
+
+			avs3_dec->sys_imem_ptr = avs3_dec->fr.sys_imem_ptr;
+			avs3_dec->sys_imem_ptr_v = avs3_dec->fr.sys_imem_ptr_v;
+#ifdef LARGE_INSTRUCTION_SPACE_SUPORT
+			if (avs3_dec->ins_offset > 512) {
+				avs3_print(dec, 0,
+					"!!!!!Error!!!!!!!!, ins_offset %d is too big (>512)\n", avs3_dec->ins_offset);
+				avs3_dec->ins_offset = 512;
+			} else if (avs3_dec->ins_offset < 256) {
+				avs3_dec->ins_offset = 256;
+				WRITE_BACK_RET(avs3_dec);
+			}
+			memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+				avs3_dec->sys_imem_ptr_v,
+				((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+				((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+
+			avs3_dec->sys_imem_ptr += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs3_dec->sys_imem_ptr_v += 2*FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#else
+			if (avs3_dec->ins_offset > 256) {
+				avs3_print(dec, 0,
+					"!!!!!Error!!!!!!!!, ins_offset %d is too big (>256)\n", avs3_dec->ins_offset);
+				avs3_dec->ins_offset = 256;
+			}
+			memcpy(avs3_dec->sys_imem_ptr_v, (void*)(&avs3_dec->instruction[0]), avs3_dec->ins_offset*4);
+			//copyToDDR_32bits(dec->fr.sys_imem_ptr, instruction, ins_offset*4, 0);
+			avs3_print(dec, AVS3_DBG_BUFMGR_DETAIL,
+				"cur_imem_ptr_v 0x%x: %02x %02x %02x %02x\n",
+				avs3_dec->sys_imem_ptr_v,
+				((u8 *)avs3_dec->sys_imem_ptr_v)[0], ((u8 *)avs3_dec->sys_imem_ptr_v)[1],
+				((u8 *)avs3_dec->sys_imem_ptr_v)[2], ((u8 *)avs3_dec->sys_imem_ptr_v)[3]);
+			avs3_dec->sys_imem_ptr += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+			avs3_dec->sys_imem_ptr_v += FB_IFBUF_SYS_IMEM_BLOCK_SIZE;
+#endif
+			if (avs3_dec->sys_imem_ptr >= avs3_dec->fb_buf_sys_imem.buf_end) {
+				avs3_print(dec, AVS3_DBG_BUFMGR,
+					"sys_imem_ptr is 0x%x, wrap around\n", avs3_dec->sys_imem_ptr);
+				avs3_dec->sys_imem_ptr = avs3_dec->fb_buf_sys_imem.buf_start;
+				avs3_dec->sys_imem_ptr_v = avs3_dec->fb_buf_sys_imem_addr;
+			}
+			if (dec->front_back_mode == 1) {
+				//WRITE_VREG(HEVC_ASSIST_RING_F_INDEX, 8);
+				//WRITE_VREG(HEVC_ASSIST_RING_F_WPTR, sys_imem_ptr);
+				//imem_count++;
+				WRITE_VREG(DOS_HEVC_STALL_START, 0); // disable stall
+			}
+		}
+
+		if ((start_code == I_PICTURE_START_CODE)
+			|| (start_code == PB_PICTURE_START_CODE)
+			|| (start_code == SEQUENCE_END_CODE)
+			|| (start_code == VIDEO_EDIT_CODE)) {
+			avs3_prepare_display_buf(dec);
+		}
+	}
+	mutex_unlock(&dec->slice_header_lock);
+
+irq_handled_exit_and_start_timer:
+	if (dec->m_ins_flag)
+		start_process_time(dec);
+
+irq_handled_exit:
+
+	dec->process_busy = 0;
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t vavs3_isr(int irq, void *data)
+{
+	//int i;
+	unsigned int dec_status;
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)data;
+	uint debug_tag = 0;
+#if 0
+	if ((debug & AVS3_DBG_BE_SIMULATE_IRQ)
+		&&(READ_VREG(DEBUG_REG1_DBE) ||
+			READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+	}
+#endif
+
+	dec_status = READ_VREG(HEVC_DEC_STATUS_REG);
+	if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		vdec_profile(hw_to_vdec(dec), VDEC_PROFILE_DECODER_END, CORE_MASK_HEVC);
+	}
+
+	WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+	if ((dec_status == AVS3_HEAD_PIC_I_READY) ||
+		(dec_status == AVS3_HEAD_PIC_PB_READY)) {
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_HEAD_DONE, TRACE_PERFORMANCE_DETAIL);
+	} else if (dec_status == HEVC_DECPIC_DATA_DONE) {
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_PIC_DONE, TRACE_PERFORMANCE_DETAIL);
+	}
+
+
+	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 0
+	if (debug & AVS3_DBG_IRQ_EVENT) {
+		if (dec->front_back_mode != 1)
+			avs3_print(dec, 0,
+				"avs3 isr dec status  = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) HEVC_SAO_CRC %x\n",
+				dec_status, READ_HREG(DEBUG_REG1), 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),
+				(get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) ?
+					READ_VREG(HEVC_SAO_CRC) : 0
+			);
+		else {
+			avs3_print(dec, 0,
+				"avs3 isr dec status  = 0x%x, debug_tag 0x%x, lcu 0x%x shiftbyte 0x%x (%x %x lev %x, wr %x, rd %x) [BE] pc %x psr %x DEC_STATUS %x shiftstatus 0x%x\n",
+				dec_status, READ_HREG(DEBUG_REG1), 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),
+				READ_VREG(HEVC_MPC_E_DBE),
+				READ_VREG(HEVC_MPSR_DBE),
+				READ_VREG(HEVC_DEC_STATUS_DBE),
+				READ_VREG(HEVC_SHIFT_STATUS)
+			);
+		}
+	}
+#endif
+
+	if (udebug_flag)
+		debug_tag = READ_HREG(DEBUG_REG1);
+	if (debug_tag != 0) {
+#if 0
+		handle_ucode_dbg(dec, debug_tag);
+		dec->process_busy = 0;
+		return IRQ_HANDLED;
+#else
+		decoder_trace(dec->trace.decode_time_name, DECODER_ISR_END, TRACE_BASIC);
+		return IRQ_WAKE_THREAD;
+#endif
+	}
+
+	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 & AVS3_DBG_IRQ_EVENT)
+				avs3_print(dec, 0, "wait_buf\n");
+			return IRQ_HANDLED;
+		} else if (force_disp_pic_index) {
+			dec->process_busy = 0;
+			return IRQ_HANDLED;
+		}
+	}
+
+	if (dec->m_ins_flag)
+		reset_process_time(dec);
+
+	decoder_trace(dec->trace.decode_time_name, DECODER_ISR_END, TRACE_BASIC);
+	return IRQ_WAKE_THREAD;
+}
+
+#ifdef NEW_FB_CODE
+static void avs3_check_timer_back_func(struct timer_list *timer)
+{
+	struct AVS3Decoder_s *dec = container_of(timer,
+			struct AVS3Decoder_s, timer_back);
+
+	if (dec->init_flag == 0) {
+		if (dec->stat & STAT_TIMER_BACK_ARM) {
+			mod_timer(&dec->timer_back, jiffies + PUT_INTERVAL);
+		}
+		return;
+	}
+
+	if (
+		(decode_timeout_val_back > 0) &&
+		(dec->start_process_time_back > 0) &&
+		((1000 * (jiffies - dec->start_process_time_back) / HZ)
+			> decode_timeout_val_back)
+	) {
+		if (dec->decode_timeout_count_back > 0)
+			dec->decode_timeout_count_back--;
+		if (dec->decode_timeout_count_back == 0)
+			timeout_process_back(dec);
+	}
+
+#if 0
+	if (debug & AVS3_DBG_BE_SIMULATE_IRQ) {
+		//struct vdec_s *vdec = hw_to_vdec(dec);
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+		//if (avs3_back_irq_cb(vdec, 0) == IRQ_WAKE_THREAD)
+		//	avs3_back_threaded_irq_cb(vdec, 0);
+	}
+#endif
+	if ((dec->start_process_time_back > 0) &&
+		(dec->decode_timeout_count_back != 0) &&
+		!(error_handle_policy & 0x4) &&
+		(decode_timeout_val_back > 0)) {
+		int current_monitor_data = 0;
+
+		WRITE_VREG(HEVC_PATH_MONITOR_CTRL, (READ_VREG(HEVC_PATH_MONITOR_CTRL) & 0xfffffe0f) | 0x91);
+		current_monitor_data = READ_VREG(HEVC_PATH_MONITOR_DATA);
+		if (dec->last_monitor_data == current_monitor_data) {
+			if (dec->decode_timeout_count_back > 0)
+				dec->decode_timeout_count_back--;
+			if (dec->decode_timeout_count_back == 0) {
+				timeout_process_back(dec);
+			}
+		} else {
+			dec->decode_timeout_count_back = fast_timer_check_count;
+		}
+		dec->last_monitor_data = current_monitor_data;
+		mod_timer(timer, jiffies + 1);
+	} else
+		mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+#endif
+
+static void vavs3_put_timer_func(struct timer_list *timer)
+{
+	struct AVS3Decoder_s *dec = container_of(timer,
+		struct AVS3Decoder_s, timer);
+	//uint8_t empty_flag;
+	//unsigned int buf_level;
+
+	//enum receiver_start_e state = RECEIVER_INACTIVE;
+	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) {
+#ifndef PXP_DEBUG
+		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 & AVS3_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
+						(dec->ASSIST_MBOX0_IRQ_REG,
+						 0x1);
+				}
+			}
+
+			if ((debug & AVS3_DBG_DIS_SYS_ERROR_PROC) == 0) {
+				/* receiver has no buffer to recycle */
+				/*if ((state == RECEIVER_INACTIVE) &&
+					(kfifo_is_empty(&dec->display_q))) {
+				pr_info("avs3 something error,need reset\n");
+				}*/
+			}
+		}
+#endif
+	} 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 {
+						avs3_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_VREG(DEBUG_REG1, 0);
+	}
+	if (debug & AVS3_DBG_DUMP_DATA) {
+		debug &= ~AVS3_DBG_DUMP_DATA;
+		avs3_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 & AVS3_DBG_DUMP_PIC_LIST) {
+		print_pic_pool(&dec->avs3_dec, "");
+		debug &= ~AVS3_DBG_DUMP_PIC_LIST;
+	}
+	if (debug & AVS3_DBG_TRIG_SLICE_SEGMENT_PROC) {
+		WRITE_VREG(dec->ASSIST_MBOX0_IRQ_REG, 0x1);
+		debug &= ~AVS3_DBG_TRIG_SLICE_SEGMENT_PROC;
+	}
+	if (debug & AVS3_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 &= ~AVS3_DBG_DUMP_RPM_BUF;
+	}
+	if (debug & AVS3_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 &= ~AVS3_DBG_DUMP_LMEM_BUF;
+	}
+	/*if (debug & AVS3_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_VREG(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);
+		}
+#ifdef DEBUG_CMD
+		else if ((dbg_cmd & 0xf) == 2) {
+			d_dump(dec, dbg_cmd & (~0xf), 128, NULL, NULL);
+		}
+#endif
+		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_AVS3,
+			frame_width, frame_height, fps) > 0)
+			dec->saved_resolution = frame_width *
+			frame_height * fps;
+	}
+
+	if ((dec->start_process_time != 0) &&
+		!(error_handle_policy & 0x4) &&
+		(decode_timeout_val > 0)) {
+		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) {
+				timeout_process(dec);
+			}
+		} else {
+			dec->decode_timeout_count = fast_timer_check_count;
+			dec->last_lcu_idx = current_lcu_idx;
+		}
+
+		mod_timer(timer, jiffies + 1);
+	} else
+		mod_timer(timer, jiffies + PUT_INTERVAL);
+}
+
+int vavs3_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_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 vavs3_set_isreset(struct vdec_s *vdec, int isreset)
+{
+#ifndef PXP_DEBUG
+	is_reset = isreset;
+#endif
+	return 0;
+}
+
+static void vavs3_prot_init(struct AVS3Decoder_s *dec)
+{
+	unsigned int data32;
+
+	avs3_config_work_space_hw(dec);
+	if (dec->pic_list_init_flag)
+		init_pic_list_hw(dec);
+#ifdef TMP_DEBUG
+	avs2_init_decoder_hw(dec);
+#else
+	avs3_init_decoder_hw(dec);
+#endif
+#if 1
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%s\n", __func__);
+#if 0
+	data32 = READ_VREG(HEVC_STREAM_CONTROL);
+	data32 = data32 |
+		(1 << 0)/*stream_fetch_enable*/
+		;
+	WRITE_VREG(HEVC_STREAM_CONTROL, data32);
+#endif
+#if 0
+	data32 = READ_VREG(HEVC_SHIFT_STARTCODE);
+	if (data32 != 0x00000100) {
+		pr_info("avs3 prot init error %d\n", __LINE__);
+		return;
+	}
+	data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+	if (data32 != 0x00000300) {
+		pr_info("avs3 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("avs3 prot init error %d\n", __LINE__);
+		return;
+	}
+	data32 = READ_VREG(HEVC_SHIFT_EMULATECODE);
+	if (data32 != 0x9abcdef0) {
+		pr_info("avs3 prot init error %d\n", __LINE__);
+		return;
+	}
+#endif
+	WRITE_VREG(HEVC_SHIFT_STARTCODE, 0x00000100);
+	WRITE_VREG(HEVC_SHIFT_EMULATECODE, 0x00000000);
+
+// 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
+
+	WRITE_VREG(HEVC_WAIT_FLAG, 1);
+
+	/* WRITE_VREG(HEVC_MPSR, 1); */
+
+	/* clear mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_CLR_REG, 1);
+
+	/* enable mailbox interrupt */
+	WRITE_VREG(dec->ASSIST_MBOX0_MASK, 1);
+	/* disable PSCALE for hardware sharing */
+#ifndef FOR_S5
+	WRITE_VREG(HEVC_PSCALE_CTRL, 0);
+#endif
+
+	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, dec->ucode_log_phy_addr);
+#endif
+	config_cuva_buf(dec);
+	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_S5) {
+		WRITE_VREG(HEVC_SAO_CRC, 0);
+		if (dec->front_back_mode == 1)
+			WRITE_VREG(HEVC_SAO_CRC_DBE1, 0);
+	}
+
+}
+
+#ifdef I_ONLY_SUPPORT
+static int vavs3_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_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 vavs3_local_init(struct AVS3Decoder_s *dec)
+{
+	int i;
+	int ret;
+	int width, height;
+
+	dec->vavs3_ratio = dec->vavs3_amstream_dec_info.ratio;
+
+	dec->gvs = vzalloc(sizeof(struct vdec_info));
+	if (NULL == dec->gvs) {
+		avs3_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->vavs3_amstream_dec_info.width;
+	height = dec->vavs3_amstream_dec_info.height;
+	dec->frame_dur =
+		(dec->vavs3_amstream_dec_info.rate ==
+			0) ? 3600 : dec->vavs3_amstream_dec_info.rate;
+	if (width && height)
+		dec->frame_ar = height * 0x100 / width;
+/*
+TODO:FOR VERSION
+*/
+	avs3_print(dec, AVS3_DBG_BUFMGR,
+		"avs3: ver (%d,%d) decinfo: %dx%d rate=%d\n", avs3_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->vavs3_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 = avs3_local_init(dec);
+
+	return ret;
+}
+
+static s32 vavs3_init(struct vdec_s *vdec)
+{
+	int ret = -1, size = -1;
+	int fw_size = 0x1000 * 16;
+	struct firmware_s *fw = NULL;
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)vdec->private;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+#ifdef NEW_FB_CODE
+	struct firmware_s *fw_back = NULL;
+#endif
+
+	avs3_dec->start_time = div64_u64(local_clock(), 1000);
+	timer_setup(&dec->timer, vavs3_put_timer_func, 0);
+#ifdef NEW_FB_CODE
+	timer_setup(&dec->timer_back, avs3_check_timer_back_func, 0);
+	dec->stat |= STAT_TIMER_BACK_INIT;
+#endif
+
+	dec->stat |= STAT_TIMER_INIT;
+	if (vavs3_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;
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1 || dec->front_back_mode == 3) {
+		fw_back = vzalloc(sizeof(struct firmware_s) + fw_size);
+		if (IS_ERR_OR_NULL(fw_back))
+			return -ENOMEM;
+
+		size = get_firmware_data(VIDEO_DEC_AVS3_FRONT, fw->data);
+
+		fw_back->len = get_firmware_data(VIDEO_DEC_AVS3_BACK, fw_back->data);
+		if (fw_back->len < 0) {
+			pr_err("get back firmware fail.\n");
+			vfree(fw_back);
+			return -1;
+		}
+	} else
+#endif
+	size = get_firmware_data(VIDEO_DEC_AVS3, 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;
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->timer_back.expires = jiffies + PUT_INTERVAL;
+			dec->fw_back = fw_back;
+		}
+#endif
+		/*add_timer(&dec->timer);
+
+		dec->stat |= STAT_TIMER_ARM;
+		dec->stat |= STAT_ISR_REG;*/
+
+		INIT_WORK(&dec->work, avs3_work);
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			INIT_WORK(&dec->work_back, avs3_work_back);
+			INIT_WORK(&dec->timeout_work_back, avs3_timeout_work_back);
+			mutex_init(&dec->fb_mutex);
+		}
+#endif
+		dec->fw = fw;
+
+		return 0;
+	}
+
+	amhevc_enable();
+
+	ret = amhevc_loadmc_ex(VFORMAT_AVS3, NULL, fw->data);
+	if (ret < 0) {
+		amhevc_disable();
+		vfree(fw);
+		pr_err("AVS3: the %s fw loading failed, err: %x\n",
+			fw_tee_enabled() ? "TEE" : "local", ret);
+		return -EBUSY;
+	}
+
+	vfree(fw);
+
+	dec->stat |= STAT_MC_LOAD;
+
+	/* enable AMRISC side protocol */
+	vavs3_prot_init(dec);
+
+	if (vdec_request_threaded_irq(VDEC_IRQ_0,
+				vavs3_isr,
+				vavs3_isr_thread_fn,
+				IRQF_ONESHOT,/*run thread on this irq disabled*/
+				"vavs3-irq", (void *)dec)) {
+		pr_info("vavs3 irq register error.\n");
+		amhevc_disable();
+		return -ENOENT;
+	}
+	dec->stat |= STAT_ISR_REG;
+
+	dec->provider_name = PROVIDER_NAME;
+	vf_provider_init(&vavs3_vf_prov, PROVIDER_NAME,
+				&vavs3_vf_provider, dec);
+	vf_reg_provider(&vavs3_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;
+	avs3_print(dec, AVS3_DBG_BUFMGR_MORE,
+		"%d, vavs3_init, RP=0x%x\n",
+		__LINE__, READ_VREG(HEVC_STREAM_RD_PTR));
+	return 0;
+}
+
+static int vmavs3_stop(struct AVS3Decoder_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;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+#endif
+	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(&vavs3_vf_prov);
+		dec->stat &= ~STAT_VF_HOOK;
+	}
+	avs3_local_uninit(dec);
+	reset_process_time(dec);
+	cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		cancel_work_sync(&dec->work_back);
+		vfree(dec->fw_back);
+		dec->fw_back = NULL;
+	}
+#endif
+	uninit_mmu_buffers(dec);
+	if (dec->fw) {
+		vfree(dec->fw);
+		dec->fw = NULL;
+	}
+
+	return 0;
+}
+
+static int vavs3_stop(struct AVS3Decoder_s *dec)
+{
+
+	dec->init_flag = 0;
+	dec->first_sc_checked = 0;
+	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(dec->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;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && (dec->stat & STAT_TIMER_BACK_ARM)) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+#endif
+
+	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(&vavs3_vf_prov);
+		dec->stat &= ~STAT_VF_HOOK;
+	}
+	avs3_local_uninit(dec);
+
+	if (dec->m_ins_flag) {
+		cancel_work_sync(&dec->work);
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			cancel_work_sync(&dec->work_back);
+			vfree(dec->fw_back);
+			dec->fw_back = NULL;
+		}
+#endif
+	} else
+		amhevc_disable();
+	uninit_mmu_buffers(dec);
+
+	return 0;
+}
+
+static int amvdec_avs3_mmu_init(struct AVS3Decoder_s *dec)
+{
+	int tvp_flag = vdec_secure(hw_to_vdec(dec)) ?
+		CODEC_MM_FLAGS_TVP : 0;
+	int buf_size = 48;
+
+	dec->need_cache_size = buf_size * SZ_1M;
+	dec->sc_start_time = get_jiffies_64();
+#ifdef AVS3_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("avs3 alloc mmu box failed!!\n");
+			return -1;
+		}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+				dec->index, FRAME_BUFFERS,
+				dec->need_cache_size,
+				tvp_flag
+				);
+			if (!dec->mmu_box_1) {
+				pr_err("avs3 alloc mmu box1 failed!!\n");
+				return -1;
+			}
+		}
+	}
+#endif
+#ifdef AVS3_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("avs3 alloc dw mmu box failed!!\n");
+			dec->dw_mmu_enable = 0;
+		}
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode) {
+			dec->dw_mmu_box_1 = decoder_mmu_box_alloc_box(DRIVER_NAME,
+				dec->index, FRAME_BUFFERS,
+				dec->need_cache_size,
+				tvp_flag
+				);
+			if (!dec->dw_mmu_box_1) {
+				pr_err("avs3 alloc dw mmu box1 failed!!\n");
+				dec->dw_mmu_enable = 0;
+			}
+		}
+#endif
+	}
+#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,
+			BMMU_ALLOC_FLAGS_WAITCLEAR);
+	if (!dec->bmmu_box) {
+		pr_err("avs3 alloc bmmu box failed!!\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int amvdec_avs3_probe(struct platform_device *pdev)
+{
+	struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+	/*struct BUF_s BUF[MAX_BUF_NUM];*/
+	struct AVS3Decoder_s *dec = &gAVS3Decoder;
+	int ret;
+	pr_info("%s\n", __func__);
+
+	dec = vzalloc(sizeof(struct AVS3Decoder_s));
+	if (!dec)
+		return -ENOMEM;
+
+	pdata->private = dec;
+	platform_set_drvdata(pdev, pdata);
+
+	mutex_lock(&vavs3_mutex);
+
+	dec->init_flag = 0;
+	dec->first_sc_checked = 0;
+	dec->eos = 0;
+	dec->start_process_time = 0;
+	dec->timeout_num = 0;
+	dec->fatal_error = 0;
+	dec->show_frame_num = 0;
+	if (pdata == NULL) {
+		avs3_print(dec, 0,
+			"\namvdec_avs3 memory resource undefined.\n");
+		mutex_unlock(&vavs3_mutex);
+		return -EFAULT;
+	}
+	dec->m_ins_flag = 0;
+	dec->platform_dev = pdev;
+	platform_set_drvdata(pdev, pdata);
+
+#ifdef NEW_FB_CODE
+	dec->front_back_mode = 0;
+#endif
+	config_hevc_irq_num(dec);
+
+#ifdef AVS3_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_avs3_mmu_init(dec) < 0) {
+		mutex_unlock(&vavs3_mutex);
+		pr_err("avs3 alloc bmmu box failed!!\n");
+		return -1;
+	}
+
+	ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box, WORK_SPACE_BUF_ID,
+			work_buf_size, DRIVER_NAME, &pdata->mem_start);
+	if (ret < 0) {
+		uninit_mmu_buffers(dec);
+		mutex_unlock(&vavs3_mutex);
+		return ret;
+	}
+	dec->buf_size = work_buf_size;
+
+	dec->buf_start = pdata->mem_start;
+
+	if (debug) {
+		avs3_print(dec, 0,
+			"===AVS3 decoder mem resource 0x%lx size 0x%x\n",
+				pdata->mem_start, dec->buf_size);
+	}
+
+	if (pdata->sys_info) {
+		dec->vavs3_amstream_dec_info = *pdata->sys_info;
+		dec->frame_width = dec->vavs3_amstream_dec_info.width;
+		dec->frame_height = dec->vavs3_amstream_dec_info.height;
+	} else {
+		dec->vavs3_amstream_dec_info.width = 0;
+		dec->vavs3_amstream_dec_info.height = 0;
+		dec->vavs3_amstream_dec_info.rate = 30;
+	}
+	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 = vavs3_dec_status;
+	/*pdata->set_isreset = vavs3_set_isreset;*/
+	is_reset = 0;
+	if (vavs3_init(pdata) < 0) {
+		pr_info("\namvdec_avs3 init failed.\n");
+		avs3_local_uninit(dec);
+		uninit_mmu_buffers(dec);
+		pdata->dec_status = NULL;
+		mutex_unlock(&vavs3_mutex);
+		return -ENODEV;
+	}
+	/*set the max clk for smooth playing...*/
+	hevc_source_changed(VFORMAT_AVS3,
+			4096, 2048, 60);
+	mutex_unlock(&vavs3_mutex);
+
+	return 0;
+}
+
+static int amvdec_avs3_remove(struct platform_device *pdev)
+{
+	struct AVS3Decoder_s *dec = &gAVS3Decoder;
+	if (debug)
+		pr_info("amvdec_avs3_remove\n");
+
+	mutex_lock(&vavs3_mutex);
+
+	vavs3_stop(dec);
+
+	hevc_source_changed(VFORMAT_AVS3, 0, 0, 0);
+
+#ifdef DEBUG_PTS
+	pr_info("pts missed %ld, pts hit %ld, duration %d\n",
+			dec->pts_missed, dec->pts_hit, dec->frame_dur);
+#endif
+
+	mutex_unlock(&vavs3_mutex);
+
+	return 0;
+}
+
+/****************************************/
+
+static struct platform_driver amvdec_avs3_driver = {
+	.probe = amvdec_avs3_probe,
+	.remove = amvdec_avs3_remove,
+#ifdef CONFIG_PM
+	.suspend = amhevc_suspend,
+	.resume = amhevc_resume,
+#endif
+	.driver = {
+		.name = DRIVER_NAME,
+	}
+};
+static struct codec_profile_t amvdec_avs3_profile = {
+	.name = "avs3",
+	.profile = ""
+};
+
+static struct codec_profile_t amvdec_avs3_profile_mult;
+static unsigned char get_data_check_sum
+	(struct AVS3Decoder_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 AVS3Decoder_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;
+
+	avs3_print(dec, 0, "padding: ");
+	for (jj = padding_size; jj > 0; jj--)
+		avs3_print_cont(dec,
+			0,
+			"%02x ", *(data - jj));
+	avs3_print_cont(dec, 0, "data adr %p\n",
+		data);
+
+	for (jj = 0; jj < size; jj++) {
+		if ((jj & 0xf) == 0)
+			avs3_print(dec,
+				0,
+				"%06x:", jj);
+		avs3_print_cont(dec,
+			0,
+			"%02x ", data[jj]);
+		if (((jj + 1) & 0xf) == 0)
+			avs3_print(dec,
+				0,
+				"\n");
+	}
+	avs3_print(dec,
+		0,
+		"\n");
+
+	if (!dec->chunk->block->is_mapped)
+		codec_mm_unmap_phyaddr(data);
+}
+
+void wait_shift_byte_search_done(struct AVS3Decoder_s *dec)
+{
+	u32 shift_byte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+	int count = 0;
+	do {
+		usleep_range(1000, 1010);
+		if (shift_byte == READ_VREG(HEVC_SHIFT_BYTE_COUNT))
+			break;
+		if (count > 200) {
+			avs3_print(dec,
+			0, "%s timeout count %d vld_rp 0x%x VLD_MEM_VIFIFO_RP 0x%x\n",
+			 __func__, count, shift_byte, READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+			break;
+		} else
+			shift_byte = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+		count++;
+	} while (1);
+		pr_err("count %d, shift_byte 0x%x\n", count, shift_byte);
+}
+void wait_hevc_search_done(struct AVS3Decoder_s *dec)
+{
+	int count = 0;
+	WRITE_VREG(HEVC_SHIFT_STATUS, 0);
+	while (READ_VREG(HEVC_STREAM_CONTROL) & 0x2) {
+		usleep_range(100, 101);
+		count++;
+		if (count > 100) {
+			avs3_print(dec, 0, "%s timeout\n", __func__);
+			break;
+		}
+	}
+}
+
+static int avs3_wait_alloc_buf(void *args)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)args;
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	init_pic_list(dec, dec->avs3_dec.lcu_size_log2);
+
+	vdec_up(vdec);
+
+	return 0;
+}
+
+static void avs3_work_implement(struct AVS3Decoder_s *dec)
+{
+	struct vdec_s *vdec = hw_to_vdec(dec);
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+	/*if (dec->dec_result == DEC_RESULT_DONE)
+		decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_START, TRACE_BASIC);
+	else if (dec->dec_result == DEC_RESULT_AGAIN)
+		decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_AGAIN, TRACE_BASIC);*/
+
+	/* finished decoding one frame or error,
+	 * notify vdec core to switch context
+	 */
+	avs3_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) {
+			avs3_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;
+
+				avs3_print(dec,
+					PRINT_FLAG_VDEC_DETAIL,
+					"amvdec_avs3: Insufficient data\n");
+
+				vdec_schedule_work(&dec->work);
+				return;
+			}
+			dec->dec_result = DEC_RESULT_NONE;
+			avs3_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, AVS3_ACTION_DONE);
+
+			start_process_time(dec);
+
+		} else{
+			dec->dec_result = DEC_RESULT_GET_DATA_RETRY;
+
+			avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+				"amvdec_avs3: Insufficient data\n");
+
+			vdec_schedule_work(&dec->work);
+		}
+		return;
+	} else if ((dec->dec_result == DEC_RESULT_DONE) ||
+		(dec->dec_result == DEC_RESULT_ERROR)) {
+		struct avs3_frame_s *pic = dec->avs3_dec.cur_pic;
+		/* 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;
+
+		if ((pic != NULL) && (pic->error_mark) &&
+			(dec->dec_result == DEC_RESULT_DONE)) {
+#ifdef NEW_FB_CODE
+			mutex_lock(&dec->fb_mutex);
+#endif
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == SLICE_I) {
+				dec->gvs->i_concealed_frames++;
+			} else if (pic->slice_type == SLICE_P) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == SLICE_B) {
+				dec->gvs->b_concealed_frames++;
+			}
+
+			if (pic->backend_ref == 0) {
+				dec->gvs->drop_frame_count++;
+				if (pic->slice_type == SLICE_I) {
+					dec->gvs->i_lost_frames++;
+				} else if (pic->slice_type == SLICE_P) {
+					dec->gvs->p_lost_frames++;
+				} else if (pic->slice_type == SLICE_B) {
+					dec->gvs->b_lost_frames++;
+				}
+			}
+#ifdef NEW_FB_CODE
+			mutex_unlock(&dec->fb_mutex);
+#endif
+		}
+
+		avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"%s (===> %d) dec_result %d %x %x %x stream crc %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_STREAM_CRC),
+			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) {
+		DEC_CTX *avs3_ctx = &avs3_dec->ctx;
+		avs3_print(dec, 0,
+			"%s: end of stream\n",
+			__func__);
+		dec->eos = 1;
+		if (dec->avs3_dec.cur_pic != NULL) {
+			avs3_bufmgr_post_process(&dec->avs3_dec);
+		}
+
+		//output all pic;
+		avs3_ctx->info.pic_header.decode_order_index =
+			avs3_ctx->info.pic_header.decode_order_index + DOI_CYCLE_LENGTH;
+		avs3_prepare_display_buf(dec);
+		vdec_vframe_dirty(hw_to_vdec(dec), dec->chunk);
+	} else if (dec->dec_result == DEC_RESULT_FORCE_EXIT) {
+		avs3_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(dec->ASSIST_MBOX0_MASK, 0);
+			vdec_free_irq(VDEC_IRQ_0, (void *)dec);
+			dec->stat &= ~STAT_ISR_REG;
+		}
+	} else if (dec->dec_result == DEC_RESULT_WAIT_BUFFER) {
+		pr_err("DEC_RESULT_WAIT_BUFFER in\n");
+		vdec_post_task(avs3_wait_alloc_buf, dec);
+		dec->pic_list_wait_alloc_done_flag = BUFFER_ALLOCATING;
+		dec->process_state =
+			PROC_STATE_DECODE_AGAIN;
+	}
+
+#ifdef NEW_FRONT_BACK_CODE
+	if (!vdec->front_pic_done && (dec->front_back_mode == 1)) {
+		fb_hw_status_clear(true);
+		avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"%s, clear front, status 0x%x, status_back 0x%x\n",
+			__func__, dec->dec_status, dec->dec_status_back);
+	}
+#endif
+
+	if (dec->front_back_mode == 1)
+		amhevc_stop_f();
+
+	if (dec->stat & STAT_TIMER_ARM) {
+		del_timer_sync(&dec->timer);
+		dec->stat &= ~STAT_TIMER_ARM;
+	}
+
+	wait_hevc_search_done(dec);
+
+	if (dec->dec_result == DEC_RESULT_DONE)
+		decoder_trace(dec->trace.decode_time_name, DECODER_WORKER_END, TRACE_PERFORMANCE_DETAIL);
+
+	if (get_dbg_flag(dec) & AVS3_DBG_QOS_INFO) {
+		avs3_print(dec, 0, "%s:frame_count %d, drop_frame_count %d, error_frame_count %d\n",
+			__func__, dec->gvs->frame_count, dec->gvs->drop_frame_count, dec->gvs->error_frame_count);
+		avs3_print(dec, 0, "i decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->i_decoded_frames, dec->gvs->i_lost_frames, dec->gvs->i_concealed_frames);
+		avs3_print(dec, 0, "p decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->p_decoded_frames, dec->gvs->p_lost_frames, dec->gvs->p_concealed_frames);
+		avs3_print(dec, 0, "b decoded_frames %d, lost_frames %d, concealed_frames %d\n",
+			dec->gvs->b_decoded_frames, dec->gvs->b_lost_frames, dec->gvs->b_concealed_frames);
+	}
+
+	/* 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, CORE_MASK_HEVC);
+}
+
+static void avs3_work(struct work_struct *work)
+{
+	struct AVS3Decoder_s *dec = container_of(work,
+		struct AVS3Decoder_s, work);
+
+	avs3_work_implement(dec);
+}
+
+#ifdef NEW_FB_CODE
+static void avs3_work_back_implement(struct AVS3Decoder_s *dec,
+	struct vdec_s *vdec, int from)
+{
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"[BE] %s result %d\n", __func__, dec->dec_back_result);
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_WORKER_START);
+
+	if (dec->dec_back_result == DEC_BACK_RESULT_TIMEOUT) {
+		avs3_frame_t* pic = avs3_dec->next_be_decode_pic[avs3_dec->fb_rd_pos];
+
+		mutex_lock(&dec->fb_mutex);
+		if (pic->error_mark == 0) {
+			dec->gvs->error_frame_count++;
+			if (pic->slice_type == SLICE_I) {
+				dec->gvs->i_concealed_frames++;
+			} else if (pic->slice_type == SLICE_P) {
+				dec->gvs->p_concealed_frames++;
+			} else if (pic->slice_type == SLICE_B) {
+				dec->gvs->b_concealed_frames++;
+			}
+		}
+		mutex_lock(&dec->fb_mutex);
+		pic->error_mark = 1;  /* set error mark for timeout pic */
+		pic_backend_ref_operation(dec, pic, 0);
+		if (debug & AVS3_DBG_PRINT_PIC_LIST)
+			print_pic_pool(avs3_dec, "after dec backend_ref");
+
+		if (without_display_mode == 0) {
+			struct vframe_s *vf = NULL;
+			if (kfifo_peek(&dec->display_q, &vf) && vf) {
+				uint8_t index = vf->index & 0xff;
+				struct avs3_frame_s *peek_pic = get_pic_by_index(dec, index);
+				if (peek_pic == pic)
+					vf_notify_receiver(dec->provider_name,
+						VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+			}
+		} else
+			vavs3_vf_put(vavs3_vf_get(dec), dec);
+
+		if ((dec->front_back_mode == 1 ||
+			dec->front_back_mode == 3) && (error_handle_policy & 0x4))
+
+			release_free_mmu_buffers(dec);
+	}
+
+	avs3_dec->backend_decoded_count++;
+
+	mutex_lock(&dec->fb_mutex);
+	avs3_dec->fb_rd_pos++;
+	if (avs3_dec->fb_rd_pos >= dec->fb_ifbuf_num)
+		avs3_dec->fb_rd_pos = 0;
+
+	avs3_dec->wait_working_buf = 0;
+	mutex_unlock(&dec->fb_mutex);
+
+	WRITE_VREG(HEVC_DEC_STATUS_DBE, AVS3_DEC_IDLE);
+	if (dec->front_back_mode == 1)
+		amhevc_stop_b();
+
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+		"fb_wr_pos %d, set next fb_rd_pos %d, set wait_working_buf %d\n",
+		avs3_dec->fb_wr_pos, avs3_dec->fb_rd_pos, avs3_dec->wait_working_buf);
+
+	if (!vdec->back_pic_done && (dec->front_back_mode == 1)) {
+		fb_hw_status_clear(false);
+		avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"%s, clear back, status 0x%x, status_back 0x%x\n",
+			__func__, dec->dec_status, dec->dec_status_back);
+	}
+
+	if (dec->stat & STAT_TIMER_BACK_ARM) {
+		del_timer_sync(&dec->timer_back);
+		dec->stat &= ~STAT_TIMER_BACK_ARM;
+	}
+	ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_WORKER_END);
+
+	vdec_core_finish_run(vdec, CORE_MASK_HEVC_BACK);
+
+	if (dec->vdec_back_cb)
+		dec->vdec_back_cb(hw_to_vdec(dec), dec->vdec_back_cb_arg, CORE_MASK_HEVC_BACK);
+
+}
+
+static void avs3_work_back(struct work_struct *work)
+{
+	struct AVS3Decoder_s *dec = container_of(work,
+			struct AVS3Decoder_s, work_back);
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	avs3_work_back_implement(dec, vdec, 0);
+
+}
+
+static void avs3_timeout_work_back(struct work_struct *work)
+{
+	struct AVS3Decoder_s *dec = container_of(work,
+		struct AVS3Decoder_s, timeout_work_back);
+	struct vdec_s *vdec = hw_to_vdec(dec);
+
+	if (work_pending(&dec->work_back))
+		return;
+	avs3_work_back_implement(dec, vdec, 1);
+}
+#endif
+
+static int avs3_hw_ctx_restore(struct AVS3Decoder_s *dec)
+{
+	/* new to do ... */
+	vavs3_prot_init(dec);
+	return 0;
+}
+
+#ifdef NEW_FB_CODE
+	/*run_ready_back*/
+static unsigned long check_input_data(struct vdec_s *vdec, unsigned long mask)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+
+	if (fbdebug_flag & 0x1)
+		return 0;
+
+	if (((avs3_dec->fb_wr_pos != avs3_dec->fb_rd_pos) || avs3_dec->wait_working_buf) &&
+		(dec->front_back_mode))
+		return mask;
+	else
+		return 0;
+}
+#endif
+
+static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	int tvp = vdec_secure(hw_to_vdec(dec)) ?
+		CODEC_MM_FLAGS_TVP : 0;
+	unsigned long ret = 0;
+	unsigned int run_ready_case = 0;
+#if 0
+	if ((debug & AVS3_DBG_BE_SIMULATE_IRQ)
+		&&(READ_VREG(DEBUG_REG1_DBE) ||
+			READ_VREG(HEVC_DEC_STATUS_DBE)== HEVC_BE_DECODE_DATA_DONE)) {
+		pr_info("Simulate BE irq\n");
+		WRITE_VREG(dec->backend_ASSIST_MBOX0_IRQ_REG, 1);
+	}
+#endif
+	if (dec->pic_list_wait_alloc_done_flag == BUFFER_ALLOCATING)
+		return 0;
+
+	if ((fbdebug_flag & 0x2) &&
+		dec->front_back_mode &&
+		(dec->avs3_dec.cur_pic != NULL) &&
+		(dec->avs3_dec.cur_pic->back_done_mark == 0) &&
+		dec->next_again_flag == 0) {
+		run_ready_case = 1;
+		avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+		return 0;
+	}
+
+	if (debug & AVS3_DBG_PIC_LEAK_WAIT) {
+		run_ready_case = 2;
+		avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+		return ret;
+	}
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode && avs3_dec->wait_working_buf) {
+		run_ready_case = 3;
+		avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+		return 0xffffffff;
+	}
+#endif
+
+	if (dec->eos) {
+		run_ready_case = 4;
+		avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+		return ret;
+	}
+	if (!dec->first_sc_checked) {
+		int size = decoder_mmu_box_sc_check(dec->mmu_box, tvp);
+#ifdef NEW_FB_CODE
+/* to do:
+		for dec->mmu_box_1
+*/
+#endif
+		dec->first_sc_checked = 1;
+		avs3_print(dec, 0, "vavs3 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);
+			run_ready_case = 5;
+			avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d buf lelvel:%x\n", __func__, run_ready_case, 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;
+	else {
+		avs3_cleanup_useless_pic_buffer_in_pm(avs3_dec);
+		if (get_free_buf_count(dec) >= run_ready_min_buf_num)
+			ret = 1;
+		else
+			run_ready_case = 0;
+	}
+
+#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
+			) {
+			run_ready_case = 10;
+			ret = 0;
+		}
+		if (run_ready_display_q_num > 0 &&
+			kfifo_len(&dec->display_q) >=
+			run_ready_display_q_num) {
+			run_ready_case = 11;
+			ret = 0;
+		}
+
+		/*if (run_ready_max_buf_num == 0xff &&
+			get_used_buf_count(dec) >=
+			dec->avs3_dec.ref_maxbuffer) {
+			run_ready_case = 12;
+			ret = 0;
+		} else*/ if (run_ready_max_buf_num &&
+			get_used_buf_count(dec) >=
+			run_ready_max_buf_num) {
+			run_ready_case = 13;
+			ret = 0;
+		}
+	}
+#endif
+	if (ret)
+		not_run_ready[dec->index] = 0;
+	else {
+		not_run_ready[dec->index]++;
+		avs3_print(dec,
+			PRINT_FLAG_VDEC_DETAIL, "%s case%d\r\n", __func__, run_ready_case);
+	}
+
+	if (vdec->parallel_dec == 1)
+#ifdef NEW_FB_CODE
+		return ret ? mask : mask & ~(CORE_MASK_HEVC);
+#else
+		return ret ? CORE_MASK_HEVC : 0;
+#endif
+	else
+		return ret ? (CORE_MASK_VDEC_1 | CORE_MASK_HEVC) : 0;
+}
+
+#ifdef NEW_FB_CODE
+static void run_back(struct vdec_s *vdec, void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	int loadr = 0;
+	int ret = 0;
+
+	ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_LOADING_FW_START);
+
+	if (vdec->mc_back_loaded || dec->front_back_mode != 1) {
+		/*firmware have load before,
+			and not changes to another.
+			ignore reload.
+		*/
+	} else {
+		loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS3, vdec,
+				"avs3_back", dec->fw_back->data);
+
+		if (loadr < 0) {
+			amhevc_disable();
+			avs3_print(dec, 0, "AVS3: the %s back fw loading failed, err: %x\n",
+				fw_tee_enabled() ? "TEE" : "local", loadr);
+			dec->dec_back_result = DEC_BACK_RESULT_FORCE_EXIT;
+			vdec_schedule_work(&dec->work_back);
+			return;
+		}
+
+		//vdec->mc_back_loaded = 1;
+		vdec->mc_back_type = VFORMAT_AVS3;
+	}
+	ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_LOADING_FW_END);
+
+	ATRACE_COUNTER(dec->trace.decode_back_run_time_name, TRACE_RUN_BACK_ALLOC_MMU_START);
+
+	run_count_back[dec->index]++;
+	dec->vdec_back_cb_arg = arg;
+	dec->vdec_back_cb = callback;
+	vdec->back_pic_done = false;
+	//pr_err("run h265_HEVC_back_test\n");
+	//vdec_post_task(h265_HEVC_back_test, hevc);
+
+	ret = BackEnd_StartDecoding(dec);
+
+	if (ret == 1) {
+		dec->dec_back_result = DEC_BACK_RESULT_DONE;
+		vdec_schedule_work(&dec->timeout_work_back);
+	} else {
+		mod_timer(&dec->timer_back, jiffies);
+		dec->stat |= STAT_TIMER_BACK_ARM;
+		start_process_time_back(dec);
+	}
+}
+
+#if 0
+static void start_front_end_multi_pic_decoding(struct AVS3Decoder_s *dec)
+{ /*multi pictures in one packe*/
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	printk("Start FrontEnd Decoding %d\n", avs3_dec->frontend_decoded_count);
+	printk("copy loopbuf to next_bk[%d]\n",avs3_dec->fb_wr_pos);
+	copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+
+	if (dec->front_back_mode == 1)
+		config_bufstate_front_hw(avs3_dec);
+	WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+}
+#endif
+#endif
+
+static void run(struct vdec_s *vdec, unsigned long mask,
+	void (*callback)(struct vdec_s *, void *, int), void *arg)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	int r;
+
+#ifdef NEW_FB_CODE
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	/*simulation code: if (dec_status == AVS3_DEC_IDLE)*/
+	avs3_print(dec, PRINT_FLAG_VDEC_DETAIL, "%s(mask = 0x%lx)\n", __func__, mask);
+	if (dec->front_back_mode == 0 || (mask & CORE_MASK_HEVC)) {
+#endif
+	if (debug & PRINT_FLAG_VDEC_STATUS)
+		WRITE_VREG(HEVC_STREAM_CRC, 0);
+	run_count[dec->index]++;
+	dec->vdec_cb_arg = arg;
+	dec->vdec_cb = callback;
+	vdec->front_pic_done = false;
+
+	decoder_trace(dec->trace.decode_time_name, DECODER_RUN_START, TRACE_PERFORMANCE_DETAIL);
+	/* dec->chunk = vdec_prepare_input(vdec); */
+#ifdef NEW_FRONT_BACK_CODE
+	/*simulation code: if (dec_status == HEVC_DECPIC_DATA_DONE) {*/
+	if (dec->front_back_mode) {
+		avs3_print(dec, PRINT_FLAG_VDEC_STATUS,
+			"Start FrontEnd Decoding %d\n", avs3_dec->frontend_decoded_count);
+		avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"copy loopbuf fr to next_bk[fb_wr_pos=%d]\n",avs3_dec->fb_wr_pos);
+		copy_loopbufs_ptr(&avs3_dec->next_bk[avs3_dec->fb_wr_pos], &avs3_dec->fr);
+
+		if (dec->front_back_mode == 1)
+			amhevc_reset_f();
+		else
+			hevc_reset_core(vdec);
+	} else
+#endif
+	{
+	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;
+
+		avs3_print(dec, PRINT_FLAG_VDEC_DETAIL,
+			"ammvdec_avs3: Insufficient data\n");
+
+		vdec_schedule_work(&dec->work);
+		return;
+	}
+
+	input_empty[dec->index] = 0;
+	dec->dec_result = DEC_RESULT_NONE;
+
+	if (debug)
+		dec->start_shift_bytes = READ_VREG(HEVC_SHIFT_BYTE_COUNT);
+
+	if (debug & PRINT_FLAG_VDEC_STATUS) {
+		int ii;
+		avs3_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;
+
+			avs3_print_cont(dec, 0, "data adr %p:",
+				data);
+			for (ii = 0; ii < 8; ii++)
+				avs3_print_cont(dec, 0, "%02x ",
+					data[ii]);
+			if (!dec->chunk->block->is_mapped)
+				codec_mm_unmap_phyaddr(data);
+		}
+		avs3_print_cont(dec, 0, "\r\n");
+	}
+
+	decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_START, TRACE_BASIC);
+	if (vdec->mc_loaded) {
+		/*firmware have load before,
+			and not changes to another.
+			ignore reload.
+		*/
+	} else {
+#ifdef NEW_FB_CODE
+		int loadr = 0;
+		if (dec->front_back_mode == 1 || dec->front_back_mode == 3)
+			loadr = amhevc_vdec_loadmc_ex(VFORMAT_AVS3, vdec,
+					"avs3_front", dec->fw->data);
+		else
+#endif
+		if (amhevc_loadmc_ex(VFORMAT_AVS3, "avs3_mmu", dec->fw->data) < 0) {
+			vdec->mc_loaded = 0;
+			amhevc_disable();
+			avs3_print(dec, 0,
+				"%s: Error amvdec_loadmc avs3_mmu fail \n", __func__);
+			dec->dec_result = DEC_RESULT_FORCE_EXIT;
+			vdec_schedule_work(&dec->work);
+			return;
+		}
+		//vdec->mc_loaded = 1;
+		vdec->mc_type = VFORMAT_AVS3;
+	}
+	decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_FW_END, TRACE_BASIC);
+
+	decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_START, TRACE_BASIC);
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode) {
+		if (efficiency_mode)
+			WRITE_VREG(HEVC_EFFICIENCY_MODE, 1 << 1);
+		else
+			WRITE_VREG(HEVC_EFFICIENCY_MODE, 0 << 1);
+
+		avs3_hw_init(dec, 1, 0);
+			//config_decode_mode(dec);
+		if (dec->front_back_mode == 1) {
+			config_bufstate_front_hw(avs3_dec);
+			if ((fbdebug_flag & 0x8) && (avs3_dec->frontend_decoded_count == 0))
+				loop_buffer_fill_zero(dec);
+		}
+		WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_ACTION_DONE);
+	} else
+#endif
+	if (avs3_hw_ctx_restore(dec) < 0) {
+		vdec_schedule_work(&dec->work);
+		return;
+	}
+	decoder_trace(dec->trace.decode_run_time_name, TRACE_RUN_LOADING_RESTORE_END, TRACE_BASIC);
+
+	if (vdec_frame_based(vdec))
+		WRITE_VREG(HEVC_SHIFT_BYTE_COUNT, 0);
+
+	vdec_enable_input(vdec);
+
+	//WRITE_VREG(HEVC_DEC_STATUS_REG, AVS3_SEARCH_NEW_PIC);
+
+	if (vdec_frame_based(vdec) && dec->chunk) {
+		if (debug & PRINT_FLAG_VDEC_DATA)
+			dump_data(dec, dec->chunk->size);
+
+		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;
+
+	/*
+	avs3_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();
+#ifdef NEW_FB_CODE
+	if (dec->front_back_mode == 1) {
+		vdec->hw_front_decode_start = local_clock();
+		amhevc_start_f();
+	} else
+#endif
+	amhevc_start();
+	dec->stat |= STAT_VDEC_RUN;
+	decoder_trace(dec->trace.decode_time_name, DECODER_RUN_END, TRACE_PERFORMANCE_DETAIL);
+#ifdef NEW_FB_CODE
+	}
+	if (dec->front_back_mode &&
+		(mask & CORE_MASK_HEVC_BACK)) {
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_RUN_START);
+		run_back(vdec, callback, arg);
+		ATRACE_COUNTER(dec->trace.decode_back_time_name, DECODER_RUN_END);
+	}
+#endif
+}
+
+static void reset(struct vdec_s *vdec)
+{
+
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+
+	avs3_print(dec,
+		PRINT_FLAG_VDEC_DETAIL, "%s\r\n", __func__);
+
+}
+
+static irqreturn_t avs3_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	return vavs3_isr(0, dec);
+}
+
+static irqreturn_t avs3_threaded_irq_cb(struct vdec_s *vdec, int irq)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+	irqreturn_t ret;
+	//unsigned long flags;
+	//lock_front_back(dec, flags);
+	ret = vavs3_isr_thread_fn(0, dec);
+	//unlock_front_back(dec, flags);
+#ifdef USE_FRONT_ISR_HANDLE_FOR_BACK
+	if ((dec->dec_status_back != AVS3_DEC_IDLE) ||
+		READ_VREG(DEBUG_REG1_DBE)) {
+		ret = vavs3_back_isr_thread_fn(dec);
+	}
+#endif
+	return ret;
+}
+
+static void avs3_dump_state(struct vdec_s *vdec)
+{
+	struct AVS3Decoder_s *dec =
+		(struct AVS3Decoder_s *)vdec->private;
+
+	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;
+		return;
+	}
+
+	avs3_print(dec, 0, "====== %s\n", __func__);
+	avs3_print(dec, 0,
+		"width/height (%d/%d), max_pb_size %d\n",
+		dec->avs3_dec.img.width,
+		dec->avs3_dec.img.height,
+		dec->avs3_dec.max_pb_size
+		);
+
+	avs3_print(dec, 0,
+		"front_back_mode (%d), 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",
+		dec->front_back_mode,
+		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 receiver_start_e state =
+		vf_notify_receiver(vdec->vf_provider_name,
+			VFRAME_EVENT_PROVIDER_QUREY_STATE,
+			NULL);
+		avs3_print(dec, 0,
+			"\nreceiver(%s) state %d\n",
+			vdec->vf_provider_name,
+			state);
+	}
+
+	avs3_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
+	);
+
+	print_pic_pool(&dec->avs3_dec, "");
+
+	avs3_print(dec, 0,
+		"HEVC_DEC_STATUS_REG=0x%x\n",
+		READ_VREG(HEVC_DEC_STATUS_REG));
+	avs3_print(dec, 0,
+		"HEVC_MPC_E=0x%x\n",
+		READ_VREG(HEVC_MPC_E));
+	avs3_print(dec, 0,
+		"DECODE_MODE=0x%x\n",
+		READ_VREG(DECODE_MODE));
+	avs3_print(dec, 0,
+		"NAL_SEARCH_CTL=0x%x\n",
+		READ_VREG(NAL_SEARCH_CTL));
+	avs3_print(dec, 0,
+		"HEVC_PARSER_LCU_START=0x%x\n",
+		READ_VREG(HEVC_PARSER_LCU_START));
+	avs3_print(dec, 0,
+		"HEVC_DECODE_SIZE=0x%x\n",
+		READ_VREG(HEVC_DECODE_SIZE));
+	avs3_print(dec, 0,
+		"HEVC_SHIFT_BYTE_COUNT=0x%x\n",
+		READ_VREG(HEVC_SHIFT_BYTE_COUNT));
+	avs3_print(dec, 0,
+		"HEVC_STREAM_START_ADDR=0x%x\n",
+		READ_VREG(HEVC_STREAM_START_ADDR));
+	avs3_print(dec, 0,
+		"HEVC_STREAM_END_ADDR=0x%x\n",
+		READ_VREG(HEVC_STREAM_END_ADDR));
+	avs3_print(dec, 0,
+		"HEVC_STREAM_LEVEL=0x%x\n",
+		READ_VREG(HEVC_STREAM_LEVEL));
+	avs3_print(dec, 0,
+		"HEVC_STREAM_WR_PTR=0x%x\n",
+		READ_VREG(HEVC_STREAM_WR_PTR));
+	avs3_print(dec, 0,
+		"HEVC_STREAM_RD_PTR=0x%x\n",
+		READ_VREG(HEVC_STREAM_RD_PTR));
+	avs3_print(dec, 0,
+		"PARSER_VIDEO_RP=0x%x\n",
+		STBUF_READ(&vdec->vbuf, get_rp));
+	avs3_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;
+			avs3_print(dec, 0,
+				"frame data size 0x%x\n",
+				dec->chunk->size);
+			for (jj = 0; jj < dec->chunk->size; jj++) {
+				if ((jj & 0xf) == 0)
+					avs3_print(dec, 0,
+						"%06x:", jj);
+				avs3_print_cont(dec, 0,
+					"%02x ", data[jj]);
+				if (((jj + 1) & 0xf) == 0)
+					avs3_print_cont(dec, 0,
+						"\n");
+			}
+
+			if (!dec->chunk->block->is_mapped)
+				codec_mm_unmap_phyaddr(data);
+		}
+	}
+
+	if (dec->front_back_mode == 1) {
+		struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+		avs3_print(dec, 0,
+			"[BE] dec_back_result 0x%x, frontend_decoded_count %d, backend_decoded_count %d, fb_wr_pos %d, fb_rd_pos %d, wait_working_buf %d\n",
+			dec->dec_back_result,
+			avs3_dec->frontend_decoded_count,
+			avs3_dec->backend_decoded_count,
+			avs3_dec->fb_wr_pos,
+			avs3_dec->fb_rd_pos,
+			avs3_dec->wait_working_buf
+		);
+
+		avs3_print(dec, 0,
+			"[BE] HEVC_DEC_STATUS_DBE=0x%x\n",
+			READ_VREG(HEVC_DEC_STATUS_DBE));
+		avs3_print(dec, 0,
+			"[BE] HEVC_MPC_E_DBE=0x%x\n",
+			READ_VREG(HEVC_MPC_E_DBE));
+		avs3_print(dec, 0,
+			"[BE] HEVC_MPSR_DBE=0x%x\n",
+			READ_VREG(HEVC_MPSR_DBE));
+		avs3_print(dec, 0,
+			"[BE] DEBUG_REG1_DBE=0x%x\n",
+			READ_VREG(DEBUG_REG1_DBE));
+		avs3_print(dec, 0,
+			"[BE] DEBUG_REG2_DBE=0x%x\n",
+			READ_VREG(DEBUG_REG2_DBE));
+		print_loopbufs_adr_size(dec);
+		print_loopbufs_ptr(dec, "fr", &avs3_dec->fr);
+		print_loopbufs_ptr(dec, "bk", &avs3_dec->bk);
+	}
+
+	if (dump_phy_adr != 0 && dump_phy_size != 0) {
+		dump_or_fill_phy_buffer(dec, dump_phy_adr, dump_phy_size, NULL, 2, NULL);
+	}
+	if (fbdebug_flag & 0x80000000) {
+		dump_loop_buffer(dec, -1, 1);
+		fbdebug_flag &= ~0x80000000;
+	}
+}
+
+static void d_dump(struct AVS3Decoder_s *dec, unsigned int phy_adr, int size,
+	struct file *fp, loff_t *wr_off, u32 * total_check_sum, u8 print_flag)
+{
+	u8 *vaddr;
+	u32 check_sum = 0;
+	vaddr = codec_mm_vmap(phy_adr, size);
+	if (vaddr) {
+		int i;
+		if (total_check_sum == NULL) {
+			for (i = 0; i < size; i++)
+				vaddr[i] = 0;
+			codec_mm_dma_flush(vaddr, size, DMA_TO_DEVICE);
+		} else {
+			codec_mm_dma_flush(vaddr, size, DMA_FROM_DEVICE);
+			if (fp) {
+				media_write(fp, vaddr, size, wr_off);
+				for (i = 0; i < size; i++)
+					check_sum += vaddr[i];
+				*total_check_sum += check_sum;
+			} else {
+				for (i = 0; i < size; i++) {
+					if (print_flag) {
+						if ((i & 0xf) == 0)
+							avs3_print_cont(dec, 0, "%08x: ", phy_adr+i);
+						avs3_print_cont(dec, 0, "%02x ", vaddr[i]);
+					}
+					check_sum += vaddr[i];
+					if (print_flag) {
+						if (((i + 1) & 0xf) == 0)
+							avs3_print_flush(dec); //avs3_print(dec, 0, "\n");
+					}
+				}
+				*total_check_sum += check_sum;
+				if (print_flag)
+					avs3_print(dec, 0, "check_sum %08x, %08x\n", *total_check_sum, check_sum);
+			}
+		}
+		codec_mm_unmap_phyaddr(vaddr);
+	} else {
+		pr_info("%s codec_mm_vmap fail\n", __func__);
+	}
+}
+
+static void dump_or_fill_phy_buffer(struct AVS3Decoder_s *dec, u32 dump_phy_adr, u32 dump_phy_size, char *file, u8 flag, char *mark)
+{
+	/*
+		flag: 1, fill zero
+		flag: 2, print data
+	*/
+	loff_t off = 0;
+	int mode = O_CREAT | O_WRONLY | O_TRUNC;
+	struct file *fp = NULL;
+
+	int dump_size = 1024;
+	int remain_size = dump_phy_size;
+	u32 phy_adr = dump_phy_adr;
+	u32 total_check_sum = 0;
+
+	if (file) {
+		fp = media_open(file, mode, 0666);
+	}
+	while (remain_size > 0) {
+		if (flag == 1)
+			d_dump(dec, phy_adr, dump_size, NULL, NULL, NULL, 0);
+		else
+			d_dump(dec, phy_adr, dump_size, fp, &off, &total_check_sum, flag == 2);
+
+		remain_size -= dump_size;
+		phy_adr += dump_size;
+		if (remain_size < dump_size)
+			dump_size = remain_size;
+		//msleep(20);
+	}
+	if (fp) {
+		media_close(fp, current->files);
+	}
+	if (flag == 1)
+		avs3_print(dec, 0, "fill phy mem %s %x (size %x):\n", mark?mark:"", dump_phy_adr, dump_phy_size);
+	else
+		avs3_print(dec, 0, "dump phy mem %s %x (size %x) check_sum %x %s\n", mark?mark:"", dump_phy_adr, dump_phy_size, total_check_sum, file? file:"");
+}
+
+static int ammvdec_avs3_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 AVS3Decoder_s *dec = NULL;
+	static struct vframe_operations_s vf_tmp_ops;
+
+	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 avs3\n",
+			__func__, get_cpu_major_id());
+		return -1;
+	}
+	if (pdata == NULL) {
+		pr_info("\nammvdec_avs3 memory resource undefined.\n");
+		return -EFAULT;
+	}
+	/*dec = (struct AVS3Decoder_s *)devm_kzalloc(&pdev->dev,
+		sizeof(struct AVS3Decoder_s), GFP_KERNEL);*/
+	memset(&vf_dp, 0, sizeof(struct vframe_master_display_colour_s));
+	dec = vzalloc(sizeof(struct AVS3Decoder_s));
+	if (dec == NULL) {
+		pr_info("\nammvdec_avs3 device data allocation failed\n");
+		return -ENOMEM;
+	}
+	/*
+	//move to other place after pic_pool is initialized
+	if (pdata->parallel_dec == 1) {
+		int i;
+		for (i = 0; i < MAX_PB_SIZE; i++) {
+			dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index = -1;
+			dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index = -1;
+		}
+	}
+	*/
+	pdata->private = dec;
+	pdata->dec_status = vavs3_dec_status;
+#ifdef I_ONLY_SUPPORT
+	pdata->set_trickmode = vavs3_set_trickmode;
+#endif
+	pdata->run_ready = run_ready;
+	pdata->run = run;
+	dec->avs3_dec.max_pb_size = MAX_PB_SIZE; //will reconfig later
+#ifdef NEW_FB_CODE
+	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S5) {
+		dec->front_back_mode = front_back_mode;
+	} else {
+		dec->front_back_mode = 0;
+	}
+	dec->fb_ifbuf_num = fb_ifbuf_num;
+	if (dec->fb_ifbuf_num > MAX_FB_IFBUF_NUM)
+		dec->fb_ifbuf_num = MAX_FB_IFBUF_NUM;
+	pdata->check_input_data = NULL;
+	if (dec->front_back_mode) {
+		pdata->check_input_data = check_input_data;
+		pdata->reset = NULL;
+		pdata->back_irq_handler = avs3_back_irq_cb;
+		pdata->back_threaded_irq_handler = avs3_back_threaded_irq_cb;
+	} else
+#endif
+	pdata->reset = reset;
+	pdata->irq_handler = avs3_irq_cb;
+	pdata->threaded_irq_handler = avs3_threaded_irq_cb;
+	pdata->dump_state = avs3_dump_state;
+
+	/*
+	 * memcpy(&BUF[0], &dec->m_BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+	 * memset(dec, 0, sizeof(struct AVS3Decoder_s));
+	 * memcpy(&dec->m_BUF[0], &BUF[0], sizeof(struct BUF_s) * MAX_BUF_NUM);
+	 */
+
+	dec->index = pdev->id;
+	dec->m_ins_flag = 1;
+
+	config_hevc_irq_num(dec);
+
+	if (is_rdma_enable()) {
+		dec->rdma_adr = decoder_dma_alloc_coherent(&dec->rdma_mem_handle, RDMA_SIZE, &dec->rdma_phy_adr, "AVS3_RDMA_BUF");
+		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->trace.vdec_name, sizeof(dec->trace.vdec_name),
+		"avs3-%d", dec->index);
+	snprintf(dec->trace.pts_name, sizeof(dec->trace.pts_name),
+		"%s-pts", dec->trace.vdec_name);
+	snprintf(dec->trace.vf_get_name, sizeof(dec->trace.vf_get_name),
+		"%s-vf_get", dec->trace.vdec_name);
+	snprintf(dec->trace.vf_put_name, sizeof(dec->trace.vf_put_name),
+		"%s-vf_put", dec->trace.vdec_name);
+	snprintf(dec->trace.set_canvas0_addr, sizeof(dec->trace.set_canvas0_addr),
+		"%s-set_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.get_canvas0_addr, sizeof(dec->trace.get_canvas0_addr),
+		"%s-get_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.put_canvas0_addr, sizeof(dec->trace.put_canvas0_addr),
+		"%s-put_canvas0_addr", dec->trace.vdec_name);
+	snprintf(dec->trace.new_q_name, sizeof(dec->trace.new_q_name),
+		"%s-newframe_q", dec->trace.vdec_name);
+	snprintf(dec->trace.disp_q_name, sizeof(dec->trace.disp_q_name),
+		"%s-dispframe_q", dec->trace.vdec_name);
+	snprintf(dec->trace.decode_time_name, sizeof(dec->trace.decode_time_name),
+		"decoder_time%d", pdev->id);
+	snprintf(dec->trace.decode_run_time_name, sizeof(dec->trace.decode_run_time_name),
+		"decoder_run_time%d", pdev->id);
+	snprintf(dec->trace.decode_header_memory_time_name, sizeof(dec->trace.decode_header_memory_time_name),
+		"decoder_header_time%d", pdev->id);
+	snprintf(dec->trace.decode_work_time_name, sizeof(dec->trace.decode_work_time_name),
+		"decoder_work_time%d", pdev->id);
+	snprintf(dec->trace.decode_back_time_name, sizeof(dec->trace.decode_back_time_name),
+		"decoder_back_time%d", pdev->id);
+	snprintf(dec->trace.decode_back_run_time_name, sizeof(dec->trace.decode_back_run_time_name),
+		"decoder_back_run_time%d", pdev->id);
+	snprintf(dec->trace.decode_back_work_time_name, sizeof(dec->trace.decode_back_work_time_name),
+		"decoder_back_work_time%d", pdev->id);
+
+	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);
+
+	memcpy(&vf_tmp_ops, &vavs3_vf_provider, sizeof(struct vframe_operations_s));
+	if (without_display_mode == 1) {
+		vf_tmp_ops.get = NULL;
+	}
+	vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name,
+		&vf_tmp_ops, 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 ((debug & IGNORE_PARAM_FROM_CONFIG) == 0 && pdata->config_len) {
+		/*use ptr config for double_write_mode, etc*/
+		avs3_print(dec, 0, "pdata->config=%s\n", pdata->config);
+		if (get_config_int(pdata->config, "avs3_double_write_mode",
+				&config_val) == 0)
+			dec->double_write_mode = config_val;
+		else
+			dec->double_write_mode = double_write_mode;
+
+#ifdef OW_TRIPLE_WRITE
+		if (get_config_int(pdata->config, "avs3_triple_write_mode",
+			&config_val) == 0)
+			dec->triple_write_mode = config_val;
+		else
+			dec->triple_write_mode = triple_write_mode;
+#endif
+
+		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 {
+		/*dec->vavs3_amstream_dec_info.width = 0;
+		dec->vavs3_amstream_dec_info.height = 0;
+		dec->vavs3_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 (double_write_mode) {
+		dec->double_write_mode = get_double_write_mode(dec);
+	}
+
+	if ((dec->double_write_mode & 0x10) == 0)
+		dec->mmu_enable = 1;
+
+#ifdef AVS3_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
+#ifdef OW_TRIPLE_WRITE
+	if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3X) {
+		if ((dec->triple_write_mode) || (triple_write_mode) ||
+			(dec->double_write_mode & 0x10000) || (double_write_mode & 0x10000)) {
+			double_write_mode &= ~(1 <<16);
+			dec->double_write_mode &= ~(1 <<16);
+			triple_write_mode = 0;
+			dec->triple_write_mode = 0;
+			pr_err("%s warn: unsupport triple write or p010 mode, force disabled\n", __func__);
+		}
+	}
+#endif
+
+	if (amvdec_avs3_mmu_init(dec) < 0) {
+		pr_err("avs3 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;
+	}
+	if (!vdec_secure(pdata))
+		codec_mm_memset(dec->cma_alloc_addr, 0, dec->cma_alloc_count * PAGE_SIZE);
+
+	dec->buf_start = dec->cma_alloc_addr;
+	dec->buf_size = work_buf_size;
+
+	dec->init_flag = 0;
+	dec->first_sc_checked = 0;
+	dec->fatal_error = 0;
+	dec->show_frame_num = 0;
+
+	if (debug) {
+		pr_info("===AVS3 decoder mem resource 0x%lx size 0x%x\n",
+				dec->buf_start,
+				dec->buf_size);
+	}
+
+	if (pdata->sys_info) {
+		dec->vavs3_amstream_dec_info = *pdata->sys_info;
+		dec->frame_width = dec->vavs3_amstream_dec_info.width;
+		dec->frame_height = dec->vavs3_amstream_dec_info.height;
+	} else {
+		dec->vavs3_amstream_dec_info.width = 0;
+		dec->vavs3_amstream_dec_info.height = 0;
+		dec->vavs3_amstream_dec_info.rate = 30;
+	}
+
+	dec->endian = HEVC_CONFIG_LITTLE_ENDIAN;
+	if (is_support_vdec_canvas())
+		dec->endian = HEVC_CONFIG_BIG_ENDIAN;
+	if (is_dw_p010(dec) || is_tw_p010(dec))
+		dec->endian = HEVC_CONFIG_P010_LE;
+	if (endian)
+		dec->endian = endian;
+
+	dec->cma_dev = pdata->cma_dev;
+	if (vavs3_init(pdata) < 0) {
+		pr_info("\namvdec_avs3 init failed.\n");
+		avs3_local_uninit(dec);
+		uninit_mmu_buffers(dec);
+		/* devm_kfree(&pdev->dev, (void *)dec); */
+		vfree((void *)dec);
+		pdata->dec_status = NULL;
+		return -ENODEV;
+	}
+	if (pdata->parallel_dec == 1) {
+		//run only after pic_pool initialzied in vavs3_init()
+		int i;
+		for (i = 0; i < MAX_PB_SIZE; i++) {
+			dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index = -1;
+			dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index = -1;
+		}
+	}
+	spin_lock_init(&dec->buffer_lock);
+	spin_lock_init(&dec->front_back_lock);
+	mutex_init(&dec->slice_header_lock);
+	vdec_set_prepare_level(pdata, start_decode_buf_level);
+	hevc_source_changed(VFORMAT_AVS3,
+			4096, 2048, 60);
+	if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode)
+			vdec_core_request(pdata, CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+		else
+#endif
+		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_avs3_remove(struct platform_device *pdev)
+{
+	struct AVS3Decoder_s *dec = (struct AVS3Decoder_s *)
+		(((struct vdec_s *)(platform_get_drvdata(pdev)))->private);
+	struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
+	struct avs3_decoder *avs3_dec = &dec->avs3_dec;
+	struct avs3_frame_s *pic;
+	int i;
+
+	if (debug)
+		pr_info("amvdec_avs3_remove\n");
+
+	vmavs3_stop(dec);
+
+	if (pdata->parallel_dec == 1) {
+#ifdef NEW_FB_CODE
+		if (dec->front_back_mode)
+			vdec_core_release(hw_to_vdec(dec), CORE_MASK_HEVC | CORE_MASK_HEVC_BACK);
+		else
+#endif
+		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 < MAX_PB_SIZE; i++) {
+			pdata->free_canvas_ex(dec->avs3_dec.pic_pool[i].buf_cfg.y_canvas_index, pdata->id);
+			pdata->free_canvas_ex(dec->avs3_dec.pic_pool[i].buf_cfg.uv_canvas_index, pdata->id);
+		}
+	}
+
+	for (i = 0; i < avs3_dec->max_pb_size; i++) {
+		pic = &avs3_dec->pic_pool[i].buf_cfg;
+		if (pic->used < 0)
+			continue;
+
+		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())
+		decoder_dma_free_coherent(dec->rdma_mem_handle, 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_avs3_driver = {
+	.probe = ammvdec_avs3_probe,
+	.remove = ammvdec_avs3_remove,
+#ifdef CONFIG_PM
+	.suspend = amvdec_suspend,
+	.resume = amvdec_resume,
+#endif
+	.driver = {
+		.name = MULTI_DRIVER_NAME,
+	}
+};
+#endif
+//#ifndef FOR_S5
+static struct mconfig avs3_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 avs3_node;
+//#endif
+static int __init amvdec_avs3_driver_init_module(void)
+{
+
+#ifdef AVS3_10B_MMU
+	struct BuffInfo_s *p_buf_info;
+	unsigned int bufspec_index = 0;
+	if (force_bufspec) {
+		bufspec_index = force_bufspec & 0xf;
+		pr_info("force buffer spec %d\n", force_bufspec & 0xf);
+	} else {
+		if (vdec_is_support_4k()) {
+			bufspec_index = 2;	/* 8k */
+		} else
+			bufspec_index = 0;/* 1080p */
+	}
+	p_buf_info = &amvavs3_workbuff_spec[bufspec_index];
+	pr_info("%s bufspec_index = %d\n", __func__, bufspec_index);
+	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_avs3 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_avs3_driver))
+		pr_err("failed to register ammvdec_avs3 driver\n");
+
+	if (platform_driver_register(&amvdec_avs3_driver)) {
+		pr_err("failed to register amvdec_avs3 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_avs3_profile.name = "avs3_unsupport";
+	} else if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SM1) {
+		if (vdec_is_support_4k())
+			amvdec_avs3_profile.profile =
+				"4k, 10bit, dwrite, compressed";
+		else
+			amvdec_avs3_profile.profile =
+				"10bit, dwrite, compressed";
+	} else {
+		/* cpu id larger than sm1 support 8k */
+		amvdec_avs3_profile.profile =
+				"8k, 10bit, dwrite, compressed";
+	}
+
+	vcodec_profile_register(&amvdec_avs3_profile);
+	amvdec_avs3_profile_mult = amvdec_avs3_profile;
+	amvdec_avs3_profile_mult.name = "mavs3";
+	vcodec_profile_register(&amvdec_avs3_profile_mult);
+
+	INIT_REG_NODE_CONFIGS("media.decoder", &avs3_node,
+		"avs3", avs3_configs, CONFIG_FOR_RW);
+	vcodec_feature_register(VFORMAT_AVS3, 0);
+	return 0;
+}
+
+static void __exit amvdec_avs3_driver_remove_module(void)
+{
+	pr_debug("amvdec_avs3 module remove.\n");
+	platform_driver_unregister(&ammvdec_avs3_driver);
+	platform_driver_unregister(&amvdec_avs3_driver);
+}
+
+/****************************************/
+
+module_param(bit_depth_luma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_luma, "\n amvdec_avs3 bit_depth_luma\n");
+
+module_param(bit_depth_chroma, uint, 0664);
+MODULE_PARM_DESC(bit_depth_chroma, "\n amvdec_avs3 bit_depth_chroma\n");
+
+module_param(frame_width, uint, 0664);
+MODULE_PARM_DESC(frame_width, "\n amvdec_avs3 frame_width\n");
+
+module_param(frame_height, uint, 0664);
+MODULE_PARM_DESC(frame_height, "\n amvdec_avs3 frame_height\n");
+
+module_param(debug, uint, 0664);
+MODULE_PARM_DESC(debug, "\n amvdec_avs3 debug\n");
+
+module_param(debug_again, uint, 0664);
+MODULE_PARM_DESC(debug_again, "\n amvdec_avs3 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_avs3 step\n");
+
+module_param(decode_pic_begin, uint, 0664);
+MODULE_PARM_DESC(decode_pic_begin, "\n amvdec_avs3 decode_pic_begin\n");
+
+module_param(slice_parse_begin, uint, 0664);
+MODULE_PARM_DESC(slice_parse_begin, "\n amvdec_avs3 slice_parse_begin\n");
+
+module_param(i_only_flag, uint, 0664);
+MODULE_PARM_DESC(i_only_flag, "\n amvdec_avs3 i_only_flag\n");
+
+module_param(error_handle_policy, uint, 0664);
+MODULE_PARM_DESC(error_handle_policy, "\n amvdec_avs3 error_handle_policy\n");
+
+module_param(re_search_seq_threshold, uint, 0664);
+MODULE_PARM_DESC(re_search_seq_threshold, "\n amvdec_avs3 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(over_decoder_shiftbytes, uint, 0664);
+MODULE_PARM_DESC(over_decoder_shiftbytes, "\n over_decoder_shiftbytes\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");
+
+#ifdef OW_TRIPLE_WRITE
+module_param(triple_write_mode, uint, 0664);
+MODULE_PARM_DESC(triple_write_mode, "\n triple_write_mode\n");
+#endif
+
+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 avs3 start_decode_buf_level\n");
+
+module_param(decode_timeout_val, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val,
+	"\n avs3 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_avs3 video_signal_type\n");
+
+module_param(force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(force_video_signal_type, "\n amvdec_avs3 force_video_signal_type\n");
+
+module_param(enable_force_video_signal_type, uint, 0664);
+MODULE_PARM_DESC(enable_force_video_signal_type, "\n amvdec_avs3 enable_force_video_signal_type\n");
+
+module_param(force_bufspec, uint, 0664);
+MODULE_PARM_DESC(force_bufspec, "\n amvdec_avs3 force_bufspec\n");
+
+module_param(fbdebug_flag, uint, 0664);
+MODULE_PARM_DESC(fbdebug_flag, "\n amvdec_avs3 fbdebug_flag\n");
+
+module_param(udebug_flag, uint, 0664);
+MODULE_PARM_DESC(udebug_flag, "\n amvdec_avs3 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(dump_phy_adr, uint, 0664);
+MODULE_PARM_DESC(dump_phy_adr, "\n dump_phy_adr\n");
+
+module_param(dump_phy_size, uint, 0664);
+MODULE_PARM_DESC(dump_phy_size, "\n dump_phy_size\n");
+
+#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");
+#endif
+
+module_param(pre_decode_buf_level, int, 0664);
+MODULE_PARM_DESC(pre_decode_buf_level,
+		"\n amvdec_avs3 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_avs3 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");
+
+#ifdef NEW_FB_CODE
+module_param(front_back_mode, uint, 0664);
+MODULE_PARM_DESC(front_back_mode, "\n amvdec_avs3 front_back_mode\n");
+
+module_param(fb_ifbuf_num, uint, 0664);
+MODULE_PARM_DESC(fb_ifbuf_num, "\n amvdec_avs3 fb_ifbuf_num\n");
+
+module_param(decode_timeout_val_back, uint, 0664);
+MODULE_PARM_DESC(decode_timeout_val_back,
+	"\n amvdec_avs3 decode_timeout_val_back\n");
+
+module_param(fast_timer_check_count, uint, 0664);
+MODULE_PARM_DESC(fast_timer_check_count,
+	"\n amvdec_avs3 fast_timer_check_count\n");
+
+module_param_array(max_process_time_back, uint,
+	&max_decode_instance_num, 0664);
+#endif
+
+module_param(trace_debug_mode, uint, 0664);
+MODULE_PARM_DESC(trace_debug_mode, "\n  trace_debug_mode\n");
+
+module_param(paral_alloc_buffer_mode, uint, 0664);
+MODULE_PARM_DESC(paral_alloc_buffer_mode, "\n  paral_alloc_buffer_mode\n");
+
+#ifdef NEW_FB_CODE
+
+module_param(efficiency_mode, uint, 0664);
+MODULE_PARM_DESC(efficiency_mode, "\n  efficiency_mode\n");
+
+#endif
+
+module_init(amvdec_avs3_driver_init_module);
+module_exit(amvdec_avs3_driver_remove_module);
+
+MODULE_DESCRIPTION("AMLOGIC avs3 Video Decoder Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tim Yao <tim.yao@amlogic.com>");
diff --git a/drivers/frame_provider/decoder/h264/vh264.h b/drivers/frame_provider/decoder/avs3/vavs3.h
similarity index 61%
copy from drivers/frame_provider/decoder/h264/vh264.h
copy to drivers/frame_provider/decoder/avs3/vavs3.h
index 6c8e4ad..f00c08f 100644
--- a/drivers/frame_provider/decoder/h264/vh264.h
+++ b/drivers/frame_provider/decoder/avs3/vavs3.h
@@ -1,7 +1,7 @@
 /*
- * drivers/amlogic/media/frame_provider/decoder/h264/vh264.h
+ * drivers/amlogic/amports/vavs3.h
  *
- * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,15 +13,14 @@
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  * more details.
  *
- */
+*/
 
-#ifndef VH264_H
-#define VH264_H
+#ifndef VAVS3_H
+#define VAVS3_H
 
-extern int query_video_status(int type, int *value);
+#define AVS3_10B_MMU
+#define AVS3_10B_MMU_DW
 
-/* extern s32 vh264_init(void); */
-
-extern s32 vh264_release(void);
-
-#endif /* VMPEG4_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);
+#endif
diff --git a/drivers/frame_provider/decoder/avs_multi/Makefile b/drivers/frame_provider/decoder/avs_multi/Makefile
index 638cec0..0a90f15 100644
--- a/drivers/frame_provider/decoder/avs_multi/Makefile
+++ b/drivers/frame_provider/decoder/avs_multi/Makefile
@@ -1,2 +1,7 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += amvdec_mavs.o
-amvdec_mavs-objs += avs_multi.o
+MODULE_NAME = amvdec_mavs
+obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI) += ${MODULE_NAME}.o
+${MODULE_NAME}-objs += avs_multi.o
+
+PR_FMT = $(subst amlogic-,,$(MODULE_NAME))
+PR_FMT_DEFINE="-Dpr_fmt(fmt)=\"[$(PR_FMT)]:\" fmt"
+ccflags-y += $(PR_FMT_DEFINE)
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.c b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
index 7dd20bb..0ba2183 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.c
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.c
@@ -1,7 +1,5 @@
 /*
- * drivers/amlogic/amports/vavs.c
- *
- * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ * 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
@@ -13,6 +11,11 @@
  * 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>
@@ -29,30 +32,26 @@
 #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 "../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 <linux/amlogic/tee.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "../../../common/chips/decoder_cpu_ver_info.h"
+#include "../../../stream_input/amports/amports_priv.h"
+#include "../../../stream_input/amports/streambuf_reg.h"
 #include "../utils/decoder_mmu_box.h"
 #include "../utils/decoder_bmmu_box.h"
 #include "../utils/firmware.h"
-#include "../../../common/chips/decoder_cpu_ver_info.h"
-#include <linux/amlogic/tee.h>
 #include "../utils/vdec_feature.h"
+#include "../utils/amvdec.h"
+#include "avs_multi.h"
+#include "../utils/decoder_dma_alloc.h"
+#include "../../../media_sync/pts_server/pts_server_core.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
 
@@ -66,9 +65,7 @@
 
 #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
@@ -82,7 +79,6 @@
 
 #define LMEM_BUF_SIZE (0x500 * 2)
 
-/* #define ORI_BUFFER_START_ADDR   0x81000000 */
 #define ORI_BUFFER_START_ADDR   0x80000000
 
 #define INTERLACE_FLAG          0x80
@@ -90,8 +86,7 @@
 
 /* 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_PIC_INFO      AV_SCRATCH_1
 #define AVS_FRAME_RATE     AV_SCRATCH_3
 
 /*#define AVS_ERROR_COUNT    AV_SCRATCH_6*/
@@ -116,6 +111,7 @@
 #define DECODE_STATUS_DECODE_BUF_EMPTY	0x2
 #define DECODE_STATUS_SEARCH_BUF_EMPTY	0x3
 #define DECODE_STATUS_SKIP_PIC_DONE     0x4
+#define DECODE_STATUS_INFO     0x5
 #define DECODE_SEARCH_HEAD	0xff
 
 #define DECODE_STOP_POS		AV_SCRATCH_J
@@ -127,12 +123,7 @@
 #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[] = {
@@ -150,14 +141,12 @@
 #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;
@@ -168,14 +157,14 @@
 	udebug_flag:
 	bit 0, enable ucode print
 	bit 1, enable ucode more print
-	bit 3, enable ucdode detail print
+	bit 3, 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)
 
 	avs only:
 	bit [8], disable empty muitl-instance handling
-	bit [9], enable writting of VC1_CONTROL_REG in ucode
+	bit [9], enable writing of VC1_CONTROL_REG in ucode
 */
 static u32 udebug_flag;
 /*
@@ -236,7 +225,6 @@
 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 *);
@@ -256,9 +244,7 @@
 	.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
@@ -287,44 +273,11 @@
 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;
@@ -333,19 +286,11 @@
 
 void *bitstream_read_tmp;
 dma_addr_t bitstream_read_tmp_phy;
+ulong bitstream_read_handle;
 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] = {
@@ -397,6 +342,25 @@
 	unsigned short decode_pic_count;
 };
 
+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;
+	u32 picture_type;
+	unsigned short decode_pic_count;
+	u32 repeat_cnt;
+	u32 error_flag;
+};
+
 struct vdec_avs_hw_s {
 	spinlock_t lock;
 	unsigned char m_ins_flag;
@@ -448,7 +412,6 @@
 
 	/*debug*/
 	u32 ucode_pause_pos;
-	/**/
 	u32 decode_pic_count;
 	u8 reset_decode_flag;
 	u32 display_frame_count;
@@ -532,7 +495,7 @@
 	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)(struct vdec_s *, void *, int);
 	void *vdec_cb_arg;
 /* for error handling */
 	u32 run_count;
@@ -554,6 +517,14 @@
 	char pts_name[32];
 	char new_q_name[32];
 	char disp_q_name[32];
+	s32 ref_use[DECODE_BUFFER_NUM_MAX];
+	s32 buf_use[DECODE_BUFFER_NUM_MAX];
+	u32 decoding_index;
+	struct pic_info_t pics[DECODE_BUFFER_NUM_MAX];
+	ulong user_data_handle;
+	ulong lmem_phy_handle;
+	bool process_busy;
+	bool run_flag;
 };
 
 static void reset_process_time(struct vdec_avs_hw_s *hw);
@@ -594,7 +565,6 @@
 #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)
@@ -610,7 +580,7 @@
 #endif
 
 #undef pr_info
-#define pr_info printk
+#define pr_info pr_cont
 static int debug_print(struct vdec_avs_hw_s *hw,
 	int flag, const char *fmt, ...)
 {
@@ -626,7 +596,6 @@
 		(1 << index))
 		&& (debug & flag))) {
 		va_list args;
-
 		va_start(args, fmt);
 		if (hw)
 			len = sprintf(buf, "[%d]", index);
@@ -660,6 +629,60 @@
 	return 0;
 }
 
+static bool is_enough_free_buffer(struct vdec_avs_hw_s *hw)
+{
+	int i;
+
+	for (i = 0; i < hw->vf_buf_num_used; i++) {
+		if ((hw->vfbuf_use[i] == 0) && (hw->ref_use[i] == 0) &&
+			(hw->buf_use[i] == 0))
+			break;
+	}
+
+	return (i == hw->vf_buf_num_used) ? false : true;
+}
+
+static int find_free_buffer(struct vdec_avs_hw_s *hw)
+{
+	int i;
+
+	for (i = 0; i < hw->vf_buf_num_used; i++) {
+		if ((hw->vfbuf_use[i] == 0) &&
+			(hw->ref_use[i] == 0) &&
+			(hw->buf_use[i] == 0))
+			break;
+	}
+
+	return i;
+}
+
+int update_reference(struct vdec_avs_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->vf_buf_num_used;
+	} else {
+		hw->ref_use[hw->refs[0]]--; 	//old ref0 unused
+		hw->refs[0] = hw->refs[1];
+		hw->refs[1] = index;
+		index = hw->refs[0];
+	}
+	debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+		"hw->refs[0] = %d, hw->refs[1] = %d\n", hw->refs[0], hw->refs[1]);
+	return index;
+}
+
+
 static void avs_pts_check_in(struct vdec_avs_hw_s *hw,
 	unsigned short decode_pic_count, struct vframe_chunk_s *chunk)
 {
@@ -751,11 +774,10 @@
 	} else
 #endif
 	{
-		vf->width = READ_VREG(AVS_PIC_WIDTH);
-		vf->height = READ_VREG(AVS_PIC_HEIGHT);
+		vf->width = READ_VREG(AVS_PIC_INFO) & 0x3fff;
+		vf->height = (READ_VREG(AVS_PIC_INFO) >> 14) & 0x3fff;
 		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
@@ -765,7 +787,6 @@
 #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);
 	}
@@ -810,19 +831,15 @@
 	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;
+	vf->codec_vfmt = VFORMAT_AVS;
 
 }
 
 #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;
@@ -864,8 +881,7 @@
 			pdata += 8;
 		}
 	} else {
-		wp_start = user_data_wp +
-			USER_DATA_SIZE - user_data_len;
+		wp_start = user_data_wp + USER_DATA_SIZE - user_data_len;
 
 		pdata = (unsigned char *)hw->user_data_buffer;
 		pdata += wp_start;
@@ -891,20 +907,10 @@
 	}
 #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)
@@ -963,16 +969,8 @@
 
 	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)
 {
@@ -987,7 +985,7 @@
 
 	if (kfifo_len(&hw->display_q) > VF_POOL_SIZE) {
 		debug_print(hw, PRINT_FLAG_RUN_FLOW,
-			"kfifo len:%d invaild, peek error\n",
+			"kfifo len:%d invalid, peek error\n",
 			kfifo_len(&hw->display_q));
 		return NULL;
 	}
@@ -1008,7 +1006,6 @@
 	}
 
 	return NULL;
-
 }
 
 static struct vframe_s *vavs_vf_get(void *op_arg)
@@ -1017,6 +1014,7 @@
 	struct vdec_avs_hw_s *hw =
 	(struct vdec_avs_hw_s *)op_arg;
 	unsigned long flags;
+	struct vdec_s *vdec = hw_to_vdec(hw);
 
 	if (hw->recover_flag)
 		return NULL;
@@ -1049,6 +1047,18 @@
 				buf_of_vf(vf)->detached);
 		}
 		spin_unlock_irqrestore(&lock, flags);
+
+		vf->vf_ud_param.magic_code = UD_MAGIC_CODE;
+		vf->vf_ud_param.ud_param.buf_len = 0;
+		vf->vf_ud_param.ud_param.pbuf_addr = NULL;
+		vf->vf_ud_param.ud_param.instance_id = vdec->afd_video_id;
+
+		vf->vf_ud_param.ud_param.meta_info.duration = vf->duration;
+		vf->vf_ud_param.ud_param.meta_info.flags = (VFORMAT_AVS << 3);
+		vf->vf_ud_param.ud_param.meta_info.vpts = vf->pts;
+		if (vf->pts)
+			vf->vf_ud_param.ud_param.meta_info.vpts_valid = 1;
+
 		return vf;
 	}
 	spin_unlock_irqrestore(&lock, flags);
@@ -1061,6 +1071,8 @@
 	int i;
 	struct vdec_avs_hw_s *hw =
 	(struct vdec_avs_hw_s *)op_arg;
+	struct vdec_s *vdec = hw_to_vdec(hw);
+	unsigned long flags;
 
 	if (vf) {
 		hw->put_num++;
@@ -1076,6 +1088,7 @@
 	if (hw->recover_flag)
 		return;
 
+	spin_lock_irqsave(&lock, flags);
 	for (i = 0; i < VF_POOL_SIZE; i++) {
 		if (vf == &hw->vfpool[i].vf)
 			break;
@@ -1083,7 +1096,9 @@
 	if (i < VF_POOL_SIZE)
 
 		kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf);
+	spin_unlock_irqrestore(&lock, flags);
 
+	vdec_up(vdec);
 }
 
 static int vavs_event_cb(int type, void *data, void *private_data)
@@ -1106,8 +1121,7 @@
 {
 	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;
 
@@ -1148,7 +1162,7 @@
 static int vavs_set_isreset(struct vdec_s *vdec, int isreset)
 {
 	struct vdec_avs_hw_s *hw =
-	(struct vdec_avs_hw_s *)vdec->private;
+		(struct vdec_avs_hw_s *)vdec->private;
 
 	hw->is_reset = isreset;
 	return 0;
@@ -1194,6 +1208,28 @@
 		decbuf_size = 0x300000;
 	}
 
+	for (i = 0; i < hw->vf_buf_num_used; i++) {
+		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;
+		}
+	}
+
 #ifdef AVSP_LONG_CABAC
 	need_alloc_buf_num = hw->vf_buf_num_used + 2;
 #else
@@ -1226,83 +1262,64 @@
 			continue;
 		}
 #endif
-		if (hw->m_ins_flag) {
-			unsigned canvas;
+		if (i < hw->vf_buf_num_used) {
+			if (hw->m_ins_flag) {
 
-			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];
+				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 =
+					vdec->canvas_mode;
+				hw->canvas_config[i][0].endian = 0;
+
+				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 =
+					vdec->canvas_mode;
+				hw->canvas_config[i][1].endian = 0;
 			} 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);
+				canvas_config(canvas_base + canvas_num * i + 0,
+						buf_start,
+						canvas_width, canvas_height,
+						CANVAS_ADDR_NOWRAP,
+						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);
 #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);
+				canvas_config(canvas_num * i + 0,
+						buf_start,
+						canvas_width, canvas_height,
+						CANVAS_ADDR_NOWRAP,
+						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);
+				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);
 #endif
-			debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
-				"canvas config %d, addr %p\n", i,
-					   (void *)buf_start);
+				debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
+					"canvas config %d, addr %p\n", i,
+						   (void *)buf_start);
+			}
 		}
 	}
 	return 0;
@@ -1422,14 +1439,12 @@
 	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);
@@ -1451,6 +1466,10 @@
 	hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR);
 	hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR);
 
+	debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+		"%s ANC0_CANVAS_ADDR = 0x%x, ANC1_CANVAS_ADDR = 0x%x, ANC2_CANVAS_ADDR = 0x%x\n",
+		__func__, READ_VREG(ANC0_CANVAS_ADDR), READ_VREG(ANC1_CANVAS_ADDR), READ_VREG(ANC2_CANVAS_ADDR));
+
 	hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE);
 
 	hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG);
@@ -1484,14 +1503,12 @@
 	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);
@@ -1504,17 +1521,34 @@
 	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(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);
+	if (hw->refs[1] == -1)
+		WRITE_VREG(ANC0_CANVAS_ADDR, 0xffffffff);
+	else
+		WRITE_VREG(ANC0_CANVAS_ADDR, hw->canvas_spec[hw->refs[1]]);
+
+	if (hw->refs[0] == -1) {
+		if (hw->refs[1] == -1)
+			WRITE_VREG(ANC1_CANVAS_ADDR, 0xffffffff);
+		else
+			WRITE_VREG(ANC1_CANVAS_ADDR, hw->canvas_spec[hw->refs[1]]);
+	}
+	else
+		WRITE_VREG(ANC1_CANVAS_ADDR, hw->canvas_spec[hw->refs[0]]);
+
+	debug_print(hw, PRINT_FLAG_DEC_DETAIL,
+		"%s ANC0_CANVAS_ADDR = 0x%x, ANC1_CANVAS_ADDR = 0x%x, ANC2_CANVAS_ADDR = 0x%x\n",
+		__func__, READ_VREG(ANC0_CANVAS_ADDR), READ_VREG(ANC1_CANVAS_ADDR), READ_VREG(ANC2_CANVAS_ADDR));
+	WRITE_VREG(MCRCC_CTL1, 0xff1);
 
     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);
@@ -1543,7 +1577,7 @@
 #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);
 
@@ -1555,15 +1589,6 @@
 	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
@@ -1574,6 +1599,16 @@
 	/*************************************************************/
 	if (hw->m_ins_flag) {
 		int i;
+		u32 index = -1;
+		index = find_free_buffer(hw);
+		if (index < 0)
+			return -1;
+		hw->decoding_index = index;
+		debug_print(hw, PRINT_FLAG_DECODING,
+			"hw->decoding_index = %d\n",
+			hw->decoding_index);
+		WRITE_VREG(AV_SCRATCH_4, index);
+		WRITE_VREG(AV_SCRATCH_B, 0);
 		if (hw->decode_pic_count == 0) {
 			r = vavs_canvas_init(hw);
 #ifndef USE_DYNAMIC_BUF_NUM
@@ -1600,21 +1635,24 @@
 			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);
+			if (hw->canvas_config[i][0].phy_addr &&
+				hw->canvas_config[i][1].phy_addr) {
+				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);
+				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);
@@ -1629,31 +1667,18 @@
 			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)
-				);
+					((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)
-			);
-		}
+			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 */
@@ -1696,15 +1721,10 @@
 #endif
 	CLEAR_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);
@@ -1776,6 +1796,9 @@
 	INIT_KFIFO(hw->recycle_q);
 	INIT_KFIFO(hw->newframe_q);
 
+	hw->refs[0] = -1;
+	hw->refs[1] = -1;
+
 	for (i = 0; i < VF_POOL_SIZE; i++) {
 		const struct vframe_s *vf = &hw->vfpool[i].vf;
 
@@ -1787,8 +1810,6 @@
 	for (i = 0; i < hw->vf_buf_num_used; i++)
 		hw->vfbuf_use[i] = 0;
 
-	/*cur_vfpool = vfpool;*/
-
 	if (hw->recover_flag == 1)
 		return;
 
@@ -1804,7 +1825,8 @@
 		MAX_BMMU_BUFFER_NUM,
 		4 + PAGE_SHIFT,
 		CODEC_MM_FLAGS_CMA_CLEAR |
-		CODEC_MM_FLAGS_FOR_VDECODER);
+		CODEC_MM_FLAGS_FOR_VDECODER,
+		BMMU_ALLOC_FLAGS_WAITCLEAR);
 	if (hw->mm_blk_handle == NULL)
 		pr_info("Error, decoder_bmmu_box_alloc_box fail\n");
 
@@ -1813,9 +1835,7 @@
 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;
-
+	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;
@@ -1856,26 +1876,10 @@
 
 	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 =
@@ -1925,11 +1929,10 @@
 		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);
+			vdec_source_changed(VFORMAT_AVS, 4096, 2048, 60);
 		} else {
 			vdec_source_changed(VFORMAT_AVS,
-			hw->frame_width, hw->frame_height, fps);
+				hw->frame_width, hw->frame_height, fps);
 		}
 
 	}
@@ -1956,25 +1959,6 @@
 #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",
@@ -1987,30 +1971,9 @@
 					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);
@@ -2059,14 +2022,7 @@
 {
 	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)) {
@@ -2077,14 +2033,7 @@
 	}
 	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);
@@ -2096,56 +2045,31 @@
 #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__);
+		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);*/
+	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__);
 		es_write_addr_virt = NULL;
 		return;
 	}
-#endif
-
 
 #ifdef BITSTREAM_READ_TMP_NO_CACHE
 	bitstream_read_tmp =
-		(void *)dma_alloc_coherent(amports_get_dma_device(),
+		(void *)decoder_dma_alloc_coherent(&bitstream_read_handle,
 			SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy,
-			 GFP_KERNEL);
+			 "AVS_BITSTREAM_BUF");
 
 #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__);
@@ -2172,23 +2096,12 @@
 	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);
 
@@ -2217,13 +2130,8 @@
 
 	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);
@@ -2241,17 +2149,13 @@
 
 	if (ret < 0) {
 		amvdec_disable();
-		/*vfree(buf);*/
 		pr_err("AVS: the %s fw loading failed, err: %x\n",
-			tee_enabled() ? "TEE" : "local", ret);
+			fw_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)
@@ -2370,9 +2274,9 @@
 #ifdef ENABLE_USER_DATA
 	if (NULL == hw->user_data_buffer) {
 		hw->user_data_buffer =
-			dma_alloc_coherent(amports_get_dma_device(),
+			decoder_dma_alloc_coherent(&hw->user_data_handle,
 				USER_DATA_SIZE,
-				&hw->user_data_buffer_phys, GFP_KERNEL);
+				&hw->user_data_buffer_phys, "AVS_AUX_BUF");
 		if (!hw->user_data_buffer) {
 			pr_info("%s: Can not allocate hw->user_data_buffer\n",
 				   __func__);
@@ -2450,7 +2354,7 @@
 
 #ifdef BITSTREAM_READ_TMP_NO_CACHE
 		if (bitstream_read_tmp) {
-			dma_free_coherent(amports_get_dma_device(),
+			decoder_dma_free_coherent(bitstream_read_handle,
 				SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
 				bitstream_read_tmp_phy);
 			bitstream_read_tmp = NULL;
@@ -2477,8 +2381,8 @@
 
 #ifdef ENABLE_USER_DATA
 	if (hw->user_data_buffer != NULL) {
-		dma_free_coherent(
-			amports_get_dma_device(),
+		decoder_dma_free_coherent(
+			hw->user_data_handle,
 			USER_DATA_SIZE,
 			hw->user_data_buffer,
 			hw->user_data_buffer_phys);
@@ -2530,7 +2434,6 @@
 	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])
@@ -2557,16 +2460,15 @@
 
 		if (level < pre_decode_buf_level) {
 			hw->not_run_ready++;
-			return 0;
+			return PRE_LEVEL_NOT_ENOUGH;
 		}
 	}
 
-	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;
+	recycle_frames(hw);
+
+	if (!is_enough_free_buffer(hw)) {
+		hw->buffer_not_ready++;
+		return 0;
 	}
 
 	if (again_threshold > 0 &&
@@ -2580,7 +2482,7 @@
 			again_threshold) {
 			int r = vdec_sync_input(vdec);
 				debug_print(hw, PRINT_FLAG_VFRAME_DETAIL,
-					"%s buf lelvel:%x\n",  __func__, r);
+					"%s buf level:%x\n",  __func__, r);
 			ret = 0;
 		}
 	}
@@ -2620,6 +2522,7 @@
 			msleep(delay);
 #endif
 		vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+		hw->chunk = NULL;
 	} else if (hw->dec_result == DEC_RESULT_AGAIN
 	&& (hw_to_vdec(hw)->next_status !=
 		VDEC_STATUS_DISCONNECTED)) {
@@ -2648,6 +2551,7 @@
 		READ_VREG(VLD_MEM_VIFIFO_WP),
 		READ_VREG(VLD_MEM_VIFIFO_RP));
 		vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk);
+		hw->chunk = NULL;
 		vdec_clean_input(hw_to_vdec(hw));
 		return;
 	} else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) {
@@ -2669,6 +2573,7 @@
 		}
 		hw->eos = 1;
 		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) {
@@ -2692,7 +2597,7 @@
 		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);
+		hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg, CORE_MASK_VDEC_1);
 		debug_print(hw, 0x80000,
 		"%s:\n", __func__);
 	}
@@ -2730,6 +2635,12 @@
 			hw->vfbuf_use[vf->index] = 0;
 		}
 	}
+	for (i = 0; i < VF_BUF_NUM_MAX; i++) {
+		hw->ref_use[i] = 0;
+		hw->buf_use[i] = 0;
+	}
+	hw->refs[0] = -1;
+	hw->refs[1] = -1;
 	if (error_handle_policy & 0x2) {
 		while (!kfifo_is_empty(&hw->display_q)) {
 			if (kfifo_get(&hw->display_q, &vf)) {
@@ -2834,6 +2745,7 @@
 			if ((vf->index < hw->vf_buf_num_used) &&
 				(buf_of_vf(vf)->detached == 0) &&
 			 (--hw->vfbuf_use[vf->index] == 0)) {
+				hw->buf_use[vf->index] --;
 				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",
@@ -2936,7 +2848,7 @@
 		hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
 	}
 
-	if (READ_VREG(AVS_SOS_COUNT)) {
+	if (!atomic_read(&hw->error_handler_run) && !work_busy(&hw->work) && READ_VREG(AVS_SOS_COUNT)) {
 		if (!error_recovery_mode) {
 			amvdec_stop();
 			if (error_handle_policy & 0x1) {
@@ -2958,6 +2870,7 @@
 			__func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL),
 			READ_VREG(AVS_SOS_COUNT));
 			reset_process_time(hw);
+			atomic_set(&hw->error_handler_run, 1);
 			vdec_schedule_work(&hw->work);
 		}
 	}
@@ -3010,13 +2923,16 @@
 }
 
 static void run(struct vdec_s *vdec, unsigned long mask,
-void (*callback)(struct vdec_s *, void *),
+void (*callback)(struct vdec_s *, void *, int),
 		void *arg)
 {
 	struct vdec_avs_hw_s *hw =
 	(struct vdec_avs_hw_s *)vdec->private;
 	int save_reg;
 	int size, ret;
+	int i;
+
+	hw->run_flag = 1;
 	if (!hw->vdec_pg_enable_flag) {
 		hw->vdec_pg_enable_flag = 1;
 		amvdec_enable();
@@ -3059,6 +2975,7 @@
 			hw->input_empty++;
 			hw->dec_result = DEC_RESULT_AGAIN;
 			vdec_schedule_work(&hw->work);
+			hw->run_flag = 0;
 			return;
 		}
 	} else {
@@ -3066,6 +2983,7 @@
 			hw->input_empty++;
 			hw->dec_result = DEC_RESULT_AGAIN;
 			vdec_schedule_work(&hw->work);
+			hw->run_flag = 0;
 			return;
 		}
 	}
@@ -3152,24 +3070,38 @@
 			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->fw->name, fw_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;
 		vdec->mc_type = VFORMAT_AVS;
 	}
+	debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "vfbuf_use:\n");
+	for (i = 0; i < hw->vf_buf_num_used; i++)
+		debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: vf_buf_use %d\n",
+			i, hw->vfbuf_use[i]);
+	debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "ref_use:\n");
+	for (i = 0; i < hw->vf_buf_num_used; i++)
+		debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: ref_use %d\n",
+			i, hw->ref_use[i]);
+	debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "buf_use:\n");
+	for (i = 0; i < hw->vf_buf_num_used; i++)
+		debug_print(hw, PRINT_FLAG_BUFFER_DETAIL, "%d: buf_use %d\n",
+			i, hw->buf_use[i]);
 	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);
+		hw->run_flag = 0;
 		return;
 	}
 
 	/*
-		This configureation of VC1_CONTROL_REG will
+		This configuration 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
@@ -3222,86 +3154,454 @@
 	hw->stat |= STAT_VDEC_RUN;
 
 	hw->stat |= STAT_TIMER_ARM;
-
+	atomic_set(&hw->error_handler_run, 0);
 	mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL);
+	hw->run_flag = 0;
 }
 
 static void reset(struct vdec_s *vdec)
 {
 }
 
+static int prepare_display_buf(struct vdec_avs_hw_s *hw,
+	struct pic_info_t *pic)
+{
+	struct vdec_s *vdec = hw_to_vdec(hw);
+	struct vframe_s *vf = NULL;
+	u32 reg = pic->buffer_info;
+	bool force_interlaced_frame = false;
+	u32 picture_type = pic->picture_type;
+	u32 repeat_count = pic->repeat_cnt;
+	unsigned int pts = pic->pts;
+	unsigned int pts_valid = pic->pts_valid;
+	unsigned int offset = pic->offset;
+	u64 pts_us64 = pic->pts64;
+	u32 buffer_index = pic->index;
+	u32 dur;
+	unsigned short decode_pic_count = pic->decode_pic_count;
+
+	if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE)
+		&& hw->frame_width == 1920 && hw->frame_height == 1080) {
+			force_interlaced_frame = true;
+	}
+
+	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 == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+				vf->pts_us64 =
+					(((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+				vf->pts = 0;
+			} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+				checkout_pts_offset pts_info;
+				pts_info.offset = (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+				if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+					vf->pts = pts_info.pts;
+					vf->pts_us64 = pts_info.pts_64;
+				} else {
+					vf->pts = 0;
+					vf->pts_us64 = 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);
+			if (hw->pics[buffer_index].error_flag) {
+				vavs_vf_put(vf, hw);
+			} else {
+				vdec_vframe_ready(vdec, vf);
+				kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+				ATRACE_COUNTER(hw->pts_name, vf->pts);
+				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 == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+				vf->pts_us64 = (u64)-1;
+				vf->pts = 0;
+			} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+				checkout_pts_offset pts_info;
+				pts_info.offset = -1;
+				if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+					vf->pts = pts_info.pts;
+					vf->pts_us64 = pts_info.pts_64;
+				} else {
+					vf->pts = 0;
+					vf->pts_us64 = 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);
+
+			if (hw->pics[buffer_index].error_flag) {
+				vavs_vf_put(vf, hw);
+			} else {
+				vdec_vframe_ready(vdec, vf);
+				kfifo_put(&hw->display_q, (const struct vframe_s *)vf);
+				ATRACE_COUNTER(hw->pts_name, vf->pts);
+				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 == MULTI_PTS_SERVER_UPPER_LOOKUP)) {
+				vf->pts_us64 =
+					(((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+				vf->pts = 0;
+			} else if (vdec->vbuf.use_ptsserv == MULTI_PTS_SERVER_DECODER_LOOKUP) {
+				checkout_pts_offset pts_info;
+				pts_info.offset = (((u64)vf->duration << 32) & 0xffffffff00000000) | offset;
+				if (!ptsserver_checkout_pts_offset((vdec->pts_server_id & 0xff), &pts_info)) {
+					vf->pts = pts_info.pts;
+					vf->pts_us64 = pts_info.pts_64;
+				} else {
+					vf->pts = 0;
+					vf->pts_us64 = 0;
+				}
+			}
+
+			if (hw->pics[buffer_index].error_flag) {
+				vavs_vf_put(vf, hw);
+			} else {
+				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->pts);
+				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);
+		return 0;
+}
+
+static void check_ref_error(struct vdec_avs_hw_s *hw, int index)
+{
+	struct pic_info_t *pic = NULL;
+	int i = 0;
+
+	pic = &hw->pics[index];
+	if ((pic->picture_type) == B_PICTURE) {
+		if ((hw->refs[0] < 0) || (hw->refs[0] >= hw->vf_buf_num_used) ||
+			(hw->refs[1] < 0) || (hw->refs[1] >= hw->vf_buf_num_used)) {
+			pic->error_flag = 1;
+			debug_print(hw, 0,
+				"avs: ref pic not exist, set cur pic error\n");
+			return ;
+		}
+		for (i = 0; i < 2; i++) {
+			if (hw->pics[hw->refs[i]].error_flag) {
+				pic->error_flag = 1;
+				debug_print(hw, 0,
+					"avs: L%d ref error, set index %d error_mark\n", i, index);
+				return ;
+			}
+		}
+	}
+
+	if ((pic->picture_type) == P_PICTURE) {
+		if ((hw->refs[1] < 0) || (hw->refs[1] >= hw->vf_buf_num_used)) {
+			pic->error_flag = 1;
+			debug_print(hw, 0,
+				"avs: ref pic not exist, set cur pic error\n");
+			return ;
+		} else if (hw->pics[hw->refs[1]].error_flag) {
+			pic->error_flag = 1;
+			debug_print(hw, 0,
+				"avs: L0 ref error, set index %d error_mark\n", index);
+		}
+	}
+}
+
+
 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;
+		unsigned int pts, 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_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, READ_VREG(AV_SCRATCH_2) 0x%x\n",
+				READ_VREG(AVS_BUFFEROUT),READ_VREG(DECODE_STATUS), READ_VREG(AV_SCRATCH_N), READ_VREG(DEBUG_REG1), READ_VREG(AV_SCRATCH_2));
 
 		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) {
+		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,
@@ -3354,14 +3654,17 @@
 				READ_VREG(DECODE_STATUS),
 				buffer_status_debug);
 		}
+		reg = READ_VREG(DECODE_STATUS); // need find a null register pyx
+		if (reg == DECODE_STATUS_INFO) {
+			WRITE_VREG(DECODE_STATUS, 0);
+			debug_print(hw, PRINT_FLAG_DECODING, "READ_VREG(AVS_PIC_INFO) = 0x%x\n", READ_VREG(AVS_PIC_INFO));
+			return IRQ_HANDLED;
+		}
 
 #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);
+				(READ_VREG(LONG_CABAC_REQ) >> 8) & 0xFF);
 			schedule_work(&long_cabac_wd_work);
 		}
 #endif
@@ -3376,17 +3679,28 @@
 				= READ_VREG(DECODE_PIC_COUNT);
 			debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n",
 				reg, decode_pic_count);
+			hw->pics[hw->decoding_index].offset = READ_VREG(AVS_OFFSET_REG);
+			hw->pics[hw->decoding_index].repeat_cnt = READ_VREG(AVS_REPEAT_COUNT);
+			hw->pics[hw->decoding_index].buffer_info = reg;
+			hw->pics[hw->decoding_index].index = hw->decoding_index;
+			hw->pics[hw->decoding_index].decode_pic_count = decode_pic_count;
+			hw->pics[hw->decoding_index].error_flag = 0;
 			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 (vdec->vbuf.use_ptsserv == SINGLE_PTS_SERVER_DECODER_LOOKUP) {
 					if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts,
 						&frame_size, 0, &pts_us64) == 0) {
-						pts_valid = 1;
+						hw->pics[hw->decoding_index].pts_valid = 1;
+						hw->pics[hw->decoding_index].pts = pts;
+						hw->pics[hw->decoding_index].pts64 = pts_us64;
 #ifdef DEBUG_PTS
 						hw->pts_hit++;
 #endif
 					} else {
+						hw->pics[hw->decoding_index].pts_valid = 0;
+						hw->pics[hw->decoding_index].pts = 0;
+						hw->pics[hw->decoding_index].pts64 = 0;
 #ifdef DEBUG_PTS
 						hw->pts_missed++;
 #endif
@@ -3394,365 +3708,66 @@
 				}
 			}
 
-			repeat_count = READ_VREG(AVS_REPEAT_COUNT);
 #ifdef USE_DYNAMIC_BUF_NUM
-			buffer_index =
-				((reg & 0x7) +
-				(((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
+			buffer_index = ((reg & 0x7) + (((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
 #else
 			if (firmware_sel == 0)
-				buffer_index =
-					((reg & 0x7) +
+				buffer_index = ((reg & 0x7) +
 					(((reg >> 8) & 0x3) << 3) - 1) & 0x1f;
 			else
-				buffer_index =
-					((reg & 0x7) - 1) & 3;
+				buffer_index = ((reg & 0x7) - 1) & 3;
 #endif
 			picture_type = (reg >> 3) & 7;
+			hw->pics[hw->decoding_index].picture_type = picture_type;
 #ifdef DEBUG_PTS
 			if (picture_type == I_PICTURE) {
-				/* pr_info("I offset 0x%x, pts_valid %d\n",
-				 *	 offset, pts_valid);
-				 */
-				if (!pts_valid)
+				if (!hw->pics[hw->decoding_index].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);
+					~(1 << hw->decoding_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;
+				WRITE_VREG(AVS_BUFFERIN, ~(1 << hw->decoding_index));
+				hw->buf_use[hw->decoding_index]--;
+			} else {
+				u32 decode_status = READ_VREG(DECODE_STATUS) & 0xff;
+				if (vdec_frame_based(vdec) && (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
+						decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY)) {
+					hw->pics[hw->decoding_index].error_flag = 1;
 				}
-				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;
+				check_ref_error(hw, hw->decoding_index);
+
+				if ((picture_type == I_PICTURE) ||
+					(picture_type == P_PICTURE)) {
+					buffer_index = update_reference(hw, hw->decoding_index);
 				} 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;
+					/* drop b frame before reference pic ready */
+					if (hw->refs[0] == -1)
+						buffer_index = hw->vf_buf_num_used;
 				}
 
-				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->pts);
-				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));
-					}
+				if (buffer_index < hw->vf_buf_num_used) {
+					debug_print(hw, PRINT_FLAG_RUN_FLOW,
+						"avs: show num %d, type %d, index %d, offset %x\n",
+						decode_pic_count, picture_type, buffer_index, offset);
+					prepare_display_buf(hw, &hw->pics[buffer_index]);
 				} 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->pts);
-				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->pts);
-				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++;
+					debug_print(hw, PRINT_FLAG_RUN_FLOW,
+						"avs: drop pic num %d, type %d, index %d, offset %x\n",
+						decode_pic_count, picture_type, buffer_index, offset);
 				}
 			}
-			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;
@@ -3786,15 +3801,19 @@
 				amvdec_stop();
 #endif
 				vavs_save_regs(hw);
+				if (reg) {
+					hw->buf_use[hw->decoding_index]++;
+				}
+
 				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",
+					"%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, AV_SCRATCH_B=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));
+					READ_VREG(VIFF_BIT_CNT), READ_VREG(AV_SCRATCH_B));
 				vdec_schedule_work(&hw->work);
 				return IRQ_HANDLED;
 			} else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY ||
@@ -3816,16 +3835,19 @@
 						hw->decode_pic_count++;
 					}
 					vavs_save_regs(hw);
+					if (reg) {
+						hw->buf_use[hw->decoding_index]++;
+					}
 				} 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",
+					"%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, AV_SCRATCH_B=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);
+					READ_VREG(VIFF_BIT_CNT), hw->decode_status_skip_pic_done_flag, hw->decode_decode_cont_start_code, READ_VREG(AV_SCRATCH_B));
 				vdec_schedule_work(&hw->work);
 				return IRQ_HANDLED;
 			}
@@ -3865,7 +3887,10 @@
 		);
 
 	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",
+		"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 fun_flag %d\n",
 		vdec_frame_based(vdec),
 		READ_VREG(DECODE_STATUS) & 0xff,
 		hw->buf_status,
@@ -3878,11 +3903,12 @@
 		hw->display_frame_count,
 		hw->run_count,
 		hw->not_run_ready,
-		hw->input_empty
+		hw->input_empty,
+		hw->run_flag
 		);
 
 	if (vf_get_receiver(vdec->vf_provider_name)) {
-		enum receviver_start_e state =
+		enum receiver_start_e state =
 		vf_notify_receiver(vdec->vf_provider_name,
 			VFRAME_EVENT_PROVIDER_QUREY_STATE,
 			NULL);
@@ -3912,6 +3938,14 @@
 	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, "ref_use:\n");
+	for (i = 0; i < hw->vf_buf_num_used; i++)
+		debug_print(hw, 0, "%d: ref_use %d\n",
+			i, hw->ref_use[i]);
+	debug_print(hw, 0, "buf_use:\n");
+	for (i = 0; i < hw->vf_buf_num_used; i++)
+		debug_print(hw, 0, "%d: buf_use %d\n",
+			i, hw->buf_use[i]);
 
 	debug_print(hw, 0,
 		"DECODE_STATUS=0x%x\n",
@@ -4009,6 +4043,7 @@
 	}
 	/*atomic_set(&hw->error_handler_run, 0);*/
 	hw->m_ins_flag = 1;
+	hw->run_flag = 0;
 
 	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans)
 		firmware_sel = 1;
@@ -4056,9 +4091,9 @@
 #ifdef ENABLE_USER_DATA
 	if (NULL == hw->user_data_buffer) {
 		hw->user_data_buffer =
-			dma_alloc_coherent(amports_get_dma_device(),
+			decoder_dma_alloc_coherent(&hw->user_data_handle,
 				USER_DATA_SIZE,
-				&hw->user_data_buffer_phys, GFP_KERNEL);
+				&hw->user_data_buffer_phys, "AVS_AUX_BUF");
 		if (!hw->user_data_buffer) {
 			pr_info("%s: Can not allocate hw->user_data_buffer\n",
 				   __func__);
@@ -4084,8 +4119,8 @@
 		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);
+	hw->lmem_addr = (dma_addr_t)decoder_dma_alloc_coherent(&hw->lmem_phy_handle,
+	               LMEM_BUF_SIZE, (dma_addr_t *)&hw->lmem_phy_addr, "AVS_LMEM_BUF");
 	if (hw->lmem_addr == 0) {
 		pr_err("%s: failed to alloc lmem buffer\n", __func__);
 		r = -1;
@@ -4143,12 +4178,12 @@
 	return 0;
 
 error4:
-	dma_free_coherent(amports_get_dma_device(),
+	decoder_dma_free_coherent(hw->lmem_phy_handle,
 		LMEM_BUF_SIZE, (void *)hw->lmem_addr,
 		hw->lmem_phy_addr);
 error3:
-	dma_free_coherent(
-		amports_get_dma_device(),
+	decoder_dma_free_coherent(
+		hw->user_data_handle,
 		USER_DATA_SIZE,
 		hw->user_data_buffer,
 		hw->user_data_buffer_phys);
@@ -4192,8 +4227,12 @@
 		cancel_work_sync(&hw->notify_work);
 
 		if (hw->mm_blk_handle) {
-			decoder_bmmu_box_free(hw->mm_blk_handle);
+			void *bmmu_box_tmp = hw->mm_blk_handle;
 			hw->mm_blk_handle = NULL;
+			if (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);
@@ -4209,8 +4248,8 @@
 		}
 	#ifdef ENABLE_USER_DATA
 		if (hw->user_data_buffer != NULL) {
-			dma_free_coherent(
-				amports_get_dma_device(),
+			decoder_dma_free_coherent(
+				hw->user_data_handle,
 				USER_DATA_SIZE,
 				hw->user_data_buffer,
 				hw->user_data_buffer_phys);
@@ -4225,7 +4264,7 @@
 			hw->lmem_addr = NULL;
 		}*/
 	if (hw->lmem_addr) {
-		dma_free_coherent(amports_get_dma_device(),
+		decoder_dma_free_coherent(hw->lmem_phy_handle,
 					LMEM_BUF_SIZE, (void *)hw->lmem_addr,
 					hw->lmem_phy_addr);
 		hw->lmem_addr = 0;
@@ -4512,7 +4551,7 @@
 		amvdec_disable();
 		/*vfree(buf);*/
 		pr_err("AVS: the %s fw loading failed, err: %x\n",
-			tee_enabled() ? "TEE" : "local", ret);
+			fw_tee_enabled() ? "TEE" : "local", ret);
 	}
 	pr_info("%s, %d\n", __func__, __LINE__);
 
@@ -4622,9 +4661,9 @@
 #ifdef ENABLE_USER_DATA
 	if (NULL == hw->user_data_buffer) {
 		hw->user_data_buffer =
-			dma_alloc_coherent(amports_get_dma_device(),
+			decoder_dma_alloc_coherent(&hw->user_data_handle,
 				USER_DATA_SIZE,
-				&hw->user_data_buffer_phys, GFP_KERNEL);
+				&hw->user_data_buffer_phys, "AVS_AUX_BUF");
 		if (!hw->user_data_buffer) {
 			pr_info("%s: Can not allocate hw->user_data_buffer\n",
 				   __func__);
@@ -4756,7 +4795,7 @@
 
 #ifdef BITSTREAM_READ_TMP_NO_CACHE
 		if (bitstream_read_tmp) {
-			dma_free_coherent(amports_get_dma_device(),
+			decoder_dma_free_coherent(bitstream_read_handle,
 				SVA_STREAM_BUF_SIZE, bitstream_read_tmp,
 				bitstream_read_tmp_phy);
 			bitstream_read_tmp = NULL;
@@ -4783,8 +4822,8 @@
 
 #ifdef ENABLE_USER_DATA
 	if (hw->user_data_buffer != NULL) {
-		dma_free_coherent(
-			amports_get_dma_device(),
+		decoder_dma_free_coherent(
+			hw->user_data_handle,
 			USER_DATA_SIZE,
 			hw->user_data_buffer,
 			hw->user_data_buffer_phys);
@@ -4975,7 +5014,7 @@
 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_PARM_DESC(udebug_flag, "\n amvdec_avs udebug_flag\n");
 
 module_param(udebug_pause_pos, uint, 0664);
 MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n");
diff --git a/drivers/frame_provider/decoder/avs_multi/avs_multi.h b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
index 8922b40..ca89e2c 100644
--- a/drivers/frame_provider/decoder/avs_multi/avs_multi.h
+++ b/drivers/frame_provider/decoder/avs_multi/avs_multi.h
@@ -1,22 +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:
-*/
+ * 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_
 
diff --git a/drivers/frame_provider/decoder/h264/Makefile b/drivers/frame_provider/decoder/h264/Makefile
deleted file mode 100644
index b7c85ee..0000000
--- a/drivers/frame_provider/decoder/h264/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264) += amvdec_h264.o
-amvdec_h264-objs += vh264.o
-
-obj-$(CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC) += amvdec_h264mvc.o
-amvdec_h264mvc-objs += vh264_mvc.o
-
diff --git a/drivers/frame_provider/decoder/h264/vh264.c b/drivers/frame_provider/decoder/h264/vh264.c
deleted file mode 100644
index 55f0581..0000000
--- a/drivers/frame_provider/decoder/h264/vh264.c
+++ /dev/null
@@ -1,4509 +0,0 @@
-/*
- * drivers/amlogic/media/frame_provider/decoder/h264/vh264.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.
- *
- */
-
-#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/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/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 "../../../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"
-#include "vh264.h"
-#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/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 "../../../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"
-#define HANDLE_H264_IRQ
-
-#if 0
-/* currently, only iptv supports this function*/
-#define SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
-#endif
-
-/* #define DEBUG_PTS */
-#if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */
-#define DROP_B_FRAME_FOR_1080P_50_60FPS
-#endif
-#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 VDEC_CLOCK_ADJUST_FRAME 30
-
-static inline bool close_to(int a, int b, int m)
-{
-	return (abs(a - b) < m) ? true : false;
-}
-
-static DEFINE_MUTEX(vh264_mutex);
-#define DEF_BUF_START_ADDR            0x1000000
-#define V_BUF_ADDR_OFFSET_NEW         (0x1ee000)
-#define V_BUF_ADDR_OFFSET             (0x13e000)
-
-#define PIC_SINGLE_FRAME        0
-#define PIC_TOP_BOT_TOP         1
-#define PIC_BOT_TOP_BOT         2
-#define PIC_DOUBLE_FRAME        3
-#define PIC_TRIPLE_FRAME        4
-#define PIC_TOP_BOT              5
-#define PIC_BOT_TOP              6
-#define PIC_INVALID              7
-
-#define EXTEND_SAR                      0xff
-
-#define VF_POOL_SIZE        64
-#define VF_BUF_NUM          24
-#define WORKSPACE_BUF_NUM	2
-#define PUT_INTERVAL        (HZ/100)
-#define NO_DISP_WD_COUNT    (3 * HZ / PUT_INTERVAL)
-
-#define SWITCHING_STATE_OFF       0
-#define SWITCHING_STATE_ON_CMD3   1
-#define SWITCHING_STATE_ON_CMD1   2
-#define SWITCHING_STATE_ON_CMD1_PENDING   3
-
-
-#define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001
-#define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE  0x0002
-#define DEC_CONTROL_FLAG_DISABLE_FAST_POC              0x0004
-
-#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 {
-	unsigned int y_addr;
-	unsigned int u_addr;
-	unsigned int v_addr;
-
-	int y_canvas_index;
-	int u_canvas_index;
-	int v_canvas_index;
-
-	unsigned int y_canvas_width;
-	unsigned int u_canvas_width;
-	unsigned int v_canvas_width;
-
-	unsigned int y_canvas_height;
-	unsigned int u_canvas_height;
-	unsigned int v_canvas_height;
-
-	unsigned long phy_addr;
-	int alloc_count;
-};
-
-#define spec2canvas(x)  \
-	(((x)->v_canvas_index << 16) | \
-	 ((x)->u_canvas_index << 8)  | \
-	 ((x)->y_canvas_index << 0))
-
-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_prot_init(void);
-static int vh264_local_init(void);
-static void vh264_put_timer_func(struct timer_list *timer);
-static void stream_switching_done(void);
-
-static const char vh264_dec_id[] = "vh264-dev";
-
-#define PROVIDER_NAME   "decoder.h264"
-
-static const struct vframe_operations_s vh264_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,
-};
-
-static struct vframe_provider_s vh264_vf_prov;
-/*TODO irq*/
-#if 1
-static u32 frame_width, frame_height, frame_dur, frame_prog, frame_packing_type,
-	   last_duration;
-static u32 saved_resolution;
-static u32 last_mb_width, last_mb_height;
-#else
-static u32 frame_buffer_size;
-static u32 frame_width, frame_height, frame_dur, frame_prog, last_duration;
-static u32 last_mb_width, last_mb_height;
-static u32 frame_packing_type;
-#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);
-static DECLARE_KFIFO(delay_display_q, struct vframe_s *, VF_POOL_SIZE);
-
-static struct vframe_s vfpool[VF_POOL_SIZE];
-static s32 vfbuf_use[VF_BUF_NUM];
-static struct buffer_spec_s buffer_spec[VF_BUF_NUM];
-static struct buffer_spec_s fense_buffer_spec[2];
-/* disp buf + keep buf+ fense buf + workspace  */
-
-#define MAX_BLK_BUFFERS (VF_BUF_NUM + 2 + WORKSPACE_BUF_NUM)
-#define VF_BUFFER_IDX(n) (WORKSPACE_BUF_NUM  + n)
-#define FENSE_BUFFER_IDX(n) (WORKSPACE_BUF_NUM + VF_BUF_NUM + n)
-
-#define USER_DATA_RUND_SIZE		(USER_DATA_SIZE + 4096)
-static struct vframe_s fense_vf[2];
-
-static struct timer_list recycle_timer;
-static u32 stat;
-static s32 buf_offset;
-static u32 pts_outside;
-static u32 sync_outside;
-static u32 dec_control;
-static u32 vh264_ratio;
-static u32 vh264_rotation;
-static u32 use_idr_framerate;
-static u32 high_bandwidth;
-
-static u32 seq_info;
-static u32 timing_info_present_flag;
-static u32 fixed_frame_rate_flag;
-static u32 fixed_frame_rate_check_count;
-static u32 aspect_ratio_info;
-static u32 num_units_in_tick;
-static u32 time_scale;
-static u32 h264_ar;
-static u32 decoder_debug_flag;
-static u32 dpb_size_adj = 6;
-static u32 fr_hint_status;
-
-#ifdef DROP_B_FRAME_FOR_1080P_50_60FPS
-static u32 last_interlaced;
-#endif
-static bool is_4k;
-static unsigned char h264_first_pts_ready;
-static bool h264_first_valid_pts_ready;
-static u32 h264pts1, h264pts2;
-static u32 h264_pts_count, duration_from_pts_done, duration_on_correcting;
-static u32 vh264_error_count;
-static u32 vh264_no_disp_count;
-static u32 fatal_error_flag;
-static u32 fatal_error_reset;
-static u32 max_refer_buf = 1;
-static u32 decoder_force_reset;
-static unsigned int no_idr_error_count;
-static unsigned int no_idr_error_max = 60;
-static unsigned int canvas_mode;
-
-#ifdef SUPPORT_BAD_MACRO_BLOCK_REDUNDANCY
-/* 0~128*/
-static u32 bad_block_scale;
-#endif
-static u32 enable_userdata_debug;
-
-static unsigned int enable_switch_fense = 1;
-#define EN_SWITCH_FENCE() (enable_switch_fense && !is_4k)
-static struct vframe_qos_s s_vframe_qos;
-static int frame_count;
-
-#if 0
-static u32 vh264_no_disp_wd_count;
-#endif
-static u32 vh264_running;
-static s32 vh264_stream_switching_state;
-static s32 vh264_eos;
-static struct vframe_s *p_last_vf;
-static s32 iponly_early_mode;
-static void *mm_blk_handle;
-static int tvp_flag;
-static bool is_reset;
-
-/*TODO irq*/
-#if 1
-static u32 last_pts, last_pts_remainder;
-#else
-static u32 last_pts;
-#endif
-static bool check_pts_discontinue;
-static u32 wait_buffer_counter;
-static u32 video_signal_from_vui;
-
-static uint error_recovery_mode;
-static uint error_recovery_mode_in = 3;
-static uint error_recovery_mode_use = 3;
-
-static uint mb_total = 0, mb_width = 0, mb_height;
-static uint saved_idc_level;
-#define UCODE_IP_ONLY 2
-#define UCODE_IP_ONLY_PARAM 1
-static uint ucode_type;
-
-#ifdef DEBUG_PTS
-static unsigned long pts_missed, pts_hit;
-#endif
-static uint debugfirmware;
-
-static atomic_t vh264_active = ATOMIC_INIT(0);
-static int vh264_reset;
-static struct work_struct error_wd_work;
-static struct work_struct stream_switching_work;
-static struct work_struct set_parameter_work;
-static struct work_struct notify_work;
-static struct work_struct set_clk_work;
-static struct work_struct userdata_push_work;
-
-struct h264_qos_data_node_t {
-	struct list_head list;
-
-	uint32_t b_offset;
-	int poc;
-	/* 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;
-};
-
-/*qos data records list waiting for match with picture that be display*/
-static struct list_head picture_qos_list;
-/*free qos data records list*/
-static struct list_head free_qos_nodes_list;
-#define MAX_FREE_QOS_NODES		64
-static struct h264_qos_data_node_t free_nodes[MAX_FREE_QOS_NODES];
-static struct work_struct qos_work;
-static struct dec_sysinfo vh264_amstream_dec_info;
-static dma_addr_t mc_dma_handle;
-static void *mc_cpu_addr;
-static u32 first_offset;
-static u32 first_pts;
-static u32 first_frame_size;
-static u64 first_pts64;
-static bool first_pts_cached;
-static void *sei_data_buffer;
-static dma_addr_t sei_data_buffer_phys;
-static int clk_adj_frame_count;
-
-#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_TOTAL_SIZE       (20*SZ_1K)
-#define MC_SWAP_SIZE        (4*SZ_1K)
-
-#define MODE_ERROR 0
-#define MODE_FULL  1
-
-static DEFINE_SPINLOCK(lock);
-static DEFINE_SPINLOCK(prepare_lock);
-static DEFINE_SPINLOCK(recycle_lock);
-
-static bool block_display_q;
-static int vh264_stop(int mode);
-static s32 vh264_init(void);
-
-
-#define DFS_HIGH_THEASHOLD 3
-
-static bool pts_discontinue;
-
-static struct ge2d_context_s *ge2d_videoh264_context;
-
-static struct vdec_info *gvs;
-
-static struct vdec_s *vdec_h264;
-
-static int ge2d_videoh264task_init(void)
-{
-	if (ge2d_videoh264_context == NULL)
-		ge2d_videoh264_context = create_ge2d_work_queue();
-
-	if (ge2d_videoh264_context == NULL) {
-		pr_info("create_ge2d_work_queue video task failed\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int ge2d_videoh264task_release(void)
-{
-	if (ge2d_videoh264_context) {
-		destroy_ge2d_work_queue(ge2d_videoh264_context);
-		ge2d_videoh264_context = NULL;
-	}
-	return 0;
-}
-
-static int ge2d_canvas_dup(struct canvas_s *srcy, struct canvas_s *srcu,
-		struct canvas_s *des, int format, u32 srcindex,
-		u32 desindex)
-{
-
-	struct config_para_ex_s ge2d_config;
-	/* pr_info("[%s]h264 ADDR srcy[0x%lx] srcu[0x%lx] des[0x%lx]\n",
-	 *	   __func__, srcy->addr, srcu->addr, des->addr);
-	 */
-	memset(&ge2d_config, 0, sizeof(struct config_para_ex_s));
-
-	ge2d_config.alu_const_color = 0;
-	ge2d_config.bitmask_en = 0;
-	ge2d_config.src1_gb_alpha = 0;
-
-	ge2d_config.src_planes[0].addr = srcy->addr;
-	ge2d_config.src_planes[0].w = srcy->width;
-	ge2d_config.src_planes[0].h = srcy->height;
-
-	ge2d_config.src_planes[1].addr = srcu->addr;
-	ge2d_config.src_planes[1].w = srcu->width;
-	ge2d_config.src_planes[1].h = srcu->height;
-
-	ge2d_config.dst_planes[0].addr = des->addr;
-	ge2d_config.dst_planes[0].w = des->width;
-	ge2d_config.dst_planes[0].h = des->height;
-
-	ge2d_config.src_para.canvas_index = srcindex;
-	ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
-	ge2d_config.src_para.format = format;
-	ge2d_config.src_para.fill_color_en = 0;
-	ge2d_config.src_para.fill_mode = 0;
-	ge2d_config.src_para.color = 0;
-	ge2d_config.src_para.top = 0;
-	ge2d_config.src_para.left = 0;
-	ge2d_config.src_para.width = srcy->width;
-	ge2d_config.src_para.height = srcy->height;
-
-	ge2d_config.dst_para.canvas_index = desindex;
-	ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
-	ge2d_config.dst_para.format = format;
-	ge2d_config.dst_para.fill_color_en = 0;
-	ge2d_config.dst_para.fill_mode = 0;
-	ge2d_config.dst_para.color = 0;
-	ge2d_config.dst_para.top = 0;
-	ge2d_config.dst_para.left = 0;
-	ge2d_config.dst_para.width = srcy->width;
-	ge2d_config.dst_para.height = srcy->height;
-
-	if (ge2d_context_config_ex(ge2d_videoh264_context, &ge2d_config) < 0) {
-		pr_info("ge2d_context_config_ex failed\n");
-		return -1;
-	}
-
-	stretchblt_noalpha(ge2d_videoh264_context, 0, 0, srcy->width,
-			srcy->height, 0, 0, srcy->width, srcy->height);
-
-	return 0;
-}
-
-static inline int fifo_level(void)
-{
-	return VF_POOL_SIZE - kfifo_len(&newframe_q);
-}
-
-
-void spec_set_canvas(struct buffer_spec_s *spec,
-		unsigned int width, unsigned int height)
-{
-	int endian;
-
-	endian = (canvas_mode == CANVAS_BLKMODE_LINEAR)?7:0;
-	config_cav_lut_ex(spec->y_canvas_index,
-			spec->y_addr,
-			width, height,
-			CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
-
-	config_cav_lut_ex(spec->u_canvas_index,
-			spec->u_addr,
-			width, height / 2,
-			CANVAS_ADDR_NOWRAP, canvas_mode, endian, VDEC_1);
-
-}
-
-static void vh264_notify_work(struct work_struct *work)
-{
-	pr_info("frame duration changed %d\n", frame_dur);
-	vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT,
-		(void *)((unsigned long)frame_dur));
-
-	return;
-}
-
-static void prepare_display_q(void)
-{
-	unsigned long flags;
-	int count;
-
-	spin_lock_irqsave(&prepare_lock, flags);
-
-	if (block_display_q) {
-		spin_unlock_irqrestore(&prepare_lock, flags);
-		return;
-	}
-
-	spin_unlock_irqrestore(&prepare_lock, flags);
-
-	count  = (int)VF_POOL_SIZE -
-		kfifo_len(&delay_display_q) -
-		kfifo_len(&display_q) -
-		kfifo_len(&recycle_q) -
-		kfifo_len(&newframe_q);
-
-	if ((vh264_stream_switching_state != SWITCHING_STATE_OFF)
-		|| !EN_SWITCH_FENCE())
-		count = 0;
-	else
-		count = (count < 2) ? 0 : 2;
-
-	while (kfifo_len(&delay_display_q) > count) {
-		struct vframe_s *vf;
-
-		if (kfifo_get(&delay_display_q, &vf)) {
-			kfifo_put(&display_q,
-				(const struct vframe_s *)vf);
-			ATRACE_COUNTER(MODULE_NAME, vf->pts);