Project import generated by Copybara.

GitOrigin-RevId: a13be63c5ff99e1fd1c223991f26f4265e6fef3e
diff --git a/Makefile b/Makefile
old mode 100755
new mode 100644
index 7481eee..6640ff9
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,3 @@
-mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
-MEDIA_MODULE_PATH := $(dir $(mkfile_path))
-VERSION_CONTROL_CFLAGS := $(shell ${MEDIA_MODULE_PATH}/version_control.sh)
 
 CONFIGS := CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \
@@ -18,25 +15,21 @@
 	CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
-	CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
-	CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
-	CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
-	CONFIG_AMLOGIC_MEDIA_GE2D=y \
-	CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
-	CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+	CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_H265=m
+
 
 EXTRA_INCLUDE := -I$(KERNEL_SRC)/$(M)/drivers/include
 
 CONFIGS_BUILD := -Wno-parentheses-equality -Wno-pointer-bool-conversion \
 				-Wno-unused-const-variable -Wno-typedef-redefinition \
-				-Wno-logical-not-parentheses -Wno-sometimes-uninitialized \
-				-Wno-frame-larger-than=
+				-Wno-logical-not-parentheses -Wno-sometimes-uninitialized
 
-KBUILD_CFLAGS_MODULE += $(GKI_EXT_MODULE_PREDEFINE)
 
 modules:
-	$(MAKE) -C  $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE) $(KBUILD_CFLAGS_MODULE) ${VERSION_CONTROL_CFLAGS}" $(CONFIGS)
+	$(MAKE) -C  $(KERNEL_SRC) M=$(M)/drivers modules "EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error $(CONFIGS_BUILD) $(EXTRA_INCLUDE)" $(CONFIGS)
 
 all: modules
 
diff --git a/Media.mk b/Media.mk
index 58db63b..68b0778 100644
--- a/Media.mk
+++ b/Media.mk
@@ -18,13 +18,13 @@
 	CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
 	CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AV1=m \
 	CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m \
 	CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
-	CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y \
-	CONFIG_AMLOGIC_MEDIA_GE2D=y \
-	CONFIG_AMLOGIC_MEDIA_VENC_MULTI=m \
-	CONFIG_AMLOGIC_MEDIA_VENC_JPEG=m
+	CONFIG_FRAME_WARN=4096
 
 define copy-media-modules
 $(foreach m, $(shell find $(strip $(1)) -name "*.ko"),\
@@ -63,10 +63,11 @@
 $(shell cp $(MEDIA_DRIVERS)/* $(MEDIA_MODULES) -rfa)
 
 define media-modules
-	PATH=$(KERNEL_TOOLPATHS):$$PATH \
-	$(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) $(KERNEL_ARGS) $(CONFIGS) \
-	"EXTRA_CFLAGS+=-I$(INCLUDE) -Wno-error" modules; \
-	find $(MEDIA_MODULES) -name "*.ko" | PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH xargs -i cp {} $(MODS_OUT)
+	PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+		$(MAKE) -C $(KDIR) M=$(MEDIA_MODULES) ARCH=$(KERNEL_ARCH) \
+		CROSS_COMPILE=$(PREFIX_CROSS_COMPILE) $(CONFIGS) \
+		EXTRA_CFLAGS+=-I$(INCLUDE) modules;
+		sh $(TOP)/device/amlogic/common/copy_modules.sh $(MEDIA_MODULES) $(MODS_OUT)
 endef
 
 else
@@ -90,10 +91,18 @@
 $(shell mkdir $(MODS_OUT) -p)
 endif
 
+ifeq ($(KERNEL_A32_SUPPORT), true)
+TOOLS := /opt/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
+else
+TOOLS := /opt/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
+endif
+
+
 modules:
-	CCACHE_NODIRECT="true" PATH=$(KERNEL_TOOLPATHS):$$PATH \
-	$(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) $(KERNEL_ARGS) $(CONFIGS) \
-	EXTRA_CFLAGS+=-I$(INCLUDE) -j64
+	CCACHE_NODIRECT="true" PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+		$(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) \
+		CROSS_COMPILE=$(TOOLS) $(CONFIGS) \
+		EXTRA_CFLAGS+=-I$(INCLUDE) -j64
 
 copy-modules:
 	@echo "start copying media modules."
@@ -102,9 +111,8 @@
 
 all: modules copy-modules
 
-
 clean:
-	PATH=$(KERNEL_TOOLPATHS):$$PATH \
-	$(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) $(KERNEL_ARGS) clean
+	PATH=$$(cd ./$(TARGET_HOST_TOOL_PATH); pwd):$$PATH \
+		$(MAKE) -C $(KDIR) M=$(MEDIA_DRIVERS) ARCH=$(KERNEL_ARCH) clean
 
 endif
diff --git a/VERSION b/VERSION
deleted file mode 100644
index 4b1504d..0000000
--- a/VERSION
+++ /dev/null
@@ -1,76 +0,0 @@
-Major_V=5
-Minor_V=3
-BaseChangeId=Ifc17e92ef9c9e211b8f01ebae1e97c5855fea084
-
-
-#history version
-#V5.2.104-g795aee00.003025 Release Notes
-#Release_ChangeId_V5_2=I34801cba60d54bfd9f459f7445d0362989c23496
-#V5.1.77-g0cdebf27.003009 Release Notes
-#Release_ChangeId_V5_1=Id7e315bbf379d166ca4b335cef13c983a8ca5078
-#Feature develop total count: 6
-#    critical feature develop count: 0
-#    important feature develop count: 4
-#    normal feature develop count: 2
-#Feature develop detail information:
-#    improve pip channel play
-#    support decoder fence
-#    fixed can't get hdr information correctly.
-#    add multi-vdec info for new format av1 after revert
-#    change ptsadjust and threshold from s64 to s32.
-#    support dw 0x100
-#Fixed BUG total count: 30
-#    fixed critical BUG count: 3
-#    fixed important feature develop count: 15
-#    fixed normal feature develop count: 12
-#Fixed BUG detail information:
-#    add VIDTYPE_COMPRESS in vf for dw mode with afbc buffer
-#    fix some the crash caused by null pointer
-#    fixed vpp wrapper memory leak.
-#    metadata lose the last byte every frame in frame mode
-#    fix avs color abnormal.
-#    fix gst secure v4l2 decoder not work
-#    fix the playback stuck when resolution changed
-#    h265 ucode send 2 interrupts cause playback stuck
-#    fix av1 freeze when burn-in test.
-#    fixed playback stuck after seek.
-#    fix 8k display abnormal.
-#    fixed irq-vdec-0 takes more cpu slice.
-#    fixed AV1 seek freezing.
-#    fixed failed to allocate tvp memory
-#    fixed issue of reports resolution change.
-#V5.0 Release Notes
-#Release_ChangeId_V5_0=I6053e02900215d9006469c38ca375ace498b849f
-#upgrade Kernel version to 5.4
-#Android R + v4l2dec (no vpp)   xts clean
-#v4ldec driver seperate from amports drivers
-#
-#V4.0.0 Release Notes
-#upgrade Kernel version to 4.19
-#v4l2 support  for h264/h265/vp9 
-#add fra support in decoder driver
-#
-#V3.0.0 Release Notes
-#upgrade Kernel version to 4.9
-#media_module remove from kernel 
-#new firmware management
-#mjpeg/mpeg12/mpeg2 multi-instance decoder support
-#h264 4k afbc support
-#AVS2 decoder support
-#vdec double write support
-#add av1 decoder support
-#add decoder QOS info report
-#upgrade TA ucode to 0.2 version
-#
-#V2.0.0 Release Notes
-#upgrade  Kernel version to 3.14 
-#Introduce codec_mm memory managment
-#add afbc scatter memory support
-#add vp9 decoder support
-#add 264/265/vp9 multi-instance decoder support
-#
-#V1.0.0 Release Notes
-#based kernel to 3.10
-#add H264 4K decoder support
-#add H265 video decoder support
-#H265 decoder support afbc output
diff --git a/build_media.sh b/build_media.sh
new file mode 100755
index 0000000..63eaf1a
--- /dev/null
+++ b/build_media.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+# Builds the media driver and updates the workspace path with output files
+
+exec_name=$0
+
+cpu_num=$(grep -c processor /proc/cpuinfo)
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+CROSS_COMPILE=$DIR/../prebuilt/toolchain/aarch64/bin/aarch64-cros-linux-gnu-
+KERNEL_ARCH=arm64
+KDIR=$DIR/../kernel
+INCLUDE=$DIR/drivers/include
+MEDIA_MODULES=$DIR/drivers
+CONFIGS="CONFIG_AMLOGIC_MEDIA_VDEC_MPEG12=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_MPEG2_MULTI=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_MPEG4_MULTI=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_VC1=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H264=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H264_MULTI=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H264_MVC=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_H265=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_VP9=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_MJPEG_MULTI=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_REAL=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS_MULTI=m \
+	CONFIG_AMLOGIC_MEDIA_VDEC_AVS2=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_H264=m \
+	CONFIG_AMLOGIC_MEDIA_VENC_H265=m \
+	CONFIG_FRAME_WARN=4096"
+
+set -o errtrace
+trap 'echo Fatal error: script ${exec_name} aborting at line $LINENO, command \"$BASH_COMMAND\" returned $?; exit 1' ERR
+
+function usage(){
+  echo "Usage: ${exec_name} <product> [workspace path]"
+  echo "supported products: sabrina"
+  echo "Note: if [workspace path] is not set, it still builds"
+}
+
+if (( $# < 1 ))
+then
+  usage
+  exit 2
+fi
+
+readonly product=$1
+readonly workspace_path=$2
+
+pushd $DIR
+
+
+make -C $KDIR M=$MEDIA_MODULES ARCH=$KERNEL_ARCH \
+CROSS_COMPILE=$CROSS_COMPILE $CONFIGS \
+EXTRA_CFLAGS+=-I$INCLUDE modules -j64
+
+case $product in
+  sabrina*)
+    ;;
+  *)
+    echo "unknown product: $product"
+    exit 1
+esac
+
+popd
+
+if [ ! -z $workspace_path ]; then
+  media_out_dir=${workspace_path}/device/google/${product}-kernel/lib/modules
+  mkdir -p ${media_out_dir}
+
+  for ko in aml_hardware_dmx.ko \
+            amvdec_avs2.ko \
+            amvdec_avs.ko \
+            amvdec_h264.ko \
+            amvdec_h264mvc.ko \
+            amvdec_h265.ko \
+            amvdec_mh264.ko \
+            amvdec_mjpeg.ko \
+            amvdec_mmjpeg.ko \
+            amvdec_mmpeg12.ko \
+            amvdec_mmpeg4.ko \
+            amvdec_mpeg12.ko \
+            amvdec_mpeg4.ko \
+            amvdec_real.ko \
+            amvdec_vc1.ko \
+            amvdec_vp9.ko \
+            decoder_common.ko \
+            encoder.ko \
+            firmware.ko \
+            media_clock.ko \
+            stream_input.ko \
+            vpu.ko \
+            amvdec_ports.ko \
+            video_framerate_adapter.ko \
+            media_sync.ko
+  do
+    find $MEDIA_MODULES -name $ko | xargs -i cp {} $media_out_dir
+  done
+  media_fw_out_dir=${workspace_path}/device/google/${product}-kernel/lib/firmware/video/
+  mkdir -p $media_fw_out_dir
+  cp -r firmware/* $media_fw_out_dir
+fi
diff --git a/drivers/Makefile b/drivers/Makefile
index e96ba44..3e487db 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -3,6 +3,6 @@
 obj-y	+=	frame_sink/
 obj-y	+=	stream_input/
 obj-y	+=	amvdec_ports/
+obj-y	+=	fake_video_out/
 obj-y	+=	framerate_adapter/
 obj-y	+=	media_sync/
-obj-$(CONFIG_AMLOGIC_MEDIA_V4L_DEC)	+=	amvdec_ports/
diff --git a/drivers/amvdec_ports/Makefile b/drivers/amvdec_ports/Makefile
index 2e7cff4..6395adf 100644
--- a/drivers/amvdec_ports/Makefile
+++ b/drivers/amvdec_ports/Makefile
@@ -3,10 +3,8 @@
 amvdec_ports-objs += aml_vcodec_dec.o
 amvdec_ports-objs += aml_vcodec_util.o
 amvdec_ports-objs += aml_vcodec_adapt.o
-amvdec_ports-objs += aml_vcodec_vpp.o
-amvdec_ports-objs += aml_vcodec_ge2d.o
+amvdec_ports-objs += aml_vcodec_vfm.o
 amvdec_ports-objs += vdec_drv_if.o
-amvdec_ports-objs += aml_task_chain.o
 amvdec_ports-objs += decoder/vdec_h264_if.o
 amvdec_ports-objs += decoder/vdec_hevc_if.o
 amvdec_ports-objs += decoder/vdec_vp9_if.o
diff --git a/drivers/amvdec_ports/aml_task_chain.c b/drivers/amvdec_ports/aml_task_chain.c
deleted file mode 100644
index 8dfe014..0000000
--- a/drivers/amvdec_ports/aml_task_chain.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include "aml_vcodec_drv.h"
-#include "aml_task_chain.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-struct task_item_name_s {
-	enum task_type_e	type;
-	const u8		*name;
-};
-
-static const struct task_item_name_s iname[] = {
-	{TASK_TYPE_DEC,		"dec"},
-	{TASK_TYPE_VPP,		"vpp"},
-	{TASK_TYPE_V4L_SINK,	"v4l-sink"},
-	{TASK_TYPE_GE2D,	"ge2d"},
-	{TASK_TYPE_MAX,		"unknown"},
-};
-
-static const u8 *type_to_name(enum task_type_e type)
-{
-	const u8 *name = "unknown";
-	int i, size = ARRAY_SIZE(iname);
-
-	for (i = 0; i < size; i++) {
-		if (type == iname[i].type)
-			name = iname[i].name;
-	}
-
-	return name;
-}
-
-static struct task_item_s *find_task_item(struct task_chain_s *task,
-					  enum task_type_e type)
-{
-	struct task_item_s *item = NULL;
-	ulong flags;
-
-	spin_lock_irqsave(&task->slock, flags);
-
-	if (!list_empty(&task->list_item)) {
-		struct task_item_s *p;
-
-		list_for_each_entry(p, &task->list_item, node) {
-			if (p->ops->type == type) {
-				item = p;
-				break;
-			}
-		}
-	}
-
-	if (item)
-		kref_get(&item->ref);
-
-	spin_unlock_irqrestore(&task->slock, flags);
-
-	return item;
-}
-
-static void task_item_release(struct kref *kref);
-
-static void task_item_vframe_push(struct task_item_s *item, struct vframe_s *vframe)
-{
-	int i = 0;
-
-	for (i = 0 ; i < 3; i++) {
-		if (item->vframe[i] == NULL) {
-			item->vframe[i] = vframe;
-			break;
-		}
-	}
-}
-
-static struct vframe_s *task_item_vframe_pop(struct task_item_s *item)
-{
-	struct vframe_s *vframe = NULL;
-	int i = 0;
-
-	for (i = 0 ; i < 3; i++) {
-		if (item->vframe[i] != NULL) {
-			vframe = item->vframe[i];
-			item->vframe[i] = NULL;
-			break;
-		}
-	}
-
-	return vframe;
-}
-
-static struct task_item_s *task_item_get(struct task_chain_s *task,
-				  enum task_type_e type)
-{
-	struct task_item_s *item = NULL;
-
-	item = find_task_item(task, type);
-	if (!item) {
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
-			"TSK(%px):%d get item:%d fail.\n", task, task->id, type);
-	}
-
-	return item;
-}
-
-static int task_item_put(struct task_item_s *item)
-{
-	return kref_put(&item->ref, task_item_release);
-}
-
-static void task_buffer_submit(struct task_chain_s *task,
-			       enum task_type_e type)
-{
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)task->obj;
-	struct task_item_s *item = NULL;
-	struct task_item_s *item2 = NULL;
-	struct vframe_s *vf = NULL;
-
-	item = task_item_get(task, type);
-	if (item) {
-		item->ops->get_vframe(item->caller, &vf);
-		fb->vframe = (void *)vf;
-		task_item_vframe_push(item, vf);
-		item->is_active = false;
-
-		item2 = task_item_get(task, task->map[0][type]);
-		if (item2) {
-			item2->is_active = true;
-			item2->ops->fill_buffer(task->ctx, fb);
-
-			v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-				"TSK(%px):%d, vf:%px, phy:%lx, submit %d => %d.\n",
-				task, task->id, vf, fb->m.mem[0].addr,
-				type, task->map[0][type]);
-
-			task->direction = TASK_DIR_SUBMIT;
-			task_item_put(item2);
-		}
-		task_item_put(item);
-	}
-}
-
-static void task_buffer_recycle(struct task_chain_s *task,
-			       enum task_type_e type)
-{
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)task->obj;
-	struct task_item_s *item = NULL;
-	struct task_item_s *item2 = NULL;
-
-	item = task_item_get(task, type);
-	if (item) {
-		item->is_active = false;
-
-		item2 = task_item_get(task, task->map[1][type]);
-		if (item2) {
-			struct vframe_s *vf = NULL;
-
-			item2->is_active = true;
-
-			vf = task_item_vframe_pop(item2);
-			item2->ops->put_vframe(item2->caller, vf);
-
-			v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-				"TSK(%px):%d, vf:%px, phy:%lx, recycle %d => %d.\n",
-				task, task->id, vf, fb->m.mem[0].addr,
-				type, task->map[1][type]);
-
-			task->direction = TASK_DIR_RECYCLE;
-			task_item_put(item2);
-		}
-		task_item_put(item);
-	}
-}
-
-void task_chain_show(struct task_chain_s *task)
-{
-	struct task_item_s *item = NULL;
-	char buf[128] = {0};
-	char *pbuf = buf;
-	ulong flags;
-
-	if (!task || !task->ctx)
-		return;
-
-	spin_lock_irqsave(&task->slock, flags);
-
-	if (!list_empty(&task->list_item)) {
-		struct vdec_v4l2_buffer *fb =
-			(struct vdec_v4l2_buffer *)task->obj;
-
-		list_for_each_entry(item, &task->list_item, node) {
-			pbuf += sprintf(pbuf, "%s(%d)",
-				item->name, item->is_active);
-			if (item->node.next != &task->list_item) {
-				if (task->direction == TASK_DIR_SUBMIT)
-					pbuf += sprintf(pbuf, " ==> ");
-				else
-					pbuf += sprintf(pbuf, " <== ");
-			}
-		}
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_PRINFO,
-			"vb:%2d, phy:%lx  %s\n",
-			task->id, fb->m.mem[0].addr, buf);
-	}
-
-	spin_unlock_irqrestore(&task->slock, flags);
-}
-EXPORT_SYMBOL(task_chain_show);
-
-static void task_chain_destroy(struct kref *kref)
-{
-	struct task_chain_s *task;
-
-	task = container_of(kref, struct task_chain_s, ref);
-
-	task->cur_type = TASK_TYPE_MAX;
-	memset(task->map, 0, sizeof(task->map));
-
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d task chain destroyed.\n", task, task->id);
-
-	kfree(task);
-}
-
-static void task_item_release(struct kref *kref)
-{
-	struct task_item_s *item;
-
-	item = container_of(kref, struct task_item_s, ref);
-	list_del(&item->node);
-
-	v4l_dbg(item->task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d task item:(%px,%d) released.\n",
-		item->task, item->task->id, item, item->ops->type);
-
-	kref_put(&item->task->ref, task_chain_destroy);
-
-	kfree(item);
-}
-
-void task_chain_clean(struct task_chain_s *task)
-{
-	struct task_item_s *item, *tmp;
-
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d task chain clean.\n", task, task->id);
-
-	if (!list_empty(&task->list_item)) {
-		list_for_each_entry_safe(item, tmp, &task->list_item, node)
-			kref_put(&item->ref, task_item_release);
-	}
-}
-EXPORT_SYMBOL(task_chain_clean);
-
-void task_chain_release(struct task_chain_s *task)
-{
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d task chain release.\n", task, task->id);
-
-	kref_put(&task->ref, task_chain_destroy);
-}
-EXPORT_SYMBOL(task_chain_release);
-
-void task_order_attach(struct task_chain_s *task,
-			 struct task_ops_s *ops,
-			 void *caller)
-{
-	struct task_item_s *item;
-
-	item = kzalloc(sizeof(struct task_item_s), GFP_ATOMIC);
-	if (!item) {
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
-			"TSK(%px):%d alloc item fail.\n", task, task->id);
-		return;
-	}
-
-	item->task	= task;
-	item->ops	= ops;
-	item->caller	= caller;
-	item->name	= type_to_name(ops->type);
-	kref_init(&item->ref);
-
-	task->map[0][ops->type] = task->cur_type;
-	task->map[1][task->cur_type] = ops->type;
-	task->cur_type = ops->type;
-	kref_get(&task->ref);
-
-	list_add(&item->node, &task->list_item);
-
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d attach item:(%px,%d).\n",
-		task, task->id, item, ops->type);
-}
-EXPORT_SYMBOL(task_order_attach);
-
-void task_chain_update_object(struct task_chain_s *task, void *obj)
-{
-	/*
-	 * Note: have to invoke this funtion
-	 * if the task object has been changed.
-	 */
-	task->obj = obj;
-
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d update task obj:%px.\n",
-		task, task->id, obj);
-}
-EXPORT_SYMBOL(task_chain_update_object);
-
-int task_chain_init(struct task_chain_s **task_out,
-			    void *v4l_ctx,
-			    void *obj,
-			    int vb_idx)
-{
-	struct task_chain_s *task;
-
-	task = kzalloc(sizeof(struct task_chain_s), GFP_ATOMIC);
-	if (!task) {
-		v4l_dbg(task->ctx, V4L_DEBUG_CODEC_ERROR,
-			"TSK(%px):%d alloc task fail.\n", task, task->id);
-		return -ENOMEM;
-	}
-
-	task->id	= vb_idx;
-	task->obj	= obj;
-	task->ctx	= v4l_ctx;
-	kref_init(&task->ref);
-	spin_lock_init(&task->slock);
-	INIT_LIST_HEAD(&task->list_item);
-
-	task->attach	= task_order_attach;
-	task->submit	= task_buffer_submit;
-	task->recycle	= task_buffer_recycle;
-
-	*task_out = task;
-
-	v4l_dbg(task->ctx, V4L_DEBUG_TASK_CHAIN,
-		"TSK(%px):%d task chain creat success.\n", task, task->id);
-	return 0;
-}
-EXPORT_SYMBOL(task_chain_init);
-
diff --git a/drivers/amvdec_ports/aml_task_chain.h b/drivers/amvdec_ports/aml_task_chain.h
deleted file mode 100644
index fdbe2fb..0000000
--- a/drivers/amvdec_ports/aml_task_chain.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#ifndef AML_TASK_CHAIN_H
-#define AML_TASK_CHAIN_H
-
-#include <linux/amlogic/media/vfm/vframe.h>
-
-enum task_type_e {
-	TASK_TYPE_DEC,
-	TASK_TYPE_VPP,
-	TASK_TYPE_V4L_SINK,
-	TASK_TYPE_GE2D,
-	TASK_TYPE_MAX
-};
-
-enum task_dir_e {
-	TASK_DIR_SUBMIT,
-	TASK_DIR_RECYCLE,
-	TASK_DIR_MAX
-};
-
-struct task_chain_s;
-
-/*
- * struct task_ops_s - interface of the task item.
- * @type	: type of task ops involves dec, vpp, v4l sink etc.
- * @get_vframe	: get the video frame from caller's fifo.
- * @put_vframe	: put the video frame to caller's fifo.
- * @fill_buffer	: submit the buffer into next process module.
- */
-struct task_ops_s {
-	enum task_type_e type;
-	void	(*get_vframe) (void *caller, struct vframe_s **vf);
-	void	(*put_vframe) (void *caller, struct vframe_s *vf);
-	void	(*fill_buffer) (void *v4l_ctx, void *fb_ctx);
-};
-
-/*
- * struct task_item_s - items of the task chain.
- * @node	: list node of the specific task item.
- * @ref		: reference count of item be used by others.
- * @name	: name of task item, map with task type.
- * @is_active	: indicate this item whether is active.
- * @vframe[3]	: store the vframes that get from caller.
- * @task	: the context of the task chain.
- * @caller	: it's the handle, meght it's dec, vpp or v4l-sink etc.
- * @ops		: sets of interface which attach from task item.
- */
-struct task_item_s {
-	struct list_head	node;
-	struct kref		ref;
-	const u8		*name;
-	bool			is_active;
-	void			*vframe[3];
-	struct task_chain_s	*task;
-	void			*caller;
-	struct task_ops_s	*ops;
-};
-
-/*
- * struct task_chain_s - the manager struct of the task chain.
- * @list_item	: all task items be attached are store in the list.
- * @node	: will register to the task chain pool.
- * @ref		: reference count of task chain be used by others.
- * @slock	: used for list item write and read safely.
- * @id		: it's vb index to be a mark used for task chain.
- * @ctx		: the context of the v4l driver.
- * @obj		: the object managed by task chain.
- * @direction	: direction incluse 2 flows submit & recycle.
- * @cur_type	: the latest item type before a new item be attached.
- * @map		: the map store the pipeline information.
- * @attach	: attach a new item to task chain.
- * @submit	: submit the finish item to next item module.
- * @recycle	: if item's date was consumed will be recycled to item.
- */
-struct task_chain_s {
-	struct list_head	list_item;
-	struct list_head	node;
-	struct kref		ref;
-	spinlock_t		slock;
-	int			id;
-	void			*ctx;
-	void			*obj;
-	enum task_dir_e		direction;
-	enum task_type_e	cur_type;
-	u8			map[2][8];
-
-	void	(*attach) (struct task_chain_s *, struct task_ops_s *, void *);
-	void	(*submit) (struct task_chain_s *, enum task_type_e);
-	void	(*recycle) (struct task_chain_s *, enum task_type_e);
-};
-
-
-int task_chain_init(struct task_chain_s **task_out,
-		     void *v4l_ctx,
-		     void *obj,
-		     int vb_idx);
-void task_order_attach(struct task_chain_s *task,
-		       struct task_ops_s *ops,
-		       void *caller);
-void task_chain_clean(struct task_chain_s *task);
-void task_chain_release(struct task_chain_s *task);
-void task_chain_show(struct task_chain_s *task);
-void task_chain_update_object(struct task_chain_s *task, void *obj);
-
-#endif //AML_TASK_CHAIN_H
-
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c
index 7e08371..95ee48a 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.c
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.c
@@ -56,11 +56,17 @@
 //#define DATA_DEBUG
 
 extern int dump_output_frame;
-extern u32 dump_output_start_position;
 extern void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle);
+static int def_4k_vstreambuf_sizeM =
+	(DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
+static int def_vstreambuf_sizeM =
+	(DEFAULT_VIDEO_BUFFER_SIZE >> 20);
 
 static int slow_input = 0;
 
+static int use_bufferlevelx10000 = 10000;
+static unsigned int amstream_buf_num = BUF_MAX_NUM;
+
 static struct stream_buf_s bufs[BUF_MAX_NUM] = {
 	{
 		.reg_base = VLD_MEM_VIFIFO_REG_BASE,
@@ -167,6 +173,60 @@
 	return 0;
 }
 
+static int reset_canuse_buferlevel(int levelx10000)
+{
+	int i;
+	struct stream_buf_s *p = NULL;
+
+	if (levelx10000 >= 0 && levelx10000 <= 10000)
+		use_bufferlevelx10000 = levelx10000;
+	else
+		use_bufferlevelx10000 = 10000;
+	for (i = 0; i < amstream_buf_num; i++) {
+		p = &bufs[i];
+		p->canusebuf_size = ((p->buf_size / 1024) *
+			use_bufferlevelx10000 / 10000) * 1024;
+		p->canusebuf_size += 1023;
+		p->canusebuf_size &= ~1023;
+
+		if (p->canusebuf_size > p->buf_size)
+			p->canusebuf_size = p->buf_size;
+	}
+
+	return 0;
+}
+
+static void change_vbufsize(struct vdec_s *vdec,
+	struct stream_buf_s *pvbuf)
+{
+	if (pvbuf->buf_start != 0) {
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR, "streambuf is alloced before\n");
+		return;
+	}
+
+	if (vdec->port->is_4k) {
+		pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M;
+
+		if (vdec->port_flag & PORT_FLAG_DRM)
+			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP;
+
+		if ((pvbuf->buf_size > 30 * SZ_1M)
+			&& (codec_mm_get_total_size() < 220 * SZ_1M)) {
+			/*if less than 250M, used 20M for 4K & 265*/
+			pvbuf->buf_size = pvbuf->buf_size >> 1;
+		}
+	} else if (pvbuf->buf_size > def_vstreambuf_sizeM * SZ_1M) {
+		if (vdec->port_flag & PORT_FLAG_DRM)
+			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
+	} else {
+		pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M;
+		if (vdec->port_flag & PORT_FLAG_DRM)
+			pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
+	}
+
+	reset_canuse_buferlevel(10000);
+}
+
 static void user_buffer_init(void)
 {
 	struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA];
@@ -177,14 +237,41 @@
 	pubuf->buf_rp = 0;
 }
 
-static void video_component_release(struct stream_port_s *port)
+static void video_component_release(struct stream_port_s *port,
+struct stream_buf_s *pbuf, int release_num)
 {
 	struct aml_vdec_adapt *ada_ctx
 		= container_of(port, struct aml_vdec_adapt, port);
 	struct vdec_s *vdec = ada_ctx->vdec;
 
-	vdec_release(vdec);
+	struct vdec_s *slave = NULL;
 
+	switch (release_num) {
+	default:
+	case 0:
+	case 4: {
+		if ((port->type & PORT_TYPE_FRAME) == 0)
+			esparser_release(pbuf);
+	}
+
+	case 3: {
+		if (vdec->slave)
+			slave = vdec->slave;
+		vdec_release(vdec);
+
+		if (slave)
+			vdec_release(slave);
+		vdec = NULL;
+	}
+
+	case 2: {
+		if ((port->type & PORT_TYPE_FRAME) == 0)
+			stbuf_release(pbuf);
+	}
+
+	case 1:
+		;
+	}
 }
 
 static int video_component_init(struct stream_port_s *port,
@@ -204,21 +291,69 @@
 		|| port->vformat == VFORMAT_H264_4K2K) {
 		port->is_4k = true;
 		if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX
-				&& (port->vformat == VFORMAT_H264))
+				&& port->vformat == VFORMAT_H264)
 			vdec_poweron(VDEC_HEVC);
 	} else
 		port->is_4k = false;
 
-	if (port->type & PORT_TYPE_FRAME ||
-		(port->type & PORT_TYPE_ES)) {
-		ret = vdec_init(vdec, port->is_4k, true);
+	if (port->type & PORT_TYPE_FRAME) {
+		ret = vdec_init(vdec, port->is_4k);
 		if (ret < 0) {
 			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "failed\n");
-			video_component_release(port);
+			video_component_release(port, pbuf, 2);
+			return ret;
+		}
+
+		return 0;
+	}
+
+	change_vbufsize(vdec, pbuf);
+
+	if (has_hevc_vdec()) {
+		if (port->type & PORT_TYPE_MPTS) {
+			if (pbuf->type == BUF_TYPE_HEVC)
+				vdec_poweroff(VDEC_1);
+			else
+				vdec_poweroff(VDEC_HEVC);
+		}
+	}
+
+	ret = stbuf_init(pbuf, vdec);
+	if (ret < 0) {
+		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "stbuf_init failed\n");
+		return ret;
+	}
+
+	/* todo: set path based on port flag */
+	ret = vdec_init(vdec, port->is_4k);
+	if (ret < 0) {
+		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
+		video_component_release(port, pbuf, 2);
+		return ret;
+	}
+
+	if (vdec_dual(vdec)) {
+		ret = vdec_init(vdec->slave, port->is_4k);
+		if (ret < 0) {
+			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "vdec_init failed\n");
+			video_component_release(port, pbuf, 2);
 			return ret;
 		}
 	}
 
+	if (port->type & PORT_TYPE_ES) {
+		ret = esparser_init(pbuf, vdec);
+		if (ret < 0) {
+			video_component_release(port, pbuf, 3);
+			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_ERROR, "esparser_init() failed\n");
+			return ret;
+		}
+	}
+
+	pbuf->flag |= BUF_FLAG_IN_USE;
+
+	vdec_connect(vdec);
+
 	return 0;
 }
 
@@ -227,8 +362,8 @@
 	struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
 
 	if (has_hevc_vdec()) {
-		if (port->vformat == VFORMAT_HEVC ||
-			port->vformat == VFORMAT_VP9)
+		if (port->vformat == VFORMAT_HEVC
+			|| port->vformat == VFORMAT_VP9)
 			pvbuf = &bufs[BUF_TYPE_HEVC];
 	}
 
@@ -241,7 +376,7 @@
 		psparser_release();
 
 	if (port->type & PORT_TYPE_VIDEO)
-		video_component_release(port);
+		video_component_release(port, pvbuf, 0);
 
 	port->pcr_inited = 0;
 	port->flag = 0;
@@ -256,6 +391,7 @@
 	vdec->port	= &ada_ctx->port;
 	vdec->format	= ada_ctx->video_type;
 	vdec->sys_info_store = ada_ctx->dec_prop;
+	vdec->vf_receiver_name = ada_ctx->recv_name;
 
 	/* binding v4l2 ctx to vdec. */
 	vdec->private = ada_ctx->ctx;
@@ -289,6 +425,7 @@
 		vdec->frame_base_video_path = aml_set_vfm_path;
 
 	vdec->port->flag = vdec->port_flag;
+	ada_ctx->vfm_path = vdec->frame_base_video_path;
 
 	vdec->config_len = ada_ctx->config.length >
 		PAGE_SIZE ? PAGE_SIZE : ada_ctx->config.length;
@@ -308,7 +445,6 @@
 	if (IS_ERR_OR_NULL(vdec))
 		return -1;
 
-	vdec->disable_vfm = true;
 	set_vdec_properity(vdec, ada_ctx);
 
 	/* init hw and gate*/
@@ -325,8 +461,8 @@
 		&& (vdec->port_flag & PORT_FLAG_VFORMAT)) {
 		vdec->port->is_4k = false;
 		if (has_hevc_vdec()) {
-			if (vdec->port->vformat == VFORMAT_HEVC ||
-				vdec->port->vformat == VFORMAT_VP9)
+			if (vdec->port->vformat == VFORMAT_HEVC
+				|| vdec->port->vformat == VFORMAT_VP9)
 				pvbuf = &bufs[BUF_TYPE_HEVC];
 		}
 
@@ -390,11 +526,9 @@
 	if (!IS_ERR(fp)) {
 		kernel_write(fp, data, size, 0);
 		filp_close(fp, NULL);
-	} else {
-		pr_info("Dump ES fail, should check RW permission, size:%x\n", size);
 	}
-}
 
+}
 int vdec_vbuf_write(struct aml_vdec_adapt *ada_ctx,
 	const char *buf, unsigned int count)
 {
@@ -445,11 +579,11 @@
 {
 	struct vdec_s *vdec = ada_ctx->vdec;
 
-	return (vdec->input.have_frame_num > 60) ? true : false;
+	return (vdec->input.have_frame_num > 600) ? true : false;
 }
 
 int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
-	const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr)
+	const char *buf, unsigned int count, u64 timestamp)
 {
 	int ret = -1;
 	struct vdec_s *vdec = ada_ctx->vdec;
@@ -457,9 +591,6 @@
 	/* set timestamp */
 	vdec_set_timestamp(vdec, timestamp);
 
-	/* set metadata */
-	vdec_set_metadata(vdec, meta_ptr);
-
 	ret = vdec_write_vframe(vdec, buf, count);
 
 	if (slow_input) {
@@ -468,12 +599,9 @@
 		msleep(30);
 	}
 
-	if (dump_output_frame > 0 &&
-		(!dump_output_start_position ||
-		(dump_output_start_position == crc32_le(0, buf, count)))) {
+	if (dump_output_frame > 0) {
 		dump("/data/es.data", buf, count);
 		dump_output_frame--;
-		dump_output_start_position = 0;
 	}
 
 	v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_INPUT,
@@ -530,14 +658,23 @@
 	int ret = 0;
 
 	if (vdec) {
-		if (ada_ctx->ctx->v4l_resolution_change)
-			*mode = V4L_RESET_MODE_LIGHT;
-		else
+		if (!ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed)
 			vdec_set_eos(vdec, false);
-
+		if (*mode == V4L_RESET_MODE_NORMAL &&
+			vdec->input.have_frame_num == 0) {
+			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
+			"no input reset mode: %d\n", *mode);
+			*mode = V4L_RESET_MODE_LIGHT;
+		}
+		if (ada_ctx->ctx->param_sets_from_ucode &&
+			*mode == V4L_RESET_MODE_NORMAL &&
+			ada_ctx->ctx->q_data[AML_Q_DATA_SRC].resolution_changed == true) {
+			v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
+			"resolution_changed reset mode: %d\n", *mode);
+			*mode = V4L_RESET_MODE_LIGHT;
+		}
 		v4l_dbg(ada_ctx->ctx, V4L_DEBUG_CODEC_PRINFO,
-			"reset mode: %d, es frames buffering: %d\n",
-			*mode, vdec_frame_number(ada_ctx));
+			"reset mode: %d\n", *mode);
 
 		ret = vdec_v4l2_reset(vdec, *mode);
 		*mode = V4L_RESET_MODE_NORMAL;
@@ -572,11 +709,6 @@
 		return -1;
 }
 
-int vdec_get_instance_num(void)
-{
-	return vdec_get_core_nr();
-}
-
 void v4l2_config_vdec_parm(struct aml_vdec_adapt *ada_ctx, u8 *data, u32 len)
 {
 	struct vdec_s *vdec = ada_ctx->vdec;
@@ -584,8 +716,3 @@
 	vdec->config_len = len > PAGE_SIZE ? PAGE_SIZE : len;
 	memcpy(vdec->config, data, vdec->config_len);
 }
-
-void vdec_set_duration(s32 duration)
-{
-	vdec_frame_rate_uevent(duration);
-}
diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.h b/drivers/amvdec_ports/aml_vcodec_adapt.h
index c8641ce..b86cbff 100644
--- a/drivers/amvdec_ports/aml_vcodec_adapt.h
+++ b/drivers/amvdec_ports/aml_vcodec_adapt.h
@@ -27,12 +27,13 @@
 #include "aml_vcodec_drv.h"
 
 struct aml_vdec_adapt {
-	int format;
+	enum vformat_e format;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
 	unsigned int signaled;
 	struct aml_vcodec_ctx *ctx;
+	struct platform_device *dev;
 	wait_queue_head_t wq;
 	struct file *filp;
 	struct vdec_s *vdec;
@@ -40,7 +41,8 @@
 	struct dec_sysinfo dec_prop;
 	struct v4l2_config_parm config;
 	int video_type;
-	char *frm_name;
+	char *recv_name;
+	int vfm_path;
 };
 
 int video_decoder_init(struct aml_vdec_adapt *ada_ctx);
@@ -51,7 +53,7 @@
 	const char *buf, unsigned int count);
 
 int vdec_vframe_write(struct aml_vdec_adapt *ada_ctx,
-	const char *buf, unsigned int count, u64 timestamp, ulong meta_ptr);
+	const char *buf, unsigned int count, u64 timestamp);
 
 void vdec_vframe_input_free(void *priv, u32 handle);
 
@@ -71,9 +73,5 @@
 
 int vdec_frame_number(struct aml_vdec_adapt *ada_ctx);
 
-int vdec_get_instance_num(void);
-
-void vdec_set_duration(s32 duration);
-
 #endif /* VDEC_ADAPT_H */
 
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 2bbfb6e..afebb7a 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -20,41 +20,27 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
-#include <media/videobuf2-dma-sg.h>
-
-#include <linux/delay.h>
-#include <linux/atomic.h>
-#include <linux/crc32.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/amlogic/meson_uvm_core.h>
-#include <linux/scatterlist.h>
-#include <linux/sched/clock.h>
-#include <linux/highmem.h>
-#include <uapi/linux/sched/types.h>
 
 #include "aml_vcodec_drv.h"
 #include "aml_vcodec_dec.h"
+//#include "aml_vcodec_intr.h"
 #include "aml_vcodec_util.h"
 #include "vdec_drv_if.h"
+#include <linux/delay.h>
+#include <linux/atomic.h>
+#include <linux/crc32.h>
 #include "aml_vcodec_adapt.h"
-#include "aml_vcodec_vpp.h"
-#include "aml_vcodec_ge2d.h"
+#include <linux/spinlock.h>
 
+#include "aml_vcodec_vfm.h"
 #include "../frame_provider/decoder/utils/decoder_bmmu_box.h"
 #include "../frame_provider/decoder/utils/decoder_mmu_box.h"
-#include "../common/chips/decoder_cpu_ver_info.h"
-#include "utils/common.h"
-#include "../frame_provider/decoder/utils/vdec_sync.h"
-
 
 #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
 #include <trace/events/meson_atrace.h>
 
-
-#define OUT_FMT_IDX		(0) //default h264
-#define CAP_FMT_IDX		(9) //capture nv21
-#define CAP_FMT_I420_IDX	(12) //use for mjpeg
+#define OUT_FMT_IDX	0 //default h264
+#define CAP_FMT_IDX	8 //capture nv21
 
 #define AML_VDEC_MIN_W	64U
 #define AML_VDEC_MIN_H	64U
@@ -63,12 +49,8 @@
 
 #define V4L2_CID_USER_AMLOGIC_BASE (V4L2_CID_USER_BASE + 0x1100)
 #define AML_V4L2_SET_DRMMODE (V4L2_CID_USER_AMLOGIC_BASE + 0)
-#define AML_V4L2_GET_INPUT_BUFFER_NUM (V4L2_CID_USER_AMLOGIC_BASE + 1)
-#define AML_V4L2_SET_DURATION (V4L2_CID_USER_AMLOGIC_BASE + 2)
-#define AML_V4L2_GET_FILMGRAIN_INFO (V4L2_CID_USER_AMLOGIC_BASE + 3)
 
 #define WORK_ITEMS_MAX (32)
-#define MAX_DI_INSTANCE (2)
 
 //#define USEC_PER_SEC 1000000
 
@@ -80,89 +62,70 @@
 
 static struct aml_video_fmt aml_video_formats[] = {
 	{
-		.name = "H.264",
 		.fourcc = V4L2_PIX_FMT_H264,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "H.265",
 		.fourcc = V4L2_PIX_FMT_HEVC,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "VP9",
 		.fourcc = V4L2_PIX_FMT_VP9,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "MPEG1",
 		.fourcc = V4L2_PIX_FMT_MPEG1,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "MPEG2",
 		.fourcc = V4L2_PIX_FMT_MPEG2,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "MPEG4",
 		.fourcc = V4L2_PIX_FMT_MPEG4,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "MJPEG",
 		.fourcc = V4L2_PIX_FMT_MJPEG,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "AV1",
 		.fourcc = V4L2_PIX_FMT_AV1,
 		.type = AML_FMT_DEC,
 		.num_planes = 1,
 	},
 	{
-		.name = "NV21",
 		.fourcc = V4L2_PIX_FMT_NV21,
 		.type = AML_FMT_FRAME,
 		.num_planes = 1,
 	},
 	{
-		.name = "NV21M",
 		.fourcc = V4L2_PIX_FMT_NV21M,
 		.type = AML_FMT_FRAME,
 		.num_planes = 2,
 	},
 	{
-		.name = "NV12",
 		.fourcc = V4L2_PIX_FMT_NV12,
 		.type = AML_FMT_FRAME,
 		.num_planes = 1,
 	},
 	{
-		.name = "NV12M",
 		.fourcc = V4L2_PIX_FMT_NV12M,
 		.type = AML_FMT_FRAME,
 		.num_planes = 2,
 	},
 	{
-		.name = "YUV420",
 		.fourcc = V4L2_PIX_FMT_YUV420,
 		.type = AML_FMT_FRAME,
 		.num_planes = 1,
 	},
-	{
-		.name = "YUV420M",
-		.fourcc = V4L2_PIX_FMT_YUV420M,
-		.type = AML_FMT_FRAME,
-		.num_planes = 2,
-	},
 };
 
 static const struct aml_codec_framesizes aml_vdec_framesizes[] = {
@@ -202,11 +165,6 @@
 				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
 	},
 	{
-		.fourcc = V4L2_PIX_FMT_AV1,
-		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
-				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
-	},
-	{
 		.fourcc = V4L2_PIX_FMT_NV21,
 		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
 				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
@@ -226,44 +184,16 @@
 		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
 				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
 	},
-	{
-		.fourcc = V4L2_PIX_FMT_YUV420,
-		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
-				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_YUV420M,
-		.stepwise = {  AML_VDEC_MIN_W, AML_VDEC_MAX_W, 2,
-				AML_VDEC_MIN_H, AML_VDEC_MAX_H, 2},
-	},
 };
 
 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(aml_vdec_framesizes)
 #define NUM_FORMATS ARRAY_SIZE(aml_video_formats)
 
 extern bool multiplanar;
-extern int dump_capture_frame;
-extern int bypass_vpp;
-extern int bypass_ge2d;
-extern bool support_format_I420;
-extern bool support_mjpeg;
-extern int bypass_progressive;
-extern int force_enable_nr;
-extern int force_enable_di_local_buffer;
-extern int max_di_instance;
-extern int bypass_nr_flag;
+extern bool dump_capture_frame;
 
 extern int dmabuf_fd_install_data(int fd, void* data, u32 size);
 extern bool is_v4l2_buf_file(struct file *file);
-extern int get_double_write_ratio(int dw_mode);
-static void box_release(struct kref *kref);
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
-					    struct vb2_buffer *vb);
-static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type);
-static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
-				       struct v4l2_pix_format *pix,
-				       struct aml_q_data *q_data,
-				       u32 type);
 
 static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
 {
@@ -279,23 +209,6 @@
 	spin_unlock_irqrestore(&ctx->slock, flags);
 }
 
-static ulong dmabuf_contiguous_size(struct sg_table *sgt)
-{
-	struct scatterlist *s;
-	dma_addr_t expected = sg_dma_address(sgt->sgl);
-	ulong size = 0;
-	u32 i;
-
-	for_each_sg(sgt->sgl, s, sgt->nents, i) {
-		if (sg_dma_address(s) != expected)
-			break;
-		expected = sg_dma_address(s) + sg_dma_len(s);
-		size += sg_dma_len(s);
-	}
-
-	return size;
-}
-
 static struct aml_video_fmt *aml_vdec_find_format(struct v4l2_format *f)
 {
 	struct aml_video_fmt *fmt;
@@ -323,6 +236,16 @@
 {
 	struct v4l2_event event = {0};
 
+	if (ctx->receive_cmd_stop &&
+			changes != V4L2_EVENT_SRC_CH_RESOLUTION &&
+			changes != V4L2_EVENT_SEND_EOS) {
+		ctx->state = AML_STATE_ABORT;
+		ATRACE_COUNTER("v4l2_state", ctx->state);
+		changes = V4L2_EVENT_REQUEST_EXIT;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+			"vcodec state (AML_STATE_ABORT)\n");
+	}
+
 	switch (changes) {
 	case V4L2_EVENT_SRC_CH_RESOLUTION:
 	case V4L2_EVENT_SRC_CH_HDRINFO:
@@ -354,176 +277,11 @@
 	aml_decoder_flush(ctx->ada_ctx);
 }
 
-/* Conditions:
- * Always connect VPP for mpeg2 and h264 when the stream size is under 2K.
- * Always connect VPP for hevc/av1/vp9 when color space is not SDR and
- *     stream size is under 2K.
- * For DV, need application to notify V4L2 driver to enforce the color space
- *     conversion. Plan to do it through a system node.
- * Do not connect VPP in other cases.
- */
-static bool vpp_needed(struct aml_vcodec_ctx *ctx, u32* mode)
+static void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
 {
-	int width = ctx->picinfo.coded_width;
-	int height = ctx->picinfo.coded_height;
-	int size = 1920 * 1088;
+	unsigned int dpbsize = 0;
+	int ret;
 
-	if (bypass_vpp)
-		return false;
-
-	if (!ctx->vpp_cfg.enable_nr &&
-		(ctx->picinfo.field == V4L2_FIELD_NONE)) {
-		return false;
-	}
-
-	if (!ctx->vpp_cfg.enable_nr &&
-		(ctx->output_pix_fmt == V4L2_PIX_FMT_HEVC)) {
-		if (is_over_size(width, height, size)) {
-			return false;
-		}
-	}
-
-	if ((ctx->output_pix_fmt == V4L2_PIX_FMT_H264) &&
-		(ctx->picinfo.field != V4L2_FIELD_NONE)) {
-		if (is_over_size(width, height, size)) {
-			return false;
-		}
-	}
-
-	if (ctx->vpp_cfg.enable_nr) {
-		if (ctx->vpp_cfg.enable_local_buf)
-			*mode = VPP_MODE_NOISE_REDUC_LOCAL;
-		else
-			*mode = VPP_MODE_NOISE_REDUC;
-	} else {
-		if (ctx->vpp_cfg.enable_local_buf)
-			*mode = VPP_MODE_DI_LOCAL;
-		else
-			*mode = VPP_MODE_DI;
-	}
-
-#if 0//enable later
-	if (ctx->colorspace != V4L2_COLORSPACE_DEFAULT &&
-		!is_over_size(width, height, size)) {
-		if (ctx->vpp_cfg.enable_local_buf)
-			*mode = VPP_MODE_COLOR_CONV_LOCAL;
-		else
-			*mode = VPP_MODE_COLOR_CONV;
-	}
-#endif
-
-	return true;
-}
-
-static bool ge2d_needed(struct aml_vcodec_ctx *ctx, u32* mode)
-{
-	bool enable_fence = (ctx->config.parm.dec.cfg.low_latency_mode & 2) ? 1 : 0;
-
-	if ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) && enable_fence) {
-		return false;
-	}
-
-	if (bypass_ge2d)
-		return false;
-
-	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
-		if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
-			(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
-			(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
-			(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
-			(ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
-			return false;
-		}
-	} else if (ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG) {
-			return false;
-	}
-
-	if (ctx->picinfo.field != V4L2_FIELD_NONE) {
-		return false;
-	}
-
-	if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12) ||
-		(ctx->cap_pix_fmt == V4L2_PIX_FMT_NV12M))
-		*mode = GE2D_MODE_CONVERT_NV12;
-	else if ((ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21) ||
-		(ctx->cap_pix_fmt == V4L2_PIX_FMT_NV21M))
-		*mode = GE2D_MODE_CONVERT_NV21;
-	else
-		*mode = GE2D_MODE_CONVERT_NV21;
-
-	*mode |= GE2D_MODE_CONVERT_LE;
-
-	return true;
-}
-
-static u32 v4l_buf_size_decision(struct aml_vcodec_ctx *ctx)
-{
-	u32 mode, total_size;
-	struct vdec_pic_info *picinfo = &ctx->picinfo;
-	struct aml_vpp_cfg_infos *vpp = &ctx->vpp_cfg;
-	struct aml_ge2d_cfg_infos *ge2d = &ctx->ge2d_cfg;
-
-	if (vpp_needed(ctx, &mode)) {
-		vpp->mode        = mode;
-		vpp->fmt         = ctx->cap_pix_fmt;
-		vpp->is_drm      = ctx->is_drm_mode;
-		vpp->buf_size = aml_v4l2_vpp_get_buf_num(vpp->mode)
-			+ picinfo->vpp_margin;
-
-		if (picinfo->field == V4L2_FIELD_NONE) {
-			vpp->is_prog = true;
-			vpp->buf_size = 0;
-		} else {
-			vpp->is_prog = false;
-			/* for between with dec & vpp. */
-			picinfo->dpb_margin = 2;
-		}
-
-		if (vpp->is_prog &&
-			!vpp->enable_local_buf &&
-			bypass_progressive) {
-			vpp->is_bypass_p = true;
-		}
-		ctx->vpp_is_need = true;
-	} else {
-		vpp->buf_size = 0;
-		ctx->vpp_is_need = false;
-	}
-
-	if (ge2d_needed(ctx, &mode)) {
-		ge2d->mode = mode;
-		ge2d->buf_size = 4 + picinfo->dpb_margin;
-		ctx->ge2d_is_need = true;
-		picinfo->dpb_margin = 2;
-	} else {
-		ge2d->buf_size = 0;
-		ctx->ge2d_is_need = false;
-	}
-
-	ctx->dpb_size = picinfo->dpb_frames + picinfo->dpb_margin;
-	ctx->vpp_size = vpp->buf_size;
-	ctx->ge2d_size = ge2d->buf_size;
-
-	total_size = ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size;
-
-	if (total_size > V4L_CAP_BUFF_MAX) {
-		if (ctx->ge2d_size) {
-			ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->ge2d_size - ctx->vpp_size;
-		} else if (ctx->vpp_size) {
-			ctx->dpb_size = V4L_CAP_BUFF_MAX - ctx->vpp_size;
-		} else {
-			ctx->dpb_size = V4L_CAP_BUFF_MAX;
-		}
-		picinfo->dpb_margin = ctx->dpb_size - picinfo->dpb_frames;
-		total_size = V4L_CAP_BUFF_MAX;
-	}
-	vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, picinfo);
-
-	return total_size;
-}
-
-void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
-{
 	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"Cannot get param : GET_PARAM_PICTURE_INFO ERR\n");
@@ -551,277 +309,287 @@
 			ctx->last_decoded_picinfo.coded_width,
 			ctx->last_decoded_picinfo.coded_width);
 
+	ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
+	if (dpbsize == 0)
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"Incorrect dpb size, ret=%d\n", ret);
+
+	/* update picture information */
+	ctx->dpb_size = dpbsize;
 	ctx->picinfo = ctx->last_decoded_picinfo;
+}
 
-	if (ctx->vpp_is_need)
-		ctx->vpp_cfg.is_vpp_reset = true;
+static bool aml_check_inst_quit(struct aml_vcodec_dev *dev,
+	struct aml_vcodec_ctx * inst, u32 id)
+{
+	struct aml_vcodec_ctx *ctx = NULL;
+	bool ret = true;
 
-	v4l_buf_size_decision(ctx);
+	if (dev == NULL)
+		return false;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Update picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
-		ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
-		ctx->picinfo.dpb_margin,
-		CTX_BUF_TOTAL(ctx));
+	mutex_lock(&dev->dev_mutex);
+
+	if (list_empty(&dev->ctx_list)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"v4l inst list is empty.\n");
+		ret = true;
+		goto out;
+	}
+
+	list_for_each_entry(ctx, &dev->ctx_list, list) {
+		if ((ctx == inst) && (ctx->id == id)) {
+			ret = ctx->receive_cmd_stop ? true : false;
+			goto out;
+		}
+	}
+out:
+	mutex_unlock(&dev->dev_mutex);
+
+	return ret;
 }
 
 void vdec_frame_buffer_release(void *data)
 {
 	struct file_private_data *priv_data =
 		(struct file_private_data *) data;
-	struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)
-		priv_data->v4l_dec_ctx;
-	struct aml_video_dec_buf *vb = (struct aml_video_dec_buf *)
+	struct aml_vcodec_dev *dev = (struct aml_vcodec_dev *)
 		priv_data->vb_handle;
-	struct uvm_hook_mod_info *uvm = NULL;
+	struct aml_vcodec_ctx *inst = (struct aml_vcodec_ctx *)
+		priv_data->v4l_dec_ctx;
+	u32 id = priv_data->v4l_inst_id;
 
-	if (ctx && ctx->uvm_proxy) {
-		uvm = &ctx->uvm_proxy[vb->internal_index];
-		uvm->free(uvm->arg);
+	if (aml_check_inst_quit(dev, inst, id)) {
+		struct vframe_s *vf = &priv_data->vf;
+
+		v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+			"[%d]: vf idx: %d, bmmu idx: %d, bmmu_box: %lx\n",
+			id, vf->index, vf->mm_box.bmmu_idx,
+			(ulong) vf->mm_box.bmmu_box);
+
+		v4l_dbg(0, V4L_DEBUG_CODEC_BUFMGR,
+			"[%d]: vf idx: %d, mmu_idx: %d, mmu_box: %lx\n",
+			id, vf->index, vf->mm_box.mmu_idx,
+			(ulong) vf->mm_box.mmu_box);
+
+		if (decoder_bmmu_box_valide_check(vf->mm_box.bmmu_box)) {
+			decoder_bmmu_box_free_idx(vf->mm_box.bmmu_box,
+				vf->mm_box.bmmu_idx);
+			decoder_bmmu_try_to_release_box(vf->mm_box.bmmu_box);
+		}
+
+		if (decoder_mmu_box_valide_check(vf->mm_box.mmu_box)) {
+			decoder_mmu_box_free_idx(vf->mm_box.mmu_box,
+				vf->mm_box.mmu_idx);
+			decoder_mmu_try_to_release_box(vf->mm_box.mmu_box);
+		}
+
 	}
 
 	memset(data, 0, sizeof(struct file_private_data));
 	kfree(data);
 }
 
-static void v4l2_buff_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
+int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb)
 {
-	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(buf->vb2_buf.vb2_queue);
-
-	mutex_lock(&ctx->buff_done_lock);
-	if (buf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "vb is not active state = %d!\n",
-			buf->vb2_buf.state);
-		mutex_unlock(&ctx->buff_done_lock);
-		return;
-	}
-	v4l2_m2m_buf_done(buf, state);
-	mutex_unlock(&ctx->buff_done_lock);
-}
-
-static void comp_buf_set_vframe(struct aml_vcodec_ctx *ctx,
-			 struct vb2_buffer *vb,
-			 struct vframe_s *vf)
-{
-	dmabuf_set_vframe(vb->planes[0].dbuf, vf, VF_SRC_DECODER);
-}
-
-static void fb_map_table_clean(struct aml_vcodec_ctx *ctx)
-{
-	int i;
 	ulong flags;
+	struct vb2_buffer *dst_buf = NULL;
+	struct vdec_v4l2_buffer *pfb;
+	struct aml_video_dec_buf *dst_buf_info, *info;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2;
 
 	flags = aml_vcodec_ctx_lock(ctx);
 
-	for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
-		ctx->fb_map[i].addr	= 0;
-		ctx->fb_map[i].vframe	= NULL;
-		ctx->fb_map[i].task	= NULL;
-		ctx->fb_map[i].icomp	= 0;
+	if (ctx->state == AML_STATE_ABORT) {
+		aml_vcodec_ctx_unlock(ctx, flags);
+		return -1;
 	}
 
-	aml_vcodec_ctx_unlock(ctx, flags);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static void fb_map_table_hold(struct aml_vcodec_ctx *ctx,
-				struct vb2_buffer *vb,
-				struct vframe_s *vf,
-				struct task_chain_s *task,
-				u32 icomp)
-{
-	int i;
-	ulong addr, flags;
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
-	for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
-		if (!ctx->fb_map[i].addr ||
-			(addr == ctx->fb_map[i].addr)) {
-			ctx->fb_map[i].task	= task;
-			ctx->fb_map[i].addr	= addr;
-			ctx->fb_map[i].vframe	= vf;
-			ctx->fb_map[i].icomp	= icomp;
-
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-				"%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
-				__func__, task, vf, addr, icomp);
-			break;
-		}
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!dst_buf) {
+		aml_vcodec_ctx_unlock(ctx, flags);
+		return -1;
 	}
 
-	aml_vcodec_ctx_unlock(ctx, flags);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+		"vbuf idx: %d, state: %d, ready: %d\n",
+		dst_buf->index, dst_buf->state,
+		v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx));
 
-	if (i >= ARRAY_SIZE(ctx->fb_map)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s, table is full. addr:%lx, vf:%px\n",
-			__func__, addr, vf);
-	}
-}
+	dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
+	dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
 
-static void fb_map_table_fetch(struct aml_vcodec_ctx *ctx,
-				struct vb2_buffer *vb,
-				struct vframe_s **vf,
-				struct task_chain_s **task,
-				u32 *icomp)
-{
-	int i;
-	ulong addr, flags;
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
-	for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
-		if (addr == ctx->fb_map[i].addr) {
-			*task = ctx->fb_map[i].task;
-			*vf = ctx->fb_map[i].vframe;
-			*icomp = ctx->fb_map[i].icomp;
-
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-				"%s, task:%px, vf:%px, addr:%lx, icomp:%u\n",
-				__func__, task, vf, addr, *icomp);
-
-			ctx->fb_map[i].task	= NULL;
-			ctx->fb_map[i].vframe	= NULL;
-			ctx->fb_map[i].addr	= 0;
-			ctx->fb_map[i].icomp	= 0;
-			break;
-		}
-	}
-
-	aml_vcodec_ctx_unlock(ctx, flags);
-
-	if (i >= ARRAY_SIZE(ctx->fb_map)) {
+	pfb	= &dst_buf_info->frame_buffer;
+	pfb->buf_idx	= dst_buf->index;
+	pfb->num_planes	= dst_buf->num_planes;
+	pfb->status		= FB_ST_NORMAL;
+	if (dst_buf->num_planes == 1) {
+		pfb->m.mem[0].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+		pfb->m.mem[0].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+		pfb->m.mem[0].size	= ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
+		pfb->m.mem[0].offset	= ctx->picinfo.y_len_sz;
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-			"%s, there is new addr:%lx.\n",
-			__func__, addr);
+			"idx: %u, 1 plane, y:(0x%lx, %d)\n", dst_buf->index,
+			pfb->m.mem[0].addr, pfb->m.mem[0].size);
+	} else if (dst_buf->num_planes == 2) {
+		pfb->m.mem[0].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+		pfb->m.mem[0].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+		pfb->m.mem[0].size	= ctx->picinfo.y_len_sz;
+		pfb->m.mem[0].offset	= 0;
+
+		pfb->m.mem[1].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+		pfb->m.mem[1].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr);
+		pfb->m.mem[1].size	= ctx->picinfo.c_len_sz;
+		pfb->m.mem[1].offset	= ctx->picinfo.c_len_sz >> 1;
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+			"idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)\n", dst_buf->index,
+			pfb->m.mem[0].addr, pfb->m.mem[0].size,
+			pfb->m.mem[1].addr, pfb->m.mem[1].size);
+	} else {
+		pfb->m.mem[0].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+		pfb->m.mem[0].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
+		pfb->m.mem[0].size	= ctx->picinfo.y_len_sz;
+		pfb->m.mem[0].offset	= 0;
+
+		pfb->m.mem[1].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+		pfb->m.mem[1].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[2].dma_addr);
+		pfb->m.mem[1].size	= ctx->picinfo.c_len_sz >> 1;
+		pfb->m.mem[1].offset	= 0;
+
+		pfb->m.mem[2].dma_addr	= vb2_dma_contig_plane_dma_addr(dst_buf, 2);
+		pfb->m.mem[2].addr	= dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr);
+		pfb->m.mem[2].size	= ctx->picinfo.c_len_sz >> 1;
+		pfb->m.mem[2].offset	= 0;
+
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+			"idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)\n",
+			dst_buf->index,
+			pfb->m.mem[0].addr, pfb->m.mem[0].size,
+			pfb->m.mem[1].addr, pfb->m.mem[1].size,
+			pfb->m.mem[2].addr, pfb->m.mem[2].size);
 	}
-}
 
-static bool is_fb_mapped(struct aml_vcodec_ctx *ctx, ulong addr)
-{
-	int i;
-	ulong flags;
+	dst_buf_info->used = true;
+	ctx->buf_used_count++;
 
-	flags = aml_vcodec_ctx_lock(ctx);
+	*out_fb = pfb;
 
-	for (i = 0; i < ARRAY_SIZE(ctx->fb_map); i++) {
-		if (addr == ctx->fb_map[i].addr)
-			break;
-	}
+	info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
+
+	ctx->cap_pool.dec++;
+	ctx->cap_pool.seq[ctx->cap_pool.out++] =
+		(V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index);
+	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
 	aml_vcodec_ctx_unlock(ctx, flags);
 
-	if (i >= ARRAY_SIZE(ctx->fb_map)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-			"%s, addr:%lx isn't output.\n",
-			__func__, addr);
-		return false;
+	return 0;
+}
+EXPORT_SYMBOL(get_fb_from_queue);
+
+int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb)
+{
+	struct aml_video_dec_buf *dstbuf;
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
+
+	if (in_fb == NULL) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "No free frame buffer\n");
+		return -1;
 	}
 
-	return true;
+	dstbuf = container_of(in_fb, struct aml_video_dec_buf, frame_buffer);
+
+	mutex_lock(&ctx->lock);
+
+	if (!dstbuf->used)
+		goto out;
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+		"status=%x queue id=%d to rdy_queue\n",
+		in_fb->status, dstbuf->vb.vb2_buf.index);
+
+	v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
+
+	dstbuf->used = false;
+out:
+	mutex_unlock(&ctx->lock);
+
+	return 0;
+
 }
+EXPORT_SYMBOL(put_fb_to_queue);
 
- static void post_frame_to_upper(struct aml_vcodec_ctx *ctx,
-	struct vdec_v4l2_buffer *fb)
+void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb)
 {
-	struct aml_video_dec_buf *dstbuf =
-		container_of(fb, struct aml_video_dec_buf, frame_buffer);
-	struct vb2_buffer *vb2_buf = &dstbuf->vb.vb2_buf;
-	struct vframe_s *vf = fb->vframe;
-	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
-
-	vf->index_disp = ctx->index_disp;
-	ctx->index_disp++;
-	ctx->post_to_upper_done = false;
+	struct aml_video_dec_buf *dstbuf = NULL;
+	struct vb2_buffer *vb2_buf = NULL;
+	struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
-		"OUT_BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
+		"FROM (%s %s) vf: %lx, ts: %llu, idx: %d, "
 		"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
-		ctx->ada_ctx->frm_name, fb->status, vf->index_disp,
-		vb2_buf->index, vb2_buf,
-		vf->index & 0xff, vf,
-		vf->timestamp,
+		vf_get_provider(ctx->ada_ctx->recv_name)->name,
+		ctx->ada_ctx->vfm_path != FRAME_BASE_PATH_V4L_VIDEO ? "OSD" : "VIDEO",
+		(ulong) vf, vf->timestamp, vf->index,
 		fb->m.mem[0].addr, fb->m.mem[0].size,
 		fb->m.mem[1].addr, fb->m.mem[1].size,
 		fb->m.mem[2].addr, fb->m.mem[2].size);
 
-	vb2_v4l2 = container_of(vb2_buf, struct vb2_v4l2_buffer, vb2_buf);
+	dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+	vb2_buf = &dstbuf->vb.vb2_buf;
 
 	if (dstbuf->frame_buffer.num_planes == 1) {
-		vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
+		vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
 	} else if (dstbuf->frame_buffer.num_planes == 2) {
-		vb2_set_plane_payload(vb2_buf, 0, fb->m.mem[0].bytes_used);
-		vb2_set_plane_payload(vb2_buf, 1, fb->m.mem[1].bytes_used);
+		vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
+		vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, fb->m.mem[1].bytes_used);
 	}
-	vb2_buf->timestamp = vf->timestamp;
-	dstbuf->vb.flags |= vf->frame_type;
+	dstbuf->vb.vb2_buf.timestamp = vf->timestamp;
+	dstbuf->ready_to_display = true;
 
-	if ((ctx->picinfo.field == V4L2_FIELD_INTERLACED) && (!ctx->vpp_is_need)) {
-		vb2_v4l2->field = V4L2_FIELD_INTERLACED;
-	}
-
-	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
+	if (dump_capture_frame) {
 		struct file *fp;
-		char file_name[32] = {0};
-
-		if (!dump_capture_frame || ctx->is_drm_mode)
-			break;
-		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
-			break;
-		if (dw_mode == VDEC_DW_AFBC_ONLY)
-			break;
-
-		snprintf(file_name, 32, "/data/dec_dump_%ux%u.raw", vf->width, vf->height);
-
-		fp = filp_open(file_name,
+		fp = filp_open("/data/dec_dump.raw",
 				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
-
 		if (!IS_ERR(fp)) {
-			struct vb2_buffer *vb = vb2_buf;
-
-			kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
+			struct vb2_buffer *vb = &dstbuf->vb.vb2_buf;
+			kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].bytesused, 0);
 			if (dstbuf->frame_buffer.num_planes == 2)
 				kernel_write(fp,vb2_plane_vaddr(vb, 1),
-						vb->planes[1].length, 0);
+						vb->planes[1].bytesused, 0);
 			pr_info("dump idx: %d %dx%d\n", dump_capture_frame, vf->width, vf->height);
-			dump_capture_frame--;
+			dump_capture_frame = false;
 			filp_close(fp, NULL);
 		}
-	} while(0);
-
-	ATRACE_COUNTER("VC_OUT_VSINK-1.submit", vb2_buf->index);
-	ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
+	}
 
 	if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
 		dstbuf->vb.flags = V4L2_BUF_FLAG_LAST;
 		if (dstbuf->frame_buffer.num_planes == 1) {
-			vb2_set_plane_payload(vb2_buf, 0, 0);
+			vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
 		} else if (dstbuf->frame_buffer.num_planes == 2) {
-			vb2_set_plane_payload(vb2_buf, 0, 0);
-			vb2_set_plane_payload(vb2_buf, 1, 0);
+			vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, 0);
+			vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, 0);
 		}
 		ctx->has_receive_eos = true;
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"recevie a empty frame. idx: %d, state: %d\n",
-			vb2_buf->index, vb2_buf->state);
+			dstbuf->vb.vb2_buf.index,
+			dstbuf->vb.vb2_buf.state);
+		ATRACE_COUNTER("v4l2_eos", 0);
 	}
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 		"receive vbuf idx: %d, state: %d\n",
-		vb2_buf->index, vb2_buf->state);
+		dstbuf->vb.vb2_buf.index,
+		dstbuf->vb.vb2_buf.state);
 
 	if (vf->flag & VFRAME_FLAG_EMPTY_FRAME_V4L) {
-		if (ctx->v4l_resolution_change) {
+		if (ctx->q_data[AML_Q_DATA_SRC].resolution_changed) {
 			/* make the run to stanby until new buffs to enque. */
 			ctx->v4l_codec_dpb_ready = false;
 			ctx->reset_flag = V4L_RESET_MODE_LIGHT;
-			ctx->vpp_cfg.res_chg = true;
 
 			/*
 			 * After all buffers containing decoded frames from
@@ -838,449 +606,50 @@
 
 	if (dstbuf->vb.vb2_buf.state == VB2_BUF_STATE_ACTIVE) {
 		/* binding vframe handle. */
-		if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
-			if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
-				if ((ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
-					(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
-					(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
-					(ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
-					(ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
-					vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-				}
-				else {
-					if (fb->status == FB_ST_GE2D)
-						vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-				}
-			}
-		} else {
-			if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
-				vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-		}
-
-		vf->omx_index = vf->index_disp;
+		vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
+		ATRACE_COUNTER("v4l2_from", vf->index_disp);
 		dstbuf->privdata.vf = *vf;
+		dstbuf->privdata.vf.omx_index =
+			dstbuf->vb.vb2_buf.index;
 
-		if (vb2_buf->memory == VB2_MEMORY_DMABUF) {
-			struct dma_buf * dma;
-
-			dma = dstbuf->vb.vb2_buf.planes[0].dbuf;
-			if (dmabuf_is_uvm(dma)) {
-				/* only Y will contain vframe */
-				comp_buf_set_vframe(ctx, vb2_buf, vf);
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-					"set vf(%px) into %dth buf\n",
-					vf, vb2_buf->index);
-			}
-		}
-
-		fb_map_table_hold(ctx, vb2_buf, vf, fb->task, dstbuf->internal_index);
-
-		v4l2_buff_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
-
-		fb->status = FB_ST_DISPLAY;
+		v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
 	}
 
 	mutex_lock(&ctx->state_lock);
 	if (ctx->state == AML_STATE_FLUSHING &&
 		ctx->has_receive_eos) {
 		ctx->state = AML_STATE_FLUSHED;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		ATRACE_COUNTER("v4l2_state", ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_FLUSHED)\n");
 	}
 	mutex_unlock(&ctx->state_lock);
 
-	if (ctx->post_to_upper_done == false) {
-		ctx->post_to_upper_done = true;
-		wake_up_interruptible(&ctx->post_done_wq);
-	}
-
 	ctx->decoded_frame_cnt++;
 }
 
-static void fill_capture_done_cb(void *v4l_ctx, void *fb_ctx)
+static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out)
 {
-	struct aml_vcodec_ctx *ctx =
-		(struct aml_vcodec_ctx *)v4l_ctx;
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)fb_ctx;
-	struct aml_video_dec_buf *aml_buff =
-		container_of(fb, struct aml_video_dec_buf, frame_buffer);
-	struct vb2_v4l2_buffer *vb = &aml_buff->vb;
+	int ret = -1;
 
-	if (ctx->is_stream_off) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
-			"ignore buff idx: %d streamoff\n", fb->buf_idx);
-		return;
-	}
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
 
-	ATRACE_COUNTER("VC_OUT_VSINK-0.receive", vb->vb2_buf.index);
-
-	mutex_lock(&ctx->capture_buffer_lock);
-	kfifo_put(&ctx->capture_buffer, vb);
-	mutex_unlock(&ctx->capture_buffer_lock);
-
-	aml_thread_post_task(ctx, AML_THREAD_CAPTURE);
-}
-
-static void update_vdec_buf_plane(struct aml_vcodec_ctx *ctx,
-				  struct vdec_v4l2_buffer *fb,
-				  struct vb2_buffer *vb)
-{
-	int i;
-	char plane_n[3] = {'Y','U','V'};
-
-	fb->num_planes = vb->num_planes;
-	fb->buf_idx = vb->index;
-
-	for (i = 0 ; i < vb->num_planes ; i++) {
-		fb->m.mem[i].addr	= vb2_dma_contig_plane_dma_addr(vb, i);
-		fb->m.mem[i].dbuf	= vb->planes[i].dbuf;
-		if (i == 0) {
-			//Y
-			if (vb->num_planes == 1) {
-				fb->m.mem[0].size	= ctx->picinfo.y_len_sz +
-					ctx->picinfo.c_len_sz;
-				fb->m.mem[0].offset = ctx->picinfo.y_len_sz;
-			} else {
-				fb->m.mem[0].size	= ctx->picinfo.y_len_sz;
-				fb->m.mem[0].offset = 0;
-			}
-		} else {
-			if (vb->num_planes == 2) {
-				//UV
-				fb->m.mem[1].size	= ctx->picinfo.c_len_sz;
-				fb->m.mem[1].offset = ctx->picinfo.c_len_sz >> 1;
-			} else {
-				fb->m.mem[i].size  = ctx->picinfo.c_len_sz >> 1;
-				fb->m.mem[i].offset = 0;
-			}
-		}
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-				"idx: %u, %c:(0x%lx, %d)\n", vb->index,
-				plane_n[i], fb->m.mem[i].addr, fb->m.mem[i].size);
-	}
-}
-
-static bool fb_token_insert(struct aml_vcodec_ctx *ctx,
-			    ulong *token)
-{
-	ulong vb_handle;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
-		if (ctx->token_table[i] &&
-			(ctx->token_table[i] == *token)) {
-			return true;
-		}
-	}
-
-	if (!v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx))
-		return false;
-
-	vb_handle = (ulong)v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-
-	for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
-		if (!ctx->token_table[i]) {
-			ctx->token_table[i] = vb_handle;
-			break;
-		}
-	}
-
-	if (i >= ARRAY_SIZE(ctx->token_table)) {
+	ret = vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER, out);
+	if (ret) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s, table is full. token:%lx\n",
-			__func__, vb_handle);
-		return false;
+			"Cannot get param : GET_PARAM_DISP_FRAME_BUFFER\n");
+		return -1;
 	}
 
-	*token = vb_handle;
-
-	return true;
-}
-
-static void fb_token_remove(struct aml_vcodec_ctx *ctx,
-			    ulong token)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
-		if (token == ctx->token_table[i]) {
-			ctx->token_table[i] = 0;
-			break;
-		}
-	}
-
-	if (i >= ARRAY_SIZE(ctx->token_table)) {
+	if (!*out) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s, remove token err, token:%lx.\n",
-			__func__, token);
+			"No display frame buffer\n");
+		return -1;
 	}
-}
-
-static void fb_token_clean(struct aml_vcodec_ctx *ctx)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ctx->token_table); i++) {
-		ctx->token_table[i] = 0;
-	}
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s done\n", __func__);
-}
-
-static bool fb_buff_query(struct aml_fb_ops *fb, ulong *token)
-{
-	struct aml_vcodec_ctx *ctx =
-		container_of(fb, struct aml_vcodec_ctx, fb_ops);
-	struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
-	bool ret = false;
-	ulong flags;
-
-	if (!que->streaming)
-		return false;
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	ret = fb_token_insert(ctx, token);
-
-	aml_vcodec_ctx_unlock(ctx, flags);
 
 	return ret;
 }
 
-static void aml_task_chain_remove(struct aml_vcodec_ctx *ctx)
-{
-	struct task_chain_s *task, *tmp;
-
-	list_for_each_entry_safe(task, tmp, &ctx->task_chain_pool, node) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"remove task chain:%d, %px\n", task->id, task);
-		list_del(&task->node);
-		task_chain_clean(task);
-		task_chain_release(task);
-	}
-}
-
-static struct task_ops_s *get_v4l_sink_ops(void);
-
-static void aml_creat_pipeline(struct aml_vcodec_ctx *ctx,
-			       struct vdec_v4l2_buffer *fb,
-			       u32 requester)
-{
-	struct task_chain_s *task = fb->task;
-	/*
-	 * line 1: dec <==> vpp <==> v4l-sink, for P / P + DI.NR.
-	 * line 2: dec <==> vpp, vpp <==> v4l-sink, for I / I + DI.NR.
-	 * line 3: dec <==> v4l-sink, only for P.
-	 * line 4: dec <==> ge2d, ge2d <==> v4l-sink, used for fmt convert.
-	 * line 5: dec <==> ge2d, ge2d <==>vpp, vpp <==> v4l-sink.
-	 * line 6: dec <==> ge2d, ge2d <==> vpp <==> v4l-sink.
-	 */
-
-	switch (requester) {
-	case AML_FB_REQ_DEC:
-		if (ctx->ge2d) {
-			/* dec <==> ge2d. */
-			task->attach(task, get_ge2d_ops(), ctx->ge2d);
-		} else if (ctx->vpp) {
-			if (ctx->vpp->is_prog) {
-				/* dec <==> vpp <==> v4l-sink. */
-				task->attach(task, get_v4l_sink_ops(), ctx);
-				task->attach(task, get_vpp_ops(), ctx->vpp);
-			} else {
-				/* dec <==> vpp. */
-				task->attach(task, get_vpp_ops(), ctx->vpp);
-			}
-		} else {
-			/* dec <==> v4l-sink. */
-			task->attach(task, get_v4l_sink_ops(), ctx);
-		}
-		break;
-
-	case AML_FB_REQ_GE2D:
-		if (ctx->vpp) {
-			if (ctx->vpp->is_prog) {
-				/* ge2d <==> vpp <==> v4l-sink. */
-				task->attach(task, get_v4l_sink_ops(), ctx);
-				task->attach(task, get_vpp_ops(), ctx->vpp);
-				task->attach(task, get_ge2d_ops(), ctx->ge2d);
-			} else {
-				/* ge2d <==> vpp. */
-				task->attach(task, get_vpp_ops(), ctx->vpp);
-				task->attach(task, get_ge2d_ops(), ctx->ge2d);
-			}
-		} else {
-			/* ge2d <==> v4l-sink. */
-			task->attach(task, get_v4l_sink_ops(), ctx);
-			task->attach(task, get_ge2d_ops(), ctx->ge2d);
-		}
-		break;
-
-	case AML_FB_REQ_VPP:
-		/* vpp <==> v4l-sink. */
-		task->attach(task, get_v4l_sink_ops(), ctx);
-		task->attach(task, get_vpp_ops(), ctx->vpp);
-		break;
-
-	default:
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"unsupport requester %x\n", requester);
-	}
-}
-
-static int fb_buff_from_queue(struct aml_fb_ops *fb_ops,
-		ulong token, struct vdec_v4l2_buffer **out_fb,
-		u32 requester)
-{
-	struct aml_vcodec_ctx *ctx =
-		container_of(fb_ops, struct aml_vcodec_ctx, fb_ops);
-	struct aml_video_dec_buf *aml_buf = NULL;
-	struct vb2_v4l2_buffer *v4l_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	u32 buf_status = 0;
-	ulong flags;
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	if (ctx->is_stream_off) {
-		aml_vcodec_ctx_unlock(ctx, flags);
-		return -1;
-	}
-
-	v4l_buf = (struct vb2_v4l2_buffer *) token;
-	if (!v4l_buf) {
-		aml_vcodec_ctx_unlock(ctx, flags);
-		return -1;
-	}
-
-	aml_buf = container_of(v4l_buf, struct aml_video_dec_buf, vb);
-
-	fb		= &aml_buf->frame_buffer;
-	fb->buf_idx	= v4l_buf->vb2_buf.index;
-	aml_buf->used	= true;
-	ctx->buf_used_count++;
-
-	if (requester == AML_FB_REQ_VPP) {
-		buf_status = V4L_CAP_BUFF_IN_VPP;
-		ctx->cap_pool.vpp++;
-	} else if (requester == AML_FB_REQ_DEC) {
-		buf_status = V4L_CAP_BUFF_IN_DEC;
-		ctx->cap_pool.dec++;
-	} else if (requester == AML_FB_REQ_GE2D) {
-		buf_status = V4L_CAP_BUFF_IN_GE2D;
-		ctx->cap_pool.ge2d++;
-	}
-
-	ctx->cap_pool.seq[ctx->cap_pool.out++] =
-		(buf_status << 16 | fb->buf_idx);
-
-	update_vdec_buf_plane(ctx, fb, &v4l_buf->vb2_buf);
-
-	aml_creat_pipeline(ctx, fb, requester);
-
-	fb_token_remove(ctx, token);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"vid:%d, task:%px, phy:%lx, state:%d, ready:%d, requester:%d\n",
-		fb->buf_idx, fb->task, fb->m.mem[0].addr, v4l_buf->vb2_buf.state,
-		v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), requester);
-
-	ATRACE_COUNTER("VC_IN_VSINK-3.require", v4l_buf->vb2_buf.index);
-
-	*out_fb = fb;
-
-	aml_vcodec_ctx_unlock(ctx, flags);
-
-	return 0;
-}
-
-static struct task_ops_s v4l_sink_ops = {
-	.type		= TASK_TYPE_V4L_SINK,
-	.fill_buffer	= fill_capture_done_cb,
-};
-
-static struct task_ops_s *get_v4l_sink_ops(void)
-{
-	return &v4l_sink_ops;
-}
-
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx)
-{
-	struct aml_q_data *outq = NULL;
-	struct aml_q_data *capq = NULL;
-	struct vdec_pic_info pic;
-
-	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &pic)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"get pic info err\n");
-		return;
-	}
-
-	outq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
-	capq = aml_vdec_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-
-	pr_info("\n==== Show Basic Information ==== \n");
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Format     : %s\n",
-		outq->fmt->name);
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Color space: %s\n",
-		capq->fmt->name);
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Scan type  : %s\n",
-		(pic.field == V4L2_FIELD_NONE) ?
-		"Progressive" : "Interlaced");
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Resolution : visible(%dx%d), coded(%dx%d)\n",
-		pic.visible_width, pic.visible_height,
-		pic.coded_width, pic.coded_height);
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Buffer num : dec:%d, vpp:%d, ge2d:%d, margin:%d, total:%d\n",
-		ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
-		ctx->picinfo.dpb_margin, CTX_BUF_TOTAL(ctx));
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Config     : dw:%d, drm:%d, byp:%d, lc:%d, nr:%d, ge2d:%x\n",
-		ctx->config.parm.dec.cfg.double_write_mode,
-		ctx->is_drm_mode,
-		ctx->vpp_cfg.is_bypass_p,
-		ctx->vpp_cfg.enable_local_buf,
-		ctx->vpp_cfg.enable_nr,
-		ctx->ge2d_cfg.mode);
-}
-
-void aml_buffer_status(struct aml_vcodec_ctx *ctx)
-{
-	struct vb2_v4l2_buffer *vb = NULL;
-	struct aml_video_dec_buf *aml_buff = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	struct vb2_queue *q = NULL;
-	ulong flags;
-	int i;
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	q = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!q->streaming) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"can't achieve buffers status before start streaming.\n");
-	}
-
-	pr_info("\n==== Show Buffer Status ======== \n");
-	for (i = 0; i < q->num_buffers; ++i) {
-		vb = to_vb2_v4l2_buffer(q->bufs[i]);
-		aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
-		fb = &aml_buff->frame_buffer;
-
-		/* print out task chain status. */
-		task_chain_show(fb->task);
-	}
-
-	aml_vcodec_ctx_unlock(ctx, flags);
-}
-
 static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx)
 {
 	if (!ctx->v4l_codec_dpb_ready) {
@@ -1291,26 +660,12 @@
 			ctx->v4l_codec_dpb_ready = true;
 
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-			"dpb: %d, vpp: %d, ready: %d, used: %d, dpb is ready: %s\n",
-			ctx->dpb_size, ctx->vpp_size,
-			v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
+			"dpb: %d, ready: %d, used: %d, dpb is ready: %s\n",
+			ctx->dpb_size, v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
 			ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no");
 	}
 }
 
-static void reconfig_vpp_status(struct aml_vcodec_ctx *ctx)
-{
-	if (bypass_nr_flag &&
-		!ctx->vpp_cfg.is_prog &&
-		((ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC_LOCAL) ||
-		(ctx->vpp_cfg.mode == VPP_MODE_NOISE_REDUC))) {
-		ctx->vpp_cfg.enable_nr = 0;
-		ctx->vpp_cfg.enable_local_buf = 0;
-
-		ctx->vpp_cfg.mode = VPP_MODE_DI;
-	}
-}
-
 static int is_vdec_ready(struct aml_vcodec_ctx *ctx)
 {
 	struct aml_vcodec_dev *dev = ctx->dev;
@@ -1326,7 +681,7 @@
 		mutex_lock(&ctx->state_lock);
 		if (ctx->state == AML_STATE_PROBE) {
 			ctx->state = AML_STATE_READY;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			ATRACE_COUNTER("v4l2_state", ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_READY)\n");
 		}
@@ -1338,7 +693,7 @@
 		if (ctx->m2m_ctx->out_q_ctx.q.streaming &&
 			ctx->m2m_ctx->cap_q_ctx.q.streaming) {
 			ctx->state = AML_STATE_ACTIVE;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			ATRACE_COUNTER("v4l2_state", ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_ACTIVE)\n");
 		}
@@ -1363,7 +718,7 @@
 	return true;
 }
 
-static void aml_wait_buf_ready(struct aml_vcodec_ctx *ctx)
+static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx)
 {
 	ulong expires;
 
@@ -1378,75 +733,34 @@
 		}
 
 		ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
-		if ((ready_num + ctx->buf_used_count) >= CTX_BUF_TOTAL(ctx))
+		if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size)
 			ctx->v4l_codec_dpb_ready = true;
 	}
 }
 
-void dmabuff_recycle_worker(struct work_struct *work)
-{
-	struct aml_vcodec_ctx *ctx =
-		container_of(work, struct aml_vcodec_ctx, dmabuff_recycle_work);
-	struct vb2_v4l2_buffer *vb = NULL;
-	struct aml_video_dec_buf *buf = NULL;
-	unsigned long flags;
-
-	for (;;) {
-		spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
-		if (!kfifo_get(&ctx->dmabuff_recycle, &vb)) {
-			spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-			break;
-		}
-		spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
-		buf = container_of(vb, struct aml_video_dec_buf, vb);
-
-		if (ctx->is_out_stream_off)
-			continue;
-
-		if (wait_event_interruptible_timeout
-			(ctx->wq, buf->used == false,
-			 msecs_to_jiffies(200)) == 0) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"wait recycle dma buff timeout.\n");
-		}
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
-			"recycle buff idx: %d, vbuf: %lx\n", vb->vb2_buf.index,
-			(ulong)sg_dma_address(buf->out_sgt->sgl));
-
-		ATRACE_COUNTER("VO_OUT_VSINK-2.write_secure_end", vb->vb2_buf.index);
-
-		if (vb->vb2_buf.state != VB2_BUF_STATE_ERROR)
-			v4l2_buff_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
-				VB2_BUF_STATE_DONE);
-	}
-}
-
 void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx, u32 handle)
 {
-	struct aml_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *vb = NULL;
-	struct vb2_queue *q = NULL;
+	struct vb2_v4l2_buffer *vb;
+	struct aml_video_dec_buf *buf;
+	struct vb2_queue *q;
 	int index = handle & 0xf;
-	unsigned long flags;
 
 	if (ctx->is_out_stream_off) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
 			"ignore buff idx: %d streamoff\n", index);
 		return;
 	}
-
 	q = v4l2_m2m_get_vq(ctx->m2m_ctx,
 		V4L2_BUF_TYPE_VIDEO_OUTPUT);
 
 	vb = to_vb2_v4l2_buffer(q->bufs[index]);
+	buf = container_of(vb, struct aml_video_dec_buf, vb);
+	v4l2_m2m_buf_done(vb, buf->error ? VB2_BUF_STATE_ERROR :
+		VB2_BUF_STATE_DONE);
 
-	spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
-	kfifo_put(&ctx->dmabuff_recycle, vb);
-	spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
-	queue_work(dev->decode_workqueue, &ctx->dmabuff_recycle_work);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
+		"recycle buff idx: %d, vbuf: %lx\n", index,
+		(ulong)vb2_dma_contig_plane_dma_addr(q->bufs[index], 0));
 }
 
 static void aml_vdec_worker(struct work_struct *work)
@@ -1454,12 +768,12 @@
 	struct aml_vcodec_ctx *ctx =
 		container_of(work, struct aml_vcodec_ctx, decode_work);
 	struct aml_vcodec_dev *dev = ctx->dev;
-	struct aml_video_dec_buf *aml_buf;
-	struct vb2_v4l2_buffer *vb2_v4l2;
-	struct vb2_buffer *vb;
+	struct vb2_buffer *src_buf;
 	struct aml_vcodec_mem buf;
 	bool res_chg = false;
 	int ret;
+	struct aml_video_dec_buf *src_buf_info;
+	struct vb2_v4l2_buffer *src_vb2_v4l2;
 
 	if (ctx->state < AML_STATE_INIT ||
 		ctx->state > AML_STATE_FLUSHED) {
@@ -1473,23 +787,21 @@
 		goto out;
 	}
 
-	vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	if (vb2_v4l2 == NULL) {
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	if (src_buf == NULL) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"src_buf empty.\n");
 		goto out;
 	}
 
-	vb = (struct vb2_buffer *)vb2_v4l2;
-
 	/*this case for google, but some frames are droped on ffmpeg, so disabled temp.*/
 	if (0 && !is_enough_work_items(ctx))
 		goto out;
 
-	aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-	if (aml_buf->lastframe) {
-		ulong expires;
+	src_vb2_v4l2 = container_of(src_buf, struct vb2_v4l2_buffer, vb2_buf);
+	src_buf_info = container_of(src_vb2_v4l2, struct aml_video_dec_buf, vb);
 
+	if (src_buf_info->lastframe) {
 		/*the empty data use to flushed the decoder.*/
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 			"Got empty flush input buffer.\n");
@@ -1497,34 +809,22 @@
 		/*
 		 * when inputs a small amount of src buff, then soon to
 		 * switch state FLUSHING, must to wait the DBP to be ready.
-		 * (!ctx->v4l_codec_dpb_ready) change to  only need one buf
-		 * for run ready in new version.
 		 */
-		expires = jiffies + msecs_to_jiffies(5000);
-		while ((vdec_frame_number(ctx->ada_ctx) > 0) &&
-			(ctx->cap_pool.in < 1)) {
-			if (time_after(jiffies, expires)) {
-				aml_vdec_flush_decoder(ctx);
-				v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-				v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-				aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"capture buffer waiting timeout.\n");
-				goto out;
-			}
-			usleep_range(5000, 5500);
+		if (!ctx->v4l_codec_dpb_ready) {
+			v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+			goto out;
 		}
 
 		mutex_lock(&ctx->state_lock);
 		if (ctx->state == AML_STATE_ACTIVE) {
 			ctx->state = AML_STATE_FLUSHING;// prepare flushing
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			ATRACE_COUNTER("v4l2_state", ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_FLUSHING-LASTFRM)\n");
 		}
 		mutex_unlock(&ctx->state_lock);
 
-		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 
 		/* sets eos data for vdec input. */
@@ -1533,22 +833,21 @@
 		goto out;
 	}
 
-	buf.index	= vb->index;
-	buf.vaddr	= vb2_plane_vaddr(vb, 0);
-	buf.addr	= sg_dma_address(aml_buf->out_sgt->sgl);
-	buf.size	= vb->planes[0].bytesused;
-	buf.model	= vb->memory;
-	buf.timestamp	= vb->timestamp;
-	buf.meta_ptr	= (ulong)aml_buf->meta_data;
+	buf.index	= src_buf->index;
+	buf.vaddr	= vb2_plane_vaddr(src_buf, 0);
+	buf.addr	= vb2_dma_contig_plane_dma_addr(src_buf, 0);
+	buf.size	= src_buf->planes[0].bytesused;
+	buf.model	= src_buf->memory;
+	buf.timestamp	= src_buf->timestamp;
 
 	if (!buf.vaddr && !buf.addr) {
 		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"id=%d src_addr is NULL.\n", vb->index);
+			"id=%d src_addr is NULL.\n", src_buf->index);
 		goto out;
 	}
 
-	aml_buf->used = true;
+	src_buf_info->used = true;
 
 	/* v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 		"size: 0x%zx, crc: 0x%x\n",
@@ -1558,52 +857,29 @@
 	/*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 		"timestamp: 0x%llx\n", src_buf->timestamp);*/
 
-	if (ctx->is_drm_mode &&
-		(buf.model == VB2_MEMORY_DMABUF)) {
-		ATRACE_COUNTER("VO_IN_VSINK-2.write_secure", buf.size);
-	} else {
-		ATRACE_COUNTER("VO_IN_VSINK-2.write", buf.size);
-	}
-
-	ATRACE_COUNTER("V_ST_VSINK-input_buffering", vdec_frame_number(ctx->ada_ctx));
-
 	ret = vdec_if_decode(ctx, &buf, &res_chg);
 	if (ret > 0) {
 		/*
 		 * we only return src buffer with VB2_BUF_STATE_DONE
 		 * when decode success without resolution change.
 		 */
-		aml_buf->used = false;
 		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
-		if (ctx->is_drm_mode &&
-			(buf.model == VB2_MEMORY_DMABUF)) {
-			wake_up_interruptible(&ctx->wq);
-		} else {
-			ATRACE_COUNTER("VO_OUT_VSINK-0.wrtie_end", buf.size);
-			v4l2_buff_done(&aml_buf->vb,
-				VB2_BUF_STATE_DONE);
-		}
+		if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF))
+			v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
 	} else if (ret && ret != -EAGAIN) {
-		aml_buf->used = false;
+		src_buf_info->error = (ret == -EIO ? true : false);
 		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 
-		if (ctx->is_drm_mode &&
-			(buf.model == VB2_MEMORY_DMABUF)) {
-			wake_up_interruptible(&ctx->wq);
-		} else {
-			ATRACE_COUNTER("VO_OUT_VSINK-3.write_error", buf.size);
-			v4l2_buff_done(&aml_buf->vb,
-				VB2_BUF_STATE_ERROR);
-		}
+		if (!(ctx->is_drm_mode && buf.model == VB2_MEMORY_DMABUF))
+			v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
 
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"error processing src data. %d.\n", ret);
 	} else if (res_chg) {
 		/* wait the DPB state to be ready. */
-		aml_wait_buf_ready(ctx);
+		aml_wait_dpb_ready(ctx);
 
-		aml_buf->used = false;
+		src_buf_info->used = false;
 		aml_vdec_pic_info_update(ctx);
 		/*
 		 * On encountering a resolution change in the stream.
@@ -1614,13 +890,13 @@
 		mutex_lock(&ctx->state_lock);
 		if (ctx->state == AML_STATE_ACTIVE) {
 			ctx->state = AML_STATE_FLUSHING;// prepare flushing
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			ATRACE_COUNTER("v4l2_state", ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_FLUSHING-RESCHG)\n");
 		}
 		mutex_unlock(&ctx->state_lock);
 
-		ctx->v4l_resolution_change = true;
+		ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
 		while (ctx->m2m_ctx->job_flags & TRANS_RUNNING) {
 			v4l2_m2m_job_pause(dev->m2m_dev_dec, ctx->m2m_ctx);
 		}
@@ -1629,10 +905,8 @@
 
 		goto out;
 	} else {
-		ATRACE_COUNTER("VO_OUT_VSINK-1.write_again", buf.size);
 		/* decoder is lack of resource, retry after short delay */
-		if (vdec_get_instance_num() < 2)
-			usleep_range(2000, 4000);
+		usleep_range(50000, 55000);
 	}
 
 	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
@@ -1650,10 +924,28 @@
 
 	if (aml_codec_reset(ctx->ada_ctx, &ctx->reset_flag)) {
 		ctx->state = AML_STATE_ABORT;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		ATRACE_COUNTER("v4l2_state", ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_ABORT).\n");
+		goto out;
 	}
+
+	if (ctx->state ==  AML_STATE_RESET) {
+		ctx->state = AML_STATE_PROBE;
+		ATRACE_COUNTER("v4l2_state", ctx->state);
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+			"vcodec state (AML_STATE_PROBE)\n");
+
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+			"dpb: %d, ready: %d, used: %d\n", ctx->dpb_size,
+			v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx),
+			ctx->buf_used_count);
+
+		/* vdec has ready to decode subsequence data of new resolution. */
+		ctx->q_data[AML_Q_DATA_SRC].resolution_changed = false;
+		v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
+	}
+
 out:
 	complete(&ctx->comp);
 	return;
@@ -1661,13 +953,13 @@
 
 void wait_vcodec_ending(struct aml_vcodec_ctx *ctx)
 {
+	struct aml_vcodec_dev *dev = ctx->dev;
+
 	/* disable queue output item to worker. */
 	ctx->output_thread_ready = false;
-	ctx->is_stream_off = true;
 
 	/* flush output buffer worker. */
-	cancel_work_sync(&ctx->decode_work);
-	cancel_work_sync(&ctx->dmabuff_recycle_work);
+	flush_workqueue(dev->decode_workqueue);
 
 	/* clean output cache and decoder status . */
 	if (ctx->state > AML_STATE_INIT)
@@ -1681,38 +973,33 @@
 	ctx->v4l_codec_dpb_ready = false;
 }
 
-void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx)
+void try_to_capture(struct aml_vcodec_ctx *ctx)
 {
-	struct vb2_v4l2_buffer *vb = NULL;
-	struct aml_video_dec_buf *aml_buff = NULL;
+	int ret = 0;
 	struct vdec_v4l2_buffer *fb = NULL;
 
-	for (;;) {
-		mutex_lock(&ctx->capture_buffer_lock);
-		if (!kfifo_get(&ctx->capture_buffer, &vb)) {
-			mutex_unlock(&ctx->capture_buffer_lock);
-			break;
-		}
-		mutex_unlock(&ctx->capture_buffer_lock);
-
-		aml_buff = container_of(vb, struct aml_video_dec_buf, vb);
-		fb = &aml_buff->frame_buffer;
-
-		if (ctx->is_stream_off)
-			continue;
-
-		post_frame_to_upper(ctx, fb);
+	ret = get_display_buffer(ctx, &fb);
+	if (ret) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"the que have no disp buf,ret: %d\n", ret);
+		return;
 	}
-}
-EXPORT_SYMBOL_GPL(aml_thread_capture_worker);
 
-static int vdec_capture_thread(void *data)
+	trans_vframe_to_user(ctx, fb);
+}
+EXPORT_SYMBOL_GPL(try_to_capture);
+
+static int vdec_thread(void *data)
 {
+	struct sched_param param =
+		{.sched_priority = MAX_RT_PRIO / 2};
 	struct aml_vdec_thread *thread =
 		(struct aml_vdec_thread *) data;
 	struct aml_vcodec_ctx *ctx =
 		(struct aml_vcodec_ctx *) thread->priv;
 
+	sched_setscheduler(current, SCHED_FIFO, &param);
+
 	for (;;) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 			"%s, state: %d\n", __func__, ctx->state);
@@ -1728,19 +1015,19 @@
 	}
 
 	while (!kthread_should_stop()) {
-		usleep_range(1000, 2000);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
 	}
 
 	return 0;
 }
 
-void aml_thread_post_task(struct aml_vcodec_ctx *ctx,
+void aml_thread_notify(struct aml_vcodec_ctx *ctx,
 	enum aml_thread_type type)
 {
 	struct aml_vdec_thread *thread = NULL;
-	ulong flags;
 
-	spin_lock_irqsave(&ctx->tsplock, flags);
+	mutex_lock(&ctx->lock);
 	list_for_each_entry(thread, &ctx->vdec_thread_list, node) {
 		if (thread->task == NULL)
 			continue;
@@ -1748,9 +1035,9 @@
 		if (thread->type == type)
 			up(&thread->sem);
 	}
-	spin_unlock_irqrestore(&ctx->tsplock, flags);
+	mutex_unlock(&ctx->lock);
 }
-EXPORT_SYMBOL_GPL(aml_thread_post_task);
+EXPORT_SYMBOL_GPL(aml_thread_notify);
 
 int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
 	enum aml_thread_type type, const char *thread_name)
@@ -1768,7 +1055,7 @@
 	thread->priv = ctx;
 	sema_init(&thread->sem, 0);
 
-	thread->task = kthread_run(vdec_capture_thread, thread, "aml-%s-%d", thread_name, ctx->id);
+	thread->task = kthread_run(vdec_thread, thread, "aml-%s", thread_name);
 	if (IS_ERR(thread->task)) {
 		ret = PTR_ERR(thread->task);
 		thread->task = NULL;
@@ -1776,10 +1063,6 @@
 	}
 	sched_setscheduler_nocheck(thread->task, SCHED_FIFO, &param);
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-			"%s, policy is:%d priority is:%d\n",
-			__func__, thread->task->policy, thread->task->rt_priority);
-
 	list_add(&thread->node, &ctx->vdec_thread_list);
 
 	return 0;
@@ -1794,14 +1077,13 @@
 void aml_thread_stop(struct aml_vcodec_ctx *ctx)
 {
 	struct aml_vdec_thread *thread = NULL;
-	ulong flags;
 
 	while (!list_empty(&ctx->vdec_thread_list)) {
 		thread = list_entry(ctx->vdec_thread_list.next,
 			struct aml_vdec_thread, node);
-		spin_lock_irqsave(&ctx->tsplock, flags);
+		mutex_lock(&ctx->lock);
 		list_del(&thread->node);
-		spin_unlock_irqrestore(&ctx->tsplock, flags);
+		mutex_unlock(&ctx->lock);
 
 		thread->stop = true;
 		up(&thread->sem);
@@ -1823,17 +1105,7 @@
 	switch (cmd->cmd) {
 	case V4L2_DEC_CMD_STOP:
 	case V4L2_DEC_CMD_START:
-		if (cmd->cmd == V4L2_DEC_CMD_START) {
-			if (cmd->start.speed == ~0)
-				cmd->start.speed = 0;
-			if (cmd->start.format == ~0)
-				cmd->start.format = 0;
-		}
-
-		if (cmd->flags == ~0)
-			cmd->flags = 0;
-
-		if ((cmd->flags != 0) && (cmd->flags != ~0)) {
+		if (cmd->flags != 0) {
 			v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 				"cmd->flags=%u\n", cmd->flags);
 			return -EINVAL;
@@ -1862,6 +1134,19 @@
 
 	switch (cmd->cmd) {
 	case V4L2_DEC_CMD_STOP:
+		ATRACE_COUNTER("v4l2_stop", 0);
+		if (ctx->state != AML_STATE_ACTIVE) {
+			if (ctx->state >= AML_STATE_IDLE &&
+				ctx->state < AML_STATE_PROBE) {
+				ctx->state = AML_STATE_ABORT;
+				ATRACE_COUNTER("v4l2_state", ctx->state);
+				aml_vdec_dispatch_event(ctx, V4L2_EVENT_REQUEST_EXIT);
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+					"vcodec state (AML_STATE_ABORT)\n");
+				return 0;
+			}
+		}
+
 		src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 		if (!vb2_is_streaming(src_vq)) {
@@ -1870,32 +1155,18 @@
 			return 0;
 		}
 
-		dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
-			multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
-			V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (!vb2_is_streaming(dst_vq)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"Capture stream is off. No need to flush.\n");
-			return 0;
-		}
-
 		/* flush pipeline */
 		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
 		v4l2_m2m_try_schedule(ctx->m2m_ctx);//pay attention
 		ctx->receive_cmd_stop = true;
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"%s, receive cmd stop and prepare flush pipeline.\n", __func__);
 		break;
 
 	case V4L2_DEC_CMD_START:
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "CMD V4L2_DEC_CMD_START\n");
 		dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 			multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
 			V4L2_BUF_TYPE_VIDEO_CAPTURE);
 		vb2_clear_last_buffer_dequeued(dst_vq);//pay attention
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"%s, receive cmd start.\n", __func__);
 		break;
 
 	default:
@@ -1905,20 +1176,6 @@
 	return 0;
 }
 
-static void aml_wait_resource(struct aml_vcodec_ctx *ctx)
-{
-	ulong expires = jiffies + msecs_to_jiffies(1000);
-
-	while (atomic_read(&ctx->dev->vpp_count) >= max_di_instance) {
-		if (time_after(jiffies, expires)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-				"wait resource timeout.\n");
-			break;
-		}
-		usleep_range(2000, 4000);
-	}
-}
-
 static int vidioc_decoder_streamon(struct file *file, void *priv,
 	enum v4l2_buf_type i)
 {
@@ -1927,80 +1184,26 @@
 	struct vb2_queue *q;
 
 	q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
-	if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
-		ctx->is_stream_off) {
-		if (ctx->vpp_is_need) {
-			int ret;
+	if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
+		if (ctx->is_stream_off) {
+			mutex_lock(&ctx->state_lock);
+			if ((ctx->state == AML_STATE_ACTIVE ||
+				ctx->state == AML_STATE_FLUSHING ||
+				ctx->state == AML_STATE_FLUSHED) ||
+				(ctx->reset_flag == V4L_RESET_MODE_LIGHT)) {
+				ctx->state = AML_STATE_RESET;
+				ATRACE_COUNTER("v4l2_state", ctx->state);
+				ctx->v4l_codec_dpb_ready = false;
 
-			if (ctx->vpp_cfg.fmt == 0)
-				ctx->vpp_cfg.fmt = ctx->cap_pix_fmt;
-
-			if (ctx->vpp == NULL)
-				aml_wait_resource(ctx);
-
-			if ((atomic_read(&ctx->dev->vpp_count) < max_di_instance) ||
-				(ctx->vpp != NULL)) {
-				if (ctx->vpp && ctx->vpp_cfg.is_vpp_reset &&
-					(ctx->vpp->is_prog == ctx->vpp_cfg.is_prog) &&
-					(ctx->vpp->is_bypass_p == ctx->vpp_cfg.is_bypass_p) &&
-					(ctx->vpp->work_mode == ctx->vpp_cfg.mode)) {
-					aml_v4l2_vpp_reset(ctx->vpp);
-				} else {
-					if (ctx->vpp) {
-						atomic_dec(&ctx->dev->vpp_count);
-						aml_v4l2_vpp_destroy(ctx->vpp);
-						ctx->vpp = NULL;
-					}
-
-					ret = aml_v4l2_vpp_init(ctx, &ctx->vpp_cfg, &ctx->vpp);
-					if (ret) {
-						v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-							"vpp_wrapper init err:%d vpp_cfg.fmt: %d\n",
-							ret, ctx->vpp_cfg.fmt);
-						return ret;
-					}
-
-					atomic_inc(&ctx->dev->vpp_count);
-
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-						"vpp_wrapper instance count: %d\n",
-						atomic_read(&ctx->dev->vpp_count));
-				}
-			} else {
-				ctx->vpp_cfg.enable_local_buf = 0;
-				ctx->vpp_cfg.enable_nr = 0;
-				ctx->picinfo.dpb_margin += ctx->vpp_size;
-				ctx->dpb_size = ctx->picinfo.dpb_margin + ctx->picinfo.dpb_frames;
-				ctx->vpp_size = 0;
-				vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo);
-				ctx->vpp_is_need = false;
+				v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
+					"vcodec state (AML_STATE_RESET)\n");
+				aml_vdec_reset(ctx);
 			}
-			ctx->vpp_cfg.is_vpp_reset = false;
-		} else {
-			if (ctx->vpp) {
-				atomic_dec(&ctx->dev->vpp_count);
-				aml_v4l2_vpp_destroy(ctx->vpp);
-				ctx->vpp = NULL;
-			}
+			mutex_unlock(&ctx->state_lock);
+
+			ctx->is_stream_off = false;
+			ctx->v4l_resolution_change = false;
 		}
-
-		if (ctx->ge2d_is_need) {
-			int ret;
-
-			if (ctx->ge2d) {
-				aml_v4l2_ge2d_destroy(ctx->ge2d);
-				ctx->ge2d = NULL;
-			}
-
-			ret = aml_v4l2_ge2d_init(ctx, &ctx->ge2d_cfg, &ctx->ge2d);
-			if (ret) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"ge2d_wrapper init err:%d\n", ret);
-				return ret;
-			}
-		}
-
-		ctx->is_stream_off = false;
 	} else
 		ctx->is_out_stream_off = false;
 
@@ -2016,26 +1219,12 @@
 	struct v4l2_fh *fh = file->private_data;
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
 	struct vb2_queue *q;
-	ulong flags;
 
 	q = v4l2_m2m_get_vq(fh->m2m_ctx, i);
-
-	flags = aml_vcodec_ctx_lock(ctx);
-
-	if (V4L2_TYPE_IS_OUTPUT(q->type))
-		ctx->is_out_stream_off = true;
-	else
+	if (!V4L2_TYPE_IS_OUTPUT(q->type))
 		ctx->is_stream_off = true;
-
-	aml_vcodec_ctx_unlock(ctx, flags);
-
-	if (!V4L2_TYPE_IS_OUTPUT(q->type)) {
-		if (ctx->vpp) {
-			reconfig_vpp_status(ctx);
-		}
-	} else {
-		ctx->index_disp = 0;
-	}
+	else
+		ctx->is_out_stream_off = true;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, type: %d\n", __func__, q->type);
@@ -2052,38 +1241,19 @@
 
 	q = v4l2_m2m_get_vq(fh->m2m_ctx, rb->type);
 
-	if (!rb->count) {
-		if (!V4L2_TYPE_IS_OUTPUT(rb->type)) {
-			if (wait_event_interruptible_timeout
-				(ctx->post_done_wq, ctx->post_to_upper_done == true,
-				 msecs_to_jiffies(200)) == 0) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"wait post frame to upper finish timeout.\n");
-			}
-		}
+	if (!rb->count)
 		vb2_queue_release(q);
-	}
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, type: %d, count: %d\n",
 		__func__, q->type, rb->count);
 
 	if (!V4L2_TYPE_IS_OUTPUT(rb->type)) {
-		/* driver needs match v4l buffer number with total size*/
-		if (rb->count > CTX_BUF_TOTAL(ctx)) {
+		/* driver needs match v4l buffer number with dpb_size */
+		if (rb->count > ctx->dpb_size) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 					"reqbufs (st:%d) %d -> %d\n",
-					ctx->state, rb->count, CTX_BUF_TOTAL(ctx));
-			ctx->picinfo.dpb_margin += (rb->count - CTX_BUF_TOTAL(ctx));
-			ctx->dpb_size = ctx->picinfo.dpb_frames + ctx->picinfo.dpb_margin;
-			vdec_if_set_param(ctx, SET_PARAM_PIC_INFO, &ctx->picinfo);
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
-					"%s buf updated, dec: %d (%d + %d), vpp %d\n",
-					__func__,
-					ctx->dpb_size,
-					ctx->picinfo.dpb_frames,
-					ctx->picinfo.dpb_margin,
-					ctx->vpp_size);
+					ctx->state, rb->count, ctx->dpb_size);
 			//rb->count = ctx->dpb_size;
 		}
 	} else {
@@ -2123,12 +1293,9 @@
 {
 	ulong flags;
 
-	if (kref_read(&ctx->box_ref))
-		kref_put(&ctx->box_ref, box_release);
-
 	flags = aml_vcodec_ctx_lock(ctx);
 	ctx->state = AML_STATE_ABORT;
-	ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+	ATRACE_COUNTER("v4l2_state", ctx->state);
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 		"vcodec state (AML_STATE_ABORT)\n");
 	aml_vcodec_ctx_unlock(ctx, flags);
@@ -2154,8 +1321,6 @@
 	memset(q_data, 0, sizeof(struct aml_q_data));
 	q_data->visible_width = DFT_CFG_WIDTH;
 	q_data->visible_height = DFT_CFG_HEIGHT;
-	q_data->coded_width = DFT_CFG_WIDTH;
-	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = &aml_video_formats[OUT_FMT_IDX];
 	q_data->field = V4L2_FIELD_NONE;
 
@@ -2169,9 +1334,6 @@
 	q_data->coded_width = DFT_CFG_WIDTH;
 	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = &aml_video_formats[CAP_FMT_IDX];
-	if (support_format_I420)
-		q_data->fmt = &aml_video_formats[CAP_FMT_I420_IDX];
-
 	q_data->field = V4L2_FIELD_NONE;
 
 	v4l_bound_align_image(&q_data->coded_width,
@@ -2187,11 +1349,8 @@
 	q_data->bytesperline[1] = q_data->coded_width;
 	ctx->reset_flag = V4L_RESET_MODE_NORMAL;
 
-	ctx->fb_ops.query	= fb_buff_query;
-	ctx->fb_ops.alloc	= fb_buff_from_queue;
-
 	ctx->state = AML_STATE_IDLE;
-	ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+	ATRACE_COUNTER("v4l2_state", ctx->state);
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 		"vcodec state (AML_STATE_IDLE)\n");
 }
@@ -2215,24 +1374,11 @@
 	ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
 
 	if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
-		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
-			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->m.planes[0].bytesused);
-			else
-				ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->m.planes[0].bytesused);
-		} else {
-			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_IN_VSINK-1.que_again", buf->length);
-			else
-				ATRACE_COUNTER("VO_IN_VSINK-0.que", buf->length);
-		}
-	} else {
 		if (ret == -EAGAIN)
-			ATRACE_COUNTER("VC_IN_VSINK-1.que_again", buf->index);
+			ATRACE_COUNTER("v4l2_qbuf_eagain", 0);
 		else
-			ATRACE_COUNTER("VC_IN_VSINK-0.que", buf->index);
+			ATRACE_COUNTER("v4l2_qbuf_ok", 0);
 	}
-
 	return ret;
 }
 
@@ -2254,47 +1400,39 @@
 	}
 
 	ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+	if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
+		if (ret == -EAGAIN)
+			ATRACE_COUNTER("v4l2_dqin_eagain", 0);
+		else
+			ATRACE_COUNTER("v4l2_dqin_ok", 0);
+	} else {
+		if (ret == -EAGAIN)
+			ATRACE_COUNTER("v4l2_dqout_eagain", 0);
+	}
+
 	if (!ret && !V4L2_TYPE_IS_OUTPUT(buf->type)) {
 		struct vb2_queue *vq;
 		struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
 		struct aml_video_dec_buf *aml_buf = NULL;
-		struct file *file = NULL;
 
 		vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
 		vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]);
 		aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-		aml_buf->privdata.vb_handle	= (ulong) aml_buf;
+		aml_buf->privdata.vb_handle	= (ulong) ctx->dev;
 		aml_buf->privdata.v4l_dec_ctx	= (ulong) ctx;
+		aml_buf->privdata.v4l_inst_id		= ctx->id;
 
 		file = fget(vb2_v4l2->private);
-		if (file && is_v4l2_buf_file(file)) {
+		if (is_v4l2_buf_file(file)) {
 			dmabuf_fd_install_data(vb2_v4l2->private,
 				(void*)&aml_buf->privdata,
 				sizeof(struct file_private_data));
+			ATRACE_COUNTER("v4l2_dqout_ok", aml_buf->privdata.vf.index_disp);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "disp: %d, vf: %lx\n",
 				aml_buf->privdata.vf.index_disp,
 				(ulong) v4l_get_vf_handle(vb2_v4l2->private));
-			fput(file);
 		}
-	}
-
-	if (V4L2_TYPE_IS_OUTPUT(buf->type)) {
-		if (V4L2_TYPE_IS_MULTIPLANAR(buf->type)) {
-			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->m.planes[0].bytesused);
-			else
-				ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->m.planes[0].bytesused);
-		} else {
-			if (ret == -EAGAIN)
-				ATRACE_COUNTER("VO_OUT_VSINK-5.deque_again", buf->length);
-			else
-				ATRACE_COUNTER("VO_OUT_VSINK-4.deque", buf->length);
-		}
-	} else {
-		if (ret == -EAGAIN)
-			ATRACE_COUNTER("VC_OUT_VSINK-3.deque_again", buf->index);
-		else
-			ATRACE_COUNTER("VC_OUT_VSINK-2.deque", buf->index);
+		fput(file);
 	}
 
 	return ret;
@@ -2304,12 +1442,10 @@
 	struct v4l2_capability *cap)
 {
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
-	struct video_device *vfd_dec = video_devdata(file);
 
 	strlcpy(cap->driver, AML_VCODEC_DEC_NAME, sizeof(cap->driver));
 	strlcpy(cap->bus_info, AML_PLATFORM_STR, sizeof(cap->bus_info));
 	strlcpy(cap->card, AML_PLATFORM_STR, sizeof(cap->card));
-	cap->device_caps = vfd_dec->device_caps;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, %s\n", __func__, cap->card);
 
@@ -2347,154 +1483,115 @@
 
 static int vidioc_try_fmt(struct v4l2_format *f, struct aml_video_fmt *fmt)
 {
+	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 	int i;
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
-		if (V4L2_TYPE_IS_OUTPUT(f->type)) {
-			pix_mp->num_planes = 1;
-			pix_mp->plane_fmt[0].bytesperline = 0;
+	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		pix_fmt_mp->num_planes = 1;
+		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
+		if (pix_fmt_mp->pixelformat != V4L2_PIX_FMT_MPEG2  &&
+		    pix_fmt_mp->pixelformat != V4L2_PIX_FMT_H264)
+			pix_fmt_mp->field = V4L2_FIELD_NONE;
+		else if (pix_fmt_mp->field != V4L2_FIELD_NONE)
+			pr_info("%s, field: %u, fmt: %u\n",
+				__func__, pix_fmt_mp->field,
+				pix_fmt_mp->pixelformat);
+	} else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
+		int tmp_w, tmp_h;
 
-			if ((pix_mp->pixelformat != V4L2_PIX_FMT_MPEG2) &&
-			    (pix_mp->pixelformat != V4L2_PIX_FMT_H264) &&
-			    (pix_mp->pixelformat != V4L2_PIX_FMT_MPEG1)) {
-				pix_mp->field = V4L2_FIELD_NONE;
-			} else if (pix_mp->field != V4L2_FIELD_NONE) {
-				if (pix_mp->field == V4L2_FIELD_ANY)
-					pix_mp->field = V4L2_FIELD_NONE;
+		pix_fmt_mp->field = V4L2_FIELD_NONE;
+		pix_fmt_mp->height = clamp(pix_fmt_mp->height,
+					AML_VDEC_MIN_H,
+					AML_VDEC_MAX_H);
+		pix_fmt_mp->width = clamp(pix_fmt_mp->width,
+					AML_VDEC_MIN_W,
+					AML_VDEC_MAX_W);
 
-				pr_info("%s, field: %u, fmt: %x\n",
-					__func__, pix_mp->field,
-					pix_mp->pixelformat);
-			}
-		} else {
-			if (pix_mp->field != V4L2_FIELD_INTERLACED)
-				pix_mp->field = V4L2_FIELD_NONE;
-			pix_mp->height = clamp(pix_mp->height,
-						AML_VDEC_MIN_H,
-						AML_VDEC_MAX_H);
-			pix_mp->width = clamp(pix_mp->width,
-						AML_VDEC_MIN_W,
-						AML_VDEC_MAX_W);
+		/*
+		 * Find next closer width align 64, heign align 64, size align
+		 * 64 rectangle
+		 * Note: This only get default value, the real HW needed value
+		 *       only available when ctx in AML_STATE_PROBE state
+		 */
+		tmp_w = pix_fmt_mp->width;
+		tmp_h = pix_fmt_mp->height;
+		v4l_bound_align_image(&pix_fmt_mp->width,
+					AML_VDEC_MIN_W,
+					AML_VDEC_MAX_W, 6,
+					&pix_fmt_mp->height,
+					AML_VDEC_MIN_H,
+					AML_VDEC_MAX_H, 6, 9);
 
-			pix_mp->num_planes = fmt->num_planes;
+		if (pix_fmt_mp->width < tmp_w &&
+			(pix_fmt_mp->width + 64) <= AML_VDEC_MAX_W)
+			pix_fmt_mp->width += 64;
+		if (pix_fmt_mp->height < tmp_h &&
+			(pix_fmt_mp->height + 64) <= AML_VDEC_MAX_H)
+			pix_fmt_mp->height += 64;
 
-			pix_mp->plane_fmt[0].bytesperline = pix_mp->width;
-			pix_mp->plane_fmt[0].sizeimage =
-				pix_mp->width * pix_mp->height;
+		pix_fmt_mp->num_planes = fmt->num_planes;
+		pix_fmt_mp->plane_fmt[0].sizeimage =
+				pix_fmt_mp->width * pix_fmt_mp->height;
+		pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
 
-			pix_mp->plane_fmt[1].bytesperline = pix_mp->width;
-			pix_mp->plane_fmt[1].sizeimage =
-				pix_mp->width * pix_mp->height / 2;
+		if (pix_fmt_mp->num_planes == 2) {
+			pix_fmt_mp->plane_fmt[1].sizeimage =
+				(pix_fmt_mp->width * pix_fmt_mp->height) / 2;
+			pix_fmt_mp->plane_fmt[1].bytesperline =
+				pix_fmt_mp->width;
 		}
-
-		for (i = 0; i < pix_mp->num_planes; i++) {
-			memset(&(pix_mp->plane_fmt[i].reserved[0]), 0x0,
-				   sizeof(pix_mp->plane_fmt[0].reserved));
-		}
-		memset(&pix_mp->reserved, 0x0, sizeof(pix_mp->reserved));
-
-		pix_mp->flags = 0;
-	} else {
-		if (V4L2_TYPE_IS_OUTPUT(f->type)) {
-			pix->bytesperline = 0;
-			if ((pix->pixelformat != V4L2_PIX_FMT_MPEG2) &&
-			    (pix->pixelformat != V4L2_PIX_FMT_H264) &&
-			    (pix->pixelformat != V4L2_PIX_FMT_MPEG1)) {
-				pix->field = V4L2_FIELD_NONE;
-			} else if (pix->field != V4L2_FIELD_NONE) {
-				if (pix->field == V4L2_FIELD_ANY)
-					pix->field = V4L2_FIELD_NONE;
-
-				pr_info("%s, field: %u, fmt: %x\n",
-					__func__, pix->field,
-					pix->pixelformat);
-			}
-		} else {
-			if (pix->field != V4L2_FIELD_INTERLACED)
-				pix->field = V4L2_FIELD_NONE;
-
-			pix->height = clamp(pix->height,
-						AML_VDEC_MIN_H,
-						AML_VDEC_MAX_H);
-			pix->width = clamp(pix->width,
-						AML_VDEC_MIN_W,
-						AML_VDEC_MAX_W);
-
-			pix->bytesperline = pix->width;
-			pix->sizeimage = pix->width * pix->height;
-		}
-		pix->flags = 0;
 	}
 
+	for (i = 0; i < pix_fmt_mp->num_planes; i++)
+		memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0,
+			   sizeof(pix_fmt_mp->plane_fmt[0].reserved));
+
+	pix_fmt_mp->flags = 0;
+	memset(&pix_fmt_mp->reserved, 0x0, sizeof(pix_fmt_mp->reserved));
 	return 0;
 }
 
-static int vidioc_try_fmt_vid_cap_out(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct aml_q_data *q_data = NULL;
 	struct aml_video_fmt *fmt = NULL;
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
-	struct vb2_queue *dst_vq;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
-		"%s, type: %u, planes: %u, fmt: %x\n",
-		__func__, f->type,
-		V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
-		f->fmt.pix_mp.num_planes : 1,
+		"%s, type: %u, planes: %u, fmt: %u\n",
+		__func__, f->type, f->fmt.pix_mp.num_planes,
 		f->fmt.pix_mp.pixelformat);
 
-	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!dst_vq) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	fmt = aml_vdec_find_format(f);
+	if (!fmt)
 		return -EINVAL;
-	}
 
-	if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
-		return -EINVAL;
+	return vidioc_try_fmt(f, fmt);
+}
+
+static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+	struct aml_video_fmt *fmt = NULL;
+	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
+		"%s, type: %u, planes: %u, fmt: %u\n",
+		__func__, f->type, f->fmt.pix_mp.num_planes,
+		f->fmt.pix_mp.pixelformat);
 
 	fmt = aml_vdec_find_format(f);
-	if (!fmt) {
-		if (V4L2_TYPE_IS_OUTPUT(f->type))
-			f->fmt.pix.pixelformat = aml_video_formats[OUT_FMT_IDX].fourcc;
-		else
-			f->fmt.pix.pixelformat = aml_video_formats[CAP_FMT_IDX].fourcc;
-		fmt = aml_vdec_find_format(f);
-	}
-
-	vidioc_try_fmt(f, fmt);
-
-	q_data = aml_vdec_get_q_data(ctx, f->type);
-	if (!q_data)
+	if (!fmt)
 		return -EINVAL;
 
-	if (ctx->state >= AML_STATE_PROBE)
-		update_ctx_dimension(ctx, f->type);
-	copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
-
-	if (!V4L2_TYPE_IS_OUTPUT(f->type))
-		return 0;
-
-	if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
-		if (pix_mp->plane_fmt[0].sizeimage == 0) {
-			v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-				"sizeimage of output format must be given\n");
-			return -EINVAL;
-		}
-	} else {
-		if (pix->sizeimage == 0) {
-			v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-				"sizeimage of output format must be given\n");
-			return -EINVAL;
-		}
+	if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"sizeimage of output format must be given\n");
+		return -EINVAL;
 	}
 
-	return 0;
+	return vidioc_try_fmt(f, fmt);
 }
 
 static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -2502,36 +1599,29 @@
 {
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
 	struct aml_q_data *q_data;
-	int ratio = 1;
 
 	if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 		(s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
 		return -EINVAL;
 
-	if (ctx->internal_dw_scale) {
-		if (ctx->state >= AML_STATE_PROBE) {
-			unsigned int dw_mode = VDEC_DW_NO_AFBC;
-			if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
-				return -EBUSY;
-			ratio = get_double_write_ratio(dw_mode);
-		}
-	}
-
 	q_data = &ctx->q_data[AML_Q_DATA_DST];
 
 	switch (s->target) {
 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
 	case V4L2_SEL_TGT_COMPOSE:
-		s->r.left = 0;
-		s->r.top = 0;
-		s->r.width = ctx->picinfo.visible_width / ratio;
-		s->r.height = ctx->picinfo.visible_height / ratio;
+		if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
+			/* set to default value if header info not ready yet*/
+			s->r.left = 0;
+			s->r.top = 0;
+			s->r.width = q_data->visible_width;
+			s->r.height = q_data->visible_height;
+		}
 		break;
 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
 		s->r.left = 0;
 		s->r.top = 0;
-		s->r.width = ctx->picinfo.coded_width / ratio;
-		s->r.height = ctx->picinfo.coded_height / ratio;
+		s->r.width = ctx->picinfo.coded_width;
+		s->r.height = ctx->picinfo.coded_height;
 		break;
 	default:
 		return -EINVAL;
@@ -2555,7 +1645,6 @@
 	struct v4l2_selection *s)
 {
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
-	int ratio = 1;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d\n",
 		__func__, s->type);
@@ -2563,21 +1652,12 @@
 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	if (ctx->internal_dw_scale) {
-		if (ctx->state >= AML_STATE_PROBE) {
-			unsigned int dw_mode = VDEC_DW_NO_AFBC;
-			if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
-				return -EBUSY;
-			ratio = get_double_write_ratio(dw_mode);
-		}
-	}
-
 	switch (s->target) {
 	case V4L2_SEL_TGT_COMPOSE:
 		s->r.left = 0;
 		s->r.top = 0;
-		s->r.width = ctx->picinfo.visible_width / ratio;
-		s->r.height = ctx->picinfo.visible_height / ratio;
+		s->r.width = ctx->picinfo.visible_width;
+		s->r.height = ctx->picinfo.visible_height;
 		break;
 	default:
 		return -EINVAL;
@@ -2586,127 +1666,89 @@
 	return 0;
 }
 
-/* called when it is beyong AML_STATE_PROBE */
-static void update_ctx_dimension(struct aml_vcodec_ctx *ctx, u32 type)
-{
-	struct aml_q_data *q_data;
-	unsigned int dw_mode = VDEC_DW_NO_AFBC;
-	int ratio = 1;
-
-	q_data = aml_vdec_get_q_data(ctx, type);
-
-	if (ctx->internal_dw_scale) {
-		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode))
-			return;
-		ratio = get_double_write_ratio(dw_mode);
-	}
-
-	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-		q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
-		q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
-
-		q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
-		q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
-
-		q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
-		q_data->bytesperline[1] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
-	} else {
-		q_data->coded_width = ALIGN(ctx->picinfo.coded_width / ratio, 64);
-		q_data->coded_height = ALIGN(ctx->picinfo.coded_height / ratio, 64);
-		q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
-		q_data->sizeimage[0] += ctx->picinfo.c_len_sz;
-		q_data->bytesperline[0] = ALIGN(ctx->picinfo.coded_width / ratio, 64);
-	}
-}
-
 static void copy_v4l2_format_dimention(struct v4l2_pix_format_mplane *pix_mp,
-				       struct v4l2_pix_format *pix,
-				       struct aml_q_data *q_data,
-				       u32 type)
+		struct aml_q_data *q_data, u32 type)
 {
-	int i;
-
-	if (!pix || !pix_mp || !q_data)
+	if (!pix_mp || !q_data)
 		return;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
-		pix_mp->width		= q_data->coded_width;
-		pix_mp->height		= q_data->coded_height;
-		pix_mp->num_planes	= q_data->fmt->num_planes;
-		pix_mp->pixelformat	= q_data->fmt->fourcc;
-
-		for (i = 0; i < q_data->fmt->num_planes; i++) {
-			pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i];
-			pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i];
-		}
+	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		pix_mp->width = q_data->visible_width;
+		pix_mp->height = q_data->visible_height;
 	} else {
-		pix->width		= q_data->coded_width;
-		pix->height		= q_data->coded_height;
-		pix->pixelformat	= q_data->fmt->fourcc;
-		pix->bytesperline	= q_data->bytesperline[0];
-		pix->sizeimage		= q_data->sizeimage[0];
+		/*
+		 * Width and height are set to the dimensions
+		 * of the movie, the buffer is bigger and
+		 * further processing stages should crop to this
+		 * rectangle.
+		 */
+		pix_mp->width = q_data->coded_width;
+		pix_mp->height = q_data->coded_height;
+	}
+
+	/*
+	 * Set pixelformat to the format in which mt vcodec
+	 * outputs the decoded frame
+	 */
+	pix_mp->num_planes = q_data->fmt->num_planes;
+	pix_mp->pixelformat = q_data->fmt->fourcc;
+	pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
+	pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
+	if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
+		pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
 	}
 }
 
 static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 	struct v4l2_format *f)
 {
-	int ret = 0;
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(priv);
-	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
-	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct aml_q_data *q_data = NULL;
+	struct v4l2_pix_format_mplane *pix_mp;
+	struct aml_q_data *q_data;
+	int ret = 0;
 	struct aml_video_fmt *fmt;
-	struct vb2_queue *dst_vq;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
-		"%s, type: %u, planes: %u, fmt: %x\n",
-		__func__, f->type,
-		V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
-		f->fmt.pix_mp.num_planes : 1,
+		"%s, type: %u, planes: %u, fmt: %u\n",
+		__func__, f->type, f->fmt.pix_mp.num_planes,
 		f->fmt.pix_mp.pixelformat);
 
-	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!dst_vq) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		return -EINVAL;
-	}
-
-	if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
-		return -EINVAL;
-
 	q_data = aml_vdec_get_q_data(ctx, f->type);
 	if (!q_data)
 		return -EINVAL;
 
+	pix_mp = &f->fmt.pix_mp;
 	if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
 	    vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"out_q_ctx buffers already requested\n");
-		ret = -EBUSY;
 	}
 
 	if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
 	    vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"cap_q_ctx buffers already requested\n");
-		ret = -EBUSY;
 	}
 
 	fmt = aml_vdec_find_format(f);
 	if (fmt == NULL) {
-		if (V4L2_TYPE_IS_OUTPUT(f->type))
-			fmt = &aml_video_formats[OUT_FMT_IDX];
-		else
-			fmt = &aml_video_formats[CAP_FMT_IDX];
-		f->fmt.pix.pixelformat = fmt->fourcc;
+		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+			f->fmt.pix.pixelformat =
+				aml_video_formats[OUT_FMT_IDX].fourcc;
+			fmt = aml_vdec_find_format(f);
+		} else if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
+			f->fmt.pix.pixelformat =
+				aml_video_formats[CAP_FMT_IDX].fourcc;
+			fmt = aml_vdec_find_format(f);
+		}
 	}
 
 	q_data->fmt = fmt;
 	vidioc_try_fmt(f, q_data->fmt);
-
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		if (ctx->is_drm_mode)
+			pix_mp->plane_fmt[0].sizeimage = 1;
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
 		q_data->coded_width = pix_mp->width;
 		q_data->coded_height = pix_mp->height;
@@ -2716,7 +1758,6 @@
 			pix_mp->width, pix_mp->height,
 			pix_mp->plane_fmt[0].sizeimage);
 
-		ctx->output_pix_fmt = pix_mp->pixelformat;
 		ctx->colorspace = f->fmt.pix_mp.colorspace;
 		ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
 		ctx->quantization = f->fmt.pix_mp.quantization;
@@ -2732,38 +1773,7 @@
 				return -EINVAL;
 			}
 			ctx->state = AML_STATE_INIT;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
-				"vcodec state (AML_STATE_INIT)\n");
-		}
-		mutex_unlock(&ctx->state_lock);
-	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		q_data->sizeimage[0] = pix->sizeimage;
-		q_data->coded_width = pix->width;
-		q_data->coded_height = pix->height;
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-			"w: %d, h: %d, size: %d\n",
-			pix->width, pix->height,
-			pix->sizeimage);
-
-		ctx->output_pix_fmt = pix->pixelformat;
-		ctx->colorspace = f->fmt.pix.colorspace;
-		ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
-		ctx->quantization = f->fmt.pix.quantization;
-		ctx->xfer_func = f->fmt.pix.xfer_func;
-
-		mutex_lock(&ctx->state_lock);
-		if (ctx->state == AML_STATE_IDLE) {
-			ret = vdec_if_init(ctx, q_data->fmt->fourcc);
-			if (ret) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"vdec_if_init() fail ret=%d\n", ret);
-				mutex_unlock(&ctx->state_lock);
-				return -EINVAL;
-			}
-			ctx->state = AML_STATE_INIT;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+			ATRACE_COUNTER("v4l2_state", ctx->state);
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 				"vcodec state (AML_STATE_INIT)\n");
 		}
@@ -2771,13 +1781,9 @@
 	}
 
 	if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
-		ctx->cap_pix_fmt = V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
-			pix_mp->pixelformat : pix->pixelformat;
-		if (ctx->state >= AML_STATE_PROBE) {
-			update_ctx_dimension(ctx, f->type);
-			copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
-			v4l_buf_size_decision(ctx);
-		}
+		ctx->cap_pix_fmt = pix_mp->pixelformat;
+		if (ctx->state >= AML_STATE_PROBE)
+			copy_v4l2_format_dimention(pix_mp, q_data, f->type);
 	}
 
 	return 0;
@@ -2827,31 +1833,16 @@
 static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
 {
 	struct aml_video_fmt *fmt;
-	int i = 0, j = 0;
+	int i, j = 0;
 
-	/* I420 only used for mjpeg. */
-	if (!output_queue && support_mjpeg && support_format_I420) {
-		for (i = 0; i < NUM_FORMATS; i++) {
-			fmt = &aml_video_formats[i];
-			if ((fmt->fourcc == V4L2_PIX_FMT_YUV420) ||
-				(fmt->fourcc == V4L2_PIX_FMT_YUV420M)) {
-				break;
-			}
-		}
-	}
-
-	for (; i < NUM_FORMATS; i++) {
-		fmt = &aml_video_formats[i];
-		if (output_queue && (fmt->type != AML_FMT_DEC))
+	for (i = 0; i < NUM_FORMATS; i++) {
+		if (output_queue && (aml_video_formats[i].type != AML_FMT_DEC))
 			continue;
-		if (!output_queue && (fmt->type != AML_FMT_FRAME))
-			continue;
-		if (support_mjpeg && !support_format_I420 &&
-			((fmt->fourcc == V4L2_PIX_FMT_YUV420) ||
-			(fmt->fourcc == V4L2_PIX_FMT_YUV420M)))
+		if (!output_queue && (aml_video_formats[i].type != AML_FMT_FRAME))
 			continue;
 
 		if (j == f->index) {
+			fmt = &aml_video_formats[i];
 			f->pixelformat = fmt->fourcc;
 			return 0;
 		}
@@ -2888,7 +1879,6 @@
 	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct vb2_queue *vq;
-	struct vb2_queue *dst_vq;
 	struct aml_q_data *q_data;
 	int ret = 0;
 
@@ -2899,29 +1889,12 @@
 		return -EINVAL;
 	}
 
-	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!dst_vq) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		return -EINVAL;
-	}
-
-	if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && dst_vq->is_multiplanar)
-		return -EINVAL;
-
 	q_data = aml_vdec_get_q_data(ctx, f->type);
 
 	ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
 	if (ret) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"GET_PARAM_PICTURE_INFO err\n");
-	} else {
-		if ((ctx->picinfo.visible_height < 16 && ctx->picinfo.visible_height > 0) ||
-			(ctx->picinfo.visible_width < 16 && ctx->picinfo.visible_width > 0)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"The width or height of the stream is less than 16\n");
-			return -EPERM;
-		}
 	}
 
 	if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
@@ -2940,8 +1913,24 @@
 
 	if ((!V4L2_TYPE_IS_OUTPUT(f->type)) &&
 	    (ctx->state >= AML_STATE_PROBE)) {
-		update_ctx_dimension(ctx, f->type);
-		copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+		/* Until STREAMOFF is called on the CAPTURE queue
+		 * (acknowledging the event), the driver operates as if
+		 * the resolution hasn't changed yet.
+		 * So we just return picinfo yet, and update picinfo in
+		 * stop_streaming hook function
+		 */
+		/* it is used for alloc the decode buffer size. */
+		q_data->sizeimage[0] = ctx->picinfo.y_len_sz;
+		q_data->sizeimage[1] = ctx->picinfo.c_len_sz;
+
+		/* it is used for alloc the EGL image buffer size. */
+		q_data->coded_width = ctx->picinfo.coded_width;
+		q_data->coded_height = ctx->picinfo.coded_height;
+
+		q_data->bytesperline[0] = ctx->picinfo.coded_width;
+		q_data->bytesperline[1] = ctx->picinfo.coded_width;
+
+		copy_v4l2_format_dimention(pix_mp, q_data, f->type);
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		/*
 		 * This is run on OUTPUT
@@ -2949,21 +1938,20 @@
 		 * so width and height have no meaning.
 		 * Assign value here to pass v4l2-compliance test
 		 */
-		copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+		copy_v4l2_format_dimention(pix_mp, q_data, f->type);
 	} else {
-		copy_v4l2_format_dimention(pix_mp, pix, q_data, f->type);
+		copy_v4l2_format_dimention(pix_mp, q_data, f->type);
 
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
 			"type=%d state=%d Format information could not be read, not ready yet!\n",
 			f->type, ctx->state);
+		return -EINVAL;
 	}
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
-		"%s, type: %u, planes: %u, fmt: %x\n",
-		__func__, f->type,
-		V4L2_TYPE_IS_MULTIPLANAR(f->type) ?
-		q_data->fmt->num_planes : 1,
-		q_data->fmt->fourcc);
+		"%s, type: %u, planes: %u, fmt: %u\n",
+		__func__, f->type, f->fmt.pix_mp.num_planes,
+		f->fmt.pix_mp.pixelformat);
 
 	return 0;
 }
@@ -3019,32 +2007,21 @@
 		for (i = 0; i < *nplanes; i++) {
 			if (sizes[i] < q_data->sizeimage[i])
 				return -EINVAL;
-			alloc_devs[i] = &ctx->dev->plat_dev->dev;
-
-			if (!V4L2_TYPE_IS_OUTPUT(vq->type))
-				alloc_devs[i] = v4l_get_dev_from_codec_mm();
+			//alloc_devs[i] = &ctx->dev->plat_dev->dev;
+			alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
 		}
 	} else {
-		int dw_mode = VDEC_DW_NO_AFBC;
-
 		if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 			*nplanes = 2;
 		else
 			*nplanes = 1;
 
-		if (!vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-			if (dw_mode == VDEC_DW_AFBC_ONLY)
-				*nplanes = 1;
-		}
-
 		for (i = 0; i < *nplanes; i++) {
 			sizes[i] = q_data->sizeimage[i];
 			if (V4L2_TYPE_IS_OUTPUT(vq->type) && ctx->output_dma_mode)
-				sizes[i] = 1;
-			alloc_devs[i] = &ctx->dev->plat_dev->dev;
-
-			if (!V4L2_TYPE_IS_OUTPUT(vq->type))
-				alloc_devs[i] = v4l_get_dev_from_codec_mm();
+				sizes[i] = 0;
+			//alloc_devs[i] = &ctx->dev->plat_dev->dev;
+			alloc_devs[i] = v4l_get_dev_from_codec_mm();//alloc mm from the codec mm
 		}
 	}
 
@@ -3059,8 +2036,6 @@
 {
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct aml_q_data *q_data;
-	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
-	struct aml_video_dec_buf *buf = NULL;
 	int i;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
@@ -3082,710 +2057,65 @@
 		}
 	}
 
-	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
-	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-
-	if (vb2_v4l2->meta_ptr && (copy_from_user(buf->meta_data,
-		(void *)vb2_v4l2->meta_ptr, META_DATA_SIZE + 4))) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"%s:copy meta data error. ptr: %lx\n", __func__, vb2_v4l2->meta_ptr);
-	}
-
 	return 0;
 }
 
-static int init_mmu_bmmu_box(struct aml_vcodec_ctx *ctx)
-{
-	int i;
-	int mmu_flag = ctx->is_drm_mode? CODEC_MM_FLAGS_TVP:0;
-	int bmmu_flag = mmu_flag;
-	u32 dw_mode = VDEC_DW_NO_AFBC;
-
-	ctx->comp_bufs = vzalloc(sizeof(*ctx->comp_bufs) * V4L_CAP_BUFF_MAX);
-	if (!ctx->comp_bufs)
-		return -ENOMEM;
-
-	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
-		goto free_comp_bufs;
-	}
-
-	/* init mmu box */
-	ctx->mmu_box = decoder_mmu_box_alloc_box("v4l2_dec",
-			ctx->id, V4L_CAP_BUFF_MAX,
-			ctx->comp_info.max_size * SZ_1M, mmu_flag);
-	if (!ctx->mmu_box) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box\n");
-		goto free_comp_bufs;
-	}
-
-	/* init bmmu box */
-	bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
-	ctx->bmmu_box  = decoder_bmmu_box_alloc_box("v4l2_dec",
-			ctx->id, V4L_CAP_BUFF_MAX,
-			4 + PAGE_SHIFT, bmmu_flag);
-	if (!ctx->bmmu_box) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box\n");
-		goto free_mmubox;
-	}
-
-	if (dw_mode & 0x20) {
-		/* init mmu box dw*/
-		ctx->mmu_box_dw = decoder_mmu_box_alloc_box("v4l2_dec",
-				ctx->id, V4L_CAP_BUFF_MAX,
-				ctx->comp_info.max_size * SZ_1M, mmu_flag);
-		if (!ctx->mmu_box_dw) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create mmu box dw\n");
-			goto free_bmmubox;
-		}
-
-		/* init bmmu box dw*/
-		bmmu_flag |= CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER;
-		ctx->bmmu_box_dw  = decoder_bmmu_box_alloc_box("v4l2_dec",
-				ctx->id, V4L_CAP_BUFF_MAX,
-				4 + PAGE_SHIFT, bmmu_flag);
-		if (!ctx->bmmu_box_dw) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to create bmmu box dw\n");
-			goto free_mmubox_dw;
-		}
-	}
-
-	kref_init(&ctx->box_ref);
-	for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-		struct internal_comp_buf *buf;
-		buf = &ctx->comp_bufs[i];
-		buf->index = i;
-		buf->ref = 0;
-		buf->box_ref = &ctx->box_ref;
-		buf->mmu_box = ctx->mmu_box;
-		buf->bmmu_box = ctx->bmmu_box;
-		buf->mmu_box_dw = ctx->mmu_box_dw;
-		buf->bmmu_box_dw = ctx->bmmu_box_dw;
-	}
-	kref_get(&ctx->ctx_ref);
-
-	ctx->uvm_proxy = vzalloc(sizeof(*ctx->uvm_proxy) * V4L_CAP_BUFF_MAX);
-	if (!ctx->uvm_proxy)
-		goto free_mmubox;
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"box init, bmmu: %px, mmu: %px, mmu_dw: %px bmmu_dw: %px\n",
-		ctx->bmmu_box, ctx->mmu_box, ctx->mmu_box_dw, ctx->bmmu_box_dw);
-
-	return 0;
-free_mmubox_dw:
-	decoder_mmu_box_free(ctx->mmu_box_dw);
-	ctx->mmu_box_dw = NULL;
-
-free_bmmubox:
-	decoder_bmmu_box_free(ctx->bmmu_box);
-	ctx->bmmu_box = NULL;
-
-free_mmubox:
-	decoder_mmu_box_free(ctx->mmu_box);
-	ctx->mmu_box = NULL;
-
-free_comp_bufs:
-	vfree(ctx->comp_bufs);
-	ctx->comp_bufs = NULL;
-
-	return -1;
-}
-
-void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag)
-{
-	int i = 0;
-
-	if (flag & DV_TYPE) {
-		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-			ctx->aux_infos.bufs[i].md_buf = vzalloc(MD_BUF_SIZE);
-			if (ctx->aux_infos.bufs[i].md_buf == NULL) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"v4l2 alloc %dth dv md buffer fail\n", i);
-			}
-
-			ctx->aux_infos.bufs[i].comp_buf = vzalloc(COMP_BUF_SIZE);
-			if (ctx->aux_infos.bufs[i].comp_buf == NULL) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"v4l2 alloc %dth dv comp buffer fail\n", i);
-			}
-		}
-	}
-
-	if (flag & SEI_TYPE) {
-		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-			ctx->aux_infos.bufs[i].sei_buf = vzalloc(SEI_BUF_SIZE);
-			if (ctx->aux_infos.bufs[i].sei_buf) {
-				ctx->aux_infos.bufs[i].sei_size  = 0;
-				ctx->aux_infos.bufs[i].sei_state = 1;
-				ctx->aux_infos.sei_need_free = false;
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-					"v4l2 alloc %dth aux buffer:%px\n",
-					i, ctx->aux_infos.bufs[i].sei_buf);
-			} else {
-				ctx->aux_infos.bufs[i].sei_buf = NULL;
-				ctx->aux_infos.bufs[i].sei_state = 0;
-				ctx->aux_infos.bufs[i].sei_size  = 0;
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"v4l2 alloc %dth aux buffer fail\n", i);
-			}
-		}
-	}
-}
-
-void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag)
-{
-	int i = 0;
-
-	if (flag & DV_TYPE) {
-		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-			if (ctx->aux_infos.bufs[i].md_buf != NULL) {
-				vfree(ctx->aux_infos.bufs[i].md_buf);
-				ctx->aux_infos.bufs[i].md_buf = NULL;
-			}
-
-			if (ctx->aux_infos.bufs[i].comp_buf != NULL) {
-				vfree(ctx->aux_infos.bufs[i].comp_buf);
-				ctx->aux_infos.bufs[i].comp_buf = NULL;
-			}
-		}
-	}
-
-	if (flag & SEI_TYPE) {
-		for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-			if (ctx->aux_infos.bufs[i].sei_buf != NULL) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-					"v4l2 free %dth aux buffer:%px\n",
-					i, ctx->aux_infos.bufs[i].sei_buf);
-				vfree(ctx->aux_infos.bufs[i].sei_buf);
-				ctx->aux_infos.bufs[i].sei_state = 0;
-				ctx->aux_infos.bufs[i].sei_size = 0;
-				ctx->aux_infos.bufs[i].sei_buf = NULL;
-			}
-		}
-	}
-}
-
-void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx)
-{
-	if (ctx->aux_infos.bufs[idx].sei_buf != NULL) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-			"v4l2 free %dth aux buffer:%px\n",
-			idx, ctx->aux_infos.bufs[idx].sei_buf);
-
-		vfree(ctx->aux_infos.bufs[idx].sei_buf);
-		ctx->aux_infos.bufs[idx].sei_state = 0;
-		ctx->aux_infos.bufs[idx].sei_size = 0;
-		ctx->aux_infos.bufs[idx].sei_buf = NULL;
-		*addr = NULL;
-		*size = 0;
-		ctx->aux_infos.sei_need_free = true;
-	}
-}
-
-void aml_bind_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx)
-{
-	int index = ctx->aux_infos.sei_index;
-	int count = 0;
-
-	if (ctx->aux_infos.sei_need_free) {
-		for (count = 0; count < V4L_CAP_BUFF_MAX; count++) {
-			if ((ctx->aux_infos.bufs[index].sei_buf != NULL) &&
-				(ctx->aux_infos.bufs[index].sei_state == 1)) {
-				break;
-			}
-			index = (index + 1) % V4L_CAP_BUFF_MAX;
-		}
-	} else {
-		for (count = 0; count < V4L_CAP_BUFF_MAX; count++) {
-			if ((ctx->aux_infos.bufs[index].sei_buf != NULL) &&
-				((ctx->aux_infos.bufs[index].sei_state == 1) ||
-				(ctx->aux_infos.bufs[index].sei_state == 2))) {
-				memset(ctx->aux_infos.bufs[index].sei_buf, 0, SEI_BUF_SIZE);
-				ctx->aux_infos.bufs[index].sei_size = 0;
-				break;
-			}
-			index = (index + 1) % V4L_CAP_BUFF_MAX;
-		}
-	}
-
-	if (count == V4L_CAP_BUFF_MAX) {
-		*addr = NULL;
-		*size = 0;
-	} else {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-			"v4l2 bind %dth aux buffer:%px, count = %d\n",
-			index, ctx->aux_infos.bufs[index].sei_buf, count);
-		*addr = ctx->aux_infos.bufs[index].sei_buf;
-		*size = ctx->aux_infos.bufs[index].sei_size;
-		*idx  = index;
-		ctx->aux_infos.bufs[index].sei_state = 2;
-		ctx->aux_infos.sei_index = (index + 1) % V4L_CAP_BUFF_MAX;
-	}
-}
-
-void aml_bind_dv_buffer(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf)
-{
-	int index = ctx->aux_infos.dv_index;
-
-	if ((ctx->aux_infos.bufs[index].comp_buf != NULL) &&
-		(ctx->aux_infos.bufs[index].md_buf != NULL)) {
-		*comp_buf = ctx->aux_infos.bufs[index].comp_buf;
-		*md_buf = ctx->aux_infos.bufs[index].md_buf;
-		ctx->aux_infos.dv_index = (index + 1) % V4L_CAP_BUFF_MAX;
-	}
-}
-
-void aml_v4l_ctx_release(struct kref *kref)
-{
-	struct aml_vcodec_ctx * ctx;
-
-	ctx = container_of(kref, struct aml_vcodec_ctx, ctx_ref);
-
-	if (ctx->vpp) {
-		atomic_dec(&ctx->dev->vpp_count);
-		aml_v4l2_vpp_destroy(ctx->vpp);
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"vpp destory inst count:%d.\n",
-			atomic_read(&ctx->dev->vpp_count));
-	}
-
-	if (ctx->ge2d) {
-		aml_v4l2_ge2d_destroy(ctx->ge2d);
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"ge2d destory.\n");
-	}
-
-	v4l2_m2m_ctx_release(ctx->m2m_ctx);
-	aml_task_chain_remove(ctx);
-
-	vfree(ctx->meta_infos.meta_bufs);
-	ctx->aux_infos.free_buffer(ctx, SEI_TYPE | DV_TYPE);
-	ctx->aux_infos.free_buffer(ctx, 1);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"v4ldec has been destroyed.\n");
-
-	if (ctx->sync) {
-		vdec_clean_all_fence(ctx->sync);
-	}
-
-	kfree(ctx);
-}
-
-static void box_release(struct kref *kref)
-{
-	struct aml_vcodec_ctx * ctx
-		= container_of(kref, struct aml_vcodec_ctx, box_ref);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, bmmu: %px, mmu: %px mmu_dw: %pu\n",
-		__func__, ctx->bmmu_box, ctx->mmu_box,ctx->mmu_box_dw);
-
-	decoder_bmmu_box_free(ctx->bmmu_box);
-	decoder_mmu_box_free(ctx->mmu_box);
-
-	if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
-		decoder_mmu_box_free(ctx->mmu_box_dw);
-		decoder_bmmu_box_free(ctx->bmmu_box_dw);
-	}
-	vfree(ctx->comp_bufs);
-	vfree(ctx->uvm_proxy);
-	kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
-}
-
-static void internal_buf_free(void *arg)
-{
-	struct internal_comp_buf* ibuf =
-		(struct internal_comp_buf*)arg;
-	struct aml_vcodec_ctx * ctx
-		= container_of(ibuf->box_ref,struct aml_vcodec_ctx, box_ref);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, idx:%d\n", __func__, ibuf->index);
-
-	mutex_lock(&ctx->comp_lock);
-
-	if (!(ibuf->ref & 0xff00)) {
-		decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
-		decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
-		if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
-			decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
-			decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
-		}
-	}
-	ibuf->ref = 0;
-
-	mutex_unlock(&ctx->comp_lock);
-
-	kref_put(ibuf->box_ref, box_release);
-}
-
-static void internal_buf_free2(void *arg)
-{
-	struct internal_comp_buf *ibuf =
-		container_of(arg, struct internal_comp_buf, priv_data);
-	struct aml_vcodec_ctx * ctx
-		= container_of(ibuf->box_ref, struct aml_vcodec_ctx, box_ref);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, idx: %d\n", __func__, ibuf->index);
-
-	mutex_lock(&ctx->comp_lock);
-
-	if (!(ibuf->ref & 0xff00)) {
-		decoder_mmu_box_free_idx(ibuf->mmu_box, ibuf->index);
-		decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-
-		if (ctx->config.parm.dec.cfg.double_write_mode & 0x20) {
-			decoder_mmu_box_free_idx(ibuf->mmu_box_dw, ibuf->index);
-			decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
-		}
-	}
-	ibuf->ref = 0;
-
-	mutex_unlock(&ctx->comp_lock);
-
-	kref_put(ibuf->box_ref, box_release);
-}
-
-static void aml_uvm_buf_free(void *arg)
-{
-	struct aml_uvm_buff_ref * ubuf =
-		(struct aml_uvm_buff_ref*)arg;
-	struct aml_vcodec_ctx * ctx
-		= container_of(ubuf->ref, struct aml_vcodec_ctx, ctx_ref);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, vb:%d, dbuf:%px, ino:%lu\n",
-		__func__, ubuf->index, ubuf->dbuf,
-		file_inode(ubuf->dbuf->file)->i_ino);
-
-	kref_put(ubuf->ref, aml_v4l_ctx_release);
-	vfree(ubuf);
-}
-
-static int uvm_attach_hook_mod_local(struct aml_vcodec_ctx *ctx,
-				     struct uvm_hook_mod_info *uvm)
-{
-	struct internal_comp_buf* ibuf = uvm->arg;
-
-	ctx->uvm_proxy[ibuf->index] = *uvm;
-
-	return 0;
-}
-
-static int update_comp_buffer_to_reuse(struct aml_vcodec_ctx *ctx,
-				       struct aml_video_dec_buf *buf)
-{
-	struct internal_comp_buf* ibuf = NULL;
-
-	mutex_lock(&ctx->comp_lock);
-
-	ibuf = vb_to_comp(ctx, &buf->vb.vb2_buf);
-	if (!ibuf) {
-		mutex_unlock(&ctx->comp_lock);
-		return 0;
-	}
-
-	if (ibuf->ref & 0xff) {
-		buf->internal_index = ibuf->index;
-		ibuf->frame_buffer_size = ctx->comp_info.frame_buffer_size;
-
-		if (ctx->comp_info.header_size != ibuf->header_size) {
-			decoder_bmmu_box_free_idx(ctx->bmmu_box, ibuf->index);
-			if (decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
-				ibuf->index, ctx->comp_info.header_size,
-				"v4l2_dec", &ibuf->header_addr) < 0) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-					"fail to alloc %dth bmmu\n",
-					ibuf->index);
-				mutex_unlock(&ctx->comp_lock);
-				return -ENOMEM;
-			}
-			ibuf->header_size = ctx->comp_info.header_size;
-		}
-
-		ibuf->ref |= (1 << 8);
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-			"%s, reuse comp buffer vb2:%d <--> internal: %d, header_addr 0x%lx, size: %u\n",
-			__func__, buf->vb.vb2_buf.index,
-			buf->internal_index,
-			ibuf->header_addr,
-			ibuf->header_size);
-	}
-
-	mutex_unlock(&ctx->comp_lock);
-
-	return (ibuf->ref & 0xff00) ? 1 : 0;
-}
-
-static int bind_comp_buffer_to_uvm(struct aml_vcodec_ctx *ctx,
-		struct aml_video_dec_buf *buf)
-{
-	int ret, i;
-	struct dma_buf * dma = buf->vb.vb2_buf.planes[0].dbuf;
-	struct aml_dec_params *parms = &ctx->config.parm.dec;
-	struct uvm_hook_mod_info u_info;
-	struct internal_comp_buf* ibuf;
-	u32 dw_mode = VDEC_DW_NO_AFBC;
-
-	/* get header and page size */
-	if (vdec_if_get_param(ctx, GET_PARAM_COMP_BUF_INFO, &ctx->comp_info)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to get comp info\n");
-		return -EINVAL;
-	}
-
-	if (!ctx->bmmu_box || !ctx->mmu_box)
-		if (init_mmu_bmmu_box(ctx))
-			return -EINVAL;
-
-	ret = update_comp_buffer_to_reuse(ctx, buf);
-	if (ret < 0)
-		return ret;
-
-	if (ret == 1 /*reused*/)
-		return 0;
-
-	for (i = 0; i < V4L_CAP_BUFF_MAX; i++) {
-		if (!ctx->comp_bufs[i].ref)
-			break;
-	}
-
-	if (i == V4L_CAP_BUFF_MAX) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "out of internal buf\n");
-		return -EINVAL;
-	}
-
-	if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
-		return -EINVAL;
-	}
-
-	buf->internal_index	= i;
-	ibuf			= &ctx->comp_bufs[i];
-	ibuf->frame_buffer_size	= ctx->comp_info.frame_buffer_size;
-	ibuf->header_size	= ctx->comp_info.header_size;
-
-	/* allocate header */
-	ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box,
-			ibuf->index, ctx->comp_info.header_size,
-			"v4l2_dec", &ibuf->header_addr);
-	if (ret < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu\n", i);
-		return -ENOMEM;
-	}
-
-	if (dw_mode & 0x20) {
-		ret = decoder_bmmu_box_alloc_buf_phy(ctx->bmmu_box_dw,
-			ibuf->index, ctx->comp_info.header_size,
-			"v4l2_dec", &ibuf->header_dw_addr);
-		if (ret < 0) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to alloc %dth bmmu dw\n", i);
-			return -ENOMEM;
-		}
-	}
-
-	kref_get(&ctx->box_ref);
-	ibuf->ref = 1;
-
-	/* frame SG buffer need to be realloc inside decoder,
-	 * just before slice decoding to save memory
-	 */
-	u_info.type = VF_SRC_DECODER;
-	u_info.arg = ibuf;
-	u_info.free = internal_buf_free;
-
-	if (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO) {
-		/* adapted video composer to use for hwc. */
-		ibuf->priv_data.v4l_inst_id = ctx->id;
-		u_info.type = VF_PROCESS_V4LVIDEO;
-		u_info.arg = &ibuf->priv_data;
-		u_info.free = internal_buf_free2;
-	}
-
-	ret = dmabuf_is_uvm(dma) ?
-		uvm_attach_hook_mod(dma, &u_info) :
-		uvm_attach_hook_mod_local(ctx, &u_info);
-	if (ret < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to set dmabuf priv buf\n");
-		goto bmmu_box_free;
-	}
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, bind vb2:(%d, %px) <--> internal: (%d, %px) header_addr 0x%lx, size: %u\n",
-		__func__, buf->vb.vb2_buf.index,
-		dma, i, ibuf, ibuf->header_addr,
-		ctx->comp_info.header_size);
-
-	return 0;
-
-bmmu_box_free:
-	if (dw_mode & 0x20) {
-		decoder_bmmu_box_free_idx(ibuf->bmmu_box_dw, ibuf->index);
-	}
-	decoder_bmmu_box_free_idx(ibuf->bmmu_box, ibuf->index);
-	kref_put(&ctx->box_ref, box_release);
-	ibuf->ref = 0;
-	return -EINVAL;
-}
-
-static int aml_uvm_buff_attach(struct vb2_buffer * vb)
-{
-	int ret = 0;
-	struct dma_buf *dbuf = vb->planes[0].dbuf;
-	struct uvm_hook_mod_info u_info;
-	struct aml_vcodec_ctx *ctx =
-		vb2_get_drv_priv(vb->vb2_queue);
-	struct aml_uvm_buff_ref *ubuf = NULL;
-
-	if (vb->memory != VB2_MEMORY_DMABUF || !dmabuf_is_uvm(dbuf))
-		return 0;
-
-	ubuf = vzalloc(sizeof(struct aml_uvm_buff_ref));
-	if (ubuf == NULL)
-		return -ENOMEM;
-
-	ubuf->index	= vb->index;
-	ubuf->addr	= vb2_dma_contig_plane_dma_addr(vb, 0);
-	ubuf->dbuf	= dbuf;
-	ubuf->ref	= &ctx->ctx_ref;
-
-	u_info.type	= VF_PROCESS_DECODER;
-	u_info.arg	= (void *)ubuf;
-	u_info.free	= aml_uvm_buf_free;
-	ret = uvm_attach_hook_mod(dbuf, &u_info);
-	if (ret < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"aml uvm buffer %d attach fail.\n",
-			ubuf->index);
-		return ret;
-	}
-
-	kref_get(ubuf->ref);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"%s, vb:%d, dbuf:%px, ino:%lu\n",
-		__func__, ubuf->index, ubuf->dbuf,
-		file_inode(ubuf->dbuf->file)->i_ino);
-
-	return ret;
-}
-
-static struct internal_comp_buf* vb_to_comp(struct aml_vcodec_ctx *ctx,
-					    struct vb2_buffer *vb)
-{
-	struct aml_dec_params *parms = &ctx->config.parm.dec;
-	bool is_v4lvideo = (parms->cfg.uvm_hook_type == VF_PROCESS_V4LVIDEO);
-	enum uvm_hook_mod_type u_type =
-		is_v4lvideo ? VF_PROCESS_V4LVIDEO : VF_SRC_DECODER;
-	struct dma_buf *dbuf = vb->planes[0].dbuf;
-	struct internal_comp_buf *ibuf = NULL;
-	struct uvm_hook_mod *uhmod = NULL;
-
-	uhmod = uvm_get_hook_mod(dbuf, u_type);
-	if (IS_ERR_OR_NULL(uhmod))
-		return NULL;
-
-	ibuf = !is_v4lvideo ? (struct internal_comp_buf *) uhmod->arg :
-		container_of(uhmod->arg, struct internal_comp_buf, priv_data);
-
-	uvm_put_hook_mod(dbuf, u_type);
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"%s, vb2: (%d, %px) --> comp: (%d, %px)\n",
-		__func__, vb->index, dbuf, ibuf->index, ibuf);
-
-	return ibuf;
-}
-
 static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
 {
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
-	struct aml_video_dec_buf *buf =
-		container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-	struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
+	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+	struct aml_video_dec_buf *buf = NULL;
 	struct aml_vcodec_mem src_mem;
+	unsigned int dpb = 0;
+
+	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, vb: %lx, type: %d, idx: %d, state: %d, used: %d, ts: %llu\n",
 		__func__, (ulong) vb, vb->vb2_queue->type,
 		vb->index, vb->state, buf->used, vb->timestamp);
-
 	/*
 	 * check if this buffer is ready to be used after decode
 	 */
 	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
-		u32 dw_mode = VDEC_DW_NO_AFBC;
-
-		if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
+		if (vb->index >= ctx->dpb_size) {
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"enque capture buf idx %d/%d is invalid.\n",
+				vb->index, ctx->dpb_size);
 			return;
-
 		}
 
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
+			"y_addr: %lx, vf_h: %lx, state: %d",
+			buf->frame_buffer.m.mem[0].addr,
+			buf->frame_buffer.vf_handle,
+			buf->frame_buffer.status);
+
 		if (!buf->que_in_m2m) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
 				"enque capture buf idx %d, vf: %lx\n",
 				vb->index, (ulong) v4l_get_vf_handle(vb2_v4l2->private));
 
-			/* bind compressed buffer to uvm */
-			if ((dw_mode != VDEC_DW_NO_AFBC) &&
-				vb->memory == VB2_MEMORY_DMABUF &&
-				bind_comp_buffer_to_uvm(ctx, buf)) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "fail to bind comp buffer\n");
-				return;
-			}
-
-			/* DI hook must be detached if the dmabuff be reused. */
-			if (ctx->vpp_cfg.enable_local_buf) {
-				struct dma_buf *dma = vb->planes[0].dbuf;
-
-				if (dmabuf_is_uvm(dma) &&
-					uvm_detach_hook_mod(dma, VF_PROCESS_DI) < 0) {
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-						"dmabuf without attach DI hook.\n");
-				}
-			}
-
-			task_chain_clean(fb->task);
-
-			ctx->cap_pool.seq[ctx->cap_pool.in++] =
-				(V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
 			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
 			buf->que_in_m2m = true;
-
-			fb->status = FB_ST_INIT;
-			ATRACE_COUNTER("VC_IN_VSINK-2.storage", vb->index);
+			buf->queued_in_vb2 = true;
+			buf->queued_in_v4l2 = true;
+			buf->ready_to_display = false;
+			ctx->cap_pool.seq[ctx->cap_pool.in++] =
+				(V4L_CAP_BUFF_IN_M2M << 16 | vb->index);
 
 			/* check dpb ready */
 			aml_check_dpb_ready(ctx);
-		} else {
-			struct vframe_s *vf = fb->vframe;
-			struct task_chain_s *task = fb->task;
+		} else if (buf->frame_buffer.status == FB_ST_DISPLAY) {
+			buf->queued_in_vb2 = false;
+			buf->queued_in_v4l2 = true;
+			buf->ready_to_display = false;
 
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
-				"IN__BUFF (%s, st:%d, seq:%d) vb:(%d, %px), vf:(%d, %px), ts:%lld, "
-				"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
-				ctx->ada_ctx->frm_name, fb->status, vf ? vf->index_disp : -1,
-				vb->index, vb,
-				vf ? vf->index & 0xff : -1, vf,
-				vf ? vf->timestamp : 0,
-				fb->m.mem[0].addr, fb->m.mem[0].size,
-				fb->m.mem[1].addr, fb->m.mem[1].size,
-				fb->m.mem[2].addr, fb->m.mem[2].size);
-
-			ATRACE_COUNTER("VC_IN_VSINK-4.recycle", vb->index);
-
-			task->recycle(task, TASK_TYPE_V4L_SINK);
+			/* recycle vf */
+			video_vf_put(ctx->ada_ctx->recv_name,
+				&buf->frame_buffer, ctx->id);
 		}
-
-		wake_up_interruptible(&ctx->cap_wq);
 		return;
 	}
 
@@ -3795,41 +2125,28 @@
 		return;
 	}
 
-	buf->used = true;
 	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
 	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
 	if (buf->lastframe) {
 		/* This shouldn't happen. Just in case. */
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"Invalid flush buffer.\n");
-		buf->used = false;
 		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-		if (ctx->is_drm_mode && (vb->memory == VB2_MEMORY_DMABUF))
-			wake_up_interruptible(&ctx->wq);
-
 		return;
 	}
 
 	src_mem.index	= vb->index;
 	src_mem.vaddr	= vb2_plane_vaddr(vb, 0);
-	src_mem.addr	= sg_dma_address(buf->out_sgt->sgl);
+	src_mem.addr	= vb2_dma_contig_plane_dma_addr(vb, 0);
 	src_mem.size	= vb->planes[0].bytesused;
 	src_mem.model	= vb->memory;
 	src_mem.timestamp = vb->timestamp;
-	src_mem.meta_ptr = (ulong)buf->meta_data;
 
 	if (vdec_if_probe(ctx, &src_mem, NULL)) {
-		buf->used = false;
 		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 
-		if (ctx->is_drm_mode &&
-			(src_mem.model == VB2_MEMORY_DMABUF)) {
-			wake_up_interruptible(&ctx->wq);
-		} else {
-			v4l2_buff_done(to_vb2_v4l2_buffer(vb),
-				VB2_BUF_STATE_DONE);
-		}
-
+		if (!(ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF))
+			v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb), VB2_BUF_STATE_DONE);
 		return;
 	}
 
@@ -3837,14 +2154,11 @@
 	 * If on model dmabuf must remove the buffer
 	 * because this data has been consumed by hw.
 	 */
-	buf->used = false;
-	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
-	if (ctx->is_drm_mode &&
-		(src_mem.model == VB2_MEMORY_DMABUF)) {
-		wake_up_interruptible(&ctx->wq);
+	if (ctx->is_drm_mode && src_mem.model == VB2_MEMORY_DMABUF) {
+		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 	} else if (ctx->param_sets_from_ucode) {
-		v4l2_buff_done(to_vb2_v4l2_buffer(vb),
+		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		v4l2_m2m_buf_done(to_vb2_v4l2_buffer(vb),
 			VB2_BUF_STATE_DONE);
 	}
 
@@ -3854,24 +2168,23 @@
 		return;
 	}
 
-	if (!ctx->picinfo.dpb_frames)
+	if (vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpb)) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"GET_PARAM_DPB_SIZE err\n");
+		return;
+	}
+
+	if (!dpb)
 		return;
 
-	v4l_buf_size_decision(ctx);
+	ctx->dpb_size = dpb;
 	ctx->last_decoded_picinfo = ctx->picinfo;
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Picture buffer count: dec:%u, vpp:%u, ge2d:%u, margin:%u, total:%u\n",
-		ctx->picinfo.dpb_frames, ctx->vpp_size, ctx->ge2d_size,
-		ctx->picinfo.dpb_margin,
-		CTX_BUF_TOTAL(ctx));
-
 	aml_vdec_dispatch_event(ctx, V4L2_EVENT_SRC_CH_RESOLUTION);
 
 	mutex_lock(&ctx->state_lock);
 	if (ctx->state == AML_STATE_INIT) {
 		ctx->state = AML_STATE_PROBE;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		ATRACE_COUNTER("v4l2_state", ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_PROBE)\n");
 	}
@@ -3883,19 +2196,26 @@
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
 	struct aml_video_dec_buf *buf = NULL;
+	bool buf_error;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT,
 		"%s, type: %d, idx: %d\n",
 		__func__, vb->vb2_queue->type, vb->index);
 
-	vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+	vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
 	buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
 
-	if (buf->error) {
+	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		buf->queued_in_v4l2 = false;
+		buf->queued_in_vb2 = false;
+	}
+	buf_error = buf->error;
+
+	if (buf_error) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"Unrecoverable error on buffer.\n");
 		ctx->state = AML_STATE_ABORT;
-		ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
+		ATRACE_COUNTER("v4l2_state", ctx->state);
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_STATE,
 			"vcodec state (AML_STATE_ABORT)\n");
 	}
@@ -3908,145 +2228,108 @@
 					struct vb2_v4l2_buffer, vb2_buf);
 	struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
 					struct aml_video_dec_buf, vb);
-	struct vdec_v4l2_buffer *fb = &buf->frame_buffer;
-	u32 size, phy_addr = 0;
-	int i;
+	unsigned int size, phy_addr = 0;
+	char *owner = __getname();
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
 		__func__, vb->vb2_queue->type, vb->index);
 
-	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+	if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		buf->used = false;
+		buf->ready_to_display = false;
+		buf->queued_in_v4l2 = false;
+		buf->frame_buffer.status = FB_ST_NORMAL;
+	} else {
 		buf->lastframe = false;
 	}
 
 	/* codec_mm buffers count */
-	if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
+	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
 		if (vb->memory == VB2_MEMORY_MMAP) {
-			char *owner = __getname();
-
-			snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
+			size = vb->planes[0].length;
+			phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+			snprintf(owner, PATH_MAX, "%s-%d", "v4l-input", ctx->id);
 			strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
 			buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
-			__putname(owner);
 
-			for (i = 0; i < vb->num_planes; i++) {
-				size = vb->planes[i].length;
-				phy_addr = vb2_dma_contig_plane_dma_addr(vb, i);
-				buf->mem[i] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
-						phy_addr, size, vb->index);
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-						"OUT %c alloc, addr: %x, size: %u, idx: %u\n",
-						(i == 0? 'Y':'C'), phy_addr, size, vb->index);
-			}
-		} else if (vb->memory == VB2_MEMORY_DMABUF) {
-			unsigned int dw_mode = VDEC_DW_NO_AFBC;
+			buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+					phy_addr, size, vb->index);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"IN alloc, addr: %x, size: %u, idx: %u\n",
+				phy_addr, size, vb->index);
+		}
+	} else {
+		snprintf(owner, PATH_MAX, "%s-%d", "v4l-output", ctx->id);
+		strncpy(buf->mem_onwer, owner, sizeof(buf->mem_onwer));
+		buf->mem_onwer[sizeof(buf->mem_onwer) - 1] = '\0';
 
-			for (i = 0; i < vb->num_planes; i++) {
-				struct dma_buf * dma;
+		if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 1)) {
+			size = vb->planes[0].length;
+			phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+			buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+				phy_addr, size, vb->index);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"OUT Y alloc, addr: %x, size: %u, idx: %u\n",
+				phy_addr, size, vb->index);
+		} else if ((vb->memory == VB2_MEMORY_MMAP) && (vb->num_planes == 2)) {
+			size = vb->planes[0].length;
+			phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+			buf->mem[0] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+				phy_addr, size, vb->index);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"OUT Y alloc, addr: %x, size: %u, idx: %u\n",
+				phy_addr, size, vb->index);
 
-				if (vdec_if_get_param(ctx, GET_PARAM_DW_MODE, &dw_mode)) {
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR, "invalid dw_mode\n");
-					return -EINVAL;
-				}
-				/* None-DW mode means single layer */
-				if (dw_mode == VDEC_DW_AFBC_ONLY && i > 0) {
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-							"only support single plane in dw mode 0\n");
-					return -EINVAL;
-				}
-				size = vb->planes[i].length;
-				dma = vb->planes[i].dbuf;
-
-				if (!dmabuf_is_uvm(dma))
-					v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "non-uvm dmabuf\n");
-			}
+			size = vb->planes[1].length;
+			phy_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
+			buf->mem[1] = v4l_reqbufs_from_codec_mm(buf->mem_onwer,
+					phy_addr, size, vb->index);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"OUT C alloc, addr: %x, size: %u, idx: %u\n",
+				phy_addr, size, vb->index);
 		}
 	}
 
-	if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
-		struct vframe_s *vf = NULL;
-		struct task_chain_s *task = NULL;
-		struct task_chain_s *task_pre = fb->task;
-		u32 icomp = -1;
-
-		fb_map_table_fetch(ctx, vb, &vf, &task, &icomp);
-		if (vf) {
-			fb->task		= task;
-			fb->vframe		= vf;
-			vf->v4l_mem_handle	= (ulong)fb;
-			buf->internal_index	= icomp;
-			task_chain_update_object(task, fb);
-		} else {
-			buf->que_in_m2m = false;
-
-			if (aml_uvm_buff_attach(vb))
-				return -EFAULT;
-
-			if (task_chain_init(&fb->task, ctx, fb, vb->index))
-				return -EFAULT;
-
-			list_add(&fb->task->node, &ctx->task_chain_pool);
- 		}
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-			"init buffer(%s), vb idx:%d, task:(%px -> %px), addr:(%lx -> %lx), icomp:%d\n",
-			vf ? "update" : "idel",
-			vb->index, task_pre, fb->task,
-			fb->m.mem[0].addr,
-			(ulong) vb2_dma_contig_plane_dma_addr(vb, 0),
-			(int)icomp);
-
-		update_vdec_buf_plane(ctx, fb, vb);
-	}
-
-	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
-		ulong contig_size;
-
-		buf->out_sgt = vb2_dma_sg_plane_desc(vb, 0);
-
-		contig_size = dmabuf_contiguous_size(buf->out_sgt);
-		if (contig_size < vb->planes[0].bytesused) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"contiguous mapping is too small %lu/%u\n",
-				contig_size, size);
-			return -EFAULT;
-		}
-	}
+	__putname(owner);
 
 	return 0;
 }
 
-static void vb2ops_vdec_buf_cleanup(struct vb2_buffer *vb)
+static void codec_mm_bufs_cnt_clean(struct vb2_queue *q)
 {
-	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
-					struct vb2_v4l2_buffer, vb2_buf);
-	struct aml_video_dec_buf *buf = container_of(vb2_v4l2,
-					struct aml_video_dec_buf, vb);
-	struct vdec_v4l2_buffer *fb = &buf->frame_buffer;;
+	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
+	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
+	struct aml_video_dec_buf *buf = NULL;
+	int i;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s, type: %d, idx: %d\n",
-		__func__, vb->vb2_queue->type, vb->index);
+	for (i = 0; i < q->num_buffers; ++i) {
+		vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
+		buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
+		if (IS_ERR_OR_NULL(buf->mem[0]))
+			return;
 
-	if (!V4L2_TYPE_IS_OUTPUT(vb->type)) {
-		if (vb->memory == VB2_MEMORY_MMAP) {
-			int i;
+		if (V4L2_TYPE_IS_OUTPUT(q->bufs[i]->type)) {
+			v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
 
-			for (i = 0; i < vb->num_planes ; i++) {
-				v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
-					"OUT %c clean, addr: %lx, size: %u, idx: %u\n",
-					(i == 0)? 'Y':'C',
-					buf->mem[i]->phy_addr, buf->mem[i]->buffer_size, vb->index);
-				v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[i]);
-				buf->mem[i] = NULL;
-			}
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"IN clean, addr: %lx, size: %u, idx: %u\n",
+				buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
+			buf->mem[0] = NULL;
+			continue;
 		}
-		if (ctx->output_thread_ready) {
-			if (!is_fb_mapped(ctx, fb->m.mem[0].addr)) {
-				list_del(&fb->task->node);
-				task_chain_clean(fb->task);
-				task_chain_release(fb->task);
-			}
+
+		if (q->memory == VB2_MEMORY_MMAP) {
+			v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[0]);
+			v4l_freebufs_back_to_codec_mm(buf->mem_onwer, buf->mem[1]);
+
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"OUT Y clean, addr: %lx, size: %u, idx: %u\n",
+				buf->mem[0]->phy_addr, buf->mem[0]->buffer_size, i);
+			v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
+				"OUT C clean, addr: %lx, size: %u, idx: %u\n",
+				buf->mem[1]->phy_addr, buf->mem[1]->buffer_size, i);
+			buf->mem[0] = NULL;
+			buf->mem[1] = NULL;
 		}
 	}
 }
@@ -4056,10 +2339,6 @@
 	struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q);
 
 	ctx->has_receive_eos = false;
-	ctx->v4l_resolution_change = false;
-
-	/* vdec has ready to decode subsequence data of new resolution. */
-	v4l2_m2m_job_resume(ctx->dev->m2m_dev_dec, ctx->m2m_ctx);
 
 	v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
 
@@ -4080,81 +2359,40 @@
 		"%s, type: %d, state: %x, frame_cnt: %d\n",
 		__func__, q->type, ctx->state, ctx->decoded_frame_cnt);
 
-	if (V4L2_TYPE_IS_OUTPUT(q->type))
-		ctx->is_out_stream_off = true;
-	else
-		ctx->is_stream_off = true;
+	codec_mm_bufs_cnt_clean(q);
 
 	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
-		struct vb2_queue * que = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
-		unsigned long flags;
-
-		cancel_work_sync(&ctx->dmabuff_recycle_work);
-		spin_lock_irqsave(&ctx->dmabuff_recycle_lock, flags);
-		INIT_KFIFO(ctx->dmabuff_recycle);
-		spin_unlock_irqrestore(&ctx->dmabuff_recycle_lock, flags);
-
 		while ((vb2_v4l2 = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
-			v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
 
 		for (i = 0; i < q->num_buffers; ++i) {
 			vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
 			if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
-				v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
-		}
-
-		/*
-		 * drop es frame was stored in the vdec_input
-		 * if the capture queue have not start streaming.
-		 */
-		if (!que->streaming &&
-			(vdec_frame_number(ctx->ada_ctx) > 0) &&
-			(ctx->state < AML_STATE_ACTIVE)) {
-			ctx->state = AML_STATE_INIT;
-			ATRACE_COUNTER("V_ST_VSINK-state", ctx->state);
-			ctx->v4l_resolution_change = false;
-			ctx->reset_flag = V4L_RESET_MODE_NORMAL;
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-				"force reset to drop es frames.\n");
-			wake_up_interruptible(&ctx->cap_wq);
-			aml_vdec_reset(ctx);
+				v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
 		}
 	} else {
 		/* clean output cache and decoder status . */
-		if (ctx->state > AML_STATE_INIT) {
-			wake_up_interruptible(&ctx->cap_wq);
+		if (ctx->state > AML_STATE_INIT)
 			aml_vdec_reset(ctx);
-		}
-
-		cancel_work_sync(&ctx->decode_work);
-		mutex_lock(&ctx->capture_buffer_lock);
-		INIT_KFIFO(ctx->capture_buffer);
-		mutex_unlock(&ctx->capture_buffer_lock);
 
 		while ((vb2_v4l2 = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)))
-			v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+			v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
 
 		for (i = 0; i < q->num_buffers; ++i) {
 			vb2_v4l2 = to_vb2_v4l2_buffer(q->bufs[i]);
 			buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
-			buf->frame_buffer.status	= FB_ST_FREE;
-			buf->frame_buffer.vframe	= NULL;
-			buf->que_in_m2m			= false;
-			buf->used			= false;
-			buf->vb.flags			= 0;
-			ctx->cap_pool.seq[i]		= 0;
+			buf->frame_buffer.status = FB_ST_NORMAL;
+			buf->que_in_m2m = false;
+			buf->vb.flags = 0;
+			ctx->cap_pool.seq[i] = 0;
 
 			if (vb2_v4l2->vb2_buf.state == VB2_BUF_STATE_ACTIVE)
-				v4l2_buff_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
+				v4l2_m2m_buf_done(vb2_v4l2, VB2_BUF_STATE_ERROR);
 
 			/*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "idx: %d, state: %d\n",
 				q->bufs[i]->index, q->bufs[i]->state);*/
 		}
 
-		fb_map_table_clean(ctx);
-
-		fb_token_clean(ctx);
-
 		ctx->buf_used_count = 0;
 		ctx->cap_pool.in = 0;
 		ctx->cap_pool.out = 0;
@@ -4172,6 +2410,15 @@
 		queue_work(dev->decode_workqueue, &ctx->decode_work);
 }
 
+void vdec_device_vf_run(struct aml_vcodec_ctx *ctx)
+{
+	if (ctx->state < AML_STATE_INIT ||
+		ctx->state > AML_STATE_FLUSHED)
+		return;
+
+	aml_thread_notify(ctx, AML_THREAD_CAPTURE);
+}
+
 static int m2mops_vdec_job_ready(void *m2m_priv)
 {
 	struct aml_vcodec_ctx *ctx = m2m_priv;
@@ -4201,23 +2448,17 @@
 	switch (ctrl->id) {
 	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
 		if (ctx->state >= AML_STATE_PROBE) {
-			ctrl->val = CTX_BUF_TOTAL(ctx);
+			ctrl->val = ctx->dpb_size;
 		} else {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 				"Seqinfo not ready.\n");
 			ctrl->val = 0;
+			ret = -EINVAL;
 		}
 		break;
 	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
 		ctrl->val = 4;
 		break;
-	case AML_V4L2_GET_INPUT_BUFFER_NUM:
-		if (ctx->ada_ctx != NULL)
-			ctrl->val = vdec_frame_number(ctx->ada_ctx);
-		break;
-	case AML_V4L2_GET_FILMGRAIN_INFO:
-		ctrl->val = ctx->film_grain_present;
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -4235,10 +2476,6 @@
 		ctx->param_sets_from_ucode = true;
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
 			"set stream mode: %x\n", ctrl->val);
-	} else if (ctrl->id == AML_V4L2_SET_DURATION) {
-		vdec_set_duration(ctrl->val);
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-			"set duration: %x\n", ctrl->val);
 	}
 
 	return 0;
@@ -4261,42 +2498,6 @@
 	.def	= 0,
 };
 
-static const struct v4l2_ctrl_config ctrl_gt_input_buffer_number = {
-	.name	= "input buffer number",
-	.id	= AML_V4L2_GET_INPUT_BUFFER_NUM,
-	.ops	= &aml_vcodec_dec_ctrl_ops,
-	.type	= V4L2_CTRL_TYPE_INTEGER,
-	.flags	= V4L2_CTRL_FLAG_VOLATILE,
-	.min	= 0,
-	.max	= 128,
-	.step	= 1,
-	.def	= 0,
-};
-
-static const struct v4l2_ctrl_config ctrl_st_duration = {
-	.name	= "duration",
-	.id	= AML_V4L2_SET_DURATION,
-	.ops	= &aml_vcodec_dec_ctrl_ops,
-	.type	= V4L2_CTRL_TYPE_INTEGER,
-	.flags	= V4L2_CTRL_FLAG_WRITE_ONLY,
-	.min	= 0,
-	.max	= 96000,
-	.step	= 1,
-	.def	= 0,
-};
-
-static const struct v4l2_ctrl_config ctrl_gt_filmgrain_info = {
-	.name	= "filmgrain info",
-	.id	= AML_V4L2_GET_FILMGRAIN_INFO,
-	.ops	= &aml_vcodec_dec_ctrl_ops,
-	.type	= V4L2_CTRL_TYPE_INTEGER,
-	.flags	= V4L2_CTRL_FLAG_VOLATILE,
-	.min	= 0,
-	.max	= 1,
-	.step	= 1,
-	.def	= 0,
-};
-
 int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx)
 {
 	int ret;
@@ -4307,42 +2508,24 @@
 				&aml_vcodec_dec_ctrl_ops,
 				V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
 				0, 32, 1, 2);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	if (ctx->ctrl_hdl.error) {
 		ret = ctx->ctrl_hdl.error;
 		goto err;
 	}
-	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
 
 	ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl,
 				&aml_vcodec_dec_ctrl_ops,
 				V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
 				0, 32, 1, 8);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	if (ctx->ctrl_hdl.error) {
 		ret = ctx->ctrl_hdl.error;
 		goto err;
 	}
-	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
 
 	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_mode, NULL);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
-		ret = ctx->ctrl_hdl.error;
-		goto err;
-	}
-
-	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_input_buffer_number, NULL);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
-		ret = ctx->ctrl_hdl.error;
-		goto err;
-	}
-
-	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_st_duration, NULL);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
-		ret = ctx->ctrl_hdl.error;
-		goto err;
-	}
-
-	ctrl = v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &ctrl_gt_filmgrain_info, NULL);
-	if ((ctrl == NULL) || (ctx->ctrl_hdl.error)) {
+	if (ctx->ctrl_hdl.error) {
 		ret = ctx->ctrl_hdl.error;
 		goto err;
 	}
@@ -4362,25 +2545,16 @@
 	struct v4l2_streamparm *a)
 {
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
-	struct vb2_queue *dst_vq;
 
-	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!dst_vq) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		return -EINVAL;
-	}
-
-	if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar)
-		return -EINVAL;
-
-	if ((a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) || (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
-		if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO, &ctx->config.parm.dec))
+	if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		if (vdec_if_get_param(ctx, GET_PARAM_CONFIG_INFO,
+			&ctx->config.parm.dec)) {
 			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 				"GET_PARAM_CONFIG_INFO err\n");
-		else
-			memcpy(a->parm.raw_data, ctx->config.parm.data,
-				sizeof(a->parm.raw_data));
+			return -1;
+		}
+		memcpy(a->parm.raw_data, ctx->config.parm.data,
+			sizeof(a->parm.raw_data));
 	}
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
@@ -4388,65 +2562,22 @@
 	return 0;
 }
 
-static int check_dec_cfginfo(struct aml_vdec_cfg_infos *cfg)
-{
-	if (cfg->double_write_mode != 0 &&
-		cfg->double_write_mode != 1 &&
-		cfg->double_write_mode != 2 &&
-		cfg->double_write_mode != 3 &&
-		cfg->double_write_mode != 4 &&
-		cfg->double_write_mode != 16 &&
-		cfg->double_write_mode != 0x21 &&
-		cfg->double_write_mode != 0x100 &&
-		cfg->double_write_mode != 0x200) {
-		pr_err("invalid double write mode %d\n", cfg->double_write_mode);
-		return -1;
-	}
-	if (cfg->ref_buf_margin > 20) {
-		pr_err("invalid margin %d\n", cfg->ref_buf_margin);
-		return -1;
-	}
-
-	if (mandatory_dw_mmu) {
-		cfg->double_write_mode = 0x21;
-	}
-
-	pr_info("double write mode %d margin %d\n",
-		cfg->double_write_mode, cfg->ref_buf_margin);
-	return 0;
-}
-
 static int vidioc_vdec_s_parm(struct file *file, void *fh,
 	struct v4l2_streamparm *a)
 {
 	struct aml_vcodec_ctx *ctx = fh_to_ctx(fh);
-	struct vb2_queue *dst_vq;
 
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s\n", __func__);
 
-	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	if (!dst_vq) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"no vb2 queue for type=%d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		return -EINVAL;
-	}
-
-	if (!V4L2_TYPE_IS_MULTIPLANAR(a->type) && dst_vq->is_multiplanar)
-		return -EINVAL;
-
-	if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
-		a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+	if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		struct aml_dec_params *in =
 			(struct aml_dec_params *) a->parm.raw_data;
 		struct aml_dec_params *dec = &ctx->config.parm.dec;
 
 		ctx->config.type = V4L2_CONFIG_PARM_DECODE;
 
-		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
-			if (check_dec_cfginfo(&in->cfg))
-				return -EINVAL;
+		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
 			dec->cfg = in->cfg;
-		}
 		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
 			dec->ps = in->ps;
 		if (in->parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -4455,37 +2586,31 @@
 			dec->cnt = in->cnt;
 
 		dec->parms_status |= in->parms_status;
-
-		/* aml v4l driver parms config. */
-		ctx->vpp_cfg.enable_nr =
-			(dec->cfg.metadata_config_flag & (1 << 15));
-		if (force_enable_nr)
-			ctx->vpp_cfg.enable_nr = true;
-
-		ctx->vpp_cfg.enable_local_buf =
-			(dec->cfg.metadata_config_flag & (1 << 14));
-		if (force_enable_di_local_buffer)
-			ctx->vpp_cfg.enable_local_buf = true;
-
-		ctx->internal_dw_scale = dec->cfg.metadata_config_flag & (1 << 13);
-		ctx->second_field_pts_mode = dec->cfg.metadata_config_flag & (1 << 12);
-
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, "%s parms:%x metadata_config_flag: 0x%x\n",
-				__func__, in->parms_status, dec->cfg.metadata_config_flag);
-
-		memset(a->parm.output.reserved, 0, sizeof(a->parm.output.reserved));
-	} else {
-		memset(a->parm.capture.reserved, 0, sizeof(a->parm.capture.reserved));
 	}
 
 	return 0;
 }
 
+static void m2mops_vdec_lock(void *m2m_priv)
+{
+	struct aml_vcodec_ctx *ctx = m2m_priv;
+
+	mutex_lock(&ctx->dev->dev_mutex);
+}
+
+static void m2mops_vdec_unlock(void *m2m_priv)
+{
+	struct aml_vcodec_ctx *ctx = m2m_priv;
+
+	mutex_unlock(&ctx->dev->dev_mutex);
+}
 
 const struct v4l2_m2m_ops aml_vdec_m2m_ops = {
 	.device_run	= m2mops_vdec_device_run,
 	.job_ready	= m2mops_vdec_job_ready,
 	.job_abort	= m2mops_vdec_job_abort,
+	.lock		= m2mops_vdec_lock,
+	.unlock		= m2mops_vdec_unlock,
 };
 
 static const struct vb2_ops aml_vdec_vb2_ops = {
@@ -4495,7 +2620,6 @@
 	.wait_prepare	= vb2_ops_wait_prepare,
 	.wait_finish	= vb2_ops_wait_finish,
 	.buf_init	= vb2ops_vdec_buf_init,
-	.buf_cleanup	= vb2ops_vdec_buf_cleanup,
 	.buf_finish	= vb2ops_vdec_buf_finish,
 	.start_streaming = vb2ops_vdec_start_streaming,
 	.stop_streaming	= vb2ops_vdec_stop_streaming,
@@ -4512,10 +2636,10 @@
 	.vidioc_qbuf			= vidioc_vdec_qbuf,
 	.vidioc_dqbuf			= vidioc_vdec_dqbuf,
 
-	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap_out,
-	.vidioc_try_fmt_vid_cap		= vidioc_try_fmt_vid_cap_out,
-	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_cap_out,
-	.vidioc_try_fmt_vid_out		= vidioc_try_fmt_vid_cap_out,
+	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap_mplane,
+	.vidioc_try_fmt_vid_cap		= vidioc_try_fmt_vid_cap_mplane,
+	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
+	.vidioc_try_fmt_vid_out		= vidioc_try_fmt_vid_out_mplane,
 
 	.vidioc_s_fmt_vid_cap_mplane	= vidioc_vdec_s_fmt,
 	.vidioc_s_fmt_vid_cap		= vidioc_vdec_s_fmt,
@@ -4528,18 +2652,17 @@
 
 	.vidioc_create_bufs		= vidioc_vdec_create_bufs,
 
-	//fixme
-	//.vidioc_enum_fmt_vid_cap_mplane	= vidioc_vdec_enum_fmt_vid_cap_mplane,
-	//.vidioc_enum_fmt_vid_out_mplane = vidioc_vdec_enum_fmt_vid_out_mplane,
+	.vidioc_enum_fmt_vid_cap_mplane	= vidioc_vdec_enum_fmt_vid_cap_mplane,
 	.vidioc_enum_fmt_vid_cap	= vidioc_vdec_enum_fmt_vid_cap_mplane,
+	.vidioc_enum_fmt_vid_out_mplane	= vidioc_vdec_enum_fmt_vid_out_mplane,
 	.vidioc_enum_fmt_vid_out	= vidioc_vdec_enum_fmt_vid_out_mplane,
 	.vidioc_enum_framesizes		= vidioc_enum_framesizes,
 
 	.vidioc_querycap		= vidioc_vdec_querycap,
 	.vidioc_subscribe_event		= vidioc_vdec_subscribe_evt,
 	.vidioc_unsubscribe_event	= vidioc_vdec_event_unsubscribe,
-	.vidioc_g_selection		= vidioc_vdec_g_selection,
-	.vidioc_s_selection		= vidioc_vdec_s_selection,
+	.vidioc_g_selection             = vidioc_vdec_g_selection,
+	.vidioc_s_selection             = vidioc_vdec_s_selection,
 
 	.vidioc_decoder_cmd		= vidioc_decoder_cmd,
 	.vidioc_try_decoder_cmd		= vidioc_try_decoder_cmd,
@@ -4557,11 +2680,11 @@
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "%s\n", __func__);
 
 	src_vq->type		= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
+	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
 	src_vq->drv_priv	= ctx;
 	src_vq->buf_struct_size = sizeof(struct aml_video_dec_buf);
 	src_vq->ops		= &aml_vdec_vb2_ops;
-	src_vq->mem_ops		= &vb2_dma_sg_memops;
+	src_vq->mem_ops		= &vb2_dma_contig_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	src_vq->lock		= &ctx->dev->dev_mutex;
 	ret = vb2_queue_init(src_vq);
@@ -4580,7 +2703,6 @@
 	dst_vq->mem_ops		= &vb2_dma_contig_memops;
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	dst_vq->lock		= &ctx->dev->dev_mutex;
-	dst_vq->min_buffers_needed = 1;
 	ret = vb2_queue_init(dst_vq);
 	if (ret) {
 		vb2_queue_release(src_vq);
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index a23522c..3653ff0 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -20,14 +20,11 @@
 #ifndef _AML_VCODEC_DEC_H_
 #define _AML_VCODEC_DEC_H_
 
-#include <linux/kref.h>
-#include <linux/scatterlist.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-v4l2.h>
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 #include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
 #include "aml_vcodec_util.h"
-#include "aml_task_chain.h"
 
 #define VCODEC_CAPABILITY_4K_DISABLED	0x10
 #define VCODEC_DEC_4K_CODED_WIDTH	4096U
@@ -41,25 +38,15 @@
 #define VDEC_GATHER_MEMORY_TYPE		0
 #define VDEC_SCATTER_MEMORY_TYPE	1
 
-#define META_DATA_SIZE			(256)
-#define MD_BUF_SIZE			(1024)
-#define COMP_BUF_SIZE			(8196)
-#define SEI_BUF_SIZE			(2 * 12 * 1024)
-#define SEI_TYPE	(1)
-#define DV_TYPE		(2)
-
-
-/*
- * struct vdec_v4l2_buffer - decoder frame buffer
+/**
+ * struct vdec_fb  - decoder frame buffer
  * @mem_type	: gather or scatter memory.
  * @num_planes	: used number of the plane
  * @mem[4]	: array mem for used planes,
  *		  mem[0]: Y, mem[1]: C/U, mem[2]: V
  * @vf_fd	: the file handle of video frame
+ * @vf_handle	: video frame handle
  * @status      : frame buffer status (vdec_fb_status)
- * @buf_idx	: the index from vb2 index.
- * @vframe	: store the vframe that get from caller.
- * @task	: the context of task chain manager.
  */
 
 struct vdec_v4l2_buffer {
@@ -69,19 +56,22 @@
 		struct	aml_vcodec_mem mem[4];
 		u32	vf_fd;
 	} m;
+	ulong	vf_handle;
 	u32	status;
 	u32	buf_idx;
-	void	*vframe;
-
-	struct task_chain_s *task;
 };
 
+
 /**
  * struct aml_video_dec_buf - Private data related to each VB2 buffer.
  * @b:		VB2 buffer
  * @list:	link list
  * @used:	Capture buffer contain decoded frame data and keep in
  *			codec data structure
+ * @ready_to_display:	Capture buffer not display yet
+ * @queued_in_vb2:	Capture buffer is queue in vb2
+ * @queued_in_v4l2:	Capture buffer is in v4l2 driver, but not in vb2
+ *			queue yet
  * @lastframe:		Intput buffer is last buffer - EOS
  * @error:		An unrecoverable error occurs on this buffer.
  * @frame_buffer:	Decode status, and buffer information of Capture buffer
@@ -97,21 +87,12 @@
 	struct codec_mm_s *mem[2];
 	char mem_onwer[32];
 	bool used;
+	bool ready_to_display;
 	bool que_in_m2m;
+	bool queued_in_vb2;
+	bool queued_in_v4l2;
 	bool lastframe;
 	bool error;
-
-	/* internal compressed buffer */
-	unsigned int internal_index;
-
-	ulong vpp_buf_handle;
-	ulong ge2d_buf_handle;
-
-	/*4 bytes data for data len*/
-	char meta_data[META_DATA_SIZE + 4];
-
-	struct sg_table *out_sgt;
-	struct sg_table *cap_sgt;
 };
 
 extern const struct v4l2_ioctl_ops aml_vdec_ioctl_ops;
@@ -130,19 +111,16 @@
 void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx);
 void aml_vcodec_dec_release(struct aml_vcodec_ctx *ctx);
 int aml_vcodec_dec_ctrls_setup(struct aml_vcodec_ctx *ctx);
+void vdec_device_vf_run(struct aml_vcodec_ctx *ctx);
+void try_to_capture(struct aml_vcodec_ctx *ctx);
+void aml_thread_notify(struct aml_vcodec_ctx *ctx,
+	enum aml_thread_type type);
+int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
+	enum aml_thread_type type, const char *thread_name);
+void aml_thread_stop(struct aml_vcodec_ctx *ctx);
 void wait_vcodec_ending(struct aml_vcodec_ctx *ctx);
 void vdec_frame_buffer_release(void *data);
 void aml_vdec_dispatch_event(struct aml_vcodec_ctx *ctx, u32 changes);
 void* v4l_get_vf_handle(int fd);
-void aml_v4l_ctx_release(struct kref *kref);
-void dmabuff_recycle_worker(struct work_struct *work);
-void aml_buffer_status(struct aml_vcodec_ctx *ctx);
-void aml_vdec_basic_information(struct aml_vcodec_ctx *ctx);
-
-void aml_alloc_buffer(struct aml_vcodec_ctx *ctx, int flag);
-void aml_free_buffer(struct aml_vcodec_ctx *ctx, int flag);
-void aml_free_one_sei_buffer(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
-void aml_bind_sei_buffer(struct aml_vcodec_ctx *v4l, char **addr, int *size, int *idx);
-void aml_bind_dv_buffer(struct aml_vcodec_ctx *v4l, char **comp_buf, char **md_buf);
 
 #endif /* _AML_VCODEC_DEC_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_dec_drv.c b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
index 18f0254..1ed0b97 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec_drv.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec_drv.c
@@ -29,11 +29,11 @@
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
 #include <linux/kthread.h>
-#include <linux/compat.h>
+
 #include "aml_vcodec_drv.h"
 #include "aml_vcodec_dec.h"
 #include "aml_vcodec_util.h"
-#include "aml_vcodec_vpp.h"
+#include "aml_vcodec_vfm.h"
 #include <linux/file.h>
 #include <linux/anon_inodes.h>
 
@@ -50,7 +50,6 @@
 
 bool param_sets_from_ucode = 1;
 bool enable_drm_mode;
-extern void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx);
 
 static int fops_vcodec_open(struct file *file)
 {
@@ -63,21 +62,12 @@
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
-	kref_init(&ctx->ctx_ref);
-
 	aml_buf = kzalloc(sizeof(*aml_buf), GFP_KERNEL);
 	if (!aml_buf) {
 		kfree(ctx);
 		return -ENOMEM;
 	}
 
-	ctx->meta_infos.meta_bufs = vzalloc(sizeof(struct meta_data) * V4L_CAP_BUFF_MAX);
-	if (ctx->meta_infos.meta_bufs == NULL) {
-		kfree(aml_buf);
-		kfree(ctx);
-		return -ENOMEM;
-	}
-
 	mutex_lock(&dev->dev_mutex);
 	ctx->empty_flush_buf = aml_buf;
 	ctx->id = dev->id_counter++;
@@ -86,26 +76,14 @@
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	INIT_LIST_HEAD(&ctx->vdec_thread_list);
-	INIT_LIST_HEAD(&ctx->task_chain_pool);
 	dev->filp = file;
 	ctx->dev = dev;
 	init_waitqueue_head(&ctx->queue);
-	mutex_init(&ctx->capture_buffer_lock);
-	mutex_init(&ctx->buff_done_lock);
 	mutex_init(&ctx->state_lock);
-	mutex_init(&ctx->comp_lock);
+	mutex_init(&ctx->lock);
 	spin_lock_init(&ctx->slock);
-	spin_lock_init(&ctx->tsplock);
-	spin_lock_init(&ctx->dmabuff_recycle_lock);
 	init_completion(&ctx->comp);
-	init_waitqueue_head(&ctx->wq);
-	init_waitqueue_head(&ctx->cap_wq);
-	init_waitqueue_head(&ctx->post_done_wq);
-	INIT_WORK(&ctx->dmabuff_recycle_work, dmabuff_recycle_worker);
-	INIT_KFIFO(ctx->dmabuff_recycle);
-	INIT_KFIFO(ctx->capture_buffer);
 
-	ctx->post_to_upper_done = true;
 	ctx->param_sets_from_ucode = param_sets_from_ucode ? 1 : 0;
 
 	if (enable_drm_mode) {
@@ -133,19 +111,9 @@
 	ctx->output_thread_ready = true;
 	ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
 	ctx->empty_flush_buf->lastframe = true;
-	ctx->vdec_pic_info_update = aml_vdec_pic_info_update;
 	aml_vcodec_dec_set_default_params(ctx);
-	ctx->is_stream_off = true;
 
-	ctx->aux_infos.dv_index = 0;
-	ctx->aux_infos.sei_index = 0;
-	ctx->aux_infos.alloc_buffer = aml_alloc_buffer;
-	ctx->aux_infos.free_buffer = aml_free_buffer;
-	ctx->aux_infos.bind_sei_buffer = aml_bind_sei_buffer;
-	ctx->aux_infos.bind_dv_buffer = aml_bind_dv_buffer;
-	ctx->aux_infos.free_one_sei_buffer = aml_free_one_sei_buffer;
-
-	ret = aml_thread_start(ctx, aml_thread_capture_worker, AML_THREAD_CAPTURE, "cap");
+	ret = aml_thread_start(ctx, try_to_capture, AML_THREAD_CAPTURE, "cap");
 	if (ret) {
 		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
 			"Failed to creat capture thread.\n");
@@ -158,7 +126,7 @@
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "%s decoder %lx\n",
 		dev_name(&dev->plat_dev->dev), (ulong)ctx);
 
-	return 0;
+	return ret;
 
 	/* Deinit when failure occurred */
 err_creat_thread:
@@ -168,7 +136,6 @@
 err_ctrls_setup:
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
-	vfree(ctx->meta_infos.meta_bufs);
 	kfree(ctx->empty_flush_buf);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
@@ -184,20 +151,24 @@
 	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "release decoder %lx\n", (ulong) ctx);
 	mutex_lock(&dev->dev_mutex);
 
+	/*
+	 * Call v4l2_m2m_ctx_release before aml_vcodec_dec_release. First, it
+	 * makes sure the worker thread is not running after vdec_if_deinit.
+	 * Second, the decoder will be flushed and all the buffers will be
+	 * returned in stop_streaming.
+	 */
 	aml_thread_stop(ctx);
 	wait_vcodec_ending(ctx);
-	vb2_queue_release(&ctx->m2m_ctx->cap_q_ctx.q);
-	vb2_queue_release(&ctx->m2m_ctx->out_q_ctx.q);
-
+	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	aml_vcodec_dec_release(ctx);
+
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
 	list_del_init(&ctx->list);
-
 	kfree(ctx->empty_flush_buf);
-	kref_put(&ctx->ctx_ref, aml_v4l_ctx_release);
+	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
 }
@@ -331,10 +302,8 @@
 
 	if (!is_v4l2_buf_file(file)) {
 		fput(file);
-#if 0
 		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the buf file checked fail!\n");
-#endif
 		return NULL;
 	}
 
@@ -446,43 +415,6 @@
 	.mmap		= v4l2_m2m_fop_mmap,
 };
 
-static ssize_t status_show(struct class *cls,
-	struct class_attribute *attr, char *buf)
-{
-	struct aml_vcodec_dev *dev = container_of(cls,
-		struct aml_vcodec_dev, v4ldec_class);
-	struct aml_vcodec_ctx *ctx = NULL;
-	char *pbuf = buf;
-
-	mutex_lock(&dev->dev_mutex);
-
-	if (list_empty(&dev->ctx_list)) {
-		pbuf += sprintf(pbuf, "No v4ldec context.\n");
-		goto out;
-	}
-
-	list_for_each_entry(ctx, &dev->ctx_list, list) {
-		/* basic information. */
-		aml_vdec_basic_information(ctx);
-
-		/* buffers status. */
-		aml_buffer_status(ctx);
-	}
-out:
-	mutex_unlock(&dev->dev_mutex);
-
-	return pbuf - buf;
-}
-
-static CLASS_ATTR_RO(status);
-
-static struct attribute *v4ldec_class_attrs[] = {
-	&class_attr_status.attr,
-	NULL
-};
-
-ATTRIBUTE_GROUPS(v4ldec_class);
-
 static int aml_vcodec_probe(struct platform_device *pdev)
 {
 	struct aml_vcodec_dev *dev;
@@ -495,7 +427,6 @@
 
 	INIT_LIST_HEAD(&dev->ctx_list);
 	dev->plat_dev = pdev;
-	atomic_set(&dev->vpp_count, 0);
 
 	mutex_init(&dev->dec_mutex);
 	mutex_init(&dev->dev_mutex);
@@ -506,7 +437,8 @@
 
 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 	if (ret) {
-		dev_err(&pdev->dev, "v4l2_device_register err=%d\n", ret);
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"v4l2_device_register err=%d\n", ret);
 		goto err_res;
 	}
 
@@ -514,7 +446,8 @@
 
 	vfd_dec = video_device_alloc();
 	if (!vfd_dec) {
-		dev_err(&pdev->dev, "Failed to allocate video device\n");
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"Failed to allocate video device\n");
 		ret = -ENOMEM;
 		goto err_dec_alloc;
 	}
@@ -526,7 +459,7 @@
 	vfd_dec->v4l2_dev	= &dev->v4l2_dev;
 	vfd_dec->vfl_dir	= VFL_DIR_M2M;
 	vfd_dec->device_caps	= V4L2_CAP_VIDEO_M2M_MPLANE |
-					V4L2_CAP_STREAMING;
+				V4L2_CAP_STREAMING;
 
 	snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
 		AML_VCODEC_DEC_NAME);
@@ -536,16 +469,18 @@
 
 	dev->m2m_dev_dec = v4l2_m2m_init(&aml_vdec_m2m_ops);
 	if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
-		dev_err(&pdev->dev, "Failed to init mem2mem dec device\n");
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"Failed to init mem2mem dec device\n");
 		ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
 		goto err_dec_mem_init;
 	}
 
 	dev->decode_workqueue =
-		alloc_ordered_workqueue("output-worker",
-			__WQ_LEGACY | WQ_MEM_RECLAIM | WQ_HIGHPRI);
+		alloc_ordered_workqueue(AML_VCODEC_DEC_NAME,
+			WQ_MEM_RECLAIM | WQ_FREEZABLE);
 	if (!dev->decode_workqueue) {
-		dev_err(&pdev->dev, "Failed to create decode workqueue\n");
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"Failed to create decode workqueue\n");
 		ret = -EINVAL;
 		goto err_event_workq;
 	}
@@ -554,26 +489,16 @@
 
 	ret = video_register_device(vfd_dec, VFL_TYPE_GRABBER, 26);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to register video device\n");
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
+			"Failed to register video device\n");
 		goto err_dec_reg;
 	}
 
-	/*init class*/
-	dev->v4ldec_class.name = "v4ldec";
-	dev->v4ldec_class.owner = THIS_MODULE;
-	dev->v4ldec_class.class_groups = v4ldec_class_groups;
-	ret = class_register(&dev->v4ldec_class);
-	if (ret) {
-		dev_err(&pdev->dev, "v4l dec class create fail.\n");
-		goto err_reg_class;
-	}
-
-	dev_info(&pdev->dev, "v4ldec registered as /dev/video%d\n", vfd_dec->num);
+	v4l_dbg(0, V4L_DEBUG_CODEC_PRINFO,
+		"decoder registered as /dev/video%d\n", vfd_dec->num);
 
 	return 0;
 
-err_reg_class:
-	class_unregister(&dev->v4ldec_class);
 err_dec_reg:
 	destroy_workqueue(dev->decode_workqueue);
 err_event_workq:
@@ -587,6 +512,13 @@
 	return ret;
 }
 
+static const struct of_device_id aml_vcodec_match[] = {
+	{.compatible = "amlogic, vcodec-dec",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, aml_vcodec_match);
+
 static int aml_vcodec_dec_remove(struct platform_device *pdev)
 {
 	struct aml_vcodec_dev *dev = platform_get_drvdata(pdev);
@@ -594,8 +526,6 @@
 	flush_workqueue(dev->decode_workqueue);
 	destroy_workqueue(dev->decode_workqueue);
 
-	class_unregister(&dev->v4ldec_class);
-
 	if (dev->m2m_dev_dec)
 		v4l2_m2m_release(dev->m2m_dev_dec);
 
@@ -604,17 +534,12 @@
 
 	v4l2_device_unregister(&dev->v4l2_dev);
 
-	dev_info(&pdev->dev, "v4ldec removed.\n");
-
 	return 0;
 }
 
-static const struct of_device_id aml_vcodec_match[] = {
-	{.compatible = "amlogic, vcodec-dec",},
-	{},
-};
-
-MODULE_DEVICE_TABLE(of, aml_vcodec_match);
+/*static void aml_vcodec_dev_release(struct device *dev)
+{
+}*/
 
 static struct platform_driver aml_vcodec_dec_driver = {
 	.probe	= aml_vcodec_probe,
@@ -625,36 +550,44 @@
 	},
 };
 
+/*
+static struct platform_device aml_vcodec_dec_device = {
+	.name		= AML_VCODEC_DEC_NAME,
+	.dev.release	= aml_vcodec_dev_release,
+};*/
+
+module_platform_driver(aml_vcodec_dec_driver);
+
+/*
 static int __init amvdec_ports_init(void)
 {
-	pr_info("v4l dec module init\n");
+	int ret;
 
-	if (platform_driver_register(&aml_vcodec_dec_driver)) {
-		pr_err("failed to register v4l dec driver\n");
-		return -ENODEV;
-	}
+	ret = platform_device_register(&aml_vcodec_dec_device);
+	if (ret)
+		return ret;
 
-	return 0;
+	ret = platform_driver_register(&aml_vcodec_dec_driver);
+	if (ret)
+		platform_device_unregister(&aml_vcodec_dec_device);
+
+	return ret;
 }
 
 static void __exit amvdec_ports_exit(void)
 {
-	pr_info("v4l dec module exit\n");
-
 	platform_driver_unregister(&aml_vcodec_dec_driver);
+	platform_device_unregister(&aml_vcodec_dec_device);
 }
 
 module_init(amvdec_ports_init);
 module_exit(amvdec_ports_exit);
+*/
 
 u32 debug_mode;
 EXPORT_SYMBOL(debug_mode);
 module_param(debug_mode, uint, 0644);
 
-u32 mandatory_dw_mmu;
-EXPORT_SYMBOL(mandatory_dw_mmu);
-module_param(mandatory_dw_mmu, uint, 0644);
-
 bool aml_set_vfm_enable;
 EXPORT_SYMBOL(aml_set_vfm_enable);
 module_param(aml_set_vfm_enable, bool, 0644);
@@ -683,72 +616,20 @@
 EXPORT_SYMBOL(multiplanar);
 module_param(multiplanar, bool, 0644);
 
-int dump_capture_frame;
+bool dump_capture_frame;
 EXPORT_SYMBOL(dump_capture_frame);
-module_param(dump_capture_frame, int, 0644);
-
-int dump_vpp_input;
-EXPORT_SYMBOL(dump_vpp_input);
-module_param(dump_vpp_input, int, 0644);
-
-int dump_ge2d_input;
-EXPORT_SYMBOL(dump_ge2d_input);
-module_param(dump_ge2d_input, int, 0644);
+module_param(dump_capture_frame, bool, 0644);
 
 int dump_output_frame;
 EXPORT_SYMBOL(dump_output_frame);
 module_param(dump_output_frame, int, 0644);
 
-u32 dump_output_start_position;
-EXPORT_SYMBOL(dump_output_start_position);
-module_param(dump_output_start_position, uint, 0644);
-
 EXPORT_SYMBOL(param_sets_from_ucode);
 module_param(param_sets_from_ucode, bool, 0644);
 
 EXPORT_SYMBOL(enable_drm_mode);
 module_param(enable_drm_mode, bool, 0644);
 
-int bypass_vpp;
-EXPORT_SYMBOL(bypass_vpp);
-module_param(bypass_vpp, int, 0644);
-
-int bypass_ge2d;
-EXPORT_SYMBOL(bypass_ge2d);
-module_param(bypass_ge2d, int, 0644);
-
-int max_di_instance = 2;
-EXPORT_SYMBOL(max_di_instance);
-module_param(max_di_instance, int, 0644);
-
-int bypass_progressive = 1;
-EXPORT_SYMBOL(bypass_progressive);
-module_param(bypass_progressive, int, 0644);
-
-bool support_mjpeg;
-EXPORT_SYMBOL(support_mjpeg);
-module_param(support_mjpeg, bool, 0644);
-
-bool support_format_I420;
-EXPORT_SYMBOL(support_format_I420);
-module_param(support_format_I420, bool, 0644);
-
-int force_enable_nr;
-EXPORT_SYMBOL(force_enable_nr);
-module_param(force_enable_nr, int, 0644);
-
-int force_enable_di_local_buffer;
-EXPORT_SYMBOL(force_enable_di_local_buffer);
-module_param(force_enable_di_local_buffer, int, 0644);
-
-int vpp_bypass_frames;
-EXPORT_SYMBOL(vpp_bypass_frames);
-module_param(vpp_bypass_frames, int, 0644);
-
-int bypass_nr_flag;
-EXPORT_SYMBOL(bypass_nr_flag);
-module_param(bypass_nr_flag, int, 0644);
-
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("AML video codec V4L2 decoder driver");
 
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 522fe67..2e9e576 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -20,19 +20,14 @@
 #ifndef _AML_VCODEC_DRV_H_
 #define _AML_VCODEC_DRV_H_
 
-#include <linux/kref.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
-#include <linux/kfifo.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-core.h>
-#include <media/videobuf2-v4l2.h>
 #include <linux/amlogic/media/vfm/vframe.h>
-#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
 #include "aml_vcodec_util.h"
-#include "aml_vcodec_dec.h"
 
 #define AML_VCODEC_DRV_NAME	"aml_vcodec_drv"
 #define AML_VCODEC_DEC_NAME	"aml-vcodec-dec"
@@ -71,8 +66,6 @@
 #define V4L_CAP_BUFF_INVALID		(0)
 #define V4L_CAP_BUFF_IN_M2M		(1)
 #define V4L_CAP_BUFF_IN_DEC		(2)
-#define V4L_CAP_BUFF_IN_VPP		(3)
-#define V4L_CAP_BUFF_IN_GE2D		(4)
 
 /* v4l reset mode */
 #define V4L_RESET_MODE_NORMAL		(1 << 0) /* reset vdec_input and decoder. */
@@ -86,7 +79,6 @@
 /* Instance is currently aborting */
 #define TRANS_ABORT		(1 << 2)
 
-#define CTX_BUF_TOTAL(ctx) (ctx->dpb_size + ctx->vpp_size + ctx->ge2d_size)
 /**
  * enum aml_hw_reg_idx - AML hw register base index
  */
@@ -127,6 +119,7 @@
  * @AML_STATE_ACTIVE	- vdec is ready for work.
  * @AML_STATE_FLUSHING	- vdec is flushing. Only used by decoder
  * @AML_STATE_FLUSHED	- decoder has transacted the last frame.
+ * @AML_STATE_RESET	- decoder has be reset after flush.
  * @AML_STATE_ABORT	- vcodec should be aborted
  */
 enum aml_instance_state {
@@ -137,6 +130,7 @@
 	AML_STATE_ACTIVE,
 	AML_STATE_FLUSHING,
 	AML_STATE_FLUSHED,
+	AML_STATE_RESET,
 	AML_STATE_ABORT,
 };
 
@@ -162,10 +156,9 @@
  * struct aml_video_fmt - Structure used to store information about pixelformats
  */
 struct aml_video_fmt {
-	u32			fourcc;
+	u32	fourcc;
 	enum aml_fmt_type	type;
-	u32			num_planes;
-	const u8		*name;
+	u32	num_planes;
 };
 
 /**
@@ -190,13 +183,13 @@
  * struct aml_q_data - Structure used to store information about queue
  */
 struct aml_q_data {
-	u32	visible_width;
-	u32	visible_height;
-	u32	coded_width;
-	u32	coded_height;
+	unsigned int	visible_width;
+	unsigned int	visible_height;
+	unsigned int	coded_width;
+	unsigned int	coded_height;
 	enum v4l2_field	field;
-	u32	bytesperline[AML_VCODEC_MAX_PLANES];
-	u32	sizeimage[AML_VCODEC_MAX_PLANES];
+	unsigned int	bytesperline[AML_VCODEC_MAX_PLANES];
+	unsigned int	sizeimage[AML_VCODEC_MAX_PLANES];
 	struct aml_video_fmt	*fmt;
 	bool resolution_changed;
 };
@@ -221,19 +214,42 @@
  * @force_intra: force/insert intra frame
  */
 struct aml_enc_params {
-	u32	bitrate;
-	u32	num_b_frame;
-	u32	rc_frame;
-	u32	rc_mb;
-	u32	seq_hdr_mode;
-	u32	intra_period;
-	u32	gop_size;
-	u32	framerate_num;
-	u32	framerate_denom;
-	u32	h264_max_qp;
-	u32	h264_profile;
-	u32	h264_level;
-	u32	force_intra;
+	unsigned int	bitrate;
+	unsigned int	num_b_frame;
+	unsigned int	rc_frame;
+	unsigned int	rc_mb;
+	unsigned int	seq_hdr_mode;
+	unsigned int	intra_period;
+	unsigned int	gop_size;
+	unsigned int	framerate_num;
+	unsigned int	framerate_denom;
+	unsigned int	h264_max_qp;
+	unsigned int	h264_profile;
+	unsigned int	h264_level;
+	unsigned int	force_intra;
+};
+
+/**
+ * struct aml_vcodec_pm - Power management data structure
+ */
+struct aml_vcodec_pm {
+	struct clk	*vdec_bus_clk_src;
+	struct clk	*vencpll;
+
+	struct clk	*vcodecpll;
+	struct clk	*univpll_d2;
+	struct clk	*clk_cci400_sel;
+	struct clk	*vdecpll;
+	struct clk	*vdec_sel;
+	struct clk	*vencpll_d2;
+	struct clk	*venc_sel;
+	struct clk	*univpll1_d2;
+	struct clk	*venc_lt_sel;
+	struct device	*larbvdec;
+	struct device	*larbvenc;
+	struct device	*larbvenclt;
+	struct device	*dev;
+	struct aml_vcodec_dev	*amldev;
 };
 
 /**
@@ -250,38 +266,20 @@
  *		plane
  * E.g. suppose picture size is 176x144,
  *      buffer size will be aligned to 176x160.
- * @profile_idc: source profile level
  * @field: frame/field information.
- * @dpb_frames: used for DPB size of calculation.
- * @dpb_margin: extra buffers for decoder.
- * @vpp_margin: extra buffers for vpp.
  */
 struct vdec_pic_info {
-	u32 visible_width;
-	u32 visible_height;
-	u32 coded_width;
-	u32 coded_height;
-	u32 y_bs_sz;
-	u32 c_bs_sz;
-	u32 y_len_sz;
-	u32 c_len_sz;
+	unsigned int visible_width;
+	unsigned int visible_height;
+	unsigned int coded_width;
+	unsigned int coded_height;
+	unsigned int y_bs_sz;
+	unsigned int c_bs_sz;
+	unsigned int y_len_sz;
+	unsigned int c_len_sz;
 	int profile_idc;
+	int ref_frame_count;
 	enum v4l2_field field;
-	u32 dpb_frames;
-	u32 dpb_margin;
-	u32 vpp_margin;
-};
-
-/**
- * struct vdec_comp_buf_info - compressed buffer info
- * @max_size: max size needed for MMU Box in MB
- * @header_size: contineous size for the compressed header
- * @frame_buffer_size: SG page number to store the frame
- */
-struct vdec_comp_buf_info {
-	u32 max_size;
-	u32 header_size;
-	u32 frame_buffer_size;
 };
 
 struct aml_vdec_cfg_infos {
@@ -292,20 +290,6 @@
 	u32 canvas_mem_mode;
 	u32 canvas_mem_endian;
 	u32 low_latency_mode;
-	u32 uvm_hook_type;
-	/*
-	 * bit 16	: force progressive output flag.
-	 * bit 15	: enable nr.
-	 * bit 14	: enable di local buff.
-	 * bit 13	: report downscale yuv buffer size flag.
-	 * bit 12	: for second field pts mode.
-	 * bit 11	: disable error policy
-	 * bit 1	: Non-standard dv flag.
-	 * bit 0	: dv two layer flag.
-	 */
-	u32 metadata_config_flag; // for metadata config flag
-	u32 duration;
-	u32 data[4];
 };
 
 struct aml_vdec_hdr_infos {
@@ -339,10 +323,8 @@
 	u32 mb_height;
 	u32 dpb_size;
 	u32 ref_frames;
-	u32 dpb_frames;
-	u32 dpb_margin;
+	u32 reorder_frames;
 	u32 field;
-	u32 data[3];
 };
 
 struct aml_vdec_cnt_infos {
@@ -379,7 +361,7 @@
 	 */
 	u32 seq[V4L_CAP_BUFF_MAX];
 	u32 in, out;
-	u32 dec, vpp, ge2d;
+	u32 dec, vpp;
 };
 
 enum aml_thread_type {
@@ -390,203 +372,35 @@
 typedef void (*aml_thread_func)(struct aml_vcodec_ctx *ctx);
 
 struct aml_vdec_thread {
-	struct list_head	node;
-	spinlock_t		lock;
-	struct semaphore	sem;
-	struct task_struct	*task;
-	enum aml_thread_type	type;
-	void			*priv;
-	int			stop;
+	struct list_head node;
+	spinlock_t lock;
+	struct semaphore sem;
+	struct task_struct *task;
+	enum aml_thread_type type;
+	void *priv;
+	int stop;
 
-	aml_thread_func		func;
+	aml_thread_func func;
 };
 
-/* struct internal_comp_buf - compressed buffer
- * @index: index of this buf within (B)MMU BOX
- * @ref: [0-7]:reference number of this buf
- *       [8-15]: use for reuse.
- * @mmu_box: mmu_box of context
- * @bmmu_box: bmmu_box of context
- * @box_ref: box_ref of context
- * @header_addr: header for compressed buffer
- * @frame_buffer_size: SG buffer page number from
- * @priv_data use for video composer
- *  struct vdec_comp_buf_info
- */
-struct internal_comp_buf {
-	u32		index;
-	u32		ref;
-	void		*mmu_box;
-	void		*bmmu_box;
-	struct kref	*box_ref;
-
-	ulong		header_addr;
-	u32		header_size;
-	u32		frame_buffer_size;
-	struct file_private_data priv_data;
-	ulong	header_dw_addr;
-	void	*mmu_box_dw;
-	void	*bmmu_box_dw;
-};
-
-/*
- * struct aml_uvm_buff_ref - uvm buff is used reseve ctx ref count.
- * @index	: index of video buffer.
- * @addr	: physic address of video buffer.
- * @ref		: reference of v4ldec context.
- * @dma		: dma buf of associated with vb.
- */
-struct aml_uvm_buff_ref {
-	int		index;
-	ulong		addr;
-	struct kref	*ref;
-	struct dma_buf	*dbuf;
-};
-
-/*
- * enum aml_fb_requester - indicate which module request fb buffers.
- */
-enum aml_fb_requester {
-	AML_FB_REQ_DEC,
-	AML_FB_REQ_VPP,
-	AML_FB_REQ_GE2D,
-	AML_FB_REQ_MAX
-};
-
-/*
- * @query: try to achieved fb token.
- * @alloc: used for allocte fb buffer.
- */
-struct aml_fb_ops {
-	bool		(*query)(struct aml_fb_ops *, ulong *);
-	int		(*alloc)(struct aml_fb_ops *, ulong, struct vdec_v4l2_buffer **, u32);
-};
-
-/*
- * struct aml_fb_map_table - record some buffer map infos
- * @addr	: yuv linear buffer address.
- * @header_addr	: used for compress buffer.
- * @vframe	: which is from decoder or vpp vf pool.
- * @task	: context of task chain.
- * @icomp	: compress buffer index.
- */
-struct aml_fb_map_table {
-	ulong		addr;
-	ulong		header_addr;
-	struct vframe_s	*vframe;
-	struct task_chain_s *task;
-	u32		icomp;
-};
-
-/*
- * struct aux_data - record sei data and dv data
- * @sei_size:	sei data size.
- * @sei_buf:	sei data addr.
- * @sei_state:	sei buffer state. (0 free, 1 not used, 2 used)
- * @comp_buf:	stores comp data parsed from sei data.
- * @md_buf:	stores md data parsed from sei data.
- */
-struct aux_data {
-	int		sei_size;
-	char*		sei_buf;
-	int		sei_state;
-	char*		comp_buf;
-	char*		md_buf;
-};
-
-/*
- * struct aux_info - record aux data infos
- * @sei_index:		sei data index.
- * @dv_index:		dv data index.
- * @sei_need_free:	sei buffer need to free.
- * @bufs:		stores aux data.
- * @alloc_buffer:	alloc aux buffer functions.
- * @free_buffer:	free aux buffer functions.
- * @free_one_sei_buffer:free sei buffer with index functions.
- * @bind_sei_buffer:	bind sei buffer functions.
- * @bind_dv_buffer:	bind dv buffer functions.
- */
-struct aux_info {
-	int	sei_index;
-	int 	dv_index;
-	bool    sei_need_free;
-	struct aux_data bufs[V4L_CAP_BUFF_MAX];
-	void 	(*alloc_buffer)(struct aml_vcodec_ctx *ctx, int flag);
-	void 	(*free_buffer)(struct aml_vcodec_ctx *ctx, int flag);
-	void 	(*free_one_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int idx);
-	void 	(*bind_sei_buffer)(struct aml_vcodec_ctx *ctx, char **addr, int *size, int *idx);
-	void	(*bind_dv_buffer)(struct aml_vcodec_ctx *ctx, char **comp_buf, char **md_buf);
-};
-
-/*
- * struct meta_data - record meta data.
- * @buf[META_DATA_SIZE]: meta data information.
- */
-struct meta_data {
-	char buf[META_DATA_SIZE];
-};
-
-/*
- * struct meta_info - record some meta data infos
- * @index: meta data index.
- * @meta_bufs: record meta data.
- */
-struct meta_info {
-	int		index;
-	struct meta_data *meta_bufs;
-};
-
-/*
- * struct aml_vpp_cfg_infos - config vpp init param
- * @mode	: vpp work mode
- * @fmt		: picture format used to switch nv21 or nv12.
- * @buf_size: config buffer size for vpp
- * @is_drm	: is drm mode
- * @is_prog	: is a progressive source.
- * @is_bypass_p	: to set progressive bypass in vpp
- * @enable_nr	: enable nosie reduce.
- * @enable_local_buf: DI used buff alloc by itself.
- * @res_chg	: indicate resolution changed.
- * @is_vpp_reset: vpp reset just used to res chg.
- */
-struct aml_vpp_cfg_infos {
-	u32	mode;
-	u32	fmt;
-	u32	buf_size;
-	bool	is_drm;
-	bool	is_prog;
-	bool	is_bypass_p;
-	bool	enable_nr;
-	bool	enable_local_buf;
-	bool	res_chg;
-	bool	is_vpp_reset;
-};
-
-struct aml_ge2d_cfg_infos {
-	u32	mode;
-	u32	buf_size;
-	bool	is_drm;
-};
-
-/*
+/**
  * struct aml_vcodec_ctx - Context (instance) private data.
+ *
  * @id: index of the context that this structure describes.
- * @ctx_ref: for deferred free of this context.
  * @type: type of the instance - decoder or encoder.
  * @dev: pointer to the aml_vcodec_dev of the device.
  * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context.
  * @ada_ctx: pointer to the aml_vdec_adapt of the context.
- * @vpp: pointer to video post processor
  * @dec_if: hooked decoder driver interface.
  * @drv_handle: driver handle for specific decode instance
  * @fh: struct v4l2_fh.
  * @ctrl_hdl: handler for v4l2 framework.
  * @slock: protect v4l2 codec context.
- * @tsplock: protect the vdec thread context.
  * @empty_flush_buf: a fake size-0 capture buffer that indicates flush.
  * @list: link to ctx_list of aml_vcodec_dev.
  * @q_data: store information of input and output queue of the context.
  * @queue: waitqueue that can be used to wait for this context to finish.
+ * @lock: protect the vdec thread.
  * @state_lock: protect the codec status.
  * @state: state of the context.
  * @decode_work: decoder work be used to output buffer.
@@ -594,7 +408,6 @@
  * @cap_pool: capture buffers are remark in the pool.
  * @vdec_thread_list: vdec thread be used to capture.
  * @dpb_size: store dpb count after header parsing
- * @vpp_size: store vpp buffer count after header parsing
  * @param_change: indicate encode parameter type
  * @param_sets_from_ucode: if true indicate ps from ucode.
  * @v4l_codec_dpb_ready: queue buffer number greater than dpb.
@@ -617,46 +430,24 @@
  * @reset_flag: reset mode includes lightly and normal mode.
  * @decoded_frame_cnt: the capture buffer deque number to be count.
  * @buf_used_count: means that decode allocate how many buffs from v4l.
- * @wq: wait recycle dma buffer finish.
- * @cap_wq: the wq used for wait capture buffer.
- * @dmabuff_recycle_lock: protect the lock dmabuff free.
- * @dmabuff_recycle_work: used for recycle dmabuff.
- * @dmabuff_recycle: kfifo used for store vb buff.
- * @capture_buffer: kfifo used for store capture vb buff.
- * @mmu_box: mmu_box of context.
- * @bmmu_box: bmmu_box of context.
- * @box_ref: box_ref of context.
- * @comp_info: compress buffer information.
- * @comp_bufs: compress buffer describe.
- * @comp_lock: used for lock ibuf free cb.
- * @fb_ops: frame buffer ops interface.
- * @dv_infos: dv data information.
- * @vpp_cfg: vpp init parms of configuration.
- * @vdec_pic_info_update: update pic info cb.
- * @vpp_is_need: the instance is need vpp.
- * @task_chain_pool: used to store task chain inst.
- * @index_disp: the number of frames output.
  */
 struct aml_vcodec_ctx {
 	int				id;
-	struct kref			ctx_ref;
 	enum aml_instance_type		type;
 	struct aml_vcodec_dev		*dev;
 	struct v4l2_m2m_ctx		*m2m_ctx;
 	struct aml_vdec_adapt		*ada_ctx;
-	struct aml_v4l2_vpp		*vpp;
 	const struct vdec_common_if	*dec_if;
 	ulong				drv_handle;
 	struct v4l2_fh			fh;
 	struct v4l2_ctrl_handler	ctrl_hdl;
 	spinlock_t			slock;
-	spinlock_t			tsplock;
 	struct aml_video_dec_buf	*empty_flush_buf;
 	struct list_head		list;
 
 	struct aml_q_data		q_data[2];
 	wait_queue_head_t		queue;
-	struct mutex			state_lock;
+	struct mutex			lock, state_lock;
 	enum aml_instance_state		state;
 	struct work_struct		decode_work;
 	bool				output_thread_ready;
@@ -664,8 +455,6 @@
 	struct list_head		vdec_thread_list;
 
 	int				dpb_size;
-	int				vpp_size;
-	int				ge2d_size;
 	bool				param_sets_from_ucode;
 	bool				v4l_codec_dpb_ready;
 	bool				v4l_resolution_change;
@@ -678,7 +467,6 @@
 	enum v4l2_quantization		quantization;
 	enum v4l2_xfer_func		xfer_func;
 	u32				cap_pix_fmt;
-	u32				output_pix_fmt;
 
 	bool				has_receive_eos;
 	bool				is_drm_mode;
@@ -689,84 +477,81 @@
 	int				reset_flag;
 	int				decoded_frame_cnt;
 	int				buf_used_count;
-	wait_queue_head_t		wq, cap_wq, post_done_wq;
-	struct mutex			capture_buffer_lock;
-	spinlock_t			dmabuff_recycle_lock;
-	struct mutex			buff_done_lock;
-	struct work_struct		dmabuff_recycle_work;
-	DECLARE_KFIFO(dmabuff_recycle, struct vb2_v4l2_buffer *, 32);
-	DECLARE_KFIFO(capture_buffer, struct vb2_v4l2_buffer *, 32);
-
-	/* compressed buffer support */
-	void				*bmmu_box;
-	void				*mmu_box;
-	struct kref			box_ref;
-	struct vdec_comp_buf_info	comp_info;
-	struct internal_comp_buf	*comp_bufs;
-	struct uvm_hook_mod_info	*uvm_proxy;
-	struct mutex			comp_lock;
-
-	struct aml_fb_ops		fb_ops;
-	ulong				token_table[32];
-
-	struct aml_fb_map_table		fb_map[32];
-	struct aml_vpp_cfg_infos 	vpp_cfg;
-	void (*vdec_pic_info_update)(struct aml_vcodec_ctx *ctx);
-	bool				vpp_is_need;
-	struct list_head		task_chain_pool;
-	struct meta_info		meta_infos;
-	struct vdec_sync		*sync;
-	u32             		internal_dw_scale;
-
-	/* ge2d field. */
-	struct aml_v4l2_ge2d		*ge2d;
-	struct aml_ge2d_cfg_infos 	ge2d_cfg;
-	bool				ge2d_is_need;
-
-	bool 				second_field_pts_mode;
-	struct aux_info			aux_infos;
-	u32				index_disp;
-	bool				post_to_upper_done;
-	bool			film_grain_present;
-	void			*bmmu_box_dw;
-	void			*mmu_box_dw;
 };
 
 /**
- * struct aml_vcodec_dev - driver data.
- * @v4l2_dev		: V4L2 device to register video devices for.
- * @vfd_dec		: Video device for decoder.
- * @plat_dev		: platform device.
- * @m2m_dev_dec		: m2m device for decoder.
- * @curr_ctx		: The context that is waiting for codec hardware.
- * @id_counter		: used to identify current opened instance.
- * @dec_capability	: used to identify decode capability, ex: 4k
- * @decode_workqueue	: the worker used to output buffer schedule.
- * @ctx_list		: list of struct aml_vcodec_ctx.
- * @irqlock		: protect data access by irq handler and work thread.
- * @dev_mutex		: video_device lock.
- * @dec_mutex		: decoder hardware lock.
- * @queue		: waitqueue for waiting for completion of device commands.
- * @vpp_count		: count the number of open vpp.
- * @v4ldec_class	: creat class sysfs uesd to show some information.
+ * struct aml_vcodec_dev - driver data
+ * @v4l2_dev: V4L2 device to register video devices for.
+ * @vfd_dec: Video device for decoder
+ * @vfd_enc: Video device for encoder.
+ *
+ * @m2m_dev_dec: m2m device for decoder
+ * @m2m_dev_enc: m2m device for encoder.
+ * @plat_dev: platform device
+ * @vpu_plat_dev: aml vpu platform device
+ * @alloc_ctx: VB2 allocator context
+ *	       (for allocations without kernel mapping).
+ * @ctx_list: list of struct aml_vcodec_ctx
+ * @irqlock: protect data access by irq handler and work thread
+ * @curr_ctx: The context that is waiting for codec hardware
+ *
+ * @reg_base: Mapped address of AML Vcodec registers.
+ *
+ * @id_counter: used to identify current opened instance
+ *
+ * @encode_workqueue: encode work queue
+ *
+ * @int_cond: used to identify interrupt condition happen
+ * @int_type: used to identify what kind of interrupt condition happen
+ * @dev_mutex: video_device lock
+ * @queue: waitqueue for waiting for completion of device commands
+ *
+ * @dec_irq: decoder irq resource
+ * @enc_irq: h264 encoder irq resource
+ * @enc_lt_irq: vp8 encoder irq resource
+ *
+ * @dec_mutex: decoder hardware lock
+ * @enc_mutex: encoder hardware lock.
+ *
+ * @pm: power management control
+ * @dec_capability: used to identify decode capability, ex: 4k
+ * @enc_capability: used to identify encode capability
  */
 struct aml_vcodec_dev {
-	struct v4l2_device		v4l2_dev;
-	struct video_device		*vfd_dec;
-	struct platform_device		*plat_dev;
-	struct v4l2_m2m_dev		*m2m_dev_dec;
-	struct aml_vcodec_ctx		*curr_ctx;
-	ulong				id_counter;
-	u32				dec_capability;
-	struct workqueue_struct		*decode_workqueue;
-	struct list_head		ctx_list;
-	struct file			*filp;
-	spinlock_t			irqlock;
-	struct mutex			dev_mutex;
-	struct mutex			dec_mutex;
-	wait_queue_head_t		queue;
-	atomic_t			vpp_count;
-	struct class			v4ldec_class;
+	struct v4l2_device v4l2_dev;
+	struct video_device *vfd_dec;
+	struct video_device *vfd_enc;
+	struct file *filp;
+
+	struct v4l2_m2m_dev *m2m_dev_dec;
+	struct v4l2_m2m_dev *m2m_dev_enc;
+	struct platform_device *plat_dev;
+	struct platform_device *vpu_plat_dev;//??
+	struct vb2_alloc_ctx *alloc_ctx;//??
+	struct list_head ctx_list;
+	spinlock_t irqlock;
+	struct aml_vcodec_ctx *curr_ctx;
+	void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE];
+
+	unsigned long id_counter;
+
+	struct workqueue_struct *decode_workqueue;
+	struct workqueue_struct *encode_workqueue;
+	int int_cond;
+	int int_type;
+	struct mutex dev_mutex;
+	wait_queue_head_t queue;
+
+	int dec_irq;
+	int enc_irq;
+	int enc_lt_irq;
+
+	struct mutex dec_mutex;
+	struct mutex enc_mutex;
+
+	struct aml_vcodec_pm pm;
+	unsigned int dec_capability;
+	unsigned int enc_capability;
 };
 
 static inline struct aml_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
@@ -779,10 +564,4 @@
 	return container_of(ctrl->handler, struct aml_vcodec_ctx, ctrl_hdl);
 }
 
-void aml_thread_capture_worker(struct aml_vcodec_ctx *ctx);
-void aml_thread_post_task(struct aml_vcodec_ctx *ctx, enum aml_thread_type type);
-int aml_thread_start(struct aml_vcodec_ctx *ctx, aml_thread_func func,
-	enum aml_thread_type type, const char *thread_name);
-void aml_thread_stop(struct aml_vcodec_ctx *ctx);
-
 #endif /* _AML_VCODEC_DRV_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.c b/drivers/amvdec_ports/aml_vcodec_ge2d.c
deleted file mode 100644
index 2d331ed..0000000
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <linux/sched/clock.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/amlogic/meson_uvm_core.h>
-#include <linux/amlogic/media/ge2d/ge2d.h>
-#include <linux/amlogic/media/canvas/canvas_mgr.h>
-
-#include "../common/chips/decoder_cpu_ver_info.h"
-#include "aml_vcodec_ge2d.h"
-#include "aml_vcodec_adapt.h"
-#include "vdec_drv_if.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-#define GE2D_BUF_GET_IDX(ge2d_buf) (ge2d_buf->aml_buf->vb.vb2_buf.index)
-#define INPUT_PORT 0
-#define OUTPUT_PORT 1
-
-extern int dump_ge2d_input;
-extern int ge2d_bypass_frames;
-
-enum GE2D_FLAG {
-	GE2D_FLAG_P		= 0x1,
-	GE2D_FLAG_I		= 0x2,
-	GE2D_FLAG_EOS		= 0x4,
-	GE2D_FLAG_BUF_BY_PASS	= 0x8,
-	GE2D_FLAG_MAX		= 0x7FFFFFFF,
-};
-
-enum videocom_source_type {
-	DECODER_8BIT_NORMAL = 0,
-	DECODER_8BIT_BOTTOM,
-	DECODER_8BIT_TOP,
-	DECODER_10BIT_NORMAL,
-	DECODER_10BIT_BOTTOM,
-	DECODER_10BIT_TOP
-};
-
-#ifndef  CONFIG_AMLOGIC_MEDIA_GE2D
-inline void stretchblt_noalpha(struct ge2d_context_s *wq,
-		int src_x, int src_y, int src_w, int src_h,
-		int dst_x, int dst_y, int dst_w, int dst_h) { return; }
-inline int ge2d_context_config_ex(struct ge2d_context_s *context,
-		struct config_para_ex_s *ge2d_config) { return -1; }
-inline struct ge2d_context_s *create_ge2d_work_queue(void) { return NULL; }
-inline int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { return -1; }
-#endif
-
-static int get_source_type(struct vframe_s *vf)
-{
-	enum videocom_source_type ret;
-	int interlace_mode;
-
-	interlace_mode = vf->type & VIDTYPE_TYPEMASK;
-
-	if ((vf->bitdepth & BITDEPTH_Y10)  &&
-		(!(vf->type & VIDTYPE_COMPRESS)) &&
-		(get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) {
-		if (interlace_mode == VIDTYPE_INTERLACE_TOP)
-			ret = DECODER_10BIT_TOP;
-		else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
-			ret = DECODER_10BIT_BOTTOM;
-		else
-			ret = DECODER_10BIT_NORMAL;
-	} else {
-		if (interlace_mode == VIDTYPE_INTERLACE_TOP)
-			ret = DECODER_8BIT_TOP;
-		else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
-			ret = DECODER_8BIT_BOTTOM;
-		else
-			ret = DECODER_8BIT_NORMAL;
-	}
-
-	return ret;
-}
-
-static int get_input_format(struct vframe_s *vf)
-{
-	int format = GE2D_FORMAT_M24_YUV420;
-	enum videocom_source_type soure_type;
-
-	soure_type = get_source_type(vf);
-
-	switch (soure_type) {
-	case DECODER_8BIT_NORMAL:
-		if (vf->type & VIDTYPE_VIU_422)
-			format = GE2D_FORMAT_S16_YUV422;
-		else if (vf->type & VIDTYPE_VIU_NV21)
-			format = GE2D_FORMAT_M24_NV21;
-		else if (vf->type & VIDTYPE_VIU_NV12)
-			format = GE2D_FORMAT_M24_NV12;
-		else if (vf->type & VIDTYPE_VIU_444)
-			format = GE2D_FORMAT_S24_YUV444;
-		else
-			format = GE2D_FORMAT_M24_YUV420;
-		break;
-	case DECODER_8BIT_BOTTOM:
-		if (vf->type & VIDTYPE_VIU_422)
-			format = GE2D_FORMAT_S16_YUV422
-				| (GE2D_FORMAT_S16_YUV422B & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_NV21)
-			format = GE2D_FORMAT_M24_NV21
-				| (GE2D_FORMAT_M24_NV21B & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_NV12)
-			format = GE2D_FORMAT_M24_NV12
-				| (GE2D_FORMAT_M24_NV12B & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_444)
-			format = GE2D_FORMAT_S24_YUV444
-				| (GE2D_FORMAT_S24_YUV444B & (3 << 3));
-		else
-			format = GE2D_FORMAT_M24_YUV420
-				| (GE2D_FMT_M24_YUV420B & (3 << 3));
-		break;
-	case DECODER_8BIT_TOP:
-		if (vf->type & VIDTYPE_VIU_422)
-			format = GE2D_FORMAT_S16_YUV422
-				| (GE2D_FORMAT_S16_YUV422T & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_NV21)
-			format = GE2D_FORMAT_M24_NV21
-				| (GE2D_FORMAT_M24_NV21T & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_NV12)
-			format = GE2D_FORMAT_M24_NV12
-				| (GE2D_FORMAT_M24_NV12T & (3 << 3));
-		else if (vf->type & VIDTYPE_VIU_444)
-			format = GE2D_FORMAT_S24_YUV444
-				| (GE2D_FORMAT_S24_YUV444T & (3 << 3));
-		else
-			format = GE2D_FORMAT_M24_YUV420
-				| (GE2D_FMT_M24_YUV420T & (3 << 3));
-		break;
-	case DECODER_10BIT_NORMAL:
-		if (vf->type & VIDTYPE_VIU_422) {
-			if (vf->bitdepth & FULL_PACK_422_MODE)
-				format = GE2D_FORMAT_S16_10BIT_YUV422;
-			else
-				format = GE2D_FORMAT_S16_12BIT_YUV422;
-		}
-		break;
-	case DECODER_10BIT_BOTTOM:
-		if (vf->type & VIDTYPE_VIU_422) {
-			if (vf->bitdepth & FULL_PACK_422_MODE)
-				format = GE2D_FORMAT_S16_10BIT_YUV422
-					| (GE2D_FORMAT_S16_10BIT_YUV422B
-					& (3 << 3));
-			else
-				format = GE2D_FORMAT_S16_12BIT_YUV422
-					| (GE2D_FORMAT_S16_12BIT_YUV422B
-					& (3 << 3));
-		}
-		break;
-	case DECODER_10BIT_TOP:
-		if (vf->type & VIDTYPE_VIU_422) {
-			if (vf->bitdepth & FULL_PACK_422_MODE)
-				format = GE2D_FORMAT_S16_10BIT_YUV422
-					| (GE2D_FORMAT_S16_10BIT_YUV422T
-					& (3 << 3));
-			else
-				format = GE2D_FORMAT_S16_12BIT_YUV422
-					| (GE2D_FORMAT_S16_12BIT_YUV422T
-					& (3 << 3));
-		}
-		break;
-	default:
-		format = GE2D_FORMAT_M24_YUV420;
-	}
-	return format;
-}
-
-static int v4l_ge2d_empty_input_done(struct aml_v4l2_ge2d_buf *buf)
-{
-	struct aml_v4l2_ge2d *ge2d = buf->caller_data;
-	struct vdec_v4l2_buffer *fb = NULL;
-	bool eos = false;
-
-	if (!ge2d || !ge2d->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d ge2d:%px\n",
-			__func__, __LINE__, ge2d);
-		return -1;
-	}
-
-	fb 	= &buf->aml_buf->frame_buffer;
-	eos	= (buf->flag & GE2D_FLAG_EOS);
-
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
-		"ge2d_input done: vf:%px, idx: %d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
-		"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-		buf->vf,
-		buf->vf->index,
-		buf->vf->flag,
-		buf->flag,
-		eos ? "eos" : "",
-		buf->vf->timestamp,
-		kfifo_len(&ge2d->input),
-		kfifo_len(&ge2d->output),
-		kfifo_len(&ge2d->frame),
-		kfifo_len(&ge2d->in_done_q),
-		kfifo_len(&ge2d->out_done_q));
-
-	fb->task->recycle(fb->task, TASK_TYPE_GE2D);
-
-	kfifo_put(&ge2d->input, buf);
-
-	ATRACE_COUNTER("VC_IN_GE2D-1.recycle", fb->buf_idx);
-
-	return 0;
-}
-
-static int v4l_ge2d_fill_output_done(struct aml_v4l2_ge2d_buf *buf)
-{
-	struct aml_v4l2_ge2d *ge2d = buf->caller_data;
-	struct vdec_v4l2_buffer *fb = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	if (!ge2d || !ge2d->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d ge2d:%px\n",
-			__func__, __LINE__, ge2d);
-		return -1;
-	}
-
-	fb	= &buf->aml_buf->frame_buffer;
-	eos	= (buf->flag & GE2D_FLAG_EOS);
-	bypass	= (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-
-	/* recovery fb handle. */
-	buf->vf->v4l_mem_handle = (ulong)fb;
-
-	kfifo_put(&ge2d->out_done_q, buf);
-
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
-		"ge2d_output done: vf:%px, idx:%d, flag(vf:%x ge2d:%x) %s, ts:%lld, "
-		"in:%d, out:%d, vf:%d, in done:%d, out done:%d, wxh:%ux%u\n",
-		buf->vf,
-		buf->vf->index,
-		buf->vf->flag,
-		buf->flag,
-		eos ? "eos" : "",
-		buf->vf->timestamp,
-		kfifo_len(&ge2d->input),
-		kfifo_len(&ge2d->output),
-		kfifo_len(&ge2d->frame),
-		kfifo_len(&ge2d->in_done_q),
-		kfifo_len(&ge2d->out_done_q),
-		buf->vf->width, buf->vf->height);
-
-	ATRACE_COUNTER("VC_OUT_GE2D-2.submit", fb->buf_idx);
-
-	fb->task->submit(fb->task, TASK_TYPE_GE2D);
-
-	ge2d->out_num[OUTPUT_PORT]++;
-
-	return 0;
-}
-
-static void ge2d_vf_get(void *caller, struct vframe_s **vf_out)
-{
-	struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
-	struct aml_v4l2_ge2d_buf *buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	struct vframe_s *vf = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	if (!ge2d || !ge2d->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d ge2d:%px\n",
-			__func__, __LINE__, ge2d);
-		return;
-	}
-
-	if (kfifo_get(&ge2d->out_done_q, &buf)) {
-		fb	= &buf->aml_buf->frame_buffer;
-		eos	= (buf->flag & GE2D_FLAG_EOS);
-		bypass	= (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-		vf	= buf->vf;
-
-		if (eos) {
-			v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
-				"%s %d got eos\n",
-				__func__, __LINE__);
-			vf->type |= VIDTYPE_V4L_EOS;
-			vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-		}
-
-		*vf_out = vf;
-
-		ATRACE_COUNTER("VC_OUT_GE2D-3.vf_get", fb->buf_idx);
-
-		v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
-			"%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld, type:%x, wxh:%ux%u\n",
-			__func__, vf,
-			vf->index,
-			vf->flag,
-			buf->flag,
-			vf->timestamp, vf->type, vf->width, vf->height);
-	}
-}
-
-static void ge2d_vf_put(void *caller, struct vframe_s *vf)
-{
-	struct aml_v4l2_ge2d *ge2d = (struct aml_v4l2_ge2d *)caller;
-	struct vdec_v4l2_buffer *fb = NULL;
-	struct aml_video_dec_buf *aml_buf = NULL;
-	struct aml_v4l2_ge2d_buf *buf = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	fb	= (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
-	aml_buf	= container_of(fb, struct aml_video_dec_buf, frame_buffer);
-	buf	= (struct aml_v4l2_ge2d_buf *) aml_buf->ge2d_buf_handle;
-	eos	= (buf->flag & GE2D_FLAG_EOS);
-	bypass	= (buf->flag & GE2D_FLAG_BUF_BY_PASS);
-
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
-		"%s: vf:%px, index:%d, flag(vf:%x ge2d:%x), ts:%lld\n",
-		__func__, vf,
-		vf->index,
-		vf->flag,
-		buf->flag,
-		vf->timestamp);
-
-	ATRACE_COUNTER("VC_IN_GE2D-0.vf_put", fb->buf_idx);
-
-	mutex_lock(&ge2d->output_lock);
-	kfifo_put(&ge2d->frame, vf);
-	kfifo_put(&ge2d->output, buf);
-	mutex_unlock(&ge2d->output_lock);
-	up(&ge2d->sem_out);
-}
-
-static int aml_v4l2_ge2d_thread(void* param)
-{
-	struct aml_v4l2_ge2d* ge2d = param;
-	struct aml_vcodec_ctx *ctx = ge2d->ctx;
-	struct config_para_ex_s ge2d_config;
-	u32 src_fmt = 0, dst_fmt = 0;
-	struct canvas_s cd;
-	ulong start_time;
-
-	v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "enter ge2d thread\n");
-	while (ge2d->running) {
-		struct aml_v4l2_ge2d_buf *in_buf;
-		struct aml_v4l2_ge2d_buf *out_buf = NULL;
-		struct vframe_s *vf_out = NULL;
-		struct vdec_v4l2_buffer *fb;
-
-		if (down_interruptible(&ge2d->sem_in))
-			goto exit;
-retry:
-		if (!ge2d->running)
-			break;
-
-		if (kfifo_is_empty(&ge2d->output)) {
-			if (down_interruptible(&ge2d->sem_out))
-				goto exit;
-			goto retry;
-		}
-
-		mutex_lock(&ge2d->output_lock);
-		if (!kfifo_get(&ge2d->output, &out_buf)) {
-			mutex_unlock(&ge2d->output_lock);
-			v4l_dbg(ctx, 0, "ge2d can not get output\n");
-			goto exit;
-		}
-		mutex_unlock(&ge2d->output_lock);
-
-		/* bind v4l2 buffers */
-		if (!out_buf->aml_buf) {
-			struct vdec_v4l2_buffer *out;
-
-			if (!ctx->fb_ops.query(&ctx->fb_ops, &ge2d->fb_token)) {
-				usleep_range(500, 550);
-				mutex_lock(&ge2d->output_lock);
-				kfifo_put(&ge2d->output, out_buf);
-				mutex_unlock(&ge2d->output_lock);
-				goto retry;
-			}
-
-			if (ctx->fb_ops.alloc(&ctx->fb_ops, ge2d->fb_token, &out, AML_FB_REQ_GE2D)) {
-				usleep_range(5000, 5500);
-				mutex_lock(&ge2d->output_lock);
-				kfifo_put(&ge2d->output, out_buf);
-				mutex_unlock(&ge2d->output_lock);
-				goto retry;
-			}
-
-			out_buf->aml_buf = container_of(out,
-				struct aml_video_dec_buf, frame_buffer);
-			out_buf->aml_buf->ge2d_buf_handle = (ulong) out_buf;
-			v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
-				"ge2d bind buf:%d to ge2d_buf:%px\n",
-				GE2D_BUF_GET_IDX(out_buf), out_buf);
-
-			out->m.mem[0].bytes_used = out->m.mem[0].size;
-			out->m.mem[1].bytes_used = out->m.mem[1].size;
-		}
-
-		/* safe to pop in_buf */
-		if (!kfifo_get(&ge2d->in_done_q, &in_buf)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"ge2d can not get input\n");
-			goto exit;
-		}
-
-		mutex_lock(&ge2d->output_lock);
-		if (!kfifo_get(&ge2d->frame, &vf_out)) {
-			mutex_unlock(&ge2d->output_lock);
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"ge2d can not get frame\n");
-			goto exit;
-		}
-		mutex_unlock(&ge2d->output_lock);
-
-		fb = &out_buf->aml_buf->frame_buffer;
-		fb->status = FB_ST_GE2D;
-
-		/* fill output vframe information. */
-		memcpy(vf_out, in_buf->vf, sizeof(*vf_out));
-		memcpy(vf_out->canvas0_config,
-			in_buf->vf->canvas0_config,
-			2 * sizeof(struct canvas_config_s));
-
-		vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
-		if (fb->num_planes == 1) {
-			vf_out->canvas0_config[1].phy_addr =
-				fb->m.mem[0].addr + fb->m.mem[0].offset;
-			vf_out->canvas0_config[2].phy_addr =
-				fb->m.mem[0].addr + fb->m.mem[0].offset
-				+ (fb->m.mem[0].offset >> 2);
-		} else {
-			vf_out->canvas0_config[1].phy_addr =
-				fb->m.mem[1].addr;
-			vf_out->canvas0_config[2].phy_addr =
-				fb->m.mem[2].addr;
-		}
-
-		/* fill outbuf parms. */
-		out_buf->vf		= vf_out;
-		out_buf->flag		= 0;
-		out_buf->caller_data	= ge2d;
-
-		/* fill inbuf parms. */
-		in_buf->caller_data	= ge2d;
-
-		memset(&ge2d_config, 0, sizeof(ge2d_config));
-
-		src_fmt = get_input_format(in_buf->vf);
-		if (in_buf->vf->canvas0_config[0].endian == 7)
-			src_fmt |= GE2D_BIG_ENDIAN;
-		else
-			src_fmt |= GE2D_LITTLE_ENDIAN;
-
-		/* negotiate format of destination */
-		dst_fmt = get_input_format(in_buf->vf);
-		if (ge2d->work_mode & GE2D_MODE_CONVERT_NV12)
-			dst_fmt |= GE2D_FORMAT_M24_NV12;
-		else if (ge2d->work_mode & GE2D_MODE_CONVERT_NV21)
-			dst_fmt |= GE2D_FORMAT_M24_NV21;
-
-		if (ge2d->work_mode & GE2D_MODE_CONVERT_LE)
-			dst_fmt |= GE2D_LITTLE_ENDIAN;
-		else
-			dst_fmt |= GE2D_BIG_ENDIAN;
-
-		if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV12) {
-			vf_out->type |= VIDTYPE_VIU_NV12;
-			vf_out->type &= ~VIDTYPE_VIU_NV21;
-		} else if ((dst_fmt & GE2D_COLOR_MAP_MASK) == GE2D_COLOR_MAP_NV21) {
-			vf_out->type |= VIDTYPE_VIU_NV21;
-			vf_out->type &= ~VIDTYPE_VIU_NV12;
-		}
-		if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_LITTLE_ENDIAN) {
-			vf_out->canvas0_config[0].endian = 0;
-			vf_out->canvas0_config[1].endian = 0;
-			vf_out->canvas0_config[2].endian = 0;
-		} else if ((dst_fmt & GE2D_ENDIAN_MASK) == GE2D_BIG_ENDIAN){
-			vf_out->canvas0_config[0].endian = 7;
-			vf_out->canvas0_config[1].endian = 7;
-			vf_out->canvas0_config[2].endian = 7;
-		}
-
-		start_time = local_clock();
-		/* src canvas configure. */
-		if ((in_buf->vf->canvas0Addr == 0) ||
-			(in_buf->vf->canvas0Addr == (u32)-1)) {
-			canvas_config_config(ge2d->src_canvas_id[0], &in_buf->vf->canvas0_config[0]);
-			canvas_config_config(ge2d->src_canvas_id[1], &in_buf->vf->canvas0_config[1]);
-			canvas_config_config(ge2d->src_canvas_id[2], &in_buf->vf->canvas0_config[2]);
-			ge2d_config.src_para.canvas_index =
-				ge2d->src_canvas_id[0] |
-				ge2d->src_canvas_id[1] << 8 |
-				ge2d->src_canvas_id[2] << 16;
-
-			ge2d_config.src_planes[0].addr =
-				in_buf->vf->canvas0_config[0].phy_addr;
-			ge2d_config.src_planes[0].w =
-				in_buf->vf->canvas0_config[0].width;
-			ge2d_config.src_planes[0].h =
-				in_buf->vf->canvas0_config[0].height;
-			ge2d_config.src_planes[1].addr =
-				in_buf->vf->canvas0_config[1].phy_addr;
-			ge2d_config.src_planes[1].w =
-				in_buf->vf->canvas0_config[1].width;
-			ge2d_config.src_planes[1].h =
-				in_buf->vf->canvas0_config[1].height;
-			ge2d_config.src_planes[2].addr =
-				in_buf->vf->canvas0_config[2].phy_addr;
-			ge2d_config.src_planes[2].w =
-				in_buf->vf->canvas0_config[2].width;
-			ge2d_config.src_planes[2].h =
-				in_buf->vf->canvas0_config[2].height;
-		} else {
-			ge2d_config.src_para.canvas_index = in_buf->vf->canvas0Addr;
-		}
-		ge2d_config.src_para.mem_type	= CANVAS_TYPE_INVALID;
-		ge2d_config.src_para.format	= src_fmt;
-		ge2d_config.src_para.fill_color_en = 0;
-		ge2d_config.src_para.fill_mode	= 0;
-		ge2d_config.src_para.x_rev	= 0;
-		ge2d_config.src_para.y_rev	= 0;
-		ge2d_config.src_para.color	= 0xffffffff;
-		ge2d_config.src_para.top	= 0;
-		ge2d_config.src_para.left	= 0;
-		ge2d_config.src_para.width	= in_buf->vf->width;
-		if (in_buf->vf->type & VIDTYPE_INTERLACE)
-			ge2d_config.src_para.height = in_buf->vf->height >> 1;
-		else
-			ge2d_config.src_para.height = in_buf->vf->height;
-
-		/* dst canvas configure. */
-		canvas_config_config(ge2d->dst_canvas_id[0], &vf_out->canvas0_config[0]);
-		if ((ge2d_config.src_para.format & 0xfffff) == GE2D_FORMAT_M24_YUV420) {
-			vf_out->canvas0_config[1].width <<= 1;
-		}
-		canvas_config_config(ge2d->dst_canvas_id[1], &vf_out->canvas0_config[1]);
-		canvas_config_config(ge2d->dst_canvas_id[2], &vf_out->canvas0_config[2]);
-		ge2d_config.dst_para.canvas_index =
-			ge2d->dst_canvas_id[0] |
-			ge2d->dst_canvas_id[1] << 8;
-		canvas_read(ge2d->dst_canvas_id[0], &cd);
-		ge2d_config.dst_planes[0].addr	= cd.addr;
-		ge2d_config.dst_planes[0].w	= cd.width;
-		ge2d_config.dst_planes[0].h	= cd.height;
-		canvas_read(ge2d->dst_canvas_id[1], &cd);
-		ge2d_config.dst_planes[1].addr	= cd.addr;
-		ge2d_config.dst_planes[1].w	= cd.width;
-		ge2d_config.dst_planes[1].h	= cd.height;
-
-		ge2d_config.dst_para.format	=  dst_fmt;
-		ge2d_config.dst_para.width	= in_buf->vf->width;
-		ge2d_config.dst_para.height	= in_buf->vf->height;
-		ge2d_config.dst_para.mem_type	= CANVAS_TYPE_INVALID;
-		ge2d_config.dst_para.fill_color_en = 0;
-		ge2d_config.dst_para.fill_mode	= 0;
-		ge2d_config.dst_para.x_rev	= 0;
-		ge2d_config.dst_para.y_rev	= 0;
-		ge2d_config.dst_para.color	= 0;
-		ge2d_config.dst_para.top	= 0;
-		ge2d_config.dst_para.left	= 0;
-
-		/* other ge2d parameters configure. */
-		ge2d_config.src_key.key_enable	= 0;
-		ge2d_config.src_key.key_mask	= 0;
-		ge2d_config.src_key.key_mode	= 0;
-		ge2d_config.alu_const_color	= 0;
-		ge2d_config.bitmask_en		= 0;
-		ge2d_config.src1_gb_alpha	= 0;
-		ge2d_config.dst_xy_swap		= 0;
-		ge2d_config.src2_para.mem_type	= CANVAS_TYPE_INVALID;
-
-		ATRACE_COUNTER("VC_OUT_GE2D-1.handle_start",
-			in_buf->aml_buf->frame_buffer.buf_idx);
-
-		v4l_dbg(ctx, V4L_DEBUG_GE2D_BUFMGR,
-			"ge2d_handle start: dec vf:%px/%d, ge2d vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, vf:%ux%u, fmt(src:%x, dst:%x), "
-			"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-			in_buf->vf, in_buf->vf->index,
-			out_buf->vf, GE2D_BUF_GET_IDX(out_buf),
-			in_buf->vf->canvas0_config[0].phy_addr,
-			in_buf->vf->canvas0_config[1].phy_addr,
-			in_buf->vf->canvas0_config[0].width,
-			in_buf->vf->canvas0_config[0].height,
-			vf_out->canvas0_config[0].phy_addr,
-			vf_out->canvas0_config[1].phy_addr,
-			vf_out->canvas0_config[0].width,
-			vf_out->canvas0_config[0].height,
-			vf_out->width, vf_out->height,
-			src_fmt, dst_fmt,
-			kfifo_len(&ge2d->input),
-			kfifo_len(&ge2d->output),
-			kfifo_len(&ge2d->frame),
-			kfifo_len(&ge2d->in_done_q),
-			kfifo_len(&ge2d->out_done_q));
-
-		if (ge2d_context_config_ex(ge2d->ge2d_context, &ge2d_config) < 0) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"ge2d_context_config_ex error.\n");
-			goto exit;
-		}
-
-		if (!(in_buf->flag & GE2D_FLAG_EOS)) {
-			if (in_buf->vf->type & VIDTYPE_INTERLACE) {
-				stretchblt_noalpha(ge2d->ge2d_context,
-					0, 0, in_buf->vf->width, in_buf->vf->height / 2,
-					0, 0, in_buf->vf->width, in_buf->vf->height);
-			} else {
-				stretchblt_noalpha(ge2d->ge2d_context,
-					0, 0, in_buf->vf->width, in_buf->vf->height,
-					0, 0, in_buf->vf->width, in_buf->vf->height);
-			}
-		}
-
-		//pr_info("consume time %d us\n", div64_u64(local_clock() - start_time, 1000));
-
-		v4l_ge2d_fill_output_done(out_buf);
-		v4l_ge2d_empty_input_done(in_buf);
-
-		ge2d->in_num[INPUT_PORT]++;
-		ge2d->out_num[INPUT_PORT]++;
-	}
-exit:
-	while (!kthread_should_stop()) {
-		usleep_range(1000, 2000);
-	}
-
-	v4l_dbg(ctx, V4L_DEBUG_GE2D_DETAIL, "exit ge2d thread\n");
-
-	return 0;
-}
-
-int aml_v4l2_ge2d_get_buf_num(u32 mode)
-{
-	return 4;
-}
-
-int aml_v4l2_ge2d_init(
-		struct aml_vcodec_ctx *ctx,
-		struct aml_ge2d_cfg_infos *cfg,
-		struct aml_v4l2_ge2d** ge2d_handle)
-{
-	struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
-	struct aml_v4l2_ge2d *ge2d;
-	u32 work_mode = cfg->mode;
-	u32 buf_size;
-	int i, ret;
-
-	if (!cfg || !ge2d_handle)
-		return -EINVAL;
-
-	ge2d = kzalloc(sizeof(*ge2d), GFP_KERNEL);
-	if (!ge2d)
-		return -ENOMEM;
-
-	ge2d->work_mode = work_mode;
-
-	/* default convert little endian. */
-	if (!ge2d->work_mode) {
-		ge2d->work_mode = GE2D_MODE_CONVERT_LE;
-	}
-
-	ge2d->ge2d_context = create_ge2d_work_queue();
-	if (!ge2d->ge2d_context) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"ge2d_create_instance fail\n");
-		ret = -EINVAL;
-		goto error;
-	}
-
-	INIT_KFIFO(ge2d->input);
-	INIT_KFIFO(ge2d->output);
-	INIT_KFIFO(ge2d->frame);
-	INIT_KFIFO(ge2d->out_done_q);
-	INIT_KFIFO(ge2d->in_done_q);
-
-	ge2d->ctx = ctx;
-	buf_size = cfg->buf_size;
-	ge2d->buf_size = buf_size;
-
-	/* setup output fifo */
-	ret = kfifo_alloc(&ge2d->output, buf_size, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc output fifo fail.\n");
-		ret = -ENOMEM;
-		goto error2;
-	}
-
-	ge2d->ovbpool = vzalloc(buf_size * sizeof(*ge2d->ovbpool));
-	if (!ge2d->ovbpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc output vb pool fail.\n");
-		ret = -ENOMEM;
-		goto error3;
-	}
-
-	/* setup vframe fifo */
-	ret = kfifo_alloc(&ge2d->frame, buf_size, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc ge2d vframe fifo fail.\n");
-		ret = -ENOMEM;
-		goto error4;
-	}
-
-	ge2d->vfpool = vzalloc(buf_size * sizeof(*ge2d->vfpool));
-	if (!ge2d->vfpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc vf pool fail.\n");
-		ret = -ENOMEM;
-		goto error5;
-	}
-
-	ret = kfifo_alloc(&ge2d->input, GE2D_FRAME_SIZE, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc input fifo fail.\n");
-		ret = -ENOMEM;
-		goto error6;
-	}
-
-	ge2d->ivbpool = vzalloc(GE2D_FRAME_SIZE * sizeof(*ge2d->ivbpool));
-	if (!ge2d->ivbpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc input vb pool fail.\n");
-		ret = -ENOMEM;
-		goto error7;
-	}
-
-	for (i = 0 ; i < GE2D_FRAME_SIZE ; i++) {
-		kfifo_put(&ge2d->input, &ge2d->ivbpool[i]);
-	}
-
-	for (i = 0 ; i < buf_size ; i++) {
-		kfifo_put(&ge2d->output, &ge2d->ovbpool[i]);
-		kfifo_put(&ge2d->frame, &ge2d->vfpool[i]);
-	}
-
-	ge2d->src_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	ge2d->src_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	ge2d->src_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	ge2d->dst_canvas_id[0] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	ge2d->dst_canvas_id[1] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	ge2d->dst_canvas_id[2] = canvas_pool_map_alloc_canvas("v4ldec-ge2d");
-	if ((ge2d->src_canvas_id[0] <= 0) ||
-		(ge2d->src_canvas_id[1] <= 0) ||
-		(ge2d->src_canvas_id[2] <= 0) ||
-		(ge2d->dst_canvas_id[0] <= 0) ||
-		(ge2d->dst_canvas_id[1] <= 0) ||
-		(ge2d->dst_canvas_id[2] <= 0)) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"canvas pool alloc fail. src(%d, %d, %d) dst(%d, %d, %d).\n",
-			ge2d->src_canvas_id[0],
-			ge2d->src_canvas_id[1],
-			ge2d->src_canvas_id[2],
-			ge2d->dst_canvas_id[0],
-			ge2d->dst_canvas_id[1],
-			ge2d->dst_canvas_id[2]);
-		goto error8;
-	}
-
-	mutex_init(&ge2d->output_lock);
-	sema_init(&ge2d->sem_in, 0);
-	sema_init(&ge2d->sem_out, 0);
-
-	ge2d->running = true;
-	ge2d->task = kthread_run(aml_v4l2_ge2d_thread, ge2d,
-		"%s", "aml-v4l2-ge2d");
-	if (IS_ERR(ge2d->task)) {
-		ret = PTR_ERR(ge2d->task);
-		goto error9;
-	}
-	sched_setscheduler_nocheck(ge2d->task, SCHED_FIFO, &param);
-
-	*ge2d_handle = ge2d;
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"GE2D_CFG bsize:%d, wkm:%x, bm:%x, drm:%d\n",
-		ge2d->buf_size,
-		ge2d->work_mode,
-		ge2d->buffer_mode,
-		cfg->is_drm);
-
-	return 0;
-
-error9:
-	if (ge2d->src_canvas_id[0] > 0)
-		canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
-	if (ge2d->src_canvas_id[1] > 0)
-		canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
-	if (ge2d->src_canvas_id[2] > 0)
-		canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
-	if (ge2d->dst_canvas_id[0] > 0)
-		canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
-	if (ge2d->dst_canvas_id[1] > 0)
-		canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
-	if (ge2d->dst_canvas_id[2] > 0)
-		canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
-error8:
-	vfree(ge2d->ivbpool);
-error7:
-	kfifo_free(&ge2d->input);
-error6:
-	vfree(ge2d->vfpool);
-error5:
-	kfifo_free(&ge2d->frame);
-error4:
-	vfree(ge2d->ovbpool);
-error3:
-	kfifo_free(&ge2d->output);
-error2:
-	destroy_ge2d_work_queue(ge2d->ge2d_context);
-error:
-	kfree(ge2d);
-
-	return ret;
-}
-EXPORT_SYMBOL(aml_v4l2_ge2d_init);
-
-int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d)
-{
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
-		"ge2d destroy begin\n");
-
-	ge2d->running = false;
-	up(&ge2d->sem_in);
-	up(&ge2d->sem_out);
-	kthread_stop(ge2d->task);
-
-	destroy_ge2d_work_queue(ge2d->ge2d_context);
-	/* no more ge2d callback below this line */
-
-	kfifo_free(&ge2d->frame);
-	vfree(ge2d->vfpool);
-	kfifo_free(&ge2d->output);
-	vfree(ge2d->ovbpool);
-	kfifo_free(&ge2d->input);
-	vfree(ge2d->ivbpool);
-	mutex_destroy(&ge2d->output_lock);
-
-	canvas_pool_map_free_canvas(ge2d->src_canvas_id[0]);
-	canvas_pool_map_free_canvas(ge2d->src_canvas_id[1]);
-	canvas_pool_map_free_canvas(ge2d->src_canvas_id[2]);
-	canvas_pool_map_free_canvas(ge2d->dst_canvas_id[0]);
-	canvas_pool_map_free_canvas(ge2d->dst_canvas_id[1]);
-	canvas_pool_map_free_canvas(ge2d->dst_canvas_id[2]);
-
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_DETAIL,
-		"ge2d destroy done\n");
-
-	kfree(ge2d);
-
-	return 0;
-}
-EXPORT_SYMBOL(aml_v4l2_ge2d_destroy);
-
-static int aml_v4l2_ge2d_push_vframe(struct aml_v4l2_ge2d* ge2d, struct vframe_s *vf)
-{
-	struct aml_v4l2_ge2d_buf* in_buf;
-	struct vdec_v4l2_buffer *fb = NULL;
-
-	if (!ge2d)
-		return -EINVAL;
-
-	if (!kfifo_get(&ge2d->input, &in_buf)) {
-		v4l_dbg(ge2d->ctx, V4L_DEBUG_CODEC_ERROR,
-			"cat not get free input buffer.\n");
-		return -1;
-	}
-
-	if (vf->type & VIDTYPE_V4L_EOS)
-		in_buf->flag |= GE2D_FLAG_EOS;
-
-	v4l_dbg(ge2d->ctx, V4L_DEBUG_GE2D_BUFMGR,
-		"ge2d_push_vframe: vf:%px, idx:%d, type:%x, ts:%lld\n",
-		vf, vf->index, vf->type, vf->timestamp);
-
-	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
-	in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-	in_buf->vf = vf;
-
-	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
-		struct file *fp;
-
-		if (!dump_ge2d_input || ge2d->ctx->is_drm_mode)
-			break;
-
-		if (vdec_if_get_param(ge2d->ctx, GET_PARAM_DW_MODE, &dw_mode))
-			break;
-
-		if (dw_mode == VDEC_DW_AFBC_ONLY)
-			break;
-
-		fp = filp_open("/data/dec_dump_before.raw",
-				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
-		if (!IS_ERR(fp)) {
-			struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
-
-			kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
-			if (in_buf->aml_buf->frame_buffer.num_planes == 2)
-				kernel_write(fp,vb2_plane_vaddr(vb, 1),
-						vb->planes[1].length, 0);
-			dump_ge2d_input--;
-			filp_close(fp, NULL);
-		}
-	} while(0);
-
-	ATRACE_COUNTER("VC_OUT_GE2D-0.receive", fb->buf_idx);
-
-	kfifo_put(&ge2d->in_done_q, in_buf);
-	up(&ge2d->sem_in);
-
-	return 0;
-}
-
-static void fill_ge2d_buf_cb(void *v4l_ctx, void *fb_ctx)
-{
-	struct aml_vcodec_ctx *ctx =
-		(struct aml_vcodec_ctx *)v4l_ctx;
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)fb_ctx;
-	int ret = -1;
-
-	ret = aml_v4l2_ge2d_push_vframe(ctx->ge2d, fb->vframe);
-	if (ret < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"ge2d push vframe err, ret: %d\n", ret);
-	}
-}
-
-static struct task_ops_s ge2d_ops = {
-	.type		= TASK_TYPE_GE2D,
-	.get_vframe	= ge2d_vf_get,
-	.put_vframe	= ge2d_vf_put,
-	.fill_buffer	= fill_ge2d_buf_cb,
-};
-
-struct task_ops_s *get_ge2d_ops(void)
-{
-	return &ge2d_ops;
-}
-EXPORT_SYMBOL(get_ge2d_ops);
-
diff --git a/drivers/amvdec_ports/aml_vcodec_ge2d.h b/drivers/amvdec_ports/aml_vcodec_ge2d.h
deleted file mode 100644
index a12931d..0000000
--- a/drivers/amvdec_ports/aml_vcodec_ge2d.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef _AML_VCODEC_GE2D_H_
-#define _AML_VCODEC_GE2D_H_
-
-#include <linux/kfifo.h>
-#include "aml_vcodec_drv.h"
-#include "aml_vcodec_dec.h"
-
-/* define ge2d work mode. */
-#define GE2D_MODE_CONVERT_NV12		(1 << 0)
-#define GE2D_MODE_CONVERT_NV21		(1 << 1)
-#define GE2D_MODE_CONVERT_LE		(1 << 2)
-#define GE2D_MODE_CONVERT_BE		(1 << 3)
-#define GE2D_MODE_SEPARATE_FIELD	(1 << 4)
-#define GE2D_MODE_422_TO_420		(1 << 5)
-
-#define GE2D_FRAME_SIZE 64
-
-struct aml_v4l2_ge2d_buf {
-	u32			flag;
-	struct vframe_s		*vf;
-	void			*caller_data;
-	struct aml_video_dec_buf *aml_buf;
-};
-
-struct aml_v4l2_ge2d {
-	struct ge2d_context_s	*ge2d_context; /* handle of GE2D */
-	u32			buf_size; /* buffer size for ge2d */
-	u32			work_mode; /* enum ge2d_work_mode */
-	u32			buffer_mode;
-	struct aml_vcodec_ctx	*ctx;
-
-	DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_ge2d_buf*));
-	DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_ge2d_buf*));
-	DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *));
-	DECLARE_KFIFO(out_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE);
-	DECLARE_KFIFO(in_done_q, struct aml_v4l2_ge2d_buf *, GE2D_FRAME_SIZE);
-
-	struct vframe_s		*vfpool;
-	struct aml_v4l2_ge2d_buf *ovbpool;
-	struct aml_v4l2_ge2d_buf *ivbpool;
-	struct task_struct	*task;
-	bool			running;
-	struct semaphore	sem_in, sem_out;
-
-	/* In p to i transition, output/frame can be multi writer */
-	struct mutex		output_lock;
-
-	/* for debugging */
-	/*
-	 * in[0] --> ge2d <-- in[1]
-	 * out[0]<-- ge2d --> out[1]
-	 */
-	int			in_num[2];
-	int			out_num[2];
-	ulong			fb_token;
-
-	int			src_canvas_id[3];
-	int			dst_canvas_id[3];
-};
-
-struct task_ops_s *get_ge2d_ops(void);
-
-int aml_v4l2_ge2d_init(
-		struct aml_vcodec_ctx *ctx,
-		struct aml_ge2d_cfg_infos *cfg,
-		struct aml_v4l2_ge2d** ge2d_handle);
-
-int aml_v4l2_ge2d_destroy(struct aml_v4l2_ge2d* ge2d);
-
-#endif
diff --git a/drivers/amvdec_ports/aml_vcodec_util.c b/drivers/amvdec_ports/aml_vcodec_util.c
index 54b0d06..509a42a 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.c
+++ b/drivers/amvdec_ports/aml_vcodec_util.c
@@ -22,6 +22,72 @@
 #include "aml_vcodec_drv.h"
 #include "aml_vcodec_util.h"
 
+void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data,
+					unsigned int reg_idx)
+{
+	struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+
+	if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"Invalid arguments, reg_idx=%d\n", reg_idx);
+		return NULL;
+	}
+	return ctx->dev->reg_base[reg_idx];
+}
+EXPORT_SYMBOL(aml_vcodec_get_reg_addr);
+
+int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data,
+			struct aml_vcodec_mem *mem)
+{
+	unsigned long size = mem->size;
+	struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+	struct device *dev = &ctx->dev->plat_dev->dev;
+
+	mem->vaddr = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL);
+	//mem->vaddr = codec_mm_dma_alloc_coherent(dev_name(dev), size,
+	//		&mem->dma_addr, GFP_KERNEL, 0);
+	if (!mem->vaddr) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"%s dma_alloc size=%ld failed!\n", dev_name(dev),
+			     size);
+		return -ENOMEM;
+	}
+
+	memset(mem->vaddr, 0, size);
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size);
+
+	return 0;
+}
+EXPORT_SYMBOL(aml_vcodec_mem_alloc);
+
+void aml_vcodec_mem_free(struct aml_vcodec_ctx *data,
+			struct aml_vcodec_mem *mem)
+{
+	unsigned long size = mem->size;
+	struct aml_vcodec_ctx *ctx = (struct aml_vcodec_ctx *)data;
+	struct device *dev = &ctx->dev->plat_dev->dev;
+
+	if (!mem->vaddr) {
+		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
+			"%s dma_free size=%ld failed!\n", dev_name(dev),
+			     size);
+		return;
+	}
+
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "va: %p\n", mem->vaddr);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "dma: 0x%lx\n", (ulong) mem->dma_addr);
+	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO, "size: 0x%lx\n", size);
+
+	dma_free_coherent(dev, size, mem->vaddr, mem->dma_addr);
+	mem->vaddr = NULL;
+	mem->dma_addr = 0;
+	mem->size = 0;
+}
+EXPORT_SYMBOL(aml_vcodec_mem_free);
+
 void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev,
 	struct aml_vcodec_ctx *ctx)
 {
diff --git a/drivers/amvdec_ports/aml_vcodec_util.h b/drivers/amvdec_ports/aml_vcodec_util.h
index 96c5453..312ee40 100644
--- a/drivers/amvdec_ports/aml_vcodec_util.h
+++ b/drivers/amvdec_ports/aml_vcodec_util.h
@@ -23,14 +23,14 @@
 #include <linux/types.h>
 #include <linux/dma-direction.h>
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
-/*
+
 typedef unsigned long long	u64;
 typedef signed long long	s64;
 typedef unsigned int		u32;
 typedef unsigned short int	u16;
 typedef short int		s16;
 typedef unsigned char		u8;
-*/
+
 #define CODEC_MODE(a, b, c, d)\
 	(((u8)(a) << 24) | ((u8)(b) << 16) | ((u8)(c) << 8) | (u8)(d))
 
@@ -45,16 +45,14 @@
 	u32	bytes_used;
 	u32	offset;
 	u64	timestamp;
+	dma_addr_t dma_addr;
 	u32	model;
-	ulong	meta_ptr;
-	struct dma_buf *dbuf;
 };
 
 struct aml_vcodec_ctx;
 struct aml_vcodec_dev;
 
 extern u32 debug_mode;
-extern u32 mandatory_dw_mmu;
 
 #ifdef v4l_dbg
 #undef v4l_dbg
@@ -71,11 +69,6 @@
 #define V4L_DEBUG_CODEC_PARSER	(1 << 6)
 #define V4L_DEBUG_CODEC_PROT	(1 << 7)
 #define V4L_DEBUG_CODEC_EXINFO	(1 << 8)
-#define V4L_DEBUG_VPP_BUFMGR	(1 << 9)
-#define V4L_DEBUG_VPP_DETAIL	(1 << 10)
-#define V4L_DEBUG_TASK_CHAIN	(1 << 11)
-#define V4L_DEBUG_GE2D_BUFMGR	(1 << 12)
-#define V4L_DEBUG_GE2D_DETAIL	(1 << 13)
 
 #define __v4l_dbg(h, id, fmt, args...)					\
 	do {								\
@@ -99,6 +92,12 @@
 		}								\
 	} while (0)
 
+void __iomem *aml_vcodec_get_reg_addr(struct aml_vcodec_ctx *data,
+				unsigned int reg_idx);
+int aml_vcodec_mem_alloc(struct aml_vcodec_ctx *data,
+				struct aml_vcodec_mem *mem);
+void aml_vcodec_mem_free(struct aml_vcodec_ctx *data,
+				struct aml_vcodec_mem *mem);
 void aml_vcodec_set_curr_ctx(struct aml_vcodec_dev *dev,
 	struct aml_vcodec_ctx *ctx);
 struct aml_vcodec_ctx *aml_vcodec_get_curr_ctx(struct aml_vcodec_dev *dev);
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.c b/drivers/amvdec_ports/aml_vcodec_vfm.c
new file mode 100644
index 0000000..62896ea
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.c
@@ -0,0 +1,245 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#include "aml_vcodec_vfm.h"
+#include "aml_vcodec_vfq.h"
+#include "aml_vcodec_util.h"
+#include "aml_vcodec_adapt.h"
+#include <media/v4l2-mem2mem.h>
+
+#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_VIDEO_COMPOSER
+#include <trace/events/meson_atrace.h>
+
+#define RECEIVER_NAME	"v4l2-video"
+#define PROVIDER_NAME	"v4l2-video"
+
+static struct vframe_s *vdec_vf_peek(void *op_arg)
+{
+	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+	return vfq_peek(&vfm->vf_que);
+}
+
+static struct vframe_s *vdec_vf_get(void *op_arg)
+{
+	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+	return vfq_pop(&vfm->vf_que);
+}
+
+static void vdec_vf_put(struct vframe_s *vf, void *op_arg)
+{
+	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+	/* If the video frame from amvide that means */
+	/* the data has been processed and finished, */
+	/* then push back to VDA. thus we don't put the */
+	/* buffer to the decoder directly.*/
+
+	//vf_put(vf, vfm->recv_name);
+	//vf_notify_provider(vfm->recv_name, VFRAME_EVENT_RECEIVER_PUT, NULL);
+
+	if (vfq_level(&vfm->vf_que_recycle) > POOL_SIZE - 1) {
+		v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "vfq full.\n");
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	vfq_push(&vfm->vf_que_recycle, vf);
+
+	/* schedule capture work. */
+	vdec_device_vf_run(vfm->ctx);
+}
+
+static int vdec_event_cb(int type, void *data, void *private_data)
+{
+
+	if (type & VFRAME_EVENT_RECEIVER_PUT) {
+	} else if (type & VFRAME_EVENT_RECEIVER_GET) {
+	} else if (type & VFRAME_EVENT_RECEIVER_FRAME_WAIT) {
+	}
+	return 0;
+}
+
+static int vdec_vf_states(struct vframe_states *states, void *op_arg)
+{
+	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)op_arg;
+
+	states->vf_pool_size	= POOL_SIZE;
+	states->buf_recycle_num	= 0;
+	states->buf_free_num	= POOL_SIZE - vfq_level(&vfm->vf_que);
+	states->buf_avail_num	= vfq_level(&vfm->vf_que);
+
+	return 0;
+}
+
+void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id)
+{
+	struct vframe_provider_s *vfp = vf_get_provider(receiver);
+	struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
+
+	ATRACE_COUNTER("v4l2_to", vf->index_disp);
+
+	v4l_dbg(0, V4L_DEBUG_CODEC_OUTPUT,
+		"[%d]: TO   (%s) vf: %p, idx: %d, "
+		"Y:(%lx, %u) C/U:(%lx, %u) V:(%lx, %u)\n",
+		id, vfp->name, vf, vf->index,
+		fb->m.mem[0].addr, fb->m.mem[0].size,
+		fb->m.mem[1].addr, fb->m.mem[1].size,
+		fb->m.mem[2].addr, fb->m.mem[2].size);
+
+	if (vfp && vf && atomic_dec_and_test(&vf->use_cnt))
+		vf_put(vf, receiver);
+}
+
+static const struct vframe_operations_s vf_provider = {
+	.peek		= vdec_vf_peek,
+	.get		= vdec_vf_get,
+	.put		= vdec_vf_put,
+	.event_cb	= vdec_event_cb,
+	.vf_states	= vdec_vf_states,
+};
+
+static int video_receiver_event_fun(int type, void *data, void *private_data)
+{
+	int ret = 0;
+	struct vframe_states states;
+	struct vcodec_vfm_s *vfm = (struct vcodec_vfm_s *)private_data;
+
+	switch (type) {
+	case VFRAME_EVENT_PROVIDER_UNREG: {
+		if (vf_get_receiver(vfm->prov_name)) {
+			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+				"unreg %s provider.\n",
+				vfm->prov_name);
+			vf_unreg_provider(&vfm->vf_prov);
+		}
+
+		break;
+	}
+
+	case VFRAME_EVENT_PROVIDER_START: {
+		if (vf_get_receiver(vfm->prov_name)) {
+			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+				"reg %s provider.\n",
+				vfm->prov_name);
+			vf_provider_init(&vfm->vf_prov, vfm->prov_name,
+				&vf_provider, vfm);
+			vf_reg_provider(&vfm->vf_prov);
+			vf_notify_receiver(vfm->prov_name,
+				VFRAME_EVENT_PROVIDER_START, NULL);
+		}
+
+		vfq_init(&vfm->vf_que, POOL_SIZE + 1, &vfm->pool[0]);
+		vfq_init(&vfm->vf_que_recycle, POOL_SIZE + 1, &vfm->pool_recycle[0]);
+
+		break;
+	}
+
+	case VFRAME_EVENT_PROVIDER_QUREY_STATE: {
+		vdec_vf_states(&states, vfm);
+		if (states.buf_avail_num > 0)
+			ret = RECEIVER_ACTIVE;
+		break;
+	}
+
+	case VFRAME_EVENT_PROVIDER_VFRAME_READY: {
+		if (vfq_level(&vfm->vf_que) > POOL_SIZE - 1)
+			ret = -1;
+
+		if (!vf_peek(vfm->recv_name))
+			ret = -1;
+
+		vfm->vf = vf_get(vfm->recv_name);
+		if (!vfm->vf)
+			ret = -1;
+
+		if (ret < 0) {
+			v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_ERROR, "receiver vf err.\n");
+			break;
+		}
+
+		vfq_push(&vfm->vf_que, vfm->vf);
+
+		if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO) {
+			vf_notify_receiver(vfm->prov_name,
+				VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+			break;
+		}
+
+		/* schedule capture work. */
+		vdec_device_vf_run(vfm->ctx);
+
+		break;
+	}
+
+	default:
+		v4l_dbg(vfm->ctx, V4L_DEBUG_CODEC_EXINFO,
+			"the vf event is %d", type);
+	}
+
+	return ret;
+}
+
+static const struct vframe_receiver_op_s vf_receiver = {
+	.event_cb	= video_receiver_event_fun
+};
+
+struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm)
+{
+	if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
+		return vfq_peek(&vfm->vf_que_recycle);
+	else
+		return vfq_peek(&vfm->vf_que);
+}
+
+struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm)
+{
+	if (vfm->ada_ctx->vfm_path == FRAME_BASE_PATH_V4L_VIDEO)
+		return vfq_pop(&vfm->vf_que_recycle);
+	else
+		return vfq_pop(&vfm->vf_que);
+}
+
+int vcodec_vfm_init(struct vcodec_vfm_s *vfm)
+{
+	int ret;
+
+	snprintf(vfm->recv_name, VF_NAME_SIZE, "%s-%d",
+		RECEIVER_NAME, vfm->ctx->id);
+	snprintf(vfm->prov_name, VF_NAME_SIZE, "%s-%d",
+		PROVIDER_NAME, vfm->ctx->id);
+
+	vfm->ada_ctx->recv_name = vfm->recv_name;
+
+	vf_receiver_init(&vfm->vf_recv, vfm->recv_name, &vf_receiver, vfm);
+	ret = vf_reg_receiver(&vfm->vf_recv);
+
+	vfm->vfm_initialized = ret ? false : true;
+
+	return ret;
+}
+
+void vcodec_vfm_release(struct vcodec_vfm_s *vfm)
+{
+	if (vfm->vfm_initialized)
+		vf_unreg_receiver(&vfm->vf_recv);
+}
+
diff --git a/drivers/amvdec_ports/aml_vcodec_vfm.h b/drivers/amvdec_ports/aml_vcodec_vfm.h
new file mode 100644
index 0000000..141e9a7
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfm.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef __AML_VCODEC_VFM_H_
+#define __AML_VCODEC_VFM_H_
+
+#include "aml_vcodec_vfq.h"
+#include "aml_vcodec_drv.h"
+#include "aml_vcodec_dec.h"
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
+#define VF_NAME_SIZE	(32)
+#define POOL_SIZE	(32)
+
+struct vcodec_vfm_s {
+	struct aml_vcodec_ctx *ctx;
+	struct aml_vdec_adapt *ada_ctx;
+	struct vfq_s vf_que;
+	struct vfq_s vf_que_recycle;
+	struct vframe_s *vf;
+	struct vframe_s *pool[POOL_SIZE + 1];
+	struct vframe_s *pool_recycle[POOL_SIZE + 1];
+	char recv_name[VF_NAME_SIZE];
+	char prov_name[VF_NAME_SIZE];
+	struct vframe_provider_s vf_prov;
+	struct vframe_receiver_s vf_recv;
+	bool vfm_initialized;
+};
+
+int vcodec_vfm_init(struct vcodec_vfm_s *vfm);
+
+void vcodec_vfm_release(struct vcodec_vfm_s *vfm);
+
+struct vframe_s *peek_video_frame(struct vcodec_vfm_s *vfm);
+
+struct vframe_s *get_video_frame(struct vcodec_vfm_s *vfm);
+
+int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_fb);
+int put_fb_to_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *in_fb);
+
+void video_vf_put(char *receiver, struct vdec_v4l2_buffer *fb, int id);
+
+#endif /* __AML_VCODEC_VFM_H_ */
diff --git a/drivers/amvdec_ports/aml_vcodec_vfq.h b/drivers/amvdec_ports/aml_vcodec_vfq.h
new file mode 100644
index 0000000..e19c53c
--- /dev/null
+++ b/drivers/amvdec_ports/aml_vcodec_vfq.h
@@ -0,0 +1,112 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#ifndef __AML_VCODEC_VFQ_H_
+#define __AML_VCODEC_VFQ_H_
+
+#include <linux/types.h>
+#include <asm/barrier.h>
+
+struct vfq_s {
+	int rp;
+	int wp;
+	int size;
+	int pre_rp;
+	int pre_wp;
+	struct vframe_s **pool;
+};
+
+static inline void vfq_lookup_start(struct vfq_s *q)
+{
+	q->pre_rp = q->rp;
+	q->pre_wp = q->wp;
+}
+static inline void vfq_lookup_end(struct vfq_s *q)
+{
+	q->rp = q->pre_rp;
+	q->wp = q->pre_wp;
+}
+
+static inline void vfq_init(struct vfq_s *q, u32 size, struct vframe_s **pool)
+{
+	q->rp = q->wp = 0;
+	q->size = size;
+	q->pool = pool;
+}
+
+static inline bool vfq_empty(struct vfq_s *q)
+{
+	return q->rp == q->wp;
+}
+
+static inline void vfq_push(struct vfq_s *q, struct vframe_s *vf)
+{
+	int wp = q->wp;
+
+	/*ToDo*/
+	smp_mb();
+
+	q->pool[wp] = vf;
+
+	/*ToDo*/
+	smp_wmb();
+
+	q->wp = (wp == (q->size - 1)) ? 0 : (wp + 1);
+}
+
+static inline struct vframe_s *vfq_pop(struct vfq_s *q)
+{
+	struct vframe_s *vf;
+	int rp;
+
+	if (vfq_empty(q))
+		return NULL;
+
+	rp = q->rp;
+
+	/*ToDo*/
+	smp_rmb();
+
+	vf = q->pool[rp];
+
+	/*ToDo*/
+	smp_mb();
+
+	q->rp = (rp == (q->size - 1)) ? 0 : (rp + 1);
+
+	return vf;
+}
+
+static inline struct vframe_s *vfq_peek(struct vfq_s *q)
+{
+	return (vfq_empty(q)) ? NULL : q->pool[q->rp];
+}
+
+static inline int vfq_level(struct vfq_s *q)
+{
+	int level = q->wp - q->rp;
+
+	if (level < 0)
+		level += q->size;
+
+	return level;
+}
+
+#endif /* __AML_VCODEC_VFQ_H_ */
+
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.c b/drivers/amvdec_ports/aml_vcodec_vpp.c
deleted file mode 100644
index 9f4e960..0000000
--- a/drivers/amvdec_ports/aml_vcodec_vpp.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <uapi/linux/sched/types.h>
-#include <linux/amlogic/meson_uvm_core.h>
-
-#include "aml_vcodec_vpp.h"
-#include "aml_vcodec_adapt.h"
-#include "vdec_drv_if.h"
-#include "../common/chips/decoder_cpu_ver_info.h"
-
-#define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
-#include <trace/events/meson_atrace.h>
-
-#define VPP_BUF_GET_IDX(vpp_buf) (vpp_buf->aml_buf->vb.vb2_buf.index)
-#define INPUT_PORT 0
-#define OUTPUT_PORT 1
-
-extern int dump_vpp_input;
-extern int vpp_bypass_frames;
-
-static void di_release_keep_buf_wrap(void *arg)
-{
-	struct di_buffer *buf = (struct di_buffer *)arg;
-
-	v4l_dbg(0, V4L_DEBUG_VPP_BUFMGR,
-		"%s release di local buffer %px, vf:%px, comm:%s, pid:%d\n",
-		__func__ , buf, buf->vf,
-		current->comm, current->pid);
-
-	di_release_keep_buf(buf);
-
-	ATRACE_COUNTER("VC_OUT_VPP_LC-2.lc_release", buf->mng.index);
-}
-
-static int attach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf)
-{
-	struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
-	struct dma_buf *dma = NULL;
-	struct aml_video_dec_buf *aml_buf = NULL;
-	struct uvm_hook_mod_info u_info;
-	int ret;
-
-	aml_buf = vpp_buf->aml_buf;
-	if (!aml_buf)
-		return -EINVAL;
-
-	dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
-	if (!dma || !dmabuf_is_uvm(dma)) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
-			"attach_DI_buffer err\n");
-		return -EINVAL;
-	}
-
-	if (!vpp_buf->di_local_buf) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-			"attach_DI_buffer nothing\n");
-		return 0;
-	}
-
-	if (uvm_get_hook_mod(dma, VF_PROCESS_DI)) {
-		uvm_put_hook_mod(dma, VF_PROCESS_DI);
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
-			"attach_DI_buffer exist hook\n");
-		return -EINVAL;
-	}
-	u_info.type = VF_PROCESS_DI;
-	u_info.arg = (void *)vpp_buf->di_local_buf;
-	u_info.free = di_release_keep_buf_wrap;
-
-	ret = uvm_attach_hook_mod(dma, &u_info);
-	if (ret < 0) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
-			"fail to set dmabuf DI hook\n");
-	}
-
-	ATRACE_COUNTER("VC_OUT_VPP_LC-0.lc_attach", vpp_buf->di_local_buf->mng.index);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"%s attach di local buffer %px, dbuf:%px\n",
-		__func__ , vpp_buf->di_local_buf, dma);
-
-	return ret;
-}
-
-static int detach_DI_buffer(struct aml_v4l2_vpp_buf *vpp_buf)
-{
-	struct aml_v4l2_vpp *vpp = vpp_buf->di_buf.caller_data;
-	struct dma_buf *dma = NULL;
-	struct aml_video_dec_buf *aml_buf = NULL;
-	int ret;
-
-	aml_buf = vpp_buf->aml_buf;
-	if (!aml_buf)
-		return -EINVAL;
-
-	dma = aml_buf->vb.vb2_buf.planes[0].dbuf;
-	if (!dma || !dmabuf_is_uvm(dma)) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
-			"detach_DI_buffer err\n");
-		return -EINVAL;
-	}
-
-	if (!vpp_buf->di_local_buf) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-			"detach_DI_buffer nothing\n");
-		return 0;
-	}
-
-	ATRACE_COUNTER("VC_OUT_VPP_LC-1.lc_detach", vpp_buf->di_local_buf->mng.index);
-
-	ret = uvm_detach_hook_mod(dma, VF_PROCESS_DI);
-	if (ret < 0) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-			"fail to remove dmabuf DI hook\n");
-	}
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"%s detach di local buffer %px, dbuf:%px\n",
-		__func__ , vpp_buf->di_local_buf, dma);
-
-	return ret;
-}
-
-static void release_DI_buff(struct aml_v4l2_vpp* vpp)
-{
-	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-
-	while (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
-		if (vpp_buf->di_buf.private_data) {
-			di_release_keep_buf(vpp_buf->di_local_buf);
-			v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-				"%s release di local buffer %px\n",
-				__func__ , vpp_buf->di_local_buf);
-		}
-	}
-}
-
-static int is_di_input_buff_full(struct aml_v4l2_vpp *vpp)
-{
-	return ((vpp->in_num[INPUT_PORT] - vpp->in_num[OUTPUT_PORT])
-		> vpp->di_ibuf_num) ? true : false;
-}
-
-static int is_di_output_buff_full(struct aml_v4l2_vpp *vpp)
-{
-	return ((vpp->out_num[INPUT_PORT] - vpp->out_num[OUTPUT_PORT])
-		> vpp->di_obuf_num) ? true : false;
-}
-
-static enum DI_ERRORTYPE
-	v4l_vpp_fill_output_done_alloc_buffer(struct di_buffer *buf)
-{
-	struct aml_v4l2_vpp *vpp = buf->caller_data;
-	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	if (!vpp || !vpp->ctx) {
-		pr_err("fatal %s %d vpp:%p\n",
-			__func__, __LINE__, vpp);
-		di_release_keep_buf_wrap(buf);
-		return DI_ERR_UNDEFINED;
-	}
-
-	if (vpp->ctx->is_stream_off) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
-			"vpp discard submit frame %s %d vpp:%p\n",
-			__func__, __LINE__, vpp);
-		di_release_keep_buf_wrap(buf);
-		return DI_ERR_UNDEFINED;
-	}
-
-	if (!kfifo_get(&vpp->processing, &vpp_buf)) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
-			"vpp doesn't get output %s %d vpp:%p\n",
-			__func__, __LINE__, vpp);
-		di_release_keep_buf_wrap(buf);
-		return DI_ERR_UNDEFINED;
-	}
-
-	fb	= &vpp_buf->aml_buf->frame_buffer;
-	eos	= (buf->flag & DI_FLAG_EOS);
-	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
-
-	vpp_buf->di_buf.vf->timestamp	= buf->vf->timestamp;
-	vpp_buf->di_buf.private_data	= buf->private_data;
-	vpp_buf->di_buf.vf->vf_ext	= buf->vf;
-	vpp_buf->di_buf.flag		= buf->flag;
-	vpp_buf->di_buf.vf->v4l_mem_handle = (ulong)fb;
-
-	if (!eos && !bypass) {
-		vpp_buf->di_local_buf = buf;
-		vpp_buf->di_buf.vf->vf_ext = buf->vf;
-		vpp_buf->di_buf.vf->flag |= VFRAME_FLAG_CONTAIN_POST_FRAME;
-	}
-
-	kfifo_put(&vpp->out_done_q, vpp_buf);
-
-	if (vpp->is_prog)
-		kfifo_put(&vpp->input, vpp_buf->inbuf);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"vpp_output local done: idx:%d, vf:%px, ext vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
-		"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-		fb->buf_idx,
-		vpp_buf->di_buf.vf,
-		vpp_buf->di_buf.vf->vf_ext,
-		vpp_buf->di_buf.vf->index,
-		vpp_buf->di_buf.vf->flag,
-		buf->flag,
-		vpp->is_prog ? "P" : "I",
-		eos ? "eos" : "",
-		vpp_buf->di_buf.vf->timestamp,
-		kfifo_len(&vpp->input),
-		kfifo_len(&vpp->output),
-		kfifo_len(&vpp->frame),
-		kfifo_len(&vpp->in_done_q),
-		kfifo_len(&vpp->out_done_q));
-
-	ATRACE_COUNTER("VC_OUT_VPP-2.lc_submit", fb->buf_idx);
-
-	fb->task->submit(fb->task, TASK_TYPE_VPP);
-
-	vpp->out_num[OUTPUT_PORT]++;
-	vpp->in_num[OUTPUT_PORT]++;
-
-	return DI_ERR_NONE;
-}
-
-static enum DI_ERRORTYPE
-	v4l_vpp_empty_input_done(struct di_buffer *buf)
-{
-	struct aml_v4l2_vpp *vpp = buf->caller_data;
-	struct aml_v4l2_vpp_buf *vpp_buf;
-	struct vdec_v4l2_buffer *fb = NULL;
-	bool eos = false;
-
-	if (!vpp || !vpp->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d vpp:%px\n",
-			__func__, __LINE__, vpp);
-		return DI_ERR_UNDEFINED;
-	}
-
-	if (vpp->ctx->is_stream_off) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
-			"vpp discard recycle frame %s %d vpp:%p\n",
-			__func__, __LINE__, vpp);
-		return DI_ERR_UNDEFINED;
-	}
-
-	vpp_buf	= container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
-	fb 	= &vpp_buf->aml_buf->frame_buffer;
-	eos	= (buf->flag & DI_FLAG_EOS);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"vpp_input done: idx:%d, vf:%px, idx: %d, flag(vf:%x di:%x) %s %s, ts:%lld, "
-		"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-		fb->buf_idx,
-		buf->vf,
-		buf->vf->index,
-		buf->vf->flag,
-		buf->flag,
-		vpp->is_prog ? "P" : "I",
-		eos ? "eos" : "",
-		buf->vf->timestamp,
-		kfifo_len(&vpp->input),
-		kfifo_len(&vpp->output),
-		kfifo_len(&vpp->frame),
-		kfifo_len(&vpp->in_done_q),
-		kfifo_len(&vpp->out_done_q));
-
-	if (!vpp->is_prog) {
-		/* recycle vf only in non-bypass mode */
-		fb->task->recycle(fb->task, TASK_TYPE_VPP);
-
-		kfifo_put(&vpp->input, vpp_buf);
-	}
-
-	if (vpp->buffer_mode != BUFFER_MODE_ALLOC_BUF)
-		vpp->in_num[OUTPUT_PORT]++;
-
-	ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
-
-	return DI_ERR_NONE;
-}
-
-static enum DI_ERRORTYPE
-	v4l_vpp_fill_output_done(struct di_buffer *buf)
-{
-	struct aml_v4l2_vpp *vpp = buf->caller_data;
-	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	if (!vpp || !vpp->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d vpp:%px\n",
-			__func__, __LINE__, vpp);
-		return DI_ERR_UNDEFINED;
-	}
-
-	if (vpp->ctx->is_stream_off) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_EXINFO,
-			"vpp discard submit frame %s %d vpp:%p\n",
-			__func__, __LINE__, vpp);
-		return DI_ERR_UNDEFINED;
-	}
-
-	vpp_buf	= container_of(buf, struct aml_v4l2_vpp_buf, di_buf);
-	fb	= &vpp_buf->aml_buf->frame_buffer;
-	eos	= (buf->flag & DI_FLAG_EOS);
-	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
-
-	/* recovery fb handle. */
-	buf->vf->v4l_mem_handle = (ulong)fb;
-
-	kfifo_put(&vpp->out_done_q, vpp_buf);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"vpp_output done: idx:%d, vf:%px, idx:%d, flag(vf:%x di:%x) %s %s, ts:%lld, "
-		"in:%d, out:%d, vf:%d, in done:%d, out done:%d\n",
-		fb->buf_idx,
-		buf->vf,
-		buf->vf->index,
-		buf->vf->flag,
-		buf->flag,
-		vpp->is_prog ? "P" : "I",
-		eos ? "eos" : "",
-		buf->vf->timestamp,
-		kfifo_len(&vpp->input),
-		kfifo_len(&vpp->output),
-		kfifo_len(&vpp->frame),
-		kfifo_len(&vpp->in_done_q),
-		kfifo_len(&vpp->out_done_q));
-
-	ATRACE_COUNTER("VC_OUT_VPP-2.submit", fb->buf_idx);
-
-	fb->task->submit(fb->task, TASK_TYPE_VPP);
-
-	vpp->out_num[OUTPUT_PORT]++;
-
-	/* count for bypass nr */
-	if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
-		vpp->in_num[OUTPUT_PORT]++;
-
-	return DI_ERR_NONE;
-}
-
-static void vpp_vf_get(void *caller, struct vframe_s **vf_out)
-{
-	struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
-	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct vdec_v4l2_buffer *fb = NULL;
-	struct di_buffer *buf = NULL;
-	struct vframe_s *vf = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	if (!vpp || !vpp->ctx) {
-		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
-			"fatal %s %d vpp:%px\n",
-			__func__, __LINE__, vpp);
-		return;
-	}
-
-	if (kfifo_get(&vpp->out_done_q, &vpp_buf)) {
-		fb	= &vpp_buf->aml_buf->frame_buffer;
-		buf	= &vpp_buf->di_buf;
-		eos	= (buf->flag & DI_FLAG_EOS);
-		bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
-		vf	= buf->vf;
-
-		if (eos) {
-			v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
-				"%s %d got eos\n",
-				__func__, __LINE__);
-			vf->type |= VIDTYPE_V4L_EOS;
-			vf->flag = VFRAME_FLAG_EMPTY_FRAME_V4L;
-		}
-
-		if (!eos && !bypass) {
-			if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
-				attach_DI_buffer(vpp_buf);
-			}
-		}
-
-		*vf_out = vf;
-
-		ATRACE_COUNTER("VC_OUT_VPP-3.vf_get", fb->buf_idx);
-
-		v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-			"%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
-			__func__, vf,
-			vf->index,
-			vf->flag,
-			buf->flag,
-			vf->timestamp);
-	}
-}
-
-static void vpp_vf_put(void *caller, struct vframe_s *vf)
-{
-	struct aml_v4l2_vpp *vpp = (struct aml_v4l2_vpp *)caller;
-	struct vdec_v4l2_buffer *fb = NULL;
-	struct aml_video_dec_buf *aml_buf = NULL;
-	struct aml_v4l2_vpp_buf *vpp_buf = NULL;
-	struct di_buffer *buf = NULL;
-	bool bypass = false;
-	bool eos = false;
-
-	fb	= (struct vdec_v4l2_buffer *) vf->v4l_mem_handle;
-	aml_buf	= container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
-
-	vpp_buf	= (struct aml_v4l2_vpp_buf *) aml_buf->vpp_buf_handle;
-	buf	= &vpp_buf->di_buf;
-	eos	= (buf->flag & DI_FLAG_EOS);
-	bypass	= (buf->flag & DI_FLAG_BUF_BY_PASS);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"%s: vf:%px, index:%d, flag(vf:%x di:%x), ts:%lld\n",
-		__func__, vf,
-		vf->index,
-		vf->flag,
-		buf->flag,
-		vf->timestamp);
-
-	ATRACE_COUNTER("VC_IN_VPP-0.vf_put", fb->buf_idx);
-
-	if (vpp->is_prog) {
-		ATRACE_COUNTER("VC_IN_VPP-1.recycle", fb->buf_idx);
-		fb->task->recycle(fb->task, TASK_TYPE_VPP);
-	}
-
-	if (!eos && !bypass) {
-		if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
-			detach_DI_buffer(vpp_buf);
-		}
-	}
-
-	mutex_lock(&vpp->output_lock);
-	kfifo_put(&vpp->frame, vf);
-	kfifo_put(&vpp->output, vpp_buf);
-	mutex_unlock(&vpp->output_lock);
-	up(&vpp->sem_out);
-}
-
-static int aml_v4l2_vpp_thread(void* param)
-{
-	struct aml_v4l2_vpp* vpp = param;
-	struct aml_vcodec_ctx *ctx = vpp->ctx;
-
-	v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "enter vpp thread\n");
-	while (vpp->running) {
-		struct aml_v4l2_vpp_buf *in_buf;
-		struct aml_v4l2_vpp_buf *out_buf = NULL;
-		struct vframe_s *vf_out = NULL;
-		struct vdec_v4l2_buffer *fb;
-
-		if (down_interruptible(&vpp->sem_in))
-			goto exit;
-retry:
-		if (!vpp->running)
-			break;
-
-		if (kfifo_is_empty(&vpp->output)) {
-			if (down_interruptible(&vpp->sem_out))
-				goto exit;
-			goto retry;
-		}
-
-		if ((vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) &&
-			(is_di_input_buff_full(vpp) || is_di_output_buff_full(vpp))) {
-			usleep_range(500, 550);
-			goto retry;
-		}
-
-		mutex_lock(&vpp->output_lock);
-		if (!kfifo_get(&vpp->output, &out_buf)) {
-			mutex_unlock(&vpp->output_lock);
-			v4l_dbg(ctx, 0, "vpp can not get output\n");
-			goto exit;
-		}
-		mutex_unlock(&vpp->output_lock);
-
-		/* bind v4l2 buffers */
-		if (!vpp->is_prog && !out_buf->aml_buf) {
-			struct vdec_v4l2_buffer *out;
-
-			if (!ctx->fb_ops.query(&ctx->fb_ops, &vpp->fb_token)) {
-				usleep_range(500, 550);
-				mutex_lock(&vpp->output_lock);
-				kfifo_put(&vpp->output, out_buf);
-				mutex_unlock(&vpp->output_lock);
-				goto retry;
-			}
-
-			if (ctx->fb_ops.alloc(&ctx->fb_ops, vpp->fb_token, &out, AML_FB_REQ_VPP)) {
-				usleep_range(5000, 5500);
-				mutex_lock(&vpp->output_lock);
-				kfifo_put(&vpp->output, out_buf);
-				mutex_unlock(&vpp->output_lock);
-				goto retry;
-			}
-
-			out_buf->aml_buf = container_of(out,
-				struct aml_video_dec_buf, frame_buffer);
-			out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
-			v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
-				"vpp bind buf:%d to vpp_buf:%px\n",
-				VPP_BUF_GET_IDX(out_buf), out_buf);
-
-			out->m.mem[0].bytes_used = out->m.mem[0].size;
-			out->m.mem[1].bytes_used = out->m.mem[1].size;
-		}
-
-		/* safe to pop in_buf */
-		if (!kfifo_get(&vpp->in_done_q, &in_buf)) {
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"vpp can not get input\n");
-			goto exit;
-		}
-
-		mutex_lock(&vpp->output_lock);
-		if (!kfifo_get(&vpp->frame, &vf_out)) {
-			mutex_unlock(&vpp->output_lock);
-			v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-				"vpp can not get frame\n");
-			goto exit;
-		}
-		mutex_unlock(&vpp->output_lock);
-
-		if (!vpp->is_prog) {
-			/* submit I to DI. */
-			fb = &out_buf->aml_buf->frame_buffer;
-			fb->status = FB_ST_VPP;
-
-			memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
-			memcpy(vf_out->canvas0_config,
-				in_buf->di_buf.vf->canvas0_config,
-				2 * sizeof(struct canvas_config_s));
-
-			vf_out->canvas0_config[0].phy_addr = fb->m.mem[0].addr;
-			if (fb->num_planes == 1)
-				vf_out->canvas0_config[1].phy_addr =
-					fb->m.mem[0].addr + fb->m.mem[0].offset;
-			else
-				vf_out->canvas0_config[1].phy_addr =
-					fb->m.mem[1].addr;
-
-			if (in_buf->di_buf.flag & DI_FLAG_EOS)
-				memset(vf_out, 0, sizeof(*vf_out));
-
-			vf_out->meta_data_size = in_buf->di_buf.vf->meta_data_size;
-			vf_out->meta_data_buf = in_buf->di_buf.vf->meta_data_buf;
-		} else {
-			/* submit P to DI. */
-			out_buf->aml_buf = in_buf->aml_buf;
-			out_buf->aml_buf->vpp_buf_handle = (ulong) out_buf;
-
-			memcpy(vf_out, in_buf->di_buf.vf, sizeof(*vf_out));
-		}
-
-		/* fill outbuf parms. */
-		out_buf->di_buf.vf	= vf_out;
-		out_buf->di_buf.flag	= 0;
-		out_buf->di_local_buf	= NULL;
-		out_buf->di_buf.caller_data = vpp;
-
-		/* fill inbuf parms. */
-		in_buf->di_buf.caller_data = vpp;
-
-		/*
-		 * HWC or SF should hold di buffres refcnt after resolution changed
-		 * that might cause stuck, thus sumbit 10 frames from dec to display directly.
-		 * then frames will be pushed out from these buffer queuen and
-		 * recycle local buffers to DI module.
-		 */
-		if (/*(ctx->vpp_cfg.res_chg) && */(vpp->is_prog) &&
-			(vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)) {
-			if (vpp->in_num[INPUT_PORT] < vpp_bypass_frames) {
-				vpp->is_bypass_p = true;
-			} else {
-				vpp->is_bypass_p = false;
-				ctx->vpp_cfg.res_chg = false;
-			}
-		}
-
-		v4l_dbg(ctx, V4L_DEBUG_VPP_BUFMGR,
-			"vpp_handle start: idx:(%d, %d), dec vf:%px/%d, vpp vf:%px/%d, iphy:%lx/%lx %dx%d ophy:%lx/%lx %dx%d, %s %s "
-			"in:%d, out:%d, vf:%d, in done:%d, out done:%d",
-			in_buf->aml_buf->frame_buffer.buf_idx,
-			out_buf->aml_buf->frame_buffer.buf_idx,
-			in_buf->di_buf.vf, in_buf->di_buf.vf->index,
-			out_buf->di_buf.vf, VPP_BUF_GET_IDX(out_buf),
-			in_buf->di_buf.vf->canvas0_config[0].phy_addr,
-			in_buf->di_buf.vf->canvas0_config[1].phy_addr,
-			in_buf->di_buf.vf->canvas0_config[0].width,
-			in_buf->di_buf.vf->canvas0_config[0].height,
-			vf_out->canvas0_config[0].phy_addr,
-			vf_out->canvas0_config[1].phy_addr,
-			vf_out->canvas0_config[0].width,
-			vf_out->canvas0_config[0].height,
-			vpp->is_prog ? "P" : "",
-			vpp->is_bypass_p ? "bypass-prog" : "",
-			kfifo_len(&vpp->input),
-			kfifo_len(&vpp->output),
-			kfifo_len(&vpp->frame),
-			kfifo_len(&vpp->in_done_q),
-			kfifo_len(&vpp->out_done_q));
-
-		if (vpp->is_bypass_p) {
-			ATRACE_COUNTER("V4L_OUT_VPP-1.direct_handle_start",
-				in_buf->aml_buf->frame_buffer.buf_idx);
-			out_buf->di_buf.flag = in_buf->di_buf.flag;
-			out_buf->di_buf.vf->vf_ext = in_buf->di_buf.vf;
-
-			v4l_vpp_fill_output_done(&out_buf->di_buf);
-			v4l_vpp_empty_input_done(&in_buf->di_buf);
-		} else {
-			if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
-				/*
-				 * the flow of DI local buffer:
-				 * empty input -> output done cb -> fetch processing fifo.
-				 */
-				ATRACE_COUNTER("VC_OUT_VPP-1.lc_handle_start",
-					in_buf->aml_buf->frame_buffer.buf_idx);
-				out_buf->inbuf = in_buf;
-				kfifo_put(&vpp->processing, out_buf);
-
-				di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
-			} else {
-				ATRACE_COUNTER("VC_OUT_VPP-1.fill_output_start",
-					out_buf->aml_buf->frame_buffer.buf_idx);
-				di_fill_output_buffer(vpp->di_handle, &out_buf->di_buf);
-
-				ATRACE_COUNTER("VC_OUT_VPP-1.empty_input_start",
-					in_buf->aml_buf->frame_buffer.buf_idx);
-				di_empty_input_buffer(vpp->di_handle, &in_buf->di_buf);
-			}
-		}
-		vpp->in_num[INPUT_PORT]++;
-		vpp->out_num[INPUT_PORT]++;
-	}
-exit:
-	while (!kthread_should_stop()) {
-		usleep_range(1000, 2000);
-	}
-
-	v4l_dbg(ctx, V4L_DEBUG_VPP_DETAIL, "exit vpp thread\n");
-
-	return 0;
-}
-
-int aml_v4l2_vpp_get_buf_num(u32 mode)
-{
-	if ((mode == VPP_MODE_DI) ||
-		(mode == VPP_MODE_COLOR_CONV) ||
-		(mode == VPP_MODE_NOISE_REDUC)) {
-		return 4;
-	}
-	//TODO: support more modes
-	return 2;
-}
-
-int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp)
-{
-	int i;
-	struct sched_param param =
-		{ .sched_priority = MAX_RT_PRIO - 1 };
-
-	vpp->running = false;
-	up(&vpp->sem_in);
-	up(&vpp->sem_out);
-	kthread_stop(vpp->task);
-
-	kfifo_reset(&vpp->input);
-	kfifo_reset(&vpp->output);
-	kfifo_reset(&vpp->frame);
-	kfifo_reset(&vpp->out_done_q);
-	kfifo_reset(&vpp->in_done_q);
-	kfifo_reset(&vpp->processing);
-
-	for (i = 0 ; i < VPP_FRAME_SIZE ; i++) {
-		memset(&vpp->ivbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf));
-
-		kfifo_put(&vpp->input, &vpp->ivbpool[i]);
-	}
-
-	for (i = 0 ; i < vpp->buf_size ; i++) {
-		memset(&vpp->ovbpool[i], 0, sizeof(struct aml_v4l2_vpp_buf));
-		memset(&vpp->vfpool[i], 0, sizeof(struct vframe_s));
-
-		kfifo_put(&vpp->output, &vpp->ovbpool[i]);
-		kfifo_put(&vpp->frame, &vpp->vfpool[i]);
-	}
-
-	vpp->in_num[0]	= 0;
-	vpp->in_num[1]	= 0;
-	vpp->out_num[0]	= 0;
-	vpp->out_num[1]	= 0;
-	vpp->fb_token	= 0;
-	sema_init(&vpp->sem_in, 0);
-	sema_init(&vpp->sem_out, 0);
-
-	vpp->running = true;
-	vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp,
-		"%s", "aml-v4l2-vpp");
-	if (IS_ERR(vpp->task)) {
-		return PTR_ERR(vpp->task);
-	}
-
-	sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, &param);
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_PRINFO, "vpp wrapper reset.\n");
-
-	return 0;
-
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_reset);
-
-int aml_v4l2_vpp_init(
-		struct aml_vcodec_ctx *ctx,
-		struct aml_vpp_cfg_infos *cfg,
-		struct aml_v4l2_vpp** vpp_handle)
-{
-	struct di_init_parm init;
-	u32 buf_size;
-	int i, ret;
-	struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
-	struct aml_v4l2_vpp *vpp;
-	u32 work_mode = cfg->mode;
-
-	if (!cfg || work_mode > VPP_MODE_MAX || !ctx || !vpp_handle)
-		return -EINVAL;
-	if (cfg->fmt != V4L2_PIX_FMT_NV12 && cfg->fmt != V4L2_PIX_FMT_NV12M &&
-		cfg->fmt != V4L2_PIX_FMT_NV21 && cfg->fmt != V4L2_PIX_FMT_NV21M)
-		return -EINVAL;
-
-	vpp = kzalloc(sizeof(*vpp), GFP_KERNEL);
-	if (!vpp)
-		return -ENOMEM;
-
-	vpp->work_mode = work_mode;
-	if (vpp->work_mode >= VPP_MODE_DI_LOCAL &&
-		vpp->work_mode <= VPP_MODE_NOISE_REDUC_LOCAL)
-		vpp->buffer_mode = BUFFER_MODE_ALLOC_BUF;
-	else
-		vpp->buffer_mode = BUFFER_MODE_USE_BUF;
-
-	init.work_mode			= WORK_MODE_PRE_POST;
-	init.buffer_mode		= vpp->buffer_mode;
-	init.ops.fill_output_done	= v4l_vpp_fill_output_done;
-	init.ops.empty_input_done	= v4l_vpp_empty_input_done;
-	init.caller_data		= (void *)vpp;
-
-	if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF) {
-		init.ops.fill_output_done =
-			v4l_vpp_fill_output_done_alloc_buffer;
-	}
-
-	if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
-		init.output_format = DI_OUTPUT_BY_DI_DEFINE;
-	else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
-		((cfg->fmt == V4L2_PIX_FMT_NV21M) || (cfg->fmt == V4L2_PIX_FMT_NV21)))
-		init.output_format = DI_OUTPUT_NV21 | DI_OUTPUT_LINEAR;
-	else if ((vpp->buffer_mode == BUFFER_MODE_USE_BUF) &&
-		((cfg->fmt == V4L2_PIX_FMT_NV12M) || (cfg->fmt == V4L2_PIX_FMT_NV12)))
-		init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
-	else /* AFBC deocde case, NV12 as default */
-		init.output_format = DI_OUTPUT_NV12 | DI_OUTPUT_LINEAR;
-
-	if (cfg->is_drm)
-		init.output_format |= DI_OUTPUT_TVP;
-
-	vpp->di_handle = di_create_instance(init);
-	if (vpp->di_handle < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"di_create_instance fail\n");
-		ret = -EINVAL;
-		goto error;
-	}
-
-	INIT_KFIFO(vpp->input);
-	INIT_KFIFO(vpp->output);
-	INIT_KFIFO(vpp->frame);
-	INIT_KFIFO(vpp->out_done_q);
-	INIT_KFIFO(vpp->in_done_q);
-	INIT_KFIFO(vpp->processing);
-
-	vpp->ctx = ctx;
-	vpp->is_prog = cfg->is_prog;
-	vpp->is_bypass_p = cfg->is_bypass_p;
-
-	buf_size = vpp->is_prog ? 16 : cfg->buf_size;
-	vpp->buf_size = buf_size;
-
-	/* setup output fifo */
-	ret = kfifo_alloc(&vpp->output, buf_size, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc output fifo fail.\n");
-		ret = -ENOMEM;
-		goto error2;
-	}
-
-	vpp->ovbpool = vzalloc(buf_size * sizeof(*vpp->ovbpool));
-	if (!vpp->ovbpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc output vb pool fail.\n");
-		ret = -ENOMEM;
-		goto error3;
-	}
-
-	/* setup vframe fifo */
-	ret = kfifo_alloc(&vpp->frame, buf_size, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc vpp vframe fifo fail.\n");
-		ret = -ENOMEM;
-		goto error4;
-	}
-
-	vpp->vfpool = vzalloc(buf_size * sizeof(*vpp->vfpool));
-	if (!vpp->vfpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc vf pool fail.\n");
-		ret = -ENOMEM;
-		goto error5;
-	}
-
-	/* setup processing fifo */
-	ret = kfifo_alloc(&vpp->processing, buf_size, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc processing fifo fail.\n");
-		ret = -ENOMEM;
-		goto error6;
-	}
-
-	ret = kfifo_alloc(&vpp->input, VPP_FRAME_SIZE, GFP_KERNEL);
-	if (ret) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc input fifo fail.\n");
-		ret = -ENOMEM;
-		goto error7;
-	}
-
-	vpp->ivbpool = vzalloc(VPP_FRAME_SIZE * sizeof(*vpp->ivbpool));
-	if (!vpp->ivbpool) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"alloc input vb pool fail.\n");
-		ret = -ENOMEM;
-		goto error8;
-	}
-
-	for (i = 0 ; i < VPP_FRAME_SIZE ; i++) {
-		kfifo_put(&vpp->input, &vpp->ivbpool[i]);
-	}
-
-	for (i = 0 ; i < buf_size ; i++) {
-		kfifo_put(&vpp->output, &vpp->ovbpool[i]);
-		kfifo_put(&vpp->frame, &vpp->vfpool[i]);
-	}
-
-	mutex_init(&vpp->output_lock);
-	sema_init(&vpp->sem_in, 0);
-	sema_init(&vpp->sem_out, 0);
-
-	vpp->running = true;
-	vpp->task = kthread_run(aml_v4l2_vpp_thread, vpp,
-		"aml-%s", "aml-v4l2-vpp");
-	if (IS_ERR(vpp->task)) {
-		ret = PTR_ERR(vpp->task);
-		goto error9;
-	}
-	sched_setscheduler_nocheck(vpp->task, SCHED_FIFO, &param);
-
-	vpp->di_ibuf_num = di_get_input_buffer_num(vpp->di_handle);
-	vpp->di_obuf_num = di_get_output_buffer_num(vpp->di_handle);
-
-	*vpp_handle = vpp;
-
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_PRINFO,
-		"vpp_wrapper init bsize:%d, di(i:%d, o:%d), wkm:%x, bm:%x, fmt:%x, drm:%d, prog:%d, byp:%d, local:%d, NR:%d\n",
-		vpp->buf_size,
-		vpp->di_ibuf_num,
-		vpp->di_obuf_num,
-		vpp->work_mode,
-		vpp->buffer_mode,
-		init.output_format,
-		cfg->is_drm,
-		cfg->is_prog,
-		cfg->is_bypass_p,
-		cfg->enable_local_buf,
-		cfg->enable_nr);
-
-	return 0;
-
-error9:
-	vfree(vpp->ivbpool);
-error8:
-	kfifo_free(&vpp->input);
-error7:
-	kfifo_free(&vpp->processing);
-error6:
-	vfree(vpp->vfpool);
-error5:
-	kfifo_free(&vpp->frame);
-error4:
-	vfree(vpp->ovbpool);
-error3:
-	kfifo_free(&vpp->output);
-error2:
-	di_destroy_instance(vpp->di_handle);
-error:
-	kfree(vpp);
-	return ret;
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_init);
-
-int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp)
-{
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
-		"vpp destroy begin\n");
-	vpp->running = false;
-	up(&vpp->sem_in);
-	up(&vpp->sem_out);
-	kthread_stop(vpp->task);
-
-	di_destroy_instance(vpp->di_handle);
-	/* no more vpp callback below this line */
-
-	if (vpp->buffer_mode == BUFFER_MODE_ALLOC_BUF)
-		release_DI_buff(vpp);
-
-	kfifo_free(&vpp->processing);
-	kfifo_free(&vpp->frame);
-	vfree(vpp->vfpool);
-	kfifo_free(&vpp->output);
-	vfree(vpp->ovbpool);
-	kfifo_free(&vpp->input);
-	vfree(vpp->ivbpool);
-	mutex_destroy(&vpp->output_lock);
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_DETAIL,
-		"vpp_wrapper destroy done\n");
-	kfree(vpp);
-
-	return 0;
-}
-EXPORT_SYMBOL(aml_v4l2_vpp_destroy);
-
-static int aml_v4l2_vpp_push_vframe(struct aml_v4l2_vpp* vpp, struct vframe_s *vf)
-{
-	struct aml_v4l2_vpp_buf *in_buf;
-	struct vdec_v4l2_buffer *fb = NULL;
-
-	if (!vpp)
-		return -EINVAL;
-
-	if (!kfifo_get(&vpp->input, &in_buf)) {
-		v4l_dbg(vpp->ctx, V4L_DEBUG_CODEC_ERROR,
-			"cat not get free input buffer.\n");
-		return -1;
-	}
-
-#if 0 //to debug di by frame
-	if (vpp->in_num[INPUT_PORT] > 2)
-		return 0;
-	if (vpp->in_num[INPUT_PORT] == 2)
-		vf->type |= VIDTYPE_V4L_EOS;
-#endif
-
-	in_buf->di_buf.vf = vf;
-	in_buf->di_buf.flag = 0;
-	if (vf->type & VIDTYPE_V4L_EOS) {
-		u32 dw_mode = VDEC_DW_NO_AFBC;
-
-		in_buf->di_buf.flag |= DI_FLAG_EOS;
-
-		if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
-			return -1;
-
-		vf->type |= vpp->ctx->vpp_cfg.is_prog ?
-			VIDTYPE_PROGRESSIVE :
-			VIDTYPE_INTERLACE;
-
-		if (dw_mode != VDEC_DW_NO_AFBC)
-			vf->type |= VIDTYPE_COMPRESS;
-	}
-
-	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
-	in_buf->aml_buf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
-
-	if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T7) {
-		if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR) {
-			if ((vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_H264) &&
-				(vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG1) &&
-				(vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG2) &&
-				(vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MPEG4) &&
-				(vpp->ctx->output_pix_fmt != V4L2_PIX_FMT_MJPEG)) {
-				vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-			}
-			else {
-				if (fb->status == FB_ST_GE2D)
-					vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-			}
-		}
-	} else {
-		if (vf->canvas0_config[0].block_mode == CANVAS_BLKMODE_LINEAR)
-			vf->flag |= VFRAME_FLAG_VIDEO_LINEAR;
-	}
-
-	v4l_dbg(vpp->ctx, V4L_DEBUG_VPP_BUFMGR,
-		"vpp_push_vframe: idx:%d, vf:%px, idx:%d, type:%x, ts:%lld\n",
-		fb->buf_idx, vf, vf->index, vf->type, vf->timestamp);
-
-	do {
-		unsigned int dw_mode = VDEC_DW_NO_AFBC;
-		struct file *fp;
-
-		if (!dump_vpp_input || vpp->ctx->is_drm_mode)
-			break;
-		if (vdec_if_get_param(vpp->ctx, GET_PARAM_DW_MODE, &dw_mode))
-			break;
-		if (dw_mode == VDEC_DW_AFBC_ONLY)
-			break;
-
-		fp = filp_open("/data/dec_dump_before.raw",
-				O_CREAT | O_RDWR | O_LARGEFILE | O_APPEND, 0600);
-		if (!IS_ERR(fp)) {
-			struct vb2_buffer *vb = &in_buf->aml_buf->vb.vb2_buf;
-
-			kernel_write(fp,vb2_plane_vaddr(vb, 0),vb->planes[0].length, 0);
-			if (in_buf->aml_buf->frame_buffer.num_planes == 2)
-				kernel_write(fp,vb2_plane_vaddr(vb, 1),
-						vb->planes[1].length, 0);
-			dump_vpp_input--;
-			filp_close(fp, NULL);
-		}
-	} while(0);
-
-	ATRACE_COUNTER("VC_OUT_VPP-0.receive", fb->buf_idx);
-
-	kfifo_put(&vpp->in_done_q, in_buf);
-	up(&vpp->sem_in);
-
-	return 0;
-}
-
-static void fill_vpp_buf_cb(void *v4l_ctx, void *fb_ctx)
-{
-	struct aml_vcodec_ctx *ctx =
-		(struct aml_vcodec_ctx *)v4l_ctx;
-	struct vdec_v4l2_buffer *fb =
-		(struct vdec_v4l2_buffer *)fb_ctx;
-	int ret = -1;
-
-	ret = aml_v4l2_vpp_push_vframe(ctx->vpp, fb->vframe);
-	if (ret < 0) {
-		v4l_dbg(ctx, V4L_DEBUG_CODEC_ERROR,
-			"vpp push vframe err, ret: %d\n", ret);
-	}
-}
-
-static struct task_ops_s vpp_ops = {
-	.type		= TASK_TYPE_VPP,
-	.get_vframe	= vpp_vf_get,
-	.put_vframe	= vpp_vf_put,
-	.fill_buffer	= fill_vpp_buf_cb,
-};
-
-struct task_ops_s *get_vpp_ops(void)
-{
-	return &vpp_ops;
-}
-EXPORT_SYMBOL(get_vpp_ops);
-
diff --git a/drivers/amvdec_ports/aml_vcodec_vpp.h b/drivers/amvdec_ports/aml_vcodec_vpp.h
deleted file mode 100644
index 7a5771d..0000000
--- a/drivers/amvdec_ports/aml_vcodec_vpp.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-* more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; if not, write to the Free Software Foundation, Inc.,
-* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-* Description:
-*/
-#ifndef _AML_VCODEC_VPP_H_
-#define _AML_VCODEC_VPP_H_
-
-#define SUPPORT_V4L_VPP
-
-#include <linux/kfifo.h>
-#ifdef SUPPORT_V4L_VPP
-#include <linux/amlogic/media/di/di_interface.h>
-#endif
-#include "aml_vcodec_drv.h"
-#include "aml_vcodec_dec.h"
-
-enum vpp_work_mode {
-	VPP_MODE_DI,
-	VPP_MODE_COLOR_CONV,
-	VPP_MODE_NOISE_REDUC,
-	VPP_MODE_DI_LOCAL = 0x81,
-	VPP_MODE_COLOR_CONV_LOCAL = 0x82,
-	VPP_MODE_NOISE_REDUC_LOCAL = 0x83,
-	VPP_MODE_MAX = 0xff
-};
-
-#define VPP_FRAME_SIZE 64
-
-struct aml_v4l2_vpp_buf {
-#ifdef SUPPORT_V4L_VPP
-	struct di_buffer di_buf;
-	struct di_buffer *di_local_buf;
-#endif
-	struct aml_video_dec_buf *aml_buf;
-	struct aml_v4l2_vpp_buf *inbuf;
-};
-
-struct aml_v4l2_vpp {
-	int di_handle; /* handle of DI */
-	struct aml_vcodec_ctx *ctx;
-	u32 buf_size; /* buffer size for vpp */
-	u32 work_mode; /* enum vpp_work_mode */
-	u32 buffer_mode;
-
-	DECLARE_KFIFO_PTR(input, typeof(struct aml_v4l2_vpp_buf*));
-	DECLARE_KFIFO_PTR(output, typeof(struct aml_v4l2_vpp_buf*));
-	DECLARE_KFIFO_PTR(processing, typeof(struct aml_v4l2_vpp_buf*));
-	DECLARE_KFIFO_PTR(frame, typeof(struct vframe_s *));
-	DECLARE_KFIFO(out_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE);
-	DECLARE_KFIFO(in_done_q, struct aml_v4l2_vpp_buf *, VPP_FRAME_SIZE);
-
-	struct vframe_s *vfpool;
-	struct aml_v4l2_vpp_buf *ovbpool;
-	struct aml_v4l2_vpp_buf *ivbpool;
-	struct task_struct *task;
-	bool running;
-	struct semaphore sem_in, sem_out;
-
-	/* In p to i transition, output/frame can be multi writer */
-	struct mutex output_lock;
-
-	/* for debugging */
-	/*
-	 * in[0] --> vpp <-- in[1]
-	 * out[0]<-- vpp --> out[1]
-	 */
-	int in_num[2];
-	int out_num[2];
-	ulong fb_token;
-
-	bool is_prog;
-	bool is_bypass_p;
-	int di_ibuf_num;
-	int di_obuf_num;
-};
-
-struct task_ops_s *get_vpp_ops(void);
-
-#ifdef SUPPORT_V4L_VPP
-/* get number of buffer needed for a working mode */
-int aml_v4l2_vpp_get_buf_num(u32 mode);
-int aml_v4l2_vpp_init(
-		struct aml_vcodec_ctx *ctx,
-		struct aml_vpp_cfg_infos *cfg,
-		struct aml_v4l2_vpp** vpp_handle);
-int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp);
-int aml_v4l2_vpp_reset(struct aml_v4l2_vpp *vpp);
-#else
-static inline int aml_v4l2_vpp_get_buf_num(u32 mode) { return -1; }
-static inline int aml_v4l2_vpp_init(
-		struct aml_vcodec_ctx *ctx,
-		struct aml_vpp_cfg_infos *cfg,
-		struct aml_v4l2_vpp** vpp_handle) { return -1; }
-static inline int aml_v4l2_vpp_destroy(struct aml_v4l2_vpp* vpp) { return -1; }
-#endif
-
-#endif
diff --git a/drivers/amvdec_ports/decoder/aml_h264_parser.c b/drivers/amvdec_ports/decoder/aml_h264_parser.c
index d0d0198..c9da299 100644
--- a/drivers/amvdec_ports/decoder/aml_h264_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_h264_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.c b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
index 24977a8..4ea76b9 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_hevc_parser.h b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
index 9223639..0c81cb5 100644
--- a/drivers/amvdec_ports/decoder/aml_hevc_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_hevc_parser.h
@@ -22,6 +22,7 @@
 #include "../aml_vcodec_drv.h"
 #include "../utils/common.h"
 
+
 #define MAX_DPB_SIZE				16 // A.4.1
 #define MAX_REFS				16
 
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
index c582ab0..fd56755 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
index 4704ba0..bbc9282 100644
--- a/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mjpeg_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
 #ifndef AML_MJPEG_PARSER_H
 #define AML_MJPEG_PARSER_H
 
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
index 748a83f..2720446 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
index c06d632..8abbc78 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mpeg12_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
 #ifndef AML_MPEG12_PARSER_H
 #define AML_MPEG12_PARSER_H
 
@@ -7,6 +23,7 @@
 #include "../utils/pixfmt.h"
 #endif
 
+
 /* Start codes. */
 #define SEQ_END_CODE            0x000001b7
 #define SEQ_START_CODE          0x000001b3
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
index 9c47c08..f680b12 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
index f9b71cf..3e5bf62 100644
--- a/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+++ b/drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
@@ -1,3 +1,19 @@
+/*
+ * drivers/amvdec_ports/decoder/aml_mpeg4_parser.h
+ *
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
 #ifndef AVCODEC_MPEG4VIDEO_H
 #define AVCODEC_MPEG4VIDEO_H
 
diff --git a/drivers/amvdec_ports/decoder/aml_vp9_parser.c b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
index 21d5283..b027b8a 100644
--- a/drivers/amvdec_ports/decoder/aml_vp9_parser.c
+++ b/drivers/amvdec_ports/decoder/aml_vp9_parser.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
diff --git a/drivers/amvdec_ports/decoder/vdec_av1_if.c b/drivers/amvdec_ports/decoder/vdec_av1_if.c
index c28ca10..e8693d4 100644
--- a/drivers/amvdec_ports/decoder/vdec_av1_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_av1_if.c
@@ -29,6 +29,7 @@
 #include "../aml_vcodec_drv.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "../utils/common.h"
 
 #define KERNEL_ATRACE_TAG KERNEL_ATRACE_TAG_V4L2
@@ -117,9 +118,9 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_av1_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
-	struct vdec_comp_buf_info comp_info;
 };
 
 /*!\brief OBU types. */
@@ -206,7 +207,6 @@
 
 static int vdec_write_nalu(struct vdec_av1_inst *inst,
 	u8 *buf, u32 size, u64 ts);
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode);
 
 static void get_pic_info(struct vdec_av1_inst *inst,
 			 struct vdec_pic_info *pic)
@@ -246,12 +246,12 @@
 	u8 *pbuf = parm;
 
 	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
-	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
-	pbuf += sprintf(pbuf, "av1_double_write_mode:1;");
+	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:11;");
+	pbuf += sprintf(pbuf, "av1_double_write_mode:3;");
 	pbuf += sprintf(pbuf, "av1_buf_width:1920;");
 	pbuf += sprintf(pbuf, "av1_buf_height:1088;");
-	pbuf += sprintf(pbuf, "av1_max_pic_w:4096;");
-	pbuf += sprintf(pbuf, "av1_max_pic_h:2304;");
+	pbuf += sprintf(pbuf, "av1_max_pic_w:8192;");
+	pbuf += sprintf(pbuf, "av1_max_pic_h:4608;");
 	pbuf += sprintf(pbuf, "save_buffer_mode:0;");
 	pbuf += sprintf(pbuf, "no_head:0;");
 	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
@@ -264,10 +264,6 @@
 {
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"%s:parms_status = 0x%x, present_flag = %d\n",
-		__func__, ctx->config.parm.dec.parms_status,
-		ctx->config.parm.dec.hdr.color_parms.present_flag);
 	if (ctx->config.parm.dec.parms_status &
 		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
 		u8 *pbuf = ctx->config.buf;
@@ -277,8 +273,10 @@
 			ctx->config.parm.dec.cfg.ref_buf_margin);
 		pbuf += sprintf(pbuf, "av1_double_write_mode:%d;",
 			ctx->config.parm.dec.cfg.double_write_mode);
-		pbuf += sprintf(pbuf, "av1_buf_width:1920;");
-		pbuf += sprintf(pbuf, "av1_buf_height:1088;");
+		pbuf += sprintf(pbuf, "av1_buf_width:%d;",
+			ctx->config.parm.dec.cfg.init_width);
+		pbuf += sprintf(pbuf, "av1_buf_height:%d;",
+			ctx->config.parm.dec.cfg.init_height);
 		pbuf += sprintf(pbuf, "save_buffer_mode:0;");
 		pbuf += sprintf(pbuf, "no_head:0;");
 		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:%d;",
@@ -287,23 +285,19 @@
 			ctx->config.parm.dec.cfg.canvas_mem_endian);
 		pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
 			ctx->config.parm.dec.cfg.low_latency_mode);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
-		ctx->config.parm.dec.cfg.double_write_mode = 1;
+		ctx->config.parm.dec.cfg.double_write_mode = 16;
 		ctx->config.parm.dec.cfg.ref_buf_margin = 7;
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
 	}
 
 	if ((ctx->config.parm.dec.parms_status &
 		V4L2_CONFIG_PARM_DECODE_HDRINFO) &&
-		ctx->config.parm.dec.hdr.color_parms.present_flag) {
+		inst->parms.hdr.color_parms.present_flag) {
 		u8 *pbuf = ctx->config.buf + ctx->config.length;
 
 		pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
-		pbuf += sprintf(pbuf, "signal_type:%d;",
-			ctx->config.parm.dec.hdr.signal_type);
 		pbuf += sprintf(pbuf, "mG.x:%d;",
 			ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
 		pbuf += sprintf(pbuf, "mG.y:%d;",
@@ -332,8 +326,6 @@
 		inst->parms.hdr		= ctx->config.parm.dec.hdr;
 		inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
 	}
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"config.buf = %s\n", ctx->config.buf);
 
 	inst->vdec.config	= ctx->config;
 	inst->parms.cfg		= ctx->config.parm.dec.cfg;
@@ -349,7 +341,6 @@
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "AV1";
 	inst->vdec.video_type	= VFORMAT_AV1;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.ctx		= ctx;
@@ -364,6 +355,16 @@
 	/* to eable av1 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_HEVC;
 
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
+		goto err;
+	}
+
 	/* probe info from the stream */
 	inst->vsi = kzalloc(sizeof(struct vdec_av1_vsi), GFP_KERNEL);
 	if (!inst->vsi) {
@@ -372,7 +373,7 @@
 	}
 
 	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
 	if (!inst->vsi->header_buf) {
 		ret = -ENOMEM;
 		goto err;
@@ -380,6 +381,9 @@
 
 	init_completion(&inst->comp);
 
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		"av1 Instance >> %lx\n", (ulong) inst);
+
 	ctx->ada_ctx	= &inst->vdec;
 	*h_vdec		= (unsigned long)inst;
 
@@ -391,13 +395,14 @@
 		goto err;
 	}
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"av1 Instance >> %lx\n", (ulong) inst);
+	//dump_init();
 
 	return 0;
 err:
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -423,7 +428,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_av1_inst *inst,
@@ -444,7 +449,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_av1_inst *inst, u8 *buf, u32 size)
@@ -499,13 +504,19 @@
 
 static void vdec_av1_deinit(unsigned long h_vdec)
 {
+	ulong flags;
 	struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
+	spin_lock_irqsave(&ctx->slock, flags);
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -513,6 +524,42 @@
 	kfree(inst);
 
 	ctx->drv_handle = 0;
+	spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_av1_get_fb(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_av1_get_vf(struct vdec_av1_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
 }
 
 // Returns 1 when OBU type is valid, and 0 otherwise.
@@ -589,7 +636,7 @@
 	int i;
 	const size_t leb_size = uleb_size_in_bytes(value);
 
-	if (value > kMaximumLeb128Value || leb_size > kMaximumLeb128Size ||
+	if (leb_size > kMaximumLeb128Size ||
 		leb_size > available || !coded_value || !coded_size) {
 		return -1;
 	}
@@ -657,12 +704,13 @@
 static int read_obu_header(struct read_bit_buffer *rb,
 	int is_annexb, struct ObuHeader *header)
 {
-	const int bit_buffer_byte_length =
-		rb->bit_buffer_end - rb->bit_buffer;
+	int bit_buffer_byte_length;
 
 	if (!rb || !header)
 		return -1;
 
+	bit_buffer_byte_length = rb->bit_buffer_end - rb->bit_buffer;
+
 	if (bit_buffer_byte_length < 1)
 		return -1;
 
@@ -1000,13 +1048,13 @@
 		parser_frame(0, src, src + size, data, &length, meta_buffer, &meta_size);
 
 		if (length)
-			ret = vdec_vframe_write(vdec, data, length, ts, 0);
+			ret = vdec_vframe_write(vdec, data, length, ts);
 		else
 			ret = -1;
 
 		vfree(data);
 	} else {
-		ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+		ret = vdec_vframe_write(vdec, buf, size, ts);
 	}
 
 	return ret;
@@ -1040,14 +1088,18 @@
 {
 	struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
-	u8 *buf = (u8 *) bs->vaddr;
-	u32 size = bs->size;
+	u8 *buf;
+	u32 size;
 	int ret = -1;
 
 	if (bs == NULL)
 		return -1;
 
+	buf = (u8 *) bs->vaddr;
+	size = bs->size;
+
 	if (vdec_input_full(vdec)) {
+		ATRACE_COUNTER("vdec_input_full", 0);
 		return -EAGAIN;
 	}
 
@@ -1069,8 +1121,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -1086,6 +1137,7 @@
 
 		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
 	}
+	ATRACE_COUNTER("v4l2_decode_write", ret);
 
 	return ret;
 }
@@ -1093,12 +1145,8 @@
  static void get_param_config_info(struct vdec_av1_inst *inst,
 	struct aml_dec_params *parms)
  {
-	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO) {
-		/* dw use v4l cfg */
-		inst->parms.cfg.double_write_mode =
-			inst->ctx->config.parm.dec.cfg.double_write_mode;
-		parms->cfg = inst->parms.cfg;
-	 }
+	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_CFGINFO)
+		 parms->cfg = inst->parms.cfg;
 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_PSINFO)
 		 parms->ps = inst->parms.ps;
 	 if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
@@ -1108,16 +1156,10 @@
 
 	 parms->parms_status |= inst->parms.parms_status;
 
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 		"parms status: %u\n", parms->parms_status);
  }
 
-static void get_param_comp_buf_info(struct vdec_av1_inst *inst,
-		struct vdec_comp_buf_info *params)
-{
-	memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
 static int vdec_av1_get_param(unsigned long h_vdec,
 			       enum vdec_get_param_type type, void *out)
 {
@@ -1125,12 +1167,20 @@
 	struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the av1 inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_av1_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_av1_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -1147,20 +1197,6 @@
 		get_param_config_info(inst, out);
 		break;
 
-	case GET_PARAM_DW_MODE:
-	{
-		u32 *mode = out;
-		u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		if (m <= 16)
-			*mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		else
-			*mode = vdec_get_dw_mode(inst, 0);
-		break;
-	}
-	case GET_PARAM_COMP_BUF_INFO:
-		get_param_comp_buf_info(inst, out);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -1175,69 +1211,12 @@
 	complete(&inst->comp);
 }
 
-static int vdec_get_dw_mode(struct vdec_av1_inst *inst, int dw_mode)
-{
-	u32 valid_dw_mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
-	int w = inst->vsi->pic.coded_width;
-	int h = inst->vsi->pic.coded_height;
-	u32 dw = 0x1; /*1:1*/
-
-	switch (valid_dw_mode) {
-	case 0x100:
-		if (w > 1920 && h > 1088)
-			dw = 0x4; /*1:2*/
-		break;
-	case 0x200:
-		if (w > 1920 && h > 1088)
-			dw = 0x2; /*1:4*/
-		break;
-	case 0x300:
-		if (w > 1280 && h > 720)
-			dw = 0x4; /*1:2*/
-		break;
-	default:
-		dw = valid_dw_mode;
-		break;
-	}
-
-	return dw;
-}
-
-static int vdec_pic_scale(struct vdec_av1_inst *inst, int length, int dw_mode)
-{
-	int ret = 64;
-
-	switch (vdec_get_dw_mode(inst, dw_mode)) {
-	case 0x0: /* only afbc, output afbc */
-	case 0x21: /* only afbc, output afbc */
-		ret = 64;
-		break;
-	case 0x1: /* afbc and (w x h), output YUV420 */
-		ret = length;
-		break;
-	case 0x2: /* afbc and (w/4 x h/4), output YUV420 */
-	case 0x3: /* afbc and (w/4 x h/4), output afbc and YUV420 */
-		ret = length >> 2;
-		break;
-	case 0x4: /* afbc and (w/2 x h/2), output YUV420 */
-		ret = length >> 1;
-		break;
-	case 0x10: /* (w x h), output YUV420-8bit) */
-	default:
-		ret = length;
-		break;
-	}
-
-	return ret;
-}
-
 static void set_param_ps_info(struct vdec_av1_inst *inst,
 	struct aml_vdec_ps_infos *ps)
 {
 	struct vdec_pic_info *pic = &inst->vsi->pic;
 	struct vdec_av1_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
-	int dw = inst->parms.cfg.double_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -1253,16 +1232,11 @@
 	pic->coded_width	= ps->coded_width;
 	pic->coded_height	= ps->coded_height;
 
-	pic->y_len_sz		= ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
-				  ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
 	/* calc DPB size */
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
-	pic->field		= ps->field;
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
@@ -1272,27 +1246,23 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
 		ps->visible_width, ps->visible_height,
-		ps->coded_width, ps->coded_height);
-}
-
-static void set_param_comp_buf_info(struct vdec_av1_inst *inst,
-		struct vdec_comp_buf_info *info)
-{
-	memcpy(&inst->comp_info, info, sizeof(*info));
+		ps->coded_width, ps->coded_height,
+		ps->dpb_size);
 }
 
 static void set_param_hdr_info(struct vdec_av1_inst *inst,
 	struct aml_vdec_hdr_infos *hdr)
 {
-	if (hdr->signal_type != 0) {
+	if ((inst->parms.parms_status &
+		V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
 		inst->parms.hdr = *hdr;
 		inst->parms.parms_status |=
 			V4L2_CONFIG_PARM_DECODE_HDRINFO;
 		aml_vdec_dispatch_event(inst->ctx,
 			V4L2_EVENT_SRC_CH_HDRINFO);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_EXINFO,
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 			"av1 set HDR infos\n");
 	}
 }
@@ -1304,12 +1274,6 @@
 			"av1 post event: %d\n", *event);
 }
 
-static void set_pic_info(struct vdec_av1_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static int vdec_av1_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -1317,7 +1281,7 @@
 	struct vdec_av1_inst *inst = (struct vdec_av1_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the av1 inst of dec is invalid.\n");
 		return -1;
 	}
@@ -1331,10 +1295,6 @@
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_COMP_BUF_INFO:
-		set_param_comp_buf_info(inst, in);
-		break;
-
 	case SET_PARAM_HDR_INFO:
 		set_param_hdr_info(inst, in);
 		break;
@@ -1342,11 +1302,6 @@
 	case SET_PARAM_POST_EVENT:
 		set_param_post_event(inst, in);
 		break;
-
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_h264_if.c b/drivers/amvdec_ports/decoder/vdec_h264_if.c
index 911c91d..d13fc34 100644
--- a/drivers/amvdec_ports/decoder/vdec_h264_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_h264_if.c
@@ -30,6 +30,7 @@
 #include "../aml_vcodec_drv.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_h264_parser.h"
 #include "../utils/common.h"
 
@@ -149,6 +150,7 @@
 	struct aml_vcodec_mem mv_buf[H264_MAX_FB_NUM];
 	struct aml_vdec_adapt vdec;
 	struct vdec_h264_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
 };
@@ -279,10 +281,6 @@
 			ctx->config.parm.dec.cfg.canvas_mem_endian);
 		pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
 			ctx->config.parm.dec.cfg.low_latency_mode);
-		pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
-			ctx->config.parm.dec.cfg.metadata_config_flag);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
 		ctx->config.parm.dec.cfg.double_write_mode = 16;
@@ -299,13 +297,14 @@
 {
 	struct vdec_h264_inst *inst = NULL;
 	int ret = -1;
+	bool dec_init = false;
 
-	inst = vzalloc(sizeof(*inst));
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "H.264";
 	inst->vdec.video_type	= VFORMAT_H264;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.ctx		= ctx;
 	inst->ctx		= ctx;
@@ -316,43 +315,60 @@
 	if (ctx->is_drm_mode)
 		inst->vdec.port.flag |= PORT_FLAG_DRM;
 
-	/* probe info from the stream */
-	inst->vsi = vzalloc(sizeof(struct vdec_h264_vsi));
-	if (!inst->vsi) {
-		ret = -ENOMEM;
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
 		goto err;
 	}
 
-	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
-	if (!inst->vsi->header_buf) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	init_completion(&inst->comp);
-
-	ctx->ada_ctx	= &inst->vdec;
-	*h_vdec		= (unsigned long)inst;
-
 	ret = video_decoder_init(&inst->vdec);
 	if (ret) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"vdec_h264 init err=%d\n", ret);
 		goto err;
 	}
+	dec_init = true;
+
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_h264_vsi), GFP_KERNEL);
+	if (!inst->vsi) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* alloc the header buffer to be used cache sps or spp etc.*/
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
+	if (!inst->vsi->header_buf) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	init_completion(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 		"H264 Instance >> %lx", (ulong) inst);
 
+	ctx->ada_ctx	= &inst->vdec;
+	*h_vdec		= (unsigned long)inst;
+
+	//dump_init();
+
 	return 0;
 err:
-	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
-	if (inst && inst->vsi)
-		vfree(inst->vsi);
+	if (dec_init)
+		video_decoder_release(&inst->vdec);
 	if (inst)
-		vfree(inst);
+		vcodec_vfm_release(&inst->vfm);
+	if (inst && inst->vsi && inst->vsi->header_buf)
+		kfree(inst->vsi->header_buf);
+	if (inst && inst->vsi)
+		kfree(inst->vsi);
+	if (inst)
+		kfree(inst);
 	*h_vdec = 0;
 
 	return ret;
@@ -481,6 +497,7 @@
 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 	pic->profile_idc	= sps->profile_idc;
+	pic->ref_frame_count= sps->ref_frame_count;
 	/* calc DPB size */
 	dec->dpb_sz		= sps->num_reorder_frames + margin;
 
@@ -492,7 +509,7 @@
 	inst->parms.ps.mb_width		= sps->mb_width;
 	inst->parms.ps.mb_height	= sps->mb_height;
 	inst->parms.ps.ref_frames	= sps->ref_frame_count;
-	inst->parms.ps.dpb_frames	= sps->num_reorder_frames;
+	inst->parms.ps.reorder_frames	= sps->num_reorder_frames;
 	inst->parms.ps.dpb_size		= dec->dpb_sz;
 	inst->parms.parms_status	|= V4L2_CONFIG_PARM_DECODE_PSINFO;
 
@@ -554,7 +571,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+	ret = vdec_vframe_write(vdec, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -565,7 +582,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_h264_inst *inst,
@@ -586,7 +603,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_h264_inst *inst, u8 *buf, u32 size)
@@ -671,20 +688,71 @@
 
 static void vdec_h264_deinit(unsigned long h_vdec)
 {
+	ulong flags;
 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
+	spin_lock_irqsave(&ctx->slock, flags);
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
-		vfree(inst->vsi);
+		kfree(inst->vsi);
 
-	vfree(inst);
+	kfree(inst);
 
 	ctx->drv_handle = 0;
+	spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_h264_get_fb(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_h264_get_vf(struct vdec_h264_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	if (fb) {
+		fb->vf_handle = (unsigned long)vf;
+		fb->status = FB_ST_DISPLAY;
+	}
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.vaddr, fb->base_c.size);
 }
 
 static int vdec_write_nalu(struct vdec_h264_inst *inst,
@@ -734,7 +802,7 @@
 		inst->vsi->head_offset += inst->vsi->sei_size;
 		ret = size;
 	} else if (inst->vsi->head_offset == 0) {
-		ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+		ret = vdec_vframe_write(vdec, buf, size, ts);
 	} else {
 		char *write_buf = vmalloc(inst->vsi->head_offset + size);
 		if (!write_buf) {
@@ -746,7 +814,7 @@
 		memcpy(write_buf + inst->vsi->head_offset, buf, size);
 
 		ret = vdec_vframe_write(vdec, write_buf,
-			inst->vsi->head_offset + size, ts, 0);
+			inst->vsi->head_offset + size, ts);
 
 		memset(inst->vsi->header_buf, 0, HEADER_BUFFER_SIZE);
 		inst->vsi->head_offset = 0;
@@ -794,7 +862,9 @@
 		inst->vsi->cur_pic.coded_height !=
 		inst->vsi->pic.coded_height) ||
 		(inst->vsi->pic.profile_idc !=
-		inst->vsi->cur_pic.profile_idc))) {
+		inst->vsi->cur_pic.profile_idc) ||
+		(inst->vsi->pic.ref_frame_count !=
+		inst->vsi->cur_pic.ref_frame_count))) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO, "res change\n");
 		inst->vsi->cur_pic = inst->vsi->pic;
 		return true;
@@ -808,13 +878,16 @@
 {
 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
-	u8 *buf = (u8 *) bs->vaddr;
-	u32 size = bs->size;
+	u8 *buf;
+	u32 size;
 	int ret = -1;
 
 	if (bs == NULL)
 		return -1;
 
+	buf = (u8 *) bs->vaddr;
+	size = bs->size;
+
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
@@ -836,8 +909,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -889,12 +961,20 @@
 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the h264 inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_h264_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_h264_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -910,14 +990,6 @@
 	case GET_PARAM_CONFIG_INFO:
 		get_param_config_info(inst, out);
 		break;
-
-	case GET_PARAM_DW_MODE:
-	{
-		unsigned int* mode = out;
-		*mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		break;
-	}
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -956,10 +1028,8 @@
 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 	pic->profile_idc	= ps->profile;
+	pic->ref_frame_count	= ps->ref_frames;
 	pic->field		= ps->field;
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 
 	inst->parms.ps 	= *ps;
@@ -972,9 +1042,10 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+		"Parse from ucode, visible(%d x %d), coded(%d x %d) dpb: %d, scan: %s\n",
 		ps->visible_width, ps->visible_height,
 		ps->coded_width, ps->coded_height,
+		dec->dpb_sz,
 		ps->field == V4L2_FIELD_NONE ? "P" : "I");
 }
 
@@ -994,12 +1065,6 @@
 	}
 }
 
-static void set_pic_info(struct vdec_h264_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static void set_param_post_event(struct vdec_h264_inst *inst, u32 *event)
 {
 	aml_vdec_dispatch_event(inst->ctx, *event);
@@ -1014,7 +1079,7 @@
 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the h264 inst of dec is invalid.\n");
 		return -1;
 	}
@@ -1035,11 +1100,6 @@
 	case SET_PARAM_POST_EVENT:
 		set_param_post_event(inst, in);
 		break;
-
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_hevc_if.c b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
index 56d492a..2a41276 100644
--- a/drivers/amvdec_ports/decoder/vdec_hevc_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_hevc_if.c
@@ -29,6 +29,7 @@
 #include "../aml_vcodec_drv.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_hevc_parser.h"
 
 #define HEVC_NAL_TYPE(value)				((value >> 1) & 0x3F)
@@ -111,9 +112,9 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_hevc_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
-	struct vdec_comp_buf_info comp_info;
 };
 
 static void get_pic_info(struct vdec_hevc_inst *inst,
@@ -154,7 +155,7 @@
 
 	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
 	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
-	pbuf += sprintf(pbuf, "hevc_double_write_mode:1;");
+	pbuf += sprintf(pbuf, "hevc_double_write_mode:16;");
 	pbuf += sprintf(pbuf, "hevc_buf_width:4096;");
 	pbuf += sprintf(pbuf, "hevc_buf_height:2304;");
 	pbuf += sprintf(pbuf, "save_buffer_mode:0;");
@@ -186,13 +187,9 @@
 			ctx->config.parm.dec.cfg.canvas_mem_endian);
 		pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
 			ctx->config.parm.dec.cfg.low_latency_mode);
-		pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
-			ctx->config.parm.dec.cfg.metadata_config_flag);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
-		ctx->config.parm.dec.cfg.double_write_mode = 1;
+		ctx->config.parm.dec.cfg.double_write_mode = 16;
 		ctx->config.parm.dec.cfg.ref_buf_margin = 7;
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
 	}
@@ -206,13 +203,14 @@
 {
 	struct vdec_hevc_inst *inst = NULL;
 	int ret = -1;
+	bool dec_init = false;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "H.265";
 	inst->vdec.video_type	= VFORMAT_HEVC;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.ctx		= ctx;
 	inst->ctx		= ctx;
@@ -226,6 +224,24 @@
 	/* to eable hevc hw.*/
 	inst->vdec.port.type = PORT_TYPE_HEVC;
 
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
+		goto err;
+	}
+
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_hevc init err=%d\n", ret);
+		goto err;
+	}
+	dec_init = true;
+
 	/* probe info from the stream */
 	inst->vsi = kzalloc(sizeof(struct vdec_hevc_vsi), GFP_KERNEL);
 	if (!inst->vsi) {
@@ -234,7 +250,7 @@
 	}
 
 	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
 	if (!inst->vsi->header_buf) {
 		ret = -ENOMEM;
 		goto err;
@@ -242,23 +258,22 @@
 
 	init_completion(&inst->comp);
 
-	ctx->ada_ctx	= &inst->vdec;
-	*h_vdec		= (unsigned long)inst;
-
-	ret = video_decoder_init(&inst->vdec);
-	if (ret) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
-			"vdec_hevc init err=%d\n", ret);
-		goto err;
-	}
-
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 		"hevc Instance >> %lx\n", (ulong) inst);
 
+	ctx->ada_ctx	= &inst->vdec;
+	*h_vdec		= (unsigned long)inst;
+
+	//dump_init();
+
 	return 0;
 err:
+	if (dec_init)
+		video_decoder_release(&inst->vdec);
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -302,8 +317,8 @@
 static int vdec_get_dw_mode(struct vdec_hevc_inst *inst, int dw_mode)
 {
 	u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
-	int w = inst->vsi->pic.coded_width;
-	int h = inst->vsi->pic.coded_height;
+	int w = inst->parms.cfg.init_width;
+	int h = inst->parms.cfg.init_height;
 	u32 dw = 0x1; /*1:1*/
 
 	switch (valid_dw_mode) {
@@ -406,7 +421,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+	ret = vdec_vframe_write(vdec, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -417,7 +432,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_hevc_inst *inst,
@@ -438,7 +453,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_hevc_inst *inst, u8 *buf, u32 size)
@@ -511,13 +526,19 @@
 
 static void vdec_hevc_deinit(unsigned long h_vdec)
 {
+	ulong flags;
 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
+	spin_lock_irqsave(&ctx->slock, flags);
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -525,6 +546,49 @@
 	kfree(inst);
 
 	ctx->drv_handle = 0;
+	spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static int vdec_hevc_get_fb(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_hevc_get_vf(struct vdec_hevc_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.vaddr, fb->base_c.size);
 }
 
 static int vdec_write_nalu(struct vdec_hevc_inst *inst,
@@ -533,7 +597,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+	ret = vdec_vframe_write(vdec, buf, size, ts);
 
 	return ret;
 }
@@ -580,13 +644,16 @@
 {
 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
-	u8 *buf = (u8 *) bs->vaddr;
-	u32 size = bs->size;
+	u8 *buf;
+	u32 size;
 	int ret = -1;
 
 	if (bs == NULL)
 		return -1;
 
+	buf = (u8 *) bs->vaddr;
+	size = bs->size;
+
 	if (vdec_input_full(vdec))
 		return -EAGAIN;
 
@@ -608,8 +675,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -647,12 +713,6 @@
 		"parms status: %u\n", parms->parms_status);
  }
 
-static void get_param_comp_buf_info(struct vdec_hevc_inst *inst,
-		struct vdec_comp_buf_info *params)
-{
-	memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
 static int vdec_hevc_get_param(unsigned long h_vdec,
 			       enum vdec_get_param_type type, void *out)
 {
@@ -660,12 +720,20 @@
 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the hevc inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_hevc_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_hevc_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -681,21 +749,6 @@
 	case GET_PARAM_CONFIG_INFO:
 		get_param_config_info(inst, out);
 		break;
-
-	case GET_PARAM_DW_MODE:
-	{
-		u32 *mode = out;
-		u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		if (m <= 16)
-			*mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		else
-			*mode = vdec_get_dw_mode(inst, 0);
-		break;
-	}
-	case GET_PARAM_COMP_BUF_INFO:
-		get_param_comp_buf_info(inst, out);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -716,7 +769,6 @@
 	struct vdec_pic_info *pic = &inst->vsi->pic;
 	struct vdec_hevc_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
-	int dw = inst->parms.cfg.double_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -732,14 +784,9 @@
 
 	pic->coded_width 	= ps->coded_width;
 	pic->coded_height 	= ps->coded_height;
-
-	pic->y_len_sz		= ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
-				  ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
 
@@ -751,27 +798,13 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d, scan: %s\n",
 		pic->visible_width, pic->visible_height,
 		pic->coded_width, pic->coded_height,
+		dec->dpb_sz,
 		pic->field == V4L2_FIELD_NONE ? "P" : "I");
 }
 
-static void set_cfg_info(struct vdec_hevc_inst *inst,
-	struct aml_vdec_cfg_infos *cfg)
-{
-	memcpy(&inst->ctx->config.parm.dec.cfg,
-		cfg, sizeof(struct aml_vdec_cfg_infos));
-	memcpy(&inst->parms.cfg,
-		cfg, sizeof(struct aml_vdec_cfg_infos));
-}
-
-static void set_param_comp_buf_info(struct vdec_hevc_inst *inst,
-		struct vdec_comp_buf_info *info)
-{
-	memcpy(&inst->comp_info, info, sizeof(*info));
-}
-
 static void set_param_hdr_info(struct vdec_hevc_inst *inst,
 	struct aml_vdec_hdr_infos *hdr)
 {
@@ -794,12 +827,6 @@
 		"H265 post event: %d\n", *event);
 }
 
-static void set_pic_info(struct vdec_hevc_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static int vdec_hevc_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -807,7 +834,7 @@
 	struct vdec_hevc_inst *inst = (struct vdec_hevc_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the hevc inst of dec is invalid.\n");
 		return -1;
 	}
@@ -817,18 +844,10 @@
 		set_param_write_sync(inst);
 		break;
 
-	case SET_PARAM_CFG_INFO:
-		set_cfg_info(inst, in);
-		break;
-
 	case SET_PARAM_PS_INFO:
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_COMP_BUF_INFO:
-		set_param_comp_buf_info(inst, in);
-		break;
-
 	case SET_PARAM_HDR_INFO:
 		set_param_hdr_info(inst, in);
 		break;
@@ -836,10 +855,6 @@
 	case SET_PARAM_POST_EVENT:
 		set_param_post_event(inst, in);
 		break;
-
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
index 8332956..f9816cc 100644
--- a/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mjpeg_if.c
@@ -28,6 +28,7 @@
 #include "../aml_vcodec_dec.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_mjpeg_parser.h"
 #include <media/v4l2-mem2mem.h>
 
@@ -111,6 +112,7 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_mjpeg_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
 };
@@ -156,7 +158,6 @@
 	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
 	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_mode:0;");
 	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:0;");
-	pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:0;");
 
 	return pbuf - parm;
 }
@@ -176,8 +177,6 @@
 			ctx->config.parm.dec.cfg.ref_buf_margin);
 		pbuf += sprintf(pbuf, "parm_v4l_canvas_mem_endian:%d;",
 			ctx->config.parm.dec.cfg.canvas_mem_endian);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -193,13 +192,14 @@
 {
 	struct vdec_mjpeg_inst *inst = NULL;
 	int ret = -1;
+	bool dec_init = false;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "MJPEG";
 	inst->vdec.video_type	= VFORMAT_MJPEG;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.config	= ctx->config;
 	inst->vdec.ctx		= ctx;
@@ -213,6 +213,24 @@
 	/* to eable mjpeg hw.*/
 	inst->vdec.port.type = PORT_TYPE_VIDEO;
 
+	/* init vfm */
+	inst->vfm.ctx	= ctx;
+	inst->vfm.ada_ctx = &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
+		goto err;
+	}
+
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_mjpeg init err=%d\n", ret);
+		goto err;
+	}
+	dec_init = true;
+
 	/* probe info from the stream */
 	inst->vsi = kzalloc(sizeof(struct vdec_mjpeg_vsi), GFP_KERNEL);
 	if (!inst->vsi) {
@@ -221,31 +239,30 @@
 	}
 
 	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
 	if (!inst->vsi->header_buf) {
 		ret = -ENOMEM;
 		goto err;
 	}
 
-	init_completion(&inst->comp);
-	ctx->ada_ctx	= &inst->vdec;
-	*h_vdec		= (unsigned long)inst;
-
-	ret = video_decoder_init(&inst->vdec);
-	if (ret) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
-			"vdec_mjpeg init err=%d\n", ret);
-		goto err;
-	}
-
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 		"mjpeg Instance >> %lx\n", (ulong) inst);
 
+	init_completion(&inst->comp);
+	ctx->ada_ctx	= &inst->vdec;
+	*h_vdec		= (unsigned long)inst;
+
+	//dump_init();
+
 	return 0;
 
 err:
+	if (dec_init)
+		video_decoder_release(&inst->vdec);
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -291,9 +308,9 @@
 	dec->dpb_sz = 8;
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_BUFMGR,
-		"The stream infos, coded:(%d x %d), visible:(%d x %d)\n",
+		"The stream infos, coded:(%d x %d), visible:(%d x %d), DPB: %d\n",
 		pic->coded_width, pic->coded_height,
-		pic->visible_width, pic->visible_height);
+		pic->visible_width, pic->visible_height, dec->dpb_sz);
 }
 
 static int parse_stream_ucode(struct vdec_mjpeg_inst *inst,
@@ -302,7 +319,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+	ret = vdec_vframe_write(vdec, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -313,7 +330,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_mjpeg_inst *inst,
@@ -334,7 +351,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_mjpeg_inst *inst, u8 *buf, u32 size)
@@ -414,8 +431,12 @@
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -423,13 +444,55 @@
 	kfree(inst);
 }
 
+static int vdec_mjpeg_get_fb(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mjpeg_get_vf(struct vdec_mjpeg_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.va, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
 static int vdec_write_nalu(struct vdec_mjpeg_inst *inst,
 	u8 *buf, u32 size, u64 ts)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+	ret = vdec_vframe_write(vdec, buf, size, ts);
 
 	return ret;
 }
@@ -457,8 +520,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -480,12 +542,20 @@
 	struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mjpeg inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_mjpeg_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_mjpeg_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -498,13 +568,6 @@
 		get_crop_info(inst, out);
 		break;
 
-	case GET_PARAM_DW_MODE:
-	{
-		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
-		break;
-	}
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -536,13 +599,9 @@
 	pic->coded_width	= ps->coded_width;
 	pic->coded_height	= ps->coded_height;
 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
-	pic->c_len_sz		= pic->y_len_sz >> 1;
+	pic->c_len_sz		= pic->y_len_sz;
 
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
-	pic->field		= ps->field;
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
@@ -552,10 +611,10 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
 		ps->visible_width, ps->visible_height,
 		ps->coded_width, ps->coded_height,
-		pic->field == V4L2_FIELD_NONE ? "P" : "I");
+		dec->dpb_sz);
 }
 
 static void set_param_write_sync(struct vdec_mjpeg_inst *inst)
@@ -563,12 +622,6 @@
 	complete(&inst->comp);
 }
 
-static void set_pic_info(struct vdec_mjpeg_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static int vdec_mjpeg_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -576,7 +629,7 @@
 	struct vdec_mjpeg_inst *inst = (struct vdec_mjpeg_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mjpeg inst of dec is invalid.\n");
 		return -1;
 	}
@@ -585,15 +638,10 @@
 	case SET_PARAM_WRITE_FRAME_SYNC:
 		set_param_write_sync(inst);
 		break;
-
 	case SET_PARAM_PS_INFO:
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
index 2472ac1..9a38e71 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg12_if.c
@@ -28,6 +28,7 @@
 #include "../aml_vcodec_dec.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_mpeg12_parser.h"
 
 #define NAL_TYPE(value)				((value) & 0x1F)
@@ -110,6 +111,7 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_mpeg12_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
 };
@@ -171,10 +173,6 @@
 			ctx->config.parm.dec.cfg.canvas_mem_mode);
 		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
 			ctx->config.parm.dec.cfg.ref_buf_margin);
-		pbuf += sprintf(pbuf, "parm_v4l_metadata_config_flag:%d;",
-			ctx->config.parm.dec.cfg.metadata_config_flag);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -189,13 +187,14 @@
 {
 	struct vdec_mpeg12_inst *inst = NULL;
 	int ret = -1;
+	bool dec_init = false;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "MPEG2";
 	inst->vdec.video_type	= VFORMAT_MPEG12;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.config	= ctx->config;
 	inst->vdec.ctx		= ctx;
@@ -210,6 +209,24 @@
 	/* to eable mpeg12 hw.*/
 	inst->vdec.port.type = PORT_TYPE_VIDEO;
 
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
+		goto err;
+	}
+
+	ret = video_decoder_init(&inst->vdec);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"vdec_mpeg12 init err=%d\n", ret);
+		goto err;
+	}
+	dec_init = true;
+
 	/* probe info from the stream */
 	inst->vsi = kzalloc(sizeof(struct vdec_mpeg12_vsi), GFP_KERNEL);
 	if (!inst->vsi) {
@@ -218,31 +235,29 @@
 	}
 
 	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
 	if (!inst->vsi->header_buf) {
 		ret = -ENOMEM;
 		goto err;
 	}
 
+	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
+		"mpeg12 Instance >> %lx\n", (ulong) inst);
 	init_completion(&inst->comp);
 	ctx->ada_ctx	= &inst->vdec;
 	*h_vdec		= (unsigned long)inst;
 
-	ret = video_decoder_init(&inst->vdec);
-	if (ret) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
-			"vdec_mpeg12 init err=%d\n", ret);
-		goto err;
-	}
-
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"mpeg12 Instance >> %lx\n", (ulong) inst);
+	//dump_init();
 
 	return 0;
 
 err:
+	if (dec_init)
+		video_decoder_release(&inst->vdec);
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -291,7 +306,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+	ret = vdec_vframe_write(vdec, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -302,7 +317,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_mpeg12_inst *inst,
@@ -323,7 +338,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_mpeg12_inst *inst, u8 *buf, u32 size)
@@ -403,8 +418,12 @@
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -412,13 +431,55 @@
 	kfree(inst);
 }
 
+static int vdec_mpeg12_get_fb(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mpeg12_get_vf(struct vdec_mpeg12_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.va, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
 static int vdec_write_nalu(struct vdec_mpeg12_inst *inst,
 	u8 *buf, u32 size, u64 ts)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+	ret = vdec_vframe_write(vdec, buf, size, ts);
 
 	return ret;
 }
@@ -446,8 +507,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -462,19 +522,6 @@
 	return ret;
 }
 
-static void get_param_config_info(struct vdec_mpeg12_inst *inst,
-  struct aml_dec_params *parms)
-{
-
-	if (inst->parms.parms_status & V4L2_CONFIG_PARM_DECODE_HDRINFO)
-		parms->hdr = inst->parms.hdr;
-
-	parms->parms_status |= inst->parms.parms_status;
-
-	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"parms status: %u\n", parms->parms_status);
-}
-
 static int vdec_mpeg12_get_param(unsigned long h_vdec,
 			       enum vdec_get_param_type type, void *out)
 {
@@ -482,12 +529,20 @@
 	struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mpeg12 inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_mpeg12_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_mpeg12_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -500,17 +555,6 @@
 		get_crop_info(inst, out);
 		break;
 
-	case GET_PARAM_CONFIG_INFO:
-		get_param_config_info(inst, out);
-		break;
-
-	case GET_PARAM_DW_MODE:
-	{
-		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
-		break;
-	}
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -525,12 +569,6 @@
 	complete(&inst->comp);
 }
 
-static void set_pic_info(struct vdec_mpeg12_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static void set_param_ps_info(struct vdec_mpeg12_inst *inst,
 	struct aml_vdec_ps_infos *ps)
 {
@@ -554,9 +592,6 @@
 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
 
@@ -568,28 +603,13 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d scan: %s\n",
 		ps->visible_width, ps->visible_height,
 		ps->coded_width, ps->coded_height,
+		dec->dpb_sz,
 		pic->field == V4L2_FIELD_NONE ? "P" : "I");
 }
 
-static void set_param_hdr_info(struct vdec_mpeg12_inst *inst,
-	struct aml_vdec_hdr_infos *hdr)
-{
-	inst->parms.hdr = *hdr;
-	if (!(inst->parms.parms_status &
-		V4L2_CONFIG_PARM_DECODE_HDRINFO)) {
-		inst->parms.hdr = *hdr;
-		inst->parms.parms_status |=
-			V4L2_CONFIG_PARM_DECODE_HDRINFO;
-		aml_vdec_dispatch_event(inst->ctx,
-			V4L2_EVENT_SRC_CH_HDRINFO);
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-			"mpeg12 set HDR infos\n");
-	}
-}
-
 static int vdec_mpeg12_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -597,7 +617,7 @@
 	struct vdec_mpeg12_inst *inst = (struct vdec_mpeg12_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mpeg12 inst of dec is invalid.\n");
 		return -1;
 	}
@@ -606,19 +626,10 @@
 	case SET_PARAM_WRITE_FRAME_SYNC:
 		set_param_write_sync(inst);
 		break;
-
-	case SET_PARAM_HDR_INFO:
-		set_param_hdr_info(inst, in);
-		break;
-
 	case SET_PARAM_PS_INFO:
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
index bc0af24..c47bafc 100644
--- a/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_mpeg4_if.c
@@ -28,6 +28,7 @@
 #include "../aml_vcodec_dec.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_mpeg4_parser.h"
 
 #define NAL_TYPE(value)				((value) & 0x1F)
@@ -110,6 +111,7 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_mpeg4_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
 };
@@ -171,8 +173,6 @@
 			ctx->config.parm.dec.cfg.canvas_mem_mode);
 		pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:%d;",
 			ctx->config.parm.dec.cfg.ref_buf_margin);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
@@ -188,14 +188,15 @@
 {
 	struct vdec_mpeg4_inst *inst = NULL;
 	int ret = -1;
+	bool dec_init = false;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "MPEG4";
 	inst->vdec.video_type	= VFORMAT_MPEG4;
 	inst->vdec.format	= VIDEO_DEC_FORMAT_MPEG4_5;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.config	= ctx->config;
 	inst->vdec.ctx		= ctx;
@@ -209,23 +210,16 @@
 	/* to eable mpeg4 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_VIDEO;
 
-	/* probe info from the stream */
-	inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL);
-	if (!inst->vsi) {
-		ret = -ENOMEM;
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
 		goto err;
 	}
-
-	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
-	if (!inst->vsi->header_buf) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	init_completion(&inst->comp);
-	ctx->ada_ctx	= &inst->vdec;
-	*h_vdec		= (unsigned long)inst;
+	dec_init = true;
 
 	ret = video_decoder_init(&inst->vdec);
 	if (ret) {
@@ -234,14 +228,38 @@
 		goto err;
 	}
 
+	/* probe info from the stream */
+	inst->vsi = kzalloc(sizeof(struct vdec_mpeg4_vsi), GFP_KERNEL);
+	if (!inst->vsi) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* alloc the header buffer to be used cache sps or spp etc.*/
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
+	if (!inst->vsi->header_buf) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
 		"mpeg4 Instance >> %lx\n", (ulong) inst);
 
+	init_completion(&inst->comp);
+	ctx->ada_ctx	= &inst->vdec;
+	*h_vdec		= (unsigned long)inst;
+
+	//dump_init();
+
 	return 0;
 
 err:
+	if (dec_init)
+		video_decoder_release(&inst->vdec);
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -298,7 +316,7 @@
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, timestamp, 0);
+	ret = vdec_vframe_write(vdec, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -309,7 +327,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_mpeg4_inst *inst,
@@ -330,7 +348,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_mpeg4_inst *inst, u8 *buf, u32 size)
@@ -410,8 +428,12 @@
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -419,13 +441,55 @@
 	kfree(inst);
 }
 
+static int vdec_mpeg4_get_fb(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_mpeg4_get_vf(struct vdec_mpeg4_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.va, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.va, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.va, fb->base_c.size);
+}
+
 static int vdec_write_nalu(struct vdec_mpeg4_inst *inst,
 	u8 *buf, u32 size, u64 ts)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
 
-	ret = vdec_vframe_write(vdec, buf, size, ts, 0);
+	ret = vdec_vframe_write(vdec, buf, size, ts);
 
 	return ret;
 }
@@ -453,8 +517,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -476,12 +539,20 @@
 	struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mpeg4 inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_mpeg4_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_mpeg4_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -493,12 +564,6 @@
 	case GET_PARAM_CROP_INFO:
 		get_crop_info(inst, out);
 		break;
-	case GET_PARAM_DW_MODE:
-	{
-		unsigned int* mode = out;
-		*mode = VDEC_DW_NO_AFBC;
-		break;
-	}
 
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
@@ -533,9 +598,6 @@
 	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
 	pic->field		= ps->field;
 
@@ -547,9 +609,10 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d), scan:%s\n",
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d, scan:%s\n",
 		ps->visible_width, ps->visible_height,
 		ps->coded_width, ps->coded_height,
+		dec->dpb_sz,
 		pic->field == V4L2_FIELD_NONE ? "P" : "I");
 }
 
@@ -558,12 +621,6 @@
 	complete(&inst->comp);
 }
 
-static void set_pic_info(struct vdec_mpeg4_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static int vdec_mpeg4_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -571,7 +628,7 @@
 	struct vdec_mpeg4_inst *inst = (struct vdec_mpeg4_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the mpeg4 inst of dec is invalid.\n");
 		return -1;
 	}
@@ -580,15 +637,10 @@
 	case SET_PARAM_WRITE_FRAME_SYNC:
 		set_param_write_sync(inst);
 		break;
-
 	case SET_PARAM_PS_INFO:
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/decoder/vdec_vp9_if.c b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
index fe81ddd..6704350 100644
--- a/drivers/amvdec_ports/decoder/vdec_vp9_if.c
+++ b/drivers/amvdec_ports/decoder/vdec_vp9_if.c
@@ -29,6 +29,7 @@
 #include "../aml_vcodec_drv.h"
 #include "../aml_vcodec_adapt.h"
 #include "../vdec_drv_base.h"
+#include "../aml_vcodec_vfm.h"
 #include "aml_vp9_parser.h"
 #include "vdec_vp9_trigger.h"
 
@@ -122,13 +123,13 @@
 	struct aml_vcodec_ctx *ctx;
 	struct aml_vdec_adapt vdec;
 	struct vdec_vp9_vsi *vsi;
+	struct vcodec_vfm_s vfm;
 	struct aml_dec_params parms;
 	struct completion comp;
-	struct vdec_comp_buf_info comp_info;
 };
 
 static int vdec_write_nalu(struct vdec_vp9_inst *inst,
-	u8 *buf, u32 size, u64 ts, ulong meta_ptr);
+	u8 *buf, u32 size, u64 ts);
 
 static void get_pic_info(struct vdec_vp9_inst *inst,
 			 struct vdec_pic_info *pic)
@@ -169,7 +170,7 @@
 
 	pbuf += sprintf(pbuf, "parm_v4l_codec_enable:1;");
 	pbuf += sprintf(pbuf, "parm_v4l_buffer_margin:7;");
-	pbuf += sprintf(pbuf, "vp9_double_write_mode:1;");
+	pbuf += sprintf(pbuf, "vp9_double_write_mode:16;");
 	pbuf += sprintf(pbuf, "vp9_buf_width:1920;");
 	pbuf += sprintf(pbuf, "vp9_buf_height:1088;");
 	pbuf += sprintf(pbuf, "vp9_max_pic_w:4096;");
@@ -186,10 +187,6 @@
 {
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"%s:parms_status = 0x%x, present_flag = %d\n",
-		__func__, ctx->config.parm.dec.parms_status,
-		ctx->config.parm.dec.hdr.color_parms.present_flag);
 	if (ctx->config.parm.dec.parms_status &
 		V4L2_CONFIG_PARM_DECODE_CFGINFO) {
 		u8 *pbuf = ctx->config.buf;
@@ -211,11 +208,9 @@
 			ctx->config.parm.dec.cfg.canvas_mem_endian);
 		pbuf += sprintf(pbuf, "parm_v4l_low_latency_mode:%d;",
 			ctx->config.parm.dec.cfg.low_latency_mode);
-		pbuf += sprintf(pbuf, "parm_v4l_duration:%d;",
-			ctx->config.parm.dec.cfg.duration);
 		ctx->config.length = pbuf - ctx->config.buf;
 	} else {
-		ctx->config.parm.dec.cfg.double_write_mode = 1;
+		ctx->config.parm.dec.cfg.double_write_mode = 16;
 		ctx->config.parm.dec.cfg.ref_buf_margin = 7;
 		ctx->config.length = vdec_config_default_parms(ctx->config.buf);
 	}
@@ -226,8 +221,6 @@
 		u8 *pbuf = ctx->config.buf + ctx->config.length;
 
 		pbuf += sprintf(pbuf, "HDRStaticInfo:%d;", 1);
-		pbuf += sprintf(pbuf, "signal_type:%d;",
-			ctx->config.parm.dec.hdr.signal_type);
 		pbuf += sprintf(pbuf, "mG.x:%d;",
 			ctx->config.parm.dec.hdr.color_parms.primaries[0][0]);
 		pbuf += sprintf(pbuf, "mG.y:%d;",
@@ -256,8 +249,6 @@
 		inst->parms.hdr		= ctx->config.parm.dec.hdr;
 		inst->parms.parms_status |= V4L2_CONFIG_PARM_DECODE_HDRINFO;
 	}
-	v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO,
-		"config.buf = %s\n", ctx->config.buf);
 
 	inst->vdec.config	= ctx->config;
 	inst->parms.cfg		= ctx->config.parm.dec.cfg;
@@ -273,8 +264,8 @@
 	if (!inst)
 		return -ENOMEM;
 
-	inst->vdec.frm_name	= "VP9";
 	inst->vdec.video_type	= VFORMAT_VP9;
+	inst->vdec.dev		= ctx->dev->vpu_plat_dev;
 	inst->vdec.filp		= ctx->dev->filp;
 	inst->vdec.ctx		= ctx;
 	inst->ctx		= ctx;
@@ -288,6 +279,16 @@
 	/* to eable vp9 hw.*/
 	inst->vdec.port.type	= PORT_TYPE_HEVC;
 
+	/* init vfm */
+	inst->vfm.ctx		= ctx;
+	inst->vfm.ada_ctx	= &inst->vdec;
+	ret = vcodec_vfm_init(&inst->vfm);
+	if (ret) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"init vfm failed.\n");
+		goto err;
+	}
+
 	/* probe info from the stream */
 	inst->vsi = kzalloc(sizeof(struct vdec_vp9_vsi), GFP_KERNEL);
 	if (!inst->vsi) {
@@ -296,7 +297,7 @@
 	}
 
 	/* alloc the header buffer to be used cache sps or spp etc.*/
-	inst->vsi->header_buf = vzalloc(HEADER_BUFFER_SIZE);
+	inst->vsi->header_buf = kzalloc(HEADER_BUFFER_SIZE, GFP_KERNEL);
 	if (!inst->vsi->header_buf) {
 		ret = -ENOMEM;
 		goto err;
@@ -318,10 +319,14 @@
 		goto err;
 	}
 
+	//dump_init();
+
 	return 0;
 err:
+	if (inst)
+		vcodec_vfm_release(&inst->vfm);
 	if (inst && inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 	if (inst && inst->vsi)
 		kfree(inst->vsi);
 	if (inst)
@@ -342,8 +347,8 @@
 static int vdec_get_dw_mode(struct vdec_vp9_inst *inst, int dw_mode)
 {
 	u32 valid_dw_mode = inst->parms.cfg.double_write_mode;
-	int w = inst->vsi->pic.coded_width;
-	int h = inst->vsi->pic.coded_height;
+	int w = inst->parms.cfg.init_width;
+	int h = inst->parms.cfg.init_height;
 	u32 dw = 0x1; /*1:1*/
 
 	switch (valid_dw_mode) {
@@ -438,11 +443,11 @@
 }
 
 static int parse_stream_ucode(struct vdec_vp9_inst *inst,
-			      u8 *buf, u32 size, u64 timestamp, ulong meta_ptr)
+			      u8 *buf, u32 size, u64 timestamp)
 {
 	int ret = 0;
 
-	ret = vdec_write_nalu(inst, buf, size, timestamp, meta_ptr);
+	ret = vdec_write_nalu(inst, buf, size, timestamp);
 	if (ret < 0) {
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write frame data failed. err: %d\n", ret);
@@ -453,7 +458,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_ucode_dma(struct vdec_vp9_inst *inst,
@@ -474,7 +479,7 @@
 	wait_for_completion_timeout(&inst->comp,
 		msecs_to_jiffies(1000));
 
-	return inst->vsi->pic.dpb_frames ? 0 : -1;
+	return inst->vsi->dec.dpb_sz ? 0 : -1;
 }
 
 static int parse_stream_cpu(struct vdec_vp9_inst *inst, u8 *buf, u32 size)
@@ -523,7 +528,7 @@
 
 			if (inst->ctx->param_sets_from_ucode) {
 				ret = parse_stream_ucode(inst, s->data,
-					s->len, bs->timestamp, 0);
+					s->len, bs->timestamp);
 			} else {
 				ret = parse_stream_cpu(inst, s->data, s->len);
 			}
@@ -534,7 +539,7 @@
 		}
 	} else {
 		if (inst->ctx->param_sets_from_ucode) {
-			ret = parse_stream_ucode(inst, buf, size, bs->timestamp, bs->meta_ptr);
+			ret = parse_stream_ucode(inst, buf, size, bs->timestamp);
 		} else {
 			ret = parse_stream_cpu(inst, buf, size);
 		}
@@ -547,13 +552,19 @@
 
 static void vdec_vp9_deinit(unsigned long h_vdec)
 {
+	ulong flags;
 	struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
 	struct aml_vcodec_ctx *ctx = inst->ctx;
 
 	video_decoder_release(&inst->vdec);
 
+	vcodec_vfm_release(&inst->vfm);
+
+	//dump_deinit();
+
+	spin_lock_irqsave(&ctx->slock, flags);
 	if (inst->vsi && inst->vsi->header_buf)
-		vfree(inst->vsi->header_buf);
+		kfree(inst->vsi->header_buf);
 
 	if (inst->vsi)
 		kfree(inst->vsi);
@@ -561,11 +572,54 @@
 	kfree(inst);
 
 	ctx->drv_handle = 0;
+	spin_unlock_irqrestore(&ctx->slock, flags);
 
 	need_trigger = false;
 	dump_cnt = 0;
 }
 
+static int vdec_vp9_get_fb(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	return get_fb_from_queue(inst->ctx, out);
+}
+
+static void vdec_vp9_get_vf(struct vdec_vp9_inst *inst, struct vdec_v4l2_buffer **out)
+{
+	struct vframe_s *vf = NULL;
+	struct vdec_v4l2_buffer *fb = NULL;
+
+	vf = peek_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"there is no vframe.\n");
+		*out = NULL;
+		return;
+	}
+
+	vf = get_video_frame(&inst->vfm);
+	if (!vf) {
+		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+			"the vframe is avalid.\n");
+		*out = NULL;
+		return;
+	}
+
+	atomic_set(&vf->use_cnt, 1);
+
+	fb = (struct vdec_v4l2_buffer *)vf->v4l_mem_handle;
+	fb->vf_handle = (unsigned long)vf;
+	fb->status = FB_ST_DISPLAY;
+
+	*out = fb;
+
+	//pr_info("%s, %d\n", __func__, fb->base_y.bytes_used);
+	//dump_write(fb->base_y.vaddr, fb->base_y.bytes_used);
+	//dump_write(fb->base_c.vaddr, fb->base_c.bytes_used);
+
+	/* convert yuv format. */
+	//swap_uv(fb->base_c.vaddr, fb->base_c.size);
+}
+
 static void add_prefix_data(struct vp9_superframe_split *s,
 	u8 **out, u32 *out_size)
 {
@@ -716,7 +770,7 @@
 	for (i = 0; i < ARRAY_SIZE(vp9_trigger_framesize); i++) {
 		frame_size = vp9_trigger_framesize[i];
 		ret = vdec_vframe_write(vdec, p,
-			frame_size, 0, 0);
+			frame_size, 0);
 		v4l_dbg(vdec->ctx, V4L_DEBUG_CODEC_ERROR,
 			"write trigger frame %d\n", ret);
 		p += frame_size;
@@ -724,7 +778,7 @@
 }
 
 static int vdec_write_nalu(struct vdec_vp9_inst *inst,
-	u8 *buf, u32 size, u64 ts, ulong meta_ptr)
+	u8 *buf, u32 size, u64 ts)
 {
 	int ret = 0;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
@@ -754,10 +808,10 @@
 
 		/*add headers.*/
 		add_prefix_data(&s, &data, &length);
-		ret = vdec_vframe_write(vdec, data, length, ts, 0);
+		ret = vdec_vframe_write(vdec, data, length, ts);
 		vfree(data);
 	} else {
-		ret = vdec_vframe_write(vdec, buf, size, ts, meta_ptr);
+		ret = vdec_vframe_write(vdec, buf, size, ts);
 	}
 
 	return ret;
@@ -791,14 +845,18 @@
 {
 	struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
 	struct aml_vdec_adapt *vdec = &inst->vdec;
-	u8 *buf = (u8 *) bs->vaddr;
-	u32 size = bs->size;
+	u8 *buf;
+	u32 size;
 	int ret = -1;
 
 	if (bs == NULL)
 		return -1;
 
+	buf = (u8 *) bs->vaddr;
+	size = bs->size;
+
 	if (vdec_input_full(vdec)) {
+		ATRACE_COUNTER("vdec_input_full", 0);
 		return -EAGAIN;
 	}
 
@@ -820,8 +878,7 @@
 			ret = vdec_vframe_write(vdec,
 				s->data,
 				s->len,
-				bs->timestamp,
-				0);
+				bs->timestamp);
 		} else if (bs->model == VB2_MEMORY_DMABUF ||
 			bs->model == VB2_MEMORY_USERPTR) {
 			ret = vdec_vframe_write_with_dma(vdec,
@@ -834,8 +891,10 @@
 		if ((!inst->ctx->param_sets_from_ucode) &&
 			(*res_chg = monitor_res_change(inst, buf, size)))
 			return 0;
-		ret = vdec_write_nalu(inst, buf, size, bs->timestamp, bs->meta_ptr);
+
+		ret = vdec_write_nalu(inst, buf, size, bs->timestamp);
 	}
+	ATRACE_COUNTER("v4l2_decode_write", ret);
 
 	return ret;
 }
@@ -858,12 +917,6 @@
 		"parms status: %u\n", parms->parms_status);
  }
 
-static void get_param_comp_buf_info(struct vdec_vp9_inst *inst,
-		struct vdec_comp_buf_info *params)
-{
-	memcpy(params, &inst->comp_info, sizeof(*params));
-}
-
 static int vdec_vp9_get_param(unsigned long h_vdec,
 			       enum vdec_get_param_type type, void *out)
 {
@@ -871,12 +924,20 @@
 	struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the vp9 inst of dec is invalid.\n");
 		return -1;
 	}
 
 	switch (type) {
+	case GET_PARAM_DISP_FRAME_BUFFER:
+		vdec_vp9_get_vf(inst, out);
+		break;
+
+	case GET_PARAM_FREE_FRAME_BUFFER:
+		ret = vdec_vp9_get_fb(inst, out);
+		break;
+
 	case GET_PARAM_PIC_INFO:
 		get_pic_info(inst, out);
 		break;
@@ -892,21 +953,6 @@
 	case GET_PARAM_CONFIG_INFO:
 		get_param_config_info(inst, out);
 		break;
-
-	case GET_PARAM_DW_MODE:
-	{
-		u32 *mode = out;
-		u32 m = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		if (m <= 16)
-			*mode = inst->ctx->config.parm.dec.cfg.double_write_mode;
-		else
-			*mode = vdec_get_dw_mode(inst, 0);
-		break;
-	}
-	case GET_PARAM_COMP_BUF_INFO:
-		get_param_comp_buf_info(inst, out);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid get parameter type=%d\n", type);
@@ -927,7 +973,6 @@
 	struct vdec_pic_info *pic = &inst->vsi->pic;
 	struct vdec_vp9_dec_info *dec = &inst->vsi->dec;
 	struct v4l2_rect *rect = &inst->vsi->crop;
-	int dw = inst->parms.cfg.double_write_mode;
 
 	/* fill visible area size that be used for EGL. */
 	pic->visible_width	= ps->visible_width;
@@ -943,16 +988,11 @@
 	pic->coded_width	= ps->coded_width;
 	pic->coded_height	= ps->coded_height;
 
-	pic->y_len_sz		= ALIGN(vdec_pic_scale(inst, pic->coded_width, dw), 64) *
-				  ALIGN(vdec_pic_scale(inst, pic->coded_height, dw), 64);
+	pic->y_len_sz		= pic->coded_width * pic->coded_height;
 	pic->c_len_sz		= pic->y_len_sz >> 1;
 
 	/* calc DPB size */
-	pic->dpb_frames		= ps->dpb_frames;
-	pic->dpb_margin		= ps->dpb_margin;
-	pic->vpp_margin		= ps->dpb_margin;
 	dec->dpb_sz		= ps->dpb_size;
-	pic->field		= ps->field;
 
 	inst->parms.ps 	= *ps;
 	inst->parms.parms_status |=
@@ -962,15 +1002,10 @@
 	complete(&inst->comp);
 
 	v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_PRINFO,
-		"Parse from ucode, visible(%d x %d), coded(%d x %d)\n",
-		pic->visible_width, pic->visible_height,
-		pic->coded_width, pic->coded_height);
-}
-
-static void set_param_comp_buf_info(struct vdec_vp9_inst *inst,
-		struct vdec_comp_buf_info *info)
-{
-	memcpy(&inst->comp_info, info, sizeof(*info));
+		"Parse from ucode, crop(%d x %d), coded(%d x %d) dpb: %d\n",
+		ps->visible_width, ps->visible_height,
+		ps->coded_width, ps->coded_height,
+		ps->dpb_size);
 }
 
 static void set_param_hdr_info(struct vdec_vp9_inst *inst,
@@ -995,12 +1030,6 @@
 			"VP9 post event: %d\n", *event);
 }
 
-static void set_pic_info(struct vdec_vp9_inst *inst,
-	struct vdec_pic_info *pic)
-{
-	inst->vsi->pic = *pic;
-}
-
 static int vdec_vp9_set_param(unsigned long h_vdec,
 	enum vdec_set_param_type type, void *in)
 {
@@ -1008,7 +1037,7 @@
 	struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
 
 	if (!inst) {
-		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
+		v4l_dbg(0, V4L_DEBUG_CODEC_ERROR,
 			"the vp9 inst of dec is invalid.\n");
 		return -1;
 	}
@@ -1022,10 +1051,6 @@
 		set_param_ps_info(inst, in);
 		break;
 
-	case SET_PARAM_COMP_BUF_INFO:
-		set_param_comp_buf_info(inst, in);
-		break;
-
 	case SET_PARAM_HDR_INFO:
 		set_param_hdr_info(inst, in);
 		break;
@@ -1033,11 +1058,6 @@
 	case SET_PARAM_POST_EVENT:
 		set_param_post_event(inst, in);
 		break;
-
-	case SET_PARAM_PIC_INFO:
-		set_pic_info(inst, in);
-		break;
-
 	default:
 		v4l_dbg(inst->ctx, V4L_DEBUG_CODEC_ERROR,
 			"invalid set parameter type=%d\n", type);
diff --git a/drivers/amvdec_ports/utils/common.c b/drivers/amvdec_ports/utils/common.c
index 67cf93b..1d621da 100644
--- a/drivers/amvdec_ports/utils/common.c
+++ b/drivers/amvdec_ports/utils/common.c
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
@@ -221,12 +240,3 @@
 	_pr_hex("print hex ending. len %d\n\n", l);
 }
 
-bool is_over_size(int w, int h, int size)
-{
-	if (h != 0 && (w > size / h))
-		return true;
-
-	return false;
-}
-
-
diff --git a/drivers/amvdec_ports/utils/common.h b/drivers/amvdec_ports/utils/common.h
index 89ae50b..dd4c51f 100644
--- a/drivers/amvdec_ports/utils/common.h
+++ b/drivers/amvdec_ports/utils/common.h
@@ -1,3 +1,22 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
 #ifndef UTILS_COMMON_H
 #define UTILS_COMMON_H
 
@@ -58,7 +77,7 @@
 #ifndef CONFIG_AMLOGIC_MEDIA_V4L_SOFTWARE_PARSER
 /**
  * YUV colorspace type.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.3.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.3.
  */
 enum AVColorSpace {
 	AVCOL_SPC_RGB         = 0,  ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
@@ -82,7 +101,7 @@
 
 /**
   * Chromaticity coordinates of the source primaries.
-  * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.1.
+  * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.1.
   */
 enum AVColorPrimaries {
 	AVCOL_PRI_RESERVED0   = 0,
@@ -106,7 +125,7 @@
 
 /**
  * Color Transfer Characteristic.
- * These values match the ones defined by ISO/IEC 23001-8_2013 ¡ì 7.2.
+ * These values match the ones defined by ISO/IEC 23001-8_2013 § 7.2.
  */
 enum AVColorTransferCharacteristic {
 	AVCOL_TRC_RESERVED0    = 0,
@@ -132,8 +151,8 @@
 	AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma"
 	AVCOL_TRC_NB                 ///< Not part of ABI
 };
-#endif
 
+#endif
 //fmt
 const char *av_color_space_name(enum AVColorSpace space);
 const char *av_color_primaries_name(enum AVColorPrimaries primaries);
@@ -150,6 +169,4 @@
 //debug
 void print_hex_debug(u8 *data, u32 len, int max);
 
-bool is_over_size(int w, int h, int size);
-
-#endif
\ No newline at end of file
+#endif
diff --git a/drivers/amvdec_ports/vdec_drv_if.c b/drivers/amvdec_ports/vdec_drv_if.c
index 01510c5..ed9f053 100644
--- a/drivers/amvdec_ports/vdec_drv_if.c
+++ b/drivers/amvdec_ports/vdec_drv_if.c
@@ -116,19 +116,6 @@
 	return ret;
 }
 
-int vdec_if_set_param(struct aml_vcodec_ctx *ctx,
-	enum vdec_set_param_type type, void *in)
-{
-	int ret = 0;
-
-	if (ctx->drv_handle == 0)
-		return -EIO;
-
-	ret = ctx->dec_if->set_param(ctx->drv_handle, type, in);
-
-	return ret;
-}
-
 void vdec_if_deinit(struct aml_vcodec_ctx *ctx)
 {
 	if (ctx->drv_handle == 0)
diff --git a/drivers/amvdec_ports/vdec_drv_if.h b/drivers/amvdec_ports/vdec_drv_if.h
index 29911f8..a04d832 100644
--- a/drivers/amvdec_ports/vdec_drv_if.h
+++ b/drivers/amvdec_ports/vdec_drv_if.h
@@ -50,48 +50,33 @@
 
 /**
  * struct vdec_fb_status  - decoder frame buffer status
- * @FB_ST_INIT		: initial state
- * @FB_ST_DECODER	: frame buffer be allocted by decoder.
- * @FB_ST_VPP		: frame buffer be allocate by vpp.
- * @FB_ST_DISPLAY	: frame buffer is ready to be displayed.
+ * @FB_ST_NORMAL	: initial state
+ * @FB_ST_DISPLAY	: frmae buffer is ready to be displayed
  * @FB_ST_FREE		: frame buffer is not used by decoder any more
  */
 enum vdec_fb_status {
-	FB_ST_INIT,
-	FB_ST_DECODER,
-	FB_ST_VPP,
-	FB_ST_GE2D,
+	FB_ST_NORMAL,
 	FB_ST_DISPLAY,
 	FB_ST_FREE
 };
 
-enum vdec_dw_mode {
-	VDEC_DW_AFBC_ONLY = 0,
-	VDEC_DW_AFBC_1_1_DW = 1,
-	VDEC_DW_AFBC_1_4_DW = 2,
-	VDEC_DW_AFBC_x2_1_4_DW = 3,
-	VDEC_DW_AFBC_1_2_DW = 4,
-	VDEC_DW_NO_AFBC = 16,
-	VDEC_DW_AFBC_AUTO_1_2 = 0x100,
-	VDEC_DW_AFBC_AUTO_1_4 = 0x200,
-};
-
-/*
+/* For GET_PARAM_DISP_FRAME_BUFFER and GET_PARAM_FREE_FRAME_BUFFER,
  * the caller does not own the returned buffer. The buffer will not be
  *				released before vdec_if_deinit.
+ * GET_PARAM_DISP_FRAME_BUFFER	: get next displayable frame buffer,
+ *				struct vdec_fb**
+ * GET_PARAM_FREE_FRAME_BUFFER	: get non-referenced framebuffer, vdec_fb**
  * GET_PARAM_PIC_INFO		: get picture info, struct vdec_pic_info*
  * GET_PARAM_CROP_INFO		: get crop info, struct v4l2_crop*
  * GET_PARAM_DPB_SIZE		: get dpb size, unsigned int*
- * GET_PARAM_DW_MODE:		: get double write mode, unsigned int*
- * GET_PARAM_COMP_BUF_INFO	: get compressed buf info,  struct vdec_comp_buf_info*
  */
 enum vdec_get_param_type {
+	GET_PARAM_DISP_FRAME_BUFFER,
+	GET_PARAM_FREE_FRAME_BUFFER,
 	GET_PARAM_PIC_INFO,
 	GET_PARAM_CROP_INFO,
 	GET_PARAM_DPB_SIZE,
-	GET_PARAM_CONFIG_INFO,
-	GET_PARAM_DW_MODE,
-	GET_PARAM_COMP_BUF_INFO
+	GET_PARAM_CONFIG_INFO
 };
 
 /*
@@ -100,11 +85,8 @@
 enum vdec_set_param_type {
 	SET_PARAM_WRITE_FRAME_SYNC,
 	SET_PARAM_PS_INFO,
-	SET_PARAM_COMP_BUF_INFO,
 	SET_PARAM_HDR_INFO,
-	SET_PARAM_POST_EVENT,
-	SET_PARAM_PIC_INFO,
-	SET_PARAM_CFG_INFO
+	SET_PARAM_POST_EVENT
 };
 
 /**
@@ -156,10 +138,7 @@
  * @type	: [in] input parameter type
  * @out	: [out] buffer to store query result
  */
-int vdec_if_get_param(struct aml_vcodec_ctx *ctx,
-	enum vdec_get_param_type type, void *out);
-
-int vdec_if_set_param(struct aml_vcodec_ctx *ctx,
-	enum vdec_set_param_type type, void *in);
+int vdec_if_get_param(struct aml_vcodec_ctx *ctx, enum vdec_get_param_type type,
+		      void *out);
 
 #endif
diff --git a/drivers/common/chips/chips.c b/drivers/common/chips/chips.c
index 158e32c..d692ca8 100644
--- a/drivers/common/chips/chips.c
+++ b/drivers/common/chips/chips.c
@@ -25,7 +25,7 @@
 #include <linux/mm.h>
 
 #include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 #include "../../stream_input/amports/amports_priv.h"
 #include "../../frame_provider/decoder/utils/vdec.h"
 #include "chips.h"
@@ -78,14 +78,6 @@
 	{AM_MESON_CPU_MAJOR_ID_TL1, "tl1"},
 	{AM_MESON_CPU_MAJOR_ID_TM2, "tm2"},
 	{AM_MESON_CPU_MAJOR_ID_SC2, "sc2"},
-	{AM_MESON_CPU_MAJOR_ID_T5, "t5"},
-	{AM_MESON_CPU_MAJOR_ID_T5D, "t5d"},
-	{AM_MESON_CPU_MAJOR_ID_T7, "t7"},
-	{AM_MESON_CPU_MAJOR_ID_S4, "s4"},
-	{AM_MESON_CPU_MAJOR_ID_T3, "t3"},
-	{AM_MESON_CPU_MAJOR_ID_P1, "p1"},
-	{AM_MESON_CPU_MAJOR_ID_S4D, "s4d"},
-	{AM_MESON_CPU_MAJOR_ID_T5W, "t5w"},
 	{0, NULL},
 };
 
diff --git a/drivers/common/chips/decoder_cpu_ver_info.c b/drivers/common/chips/decoder_cpu_ver_info.c
index af162b8..d74728c 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.c
+++ b/drivers/common/chips/decoder_cpu_ver_info.c
@@ -24,7 +24,7 @@
 #include <linux/errno.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 #include "decoder_cpu_ver_info.h"
 
 #define DECODE_CPU_VER_ID_NODE_NAME "cpu_ver_name"
@@ -32,7 +32,6 @@
 #define MAJOR_ID_START AM_MESON_CPU_MAJOR_ID_M6
 
 static enum AM_MESON_CPU_MAJOR_ID cpu_ver_id = AM_MESON_CPU_MAJOR_ID_MAX;
-static int cpu_sub_id = 0;
 
 static enum AM_MESON_CPU_MAJOR_ID cpu_ver_info[AM_MESON_CPU_MAJOR_ID_MAX - MAJOR_ID_START]=
 {
@@ -58,22 +57,13 @@
 	AM_MESON_CPU_MAJOR_ID_G12B,
 	AM_MESON_CPU_MAJOR_ID_GXLX2,
 	AM_MESON_CPU_MAJOR_ID_SM1,
-	AM_MESON_CPU_MAJOR_ID_A1,
+	AM_MESON_CPU_MAJOR_ID_RES_0x2c,
 	AM_MESON_CPU_MAJOR_ID_RES_0x2d,
 	AM_MESON_CPU_MAJOR_ID_TL1,
 	AM_MESON_CPU_MAJOR_ID_TM2,
-	AM_MESON_CPU_MAJOR_ID_C1,
+	AM_MESON_CPU_MAJOR_ID_RES_0x30,
 	AM_MESON_CPU_MAJOR_ID_RES_0x31,
 	AM_MESON_CPU_MAJOR_ID_SC2,
-	AM_MESON_CPU_MAJOR_ID_C2,
-	AM_MESON_CPU_MAJOR_ID_T5,
-	AM_MESON_CPU_MAJOR_ID_T5D,
-	AM_MESON_CPU_MAJOR_ID_T7,
-	AM_MESON_CPU_MAJOR_ID_S4,
-	AM_MESON_CPU_MAJOR_ID_T3,
-	AM_MESON_CPU_MAJOR_ID_P1,
-	AM_MESON_CPU_MAJOR_ID_S4D,
-	AM_MESON_CPU_MAJOR_ID_T5W,
 };
 
 static const struct of_device_id cpu_ver_of_match[] = {
@@ -124,90 +114,32 @@
 		.compatible = "amlogic, cpu-major-id-sc2",
 		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_SC2 - MAJOR_ID_START],
 	},
-	{
-		.compatible = "amlogic, cpu-major-id-t5",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5 - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-t5d",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5D - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-t7",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T7 - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-s4",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4 - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-t3",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T3 - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-p1",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_P1 - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-s4d",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_S4D - MAJOR_ID_START],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-t5w",
-		.data = &cpu_ver_info[AM_MESON_CPU_MAJOR_ID_T5W - MAJOR_ID_START],
-	},
 	{},
 };
 
-static const int cpu_sub_info[] = {
-		AM_MESON_CPU_MINOR_ID_REVB_G12B,
-		AM_MESON_CPU_MINOR_ID_REVB_TM2,
-		AM_MESON_CPU_MINOR_ID_S4_S805X2,
-};
-
-static const struct of_device_id cpu_sub_id_of_match[] = {
-	{
-		.compatible = "amlogic, cpu-major-id-g12b-b",
-		.data = &cpu_sub_info[0],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-tm2-b",
-		.data = &cpu_sub_info[1],
-	},
-	{
-		.compatible = "amlogic, cpu-major-id-s4-805x2",
-		.data = &cpu_sub_info[2],
-	},
-};
-
-static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pid_type, int *sub_id)
+static bool get_cpu_id_from_dtb(enum AM_MESON_CPU_MAJOR_ID *pidType)
 {
-	struct device_node *pnode = NULL;
-	struct platform_device *pdev = NULL;
-	const struct of_device_id *pmatch = NULL;
+	struct device_node *pNode = NULL;
+	struct platform_device* pDev = NULL;
+	const struct of_device_id *pMatch = NULL;
 
-	pnode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
-	if (NULL == pnode) {
+	pNode = of_find_node_by_name(NULL, DECODE_CPU_VER_ID_NODE_NAME);
+	if (NULL == pNode) {
 		pr_err("No find node.\n");
 		return -EINVAL;
 	}
 
-	pdev =  of_find_device_by_node(pnode);
-	if (NULL == pdev)
+	pDev =  of_find_device_by_node(pNode);
+	if (NULL == pDev)
 		return -EINVAL;
 
-	pmatch = of_match_device(cpu_ver_of_match, &pdev->dev);
-	if (NULL == pmatch) {
-		pmatch = of_match_device(cpu_sub_id_of_match, &pdev->dev);
-		if (NULL == pmatch) {
-			pr_err("No find of_match_device\n");
-			return -EINVAL;
-		}
+	pMatch = of_match_device(cpu_ver_of_match, &pDev->dev);
+	if (NULL == pMatch) {
+		pr_err("No find of_match_device\n");
+		return -EINVAL;
 	}
 
-	*pid_type = (enum AM_MESON_CPU_MAJOR_ID)(*(int *)pmatch->data) & (MAJOY_ID_MASK);
-
-	*sub_id = ((*(int *)pmatch->data) & (SUB_ID_MASK)) >> 8;
+	*pidType = *(enum AM_MESON_CPU_MAJOR_ID *)pMatch->data;
 
 	return AM_SUCESS;
 }
@@ -215,20 +147,15 @@
 static void initial_cpu_id(void)
 {
 	enum AM_MESON_CPU_MAJOR_ID id_type = AM_MESON_CPU_MAJOR_ID_MAX;
-	int sub_id = 0;
 
-	if (AM_SUCESS == get_cpu_id_from_dtb(&id_type, &sub_id)) {
+	if (AM_SUCESS == get_cpu_id_from_dtb(&id_type))
 		cpu_ver_id = id_type;
-		cpu_sub_id = sub_id;
-	} else {
+	else
 		cpu_ver_id = (enum AM_MESON_CPU_MAJOR_ID)get_cpu_type();
-		cpu_sub_id = (is_meson_rev_b()) ? CHIP_REVB : CHIP_REVA;
-	}
 
-	if ((AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id) && (CHIP_REVB == cpu_sub_id))
-		cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
-
-	pr_info("vdec init cpu id: 0x%x(%d)", cpu_ver_id, cpu_sub_id);
+	if (AM_MESON_CPU_MAJOR_ID_G12B == cpu_ver_id)
+		if (is_meson_rev_b())
+			cpu_ver_id = AM_MESON_CPU_MAJOR_ID_TL1;
 }
 
 enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void)
@@ -240,32 +167,10 @@
 }
 EXPORT_SYMBOL(get_cpu_major_id);
 
-int get_cpu_sub_id(void)
-{
-	return cpu_sub_id;
-}
-EXPORT_SYMBOL(get_cpu_sub_id);
-
-bool is_cpu_meson_revb(void)
-{
-	if (AM_MESON_CPU_MAJOR_ID_MAX == cpu_ver_id)
-		initial_cpu_id();
-
-	return (cpu_sub_id == CHIP_REVB);
-}
-EXPORT_SYMBOL(is_cpu_meson_revb);
-
 bool is_cpu_tm2_revb(void)
 {
-	return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2)
-		&& (is_cpu_meson_revb()));
+	return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_TM2) &&
+		(is_meson_rev_b()));
 }
 EXPORT_SYMBOL(is_cpu_tm2_revb);
 
-bool is_cpu_s4_s805x2(void)
-{
-	return ((get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_S4)
-		&& (get_cpu_sub_id() == CHIP_REVX));
-}
-EXPORT_SYMBOL(is_cpu_s4_s805x2);
-
diff --git a/drivers/common/chips/decoder_cpu_ver_info.h b/drivers/common/chips/decoder_cpu_ver_info.h
index 6129244..673b001 100644
--- a/drivers/common/chips/decoder_cpu_ver_info.h
+++ b/drivers/common/chips/decoder_cpu_ver_info.h
@@ -19,11 +19,9 @@
 */
 #ifndef DECODER_CPU_VER_INFO_H
 #define DECODER_CPU_VER_INFO_H
-#include <linux/amlogic/media/registers/cpu_version.h>
-/* majoy chip id define */
-#define MAJOY_ID_MASK (0x000000ff)
 
-enum AM_MESON_CPU_MAJOR_ID {
+enum AM_MESON_CPU_MAJOR_ID
+{
 	AM_MESON_CPU_MAJOR_ID_M6	= 0x16,
 	AM_MESON_CPU_MAJOR_ID_M6TV	= 0x17,
 	AM_MESON_CPU_MAJOR_ID_M6TVL	= 0x18,
@@ -46,50 +44,18 @@
 	AM_MESON_CPU_MAJOR_ID_G12B	= 0x29,
 	AM_MESON_CPU_MAJOR_ID_GXLX2	= 0x2a,
 	AM_MESON_CPU_MAJOR_ID_SM1	= 0x2b,
-	AM_MESON_CPU_MAJOR_ID_A1	= 0x2c,
+	AM_MESON_CPU_MAJOR_ID_RES_0x2c,
 	AM_MESON_CPU_MAJOR_ID_RES_0x2d,
 	AM_MESON_CPU_MAJOR_ID_TL1	= 0x2e,
 	AM_MESON_CPU_MAJOR_ID_TM2	= 0x2f,
-	AM_MESON_CPU_MAJOR_ID_C1	= 0x30,
+	AM_MESON_CPU_MAJOR_ID_RES_0x30,
 	AM_MESON_CPU_MAJOR_ID_RES_0x31,
 	AM_MESON_CPU_MAJOR_ID_SC2	= 0x32,
-	AM_MESON_CPU_MAJOR_ID_C2	= 0x33,
-	AM_MESON_CPU_MAJOR_ID_T5	= 0x34,
-	AM_MESON_CPU_MAJOR_ID_T5D	= 0x35,
-	AM_MESON_CPU_MAJOR_ID_T7	= 0x36,
-	AM_MESON_CPU_MAJOR_ID_S4	= 0x37,
-	AM_MESON_CPU_MAJOR_ID_T3	= 0x38,
-	AM_MESON_CPU_MAJOR_ID_P1	= 0x39,
-	AM_MESON_CPU_MAJOR_ID_S4D	= 0x3a,
-	AM_MESON_CPU_MAJOR_ID_T5W	= 0x3b,
+	AM_MESON_CPU_MAJOR_ID_RES_0x33,
+	AM_MESON_CPU_MAJOR_ID_T5,
 	AM_MESON_CPU_MAJOR_ID_MAX,
 };
 
-/* chips sub id define */
-#define CHIP_REVA 0x0
-#define CHIP_REVB 0x1
-#define CHIP_REVC 0x2
-#define CHIP_REVX 0x10
-
-#define REVB_MASK (CHIP_REVB << 8)
-#define REVC_MASK (CHIP_REVC << 8)
-#define REVX_MASK (CHIP_REVX << 8)
-
-#define SUB_ID_MASK (REVB_MASK | REVC_MASK | REVX_MASK)
-
-#define AM_MESON_CPU_MINOR_ID_REVB_G12B	 (REVB_MASK | AM_MESON_CPU_MAJOR_ID_G12B)
-#define AM_MESON_CPU_MINOR_ID_REVB_TM2   (REVB_MASK | AM_MESON_CPU_MAJOR_ID_TM2)
-#define AM_MESON_CPU_MINOR_ID_S4_S805X2  (REVX_MASK | AM_MESON_CPU_MAJOR_ID_S4)
-
-/* export functions */
 enum AM_MESON_CPU_MAJOR_ID get_cpu_major_id(void);
-
-bool is_cpu_meson_revb(void);
-
 bool is_cpu_tm2_revb(void);
-
-int get_cpu_sub_id(void);
-
-bool is_cpu_s4_s805x2(void);
-
 #endif
diff --git a/drivers/common/firmware/firmware_drv.c b/drivers/common/firmware/firmware_drv.c
index 9422198..85a81e6 100644
--- a/drivers/common/firmware/firmware_drv.c
+++ b/drivers/common/firmware/firmware_drv.c
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 
 #include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 #include "../../stream_input/amports/amports_priv.h"
 #include "../../frame_provider/decoder/utils/vdec.h"
 #include "firmware_priv.h"
@@ -34,14 +34,13 @@
 #include <linux/amlogic/media/utils/log.h>
 #include <linux/firmware.h>
 #include <linux/amlogic/tee.h>
-//#include <linux/amlogic/major.h> //if kernel is 4.9 then use this one
-#include <uapi/linux/major.h>
+#include <linux/amlogic/major.h>
 #include <linux/cdev.h>
 #include <linux/crc32.h>
 #include "../chips/decoder_cpu_ver_info.h"
 
 /* major.minor */
-#define PACK_VERS "v0.3"
+#define PACK_VERS "v0.2"
 
 #define CLASS_NAME	"firmware_codec"
 #define DEV_NAME	"firmware_vdec"
@@ -76,7 +75,6 @@
 
 struct fw_mgr_s *g_mgr;
 struct fw_dev_s *g_dev;
-struct package_head_s package_head;
 
 static u32 debug;
 static u32 detail;
@@ -87,7 +85,7 @@
 	struct fw_mgr_s *mgr = g_mgr;
 	struct fw_info_s *info;
 
-	pr_info("[%s], the fw (%s) will be loaded...\n",
+	pr_info("[%s], the fw (%s) will be loaded.\n",
 		tee_enabled() ? "TEE" : "LOCAL",
 		get_fw_format_name(format));
 
@@ -111,7 +109,6 @@
 
 		break;
 	}
-
 out:
 	mutex_unlock(&mutex);
 
@@ -344,8 +341,6 @@
 	struct fw_info_s *info;
 	unsigned int secs = 0;
 	struct tm tm;
-	char history_change_id[7] = {0};
-	int i;
 
 	mutex_lock(&mutex);
 
@@ -355,21 +350,7 @@
 	}
 
 	/* shows version of driver. */
-	pr_info("The ucode driver version is %s\n", PACK_VERS);
-
-	pr_info("The firmware version is %d.%d.%d-g%s\n",
-			(package_head.version >> 16) & 0xff,
-			package_head.version & 0xff,
-			package_head.submit_count,
-			package_head.commit);
-
-	pr_info("change id history:\n");
-	for (i = 0; i < 5; i++) {
-		memset(history_change_id, 0, sizeof(history_change_id));
-		strncpy(history_change_id, &(package_head.history_change_id[i * 6]), 6);
-		pr_info("\t%s\n", history_change_id);
-		
-	}
+	pr_info("The driver version is %s\n", PACK_VERS);
 
 	list_for_each_entry(info, &mgr->fw_head, node) {
 		if (IS_ERR_OR_NULL(info->data))
@@ -394,8 +375,7 @@
 
 		secs = info->data->head.time
 			- sys_tz.tz_minuteswest * 60;
-		//time_to_tm(secs, 0, &tm);//kernel4.9
-		time64_to_tm(secs, 0, &tm);
+		time_to_tm(secs, 0, &tm);
 
 		pr_info("%s %-16s, %02d:%02d:%02d %d/%d/%ld, %s %-8s, %s %-8s, %s %s\n",
 			"fmt:", info->data->head.format,
@@ -597,7 +577,6 @@
 	if (ret != 2)
 		return -1;
 
-	package_head = pack->head;
 	major_fw = (pack->head.version >> 16) & 0xff;
 	minor_fw = pack->head.version & 0xff;
 
@@ -616,7 +595,7 @@
 	if (debug) {
 		pr_info("The package has %d fws totally.\n", pack->head.total);
 		pr_info("The driver ver is v%d.%d\n", major, minor);
-		pr_info("The firmware ver is v%d.%d.%d\n", major_fw, minor_fw, pack->head.submit_count);
+		pr_info("The firmware ver is v%d.%d\n", major_fw, minor_fw);
 	}
 
 	return 0;
@@ -931,7 +910,6 @@
 	return count;
 }
 
-#if 0 //kernel4.9
 static struct class_attribute fw_class_attrs[] = {
 	__ATTR(info, 0664, info_show, info_store),
 	__ATTR(reload, 0664, reload_show, reload_store),
@@ -943,26 +921,7 @@
 	.name = CLASS_NAME,
 	.class_attrs = fw_class_attrs,
 };
-#else //below is for kernel 4.19 and 5.4
-static CLASS_ATTR_RW(info);
-static CLASS_ATTR_RW(reload);
-static CLASS_ATTR_RW(debug);
 
-static struct attribute *fw_class_attrs[] = {
-	&class_attr_info.attr,
-	&class_attr_reload.attr,
-	&class_attr_debug.attr,
-	NULL
-};
-
-ATTRIBUTE_GROUPS(fw_class);
-
-static struct class fw_class = {
-	.name = CLASS_NAME,
-	.class_groups = fw_class_groups,
-};
-
-#endif
 static int fw_driver_init(void)
 {
 	int ret = -1;
diff --git a/drivers/common/firmware/firmware_priv.h b/drivers/common/firmware/firmware_priv.h
index d901f9d..410745b 100644
--- a/drivers/common/firmware/firmware_priv.h
+++ b/drivers/common/firmware/firmware_priv.h
@@ -85,11 +85,7 @@
 	int checksum;
 	int total;
 	int version;
-	int submit_count;
-	char change_id[16];
-	char commit[16];
-	char history_change_id[30];
-	char reserved[62];
+	char reserved[128];
 };
 
 struct package_s {
diff --git a/drivers/common/firmware/firmware_type.c b/drivers/common/firmware/firmware_type.c
index 8d95c12..c232020 100644
--- a/drivers/common/firmware/firmware_type.c
+++ b/drivers/common/firmware/firmware_type.c
@@ -76,13 +76,6 @@
 	{AM_MESON_CPU_MAJOR_ID_TL1,	"tl1"},
 	{AM_MESON_CPU_MAJOR_ID_TM2,	"tm2"},
 	{AM_MESON_CPU_MAJOR_ID_SC2,	"sc2"},
-	{AM_MESON_CPU_MAJOR_ID_T5,	"t5"},
-	{AM_MESON_CPU_MAJOR_ID_T5D,	"t5d"},
-	{AM_MESON_CPU_MAJOR_ID_T7,	"t7"},
-	{AM_MESON_CPU_MAJOR_ID_S4,	"s4"},
-	{AM_MESON_CPU_MAJOR_ID_T3,	"t3"},
-	{AM_MESON_CPU_MAJOR_ID_P1,	"p1"},
-	{AM_MESON_CPU_MAJOR_ID_S4D,	"s4d"},
 };
 
 const char *get_fw_format_name(unsigned int format)
diff --git a/drivers/common/firmware/firmware_type.h b/drivers/common/firmware/firmware_type.h
index 4615baf..e997057 100644
--- a/drivers/common/firmware/firmware_type.h
+++ b/drivers/common/firmware/firmware_type.h
@@ -80,7 +80,6 @@
 #define OPTEE_VDEC_LEGENCY		(0)
 #define OPTEE_VDEC			(1)
 #define OPTEE_VDEC_HEVC			(2)
-#define OPTEE_VDEC_HCDEC			(3)
 
 struct format_name_s {
 	unsigned int format;
diff --git a/drivers/common/media_clock/clk/clk.c b/drivers/common/media_clock/clk/clk.c
index 6340c1a..972bcc1 100644
--- a/drivers/common/media_clock/clk/clk.c
+++ b/drivers/common/media_clock/clk/clk.c
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 
 #include <linux/amlogic/media/utils/vformat.h>
-#include <linux/amlogic/media/registers/cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 #include "../../../stream_input/amports/amports_priv.h"
 #include "../../../frame_provider/decoder/utils/vdec.h"
 #include "../../chips/chips.h"
@@ -165,7 +165,7 @@
 
 void hcodec_clock_enable(void)
 {
-	hcodec_clock_set(667);
+	hcodec_clock_set(1);
 }
 EXPORT_SYMBOL(hcodec_clock_enable);
 
@@ -311,21 +311,6 @@
 }
 EXPORT_SYMBOL(get_clk_with_source);
 
-bool is_hevc_front_back_clk_combined(void)
-{
-	int cpu_id = get_cpu_major_id();
-
-	if (cpu_id == AM_MESON_CPU_MAJOR_ID_T5 ||
-		(cpu_id == AM_MESON_CPU_MAJOR_ID_T5D) ||
-		(cpu_id == AM_MESON_CPU_MAJOR_ID_S4) ||
-		(cpu_id == AM_MESON_CPU_MAJOR_ID_S4D) ||
-		(cpu_id == AM_MESON_CPU_MAJOR_ID_T5W))
-		return true;
-
-	return false;
-}
-EXPORT_SYMBOL(is_hevc_front_back_clk_combined);
-
 int vdec_source_changed_for_clk_set(int format, int width, int height, int fps)
 {
 	int clk = get_clk_with_source(format, width * height * fps);
@@ -353,8 +338,7 @@
 		|| format == VFORMAT_AV1) {
 		ret_clk = hevc_clock_set(clk);
 		clock_source_wxhxfps_saved[VDEC_HEVC] = width * height * fps;
-		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A &&
-			!is_hevc_front_back_clk_combined()) {
+		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) {
 			ret_clk = hevc_back_clock_set(clk);
 			clock_source_wxhxfps_saved[VDEC_HEVCB] = width * height * fps;
 		}
@@ -388,7 +372,7 @@
 		 */
 		return 0;	/* ignore don't needed firmare. */
 	}
-	mgr = kmalloc(sizeof(struct chip_vdec_clk_s), GFP_KERNEL);
+	mgr = vzalloc(sizeof(struct chip_vdec_clk_s));
 	if (!mgr)
 		return -ENOMEM;
 	*mgr = *t_mgr;
@@ -397,7 +381,7 @@
 	 */
 	if (mgr->clock_init) {
 		if (mgr->clock_init()) {
-			kfree(mgr);
+			vfree(mgr);
 			return -ENOMEM;
 		}
 	}
@@ -420,7 +404,7 @@
 
 int unregister_vdec_clk_mgr(enum vdec_type_e vdec_type)
 {
-	kfree(get_current_vdec_chip()->clk_mgr[vdec_type]);
+	vfree(get_current_vdec_chip()->clk_mgr[vdec_type]);
 
 	return 0;
 }
@@ -439,7 +423,7 @@
 		 */
 		return 0;	/* ignore don't needed this setting . */
 	}
-	p_setting = kmalloc(size, GFP_KERNEL);
+	p_setting = vzalloc(size);
 	if (!p_setting)
 		return -ENOMEM;
 	memcpy(p_setting, setting, size);
@@ -465,7 +449,7 @@
 
 int unregister_vdec_clk_setting(void)
 {
-	kfree(get_current_vdec_chip()->clk_setting_array);
+	vfree(get_current_vdec_chip()->clk_setting_array);
 
 	return 0;
 }
diff --git a/drivers/common/media_clock/clk/clk.h b/drivers/common/media_clock/clk/clk.h
index bbc3bee..82eec1d 100644
--- a/drivers/common/media_clock/clk/clk.h
+++ b/drivers/common/media_clock/clk/clk.h
@@ -52,8 +52,6 @@
 int vdec_source_get(enum vdec_type_e core);
 int vdec_clk_get(enum vdec_type_e core);
 
-bool is_hevc_front_back_clk_combined(void);
-
 int vdec_source_changed_for_clk_set(int format, int width, int height, int fps);
 int get_clk_with_source(int format, int w_x_h_fps);
 
@@ -132,7 +130,7 @@
 #endif
 #ifdef VDEC_HAS_HEVC
 	register_vdec_clk_mgr(cpus, VDEC_HEVC, &vdec_hevc_clk_mgr);
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A)
+	if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_G12A)
 		register_vdec_clk_mgr(cpus, VDEC_HEVCB, &vdec_hevc_back_clk_mgr);
 #endif
 #ifdef VDEC_HAS_VDEC_HCODEC
diff --git a/drivers/common/media_clock/clk/clkg12.c b/drivers/common/media_clock/clk/clkg12.c
index c49d150..be2401c 100644
--- a/drivers/common/media_clock/clk/clkg12.c
+++ b/drivers/common/media_clock/clk/clkg12.c
@@ -114,6 +114,11 @@
 	WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1);\
 }while(0)
 
+#define CHECK_RET(_ret) if (ret) {debug_print(\
+		"%s:%d:function call failed with result: %d\n",\
+		__FUNCTION__, __LINE__, _ret);}
+
+
 static int clock_real_clk[VDEC_MAX + 1];
 
 static unsigned int set_frq_enable, vdec_frq, hevc_frq, hevcb_frq;
@@ -125,14 +130,19 @@
 static int gp_pll_user_cb_vdec(struct gp_pll_user_handle_s *user,
 			int event)
 {
+	int ret;
+
 	debug_print("gp_pll_user_cb_vdec call\n");
 	if (event == GP_PLL_USER_EVENT_GRANT) {
 		struct clk *clk = clk_get(NULL, "gp0_pll");
 		if (!IS_ERR(clk)) {
-			if (is_gp0_div2)
-				clk_set_rate(clk, 1296000000UL);
-			else
-				clk_set_rate(clk, 648000000UL);
+			if (is_gp0_div2) {
+				ret = clk_set_rate(clk, 1296000000UL);
+				CHECK_RET(ret);
+			} else {
+				ret = clk_set_rate(clk, 648000000UL);
+				CHECK_RET(ret);
+			}
 			VDEC1_SAFE_CLOCK();
 			VDEC1_CLOCK_OFF();
 			if (is_gp0_div2)
@@ -416,9 +426,7 @@
 	struct gate_switch_node *node = NULL;
 	char *hevc_mux_str = NULL;
 
-	if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2) ||
-		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5) ||
-		(get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_T5D))
+	if (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)
 		hevc_mux_str = "clk_hevc_mux";
 	else
 		hevc_mux_str = "clk_hevcf_mux";
@@ -458,6 +466,7 @@
 static int vdec_set_clk(int dec, int rate)
 {
 	struct clk *clk = NULL;
+	int ret;
 
 	switch (dec) {
 	case VDEC_1:
@@ -497,7 +506,8 @@
 		return -1;
 	}
 
-	clk_set_rate(clk, rate);
+	ret = clk_set_rate(clk, rate);
+	CHECK_RET(ret);
 
 	return 0;
 }
@@ -513,12 +523,12 @@
 {
 	gp_pll_user_vdec = gp_pll_user_register("vdec", 0,
 		gp_pll_user_cb_vdec);
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL)
+	if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL)
 		is_gp0_div2 = false;
 	else
 		is_gp0_div2 = true;
 
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXL) {
+	if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) {
 		pr_info("used fix clk for vdec clk source!\n");
 		//update_vdec_clk_config_settings(1);
 	}
@@ -733,14 +743,9 @@
 	}
 
 	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1 &&
-		get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1 &&
-		get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5 &&
-		get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D)
+		get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)
 		clk = 800;
 
-	if (is_cpu_s4_s805x2())
-		clk = 500;
-
 	if (set_frq_enable && vdec_frq) {
 		pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
 		clk = vdec_frq;
@@ -836,15 +841,10 @@
 	if ((clk > 500 && clk != 667)) {
 		if (clock_real_clk[VDEC_HEVC] == 648)
 			return 648;
-		if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) &&
-			(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5) &&
-			(get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_T5D))
+		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
 			clk = TL1_HEVC_MAX_CLK;
 		else
 			clk = 667;
-
-		if (is_cpu_s4_s805x2())
-			clk = 500;
 	}
 
 	if (set_frq_enable && hevc_frq) {
@@ -1042,14 +1042,6 @@
 	AM_MESON_CPU_MAJOR_ID_TL1,\
 	AM_MESON_CPU_MAJOR_ID_TM2,\
 	AM_MESON_CPU_MAJOR_ID_SC2,\
-	AM_MESON_CPU_MAJOR_ID_T5,\
-	AM_MESON_CPU_MAJOR_ID_T5D,\
-	AM_MESON_CPU_MAJOR_ID_T7,\
-	AM_MESON_CPU_MAJOR_ID_S4,\
-	AM_MESON_CPU_MAJOR_ID_T3,\
-	AM_MESON_CPU_MAJOR_ID_P1,\
-	AM_MESON_CPU_MAJOR_ID_S4D,\
-	AM_MESON_CPU_MAJOR_ID_T5W,\
 	0}
 #include "clk.h"
 
diff --git a/drivers/common/media_clock/switch/amports_gate.c b/drivers/common/media_clock/switch/amports_gate.c
index 58a0289..9d5f7b4 100644
--- a/drivers/common/media_clock/switch/amports_gate.c
+++ b/drivers/common/media_clock/switch/amports_gate.c
@@ -99,11 +99,11 @@
 		gates[i].clk = devm_clk_get(dev, gates[i].name);
 		if (IS_ERR_OR_NULL(gates[i].clk)) {
 			gates[i].clk = NULL;
-			pr_info("get gate %s control failed %px\n",
+			pr_info("get gate %s control failed %p\n",
 				gates[i].name,
 				gates[i].clk);
 		} else {
-			pr_info("get gate %s control ok %px\n",
+			pr_info("get gate %s control ok %p\n",
 				gates[i].name,
 				gates[i].clk);
 		}
diff --git a/drivers/fake_video_out/Makefile b/drivers/fake_video_out/Makefile
new file mode 100644
index 0000000..1dd937c
--- /dev/null
+++ b/drivers/fake_video_out/Makefile
@@ -0,0 +1 @@
+obj-m   += fake_video.o
diff --git a/drivers/fake_video_out/fake_video.c b/drivers/fake_video_out/fake_video.c
new file mode 100644
index 0000000..e0e9b16
--- /dev/null
+++ b/drivers/fake_video_out/fake_video.c
@@ -0,0 +1,309 @@
+/*
+* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Description:
+*/
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
+#include <linux/sched.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/major.h>
+#include "../frame_provider/decoder/utils/vdec.h"
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#define RECEIVER_NAME "fake-amvideo"
+#define DEVICE_NAME "fake-amvideo"
+
+#define TUNNEL_MODE	(0)
+#define NON_TUNNEL_MODE	(1)
+
+static u32 display_mode = TUNNEL_MODE;
+module_param(display_mode, uint, 0664);
+MODULE_PARM_DESC(display_mode, "\n display_mode\n");
+
+static struct device *amvideo_dev = NULL;
+struct timer_list timer;
+struct task_struct *task;
+bool thread_stop = false;
+atomic_t frame_count;
+
+static struct vframe_receiver_s fake_video_vf_recv;
+static int video_receiver_event_fun(int type, void *data, void *);
+static const struct vframe_receiver_op_s fake_video_vf_receiver = {
+	.event_cb = video_receiver_event_fun
+};
+
+static struct vframe_s *video_vf_peek(void)
+{
+	return vf_peek(RECEIVER_NAME);
+}
+
+static struct vframe_s *video_vf_get(void)
+{
+	struct vframe_s *vf = NULL;
+
+	vf = vf_get(RECEIVER_NAME);
+
+	if (vf) {
+		atomic_set(&vf->use_cnt, 1);
+		/*pr_err("Get vframe  w: %d, h: %d, fence: %lx, idx: %d\n",
+			vf->width, vf->height, (ulong)vf->fence, vf->index & 0xff);*/
+	}
+
+	return vf;
+}
+
+static void video_vf_put(struct vframe_s *vf)
+{
+	struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME);
+
+	if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) {
+		vf_put(vf, RECEIVER_NAME);
+	}
+}
+
+static int video_receiver_event_fun(int type, void *data, void *private_data)
+{
+	switch (type) {
+	case VFRAME_EVENT_PROVIDER_UNREG: {
+		atomic_set(&frame_count, 0);
+		pr_info("VFRAME_EVENT_PROVIDER_UNREG\n");
+		break;
+	}
+	case VFRAME_EVENT_PROVIDER_START: {
+		pr_info("VFRAME_EVENT_PROVIDER_START\n");
+		break;
+	}
+	case VFRAME_EVENT_PROVIDER_QUREY_STATE: {
+		break;
+	}
+	case VFRAME_EVENT_PROVIDER_VFRAME_READY: {
+		pr_info("VFRAME_EVENT_PROVIDER_VFRAME_READY\n");
+		atomic_inc(&frame_count);
+		break;
+	}
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static void display_timer_func(unsigned long arg)
+{
+	struct vframe_s *vf = NULL;
+
+	if (display_mode != TUNNEL_MODE)
+		goto out;
+
+	vf = video_vf_peek();
+	if (!vf) {
+		goto out;
+	}
+
+	if (vf->fence) {
+		if (vdec_fence_status_get(vf->fence) == 1) {
+			pr_info("[VDEC-FENCE]: Display, idx: %d\n",
+				vf->index & 0xff);
+			vf = video_vf_get();
+			video_vf_put(vf);
+		} else {
+			pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n");
+		}
+	}
+
+out:
+	mod_timer(&timer, jiffies + msecs_to_jiffies(16));
+}
+
+static int display_thread(void *data)
+{
+	struct vframe_s *vf = NULL;
+
+	for (;;) {
+		if (thread_stop)
+			break;
+
+		if ((atomic_read(&frame_count) == 0) ||
+			display_mode != NON_TUNNEL_MODE)
+			continue;
+
+		if (video_vf_peek()) {
+			vf = video_vf_get();
+			if (!vf) {
+				pr_err("receiver vf err.\n");
+				break;
+			}
+
+			atomic_dec(&frame_count);
+
+			if (vf->fence) {
+				u64 timestamp = local_clock();
+				/* fence waiting until frame ready. */
+				vdec_fence_wait(vf->fence, msecs_to_jiffies(2000));
+
+				if (vdec_fence_status_get(vf->fence) == 1) {
+					pr_info("[VDEC-FENCE]: Display, idx: %d, dec cost: %lld\n",
+						vf->index & 0xff, local_clock() - timestamp);
+				} else {
+					pr_err("[VDEC-FENCE]: Display invalid, fence status err.\n");
+				}
+			}
+
+			video_vf_put(vf);
+		}
+		msleep(16);
+	}
+	return 0;
+}
+
+static int amvideo_open(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+static int amvideo_release(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+#ifdef CONFIG_COMPAT
+static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+	file->private_data = NULL;
+	return 0;
+}
+#endif
+
+static const struct file_operations amvideo_fops = {
+	.owner = THIS_MODULE,
+	.open = amvideo_open,
+	.release = amvideo_release,
+	.unlocked_ioctl = amvideo_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = amvideo_compat_ioctl,
+#endif
+	//.poll = amvideo_poll,
+};
+
+static struct class amvideo_class = {
+	.name = "fake_video",
+};
+
+#define FAKEVIDEO_MAJOR		(23 + (AML_BASE))
+
+static int __init fake_video_init(void)
+{
+	int ret = 0;
+
+	ret = class_register(&amvideo_class);
+	if (ret) {
+		pr_err("create video class fail.\n");
+		return 0;
+	}
+
+
+	/* create video device */
+	ret = register_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME, &amvideo_fops);
+	if (ret < 0) {
+		pr_err("Can't register major for amvideo device\n");
+		goto err1;
+	}
+
+	amvideo_dev = device_create(&amvideo_class, NULL,
+		MKDEV(FAKEVIDEO_MAJOR, 0), NULL, DEVICE_NAME);
+	if (IS_ERR(amvideo_dev)) {
+		pr_err("Can't create amvideo device\n");
+		goto err;
+	}
+
+	vf_receiver_init(&fake_video_vf_recv, RECEIVER_NAME,
+		&fake_video_vf_receiver, NULL);
+	vf_reg_receiver(&fake_video_vf_recv);
+
+	atomic_set(&frame_count, 0);
+
+	init_timer(&timer);
+	//timer.data = 0;
+	timer.function = display_timer_func;
+	timer.expires = jiffies + HZ;
+	add_timer(&timer);
+
+	thread_stop = false;
+	task = kthread_run(display_thread, NULL, "aml-%s", "fake-video-thread");
+	if (IS_ERR(task)) {
+		ret = PTR_ERR(task);
+		pr_err("Failed to creat display thread, ret: %d.\n", ret);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME);
+err1:
+	class_unregister(&amvideo_class);
+
+	return ret;
+}
+
+static void __exit fake_video_exit(void)
+{
+	thread_stop = true;
+	kthread_stop(task);
+
+	del_timer_sync(&timer);
+
+	vf_unreg_receiver(&fake_video_vf_recv);
+
+	device_destroy(&amvideo_class, MKDEV(FAKEVIDEO_MAJOR, 0));
+	unregister_chrdev(FAKEVIDEO_MAJOR, DEVICE_NAME);
+	class_unregister(&amvideo_class);
+
+}
+
+
+module_init(fake_video_init);
+module_exit(fake_video_exit);
+
+
+MODULE_DESCRIPTION("AMLOGIC fake video output driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>");
+
diff --git a/drivers/frame_provider/Makefile b/drivers/frame_provider/Makefile
index f30c4f1..371e088 100644
--- a/drivers/frame_provider/Makefile
+++ b/drivers/frame_provider/Makefile
@@ -1,2 +1 @@
 obj-y	+=	decoder/
-obj-y	+=	decoder_v4l/
diff --git a/drivers/frame_provider/decoder/Makefile b/drivers/frame_provider/decoder/Makefile
index bb0079e..349d381 100644
--- a/drivers/frame_provider/decoder/Makefile
+++ b/drivers/frame_provider/decoder/Makefile
@@ -7,6 +7,7 @@
 obj-y	+=	h265/
 obj-y	+=	vp9/
 obj-y	+=	mjpeg/
+obj-y	+=	real/
 obj-y	+=	avs/
 obj-y	+=	avs2/
 obj-y	+=	avs_multi/
diff --git a/drivers/frame_provider/decoder/avs/avs.c b/drivers/frame_provider/decoder/avs/avs.c
index 5869eac..6314f9d 100644
--- a/drivers/frame_provider/decoder/avs/avs.c
+++ b/drivers/frame_provider/decoder/avs/avs.c
@@ -43,8 +43,8 @@
 #include "../utils/decoder_bmmu_box.h"
 #include "../utils/firmware.h"
 #include "../../../common/chips/decoder_cpu_ver_info.h"
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
+#include <linux/amlogic/tee.h>
+
 
 #define DRIVER_NAME "amvdec_avs"
 #define MODULE_NAME "amvdec_avs"
@@ -162,6 +162,7 @@
 	int	canvas_num = 3;
 #endif
 
+
 static struct vframe_s vfpool[VF_POOL_SIZE];
 /*static struct vframe_s vfpool2[VF_POOL_SIZE];*/
 static struct vframe_s *cur_vfpool;
@@ -412,7 +413,6 @@
 	}
 }
 
-
 #ifdef HANDLE_AVS_IRQ
 static irqreturn_t vavs_isr(int irq, void *dev_id)
 #else
@@ -654,7 +654,6 @@
 				decoder_bmmu_box_get_mem_handle(
 					mm_blk_handle,
 					buffer_index);
-
 			kfifo_put(&display_q,
 					  (const struct vframe_s *)vf);
 			ATRACE_COUNTER(MODULE_NAME, vf->pts);
@@ -741,6 +740,7 @@
 				decoder_bmmu_box_get_mem_handle(
 					mm_blk_handle,
 					buffer_index);
+
 			decoder_do_frame_check(NULL, vf);
 			kfifo_put(&display_q,
 					  (const struct vframe_s *)vf);
@@ -945,35 +945,35 @@
 		else
 			endian = 0;
 #ifdef NV21
-			config_cav_lut_ex(canvas_base + canvas_num * i + 0,
+			canvas_config_ex(canvas_base + canvas_num * i + 0,
 					buf_start,
 					canvas_width, canvas_height,
 					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
-			config_cav_lut_ex(canvas_base + canvas_num * i + 1,
+					vdec->canvas_mode, endian);
+			canvas_config_ex(canvas_base + canvas_num * i + 1,
 					buf_start +
 					decbuf_y_size, canvas_width,
 					canvas_height / 2,
 					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
+					vdec->canvas_mode, endian);
 #else
-			config_cav_lut_ex(canvas_num * i + 0,
+			canvas_config_ex(canvas_num * i + 0,
 					buf_start,
 					canvas_width, canvas_height,
 					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
-			config_cav_lut_ex(canvas_num * i + 1,
+					vdec->canvas_mode, endian);
+			canvas_config_ex(canvas_num * i + 1,
 					buf_start +
 					decbuf_y_size, canvas_width / 2,
 					canvas_height / 2,
 					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
-			config_cav_lut_ex(canvas_num * i + 2,
+					vdec->canvas_mode, endian);
+			canvas_config_ex(canvas_num * i + 2,
 					buf_start +
 					decbuf_y_size + decbuf_uv_size,
 					canvas_width / 2, canvas_height / 2,
 					CANVAS_ADDR_NOWRAP,
-					vdec->canvas_mode, endian, VDEC_1);
+					vdec->canvas_mode, endian);
 #endif
 			if (debug_flag & AVS_DEBUG_PRINT) {
 				pr_info("canvas config %d, addr %p\n", i,
@@ -1353,8 +1353,10 @@
 		}
 }
 
-static void vavs_put_timer_func(struct timer_list *timer)
+static void vavs_put_timer_func(unsigned long arg)
 {
+	struct timer_list *timer = (struct timer_list *)arg;
+
 #ifndef HANDLE_AVS_IRQ
 	vavs_isr();
 #endif
@@ -1571,6 +1573,7 @@
 		return -ENOMEM;
 
 	pr_info("vavs_init\n");
+	init_timer(&recycle_timer);
 
 	stat |= STAT_TIMER_INIT;
 
@@ -1654,8 +1657,10 @@
 
 	stat |= STAT_VF_HOOK;
 
-	timer_setup(&recycle_timer, vavs_put_timer_func, 0);
+	recycle_timer.data = (ulong)(&recycle_timer);
+	recycle_timer.function = vavs_put_timer_func;
 	recycle_timer.expires = jiffies + PUT_INTERVAL;
+
 	add_timer(&recycle_timer);
 
 	stat |= STAT_TIMER_ARM;
diff --git a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
index de9a3d2..3da87e4 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
+++ b/drivers/frame_provider/decoder/avs2/avs2_bufmgr.c
@@ -39,9 +39,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-contiguous.h>
 #include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
 #include "../../../stream_input/amports/amports_priv.h"
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 #include "../utils/decoder_mmu_box.h"
diff --git a/drivers/frame_provider/decoder/avs2/avs2_global.h b/drivers/frame_provider/decoder/avs2/avs2_global.h
index be35a5e..3e7fcb8 100644
--- a/drivers/frame_provider/decoder/avs2/avs2_global.h
+++ b/drivers/frame_provider/decoder/avs2/avs2_global.h
@@ -772,9 +772,6 @@
 	uint8_t bg_flag;
 	/**/
 	unsigned long header_adr;
-	/*AVS2_10B_MMU_DW*/
-	unsigned long dw_header_adr;
-
 	int buf_size;
 	int lcu_total;
 	int comp_body_size;
@@ -817,9 +814,6 @@
 
 	u32 hw_decode_time;
 	u32 frame_size; // For frame base mode
-
-	char *cuva_data_buf;
-	int  cuva_data_size;
 };
 
 
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c
index e21dc55..a5d550f 100644
--- a/drivers/frame_provider/decoder/avs2/vavs2.c
+++ b/drivers/frame_provider/decoder/avs2/vavs2.c
@@ -37,9 +37,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-contiguous.h>
 #include <linux/slab.h>
-//#include <linux/amlogic/tee.h>
-#include <uapi/linux/tee.h>
-#include <linux/sched/clock.h>
+#include <linux/amlogic/tee.h>
 #include "../../../stream_input/amports/amports_priv.h"
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 #include "../utils/decoder_mmu_box.h"
@@ -57,46 +55,26 @@
 #include "../utils/config_parser.h"
 #include "../utils/firmware.h"
 #include "../../../common/chips/decoder_cpu_ver_info.h"
-#include "../utils/vdec_feature.h"
+#include <linux/amlogic/tee.h>
+
 
 #define I_ONLY_SUPPORT
 #define MIX_STREAM_SUPPORT
+#define G12A_BRINGUP_DEBUG
 #define CONSTRAIN_MAX_BUF_NUM
 
-#define CO_MV_COMPRESS
-
 #include "vavs2.h"
 #define HEVC_SHIFT_LENGTH_PROTECT                  0x313a
-#define HEVC_MPRED_CTRL4                           0x324c
 #define HEVC_MPRED_CTRL9                           0x325b
 #define HEVC_DBLK_CFGD                             0x350d
+
+
 #define HEVC_CM_HEADER_START_ADDR                  0x3628
 #define HEVC_DBLK_CFGB                             0x350b
 #define HEVCD_MPP_ANC2AXI_TBL_DATA                 0x3464
 #define HEVC_SAO_MMU_VH1_ADDR                      0x363b
 #define HEVC_SAO_MMU_VH0_ADDR                      0x363a
 
-#define HEVC_CM_BODY_LENGTH2                       0x3663
-#define HEVC_CM_HEADER_OFFSET2                     0x3664
-#define HEVC_CM_HEADER_LENGTH2                     0x3665
-
-#define HEVC_ASSIST_MMU_MAP_ADDR                   0x3009
-
-#define HEVC_CM_HEADER_START_ADDR                  0x3628
-#define HEVC_CM_HEADER_START_ADDR2                 0x364a
-#define HEVC_SAO_MMU_VH1_ADDR                      0x363b
-#define HEVC_SAO_MMU_VH0_ADDR                      0x363a
-#define HEVC_SAO_MMU_VH0_ADDR2                     0x364d
-#define HEVC_SAO_MMU_VH1_ADDR2                     0x364e
-
-#define HEVC_SAO_MMU_DMA_CTRL2                     0x364c
-#define HEVC_SAO_MMU_STATUS2                       0x3650
-#define HEVC_DW_VH0_ADDDR                          0x365e
-#define HEVC_DW_VH1_ADDDR                          0x365f
-
-#define HEVC_SAO_CTRL9                             0x362d
-
-
 
 /*
  * AVS2_DEC_STATUS define
@@ -249,9 +227,6 @@
 #define unlock_buffer(dec, flags) \
 		spin_unlock_irqrestore(&dec->buffer_lock, flags)
 
-static u32 debug_mask = 0xffffffff;
-#define get_dbg_flag(dec) ((debug_mask & (1 << dec->index)) ? debug : 0)
-
 static unsigned int max_decode_instance_num
 				= MAX_DECODE_INSTANCE_NUM;
 static unsigned int decode_frame_count[MAX_DECODE_INSTANCE_NUM];
@@ -261,11 +236,17 @@
 static unsigned int input_empty[MAX_DECODE_INSTANCE_NUM];
 static unsigned int not_run_ready[MAX_DECODE_INSTANCE_NUM];
 
+#ifdef G12A_BRINGUP_DEBUG
 static u32 decode_timeout_val = 200;
-
+#else
+static u32 decode_timeout_val = 200;
+#endif
 static int start_decode_buf_level = 0x8000;
-
-static u32 work_buf_size;
+#ifdef AVS2_10B_MMU
+static u32 work_buf_size; /* = 24 * 1024 * 1024*/;
+#else
+static u32 work_buf_size = 32 * 1024 * 1024;
+#endif
 
 static u32 mv_buf_margin;
 static int pre_decode_buf_level = 0x1000;
@@ -279,7 +260,6 @@
  *	2, (1/4):(1/4) ratio;
  *	3, (1/4):(1/4) ratio, with both compressed frame included
  *	4, (1/2):(1/2) ratio;
- *	8, (1/8):(1/8) ratio;
  *	0x10, double write only
  *	0x100, if > 1080p,use mode 4,else use mode 1;
  *	0x200, if > 1080p,use mode 2,else use mode 1;
@@ -318,7 +298,7 @@
 static s32 vavs2_init(struct vdec_s *vdec);
 static void vavs2_prot_init(struct AVS2Decoder_s *dec);
 static int vavs2_local_init(struct AVS2Decoder_s *dec);
-static void vavs2_put_timer_func(struct timer_list *timer);
+static void vavs2_put_timer_func(unsigned long arg);
 static void dump_data(struct AVS2Decoder_s *dec, int size);
 static unsigned char get_data_check_sum
 	(struct AVS2Decoder_s *dec, int size);
@@ -350,8 +330,6 @@
 static u32 force_video_signal_type;
 static u32 enable_force_video_signal_type;
 #define VIDEO_SIGNAL_TYPE_AVAILABLE_MASK	0x20000000
-#define HDR_CUVA_MASK                           0x40000000
-
 
 static const char * const video_format_names[] = {
 	"component", "PAL", "NTSC", "SECAM",
@@ -427,6 +405,11 @@
 #define DOUBLE_WRITE_YSTART_TEMP 0x02000000
 #define DOUBLE_WRITE_CSTART_TEMP 0x02900000
 
+
+
+typedef unsigned int u32;
+typedef unsigned short u16;
+
 #define AVS2_DBG_BUFMGR                   0x01
 #define AVS2_DBG_BUFMGR_MORE              0x02
 #define AVS2_DBG_BUFMGR_DETAIL            0x04
@@ -442,7 +425,6 @@
 #define AVS2_DBG_PIC_LEAK                 0x1000
 #define AVS2_DBG_PIC_LEAK_WAIT            0x2000
 #define AVS2_DBG_HDR_INFO                 0x4000
-#define AVS2_DBG_HDR_DATA                 0x8000
 #define AVS2_DBG_DIS_LOC_ERROR_PROC       0x10000
 #define AVS2_DBG_DIS_SYS_ERROR_PROC   0x20000
 #define AVS2_DBG_DUMP_PIC_LIST       0x40000
@@ -515,9 +497,6 @@
 
 static u32 force_disp_pic_index;
 
-#define AUX_BUF_ALIGN(adr) ((adr + 0xf) & (~0xf))
-static u32 cuva_buf_size = 512;
-
 #define DEBUG_REG
 #ifdef DEBUG_REG
 static void WRITE_VREG_DBG2(unsigned adr, unsigned val)
@@ -532,6 +511,11 @@
 #define WRITE_VREG WRITE_VREG_DBG2
 #endif
 
+
+//#ifdef AVS2_10B_MMU
+//#define MMU_COMPRESS_HEADER_SIZE  0x48000
+//#define MMU_COMPRESS_8K_HEADER_SIZE  0x48000*4
+//#endif
 #define MMU_COMPRESS_HEADER_SIZE_1080P  0x10000
 #define MMU_COMPRESS_HEADER_SIZE_4K  0x48000
 #define MMU_COMPRESS_HEADER_SIZE_8K  0x120000
@@ -546,7 +530,7 @@
 #define FRAME_CONTEXTS_LOG2 2
 #define FRAME_CONTEXTS (1 << FRAME_CONTEXTS_LOG2)
 /*buffer + header buffer + workspace*/
-
+#undef MV_USE_FIXED_BUF
 #ifdef MV_USE_FIXED_BUF
 #define MAX_BMMU_BUFFER_NUM ((FRAME_BUFFERS + HEADER_FRAME_BUFFERS + 1)+1)
 #define VF_BUFFER_IDX(n) (n)
@@ -558,7 +542,6 @@
 #define HEADER_BUFFER_IDX(n) (FRAME_BUFFERS + n+1)
 #define MV_BUFFER_IDX(n) ((FRAME_BUFFERS * 2) + n+1)
 #define WORK_SPACE_BUF_ID ((FRAME_BUFFERS * 2) + HEADER_FRAME_BUFFERS+1)
-//#define DW_HEADER_BUFFER_IDX(n) ((FRAME_BUFFERS * 3) + n+1)
 #endif
 
 #define CO_MV_BUF_SIZE_1080P  0x3fc00
@@ -601,10 +584,6 @@
 	struct buff_s mmu_vbh;
 	struct buff_s cm_header;
 #endif
-#ifdef AVS2_10B_MMU_DW
-	struct buff_s mmu_vbh_dw;
-	struct buff_s cm_header_dw;
-#endif
 	struct buff_s mpred_above;
 #ifdef MV_USE_FIXED_BUF
 	struct buff_s mpred_mv;
@@ -689,22 +668,11 @@
 	unsigned short *lmem_ptr;
 	unsigned short *debug_ptr;
 
-#ifdef AVS2_10B_MMU
-	bool mmu_enable;
-
-	u32 cuva_size;
-	void *cuva_addr;
-	dma_addr_t cuva_phy_addr;
-
+#if 1
+	/*AVS2_10B_MMU*/
 	void *frame_mmu_map_addr;
 	dma_addr_t frame_mmu_map_phy_addr;
 #endif
-#ifdef AVS2_10B_MMU_DW
-	bool dw_mmu_enable;
-	void *dw_mmu_box;
-	void *dw_frame_mmu_map_addr;
-	dma_addr_t dw_frame_mmu_map_phy_addr;
-#endif
 	unsigned int use_cma_flag;
 
 	struct BUF_s m_BUF[MAX_BUF_NUM];
@@ -807,14 +775,10 @@
 	u32 dynamic_buf_margin;
 	int sidebind_type;
 	int sidebind_channel_id;
-	u32 endian;
 	char vdec_name[32];
 	char pts_name[32];
 	char new_q_name[32];
 	char disp_q_name[32];
-	dma_addr_t rdma_phy_adr;
-	unsigned *rdma_adr;
-	int hdr_flag;
 };
 
 static int  compute_losless_comp_body_size(
@@ -924,19 +888,10 @@
 
 static u32 get_valid_double_write_mode(struct AVS2Decoder_s *dec)
 {
-	u32 dw_mode;
-
-	dw_mode = (dec->m_ins_flag &&
+	return (dec->m_ins_flag &&
 		((double_write_mode & 0x80000000) == 0)) ?
 		dec->double_write_mode :
 		(double_write_mode & 0x7fffffff);
-	if (dw_mode & 0x20) {
-		if ((get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_T3)
-			&& ((dw_mode & 0xf) == 2 || (dw_mode & 0xf) == 3))
-			dw_mode = 0;
-	}
-
-	return dw_mode;
 }
 
 static int get_double_write_mode(struct AVS2Decoder_s *dec)
@@ -994,6 +949,18 @@
 	return dw;
 }
 
+static int get_double_write_ratio(struct AVS2Decoder_s *dec,
+	int dw_mode)
+{
+	int ratio = 1;
+	if ((dw_mode == 2) ||
+			(dw_mode == 3))
+		ratio = 4;
+	else if (dw_mode == 4)
+		ratio = 2;
+	return ratio;
+}
+
 //#define	MAX_4K_NUM		0x1200
 #ifdef AVS2_10B_MMU
 int avs2_alloc_mmu(
@@ -1007,6 +974,25 @@
 	int bit_depth_10 = (bit_depth == AVS2_BITS_10);
 	int picture_size;
 	int cur_mmu_4k_number, max_frame_num;
+#ifdef DYNAMIC_ALLOC_HEAD
+	unsigned long buf_addr;
+	struct avs2_frame_s *pic = dec->avs2_dec.hc.cur_pic;
+	if (pic->header_adr == 0) {
+		if (decoder_bmmu_box_alloc_buf_phy
+				(dec->bmmu_box,
+				HEADER_BUFFER_IDX(cur_buf_idx),
+				get_compress_header_size(dec),
+				DRIVER_HEADER_NAME,
+				&buf_addr) < 0){
+			avs2_print(dec, 0,
+				"%s malloc compress header failed %d\n",
+				DRIVER_HEADER_NAME, cur_buf_idx);
+			dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+			return -1;
+		} else
+			pic->header_adr = buf_addr;
+	}
+#endif
 
 	picture_size = compute_losless_comp_body_size(
 		dec, pic_width, pic_height,
@@ -1029,38 +1015,157 @@
 }
 #endif
 
-#ifdef AVS2_10B_MMU_DW
-int avs2_alloc_dw_mmu(
-	struct AVS2Decoder_s *dec,
-	int cur_buf_idx,
-	int pic_width,
-	int pic_height,
-	unsigned short bit_depth,
-	unsigned int *mmu_index_adr)
+#if 0
+/*ndef MV_USE_FIXED_BUF*/
+static void dealloc_mv_bufs(struct AVS2Decoder_s *dec)
 {
-	int bit_depth_10 = (bit_depth == AVS2_BITS_10);
-	int picture_size;
-	int cur_mmu_4k_number, max_frame_num;
-
-	picture_size = compute_losless_comp_body_size(
-		dec, pic_width, pic_height,
-		bit_depth_10);
-	cur_mmu_4k_number = ((picture_size + (1 << 12) - 1) >> 12);
-	if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
-		max_frame_num = MAX_FRAME_8K_NUM;
-	else
-		max_frame_num = MAX_FRAME_4K_NUM;
-	if (cur_mmu_4k_number > max_frame_num) {
-		pr_err("over max !! cur_mmu_4k_number 0x%x width %d height %d\n",
-			cur_mmu_4k_number, pic_width, pic_height);
-		return -1;
+	int i;
+	for (i = 0; i < FRAME_BUFFERS; i++) {
+		if (dec->m_mv_BUF[i].start_adr) {
+			if (debug)
+				pr_info(
+				"dealloc mv buf(%d) adr %ld size 0x%x used_flag %d\n",
+				i, dec->m_mv_BUF[i].start_adr,
+				dec->m_mv_BUF[i].size,
+				dec->m_mv_BUF[i].used_flag);
+			decoder_bmmu_box_free_idx(
+				dec->bmmu_box,
+				MV_BUFFER_IDX(i));
+			dec->m_mv_BUF[i].start_adr = 0;
+			dec->m_mv_BUF[i].size = 0;
+			dec->m_mv_BUF[i].used_flag = 0;
+		}
 	}
-	return decoder_mmu_box_alloc_idx(
-		dec->dw_mmu_box,
-		cur_buf_idx,
-		cur_mmu_4k_number,
-		mmu_index_adr);
 }
+
+static int alloc_mv_buf(struct AVS2Decoder_s *dec,
+	int i, int size)
+{
+	int ret = 0;
+	if (decoder_bmmu_box_alloc_buf_phy
+		(dec->bmmu_box,
+		MV_BUFFER_IDX(i), size,
+		DRIVER_NAME,
+		&dec->m_mv_BUF[i].start_adr) < 0) {
+		dec->m_mv_BUF[i].start_adr = 0;
+		ret = -1;
+	} else {
+		dec->m_mv_BUF[i].size = size;
+		dec->m_mv_BUF[i].used_flag = 0;
+		ret = 0;
+		if (debug) {
+			pr_info(
+			"MV Buffer %d: start_adr %p size %x\n",
+			i,
+			(void *)dec->m_mv_BUF[i].start_adr,
+			dec->m_mv_BUF[i].size);
+		}
+	}
+	return ret;
+}
+
+static int init_mv_buf_list(struct AVS2Decoder_s *dec)
+{
+	int i;
+	int ret = 0;
+	int count = FRAME_BUFFERS;
+	int pic_width = dec->init_pic_w;
+	int pic_height = dec->init_pic_h;
+	int lcu_size = 64; /*fixed 64*/
+	int pic_width_64 = (pic_width + 63) & (~0x3f);
+	int pic_height_32 = (pic_height + 31) & (~0x1f);
+	int pic_width_lcu  = (pic_width_64 % lcu_size) ?
+				pic_width_64 / lcu_size  + 1
+				: pic_width_64 / lcu_size;
+	int pic_height_lcu = (pic_height_32 % lcu_size) ?
+				pic_height_32 / lcu_size + 1
+				: pic_height_32 / lcu_size;
+	int lcu_total       = pic_width_lcu * pic_height_lcu;
+	int size = ((lcu_total * MV_MEM_UNIT) + 0xffff) &
+		(~0xffff);
+	if (mv_buf_margin > 0)
+		count = dec->avs2_dec.ref_maxbuffer + mv_buf_margin;
+	for (i = 0; i < count; i++) {
+		if (alloc_mv_buf(dec, i, size) < 0) {
+			ret = -1;
+			break;
+		}
+	}
+	return ret;
+}
+#if 0
+
+static int get_mv_buf(struct AVS2Decoder_s *dec,
+				struct avs2_frame_s *pic)
+{
+	int i;
+	int ret = -1;
+	for (i = 0; i < FRAME_BUFFERS; i++) {
+		if (dec->m_mv_BUF[i].start_adr &&
+			dec->m_mv_BUF[i].used_flag == 0) {
+			dec->m_mv_BUF[i].used_flag = 1;
+			ret = i;
+			break;
+		}
+	}
+
+	if (ret >= 0) {
+		pic->mv_buf_index = ret;
+		pic->mpred_mv_wr_start_addr =
+			(dec->m_mv_BUF[ret].start_adr + 0xffff) &
+			(~0xffff);
+		if (debug & AVS2_DBG_BUFMGR_MORE)
+			pr_info(
+			"%s => %d (%d) size 0x%x\n",
+			__func__, ret,
+			pic->mpred_mv_wr_start_addr,
+			dec->m_mv_BUF[ret].size);
+	} else {
+		pr_info(
+		"%s: Error, mv buf is not enough\n",
+		__func__);
+	}
+	return ret;
+}
+
+static void put_mv_buf(struct AVS2Decoder_s *dec,
+				struct avs2_frame_s *pic)
+{
+	int i = pic->mv_buf_index;
+	if (i >= FRAME_BUFFERS) {
+		if (debug & AVS2_DBG_BUFMGR_MORE)
+			pr_info(
+			"%s: index %d beyond range\n",
+			__func__, i);
+		return;
+	}
+	if (debug & AVS2_DBG_BUFMGR_MORE)
+		pr_info(
+		"%s(%d): used_flag(%d)\n",
+		__func__, i,
+		dec->m_mv_BUF[i].used_flag);
+
+	pic->mv_buf_index = -1;
+	if (dec->m_mv_BUF[i].start_adr &&
+		dec->m_mv_BUF[i].used_flag)
+		dec->m_mv_BUF[i].used_flag = 0;
+}
+
+static void	put_un_used_mv_bufs(struct AVS2Decoder_s *dec)
+{
+	struct VP9_Common_s *const cm = &dec->common;
+	struct RefCntBuffer_s *const frame_bufs = cm->buffer_pool->frame_bufs;
+	int i;
+	for (i = 0; i < dec->used_buf_num; ++i) {
+		if ((frame_bufs[i].ref_count == 0) &&
+			(frame_bufs[i].buf.index != -1) &&
+			(frame_bufs[i].buf.mv_buf_index >= 0)
+			)
+			put_mv_buf(dec, &frame_bufs[i].buf);
+	}
+}
+#endif
+
 #endif
 
 static int get_free_buf_count(struct AVS2Decoder_s *dec)
@@ -1203,19 +1308,13 @@
 
 
 const u32 avs2_version = 201602101;
+static u32 debug;
 static u32 radr;
 static u32 rval;
 static u32 pop_shorts;
 static u32 dbg_cmd;
 static u32 dbg_skip_decode_index;
-/*
- * bit 0~3, for HEVCD_IPP_AXIIF_CONFIG endian config
- * bit 8~23, for HEVC_SAO_CTRL1 endian config
- */
-static u32 endian;
-#define HEVC_CONFIG_BIG_ENDIAN     ((0x880 << 8) | 0x8)
-#define HEVC_CONFIG_LITTLE_ENDIAN  ((0xff0 << 8) | 0xf)
-
+static u32 endian = 0xff0;
 #ifdef ERROR_HANDLE_DEBUG
 static u32 dbg_nal_skip_flag;
 		/* bit[0], skip vps; bit[1], skip sps; bit[2], skip pps */
@@ -1319,9 +1418,6 @@
 #define VP9_COUNT_SWAP_BUFFER     HEVC_ASSIST_SCRATCH_A
 #define VP9_SEG_MAP_BUFFER        HEVC_ASSIST_SCRATCH_B
 */
-#define AVS2_CUVA_ADR             HEVC_ASSIST_SCRATCH_A
-#define AVS2_CUVA_DATA_SIZE       HEVC_ASSIST_SCRATCH_B
-
 //#define HEVC_SCALELUT             HEVC_ASSIST_SCRATCH_D
 #define HEVC_WAIT_FLAG            HEVC_ASSIST_SCRATCH_E
 #define RPM_CMD_REG               HEVC_ASSIST_SCRATCH_F
@@ -1380,10 +1476,7 @@
 #define DW_VBH_BUF_SIZE_8K (VBH_BUF_SIZE_8K * 2)
 #define DW_VBH_BUF_SIZE(bufspec) (bufspec->mmu_vbh_dw.buf_size / 4)
 
-/* necessary 4K page size align for t7/t3 decoder and after */
-#define WORKBUF_ALIGN(addr) (ALIGN(addr, PAGE_SIZE))
-
-#define WORK_BUF_SPEC_NUM 6
+#define WORK_BUF_SPEC_NUM 3
 static struct BuffInfo_s amvavs2_workbuff_spec[WORK_BUF_SPEC_NUM] = {
 	{
 		/* 8M bytes */
@@ -1392,283 +1485,6 @@
 		.ipp = {
 			/* IPP work space calculation :
 			   4096 * (Y+CbCr+Flags) = 12k, round to 16k */
-			.buf_size = 0x4000,
-		},
-		.sao_abv = {
-			.buf_size = 0x30000,
-		},
-		.sao_vb = {
-			.buf_size = 0x30000,
-		},
-		.short_term_rps = {
-			/* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
-			   total 64x16x2 = 2048 bytes (0x800) */
-			.buf_size = 0x800,
-		},
-		.rcs = {
-			/* RCS STORE AREA - Max 32 RCS, each has 32 bytes,
-				total 0x0400 bytes */
-			.buf_size = 0x400,
-		},
-		.sps = {
-			/* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
-			total 0x0800 bytes*/
-			.buf_size = 0x800,
-		},
-		.pps = {
-			/*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
-			total 0x2000 bytes*/
-			.buf_size = 0x2000,
-		},
-		.sao_up = {
-			/* SAO UP STORE AREA - Max 640(10240/16) LCU,
-			   each has 16 bytes total 0x2800 bytes */
-			.buf_size = 0x2800,
-		},
-		.swap_buf = {
-			/* 256cyclex64bit = 2K bytes 0x800
-			   (only 144 cycles valid) */
-			.buf_size = 0x800,
-		},
-		.swap_buf2 = {
-			.buf_size = 0x800,
-		},
-		.scalelut = {
-			/* support up to 32 SCALELUT 1024x32 =
-			   32Kbytes (0x8000) */
-			.buf_size = 0x8000,
-		},
-		.dblk_para = {
-			/* DBLK -> Max 256(4096/16) LCU,
-			each para 1024bytes(total:0x40000),
-			data 1024bytes(total:0x40000)*/
-			.buf_size = 0x40000,
-		},
-		.dblk_data = {
-			.buf_size = 0x40000,
-		},
-		.dblk_data2 = {
-			.buf_size = 0x40000,
-		},
-#ifdef AVS2_10B_MMU
-		.mmu_vbh = {
-			.buf_size = 0x5000, /*2*16*(more than 2304)/4, 4K*/
-		},
-#if 0
-		.cm_header = {
-			/*add one for keeper.*/
-			.buf_size = MMU_COMPRESS_HEADER_SIZE *
-						(FRAME_BUFFERS + 1),
-			/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
-		},
-#endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x8000, /* 2 * size of hevc*/
-		},
-#ifdef MV_USE_FIXED_BUF
-		.mpred_mv = {/* 1080p, 0x40000 per buffer */
-			.buf_size = 0x40000 * FRAME_BUFFERS,
-		},
-#endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
-	},
-	{
-		.max_width = 4096,
-		.max_height = 2304,
-		.ipp = {
-			/* IPP work space calculation :
-			   4096 * (Y+CbCr+Flags) = 12k, round to 16k */
-			.buf_size = 0x4000,
-		},
-		.sao_abv = {
-			.buf_size = 0x30000,
-		},
-		.sao_vb = {
-			.buf_size = 0x30000,
-		},
-		.short_term_rps = {
-			/* SHORT_TERM_RPS - Max 64 set, 16 entry every set,
-			   total 64x16x2 = 2048 bytes (0x800) */
-			.buf_size = 0x800,
-		},
-		.rcs = {
-			/* RCS STORE AREA - Max 16 RCS, each has 32 bytes,
-			total 0x0400 bytes */
-			.buf_size = 0x400,
-		},
-		.sps = {
-			/* SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
-			   total 0x0800 bytes */
-			.buf_size = 0x800,
-		},
-		.pps = {
-			/* PPS STORE AREA - Max 64 PPS, each has 0x80 bytes,
-			   total 0x2000 bytes */
-			.buf_size = 0x2000,
-		},
-		.sao_up = {
-			/* SAO UP STORE AREA - Max 640(10240/16) LCU,
-			   each has 16 bytes total 0x2800 bytes */
-			.buf_size = 0x2800,
-		},
-		.swap_buf = {
-			/* 256cyclex64bit = 2K bytes 0x800
-			   (only 144 cycles valid) */
-			.buf_size = 0x800,
-		},
-		.swap_buf2 = {
-			.buf_size = 0x800,
-		},
-		.scalelut = {
-			/* support up to 32 SCALELUT 1024x32 = 32Kbytes
-			   (0x8000) */
-			.buf_size = 0x8000,
-		},
-		.dblk_para = {
-			/* DBLK -> Max 256(4096/16) LCU,
-			each para 1024bytes(total:0x40000),
-			data 1024bytes(total:0x40000)*/
-			.buf_size = 0x80000,
-		},
-		.dblk_data = {
-			/*DBLK -> Max 256(4096/16) LCU,
-			each para 1024bytes(total:0x40000),
-			data 1024bytes(total:0x40000)*/
-			.buf_size = 0x80000,
-		},
-		.dblk_data2 = {
-			.buf_size = 0x80000,
-		},
-#ifdef AVS2_10B_MMU
-		.mmu_vbh = {
-			.buf_size = 0x5000,/*2*16*(more than 2304)/4, 4K*/
-		},
-#if 0
-		.cm_header = {
-			/*add one for keeper.*/
-			.buf_size = MMU_COMPRESS_HEADER_SIZE *
-						(FRAME_BUFFERS + 1),
-			/* 0x44000 = ((1088*2*1024*4)/32/4)*(32/8) */
-		},
-#endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x10000, /* 2 * size of hevc*/
-		},
-#ifdef MV_USE_FIXED_BUF
-		.mpred_mv = {
-			/* .buf_size = 0x100000*16,
-			//4k2k , 0x100000 per buffer */
-			/* 4096x2304 , 0x120000 per buffer */
-			.buf_size = 0x120000 * FRAME_BUFFERS,
-		},
-#endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
-	},
-	{
-		.max_width = 4096 * 2,
-		.max_height = 2304 * 2,
-		.ipp = {
-		/*IPP work space calculation : 4096 * (Y+CbCr+Flags) = 12k,
-		round to 16k*/
-			.buf_size = 0x4000 * 2,
-		},
-		.sao_abv = {
-			.buf_size = 0x30000 * 2,
-		},
-		.sao_vb = {
-			.buf_size = 0x30000 * 2,
-		},
-		.short_term_rps = {
-		/*SHORT_TERM_RPS - Max 64 set, 16 entry every set,
-			total 64x16x2 = 2048 bytes (0x800)*/
-			.buf_size = 0x800,
-		},
-		.rcs = {
-		/*RCS STORE AREA - Max 16 RCS, each has 32 bytes,
-		total 0x0400 bytes*/
-			.buf_size = 0x400,
-		},
-		.sps = {
-		/*SPS STORE AREA - Max 16 SPS, each has 0x80 bytes,
-			total 0x0800 bytes*/
-			.buf_size = 0x800,
-		},
-		.pps = {
-		/*PPS STORE AREA - Max 64 PPS, each has 0x80 bytes, total
-			0x2000 bytes*/
-			.buf_size = 0x2000,
-		},
-		.sao_up = {
-		/*SAO UP STORE AREA - Max 640(10240/16) LCU, each has 16 bytes i
-				total 0x2800 bytes*/
-			.buf_size = 0x2800 * 2,
-		},
-		.swap_buf = {
-		/*256cyclex64bit = 2K bytes 0x800 (only 144 cycles valid)*/
-			.buf_size = 0x800,
-		},
-		.swap_buf2 = {
-			.buf_size = 0x800,
-		},
-		.scalelut = {
-		/*support up to 32 SCALELUT 1024x32 = 32Kbytes (0x8000)*/
-			.buf_size = 0x8000 * 2,
-		},
-		.dblk_para  = {
-			.buf_size = 0x40000 * 2,
-		},
-		.dblk_data  = {
-			.buf_size = 0x80000 * 2,
-		},
-		.dblk_data2 = {
-			.buf_size = 0x80000 * 2,
-		},
-#ifdef AVS2_10B_MMU
-		.mmu_vbh = {
-		  .buf_size = 0x5000 * 2, /*2*16*2304/4, 4K*/
-		},
-#if 0
-		.cm_header = {
-			/*0x44000 = ((1088*2*1024*4)/32/4)*(32/8)*/
-			.buf_size = MMU_COMPRESS_8K_HEADER_SIZE * 17,
-		},
-#endif
-#endif
-		.mpred_above = {
-			.buf_size = 0x8000 * 2,
-		},
-#ifdef MV_USE_FIXED_BUF
-		.mpred_mv = {
-			/*4k2k , 0x100000 per buffer*/
-			.buf_size = 0x120000 * FRAME_BUFFERS * 4,
-		},
-#endif
-		.rpm = {
-			.buf_size = RPM_BUF_SIZE,
-		},
-		.lmem = {
-			.buf_size = 0x400 * 2,
-		}
-	},
-	{
-		/* 8M bytes */
-		.max_width = 1920,
-		.max_height = 1088,
-		.ipp = {
-			/* IPP work space calculation :
-			   4096 * (Y+CbCr+Flags) = 12k, round to 16k */
 			.buf_size = 0x1e00,
 		},
 		.sao_abv = {
@@ -1740,16 +1556,6 @@
 		},
 #endif
 #endif
-#ifdef AVS2_10B_MMU_DW
-		.mmu_vbh_dw = {
-			.buf_size = DW_VBH_BUF_SIZE_1080P, //2*16*2304/4, 4K
-		},
-#if 0
-		.cm_header_dw = {
-			.buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
-		},
-#endif
-#endif
 		.mpred_above = {
 			.buf_size = 0x1e00, /* 2 * size of hevc*/
 		},
@@ -1845,16 +1651,6 @@
 		},
 #endif
 #endif
-#ifdef AVS2_10B_MMU_DW
-		.mmu_vbh_dw = {
-			.buf_size = DW_VBH_BUF_SIZE_4K, //2*16*2304/4, 4K
-		},
-#if 0
-		.cm_header_dw = {
-			.buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
-		},
-#endif
-#endif
 		.mpred_above = {
 			.buf_size = 0x4000, /* 2 * size of hevc*/
 		},
@@ -1943,16 +1739,6 @@
 		},
 #endif
 #endif
-#ifdef AVS2_10B_MMU_DW
-		.mmu_vbh_dw = {
-			.buf_size = DW_VBH_BUF_SIZE_8K, //2*16*2304/4, 4K
-		},
-#if 0
-		.cm_header_dw = {
-			.buf_size = MMU_COMPRESS_HEADER_SIZE_DW*17, // 0x44000 = ((1088*2*1024*4)/32/4)*(32/8)
-		},
-#endif
-#endif
 		.mpred_above = {
 			.buf_size = 0x8000,
 		},
@@ -2054,70 +1840,64 @@
 	struct BuffInfo_s *buf_spec)
 {
 	void *mem_start_virt;
-	buf_spec->ipp.buf_start =
-		WORKBUF_ALIGN(buf_spec->start_adr);
+	buf_spec->ipp.buf_start = buf_spec->start_adr;
 	buf_spec->sao_abv.buf_start =
-		WORKBUF_ALIGN(buf_spec->ipp.buf_start + buf_spec->ipp.buf_size);
+		buf_spec->ipp.buf_start + buf_spec->ipp.buf_size;
+
 	buf_spec->sao_vb.buf_start =
-		WORKBUF_ALIGN(buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size);
+		buf_spec->sao_abv.buf_start + buf_spec->sao_abv.buf_size;
 	buf_spec->short_term_rps.buf_start =
-		WORKBUF_ALIGN(buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size);
+		buf_spec->sao_vb.buf_start + buf_spec->sao_vb.buf_size;
 	buf_spec->rcs.buf_start =
-		WORKBUF_ALIGN(buf_spec->short_term_rps.buf_start + buf_spec->short_term_rps.buf_size);
+		buf_spec->short_term_rps.buf_start +
+		buf_spec->short_term_rps.buf_size;
 	buf_spec->sps.buf_start =
-		WORKBUF_ALIGN(buf_spec->rcs.buf_start + buf_spec->rcs.buf_size);
+		buf_spec->rcs.buf_start + buf_spec->rcs.buf_size;
 	buf_spec->pps.buf_start =
-		WORKBUF_ALIGN(buf_spec->sps.buf_start + buf_spec->sps.buf_size);
+		buf_spec->sps.buf_start + buf_spec->sps.buf_size;
 	buf_spec->sao_up.buf_start =
-		WORKBUF_ALIGN(buf_spec->pps.buf_start + buf_spec->pps.buf_size);
+		buf_spec->pps.buf_start + buf_spec->pps.buf_size;
 	buf_spec->swap_buf.buf_start =
-		WORKBUF_ALIGN(buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size);
+		buf_spec->sao_up.buf_start + buf_spec->sao_up.buf_size;
 	buf_spec->swap_buf2.buf_start =
-		WORKBUF_ALIGN(buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size);
+		buf_spec->swap_buf.buf_start + buf_spec->swap_buf.buf_size;
 	buf_spec->scalelut.buf_start =
-		WORKBUF_ALIGN(buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size);
+		buf_spec->swap_buf2.buf_start + buf_spec->swap_buf2.buf_size;
 	buf_spec->dblk_para.buf_start =
-		WORKBUF_ALIGN(buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size);
+		buf_spec->scalelut.buf_start + buf_spec->scalelut.buf_size;
 	buf_spec->dblk_data.buf_start =
-		WORKBUF_ALIGN(buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size);
+		buf_spec->dblk_para.buf_start + buf_spec->dblk_para.buf_size;
 	buf_spec->dblk_data2.buf_start =
-		WORKBUF_ALIGN(buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size);
+		buf_spec->dblk_data.buf_start + buf_spec->dblk_data.buf_size;
 #ifdef AVS2_10B_MMU
 	buf_spec->mmu_vbh.buf_start  =
-		WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
-	#ifdef AVS2_10B_MMU_DW
-	buf_spec->mmu_vbh_dw.buf_start =
-		WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
+		buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size;
 	buf_spec->mpred_above.buf_start =
-		WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
-	#else
+		buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size;
+#else
 	buf_spec->mpred_above.buf_start =
-		WORKBUF_ALIGN(buf_spec->mmu_vbh.buf_start + buf_spec->mmu_vbh.buf_size);
-	#endif
-#else /* AVS2_10B_MMU */
-	#ifdef AVS2_10B_MMU_DW
-	buf_spec->mmu_vbh_dw.buf_start =
-		WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
-	buf_spec->mpred_above.buf_start =
-		WORKBUF_ALIGN(buf_spec->mmu_vbh_dw.buf_start + buf_spec->mmu_vbh_dw.buf_size);
-	#else
-	buf_spec->mpred_above.buf_start =
-		WORKBUF_ALIGN(buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size);
-	#endif
-#endif /* AVS2_10B_MMU */
+		buf_spec->dblk_data2.buf_start + buf_spec->dblk_data2.buf_size;
+#endif
 #ifdef MV_USE_FIXED_BUF
 	buf_spec->mpred_mv.buf_start =
-		WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+		buf_spec->mpred_above.buf_start +
+		buf_spec->mpred_above.buf_size;
+
 	buf_spec->rpm.buf_start =
-		WORKBUF_ALIGN(buf_spec->mpred_mv.buf_start + buf_spec->mpred_mv.buf_size);
+		buf_spec->mpred_mv.buf_start +
+		buf_spec->mpred_mv.buf_size;
 #else
 	buf_spec->rpm.buf_start =
-		WORKBUF_ALIGN(buf_spec->mpred_above.buf_start + buf_spec->mpred_above.buf_size);
+		buf_spec->mpred_above.buf_start +
+		buf_spec->mpred_above.buf_size;
+
 #endif
 	buf_spec->lmem.buf_start =
-		WORKBUF_ALIGN(buf_spec->rpm.buf_start + buf_spec->rpm.buf_size);
+		buf_spec->rpm.buf_start +
+		buf_spec->rpm.buf_size;
 	buf_spec->end_adr =
-		WORKBUF_ALIGN(buf_spec->lmem.buf_start + buf_spec->lmem.buf_size);
+		buf_spec->lmem.buf_start +
+		buf_spec->lmem.buf_size;
 
 	if (dec) {
 		mem_start_virt =
@@ -2170,10 +1950,6 @@
 			pr_info("mmu_vbh.buf_start     :%x\n",
 				buf_spec->mmu_vbh.buf_start);
 	#endif
-	#ifdef AVS2_10B_MMU_DW
-			pr_info("mmu_vbh_dw.buf_start     :%x\n",
-				buf_spec->mmu_vbh_dw.buf_start);
-	#endif
 			pr_info("mpred_above.buf_start     :%x\n",
 				   buf_spec->mpred_above.buf_start);
 #ifdef MV_USE_FIXED_BUF
@@ -2191,11 +1967,9 @@
 
 static void uninit_mmu_buffers(struct AVS2Decoder_s *dec)
 {
-#ifdef AVS2_10B_MMU_DW
-	if (dec->dw_mmu_enable && dec->dw_mmu_box) {
-		decoder_mmu_box_free(dec->dw_mmu_box);
-		dec->dw_mmu_box = NULL;
-	}
+#if 0
+/*ndef MV_USE_FIXED_BUF*/
+	dealloc_mv_bufs(dec);
 #endif
 	decoder_mmu_box_free(dec->mmu_box);
 	dec->mmu_box = NULL;
@@ -2236,9 +2010,9 @@
 
 	if (dw_mode) {
 		int pic_width_dw = pic_width /
-			get_double_write_ratio(dw_mode);
+			get_double_write_ratio(dec, dw_mode);
 		int pic_height_dw = pic_height /
-			get_double_write_ratio(dw_mode);
+			get_double_write_ratio(dec, dw_mode);
 		int lcu_size = 64; /*fixed 64*/
 		int pic_width_64 = (pic_width_dw + 63) & (~0x3f);
 		int pic_height_32 = (pic_height_dw + 31) & (~0x1f);
@@ -2269,7 +2043,7 @@
 	for (i = 0; i < dec->used_buf_num; i++) {
 		if (((i + 1) * buf_size) > dec->mc_buf->buf_size)
 			dec->use_cma_flag = 1;
-
+#ifndef AVS2_10B_MMU
 		dec->m_BUF[i].alloc_flag = 0;
 		dec->m_BUF[i].index = i;
 
@@ -2310,6 +2084,7 @@
 			"Buffer %d: start_adr %p size %x\n", i,
 			   (void *)dec->m_BUF[i].start_adr,
 			   dec->m_BUF[i].size);
+#endif
 	}
 	dec->buf_num = i;
 }
@@ -2334,7 +2109,15 @@
 				pic_height_32 / lcu_size + 1
 				: pic_height_32 / lcu_size;
 	int lcu_total       = pic_width_lcu * pic_height_lcu;
-
+#if 0
+	int32_t MV_MEM_UNIT =
+		(lcu_size_log2 == 6) ? 0x200 :
+		((lcu_size_log2 == 5) ? 0x80 : 0x20);
+#endif
+#ifdef MV_USE_FIXED_BUF
+	u32 mpred_mv_end = dec->work_space_buf->mpred_mv.buf_start +
+			dec->work_space_buf->mpred_mv.buf_size;
+#endif
 	u32 y_adr = 0;
 	int buf_size = 0;
 
@@ -2350,11 +2133,11 @@
 	int mc_buffer_size_u_v_h = 0;
 	int dw_mode = get_double_write_mode_init(dec);
 
-	if (dw_mode && ((dw_mode & 0x20) == 0)) {
+	if (dw_mode) {
 		int pic_width_dw = pic_width /
-			get_double_write_ratio(dw_mode);
+			get_double_write_ratio(dec, dw_mode);
 		int pic_height_dw = pic_height /
-			get_double_write_ratio(dw_mode);
+			get_double_write_ratio(dec, dw_mode);
 		int pic_width_64_dw = (pic_width_dw + 63) & (~0x3f);
 		int pic_height_32_dw = (pic_height_dw + 31) & (~0x1f);
 		int pic_width_lcu_dw  = (pic_width_64_dw % lcu_size) ?
@@ -2373,150 +2156,171 @@
 	}
 	if (mc_buffer_size & 0xffff) /*64k alignment*/
 		mc_buffer_size_h += 1;
-
-
-#ifdef AVS2_10B_MMU
-	if (dec->mmu_enable) {
-		pic->header_adr = decoder_bmmu_box_get_phy_addr(
-				dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
-
-#ifdef AVS2_10B_MMU_DW
-		if (dec->dw_mmu_enable) {
-			pic->dw_header_adr = pic->header_adr
-				+ get_compress_header_size(dec);
-		}
-#endif
-		avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
-			"buf_size %d, MMU header_adr %d: %ld\n",
-			buf_size, pic->index, pic->header_adr);
-	}
-#else
+#ifndef AVS2_10B_MMU
 	if ((dw_mode & 0x10) == 0)
 		buf_size += (mc_buffer_size_h << 16);
 #endif
 
-	i = pic->index;
-
-#ifndef AVS2_10B_MMU
-	if (debug) {
-		pr_err("start %x  .size=%d\n",
-			dec->mc_buf_spec.buf_start + i * buf_size, buf_size);
-	}
-	for (i = 0; i < dec->buf_num; i++) {
-		y_adr = ((dec->m_BUF[i].free_start_adr
-			+ 0xffff) >> 16) << 16;
-		/*64k alignment*/
-		if ((y_adr+buf_size) <=	(dec->m_BUF[i].start_adr+
-			dec->m_BUF[i].size)) {
-			dec->m_BUF[i].free_start_adr =
-				y_adr + buf_size;
-			break;
-		}
-	}
-	if (i < dec->buf_num)
-#else
-	/*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
-		dec->mc_buf->buf_end)
-		y_adr = dec->mc_buf->buf_start + i * buf_size;
-	else {*/
-	if (buf_size > 0 && pic->cma_alloc_addr == 0) {
-		ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
-				VF_BUFFER_IDX(i),
-				buf_size, DRIVER_NAME,
-				&pic->cma_alloc_addr);
-		if (ret < 0) {
-			avs2_print(dec, 0,
-				"decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
-				VF_BUFFER_IDX(i),
-				buf_size
-				);
-			return ret;
-		}
-
-		if (pic->cma_alloc_addr)
-			y_adr = pic->cma_alloc_addr;
-		else {
-			avs2_print(dec, 0,
-				"decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
-				VF_BUFFER_IDX(i),
-				buf_size
-				);
-			return -1;
-		}
-	}
-#endif
-	{
-		/*ensure get_pic_by_POC()
-		not get the buffer not decoded*/
-		pic->BUF_index = i;
-		pic->lcu_total = lcu_total;
-
-		pic->comp_body_size = losless_comp_body_size;
-		pic->buf_size = buf_size;
-		pic->mc_canvas_y = pic->index;
-		pic->mc_canvas_u_v = pic->index;
-#ifndef AVS2_10B_MMU
-		pic->mc_y_adr = y_adr;
-		if (dw_mode & 0x10) {
-			pic->mc_u_v_adr = y_adr +
-			((mc_buffer_size_u_v_h << 16) << 1);
-
-			pic->mc_canvas_y =
-				(pic->index << 1);
-			pic->mc_canvas_u_v =
-				(pic->index << 1) + 1;
-
-			pic->dw_y_adr = y_adr;
-			pic->dw_u_v_adr = pic->mc_u_v_adr;
-		} else
-#endif
-		if (dw_mode) {
 #ifdef AVS2_10B_MMU
-			pic->dw_y_adr = y_adr;
-			pic->dw_u_v_adr = pic->dw_y_adr +
-				((mc_buffer_size_u_v_h << 16) << 1);
-			pic->mc_y_adr = pic->dw_y_adr;
-			pic->mc_u_v_adr = pic->dw_u_v_adr;
-#else
-			pic->dw_y_adr = y_adr + (mc_buffer_size_h << 16);
-			pic->dw_u_v_adr = pic->dw_y_adr +
-				((mc_buffer_size_u_v_h << 16) << 1);
+#ifndef DYNAMIC_ALLOC_HEAD
+	pic->header_adr = decoder_bmmu_box_get_phy_addr(
+			dec->bmmu_box, HEADER_BUFFER_IDX(pic->index));
+
+	avs2_print(dec, AVS2_DBG_BUFMGR_MORE,
+		"buf_size %d, MMU header_adr %d: %ld\n",
+		buf_size, pic->index, pic->header_adr);
 #endif
+#endif
+
+	i = pic->index;
+#ifdef MV_USE_FIXED_BUF
+#ifdef G12A_BRINGUP_DEBUG
+	if (1) {
+#else
+	if ((dec->work_space_buf->mpred_mv.buf_start +
+		(((i + 1) * lcu_total) * MV_MEM_UNIT))
+		<= mpred_mv_end
+	) {
+#endif
+#endif
+#ifndef AVS2_10B_MMU
+		if (debug) {
+			pr_err("start %x  .size=%d\n",
+				dec->mc_buf_spec.buf_start + i * buf_size,
+				buf_size);
+		}
+#endif
+#ifndef AVS2_10B_MMU
+		for (i = 0; i < dec->buf_num; i++) {
+			y_adr = ((dec->m_BUF[i].free_start_adr
+				+ 0xffff) >> 16) << 16;
+			/*64k alignment*/
+			if ((y_adr+buf_size) <=	(dec->m_BUF[i].start_adr+
+				dec->m_BUF[i].size)) {
+				dec->m_BUF[i].free_start_adr =
+					y_adr + buf_size;
+				break;
+			}
+		}
+		if (i < dec->buf_num)
+#else
+		/*if ((dec->mc_buf->buf_start + (i + 1) * buf_size) <
+			dec->mc_buf->buf_end)
+			y_adr = dec->mc_buf->buf_start + i * buf_size;
+		else {*/
+		if (buf_size > 0 && pic->cma_alloc_addr == 0) {
+			ret = decoder_bmmu_box_alloc_buf_phy(dec->bmmu_box,
+					VF_BUFFER_IDX(i),
+					buf_size, DRIVER_NAME,
+					&pic->cma_alloc_addr);
+			if (ret < 0) {
+				avs2_print(dec, 0,
+					"decoder_bmmu_box_alloc_buf_phy idx %d size %d fail\n",
+					VF_BUFFER_IDX(i),
+					buf_size
+					);
+				return ret;
+			}
+
+			if (pic->cma_alloc_addr)
+				y_adr = pic->cma_alloc_addr;
+			else {
+				avs2_print(dec, 0,
+					"decoder_bmmu_box_alloc_buf_phy idx %d size %d return null\n",
+					VF_BUFFER_IDX(i),
+					buf_size
+					);
+				return -1;
+			}
+		}
+#endif
+		{
+			/*ensure get_pic_by_POC()
+			not get the buffer not decoded*/
+			pic->BUF_index = i;
+			pic->lcu_total = lcu_total;
+
+			pic->comp_body_size = losless_comp_body_size;
+			pic->buf_size = buf_size;
+#ifndef AVS2_10B_MMU
+			pic->mc_y_adr = y_adr;
+#endif
+			pic->mc_canvas_y = pic->index;
+			pic->mc_canvas_u_v = pic->index;
+#ifndef AVS2_10B_MMU
+			if (dw_mode & 0x10) {
+				pic->mc_u_v_adr = y_adr +
+				((mc_buffer_size_u_v_h << 16) << 1);
+
+				pic->mc_canvas_y =
+					(pic->index << 1);
+				pic->mc_canvas_u_v =
+					(pic->index << 1) + 1;
+
+				pic->dw_y_adr = y_adr;
+				pic->dw_u_v_adr = pic->mc_u_v_adr;
+			} else
+#endif
+			if (dw_mode) {
+				pic->dw_y_adr = y_adr
+#ifndef AVS2_10B_MMU
+				+ (mc_buffer_size_h << 16)
+#endif
+				;
+				pic->dw_u_v_adr = pic->dw_y_adr +
+					((mc_buffer_size_u_v_h << 16) << 1);
+#ifdef AVS2_10B_MMU
+				pic->mc_y_adr = pic->dw_y_adr;
+				pic->mc_u_v_adr = pic->dw_u_v_adr;
+#endif
+			}
+#ifdef MV_USE_FIXED_BUF
+#ifdef G12A_BRINGUP_DEBUG
+			if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1) {
+				pic->mpred_mv_wr_start_addr =
+				dec->work_space_buf->mpred_mv.buf_start +
+					(pic->index * 0x120000 * 4);
+			} else {
+				pic->mpred_mv_wr_start_addr =
+				dec->work_space_buf->mpred_mv.buf_start +
+					(pic->index * 0x120000);
+			}
+#else
+			pic->mpred_mv_wr_start_addr =
+			dec->work_space_buf->mpred_mv.buf_start +
+					((pic->index * lcu_total)
+					* MV_MEM_UNIT);
+#endif
+#endif
+			if (debug) {
+				avs2_print(dec, AVS2_DBG_BUFMGR,
+				"%s index %d BUF_index %d mc_y_adr %x ",
+				__func__, pic->index,
+				pic->BUF_index,
+				pic->mc_y_adr);
+				avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+				"comp_body_size %x comp_buf_size %x ",
+				pic->comp_body_size,
+				pic->buf_size);
+				avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+				"mpred_mv_wr_start_adr %d\n",
+				pic->mpred_mv_wr_start_addr);
+				avs2_print_cont(dec, AVS2_DBG_BUFMGR,
+					"dw_y_adr %d, pic->dw_u_v_adr =%d\n",
+					pic->dw_y_adr,
+					pic->dw_u_v_adr);
+			}
+			ret = 0;
 		}
 #ifdef MV_USE_FIXED_BUF
-		pic->mpred_mv_wr_start_addr =
-			dec->work_space_buf->mpred_mv.buf_start +
-			pic->index * (dec->work_space_buf->mpred_mv.buf_size / FRAME_BUFFERS);
-		if (pic->mpred_mv_wr_start_addr >
-			(dec->work_space_buf->mpred_mv.buf_start
-			+ dec->work_space_buf->mpred_mv.buf_size)) {
-			avs2_print(dec, 0, "err: fixed mv buf out of size, 0x0%x\n",
-				pic->mpred_mv_wr_start_addr);
-			pic->mpred_mv_wr_start_addr =
-				dec->work_space_buf->mpred_mv.buf_start;
-		}
-#endif
-		if (debug) {
-			avs2_print(dec, AVS2_DBG_BUFMGR,
-			"%s index %d BUF_index %d mc_y_adr %x ",
-			__func__, pic->index,
-			pic->BUF_index,
-			pic->mc_y_adr);
-			avs2_print_cont(dec, AVS2_DBG_BUFMGR,
-			"comp_body_size %x comp_buf_size %x ",
-			pic->comp_body_size,
-			pic->buf_size);
-			avs2_print_cont(dec, AVS2_DBG_BUFMGR,
-			"mpred_mv_wr_start_adr %d\n",
-			pic->mpred_mv_wr_start_addr);
-			avs2_print_cont(dec, AVS2_DBG_BUFMGR,
-				"dw_y_adr %d, pic->dw_u_v_adr =%d\n",
-				pic->dw_y_adr,
-				pic->dw_u_v_adr);
-		}
-		ret = 0;
+	} else {
+		avs2_print(dec, 0,
+			"mv buffer alloc fail %x > %x\n",
+		dec->work_space_buf->mpred_mv.buf_start +
+		(((i + 1) * lcu_total) * MV_MEM_UNIT),
+		mpred_mv_end);
 	}
-
+#endif
 	return ret;
 }
 
@@ -2527,28 +2331,36 @@
 	struct avs2_decoder *avs2_dec = &dec->avs2_dec;
 	struct avs2_frame_s *pic;
 #ifdef AVS2_10B_MMU
-	if (dec->mmu_enable) {
-		for (i = 0; i < dec->used_buf_num; i++) {
-			unsigned long buf_addr;
-			u32 header_size = get_compress_header_size(dec);
-#ifdef AVS2_10B_MMU_DW
-			if (dec->dw_mmu_enable)
-				header_size <<= 1;
-#endif
-			if (decoder_bmmu_box_alloc_buf_phy
-					(dec->bmmu_box,
-					HEADER_BUFFER_IDX(i), header_size,
-					DRIVER_HEADER_NAME,
-					&buf_addr) < 0){
-				avs2_print(dec, 0,
-					"%s malloc compress header failed %d\n",
-					DRIVER_HEADER_NAME, i);
-				dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
-				return;
-			}
+	unsigned long buf_addr1;
+	/*alloc AVS2 compress header first*/
+		if (decoder_bmmu_box_alloc_buf_phy
+				(dec->bmmu_box,
+				HEADER_BUFFER_IDX(-1), get_compress_header_size(dec),
+				DRIVER_HEADER_NAME,
+				&buf_addr1) < 0){
+			avs2_print(dec, 0,
+				"%s malloc compress header failed %d\n",
+				DRIVER_HEADER_NAME, -1);
+			dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+			return;
+		}
+#ifndef DYNAMIC_ALLOC_HEAD
+	for (i = 0; i < dec->used_buf_num; i++) {
+		unsigned long buf_addr;
+		if (decoder_bmmu_box_alloc_buf_phy
+				(dec->bmmu_box,
+				HEADER_BUFFER_IDX(i), get_compress_header_size(dec),
+				DRIVER_HEADER_NAME,
+				&buf_addr) < 0){
+			avs2_print(dec, 0,
+				"%s malloc compress header failed %d\n",
+				DRIVER_HEADER_NAME, i);
+			dec->fatal_error |= DECODER_FATAL_ERROR_NO_MEM;
+			return;
 		}
 	}
 #endif
+#endif
 	dec->frame_height = avs2_dec->img.height;
 	dec->frame_width = avs2_dec->img.width;
 
@@ -3261,7 +3073,7 @@
 	if ((get_double_write_mode(dec) & 0x10) == 0)
 		WRITE_VREG(HEVC_CM_BODY_START_ADDR, cur_pic->mc_y_adr);
 #endif
-	if ((get_double_write_mode(dec) & 0x20) == 0) {
+	if (get_double_write_mode(dec)) {
 		WRITE_VREG(HEVC_SAO_Y_START_ADDR, cur_pic->dw_y_adr);
 		WRITE_VREG(HEVC_SAO_C_START_ADDR, cur_pic->dw_u_v_adr);
 		WRITE_VREG(HEVC_SAO_Y_WPTR, cur_pic->dw_y_adr);
@@ -3273,14 +3085,6 @@
 #ifdef AVS2_10B_MMU
 	WRITE_VREG(HEVC_CM_HEADER_START_ADDR, cur_pic->header_adr);
 #endif
-#ifdef AVS2_10B_MMU_DW
-	if (dec->dw_mmu_enable) {
-		WRITE_VREG(HEVC_CM_HEADER_START_ADDR2, cur_pic->dw_header_adr);
-		WRITE_VREG(HEVC_SAO_Y_START_ADDR, 0);
-		WRITE_VREG(HEVC_SAO_C_START_ADDR, 0);
-	}
-#endif
-
 	data32 = (mc_buffer_size_u_v_h << 16) << 1;
 	/*pr_info("data32=%x,mc_buffer_size_u_v_h=%x,lcu_total=%x\n",
 		data32, mc_buffer_size_u_v_h, cur_pic->lcu_total);*/
@@ -3297,22 +3101,6 @@
 	data32 |= (MEM_MAP_MODE << 12);
 	data32 &= (~0x3);
 	data32 |= 0x1; /* [1]:dw_disable [0]:cm_disable*/
-
-	/*
-	*  [31:24] ar_fifo1_axi_thred
-	*  [23:16] ar_fifo0_axi_thred
-	*  [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
-	*  [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
-	*  [11:08] axi_lendian_C
-	*  [07:04] axi_lendian_Y
-	*  [3]     reserved
-	*  [2]     clk_forceon
-	*  [1]     dw_disable:disable double write output
-	*  [0]     cm_disable:disable compress output
-	*/
-	data32 &= (~(3 << 14));
-	data32 |= (2 << 14);
-
 	WRITE_VREG(HEVC_SAO_CTRL1, data32);
 	/*[23:22] dw_v1_ctrl [21:20] dw_v0_ctrl [19:18] dw_h1_ctrl
 		[17:16] dw_h0_ctrl*/
@@ -3344,41 +3132,23 @@
 	data32 &= ~(0xff << 16);
 	WRITE_VREG(HEVC_SAO_CTRL5, data32);
 
-	/*
-	* [3:0]   little_endian
-	* [5:4]   address_format 00:linear 01:32x32 10:64x32
-	* [7:6]   reserved
-	* [9:8]   Linear_LineAlignment 00:16byte 01:32byte 10:64byte
-	* [11:10] reserved
-	* [12]    CbCr_byte_swap
-	* [31:13] reserved
-	*/
-
 	data32 = READ_VREG(HEVCD_IPP_AXIIF_CONFIG);
 	data32 &= (~0x30);
 	/*[5:4] address_format 00:linear 01:32x32 10:64x32*/
 	data32 |= (MEM_MAP_MODE << 4);
 	data32 &= (~0xF);
 	data32 |= 0x8; /*Big-Endian per 64-bit*/
-
-	data32 &= (~(3 << 8));
-	data32 |= (2 << 8);
 	WRITE_VREG(HEVCD_IPP_AXIIF_CONFIG, data32);
 #endif
 #else
 	data32 = READ_VREG(HEVC_SAO_CTRL1);
-	data32 &= (~(3 << 14));
-	data32 |= (2 << 14);	/* line align with 64*/
 	data32 &= (~0x3000);
-	data32 |= (MEM_MAP_MODE << 12);	/* [13:12] axi_aformat, 0-Linear,
+	data32 |= (MEM_MAP_MODE <<
+			   12);	/* [13:12] axi_aformat, 0-Linear,
 				   1-32x32, 2-64x32 */
 	data32 &= (~0xff0);
-#ifdef AVS2_10B_MMU_DW
-	if (dec->dw_mmu_enable == 0)
-		data32 |= ((dec->endian >> 8) & 0xfff);
-#else
-	data32 |= ((dec->endian >> 8) & 0xfff);	/* data32 |= 0x670; Big-Endian per 64-bit */
-#endif
+	/* data32 |= 0x670;  // Big-Endian per 64-bit */
+	data32 |= endian;	/* Big-Endian per 64-bit */
 	data32 &= (~0x3); /*[1]:dw_disable [0]:cm_disable*/
 #if 0
 	if  (get_cpu_major_id() < MESON_CPU_MAJOR_ID_G12A) {
@@ -3396,18 +3166,6 @@
 	else if (get_double_write_mode(dec) & 0x10)
 		data32 |= 0x1; /*disable cm*/
 
-	/*
-	*  [31:24] ar_fifo1_axi_thred
-	*  [23:16] ar_fifo0_axi_thred
-	*  [15:14] axi_linealign, 0-16bytes, 1-32bytes, 2-64bytes
-	*  [13:12] axi_aformat, 0-Linear, 1-32x32, 2-64x32
-	*  [11:08] axi_lendian_C
-	*  [07:04] axi_lendian_Y
-	*  [3]     reserved
-	*  [2]     clk_forceon
-	*  [1]     dw_disable:disable double write output
-	*  [0]     cm_disable:disable compress output
-	*/
 	WRITE_VREG(HEVC_SAO_CTRL1, data32);
 
 	if (get_double_write_mode(dec) & 0x10) {
@@ -3421,55 +3179,26 @@
 		data32 &= ~(0xff << 16);
 		WRITE_VREG(HEVC_SAO_CTRL5, data32);
 	} else {
-		if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_T7)
-			WRITE_VREG(HEVC_SAO_CTRL26, 0);
-
 		data32 = READ_VREG(HEVC_SAO_CTRL5);
 		data32 &= (~(0xff << 16));
-		if ((get_double_write_mode(dec) & 0xf) == 8 ||
-			(get_double_write_mode(dec) & 0xf) == 9) {
+		if (get_double_write_mode(dec) == 2 ||
+			get_double_write_mode(dec) == 3)
 			data32 |= (0xff<<16);
-			WRITE_VREG(HEVC_SAO_CTRL26, 0xf);
-		} else if ((get_double_write_mode(dec) & 0xf) == 2 ||
-			(get_double_write_mode(dec) & 0xf) == 3)
-			data32 |= (0xff<<16);
-		else if ((get_double_write_mode(dec) & 0xf) == 4)
+		else if (get_double_write_mode(dec) == 4)
 			data32 |= (0x33<<16);
 		WRITE_VREG(HEVC_SAO_CTRL5, data32);