deinterlace: add di-multi folder v2 [2/3]
authorJihong Sui <jihong.sui@amlogic.com>
Mon, 5 Aug 2019 06:17:07 +0000 (14:17 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Mon, 19 Aug 2019 02:26:00 +0000 (19:26 -0700)
PD#SWPL-10064

Problem:
add di-multi folder

Solution:
1. add di_multi folder;
2. it can be enable by dts;
3. only one of di can be enabled at the same time;
4. no di-pq filse;

Verify:
U212

Change-Id: I8726d2430cf1beb58d0cd37c0358b7ea8e06c414
Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
41 files changed:
MAINTAINERS
drivers/amlogic/media/Kconfig
drivers/amlogic/media/Makefile
drivers/amlogic/media/di_multi/Kconfig [new file with mode: 0644]
drivers/amlogic/media/di_multi/Makefile [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace_dbg.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace_dbg.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace_hw.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/deinterlace_hw.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_api.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_api.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_data.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_data_l.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_dbg.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_dbg.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_post.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_post.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_pps.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_pps.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_prc.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_prc.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_pre.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_pre.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_que.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_que.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_reg_tab.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_reg_tab.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_sys.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_sys.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_task.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_task.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_vframe.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/di_vframe.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/dim_trace.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/nr_downscale.c [new file with mode: 0644]
drivers/amlogic/media/di_multi/nr_downscale.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/register.h [new file with mode: 0644]
drivers/amlogic/media/di_multi/register_nr4.h [new file with mode: 0644]
include/linux/amlogic/media/vfm/vframe.h

index 6b64651..2e0f76a 100644 (file)
@@ -15104,3 +15104,7 @@ AMLOGIC DEINTERLACE DRIVER
 M:     Jihong Sui <jihong.sui@amlogic.com>
 F:     drivers/amlogic/media/deinterlace/di_pqa.h
 F:     drivers/amlogic/media/di_local/*
+
+AMLOGIC ADD DI_MULTI DRIVER
+M:     Jihong Sui <jihong.sui@amlogic.com>
+F:     drivers/amlogic/media/di_multi/*
index 46220fa..6159286 100644 (file)
@@ -89,6 +89,7 @@ source "drivers/amlogic/media/vout/Kconfig"
 source "drivers/amlogic/media/osd/Kconfig"
 source "drivers/amlogic/media/osd_ext/Kconfig"
 source "drivers/amlogic/media/deinterlace/Kconfig"
+source "drivers/amlogic/media/di_multi/Kconfig"
 source "drivers/amlogic/media/di_local/Kconfig"
 source "drivers/amlogic/media/vin/Kconfig"
 source "drivers/amlogic/media/video_processor/Kconfig"
index c72ece4..fe43ed7 100644 (file)
@@ -5,6 +5,7 @@ obj-$(CONFIG_AMLOGIC_MEDIA_FB)  +=      osd/
 obj-$(CONFIG_AMLOGIC_MEDIA_FB_EXT)     +=      osd_ext/
 obj-$(CONFIG_AMLOGIC_VOUT)             +=      vout/
 obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE)        +=      deinterlace/
+obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE)        +=      di_multi/
 obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE)        +=      di_local/
 obj-$(CONFIG_AMLOGIC_MEDIA_VIN)                +=      vin/
 obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR)    +=      video_processor/
diff --git a/drivers/amlogic/media/di_multi/Kconfig b/drivers/amlogic/media/di_multi/Kconfig
new file mode 100644 (file)
index 0000000..8670046
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Deinterlace driver configuration
+#
+
+menu "DI_MULTI driver"
+
+config AMLOGIC_MEDIA_DEINTERLACE
+       tristate "DI_MULTI driver"
+       default n
+       help
+               Select to enable AMLOGIC DEINTERLACE driver
+               process interlace source need three continueed fields,
+               wave progressive source with two interlace fields from
+               one progreesive fields
+endmenu
diff --git a/drivers/amlogic/media/di_multi/Makefile b/drivers/amlogic/media/di_multi/Makefile
new file mode 100644 (file)
index 0000000..23df552
--- /dev/null
@@ -0,0 +1,34 @@
+# # Makefile for the Post Process Manager device #
+ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+ccflags-y := -D DEBUG_SUPPORT
+ccflags-y := -DDEBUG
+else
+ccflags-y := -DDEBUG
+endif
+ccflags-y += -I.
+CFLAGS_dim.o := -I$(src)
+obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += dim.o
+dim-objs += deinterlace.o
+dim-objs += deinterlace_hw.o
+#dim-objs += deinterlace_mtn.o
+dim-objs += deinterlace_dbg.o
+#dim-objs += nr_drv.o
+#dim-objs += pulldown_drv.o
+#dim-objs += detect3d.o
+dim-objs += nr_downscale.o
+dim-objs += di_pps.o
+dim-objs += di_vframe.o
+dim-objs += di_prc.o
+dim-objs += di_pre.o
+dim-objs += di_post.o
+dim-objs += di_reg_tab.o
+dim-objs += di_dbg.o
+dim-objs += di_que.o
+dim-objs += di_sys.o
+dim-objs += di_task.o
+dim-objs += di_api.o
+#dim-objs += film_mode_fmw/vof_soft_top.o
+#dim-objs += film_mode_fmw/flm_mod_xx.o
+#dim-objs += film_mode_fmw/film_fw1.o
+ccflags-y += -Idrivers/amlogic/media/common/rdma/
+ccflags-y += -I$(src)
\ No newline at end of file
diff --git a/drivers/amlogic/media/di_multi/deinterlace.c b/drivers/amlogic/media/di_multi/deinterlace.c
new file mode 100644 (file)
index 0000000..daa6e1a
--- /dev/null
@@ -0,0 +1,8401 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/cdev.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_irq.h>
+#include <linux/uaccess.h>
+#include <linux/of_fdt.h>
+#include <linux/cma.h>
+#include <linux/dma-contiguous.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/amlogic/iomap.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/amlogic/cpu_version.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h>
+#include <linux/amlogic/media/vout/vinfo.h>
+#include <linux/amlogic/media/vout/vout_notify.h>
+#include <linux/amlogic/media/vpu/vpu.h>
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+#include <linux/amlogic/media/rdma/rdma_mgr.h>
+#endif
+#include <linux/amlogic/media/video_sink/video.h>
+#include "register.h"
+#include "deinterlace.h"
+#include "deinterlace_dbg.h"
+#include "nr_downscale.h"
+
+#include "di_data_l.h"
+#include "di_dbg.h"
+#include "di_pps.h"
+#include "di_pre.h"
+#include "di_prc.h"
+#include "di_task.h"
+#include "di_vframe.h"
+#include "di_que.h"
+#include "di_api.h"
+#include "di_sys.h"
+
+/*2018-07-18 add debugfs*/
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+/*2018-07-18 -----------*/
+
+#ifdef DET3D
+#include "detect3d.h"
+#endif
+#define ENABLE_SPIN_LOCK_ALWAYS
+
+static DEFINE_SPINLOCK(di_lock2);
+
+#define di_lock_irqfiq_save(irq_flag) \
+       spin_lock_irqsave(&di_lock2, irq_flag)
+
+#define di_unlock_irqfiq_restore(irq_flag) \
+       spin_unlock_irqrestore(&di_lock2, irq_flag)
+
+#ifdef SUPPORT_MPEG_TO_VDIN
+static int mpeg2vdin_flag;
+static int mpeg2vdin_en;
+#endif
+
+static int di_reg_unreg_cnt = 40;
+static bool overturn;
+
+int dim_get_reg_unreg_cnt(void)
+{
+       return di_reg_unreg_cnt;
+}
+
+static bool mc_mem_alloc;
+
+static unsigned int di_pre_rdma_enable;
+
+/**************************************
+ *
+ *
+ *************************************/
+unsigned int di_dbg = DBG_M_EVENT;
+module_param(di_dbg, uint, 0664);
+MODULE_PARM_DESC(di_dbg, "debug print");
+
+/* destroy unnecessary frames before display */
+static unsigned int hold_video;
+
+DEFINE_SPINLOCK(plist_lock);
+
+static const char version_s[] = "2019-04-25ma";
+
+/*1:enable bypass pre,ei only;
+ * 2:debug force bypass pre,ei for post
+ */
+static int bypass_pre;
+
+static int invert_top_bot;
+
+/* add avoid vframe put/get error */
+static int di_blocking;
+/*
+ * bit[2]: enable bypass all when skip
+ * bit[1:0]: enable bypass post when skip
+ */
+/*static int di_vscale_skip_enable;*/
+
+/* 0: not support nr10bit, 1: support nr10bit */
+/*static unsigned int nr10bit_support;*/
+
+#ifdef RUN_DI_PROCESS_IN_IRQ
+/*
+ * di_process() run in irq,
+ * dim_reg_process(), dim_unreg_process() run in kernel thread
+ * dim_reg_process_irq(), di_unreg_process_irq() run in irq
+ * di_vf_put(), di_vf_peek(), di_vf_get() run in irq
+ * di_receiver_event_fun() run in task or irq
+ */
+/*
+ * important:
+ * to set input2pre, VFRAME_EVENT_PROVIDER_VFRAME_READY of
+ * vdin should be sent in irq
+ */
+
+static int input2pre;
+/*false:process progress by field;
+ * true: process progress by frame with 2 interlace buffer
+ */
+static int input2pre_buf_miss_count;
+static int input2pre_proc_miss_count;
+static int input2pre_throw_count;
+static int input2pre_miss_policy;
+/* 0, do not force pre_de_busy to 0, use di_wr_buf after dim_irq happen;
+ * 1, force pre_de_busy to 0 and call
+ *     dim_pre_de_done_buf_clear to clear di_wr_buf
+ */
+#endif
+/*false:process progress by field;
+ * bit0: process progress by frame with 2 interlace buffer
+ * bit1: temp add debug for 3d process FA,1:bit0 force to 1;
+ */
+/*static int use_2_interlace_buff;*/
+/* prog_proc_config,
+ * bit[2:1]: when two field buffers are used,
+ * 0 use vpp for blending ,
+ * 1 use post_di module for blending
+ * 2 debug mode, bob with top field
+ * 3 debug mode, bot with bot field
+ * bit[0]:
+ * 0 "prog vdin" use two field buffers,
+ * 1 "prog vdin" use single frame buffer
+ * bit[4]:
+ * 0 "prog frame from decoder/vdin" use two field buffers,
+ * 1 use single frame buffer
+ * bit[5]:
+ * when two field buffers are used for decoder (bit[4] is 0):
+ * 1,handle prog frame as two interlace frames
+ * bit[6]:(bit[4] is 0,bit[5] is 0,use_2_interlace_buff is 0): 0,
+ * process progress frame as field,blend by post;
+ * 1, process progress frame as field,process by normal di
+ */
+/*static int prog_proc_config = (1 << 5) | (1 << 1) | 1;*/
+/*
+ * for source include both progressive and interlace pictures,
+ * always use post_di module for blending
+ */
+#define is_handle_prog_frame_as_interlace(vframe)                      \
+       (((dimp_get(eDI_MP_prog_proc_config) & 0x30) == 0x20) &&        \
+        (((vframe)->type & VIDTYPE_VIU_422) == 0))
+
+static int frame_count;
+static int disp_frame_count;
+int di_get_disp_cnt(void)
+{
+       return disp_frame_count;
+}
+
+static unsigned long reg_unreg_timeout_cnt;
+#ifdef DET3D
+static unsigned int det3d_mode;
+static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf);
+#endif
+
+static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr);
+static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *);
+
+static unsigned int unreg_cnt;/*cnt for vframe unreg*/
+static unsigned int reg_cnt;/*cnt for vframe reg*/
+
+static unsigned char recovery_flag;
+
+static unsigned int recovery_log_reason;
+static unsigned int recovery_log_queue_idx;
+static struct di_buf_s *recovery_log_di_buf;
+
+unsigned char dim_vcry_get_flg(void)
+{
+       return recovery_flag;
+}
+
+void dim_vcry_flg_inc(void)
+{
+       recovery_flag++;
+}
+
+void dim_vcry_set_flg(unsigned char val)
+{
+       recovery_flag = val;
+}
+
+void dim_reg_timeout_inc(void)
+{
+       reg_unreg_timeout_cnt++;
+}
+
+/********************************/
+unsigned int dim_vcry_get_log_reason(void)
+{
+       return recovery_log_reason;
+}
+
+void dim_vcry_set_log_reason(unsigned int val)
+{
+       recovery_log_reason = val;
+}
+
+/********************************/
+unsigned char dim_vcry_get_log_q_idx(void)
+{
+       return recovery_log_queue_idx;
+}
+
+void dim_vcry_set_log_q_idx(unsigned int val)
+{
+       recovery_log_queue_idx = val;
+}
+
+/********************************/
+struct di_buf_s **dim_vcry_get_log_di_buf(void)
+{
+       return &recovery_log_di_buf;
+}
+
+void dim_vcry_set_log_di_buf(struct di_buf_s *di_bufp)
+{
+       recovery_log_di_buf = di_bufp;
+}
+
+void dim_vcry_set(unsigned int reason, unsigned int idx,
+                 struct di_buf_s *di_bufp)
+{
+       recovery_log_reason = reason;
+       recovery_log_queue_idx = idx;
+       recovery_log_di_buf = di_bufp;
+}
+
+static long same_field_top_count;
+static long same_field_bot_count;
+/* bit 0:
+ * 0, keep 3 buffers in pre_ready_list for checking;
+ * 1, keep 4 buffers in pre_ready_list for checking;
+ */
+
+static struct queue_s *get_queue_by_idx(unsigned int channel, int idx);
+static void dump_state(unsigned int channel);
+static void recycle_keep_buffer(unsigned int channel);
+
+#define DI_PRE_INTERVAL         (HZ / 100)
+
+/*
+ * progressive frame process type config:
+ * 0, process by field;
+ * 1, process by frame (only valid for vdin source whose
+ * width/height does not change)
+ */
+
+static struct di_buf_s *cur_post_ready_di_buf;
+
+/************For Write register**********************/
+
+static unsigned int num_di_stop_reg_addr = 4;
+static unsigned int di_stop_reg_addr[4] = {0};
+
+static unsigned int is_need_stop_reg(unsigned int addr)
+{
+       int idx = 0;
+
+       if (dimp_get(eDI_MP_di_stop_reg_flag)) {
+               for (idx = 0; idx < num_di_stop_reg_addr; idx++) {
+                       if (addr == di_stop_reg_addr[idx]) {
+                               pr_dbg("stop write addr: %x\n", addr);
+                               return 1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+void dim_DI_Wr(unsigned int addr, unsigned int val)
+{
+       if (is_need_stop_reg(addr))
+               return;
+       ddbg_reg_save(addr, val, 0, 32);
+       Wr(addr, val);
+}
+
+void dim_DI_Wr_reg_bits(unsigned int adr, unsigned int val,
+                       unsigned int start, unsigned int len)
+{
+       if (is_need_stop_reg(adr))
+               return;
+       ddbg_reg_save(adr, val, start, len); /*ary add for debug*/
+       Wr_reg_bits(adr, val, start, len);
+}
+
+void dim_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val)
+{
+       if (is_need_stop_reg(addr))
+               return;
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support))
+               dim_DI_Wr(addr, val);
+       else
+               VSYNC_WR_MPEG_REG(addr, val);
+}
+
+void dim_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val,
+                               unsigned int start, unsigned int len)
+{
+       if (is_need_stop_reg(addr))
+               return;
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support))
+               dim_DI_Wr_reg_bits(addr, val, start, len);
+       else
+               VSYNC_WR_MPEG_REG_BITS(addr, val, start, len);
+}
+
+#ifdef DI_V2
+unsigned int DI_POST_REG_RD(unsigned int addr)
+{
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+
+       if (IS_ERR_OR_NULL(de_devp))
+               return 0;
+       if (de_devp->flags & DI_SUSPEND_FLAG) {
+               PR_ERR("REG 0x%x access prohibited.\n", addr);
+               return 0;
+       }
+       return VSYNC_RD_MPEG_REG(addr);
+}
+EXPORT_SYMBOL(DI_POST_REG_RD);
+
+int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
+{
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+
+       if (IS_ERR_OR_NULL(de_devp))
+               return 0;
+       if (de_devp->flags & DI_SUSPEND_FLAG) {
+               PR_ERR("REG 0x%x access prohibited.\n", adr);
+               return -1;
+       }
+       return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
+}
+EXPORT_SYMBOL(DI_POST_WR_REG_BITS);
+#else
+unsigned int l_DI_POST_REG_RD(unsigned int addr)
+{
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+
+       if (IS_ERR_OR_NULL(de_devp))
+               return 0;
+       if (de_devp->flags & DI_SUSPEND_FLAG) {
+               PR_ERR("REG 0x%x access prohibited.\n", addr);
+               return 0;
+       }
+       return VSYNC_RD_MPEG_REG(addr);
+}
+
+int l_DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
+{
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+
+       if (IS_ERR_OR_NULL(de_devp))
+               return 0;
+       if (de_devp->flags & DI_SUSPEND_FLAG) {
+               PR_ERR("REG 0x%x access prohibited.\n", adr);
+               return -1;
+       }
+       return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
+}
+
+#endif
+/**********************************/
+
+/*****************************
+ *      di attr management :
+ *      enable
+ *      mode
+ *      reg
+ ******************************/
+/*config attr*/
+
+int pre_run_flag = DI_RUN_FLAG_RUN;
+static int dump_state_flag;
+
+const char *dim_get_version_s(void)
+{
+       return version_s;
+}
+
+int dim_get_blocking(void)
+{
+       return di_blocking;
+}
+
+unsigned long dim_get_reg_unreg_timeout_cnt(void)
+{
+       return reg_unreg_timeout_cnt;
+}
+
+struct di_buf_s *dim_get_recovery_log_di_buf(void)
+{
+       return recovery_log_di_buf;
+}
+
+struct vframe_s **dim_get_vframe_in(unsigned int ch)
+{
+       return get_vframe_in(ch);
+}
+
+int dim_get_dump_state_flag(void)
+{
+       return dump_state_flag;
+}
+
+/*--------------------------*/
+
+ssize_t
+store_dbg(struct device *dev,
+         struct device_attribute *attr,
+         const char *buf, size_t count)
+{
+       unsigned int channel = get_current_channel();   /* debug only*/
+       struct di_buf_s *pbuf_local = get_buf_local(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       if (strncmp(buf, "buf", 3) == 0) {
+               struct di_buf_s *di_buf_tmp = 0;
+
+               if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp))
+                       return count;
+               dim_dump_di_buf(di_buf_tmp);
+       } else if (strncmp(buf, "vframe", 6) == 0) {
+               vframe_t *vf = 0;
+
+               if (kstrtoul(buf + 6, 16, (unsigned long *)&vf))
+                       return count;
+               dim_dump_vframe(vf);
+       } else if (strncmp(buf, "pool", 4) == 0) {
+               unsigned long idx = 0;
+
+               if (kstrtoul(buf + 4, 10, &idx))
+                       return count;
+               dim_dump_pool(get_queue_by_idx(channel, idx));
+       } else if (strncmp(buf, "state", 4) == 0) {
+               dump_state(channel);
+               pr_info("add new debugfs: cat /sys/kernel/debug/di/state\n");
+       } else if (strncmp(buf, "prog_proc_config", 16) == 0) {
+               if (buf[16] == '1')
+                       dimp_set(eDI_MP_prog_proc_config, 1);
+               else
+                       dimp_set(eDI_MP_prog_proc_config, 0);
+       } else if (strncmp(buf, "init_flag", 9) == 0) {
+               if (buf[9] == '1')
+                       set_init_flag(0, true);/*init_flag = 1;*/
+               else
+                       set_init_flag(0, false);/*init_flag = 0;*/
+       } else if (strncmp(buf, "prun", 4) == 0) {
+               pre_run_flag = DI_RUN_FLAG_RUN;
+       } else if (strncmp(buf, "ppause", 6) == 0) {
+               pre_run_flag = DI_RUN_FLAG_PAUSE;
+       } else if (strncmp(buf, "pstep", 5) == 0) {
+               pre_run_flag = DI_RUN_FLAG_STEP;
+       } else if (strncmp(buf, "dumpreg", 7) == 0) {
+               pr_info("add new debugfs: cat /sys/kernel/debug/di/dumpreg\n");
+       } else if (strncmp(buf, "dumpmif", 7) == 0) {
+               dim_dump_mif_size_state(ppre, ppost);
+       } else if (strncmp(buf, "recycle_buf", 11) == 0) {
+               recycle_keep_buffer(channel);
+       } else if (strncmp(buf, "recycle_post", 12) == 0) {
+               if (di_vf_l_peek(channel))
+                       di_vf_l_put(di_vf_l_get(channel), channel);
+       } else if (strncmp(buf, "mem_map", 7) == 0) {
+               dim_dump_buf_addr(pbuf_local, MAX_LOCAL_BUF_NUM * 2);
+       } else {
+               pr_info("DI no support cmd %s!!!\n", buf);
+       }
+
+       return count;
+}
+
+#ifdef ARY_TEMP
+static int __init di_read_canvas_reverse(char *str)
+{
+       unsigned char *ptr = str;
+
+       pr_dbg("%s: bootargs is %s.\n", __func__, str);
+       if (strstr(ptr, "1")) {
+               invert_top_bot |= 0x1;
+               overturn = true;
+       } else {
+               invert_top_bot &= (~0x1);
+               overturn = false;
+       }
+
+       return 0;
+}
+
+__setup("video_reverse=", di_read_canvas_reverse);
+#endif
+
+static unsigned char *di_log_buf;
+static unsigned int di_log_wr_pos;
+static unsigned int di_log_rd_pos;
+static unsigned int di_log_buf_size;
+
+static unsigned int buf_state_log_start;
+/*  set to 1 by condition of "post_ready count < buf_state_log_threshold",
+ * reset to 0 by set buf_state_log_threshold as 0
+ */
+
+static DEFINE_SPINLOCK(di_print_lock);
+
+#define PRINT_TEMP_BUF_SIZE 128
+
+static int di_print_buf(char *buf, int len)
+{
+       unsigned long flags;
+       int pos;
+       int di_log_rd_pos_;
+
+       if (di_log_buf_size == 0)
+               return 0;
+
+       spin_lock_irqsave(&di_print_lock, flags);
+       di_log_rd_pos_ = di_log_rd_pos;
+       if (di_log_wr_pos >= di_log_rd_pos)
+               di_log_rd_pos_ += di_log_buf_size;
+
+       for (pos = 0; pos < len && di_log_wr_pos < (di_log_rd_pos_ - 1);
+            pos++, di_log_wr_pos++) {
+               if (di_log_wr_pos >= di_log_buf_size)
+                       di_log_buf[di_log_wr_pos - di_log_buf_size] = buf[pos];
+               else
+                       di_log_buf[di_log_wr_pos] = buf[pos];
+       }
+       if (di_log_wr_pos >= di_log_buf_size)
+               di_log_wr_pos -= di_log_buf_size;
+       spin_unlock_irqrestore(&di_print_lock, flags);
+       return pos;
+}
+
+/* static int log_seq = 0; */
+int dim_print(const char *fmt, ...)
+{
+       va_list args;
+       int avail = PRINT_TEMP_BUF_SIZE;
+       char buf[PRINT_TEMP_BUF_SIZE];
+       int pos, len = 0;
+
+       if (dimp_get(eDI_MP_di_printk_flag) & 1) {
+               if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_PRECISE_TIMESTAMP)
+                       pr_dbg("%llums:", cur_to_msecs());
+               va_start(args, fmt);
+               vprintk(fmt, args);
+               va_end(args);
+               return 0;
+       }
+
+       if (di_log_buf_size == 0)
+               return 0;
+
+/* len += snprintf(buf+len, avail-len, "%d:",log_seq++); */
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_TIMESTAMP)
+               len += snprintf(buf + len, avail - len, "%u:",
+                       jiffies_to_msecs(jiffies_64));
+
+       va_start(args, fmt);
+       len += vsnprintf(buf + len, avail - len, fmt, args);
+       va_end(args);
+
+       if ((avail - len) <= 0)
+               buf[PRINT_TEMP_BUF_SIZE - 1] = '\0';
+
+       pos = di_print_buf(buf, len);
+/* pr_dbg("dim_print:%d %d\n", di_log_wr_pos, di_log_rd_pos); */
+       return pos;
+}
+
+ssize_t dim_read_log(char *buf)
+{
+       unsigned long flags;
+       ssize_t read_size = 0;
+
+       if (di_log_buf_size == 0)
+               return 0;
+/* pr_dbg("show_log:%d %d\n", di_log_wr_pos, di_log_rd_pos); */
+       spin_lock_irqsave(&di_print_lock, flags);
+       if (di_log_rd_pos < di_log_wr_pos)
+               read_size = di_log_wr_pos - di_log_rd_pos;
+
+       else if (di_log_rd_pos > di_log_wr_pos)
+               read_size = di_log_buf_size - di_log_rd_pos;
+
+       if (read_size > PAGE_SIZE)
+               read_size = PAGE_SIZE;
+       if (read_size > 0)
+               memcpy(buf, di_log_buf + di_log_rd_pos, read_size);
+
+       di_log_rd_pos += read_size;
+       if (di_log_rd_pos >= di_log_buf_size)
+               di_log_rd_pos = 0;
+       spin_unlock_irqrestore(&di_print_lock, flags);
+       return read_size;
+}
+
+ssize_t
+store_log(struct device *dev,
+         struct device_attribute *attr,
+         const char *buf, size_t count)
+{
+       unsigned long flags, tmp;
+
+       if (strncmp(buf, "bufsize", 7) == 0) {
+               if (kstrtoul(buf + 7, 10, &tmp))
+                       return count;
+               spin_lock_irqsave(&di_print_lock, flags);
+               kfree(di_log_buf);
+               di_log_buf = NULL;
+               di_log_buf_size = 0;
+               di_log_rd_pos = 0;
+               di_log_wr_pos = 0;
+               if (tmp >= 1024) {
+                       di_log_buf_size = 0;
+                       di_log_rd_pos = 0;
+                       di_log_wr_pos = 0;
+                       di_log_buf = kmalloc(tmp, GFP_KERNEL);
+                       if (di_log_buf)
+                               di_log_buf_size = tmp;
+               }
+               spin_unlock_irqrestore(&di_print_lock, flags);
+               pr_dbg("di_store:set bufsize tmp %lu %u\n",
+                      tmp, di_log_buf_size);
+       } else if (strncmp(buf, "printk", 6) == 0) {
+               if (kstrtoul(buf + 6, 10, &tmp))
+                       return count;
+
+               dimp_set(eDI_MP_di_printk_flag, tmp);
+       } else {
+               dim_print("%s", buf);
+       }
+       return 16;
+}
+
+ssize_t
+show_vframe_status(struct device *dev,
+                  struct device_attribute *attr,
+                  char *buf)
+{
+       int ret = 0;
+       int get_ret = 0;
+
+       struct vframe_states states;
+       int ch;
+       struct di_mng_s *pbm = get_bufmng();
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               if (!pbm->sub_act_flg[ch])
+                       continue;
+               else
+                       ret += sprintf(buf + ret, "ch[%d]\n", ch);
+
+               get_ret = vf_get_states_by_name(di_rev_name[ch], &states);
+
+               if (get_ret == 0) {
+                       ret += sprintf(buf + ret, "vframe_pool_size=%d\n",
+                               states.vf_pool_size);
+                       ret += sprintf(buf + ret, "vframe buf_free_num=%d\n",
+                               states.buf_free_num);
+                       ret += sprintf(buf + ret, "vframe buf_recycle_num=%d\n",
+                               states.buf_recycle_num);
+                       ret += sprintf(buf + ret, "vframe buf_avail_num=%d\n",
+                               states.buf_avail_num);
+               } else {
+                       ret += sprintf(buf + ret, "vframe no states\n");
+               }
+       }
+       return ret;
+}
+
+/***************************
+ * di buffer management
+ ***************************/
+
+static const char * const vframe_type_name[] = {
+       "", "di_buf_in", "di_buf_loc", "di_buf_post"
+};
+
+const char *dim_get_vfm_type_name(unsigned int nub)
+{
+       if (nub < 4)
+               return vframe_type_name[nub];
+
+       return "";
+}
+
+static unsigned int default_width = 1920;
+static unsigned int default_height = 1080;
+
+/*
+ * all buffers are in
+ * 1) list of local_free_list,in_free_list,pre_ready_list,recycle_list
+ * 2) di_pre_stru.di_inp_buf
+ * 3) di_pre_stru.di_wr_buf
+ * 4) cur_post_ready_di_buf
+ * 5) (struct di_buf_s*)(vframe->private_data)->di_buf[]
+ *
+ * 6) post_free_list_head
+ * 8) (struct di_buf_s*)(vframe->private_data)
+ */
+
+/*move to deinterlace .h #define queue_t struct queue_s*/
+
+static struct queue_s *get_queue_by_idx(unsigned int channel, int idx)
+{
+       struct queue_s *pqueue = get_queue(channel);
+
+       if (idx < QUEUE_NUM)
+               return &pqueue[idx];
+       else
+               return NULL;
+}
+
+struct di_buf_s *dim_get_buf(unsigned int channel, int queue_idx,
+                            int *start_pos)
+{
+       struct queue_s *pqueue = get_queue(channel);
+       queue_t *q = &pqueue[queue_idx];
+       int idx = 0;
+       unsigned int pool_idx, di_buf_idx;
+       struct di_buf_s *di_buf = NULL;
+       int start_pos_init = *start_pos;
+       struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s:<%d:%d,%d,%d> %d\n", __func__, queue_idx,
+                         q->num, q->in_idx, q->out_idx, *start_pos);
+
+       if (q->type == 0) {
+               if ((*start_pos) < q->num) {
+                       idx = q->out_idx + (*start_pos);
+                       if (idx >= MAX_QUEUE_POOL_SIZE)
+                               idx -= MAX_QUEUE_POOL_SIZE;
+
+                       (*start_pos)++;
+               } else {
+                       idx = MAX_QUEUE_POOL_SIZE;
+               }
+       } else if ((q->type == 1) || (q->type == 2)) {
+               for (idx = (*start_pos); idx < MAX_QUEUE_POOL_SIZE; idx++) {
+                       if (q->pool[idx] != 0) {
+                               *start_pos = idx + 1;
+                               break;
+                       }
+               }
+       }
+       if (idx < MAX_QUEUE_POOL_SIZE) {
+               pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1;
+               di_buf_idx = q->pool[idx] & 0xff;
+               if (pool_idx < VFRAME_TYPE_NUM) {
+                       if (di_buf_idx < pbuf_pool[pool_idx].size)
+                               di_buf =
+                                       &(pbuf_pool[pool_idx].di_buf_ptr[
+                                                 di_buf_idx]);
+               }
+       }
+
+       if ((di_buf) && ((((pool_idx + 1) << 8) | di_buf_idx)
+                        != ((di_buf->type << 8) | (di_buf->index)))) {
+               PR_ERR("%s:(%x,%x)\n", __func__,
+                      (((pool_idx + 1) << 8) | di_buf_idx),
+                      ((di_buf->type << 8) | (di_buf->index)));
+               if (recovery_flag == 0) {
+                       recovery_log_reason = 1;
+                       recovery_log_queue_idx =
+                               (start_pos_init << 8) | queue_idx;
+                       recovery_log_di_buf = di_buf;
+               }
+               recovery_flag++;
+               di_buf = NULL;
+       }
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) {
+               if (di_buf)
+                       dim_print("%s: %x(%d,%d)\n", __func__, di_buf,
+                                 pool_idx, di_buf_idx);
+               else
+                       dim_print("%s: %x\n", __func__, di_buf);
+       }
+
+       return di_buf;
+}
+
+/*--------------------------*/
+u8 *dim_vmap(ulong addr, u32 size, bool *bflg)
+{
+       u8 *vaddr = NULL;
+       ulong phys = addr;
+       u32 offset = phys & ~PAGE_MASK;
+       u32 npages = PAGE_ALIGN(size) / PAGE_SIZE;
+       struct page **pages = NULL;
+       pgprot_t pgprot;
+       int i;
+
+       if (!PageHighMem(phys_to_page(phys)))
+               return phys_to_virt(phys);
+
+       if (offset)
+               npages++;
+
+       pages = vmalloc(sizeof(struct page *) * npages);
+       if (!pages)
+               return NULL;
+
+       for (i = 0; i < npages; i++) {
+               pages[i] = phys_to_page(phys);
+               phys += PAGE_SIZE;
+       }
+
+       /*nocache*/
+       pgprot = pgprot_writecombine(PAGE_KERNEL);
+
+       vaddr = vmap(pages, npages, VM_MAP, pgprot);
+       if (!vaddr) {
+               PR_ERR("the phy(%lx) vmaped fail, size: %d\n",
+                      addr - offset, npages << PAGE_SHIFT);
+               vfree(pages);
+               return NULL;
+       }
+
+       vfree(pages);
+#if 0
+       if (debug_mode & 0x20) {
+               dim_print("[HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n",
+                         __func__, addr, vaddr + offset,
+                         npages << PAGE_SHIFT);
+       }
+#endif
+       *bflg = true;
+
+       return vaddr + offset;
+}
+
+void dim_unmap_phyaddr(u8 *vaddr)
+{
+       void *addr = (void *)(PAGE_MASK & (ulong)vaddr);
+
+       vunmap(addr);
+}
+
+/*--------------------------*/
+ssize_t
+store_dump_mem(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t len)
+{
+       unsigned int n = 0, canvas_w = 0, canvas_h = 0;
+       unsigned long nr_size = 0, dump_adr = 0;
+       struct di_buf_s *di_buf = NULL;
+       struct vframe_s *post_vf = NULL;
+       char *buf_orig, *ps, *token;
+       char *parm[5] = { NULL };
+       char delim1[3] = " ";
+       char delim2[2] = "\n";
+       struct file *filp = NULL;
+       loff_t pos = 0;
+       void *buff = NULL;
+       mm_segment_t old_fs;
+       bool bflg_vmap = false;
+       unsigned int channel = get_current_channel();/* debug only*/
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+       /*ary add 2019-07-2 being*/
+       unsigned int indx;
+       struct di_buf_s *pbuf_post;
+       struct di_buf_s *pbuf_local;
+       struct di_post_stru_s *ppost;
+       struct di_mm_s *mm = dim_mm_get();/*mm-0705*/
+       /*************************/
+
+       buf_orig = kstrdup(buf, GFP_KERNEL);
+       ps = buf_orig;
+       strcat(delim1, delim2);
+       while (1) {
+               token = strsep(&ps, delim1);
+               if (!token)
+                       break;
+               if (*token == '\0')
+                       continue;
+               parm[n++] = token;
+       }
+       if (strcmp(parm[0], "capture") == 0) {
+               di_buf = ppre->di_mem_buf_dup_p;
+       } else if (strcmp(parm[0], "c_post") == 0) {
+               /*ary add 2019-07-2*/
+               if (kstrtouint(parm[2], 0, &channel)) {
+                       PR_ERR("c_post:ch is not number\n");
+                       kfree(buf_orig);
+                       return 0;
+               }
+               if (kstrtouint(parm[3], 0, &indx)) {
+                       PR_ERR("c_post:ch is not number\n");
+                       kfree(buf_orig);
+                       return 0;
+               }
+               di_pr_info("c_post:ch[%d],index[%d]\n", channel, indx);
+
+               ppre = get_pre_stru(channel);
+               ppost = get_post_stru(channel);
+               /*mm-0705       if (indx >= ppost->di_post_num) {*/
+               if (indx >= mm->sts.num_post) {
+                       PR_ERR("c_post:index is overflow:%d[%d]\n", indx,
+                              mm->sts.num_post);
+                       kfree(buf_orig);
+                       return 0;
+               }
+               pbuf_post = get_buf_post(channel);
+               di_buf = &pbuf_post[indx];
+       } else if (strcmp(parm[0], "c_local") == 0) {
+               /*ary add 2019-07-2*/
+               if (kstrtouint(parm[2], 0, &channel)) {
+                       PR_ERR("c_local:ch is not number\n");
+                       kfree(buf_orig);
+                       return 0;
+               }
+               if (kstrtouint(parm[3], 0, &indx)) {
+                       PR_ERR("c_local:ch is not number\n");
+                       kfree(buf_orig);
+                       return 0;
+               }
+               di_pr_info("c_local:ch[%d],index[%d]\n", channel, indx);
+
+               ppre = get_pre_stru(channel);
+               ppost = get_post_stru(channel);
+               #if 0
+               if (indx >= ppost->di_post_num) {
+                       PR_ERR("c_local:index is overflow:%d[%d]\n",
+                              indx, ppost->di_post_num);
+                       kfree(buf_orig);
+                       return 0;
+               }
+               #endif
+               pbuf_local = get_buf_local(channel);
+               di_buf = &pbuf_local[indx];
+       } else if (strcmp(parm[0], "capture_pready") == 0) {    /*ary add*/
+
+               if (!di_que_is_empty(channel, QUE_POST_READY)) {
+                       di_buf = di_que_peek(channel, QUE_POST_READY);
+                       pr_info("get post ready di_buf:%d:0x%p\n",
+                               di_buf->index, di_buf);
+               } else {
+                       pr_info("war:no post ready buf\n");
+               }
+       } else if (strcmp(parm[0], "capture_post") == 0) {
+               if (di_vf_l_peek(channel)) {
+                       post_vf = di_vf_l_get(channel);
+                       if (!IS_ERR_OR_NULL(post_vf)) {
+                               di_buf = post_vf->private_data;
+                               di_vf_l_put(post_vf, channel);
+                               pr_info("get post di_buf:%d:0x%p\n",
+                                       di_buf->index, di_buf);
+                       } else {
+                               pr_info("war:peek no post buf, vfm[0x%p]\n",
+                                       post_vf);
+                       }
+
+                       post_vf = NULL;
+               } else {
+                       pr_info("war:can't peek post buf\n");
+               }
+       } else if (strcmp(parm[0], "capture_nrds") == 0) {
+               dim_get_nr_ds_buf(&dump_adr, &nr_size);
+       } else {
+               PR_ERR("wrong dump cmd\n");
+               kfree(buf_orig);
+               return len;
+       }
+       if (nr_size == 0) {
+               if (unlikely(!di_buf)) {
+                       pr_info("war:di_buf is null\n");
+                       kfree(buf_orig);
+                       return len;
+               }
+               canvas_w = di_buf->canvas_width[NR_CANVAS];
+               canvas_h = di_buf->canvas_height;
+               nr_size = canvas_w * canvas_h * 2;
+               dump_adr = di_buf->nr_adr;
+
+               pr_info("w=%d,h=%d,size=%ld,addr=%lu\n",
+                       canvas_w, canvas_h, nr_size, dump_adr);
+       }
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       /* pr_dbg("dump path =%s\n",dump_path); */
+       filp = filp_open(parm[1], O_RDWR | O_CREAT, 0666);
+       if (IS_ERR(filp)) {
+               PR_ERR("create %s error.\n", parm[1]);
+               kfree(buf_orig);
+               return len;
+       }
+       dump_state_flag = 1;
+       if (de_devp->flags & DI_MAP_FLAG) {
+               /*buff = (void *)phys_to_virt(dump_adr);*/
+               buff = dim_vmap(dump_adr, nr_size, &bflg_vmap);
+               if (!buff) {
+                       if (nr_size <= 5222400) {
+                               pr_info("di_vap err\n");
+                               filp_close(filp, NULL);
+                               kfree(buf_orig);
+                               return len;
+
+                               /*try again:*/
+                               PR_INF("vap err,size to 5222400, try again\n");
+                               nr_size = 5222400;
+                               buff = dim_vmap(dump_adr, nr_size, &bflg_vmap);
+                               if (!buff) {
+                                       filp_close(filp, NULL);
+                                       kfree(buf_orig);
+                                       return len;
+                               }
+                       }
+               }
+       } else {
+               buff = ioremap(dump_adr, nr_size);
+       }
+       if (IS_ERR_OR_NULL(buff))
+               PR_ERR("%s: ioremap error.\n", __func__);
+       vfs_write(filp, buff, nr_size, &pos);
+/*     pr_dbg("di_chan2_buf_dup_p:\n   nr:%u,mtn:%u,cnt:%u\n",
+ * di_pre_stru.di_chan2_buf_dup_p->nr_adr,
+ * di_pre_stru.di_chan2_buf_dup_p->mtn_adr,
+ * di_pre_stru.di_chan2_buf_dup_p->cnt_adr);
+ * pr_dbg("di_inp_buf:\n       nr:%u,mtn:%u,cnt:%u\n",
+ * di_pre_stru.di_inp_buf->nr_adr,
+ * di_pre_stru.di_inp_buf->mtn_adr,
+ * di_pre_stru.di_inp_buf->cnt_adr);
+ * pr_dbg("di_wr_buf:\n        nr:%u,mtn:%u,cnt:%u\n",
+ * di_pre_stru.di_wr_buf->nr_adr,
+ * di_pre_stru.di_wr_buf->mtn_adr,
+ * di_pre_stru.di_wr_buf->cnt_adr);
+ * pr_dbg("di_mem_buf_dup_p:\n  nr:%u,mtn:%u,cnt:%u\n",
+ * di_pre_stru.di_mem_buf_dup_p->nr_adr,
+ * di_pre_stru.di_mem_buf_dup_p->mtn_adr,
+ * di_pre_stru.di_mem_buf_dup_p->cnt_adr);
+ * pr_dbg("di_mem_start=%u\n",di_mem_start);
+ */
+       vfs_fsync(filp, 0);
+       pr_info("write buffer 0x%lx  to %s.\n", dump_adr, parm[1]);
+       if (bflg_vmap)
+               dim_unmap_phyaddr(buff);
+
+       if (!(de_devp->flags & DI_MAP_FLAG))
+               iounmap(buff);
+       dump_state_flag = 0;
+       filp_close(filp, NULL);
+       set_fs(old_fs);
+       kfree(buf_orig);
+       return len;
+}
+
+static void recycle_vframe_type_pre(struct di_buf_s *di_buf,
+                                   unsigned int channel);
+static void recycle_vframe_type_post(struct di_buf_s *di_buf,
+                                    unsigned int channel);
+static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf,
+                                     unsigned int channel);
+#ifdef DI_BUFFER_DEBUG
+static void
+recycle_vframe_type_post_print(struct di_buf_s *di_buf,
+                              const char *func,
+                              const int line);
+#endif
+
+static void dis2_di(void)
+{
+       ulong flags = 0, irq_flag2 = 0;
+       unsigned int channel = get_current_channel();/* debug only*/
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       set_init_flag(channel, false);/*init_flag = 0;*/
+       di_lock_irqfiq_save(irq_flag2);
+/* vf_unreg_provider(&di_vf_prov); */
+       pw_vf_light_unreg_provider(channel);
+       di_unlock_irqfiq_restore(irq_flag2);
+       set_reg_flag(channel, false);
+       spin_lock_irqsave(&plist_lock, flags);
+       di_lock_irqfiq_save(irq_flag2);
+       if (ppre->di_inp_buf) {
+               if (pvframe_in[ppre->di_inp_buf->index]) {
+                       pw_vf_put(pvframe_in[ppre->di_inp_buf->index],
+                                 channel);
+                       pvframe_in[ppre->di_inp_buf->index] = NULL;
+                       pw_vf_notify_provider(channel,
+                               VFRAME_EVENT_RECEIVER_PUT, NULL);
+               }
+               ppre->di_inp_buf->invert_top_bot_flag = 0;
+
+               di_que_in(channel, QUE_IN_FREE, ppre->di_inp_buf);
+               ppre->di_inp_buf = NULL;
+       }
+       dim_uninit_buf(0, channel);
+       if (get_blackout_policy()) {
+               dim_DI_Wr(DI_CLKG_CTRL, 0x2);
+               if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) {
+                       dimh_enable_di_post_mif(GATE_OFF);
+                       dim_post_gate_control(false);
+                       dim_top_gate_control(false, false);
+               }
+       }
+
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support))
+               dim_set_power_control(0);
+
+       di_unlock_irqfiq_restore(irq_flag2);
+       spin_unlock_irqrestore(&plist_lock, flags);
+}
+
+ssize_t
+store_config(struct device *dev,
+            struct device_attribute *attr,
+            const char *buf, size_t count)
+{
+       int rc = 0;
+       char *parm[2] = { NULL }, *buf_orig;
+       unsigned int channel = get_current_channel();/* debug only*/
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       buf_orig = kstrdup(buf, GFP_KERNEL);
+       dim_parse_cmd_params(buf_orig, (char **)(&parm));
+
+       if (strncmp(buf, "disable", 7) == 0) {
+               dim_print("%s: disable\n", __func__);
+
+               if (get_init_flag(channel)) {/*if (init_flag) {*/
+                       ppre->disable_req_flag = 1;
+
+                       while (ppre->disable_req_flag)
+                               usleep_range(1000, 1001);
+               }
+       } else if (strncmp(buf, "dis2", 4) == 0) {
+               dis2_di();
+       } else if (strcmp(parm[0], "hold_video") == 0) {
+               pr_info("%s(%s %s)\n", __func__, parm[0], parm[1]);
+               rc = kstrtouint(parm[1], 10, &hold_video);
+       }
+       kfree(buf_orig);
+       return count;
+}
+
+static unsigned char is_progressive(vframe_t *vframe)
+{
+       unsigned char ret = 0;
+
+       ret = ((vframe->type & VIDTYPE_TYPEMASK) == VIDTYPE_PROGRESSIVE);
+       return ret;
+}
+
+static unsigned char is_source_change(vframe_t *vframe, unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+#define VFRAME_FORMAT_MASK      \
+       (VIDTYPE_VIU_422 | VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_444 | \
+        VIDTYPE_MVC)
+       if ((ppre->cur_width != vframe->width)                  ||
+           (ppre->cur_height != vframe->height)                ||
+           (((ppre->cur_inp_type & VFRAME_FORMAT_MASK)         !=
+           (vframe->type & VFRAME_FORMAT_MASK))                &&
+           (!is_handle_prog_frame_as_interlace(vframe)))       ||
+           (ppre->cur_source_type != vframe->source_type)) {
+               /* video format changed */
+               return 1;
+       } else if (((ppre->cur_prog_flag != is_progressive(vframe)) &&
+                  (!is_handle_prog_frame_as_interlace(vframe))) ||
+                  ((ppre->cur_inp_type & VIDTYPE_VIU_FIELD) !=
+                  (vframe->type & VIDTYPE_VIU_FIELD))
+       ) {
+               /* just scan mode changed */
+               if (!ppre->force_interlace)
+                       pr_dbg("DI I<->P.\n");
+               return 2;
+       }
+       return 0;
+}
+
+/*
+ * static unsigned char is_vframe_type_change(vframe_t* vframe)
+ * {
+ * if(
+ * (di_pre_stru.cur_prog_flag!=is_progressive(vframe))||
+ * ((di_pre_stru.cur_inp_type&VFRAME_FORMAT_MASK)!=
+ * (vframe->type&VFRAME_FORMAT_MASK))
+ * )
+ * return 1;
+ *
+ * return 0;
+ * }
+ */
+static int trick_mode;
+
+unsigned char dim_is_bypass(vframe_t *vf_in, unsigned int channel)
+{
+       unsigned int vtype = 0;
+       int ret = 0;
+       static vframe_t vf_tmp;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (dimp_get(eDI_MP_di_debug_flag) & 0x10000) /* for debugging */
+               return (dimp_get(eDI_MP_di_debug_flag) >> 17) & 0x1;
+
+       if (di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL))
+               return 1;
+       if (ppre->cur_prog_flag         &&
+           ((ppre->cur_width > 1920)   ||
+           (ppre->cur_height > 1080)   ||
+           (ppre->cur_inp_type & VIDTYPE_VIU_444))
+           )
+               return 1;
+
+       if ((ppre->cur_width < 16) || (ppre->cur_height < 16))
+               return 1;
+
+       if (ppre->cur_inp_type & VIDTYPE_MVC)
+               return 1;
+
+       if (ppre->cur_source_type == VFRAME_SOURCE_TYPE_PPMGR)
+               return 1;
+
+       if (dimp_get(eDI_MP_bypass_trick_mode)) {
+               int trick_mode_fffb = 0;
+               int trick_mode_i = 0;
+
+               if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1)
+                       query_video_status(0, &trick_mode_fffb);
+               if (dimp_get(eDI_MP_bypass_trick_mode) & 0x2)
+                       query_video_status(1, &trick_mode_i);
+               trick_mode = trick_mode_fffb | (trick_mode_i << 1);
+               if (trick_mode)
+                       return 1;
+       }
+
+       if (dimp_get(eDI_MP_bypass_3d)  &&
+           (ppre->source_trans_fmt != 0))
+               return 1;
+
+/*prot is conflict with di post*/
+       if (vf_in && vf_in->video_angle)
+               return 1;
+       if (vf_in && (vf_in->type & VIDTYPE_PIC))
+               return 1;
+#if 0
+       if (vf_in && (vf_in->type & VIDTYPE_COMPRESS))
+               return 1;
+#endif
+       if ((dimp_get(eDI_MP_di_vscale_skip_enable) & 0x4) &&
+           vf_in && !dimp_get(eDI_MP_post_wr_en)) {
+               /*--------------------------*/
+               if (vf_in->type & VIDTYPE_COMPRESS) {
+                       vf_tmp.width = vf_in->compWidth;
+                       vf_tmp.height = vf_in->compHeight;
+                       if (vf_tmp.width > 1920 || vf_tmp.height > 1088)
+                               return 1;
+               }
+               /*--------------------------*/
+               /*backup vtype,set type as progressive*/
+               vtype = vf_in->type;
+               vf_in->type &= (~VIDTYPE_TYPEMASK);
+               vf_in->type &= (~VIDTYPE_VIU_NV21);
+               vf_in->type |= VIDTYPE_VIU_SINGLE_PLANE;
+               vf_in->type |= VIDTYPE_VIU_FIELD;
+               vf_in->type |= VIDTYPE_PRE_INTERLACE;
+               vf_in->type |= VIDTYPE_VIU_422;
+               ret = ext_ops.get_current_vscale_skip_count(vf_in);
+               /*di_vscale_skip_count = (ret&0xff);*/
+               dimp_set(eDI_MP_di_vscale_skip_count, ret & 0xff);
+               /*vpp_3d_mode = ((ret>>8)&0xff);*/
+               dimp_set(eDI_MP_vpp_3d_mode, ((ret >> 8) & 0xff));
+               vf_in->type = vtype;
+               if (dimp_get(eDI_MP_di_vscale_skip_count) > 0 ||
+                   (dimp_get(eDI_MP_vpp_3d_mode)
+                       #ifdef DET3D
+                       && (!dimp_get(eDI_MP_det3d_en))
+                       #endif
+                       )
+                       )
+                       return 1;
+       }
+
+       return 0;
+}
+
+static bool need_bypass(struct vframe_s *vf);
+
+/**********************************
+ *diff with  dim_is_bypass
+ *     delet di_vscale_skip_enable
+ *     use vf_in replace ppre
+ **********************************/
+bool is_bypass2(struct vframe_s *vf_in, unsigned int ch)
+{
+       /*check debug info*/
+       if (dimp_get(eDI_MP_di_debug_flag) & 0x10000) /* for debugging */
+               return true;
+
+       if (di_cfgx_get(ch, eDI_CFGX_BYPASS_ALL))       /*bypass_all*/
+               return true;
+
+       if (dimp_get(eDI_MP_bypass_trick_mode)) {
+               int trick_mode_fffb = 0;
+               int trick_mode_i = 0;
+
+               if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1)
+                       query_video_status(0, &trick_mode_fffb);
+               if (dimp_get(eDI_MP_bypass_trick_mode) & 0x2)
+                       query_video_status(1, &trick_mode_i);
+               trick_mode = trick_mode_fffb | (trick_mode_i << 1);
+               if (trick_mode)
+                       return true;
+       }
+       /* check vframe */
+       if (!vf_in)
+               return false;
+
+       if (need_bypass(vf_in))
+               return true;
+
+       if ((vf_in->width < 16) || (vf_in->height < 16))
+               return true;
+
+       if (dimp_get(eDI_MP_bypass_3d)  &&
+           (vf_in->trans_fmt != 0))
+               return true;
+
+/*prot is conflict with di post*/
+       if (vf_in->video_angle)
+               return true;
+
+       return false;
+}
+
+static unsigned char is_bypass_post(unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (dimp_get(eDI_MP_di_debug_flag) & 0x40000) /* for debugging */
+               return (dimp_get(eDI_MP_di_debug_flag) >> 19) & 0x1;
+
+       /*prot is conflict with di post*/
+       if (ppre->orientation)
+               return 1;
+       if (dimp_get(eDI_MP_bypass_post))
+               return 1;
+
+#ifdef DET3D
+       if (ppre->vframe_interleave_flag != 0)
+               return 1;
+
+#endif
+       return 0;
+}
+
+#ifdef RUN_DI_PROCESS_IN_IRQ
+static unsigned char is_input2pre(void, unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (input2pre           &&
+           ppre->cur_prog_flag &&
+           ppre->vdin_source   &&
+           (di_bypass_state_get(channel) == 0))
+               return 1;
+
+       return 0;
+}
+#endif
+
+#ifdef DI_USE_FIXED_CANVAS_IDX
+static int di_post_idx[2][6];
+static int di_pre_idx[2][10];
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+static unsigned int di_inp_idx[3];
+#else
+static int di_wr_idx;
+#endif
+
+int dim_get_canvas(void)
+{
+       unsigned int pre_num = 7, post_num = 6;
+       struct di_dev_s  *de_devp = get_dim_de_devp();
+
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               /* mem/chan2/nr/mtn/contrd/contrd2/
+                * contw/mcinfrd/mcinfow/mcvecw
+                */
+               pre_num = 10;
+               /* buf0/buf1/buf2/mtnp/mcvec */
+               post_num = 6;
+       }
+       if (ext_ops.canvas_pool_alloc_canvas_table("di_pre",
+                                                  &di_pre_idx[0][0],
+                                                  pre_num,
+                                                  CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s allocate di pre canvas error.\n", __func__);
+               return 1;
+       }
+       if (di_pre_rdma_enable) {
+               if (ext_ops.canvas_pool_alloc_canvas_table("di_pre",
+                                                          &di_pre_idx[1][0],
+                                                          pre_num,
+                                                  CANVAS_MAP_TYPE_1)) {
+                       PR_ERR("%s allocate di pre canvas error.\n", __func__);
+                       return 1;
+               }
+       } else {
+               #if 0
+               for (i = 0; i < pre_num; i++)
+                       di_pre_idx[1][i] = di_pre_idx[0][i];
+               #else
+               memcpy(&di_pre_idx[1][0],
+                      &di_pre_idx[0][0], sizeof(int) * pre_num);
+               #endif
+       }
+       if (ext_ops.canvas_pool_alloc_canvas_table("di_post",
+                                                  &di_post_idx[0][0],
+                                                  post_num,
+                                                  CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s allocate di post canvas error.\n", __func__);
+               return 1;
+       }
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+       if (ext_ops.canvas_pool_alloc_canvas_table("di_post",
+                                                  &di_post_idx[1][0],
+                                                  post_num,
+                                                  CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s allocate di post canvas error.\n", __func__);
+               return 1;
+       }
+#else
+       for (i = 0; i < post_num; i++)
+               di_post_idx[1][i] = di_post_idx[0][i];
+#endif
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+       if (ext_ops.canvas_pool_alloc_canvas_table("di_inp", &di_inp_idx[0], 3,
+                                                  CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s allocat di inp canvas error.\n", __func__);
+               return 1;
+       }
+       pr_info("DI: support multi decoding %u~%u~%u.\n",
+               di_inp_idx[0], di_inp_idx[1], di_inp_idx[2]);
+#endif
+       if (de_devp->post_wr_support == 0)
+               return 0;
+
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+       if (ext_ops.canvas_pool_alloc_canvas_table("di_wr",
+                                                  &di_wr_idx, 1,
+                                                  CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s allocat di write back canvas error.\n",
+                      __func__);
+               return 1;
+       }
+       pr_info("DI: support post write back %u.\n", di_wr_idx);
+#endif
+       return 0;
+}
+
+static void config_canvas_idx(struct di_buf_s *di_buf, int nr_canvas_idx,
+                             int mtn_canvas_idx)
+{
+       unsigned int height = 0;
+
+       if (!di_buf)
+               return;
+       if (di_buf->canvas_config_flag == 1) {
+               if (nr_canvas_idx >= 0) {
+                       /* linked two interlace buffer should double height*/
+                       if (di_buf->di_wr_linked_buf)
+                               height = (di_buf->canvas_height << 1);
+                       else
+                               height =  di_buf->canvas_height;
+                       di_buf->nr_canvas_idx = nr_canvas_idx;
+                       canvas_config(nr_canvas_idx, di_buf->nr_adr,
+                                     di_buf->canvas_width[NR_CANVAS],
+                                     height, 0, 0);
+               }
+       } else if (di_buf->canvas_config_flag == 2) {
+               if (nr_canvas_idx >= 0) {
+                       di_buf->nr_canvas_idx = nr_canvas_idx;
+                       canvas_config(nr_canvas_idx, di_buf->nr_adr,
+                                     di_buf->canvas_width[NR_CANVAS],
+                                     di_buf->canvas_height, 0, 0);
+               }
+               if (mtn_canvas_idx >= 0) {
+                       di_buf->mtn_canvas_idx = mtn_canvas_idx;
+                       canvas_config(mtn_canvas_idx, di_buf->mtn_adr,
+                                     di_buf->canvas_width[MTN_CANVAS],
+                                     di_buf->canvas_height, 0, 0);
+               }
+       }
+       if (nr_canvas_idx >= 0) {
+               di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx;
+               di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx;
+       }
+}
+
+static void config_cnt_canvas_idx(struct di_buf_s *di_buf,
+                                 unsigned int cnt_canvas_idx)
+{
+       if (!di_buf)
+               return;
+
+       di_buf->cnt_canvas_idx = cnt_canvas_idx;
+       canvas_config(cnt_canvas_idx, di_buf->cnt_adr,
+                     di_buf->canvas_width[MTN_CANVAS],
+                     di_buf->canvas_height, 0, 0);
+}
+
+static void config_mcinfo_canvas_idx(struct di_buf_s *di_buf,
+                                    int mcinfo_canvas_idx)
+{
+       if (!di_buf)
+               return;
+
+       di_buf->mcinfo_canvas_idx = mcinfo_canvas_idx;
+       canvas_config(mcinfo_canvas_idx,
+                     di_buf->mcinfo_adr,
+                     di_buf->canvas_height_mc, 2, 0, 0);
+}
+
+static void config_mcvec_canvas_idx(struct di_buf_s *di_buf,
+                                   int mcvec_canvas_idx)
+{
+       if (!di_buf)
+               return;
+
+       di_buf->mcvec_canvas_idx = mcvec_canvas_idx;
+       canvas_config(mcvec_canvas_idx,
+                     di_buf->mcvec_adr,
+                     di_buf->canvas_width[MV_CANVAS],
+                     di_buf->canvas_height, 0, 0);
+}
+
+#else
+
+static void config_canvas(struct di_buf_s *di_buf)
+{
+       unsigned int height = 0;
+
+       if (!di_buf)
+               return;
+
+       if (di_buf->canvas_config_flag == 1) {
+               /* linked two interlace buffer should double height*/
+               if (di_buf->di_wr_linked_buf)
+                       height = (di_buf->canvas_height << 1);
+               else
+                       height =  di_buf->canvas_height;
+               canvas_config(di_buf->nr_canvas_idx, di_buf->nr_adr,
+                             di_buf->canvas_width[NR_CANVAS], height, 0, 0);
+               di_buf->canvas_config_flag = 0;
+       } else if (di_buf->canvas_config_flag == 2) {
+               canvas_config(di_buf->nr_canvas_idx, di_buf->nr_adr,
+                             di_buf->canvas_width[MV_CANVAS],
+                             di_buf->canvas_height, 0, 0);
+               canvas_config(di_buf->mtn_canvas_idx, di_buf->mtn_adr,
+                             di_buf->canvas_width[MTN_CANVAS],
+                             di_buf->canvas_height, 0, 0);
+               di_buf->canvas_config_flag = 0;
+       }
+}
+
+#endif
+
+#ifdef CONFIG_CMA
+/**********************************************************
+ * ./include/linux/amlogic/media/codec_mm/codec_mm.h:
+ *     unsigned long codec_mm_alloc_for_dma(const char *owner,
+ *                                     int page_cnt,
+ *                                     int align2n,
+ *                                     int memflags);
+ *     int codec_mm_free_for_dma(const char *owner,
+ *                             unsigned long phy_addr);
+ *     void *codec_mm_phys_to_virt(unsigned long phy_addr);
+ ***********************************************************/
+
+#define TVP_MEM_PAGES  0xffff
+/**********************************************************
+ * alloc mm from codec mm
+ * o: out:
+ * return:
+ *     true: seccuss
+ *     false: failed
+ ***********************************************************/
+static bool mm_codec_alloc(const char *owner, size_t count,
+                          int cma_mode,
+                          struct dim_mm_s *o)
+{
+       int flags = 0;
+       bool istvp = false;
+
+       if (codec_mm_video_tvp_enabled()) {
+               istvp = true;
+               flags |= CODEC_MM_FLAGS_TVP;
+       } else {
+               flags |= CODEC_MM_FLAGS_RESERVED | CODEC_MM_FLAGS_CPU;
+       }
+
+       if (cma_mode == 4 && !istvp)
+               flags = CODEC_MM_FLAGS_CMA_FIRST |
+                       CODEC_MM_FLAGS_CPU;
+
+       o->addr = codec_mm_alloc_for_dma(owner,
+                                       count,
+                                       0,
+                                       flags);
+
+       if (o->addr == 0) {
+               /*failed*/
+               PR_ERR("%s: failed\n", __func__);
+               return false;
+       }
+
+       if (istvp)
+               o->ppage = (struct page *)TVP_MEM_PAGES;
+       else
+               o->ppage = codec_mm_phys_to_virt(o->addr);
+
+       /*PR_INF("%s:page:0x%p,add:0x%lx\n", __func__, o->ppage, o->addr);*/
+       return true;
+}
+
+/**********************************************************
+ *     ./include/linux/dma-contiguous.h:
+ * struct page *dma_alloc_from_contiguous(struct device *dev,
+ *                                     size_t count,
+ *                                     unsigned int order);
+ * bool dma_release_from_contiguous(struct device *dev,
+ *                                     struct page *pages,
+ *                                     int count);
+ *
+ ***********************************************************/
+
+/**********************************************************
+ * alloc mm by cma
+ * o: out:
+ * return:
+ *     true: seccuss
+ *     false: failed
+ ***********************************************************/
+static bool mm_cma_alloc(struct device *dev, size_t count,
+                        struct dim_mm_s *o)
+{
+       o->ppage = dma_alloc_from_contiguous(dev, count, 0);
+       if (o->ppage) {
+               o->addr = page_to_phys(o->ppage);
+               return true;
+       }
+       PR_ERR("%s: failed\n", __func__);
+       return false;
+}
+
+bool dim_mm_alloc(int cma_mode, size_t count, struct dim_mm_s *o)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       bool ret;
+
+       if (cma_mode == 3 || cma_mode == 4)
+               ret = mm_codec_alloc(DEVICE_NAME,
+                                    count,
+                                    cma_mode,
+                                    o);
+       else
+               ret = mm_cma_alloc(&de_devp->pdev->dev, count, o);
+
+       return ret;
+}
+
+bool dim_mm_release(int cma_mode,
+                   struct page *pages,
+                   int count,
+                   unsigned long addr)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       bool ret = true;
+
+       if (cma_mode == 3 || cma_mode == 4)
+               codec_mm_free_for_dma(DEVICE_NAME, addr);
+       else
+               ret = dma_release_from_contiguous(&de_devp->pdev->dev,
+                                                 pages,
+                                                 count);
+       return ret;
+}
+
+/***********************************************************/
+unsigned int dim_cma_alloc_total(struct di_dev_s *de_devp)
+{
+       /*struct di_dev_s *de_devp = get_dim_de_devp();*/
+       /*****************************************************/
+       struct dim_mm_s omm;
+       bool ret;
+
+       ret = dim_mm_alloc(de_devp->flag_cma,
+                          de_devp->mem_size >> PAGE_SHIFT, &omm);
+
+       if (!ret) /*failed*/
+               return 0;
+
+       de_devp->total_pages = omm.ppage;
+       de_devp->mem_start = omm.addr;
+
+       if (de_devp->flag_cma != 0 && de_devp->nrds_enable) {
+               dim_nr_ds_buf_init(de_devp->flag_cma, 0,
+                                  &de_devp->pdev->dev);
+       }
+
+       return 1;
+}
+
+static unsigned int di_cma_alloc(struct di_dev_s *devp, unsigned int channel)
+{
+       unsigned int start_time, end_time, delta_time;
+       struct di_buf_s *buf_p = NULL;
+       int itmp, alloc_cnt = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/
+       unsigned int psize; /*new que*/
+       struct di_mm_s *mm = dim_mm_get();/*mm-0705*/
+
+       bool aret;
+       struct dim_mm_s omm;
+
+       start_time = jiffies_to_msecs(jiffies);
+       queue_for_each_entry(buf_p, channel, QUEUE_LOCAL_FREE, list) {
+               if (buf_p->pages) {
+                       PR_ERR("1:%s:buf[%d] page:0x%p alloced skip\n",
+                              __func__, buf_p->index, buf_p->pages);
+                       continue;
+               }
+
+               aret = dim_mm_alloc(devp->flag_cma,
+                       devp->buffer_size >> PAGE_SHIFT,
+                       &omm);
+
+               if (!aret) {
+                       buf_p->pages = NULL;
+                       PR_ERR("2:%s: alloc failed %d fail.\n",
+                              __func__, buf_p->index);
+                       return 0;
+               }
+
+               buf_p->pages = omm.ppage;
+               buf_p->nr_adr = omm.addr;
+               alloc_cnt++;
+               mm->sts.num_local++;
+               if (dimp_get(eDI_MP_cma_print))
+                       PR_INF("CMA  allocate buf[%d]page:0x%p\n",
+                              buf_p->index, buf_p->pages);
+
+               if (dimp_get(eDI_MP_cma_print))
+                       pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr);
+               if (ppre->buf_alloc_mode == 0) {
+                       buf_p->mtn_adr = buf_p->nr_adr +
+                               ppre->nr_size;
+                       buf_p->cnt_adr = buf_p->nr_adr +
+                               ppre->nr_size +
+                               ppre->mtn_size;
+                       if (mc_mem_alloc) {
+                               buf_p->mcvec_adr = buf_p->nr_adr +
+                                       ppre->nr_size +
+                                       ppre->mtn_size +
+                                       ppre->count_size;
+                               buf_p->mcinfo_adr =
+                                       buf_p->nr_adr +
+                                       ppre->nr_size +
+                                       ppre->mtn_size +
+                                       ppre->count_size +
+                                       ppre->mv_size;
+                       }
+               }
+       }
+       PR_INF("%s:num_local[%d]\n", __func__, mm->sts.num_local);
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) {
+               di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize);
+
+               for (itmp = 0; itmp < psize; itmp++) {
+                       buf_p = pw_qindex_2_buf(channel, tmpa[itmp]);
+
+                       if (buf_p->pages) {
+                               PR_ERR("3:%s:buf[%d] page:0x%p skip\n",
+                                      __func__,
+                                      buf_p->index, buf_p->pages);
+                               continue;
+                       }
+
+                       aret = dim_mm_alloc(devp->flag_cma,
+                                       devp->post_buffer_size >> PAGE_SHIFT,
+                                       &omm);
+
+                       if (!aret) {
+                               buf_p->pages = NULL;
+                               PR_ERR("4:%s: alloc failed %d fail.\n",
+                                      __func__, buf_p->index);
+                               return 0;
+                       }
+
+                       buf_p->pages = omm.ppage;
+                       buf_p->nr_adr = omm.addr;
+                       mm->sts.num_post++;
+                       alloc_cnt++;
+                       if (dimp_get(eDI_MP_cma_print))
+                               PR_INF("%s:pbuf[%d]page:0x%p\n",
+                                      __func__,
+                                      buf_p->index, buf_p->pages);
+                       if (dimp_get(eDI_MP_cma_print))
+                               pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr);
+               }
+               PR_INF("%s:num_pst[%d]\n", __func__, mm->sts.num_post);
+       }
+       if (de_devp->flag_cma != 0 && de_devp->nrds_enable) {
+               dim_nr_ds_buf_init(de_devp->flag_cma, 0,
+                                  &de_devp->pdev->dev);
+       }
+
+       end_time = jiffies_to_msecs(jiffies);
+       delta_time = end_time - start_time;
+       pr_info("%s:alloc %u buffer use %u ms(%u~%u)\n",
+               __func__, alloc_cnt, delta_time, start_time, end_time);
+       return 1;
+}
+
+static void di_cma_release(struct di_dev_s *devp, unsigned int channel)
+{
+       unsigned int i, ii, rels_cnt = 0, start_time, end_time, delta_time;
+       struct di_buf_s *buf_p;
+       struct di_buf_s *pbuf_local = get_buf_local(channel);
+       struct di_buf_s *pbuf_post = get_buf_post(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       bool ret;
+       struct di_mm_s *mm = dim_mm_get();
+
+       start_time = jiffies_to_msecs(jiffies);
+       for (i = 0; (i < mm->cfg.num_local); i++) {
+               buf_p = &pbuf_local[i];
+               ii = USED_LOCAL_BUF_MAX;
+
+               if ((ii >= USED_LOCAL_BUF_MAX) &&
+                   buf_p->pages) {
+                       ret = dim_mm_release(devp->flag_cma, buf_p->pages,
+                                            devp->buffer_size >> PAGE_SHIFT,
+                                            buf_p->nr_adr);
+                       if (ret) {
+                               buf_p->pages = NULL;
+                               mm->sts.num_local--;
+                               rels_cnt++;
+                               if (dimp_get(eDI_MP_cma_print))
+                                       pr_info(
+                                       "DI release buf[%d] ok.\n", i);
+                       } else {
+                               PR_ERR("%s:release buf[%d] fail.\n",
+                                      __func__, i);
+                       }
+               } else {
+                       if (!IS_ERR_OR_NULL(buf_p->pages)       &&
+                           dimp_get(eDI_MP_cma_print)) {
+                               pr_info("DI buf[%d] page:0x%p no release.\n",
+                                       buf_p->index, buf_p->pages);
+                       }
+               }
+       }
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) {
+               /*mm-0705 for (i = 0; i < ppost->di_post_num; i++) {*/
+               for (i = 0; i < mm->cfg.num_post; i++) {
+                       buf_p = &pbuf_post[i];
+                       if (ppost->keep_buf_post        &&
+                           i == ppost->keep_buf_post->index)
+                               continue;
+
+                       if (!buf_p->pages) {
+                               PR_ERR("2:%s:post buf[%d] is null\n",
+                                      __func__, i);
+                               continue;
+                       }
+
+                       ret = dim_mm_release(devp->flag_cma,
+                                            buf_p->pages,
+                                    devp->post_buffer_size >> PAGE_SHIFT,
+                                            buf_p->nr_adr);
+                       if (ret) {
+                               buf_p->pages = NULL;
+                               mm->sts.num_post--;
+                               rels_cnt++;
+                               if (dimp_get(eDI_MP_cma_print))
+                                       pr_info(
+                                       "DI release post buf[%d] ok.\n", i);
+                       } else {
+                               PR_ERR("%s:release post buf[%d] fail\n",
+                                      __func__, i);
+                       }
+               }
+       }
+       if (de_devp->nrds_enable) {
+               dim_nr_ds_buf_uninit(de_devp->flag_cma,
+                                    &de_devp->pdev->dev);
+       }
+       if (mm->sts.num_local < 0 || mm->sts.num_post < 0)
+               PR_ERR("%s:mm:nub_local=%d,nub_post=%d\n",
+                      __func__,
+                      mm->sts.num_local,
+                      mm->sts.num_post);
+       end_time = jiffies_to_msecs(jiffies);
+       delta_time = end_time - start_time;
+       pr_info("%s:release %u buffer use %u ms(%u~%u)\n",
+               __func__, rels_cnt, delta_time, start_time, end_time);
+}
+#endif
+
+bool dim_cma_top_alloc(unsigned int ch)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       bool ret = false;
+
+#ifdef CONFIG_CMA
+
+       if (di_cma_alloc(de_devp, ch))
+               ret = true;
+#endif
+       return ret;
+}
+
+bool dim_cma_top_release(unsigned int ch)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+#ifdef CONFIG_CMA
+       di_cma_release(de_devp, ch);
+
+#endif
+       return true;
+}
+
+/*******************************************
+ *
+ *
+ ******************************************/
+#define DI_KEEP_BUF_SIZE 3
+static struct di_buf_s *di_keep_buf[DI_KEEP_BUF_SIZE];
+static int di_keep_point;
+
+void keep_buf_clear(void)
+{
+       int i;
+
+       for (i = 0; i < DI_KEEP_BUF_SIZE; i++)
+               di_keep_buf[i] = NULL;
+
+       di_keep_point = -1;
+}
+
+void keep_buf_in(struct di_buf_s *ready_buf)
+{
+       di_keep_point++;
+       if (di_keep_point >= DI_KEEP_BUF_SIZE)
+               di_keep_point = 0;
+       di_keep_buf[di_keep_point] = ready_buf;
+}
+
+void keep_buf_in_full(struct di_buf_s *ready_buf)
+{
+       int i;
+
+       keep_buf_in(ready_buf);
+       for (i = 0; i < DI_KEEP_BUF_SIZE; i++) {
+               if (!di_keep_buf[i])
+                       di_keep_buf[i] = ready_buf;
+       }
+}
+
+int di_cnt_buf(int width, int height, int prog_flag, int mc_mm,
+              int bit10_support, int pack422)
+{
+       int canvas_height = height + 8;
+       unsigned int di_buf_size = 0, di_post_buf_size = 0, mtn_size = 0;
+       unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0;
+       unsigned int nr_width = width, mtn_width = width, mv_width = width;
+       unsigned int nr_canvas_width = width, mtn_canvas_width = width;
+       unsigned int mv_canvas_width = width, canvas_align_width = 32;
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               canvas_align_width = 64;
+
+       if (dimp_get(eDI_MP_nr10bit_support)) {
+               if (dimp_get(eDI_MP_full_422_pack))
+                       nr_width = (width * 5) / 4;
+               else
+                       nr_width = (width * 3) / 2;
+       } else {
+               nr_width = width;
+       }
+       /* make sure canvas width must be divided by 256bit|32byte align */
+       nr_canvas_width = nr_width << 1;
+       mtn_canvas_width = mtn_width >> 1;
+       mv_canvas_width = (mv_width << 1) / 5;
+       nr_canvas_width = roundup(nr_canvas_width, canvas_align_width);
+       mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width);
+       mv_canvas_width = roundup(mv_canvas_width, canvas_align_width);
+       nr_width = nr_canvas_width >> 1;
+       mtn_width = mtn_canvas_width << 1;
+       mv_width = (mv_canvas_width * 5) >> 1;
+
+       if (prog_flag) {
+               di_buf_size = nr_width * canvas_height * 2;
+               di_buf_size = roundup(di_buf_size, PAGE_SIZE);
+
+       } else {
+               /*pr_info("canvas_height=%d\n", canvas_height);*/
+
+               /*nr_size(bits)=w*active_h*8*2(yuv422)
+                * mtn(bits)=w*active_h*4
+                * cont(bits)=w*active_h*4 mv(bits)=w*active_h/5*16
+                * mcinfo(bits)=active_h*16
+                */
+               nr_size = (nr_width * canvas_height) * 8 * 2 / 16;
+               mtn_size = (mtn_width * canvas_height) * 4 / 16;
+               count_size = (mtn_width * canvas_height) * 4 / 16;
+               mv_size = (mv_width * canvas_height) / 5;
+               /*mc_size = canvas_height;*/
+               mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1;
+               if (mc_mm) {
+                       di_buf_size = nr_size + mtn_size + count_size +
+                               mv_size + mc_size;
+               } else {
+                       di_buf_size = nr_size + mtn_size + count_size;
+               }
+               di_buf_size = roundup(di_buf_size, PAGE_SIZE);
+       }
+
+       PR_INF("size:0x%x\n", di_buf_size);
+       PR_INF("\t%-15s:0x%x\n", "nr_size", nr_size);
+       PR_INF("\t%-15s:0x%x\n", "count", count_size);
+       PR_INF("\t%-15s:0x%x\n", "mtn", mtn_size);
+       PR_INF("\t%-15s:0x%x\n", "mv", mv_size);
+       PR_INF("\t%-15s:0x%x\n", "mcinfo", mc_size);
+
+       di_post_buf_size = nr_width * canvas_height * 2;
+       /*PR_INF("size:post:0x%x\n", di_post_buf_size);*/
+       di_post_buf_size = roundup(di_post_buf_size, PAGE_SIZE);
+       PR_INF("size:post:0x%x\n", di_post_buf_size);
+
+       return 0;
+}
+
+static int di_init_buf(int width, int height, unsigned char prog_flag,
+                      unsigned int channel)
+{
+       int i;
+       int canvas_height = height + 8;
+       struct page *tmp_page = NULL;
+       unsigned int di_buf_size = 0, di_post_buf_size = 0, mtn_size = 0;
+       unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0;
+       unsigned int nr_width = width, mtn_width = width, mv_width = width;
+       unsigned int nr_canvas_width = width, mtn_canvas_width = width;
+       unsigned int mv_canvas_width = width, canvas_align_width = 32;
+       unsigned long di_post_mem = 0, nrds_mem = 0;
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel);
+       struct vframe_s *pvframe_local = get_vframe_local(channel);
+       struct vframe_s *pvframe_post = get_vframe_post(channel);
+       struct di_buf_s *pbuf_local = get_buf_local(channel);
+       struct di_buf_s *pbuf_in = get_buf_in(channel);
+       struct di_buf_s *pbuf_post = get_buf_post(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_buf_s *keep_buf = ppost->keep_buf;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       struct di_buf_s *keep_buf_post = ppost->keep_buf_post;
+       struct di_mm_s *mm = dim_mm_get(); /*mm-0705*/
+
+       unsigned int mem_st_local;
+
+       /**********************************************/
+       /* count buf info */
+       /**********************************************/
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               canvas_align_width = 64;
+
+       pr_info("%s:begin\n", __func__);
+       frame_count = 0;
+       disp_frame_count = 0;
+       cur_post_ready_di_buf = NULL;
+       /* decoder'buffer had been releae no need put */
+       for (i = 0; i < MAX_IN_BUF_NUM; i++)
+               pvframe_in[i] = NULL;
+       /*pre init*/
+       memset(ppre, 0, sizeof(struct di_pre_stru_s));
+
+       if (dimp_get(eDI_MP_nr10bit_support)) {
+               if (dimp_get(eDI_MP_full_422_pack))
+                       nr_width = (width * 5) / 4;
+               else
+                       nr_width = (width * 3) / 2;
+       } else {
+               nr_width = width;
+       }
+       /* make sure canvas width must be divided by 256bit|32byte align */
+       nr_canvas_width = nr_width << 1;
+       mtn_canvas_width = mtn_width >> 1;
+       mv_canvas_width = (mv_width << 1) / 5;
+       nr_canvas_width = roundup(nr_canvas_width, canvas_align_width);
+       mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width);
+       mv_canvas_width = roundup(mv_canvas_width, canvas_align_width);
+       nr_width = nr_canvas_width >> 1;
+       mtn_width = mtn_canvas_width << 1;
+       mv_width = (mv_canvas_width * 5) >> 1;
+
+       if (prog_flag) {
+               ppre->prog_proc_type = 1;
+               ppre->buf_alloc_mode = 1;
+               di_buf_size = nr_width * canvas_height * 2;
+               di_buf_size = roundup(di_buf_size, PAGE_SIZE);
+       } else {
+               /*pr_info("canvas_height=%d\n", canvas_height);*/
+               ppre->prog_proc_type = 0;
+               ppre->buf_alloc_mode = 0;
+               /*nr_size(bits) = w * active_h * 8 * 2(yuv422)
+                * mtn(bits) = w * active_h * 4
+                * cont(bits) = w * active_h * 4 mv(bits) = w * active_h / 5*16
+                * mcinfo(bits) = active_h * 16
+                */
+               nr_size = (nr_width * canvas_height) * 8 * 2 / 16;
+               mtn_size = (mtn_width * canvas_height) * 4 / 16;
+               count_size = (mtn_width * canvas_height) * 4 / 16;
+               mv_size = (mv_width * canvas_height) / 5;
+               /*mc_size = canvas_height;*/
+               mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1;
+               if (mc_mem_alloc) {
+                       di_buf_size = nr_size + mtn_size + count_size +
+                               mv_size + mc_size;
+               } else {
+                       di_buf_size = nr_size + mtn_size + count_size;
+               }
+               di_buf_size = roundup(di_buf_size, PAGE_SIZE);
+       }
+       de_devp->buffer_size = di_buf_size;
+       ppre->nr_size = nr_size;
+       ppre->count_size = count_size;
+       ppre->mtn_size = mtn_size;
+       ppre->mv_size = mv_size;
+       ppre->mcinfo_size = mc_size;
+       dimp_set(eDI_MP_same_field_top_count, 0);
+       same_field_bot_count = 0;
+       dbg_init("size:\n");
+       dbg_init("\t%-15s:0x%x\n", "nr_size", ppre->nr_size);
+       dbg_init("\t%-15s:0x%x\n", "count", ppre->count_size);
+       dbg_init("\t%-15s:0x%x\n", "mtn", ppre->mtn_size);
+       dbg_init("\t%-15s:0x%x\n", "mv", ppre->mv_size);
+       dbg_init("\t%-15s:0x%x\n", "mcinfo", ppre->mcinfo_size);
+
+       /**********************************************/
+       /* que init */
+       /**********************************************/
+
+       queue_init(channel, mm->cfg.num_local);
+       di_que_init(channel); /*new que*/
+
+       mem_st_local = di_get_mem_start(channel);
+
+       /**********************************************/
+       /* local buf init */
+       /**********************************************/
+
+       for (i = 0; i < mm->cfg.num_local; i++) {
+               struct di_buf_s *di_buf = &pbuf_local[i];
+               int ii = USED_LOCAL_BUF_MAX;
+
+               if (!IS_ERR_OR_NULL(keep_buf)) {
+                       for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) {
+                               if (di_buf == keep_buf->di_buf_dup_p[ii]) {
+                                       dim_print("%s skip %d\n", __func__, i);
+                                       break;
+                               }
+                       }
+               }
+
+               if (ii >= USED_LOCAL_BUF_MAX) {
+                       /* backup cma pages */
+                       tmp_page = di_buf->pages;
+                       memset(di_buf, 0, sizeof(struct di_buf_s));
+                       di_buf->pages = tmp_page;
+                       di_buf->type = VFRAME_TYPE_LOCAL;
+                       di_buf->pre_ref_count = 0;
+                       di_buf->post_ref_count = 0;
+                       di_buf->canvas_width[NR_CANVAS] = nr_canvas_width;
+                       di_buf->canvas_width[MTN_CANVAS] = mtn_canvas_width;
+                       di_buf->canvas_width[MV_CANVAS] = mv_canvas_width;
+                       if (prog_flag) {
+                               di_buf->canvas_height = canvas_height;
+                               di_buf->canvas_height_mc = canvas_height;
+                               di_buf->nr_adr = mem_st_local +
+                                       di_buf_size * i;
+                               di_buf->canvas_config_flag = 1;
+                       } else {
+                               di_buf->canvas_height = (canvas_height >> 1);
+                               di_buf->canvas_height_mc =
+                                       roundup(di_buf->canvas_height,
+                                               canvas_align_width);
+                               di_buf->nr_adr = mem_st_local +
+                                       di_buf_size * i;
+                               di_buf->mtn_adr = mem_st_local +
+                                       di_buf_size * i +
+                                       nr_size;
+                               di_buf->cnt_adr = mem_st_local +
+                                       di_buf_size * i +
+                                       nr_size + mtn_size;
+
+                               if (mc_mem_alloc) {
+                                       di_buf->mcvec_adr = mem_st_local +
+                                               di_buf_size * i +
+                                               nr_size + mtn_size
+                                               + count_size;
+                                       di_buf->mcinfo_adr =
+                                               mem_st_local +
+                                               di_buf_size * i + nr_size +
+                                               mtn_size + count_size
+                                               + mv_size;
+                               }
+                               di_buf->canvas_config_flag = 2;
+                       }
+                       di_buf->index = i;
+                       di_buf->vframe = &pvframe_local[i];
+                       di_buf->vframe->private_data = di_buf;
+                       di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx;
+                       di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx;
+                       di_buf->queue_index = -1;
+                       di_buf->invert_top_bot_flag = 0;
+                       di_buf->channel = channel;
+                       queue_in(channel, di_buf, QUEUE_LOCAL_FREE);
+                       dbg_init("buf[%d], addr=0x%lx\n", di_buf->index,
+                                di_buf->nr_adr);
+               }
+       }
+
+       if (de_devp->flag_cma == 1      ||
+           de_devp->flag_cma == 4      ||
+           de_devp->flag_cma == 3) {   /*trig cma alloc*/
+               dip_wq_cma_run(channel, true);
+       }
+
+       dbg_init("one local buf size:0x%x\n", di_buf_size);
+       /*mm-0705       di_post_mem = mem_st_local +*/
+       /*mm-0705               di_buf_size*de_devp->buf_num_avail;*/
+       di_post_mem = mem_st_local + di_buf_size * mm->cfg.num_local;
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) {
+               di_post_buf_size = nr_width * canvas_height * 2;
+               #if 0   /*ary test for vout 25Hz*/
+               /* pre buffer must 2 more than post buffer */
+               if ((de_devp->buf_num_avail - 2) > MAX_POST_BUF_NUM)
+                       ppost->di_post_num = MAX_POST_BUF_NUM;
+               else
+                       ppost->di_post_num = (de_devp->buf_num_avail - 2);
+               #else
+                       /*mm-0705 ppost->di_post_num = MAX_POST_BUF_NUM;*/
+               #endif
+               dbg_init("DI: di post buffer size 0x%x byte.\n",
+                        di_post_buf_size);
+       } else {
+               /*mm-0705 ppost->di_post_num = MAX_POST_BUF_NUM;*/
+               di_post_buf_size = 0;
+       }
+       de_devp->post_buffer_size = di_post_buf_size;
+
+       /**********************************************/
+       /* input buf init */
+       /**********************************************/
+
+       for (i = 0; i < MAX_IN_BUF_NUM; i++) {
+               struct di_buf_s *di_buf = &pbuf_in[i];
+
+               if (di_buf) {
+                       memset(di_buf, 0, sizeof(struct di_buf_s));
+                       di_buf->type = VFRAME_TYPE_IN;
+                       di_buf->pre_ref_count = 0;
+                       di_buf->post_ref_count = 0;
+                       di_buf->vframe = &pvframe_in_dup[i];
+                       di_buf->vframe->private_data = di_buf;
+                       di_buf->index = i;
+                       di_buf->queue_index = -1;
+                       di_buf->invert_top_bot_flag = 0;
+                       di_buf->channel = channel;
+                       di_que_in(channel, QUE_IN_FREE, di_buf);
+               }
+       }
+       /**********************************************/
+       /* post buf init */
+       /**********************************************/
+       /*mm-0705 for (i = 0; i < ppost->di_post_num; i++) {*/
+       for (i = 0; i < mm->cfg.num_post; i++) {
+               struct di_buf_s *di_buf = &pbuf_post[i];
+
+               if (di_buf) {
+                       if (dimp_get(eDI_MP_post_wr_en) &&
+                           dimp_get(eDI_MP_post_wr_support)) {
+                               /*ary:for keep buf*/
+                               if (keep_buf_post && di_buf == keep_buf_post) {
+                                       dbg_reg("%s:post keep buf %d:%d\n",
+                                               __func__,
+                                               i, keep_buf_post->index);
+                                       continue;
+                               }
+                       }
+
+                       memset(di_buf, 0, sizeof(struct di_buf_s));
+                       di_buf->type = VFRAME_TYPE_POST;
+                       di_buf->index = i;
+                       di_buf->vframe = &pvframe_post[i];
+                       di_buf->vframe->private_data = di_buf;
+                       di_buf->queue_index = -1;
+                       di_buf->invert_top_bot_flag = 0;
+                       di_buf->channel = channel;
+                       if (dimp_get(eDI_MP_post_wr_en) &&
+                           dimp_get(eDI_MP_post_wr_support)) {
+                               di_buf->canvas_width[NR_CANVAS] =
+                                       (nr_width << 1);
+                               di_buf->canvas_height = canvas_height;
+                               di_buf->canvas_config_flag = 1;
+                               di_buf->nr_adr = di_post_mem
+                                       + di_post_buf_size * i;
+                               dbg_init("[%d]post buf:%d: addr=0x%lx\n", i,
+                                        di_buf->index, di_buf->nr_adr);
+                       }
+
+                       di_que_in(channel, QUE_POST_FREE, di_buf);
+
+               } else {
+                       PR_ERR("%s:%d:post buf is null\n", __func__, i);
+               }
+       }
+       if (de_devp->flag_cma == 0 && de_devp->nrds_enable) {
+               nrds_mem = di_post_mem + mm->cfg.num_post * di_post_buf_size;
+               /*mm-0705 ppost->di_post_num * di_post_buf_size;*/
+               dim_nr_ds_buf_init(de_devp->flag_cma, nrds_mem,
+                                  &de_devp->pdev->dev);
+       }
+       return 0;
+}
+
+void dim_keep_mirror_buffer(unsigned int channel)      /*not use*/
+{
+       struct di_buf_s *p = NULL;
+       int i = 0, ii = 0, itmp;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) {
+       if (p->di_buf[0]->type != VFRAME_TYPE_IN        &&
+           (p->process_fun_index != PROCESS_FUN_NULL)  &&
+           (ii < USED_LOCAL_BUF_MAX)                   &&
+           (p->index == ppost->cur_disp_index)) {
+               ppost->keep_buf = p;
+               for (i = 0; i < USED_LOCAL_BUF_MAX; i++) {
+                       if (IS_ERR_OR_NULL(p->di_buf_dup_p[i]))
+                               continue;
+                       /* prepare for recycle
+                        * the keep buffer
+                        */
+                       p->di_buf_dup_p[i]->pre_ref_count = 0;
+                       p->di_buf_dup_p[i]->post_ref_count = 0;
+                       if ((p->di_buf_dup_p[i]->queue_index >= 0) &&
+                           (p->di_buf_dup_p[i]->queue_index < QUEUE_NUM)) {
+                               if (is_in_queue(channel,
+                                               p->di_buf_dup_p[i],
+                                               p->di_buf_dup_p[i]->queue_index
+                                               ))
+                                       queue_out(channel, p->di_buf_dup_p[i]);
+                                       /*which que?*/
+                       }
+                       ii++;
+                       if (p->di_buf_dup_p[i]->di_wr_linked_buf)
+                               p->di_buf_dup_p[i + 1] =
+                                       p->di_buf_dup_p[i]->di_wr_linked_buf;
+               }
+               queue_out(channel, p);  /*which que?*/
+               break;
+       }
+       }
+}
+
+void dim_post_keep_mirror_buffer(unsigned int channel)
+{
+       struct di_buf_s *p = NULL;
+       int itmp;
+       bool flg = false;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) {
+               if (p->type != VFRAME_TYPE_POST ||
+                   !p->process_fun_index) {
+                       dbg_reg("%s:not post buf:%d\n",
+                               __func__, p->type);
+                       continue;
+               }
+
+               ppost->keep_buf_post = p;       /*only keep one*/
+               flg = true;
+               dbg_reg("%s %d\n", __func__, p->index);
+       }
+
+       if (flg && ppost->keep_buf_post) {
+               ppost->keep_buf_post->queue_index = -1;
+               ppost->keep_buf_post->invert_top_bot_flag = 0;
+       }
+}
+
+void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel)
+{
+       /*int i = 0;*/
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (!queue_empty(channel, QUEUE_DISPLAY) || disable_mirror)
+               ppost->keep_buf = NULL;
+#if 0
+       if (disable_mirror != 1)
+               dim_keep_mirror_buffer();
+
+       if (!IS_ERR_OR_NULL(di_post_stru.keep_buf)) {
+               keep_buf = di_post_stru.keep_buf;
+               pr_dbg("%s keep cur di_buf %d (",
+                      __func__, keep_buf->index);
+               for (i = 0; i < USED_LOCAL_BUF_MAX; i++) {
+                       if (!IS_ERR_OR_NULL(keep_buf->di_buf_dup_p[i]))
+                               pr_dbg("%d\t",
+                                      keep_buf->di_buf_dup_p[i]->index);
+               }
+               pr_dbg(")\n");
+       }
+#else
+       if (!disable_mirror)
+               dim_post_keep_mirror_buffer(channel);
+#endif
+       queue_init(channel, 0);
+       di_que_init(channel); /*new que*/
+
+       /* decoder'buffer had been releae no need put */
+       #if 0
+       for (i = 0; i < MAX_IN_BUF_NUM; i++)
+               pvframe_in[i] = NULL;
+       #else
+       memset(pvframe_in, 0, sizeof(*pvframe_in) * MAX_IN_BUF_NUM);
+       #endif
+       ppre->pre_de_process_flag = 0;
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) {
+               ppost->cur_post_buf = NULL;
+               ppost->post_de_busy = 0;
+               ppost->de_post_process_done = 0;
+               ppost->post_wr_cnt = 0;
+       }
+       if (de_devp->flag_cma == 0 && de_devp->nrds_enable) {
+               dim_nr_ds_buf_uninit(de_devp->flag_cma,
+                                    &de_devp->pdev->dev);
+       }
+}
+
+void dim_log_buffer_state(unsigned char *tag, unsigned int channel)
+{
+       struct di_pre_stru_s *ppre;
+       unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/
+       unsigned int psize; /*new que*/
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_BUFFER_STATE) {
+               struct di_buf_s *p = NULL;/* , *ptmp; */
+               int itmp;
+               int in_free = 0;
+               int local_free = 0;
+               int pre_ready = 0;
+               int post_free = 0;
+               int post_ready = 0;
+               int post_ready_ext = 0;
+               int display = 0;
+               int display_ext = 0;
+               int recycle = 0;
+               int di_inp = 0;
+               int di_wr = 0;
+               ulong irq_flag2 = 0;
+
+               ppre = get_pre_stru(channel);
+
+               di_lock_irqfiq_save(irq_flag2);
+               in_free = di_que_list_count(channel, QUE_IN_FREE);
+               local_free = list_count(channel, QUEUE_LOCAL_FREE);
+               pre_ready = di_que_list_count(channel, QUE_PRE_READY);
+               post_free = di_que_list_count(channel, QUE_POST_FREE);
+               post_ready = di_que_list_count(channel, QUE_POST_READY);
+
+               di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize);
+               /*di_que_for_each(channel, p, psize, &tmpa[0]) {*/
+               for (itmp = 0; itmp < psize; itmp++) {
+                       p = pw_qindex_2_buf(channel, tmpa[itmp]);
+                       if (p->di_buf[0])
+                               post_ready_ext++;
+
+                       if (p->di_buf[1])
+                               post_ready_ext++;
+               }
+               queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) {
+                       display++;
+                       if (p->di_buf[0])
+                               display_ext++;
+
+                       if (p->di_buf[1])
+                               display_ext++;
+               }
+               recycle = list_count(channel, QUEUE_RECYCLE);
+
+               if (ppre->di_inp_buf)
+                       di_inp++;
+               if (ppre->di_wr_buf)
+                       di_wr++;
+
+               if (dimp_get(eDI_MP_buf_state_log_threshold) == 0)
+                       buf_state_log_start = 0;
+               else if (post_ready < dimp_get(eDI_MP_buf_state_log_threshold))
+                       buf_state_log_start = 1;
+
+               if (buf_state_log_start) {
+                       dim_print(
+               "[%s]i i_f %d/%d, l_f %d, pre_r %d, post_f %d/%d,",
+                               tag,
+                               in_free, MAX_IN_BUF_NUM,
+                               local_free,
+                               pre_ready,
+                               post_free, MAX_POST_BUF_NUM);
+                       dim_print(
+               "post_r (%d:%d), disp (%d:%d),rec %d, di_i %d, di_w %d\n",
+                               post_ready, post_ready_ext,
+                               display, display_ext,
+                               recycle,
+                               di_inp, di_wr
+                               );
+               }
+               di_unlock_irqfiq_restore(irq_flag2);
+       }
+}
+
+static void dump_state(unsigned int channel)
+{
+       struct di_buf_s *p = NULL, *keep_buf;
+       int itmp, i;
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       unsigned int tmpa[MAX_FIFO_SIZE];       /*new que*/
+       unsigned int psize;             /*new que*/
+       struct di_mm_s *mm = dim_mm_get(); /*mm-0705*/
+
+       dump_state_flag = 1;
+       pr_info("version %s, init_flag %d, is_bypass %d\n",
+               version_s, get_init_flag(channel),
+               dim_is_bypass(NULL, channel));
+       pr_info("recovery_flag = %d, recovery_log_reason=%d, di_blocking=%d",
+               recovery_flag, recovery_log_reason, di_blocking);
+       pr_info("recovery_log_queue_idx=%d, recovery_log_di_buf=0x%p\n",
+               recovery_log_queue_idx, recovery_log_di_buf);
+       pr_info("buffer_size=%d, mem_flag=%s, cma_flag=%d\n",
+               /*atomic_read(&de_devp->mem_flag)*/
+               de_devp->buffer_size, di_cma_dbg_get_st_name(channel),
+               de_devp->flag_cma);
+       keep_buf = ppost->keep_buf;
+       pr_info("used_post_buf_index %d(0x%p),",
+               IS_ERR_OR_NULL(keep_buf) ?
+               -1 : keep_buf->index, keep_buf);
+#if 0
+       if (!IS_ERR_OR_NULL(keep_buf)) {
+               pr_info("used_local_buf_index:\n");
+               for (i = 0; i < USED_LOCAL_BUF_MAX; i++) {
+                       p = keep_buf->di_buf_dup_p[i];
+                       pr_info("%d(0x%p) ",
+                               IS_ERR_OR_NULL(p) ? -1 : p->index, p);
+               }
+       }
+#endif
+       pr_info("\nin_free_list (max %d):\n", MAX_IN_BUF_NUM);
+
+       di_que_list(channel, QUE_IN_FREE, &tmpa[0], &psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+               pr_info("index %2d, 0x%p, type %d\n",
+                       p->index, p, p->type);
+       }
+       pr_info("local_free_list (max %d):\n", mm->cfg.num_local);
+       queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) {
+               pr_info("index %2d, 0x%p, type %d\n", p->index, p, p->type);
+       }
+
+       pr_info("post_doing_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_POST_DOING, list) {
+               dim_print_di_buf(p, 2);
+       }
+       pr_info("pre_ready_list:\n");
+
+       di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+               dim_print_di_buf(p, 2);
+       }
+       pr_info("post_free_list (max %d):\n", mm->cfg.num_post);
+
+       di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+
+               pr_info("index %2d, 0x%p, type %d, vframetype 0x%x\n",
+                       p->index, p, p->type, p->vframe->type);
+       }
+       pr_info("post_ready_list:\n");
+
+       di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+
+               dim_print_di_buf(p, 2);
+               dim_print_di_buf(p->di_buf[0], 1);
+               dim_print_di_buf(p->di_buf[1], 1);
+       }
+       pr_info("display_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) {
+               dim_print_di_buf(p, 2);
+               dim_print_di_buf(p->di_buf[0], 1);
+               dim_print_di_buf(p->di_buf[1], 1);
+       }
+       pr_info("recycle_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_RECYCLE, list) {
+               pr_info(
+"index %d, 0x%p, type %d, vframetype 0x%x pre_ref_count %d post_ref_count %d\n",
+                       p->index, p, p->type,
+                       p->vframe->type,
+                       p->pre_ref_count,
+                       p->post_ref_count);
+               if (p->di_wr_linked_buf) {
+                       pr_info(
+       "linked index %2d, 0x%p, type %d pre_ref_count %d post_ref_count %d\n",
+                               p->di_wr_linked_buf->index,
+                               p->di_wr_linked_buf,
+                               p->di_wr_linked_buf->type,
+                               p->di_wr_linked_buf->pre_ref_count,
+                               p->di_wr_linked_buf->post_ref_count);
+               }
+       }
+       if (ppre->di_inp_buf) {
+               pr_info("di_inp_buf:index %d, 0x%p, type %d\n",
+                       ppre->di_inp_buf->index,
+                       ppre->di_inp_buf,
+                       ppre->di_inp_buf->type);
+       } else {
+               pr_info("di_inp_buf: NULL\n");
+       }
+       if (ppre->di_wr_buf) {
+               pr_info("di_wr_buf:index %d, 0x%p, type %d\n",
+                       ppre->di_wr_buf->index,
+                       ppre->di_wr_buf,
+                       ppre->di_wr_buf->type);
+       } else {
+               pr_info("di_wr_buf: NULL\n");
+       }
+       dim_dump_pre_stru(ppre);
+       dim_dump_post_stru(ppost);
+       pr_info("vframe_in[]:");
+
+       for (i = 0; i < MAX_IN_BUF_NUM; i++)
+               pr_info("0x%p ", pvframe_in[i]);
+
+       pr_info("\n");
+       pr_info("vf_peek()=>0x%p, video_peek_cnt = %d\n",
+               pw_vf_peek(channel), di_sum_get(channel, eDI_SUM_O_PEEK_CNT));
+       pr_info("reg_unreg_timerout = %lu\n", reg_unreg_timeout_cnt);
+       dump_state_flag = 0;
+}
+
+unsigned char dim_check_di_buf(struct di_buf_s *di_buf, int reason,
+                              unsigned int channel)
+{
+       int error = 0;
+       struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel);
+       struct vframe_s *pvframe_local = get_vframe_local(channel);
+       struct vframe_s *pvframe_post = get_vframe_post(channel);
+
+       if (!di_buf) {
+               PR_ERR("%s: %d, di_buf is NULL\n", __func__, reason);
+               return 1;
+       }
+
+       if (di_buf->type == VFRAME_TYPE_IN) {
+               if (di_buf->vframe != &pvframe_in_dup[di_buf->index])
+                       error = 1;
+       } else if (di_buf->type == VFRAME_TYPE_LOCAL) {
+               if (di_buf->vframe != &pvframe_local[di_buf->index])
+                       error = 1;
+       } else if (di_buf->type == VFRAME_TYPE_POST) {
+               if (di_buf->vframe != &pvframe_post[di_buf->index])
+                       error = 1;
+       } else {
+               error = 1;
+       }
+
+       if (error) {
+               PR_ERR("%s: %d, di_buf wrong\n", __func__, reason);
+               if (recovery_flag == 0)
+                       recovery_log_reason = reason;
+               recovery_flag++;
+               dim_dump_di_buf(di_buf);
+               return 1;
+       }
+
+       return 0;
+}
+
+/*
+ *  di pre process
+ */
+static void
+config_di_mcinford_mif(struct DI_MC_MIF_s *di_mcinford_mif,
+                      struct di_buf_s *di_buf)
+{
+       if (di_buf) {
+               di_mcinford_mif->size_x = (di_buf->vframe->height + 2) / 4 - 1;
+               di_mcinford_mif->size_y = 1;
+               di_mcinford_mif->canvas_num = di_buf->mcinfo_canvas_idx;
+       }
+}
+
+static void
+config_di_pre_mc_mif(struct DI_MC_MIF_s *di_mcinfo_mif,
+                    struct DI_MC_MIF_s *di_mcvec_mif,
+                    struct di_buf_s *di_buf)
+{
+       unsigned int pre_size_w = 0, pre_size_h = 0;
+
+       if (di_buf) {
+               pre_size_w = di_buf->vframe->width;
+               pre_size_h = (di_buf->vframe->height + 1) / 2;
+               di_mcinfo_mif->size_x = (pre_size_h + 1) / 2 - 1;
+               di_mcinfo_mif->size_y = 1;
+               di_mcinfo_mif->canvas_num = di_buf->mcinfo_canvas_idx;
+
+               di_mcvec_mif->size_x = (pre_size_w + 4) / 5 - 1;
+               di_mcvec_mif->size_y = pre_size_h - 1;
+               di_mcvec_mif->canvas_num = di_buf->mcvec_canvas_idx;
+       }
+}
+
+static void config_di_cnt_mif(struct DI_SIM_MIF_s *di_cnt_mif,
+                             struct di_buf_s *di_buf)
+{
+       if (di_buf) {
+               di_cnt_mif->start_x = 0;
+               di_cnt_mif->end_x = di_buf->vframe->width - 1;
+               di_cnt_mif->start_y = 0;
+               di_cnt_mif->end_y = di_buf->vframe->height / 2 - 1;
+               di_cnt_mif->canvas_num = di_buf->cnt_canvas_idx;
+       }
+}
+
+static void
+config_di_wr_mif(struct DI_SIM_MIF_s *di_nrwr_mif,
+                struct DI_SIM_MIF_s *di_mtnwr_mif,
+                struct di_buf_s *di_buf, unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       vframe_t *vf = di_buf->vframe;
+
+       di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx;
+       di_nrwr_mif->start_x = 0;
+       di_nrwr_mif->end_x = vf->width - 1;
+       di_nrwr_mif->start_y = 0;
+       if (di_buf->vframe->bitdepth & BITDEPTH_Y10)
+               di_nrwr_mif->bit_mode =
+                       (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ?
+                       3 : 1;
+       else
+               di_nrwr_mif->bit_mode = 0;
+       if (ppre->prog_proc_type == 0)
+               di_nrwr_mif->end_y = vf->height / 2 - 1;
+       else
+               di_nrwr_mif->end_y = vf->height - 1;
+       if (ppre->prog_proc_type == 0) {
+               di_mtnwr_mif->start_x = 0;
+               di_mtnwr_mif->end_x = vf->width - 1;
+               di_mtnwr_mif->start_y = 0;
+               di_mtnwr_mif->end_y = vf->height / 2 - 1;
+               di_mtnwr_mif->canvas_num = di_buf->mtn_canvas_idx;
+       }
+}
+
+static void config_di_mif(struct DI_MIF_s *di_mif, struct di_buf_s *di_buf,
+                         unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (!di_buf)
+               return;
+       di_mif->canvas0_addr0 =
+               di_buf->vframe->canvas0Addr & 0xff;
+       di_mif->canvas0_addr1 =
+               (di_buf->vframe->canvas0Addr >> 8) & 0xff;
+       di_mif->canvas0_addr2 =
+               (di_buf->vframe->canvas0Addr >> 16) & 0xff;
+
+       di_mif->nocompress = (di_buf->vframe->type & VIDTYPE_COMPRESS) ? 0 : 1;
+
+       if (di_buf->vframe->bitdepth & BITDEPTH_Y10) {
+               if (di_buf->vframe->type & VIDTYPE_VIU_444)
+                       di_mif->bit_mode =
+                       (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ?
+                       3 : 2;
+               else if (di_buf->vframe->type & VIDTYPE_VIU_422)
+                       di_mif->bit_mode =
+                       (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ?
+                       3 : 1;
+       } else {
+               di_mif->bit_mode = 0;
+       }
+       if (di_buf->vframe->type & VIDTYPE_VIU_422) {
+               /* from vdin or local vframe */
+               if ((!is_progressive(di_buf->vframe))   ||
+                   (ppre->prog_proc_type)) {
+                       di_mif->video_mode = 0;
+                       di_mif->set_separate_en = 0;
+                       di_mif->src_field_mode = 0;
+                       di_mif->output_field_num = 0;
+                       di_mif->luma_x_start0 = 0;
+                       di_mif->luma_x_end0 =
+                               di_buf->vframe->width - 1;
+                       di_mif->luma_y_start0 = 0;
+                       if (ppre->prog_proc_type)
+                               di_mif->luma_y_end0 =
+                                       di_buf->vframe->height - 1;
+                       else
+                               di_mif->luma_y_end0 =
+                                       di_buf->vframe->height / 2 - 1;
+                       di_mif->chroma_x_start0 = 0;
+                       di_mif->chroma_x_end0 = 0;
+                       di_mif->chroma_y_start0 = 0;
+                       di_mif->chroma_y_end0 = 0;
+                       di_mif->canvas0_addr0 =
+                               di_buf->vframe->canvas0Addr & 0xff;
+                       di_mif->canvas0_addr1 =
+                               (di_buf->vframe->canvas0Addr >> 8) & 0xff;
+                       di_mif->canvas0_addr2 =
+                               (di_buf->vframe->canvas0Addr >> 16) & 0xff;
+               }
+       } else {
+               if (di_buf->vframe->type & VIDTYPE_VIU_444)
+                       di_mif->video_mode = 1;
+               else
+                       di_mif->video_mode = 0;
+               if (di_buf->vframe->type & VIDTYPE_VIU_NV21)
+                       di_mif->set_separate_en = 2;
+               else
+                       di_mif->set_separate_en = 1;
+
+               if (is_progressive(di_buf->vframe) &&
+                   (ppre->prog_proc_type)) {
+                       di_mif->src_field_mode = 0;
+                       di_mif->output_field_num = 0; /* top */
+                       di_mif->luma_x_start0 = 0;
+                       di_mif->luma_x_end0 =
+                               di_buf->vframe->width - 1;
+                       di_mif->luma_y_start0 = 0;
+                       di_mif->luma_y_end0 =
+                               di_buf->vframe->height - 1;
+                       di_mif->chroma_x_start0 = 0;
+                       di_mif->chroma_x_end0 =
+                               di_buf->vframe->width / 2 - 1;
+                       di_mif->chroma_y_start0 = 0;
+                       di_mif->chroma_y_end0 =
+                               di_buf->vframe->height / 2 - 1;
+               } else {
+                       /*move to mp    di_mif->src_prog = force_prog?1:0;*/
+                       if (ppre->cur_inp_type  & VIDTYPE_INTERLACE)
+                               di_mif->src_prog = 0;
+                       else
+                               di_mif->src_prog
+                               = dimp_get(eDI_MP_force_prog) ? 1 : 0;
+                       di_mif->src_field_mode = 1;
+                       if (
+                               (di_buf->vframe->type & VIDTYPE_TYPEMASK) ==
+                               VIDTYPE_INTERLACE_TOP) {
+                               di_mif->output_field_num = 0; /* top */
+                               di_mif->luma_x_start0 = 0;
+                               di_mif->luma_x_end0 =
+                                       di_buf->vframe->width - 1;
+                               di_mif->luma_y_start0 = 0;
+                               di_mif->luma_y_end0 =
+                                       di_buf->vframe->height - 2;
+                               di_mif->chroma_x_start0 = 0;
+                               di_mif->chroma_x_end0 =
+                                       di_buf->vframe->width / 2 - 1;
+                               di_mif->chroma_y_start0 = 0;
+                               di_mif->chroma_y_end0 =
+                                       di_buf->vframe->height / 2
+                                               - (di_mif->src_prog ? 1 : 2);
+                       } else {
+                               di_mif->output_field_num = 1;
+                               /* bottom */
+                               di_mif->luma_x_start0 = 0;
+                               di_mif->luma_x_end0 =
+                                       di_buf->vframe->width - 1;
+                               di_mif->luma_y_start0 = 1;
+                               di_mif->luma_y_end0 =
+                                       di_buf->vframe->height - 1;
+                               di_mif->chroma_x_start0 = 0;
+                               di_mif->chroma_x_end0 =
+                                       di_buf->vframe->width / 2 - 1;
+                               di_mif->chroma_y_start0 =
+                                       (di_mif->src_prog ? 0 : 1);
+                               di_mif->chroma_y_end0 =
+                                       di_buf->vframe->height / 2 - 1;
+                       }
+               }
+       }
+}
+
+static void di_pre_size_change(unsigned short width,
+                              unsigned short height,
+                              unsigned short vf_type,
+                              unsigned int channel);
+
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+static void pre_inp_canvas_config(struct vframe_s *vf);
+#endif
+void dim_pre_de_process(unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       unsigned short pre_width = 0, pre_height = 0;
+       unsigned char chan2_field_num = 1;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       int canvases_idex = ppre->field_count_for_cont % 2;
+       unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK;
+       unsigned short int_mask = 0x7f;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       ppre->pre_de_process_flag = 1;
+       dim_ddbg_mod_save(eDI_DBG_MOD_PRE_SETB, channel, ppre->in_seq);/*dbg*/
+
+       #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+       pre_inp_canvas_config(ppre->di_inp_buf->vframe);
+       #endif
+
+       config_di_mif(&ppre->di_inp_mif, ppre->di_inp_buf, channel);
+       /* pr_dbg("set_separate_en=%d vframe->type %d\n",
+        * di_pre_stru.di_inp_mif.set_separate_en,
+        * di_pre_stru.di_inp_buf->vframe->type);
+        */
+#ifdef DI_USE_FIXED_CANVAS_IDX
+       if (ppre->di_mem_buf_dup_p      &&
+           ppre->di_mem_buf_dup_p != ppre->di_inp_buf) {
+               config_canvas_idx(ppre->di_mem_buf_dup_p,
+                                 di_pre_idx[canvases_idex][0], -1);
+               config_cnt_canvas_idx(ppre->di_mem_buf_dup_p,
+                                     di_pre_idx[canvases_idex][1]);
+       } else {
+               config_cnt_canvas_idx(ppre->di_wr_buf,
+                                     di_pre_idx[canvases_idex][1]);
+               config_di_cnt_mif(&ppre->di_contp2rd_mif,
+                                 ppre->di_wr_buf);
+       }
+       if (ppre->di_chan2_buf_dup_p) {
+               config_canvas_idx(ppre->di_chan2_buf_dup_p,
+                                 di_pre_idx[canvases_idex][2], -1);
+               config_cnt_canvas_idx(ppre->di_chan2_buf_dup_p,
+                                     di_pre_idx[canvases_idex][3]);
+       } else {
+               config_cnt_canvas_idx(ppre->di_wr_buf,
+                                     di_pre_idx[canvases_idex][3]);
+       }
+       config_canvas_idx(ppre->di_wr_buf,
+                         di_pre_idx[canvases_idex][4],
+                         di_pre_idx[canvases_idex][5]);
+       config_cnt_canvas_idx(ppre->di_wr_buf,
+                             di_pre_idx[canvases_idex][6]);
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               if (ppre->di_chan2_buf_dup_p)
+                       config_mcinfo_canvas_idx(ppre->di_chan2_buf_dup_p,
+                                                di_pre_idx[canvases_idex][7]);
+               else
+                       config_mcinfo_canvas_idx(ppre->di_wr_buf,
+                                                di_pre_idx[canvases_idex][7]);
+
+               config_mcinfo_canvas_idx(ppre->di_wr_buf,
+                                        di_pre_idx[canvases_idex][8]);
+               config_mcvec_canvas_idx(ppre->di_wr_buf,
+                                       di_pre_idx[canvases_idex][9]);
+       }
+#endif
+       config_di_mif(&ppre->di_mem_mif, ppre->di_mem_buf_dup_p, channel);
+       if (!ppre->di_chan2_buf_dup_p) {
+               config_di_mif(&ppre->di_chan2_mif,
+                             ppre->di_inp_buf, channel);
+       } else
+               config_di_mif(&ppre->di_chan2_mif,
+                             ppre->di_chan2_buf_dup_p, channel);
+       config_di_wr_mif(&ppre->di_nrwr_mif, &ppre->di_mtnwr_mif,
+                        ppre->di_wr_buf, channel);
+
+       if (ppre->di_chan2_buf_dup_p)
+               config_di_cnt_mif(&ppre->di_contprd_mif,
+                                 ppre->di_chan2_buf_dup_p);
+       else
+               config_di_cnt_mif(&ppre->di_contprd_mif,
+                                 ppre->di_wr_buf);
+
+       config_di_cnt_mif(&ppre->di_contwr_mif, ppre->di_wr_buf);
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               if (ppre->di_chan2_buf_dup_p)
+                       config_di_mcinford_mif(&ppre->di_mcinford_mif,
+                                              ppre->di_chan2_buf_dup_p);
+               else
+                       config_di_mcinford_mif(&ppre->di_mcinford_mif,
+                                              ppre->di_wr_buf);
+
+               config_di_pre_mc_mif(&ppre->di_mcinfowr_mif,
+                                    &ppre->di_mcvecwr_mif, ppre->di_wr_buf);
+       }
+
+       if ((ppre->di_chan2_buf_dup_p) &&
+           ((ppre->di_chan2_buf_dup_p->vframe->type & VIDTYPE_TYPEMASK)
+            == VIDTYPE_INTERLACE_TOP))
+               chan2_field_num = 0;
+
+       pre_width = ppre->di_nrwr_mif.end_x + 1;
+       pre_height = ppre->di_nrwr_mif.end_y + 1;
+       if (ppre->input_size_change_flag) {
+               cur_inp_field_type =
+               (ppre->di_inp_buf->vframe->type & VIDTYPE_TYPEMASK);
+               cur_inp_field_type =
+       ppre->cur_prog_flag ? VIDTYPE_PROGRESSIVE : cur_inp_field_type;
+               /*di_async_reset2();*/
+               di_pre_size_change(pre_width, pre_height,
+                                  cur_inp_field_type, channel);
+               ppre->input_size_change_flag = false;
+       }
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if (de_devp->nrds_enable) {
+                       dim_nr_ds_mif_config();
+                       dim_nr_ds_hw_ctrl(true);
+                       int_mask = 0x3f;
+               } else {
+                       dim_nr_ds_hw_ctrl(false);
+               }
+       }
+
+       /* set interrupt mask for pre module.
+        * we need to only leave one mask open
+        * to prevent multiple entry for dim_irq
+        */
+
+       /*dim_dbg_pre_cnt(channel, "s2");*/
+
+       dimh_enable_di_pre_aml(&ppre->di_inp_mif,
+                              &ppre->di_mem_mif,
+                              &ppre->di_chan2_mif,
+                              &ppre->di_nrwr_mif,
+                              &ppre->di_mtnwr_mif,
+                              &ppre->di_contp2rd_mif,
+                              &ppre->di_contprd_mif,
+                              &ppre->di_contwr_mif,
+                              ppre->madi_enable,
+                              chan2_field_num,
+                              ppre->vdin2nr);
+
+       dimh_enable_afbc_input(ppre->di_inp_buf->vframe);
+
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+                       dimh_enable_mc_di_pre_g12(&ppre->di_mcinford_mif,
+                                                 &ppre->di_mcinfowr_mif,
+                                                 &ppre->di_mcvecwr_mif,
+                                                 ppre->mcdi_enable);
+               else
+                       dimh_enable_mc_di_pre(&ppre->di_mcinford_mif,
+                                             &ppre->di_mcinfowr_mif,
+                                             &ppre->di_mcvecwr_mif,
+                                             ppre->mcdi_enable);
+       }
+
+       ppre->field_count_for_cont++;
+       dimh_txl_patch_prog(ppre->cur_prog_flag,
+                           ppre->field_count_for_cont,
+                           dimp_get(eDI_MP_mcpre_en));
+
+#ifdef SUPPORT_MPEG_TO_VDIN
+       if (mpeg2vdin_flag) {
+               struct vdin_arg_s vdin_arg;
+               struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops();
+
+               vdin_arg.cmd = VDIN_CMD_FORCE_GO_FIELD;
+               if (vdin_ops->tvin_vdin_func)
+                       vdin_ops->tvin_vdin_func(0, &vdin_arg);
+       }
+#endif
+       /* must make sure follow part issue without interrupts,
+        * otherwise may cause watch dog reboot
+        */
+       di_lock_irqfiq_save(irq_flag2);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dim_pre_frame_reset_g12(ppre->madi_enable,
+                                       ppre->mcdi_enable);
+       else
+               dim_pre_frame_reset();
+
+       /* enable mc pre mif*/
+       dimh_enable_di_pre_mif(true, dimp_get(eDI_MP_mcpre_en));
+       /*dbg_set_DI_PRE_CTRL();*/
+       di_pre_wait_irq_set(true);
+       di_unlock_irqfiq_restore(irq_flag2);
+       /*reinit pre busy flag*/
+       ppre->pre_de_busy = 1;
+
+       #ifdef SUPPORT_MPEG_TO_VDIN
+       if (mpeg2vdin_flag)
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 13, 1);
+       #endif
+       dim_dbg_pre_cnt(channel, "s3");
+       ppre->irq_time[0] = cur_to_msecs();
+       ppre->irq_time[1] = cur_to_msecs();
+       dim_ddbg_mod_save(eDI_DBG_MOD_PRE_SETE, channel, ppre->in_seq);/*dbg*/
+       dim_tr_ops.pre_set(ppre->di_wr_buf->vframe->omx_index);
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+       if (di_pre_rdma_enable & 0x2)
+               rdma_config(de_devp->rdma_handle, RDMA_TRIGGER_MANUAL);
+       else if (di_pre_rdma_enable & 1)
+               rdma_config(de_devp->rdma_handle, RDMA_DEINT_IRQ);
+#endif
+       ppre->pre_de_process_flag = 0;
+}
+
+void dim_pre_de_done_buf_clear(unsigned int channel)
+{
+       struct di_buf_s *wr_buf = NULL;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (ppre->di_wr_buf) {
+               wr_buf = ppre->di_wr_buf;
+               if ((ppre->prog_proc_type == 2) &&
+                   wr_buf->di_wr_linked_buf) {
+                       wr_buf->di_wr_linked_buf->pre_ref_count = 0;
+                       wr_buf->di_wr_linked_buf->post_ref_count = 0;
+                       queue_in(channel, wr_buf->di_wr_linked_buf,
+                                QUEUE_RECYCLE);
+                       wr_buf->di_wr_linked_buf = NULL;
+               }
+               wr_buf->pre_ref_count = 0;
+               wr_buf->post_ref_count = 0;
+               queue_in(channel, wr_buf, QUEUE_RECYCLE);
+               ppre->di_wr_buf = NULL;
+       }
+       if (ppre->di_inp_buf) {
+               if (ppre->di_mem_buf_dup_p == ppre->di_inp_buf)
+                       ppre->di_mem_buf_dup_p = NULL;
+
+               queue_in(channel, ppre->di_inp_buf, QUEUE_RECYCLE);
+               ppre->di_inp_buf = NULL;
+       }
+}
+
+static void top_bot_config(struct di_buf_s *di_buf)
+{
+       vframe_t *vframe = di_buf->vframe;
+
+       if (((invert_top_bot & 0x1) != 0) && (!is_progressive(vframe))) {
+               if (di_buf->invert_top_bot_flag == 0) {
+                       if ((vframe->type & VIDTYPE_TYPEMASK) ==
+                           VIDTYPE_INTERLACE_TOP) {
+                               vframe->type &= (~VIDTYPE_TYPEMASK);
+                               vframe->type |= VIDTYPE_INTERLACE_BOTTOM;
+                       } else {
+                               vframe->type &= (~VIDTYPE_TYPEMASK);
+                               vframe->type |= VIDTYPE_INTERLACE_TOP;
+                       }
+                       di_buf->invert_top_bot_flag = 1;
+               }
+       }
+}
+
+void dim_pre_de_done_buf_config(unsigned int channel, bool flg_timeout)
+{
+       ulong irq_flag2 = 0;
+       int tmp_cur_lev;
+       struct di_buf_s *post_wr_buf = NULL;
+       unsigned int glb_frame_mot_num = 0;
+       unsigned int glb_field_mot_num = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       dim_dbg_pre_cnt(channel, "d1");
+       dim_ddbg_mod_save(eDI_DBG_MOD_PRE_DONEB, channel, ppre->in_seq);/*dbg*/
+       if (ppre->di_wr_buf) {
+               dim_tr_ops.pre_ready(ppre->di_wr_buf->vframe->omx_index);
+               if (ppre->pre_throw_flag > 0) {
+                       ppre->di_wr_buf->throw_flag = 1;
+                       ppre->pre_throw_flag--;
+               } else {
+                       ppre->di_wr_buf->throw_flag = 0;
+               }
+#ifdef DET3D
+               if (ppre->di_wr_buf->vframe->trans_fmt == 0     &&
+                   ppre->det3d_trans_fmt != 0                  &&
+                   dimp_get(eDI_MP_det3d_en)) {
+                       ppre->di_wr_buf->vframe->trans_fmt =
+                       ppre->det3d_trans_fmt;
+                       set3d_view(ppre->det3d_trans_fmt,
+                                  ppre->di_wr_buf->vframe);
+               }
+#endif
+               if (!di_pre_rdma_enable)
+                       ppre->di_post_wr_buf = ppre->di_wr_buf;
+               post_wr_buf = ppre->di_post_wr_buf;
+
+               if (post_wr_buf && !ppre->cur_prog_flag &&
+                   !flg_timeout) {
+                       dim_read_pulldown_info(&glb_frame_mot_num,
+                                              &glb_field_mot_num);
+                       if (dimp_get(eDI_MP_pulldown_enable))
+                               /*pulldown_detection*/
+                       get_ops_pd()->detection(&post_wr_buf->pd_config,
+                                               ppre->mtn_status,
+                                               overturn,
+                                               ppre->di_inp_buf->vframe);
+                       /*if (combing_fix_en)*/
+                       if (dimp_get(eDI_MP_combing_fix_en)) {
+                               tmp_cur_lev /*cur_lev*/
+                               = get_ops_mtn()->adaptive_combing_fixing(
+                                       ppre->mtn_status,
+                                       glb_field_mot_num,
+                                       glb_frame_mot_num,
+                                       dimp_get(eDI_MP_di_force_bit_mode));
+                               dimp_set(eDI_MP_cur_lev, tmp_cur_lev);
+                       }
+
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX))
+                               get_ops_nr()->adaptive_cue_adjust(
+                                       glb_frame_mot_num,
+                                       glb_field_mot_num);
+                       dim_pulldown_info_clear_g12a();
+               }
+
+               if (ppre->cur_prog_flag) {
+                       if (ppre->prog_proc_type == 0) {
+                               /* di_mem_buf_dup->vfrme
+                                * is either local vframe,
+                                * or bot field of vframe from in_list
+                                */
+                               ppre->di_mem_buf_dup_p->pre_ref_count = 0;
+                               ppre->di_mem_buf_dup_p
+                                       = ppre->di_chan2_buf_dup_p;
+                               ppre->di_chan2_buf_dup_p
+                                       = ppre->di_wr_buf;
+#ifdef DI_BUFFER_DEBUG
+                       dim_print("%s:set di_mem to di_chan2,", __func__);
+                       dim_print("%s:set di_chan2 to di_wr_buf\n", __func__);
+#endif
+                       } else {
+                               ppre->di_mem_buf_dup_p->pre_ref_count = 0;
+                               /*recycle the progress throw buffer*/
+                               if (ppre->di_wr_buf->throw_flag) {
+                                       ppre->di_wr_buf->
+                                               pre_ref_count = 0;
+                                       ppre->di_mem_buf_dup_p = NULL;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                               "%s set throw %s[%d] pre_ref_count to 0.\n",
+                               __func__,
+                               vframe_type_name[ppre->di_wr_buf->type],
+                               ppre->di_wr_buf->index);
+#endif
+                               } else {
+                                       ppre->di_mem_buf_dup_p
+                                               = ppre->di_wr_buf;
+                               }
+#ifdef DI_BUFFER_DEBUG
+                       dim_print(
+                               "%s: set di_mem_buf_dup_p to di_wr_buf\n",
+                               __func__);
+#endif
+                       }
+
+                       ppre->di_wr_buf->seq
+                               = ppre->pre_ready_seq++;
+                       ppre->di_wr_buf->post_ref_count = 0;
+                       ppre->di_wr_buf->left_right
+                               = ppre->left_right;
+                       if (ppre->source_change_flag) {
+                               ppre->di_wr_buf->new_format_flag = 1;
+                               ppre->source_change_flag = 0;
+                       } else {
+                               ppre->di_wr_buf->new_format_flag = 0;
+                       }
+                       if (di_bypass_state_get(channel) == 1) {
+                               ppre->di_wr_buf->new_format_flag = 1;
+                               /*bypass_state = 0;*/
+                               di_bypass_state_set(channel, false);
+#ifdef DI_BUFFER_DEBUG
+               dim_print(
+                       "%s:bypass_state->0, is_bypass() %d\n",
+                       __func__, dim_is_bypass(NULL, channel));
+               dim_print(
+                       "trick_mode %d bypass_all %d\n",
+                       trick_mode, di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL));
+#endif
+                       }
+                       if (ppre->di_post_wr_buf)
+                               di_que_in(channel, QUE_PRE_READY,
+                                         ppre->di_post_wr_buf);
+
+#ifdef DI_BUFFER_DEBUG
+                       dim_print(
+                               "%s: %s[%d] => pre_ready_list\n", __func__,
+                               vframe_type_name[ppre->di_wr_buf->type],
+                               ppre->di_wr_buf->index);
+#endif
+                       if (ppre->di_wr_buf) {
+                               if (di_pre_rdma_enable)
+                                       ppre->di_post_wr_buf =
+                               ppre->di_wr_buf;
+                               else
+                                       ppre->di_post_wr_buf = NULL;
+                               ppre->di_wr_buf = NULL;
+                       }
+               } else {
+                       ppre->di_mem_buf_dup_p->pre_ref_count = 0;
+                       ppre->di_mem_buf_dup_p = NULL;
+                       if (ppre->di_chan2_buf_dup_p) {
+                               ppre->di_mem_buf_dup_p =
+                                       ppre->di_chan2_buf_dup_p;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                               "%s: di_mem_buf_dup_p = di_chan2_buf_dup_p\n",
+                               __func__);
+#endif
+                       }
+                       ppre->di_chan2_buf_dup_p = ppre->di_wr_buf;
+
+                       if (ppre->source_change_flag) {
+                               /* add dummy buf, will not be displayed */
+                               add_dummy_vframe_type_pre(post_wr_buf,
+                                                         channel);
+                       }
+                       ppre->di_wr_buf->seq = ppre->pre_ready_seq++;
+                       ppre->di_wr_buf->left_right = ppre->left_right;
+                       ppre->di_wr_buf->post_ref_count = 0;
+
+                       if (ppre->source_change_flag) {
+                               ppre->di_wr_buf->new_format_flag = 1;
+                               ppre->source_change_flag = 0;
+                       } else {
+                               ppre->di_wr_buf->new_format_flag = 0;
+                       }
+                       if (di_bypass_state_get(channel) == 1) {
+                               ppre->di_wr_buf->new_format_flag = 1;
+                               /*bypass_state = 0;*/
+                               di_bypass_state_set(channel, false);
+
+#ifdef DI_BUFFER_DEBUG
+               dim_print(
+                       "%s:bypass_state->0, is_bypass() %d\n",
+                       __func__, dim_is_bypass(NULL, channel));
+               dim_print(
+                       "trick_mode %d bypass_all %d\n",
+                       trick_mode, di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL));
+#endif
+                       }
+
+                       if (ppre->di_post_wr_buf)
+                               di_que_in(channel, QUE_PRE_READY,
+                                         ppre->di_post_wr_buf);
+
+                       dim_print("%s: %s[%d] => pre_ready_list\n", __func__,
+                                 vframe_type_name[ppre->di_wr_buf->type],
+                                 ppre->di_wr_buf->index);
+
+                       if (ppre->di_wr_buf) {
+                               if (di_pre_rdma_enable)
+                                       ppre->di_post_wr_buf = ppre->di_wr_buf;
+                               else
+                                       ppre->di_post_wr_buf = NULL;
+
+                               ppre->di_wr_buf = NULL;
+                       }
+               }
+       }
+       if (ppre->di_post_inp_buf && di_pre_rdma_enable) {
+#ifdef DI_BUFFER_DEBUG
+               dim_print("%s: %s[%d] => recycle_list\n", __func__,
+                         vframe_type_name[ppre->di_post_inp_buf->type],
+                         ppre->di_post_inp_buf->index);
+#endif
+               di_lock_irqfiq_save(irq_flag2);
+               queue_in(channel, ppre->di_post_inp_buf, QUEUE_RECYCLE);
+               ppre->di_post_inp_buf = NULL;
+               di_unlock_irqfiq_restore(irq_flag2);
+       }
+       if (ppre->di_inp_buf) {
+               if (!di_pre_rdma_enable) {
+#ifdef DI_BUFFER_DEBUG
+                       dim_print("%s: %s[%d] => recycle_list\n", __func__,
+                                 vframe_type_name[ppre->di_inp_buf->type],
+                                 ppre->di_inp_buf->index);
+#endif
+                       di_lock_irqfiq_save(irq_flag2);
+                       queue_in(channel, ppre->di_inp_buf, QUEUE_RECYCLE);
+                       ppre->di_inp_buf = NULL;
+                       di_unlock_irqfiq_restore(irq_flag2);
+               } else {
+                       ppre->di_post_inp_buf = ppre->di_inp_buf;
+                       ppre->di_inp_buf = NULL;
+               }
+       }
+       dim_ddbg_mod_save(eDI_DBG_MOD_PRE_DONEE, channel, ppre->in_seq);/*dbg*/
+
+       dim_dbg_pre_cnt(channel, "d2");
+}
+
+static void recycle_vframe_type_pre(struct di_buf_s *di_buf,
+                                   unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+
+       di_lock_irqfiq_save(irq_flag2);
+
+       queue_in(channel, di_buf, QUEUE_RECYCLE);
+
+       di_unlock_irqfiq_restore(irq_flag2);
+}
+
+/*
+ * add dummy buffer to pre ready queue
+ */
+static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf,
+                                     unsigned int channel)
+{
+       struct di_buf_s *di_buf_tmp = NULL;
+
+       if (!queue_empty(channel, QUEUE_LOCAL_FREE)) {
+               di_buf_tmp = get_di_buf_head(channel, QUEUE_LOCAL_FREE);
+               if (di_buf_tmp) {
+                       queue_out(channel, di_buf_tmp);
+                       di_buf_tmp->pre_ref_count = 0;
+                       di_buf_tmp->post_ref_count = 0;
+                       di_buf_tmp->post_proc_flag = 3;
+                       di_buf_tmp->new_format_flag = 0;
+                       if (!IS_ERR_OR_NULL(src_buf))
+                               memcpy(di_buf_tmp->vframe, src_buf->vframe,
+                                      sizeof(vframe_t));
+
+                       di_que_in(channel, QUE_PRE_READY, di_buf_tmp);
+                       #ifdef DI_BUFFER_DEBUG
+                       dim_print("%s: dummy %s[%d] => pre_ready_list\n",
+                                 __func__,
+                                 vframe_type_name[di_buf_tmp->type],
+                                 di_buf_tmp->index);
+                       #endif
+               }
+       }
+}
+
+/*
+ * it depend on local buffer queue type is 2
+ */
+static int peek_free_linked_buf(unsigned int channel)
+{
+       struct di_buf_s *p = NULL;
+       int itmp, p_index = -2;
+
+       if (list_count(channel, QUEUE_LOCAL_FREE) < 2)
+               return -1;
+
+       queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) {
+               if (abs(p->index - p_index) == 1)
+                       return min(p->index, p_index);
+               p_index = p->index;
+       }
+       return -1;
+}
+
+/*
+ * it depend on local buffer queue type is 2
+ */
+static struct di_buf_s *get_free_linked_buf(int idx, unsigned int channel)
+{
+       struct di_buf_s *di_buf = NULL, *di_buf_linked = NULL;
+       int pool_idx = 0, di_buf_idx = 0;
+       struct queue_s *pqueue = get_queue(channel);
+       struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
+
+       queue_t *q = &pqueue[QUEUE_LOCAL_FREE];
+
+       if (list_count(channel, QUEUE_LOCAL_FREE) < 2)
+               return NULL;
+       if (q->pool[idx] != 0 && q->pool[idx + 1] != 0) {
+               pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1;
+               di_buf_idx = q->pool[idx] & 0xff;
+               if (pool_idx < VFRAME_TYPE_NUM) {
+                       if (di_buf_idx < pbuf_pool[pool_idx].size) {
+                               di_buf = &(pbuf_pool[pool_idx].
+                                       di_buf_ptr[di_buf_idx]);
+                               queue_out(channel, di_buf);
+                       }
+               }
+               pool_idx = ((q->pool[idx + 1] >> 8) & 0xff) - 1;
+               di_buf_idx = q->pool[idx + 1] & 0xff;
+               if (pool_idx < VFRAME_TYPE_NUM) {
+                       if (di_buf_idx < pbuf_pool[pool_idx].size) {
+                               di_buf_linked = &(pbuf_pool[pool_idx].
+                                       di_buf_ptr[di_buf_idx]);
+                               queue_out(channel, di_buf_linked);
+                       }
+               }
+               if (IS_ERR_OR_NULL(di_buf))
+                       return NULL;
+               di_buf->di_wr_linked_buf = di_buf_linked;
+       }
+       return di_buf;
+}
+
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+static void pre_inp_canvas_config(struct vframe_s *vf)
+{
+       if (vf->canvas0Addr == (u32)-1) {
+               canvas_config_config(di_inp_idx[0],
+                                    &vf->canvas0_config[0]);
+               canvas_config_config(di_inp_idx[1],
+                                    &vf->canvas0_config[1]);
+               vf->canvas0Addr = (di_inp_idx[1] << 8) | (di_inp_idx[0]);
+               if (vf->plane_num == 2) {
+                       vf->canvas0Addr |= (di_inp_idx[1] << 16);
+               } else if (vf->plane_num == 3) {
+                       canvas_config_config(di_inp_idx[2],
+                                            &vf->canvas0_config[2]);
+                       vf->canvas0Addr |= (di_inp_idx[2] << 16);
+               }
+               vf->canvas1Addr = vf->canvas0Addr;
+       }
+}
+#endif
+
+#if 0
+bool di_get_pre_hsc_down_en(void)
+{
+       return pre_hsc_down_en;
+}
+#endif
+bool dbg_first_frame;  /*debug */
+unsigned int  dbg_first_cnt_pre;
+unsigned int  dbg_first_cnt_post;
+#define DI_DBG_CNT     (2)
+void dim_dbg_pre_cnt(unsigned int channel, char *item)
+{
+       bool flgs = false;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (ppre->field_count_for_cont < DI_DBG_CNT) {
+               dbg_first_frame("%d:%s:%d\n", channel, item,
+                               ppre->field_count_for_cont);
+               dbg_first_frame = true;
+               flgs = true;
+               dbg_first_cnt_pre = DI_DBG_CNT * 5;
+               dbg_first_cnt_post = DI_DBG_CNT * 4 + 1;
+       } else if (ppre->field_count_for_cont == DI_DBG_CNT) {/*don't use >=*/
+               dbg_first_frame = false;
+               dbg_first_cnt_pre = 0;
+               dbg_first_cnt_post = 0;
+       }
+
+       if ((dbg_first_frame) && !flgs && dbg_first_cnt_pre) {
+               dbg_first_frame("%d:n%s:%d\n", channel, item,
+                               ppre->field_count_for_cont);
+               dbg_first_cnt_pre--;
+       }
+}
+
+static void dbg_post_cnt(unsigned int ch, char *item)
+{
+       struct di_post_stru_s *ppost = get_post_stru(ch);
+
+       if (dbg_first_cnt_post) {
+               dbg_first_frame("%d:%s:%d\n", ch, item,
+                               ppost->frame_cnt);
+               dbg_first_cnt_post--;
+       }
+}
+
+#if 0
+/*must been called when dim_pre_de_buf_config return true*/
+void pre_p_asi_set_next(unsigned int ch)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+
+       ppre->p_asi_next = ppre->di_inp_buf;
+}
+#endif
+
+unsigned char pre_p_asi_de_buf_config(unsigned int ch)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+
+#if 0
+       if (di_blocking || !dip_cma_st_is_ready(ch))
+               return 0;
+
+       if (di_que_list_count(ch, QUE_IN_FREE) < 1)
+               return 0;
+
+       if (queue_empty(ch, QUEUE_LOCAL_FREE))
+               return 0;
+#endif
+       ppre->di_inp_buf = ppre->di_inp_buf_next;
+       ppre->di_inp_buf_next = NULL;
+
+       if (!ppre->di_mem_buf_dup_p) {/* use n */
+               ppre->di_mem_buf_dup_p = ppre->di_inp_buf;
+       }
+
+       return 1;
+}
+
+/*for first frame no need to ready buf*/
+bool dim_bypass_first_frame(unsigned int ch)
+{
+       struct di_buf_s *di_buf = NULL;
+       struct di_buf_s *di_buf_post = NULL;
+       struct vframe_s *vframe;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+       struct vframe_s **pvframe_in = get_vframe_in(ch);
+       ulong irq_flag2 = 0;
+
+       vframe = pw_vf_peek(ch);
+
+       if (!vframe)
+               return false;
+       if (di_que_is_empty(ch, QUE_POST_FREE))
+               return false;
+
+       vframe = pw_vf_get(ch);
+
+       di_buf = di_que_out_to_di_buf(ch, QUE_IN_FREE);
+
+       if (dim_check_di_buf(di_buf, 10, ch))
+               return 0;
+
+       memcpy(di_buf->vframe, vframe, sizeof(struct vframe_s));
+       di_buf->vframe->private_data = di_buf;
+       pvframe_in[di_buf->index] = vframe;
+       di_buf->seq = ppre->in_seq;
+       ppre->in_seq++;
+
+       #if 0
+
+       if (vframe->type & VIDTYPE_COMPRESS) {  /*?*/
+               vframe->width = vframe->compWidth;
+               vframe->height = vframe->compHeight;
+       }
+
+       di_que_in(ch, QUE_PRE_READY, di_buf);
+       #endif
+
+       di_buf_post = di_que_out_to_di_buf(ch, QUE_POST_FREE);
+       memcpy(di_buf_post->vframe, vframe, sizeof(struct vframe_s));
+       di_buf_post->vframe->private_data = di_buf_post;
+       di_lock_irqfiq_save(irq_flag2);
+
+       di_que_in(ch, QUE_POST_READY, di_buf_post);
+
+       di_unlock_irqfiq_restore(irq_flag2);
+       pw_vf_notify_receiver(ch,
+                             VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+
+       PR_INF("%s:ok\n", __func__);
+       return true;
+}
+
+unsigned char dim_pre_de_buf_config(unsigned int channel)
+{
+       struct di_buf_s *di_buf = NULL;
+       struct vframe_s *vframe;
+       int i, di_linked_buf_idx = -1;
+       unsigned char change_type = 0;
+       unsigned char change_type2 = 0;
+       bool bit10_pack_patch = false;
+       unsigned int width_roundup = 2;
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       int cfg_prog_proc = dimp_get(eDI_MP_prog_proc_config);
+
+       if (di_blocking || !dip_cma_st_is_ready(channel))
+               return 0;
+
+       if (di_que_list_count(channel, QUE_IN_FREE) < 1)
+               return 0;
+
+       if ((di_que_list_count(channel, QUE_IN_FREE) < 2        &&
+            (!ppre->di_inp_buf_next))                          ||
+           (queue_empty(channel, QUEUE_LOCAL_FREE)))
+               return 0;
+
+       if (di_que_list_count(channel, QUE_PRE_READY) >= DI_PRE_READY_LIMIT)
+               return 0;
+
+       if (dim_is_bypass(NULL, channel)) {
+               /* some provider has problem if receiver
+                * get all buffers of provider
+                */
+               int in_buf_num = 0;
+               /*cur_lev = 0;*/
+               dimp_set(eDI_MP_cur_lev, 0);
+               for (i = 0; i < MAX_IN_BUF_NUM; i++)
+                       if (pvframe_in[i])
+                               in_buf_num++;
+               if (in_buf_num > BYPASS_GET_MAX_BUF_NUM
+#ifdef DET3D
+                       && (ppre->vframe_interleave_flag == 0)
+#endif
+                   )
+                       return 0;
+
+               dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
+       } else if (ppre->prog_proc_type == 2) {
+               di_linked_buf_idx = peek_free_linked_buf(channel);
+               if (di_linked_buf_idx == -1 &&
+                   !IS_ERR_OR_NULL(ppost->keep_buf)) {
+                       recycle_keep_buffer(channel);
+               pr_info("%s: recycle keep buffer for peek null linked buf\n",
+                       __func__);
+                       return 0;
+               }
+       }
+       if (ppre->di_inp_buf_next) {
+               ppre->di_inp_buf = ppre->di_inp_buf_next;
+               ppre->di_inp_buf_next = NULL;
+#ifdef DI_BUFFER_DEBUG
+               dim_print("%s: di_inp_buf_next %s[%d] => di_inp_buf\n",
+                         __func__,
+                         vframe_type_name[ppre->di_inp_buf->type],
+                         ppre->di_inp_buf->index);
+#endif
+               if (!ppre->di_mem_buf_dup_p) {/* use n */
+                       ppre->di_mem_buf_dup_p = ppre->di_inp_buf;
+#ifdef DI_BUFFER_DEBUG
+                       dim_print(
+                               "%s: set di_mem_buf_dup_p to be di_inp_buf\n",
+                               __func__);
+#endif
+               }
+       } else {
+               /* check if source change */
+               vframe = pw_vf_peek(channel);
+
+               if (vframe && is_from_vdin(vframe)) {
+#ifdef RUN_DI_PROCESS_IN_IRQ
+                       ppre->vdin2nr = is_input2pre(channel);
+#endif
+               }
+
+               vframe = pw_vf_get(channel);
+
+               if (!vframe)
+                       return 0;
+
+               dim_tr_ops.pre_get(vframe->omx_index);
+               didbg_vframe_in_copy(channel, vframe);
+
+               if (vframe->type & VIDTYPE_COMPRESS) {
+                       vframe->width = vframe->compWidth;
+                       vframe->height = vframe->compHeight;
+               }
+               dim_print("DI:ch[%d] get %dth vf[0x%p] from frontend %u ms.\n",
+                         channel,
+                         ppre->in_seq, vframe,
+                         jiffies_to_msecs(jiffies_64 -
+                         vframe->ready_jiffies64));
+               vframe->prog_proc_config
+                       = (cfg_prog_proc & 0x20) >> 5;
+
+               if (vframe->width > 10000 || vframe->height > 10000 ||
+                   hold_video || ppre->bad_frame_throw_count > 0) {
+                       if (vframe->width > 10000 || vframe->height > 10000)
+                               ppre->bad_frame_throw_count = 10;
+                       ppre->bad_frame_throw_count--;
+                       pw_vf_put(vframe, channel);
+                       pw_vf_notify_provider(
+                               channel, VFRAME_EVENT_RECEIVER_PUT, NULL);
+                       return 0;
+               }
+               bit10_pack_patch =  (is_meson_gxtvbb_cpu() ||
+                                                       is_meson_gxl_cpu() ||
+                                                       is_meson_gxm_cpu());
+               width_roundup = bit10_pack_patch ? 16 : width_roundup;
+               if (dimp_get(eDI_MP_di_force_bit_mode) == 10)
+                       dimp_set(eDI_MP_force_width,
+                                roundup(vframe->width, width_roundup));
+               else
+                       dimp_set(eDI_MP_force_width, 0);
+               ppre->source_trans_fmt = vframe->trans_fmt;
+               ppre->left_right = ppre->left_right ? 0 : 1;
+               ppre->invert_flag =
+                       (vframe->type &  TB_DETECT_MASK) ? true : false;
+               vframe->type &= ~TB_DETECT_MASK;
+
+               if ((((invert_top_bot & 0x2) != 0)      ||
+                    ppre->invert_flag)                 &&
+                   (!is_progressive(vframe))) {
+                       if (
+                               (vframe->type & VIDTYPE_TYPEMASK) ==
+                               VIDTYPE_INTERLACE_TOP) {
+                               vframe->type &= (~VIDTYPE_TYPEMASK);
+                               vframe->type |= VIDTYPE_INTERLACE_BOTTOM;
+                       } else {
+                               vframe->type &= (~VIDTYPE_TYPEMASK);
+                               vframe->type |= VIDTYPE_INTERLACE_TOP;
+                       }
+               }
+               ppre->width_bk = vframe->width;
+               if (dimp_get(eDI_MP_force_width))
+                       vframe->width = dimp_get(eDI_MP_force_width);
+               if (dimp_get(eDI_MP_force_height))
+                       vframe->height = dimp_get(eDI_MP_force_height);
+
+               /* backup frame motion info */
+               vframe->combing_cur_lev = dimp_get(eDI_MP_cur_lev);/*cur_lev;*/
+
+               dim_print("%s: vf_get => 0x%p\n", __func__, vframe);
+
+               di_buf = di_que_out_to_di_buf(channel, QUE_IN_FREE);
+
+               if (dim_check_di_buf(di_buf, 10, channel))
+                       return 0;
+
+               if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_VFRAME)
+                       dim_dump_vframe(vframe);
+
+#ifdef SUPPORT_MPEG_TO_VDIN
+               if (
+                       (!is_from_vdin(vframe)) &&
+                       (vframe->sig_fmt == TVIN_SIG_FMT_NULL) &&
+                       mpeg2vdin_flag) {
+                       struct vdin_arg_s vdin_arg;
+                       struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops();
+
+                       vdin_arg.cmd = VDIN_CMD_GET_HISTGRAM;
+                       vdin_arg.private = (unsigned int)vframe;
+                       if (vdin_ops->tvin_vdin_func)
+                               vdin_ops->tvin_vdin_func(0, &vdin_arg);
+               }
+#endif
+               memcpy(di_buf->vframe, vframe, sizeof(vframe_t));
+               dim_dbg_pre_cnt(channel, "cf1");
+               di_buf->width_bk = ppre->width_bk;      /*ary.sui 2019-04-23*/
+               di_buf->vframe->private_data = di_buf;
+               pvframe_in[di_buf->index] = vframe;
+               di_buf->seq = ppre->in_seq;
+               ppre->in_seq++;
+
+               pre_vinfo_set(channel, vframe);
+               change_type = is_source_change(vframe, channel);
+               #if 0
+               if (!change_type)
+                       change_type = is_vinfo_change(channel);
+               #endif
+               /* source change, when i mix p,force p as i*/
+               if (change_type == 1 || (change_type == 2 &&
+                                        ppre->cur_prog_flag == 1)) {
+                       if (ppre->di_mem_buf_dup_p) {
+                               /*avoid only 2 i field then p field*/
+                               if (
+                                       (ppre->cur_prog_flag == 0) &&
+                                       dimp_get(eDI_MP_use_2_interlace_buff))
+                                       ppre->di_mem_buf_dup_p->
+                                       post_proc_flag = -1;
+                               ppre->di_mem_buf_dup_p->pre_ref_count = 0;
+                               ppre->di_mem_buf_dup_p = NULL;
+                       }
+                       if (ppre->di_chan2_buf_dup_p) {
+                               /*avoid only 1 i field then p field*/
+                               if (
+                                       (ppre->cur_prog_flag == 0) &&
+                                       dimp_get(eDI_MP_use_2_interlace_buff))
+                                       ppre->di_chan2_buf_dup_p->
+                                       post_proc_flag = -1;
+                               ppre->di_chan2_buf_dup_p->pre_ref_count =
+                                       0;
+                               ppre->di_chan2_buf_dup_p = NULL;
+                       }
+                       #if 0
+                       /* channel change will occur between atv and dtv,
+                        * that need mirror
+                        */
+                       if (!IS_ERR_OR_NULL(di_post_stru.keep_buf)) {
+                               if (di_post_stru.keep_buf->vframe
+                                       ->source_type !=
+                                       di_buf->vframe->source_type) {
+                                       recycle_keep_buffer();
+                                       pr_info("%s: source type changed recycle buffer!!!\n",
+                                               __func__);
+                               }
+                       }
+                       #endif
+                       pr_info(
+                       "%s:ch[%d]:%ums %dth source change: 0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n",
+                               __func__,
+                               channel,
+                               jiffies_to_msecs(jiffies_64),
+                               ppre->in_seq,
+                               ppre->cur_inp_type,
+                               ppre->cur_width,
+                               ppre->cur_height,
+                               ppre->cur_source_type,
+                               di_buf->vframe->type,
+                               di_buf->vframe->width,
+                               di_buf->vframe->height,
+                               di_buf->vframe->source_type);
+                       if (di_buf->type & VIDTYPE_COMPRESS) {
+                               ppre->cur_width =
+                                       di_buf->vframe->compWidth;
+                               ppre->cur_height =
+                                       di_buf->vframe->compHeight;
+                       } else {
+                               ppre->cur_width = di_buf->vframe->width;
+                               ppre->cur_height = di_buf->vframe->height;
+                       }
+                       ppre->cur_prog_flag =
+                               is_progressive(di_buf->vframe);
+                       if (ppre->cur_prog_flag) {
+                               if ((dimp_get(eDI_MP_use_2_interlace_buff)) &&
+                                   !(cfg_prog_proc & 0x10))
+                                       ppre->prog_proc_type = 2;
+                               else
+                                       ppre->prog_proc_type
+                                               = cfg_prog_proc & 0x10;
+                       } else {
+                               ppre->prog_proc_type = 0;
+                       }
+                       ppre->cur_inp_type = di_buf->vframe->type;
+                       ppre->cur_source_type =
+                               di_buf->vframe->source_type;
+                       ppre->cur_sig_fmt = di_buf->vframe->sig_fmt;
+                       ppre->orientation = di_buf->vframe->video_angle;
+                       ppre->source_change_flag = 1;
+                       ppre->input_size_change_flag = true;
+#ifdef SUPPORT_MPEG_TO_VDIN
+                       if ((!is_from_vdin(vframe)) &&
+                           (vframe->sig_fmt == TVIN_SIG_FMT_NULL) &&
+                           (mpeg2vdin_en)) {
+                               struct vdin_arg_s vdin_arg;
+                               struct vdin_v4l2_ops_s *vdin_ops =
+                                       get_vdin_v4l2_ops();
+                               vdin_arg.cmd = VDIN_CMD_MPEGIN_START;
+                               vdin_arg.h_active = ppre->cur_width;
+                               vdin_arg.v_active = ppre->cur_height;
+                               if (vdin_ops->tvin_vdin_func)
+                                       vdin_ops->tvin_vdin_func(0, &vdin_arg);
+                               mpeg2vdin_flag = 1;
+                       }
+#endif
+                       ppre->field_count_for_cont = 0;
+               } else if (ppre->cur_prog_flag == 0) {
+                       /* check if top/bot interleaved */
+                       if (change_type == 2)
+                               /* source is i interleaves p fields */
+                               ppre->force_interlace = true;
+                       if ((ppre->cur_inp_type &
+                       VIDTYPE_TYPEMASK) == (di_buf->vframe->type &
+                       VIDTYPE_TYPEMASK)) {
+                               if ((di_buf->vframe->type &
+                               VIDTYPE_TYPEMASK) ==
+                               VIDTYPE_INTERLACE_TOP)
+                                       same_field_top_count++;
+                               else
+                                       same_field_bot_count++;
+                       }
+                       ppre->cur_inp_type = di_buf->vframe->type;
+               } else {
+                       ppre->cur_inp_type = di_buf->vframe->type;
+               }
+               /*--------------------------*/
+               if (!change_type) {
+                       change_type2 = is_vinfo_change(channel);
+                       if (change_type2) {
+                               /*ppre->source_change_flag = 1;*/
+                               ppre->input_size_change_flag = true;
+                       }
+               }
+
+               /*--------------------------*/
+               if (dim_is_bypass(di_buf->vframe, channel)
+                       /*|| is_bypass_i_p()*/
+                       /*|| ((ppre->pre_ready_seq % 5)== 0)*/
+                       /*|| (ppre->pre_ready_seq == 10)*/
+                       ) {
+                       /* bypass progressive */
+                       di_buf->seq = ppre->pre_ready_seq++;
+                       di_buf->post_ref_count = 0;
+                       /*cur_lev = 0;*/
+                       dimp_set(eDI_MP_cur_lev, 0);
+                       if (ppre->source_change_flag) {
+                               di_buf->new_format_flag = 1;
+                               ppre->source_change_flag = 0;
+                       } else {
+                               di_buf->new_format_flag = 0;
+                       }
+
+               if (di_bypass_state_get(channel) == 0) {
+                       if (ppre->di_mem_buf_dup_p) {
+                               ppre->di_mem_buf_dup_p->pre_ref_count = 0;
+                               ppre->di_mem_buf_dup_p = NULL;
+                       }
+                       if (ppre->di_chan2_buf_dup_p) {
+                               ppre->di_chan2_buf_dup_p->pre_ref_count = 0;
+                               ppre->di_chan2_buf_dup_p = NULL;
+                       }
+
+                               if (ppre->di_wr_buf) {
+                                       ppre->di_wr_buf->pre_ref_count = 0;
+                                       ppre->di_wr_buf->post_ref_count = 0;
+                                       recycle_vframe_type_pre(
+                                               ppre->di_wr_buf, channel);
+#ifdef DI_BUFFER_DEBUG
+                       dim_print(
+                               "%s: %s[%d] => recycle_list\n",
+                               __func__,
+                               vframe_type_name[ppre->di_wr_buf->type],
+                               ppre->di_wr_buf->index);
+#endif
+                                       ppre->di_wr_buf = NULL;
+                               }
+
+                       di_buf->new_format_flag = 1;
+                       di_bypass_state_set(channel, true);/*bypass_state:1;*/
+
+                       dim_print(
+                               "%s:bypass_state = 1, is_bypass() %d\n",
+                               __func__, dim_is_bypass(NULL, channel));
+#ifdef DI_BUFFER_DEBUG
+
+                       dim_print(
+                               "trick_mode %d bypass_all %d\n",
+                               trick_mode,
+                               di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL));
+#endif
+                       }
+
+                       top_bot_config(di_buf);
+
+                       di_que_in(channel, QUE_PRE_READY, di_buf);
+                       /*if previous isn't bypass post_wr_buf not recycled */
+                       if (ppre->di_post_wr_buf && di_pre_rdma_enable) {
+                               queue_in(channel, ppre->di_post_inp_buf,
+                                        QUEUE_RECYCLE);
+                               ppre->di_post_inp_buf = NULL;
+                       }
+
+                       if ((bypass_pre & 0x2) && !ppre->cur_prog_flag)
+                               di_buf->post_proc_flag = -2;
+                       else
+                               di_buf->post_proc_flag = 0;
+
+                       dim_print("di:cfg:post_proc_flag=%d\n",
+                                 di_buf->post_proc_flag);
+#ifdef DI_BUFFER_DEBUG
+                       dim_print(
+                               "%s: %s[%d] => pre_ready_list\n", __func__,
+                               vframe_type_name[di_buf->type], di_buf->index);
+#endif
+                       return 0;
+               } else if (is_progressive(di_buf->vframe)) {
+                       if (is_handle_prog_frame_as_interlace(vframe) &&
+                           is_progressive(vframe)) {
+                               struct di_buf_s *di_buf_tmp = NULL;
+
+                               pvframe_in[di_buf->index] = NULL;
+                               di_buf->vframe->type &=
+                                       (~VIDTYPE_TYPEMASK);
+                               di_buf->vframe->type |=
+                                       VIDTYPE_INTERLACE_TOP;
+                               di_buf->post_proc_flag = 0;
+
+               di_buf_tmp = di_que_out_to_di_buf(channel, QUE_IN_FREE);
+               if (dim_check_di_buf(di_buf_tmp, 10, channel)) {
+                       recycle_vframe_type_pre(di_buf, channel);
+                       PR_ERR("DI:no free in_buffer for progressive skip.\n");
+                       return 0;
+               }
+
+                               di_buf_tmp->vframe->private_data = di_buf_tmp;
+                               di_buf_tmp->seq = ppre->in_seq;
+                               ppre->in_seq++;
+                               pvframe_in[di_buf_tmp->index] = vframe;
+                               memcpy(di_buf_tmp->vframe, vframe,
+                                      sizeof(vframe_t));
+                               ppre->di_inp_buf_next = di_buf_tmp;
+                               di_buf_tmp->vframe->type &=
+                                       (~VIDTYPE_TYPEMASK);
+                               di_buf_tmp->vframe->type |=
+                                       VIDTYPE_INTERLACE_BOTTOM;
+                               di_buf_tmp->post_proc_flag = 0;
+
+                               ppre->di_inp_buf = di_buf;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                       "%s: %s[%d] => di_inp_buf; %s[%d] => di_inp_buf_next\n",
+                                       __func__,
+                                       vframe_type_name[di_buf->type],
+                                       di_buf->index,
+                                       vframe_type_name[di_buf_tmp->type],
+                                       di_buf_tmp->index);
+#endif
+                               if (!ppre->di_mem_buf_dup_p) {
+                                       ppre->di_mem_buf_dup_p = di_buf;
+#ifdef DI_BUFFER_DEBUG
+                                       dim_print(
+                               "%s: set di_mem_buf_dup_p to be di_inp_buf\n",
+                                               __func__);
+#endif
+                               }
+                       } else {
+                               di_buf->post_proc_flag = 0;
+                               if ((cfg_prog_proc & 0x40) ||
+                                   ppre->force_interlace)
+                                       di_buf->post_proc_flag = 1;
+
+                               ppre->di_inp_buf = di_buf;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                                       "%s: %s[%d] => di_inp_buf\n",
+                                       __func__,
+                                       vframe_type_name[di_buf->type],
+                                       di_buf->index);
+#endif
+                               if (!ppre->di_mem_buf_dup_p) {
+                                       /* use n */
+                                       ppre->di_mem_buf_dup_p = di_buf;
+#ifdef DI_BUFFER_DEBUG
+                                       dim_print(
+                               "%s: set di_mem_buf_dup_p to be di_inp_buf\n",
+                                               __func__);
+#endif
+                               }
+                       }
+               } else {
+               /*********************************/
+               if ((di_buf->vframe->width >= 1920)     &&
+                   (di_buf->vframe->height >= 1080)    &&
+                   is_meson_tl1_cpu()) {
+                       /*if (combing_fix_en) {*/
+                       if (dimp_get(eDI_MP_combing_fix_en)) {
+                               /*combing_fix_en = false;*/
+                               dimp_set(eDI_MP_combing_fix_en, 0);
+                               get_ops_mtn()->fix_tl1_1080i_sawtooth_patch();
+                       }
+               } else {
+                       /*combing_fix_en = true;*/
+                       dimp_set(eDI_MP_combing_fix_en, 1);
+               }
+
+               /*********************************/
+                       if (!ppre->di_chan2_buf_dup_p) {
+                               ppre->field_count_for_cont = 0;
+                               /* ignore contp2rd and contprd */
+                       }
+                       di_buf->post_proc_flag = 1;
+                       ppre->di_inp_buf = di_buf;
+                       dim_print("%s: %s[%d] => di_inp_buf\n", __func__,
+                                 vframe_type_name[di_buf->type],
+                                 di_buf->index);
+
+                       if (!ppre->di_mem_buf_dup_p) {/* use n */
+                               ppre->di_mem_buf_dup_p = di_buf;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                               "%s: set di_mem_buf_dup_p to be di_inp_buf\n",
+                                       __func__);
+#endif
+                       }
+               }
+       }
+       /*dim_dbg_pre_cnt(channel, "cfg");*/
+       /* di_wr_buf */
+       if (ppre->prog_proc_type == 2) {
+               di_linked_buf_idx = peek_free_linked_buf(channel);
+               if (di_linked_buf_idx != -1)
+                       di_buf = get_free_linked_buf(di_linked_buf_idx,
+                                                    channel);
+               else
+                       di_buf = NULL;
+               if (!di_buf) {
+                       /* recycle_vframe_type_pre(di_pre_stru.di_inp_buf);
+                        *save for next process
+                        */
+                       recycle_keep_buffer(channel);
+                       ppre->di_inp_buf_next = ppre->di_inp_buf;
+                       return 0;
+               }
+               di_buf->post_proc_flag = 0;
+               di_buf->di_wr_linked_buf->pre_ref_count = 0;
+               di_buf->di_wr_linked_buf->post_ref_count = 0;
+               di_buf->canvas_config_flag = 1;
+       } else {
+               di_buf = get_di_buf_head(channel, QUEUE_LOCAL_FREE);
+               if (dim_check_di_buf(di_buf, 11, channel)) {
+                       /* recycle_keep_buffer();
+                        *  pr_dbg("%s:recycle keep buffer\n", __func__);
+                        */
+                       recycle_vframe_type_pre(ppre->di_inp_buf, channel);
+                       return 0;
+               }
+               queue_out(channel, di_buf);/*QUEUE_LOCAL_FREE*/
+               if (ppre->prog_proc_type & 0x10)
+                       di_buf->canvas_config_flag = 1;
+               else
+                       di_buf->canvas_config_flag = 2;
+               di_buf->di_wr_linked_buf = NULL;
+       }
+
+       ppre->di_wr_buf = di_buf;
+       ppre->di_wr_buf->pre_ref_count = 1;
+
+#ifdef DI_BUFFER_DEBUG
+       dim_print("%s: %s[%d] => di_wr_buf\n", __func__,
+                 vframe_type_name[di_buf->type], di_buf->index);
+       if (di_buf->di_wr_linked_buf)
+               dim_print("%s: linked %s[%d] => di_wr_buf\n", __func__,
+                         vframe_type_name[di_buf->di_wr_linked_buf->type],
+                         di_buf->di_wr_linked_buf->index);
+#endif
+       if (ppre->cur_inp_type & VIDTYPE_COMPRESS) {
+               ppre->di_inp_buf->vframe->width =
+                       ppre->di_inp_buf->vframe->compWidth;
+               ppre->di_inp_buf->vframe->height =
+                       ppre->di_inp_buf->vframe->compHeight;
+       }
+
+       memcpy(di_buf->vframe,
+              ppre->di_inp_buf->vframe, sizeof(vframe_t));
+       di_buf->vframe->private_data = di_buf;
+       di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx;
+       di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx;
+       /* set vframe bit info */
+       di_buf->vframe->bitdepth &= ~(BITDEPTH_YMASK);
+       di_buf->vframe->bitdepth &= ~(FULL_PACK_422_MODE);
+       if (de_devp->pps_enable && dimp_get(eDI_MP_pps_position)) {
+               if (dimp_get(eDI_MP_pps_dstw) != di_buf->vframe->width) {
+                       di_buf->vframe->width = dimp_get(eDI_MP_pps_dstw);
+                       ppre->width_bk = dimp_get(eDI_MP_pps_dstw);
+               }
+               if (dimp_get(eDI_MP_pps_dsth) != di_buf->vframe->height)
+                       di_buf->vframe->height = dimp_get(eDI_MP_pps_dsth);
+       } else if (de_devp->h_sc_down_en) {
+               if (di_mp_uit_get(eDI_MP_pre_hsc_down_width)
+                       != di_buf->vframe->width) {
+                       pr_info("di: hscd %d to %d\n", di_buf->vframe->width,
+                               di_mp_uit_get(eDI_MP_pre_hsc_down_width));
+                       di_buf->vframe->width =
+                               di_mp_uit_get(eDI_MP_pre_hsc_down_width);
+                       /*di_pre_stru.width_bk = pre_hsc_down_width;*/
+                       di_buf->width_bk =
+                               di_mp_uit_get(eDI_MP_pre_hsc_down_width);
+               }
+       }
+       if (dimp_get(eDI_MP_di_force_bit_mode) == 10) {
+               di_buf->vframe->bitdepth |= (BITDEPTH_Y10);
+               if (dimp_get(eDI_MP_full_422_pack))
+                       di_buf->vframe->bitdepth |= (FULL_PACK_422_MODE);
+       } else {
+               di_buf->vframe->bitdepth |= (BITDEPTH_Y8);
+       }
+       di_buf->width_bk = ppre->width_bk;      /*ary:2019-04-23*/
+       if (ppre->prog_proc_type) {
+               di_buf->vframe->type = VIDTYPE_PROGRESSIVE |
+                                      VIDTYPE_VIU_422 |
+                                      VIDTYPE_VIU_SINGLE_PLANE |
+                                      VIDTYPE_VIU_FIELD;
+               if (ppre->cur_inp_type & VIDTYPE_PRE_INTERLACE)
+                       di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE;
+       } else {
+               if (
+                       ((ppre->di_inp_buf->vframe->type &
+                         VIDTYPE_TYPEMASK) ==
+                        VIDTYPE_INTERLACE_TOP))
+                       di_buf->vframe->type = VIDTYPE_INTERLACE_TOP |
+                                              VIDTYPE_VIU_422 |
+                                              VIDTYPE_VIU_SINGLE_PLANE |
+                                              VIDTYPE_VIU_FIELD;
+               else
+                       di_buf->vframe->type = VIDTYPE_INTERLACE_BOTTOM |
+                                              VIDTYPE_VIU_422 |
+                                              VIDTYPE_VIU_SINGLE_PLANE |
+                                              VIDTYPE_VIU_FIELD;
+               /*add for vpp skip line ref*/
+               if (di_bypass_state_get(channel) == 0)
+                       di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE;
+       }
+
+       if (is_bypass_post(channel)) {
+               if (dimp_get(eDI_MP_bypass_post_state) == 0)
+                       ppre->source_change_flag = 1;
+
+               dimp_set(eDI_MP_bypass_post_state, 1);
+       } else {
+               if (dimp_get(eDI_MP_bypass_post_state))
+                       ppre->source_change_flag = 1;
+
+               dimp_set(eDI_MP_bypass_post_state, 0);
+       }
+
+       if (ppre->di_inp_buf->post_proc_flag == 0) {
+               ppre->madi_enable = 0;
+               ppre->mcdi_enable = 0;
+               di_buf->post_proc_flag = 0;
+               dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
+       } else if (dimp_get(eDI_MP_bypass_post_state)) {
+               ppre->madi_enable = 0;
+               ppre->mcdi_enable = 0;
+               di_buf->post_proc_flag = 0;
+               dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
+       } else {
+               ppre->madi_enable = (dimp_get(eDI_MP_pre_enable_mask) & 1);
+               ppre->mcdi_enable =
+                       ((dimp_get(eDI_MP_pre_enable_mask) >> 1) & 1);
+               di_buf->post_proc_flag = 1;
+               dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER,
+                                            dimp_get(eDI_MP_mcpre_en));/*en*/
+       }
+       if ((ppre->di_mem_buf_dup_p == ppre->di_wr_buf) ||
+           (ppre->di_chan2_buf_dup_p == ppre->di_wr_buf)) {
+               pr_dbg("+++++++++++++++++++++++\n");
+               if (recovery_flag == 0)
+                       recovery_log_reason = 12;
+
+               recovery_flag++;
+               return 0;
+       }
+       return 1;
+}
+
+int dim_check_recycle_buf(unsigned int channel)
+{
+       struct di_buf_s *di_buf = NULL;/* , *ptmp; */
+       int itmp;
+       int ret = 0;
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (di_blocking)
+               return ret;
+       queue_for_each_entry(di_buf, channel, QUEUE_RECYCLE, list) {
+               if ((di_buf->pre_ref_count == 0) &&
+                   (di_buf->post_ref_count <= 0)) {    /*ary maybe <=*/
+                       if (di_buf->type == VFRAME_TYPE_IN) {
+                               queue_out(channel, di_buf);
+                               if (pvframe_in[di_buf->index]) {
+                                       pw_vf_put(
+                                               pvframe_in[di_buf->index],
+                                               channel);
+                                       pw_vf_notify_provider(channel,
+                                               VFRAME_EVENT_RECEIVER_PUT,
+                                               NULL);
+                       dim_print(
+                               "%s: ch[%d],vf_put(%d) %x, %u ms\n",
+                               __func__,
+                               channel,
+                               ppre->recycle_seq,
+                               pvframe_in[di_buf->index],
+                               jiffies_to_msecs(jiffies_64 -
+                               pvframe_in[di_buf->index]->ready_jiffies64));
+                                       pvframe_in[di_buf->index] = NULL;
+                               }
+                               di_buf->invert_top_bot_flag = 0;
+
+                               di_que_in(channel, QUE_IN_FREE, di_buf);
+                               ppre->recycle_seq++;
+                               ret |= 1;
+                       } else {
+                               queue_out(channel, di_buf);
+                               di_buf->invert_top_bot_flag = 0;
+                               queue_in(channel, di_buf, QUEUE_LOCAL_FREE);
+                               di_buf->post_ref_count = 0;/*ary maybe*/
+                               if (di_buf->di_wr_linked_buf) {
+                                       queue_in(channel,
+                                                di_buf->di_wr_linked_buf,
+                                                QUEUE_LOCAL_FREE);
+#ifdef DI_BUFFER_DEBUG
+                                       dim_print(
+                                       "%s: linked %s[%d]=>recycle_list\n",
+                                               __func__,
+                                               vframe_type_name[
+                                               di_buf->di_wr_linked_buf->type],
+                                               di_buf->di_wr_linked_buf->index
+                                       );
+#endif
+                                       di_buf->di_wr_linked_buf = NULL;
+                               }
+                               ret |= 2;
+                       }
+#ifdef DI_BUFFER_DEBUG
+                       dim_print("%s: recycle %s[%d]\n", __func__,
+                                 vframe_type_name[di_buf->type],
+                                 di_buf->index);
+#endif
+               }
+       }
+       return ret;
+}
+
+#ifdef DET3D
+static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf)
+{
+       struct vframe_view_s *left_eye, *right_eye;
+
+       left_eye = &vf->left_eye;
+       right_eye = &vf->right_eye;
+
+       switch (trans_fmt) {
+       case TVIN_TFMT_3D_DET_LR:
+       case TVIN_TFMT_3D_LRH_OLOR:
+               left_eye->start_x = 0;
+               left_eye->start_y = 0;
+               left_eye->width = vf->width >> 1;
+               left_eye->height = vf->height;
+               right_eye->start_x = vf->width >> 1;
+               right_eye->start_y = 0;
+               right_eye->width = vf->width >> 1;
+               right_eye->height = vf->height;
+               break;
+       case TVIN_TFMT_3D_DET_TB:
+       case TVIN_TFMT_3D_TB:
+               left_eye->start_x = 0;
+               left_eye->start_y = 0;
+               left_eye->width = vf->width;
+               left_eye->height = vf->height >> 1;
+               right_eye->start_x = 0;
+               right_eye->start_y = vf->height >> 1;
+               right_eye->width = vf->width;
+               right_eye->height = vf->height >> 1;
+               break;
+       case TVIN_TFMT_3D_DET_INTERLACE:
+               left_eye->start_x = 0;
+               left_eye->start_y = 0;
+               left_eye->width = vf->width;
+               left_eye->height = vf->height >> 1;
+               right_eye->start_x = 0;
+               right_eye->start_y = 0;
+               right_eye->width = vf->width;
+               right_eye->height = vf->height >> 1;
+               break;
+       case TVIN_TFMT_3D_DET_CHESSBOARD:
+/***
+ * LRLRLR        LRLRLR
+ * LRLRLR  or RLRLRL
+ * LRLRLR        LRLRLR
+ * LRLRLR        RLRLRL
+ */
+               break;
+       default: /* 2D */
+               left_eye->start_x = 0;
+               left_eye->start_y = 0;
+               left_eye->width = 0;
+               left_eye->height = 0;
+               right_eye->start_x = 0;
+               right_eye->start_y = 0;
+               right_eye->width = 0;
+               right_eye->height = 0;
+               break;
+       }
+}
+
+/*
+ * static int get_3d_info(struct vframe_s *vf)
+ * {
+ * int ret = 0;
+ *
+ * vf->trans_fmt = det3d_fmt_detect();
+ * pr_dbg("[det3d..]new 3d fmt: %d\n", vf->trans_fmt);
+ *
+ * vdin_set_view(vf->trans_fmt, vf);
+ *
+ * return ret;
+ * }
+ */
+static unsigned int det3d_frame_cnt = 50;
+module_param_named(det3d_frame_cnt, det3d_frame_cnt, uint, 0644);
+static void det3d_irq(unsigned int channel)
+{
+       unsigned int data32 = 0, likely_val = 0;
+       unsigned long frame_sum = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (!dimp_get(eDI_MP_det3d_en))
+               return;
+
+       data32 = get_ops_3d()->det3d_fmt_detect();/*det3d_fmt_detect();*/
+       switch (data32) {
+       case TVIN_TFMT_3D_DET_LR:
+       case TVIN_TFMT_3D_LRH_OLOR:
+               ppre->det_lr++;
+               break;
+       case TVIN_TFMT_3D_DET_TB:
+       case TVIN_TFMT_3D_TB:
+               ppre->det_tp++;
+               break;
+       case TVIN_TFMT_3D_DET_INTERLACE:
+               ppre->det_la++;
+               break;
+       default:
+               ppre->det_null++;
+               break;
+       }
+
+       if (det3d_mode != data32) {
+               det3d_mode = data32;
+               dim_print("[det3d..]new 3d fmt: %d\n", det3d_mode);
+       }
+       if (frame_count > 20) {
+               frame_sum = ppre->det_lr + ppre->det_tp
+                                       + ppre->det_la
+                                       + ppre->det_null;
+               if ((frame_count % det3d_frame_cnt) || (frame_sum > UINT_MAX))
+                       return;
+               likely_val = max3(ppre->det_lr,
+                                 ppre->det_tp,
+                                 ppre->det_la);
+               if (ppre->det_null >= likely_val)
+                       det3d_mode = 0;
+               else if (likely_val == ppre->det_lr)
+                       det3d_mode = TVIN_TFMT_3D_LRH_OLOR;
+               else if (likely_val == ppre->det_tp)
+                       det3d_mode = TVIN_TFMT_3D_TB;
+               else
+                       det3d_mode = TVIN_TFMT_3D_DET_INTERLACE;
+               ppre->det3d_trans_fmt = det3d_mode;
+       } else {
+               ppre->det3d_trans_fmt = 0;
+       }
+}
+#endif
+
+static unsigned int ro_mcdi_col_cfd[26];
+static void get_mcinfo_from_reg_in_irq(unsigned int channel)
+{
+       unsigned int i = 0, ncolcrefsum = 0, blkcount = 0, *reg = NULL;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+/*get info for current field process by post*/
+       ppre->di_wr_buf->curr_field_mcinfo.highvertfrqflg =
+               (Rd(MCDI_RO_HIGH_VERT_FRQ_FLG) & 0x1);
+/* post:MCDI_MC_REL_GAIN_OFFST_0 */
+       ppre->di_wr_buf->curr_field_mcinfo.motionparadoxflg =
+               (Rd(MCDI_RO_MOTION_PARADOX_FLG) & 0x1);
+/* post:MCDI_MC_REL_GAIN_OFFST_0 */
+       reg = ppre->di_wr_buf->curr_field_mcinfo.regs;
+       for (i = 0; i < 26; i++) {
+               ro_mcdi_col_cfd[i] = Rd(0x2fb0 + i);
+               ppre->di_wr_buf->curr_field_mcinfo.regs[i] = 0;
+               if (!dimp_get(eDI_MP_calc_mcinfo_en))
+                       *(reg + i) = ro_mcdi_col_cfd[i];
+       }
+       if (dimp_get(eDI_MP_calc_mcinfo_en)) {
+               blkcount = (ppre->cur_width + 4) / 5;
+               for (i = 0; i < blkcount; i++) {
+                       ncolcrefsum +=
+                               ((ro_mcdi_col_cfd[i / 32] >> (i % 32)) & 0x1);
+                       if (
+                               ((ncolcrefsum + (blkcount >> 1)) << 8) /
+                               blkcount > dimp_get(eDI_MP_colcfd_thr))
+                               for (i = 0; i < blkcount; i++)
+                                       *(reg + i / 32) += (1 << (i % 32));
+               }
+       }
+}
+
+static unsigned int bit_reverse(unsigned int val)
+{
+       unsigned int i = 0, res = 0;
+
+       for (i = 0; i < 16; i++) {
+               res |= (((val & (1 << i)) >> i) << (31 - i));
+               res |= (((val & (1 << (31 - i))) << i) >> (31 - i));
+       }
+       return res;
+}
+
+static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo)
+{
+       unsigned int i = 0, value = 0;
+
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0,
+                                  curr_field_mcinfo->highvertfrqflg, 24, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0,
+                                  curr_field_mcinfo->motionparadoxflg, 25, 1);
+       for (i = 0; i < 26; i++) {
+               if (overturn)
+                       value = bit_reverse(curr_field_mcinfo->regs[i]);
+               else
+                       value = curr_field_mcinfo->regs[i];
+               dim_VSYNC_WR_MPEG_REG(0x2f78 + i, value);
+       }
+}
+
+static unsigned char intr_mode;
+
+irqreturn_t dim_irq(int irq, void *dev_instance)
+{
+       unsigned int channel;
+       struct di_pre_stru_s *ppre;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       struct di_hpre_s  *pre = get_hw_pre();
+
+#ifndef CHECK_DI_DONE
+       unsigned int data32 = Rd(DI_INTR_CTRL);
+       unsigned int mask32 = (data32 >> 16) & 0x3ff;
+       unsigned int flag = 0;
+
+       channel = pre->curr_ch;
+       ppre = pre->pres;
+
+       data32 &= 0x3fffffff;
+       if ((data32 & 1) == 0 && dimp_get(eDI_MP_di_dbg_mask) & 8)
+               pr_info("irq[%d]pre|post=0 write done.\n", irq);
+       if (ppre->pre_de_busy) {
+               /* only one inetrrupr mask should be enable */
+               if ((data32 & 2) && !(mask32 & 2)) {
+                       dim_print("irq pre MTNWR ==ch[%d]\n", channel);
+                       flag = 1;
+               } else if ((data32 & 1) && !(mask32 & 1)) {
+                       dim_print("irq pre NRWR ==ch[%d]\n", channel);
+                       flag = 1;
+               } else {
+                       dim_print("irq pre DI IRQ 0x%x ==\n", data32);
+                       flag = 0;
+               }
+       }
+
+#else
+       channel = pre->curr_ch;
+       ppre = pre->pres;
+#endif
+
+#ifdef DET3D
+       if (dimp_get(eDI_MP_det3d_en)) {
+               if ((data32 & 0x100) && !(mask32 & 0x100) && flag) {
+                       dim_DI_Wr(DI_INTR_CTRL, data32);
+                       det3d_irq(channel);
+               } else {
+                       goto end;
+               }
+       } else {
+               dim_DI_Wr(DI_INTR_CTRL, data32);
+       }
+#else
+       if (flag)
+               dim_DI_Wr(DI_INTR_CTRL,
+                         (data32 & 0xfffffffb) | (intr_mode << 30));
+#endif
+
+       /*if (ppre->pre_de_busy == 0) {*/
+       if (!di_pre_wait_irq_get()) {
+               PR_ERR("%s:ch[%d]:enter:reg[0x%x]= 0x%x,dtab[%d]\n", __func__,
+                      channel,
+                      DI_INTR_CTRL,
+                      Rd(DI_INTR_CTRL),
+                      pre->sdt_mode.op_crr);
+               return IRQ_HANDLED;
+       }
+
+       if (flag) {
+               ppre->irq_time[0] =
+                       (cur_to_msecs() - ppre->irq_time[0]);
+
+               dim_tr_ops.pre(ppre->field_count_for_cont, ppre->irq_time[0]);
+
+               /*add from valsi wang.feng*/
+               dim_arb_sw(false);
+               dim_arb_sw(true);
+               if (dimp_get(eDI_MP_mcpre_en)) {
+                       get_mcinfo_from_reg_in_irq(channel);
+                       if ((is_meson_gxlx_cpu()                &&
+                            ppre->field_count_for_cont >= 4)   ||
+                           is_meson_txhd_cpu())
+                               dimh_mc_pre_mv_irq();
+                       dimh_calc_lmv_base_mcinfo((ppre->cur_height >> 1),
+                                                 ppre->di_wr_buf->mcinfo_adr,
+                                                 ppre->mcinfo_size);
+               }
+               get_ops_nr()->nr_process_in_irq();
+               if ((data32 & 0x200) && de_devp->nrds_enable)
+                       dim_nr_ds_irq();
+               /* disable mif */
+               dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en));
+
+               ppre->pre_de_busy = 0;
+
+               if (get_init_flag(channel))
+                       /* pr_dbg("%s:up di sema\n", __func__); */
+                       task_send_ready();
+
+               pre->flg_int_done = 1;
+       }
+
+       return IRQ_HANDLED;
+}
+
+irqreturn_t dim_post_irq(int irq, void *dev_instance)
+{
+       unsigned int data32 = Rd(DI_INTR_CTRL);
+       unsigned int channel;
+       struct di_post_stru_s *ppost;
+       struct di_hpst_s  *pst = get_hw_pst();
+
+       channel = pst->curr_ch;
+       ppost = pst->psts;
+
+       data32 &= 0x3fffffff;
+       if ((data32 & 4) == 0) {
+               if (dimp_get(eDI_MP_di_dbg_mask) & 8)
+                       pr_info("irq[%d]post write undone.\n", irq);
+                       return IRQ_HANDLED;
+       }
+
+       if (pst->state != eDI_PST_ST_WAIT_INT) {
+               PR_ERR("%s:ch[%d]:s[%d]\n", __func__, channel, pst->state);
+               ddbg_sw(eDI_LOG_TYPE_MOD, false);
+               return IRQ_HANDLED;
+       }
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_IRQB, pst->curr_ch,
+                         ppost->frame_cnt);
+       dim_tr_ops.post_ir(0);
+
+       if ((dimp_get(eDI_MP_post_wr_en)        &&
+            dimp_get(eDI_MP_post_wr_support))  &&
+           (data32 & 0x4)) {
+               ppost->de_post_process_done = 1;
+               ppost->post_de_busy = 0;
+               ppost->irq_time =
+                       (cur_to_msecs() - ppost->irq_time);
+
+               dim_tr_ops.post(ppost->post_wr_cnt, ppost->irq_time);
+
+               dim_DI_Wr(DI_INTR_CTRL,
+                         (data32 & 0xffff0004) | (intr_mode << 30));
+               /* disable wr back avoid pps sreay in g12a */
+               dim_DI_Wr_reg_bits(DI_POST_CTRL, 0, 7, 1);
+               di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP);  /*dbg a*/
+               dim_print("irq p ch[%d]done\n", channel);
+               pst->flg_int_done = true;
+       }
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_IRQE, pst->curr_ch,
+                         ppost->frame_cnt);
+
+       if (get_init_flag(channel))
+               task_send_ready();
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * di post process
+ */
+static void inc_post_ref_count(struct di_buf_s *di_buf)
+{
+       int i;  /*debug only:*/
+
+       /* int post_blend_mode; */
+       if (IS_ERR_OR_NULL(di_buf)) {
+               PR_ERR("%s:\n", __func__);
+               if (recovery_flag == 0)
+                       recovery_log_reason = 13;
+
+               recovery_flag++;
+               return;
+       }
+
+       if (di_buf->di_buf_dup_p[1])
+               di_buf->di_buf_dup_p[1]->post_ref_count++;
+
+       if (di_buf->di_buf_dup_p[0])
+               di_buf->di_buf_dup_p[0]->post_ref_count++;
+
+       if (di_buf->di_buf_dup_p[2])
+               di_buf->di_buf_dup_p[2]->post_ref_count++;
+
+       /*debug only:*/
+       for (i = 0; i < 3; i++) {
+               if (di_buf->di_buf_dup_p[i])
+                       dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n",
+                                    __func__,
+                                    di_buf->index,
+                                    i,
+                                    di_buf->di_buf_dup_p[i]->post_ref_count);
+       }
+}
+
+static void dec_post_ref_count(struct di_buf_s *di_buf)
+{
+       int i;  /*debug only:*/
+
+       if (IS_ERR_OR_NULL(di_buf)) {
+               PR_ERR("%s:\n", __func__);
+               if (recovery_flag == 0)
+                       recovery_log_reason = 14;
+
+               recovery_flag++;
+               return;
+       }
+       if (di_buf->pd_config.global_mode == PULL_DOWN_BUF1)
+               return;
+       if (di_buf->di_buf_dup_p[1])
+               di_buf->di_buf_dup_p[1]->post_ref_count--;
+
+       if (di_buf->di_buf_dup_p[0] &&
+           di_buf->di_buf_dup_p[0]->post_proc_flag != -2)
+               di_buf->di_buf_dup_p[0]->post_ref_count--;
+
+       if (di_buf->di_buf_dup_p[2])
+               di_buf->di_buf_dup_p[2]->post_ref_count--;
+
+       /*debug only:*/
+       for (i = 0; i < 3; i++) {
+               if (di_buf->di_buf_dup_p[i])
+                       dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n",
+                                    __func__,
+                                    di_buf->index,
+                                    i,
+                                    di_buf->di_buf_dup_p[i]->post_ref_count);
+       }
+}
+
+#if 0  /*no use*/
+static void vscale_skip_disable_post(struct di_buf_s *di_buf,
+                                    vframe_t *disp_vf, unsigned int channel)
+{
+       struct di_buf_s *di_buf_i = NULL;
+       int canvas_height = di_buf->di_buf[0]->canvas_height;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       if (di_vscale_skip_enable & 0x2) {/* drop the bottom field */
+               if ((di_buf->di_buf_dup_p[0]) && (di_buf->di_buf_dup_p[1]))
+                       di_buf_i =
+                               (di_buf->di_buf_dup_p[1]->vframe->type &
+                                VIDTYPE_TYPEMASK) ==
+                               VIDTYPE_INTERLACE_TOP ? di_buf->di_buf_dup_p[1]
+                               : di_buf->di_buf_dup_p[0];
+               else
+                       di_buf_i = di_buf->di_buf[0];
+       } else {
+               if ((di_buf->di_buf[0]->post_proc_flag > 0) &&
+                   (di_buf->di_buf_dup_p[1]))
+                       di_buf_i = di_buf->di_buf_dup_p[1];
+               else
+                       di_buf_i = di_buf->di_buf[0];
+       }
+       disp_vf->type = di_buf_i->vframe->type;
+       /* pr_dbg("%s (%x %x) (%x %x)\n", __func__,
+        * disp_vf, disp_vf->type, di_buf_i->vframe,
+        * di_buf_i->vframe->type);
+        */
+       disp_vf->width = di_buf_i->vframe->width;
+       disp_vf->height = di_buf_i->vframe->height;
+       disp_vf->duration = di_buf_i->vframe->duration;
+       disp_vf->pts = di_buf_i->vframe->pts;
+       disp_vf->flag = di_buf_i->vframe->flag;
+       disp_vf->canvas0Addr = di_post_idx[ppost->canvas_id][0];
+       disp_vf->canvas1Addr = di_post_idx[ppost->canvas_id][0];
+       canvas_config(
+               di_post_idx[ppost->canvas_id][0],
+               di_buf_i->nr_adr, di_buf_i->canvas_width[NR_CANVAS],
+               canvas_height, 0, 0);
+       dimh_disable_post_deinterlace_2();
+       ppost->vscale_skip_flag = true;
+}
+#endif
+
+/*early_process_fun*/
+static int early_NONE(void)
+{
+       return 0;
+}
+
+int dim_do_post_wr_fun(void *arg, vframe_t *disp_vf)
+{
+       #if 0
+       struct di_post_stru_s *ppost;
+       int i;
+
+       for (i = 0; i < DI_CHANNEL_NUB; i++) {
+               ppost = get_post_stru(i);
+
+               ppost->toggle_flag = true;
+       }
+       return 1;
+       #else
+       return early_NONE();
+       #endif
+}
+
+static int de_post_disable_fun(void *arg, vframe_t *disp_vf)
+{
+       #if 0
+       struct di_buf_s *di_buf = (struct di_buf_s *)arg;
+       unsigned int channel = di_buf->channel;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       ppost->vscale_skip_flag = false;
+       ppost->toggle_flag = true;
+
+       PR_ERR("%s------------------------------\n", __func__);
+
+       process_vscale_skip(di_buf, disp_vf, channel);
+/* for atv static image flickering */
+       if (di_buf->process_fun_index == PROCESS_FUN_NULL)
+               dimh_disable_post_deinterlace_2();
+
+       return 1;
+/* called for new_format_flag, make
+ * video set video_property_changed
+ */
+       #else
+       return early_NONE();
+       #endif
+}
+
+static int do_nothing_fun(void *arg, vframe_t *disp_vf)
+{
+       #if 0
+       struct di_buf_s *di_buf = (struct di_buf_s *)arg;
+       unsigned int channel = di_buf->channel;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       ppost->vscale_skip_flag = false;
+       ppost->toggle_flag = true;
+
+       PR_ERR("%s------------------------------\n", __func__);
+
+       process_vscale_skip(di_buf, disp_vf, channel);
+
+       if (di_buf->process_fun_index == PROCESS_FUN_NULL) {
+               if (Rd(DI_IF1_GEN_REG) & 0x1 || Rd(DI_POST_CTRL) & 0xf)
+                       dimh_disable_post_deinterlace_2();
+       /*if(di_buf->pulldown_mode == PULL_DOWN_EI && Rd(DI_IF1_GEN_REG)&0x1)
+        * dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30);
+        */
+       }
+       return 0;
+       #else
+       return early_NONE();
+       #endif
+}
+
+static int do_pre_only_fun(void *arg, vframe_t *disp_vf)
+{
+       #if 0
+       unsigned int channel;
+       struct di_post_stru_s *ppost;
+
+       PR_ERR("%s------------------------------\n", __func__);
+#ifdef DI_USE_FIXED_CANVAS_IDX
+       if (arg) {
+               struct di_buf_s *di_buf = (struct di_buf_s *)arg;
+               vframe_t *vf = di_buf->vframe;
+               int width, canvas_height;
+
+               channel = di_buf->channel;
+               ppost = get_post_stru(channel);
+
+               ppost->vscale_skip_flag = false;
+               ppost->toggle_flag = true;
+
+               if (!vf || !di_buf->di_buf[0]) {
+                       dim_print("error:%s,NULL point!!\n", __func__);
+                       return 0;
+               }
+               width = di_buf->di_buf[0]->canvas_width[NR_CANVAS];
+               /* linked two interlace buffer should double height*/
+               if (di_buf->di_buf[0]->di_wr_linked_buf)
+                       canvas_height =
+                       (di_buf->di_buf[0]->canvas_height << 1);
+               else
+                       canvas_height =
+                       di_buf->di_buf[0]->canvas_height;
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+               if (is_vsync_rdma_enable()) {
+                       ppost->canvas_id = ppost->next_canvas_id;
+               } else {
+                       ppost->canvas_id = 0;
+                       ppost->next_canvas_id = 1;
+                       if (post_wr_en && post_wr_support)
+                               ppost->canvas_id = ppost->next_canvas_id;
+               }
+#endif
+
+               canvas_config(
+                       di_post_idx[ppost->canvas_id][0],
+                       di_buf->di_buf[0]->nr_adr,
+                       di_buf->di_buf[0]->canvas_width[NR_CANVAS],
+                       canvas_height, 0, 0);
+
+               vf->canvas0Addr =
+                       di_post_idx[ppost->canvas_id][0];
+               vf->canvas1Addr =
+                       di_post_idx[ppost->canvas_id][0];
+#ifdef DET3D
+               if (ppre->vframe_interleave_flag && di_buf->di_buf[1]) {
+                       canvas_config(
+                               di_post_idx[ppost->canvas_id][1],
+                               di_buf->di_buf[1]->nr_adr,
+                               di_buf->di_buf[1]->canvas_width[NR_CANVAS],
+                               canvas_height, 0, 0);
+                       vf->canvas1Addr =
+                               di_post_idx[ppost->canvas_id][1];
+                       vf->duration <<= 1;
+               }
+#endif
+               ppost->next_canvas_id = ppost->canvas_id ? 0 : 1;
+
+               if (di_buf->process_fun_index == PROCESS_FUN_NULL) {
+                       if (Rd(DI_IF1_GEN_REG) & 0x1 ||
+                           Rd(DI_POST_CTRL) & 0x10f)
+                               dimh_disable_post_deinterlace_2();
+               }
+       }
+#endif
+
+       return 0;
+#else
+       return early_NONE();
+#endif
+}
+
+static void get_vscale_skip_count(unsigned int par)
+{
+       /*di_vscale_skip_count_real = (par >> 24) & 0xff;*/
+       dimp_set(eDI_MP_di_vscale_skip_count_real,
+                (par >> 24) & 0xff);
+}
+
+#define get_vpp_reg_update_flag(par) (((par) >> 16) & 0x1)
+
+static unsigned int pldn_dly = 1;
+
+int dim_post_process(void *arg, unsigned int zoom_start_x_lines,
+                    unsigned int zoom_end_x_lines,
+                    unsigned int zoom_start_y_lines,
+                    unsigned int zoom_end_y_lines,
+                    vframe_t *disp_vf)
+{
+       struct di_buf_s *di_buf = (struct di_buf_s *)arg;
+       struct di_buf_s *di_pldn_buf = NULL;
+       unsigned int di_width, di_height, di_start_x, di_end_x, mv_offset;
+       unsigned int di_start_y, di_end_y, hold_line;
+       unsigned int post_blend_en = 0, post_blend_mode = 0,
+                    blend_mtn_en = 0, ei_en = 0, post_field_num = 0;
+       int di_vpp_en, di_ddr_en;
+       unsigned char mc_pre_flag = 0;
+       bool invert_mv = false;
+       static int post_index = -1;
+       unsigned char tmp_idx = 0;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       struct di_hpst_s  *pst = get_hw_pst();
+
+       unsigned char channel = pst->curr_ch;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       dimp_inc(eDI_MP_post_cnt);
+       if (ppost->vscale_skip_flag)
+               return 0;
+
+       get_vscale_skip_count(zoom_start_x_lines);
+
+       if (IS_ERR_OR_NULL(di_buf))
+               return 0;
+       else if (IS_ERR_OR_NULL(di_buf->di_buf_dup_p[0]))
+               return 0;
+
+       hold_line = dimp_get(eDI_MP_post_hold_line);
+       di_pldn_buf = di_buf->di_buf_dup_p[pldn_dly];
+
+       if (di_que_is_in_que(channel, QUE_POST_FREE, di_buf) &&
+           post_index != di_buf->index) {
+               post_index = di_buf->index;
+               PR_ERR("%s:post_buf[%d] is in post free list.\n",
+                      __func__, di_buf->index);
+               return 0;
+       }
+       hpst_dbg_mem_pd_trig(0);
+
+       if (ppost->toggle_flag && di_buf->di_buf_dup_p[1])
+               top_bot_config(di_buf->di_buf_dup_p[1]);
+
+       ppost->toggle_flag = false;
+
+       ppost->cur_disp_index = di_buf->index;
+
+       if (get_vpp_reg_update_flag(zoom_start_x_lines) ||
+           dimp_get(eDI_MP_post_refresh))
+               ppost->update_post_reg_flag = 1;
+
+       zoom_start_x_lines = zoom_start_x_lines & 0xffff;
+       zoom_end_x_lines = zoom_end_x_lines & 0xffff;
+       zoom_start_y_lines = zoom_start_y_lines & 0xffff;
+       zoom_end_y_lines = zoom_end_y_lines & 0xffff;
+
+       if (!get_init_flag(channel) && IS_ERR_OR_NULL(ppost->keep_buf)) {
+               PR_ERR("%s 2:\n", __func__);
+               return 0;
+       }
+       dim_tr_ops.post_set(di_buf->vframe->omx_index);
+       /*dbg*/
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_SETB, channel, ppost->frame_cnt);
+       dbg_post_cnt(channel, "ps1");
+       di_start_x = zoom_start_x_lines;
+       di_end_x = zoom_end_x_lines;
+       di_width = di_end_x - di_start_x + 1;
+       di_start_y = zoom_start_y_lines;
+       di_end_y = zoom_end_y_lines;
+       di_height = di_end_y - di_start_y + 1;
+       di_height
+       = di_height / (dimp_get(eDI_MP_di_vscale_skip_count_real) + 1);
+       /* make sure the height is even number */
+       if (di_height % 2) {
+               /*for skip mode,post only half line-1*/
+               if (!dimp_get(eDI_MP_post_wr_en)        &&
+                   ((di_height > 150)                  &&
+                   (di_height < 1080))                 &&
+                   dimp_get(eDI_MP_di_vscale_skip_count_real))
+                       di_height = di_height - 3;
+               else
+                       di_height++;
+       }
+       #if 0
+       dimh_post_ctrl(DI_HW_POST_CTRL_INIT,
+                      (post_wr_en && post_wr_support));
+       #endif
+
+       if (Rd(DI_POST_SIZE) != ((di_width - 1) | ((di_height - 1) << 16)) ||
+           ppost->buf_type != di_buf->di_buf_dup_p[0]->type ||
+           (ppost->di_buf0_mif.luma_x_start0 != di_start_x) ||
+           (ppost->di_buf0_mif.luma_y_start0 != di_start_y / 2)) {
+               dim_ddbg_mod_save(eDI_DBG_MOD_POST_RESIZE, channel,
+                                 ppost->frame_cnt);/*dbg*/
+               ppost->buf_type = di_buf->di_buf_dup_p[0]->type;
+
+               dimh_initial_di_post_2(di_width, di_height,
+                                      hold_line,
+                       (dimp_get(eDI_MP_post_wr_en) &&
+                       dimp_get(eDI_MP_post_wr_support)));
+
+               if (!di_buf->di_buf_dup_p[0]->vframe ||
+                   !di_buf->vframe) {
+                       PR_ERR("%s 3:\n", __func__);
+                       return 0;
+               }
+               /* bit mode config */
+               if (di_buf->vframe->bitdepth & BITDEPTH_Y10) {
+                       if (di_buf->vframe->type & VIDTYPE_VIU_444) {
+                               ppost->di_buf0_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2;
+                               ppost->di_buf1_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2;
+                               ppost->di_buf2_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2;
+                               ppost->di_diwr_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2;
+
+                       } else {
+                               ppost->di_buf0_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1;
+                               ppost->di_buf1_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1;
+                               ppost->di_buf2_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1;
+                               ppost->di_diwr_mif.bit_mode =
+               (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1;
+                       }
+               } else {
+                       ppost->di_buf0_mif.bit_mode = 0;
+                       ppost->di_buf1_mif.bit_mode = 0;
+                       ppost->di_buf2_mif.bit_mode = 0;
+                       ppost->di_diwr_mif.bit_mode = 0;
+               }
+               if (di_buf->vframe->type & VIDTYPE_VIU_444) {
+                       ppost->di_buf0_mif.video_mode = 1;
+                       ppost->di_buf1_mif.video_mode = 1;
+                       ppost->di_buf2_mif.video_mode = 1;
+               } else {
+                       ppost->di_buf0_mif.video_mode = 0;
+                       ppost->di_buf1_mif.video_mode = 0;
+                       ppost->di_buf2_mif.video_mode = 0;
+               }
+               if (ppost->buf_type == VFRAME_TYPE_IN &&
+                   !(di_buf->di_buf_dup_p[0]->vframe->type &
+                     VIDTYPE_VIU_FIELD)) {
+                       if (di_buf->vframe->type & VIDTYPE_VIU_NV21) {
+                               ppost->di_buf0_mif.set_separate_en = 1;
+                               ppost->di_buf1_mif.set_separate_en = 1;
+                               ppost->di_buf2_mif.set_separate_en = 1;
+                       } else {
+                               ppost->di_buf0_mif.set_separate_en = 0;
+                               ppost->di_buf1_mif.set_separate_en = 0;
+                               ppost->di_buf2_mif.set_separate_en = 0;
+                       }
+                       ppost->di_buf0_mif.luma_y_start0 = di_start_y;
+                       ppost->di_buf0_mif.luma_y_end0 = di_end_y;
+               } else { /* from vdin or local vframe process by di pre */
+                       ppost->di_buf0_mif.set_separate_en = 0;
+                       ppost->di_buf0_mif.luma_y_start0 =
+                               di_start_y >> 1;
+                       ppost->di_buf0_mif.luma_y_end0 = di_end_y >> 1;
+                       ppost->di_buf1_mif.set_separate_en = 0;
+                       ppost->di_buf1_mif.luma_y_start0 =
+                               di_start_y >> 1;
+                       ppost->di_buf1_mif.luma_y_end0 = di_end_y >> 1;
+                       ppost->di_buf2_mif.set_separate_en = 0;
+                       ppost->di_buf2_mif.luma_y_end0 = di_end_y >> 1;
+                       ppost->di_buf2_mif.luma_y_start0 =
+                               di_start_y >> 1;
+               }
+               ppost->di_buf0_mif.luma_x_start0 = di_start_x;
+               ppost->di_buf0_mif.luma_x_end0 = di_end_x;
+               ppost->di_buf1_mif.luma_x_start0 = di_start_x;
+               ppost->di_buf1_mif.luma_x_end0 = di_end_x;
+               ppost->di_buf2_mif.luma_x_start0 = di_start_x;
+               ppost->di_buf2_mif.luma_x_end0 = di_end_x;
+
+               if (dimp_get(eDI_MP_post_wr_en) &&
+                   dimp_get(eDI_MP_post_wr_support)) {
+                       if (de_devp->pps_enable &&
+                           dimp_get(eDI_MP_pps_position) == 0) {
+                               dim_pps_config(0, di_width, di_height,
+                                              dimp_get(eDI_MP_pps_dstw),
+                                              dimp_get(eDI_MP_pps_dsth));
+                               ppost->di_diwr_mif.start_x = 0;
+                               ppost->di_diwr_mif.end_x
+                                       = dimp_get(eDI_MP_pps_dstw) - 1;
+                               ppost->di_diwr_mif.start_y = 0;
+                               ppost->di_diwr_mif.end_y
+                                       = dimp_get(eDI_MP_pps_dsth) - 1;
+                       } else {
+                               ppost->di_diwr_mif.start_x = di_start_x;
+                               ppost->di_diwr_mif.end_x   = di_end_x;
+                               ppost->di_diwr_mif.start_y = di_start_y;
+                               ppost->di_diwr_mif.end_y   = di_end_y;
+                       }
+               }
+
+               ppost->di_mtnprd_mif.start_x = di_start_x;
+               ppost->di_mtnprd_mif.end_x = di_end_x;
+               ppost->di_mtnprd_mif.start_y = di_start_y >> 1;
+               ppost->di_mtnprd_mif.end_y = di_end_y >> 1;
+               if (dimp_get(eDI_MP_mcpre_en)) {
+                       ppost->di_mcvecrd_mif.start_x = di_start_x / 5;
+                       mv_offset = (di_start_x % 5) ? (5 - di_start_x % 5) : 0;
+                       ppost->di_mcvecrd_mif.vecrd_offset =
+                               overturn ? (di_end_x + 1) % 5 : mv_offset;
+                       ppost->di_mcvecrd_mif.start_y =
+                               (di_start_y >> 1);
+                       ppost->di_mcvecrd_mif.size_x =
+                               (di_end_x + 1 + 4) / 5 - 1 - di_start_x / 5;
+                       ppost->di_mcvecrd_mif.end_y =
+                               (di_end_y >> 1);
+               }
+               ppost->update_post_reg_flag = 1;
+               /* if height decrease, mtn will not enough */
+               if (di_buf->pd_config.global_mode != PULL_DOWN_BUF1 &&
+                   !dimp_get(eDI_MP_post_wr_en))
+                       di_buf->pd_config.global_mode = PULL_DOWN_EI;
+       }
+
+#ifdef DI_USE_FIXED_CANVAS_IDX
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+       if (is_vsync_rdma_enable()) {
+               ppost->canvas_id = ppost->next_canvas_id;
+       } else {
+               ppost->canvas_id = 0;
+               ppost->next_canvas_id = 1;
+               if (dimp_get(eDI_MP_post_wr_en) &&
+                   dimp_get(eDI_MP_post_wr_support))
+                       ppost->canvas_id =
+                               ppost->next_canvas_id;
+       }
+#endif
+       /*post_blend = di_buf->pd_config.global_mode;*/
+       dimp_set(eDI_MP_post_blend, di_buf->pd_config.global_mode);
+       dim_print("%s:ch[%d]\n", __func__, channel);
+       switch (dimp_get(eDI_MP_post_blend)) {
+       case PULL_DOWN_BLEND_0:
+       case PULL_DOWN_NORMAL:
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[1],
+                       di_post_idx[ppost->canvas_id][0], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[2], -1,
+                       di_post_idx[ppost->canvas_id][2]);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[0],
+                       di_post_idx[ppost->canvas_id][1], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[2],
+                       di_post_idx[ppost->canvas_id][3], -1);
+               if (dimp_get(eDI_MP_mcpre_en))
+                       config_mcvec_canvas_idx(
+                               di_buf->di_buf_dup_p[2],
+                               di_post_idx[ppost->canvas_id][4]);
+               break;
+       case PULL_DOWN_BLEND_2:
+       case PULL_DOWN_NORMAL_2:
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[0],
+                       di_post_idx[ppost->canvas_id][3], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[1],
+                       di_post_idx[ppost->canvas_id][0], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[2], -1,
+                       di_post_idx[ppost->canvas_id][2]);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[2],
+                       di_post_idx[ppost->canvas_id][1], -1);
+               if (dimp_get(eDI_MP_mcpre_en))
+                       config_mcvec_canvas_idx(
+                               di_buf->di_buf_dup_p[2],
+                               di_post_idx[ppost->canvas_id][4]);
+               break;
+       case PULL_DOWN_MTN:
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[1],
+                       di_post_idx[ppost->canvas_id][0], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[2], -1,
+                       di_post_idx[ppost->canvas_id][2]);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[0],
+                       di_post_idx[ppost->canvas_id][1], -1);
+               break;
+       case PULL_DOWN_BUF1:/* wave with buf1 */
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[1],
+                       di_post_idx[ppost->canvas_id][0], -1);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[1], -1,
+                       di_post_idx[ppost->canvas_id][2]);
+               config_canvas_idx(
+                       di_buf->di_buf_dup_p[0],
+                       di_post_idx[ppost->canvas_id][1], -1);
+               break;
+       case PULL_DOWN_EI:
+               if (di_buf->di_buf_dup_p[1])
+                       config_canvas_idx(
+                               di_buf->di_buf_dup_p[1],
+                               di_post_idx[ppost->canvas_id][0], -1);
+               break;
+       default:
+               break;
+       }
+       ppost->next_canvas_id = ppost->canvas_id ? 0 : 1;
+#endif
+       if (!di_buf->di_buf_dup_p[1]) {
+               PR_ERR("%s 4:\n", __func__);
+               return 0;
+       }
+       if (!di_buf->di_buf_dup_p[1]->vframe ||
+           !di_buf->di_buf_dup_p[0]->vframe) {
+               PR_ERR("%s 5:\n", __func__);
+               return 0;
+       }
+
+       if (is_meson_txl_cpu() && overturn && di_buf->di_buf_dup_p[2]) {
+               /*sync from kernel 3.14 txl*/
+               if (dimp_get(eDI_MP_post_blend) == PULL_DOWN_BLEND_2)
+                       dimp_set(eDI_MP_post_blend, PULL_DOWN_BLEND_0);
+               else if (dimp_get(eDI_MP_post_blend) == PULL_DOWN_BLEND_0)
+                       dimp_set(eDI_MP_post_blend, PULL_DOWN_BLEND_2);
+       }
+
+       switch (dimp_get(eDI_MP_post_blend)) {
+       case PULL_DOWN_BLEND_0:
+       case PULL_DOWN_NORMAL:
+               post_field_num =
+               (di_buf->di_buf_dup_p[1]->vframe->type &
+                VIDTYPE_TYPEMASK)
+               == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+               ppost->di_buf0_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[1]->nr_canvas_idx;
+               ppost->di_buf1_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[0]->nr_canvas_idx;
+               ppost->di_buf2_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[2]->nr_canvas_idx;
+               ppost->di_mtnprd_mif.canvas_num =
+                       di_buf->di_buf_dup_p[2]->mtn_canvas_idx;
+               /*mc_pre_flag = is_meson_txl_cpu()?2:(overturn?0:1);*/
+               if (is_meson_txl_cpu() && overturn) {
+                       /* swap if1&if2 mean negation of mv for normal di*/
+                       tmp_idx = ppost->di_buf1_mif.canvas0_addr0;
+                       ppost->di_buf1_mif.canvas0_addr0 =
+                               ppost->di_buf2_mif.canvas0_addr0;
+                       ppost->di_buf2_mif.canvas0_addr0 = tmp_idx;
+               }
+               mc_pre_flag = overturn ? 0 : 1;
+               if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL) {
+                       post_blend_mode = 3;
+                       /*if pulldown, mcdi_mcpreflag is 1,*/
+                       /*it means use previous field for MC*/
+                       /*else not pulldown,mcdi_mcpreflag is 2*/
+                       /*it means use forward & previous field for MC*/
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+                               mc_pre_flag = 2;
+               } else {
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+                               mc_pre_flag = 1;
+                       post_blend_mode = 1;
+               }
+               if (is_meson_txl_cpu() && overturn)
+                       mc_pre_flag = 1;
+
+               if (dimp_get(eDI_MP_mcpre_en)) {
+                       ppost->di_mcvecrd_mif.canvas_num =
+                               di_buf->di_buf_dup_p[2]->mcvec_canvas_idx;
+               }
+               blend_mtn_en = 1;
+               ei_en = 1;
+               dimp_set(eDI_MP_post_ei, 1);
+               post_blend_en = 1;
+               break;
+       case PULL_DOWN_BLEND_2:
+       case PULL_DOWN_NORMAL_2:
+               post_field_num =
+                       (di_buf->di_buf_dup_p[1]->vframe->type &
+                        VIDTYPE_TYPEMASK)
+                       == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+               ppost->di_buf0_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[1]->nr_canvas_idx;
+               ppost->di_buf1_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[2]->nr_canvas_idx;
+               ppost->di_buf2_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[0]->nr_canvas_idx;
+               ppost->di_mtnprd_mif.canvas_num =
+                       di_buf->di_buf_dup_p[2]->mtn_canvas_idx;
+               if (is_meson_txl_cpu() && overturn) {
+                       ppost->di_buf1_mif.canvas0_addr0 =
+                       ppost->di_buf2_mif.canvas0_addr0;
+               }
+               if (dimp_get(eDI_MP_mcpre_en)) {
+                       ppost->di_mcvecrd_mif.canvas_num =
+                               di_buf->di_buf_dup_p[2]->mcvec_canvas_idx;
+                       mc_pre_flag = is_meson_txl_cpu() ? 0 :
+                               (overturn ? 1 : 0);
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
+                               invert_mv = true;
+                       else if (!overturn)
+                               ppost->di_buf2_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[2]->nr_canvas_idx;
+               }
+               if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL_2) {
+                       post_blend_mode = 3;
+                       /*if pulldown, mcdi_mcpreflag is 1,*/
+                       /*it means use previous field for MC*/
+                       /*else not pulldown,mcdi_mcpreflag is 2*/
+                       /*it means use forward & previous field for MC*/
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+                               mc_pre_flag = 2;
+               } else {
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+                               mc_pre_flag = 1;
+                       post_blend_mode = 1;
+               }
+               blend_mtn_en = 1;
+               ei_en = 1;
+               dimp_set(eDI_MP_post_ei, 1);
+               post_blend_en = 1;
+               break;
+       case PULL_DOWN_MTN:
+               post_field_num =
+                       (di_buf->di_buf_dup_p[1]->vframe->type &
+                        VIDTYPE_TYPEMASK)
+                       == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+               ppost->di_buf0_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[1]->nr_canvas_idx;
+               ppost->di_buf1_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[0]->nr_canvas_idx;
+               ppost->di_mtnprd_mif.canvas_num =
+                       di_buf->di_buf_dup_p[2]->mtn_canvas_idx;
+               post_blend_mode = 0;
+               blend_mtn_en = 1;
+               ei_en = 1;
+               dimp_set(eDI_MP_post_ei, 1);
+               post_blend_en = 1;
+               break;
+       case PULL_DOWN_BUF1:
+               post_field_num =
+                       (di_buf->di_buf_dup_p[1]->vframe->type &
+                        VIDTYPE_TYPEMASK)
+                       == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+               ppost->di_buf0_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[1]->nr_canvas_idx;
+               ppost->di_mtnprd_mif.canvas_num =
+                       di_buf->di_buf_dup_p[1]->mtn_canvas_idx;
+               ppost->di_buf1_mif.canvas0_addr0 =
+                       di_buf->di_buf_dup_p[0]->nr_canvas_idx;
+               post_blend_mode = 1;
+               blend_mtn_en = 0;
+               ei_en = 0;
+               dimp_set(eDI_MP_post_ei, 0);
+               post_blend_en = 0;
+               break;
+       case PULL_DOWN_EI:
+               if (di_buf->di_buf_dup_p[1]) {
+                       ppost->di_buf0_mif.canvas0_addr0 =
+                               di_buf->di_buf_dup_p[1]->nr_canvas_idx;
+                       post_field_num =
+                               (di_buf->di_buf_dup_p[1]->vframe->type &
+                                VIDTYPE_TYPEMASK)
+                               == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+               } else {
+                       post_field_num =
+                               (di_buf->di_buf_dup_p[0]->vframe->type &
+                                VIDTYPE_TYPEMASK)
+                               == VIDTYPE_INTERLACE_TOP ? 0 : 1;
+                       ppost->di_buf0_mif.src_field_mode
+                               = post_field_num;
+               }
+               post_blend_mode = 2;
+               blend_mtn_en = 0;
+               ei_en = 1;
+               dimp_set(eDI_MP_post_ei, 1);
+               post_blend_en = 0;
+               break;
+       default:
+               break;
+       }
+
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) {
+               config_canvas_idx(di_buf,
+                                 di_post_idx[ppost->canvas_id][5], -1);
+               ppost->di_diwr_mif.canvas_num = di_buf->nr_canvas_idx;
+               di_vpp_en = 0;
+               di_ddr_en = 1;
+       } else {
+               di_vpp_en = 1;
+               di_ddr_en = 0;
+       }
+
+       /* if post size < MIN_POST_WIDTH, force ei */
+       if ((di_width < MIN_BLEND_WIDTH) &&
+           (di_buf->pd_config.global_mode == PULL_DOWN_BLEND_0 ||
+           di_buf->pd_config.global_mode == PULL_DOWN_BLEND_2  ||
+           di_buf->pd_config.global_mode == PULL_DOWN_NORMAL
+           )) {
+               post_blend_mode = 1;
+               blend_mtn_en = 0;
+               ei_en = 0;
+               dimp_set(eDI_MP_post_ei, 0);
+               post_blend_en = 0;
+       }
+
+       if (dimp_get(eDI_MP_mcpre_en))
+               ppost->di_mcvecrd_mif.blend_en = post_blend_en;
+       invert_mv = overturn ? (!invert_mv) : invert_mv;
+       if (ppost->update_post_reg_flag) {
+               dimh_enable_di_post_2(
+                       &ppost->di_buf0_mif,
+                       &ppost->di_buf1_mif,
+                       &ppost->di_buf2_mif,
+                       &ppost->di_diwr_mif,
+                       &ppost->di_mtnprd_mif,
+                       ei_en,                  /* ei enable */
+                       post_blend_en,          /* blend enable */
+                       blend_mtn_en,           /* blend mtn enable */
+                       post_blend_mode,        /* blend mode. */
+                       di_vpp_en,              /* di_vpp_en. */
+                       di_ddr_en,              /* di_ddr_en. */
+                       post_field_num,         /* 1 bottom generate top */
+                       hold_line,
+                       dimp_get(eDI_MP_post_urgent),
+                       (invert_mv ? 1 : 0),
+                       dimp_get(eDI_MP_di_vscale_skip_count_real)
+                       );
+               if (dimp_get(eDI_MP_mcpre_en)) {
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+                               dimh_enable_mc_di_post_g12(
+                                       &ppost->di_mcvecrd_mif,
+                                       dimp_get(eDI_MP_post_urgent),
+                                       overturn, (invert_mv ? 1 : 0));
+                       else
+                               dimh_enable_mc_di_post(
+                                       &ppost->di_mcvecrd_mif,
+                                       dimp_get(eDI_MP_post_urgent),
+                                       overturn, (invert_mv ? 1 : 0));
+               } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+               }
+       } else {
+               dimh_post_switch_buffer(
+                       &ppost->di_buf0_mif,
+                       &ppost->di_buf1_mif,
+                       &ppost->di_buf2_mif,
+                       &ppost->di_diwr_mif,
+                       &ppost->di_mtnprd_mif,
+                       &ppost->di_mcvecrd_mif,
+                       ei_en,                  /* ei enable */
+                       post_blend_en,          /* blend enable */
+                       blend_mtn_en,           /* blend mtn enable */
+                       post_blend_mode,        /* blend mode. */
+                       di_vpp_en,      /* di_vpp_en. */
+                       di_ddr_en,      /* di_ddr_en. */
+                       post_field_num,         /* 1 bottom generate top */
+                       hold_line,
+                       dimp_get(eDI_MP_post_urgent),
+                       (invert_mv ? 1 : 0),
+                       dimp_get(eDI_MP_pulldown_enable),
+                       dimp_get(eDI_MP_mcpre_en),
+                       dimp_get(eDI_MP_di_vscale_skip_count_real)
+                       );
+       }
+
+               if (is_meson_gxtvbb_cpu()       ||
+                   is_meson_txl_cpu()          ||
+                   is_meson_txlx_cpu()         ||
+                   is_meson_gxlx_cpu()         ||
+                   is_meson_txhd_cpu()         ||
+                   is_meson_g12a_cpu()         ||
+                   is_meson_g12b_cpu()         ||
+                   is_meson_tl1_cpu()          ||
+                   is_meson_tm2_cpu()          ||
+                   is_meson_sm1_cpu()) {
+                       if (di_cfg_top_get(eDI_CFG_ref_2)       &&
+                           mc_pre_flag                         &&
+                           dimp_get(eDI_MP_post_wr_en)) { /*OTT-3210*/
+                               dbg_once("mc_old=%d\n", mc_pre_flag);
+                               mc_pre_flag = 1;
+                       }
+               dim_post_read_reverse_irq(overturn, mc_pre_flag,
+                       post_blend_en ? dimp_get(eDI_MP_mcpre_en) : false);
+               /* disable mc for first 2 fieldes mv unreliable */
+               if (di_buf->seq < 2)
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+       }
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               if (di_buf->di_buf_dup_p[2])
+                       set_post_mcinfo(&di_buf->di_buf_dup_p[2]
+                               ->curr_field_mcinfo);
+       } else if (is_meson_gxlx_cpu()  ||
+                  is_meson_txl_cpu()   ||
+                  is_meson_txlx_cpu()) {
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+       }
+
+/* set pull down region (f(t-1) */
+
+       if (di_pldn_buf                         &&
+           dimp_get(eDI_MP_pulldown_enable)    &&
+           !ppre->cur_prog_flag) {
+               unsigned short offset = (di_start_y >> 1);
+
+               if (overturn)
+                       offset = ((di_buf->vframe->height - di_end_y) >> 1);
+               else
+                       offset = 0;
+               /*pulldown_vof_win_vshift*/
+               get_ops_pd()->vof_win_vshift(&di_pldn_buf->pd_config, offset);
+               dimh_pulldown_vof_win_config(&di_pldn_buf->pd_config);
+       }
+       post_mif_sw(true);      /*position?*/
+       /*dimh_post_ctrl(DI_HW_POST_CTRL_RESET, di_ddr_en);*/
+       /*add by wangfeng 2018-11-15*/
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_DIWR_CTRL, 1, 31, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_DIWR_CTRL, 0, 31, 1);
+       /*ary add for post crash*/
+       di_post_set_flow((dimp_get(eDI_MP_post_wr_en)   &&
+                         dimp_get(eDI_MP_post_wr_support)),
+                        eDI_POST_FLOW_STEP2_START);
+
+       if (ppost->update_post_reg_flag > 0)
+               ppost->update_post_reg_flag--;
+
+       /*dbg*/
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_SETE, channel, ppost->frame_cnt);
+       dbg_post_cnt(channel, "ps2");
+       ppost->frame_cnt++;
+
+       return 0;
+}
+
+#ifndef DI_DEBUG_POST_BUF_FLOW
+static void post_ready_buf_set(unsigned int ch, struct di_buf_s *di_buf)
+{
+       vframe_t *vframe_ret = NULL;
+       struct di_buf_s *nr_buf = NULL;
+
+       vframe_ret = di_buf->vframe;
+       nr_buf = di_buf->di_buf_dup_p[1];
+       if ((dimp_get(eDI_MP_post_wr_en)        &&
+            dimp_get(eDI_MP_post_wr_support))  &&
+           (di_buf->process_fun_index != PROCESS_FUN_NULL)) {
+       #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+               vframe_ret->canvas0_config[0].phy_addr =
+                       di_buf->nr_adr;
+               vframe_ret->canvas0_config[0].width =
+                       di_buf->canvas_width[NR_CANVAS],
+               vframe_ret->canvas0_config[0].height =
+                       di_buf->canvas_height;
+               vframe_ret->canvas0_config[0].block_mode = 0;
+               vframe_ret->plane_num = 1;
+               vframe_ret->canvas0Addr = -1;
+               vframe_ret->canvas1Addr = -1;
+               if (di_mp_uit_get(eDI_MP_show_nrwr)) {
+                       vframe_ret->canvas0_config[0].phy_addr =
+                               nr_buf->nr_adr;
+                       vframe_ret->canvas0_config[0].width =
+                               nr_buf->canvas_width[NR_CANVAS];
+                       vframe_ret->canvas0_config[0].height =
+                               nr_buf->canvas_height;
+               }
+       #else
+               config_canvas_idx(di_buf, di_wr_idx, -1);
+               vframe_ret->canvas0Addr = di_buf->nr_canvas_idx;
+               vframe_ret->canvas1Addr = di_buf->nr_canvas_idx;
+               if (di_mp_uit_get(eDI_MP_show_nrwr)) {
+                       config_canvas_idx(nr_buf,
+                                         di_wr_idx, -1);
+                       vframe_ret->canvas0Addr = di_wr_idx;
+                       vframe_ret->canvas1Addr = di_wr_idx;
+               }
+       #endif
+               vframe_ret->early_process_fun = dim_do_post_wr_fun;
+               vframe_ret->process_fun = NULL;
+
+               /* 2019-04-22 Suggestions from brian.zhu*/
+               vframe_ret->mem_handle = NULL;
+               vframe_ret->type |= VIDTYPE_DI_PW;
+               /* 2019-04-22 */
+       }
+}
+
+#endif
+void dim_post_de_done_buf_config(unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       struct di_buf_s *di_buf = NULL;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (!ppost->cur_post_buf)
+               return;
+       dbg_post_cnt(channel, "pd1");
+       /*dbg*/
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_DB, channel, ppost->frame_cnt);
+
+       di_lock_irqfiq_save(irq_flag2);
+       queue_out(channel, ppost->cur_post_buf);/*? which que?post free*/
+       di_buf = ppost->cur_post_buf;
+
+       if (de_devp->pps_enable && dimp_get(eDI_MP_pps_position) == 0) {
+               di_buf->vframe->width = dimp_get(eDI_MP_pps_dstw);
+               di_buf->vframe->height = dimp_get(eDI_MP_pps_dsth);
+       }
+
+       #ifdef DI_DEBUG_POST_BUF_FLOW
+       #else
+       post_ready_buf_set(channel, di_buf);
+       #endif
+       di_que_in(channel, QUE_POST_READY, ppost->cur_post_buf);
+
+       #ifdef DI_DEBUG_POST_BUF_FLOW
+       #else
+       /*add by ary:*/
+       recycle_post_ready_local(ppost->cur_post_buf, channel);
+       #endif
+       di_unlock_irqfiq_restore(irq_flag2);
+       dim_tr_ops.post_ready(di_buf->vframe->omx_index);
+       pw_vf_notify_receiver(channel,
+                             VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+       ppost->cur_post_buf = NULL;
+       /*dbg*/
+       dim_ddbg_mod_save(eDI_DBG_MOD_POST_DE, channel, ppost->frame_cnt);
+       dbg_post_cnt(channel, "pd2");
+}
+
+#if 0
+static void di_post_process(unsigned int channel)
+{
+       struct di_buf_s *di_buf = NULL;
+       vframe_t *vf_p = NULL;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       if (ppost->post_de_busy)
+               return;
+       if (queue_empty(channel, QUEUE_POST_DOING)) {
+               ppost->post_peek_underflow++;
+               return;
+       }
+
+       di_buf = get_di_buf_head(channel, QUEUE_POST_DOING);
+       if (dim_check_di_buf(di_buf, 20, channel))
+               return;
+       vf_p = di_buf->vframe;
+       if (ppost->run_early_proc_fun_flag) {
+               if (vf_p->early_process_fun)
+                       vf_p->early_process_fun = dim_do_post_wr_fun;
+       }
+       if (di_buf->process_fun_index) {
+               ppost->post_wr_cnt++;
+               dim_post_process(di_buf, 0, vf_p->width - 1,
+                                0, vf_p->height - 1, vf_p);
+               ppost->post_de_busy = 1;
+               ppost->irq_time = cur_to_msecs();
+       } else {
+               ppost->de_post_process_done = 1;
+       }
+       ppost->cur_post_buf = di_buf;
+}
+#endif
+
+static void recycle_vframe_type_post(struct di_buf_s *di_buf,
+                                    unsigned int channel)
+{
+       int i;
+
+       if (!di_buf) {
+               PR_ERR("%s:\n", __func__);
+               if (recovery_flag == 0)
+                       recovery_log_reason = 15;
+
+               recovery_flag++;
+               return;
+       }
+       if (di_buf->process_fun_index == PROCESS_FUN_DI)
+               dec_post_ref_count(di_buf);
+
+       for (i = 0; i < 2; i++) {
+               if (di_buf->di_buf[i]) {
+                       queue_in(channel, di_buf->di_buf[i], QUEUE_RECYCLE);
+                       dim_print("%s: ch[%d]:di_buf[%d],type=%d\n", __func__,
+                                 channel, di_buf->di_buf[i]->index,
+                                 di_buf->di_buf[i]->type);
+               }
+       }
+       queue_out(channel, di_buf); /* remove it from display_list_head */
+       if (di_buf->queue_index != -1) {
+               PR_ERR("qout err:index[%d],typ[%d],qindex[%d]\n",
+                      di_buf->index, di_buf->type, di_buf->queue_index);
+       /* queue_out_dbg(channel, di_buf);*/
+       }
+       di_buf->invert_top_bot_flag = 0;
+       di_que_in(channel, QUE_POST_FREE, di_buf);
+}
+
+void recycle_post_ready_local(struct di_buf_s *di_buf, unsigned int channel)
+{
+       int i;
+
+       if (di_buf->type != VFRAME_TYPE_POST)
+               return;
+
+       if (di_buf->process_fun_index == PROCESS_FUN_NULL)      /*bypass?*/
+               return;
+
+       if (di_buf->process_fun_index == PROCESS_FUN_DI)
+               dec_post_ref_count(di_buf);
+
+       for (i = 0; i < 2; i++) {
+               if (di_buf->di_buf[i]) {
+                       queue_in(channel, di_buf->di_buf[i], QUEUE_RECYCLE);
+                       dim_print("%s: ch[%d]:di_buf[%d],type=%d\n",
+                                 __func__,
+                                 channel,
+                                 di_buf->di_buf[i]->index,
+                                 di_buf->di_buf[i]->type);
+                       di_buf->di_buf[i] = NULL;
+               }
+       }
+}
+
+#ifdef DI_BUFFER_DEBUG
+static void
+recycle_vframe_type_post_print(struct di_buf_s *di_buf,
+                              const char *func,
+                              const int        line)
+{
+       int i;
+
+       dim_print("%s:%d ", func, line);
+       for (i = 0; i < 2; i++) {
+               if (di_buf->di_buf[i])
+                       dim_print("%s[%d]<%d>=>recycle_list; ",
+                                 vframe_type_name[di_buf->di_buf[i]->type],
+                                 di_buf->di_buf[i]->index, i);
+       }
+       dim_print("%s[%d] =>post_free_list\n",
+                 vframe_type_name[di_buf->type], di_buf->index);
+}
+#endif
+
+static unsigned int pldn_dly1 = 1;
+static void set_pulldown_mode(struct di_buf_s *di_buf, unsigned int channel)
+{
+       struct di_buf_s *pre_buf_p = di_buf->di_buf_dup_p[pldn_dly1];
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) {
+               if (dimp_get(eDI_MP_pulldown_enable) &&
+                   !ppre->cur_prog_flag) {
+                       if (pre_buf_p) {
+                               di_buf->pd_config.global_mode =
+                                       pre_buf_p->pd_config.global_mode;
+                       } else {
+                               /* ary add 2019-06-19*/
+                               di_buf->pd_config.global_mode
+                                       = PULL_DOWN_EI;
+                               PR_ERR("[%s]: index out of range.\n",
+                                      __func__);
+                       }
+               } else {
+                       di_buf->pd_config.global_mode
+                               = PULL_DOWN_NORMAL;
+               }
+       }
+}
+
+static void drop_frame(int check_drop, int throw_flag, struct di_buf_s *di_buf,
+                      unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       int i = 0, drop_flag = 0;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       di_lock_irqfiq_save(irq_flag2);
+       if ((frame_count == 0) && check_drop)
+               ppost->start_pts = di_buf->vframe->pts;
+       if ((check_drop &&
+            (frame_count < dimp_get(eDI_MP_start_frame_drop_count))) ||
+            throw_flag) {
+               drop_flag = 1;
+       } else {
+               if (check_drop && (frame_count
+                       == dimp_get(eDI_MP_start_frame_drop_count))) {
+                       if ((ppost->start_pts) &&
+                           (di_buf->vframe->pts == 0))
+                               di_buf->vframe->pts = ppost->start_pts;
+                       ppost->start_pts = 0;
+               }
+               for (i = 0; i < 3; i++) {
+                       if (di_buf->di_buf_dup_p[i]) {
+                               if (di_buf->di_buf_dup_p[i]->vframe->bitdepth !=
+                                       di_buf->vframe->bitdepth) {
+                                       pr_info("%s buf[%d] not match bit mode\n",
+                                               __func__, i);
+                                       drop_flag = 1;
+                                       break;
+                               }
+                       }
+               }
+       }
+       if (drop_flag) {
+               queue_in(channel, di_buf, QUEUE_TMP);
+               recycle_vframe_type_post(di_buf, channel);
+#ifdef DI_BUFFER_DEBUG
+               recycle_vframe_type_post_print(
+                               di_buf, __func__,
+                               __LINE__);
+#endif
+       } else {
+               dim_print("%s:wr_en[%d],support[%d]\n", __func__,
+                         dimp_get(eDI_MP_post_wr_en),
+                         dimp_get(eDI_MP_post_wr_support));
+
+               if (dimp_get(eDI_MP_post_wr_en) &&
+                   dimp_get(eDI_MP_post_wr_support))
+                       queue_in(channel, di_buf, QUEUE_POST_DOING);
+               else
+                       di_que_in(channel, QUE_POST_READY, di_buf);
+
+               dim_tr_ops.post_do(di_buf->vframe->omx_index);
+               dim_print("di:ch[%]:%dth %s[%d] => post ready %u ms.\n",
+                         channel,
+                         frame_count,
+                         vframe_type_name[di_buf->type], di_buf->index,
+                         jiffies_to_msecs(jiffies_64 -
+                         di_buf->vframe->ready_jiffies64));
+       }
+       di_unlock_irqfiq_restore(irq_flag2);
+}
+
+int dim_process_post_vframe(unsigned int channel)
+{
+/*
+ * 1) get buf from post_free_list, config it according to buf
+ * in pre_ready_list, send it to post_ready_list
+ * (it will be send to post_free_list in di_vf_put())
+ * 2) get buf from pre_ready_list, attach it to buf from post_free_list
+ * (it will be send to recycle_list in di_vf_put() )
+ */
+       ulong irq_flag2 = 0;
+       int i = 0;
+       int ret = 0;
+       int buffer_keep_count = 3;
+       struct di_buf_s *di_buf = NULL;
+       struct di_buf_s *ready_di_buf;
+       struct di_buf_s *p = NULL;/* , *ptmp; */
+       int itmp;
+       /* new que int ready_count = list_count(channel, QUEUE_PRE_READY);*/
+       int ready_count = di_que_list_count(channel, QUE_PRE_READY);
+       bool check_drop = false;
+       unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/
+       unsigned int psize; /*new que*/
+
+#if 1
+       if (di_que_is_empty(channel, QUE_POST_FREE))
+               return 0;
+       /*add : for now post buf only 3.*/
+       if (list_count(channel, QUEUE_POST_DOING) > 2)
+               return 0;
+#else
+       /*for post write mode ,need reserved a post free buf;*/
+       if (di_que_list_count(channel, QUE_POST_FREE) < 2)
+               return 0;
+#endif
+       if (ready_count == 0)
+               return 0;
+
+       ready_di_buf = di_que_peek(channel, QUE_PRE_READY);
+       if (!ready_di_buf || !ready_di_buf->vframe) {
+               pr_dbg("%s:Error1\n", __func__);
+
+               if (recovery_flag == 0)
+                       recovery_log_reason = 16;
+
+               recovery_flag++;
+               return 0;
+       }
+       dim_print("%s:1 ready_count[%d]:post_proc_flag[%d]\n", __func__,
+                 ready_count, ready_di_buf->post_proc_flag);
+       if ((ready_di_buf->post_proc_flag) &&
+           (ready_count >= buffer_keep_count)) {
+               i = 0;
+
+               di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize);
+               for (itmp = 0; itmp < psize; itmp++) {
+                       p = pw_qindex_2_buf(channel, tmpa[itmp]);
+                       /* if(p->post_proc_flag == 0){ */
+                       if (p->type == VFRAME_TYPE_IN) {
+                               ready_di_buf->post_proc_flag = -1;
+                               ready_di_buf->new_format_flag = 1;
+                       }
+                       i++;
+                       if (i > 2)
+                               break;
+               }
+       }
+       if (ready_di_buf->post_proc_flag > 0) {
+               if (ready_count >= buffer_keep_count) {
+                       di_lock_irqfiq_save(irq_flag2);
+
+                       di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE);
+                       if (dim_check_di_buf(di_buf, 17, channel)) {
+                               di_unlock_irqfiq_restore(irq_flag2);
+                               return 0;
+                       }
+
+                       di_unlock_irqfiq_restore(irq_flag2);
+
+                       i = 0;
+
+                       di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize);
+
+                       for (itmp = 0; itmp < psize; itmp++) {
+                               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+                               dim_print("di:keep[%d]:t[%d]:idx[%d]\n",
+                                         i, tmpa[itmp], p->index);
+                               di_buf->di_buf_dup_p[i++] = p;
+
+                               if (i >= buffer_keep_count)
+                                       break;
+                       }
+                       if (i < buffer_keep_count) {
+                               PR_ERR("%s:3\n", __func__);
+
+                               if (recovery_flag == 0)
+                                       recovery_log_reason = 18;
+                               recovery_flag++;
+                               return 0;
+                       }
+
+                       memcpy(di_buf->vframe,
+                              di_buf->di_buf_dup_p[1]->vframe,
+                              sizeof(vframe_t));
+                       di_buf->vframe->private_data = di_buf;
+                       if (di_buf->di_buf_dup_p[1]->post_proc_flag == 3) {
+                               /* dummy, not for display */
+                               inc_post_ref_count(di_buf);
+                               di_buf->di_buf[0] = di_buf->di_buf_dup_p[0];
+                               di_buf->di_buf[1] = NULL;
+                               queue_out(channel, di_buf->di_buf[0]);
+                               di_lock_irqfiq_save(irq_flag2);
+                               queue_in(channel, di_buf, QUEUE_TMP);
+                               recycle_vframe_type_post(di_buf, channel);
+
+                               di_unlock_irqfiq_restore(irq_flag2);
+                               dim_print("%s <dummy>: ", __func__);
+#ifdef DI_BUFFER_DEBUG
+                               dim_print("%s <dummy>: ", __func__);
+#endif
+                       } else {
+                               if (di_buf->di_buf_dup_p[1]->post_proc_flag
+                                               == 2) {
+                                       di_buf->pd_config.global_mode
+                                               = PULL_DOWN_BLEND_2;
+                                       /* blend with di_buf->di_buf_dup_p[2] */
+                               } else {
+                                       set_pulldown_mode(di_buf, channel);
+                               }
+                               di_buf->vframe->type =
+                                       VIDTYPE_PROGRESSIVE |
+                                       VIDTYPE_VIU_422 |
+                                       VIDTYPE_VIU_SINGLE_PLANE |
+                                       VIDTYPE_VIU_FIELD |
+                                       VIDTYPE_PRE_INTERLACE;
+
+                       di_buf->vframe->width
+                               = di_buf->di_buf_dup_p[1]->width_bk;
+
+                       if (di_buf->di_buf_dup_p[1]->new_format_flag) {
+                               /* if (di_buf->di_buf_dup_p[1]
+                                * ->post_proc_flag == 2) {
+                                */
+                               di_buf->vframe->early_process_fun =
+                                               de_post_disable_fun;
+                       } else {
+                               di_buf->vframe->early_process_fun =
+                                                       do_nothing_fun;
+                       }
+
+                       if (di_buf->di_buf_dup_p[1]->type == VFRAME_TYPE_IN) {
+                               /* next will be bypass */
+                               di_buf->vframe->type
+                                       = VIDTYPE_PROGRESSIVE |
+                                         VIDTYPE_VIU_422 |
+                                         VIDTYPE_VIU_SINGLE_PLANE |
+                                               VIDTYPE_VIU_FIELD |
+                                               VIDTYPE_PRE_INTERLACE;
+                               di_buf->vframe->height >>= 1;
+                               di_buf->vframe->canvas0Addr =
+                                       di_buf->di_buf_dup_p[0]
+                                       ->nr_canvas_idx; /* top */
+                               di_buf->vframe->canvas1Addr =
+                                       di_buf->di_buf_dup_p[0]
+                                       ->nr_canvas_idx;
+                               di_buf->vframe->process_fun =
+                                       NULL;
+                               di_buf->process_fun_index = PROCESS_FUN_NULL;
+                       } else {
+                               /*for debug*/
+                               if (dimp_get(eDI_MP_debug_blend_mode) != -1)
+                                       di_buf->pd_config.global_mode
+                                       = dimp_get(eDI_MP_debug_blend_mode);
+
+                               di_buf->vframe->process_fun =
+((dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ?
+                               NULL : dim_post_process);
+                               di_buf->process_fun_index = PROCESS_FUN_DI;
+                                       inc_post_ref_count(di_buf);
+                               }
+                               di_buf->di_buf[0]       /*ary:di_buf_di_buf*/
+                                       = di_buf->di_buf_dup_p[0];
+                               di_buf->di_buf[1] = NULL;
+                               queue_out(channel, di_buf->di_buf[0]);
+
+                               drop_frame(true,
+                               (di_buf->di_buf_dup_p[0]->throw_flag) ||
+                               (di_buf->di_buf_dup_p[1]->throw_flag) ||
+                               (di_buf->di_buf_dup_p[2]->throw_flag),
+                               di_buf, channel);
+
+                               frame_count++;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print("%s <interlace>: ", __func__);
+#endif
+                               if (!(dimp_get(eDI_MP_post_wr_en) &&
+                                     dimp_get(eDI_MP_post_wr_support)))
+                                       pw_vf_notify_receiver(channel,
+VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL);
+                       }
+                       ret = 1;
+               }
+       } else {
+               if (is_progressive(ready_di_buf->vframe) ||
+                   ready_di_buf->type == VFRAME_TYPE_IN ||
+                   ready_di_buf->post_proc_flag < 0 ||
+                   dimp_get(eDI_MP_bypass_post_state)
+                   ){
+                       int vframe_process_count = 1;
+#ifdef DET3D
+                       int dual_vframe_flag = 0;
+
+                       if ((ppre->vframe_interleave_flag &&
+                            ready_di_buf->left_right) ||
+                           (dimp_get(eDI_MP_bypass_post) & 0x100)) {
+                               dual_vframe_flag = 1;
+                               vframe_process_count = 2;
+                       }
+#endif
+                       if (dimp_get(eDI_MP_skip_top_bot) &&
+                           (!is_progressive(ready_di_buf->vframe)))
+                               vframe_process_count = 2;
+
+                       if (ready_count >= vframe_process_count) {
+                               struct di_buf_s *di_buf_i;
+
+                               di_lock_irqfiq_save(irq_flag2);
+
+               di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE);
+                               if (dim_check_di_buf(di_buf, 19, channel)) {
+                                       di_unlock_irqfiq_restore(irq_flag2);
+                                       return 0;
+                               }
+
+                               di_unlock_irqfiq_restore(irq_flag2);
+
+                               i = 0;
+
+               di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize);
+
+                               for (itmp = 0; itmp < psize; itmp++) {
+                                       p = pw_qindex_2_buf(channel,
+                                               tmpa[itmp]);
+                                       di_buf->di_buf_dup_p[i++] = p;
+                                       if (i >= vframe_process_count) {
+                                               di_buf->di_buf_dup_p[i]
+                                                       = NULL;
+                                               di_buf->di_buf_dup_p[i + 1]
+                                                       = NULL;
+                                               break;
+                                       }
+                               }
+                               if (i < vframe_process_count) {
+                                       PR_ERR("%s:6\n", __func__);
+                                       if (recovery_flag == 0)
+                                               recovery_log_reason = 22;
+
+                                       recovery_flag++;
+                                       return 0;
+                               }
+
+                               di_buf_i = di_buf->di_buf_dup_p[0];
+                               if (!is_progressive(ready_di_buf->vframe) &&
+                                   ((dimp_get(eDI_MP_skip_top_bot) == 1) ||
+                                   (dimp_get(eDI_MP_skip_top_bot) == 2))) {
+                                       unsigned int frame_type =
+                                               di_buf->di_buf_dup_p[1]->
+                                               vframe->type &
+                                               VIDTYPE_TYPEMASK;
+                                       if (dimp_get(eDI_MP_skip_top_bot)
+                                               == 1) {
+                                               di_buf_i = (frame_type ==
+                                               VIDTYPE_INTERLACE_TOP)
+                                               ? di_buf->di_buf_dup_p[1]
+                                               : di_buf->di_buf_dup_p[0];
+                                       } else if (
+                                               dimp_get(eDI_MP_skip_top_bot)
+                                               == 2) {
+                                               di_buf_i = (frame_type ==
+                                               VIDTYPE_INTERLACE_BOTTOM)
+                                               ? di_buf->di_buf_dup_p[1]
+                                               : di_buf->di_buf_dup_p[0];
+                                       }
+                               }
+
+                               memcpy(di_buf->vframe, di_buf_i->vframe,
+                                      sizeof(vframe_t));
+
+                               di_buf->vframe->width = di_buf_i->width_bk;
+                               di_buf->vframe->private_data = di_buf;
+
+                               if (ready_di_buf->new_format_flag &&
+                               (ready_di_buf->type == VFRAME_TYPE_IN)) {
+                                       pr_info("DI:ch[%d],%d disable post.\n",
+                                               channel,
+                                               __LINE__);
+                                       di_buf->vframe->early_process_fun
+                                               = de_post_disable_fun;
+                               } else {
+                                       if (ready_di_buf->type ==
+                                               VFRAME_TYPE_IN)
+                                               di_buf->vframe->
+                                               early_process_fun
+                                                = do_nothing_fun;
+
+                                       else
+                                               di_buf->vframe->
+                                               early_process_fun
+                                                = do_pre_only_fun;
+                               }
+                               dim_print("%s:2\n", __func__);
+                               if (ready_di_buf->post_proc_flag == -2) {
+                                       di_buf->vframe->type
+                                               |= VIDTYPE_VIU_FIELD;
+                                       di_buf->vframe->type
+                                               &= ~(VIDTYPE_TYPEMASK);
+                                       di_buf->vframe->process_fun
+= (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ? NULL :
+                                       dim_post_process;
+                                       di_buf->process_fun_index =
+                                               PROCESS_FUN_DI;
+                                       di_buf->pd_config.global_mode
+                                               = PULL_DOWN_EI;
+                               } else {
+                                       di_buf->vframe->process_fun =
+                                               NULL;
+                                       di_buf->process_fun_index =
+                                                       PROCESS_FUN_NULL;
+                                       di_buf->pd_config.global_mode =
+                                               PULL_DOWN_NORMAL;
+                               }
+                               di_buf->di_buf[0] = ready_di_buf;
+                               di_buf->di_buf[1] = NULL;
+                               queue_out(channel, ready_di_buf);
+
+#ifdef DET3D
+                               if (dual_vframe_flag) {
+                                       di_buf->di_buf[1] =
+                                               di_buf->di_buf_dup_p[1];
+                                       queue_out(channel, di_buf->di_buf[1]);
+                               }
+#endif
+                               drop_frame(check_drop,
+                                       di_buf->di_buf[0]->throw_flag,
+                                       di_buf, channel);
+
+                               frame_count++;
+#ifdef DI_BUFFER_DEBUG
+                               dim_print(
+                                       "%s <prog by frame>: ",
+                                       __func__);
+#endif
+                               ret = 1;
+                               pw_vf_notify_receiver(channel,
+                                       VFRAME_EVENT_PROVIDER_VFRAME_READY,
+                                       NULL);
+                       }
+               } else if (ready_count >= 2) {
+                       /*for progressive input,type
+                        * 1:separate tow fields,type
+                        * 2:bypass post as frame
+                        */
+                       unsigned char prog_tb_field_proc_type =
+                               (dimp_get(eDI_MP_prog_proc_config) >> 1) & 0x3;
+                       di_lock_irqfiq_save(irq_flag2);
+
+                       di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE);
+                       if (dim_check_di_buf(di_buf, 20, channel)) {
+                               di_unlock_irqfiq_restore(irq_flag2);
+                               return 0;
+                       }
+
+                       di_unlock_irqfiq_restore(irq_flag2);
+
+                       i = 0;
+
+                       di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize);
+
+                       for (itmp = 0; itmp < psize; itmp++) {
+                               p = pw_qindex_2_buf(channel, tmpa[itmp]);
+                               di_buf->di_buf_dup_p[i++] = p;
+                               if (i >= 2) {
+                                       di_buf->di_buf_dup_p[i] = NULL;
+                                       break;
+                               }
+                       }
+                       if (i < 2) {
+                               PR_ERR("%s:Error6\n", __func__);
+
+                               if (recovery_flag == 0)
+                                       recovery_log_reason = 21;
+
+                               recovery_flag++;
+                               return 0;
+                       }
+
+                       memcpy(di_buf->vframe,
+                              di_buf->di_buf_dup_p[0]->vframe,
+                              sizeof(vframe_t));
+                       di_buf->vframe->private_data = di_buf;
+
+                       /*separate one progressive frame
+                        * as two interlace fields
+                        */
+                       if (prog_tb_field_proc_type == 1) {
+                               /* do weave by di post */
+                               di_buf->vframe->type =
+                                       VIDTYPE_PROGRESSIVE |
+                                       VIDTYPE_VIU_422 |
+                                       VIDTYPE_VIU_SINGLE_PLANE |
+                                       VIDTYPE_VIU_FIELD |
+                                       VIDTYPE_PRE_INTERLACE;
+                               if (
+                                       di_buf->di_buf_dup_p[0]->
+                                       new_format_flag)
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               de_post_disable_fun;
+                               else
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               do_nothing_fun;
+
+                               di_buf->pd_config.global_mode =
+                                       PULL_DOWN_BUF1;
+                               di_buf->vframe->process_fun =
+(dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ? NULL :
+                               dim_post_process;
+                               di_buf->process_fun_index = PROCESS_FUN_DI;
+                       } else if (prog_tb_field_proc_type == 0) {
+                               /* to do: need change for
+                                * DI_USE_FIXED_CANVAS_IDX
+                                */
+                               /* do weave by vpp */
+                               di_buf->vframe->type =
+                                       VIDTYPE_PROGRESSIVE |
+                                       VIDTYPE_VIU_422 |
+                                       VIDTYPE_VIU_SINGLE_PLANE;
+                               if (
+                                       (di_buf->di_buf_dup_p[0]->
+                                        new_format_flag) ||
+                                       (Rd(DI_IF1_GEN_REG) & 1))
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               de_post_disable_fun;
+                               else
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               do_nothing_fun;
+                               di_buf->vframe->process_fun = NULL;
+                               di_buf->process_fun_index = PROCESS_FUN_NULL;
+                               di_buf->vframe->canvas0Addr =
+                                       di_buf->di_buf_dup_p[0]->
+                                       nr_canvas_idx;
+                               di_buf->vframe->canvas1Addr =
+                                       di_buf->di_buf_dup_p[1]->
+                                       nr_canvas_idx;
+                       } else {
+                               /* to do: need change for
+                                * DI_USE_FIXED_CANVAS_IDX
+                                */
+                               di_buf->vframe->type =
+                                       VIDTYPE_PROGRESSIVE |
+                                       VIDTYPE_VIU_422 |
+                                       VIDTYPE_VIU_SINGLE_PLANE |
+                                       VIDTYPE_VIU_FIELD |
+                                       VIDTYPE_PRE_INTERLACE;
+                               di_buf->vframe->height >>= 1;
+
+                               di_buf->vframe->width
+                                       = di_buf->di_buf_dup_p[0]->width_bk;
+                               if (
+                                       (di_buf->di_buf_dup_p[0]->
+                                        new_format_flag) ||
+                                       (Rd(DI_IF1_GEN_REG) & 1))
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               de_post_disable_fun;
+                               else
+                                       di_buf->vframe->
+                                       early_process_fun =
+                                               do_nothing_fun;
+                               if (prog_tb_field_proc_type == 2) {
+                                       di_buf->vframe->canvas0Addr =
+                                               di_buf->di_buf_dup_p[0]
+                                               ->nr_canvas_idx;
+/* top */
+                                       di_buf->vframe->canvas1Addr =
+                                               di_buf->di_buf_dup_p[0]
+                                               ->nr_canvas_idx;
+                               } else {
+                                       di_buf->vframe->canvas0Addr =
+                                               di_buf->di_buf_dup_p[1]
+                                               ->nr_canvas_idx; /* top */
+                                       di_buf->vframe->canvas1Addr =
+                                               di_buf->di_buf_dup_p[1]
+                                               ->nr_canvas_idx;
+                               }
+                       }
+
+                       di_buf->di_buf[0] = di_buf->di_buf_dup_p[0];
+                       queue_out(channel, di_buf->di_buf[0]);
+                       /*check if the field is error,then drop*/
+                       if (
+                               (di_buf->di_buf_dup_p[0]->vframe->type &
+                                VIDTYPE_TYPEMASK) ==
+                               VIDTYPE_INTERLACE_BOTTOM) {
+                               di_buf->di_buf[1] =
+                                       di_buf->di_buf_dup_p[1] = NULL;
+                               queue_in(channel, di_buf, QUEUE_TMP);
+                               recycle_vframe_type_post(di_buf, channel);
+                               pr_dbg("%s drop field %d.\n", __func__,
+                                      di_buf->di_buf_dup_p[0]->seq);
+                       } else {
+                               di_buf->di_buf[1] =
+                                       di_buf->di_buf_dup_p[1];
+                               queue_out(channel, di_buf->di_buf[1]);
+
+                               drop_frame(
+                                       dimp_get(eDI_MP_check_start_drop_prog),
+                                       (di_buf->di_buf_dup_p[0]->throw_flag) ||
+                                       (di_buf->di_buf_dup_p[1]->throw_flag),
+                                       di_buf, channel);
+                       }
+                       frame_count++;
+#ifdef DI_BUFFER_DEBUG
+                       dim_print("%s <prog by field>: ", __func__);
+#endif
+                       ret = 1;
+                       pw_vf_notify_receiver(channel,
+                               VFRAME_EVENT_PROVIDER_VFRAME_READY,
+                               NULL);
+               }
+       }
+
+#ifdef DI_BUFFER_DEBUG
+       if (di_buf) {
+               dim_print("%s[%d](",
+                         vframe_type_name[di_buf->type], di_buf->index);
+               for (i = 0; i < 2; i++) {
+                       if (di_buf->di_buf[i])
+                               dim_print("%s[%d],",
+                               vframe_type_name[di_buf->di_buf[i]->type],
+                               di_buf->di_buf[i]->index);
+               }
+               dim_print(")(vframe type %x dur %d)",
+                         di_buf->vframe->type, di_buf->vframe->duration);
+               if (di_buf->di_buf_dup_p[1] &&
+                   (di_buf->di_buf_dup_p[1]->post_proc_flag == 3))
+                       dim_print("=> recycle_list\n");
+               else
+                       dim_print("=> post_ready_list\n");
+       }
+#endif
+       return ret;
+}
+
+/*
+ * di task
+ */
+void dim_unreg_process(unsigned int channel)
+{
+       unsigned long start_jiffes = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       pr_info("%s unreg start %d.\n", __func__, get_reg_flag(channel));
+       if (get_reg_flag(channel)) {
+               start_jiffes = jiffies_64;
+               di_vframe_unreg(channel);
+               pr_dbg("%s vf unreg cost %u ms.\n", __func__,
+                       jiffies_to_msecs(jiffies_64 - start_jiffes));
+               unreg_cnt++;
+               if (unreg_cnt > 0x3fffffff)
+                       unreg_cnt = 0;
+               pr_dbg("%s unreg stop %d.\n", __func__, get_reg_flag(channel));
+
+       } else {
+               ppre->force_unreg_req_flag = 0;
+               ppre->disable_req_flag = 0;
+               recovery_flag = 0;
+       }
+}
+
+void di_unreg_setting(void)
+{
+       unsigned int mirror_disable = get_blackout_policy();
+
+       if (!get_hw_reg_flg()) {
+               PR_ERR("%s:have setting?do nothing\n", __func__);
+               return;
+       }
+
+       pr_info("%s:\n", __func__);
+       /*set flg*/
+       set_hw_reg_flg(false);
+
+       dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en));
+       post_close_new();       /*2018-11-29*/
+       dimh_afbc_reg_sw(false);
+       dimh_hw_uninit();
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()  ||
+           is_meson_sm1_cpu()) {
+               dim_pre_gate_control(false, dimp_get(eDI_MP_mcpre_en));
+               get_ops_nr()->nr_gate_control(false);
+       } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
+               dim_DI_Wr(DI_CLKG_CTRL, 0x80f60000);
+               dim_DI_Wr(DI_PRE_CTRL, 0);
+       } else {
+               dim_DI_Wr(DI_CLKG_CTRL, 0xf60000);
+       }
+       /*ary add for switch to post wr, can't display*/
+       pr_info("di: patch dimh_disable_post_deinterlace_2\n");
+       dimh_disable_post_deinterlace_2();
+       /* nr/blend0/ei0/mtn0 clock gate */
+
+       dim_hw_disable(dimp_get(eDI_MP_mcpre_en));
+
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()  ||
+           is_meson_sm1_cpu()) {
+               dimh_enable_di_post_mif(GATE_OFF);
+               dim_post_gate_control(false);
+               dim_top_gate_control(false, false);
+       } else {
+               dim_DI_Wr(DI_CLKG_CTRL, 0x80000000);
+       }
+       if (!is_meson_gxl_cpu() &&
+           !is_meson_gxm_cpu() &&
+           !is_meson_gxbb_cpu() &&
+           !is_meson_txlx_cpu())
+               diext_clk_b_sw(false);
+       pr_info("%s disable di mirror image.\n", __func__);
+
+#if 0
+       if (mirror_disable) {
+               /*no mirror:*/
+               if (dimp_get(eDI_MP_post_wr_en) &&
+                   dimp_get(eDI_MP_post_wr_support))
+                       dim_set_power_control(0);
+
+       } else {
+               /*have mirror:*/
+       }
+#else  /*0624?*/
+       if ((dimp_get(eDI_MP_post_wr_en)        &&
+            dimp_get(eDI_MP_post_wr_support))  ||
+            mirror_disable) {
+               /*diwr_set_power_control(0);*/
+               hpst_mem_pd_sw(0);
+       }
+       if (mirror_disable)
+               hpst_vd1_sw(0);
+#endif
+
+       #if 0   /*tmp*/
+       if (post_wr_en && post_wr_support)
+               dim_set_power_control(0);
+       #endif
+
+       disp_frame_count = 0;/* debug only*/
+}
+
+void di_unreg_variable(unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       unsigned int mirror_disable = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+#if (defined ENABLE_SPIN_LOCK_ALWAYS)
+       ulong flags = 0;
+
+       spin_lock_irqsave(&plist_lock, flags);
+#endif
+       pr_info("%s:\n", __func__);
+       set_init_flag(channel, false);  /*init_flag = 0;*/
+       mirror_disable = get_blackout_policy();
+       di_lock_irqfiq_save(irq_flag2);
+       dim_print("%s: dim_uninit_buf\n", __func__);
+       dim_uninit_buf(mirror_disable, channel);
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+       if (di_pre_rdma_enable)
+               rdma_clear(de_devp->rdma_handle);
+#endif
+       get_ops_mtn()->adpative_combing_exit();
+
+       di_unlock_irqfiq_restore(irq_flag2);
+
+#if (defined ENABLE_SPIN_LOCK_ALWAYS)
+       spin_unlock_irqrestore(&plist_lock, flags);
+#endif
+       dimh_patch_post_update_mc_sw(DI_MC_SW_REG, false);
+
+       ppre->force_unreg_req_flag = 0;
+       ppre->disable_req_flag = 0;
+       recovery_flag = 0;
+       ppre->cur_prog_flag = 0;
+
+       if (de_devp->flag_cma == 1      ||
+           de_devp->flag_cma == 3      ||
+           de_devp->flag_cma == 4)
+               dip_wq_cma_run(channel, false);
+
+       sum_g_clear(channel);
+       sum_p_clear(channel);
+       dbg_reg("%s:end\n", __func__);
+}
+
+void dim_unreg_process_irq(unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       unsigned int mirror_disable = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+#if (defined ENABLE_SPIN_LOCK_ALWAYS)
+       ulong flags = 0;
+
+       spin_lock_irqsave(&plist_lock, flags);
+#endif
+       pr_info("%s:warn:not use\n", __func__);
+       set_init_flag(channel, false);  /*init_flag = 0;*/
+       mirror_disable = 1;     /*get_blackout_policy()*/;
+       di_lock_irqfiq_save(irq_flag2);
+       dim_print("%s: dim_uninit_buf\n", __func__);
+       dim_uninit_buf(mirror_disable, channel);
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+       if (di_pre_rdma_enable)
+               rdma_clear(de_devp->rdma_handle);
+#endif
+       get_ops_mtn()->adpative_combing_exit();
+       dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en));
+       dimh_afbc_reg_sw(false);
+       dimh_hw_uninit();
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_sm1_cpu()  ||
+           is_meson_tm2_cpu()) {
+               dim_pre_gate_control(false, dimp_get(eDI_MP_mcpre_en));
+               get_ops_nr()->nr_gate_control(false);
+       } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
+               dim_DI_Wr(DI_CLKG_CTRL, 0x80f60000);
+               dim_DI_Wr(DI_PRE_CTRL, 0);
+       } else {
+               dim_DI_Wr(DI_CLKG_CTRL, 0xf60000);
+       }
+       /*ary add for switch to post wr, can't display*/
+       pr_info("di: patch dimh_disable_post_deinterlace_2\n");
+       dimh_disable_post_deinterlace_2();
+
+/* nr/blend0/ei0/mtn0 clock gate */
+       if (mirror_disable) {
+               dim_hw_disable(dimp_get(eDI_MP_mcpre_en));
+               if (is_meson_txlx_cpu() ||
+                   is_meson_txhd_cpu() ||
+                   is_meson_g12a_cpu() ||
+                   is_meson_g12b_cpu() ||
+                   is_meson_tl1_cpu()  ||
+                   is_meson_sm1_cpu()  ||
+                   is_meson_tm2_cpu()) {
+                       dimh_enable_di_post_mif(GATE_OFF);
+                       dim_post_gate_control(false);
+                       dim_top_gate_control(false, false);
+               } else {
+                       dim_DI_Wr(DI_CLKG_CTRL, 0x80000000);
+               }
+               if (!is_meson_gxl_cpu()         &&
+                   !is_meson_gxm_cpu()         &&
+                   !is_meson_gxbb_cpu()        &&
+                   !is_meson_txlx_cpu())
+                       diext_clk_b_sw(false);
+
+               pr_info("%s disable di mirror image.\n", __func__);
+       }
+       if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support))
+               dim_set_power_control(0);
+       di_unlock_irqfiq_restore(irq_flag2);
+
+#if (defined ENABLE_SPIN_LOCK_ALWAYS)
+       spin_unlock_irqrestore(&plist_lock, flags);
+#endif
+       dimh_patch_post_update_mc_sw(DI_MC_SW_REG, false);
+       ppre->force_unreg_req_flag = 0;
+       ppre->disable_req_flag = 0;
+       recovery_flag = 0;
+       ppre->cur_prog_flag = 0;
+
+#if 0
+#ifdef CONFIG_CMA
+       if (de_devp->flag_cma == 1) {
+               pr_dbg("%s:cma release req time: %d ms\n",
+                      __func__, jiffies_to_msecs(jiffies));
+               ppre->cma_release_req = 1;
+               up(get_sema());
+       }
+#endif
+#else
+       if (de_devp->flag_cma == 1)
+               dip_wq_cma_run(channel, false);
+
+#endif
+}
+
+void diext_clk_b_sw(bool on)
+{
+       if (on)
+               ext_ops.switch_vpu_clk_gate_vmod(VPU_VPU_CLKB,
+                               VPU_CLK_GATE_ON);
+       else
+               ext_ops.switch_vpu_clk_gate_vmod(VPU_VPU_CLKB,
+                               VPU_CLK_GATE_OFF);
+}
+
+void dim_reg_process(unsigned int channel)
+{
+       /*get vout information first time*/
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (get_reg_flag(channel))
+               return;
+       di_vframe_reg(channel);
+
+       ppre->bypass_flag = false;
+       reg_cnt++;
+       if (reg_cnt > 0x3fffffff)
+               reg_cnt = 0;
+       dim_print("########%s\n", __func__);
+}
+
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+/* di pre rdma operation */
+static void di_rdma_irq(void *arg)
+{
+       struct di_dev_s *di_devp = (struct di_dev_s *)arg;
+       unsigned int channel = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (IS_ERR_OR_NULL(di_devp))
+               return;
+       if (di_devp->rdma_handle <= 0) {
+               PR_ERR("%s rdma handle %d error.\n", __func__,
+                      di_devp->rdma_handle);
+               return;
+       }
+       if (dimp_get(eDI_MP_di_printk_flag))
+               pr_dbg("%s...%d.\n", __func__,
+                      ppre->field_count_for_cont);
+}
+
+static struct rdma_op_s di_rdma_op = {
+       di_rdma_irq,
+       NULL
+};
+#endif
+
+void dim_rdma_init(void)
+{
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+       struct di_dev_s *de_devp = get_dim_de_devp();
+/* rdma handle */
+       if (di_pre_rdma_enable) {
+               di_rdma_op.arg = de_devp;
+               de_devp->rdma_handle = rdma_register(&di_rdma_op,
+                       de_devp, RDMA_TABLE_SIZE);
+       }
+
+#endif
+}
+
+void dim_rdma_exit(void)
+{
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       /* rdma handle */
+       if (de_devp->rdma_handle > 0)
+               rdma_unregister(de_devp->rdma_handle);
+#endif
+}
+
+static void di_load_pq_table(void)
+{
+       struct di_pq_parm_s *pos = NULL, *tmp = NULL;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (atomic_read(&de_devp->pq_flag) == 0 &&
+           (de_devp->flags & DI_LOAD_REG_FLAG)) {
+               atomic_set(&de_devp->pq_flag, 1);
+               list_for_each_entry_safe(pos, tmp,
+                                        &de_devp->pq_table_list, list) {
+                       dimh_load_regs(pos);
+                       list_del(&pos->list);
+                       di_pq_parm_destroy(pos);
+               }
+               de_devp->flags &= ~DI_LOAD_REG_FLAG;
+               atomic_set(&de_devp->pq_flag, 0);
+       }
+}
+
+static void di_pre_size_change(unsigned short width,
+                              unsigned short height,
+                              unsigned short vf_type,
+                              unsigned int channel)
+{
+       unsigned int blkhsize = 0;
+       int pps_w = 0, pps_h = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       /*pr_info("%s:\n", __func__);*/
+       /*debug only:*/
+       /*di_pause(channel, true);*/
+       get_ops_nr()->nr_all_config(width, height, vf_type);
+       #ifdef DET3D
+       /*det3d_config*/
+       get_ops_3d()->det3d_config(dimp_get(eDI_MP_det3d_en) ? 1 : 0);
+       #endif
+       if (dimp_get(eDI_MP_pulldown_enable)) {
+               /*pulldown_init(width, height);*/
+               get_ops_pd()->init(width, height);
+               dimh_init_field_mode(height);
+
+               if (is_meson_txl_cpu()  ||
+                   is_meson_txlx_cpu() ||
+                   is_meson_gxlx_cpu() ||
+                   is_meson_txhd_cpu() ||
+                   is_meson_g12a_cpu() ||
+                   is_meson_g12b_cpu() ||
+                   is_meson_tl1_cpu()  ||
+                   is_meson_tm2_cpu()  ||
+                   is_meson_sm1_cpu())
+                       dim_film_mode_win_config(width, height);
+       }
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               dimh_combing_pd22_window_config(width, height);
+       dim_RDMA_WR(DI_PRE_SIZE, (width - 1) |
+               ((height - 1) << 16));
+
+       if (dimp_get(eDI_MP_mcpre_en)) {
+               blkhsize = (width + 4) / 5;
+               dim_RDMA_WR(MCDI_HV_SIZEIN, height
+                       | (width << 16));
+               dim_RDMA_WR(MCDI_HV_BLKSIZEIN, (overturn ? 3 : 0) << 30
+                       | blkhsize << 16 | height);
+               dim_RDMA_WR(MCDI_BLKTOTAL, blkhsize * height);
+               if (is_meson_gxlx_cpu()) {
+                       dim_RDMA_WR(MCDI_PD_22_CHK_FLG_CNT, 0);
+                       dim_RDMA_WR(MCDI_FIELD_MV, 0);
+               }
+       }
+       if (channel == 0)
+               di_load_pq_table();
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dim_RDMA_WR(DI_PRE_GL_CTRL, 0x80000005);
+       if (de_devp->nrds_enable)
+               dim_nr_ds_init(width, height);
+       if (de_devp->pps_enable && dimp_get(eDI_MP_pps_position)) {
+               pps_w = ppre->cur_width;
+               pps_h = ppre->cur_height >> 1;
+               dim_pps_config(1, pps_w, pps_h,
+                              dimp_get(eDI_MP_pps_dstw),
+                              (dimp_get(eDI_MP_pps_dsth) >> 1));
+       }
+       if (is_meson_sm1_cpu() || is_meson_tm2_cpu()) {
+               if (de_devp->h_sc_down_en) {
+                       pps_w = ppre->cur_width;
+                       dim_inp_hsc_setting(pps_w,
+                               di_mp_uit_get(eDI_MP_pre_hsc_down_width));
+               } else {
+                       dim_inp_hsc_setting(ppre->cur_width,
+                                           ppre->cur_width);
+               }
+       }
+       #if 0
+       dimh_interrupt_ctrl(ppre->madi_enable,
+                           det3d_en ? 1 : 0,
+                           de_devp->nrds_enable,
+                           post_wr_en,
+                           ppre->mcdi_enable);
+       #else
+       /*dimh_int_ctr(0, 0, 0, 0, 0, 0);*/
+       dimh_int_ctr(1, ppre->madi_enable,
+                    dimp_get(eDI_MP_det3d_en) ? 1 : 0,
+                    de_devp->nrds_enable,
+                    dimp_get(eDI_MP_post_wr_en),
+                    ppre->mcdi_enable);
+       #endif
+}
+
+static bool need_bypass(struct vframe_s *vf)
+{
+       if (vf->type & VIDTYPE_MVC)
+               return true;
+
+       if (vf->source_type == VFRAME_SOURCE_TYPE_PPMGR)
+               return true;
+
+       if (vf->type & VIDTYPE_VIU_444)
+               return true;
+
+       if (vf->type & VIDTYPE_PIC)
+               return true;
+#if 0
+       if (vf->type & VIDTYPE_COMPRESS)
+               return true;
+#else
+       /*support G12A and TXLX platform*/
+       if (vf->type & VIDTYPE_COMPRESS) {
+               if (!dimh_afbc_is_supported())
+                       return true;
+               if ((vf->compHeight > (default_height + 8))     ||
+                   (vf->compWidth > default_width))
+                       return true;
+       }
+#endif
+       if ((vf->width > default_width) ||
+           (vf->height > (default_height + 8)))
+               return true;
+#if 1
+       if (vf_type_is_prog(vf->type)) {/*temp bypass p*/
+               return true;
+       }
+#endif
+       /*true bypass for 720p above*/
+       if ((vf->flag & VFRAME_FLAG_GAME_MODE) &&
+           (vf->width > 720))
+               return true;
+
+       return false;
+}
+
+/*********************************
+ *
+ * setting register only call when
+ * from di_reg_process_irq
+ *********************************/
+void di_reg_setting(unsigned int channel, struct vframe_s *vframe)
+{
+       unsigned short nr_height = 0, first_field_type;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       pr_info("%s:ch[%d]:for first ch reg:\n", __func__, channel);
+
+       if (get_hw_reg_flg()) {
+               PR_ERR("%s:have setting?do nothing\n", __func__);
+               return;
+       }
+       /*set flg*/
+       set_hw_reg_flg(true);
+
+       diext_clk_b_sw(true);
+
+       dim_ddbg_mod_save(eDI_DBG_MOD_REGB, channel, 0);
+
+       if (dimp_get(eDI_MP_post_wr_en) &&
+           dimp_get(eDI_MP_post_wr_support))
+               dim_set_power_control(1);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) {
+               /*if (!use_2_interlace_buff) {*/
+               if (1) {
+                       dim_top_gate_control(true, true);
+                       dim_post_gate_control(true);
+                       /* freerun for reg configuration */
+                       dimh_enable_di_post_mif(GATE_AUTO);
+               } else {
+                       dim_top_gate_control(true, false);
+               }
+               de_devp->flags |= DI_VPU_CLKB_SET;
+               #if 1   /*set clkb to max */
+               if (is_meson_g12a_cpu() ||
+                   is_meson_g12b_cpu() ||
+                   is_meson_tl1_cpu()  ||
+                   is_meson_tm2_cpu()  ||
+                   is_meson_sm1_cpu()
+                   ) {
+                       #ifdef CLK_TREE_SUPPORT
+                       clk_set_rate(de_devp->vpu_clkb,
+                                    de_devp->clkb_max_rate);
+                       #endif
+               }
+               #endif
+               dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en));
+               dim_pre_gate_control(true, dimp_get(eDI_MP_mcpre_en));
+               dim_rst_protect(true);/*2019-01-22 by VLSI feng.wang*/
+               dim_pre_nr_wr_done_sel(true);
+               get_ops_nr()->nr_gate_control(true);
+       } else {
+               /* if mcdi enable DI_CLKG_CTRL should be 0xfef60000 */
+               dim_DI_Wr(DI_CLKG_CTRL, 0xfef60001);
+               /* nr/blend0/ei0/mtn0 clock gate */
+       }
+       /*--------------------------*/
+       dim_init_setting_once();
+       /*--------------------------*/
+       /*di_post_reset();*/ /*add by feijun 2018-11-19 */
+       post_mif_sw(false);
+       post_dbg_contr();
+       /*--------------------------*/
+
+       nr_height = (vframe->height >> 1);/*temp*/
+       /*--------------------------*/
+       dimh_calc_lmv_init();
+       first_field_type = (vframe->type & VIDTYPE_TYPEMASK);
+       di_pre_size_change(vframe->width, nr_height,
+                          first_field_type, channel);
+       get_ops_nr()->cue_int();
+       dim_ddbg_mod_save(eDI_DBG_MOD_REGE, channel, 0);
+
+       /*--------------------------*/
+       /*test*/
+       dimh_int_ctr(0, 0, 0, 0, 0, 0);
+}
+
+/*********************************
+ *
+ * setting variable
+ * from di_reg_process_irq
+ *
+ *********************************/
+void di_reg_variable(unsigned int channel, struct vframe_s *vframe)
+{
+       ulong irq_flag2 = 0;
+       #ifndef RUN_DI_PROCESS_IN_IRQ
+       ulong flags = 0;
+       #endif
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if ((pre_run_flag != DI_RUN_FLAG_RUN) &&
+           (pre_run_flag != DI_RUN_FLAG_STEP))
+               return;
+       if (pre_run_flag == DI_RUN_FLAG_STEP)
+               pre_run_flag = DI_RUN_FLAG_STEP_DONE;
+
+       dbg_reg("%s:\n", __func__);
+
+       dim_print("%s:0x%p\n", __func__, vframe);
+       if (vframe) {
+               dip_init_value_reg(channel);/*add 0404 for post*/
+               dim_ddbg_mod_save(eDI_DBG_MOD_RVB, channel, 0);
+               if (need_bypass(vframe) ||
+                   ((dimp_get(eDI_MP_di_debug_flag) >> 20) & 0x1)) {
+                       if (!ppre->bypass_flag) {
+                               pr_info("DI  %ux%u-0x%x.\n",
+                                       vframe->width,
+                                       vframe->height,
+                                       vframe->type);
+                       }
+                       ppre->bypass_flag = true;
+                       dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false);
+                       return;
+
+               ppre->bypass_flag = false;
+               }
+               /* patch for vdin progressive input */
+               if ((is_from_vdin(vframe)       &&
+                   is_progressive(vframe))
+                       #ifdef DET3D
+                       || dimp_get(eDI_MP_det3d_en)
+                       #endif
+                       || (dimp_get(eDI_MP_use_2_interlace_buff) & 0x2)
+                       ) {
+                       dimp_set(eDI_MP_use_2_interlace_buff, 1);
+               } else {
+                       dimp_set(eDI_MP_use_2_interlace_buff, 0);
+               }
+               de_devp->nrds_enable = dimp_get(eDI_MP_nrds_en);
+               de_devp->pps_enable = dimp_get(eDI_MP_pps_en);
+               /*di pre h scaling down: sm1 tm2*/
+               de_devp->h_sc_down_en = di_mp_uit_get(eDI_MP_pre_hsc_down_en);
+
+               if (dimp_get(eDI_MP_di_printk_flag) & 2)
+                       dimp_set(eDI_MP_di_printk_flag, 1);
+
+               dim_print("%s: vframe come => di_init_buf\n", __func__);
+
+               if (de_devp->flag_cma == 0 && !de_devp->mem_flg)
+                       dim_rev_mem_check();
+
+               /*(is_progressive(vframe) && (prog_proc_config & 0x10)) {*/
+               if (0) {
+#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS)
+                       spin_lock_irqsave(&plist_lock, flags);
+#endif
+                       di_lock_irqfiq_save(irq_flag2);
+                       /*
+                        * 10 bit mode need 1.5 times buffer size of
+                        * 8 bit mode, init the buffer size as 10 bit
+                        * mode size, to make sure can switch bit mode
+                        * smoothly.
+                        */
+                       di_init_buf(default_width, default_height, 1, channel);
+
+                       di_unlock_irqfiq_restore(irq_flag2);
+
+#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS)
+                       spin_unlock_irqrestore(&plist_lock, flags);
+#endif
+               } else {
+#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS)
+                       spin_lock_irqsave(&plist_lock, flags);
+#endif
+                       di_lock_irqfiq_save(irq_flag2);
+                       /*
+                        * 10 bit mode need 1.5 times buffer size of
+                        * 8 bit mode, init the buffer size as 10 bit
+                        * mode size, to make sure can switch bit mode
+                        * smoothly.
+                        */
+                       di_init_buf(default_width, default_height, 0, channel);
+
+                       di_unlock_irqfiq_restore(irq_flag2);
+
+#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS)
+                       spin_unlock_irqrestore(&plist_lock, flags);
+#endif
+               }
+
+               ppre->mtn_status =
+                       get_ops_mtn()->adpative_combing_config(vframe->width,
+                                       (vframe->height >> 1),
+                                       (vframe->source_type),
+                                       is_progressive(vframe),
+                                       vframe->sig_fmt);
+
+               dimh_patch_post_update_mc_sw(DI_MC_SW_REG, true);
+               di_sum_reg_init(channel);
+
+               set_init_flag(channel, true);/*init_flag = 1;*/
+
+               dim_ddbg_mod_save(eDI_DBG_MOD_RVE, channel, 0);
+       }
+}
+
+/*para 1 not use*/
+
+/*
+ * provider/receiver interface
+ */
+
+/*************************/
+int di_ori_event_unreg(unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       pr_dbg("%s , is_bypass() %d trick_mode %d bypass_all %d\n",
+              __func__,
+              dim_is_bypass(NULL, channel),
+              trick_mode,
+              di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL));
+       /*dbg_ev("%s:unreg\n", __func__);*/
+       dip_even_unreg_val(channel);    /*new*/
+
+       ppre->vdin_source = false;
+
+       dip_event_unreg_chst(channel);
+
+#ifdef SUPPORT_MPEG_TO_VDIN
+       if (mpeg2vdin_flag) {
+               struct vdin_arg_s vdin_arg;
+               struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops();
+
+               vdin_arg.cmd = VDIN_CMD_MPEGIN_STOP;
+               if (vdin_ops->tvin_vdin_func)
+                       vdin_ops->tvin_vdin_func(0, &vdin_arg);
+
+               mpeg2vdin_flag = 0;
+       }
+#endif
+       di_bypass_state_set(channel, true);
+#ifdef RUN_DI_PROCESS_IN_IRQ
+       if (ppre->vdin_source)
+               dim_DI_Wr_reg_bits(VDIN_WR_CTRL, 0x3, 24, 3);
+#endif
+
+       dbg_ev("ch[%d]unreg end\n", channel);
+       return 0;
+}
+
+int di_ori_event_reg(void *data, unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       struct vframe_receiver_s *preceiver;
+
+       char *provider_name = (char *)data;
+       const char *receiver_name = NULL;
+
+       dip_even_reg_init_val(channel);
+       if (de_devp->flags & DI_SUSPEND_FLAG) {
+               PR_ERR("reg event device hasn't resumed\n");
+               return -1;
+       }
+       if (get_reg_flag(channel)) {
+               PR_ERR("no muti instance.\n");
+               return -1;
+       }
+       dbg_ev("reg:%s\n", provider_name);
+
+       di_bypass_state_set(channel, false);
+
+       dip_event_reg_chst(channel);
+
+       if (strncmp(provider_name, "vdin0", 4) == 0)
+               ppre->vdin_source = true;
+       else
+               ppre->vdin_source = false;
+
+       /*ary: need use interface api*/
+       /*receiver_name = vf_get_receiver_name(VFM_NAME);*/
+       preceiver = vf_get_receiver(di_rev_name[channel]);
+       receiver_name = preceiver->name;
+       if (receiver_name) {
+               if (!strcmp(receiver_name, "amvideo")) {
+                       ppost->run_early_proc_fun_flag = 0;
+                       if (dimp_get(eDI_MP_post_wr_en) &&
+                           dimp_get(eDI_MP_post_wr_support))
+                               ppost->run_early_proc_fun_flag = 1;
+               } else {
+                       ppost->run_early_proc_fun_flag = 1;
+                       pr_info("set run_early_proc_fun_flag to 1\n");
+               }
+       } else {
+               pr_info("%s error receiver is null.\n", __func__);
+       }
+
+       dbg_ev("ch[%d]:reg end\n", channel);
+       return 0;
+}
+
+int di_ori_event_qurey_vdin2nr(unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       return ppre->vdin2nr;
+}
+
+int di_ori_event_reset(unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       int i;
+       ulong flags;
+
+       /*block*/
+       di_blocking = 1;
+
+       /*dbg_ev("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__);*/
+       if (dim_is_bypass(NULL, channel)        ||
+           di_bypass_state_get(channel)        ||
+           ppre->bypass_flag) {
+               pw_vf_notify_receiver(channel,
+                                     VFRAME_EVENT_PROVIDER_RESET,
+                       NULL);
+       }
+
+       spin_lock_irqsave(&plist_lock, flags);
+       for (i = 0; i < MAX_IN_BUF_NUM; i++) {
+               if (pvframe_in[i])
+                       pr_dbg("DI:clear vframe_in[%d]\n", i);
+
+               pvframe_in[i] = NULL;
+       }
+       spin_unlock_irqrestore(&plist_lock, flags);
+       di_blocking = 0;
+
+       return 0;
+}
+
+int di_ori_event_light_unreg(unsigned int channel)
+{
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       int i;
+       ulong flags;
+
+       di_blocking = 1;
+
+       pr_dbg("%s: vf_notify_receiver ligth unreg\n", __func__);
+
+       spin_lock_irqsave(&plist_lock, flags);
+       for (i = 0; i < MAX_IN_BUF_NUM; i++) {
+               if (pvframe_in[i])
+                       pr_dbg("DI:clear vframe_in[%d]\n", i);
+
+               pvframe_in[i] = NULL;
+       }
+       spin_unlock_irqrestore(&plist_lock, flags);
+       di_blocking = 0;
+
+       return 0;
+}
+
+int di_ori_event_light_unreg_revframe(unsigned int channel)
+{
+       struct vframe_s **pvframe_in = get_vframe_in(channel);
+       int i;
+       ulong flags;
+
+       unsigned char vf_put_flag = 0;
+
+       pr_info(
+               "%s:VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME\n",
+               __func__);
+/*
+ * do not display garbage when 2d->3d or 3d->2d
+ */
+       spin_lock_irqsave(&plist_lock, flags);
+       for (i = 0; i < MAX_IN_BUF_NUM; i++) {
+               if (pvframe_in[i]) {
+                       pw_vf_put(pvframe_in[i], channel);
+                       pr_dbg("DI:clear vframe_in[%d]\n", i);
+                       vf_put_flag = 1;
+               }
+               pvframe_in[i] = NULL;
+       }
+       if (vf_put_flag)
+               pw_vf_notify_provider(channel,
+                                     VFRAME_EVENT_RECEIVER_PUT, NULL);
+
+       spin_unlock_irqrestore(&plist_lock, flags);
+
+       return 0;
+}
+
+int di_irq_ori_event_ready(unsigned int channel)
+{
+       return 0;
+}
+
+int di_ori_event_ready(unsigned int channel)
+{
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (ppre->bypass_flag)
+               pw_vf_notify_receiver(channel,
+                                     VFRAME_EVENT_PROVIDER_VFRAME_READY,
+                                     NULL);
+
+       if (dip_chst_get(channel) == eDI_TOP_STATE_REG_STEP1)
+               task_send_cmd(LCMD1(eCMD_READY, channel));
+       else
+               task_send_ready();
+
+       di_irq_ori_event_ready(channel);
+       return 0;
+}
+
+int di_ori_event_qurey_state(unsigned int channel)
+{
+       /*int in_buf_num = 0;*/
+       struct vframe_states states;
+
+       if (recovery_flag)
+               return RECEIVER_INACTIVE;
+
+       /*fix for ucode reset method be break by di.20151230*/
+       di_vf_l_states(&states, channel);
+       if (states.buf_avail_num > 0)
+               return RECEIVER_ACTIVE;
+
+       if (pw_vf_notify_receiver(
+               channel,
+               VFRAME_EVENT_PROVIDER_QUREY_STATE,
+               NULL) == RECEIVER_ACTIVE)
+               return RECEIVER_ACTIVE;
+
+       return RECEIVER_INACTIVE;
+}
+
+void  di_ori_event_set_3D(int type, void *data, unsigned int channel)
+{
+#ifdef DET3D
+
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) {
+               int flag = (long)data;
+
+               ppre->vframe_interleave_flag = flag;
+       }
+
+#endif
+}
+
+/*************************/
+
+/*recycle the buffer for keeping buffer*/
+static void recycle_keep_buffer(unsigned int channel)
+{
+       ulong irq_flag2 = 0;
+       int i = 0;
+       struct di_buf_s *keep_buf;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       keep_buf = ppost->keep_buf;
+       if (!IS_ERR_OR_NULL(keep_buf)) {
+               PR_ERR("%s:\n", __func__);
+               if (keep_buf->type == VFRAME_TYPE_POST) {
+                       pr_dbg("%s recycle keep cur di_buf %d (",
+                              __func__, keep_buf->index);
+                       di_lock_irqfiq_save(irq_flag2);
+                       for (i = 0; i < USED_LOCAL_BUF_MAX; i++) {
+                               if (keep_buf->di_buf_dup_p[i]) {
+                                       queue_in(channel,
+                                                keep_buf->di_buf_dup_p[i],
+                                                QUEUE_RECYCLE);
+                                       pr_dbg(" %d ",
+                                       keep_buf->di_buf_dup_p[i]->index);
+                               }
+                       }
+                       di_que_in(channel, QUE_POST_FREE, keep_buf);
+                       di_unlock_irqfiq_restore(irq_flag2);
+                       pr_dbg(")\n");
+               }
+               ppost->keep_buf = NULL;
+       }
+}
+
+/************************************/
+/************************************/
+struct vframe_s *di_vf_l_get(unsigned int channel)
+{
+       vframe_t *vframe_ret = NULL;
+       struct di_buf_s *di_buf = NULL;
+#ifdef DI_DEBUG_POST_BUF_FLOW
+       struct di_buf_s *nr_buf = NULL;
+#endif
+
+       ulong irq_flag2 = 0;
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       dim_print("%s:ch[%d]\n", __func__, channel);
+
+       if (!get_init_flag(channel)     ||
+           recovery_flag               ||
+           di_blocking                 ||
+           !get_reg_flag(channel)      ||
+           dump_state_flag) {
+               dim_tr_ops.post_get2(1);
+               return NULL;
+       }
+
+       /**************************/
+       if (list_count(channel, QUEUE_DISPLAY) > 2) {
+               dim_tr_ops.post_get2(2);
+               return NULL;
+       }
+       /**************************/
+
+#ifdef SUPPORT_START_FRAME_HOLD
+       if ((disp_frame_count == 0) && (dim_is_bypass(NULL, channel) == 0)) {
+               int ready_count = di_que_list_count(channel, QUE_POST_READY);
+
+               if (ready_count > start_frame_hold_count)
+                       goto get_vframe;
+       } else
+#endif
+       if (!di_que_is_empty(channel, QUE_POST_READY)) {
+#ifdef SUPPORT_START_FRAME_HOLD
+get_vframe:
+#endif
+               dim_log_buffer_state("ge_", channel);
+               di_lock_irqfiq_save(irq_flag2);
+
+               di_buf = di_que_out_to_di_buf(channel, QUE_POST_READY);
+               if (dim_check_di_buf(di_buf, 21, channel)) {
+                       di_unlock_irqfiq_restore(irq_flag2);
+                       return NULL;
+               }
+               /* add it into display_list */
+               queue_in(channel, di_buf, QUEUE_DISPLAY);
+
+               di_unlock_irqfiq_restore(irq_flag2);
+
+               if (di_buf) {
+                       vframe_ret = di_buf->vframe;
+#ifdef DI_DEBUG_POST_BUF_FLOW
+       nr_buf = di_buf->di_buf_dup_p[1];
+       if (dimp_get(eDI_MP_post_wr_en)         &&
+           dimp_get(eDI_MP_post_wr_support)    &&
+           (di_buf->process_fun_index != PROCESS_FUN_NULL)) {
+               #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+               vframe_ret->canvas0_config[0].phy_addr =
+                       di_buf->nr_adr;
+               vframe_ret->canvas0_config[0].width =
+                       di_buf->canvas_width[NR_CANVAS],
+               vframe_ret->canvas0_config[0].height =
+                       di_buf->canvas_height;
+               vframe_ret->canvas0_config[0].block_mode = 0;
+               vframe_ret->plane_num = 1;
+               vframe_ret->canvas0Addr = -1;
+               vframe_ret->canvas1Addr = -1;
+               if (di_mp_uit_get(eDI_MP_show_nrwr)) {
+                       vframe_ret->canvas0_config[0].phy_addr =
+                               nr_buf->nr_adr;
+                       vframe_ret->canvas0_config[0].width =
+                               nr_buf->canvas_width[NR_CANVAS];
+                       vframe_ret->canvas0_config[0].height =
+                               nr_buf->canvas_height;
+               }
+               #else
+               config_canvas_idx(di_buf, di_wr_idx, -1);
+               vframe_ret->canvas0Addr = di_buf->nr_canvas_idx;
+               vframe_ret->canvas1Addr = di_buf->nr_canvas_idx;
+               if (di_mp_uit_get(eDI_MP_show_nrwr)) {
+                       config_canvas_idx(nr_buf,
+                                         di_wr_idx, -1);
+                       vframe_ret->canvas0Addr = di_wr_idx;
+                       vframe_ret->canvas1Addr = di_wr_idx;
+               }
+               #endif
+               vframe_ret->early_process_fun = dim_do_post_wr_fun;
+               vframe_ret->process_fun = NULL;
+       }
+#endif
+                       di_buf->seq = disp_frame_count;
+                       atomic_set(&di_buf->di_cnt, 1);
+               }
+               disp_frame_count++;
+
+               dim_log_buffer_state("get", channel);
+       }
+       if (vframe_ret) {
+               dim_print("%s: %s[%d]:%x %u ms\n", __func__,
+                         vframe_type_name[di_buf->type],
+                         di_buf->index,
+                         vframe_ret,
+                         jiffies_to_msecs(jiffies_64 -
+                         vframe_ret->ready_jiffies64));
+               didbg_vframe_out_save(vframe_ret);
+
+               dim_tr_ops.post_get(vframe_ret->omx_index);
+       } else {
+               dim_tr_ops.post_get2(3);
+       }
+
+       if (!dimp_get(eDI_MP_post_wr_en)        &&
+           ppost->run_early_proc_fun_flag      &&
+           vframe_ret) {
+               if (vframe_ret->early_process_fun == do_pre_only_fun)
+                       vframe_ret->early_process_fun(vframe_ret->private_data,
+                                                     vframe_ret);
+       }
+       return vframe_ret;
+}
+
+void di_vf_l_put(struct vframe_s *vf, unsigned char channel)
+{
+       struct di_buf_s *di_buf = NULL;
+       ulong irq_flag2 = 0;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       dim_print("%s:ch[%d]\n", __func__, channel);
+
+       if (ppre->bypass_flag) {
+               pw_vf_put(vf, channel);
+               pw_vf_notify_provider(channel,
+                                     VFRAME_EVENT_RECEIVER_PUT, NULL);
+               if (!IS_ERR_OR_NULL(ppost->keep_buf))
+                       recycle_keep_buffer(channel);
+               return;
+       }
+/* struct di_buf_s *p = NULL; */
+/* int itmp = 0; */
+       if (!get_init_flag(channel)     ||
+           recovery_flag               ||
+           IS_ERR_OR_NULL(vf)) {
+               PR_ERR("%s: 0x%p\n", __func__, vf);
+               return;
+       }
+       if (di_blocking)
+               return;
+       dim_log_buffer_state("pu_", channel);
+       di_buf = (struct di_buf_s *)vf->private_data;
+       if (IS_ERR_OR_NULL(di_buf)) {
+               pw_vf_put(vf, channel);
+               pw_vf_notify_provider(channel,
+                                     VFRAME_EVENT_RECEIVER_PUT, NULL);
+               PR_ERR("%s: get vframe %p without di buf\n",
+                      __func__, vf);
+               return;
+       }
+#if 0
+       if (ppost->keep_buf == di_buf) {
+               pr_info("[DI]recycle buffer %d, get cnt %d.\n",
+                       di_buf->index, disp_frame_count);
+               recycle_keep_buffer(channel);
+       }
+#else
+
+#endif
+
+       if (di_buf->type == VFRAME_TYPE_POST
+               ) {
+#if 0
+               dim_print("%s:put:%d\n", __func__, di_buf->index);
+
+               di_lock_irqfiq_save(irq_flag2);
+
+               if (is_in_queue(channel, di_buf, QUEUE_DISPLAY)) {
+                       if (!atomic_dec_and_test(&di_buf->di_cnt))
+                               dim_print("%s,di_cnt > 0\n", __func__);
+                       dim_print("%s:put:%d\n", __func__, di_buf->index);
+                       recycle_vframe_type_post(di_buf, channel);
+               } else {
+                       dim_print("%s: %s[%d] not in display list\n", __func__,
+                                  vframe_type_name[di_buf->type],
+                                  di_buf->index);
+               }
+               di_unlock_irqfiq_restore(irq_flag2);
+#ifdef DI_BUFFER_DEBUG
+               recycle_vframe_type_post_print(di_buf, __func__, __LINE__);
+#endif
+#else
+               pw_queue_in(channel, QUE_POST_BACK, di_buf->index);
+#endif
+       } else {
+               di_lock_irqfiq_save(irq_flag2);
+               queue_in(channel, di_buf, QUEUE_RECYCLE);
+               di_unlock_irqfiq_restore(irq_flag2);
+
+               dim_print("%s: %s[%d] =>recycle_list\n", __func__,
+                          vframe_type_name[di_buf->type], di_buf->index);
+       }
+
+       task_send_ready();
+}
+
+void dim_recycle_post_back(unsigned int channel)
+{
+       struct di_buf_s *di_buf = NULL;
+       unsigned int post_buf_index;
+       struct di_buf_s *pbuf_post = get_buf_post(channel);
+       ulong irq_flag2 = 0;
+
+       struct di_post_stru_s *ppost = get_post_stru(channel);
+
+       if (pw_queue_empty(channel, QUE_POST_BACK))
+               return;
+
+       while (pw_queue_out(channel, QUE_POST_BACK, &post_buf_index)) {
+               /*pr_info("dp2:%d\n", post_buf_index);*/
+               if (post_buf_index >= MAX_POST_BUF_NUM) {
+                       PR_ERR("%s:index is overlfow[%d]\n",
+                              __func__, post_buf_index);
+                       break;
+               }
+               dim_print("di_back:%d\n", post_buf_index);
+               di_lock_irqfiq_save(irq_flag2); /**/
+
+               di_buf = &pbuf_post[post_buf_index];
+               if (!atomic_dec_and_test(&di_buf->di_cnt))
+                       PR_ERR("%s,di_cnt > 0\n", __func__);
+               recycle_vframe_type_post(di_buf, channel);
+               di_unlock_irqfiq_restore(irq_flag2);
+       }
+       /*back keep_buf:*/
+       if (ppost->keep_buf_post) {
+               PR_INF("ch[%d]:%s:%d\n",
+                      channel,
+                      __func__,
+                      ppost->keep_buf_post->index);
+               di_lock_irqfiq_save(irq_flag2); /**/
+               di_que_in(channel, QUE_POST_FREE, ppost->keep_buf_post);
+               di_unlock_irqfiq_restore(irq_flag2);
+               ppost->keep_buf_post = NULL;
+       }
+}
+
+struct vframe_s *di_vf_l_peek(unsigned int channel)
+{
+       struct vframe_s *vframe_ret = NULL;
+       struct di_buf_s *di_buf = NULL;
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       /*dim_print("%s:ch[%d]\n",__func__, channel);*/
+
+       di_sum_inc(channel, eDI_SUM_O_PEEK_CNT);
+       if (ppre->bypass_flag) {
+               dim_tr_ops.post_peek(0);
+               return pw_vf_peek(channel);
+       }
+       if (!get_init_flag(channel)     ||
+           recovery_flag               ||
+           di_blocking                 ||
+           !get_reg_flag(channel)      ||
+           dump_state_flag) {
+               dim_tr_ops.post_peek(1);
+               return NULL;
+       }
+
+       /**************************/
+       if (list_count(channel, QUEUE_DISPLAY) > DI_POST_GET_LIMIT) {
+               dim_tr_ops.post_peek(2);
+               return NULL;
+       }
+       /**************************/
+       dim_log_buffer_state("pek", channel);
+
+#ifdef SUPPORT_START_FRAME_HOLD
+       if ((disp_frame_count == 0) && (dim_is_bypass(NULL, channel) == 0)) {
+               int ready_count = di_que_list_count(channel, QUE_POST_READY);
+
+               if (ready_count > start_frame_hold_count) {
+                       di_buf = di_que_peek(channel, QUE_POST_READY);
+                       if (di_buf)
+                               vframe_ret = di_buf->vframe;
+               }
+       } else
+#endif
+       {
+               if (!di_que_is_empty(channel, QUE_POST_READY)) {
+                       di_buf = di_que_peek(channel, QUE_POST_READY);
+                       if (di_buf)
+                               vframe_ret = di_buf->vframe;
+               }
+       }
+#ifdef DI_BUFFER_DEBUG
+       if (vframe_ret)
+               dim_print("%s: %s[%d]:%x\n", __func__,
+                         vframe_type_name[di_buf->type],
+                         di_buf->index, vframe_ret);
+#endif
+       if (vframe_ret)
+               dim_tr_ops.post_peek(9);
+       else
+               dim_tr_ops.post_peek(4);
+       return vframe_ret;
+}
+
+int di_vf_l_states(struct vframe_states *states, unsigned int channel)
+{
+       struct di_mm_s *mm = dim_mm_get();
+
+       /*pr_info("%s: ch[%d]\n", __func__, channel);*/
+       if (!states)
+               return -1;
+       states->vf_pool_size = mm->sts.num_local;
+       states->buf_free_num = list_count(channel, QUEUE_LOCAL_FREE);
+
+       states->buf_avail_num = di_que_list_count(channel, QUE_POST_READY);
+       states->buf_recycle_num = list_count(channel, QUEUE_RECYCLE);
+       if (dimp_get(eDI_MP_di_dbg_mask) & 0x1) {
+               di_pr_info("di-pre-ready-num:%d\n",
+                          /*new que list_count(channel, QUEUE_PRE_READY));*/
+                          di_que_list_count(channel, QUE_PRE_READY));
+               di_pr_info("di-display-num:%d\n",
+                          list_count(channel, QUEUE_DISPLAY));
+       }
+       return 0;
+}
+
+/**********************************************/
+
+/*****************************
+ *      di driver file_operations
+ *
+ ******************************/
+#if 0 /*move to di_sys.c*/
+static int di_open(struct inode *node, struct file *file)
+{
+       di_dev_t *di_in_devp;
+
+/* Get the per-device structure that contains this cdev */
+       di_in_devp = container_of(node->i_cdev, di_dev_t, cdev);
+       file->private_data = di_in_devp;
+
+       return 0;
+}
+
+static int di_release(struct inode *node, struct file *file)
+{
+/* di_dev_t *di_in_devp = file->private_data; */
+
+/* Reset file pointer */
+
+/* Release some other fields */
+       file->private_data = NULL;
+       return 0;
+}
+
+#endif /*move to di_sys.c*/
+
+static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *pq_parm_p)
+{
+       struct di_pq_parm_s *pq_ptr = NULL;
+       struct am_reg_s *am_reg_p = NULL;
+       size_t mem_size = 0;
+
+       pq_ptr = vzalloc(sizeof(*pq_ptr));
+       mem_size = sizeof(struct am_pq_parm_s);
+       memcpy(&pq_ptr->pq_parm, pq_parm_p, mem_size);
+       mem_size = sizeof(struct am_reg_s) * pq_parm_p->table_len;
+       am_reg_p = vzalloc(mem_size);
+       if (!am_reg_p) {
+               vfree(pq_ptr);
+               PR_ERR("alloc pq table memory errors\n");
+               return NULL;
+       }
+       pq_ptr->regs = am_reg_p;
+
+       return pq_ptr;
+}
+
+static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr)
+{
+       if (!pq_ptr) {
+               PR_ERR("%s pq parm pointer null.\n", __func__);
+               return;
+       }
+       vfree(pq_ptr->regs);
+       vfree(pq_ptr);
+}
+
+/*move from ioctrl*/
+long dim_pq_load_io(unsigned long arg)
+{
+       long ret = 0, tab_flag = 0;
+       di_dev_t *di_devp;
+       void __user *argp = (void __user *)arg;
+       size_t mm_size = 0;
+       struct am_pq_parm_s tmp_pq_s = {0};
+       struct di_pq_parm_s *di_pq_ptr = NULL;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       unsigned int channel = 0;       /*fix to channel 0*/
+
+       di_devp = de_devp;
+
+       mm_size = sizeof(struct am_pq_parm_s);
+       if (copy_from_user(&tmp_pq_s, argp, mm_size)) {
+               PR_ERR("set pq parm errors\n");
+               return -EFAULT;
+       }
+       if (tmp_pq_s.table_len >= TABLE_LEN_MAX) {
+               PR_ERR("load 0x%x wrong pq table_len.\n",
+                      tmp_pq_s.table_len);
+               return -EFAULT;
+       }
+       tab_flag = TABLE_NAME_DI | TABLE_NAME_NR | TABLE_NAME_MCDI |
+               TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO;
+       if (tmp_pq_s.table_name & tab_flag) {
+               pr_info("[DI] load 0x%x pq table len %u %s.\n",
+                       tmp_pq_s.table_name, tmp_pq_s.table_len,
+                       get_init_flag(channel) ? "directly" : "later");
+       } else {
+               PR_ERR("load 0x%x wrong pq table.\n",
+                      tmp_pq_s.table_name);
+               return -EFAULT;
+       }
+       di_pq_ptr = di_pq_parm_create(&tmp_pq_s);
+       if (!di_pq_ptr) {
+               PR_ERR("allocat pq parm struct error.\n");
+               return -EFAULT;
+       }
+       argp = (void __user *)tmp_pq_s.table_ptr;
+       mm_size = tmp_pq_s.table_len * sizeof(struct am_reg_s);
+       if (copy_from_user(di_pq_ptr->regs, argp, mm_size)) {
+               PR_ERR("user copy pq table errors\n");
+               return -EFAULT;
+       }
+       if (get_init_flag(channel)) {
+               dimh_load_regs(di_pq_ptr);
+               di_pq_parm_destroy(di_pq_ptr);
+
+               return ret;
+       }
+       if (atomic_read(&de_devp->pq_flag) == 0) {
+               atomic_set(&de_devp->pq_flag, 1);
+               if (di_devp->flags & DI_LOAD_REG_FLAG) {
+                       struct di_pq_parm_s *pos = NULL, *tmp = NULL;
+
+                       list_for_each_entry_safe(pos, tmp,
+                               &di_devp->pq_table_list, list) {
+                               if (di_pq_ptr->pq_parm.table_name ==
+                                   pos->pq_parm.table_name) {
+                                       pr_info("[DI] remove 0x%x table.\n",
+                                               pos->pq_parm.table_name);
+                                       list_del(&pos->list);
+                                       di_pq_parm_destroy(pos);
+                               }
+                       }
+               }
+               list_add_tail(&di_pq_ptr->list,
+                             &di_devp->pq_table_list);
+               di_devp->flags |= DI_LOAD_REG_FLAG;
+               atomic_set(&de_devp->pq_flag, 0);
+       } else {
+               PR_ERR("please retry table name 0x%x.\n",
+                      di_pq_ptr->pq_parm.table_name);
+               di_pq_parm_destroy(di_pq_ptr);
+               ret = -EFAULT;
+       }
+
+       return ret;
+}
+
+#if 0 /*#ifdef CONFIG_AMLOGIC_MEDIA_RDMA*/
+unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start,
+                             unsigned int len)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (de_devp->rdma_handle && di_pre_rdma_enable)
+               return rdma_read_reg(de_devp->rdma_handle, adr) &
+                      (((1 << len) - 1) << start);
+       else
+               return Rd_reg_bits(adr, start, len);
+}
+
+unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val)
+{
+       unsigned int channel = get_current_channel();
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (is_need_stop_reg(adr))
+               return 0;
+
+       if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) {
+               if (ppre->field_count_for_cont < 1)
+                       dim_DI_Wr(adr, val);
+               else
+                       rdma_write_reg(de_devp->rdma_handle, adr, val);
+               return 0;
+       }
+
+       dim_DI_Wr(adr, val);
+       return 1;
+}
+
+unsigned int dim_RDMA_RD(unsigned int adr)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (de_devp->rdma_handle > 0 && di_pre_rdma_enable)
+               return rdma_read_reg(de_devp->rdma_handle, adr);
+       else
+               return Rd(adr);
+}
+
+unsigned int dim_RDMA_WR_BITS(unsigned int adr, unsigned int val,
+                             unsigned int start, unsigned int len)
+{
+       unsigned int channel = get_current_channel();
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (is_need_stop_reg(adr))
+               return 0;
+
+       if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) {
+               if (ppre->field_count_for_cont < 1)
+                       dim_DI_Wr_reg_bits(adr, val, start, len);
+               else
+                       rdma_write_reg_bits(de_devp->rdma_handle,
+                                           adr, val, start, len);
+               return 0;
+       }
+       dim_DI_Wr_reg_bits(adr, val, start, len);
+       return 1;
+}
+#else
+unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start,
+                             unsigned int len)
+{
+       return Rd_reg_bits(adr, start, len);
+}
+
+unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val)
+{
+       dim_DI_Wr(adr, val);
+       return 1;
+}
+
+unsigned int dim_RDMA_RD(unsigned int adr)
+{
+       return Rd(adr);
+}
+
+unsigned int dim_RDMA_WR_BITS(unsigned int adr, unsigned int val,
+                             unsigned int start, unsigned int len)
+{
+       dim_DI_Wr_reg_bits(adr, val, start, len);
+       return 1;
+}
+#endif
+
+void dim_set_di_flag(void)
+{
+       if (is_meson_txl_cpu()  ||
+           is_meson_txlx_cpu() ||
+           is_meson_gxlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()  ||
+           is_meson_sm1_cpu()) {
+               dimp_set(eDI_MP_mcpre_en, 1);
+               mc_mem_alloc = true;
+               dimp_set(eDI_MP_pulldown_enable, 0);
+               di_pre_rdma_enable = false;
+               /*
+                * txlx atsc 1080i ei only will cause flicker
+                * when full to small win in home screen
+                */
+
+               dimp_set(eDI_MP_di_vscale_skip_enable,
+                        (is_meson_txlx_cpu()   ||
+                        is_meson_txhd_cpu()) ? 12 : 4);
+               /*use_2_interlace_buff = is_meson_gxlx_cpu()?0:1;*/
+               dimp_set(eDI_MP_use_2_interlace_buff,
+                        is_meson_gxlx_cpu() ? 0 : 1);
+               if (is_meson_txl_cpu()  ||
+                   is_meson_txlx_cpu() ||
+                   is_meson_gxlx_cpu() ||
+                   is_meson_txhd_cpu() ||
+                   is_meson_g12a_cpu() ||
+                   is_meson_g12b_cpu() ||
+                   is_meson_tl1_cpu()  ||
+                   is_meson_tm2_cpu()  ||
+                   is_meson_sm1_cpu()) {
+                       dimp_set(eDI_MP_full_422_pack, 1);
+               }
+
+               if (dimp_get(eDI_MP_nr10bit_support)) {
+                       dimp_set(eDI_MP_di_force_bit_mode, 10);
+               } else {
+                       dimp_set(eDI_MP_di_force_bit_mode, 8);
+                       dimp_set(eDI_MP_full_422_pack, 0);
+               }
+
+               dimp_set(eDI_MP_post_hold_line,
+                        (is_meson_g12a_cpu()   ||
+                        is_meson_g12b_cpu()    ||
+                        is_meson_tl1_cpu()     ||
+                        is_meson_tm2_cpu()     ||
+                        is_meson_sm1_cpu()) ? 10 : 17);
+       } else {
+               /*post_hold_line = 8;*/ /*2019-01-10: from VLSI feijun*/
+               dimp_set(eDI_MP_post_hold_line, 8);
+               dimp_set(eDI_MP_mcpre_en, 0);
+               dimp_set(eDI_MP_pulldown_enable, 0);
+               di_pre_rdma_enable = false;
+               dimp_set(eDI_MP_di_vscale_skip_enable, 4);
+               dimp_set(eDI_MP_use_2_interlace_buff, 0);
+               dimp_set(eDI_MP_di_force_bit_mode, 8);
+       }
+       /*if (is_meson_tl1_cpu() || is_meson_tm2_cpu())*/
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dimp_set(eDI_MP_pulldown_enable, 1);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               intr_mode = 3;
+       if (di_pre_rdma_enable) {
+               pldn_dly = 1;
+               pldn_dly1 = 1;
+       } else {
+               pldn_dly = 2;
+               pldn_dly1 = 2;
+       }
+
+       get_ops_mtn()->mtn_int_combing_glbmot();
+}
+
+#if 0  /*move to di_sys.c*/
+static const struct reserved_mem_ops rmem_di_ops = {
+       .device_init    = rmem_di_device_init,
+       .device_release = rmem_di_device_release,
+};
+
+static int __init rmem_di_setup(struct reserved_mem *rmem)
+{
+       rmem->ops = &rmem_di_ops;
+/* rmem->priv = cma; */
+
+       di_pr_info(
+       "DI reserved memory: created CMA memory pool at %pa, size %ld MiB\n",
+               &rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+       return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup);
+#endif
+
+void dim_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev)
+{
+       int ret = 0;
+       unsigned int tmp_clk[2] = {0, 0};
+       struct clk *vpu_clk = NULL;
+       struct clk *clkb_tmp_comp = NULL;
+
+       vpu_clk = clk_get(dev, "vpu_mux");
+       if (IS_ERR(vpu_clk))
+               PR_ERR("%s: get clk vpu error.\n", __func__);
+       else
+               clk_prepare_enable(vpu_clk);
+
+       ret = of_property_read_u32_array(dev->of_node, "clock-range",
+                                        tmp_clk, 2);
+       if (ret) {
+               pdev->clkb_min_rate = 250000000;
+               pdev->clkb_max_rate = 500000000;
+       } else {
+               pdev->clkb_min_rate = tmp_clk[0] * 1000000;
+               pdev->clkb_max_rate = tmp_clk[1] * 1000000;
+       }
+       pr_info("DI: vpu clkb <%lu, %lu>\n", pdev->clkb_min_rate,
+               pdev->clkb_max_rate);
+       #ifdef CLK_TREE_SUPPORT
+       pdev->vpu_clkb = clk_get(dev, "vpu_clkb_composite");
+       if (is_meson_tl1_cpu()) {
+               clkb_tmp_comp = clk_get(dev, "vpu_clkb_tmp_composite");
+               if (IS_ERR(clkb_tmp_comp)) {
+                       PR_ERR("clkb_tmp_comp error\n");
+               } else {
+                       /*ary: this make clk from 500 to 666?*/
+                       if (!IS_ERR(vpu_clk))
+                               clk_set_parent(clkb_tmp_comp, vpu_clk);
+               }
+       }
+
+       if (IS_ERR(pdev->vpu_clkb)) {
+               PR_ERR("%s: get vpu clkb gate error.\n", __func__);
+       } else {
+               clk_set_rate(pdev->vpu_clkb, pdev->clkb_min_rate);
+               pr_info("get clkb rate:%ld\n", clk_get_rate(pdev->vpu_clkb));
+       }
+
+       #endif
+}
+
+module_param_named(invert_top_bot, invert_top_bot, int, 0664);
+
+#ifdef SUPPORT_START_FRAME_HOLD
+module_param_named(start_frame_hold_count, start_frame_hold_count, int, 0664);
+#endif
+
+#ifdef DET3D
+
+MODULE_PARM_DESC(det3d_mode, "\n det3d_mode\n");
+module_param(det3d_mode, uint, 0664);
+#endif
+
+module_param_array(di_stop_reg_addr, uint, &num_di_stop_reg_addr,
+                  0664);
+
+module_param_named(overturn, overturn, bool, 0664);
+
+#ifdef DEBUG_SUPPORT
+#ifdef RUN_DI_PROCESS_IN_IRQ
+module_param_named(input2pre, input2pre, uint, 0664);
+module_param_named(input2pre_buf_miss_count, input2pre_buf_miss_count,
+                  uint, 0664);
+module_param_named(input2pre_proc_miss_count, input2pre_proc_miss_count,
+                  uint, 0664);
+module_param_named(input2pre_miss_policy, input2pre_miss_policy, uint, 0664);
+module_param_named(input2pre_throw_count, input2pre_throw_count, uint, 0664);
+#endif
+#ifdef SUPPORT_MPEG_TO_VDIN
+module_param_named(mpeg2vdin_en, mpeg2vdin_en, int, 0664);
+module_param_named(mpeg2vdin_flag, mpeg2vdin_flag, int, 0664);
+#endif
+module_param_named(di_pre_rdma_enable, di_pre_rdma_enable, uint, 0664);
+module_param_named(pldn_dly, pldn_dly, uint, 0644);
+module_param_named(pldn_dly1, pldn_dly1, uint, 0644);
+module_param_named(di_reg_unreg_cnt, di_reg_unreg_cnt, int, 0664);
+module_param_named(bypass_pre, bypass_pre, int, 0664);
+module_param_named(frame_count, frame_count, int, 0664);
+#endif
+
+int dim_seq_file_module_para_di(struct seq_file *seq)
+{
+       seq_puts(seq, "di---------------\n");
+
+#ifdef DET3D
+       seq_printf(seq, "%-15s:%d\n", "det3d_frame_cnt", det3d_frame_cnt);
+#endif
+
+#ifdef SUPPORT_START_FRAME_HOLD
+       seq_printf(seq, "%-15s:%d\n", "start_frame_hold_count",
+                  start_frame_hold_count);
+#endif
+       seq_printf(seq, "%-15s:%ld\n", "same_field_top_count",
+                  same_field_top_count);
+       seq_printf(seq, "%-15s:%ld\n", "same_field_bot_count",
+                  same_field_bot_count);
+
+       seq_printf(seq, "%-15s:%d\n", "overturn", overturn);
+
+#ifdef DEBUG_SUPPORT
+#ifdef RUN_DI_PROCESS_IN_IRQ
+       seq_printf(seq, "%-15s:%d\n", "input2pre", input2pre);
+       seq_printf(seq, "%-15s:%d\n", "input2pre_buf_miss_count",
+                  input2pre_buf_miss_count);
+       seq_printf(seq, "%-15s:%d\n", "input2pre_proc_miss_count",
+                  input2pre_proc_miss_count);
+       seq_printf(seq, "%-15s:%d\n", "input2pre_miss_policy",
+                  input2pre_miss_policy);
+       seq_printf(seq, "%-15s:%d\n", "input2pre_throw_count",
+                  input2pre_throw_count);
+#endif
+#ifdef SUPPORT_MPEG_TO_VDIN
+
+       seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_en", mpeg2vdin_en);
+       seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_flag", mpeg2vdin_flag);
+#endif
+       seq_printf(seq, "%-15s:%d\n", "di_pre_rdma_enable",
+                  di_pre_rdma_enable);
+       seq_printf(seq, "%-15s:%d\n", "pldn_dly", pldn_dly);
+       seq_printf(seq, "%-15s:%d\n", "pldn_dly1", pldn_dly1);
+       seq_printf(seq, "%-15s:%d\n", "di_reg_unreg_cnt", di_reg_unreg_cnt);
+       seq_printf(seq, "%-15s:%d\n", "bypass_pre", bypass_pre);
+       seq_printf(seq, "%-15s:%d\n", "frame_count", frame_count);
+#endif
+/******************************/
+
+#ifdef DET3D
+       seq_printf(seq, "%-15s:%d\n", "det3d_mode", det3d_mode);
+#endif
+       return 0;
+}
+
+#if 0 /*move to di_sys.c*/
+MODULE_DESCRIPTION("AMLOGIC DEINTERLACE driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("4.0.0");
+#endif
diff --git a/drivers/amlogic/media/di_multi/deinterlace.h b/drivers/amlogic/media/di_multi/deinterlace.h
new file mode 100644 (file)
index 0000000..8a1cac0
--- /dev/null
@@ -0,0 +1,656 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _DI_H
+#define _DI_H
+#include <linux/cdev.h>
+#include <linux/types.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+
+#include "../di_local/di_local.h"
+#include <linux/clk.h>
+#include <linux/atomic.h>
+#include "deinterlace_hw.h"
+#include "../deinterlace/di_pqa.h"
+
+/*trigger_pre_di_process param*/
+#define TRIGGER_PRE_BY_PUT                     'p'
+#define TRIGGER_PRE_BY_DE_IRQ                  'i'
+#define TRIGGER_PRE_BY_UNREG                   'u'
+/*di_timer_handle*/
+#define TRIGGER_PRE_BY_TIMER                   't'
+#define TRIGGER_PRE_BY_FORCE_UNREG             'f'
+#define TRIGGER_PRE_BY_VFRAME_READY            'r'
+#define TRIGGER_PRE_BY_PROVERDER_UNREG         'n'
+#define TRIGGER_PRE_BY_DEBUG_DISABLE           'd'
+#define TRIGGER_PRE_BY_PROVERDER_REG           'R'
+
+#define DI_RUN_FLAG_RUN                                0
+#define DI_RUN_FLAG_PAUSE                      1
+#define DI_RUN_FLAG_STEP                       2
+#define DI_RUN_FLAG_STEP_DONE                  3
+
+#define USED_LOCAL_BUF_MAX                     3
+#define BYPASS_GET_MAX_BUF_NUM                 4
+
+/* buffer management related */
+#define MAX_IN_BUF_NUM                         (4)
+#define MAX_LOCAL_BUF_NUM                      (7)
+#define MAX_POST_BUF_NUM                       (7)     /*(5)*/ /* 16 */
+
+#define VFRAME_TYPE_IN                         1
+#define VFRAME_TYPE_LOCAL                      2
+#define VFRAME_TYPE_POST                       3
+#define VFRAME_TYPE_NUM                                3
+
+#define DI_POST_GET_LIMIT                      4
+#define DI_PRE_READY_LIMIT                     4
+/*vframe define*/
+#define vframe_t struct vframe_s
+
+#define is_from_vdin(vframe) ((vframe)->type & VIDTYPE_VIU_422)
+
+/* canvas defination */
+#define DI_USE_FIXED_CANVAS_IDX
+/*#define      DET3D */
+#undef SUPPORT_MPEG_TO_VDIN
+#define CLK_TREE_SUPPORT
+#ifndef CONFIG_AMLOGIC_MEDIA_RDMA
+#ifndef VSYNC_WR_MPEG_REG
+#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val)
+#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len)   \
+               aml_vcbus_update_bits((adr),            \
+               ((1 << (len)) - 1) << (start), (val) << (start))
+
+#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr)
+#endif
+#endif
+
+#define IS_VDIN_SRC(src) (                             \
+       ((src) == VFRAME_SOURCE_TYPE_TUNER)     ||      \
+       ((src) == VFRAME_SOURCE_TYPE_CVBS)      ||      \
+       ((src) == VFRAME_SOURCE_TYPE_COMP)      ||      \
+       ((src) == VFRAME_SOURCE_TYPE_HDMI))
+
+#define IS_I_SRC(vftype) ((vftype) & VIDTYPE_INTERLACE_BOTTOM)
+
+#define IS_COMP_MODE(vftype) ((vftype) & VIDTYPE_COMPRESS)
+
+enum process_fun_index_e {
+       PROCESS_FUN_NULL = 0,
+       PROCESS_FUN_DI,
+       PROCESS_FUN_PD,
+       PROCESS_FUN_PROG,
+       PROCESS_FUN_BOB
+};
+
+#define process_fun_index_t enum process_fun_index_e
+
+enum canvas_idx_e {
+       NR_CANVAS,
+       MTN_CANVAS,
+       MV_CANVAS,
+};
+
+#define pulldown_mode_t enum pulldown_mode_e
+struct di_buf_s {
+       struct vframe_s *vframe;
+       int index; /* index in vframe_in_dup[] or vframe_in[],
+                   * only for type of VFRAME_TYPE_IN
+                   */
+       int post_proc_flag; /* 0,no post di; 1, normal post di;
+                            * 2, edge only; 3, dummy
+                            */
+       int new_format_flag;
+       int type;
+       int throw_flag;
+       int invert_top_bot_flag;
+       int seq;
+       int pre_ref_count; /* none zero, is used by mem_mif,
+                           * chan2_mif, or wr_buf
+                           */
+       int post_ref_count; /* none zero, is used by post process */
+       int queue_index;
+       /*below for type of VFRAME_TYPE_LOCAL */
+       unsigned long nr_adr;
+       int nr_canvas_idx;
+       unsigned long mtn_adr;
+       int mtn_canvas_idx;
+       unsigned long cnt_adr;
+       int cnt_canvas_idx;
+       unsigned long mcinfo_adr;
+       int mcinfo_canvas_idx;
+       unsigned long mcvec_adr;
+       int mcvec_canvas_idx;
+       struct mcinfo_pre_s {
+               unsigned int highvertfrqflg;
+               unsigned int motionparadoxflg;
+               unsigned int regs[26];/* reg 0x2fb0~0x2fc9 */
+       } curr_field_mcinfo;
+       /* blend window */
+       struct pulldown_detected_s
+       pd_config;
+       /* tff bff check result bit[1:0]*/
+       unsigned int privated;
+       unsigned int canvas_config_flag;
+       /* 0,configed; 1,config type 1 (prog);
+        * 2, config type 2 (interlace)
+        */
+       unsigned int canvas_height;
+       unsigned int canvas_height_mc;  /*ary add for mc h is diff*/
+       unsigned int canvas_width[3];/* nr/mtn/mv */
+       process_fun_index_t process_fun_index;
+       int early_process_fun_index;
+       int left_right;/*1,left eye; 0,right eye in field alternative*/
+       /*below for type of VFRAME_TYPE_POST*/
+       struct di_buf_s *di_buf[2];
+       struct di_buf_s *di_buf_dup_p[5];
+       /* 0~4: n-2, n-1, n, n+1, n+2;  n is the field to display*/
+       /*0: n-2*/
+       /*1: n-1*/
+       /*2: n*/
+       /*3: n+1*/
+       /*4: n+2*/
+       struct di_buf_s *di_wr_linked_buf;
+       /* debug for di-vf-get/put
+        * 1: after get
+        * 0: after put
+        */
+       atomic_t di_cnt;
+       struct page     *pages;
+       /*ary add */
+       unsigned int channel;
+       unsigned int width_bk; /*move from ppre*/
+};
+
+#define RDMA_DET3D_IRQ                 0x20
+/* vdin0 rdma irq */
+#define RDMA_DEINT_IRQ                 0x2
+#define RDMA_TABLE_SIZE                        ((PAGE_SIZE) << 1)
+
+#define MAX_CANVAS_WIDTH               1920
+#define MAX_CANVAS_HEIGHT              1088
+
+/* #define DI_BUFFER_DEBUG */
+
+#define DI_LOG_MTNINFO                 0x02
+#define DI_LOG_PULLDOWN                        0x10
+#define DI_LOG_BUFFER_STATE            0x20
+#define DI_LOG_TIMESTAMP               0x100
+#define DI_LOG_PRECISE_TIMESTAMP       0x200
+#define DI_LOG_QUEUE                   0x40
+#define DI_LOG_VFRAME                  0x80
+
+#if 0
+#define QUEUE_LOCAL_FREE               0
+#define QUEUE_IN_FREE                  1
+#define QUEUE_PRE_READY                        2
+#define QUEUE_POST_FREE                        3
+#define QUEUE_POST_READY               4
+#define QUEUE_RECYCLE                  5
+#define QUEUE_DISPLAY                  6
+#define QUEUE_TMP                      7
+#define QUEUE_POST_DOING               8
+#define QUEUE_NUM                      9
+#else
+#define QUEUE_LOCAL_FREE               0
+#define QUEUE_RECYCLE                  1       /* 5 */
+#define QUEUE_DISPLAY                  2       /* 6 */
+#define QUEUE_TMP                      3       /* 7 */
+#define QUEUE_POST_DOING               4       /* 8 */
+
+#define QUEUE_IN_FREE                  5       /* 1 */
+#define QUEUE_PRE_READY                        6       /* 2 */
+#define QUEUE_POST_FREE                        7       /* 3 */
+#define QUEUE_POST_READY               8       /* 4    QUE_POST_READY */
+
+/*new use this for put back control*/
+#define QUEUE_POST_PUT_BACK            (9)
+
+#define QUEUE_NUM                      5       /* 9 */
+#define QUEUE_NEW_THD_MIN              (QUEUE_IN_FREE - 1)
+#define QUEUE_NEW_THD_MAX              (QUEUE_POST_READY + 1)
+
+#endif
+
+#define queue_t struct queue_s
+
+#define VFM_NAME               "deinterlace"
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+void enable_rdma(int enable_flag);
+int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
+int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len);
+u32 VSYNC_RD_MPEG_REG(u32 adr);
+bool is_vsync_rdma_enable(void);
+#else
+#ifndef VSYNC_WR_MPEG_REG
+#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val)
+#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len)           \
+                              aml_vcbus_update_bits((adr),     \
+                              ((1 << (len)) - 1) << (start), (val) << (start))
+
+#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr)
+#endif
+#endif
+
+#define DI_COUNT   1
+#define DI_MAP_FLAG    0x1
+#define DI_SUSPEND_FLAG 0x2
+#define DI_LOAD_REG_FLAG 0x4
+#define DI_VPU_CLKB_SET 0x8
+
+struct di_dev_s {
+       dev_t                      devt;
+       struct cdev                cdev; /* The cdev structure */
+       struct device      *dev;
+       struct platform_device  *pdev;
+       dev_t   devno;
+       struct class    *pclss;
+
+       bool sema_flg;  /*di_sema_init_flag*/
+
+       struct task_struct *task;
+       struct clk      *vpu_clkb;
+       unsigned long clkb_max_rate;
+       unsigned long clkb_min_rate;
+       struct list_head   pq_table_list;
+       atomic_t               pq_flag;
+       unsigned char      di_event;
+       unsigned int       pre_irq;
+       unsigned int       post_irq;
+       unsigned int       flags;
+       unsigned long      jiffy;
+       unsigned long      mem_start;
+       unsigned int       mem_size;
+       bool    mem_flg;        /*ary add for make sure mem is ok*/
+       unsigned int       buffer_size;
+       unsigned int       post_buffer_size;
+       unsigned int       buf_num_avail;
+       int             rdma_handle;
+       /* is support nr10bit */
+       unsigned int       nr10bit_support;
+       /* is DI support post wr to mem for OMX */
+       unsigned int       post_wr_support;
+       unsigned int nrds_enable;
+       unsigned int pps_enable;
+       unsigned int h_sc_down_en;/*sm1, tm2 ...*/
+       /*struct        mutex      cma_mutex;*/
+       unsigned int       flag_cma;
+       struct page                     *total_pages;
+       struct dentry *dbg_root;        /*dbg_fs*/
+       /***************************/
+       /*struct di_data_l_s    data_l;*/
+       void *data_l;
+
+};
+
+struct di_pre_stru_s {
+/* pre input */
+       struct DI_MIF_s di_inp_mif;
+       struct DI_MIF_s di_mem_mif;
+       struct DI_MIF_s di_chan2_mif;
+       struct di_buf_s *di_inp_buf;
+       struct di_buf_s *di_post_inp_buf;
+       struct di_buf_s *di_inp_buf_next;
+       /* p_asi_next: ary:add for p */
+       struct di_buf_s *p_asi_next;
+       struct di_buf_s *di_mem_buf_dup_p;
+       struct di_buf_s *di_chan2_buf_dup_p;
+/* pre output */
+       struct DI_SIM_MIF_s     di_nrwr_mif;
+       struct DI_SIM_MIF_s     di_mtnwr_mif;
+       struct di_buf_s *di_wr_buf;
+       struct di_buf_s *di_post_wr_buf;
+       struct DI_SIM_MIF_s     di_contp2rd_mif;
+       struct DI_SIM_MIF_s     di_contprd_mif;
+       struct DI_SIM_MIF_s     di_contwr_mif;
+       int             field_count_for_cont;
+/*
+ * 0 (f0,null,f0)->nr0,
+ * 1 (f1,nr0,f1)->nr1_cnt,
+ * 2 (f2,nr1_cnt,nr0)->nr2_cnt
+ * 3 (f3,nr2_cnt,nr1_cnt)->nr3_cnt
+ */
+       struct DI_MC_MIF_s              di_mcinford_mif;
+       struct DI_MC_MIF_s              di_mcvecwr_mif;
+       struct DI_MC_MIF_s              di_mcinfowr_mif;
+/* pre state */
+       int     in_seq;
+       int     recycle_seq;
+       int     pre_ready_seq;
+
+       int     pre_de_busy;            /* 1 if pre_de is not done */
+       int     pre_de_process_flag;    /* flag when dim_pre_de_process done */
+       int     pre_de_clear_flag;
+       /* flag is set when VFRAME_EVENT_PROVIDER_UNREG*/
+       int     unreg_req_flag_cnt;
+
+       int     reg_req_flag_cnt;
+       int     force_unreg_req_flag;
+       int     disable_req_flag;
+       /* current source info */
+       int     cur_width;
+       int     cur_height;
+       int     cur_inp_type;
+       int     cur_source_type;
+       int     cur_sig_fmt;
+       unsigned int orientation;
+       int     cur_prog_flag; /* 1 for progressive source */
+/* valid only when prog_proc_type is 0, for
+ * progressive source: top field 1, bot field 0
+ */
+       int     source_change_flag;
+/* input size change flag, 1: need reconfig pre/nr/dnr size */
+/* 0: not need config pre/nr/dnr size*/
+       bool input_size_change_flag;
+/* true: bypass di all logic, false: not bypass */
+       bool bypass_flag;
+       unsigned char prog_proc_type;
+/* set by prog_proc_config when source is vdin,0:use 2 i
+ * serial buffer,1:use 1 p buffer,3:use 2 i paralleling buffer
+ */
+/* ary: loacal play p mode is 0
+ * local play i mode is 0
+ */
+
+       unsigned char buf_alloc_mode;
+/* alloc di buf as p or i;0: alloc buf as i;
+ * 1: alloc buf as p;
+ */
+       unsigned char madi_enable;
+       unsigned char mcdi_enable;
+       unsigned int  pps_dstw; /*no use ?*/
+       unsigned int  pps_dsth; /*no use ?*/
+       int     left_right;/*1,left eye; 0,right eye in field alternative*/
+/*input2pre*/
+       int     bypass_start_count;
+/* need discard some vframe when input2pre => bypass */
+       unsigned char vdin2nr;
+       enum tvin_trans_fmt     source_trans_fmt;
+       enum tvin_trans_fmt     det3d_trans_fmt;
+       unsigned int det_lr;
+       unsigned int det_tp;
+       unsigned int det_la;
+       unsigned int det_null;
+       unsigned int width_bk;
+#ifdef DET3D
+       int     vframe_interleave_flag;
+#endif
+/**/
+       int     pre_de_irq_timeout_count;
+       int     pre_throw_flag;
+       int     bad_frame_throw_count;
+/*for static pic*/
+       int     static_frame_count;
+       bool force_interlace;
+       bool bypass_pre;
+       bool invert_flag;
+       bool vdin_source;
+       int nr_size;
+       int count_size;
+       int mcinfo_size;
+       int mv_size;
+       int mtn_size;
+
+       int cma_release_req;
+       /* for performance debug */
+       unsigned long irq_time[2];
+       /* combing adaptive */
+       struct combing_status_s *mtn_status;
+};
+
+struct di_post_stru_s {
+       struct DI_MIF_s di_buf0_mif;
+       struct DI_MIF_s di_buf1_mif;
+       struct DI_MIF_s di_buf2_mif;
+       struct DI_SIM_MIF_s di_diwr_mif;
+       struct DI_SIM_MIF_s     di_mtnprd_mif;
+       struct DI_MC_MIF_s      di_mcvecrd_mif;
+       /*post doing buf and write buf to post ready*/
+       struct di_buf_s *cur_post_buf;
+       struct di_buf_s *keep_buf;
+       struct di_buf_s *keep_buf_post; /*ary add for keep post buf*/
+       int             update_post_reg_flag;
+       int             run_early_proc_fun_flag;
+       int             cur_disp_index;
+       int             canvas_id;
+       int             next_canvas_id;
+       bool            toggle_flag;
+       bool            vscale_skip_flag;
+       uint            start_pts;
+       int             buf_type;
+       int de_post_process_done;
+       int post_de_busy;
+       int di_post_num;
+       unsigned int post_peek_underflow;
+       unsigned int di_post_process_cnt;
+       unsigned int check_recycle_buf_cnt;/*cp to di_hpre_s*/
+       /* performance debug */
+       unsigned int  post_wr_cnt;
+       unsigned long irq_time;
+
+       /*frame cnt*/
+       unsigned int frame_cnt; /*cnt for post process*/
+};
+
+#define MAX_QUEUE_POOL_SIZE   256
+struct queue_s {
+       unsigned int num;
+       unsigned int in_idx;
+       unsigned int out_idx;
+       unsigned int type;
+/* 0, first in first out;
+ * 1, general;2, fix position for di buf
+ */
+       unsigned int pool[MAX_QUEUE_POOL_SIZE];
+};
+
+struct di_buf_pool_s {
+       struct di_buf_s *di_buf_ptr;
+       unsigned int size;
+};
+
+struct dim_mm_s {
+       struct page     *ppage;
+       unsigned long   addr;
+};
+
+bool dim_mm_alloc(int cma_mode, size_t count, struct dim_mm_s *o);
+bool dim_mm_release(int cma_mode,
+                   struct page *pages,
+                   int count,
+                   unsigned long addr);
+
+unsigned char dim_is_bypass(vframe_t *vf_in, unsigned int channel);
+bool dim_bypass_first_frame(unsigned int ch);
+
+int di_cnt_buf(int width, int height, int prog_flag, int mc_mm,
+              int bit10_support, int pack422);
+
+/*---get di state parameter---*/
+struct di_dev_s *get_dim_de_devp(void);
+
+const char *dim_get_version_s(void);
+int dim_get_dump_state_flag(void);
+
+int dim_get_blocking(void);
+
+struct di_buf_s *dim_get_recovery_log_di_buf(void);
+
+unsigned long dim_get_reg_unreg_timeout_cnt(void);
+struct vframe_s **dim_get_vframe_in(unsigned int ch);
+int dim_check_recycle_buf(unsigned int channel);
+
+int dim_seq_file_module_para_di(struct seq_file *seq);
+int dim_seq_file_module_para_hw(struct seq_file *seq);
+
+int dim_seq_file_module_para_film_fw1(struct seq_file *seq);
+int dim_seq_file_module_para_mtn(struct seq_file *seq);
+
+int dim_seq_file_module_para_pps(struct seq_file *seq);
+
+int dim_seq_file_module_para_(struct seq_file *seq);
+
+/***********************/
+
+unsigned int di_get_dts_nrds_en(void);
+int di_get_disp_cnt(void);
+
+/*---------------------*/
+long dim_pq_load_io(unsigned long arg);
+int dim_get_canvas(void);
+unsigned int dim_cma_alloc_total(struct di_dev_s *de_devp);
+irqreturn_t dim_irq(int irq, void *dev_instance);
+irqreturn_t dim_post_irq(int irq, void *dev_instance);
+
+void dim_rdma_init(void);
+void dim_rdma_exit(void);
+
+void dim_set_di_flag(void);
+void dim_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev);
+
+void dim_log_buffer_state(unsigned char *tag, unsigned int channel);
+
+unsigned char dim_pre_de_buf_config(unsigned int channel);
+void dim_pre_de_process(unsigned int channel);
+void dim_pre_de_done_buf_config(unsigned int channel, bool flg_timeout);
+void dim_pre_de_done_buf_clear(unsigned int channel);
+
+void di_reg_setting(unsigned int channel, struct vframe_s *vframe);
+void di_reg_variable(unsigned int channel, struct vframe_s *vframe);
+
+void dim_unreg_process_irq(unsigned int channel);
+void di_unreg_variable(unsigned int channel);
+void di_unreg_setting(void);
+
+void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel);
+void dim_unreg_process(unsigned int channel);
+
+int dim_process_post_vframe(unsigned int channel);
+unsigned char dim_check_di_buf(struct di_buf_s *di_buf, int reason,
+                              unsigned int channel);
+int dim_do_post_wr_fun(void *arg, vframe_t *disp_vf);
+int dim_post_process(void *arg, unsigned int zoom_start_x_lines,
+                    unsigned int zoom_end_x_lines,
+                    unsigned int zoom_start_y_lines,
+                    unsigned int zoom_end_y_lines, vframe_t *disp_vf);
+void dim_post_de_done_buf_config(unsigned int channel);
+void dim_recycle_post_back(unsigned int channel);
+void recycle_post_ready_local(struct di_buf_s *di_buf,
+                             unsigned int channel);
+
+/*--------------------------*/
+unsigned char dim_vcry_get_flg(void);
+void dim_vcry_flg_inc(void);
+void dim_vcry_set_flg(unsigned char val);
+/*--------------------------*/
+unsigned int dim_vcry_get_log_reason(void);
+void dim_vcry_set_log_reason(unsigned int val);
+/*--------------------------*/
+unsigned char dim_vcry_get_log_q_idx(void);
+void dim_vcry_set_log_q_idx(unsigned int val);
+/*--------------------------*/
+struct di_buf_s **dim_vcry_get_log_di_buf(void);
+void dim_vcry_set_log_di_buf(struct di_buf_s *di_bufp);
+void dim_vcry_set(unsigned int reason, unsigned int idx,
+                 struct di_buf_s *di_bufp);
+
+const char *dim_get_vfm_type_name(unsigned int nub);
+
+bool dim_cma_top_alloc(unsigned int ch);
+bool dim_cma_top_release(unsigned int ch);
+
+int dim_get_reg_unreg_cnt(void);
+void dim_reg_timeout_inc(void);
+
+void dim_reg_process(unsigned int channel);
+bool is_bypass2(struct vframe_s *vf_in, unsigned int ch);
+
+/*--------------------------*/
+int di_ori_event_unreg(unsigned int channel);
+int di_ori_event_reg(void *data, unsigned int channel);
+int di_ori_event_qurey_vdin2nr(unsigned int channel);
+int di_ori_event_reset(unsigned int channel);
+int di_ori_event_light_unreg(unsigned int channel);
+int di_ori_event_light_unreg_revframe(unsigned int channel);
+int di_ori_event_ready(unsigned int channel);
+int di_ori_event_qurey_state(unsigned int channel);
+void  di_ori_event_set_3D(int type, void *data, unsigned int channel);
+
+/*--------------------------*/
+extern int pre_run_flag;
+extern unsigned int dbg_first_cnt_pre;
+extern spinlock_t plist_lock;
+
+void dim_dbg_pre_cnt(unsigned int channel, char *item);
+
+void diext_clk_b_sw(bool on);
+
+int di_vf_l_states(struct vframe_states *states, unsigned int channel);
+struct vframe_s *di_vf_l_peek(unsigned int channel);
+void di_vf_l_put(struct vframe_s *vf, unsigned char channel);
+struct vframe_s *di_vf_l_get(unsigned int channel);
+
+unsigned char pre_p_asi_de_buf_config(unsigned int ch);
+
+/*---------------------*/
+
+ssize_t
+store_config(struct device *dev,
+            struct device_attribute *attr,
+            const char *buf, size_t count);
+ssize_t
+store_dbg(struct device *dev,
+         struct device_attribute *attr,
+         const char *buf, size_t count);
+ssize_t
+store_dump_mem(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t len);
+ssize_t
+store_log(struct device *dev,
+         struct device_attribute *attr,
+         const char *buf, size_t count);
+ssize_t
+show_vframe_status(struct device *dev,
+                  struct device_attribute *attr,
+                  char *buf);
+
+ssize_t dim_read_log(char *buf);
+
+/*---------------------*/
+
+struct di_buf_s *dim_get_buf(unsigned int channel,
+                            int queue_idx, int *start_pos);
+
+#define queue_for_each_entry(di_buf, channel, queue_idx, list) \
+       for (itmp = 0;                                          \
+           ((di_buf = dim_get_buf(channel, queue_idx, &itmp)) != NULL);)
+
+#define di_dev_t struct di_dev_s
+
+#define di_pr_info(fmt, args ...)   pr_info("DI: " fmt, ## args)
+
+#define pr_dbg(fmt, args ...)       pr_debug("DI: " fmt, ## args)
+
+#define pr_error(fmt, args ...)     pr_err("DI: " fmt, ## args)
+
+/*this is debug for buf*/
+/*#define DI_DEBUG_POST_BUF_FLOW       (1)*/
+
+#endif
diff --git a/drivers/amlogic/media/di_multi/deinterlace_dbg.c b/drivers/amlogic/media/di_multi/deinterlace_dbg.c
new file mode 100644 (file)
index 0000000..153f6e0
--- /dev/null
@@ -0,0 +1,1214 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace_dbg.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/semaphore.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <linux/of_irq.h>
+#include <linux/uaccess.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include "register.h"
+#include "deinterlace_dbg.h"
+#include "di_pps.h"
+#include "nr_downscale.h"
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include "deinterlace.h"
+
+#include "di_data_l.h"
+#include "di_que.h"
+#include "di_prc.h"
+#include "di_pre.h"
+#include "di_post.h"
+
+#include "di_vframe.h"
+
+/*2018-07-18 add debugfs*/
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+/*2018-07-18 -----------*/
+
+void dim_parse_cmd_params(char *buf_orig, char **parm)
+{
+       char *ps, *token;
+       char delim1[3] = " ";
+       char delim2[2] = "\n";
+       unsigned int n = 0;
+
+       strcat(delim1, delim2);
+       ps = buf_orig;
+       while (1) {
+               token = strsep(&ps, delim1);
+               if (!token)
+                       break;
+               if (*token == '\0')
+                       continue;
+               parm[n++] = token;
+       }
+}
+
+static const unsigned int size_reg_addr1[] = {
+       0x1702, 0x1703, 0x2d01,
+       0x2d01, 0x2d8f, 0x2d08,
+       0x2d09, 0x2f00, 0x2f01,
+       0x17d0, 0x17d1, 0x17d2,
+       0x17d3, 0x17dd, 0x17de,
+       0x17df, 0x17e0, 0x17f7,
+       0x17f8, 0x17f9, 0x17fa,
+       0x17c0, 0x17c1, 0x17a0,
+       0x17a1, 0x17c3, 0x17c4,
+       0x17cb, 0x17cc, 0x17a3,
+       0x17a4, 0x17a5, 0x17a6,
+       0x2f92, 0x2f93, 0x2f95,
+       0x2f96, 0x2f98, 0x2f99,
+       0x2f9b, 0x2f9c, 0x2f65,
+       0x2f66, 0x2f67, 0x2f68,
+       0x1a53, 0x1a54, 0x1a55,
+       0x1a56, 0x17ea, 0x17eb,
+       0x17ec, 0x17ed, 0x2012,
+       0x2013, 0x2014, 0x2015,
+       0xffff
+};
+
+/*g12 new added*/
+static const unsigned int size_reg_addr2[] = {
+       0x37d2, 0x37d3, 0x37d7,
+       0x37d8, 0x37dc, 0x37dd,
+       0x37e1, 0x37e2, 0x37e6,
+       0x37e7, 0x37e9, 0x37ea,
+       0x37ed, 0x37ee, 0x37f1,
+       0x37f2, 0x37f4, 0x37f5,
+       0x37f6, 0x37f8, 0x3751,
+       0x3752, 0x376e, 0x376f,
+       0x37f9, 0x37fa, 0x37fc,
+       0x3740, 0x3757, 0x3762,
+       0xffff
+};
+
+/*2018-08-17 add debugfs*/
+static int seq_file_dump_di_reg_show(struct seq_file *seq, void *v)
+{
+       unsigned int i = 0, base_addr = 0;
+
+       if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
+               base_addr = 0xff900000;
+       else
+               base_addr = 0xd0100000;
+
+       seq_puts(seq, "----dump di reg----\n");
+       seq_puts(seq, "----dump size reg---\n");
+       /*txl crash when dump 0x37d2~0x3762 of size_reg_addr*/
+       for (i = 0; size_reg_addr1[i] != 0xffff; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((size_reg_addr1[i]) << 2),
+                          size_reg_addr1[i], dim_RDMA_RD(size_reg_addr1[i]));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               for (i = 0; size_reg_addr2[i] != 0xffff; i++)
+                       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                                  base_addr + ((size_reg_addr2[i]) << 2),
+                                  size_reg_addr2[i],
+                                  dim_RDMA_RD(size_reg_addr2[i]));
+       }
+       for (i = 0; i < 255; i++) {
+               if (i == 0x45)
+                       seq_puts(seq, "----nr reg----");
+               if (i == 0x80)
+                       seq_puts(seq, "----3d reg----");
+               if (i == 0x9e)
+                       seq_puts(seq, "---nr reg done---");
+               if (i == 0x9c)
+                       seq_puts(seq, "---3d reg done---");
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x1700 + i) << 2),
+                          0x1700 + i, dim_RDMA_RD(0x1700 + i));
+       }
+       for (i = 0; i < 4; i++) {
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x20ab + i) << 2),
+                          0x20ab + i, dim_RDMA_RD(0x20ab + i));
+       }
+       seq_puts(seq, "----dump mcdi reg----\n");
+       for (i = 0; i < 201; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x2f00 + i) << 2),
+                          0x2f00 + i, dim_RDMA_RD(0x2f00 + i));
+       seq_puts(seq, "----dump pulldown reg----\n");
+       for (i = 0; i < 26; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x2fd0 + i) << 2),
+                          0x2fd0 + i, dim_RDMA_RD(0x2fd0 + i));
+       seq_puts(seq, "----dump bit mode reg----\n");
+       for (i = 0; i < 4; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x20a7 + i) << 2),
+                          0x20a7 + i, dim_RDMA_RD(0x20a7 + i));
+       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                  base_addr + (0x2022 << 2),
+                  0x2022, dim_RDMA_RD(0x2022));
+       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                  base_addr + (0x17c1 << 2),
+                  0x17c1, dim_RDMA_RD(0x17c1));
+       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                  base_addr + (0x17c2 << 2),
+                  0x17c2, dim_RDMA_RD(0x17c2));
+       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                  base_addr + (0x1aa7 << 2),
+                  0x1aa7, dim_RDMA_RD(0x1aa7));
+       seq_puts(seq, "----dump dnr reg----\n");
+       for (i = 0; i < 29; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x2d00 + i) << 2),
+                          0x2d00 + i, dim_RDMA_RD(0x2d00 + i));
+       seq_puts(seq, "----dump if0 reg----\n");
+       for (i = 0; i < 26; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x1a60 + i) << 2),
+                          0x1a50 + i, dim_RDMA_RD(0x1a50 + i));
+       seq_puts(seq, "----dump gate reg----\n");
+       seq_printf(seq, "[0x%x][0x1718]=0x%x\n",
+                  base_addr + ((0x1718) << 2),
+                  dim_RDMA_RD(0x1718));
+       for (i = 0; i < 5; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x2006 + i) << 2),
+                          0x2006 + i, dim_RDMA_RD(0x2006 + i));
+       seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                  base_addr + ((0x2dff) << 2),
+                  0x2dff, dim_RDMA_RD(0x2dff));
+       seq_puts(seq, "----dump if2 reg----\n");
+       for (i = 0; i < 29; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + ((0x2010 + i) << 2),
+                          0x2010 + i, dim_RDMA_RD(0x2010 + i));
+       if (!is_meson_txl_cpu()) {
+               seq_puts(seq, "----dump nr4 reg----\n");
+       for (i = 0x2da4; i < 0x2df6; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + (i << 2),
+                          i, dim_RDMA_RD(i));
+       for (i = 0x3700; i < 0x373f; i++)
+               seq_printf(seq, "[0x%x][0x%x]=0x%x\n",
+                          base_addr + (i << 2),
+                          i, dim_RDMA_RD(i));
+       }
+       seq_puts(seq, "----dump reg done----\n");
+       return 0;
+}
+
+static void dump_mif_state(struct DI_MIF_s *mif)
+{
+       pr_info("luma <%u, %u> <%u %u>.\n",
+               mif->luma_x_start0, mif->luma_x_end0,
+               mif->luma_y_start0, mif->luma_y_end0);
+       pr_info("chroma <%u, %u> <%u %u>.\n",
+               mif->chroma_x_start0, mif->chroma_x_end0,
+               mif->chroma_y_start0, mif->chroma_y_end0);
+       pr_info("canvas id <%u %u %u>.\n",
+               mif->canvas0_addr0,
+               mif->canvas0_addr1,
+               mif->canvas0_addr2);
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dump_mif_state*/
+static void dump_mif_state_seq(struct DI_MIF_s *mif,
+                              struct seq_file *seq)
+{
+       seq_printf(seq, "luma <%u, %u> <%u %u>.\n",
+                  mif->luma_x_start0, mif->luma_x_end0,
+                  mif->luma_y_start0, mif->luma_y_end0);
+       seq_printf(seq, "chroma <%u, %u> <%u %u>.\n",
+                  mif->chroma_x_start0, mif->chroma_x_end0,
+                  mif->chroma_y_start0, mif->chroma_y_end0);
+       seq_printf(seq, "canvas id <%u %u %u>.\n",
+                  mif->canvas0_addr0,
+                  mif->canvas0_addr1,
+                  mif->canvas0_addr2);
+}
+
+static void dump_simple_mif_state(struct DI_SIM_MIF_s *simp_mif)
+{
+       pr_info("<%u %u> <%u %u>.\n",
+               simp_mif->start_x, simp_mif->end_x,
+               simp_mif->start_y, simp_mif->end_y);
+       pr_info("canvas num <%u>.\n",
+               simp_mif->canvas_num);
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dump_simple_mif_state*/
+static void dump_simple_mif_state_seq(struct DI_SIM_MIF_s *simp_mif,
+                                     struct seq_file *seq)
+{
+       seq_printf(seq, "<%u %u> <%u %u>.\n",
+                  simp_mif->start_x, simp_mif->end_x,
+                  simp_mif->start_y, simp_mif->end_y);
+       seq_printf(seq, "canvas num <%u>.\n",
+                  simp_mif->canvas_num);
+}
+
+static void dump_mc_mif_state(struct DI_MC_MIF_s *mc_mif)
+{
+       pr_info("startx %u,<%u %u>, size <%u %u>.\n",
+               mc_mif->start_x, mc_mif->start_y,
+               mc_mif->end_y, mc_mif->size_x,
+               mc_mif->size_y);
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dump_mc_mif_state*/
+static void dump_mc_mif_state_seq(struct DI_MC_MIF_s *mc_mif,
+                                 struct seq_file *seq)
+{
+       seq_printf(seq, "startx %u,<%u %u>, size <%u %u>.\n",
+                  mc_mif->start_x, mc_mif->start_y,
+                  mc_mif->end_y, mc_mif->size_x,
+                  mc_mif->size_y);
+}
+
+void dim_dump_pre_stru(struct di_pre_stru_s *ppre)
+{
+       pr_info("di_pre_stru:\n");
+       pr_info("di_mem_buf_dup_p          = 0x%p\n",
+               ppre->di_mem_buf_dup_p);
+       pr_info("di_chan2_buf_dup_p        = 0x%p\n",
+               ppre->di_chan2_buf_dup_p);
+       pr_info("in_seq                            = %d\n",
+               ppre->in_seq);
+       pr_info("recycle_seq               = %d\n",
+               ppre->recycle_seq);
+       pr_info("pre_ready_seq             = %d\n",
+               ppre->pre_ready_seq);
+       pr_info("pre_de_busy               = %d\n",
+               ppre->pre_de_busy);
+
+       pr_info("pre_de_process_flag   = %d\n",
+               ppre->pre_de_process_flag);
+       pr_info("pre_de_irq_timeout_count=%d\n",
+               ppre->pre_de_irq_timeout_count);
+
+       pr_info("cur_width                         = %d\n",
+               ppre->cur_width);
+       pr_info("cur_height                        = %d\n",
+               ppre->cur_height);
+       pr_info("cur_inp_type              = 0x%x\n",
+               ppre->cur_inp_type);
+       pr_info("cur_source_type           = %d\n",
+               ppre->cur_source_type);
+       pr_info("cur_prog_flag             = %d\n",
+               ppre->cur_prog_flag);
+       pr_info("source_change_flag        = %d\n",
+               ppre->source_change_flag);
+       pr_info("bypass_flag = %s\n",
+               ppre->bypass_flag ? "true" : "false");
+       pr_info("prog_proc_type            = %d\n",
+               ppre->prog_proc_type);
+       pr_info("madi_enable               = %u\n",
+               ppre->madi_enable);
+       pr_info("mcdi_enable    = %u\n",
+               ppre->mcdi_enable);
+#ifdef DET3D
+       pr_info("vframe_interleave_flag = %d\n",
+               ppre->vframe_interleave_flag);
+#endif
+       pr_info("left_right                = %d\n",
+               ppre->left_right);
+       pr_info("force_interlace   = %s\n",
+               ppre->force_interlace ? "true" : "false");
+       pr_info("vdin2nr                   = %d\n",
+               ppre->vdin2nr);
+       pr_info("bypass_pre                = %s\n",
+               ppre->bypass_pre ? "true" : "false");
+       pr_info("invert_flag       = %s\n",
+               ppre->invert_flag ? "true" : "false");
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dim_dump_pre_stru*/
+static int dump_di_pre_stru_seq(struct seq_file *seq, void *v,
+                               unsigned int channel)
+
+{
+       struct di_pre_stru_s *di_pre_stru_p = get_pre_stru(channel);
+
+       seq_printf(seq, "di_pre_stru[%d]:\n", channel);
+       seq_printf(seq, "%-25s = 0x%p\n", "di_mem_buf_dup_p",
+                  di_pre_stru_p->di_mem_buf_dup_p);
+       seq_printf(seq, "%-25s = 0x%p\n", "di_chan2_buf_dup_p",
+                  di_pre_stru_p->di_chan2_buf_dup_p);
+       seq_printf(seq, "%-25s = %d\n", "in_seq",
+                  di_pre_stru_p->in_seq);
+       seq_printf(seq, "%-25s = %d\n", "recycle_seq",
+                  di_pre_stru_p->recycle_seq);
+       seq_printf(seq, "%-25s = %d\n", "pre_ready_seq",
+                  di_pre_stru_p->pre_ready_seq);
+       seq_printf(seq, "%-25s = %d\n", "pre_de_busy",
+                  di_pre_stru_p->pre_de_busy);
+       seq_printf(seq, "%-25s = %d\n", "pre_de_process_flag",
+                  di_pre_stru_p->pre_de_process_flag);
+       seq_printf(seq, "%-25s =%d\n", "pre_de_irq_timeout_count",
+                  di_pre_stru_p->pre_de_irq_timeout_count);
+       seq_printf(seq, "%-25s = %d\n", "cur_width",
+                  di_pre_stru_p->cur_width);
+       seq_printf(seq, "%-25s = %d\n", "cur_height",
+                  di_pre_stru_p->cur_height);
+       seq_printf(seq, "%-25s = 0x%x\n", "cur_inp_type",
+                  di_pre_stru_p->cur_inp_type);
+       seq_printf(seq, "%-25s = %d\n", "cur_source_type",
+                  di_pre_stru_p->cur_source_type);
+       seq_printf(seq, "%-25s = %d\n", "cur_prog_flag",
+                  di_pre_stru_p->cur_prog_flag);
+       seq_printf(seq, "%-25s = %d\n", "source_change_flag",
+                  di_pre_stru_p->source_change_flag);
+       seq_printf(seq, "%-25s = %s\n", "bypass_flag",
+                  di_pre_stru_p->bypass_flag ? "true" : "false");
+       seq_printf(seq, "%-25s = %d\n", "prog_proc_type",
+                  di_pre_stru_p->prog_proc_type);
+       seq_printf(seq, "%-25s = %d\n", "madi_enable",
+                  di_pre_stru_p->madi_enable);
+       seq_printf(seq, "%-25s = %d\n", "mcdi_enable",
+                  di_pre_stru_p->mcdi_enable);
+#ifdef DET3D
+       seq_printf(seq, "%-25s = %d\n", "vframe_interleave_flag",
+                  di_pre_stru_p->vframe_interleave_flag);
+#endif
+       seq_printf(seq, "%-25s = %d\n", "left_right",
+                  di_pre_stru_p->left_right);
+       seq_printf(seq, "%-25s = %s\n", "force_interlace",
+                  di_pre_stru_p->force_interlace ? "true" : "false");
+       seq_printf(seq, "%-25s = %d\n", "vdin2nr",
+                  di_pre_stru_p->vdin2nr);
+       seq_printf(seq, "%-25s = %s\n", "bypass_pre",
+                  di_pre_stru_p->bypass_pre ? "true" : "false");
+       seq_printf(seq, "%-25s = %s\n", "invert_flag",
+                  di_pre_stru_p->invert_flag ? "true" : "false");
+
+       return 0;
+}
+
+void dim_dump_post_stru(struct di_post_stru_s *di_post_stru_p)
+{
+       pr_info("\ndi_post_stru:\n");
+       pr_info("run_early_proc_fun_flag        = %d\n",
+               di_post_stru_p->run_early_proc_fun_flag);
+       pr_info("cur_disp_index = %d\n",
+               di_post_stru_p->cur_disp_index);
+       pr_info("post_de_busy                   = %d\n",
+               di_post_stru_p->post_de_busy);
+       pr_info("de_post_process_done   = %d\n",
+               di_post_stru_p->de_post_process_done);
+       pr_info("cur_post_buf                   = 0x%p\n",
+               di_post_stru_p->cur_post_buf);
+       pr_info("post_peek_underflow    = %u\n",
+               di_post_stru_p->post_peek_underflow);
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dim_dump_post_stru*/
+static int dump_di_post_stru_seq(struct seq_file *seq, void *v,
+                                unsigned int channel)
+{
+       struct di_post_stru_s *di_post_stru_p = get_post_stru(channel);
+
+       seq_printf(seq, "di_post_stru[%d]:\n", channel);
+       seq_printf(seq, "run_early_proc_fun_flag        = %d\n",
+                  di_post_stru_p->run_early_proc_fun_flag);
+       seq_printf(seq, "cur_disp_index = %d\n",
+                  di_post_stru_p->cur_disp_index);
+       seq_printf(seq, "post_de_busy                   = %d\n",
+                  di_post_stru_p->post_de_busy);
+       seq_printf(seq, "de_post_process_done   = %d\n",
+                  di_post_stru_p->de_post_process_done);
+       seq_printf(seq, "cur_post_buf                   = 0x%p\n",
+                  di_post_stru_p->cur_post_buf);
+       seq_printf(seq, "post_peek_underflow    = %u\n",
+                  di_post_stru_p->post_peek_underflow);
+
+       return 0;
+}
+
+void dim_dump_mif_size_state(struct di_pre_stru_s *pre_stru_p,
+                            struct di_post_stru_s *post_stru_p)
+{
+       pr_info("======pre mif status======\n");
+       pr_info("DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL));
+       pr_info("DI_PRE_SIZE H=%d, V=%d\n",
+               (Rd(DI_PRE_SIZE) >> 16) & 0xffff,
+               Rd(DI_PRE_SIZE) & 0xffff);
+       pr_info("DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               pr_info("CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec));
+               pr_info("MTNWR_CAN_SIZE=0x%x\n", Rd(0x37f0));
+       }
+       pr_info("DNR_STAT_X_START_END=0x%x\n", Rd(0x2d08));
+       pr_info("DNR_STAT_Y_START_END=0x%x\n", Rd(0x2d09));
+       pr_info("MCDI_HV_SIZEIN=0x%x\n", Rd(0x2f00));
+       pr_info("MCDI_HV_BLKSIZEIN=0x%x\n", Rd(0x2f01));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               pr_info("MCVECWR_CAN_SIZE=0x%x\n", Rd(0x37f4));
+               pr_info("MCINFWR_CAN_SIZE=0x%x\n", Rd(0x37f8));
+               pr_info("NRDSWR_CAN_SIZE=0x%x\n", Rd(0x37fc));
+               pr_info("NR_DS_BUF_SIZE=0x%x\n", Rd(0x3740));
+       }
+
+       pr_info("=====inp mif:\n");
+#if 0
+       Wr(DI_DBG_CTRL, 0x1b);
+       Wr(DI_DBG_CTRL1, 0x640064);
+       Wr_reg_bits(DI_PRE_GL_CTRL, 0, 31, 1);
+       Wr_reg_bits(DI_PRE_CTRL, 0, 11, 1);
+       Wr_reg_bits(DI_PRE_CTRL, 1, 31, 1);
+       Wr_reg_bits(DI_PRE_GL_CTRL, 1, 31, 1);
+       pr_info("DI_DBG_SRDY_INF=0x%x\n", Rd(DI_DBG_SRDY_INF));
+       pr_info("DI_DBG_RRDY_INF=0x%x\n", Rd(DI_DBG_RRDY_INF));
+#endif
+       pr_info("DI_INP_GEN_REG=0x%x\n", Rd(DI_INP_GEN_REG));
+       dump_mif_state(&pre_stru_p->di_inp_mif);
+       pr_info("=====mem mif:\n");
+       pr_info("DI_MEM_GEN_REG=0x%x\n", Rd(DI_MEM_GEN_REG));
+       dump_mif_state(&pre_stru_p->di_mem_mif);
+       pr_info("=====chan2 mif:\n");
+       pr_info("DI_CHAN2_GEN_REG=0x%x\n", Rd(DI_CHAN2_GEN_REG));
+       dump_mif_state(&pre_stru_p->di_chan2_mif);
+       pr_info("=====nrwr mif:\n");
+       pr_info("DI_NRWR_CTRL=0x%x\n", Rd(DI_NRWR_CTRL));
+       dump_simple_mif_state(&pre_stru_p->di_nrwr_mif);
+       pr_info("=====mtnwr mif:\n");
+       dump_simple_mif_state(&pre_stru_p->di_mtnwr_mif);
+       pr_info("=====contp2rd mif:\n");
+       dump_simple_mif_state(&pre_stru_p->di_contp2rd_mif);
+       pr_info("=====contprd mif:\n");
+       dump_simple_mif_state(&pre_stru_p->di_contprd_mif);
+       pr_info("=====contwr mif:\n");
+       dump_simple_mif_state(&pre_stru_p->di_contwr_mif);
+       pr_info("=====mcinford mif:\n");
+       dump_mc_mif_state(&pre_stru_p->di_mcinford_mif);
+       pr_info("=====mcinfowr mif:\n");
+       dump_mc_mif_state(&pre_stru_p->di_mcinfowr_mif);
+       pr_info("=====mcvecwr mif:\n");
+       dump_mc_mif_state(&pre_stru_p->di_mcvecwr_mif);
+       pr_info("======post mif status======\n");
+       pr_info("DI_POST_SIZE=0x%x\n", Rd(DI_POST_SIZE));
+       pr_info("DECOMB_FRM_SIZE=0x%x\n", Rd(0x2d8f));
+       pr_info("=====if0 mif:\n");
+       pr_info("DI_IF0_GEN_REG=0x%x\n", Rd(0x2030));
+       dump_mif_state(&post_stru_p->di_buf0_mif);
+       pr_info("=====if1 mif:\n");
+       pr_info("DI_IF1_GEN_REG=0x%x\n", Rd(0x17e8));
+       dump_mif_state(&post_stru_p->di_buf1_mif);
+       pr_info("=====if2 mif:\n");
+       pr_info("DI_IF2_GEN_REG=0x%x\n", Rd(0x2010));
+       dump_mif_state(&post_stru_p->di_buf2_mif);
+       pr_info("=====diwr mif:\n");
+       dump_simple_mif_state(&post_stru_p->di_diwr_mif);
+       pr_info("=====mtnprd mif:\n");
+       dump_simple_mif_state(&post_stru_p->di_mtnprd_mif);
+       pr_info("=====mcvecrd mif:\n");
+       dump_mc_mif_state(&post_stru_p->di_mcvecrd_mif);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               pr_info("======pps size status======\n");
+               pr_info("DI_SC_LINE_IN_LENGTH=0x%x\n", Rd(0x3751));
+               pr_info("DI_SC_PIC_IN_HEIGHT=0x%x\n", Rd(0x3752));
+               pr_info("DI_HDR_IN_HSIZE=0x%x\n", Rd(0x376e));
+               pr_info("DI_HDR_IN_VSIZE=0x%x\n", Rd(0x376f));
+       }
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dump_mif_size_state*/
+int dim_dump_mif_size_state_show(struct seq_file *seq,
+                                void *v, unsigned int channel)
+{
+       struct di_pre_stru_s *di_pre_stru_p;
+       struct di_post_stru_s *di_post_stru_p;
+
+       di_pre_stru_p = get_pre_stru(channel);
+       di_post_stru_p = get_post_stru(channel);
+
+       seq_puts(seq, "======pre mif status======\n");
+       seq_printf(seq, "DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL));
+       seq_printf(seq, "DI_PRE_SIZE=0x%x\n", Rd(DI_PRE_SIZE));
+       seq_printf(seq, "DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               seq_printf(seq, "CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec));
+               seq_printf(seq, "MTNWR_CAN_SIZE=0x%x\n", Rd(0x37f0));
+       }
+       seq_printf(seq, "DNR_STAT_X_START_END=0x%x\n", Rd(0x2d08));
+       seq_printf(seq, "DNR_STAT_Y_START_END=0x%x\n", Rd(0x2d09));
+       seq_printf(seq, "MCDI_HV_SIZEIN=0x%x\n", Rd(0x2f00));
+       seq_printf(seq, "MCDI_HV_BLKSIZEIN=0x%x\n", Rd(0x2f01));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               seq_printf(seq, "MCVECWR_CAN_SIZE=0x%x\n", Rd(0x37f4));
+               seq_printf(seq, "MCINFWR_CAN_SIZE=0x%x\n", Rd(0x37f8));
+               seq_printf(seq, "NRDSWR_CAN_SIZE=0x%x\n", Rd(0x37fc));
+               seq_printf(seq, "NR_DS_BUF_SIZE=0x%x\n", Rd(0x3740));
+       }
+
+       seq_puts(seq, "=====inp mif:\n");
+
+       seq_printf(seq, "DI_INP_GEN_REG=0x%x\n", Rd(DI_INP_GEN_REG));
+       dump_mif_state_seq(&di_pre_stru_p->di_inp_mif, seq);/*dump_mif_state*/
+       seq_puts(seq, "=====mem mif:\n");
+       seq_printf(seq, "DI_MEM_GEN_REG=0x%x\n", Rd(DI_MEM_GEN_REG));
+       dump_mif_state_seq(&di_pre_stru_p->di_mem_mif, seq);
+       seq_puts(seq, "=====chan2 mif:\n");
+       seq_printf(seq, "DI_CHAN2_GEN_REG=0x%x\n", Rd(DI_CHAN2_GEN_REG));
+       dump_mif_state_seq(&di_pre_stru_p->di_chan2_mif, seq);
+       seq_puts(seq, "=====nrwr mif:\n");
+       seq_printf(seq, "DI_NRWR_CTRL=0x%x\n", Rd(DI_NRWR_CTRL));
+       /*dump_simple_mif_state*/
+       dump_simple_mif_state_seq(&di_pre_stru_p->di_nrwr_mif, seq);
+       seq_puts(seq, "=====mtnwr mif:\n");
+       dump_simple_mif_state_seq(&di_pre_stru_p->di_mtnwr_mif, seq);
+       seq_puts(seq, "=====contp2rd mif:\n");
+       dump_simple_mif_state_seq(&di_pre_stru_p->di_contp2rd_mif, seq);
+       seq_puts(seq, "=====contprd mif:\n");
+       dump_simple_mif_state_seq(&di_pre_stru_p->di_contprd_mif, seq);
+       seq_puts(seq, "=====contwr mif:\n");
+       dump_simple_mif_state_seq(&di_pre_stru_p->di_contwr_mif, seq);
+       seq_puts(seq, "=====mcinford mif:\n");
+       /*dump_mc_mif_state*/
+       dump_mc_mif_state_seq(&di_pre_stru_p->di_mcinford_mif, seq);
+       seq_puts(seq, "=====mcinfowr mif:\n");
+       dump_mc_mif_state_seq(&di_pre_stru_p->di_mcinfowr_mif, seq);
+       seq_puts(seq, "=====mcvecwr mif:\n");
+       dump_mc_mif_state_seq(&di_pre_stru_p->di_mcvecwr_mif, seq);
+       seq_puts(seq, "======post mif status======\n");
+       seq_printf(seq, "DI_POST_SIZE=0x%x\n", Rd(DI_POST_SIZE));
+       seq_printf(seq, "DECOMB_FRM_SIZE=0x%x\n", Rd(0x2d8f));
+       seq_puts(seq, "=====if0 mif:\n");
+       seq_printf(seq, "DI_IF0_GEN_REG=0x%x\n", Rd(0x2030));
+       dump_mif_state_seq(&di_post_stru_p->di_buf0_mif, seq);
+       seq_puts(seq, "=====if1 mif:\n");
+       seq_printf(seq, "DI_IF1_GEN_REG=0x%x\n", Rd(0x17e8));
+       dump_mif_state_seq(&di_post_stru_p->di_buf1_mif, seq);
+       seq_puts(seq, "=====if2 mif:\n");
+       seq_printf(seq, "DI_IF2_GEN_REG=0x%x\n", Rd(0x2010));
+       dump_mif_state_seq(&di_post_stru_p->di_buf2_mif, seq);
+       seq_puts(seq, "=====diwr mif:\n");
+       dump_simple_mif_state_seq(&di_post_stru_p->di_diwr_mif, seq);
+       seq_puts(seq, "=====mtnprd mif:\n");
+       dump_simple_mif_state_seq(&di_post_stru_p->di_mtnprd_mif, seq);
+       seq_puts(seq, "=====mcvecrd mif:\n");
+       dump_mc_mif_state_seq(&di_post_stru_p->di_mcvecrd_mif, seq);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               seq_puts(seq, "======pps size status======\n");
+               seq_printf(seq, "DI_SC_LINE_IN_LENGTH=0x%x\n", Rd(0x3751));
+               seq_printf(seq, "DI_SC_PIC_IN_HEIGHT=0x%x\n", Rd(0x3752));
+               seq_printf(seq, "DI_HDR_IN_HSIZE=0x%x\n", Rd(0x376e));
+               seq_printf(seq, "DI_HDR_IN_VSIZE=0x%x\n", Rd(0x376f));
+       }
+       return 0;
+}
+
+void dim_dump_di_buf(struct di_buf_s *di_buf)
+{
+       pr_info("di_buf %p vframe %p:\n", di_buf, di_buf->vframe);
+       pr_info("index %d, post_proc_flag %d, new_format_flag %d, type %d,",
+               di_buf->index, di_buf->post_proc_flag,
+               di_buf->new_format_flag, di_buf->type);
+       pr_info("seq %d, pre_ref_count %d,post_ref_count %d, queue_index %d,",
+               di_buf->seq, di_buf->pre_ref_count, di_buf->post_ref_count,
+               di_buf->queue_index);
+       pr_info("pulldown_mode %d process_fun_index %d\n",
+               di_buf->pd_config.global_mode, di_buf->process_fun_index);
+       pr_info("di_buf: %p, %p, di_buf_dup_p: %p, %p, %p, %p, %p\n",
+               di_buf->di_buf[0], di_buf->di_buf[1], di_buf->di_buf_dup_p[0],
+               di_buf->di_buf_dup_p[1], di_buf->di_buf_dup_p[2],
+               di_buf->di_buf_dup_p[3], di_buf->di_buf_dup_p[4]);
+       pr_info(
+       "nr_adr 0x%lx, nr_canvas_idx 0x%x, mtn_adr 0x%lx, mtn_canvas_idx 0x%x",
+               di_buf->nr_adr, di_buf->nr_canvas_idx, di_buf->mtn_adr,
+               di_buf->mtn_canvas_idx);
+       pr_info("cnt_adr 0x%lx, cnt_canvas_idx 0x%x\n",
+               di_buf->cnt_adr, di_buf->cnt_canvas_idx);
+       pr_info("di_cnt %d, priveated %u.\n",
+               atomic_read(&di_buf->di_cnt), di_buf->privated);
+}
+
+void dim_dump_pool(struct queue_s *q)
+{
+       int j;
+
+       pr_info("queue: in_idx %d, out_idx %d, num %d, type %d\n",
+               q->in_idx, q->out_idx, q->num, q->type);
+       for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++) {
+               pr_info("0x%x ", q->pool[j]);
+               if (((j + 1) % 16) == 0)
+                       pr_debug("\n");
+       }
+       pr_info("\n");
+}
+
+void dim_dump_vframe(struct vframe_s *vf)
+{
+       pr_info("vframe %p:\n", vf);
+       pr_info("index %d, type 0x%x, type_backup 0x%x, blend_mode %d bitdepth %d\n",
+               vf->index, vf->type, vf->type_backup,
+               vf->blend_mode, (vf->bitdepth & BITDEPTH_Y10) ? 10 : 8);
+       pr_info("duration %d, duration_pulldown %d, pts %d, flag 0x%x\n",
+               vf->duration, vf->duration_pulldown, vf->pts, vf->flag);
+       pr_info("canvas0Addr 0x%x, canvas1Addr 0x%x, bufWidth %d\n",
+               vf->canvas0Addr, vf->canvas1Addr, vf->bufWidth);
+       pr_info("width %d, height %d, ratio_control 0x%x, orientation 0x%x\n",
+               vf->width, vf->height, vf->ratio_control, vf->orientation);
+       pr_info("source_type %d, phase %d, soruce_mode %d, sig_fmt %d\n",
+               vf->source_type, vf->phase, vf->source_mode, vf->sig_fmt);
+       pr_info(
+               "trans_fmt 0x%x, lefteye(%d %d %d %d), righteye(%d %d %d %d)\n",
+               vf->trans_fmt, vf->left_eye.start_x, vf->left_eye.start_y,
+               vf->left_eye.width, vf->left_eye.height,
+               vf->right_eye.start_x, vf->right_eye.start_y,
+               vf->right_eye.width, vf->right_eye.height);
+       pr_info("mode_3d_enable %d, use_cnt %d,",
+               vf->mode_3d_enable, atomic_read(&vf->use_cnt));
+       pr_info("early_process_fun 0x%p, process_fun 0x%p, private_data %p\n",
+               vf->early_process_fun,
+               vf->process_fun, vf->private_data);
+       pr_info("pixel_ratio %d list %p\n",
+               vf->pixel_ratio, &vf->list);
+}
+
+void dim_print_di_buf(struct di_buf_s *di_buf, int format)
+{
+       if (!di_buf)
+               return;
+       if (format == 1) {
+               pr_info(
+               "\t+index %d, 0x%p, type %d, vframetype 0x%x, trans_fmt %u,bitdepath %d\n",
+                       di_buf->index,
+                       di_buf,
+                       di_buf->type,
+                       di_buf->vframe->type,
+                       di_buf->vframe->trans_fmt,
+                       di_buf->vframe->bitdepth);
+               if (di_buf->di_wr_linked_buf) {
+                       pr_info("\tlinked  +index %d, 0x%p, type %d\n",
+                               di_buf->di_wr_linked_buf->index,
+                               di_buf->di_wr_linked_buf,
+                               di_buf->di_wr_linked_buf->type);
+               }
+       } else if (format == 2) {
+               pr_info("index %d, 0x%p(vframe 0x%p), type %d\n",
+                       di_buf->index, di_buf,
+                       di_buf->vframe, di_buf->type);
+               pr_info("vframetype 0x%x, trans_fmt %u,duration %d pts %d,bitdepth %d\n",
+                       di_buf->vframe->type,
+                       di_buf->vframe->trans_fmt,
+                       di_buf->vframe->duration,
+                       di_buf->vframe->pts,
+                       di_buf->vframe->bitdepth);
+               if (di_buf->di_wr_linked_buf) {
+                       pr_info("linked index %d, 0x%p, type %d\n",
+                               di_buf->di_wr_linked_buf->index,
+                               di_buf->di_wr_linked_buf,
+                               di_buf->di_wr_linked_buf->type);
+               }
+       }
+}
+
+/*2018-08-17 add debugfs*/
+/*same as print_di_buf*/
+static void print_di_buf_seq(struct di_buf_s *di_buf, int format,
+                            struct seq_file *seq)
+{
+       if (!di_buf)
+               return;
+       if (format == 1) {
+               seq_printf(seq, "\t+index %d, 0x%p, type %d\n",
+                          di_buf->index,
+                          di_buf,
+                          di_buf->type);
+               seq_printf(seq, "vframetype 0x%x, trans_fmt %u,bitdepath %d\n",
+                          di_buf->vframe->type,
+                          di_buf->vframe->trans_fmt,
+                          di_buf->vframe->bitdepth);
+               if (di_buf->di_wr_linked_buf) {
+                       seq_printf(seq, "\tlinked  +index %d, 0x%p, type %d\n",
+                                  di_buf->di_wr_linked_buf->index,
+                                  di_buf->di_wr_linked_buf,
+                                  di_buf->di_wr_linked_buf->type);
+               }
+       } else if (format == 2) {
+               seq_printf(seq, "index %d, 0x%p(vframe 0x%p), type %d\n",
+                          di_buf->index, di_buf,
+                          di_buf->vframe, di_buf->type);
+               seq_printf(seq, "vfmtype 0x%x, trans_fmt %u\n",
+                          di_buf->vframe->type,
+                          di_buf->vframe->trans_fmt);
+               seq_printf(seq, ",duration %d pts %d,bitdepth %d\n",
+                          di_buf->vframe->duration,
+                          di_buf->vframe->pts,
+                          di_buf->vframe->bitdepth);
+               if (di_buf->di_wr_linked_buf) {
+                       seq_printf(seq, "linked index %d, 0x%p, type %d\n",
+                                  di_buf->di_wr_linked_buf->index,
+                                  di_buf->di_wr_linked_buf,
+                                  di_buf->di_wr_linked_buf->type);
+               }
+       }
+}
+
+void dim_dump_pre_mif_state(void)
+{
+       unsigned int i = 0;
+
+       Wr_reg_bits(DI_INP_GEN_REG3, 3, 10, 2);
+       Wr_reg_bits(DI_MEM_GEN_REG3, 3, 10, 2);
+       Wr_reg_bits(DI_CHAN2_GEN_REG3, 3, 10, 2);
+       pr_info("DI_INP_GEN_REG2=0x%x.\n", Rd(DI_INP_GEN_REG2));
+       pr_info("DI_INP_GEN_REG3=0x%x.\n", Rd(DI_INP_GEN_REG3));
+       for (i = 0; i < 10; i++)
+               pr_info("0x%x=0x%x.\n", 0x17ce + i, Rd(0x17ce + i));
+       pr_info("DI_MEM_GEN_REG2=0x%x.\n", Rd(DI_MEM_GEN_REG2));
+       pr_info("DI_MEM_GEN_REG3=0x%x.\n", Rd(DI_MEM_GEN_REG3));
+       pr_info("DI_MEM_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_MEM_LUMA_FIFO_SIZE));
+       for (i = 0; i < 10; i++)
+               pr_info("0x%x=0x%x.\n", 0x17db + i, Rd(0x17db + i));
+       pr_info("DI_CHAN2_GEN_REG2=0x%x.\n", Rd(DI_CHAN2_GEN_REG2));
+       pr_info("DI_CHAN2_GEN_REG3=0x%x.\n", Rd(DI_CHAN2_GEN_REG3));
+       pr_info("DI_CHAN2_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_CHAN2_LUMA_FIFO_SIZE));
+       for (i = 0; i < 10; i++)
+               pr_info("0x%x=0x%x.\n", 0x17f5 + i, Rd(0x17f5 + i));
+}
+
+void dim_dump_post_mif_reg(void)
+{
+       pr_info("VIU_MISC_CTRL0=0x%x\n", Rd(VIU_MISC_CTRL0));
+
+       pr_info("VD1_IF0_GEN_REG=0x%x\n", Rd(VD1_IF0_GEN_REG));
+       pr_info("VD1_IF0_GEN_REG2=0x%x\n", Rd(VD1_IF0_GEN_REG2));
+       pr_info("VD1_IF0_GEN_REG3=0x%x\n", Rd(VD1_IF0_GEN_REG3));
+       pr_info("VD1_IF0_LUMA_X0=0x%x\n", Rd(VD1_IF0_LUMA_X0));
+       pr_info("VD1_IF0_LUMA_Y0=0x%x\n", Rd(VD1_IF0_LUMA_Y0));
+       pr_info("VD1_IF0_CHROMA_X0=0x%x\n", Rd(VD1_IF0_CHROMA_X0));
+       pr_info("VD1_IF0_CHROMA_Y0=0x%x\n", Rd(VD1_IF0_CHROMA_Y0));
+       pr_info("VD1_IF0_LUMA_X1=0x%x\n", Rd(VD1_IF0_LUMA_X1));
+       pr_info("VD1_IF0_LUMA_Y1=0x%x\n", Rd(VD1_IF0_LUMA_Y1));
+       pr_info("VD1_IF0_CHROMA_X1=0x%x\n", Rd(VD1_IF0_CHROMA_X1));
+       pr_info("VD1_IF0_CHROMA_Y1=0x%x\n", Rd(VD1_IF0_CHROMA_Y1));
+       pr_info("VD1_IF0_REPEAT_LOOP=0x%x\n", Rd(VD1_IF0_RPT_LOOP));
+       pr_info("VD1_IF0_LUMA0_RPT_PAT=0x%x\n", Rd(VD1_IF0_LUMA0_RPT_PAT));
+       pr_info("VD1_IF0_CHROMA0_RPT_PAT=0x%x\n", Rd(VD1_IF0_CHROMA0_RPT_PAT));
+       pr_info("VD1_IF0_LUMA_PSEL=0x%x\n", Rd(VD1_IF0_LUMA_PSEL));
+       pr_info("VD1_IF0_CHROMA_PSEL=0x%x\n", Rd(VD1_IF0_CHROMA_PSEL));
+       pr_info("VIU_VD1_FMT_CTRL=0x%x\n", Rd(VIU_VD1_FMT_CTRL));
+       pr_info("VIU_VD1_FMT_W=0x%x\n", Rd(VIU_VD1_FMT_W));
+
+       pr_info("DI_IF1_GEN_REG=0x%x\n", Rd(DI_IF1_GEN_REG));
+       pr_info("DI_IF1_GEN_REG2=0x%x\n", Rd(DI_IF1_GEN_REG2));
+       pr_info("DI_IF1_GEN_REG3=0x%x\n", Rd(DI_IF1_GEN_REG3));
+       pr_info("DI_IF1_CANVAS0=0x%x\n", Rd(DI_IF1_CANVAS0));
+       pr_info("DI_IF1_LUMA_X0=0x%x\n", Rd(DI_IF1_LUMA_X0));
+       pr_info("DI_IF1_LUMA_Y0=0x%x\n", Rd(DI_IF1_LUMA_Y0));
+       pr_info("DI_IF1_CHROMA_X0=0x%x\n", Rd(DI_IF1_CHROMA_X0));
+       pr_info("DI_IF1_CHROMA_Y0=0x%x\n", Rd(DI_IF1_CHROMA_Y0));
+       pr_info("DI_IF1_LUMA0_RPT_PAT=0x%x\n", Rd(DI_IF1_LUMA0_RPT_PAT));
+       pr_info("DI_IF1_CHROMA0_RPT_PAT=0x%x\n", Rd(DI_IF1_LUMA0_RPT_PAT));
+       pr_info("DI_IF1_FMT_CTRL=0x%x\n", Rd(DI_IF1_FMT_CTRL));
+       pr_info("DI_IF1_FMT_W=0x%x\n", Rd(DI_IF1_FMT_W));
+
+       pr_info("DI_IF2_GEN_REG=0x%x\n", Rd(DI_IF2_GEN_REG));
+       pr_info("DI_IF2_GEN_REG2=0x%x\n", Rd(DI_IF2_GEN_REG2));
+       pr_info("DI_IF2_GEN_REG3=0x%x\n", Rd(DI_IF2_GEN_REG3));
+       pr_info("DI_IF2_CANVAS0=0x%x\n", Rd(DI_IF2_CANVAS0));
+       pr_info("DI_IF2_LUMA_X0=0x%x\n", Rd(DI_IF2_LUMA_X0));
+       pr_info("DI_IF2_LUMA_Y0=0x%x\n", Rd(DI_IF2_LUMA_Y0));
+       pr_info("DI_IF2_CHROMA_X0=0x%x\n", Rd(DI_IF2_CHROMA_X0));
+       pr_info("DI_IF2_CHROMA_Y0=0x%x\n", Rd(DI_IF2_CHROMA_Y0));
+       pr_info("DI_IF2_LUMA0_RPT_PAT=0x%x\n", Rd(DI_IF2_LUMA0_RPT_PAT));
+       pr_info("DI_IF2_CHROMA0_RPT_PAT=0x%x\n", Rd(DI_IF2_LUMA0_RPT_PAT));
+       pr_info("DI_IF2_FMT_CTRL=0x%x\n", Rd(DI_IF2_FMT_CTRL));
+       pr_info("DI_IF2_FMT_W=0x%x\n", Rd(DI_IF2_FMT_W));
+
+       pr_info("DI_DIWR_Y=0x%x\n", Rd(DI_DIWR_Y));
+       pr_info("DI_DIWR_CTRL=0x%x", Rd(DI_DIWR_CTRL));
+       pr_info("DI_DIWR_X=0x%x.\n", Rd(DI_DIWR_X));
+}
+
+void dim_dump_buf_addr(struct di_buf_s *di_buf, unsigned int num)
+{
+       unsigned int i = 0;
+       struct di_buf_s *di_buf_p = NULL;
+
+       for (i = 0; i < num; i++) {
+               di_buf_p = (di_buf + i);
+               pr_info("di_buf[%d] nr_addr 0x%lx,",
+                       di_buf_p->index, di_buf_p->nr_adr);
+               pr_info("mtn_addr 0x%lx, cnt_adr 0x%lx,",
+                       di_buf_p->mtn_adr, di_buf_p->cnt_adr);
+               pr_info("mv_adr 0x%lx, mcinfo_adr 0x%lx.\n",
+                       di_buf_p->mcvec_adr, di_buf_p->mcinfo_adr);
+       }
+}
+
+static int seq_file_module_para_show(struct seq_file *seq, void *v)
+{
+       dim_seq_file_module_para_di(seq);
+       dim_seq_file_module_para_hw(seq);
+       dim_seq_file_module_para_pps(seq);
+       get_ops_mtn()->module_para(seq);
+       get_ops_nr()->module_para(seq);
+       get_ops_pd()->module_para(seq);
+
+       return 0;
+}
+
+/*2018-08-17 add debugfs*/
+/*same as dump_state*/
+int dim_state_show(struct seq_file *seq, void *v, unsigned int channel)
+{
+       int itmp, i;
+       struct di_buf_s *p = NULL, *keep_buf;/* ptmp; */
+       struct di_pre_stru_s *di_pre_stru_p;
+       struct di_post_stru_s *di_post_stru_p;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+       const char *version_s = dim_get_version_s();
+       int dump_state_flag = dim_get_dump_state_flag();
+       unsigned char recovery_flag = dim_vcry_get_flg();
+       unsigned int recovery_log_reason = dim_vcry_get_log_reason();
+       int di_blocking = dim_get_blocking();
+       unsigned int recovery_log_queue_idx = dim_vcry_get_log_q_idx();
+       struct di_buf_s *recovery_log_di_buf = dim_get_recovery_log_di_buf();
+       unsigned long reg_unreg_timeout_cnt = dim_get_reg_unreg_timeout_cnt();
+       struct vframe_s **vframe_in = dim_get_vframe_in(channel);
+       unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/
+       unsigned int psize; /*new que*/
+       struct di_hpre_s  *pre = get_hw_pre();
+       struct di_hpst_s *post = get_hw_pst();
+       struct di_buf_s *keep_buf_post = NULL;
+       char *splt = "---------------------------";
+       struct di_mm_s *mm = dim_mm_get();      /*mm-0705*/
+
+       di_pre_stru_p = get_pre_stru(channel);
+       di_post_stru_p = get_post_stru(channel);
+
+       dump_state_flag = 1;
+       seq_printf(seq, "%s:ch[%d]\n", __func__, channel);
+       seq_printf(seq, "version %s, init_flag %d, is_bypass %d\n",
+                  version_s,
+                  get_init_flag(channel),
+                  dim_is_bypass(NULL, channel));
+       seq_printf(seq, "recovery_flag = %d, reason=%d, di_blocking=%d",
+                  recovery_flag, recovery_log_reason, di_blocking);
+       seq_printf(seq, "recovery_log_q_idx=%d, recovery_log_di_buf=0x%p\n",
+                  recovery_log_queue_idx, recovery_log_di_buf);
+       seq_printf(seq, "buffer_size=%d, mem_flag=%s, cma_flag=%d\n",
+                  de_devp->buffer_size,
+                  di_cma_dbg_get_st_name(channel),
+                  de_devp->flag_cma);
+       keep_buf = di_post_stru_p->keep_buf;
+       seq_printf(seq, "used_post_buf_index %d(0x%p),",
+                  IS_ERR_OR_NULL(keep_buf) ?
+                  -1 : keep_buf->index, keep_buf);
+       if (!IS_ERR_OR_NULL(keep_buf)) {
+               seq_puts(seq, "used_local_buf_index:\n");
+               for (i = 0; i < USED_LOCAL_BUF_MAX; i++) {
+                       p = keep_buf->di_buf_dup_p[i];
+                       seq_printf(seq, "%d(0x%p) ",
+                                  IS_ERR_OR_NULL(p) ? -1 : p->index, p);
+               }
+       }
+       /********************************/
+       /* check keep buf post          */
+       /********************************/
+       keep_buf_post = di_post_stru_p->keep_buf_post;
+
+       if (IS_ERR_OR_NULL(keep_buf_post))
+               seq_printf(seq, "%s:NULL\n", "keep_buf_post");
+       else
+               seq_printf(seq, "%s:type=%d:index=%d\n",
+                          "keep_buf_post",
+                          keep_buf_post->type, keep_buf_post->index);
+       /********************************/
+       /* in_free_list                 */
+       /********************************/
+       di_que_list(channel, QUE_IN_FREE, &tmpa[0], &psize); /*new que*/
+       seq_printf(seq, "\nin_free_list max(%d) curr(%d):\n",
+                  MAX_IN_BUF_NUM, psize);
+       for (itmp = 0; itmp < psize; itmp++) {                  /*new que*/
+               p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/
+
+               seq_printf(seq, "index %2d, 0x%p, type %d\n",
+                          p->index, p, p->type);
+       }
+       seq_printf(seq, "%s\n", splt);
+       /********************************/
+       /* local_free_list              */
+       /********************************/
+       seq_printf(seq, "local_free_list (max %d):\n", mm->cfg.num_local);
+       queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) {
+               seq_printf(seq, "index %2d, 0x%p, type %d\n",
+                          p->index, p, p->type);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* post_doing_list              */
+       /********************************/
+       seq_puts(seq, "post_doing_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_POST_DOING, list) {
+               print_di_buf_seq(p, 2, seq);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* pre_ready_list               */
+       /********************************/
+       seq_puts(seq, "pre_ready_list:\n");
+       di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); /*new que*/
+       for (itmp = 0; itmp < psize; itmp++) {                  /*new que*/
+               p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/
+
+               print_di_buf_seq(p, 2, seq);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* post_free_list               */
+       /********************************/
+       di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize); /*new que*/
+       seq_printf(seq, "post_free_list (max %d) (crr %d):\n",
+                  mm->cfg.num_post, psize);
+       for (itmp = 0; itmp < psize; itmp++) {                  /*new que*/
+               p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/
+
+               seq_printf(seq, "index %2d, 0x%p, type %d, vframetype 0x%x\n",
+                          p->index, p, p->type, p->vframe->type);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* post_ready_list              */
+       /********************************/
+       di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); /*new que*/
+       seq_printf(seq, "post_ready_list: curr(%d)\n", psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {                  /*new que*/
+               p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/
+
+               print_di_buf_seq(p, 2, seq);
+               print_di_buf_seq(p->di_buf[0], 1, seq);
+               print_di_buf_seq(p->di_buf[1], 1, seq);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* display_list                 */
+       /********************************/
+       seq_puts(seq, "display_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) {
+               print_di_buf_seq(p, 2, seq);
+               print_di_buf_seq(p->di_buf[0], 1, seq);
+               print_di_buf_seq(p->di_buf[1], 1, seq);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* recycle_list                 */
+       /********************************/
+       seq_puts(seq, "recycle_list:\n");
+       queue_for_each_entry(p, channel, QUEUE_RECYCLE, list) {
+               seq_printf(seq,
+                       "index %d, 0x%p, type %d, vfm 0x%x pre %d postt %d\n",
+                       p->index, p, p->type,
+                       p->vframe->type,
+                       p->pre_ref_count,
+                       p->post_ref_count);
+               if (p->di_wr_linked_buf) {
+                       seq_printf(seq,
+                               "ld index %2d, 0x%p, type %d pret %d pst %d\n",
+                               p->di_wr_linked_buf->index,
+                               p->di_wr_linked_buf,
+                               p->di_wr_linked_buf->type,
+                               p->di_wr_linked_buf->pre_ref_count,
+                               p->di_wr_linked_buf->post_ref_count);
+               }
+       }
+       seq_printf(seq, "%s\n", splt);
+       /********************************/
+       /* post back                    */
+       /********************************/
+       di_que_list(channel, QUE_POST_BACK, &tmpa[0], &psize); /*new que*/
+       seq_printf(seq, "post_back: curr(%d)\n", psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {                  /*new que*/
+               seq_printf(seq, "%d\n", tmpa[itmp]);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+
+       if (di_pre_stru_p->di_inp_buf) {
+               seq_printf(seq, "di_inp_buf:index %d, 0x%p, type %d\n",
+                          di_pre_stru_p->di_inp_buf->index,
+                          &di_pre_stru_p->di_inp_buf,
+                          di_pre_stru_p->di_inp_buf->type);
+       } else {
+               seq_puts(seq, "di_inp_buf: NULL\n");
+       }
+       if (di_pre_stru_p->di_wr_buf) {
+               seq_printf(seq, "di_wr_buf:index %d, 0x%p, type %d\n",
+                          di_pre_stru_p->di_wr_buf->index,
+                          &di_pre_stru_p->di_wr_buf,
+                          di_pre_stru_p->di_wr_buf->type);
+       } else {
+               seq_puts(seq, "di_wr_buf: NULL\n");
+       }
+       dump_di_pre_stru_seq(seq, v, channel);
+       dump_di_post_stru_seq(seq, v, channel);
+       seq_puts(seq, "vframe_in[]:");
+
+       for (i = 0; i < MAX_IN_BUF_NUM; i++) {
+               seq_printf(seq, "0x%p\n", *vframe_in);
+               vframe_in++;
+       }
+
+       seq_puts(seq, "\n");
+       seq_printf(seq, "vf_peek()=>0x%p, video_peek_cnt = %d\n",
+                  pw_vf_peek(channel),
+                  di_sum_get(channel, eDI_SUM_O_PEEK_CNT));
+       seq_printf(seq, "reg_unreg_timerout = %lu\n",
+                  reg_unreg_timeout_cnt);
+       seq_printf(seq, "%-15s=%s\n", "top_state",
+                  dip_chst_get_name_curr(channel));
+       seq_printf(seq, "%-15s=%d\n", "trig_unreg",
+                  get_flag_trig_unreg(channel));
+       seq_printf(seq, "%-15s=%d\n", "bypass_compelet",
+                  is_bypss2_complete(channel));
+       seq_printf(seq, "%-15s=%d\n", "reg_flag",
+                  get_reg_flag(channel));
+       seq_printf(seq, "%-15s=%s\n", "pre_state",
+                  dpre_state4_name_get(pre->pre_st));
+       seq_printf(seq, "%-15s=%s\n", "post_state",
+                  dpst_state_name_get(post->state));
+
+       seq_printf(seq, "%-15s=%d\n", "pre_get_sum",
+                  get_sum_g(channel));
+       seq_printf(seq, "%-15s=%d\n", "pre_put_sum",
+                  get_sum_p(channel));
+       dump_state_flag = 0;
+       return 0;
+}
+
+static int seq_file_afbc_show(struct seq_file *seq, void *v)
+{
+       seq_puts(seq, "******dump VD2 AFBC********\n");
+       seq_printf(seq, "VD2_AFBC_ENABLE 0x%x.\n",
+                  dim_RDMA_RD(VD2_AFBC_ENABLE));
+       seq_printf(seq, "VD2_AFBC_STAT 0x%x.\n", dim_RDMA_RD(VD2_AFBC_STAT));
+       seq_printf(seq, "VD2_AFBCD1_MISC_CTRL 0x%x.\n",
+                  dim_RDMA_RD(VD2_AFBCD1_MISC_CTRL));
+
+       seq_puts(seq, "******dump VD1 AFBC********\n");
+       seq_printf(seq, "AFBC_ENABLE 0x%x.\n", dim_RDMA_RD(AFBC_ENABLE));
+       seq_printf(seq, "AFBC_STAT 0x%x.\n", dim_RDMA_RD(AFBC_STAT));
+       seq_printf(seq, "VD1_AFBCD0_MISC_CTRL 0x%x.\n",
+                  dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL));
+       seq_puts(seq, "***************************\n");
+
+       seq_printf(seq, "VIU_MISC_CTRL0 0x%x.\n", dim_RDMA_RD(VIU_MISC_CTRL0));
+       seq_printf(seq, "VIU_MISC_CTRL1 0x%x.\n", dim_RDMA_RD(VIU_MISC_CTRL1));
+       seq_printf(seq, "VIUB_MISC_CTRL0 0x%x.\n",
+                  dim_RDMA_RD(VIUB_MISC_CTRL0));
+
+       seq_printf(seq, "DI_PRE_CTRL bit8=%d,bit 28 =%d.\n",
+                  dim_RDMA_RD_BITS(DI_PRE_CTRL, 8, 1),
+                  dim_RDMA_RD_BITS(DI_PRE_CTRL, 28, 1));
+
+       return 0;
+}
+
+/*2018-08-17 add debugfs*/
+#define DEFINE_SHOW_DI(__name) \
+static int __name ## _open(struct inode *inode, struct file *file)     \
+{ \
+       return single_open(file, __name ## _show, inode->i_private);    \
+} \
+                                                                       \
+static const struct file_operations __name ## _fops = {                        \
+       .owner = THIS_MODULE,           \
+       .open = __name ## _open,        \
+       .read = seq_read,               \
+       .llseek = seq_lseek,            \
+       .release = single_release,      \
+}
+
+DEFINE_SHOW_DI(seq_file_module_para);
+/*DEFINE_SHOW_DI(seq_file_di_state);*/
+DEFINE_SHOW_DI(seq_file_dump_di_reg);
+/*DEFINE_SHOW_DI(seq_file_dump_mif_size_state);*/
+DEFINE_SHOW_DI(seq_file_afbc);
+
+struct di_debugfs_files_t {
+       const char *name;
+       const umode_t mode;
+       const struct file_operations *fops;
+};
+
+static struct di_debugfs_files_t di_debugfs_files[] = {
+/*     {"state", S_IFREG | 0644, &seq_file_di_state_fops},*/
+       {"dumpreg", S_IFREG | 0644, &seq_file_dump_di_reg_fops},
+/*     {"dumpmif", S_IFREG | 0644, &seq_file_dump_mif_size_state_fops},*/
+       {"dumpafbc", S_IFREG | 0644, &seq_file_afbc_fops},
+       {"dumppara", S_IFREG | 0644, &seq_file_module_para_fops},
+};
+
+void dim_debugfs_init(void)
+{
+       int i;
+       struct dentry *ent;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (de_devp->dbg_root)
+               return;
+
+       de_devp->dbg_root = debugfs_create_dir("di", NULL);
+       if (!de_devp->dbg_root) {
+               PR_ERR("can't create debugfs dir di\n");
+               return;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(di_debugfs_files); i++) {
+               ent = debugfs_create_file(di_debugfs_files[i].name,
+                                         di_debugfs_files[i].mode,
+                                         de_devp->dbg_root, NULL,
+                                         di_debugfs_files[i].fops);
+               if (!ent)
+                       PR_ERR("debugfs create failed\n");
+       }
+}
+
+void dim_debugfs_exit(void)
+{
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       if (de_devp && de_devp->dbg_root)
+               debugfs_remove_recursive(de_devp->dbg_root);
+}
+
+/*-----------------------*/
diff --git a/drivers/amlogic/media/di_multi/deinterlace_dbg.h b/drivers/amlogic/media/di_multi/deinterlace_dbg.h
new file mode 100644 (file)
index 0000000..7aa2ed2
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace_dbg.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _DI_DBG_H
+#define _DI_DBG_H
+#include "deinterlace.h"
+
+void dim_parse_cmd_params(char *buf_orig, char **parm);
+void dim_dump_pre_stru(struct di_pre_stru_s *ppre);
+void dim_dump_post_stru(struct di_post_stru_s *di_post_stru_p);
+void dim_dump_di_buf(struct di_buf_s *di_buf);
+void dim_dump_pool(struct queue_s *q);
+void dim_dump_vframe(vframe_t *vf);
+void dim_print_di_buf(struct di_buf_s *di_buf, int format);
+void dim_dump_pre_mif_state(void);
+void dim_dump_post_mif_reg(void);
+void dim_dump_buf_addr(struct di_buf_s *di_buf, unsigned int num);
+void dim_dump_mif_size_state(struct di_pre_stru_s *pre,
+                            struct di_post_stru_s *post);
+void debug_device_files_add(struct device *dev);
+void debug_device_files_del(struct device *dev);
+void dim_debugfs_init(void);
+void dim_debugfs_exit(void);
+int dim_state_show(struct seq_file *seq, void *v,
+                  unsigned int channel);
+int dim_dump_mif_size_state_show(struct seq_file *seq, void *v,
+                                unsigned int channel);
+
+#endif
diff --git a/drivers/amlogic/media/di_multi/deinterlace_hw.c b/drivers/amlogic/media/di_multi/deinterlace_hw.c
new file mode 100644 (file)
index 0000000..5fa6bfb
--- /dev/null
@@ -0,0 +1,4236 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace_hw.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/atomic.h>
+
+#include <linux/amlogic/media/vpu/vpu.h>
+#include <linux/amlogic/cpu_version.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/video_sink/video.h>
+#include "deinterlace.h"
+#include "di_data_l.h"
+
+#include "deinterlace_hw.h"
+#include "register.h"
+#include "register_nr4.h"
+#ifdef DET3D
+#include "detect3d.h"
+#endif
+#include "di_api.h"
+#include "di_reg_tab.h"
+#include "di_prc.h"
+
+#include <linux/seq_file.h>
+
+static unsigned int ctrl_regs[SKIP_CTRE_NUM];
+
+static void set_di_inp_fmt_more(
+               unsigned int repeat_l0_en,
+               int hz_yc_ratio,        /* 2bit */
+               int hz_ini_phase,       /* 4bit */
+               int vfmt_en,
+               int vt_yc_ratio,        /* 2bit */
+               int vt_ini_phase,       /* 4bit */
+               int y_length,
+               int c_length,
+               int hz_rpt              /* 1bit */
+       );
+
+static void set_di_inp_mif(struct DI_MIF_s  *mif, int urgent, int hold_line);
+
+static void set_di_mem_fmt_more(
+               int hfmt_en,
+               int hz_yc_ratio,        /* 2bit */
+               int hz_ini_phase,       /* 4bit */
+               int vfmt_en,
+               int vt_yc_ratio,        /* 2bit */
+               int vt_ini_phase,       /* 4bit */
+               int y_length,
+               int c_length,
+               int hz_rpt      /* 1bit */
+       );
+
+static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line);
+
+static void set_di_if0_fmt_more(
+               int hfmt_en,
+               int hz_yc_ratio,                /* 2bit */
+               int hz_ini_phase,               /* 4bit */
+               int vfmt_en,
+               int vt_yc_ratio,                /* 2bit */
+               int vt_ini_phase,               /* 4bit */
+               int y_length,
+               int c_length,
+               int hz_rpt                                /* 1bit */
+       );
+
+static void set_di_if1_fmt_more(
+               int hfmt_en,
+               int hz_yc_ratio,        /* 2bit */
+               int hz_ini_phase,       /* 4bit */
+               int vfmt_en,
+               int vt_yc_ratio,        /* 2bit */
+               int vt_ini_phase,       /* 4bit */
+               int y_length,
+               int c_length,
+               int hz_rpt              /* 1bit */
+       );
+
+static void set_di_if1_mif(struct DI_MIF_s *mif, int urgent,
+                          int hold_line, int vskip_cnt);
+
+static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line);
+
+static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent,
+                          int hold_line, int vskip_cnt, int wr_en);
+
+static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent,
+                              int hold_line, int vskip_cnt, int wr_en);
+
+static void ma_di_init(void)
+{
+       /* 420->422 chrome difference is large motion is large,flick */
+       dim_DI_Wr(DI_MTN_1_CTRL4, 0x01800880);
+       dim_DI_Wr(DI_MTN_1_CTRL7, 0x0a800480);
+       /* mtn setting */
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) {
+               dim_DI_Wr_reg_bits(DI_MTN_CTRL, 1, 0, 1);
+               dim_DI_Wr(DI_MTN_1_CTRL1, 0x202015);
+       } else {
+               dim_DI_Wr(DI_MTN_1_CTRL1, 0xa0202015);
+       }
+       /* invert chan2 field num */
+       dim_DI_Wr(DI_MTN_CTRL1, (1 << 17) | 2);
+               /* no invert chan2 field num from gxlx*/
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX))
+               dim_DI_Wr(DI_MTN_CTRL1, 2);
+}
+
+static void ei_hw_init(void)
+{
+       /* ei setting */
+       dim_DI_Wr(DI_EI_CTRL0, 0x00ff0100);
+       dim_DI_Wr(DI_EI_CTRL1, 0x5a0a0f2d);
+       dim_DI_Wr(DI_EI_CTRL2, 0x050a0a5d);
+       dim_DI_Wr(DI_EI_CTRL3, 0x80000013);
+       if (is_meson_txlx_cpu()) {
+               dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL, 1, 30, 1);
+               dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL, 1, 31, 1);
+       } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) {
+               dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL_GXLX, 1, 30, 1);
+               dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL_GXLX, 1, 31, 1);
+       }
+}
+
+static void mc_di_param_init(void)
+{
+       dim_DI_Wr(MCDI_CHK_EDGE_GAIN_OFFST, 0x4f6124);
+       dim_DI_Wr(MCDI_LMV_RT, 0x7455);
+       dim_DI_Wr(MCDI_LMV_GAINTHD, 0x6014d409);
+       dim_DI_Wr(MCDI_REL_DET_LPF_MSK_22_30, 0x0a010001);
+       dim_DI_Wr(MCDI_REL_DET_LPF_MSK_31_34, 0x01010101);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               dim_DI_Wr_reg_bits(MCDI_REF_MV_NUM, 2, 0, 2);
+}
+
+void dimh_init_field_mode(unsigned short height)
+{
+       dim_DI_Wr(DIPD_COMB_CTRL0, 0x02400210);
+       dim_DI_Wr(DIPD_COMB_CTRL1, 0x88080808);
+       dim_DI_Wr(DIPD_COMB_CTRL2, 0x41041008);
+       dim_DI_Wr(DIPD_COMB_CTRL3, 0x00008053);
+       dim_DI_Wr(DIPD_COMB_CTRL4, 0x20070002);
+       if (height > 288)
+               dim_DI_Wr(DIPD_COMB_CTRL5, 0x04041020);
+       else
+               dim_DI_Wr(DIPD_COMB_CTRL5, 0x04040804);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX))
+               dim_DI_Wr(DIPD_COMB_CTRL6, 0x00107064);
+       dim_DI_Wr_reg_bits(DI_MC_32LVL0, 16, 0, 8);
+       dim_DI_Wr_reg_bits(DI_MC_22LVL0, 256, 0, 16);
+}
+
+static void mc_pd22_check_irq(void)
+{
+       int cls_2_stl_thd = 1, cls_2_stl = 0;
+       int is_zmv = 0, no_gmv = 0;
+       int i, last_gmv, last_22_flg;
+       int cur_gmv, cur_22_flg;
+       unsigned int reg_val = 0;
+
+       if (!dimp_get(eDI_MP_pd22_flg_calc_en))
+               return;
+
+       is_zmv  = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 1, 1);
+       last_gmv = dim_RDMA_RD_BITS(MCDI_FIELD_MV, 0, 6);
+       last_gmv = last_gmv > 32 ? (32 - last_gmv) : last_gmv;
+       cur_gmv = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 2, 6);
+       cur_gmv = cur_gmv > 32 ? (32 - cur_gmv) : cur_gmv;
+
+       cls_2_stl = abs(cur_gmv) <= cls_2_stl_thd;
+       no_gmv  = (abs(cur_gmv) == 32 && (abs(last_gmv) <= cls_2_stl_thd));
+       for (i = 0; i < 3; i++) {
+               last_22_flg =
+                       dim_RDMA_RD_BITS(MCDI_PD_22_CHK_FLG_CNT, (24 + i), 1);
+               cur_22_flg = dim_RDMA_RD_BITS(MCDI_RO_PD_22_FLG, (24 + i), 1);
+               if ((is_zmv == 1 || cls_2_stl == 1 || no_gmv == 1) &&
+                   last_22_flg == 1 && cur_22_flg == 0) {
+                       dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT,
+                                        last_22_flg, (24 + i), 1);
+                       reg_val = dim_RDMA_RD_BITS(MCDI_PD22_CHK_THD_RT,
+                                                  0, 5) - 1;
+                       dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT,
+                                        reg_val, i * 8, 8);
+               } else {
+                       dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT,
+                                        cur_22_flg, (24 + i), 1);
+                       reg_val =
+                               dim_RDMA_RD_BITS(MCDI_RO_PD_22_FLG, i * 8, 8);
+                       dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT,
+                                        reg_val, i * 8, 8);
+               }
+       }
+}
+
+void dimh_mc_pre_mv_irq(void)
+{
+       unsigned int val1;
+
+       if (dimp_get(eDI_MP_pd22_flg_calc_en) && is_meson_gxlx_cpu()) {
+               mc_pd22_check_irq();
+       } else {
+               val1 = dim_RDMA_RD(MCDI_RO_PD_22_FLG);
+               dim_RDMA_WR(MCDI_PD_22_CHK_FLG_CNT, val1);
+       }
+
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 0, 1);
+       dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 0, 1);
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 1, 2);
+       dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 2, 2);
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 8, 8);
+       dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 8, 8);
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_MOTION_PARADOX_FLG, 0, 16);
+       dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 16, 16);
+
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_RPT_MV, 0, 6);
+       if (val1 == 32) {
+               val1 = 0;
+               dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 15, 1);
+       } else {
+               dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 15, 1);
+       }
+
+       dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 8, 6);
+
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 0, 1);
+       dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 14, 1);
+
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 8, 8);
+       dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 16, 8);
+
+       val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 2, 6);
+       if (val1 == 32) {
+               val1 = 0;
+               dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 14, 1);
+       } else {
+               dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 14, 1);
+       }
+       dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 0, 6);
+
+       val1 = dim_RDMA_RD(MCDI_FIELD_LUMA_AVG_SUM_1);
+       dim_RDMA_WR(MCDI_FIELD_LUMA_AVG_SUM_0, val1);
+
+       val1 = dim_RDMA_RD(MCDI_RO_FLD_LUMA_AVG_SUM);
+       dim_RDMA_WR(MCDI_FIELD_LUMA_AVG_SUM_1, val1);
+}
+
+static void lmvs_init(struct mcinfo_lmv_s *lmvs, unsigned short lmv)
+{
+       lmvs->lock_flag = (lmv >> 14) & 3;
+       lmvs->lmv = (lmv >> 8) & 63;
+       lmvs->lmv = lmvs->lmv > 32 ? (32 - lmvs->lmv) : lmvs->lmv;
+       lmvs->lock_cnt = (lmv & 255);
+}
+
+void dimh_calc_lmv_init(void)
+{
+       if (dimp_get(eDI_MP_lmv_lock_win_en)) {
+               dim_RDMA_WR_BITS(MCDI_REL_DET_LMV_DIF_CHK, 3, 12, 2);
+               dim_RDMA_WR_BITS(MCDI_LMVLCKSTEXT_1, 3, 30, 2);
+       } else {
+               dim_RDMA_WR_BITS(MCDI_REL_DET_LMV_DIF_CHK, 0, 12, 2);
+               dim_RDMA_WR_BITS(MCDI_LMVLCKSTEXT_1, 0, 30, 2);
+       }
+}
+
+static struct mcinfo_lmv_s lines_mv[540];
+
+void dimh_calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
+                              unsigned int mcinfo_size)
+{
+       unsigned short i, top_str, bot_str, top_end, bot_end, j = 0;
+       unsigned short *mcinfo_vadr = NULL, lck_num;
+       unsigned short flg_m1 = 0, flg_i = 0, nLmvLckSt = 0;
+       unsigned short lmv_lckstext[3] = {0, 0, 0}, nLmvLckEd;
+       unsigned short lmv_lckedext[3] = {0, 0, 0}, nLmvLckNum;
+       bool bflg_vmap = false;
+       u8 *tmp;
+
+       /*mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr);*/
+
+       if (!dimp_get(eDI_MP_lmv_lock_win_en))
+               return;
+
+       tmp = dim_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap);
+       if (!tmp) {
+               dim_print("err:dim_vmap failed\n");
+               return;
+       }
+       mcinfo_vadr = (unsigned short *)tmp;
+
+       for (i = 0; i < (vf_height >> 1); i++) {
+               lmvs_init(&lines_mv[i], *(mcinfo_vadr + i));
+               j = i + (vf_height >> 1);
+               lmvs_init(&lines_mv[j], *(mcinfo_vadr + i + 272));
+               if (dimp_get(eDI_MP_pr_mcinfo_cnt) && j < (vf_height - 10) &&
+                   j > (vf_height - dimp_get(eDI_MP_offset_lmv))) {
+                       pr_info("MCINFO[%u]=0x%x\t", j,
+                               *(mcinfo_vadr + i + 272));
+                       if (i % 16 == 0)
+                               pr_info("\n");
+               }
+       }
+       if (bflg_vmap)
+               dim_unmap_phyaddr(tmp);
+
+       /*pr_mcinfo_cnt ? pr_mcinfo_cnt-- : (pr_mcinfo_cnt = 0);*/
+       dimp_get(eDI_MP_pr_mcinfo_cnt) ?
+               dimp_dec(eDI_MP_pr_mcinfo_cnt) :
+               dimp_set(eDI_MP_pr_mcinfo_cnt, 0);
+
+       top_str = 0;
+       top_end = dimp_get(eDI_MP_offset_lmv);
+       i = top_str;
+       j = 0;
+       lck_num = Rd_reg_bits(MCDI_LMVLCKSTEXT_1, 16, 12);
+
+       while (i < top_end) {
+               flg_m1 = (i == top_str) ? 0 :
+                       (lines_mv[i - 1].lock_flag > 0);
+               flg_i  = (i == top_end - 1) ? 0 :
+                       lines_mv[i].lock_flag > 0;
+               if (!flg_m1 && flg_i) {
+                       #if 0
+                       nLmvLckSt = (j == 0) ? i : ((i < (lmv_lckedext[j - 1] +
+                               dimp_get(eDI_MP_lmv_dist))) ?
+                               lmv_lckstext[j - 1] : i);
+                       #else
+                       if (j == 0) {
+                               nLmvLckSt = i;
+                       } else {
+                               if (i < (lmv_lckedext[j - 1] +
+                                        dimp_get(eDI_MP_lmv_dist)))
+                                       nLmvLckSt = lmv_lckstext[j - 1];
+                               else
+                                       nLmvLckSt = i;
+                       }
+                       #endif
+                       j = (nLmvLckSt != i) ? (j - 1) : j;
+               } else if (flg_m1 && !flg_i) {
+                       nLmvLckEd = i;
+                       nLmvLckNum = (nLmvLckEd - nLmvLckSt + 1);
+                       if (nLmvLckNum >= lck_num) {
+                               lmv_lckstext[j] = nLmvLckSt;
+                               lmv_lckedext[j] = nLmvLckEd;
+                               j++;
+                       }
+               }
+               i++;
+               if (j > 2)
+                       break;
+       }
+
+       bot_str = vf_height - dimp_get(eDI_MP_offset_lmv) - 1;
+       bot_end = vf_height;
+       i = bot_str;
+       while (i < bot_end && j < 3) {
+               flg_m1 = (i == bot_str) ? 0 :
+                       (lines_mv[i - 1].lock_flag > 0);
+               flg_i  = (i == bot_end - 1) ? 0 :
+                       lines_mv[i].lock_flag > 0;
+               if (!flg_m1 && flg_i) {
+                       nLmvLckSt = (j == 0) ? i : ((i < (lmv_lckedext[j - 1] +
+                               dimp_get(eDI_MP_lmv_dist))) ?
+                               lmv_lckstext[j - 1] : i);
+                       j = (nLmvLckSt != i) ? (j - 1) : j;
+               } else if (flg_m1 && !flg_i) {
+                       nLmvLckEd = i;
+                       nLmvLckNum = (nLmvLckEd - nLmvLckSt + 1);
+                       if (nLmvLckNum >= lck_num) {
+                               lmv_lckstext[j] = nLmvLckSt;
+                               lmv_lckedext[j] = nLmvLckEd;
+                               j++;
+                       }
+               }
+               i++;
+               if (j > 2)
+                       break;
+       }
+
+       Wr(MCDI_LMVLCKSTEXT_0, lmv_lckstext[1] << 16 | lmv_lckstext[0]);
+       Wr_reg_bits(MCDI_LMVLCKSTEXT_1, lmv_lckstext[2], 0, 12);
+       Wr(MCDI_LMVLCKEDEXT_0, lmv_lckedext[1] << 16 | lmv_lckedext[0]);
+       Wr(MCDI_LMVLCKEDEXT_1, lmv_lckedext[2]);
+}
+
+/*
+ * config pre hold ratio & mif request block len
+ * pass_ratio = (pass_cnt + 1)/(pass_cnt + 1 + hold_cnt + 1)
+ */
+static void pre_hold_block_mode_config(void)
+{
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               dim_DI_Wr(DI_PRE_HOLD, 0);
+               /* go field after 2 lines */
+               dim_DI_Wr(DI_PRE_GL_CTRL,
+                         (0x80000000 | dimp_get(eDI_MP_line_num_pre_frst)));
+       } else if (is_meson_txlx_cpu()) {
+               /* setup pre process ratio to 66.6%*/
+               dim_DI_Wr(DI_PRE_HOLD, (1 << 31) | (1 << 16) | 3);
+               /* block len, after block insert null req to balance reqs */
+               dim_DI_Wr_reg_bits(DI_INP_GEN_REG3, 0, 4, 3);
+               dim_DI_Wr_reg_bits(DI_MEM_GEN_REG3, 0, 4, 3);
+               dim_DI_Wr_reg_bits(DI_CHAN2_GEN_REG3, 0, 4, 3);
+               dim_DI_Wr_reg_bits(DI_IF1_GEN_REG3, 0, 4, 3);
+               dim_DI_Wr_reg_bits(DI_IF2_GEN_REG3, 0, 4, 3);
+               dim_DI_Wr_reg_bits(VD1_IF0_GEN_REG3, 0, 4, 3);
+       } else {
+               dim_DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31);
+       }
+}
+
+/*
+ * ctrl or size related regs configured
+ * in software base on real size and condition
+ */
+static void set_skip_ctrl_size_regs(void)
+{
+       ctrl_regs[0]    = DI_CLKG_CTRL;
+       ctrl_regs[1]    = DI_MTN_1_CTRL1;
+       ctrl_regs[2]    = MCDI_MOTINEN;
+       ctrl_regs[3]    = MCDI_CTRL_MODE;
+       ctrl_regs[4]    = MCDI_MC_CRTL;
+       ctrl_regs[5]    = MCDI_PD_22_CHK_WND0_X;
+       ctrl_regs[6]    = MCDI_PD_22_CHK_WND0_Y;
+       ctrl_regs[7]    = MCDI_PD_22_CHK_WND1_X;
+       ctrl_regs[8]    = MCDI_PD_22_CHK_WND1_Y;
+       ctrl_regs[9]    = NR4_MCNR_LUMA_STAT_LIMTX;
+       ctrl_regs[10]   = NR4_MCNR_LUMA_STAT_LIMTY;
+       ctrl_regs[11]   = NR4_NM_X_CFG;
+       ctrl_regs[12]   = NR4_NM_Y_CFG;
+}
+
+void dim_hw_init_reg(void)
+{
+       unsigned short fifo_size_post = 0x120;/*feijun 08-02*/
+
+       if (is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_sm1_cpu()) {
+               dim_DI_Wr(DI_IF1_LUMA_FIFO_SIZE, fifo_size_post);
+               /* 17f2 is  DI_IF1_luma_fifo_size */
+               dim_DI_Wr(DI_IF2_LUMA_FIFO_SIZE, fifo_size_post);
+               dim_DI_Wr(DI_IF0_LUMA_FIFO_SIZE, fifo_size_post);
+       }
+
+       PR_INF("%s, 0x%x\n", __func__, dim_RDMA_RD(DI_IF0_LUMA_FIFO_SIZE));
+}
+
+void dimh_hw_init(bool pd_enable, bool mc_enable)
+{
+       unsigned short fifo_size_vpp = 0xc0;
+       unsigned short fifo_size_di = 0xc0;
+
+       diext_clk_b_sw(true);
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_sm1_cpu()  ||
+           is_meson_tm2_cpu())
+               dim_top_gate_control(true, true);
+       else if (is_meson_gxl_cpu()     ||
+                is_meson_gxm_cpu()     ||
+                is_meson_gxlx_cpu())
+               dim_DI_Wr(DI_CLKG_CTRL, 0xffff0001);
+       else
+               dim_DI_Wr(DI_CLKG_CTRL, 0x1); /* di no clock gate */
+
+       if (is_meson_txl_cpu()  ||
+           is_meson_txlx_cpu() ||
+           is_meson_gxlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_sm1_cpu()  ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()) {
+               /* vpp fifo max size on txl :128*3=384[0x180] */
+               /* di fifo max size on txl :96*3=288[0x120] */
+               fifo_size_vpp = 0x180;
+               fifo_size_di = 0x120;
+       }
+
+       /*enable lock win, suggestion from vlsi zheng.bao*/
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dimp_set(eDI_MP_lmv_lock_win_en, 0);/*lmv_lock_win_en = 0;*/
+
+       dim_DI_Wr(VD1_IF0_LUMA_FIFO_SIZE, fifo_size_vpp);
+       dim_DI_Wr(VD2_IF0_LUMA_FIFO_SIZE, fifo_size_vpp);
+       /* 1a83 is vd2_if0_luma_fifo_size */
+       dim_DI_Wr(DI_INP_LUMA_FIFO_SIZE,        fifo_size_di);
+       /* 17d8 is DI_INP_luma_fifo_size */
+       dim_DI_Wr(DI_MEM_LUMA_FIFO_SIZE,        fifo_size_di);
+       /* 17e5 is DI_MEM_luma_fifo_size */
+       dim_DI_Wr(DI_IF1_LUMA_FIFO_SIZE,        fifo_size_di);
+       /* 17f2 is  DI_IF1_luma_fifo_size */
+       dim_DI_Wr(DI_IF2_LUMA_FIFO_SIZE,        fifo_size_di);
+       /* 201a is if2 fifo size */
+       dim_DI_Wr(DI_CHAN2_LUMA_FIFO_SIZE, fifo_size_di);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               dim_DI_Wr(DI_IF0_LUMA_FIFO_SIZE, fifo_size_di);
+               dim_DI_Wr(DI_ARB_CTRL, 0);
+       } else {
+               /* enable di all arb */
+               dim_DI_Wr_reg_bits(DI_ARB_CTRL, 0xf0f, 0, 16);
+       }
+       /* 17b3 is DI_chan2_luma_fifo_size */
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_sm1_cpu()  ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()) {
+               dim_pre_gate_control(true, true);
+               dim_post_gate_control(true);
+       }
+
+       pre_hold_block_mode_config();
+       set_skip_ctrl_size_regs();
+       ma_di_init();
+       ei_hw_init();
+       get_ops_nr()->nr_hw_init();
+       if (pd_enable)
+               dimh_init_field_mode(288);
+
+       if (mc_enable)
+               mc_di_param_init();
+       if (is_meson_txlx_cpu() ||
+           is_meson_txhd_cpu() ||
+           is_meson_g12a_cpu() ||
+           is_meson_sm1_cpu()  ||
+           is_meson_g12b_cpu() ||
+           is_meson_tl1_cpu()  ||
+           is_meson_tm2_cpu()) {
+               dim_pre_gate_control(false, true);
+               dim_post_gate_control(false);
+               dim_top_gate_control(false, false);
+       } else if (is_meson_txl_cpu() || is_meson_gxlx_cpu()) {
+               /* di clock div enable for pq load */
+               dim_DI_Wr(DI_CLKG_CTRL, 0x80000000);
+       } else {
+               dim_DI_Wr(DI_CLKG_CTRL, 0x2); /* di clock gate all */
+       }
+
+       diext_clk_b_sw(false);
+
+       /*move from prob*/
+       dim_DI_Wr_reg_bits(MCDI_MC_CRTL, 0, 0, 1);
+}
+
+void dimh_hw_uninit(void)
+{
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
+               get_ops_nr()->nr_gate_control(false);
+}
+
+/*
+ * mtn wr mif, contprd mif, contp2rd mif,
+ * contwr mif config
+ */
+static void set_ma_pre_mif(struct DI_SIM_MIF_s *mtnwr_mif,
+                          struct DI_SIM_MIF_s *contprd_mif,
+                          struct DI_SIM_MIF_s *contp2rd_mif,
+                          struct DI_SIM_MIF_s *contwr_mif,
+                          unsigned short urgent)
+{
+       /* current field mtn canvas index. */
+       dim_RDMA_WR(DI_MTNWR_X,
+                   (mtnwr_mif->start_x << 16)  |
+                   (mtnwr_mif->end_x));
+       dim_RDMA_WR(DI_MTNWR_Y,
+                   (mtnwr_mif->start_y << 16)  |
+                   (mtnwr_mif->end_y));
+       dim_RDMA_WR(DI_MTNWR_CTRL,
+                   mtnwr_mif->canvas_num       |
+                   (urgent << 8));     /* urgent. */
+
+       dim_RDMA_WR(DI_CONTPRD_X,
+                   (contprd_mif->start_x << 16)        |
+                   (contprd_mif->end_x));
+       dim_RDMA_WR(DI_CONTPRD_Y,
+                   (contprd_mif->start_y << 16)        |
+                   (contprd_mif->end_y));
+       dim_RDMA_WR(DI_CONTP2RD_X,
+                   (contp2rd_mif->start_x << 16)       |
+                   (contp2rd_mif->end_x));
+       dim_RDMA_WR(DI_CONTP2RD_Y,
+                   (contp2rd_mif->start_y << 16)       |
+                   (contp2rd_mif->end_y));
+       dim_RDMA_WR(DI_CONTRD_CTRL,
+                   (contprd_mif->canvas_num << 8)      |
+                   (urgent << 16)                      | /* urgent */
+                   contp2rd_mif->canvas_num);
+
+       dim_RDMA_WR(DI_CONTWR_X,
+                   (contwr_mif->start_x << 16) |
+                   (contwr_mif->end_x));
+       dim_RDMA_WR(DI_CONTWR_Y,
+                   (contwr_mif->start_y << 16) |
+                   (contwr_mif->end_y));
+       dim_RDMA_WR(DI_CONTWR_CTRL,
+                   contwr_mif->canvas_num      |
+                   (urgent << 8));/* urgent. */
+}
+
+static void set_ma_pre_mif_g12(struct DI_SIM_MIF_s *mtnwr_mif,
+                              struct DI_SIM_MIF_s *contprd_mif,
+                              struct DI_SIM_MIF_s *contp2rd_mif,
+                              struct DI_SIM_MIF_s *contwr_mif,
+                              unsigned short urgent)
+{
+       dim_RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->start_x, 0, 13);
+       dim_RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->end_x, 16, 13);
+       dim_RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->start_y, 0, 13);
+       dim_RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->end_y, 16, 13);
+       dim_RDMA_WR_BITS(CONTRD_CTRL1, contprd_mif->canvas_num, 16, 8);
+       dim_RDMA_WR_BITS(CONTRD_CTRL1, 2, 8, 2);
+       dim_RDMA_WR_BITS(CONTRD_CTRL1, 0, 0, 3);
+
+       dim_RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->start_x, 0, 13);
+       dim_RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->end_x, 16, 13);
+       dim_RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->start_y, 0, 13);
+       dim_RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->end_y, 16, 13);
+       dim_RDMA_WR_BITS(CONT2RD_CTRL1, contp2rd_mif->canvas_num, 16, 8);
+       dim_RDMA_WR_BITS(CONT2RD_CTRL1, 2, 8, 2);
+       dim_RDMA_WR_BITS(CONT2RD_CTRL1, 0, 0, 3);
+
+       /* current field mtn canvas index. */
+       dim_RDMA_WR_BITS(MTNWR_X, mtnwr_mif->start_x, 16, 13);
+       dim_RDMA_WR_BITS(MTNWR_X, mtnwr_mif->end_x, 0, 13);
+       dim_RDMA_WR_BITS(MTNWR_X, 2, 30, 2);
+       dim_RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->start_y, 16, 13);
+       dim_RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->end_y, 0, 13);
+       dim_RDMA_WR_BITS(MTNWR_CTRL, mtnwr_mif->canvas_num, 0, 8);
+       dim_RDMA_WR_BITS(MTNWR_CAN_SIZE,
+                        (mtnwr_mif->end_y - mtnwr_mif->start_y), 0, 13);
+       dim_RDMA_WR_BITS(MTNWR_CAN_SIZE,
+                        (mtnwr_mif->end_x - mtnwr_mif->start_x), 16, 13);
+
+       dim_RDMA_WR_BITS(CONTWR_X, contwr_mif->start_x, 16, 13);
+       dim_RDMA_WR_BITS(CONTWR_X, contwr_mif->end_x, 0, 13);
+       dim_RDMA_WR_BITS(CONTWR_X, 2, 30, 2);
+       dim_RDMA_WR_BITS(CONTWR_Y, contwr_mif->start_y, 16, 13);
+       dim_RDMA_WR_BITS(CONTWR_Y, contwr_mif->end_y, 0, 13);
+       dim_RDMA_WR_BITS(CONTWR_CTRL, contwr_mif->canvas_num, 0, 8);
+       dim_RDMA_WR_BITS(CONTWR_CAN_SIZE,
+                        (contwr_mif->end_y - contwr_mif->start_y), 0, 13);
+       dim_RDMA_WR_BITS(CONTWR_CAN_SIZE,
+                        (contwr_mif->end_x - contwr_mif->start_x), 16, 13);
+}
+
+static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif,
+                           unsigned short urgent)
+{
+       dim_RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->end_x, 0, 14);
+       dim_RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->start_x, 16, 14);
+       dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->start_y, 16, 13);
+       dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->end_y, 0, 13);
+       /* wr ext en from gxtvbb */
+       dim_RDMA_WR_BITS(DI_NRWR_Y, 1, 15, 1);
+       dim_RDMA_WR_BITS(DI_NRWR_Y, 3, 30, 2);
+
+       dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->bit_mode & 0x1, 14, 1);
+
+       /*fix 1080i crash when di work on low speed*/
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) &&
+           ((nrwr_mif->bit_mode & 0x3) == 0x3)) {
+               dim_RDMA_WR(DI_NRWR_CTRL,
+                           nrwr_mif->canvas_num |
+                           (urgent << 16)       |
+                           3 << 22              |
+                           1 << 24              |
+                           2 << 26              | /*burst_lim 1->2 2->4*/
+                           1 << 30); /* urgent bit 16 */
+       } else {
+               dim_RDMA_WR(DI_NRWR_CTRL,
+                           nrwr_mif->canvas_num |
+                           (urgent << 16)       |
+                           1 << 24              |
+                           2 << 26              | /*burst_lim 1->2 2->4*/
+                           1 << 30);              /* urgent bit 16 */
+       }
+}
+
+void dimh_interrupt_ctrl(unsigned char ma_en,
+                        unsigned char det3d_en, unsigned char nrds_en,
+                        unsigned char post_wr, unsigned char mc_en)
+{
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 17, 1);
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 20, 1);
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, mc_en ? 0 : 3, 22, 2);
+       /* enable nr wr int */
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, 0, 16, 1);
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, post_wr ? 0 : 1, 18, 1);
+       /* mask me interrupt hit abnormal */
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, 1, 21, 1);
+       /* mask hist interrupt */
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, 1, 19, 1);
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, det3d_en ? 0 : 1, 24, 1);
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, nrds_en ? 0 : 1, 25, 1);
+       /* clean all pending interrupt bits */
+       dim_RDMA_WR_BITS(DI_INTR_CTRL, 0xffff, 0, 16);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, 3, 30, 2);
+       else
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, 0, 30, 2);
+}
+
+void dimh_int_ctr(unsigned int set_mod, unsigned char ma_en,
+                 unsigned char det3d_en, unsigned char nrds_en,
+                 unsigned char post_wr, unsigned char mc_en)
+{
+       static unsigned char lst_ma, lst_det3d, lst_nrds, lst_pw, lst_mc;
+
+       if (set_mod == 0) {
+               /*int:*/
+               lst_ma = 1;
+               lst_det3d = 0;
+               lst_nrds = 1;
+               lst_pw = 1;
+               lst_mc = 1;
+               dimh_interrupt_ctrl(lst_ma,
+                                   lst_det3d,
+                                   lst_nrds,
+                                   lst_pw,
+                                   lst_mc);
+               return;
+       }
+
+       if (ma_en != lst_ma) {
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 17, 1);
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 20, 1);
+               lst_ma = ma_en;
+       }
+       if (mc_en != lst_mc) {
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, mc_en ? 0 : 3, 22, 2);
+               lst_mc = mc_en;
+       }
+
+       if (post_wr != lst_pw) {
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, post_wr ? 0 : 1, 18, 1);
+               lst_pw = post_wr;
+       }
+
+       if (det3d_en != lst_det3d) {
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, det3d_en ? 0 : 1, 24, 1);
+               lst_det3d = det3d_en;
+       }
+
+       if (nrds_en != lst_nrds) {
+               dim_RDMA_WR_BITS(DI_INTR_CTRL, nrds_en ? 0 : 1, 25, 1);
+               lst_nrds = nrds_en;
+       }
+}
+
+void dimh_enable_di_pre_aml(
+       struct DI_MIF_s            *di_inp_mif,
+       struct DI_MIF_s            *di_mem_mif,
+       struct DI_MIF_s            *di_chan2_mif,
+       struct DI_SIM_MIF_s    *di_nrwr_mif,
+       struct DI_SIM_MIF_s    *di_mtnwr_mif,
+       struct DI_SIM_MIF_s    *di_contp2rd_mif,
+       struct DI_SIM_MIF_s    *di_contprd_mif,
+       struct DI_SIM_MIF_s    *di_contwr_mif,
+       unsigned char madi_en, unsigned char pre_field_num,
+       unsigned char pre_vdin_link)
+{
+       bool mem_bypass = false, chan2_disable = false;
+       unsigned short nrwr_hsize = 0, nrwr_vsize = 0;
+       unsigned short chan2_hsize = 0, chan2_vsize = 0;
+       unsigned short mem_hsize = 0, mem_vsize = 0;
+
+       set_di_inp_mif(di_inp_mif,
+                      dimp_get(eDI_MP_pre_urgent),
+                      dimp_get(eDI_MP_pre_hold_line));
+       set_di_nrwr_mif(di_nrwr_mif,
+                       dimp_get(eDI_MP_pre_urgent));
+       set_di_mem_mif(di_mem_mif,
+                      dimp_get(eDI_MP_pre_urgent),
+                      dimp_get(eDI_MP_pre_hold_line));
+       set_di_chan2_mif(di_chan2_mif,
+                        dimp_get(eDI_MP_pre_urgent),
+                        dimp_get(eDI_MP_pre_hold_line));
+
+       nrwr_hsize = di_nrwr_mif->end_x -
+               di_nrwr_mif->start_x + 1;
+       nrwr_vsize = di_nrwr_mif->end_y -
+               di_nrwr_mif->start_y + 1;
+       chan2_hsize = di_chan2_mif->luma_x_end0 -
+               di_chan2_mif->luma_x_start0 + 1;
+       chan2_vsize = di_chan2_mif->luma_y_end0 -
+               di_chan2_mif->luma_y_start0 + 1;
+       mem_hsize = di_mem_mif->luma_x_end0 -
+               di_mem_mif->luma_x_start0 + 1;
+       mem_vsize = di_mem_mif->luma_y_end0 -
+               di_mem_mif->luma_y_start0 + 1;
+       if ((chan2_hsize != nrwr_hsize) || (chan2_vsize != nrwr_vsize))
+               chan2_disable = true;
+       if ((mem_hsize != nrwr_hsize) || (mem_vsize != nrwr_vsize))
+               mem_bypass = true;
+       /*
+        * enable&disable contwr txt
+        */
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B))
+               dim_RDMA_WR_BITS(DI_MTN_CTRL, madi_en ? 5 : 0, 29, 3);
+       else
+               dim_RDMA_WR_BITS(DI_MTN_1_CTRL1, madi_en ? 5 : 0, 29, 3);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if (madi_en) {
+                       set_ma_pre_mif_g12(di_mtnwr_mif,
+                                          di_contprd_mif,
+                                          di_contp2rd_mif,
+                                          di_contwr_mif,
+                                          dimp_get(eDI_MP_pre_urgent));
+               } else {
+                       chan2_disable = true;
+               }
+               dim_RDMA_WR_BITS(DI_PRE_GL_THD,
+                                dimp_get(eDI_MP_pre_hold_line), 16, 6);
+               if (dimp_get(eDI_MP_pre_ctrl))
+                       dim_RDMA_WR_BITS(DI_PRE_CTRL,
+                               dimp_get(eDI_MP_pre_ctrl), 0, 29);
+               else
+                       dim_RDMA_WR(DI_PRE_CTRL,
+                                   1                   | /* nr wr en */
+                                   (madi_en << 1)      | /* mtn en */
+                                   (madi_en << 2)      | /* check3:2pulldown*/
+                                   (madi_en << 3)      | /* check2:2pulldown*/
+                                   (1 << 4)            |
+                                   (madi_en << 5)      | /*hist check enable*/
+                               /* hist check  use chan2. */
+                                   (madi_en << 6)      |
+                               /*hist check use data before noise reduction.*/
+                                   ((chan2_disable ? 0 : 1) << 8) |
+                               /* chan 2 enable for 2:2 pull down check.*/
+                               /* line buffer 2 enable */
+                                   ((chan2_disable ? 0 : 1) << 9) |
+                                   (0 << 10)           | /* pre drop first. */
+                                   (1 << 11)           | /* nrds mif enable */
+                                   (0 << 12)           | /* pre viu link */
+                                   (pre_vdin_link << 13)          |
+                               /* pre go line link */
+                                   (pre_vdin_link << 14)          |
+                                   (1 << 21)           | /*invertNRfield num*/
+                                   (1 << 22)           | /* MTN after NR. */
+                                   (0 << 25)           | /* contrd en */
+                                   ((mem_bypass ? 1 : 0) << 28)   |
+                                   pre_field_num << 29);
+       } else {
+               if (madi_en) {
+                       set_ma_pre_mif(di_mtnwr_mif,
+                                      di_contprd_mif,
+                                      di_contp2rd_mif,
+                                      di_contwr_mif,
+                                      dimp_get(eDI_MP_pre_urgent));
+               }
+               dim_RDMA_WR(DI_PRE_CTRL,
+                           1                   /* nr enable */
+                           | (madi_en << 1)    /* mtn_en */
+                           | (madi_en << 2)    /* check 3:2 pulldown */
+                           | (madi_en << 3)    /* check 2:2 pulldown */
+                           | (1 << 4)
+                           | (madi_en << 5)    /* hist check enable */
+                           | (1 << 6)          /* hist check  use chan2. */
+                           | (0 << 7)
+                           /* hist check use data before noise reduction. */
+                           | (madi_en << 8)
+                           /* chan 2 enable for 2:2 pull down check.*/
+                           | (madi_en << 9)    /* line buffer 2 enable */
+                           | (0 << 10)         /* pre drop first. */
+                           | (0 << 11)         /* di pre repeat */
+                           | (0 << 12)         /* pre viu link */
+                           | (pre_vdin_link << 13)
+                           | (pre_vdin_link << 14)     /* pre go line link */
+                           | (dimp_get(eDI_MP_pre_hold_line) << 16)
+                           /* pre hold line number */
+                           | (1 << 22)         /* MTN after NR. */
+                           | (madi_en << 25)   /* contrd en */
+                           | (pre_field_num << 29)     /* pre field number.*/
+                           );
+       }
+}
+
+/*
+ * after g12a, framereset will not reset simple
+ * wr mif of pre such as mtn&cont&mv&mcinfo wr
+ */
+static const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = {
+       {
+               AFBC_ENABLE,
+               AFBC_MODE,
+               AFBC_SIZE_IN,
+               AFBC_DEC_DEF_COLOR,
+               AFBC_CONV_CTRL,
+               AFBC_LBUF_DEPTH,
+               AFBC_HEAD_BADDR,
+               AFBC_BODY_BADDR,
+               AFBC_SIZE_OUT,
+               AFBC_OUT_YSCOPE,
+               AFBC_STAT,
+               AFBC_VD_CFMT_CTRL,
+               AFBC_VD_CFMT_W,
+               AFBC_MIF_HOR_SCOPE,
+               AFBC_MIF_VER_SCOPE,
+               AFBC_PIXEL_HOR_SCOPE,
+               AFBC_PIXEL_VER_SCOPE,
+               AFBC_VD_CFMT_H,
+       },
+       {
+               VD2_AFBC_ENABLE,
+               VD2_AFBC_MODE,
+               VD2_AFBC_SIZE_IN,
+               VD2_AFBC_DEC_DEF_COLOR,
+               VD2_AFBC_CONV_CTRL,
+               VD2_AFBC_LBUF_DEPTH,
+               VD2_AFBC_HEAD_BADDR,
+               VD2_AFBC_BODY_BADDR,
+               VD2_AFBC_OUT_XSCOPE,
+               VD2_AFBC_OUT_YSCOPE,
+               VD2_AFBC_STAT,
+               VD2_AFBC_VD_CFMT_CTRL,
+               VD2_AFBC_VD_CFMT_W,
+               VD2_AFBC_MIF_HOR_SCOPE,
+               VD2_AFBC_MIF_VER_SCOPE,
+               VD2_AFBC_PIXEL_HOR_SCOPE,
+               VD2_AFBC_PIXEL_VER_SCOPE,
+               VD2_AFBC_VD_CFMT_H,
+
+       },
+
+};
+
+#define AFBC_DEC_SEL   (eAFBC_DEC1)
+
+static enum eAFBC_DEC afbc_get_decnub(void)
+{
+       enum eAFBC_DEC sel_dec = eAFBC_DEC0;
+
+       if (is_meson_gxl_cpu())
+               sel_dec = eAFBC_DEC0;
+       else if (is_meson_txlx_cpu())
+               sel_dec = eAFBC_DEC1;
+       else if (is_meson_g12a_cpu())
+               sel_dec = AFBC_DEC_SEL;
+       /* TL1 only have AFBC0 */
+       else if (is_meson_tl1_cpu())
+               sel_dec = eAFBC_DEC0;
+       return sel_dec;
+}
+
+static const unsigned int *afbc_get_regbase(void)
+{
+       return &reg_AFBC[afbc_get_decnub()][0];
+}
+
+bool dimh_afbc_is_supported(void)
+{
+       bool ret = false;
+
+       /*currently support txlx and g12a*/
+       if (is_meson_txlx_cpu() ||
+           is_meson_g12a_cpu()
+               /*|| is_meson_tl1_cpu()*/)
+               ret = false;
+       return ret;
+}
+
+static void afbc_sw_trig(bool  on);
+
+void dimh_enable_afbc_input(struct vframe_s *vf)
+{
+       unsigned int r, u, v, w_aligned, h_aligned;
+       unsigned int out_height = 0;
+       unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0;
+       const unsigned int *reg = afbc_get_regbase();
+
+       if (!dimh_afbc_is_supported())
+               return;
+
+       if ((vf->type & VIDTYPE_COMPRESS)) {
+               /* only reg for the first time*/
+               dimh_afbc_reg_sw(true);
+               afbc_sw_trig(true);
+       } else {
+               afbc_sw_trig(false);
+               return;
+       }
+       w_aligned = round_up((vf->width - 1), 32);
+       h_aligned = round_up((vf->height - 1), 4);
+       r = (3 << 24)   |
+           (10 << 16)  |
+           (1 << 14)   | /*burst1 1*/
+           (vf->bitdepth & BITDEPTH_MASK);
+       if (vf->bitdepth & BITDEPTH_SAVING_MODE)
+               r |= (1 << 28); /* mem_saving_mode */
+       if (vf->type & VIDTYPE_SCATTER)
+               r |= (1 << 29);
+       out_height = h_aligned;
+       if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
+               r |= 0x40;
+               vt_ini_phase = 0xc;
+               out_height = h_aligned >> 1;
+       } else if ((vf->type & VIDTYPE_TYPEMASK) ==
+                       VIDTYPE_INTERLACE_BOTTOM) {
+               r |= 0x80;
+               vt_ini_phase = 0x4;
+               vfmt_rpt_first = 0;
+               out_height = h_aligned >> 1;
+       }
+       dim_RDMA_WR(reg[eAFBC_MODE], r);
+       r = 0x100;
+       /* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420
+        * di does not support yuv444, so for fmt yuv444 di will bypass+
+        */
+       if (is_meson_tl1_cpu()) {
+               if (vf->type & VIDTYPE_VIU_444)
+                       r |= (0 << 12);
+               else if (vf->type & VIDTYPE_VIU_422)
+                       r |= (1 << 12);
+               else
+                       r |= (2 << 12);
+       }
+       dim_RDMA_WR(reg[eAFBC_CONV_CTRL], r);
+       u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3;
+       v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3;
+       dim_RDMA_WR(reg[eAFBC_DEC_DEF_COLOR],
+                   0x3FF00000          | /*Y,bit20+*/
+                   0x80 << (u + 10)    |
+                   0x80 << v);
+       /* chroma formatter */
+       dim_RDMA_WR(reg[eAFBC_VD_CFMT_CTRL],
+                   (1 << 21)                   | /* HFORMATTER_YC_RATIO_2_1 */
+                   (1 << 20)                   | /* HFORMATTER_EN */
+                   (vfmt_rpt_first << 16)      | /* VFORMATTER_RPTLINE0_EN */
+                   (vt_ini_phase << 8)         |
+                   (16 << 1)                   | /* VFORMATTER_PHASE_BIT */
+                   0);                           /* different with inp */
+
+       dim_RDMA_WR(reg[eAFBC_VD_CFMT_W],
+                   (w_aligned << 16) | (w_aligned / 2));
+       dim_RDMA_WR(reg[eAFBC_MIF_HOR_SCOPE],
+                   (0 << 16) | ((w_aligned >> 5) - 1));
+       dim_RDMA_WR(reg[eAFBC_MIF_VER_SCOPE],
+                   (0 << 16) | ((h_aligned >> 2) - 1));
+
+       dim_RDMA_WR(reg[eAFBC_PIXEL_HOR_SCOPE],
+                   (0 << 16) | (vf->width - 1));
+       dim_RDMA_WR(reg[eAFBC_VD_CFMT_H], out_height);
+
+       dim_RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE],
+                   0 << 16 | (vf->height - 1));
+       dim_RDMA_WR(reg[eAFBC_SIZE_IN], h_aligned | w_aligned << 16);
+       dim_RDMA_WR(reg[eAFBC_SIZE_OUT], out_height | w_aligned << 16);
+       dim_RDMA_WR(reg[eAFBC_HEAD_BADDR], vf->compHeadAddr >> 4);
+       dim_RDMA_WR(reg[eAFBC_BODY_BADDR], vf->compBodyAddr >> 4);
+}
+
+static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on)     /*g12a*/
+{
+       unsigned int reg_ctrl;
+
+       if (decsel == eAFBC_DEC0)
+               reg_ctrl = VD1_AFBCD0_MISC_CTRL;
+       else
+               reg_ctrl = VD2_AFBCD1_MISC_CTRL;
+       if (on)
+               dim_RDMA_WR_BITS(reg_ctrl, 0, 0, 8);
+       else
+               dim_RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8);
+}
+
+static void afbcx_sw(bool on)  /*g12a*/
+{
+       unsigned int tmp;
+       unsigned int mask;
+       unsigned int reg_ctrl, reg_en;
+       enum eAFBC_DEC dec_sel;
+
+       dec_sel = afbc_get_decnub();
+
+       if (dec_sel == eAFBC_DEC0) {
+               reg_ctrl = VD1_AFBCD0_MISC_CTRL;
+               reg_en = AFBC_ENABLE;
+       } else {
+               reg_ctrl = VD2_AFBCD1_MISC_CTRL;
+               reg_en = VD2_AFBC_ENABLE;
+       }
+
+       mask = (3 << 20)  | (1 << 12) | (1 << 9);
+       /*clear*/
+       tmp = dim_RDMA_RD(reg_ctrl) & (~mask);
+
+       if (on) {
+               tmp = tmp               |
+                       (2 << 20)       |
+                       (1 << 12)       |
+                       (1 << 9);
+               dim_RDMA_WR(reg_ctrl, tmp);
+               dim_RDMA_WR_BITS(VD2_AFBCD1_MISC_CTRL,
+                                (reg_ctrl == VD1_AFBCD0_MISC_CTRL) ? 0 : 1,
+                                8, 1);
+               dim_RDMA_WR(reg_en, 0x1600);
+               dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1);
+               /*TL1 add mem control bit */
+               if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+                       dim_RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 1, 22, 1);
+       } else {
+               dim_RDMA_WR(reg_ctrl, tmp);
+               dim_RDMA_WR(reg_en, 0x1600);
+               dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1);
+               if (is_meson_tl1_cpu() || is_meson_tm2_cpu())
+                       dim_RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 0, 22, 1);
+       }
+#if 0
+       PR_INF("%s,on[%d],CTRL[0x%x],en[0x%x]\n", __func__, on,
+              dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL),
+              dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL));
+#endif
+}
+
+static void afbc_sw_old(bool on)/*txlx*/
+{
+       enum eAFBC_DEC dec_sel;
+       unsigned int reg_en;
+
+       dec_sel = afbc_get_decnub();
+
+       if (dec_sel == eAFBC_DEC0) {
+               /*reg_ctrl = VD1_AFBCD0_MISC_CTRL;*/
+               reg_en = AFBC_ENABLE;
+       } else {
+               /*reg_ctrl = VD2_AFBCD1_MISC_CTRL;*/
+               reg_en = VD2_AFBC_ENABLE;
+       }
+
+       if (on) {
+               /* DI inp(current data) switch to AFBC */
+               if (dim_RDMA_RD_BITS(VIU_MISC_CTRL0, 29, 1) != 1)
+                       dim_RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 29, 1);
+               if (dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 1)
+                       dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1);
+               if (dim_RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 1)
+                       dim_RDMA_WR_BITS(VIU_MISC_CTRL1, 1, 0, 1);
+               if (dec_sel == eAFBC_DEC0) {
+                       /*gxl only?*/
+                       if (dim_RDMA_RD_BITS(VIU_MISC_CTRL0, 19, 1) != 1)
+                               dim_RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 19, 1);
+               }
+               if (dim_RDMA_RD(reg_en) != 0x1600)
+                       dim_RDMA_WR(reg_en, 0x1600);
+
+       } else {
+               dim_RDMA_WR(reg_en, 0);
+               /* afbc to vpp(replace vd1) enable */
+
+               if (dim_RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 0 ||
+                   dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 0) {
+                       dim_RDMA_WR_BITS(VIU_MISC_CTRL1, 0, 0, 1);
+                       dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1);
+               }
+       }
+}
+
+static bool afbc_is_used(void)
+{
+       bool ret = false;
+
+       if (dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) == 1)
+               ret = true;
+
+       /*dim_print("%s:%d\n",__func__,ret);*/
+
+       return ret;
+}
+
+static void afbc_power_sw(bool on)
+{
+       /*afbc*/
+       enum eAFBC_DEC dec_sel;
+       unsigned int vpu_sel;
+
+       dec_sel = afbc_get_decnub();
+       if (dec_sel == eAFBC_DEC0)
+               vpu_sel = VPU_AFBC_DEC;
+       else
+               vpu_sel = VPU_AFBC_DEC1;
+
+       ext_ops.switch_vpu_mem_pd_vmod(vpu_sel, on);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               afbcx_power_sw(dec_sel, on);
+}
+
+static int afbc_reg_unreg_flag;
+void dimh_afbc_reg_sw(bool on)
+{
+       if (!dimh_afbc_is_supported())
+               return;
+
+       if (on && (!afbc_reg_unreg_flag)) {
+               afbc_power_sw(true);
+               afbc_reg_unreg_flag = 1;
+       }
+       if ((!on) && afbc_reg_unreg_flag) {
+               afbc_sw_trig(false);
+               afbc_power_sw(false);
+               afbc_reg_unreg_flag = 0;
+       }
+}
+
+static void afbc_sw(bool on)
+{
+       if (is_meson_gxl_cpu() || is_meson_txlx_cpu())
+               afbc_sw_old(on);
+       else
+               afbcx_sw(on);
+}
+
+static void afbc_sw_trig(bool  on)
+{
+       afbc_sw(on);
+}
+
+static void afbc_input_sw(bool on)
+{
+       const unsigned int *reg = afbc_get_regbase();
+       unsigned int reg_AFBC_ENABLE;
+
+       if (!dimh_afbc_is_supported())
+               return;
+
+       reg_AFBC_ENABLE = reg[eAFBC_ENABLE];
+
+       /*dim_print("%s:0x%x\n", __func__,reg_AFBC_ENABLE);*/
+       if (on)
+               dim_RDMA_WR_BITS(reg_AFBC_ENABLE, 1, 8, 1);
+       else
+               dim_RDMA_WR_BITS(reg_AFBC_ENABLE, 0, 8, 1);
+}
+
+void dimh_enable_mc_di_pre_g12(struct DI_MC_MIF_s *mcinford_mif,
+                              struct DI_MC_MIF_s *mcinfowr_mif,
+                              struct DI_MC_MIF_s *mcvecwr_mif,
+                              unsigned char mcdi_en)
+{
+       dim_RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en ? 3 : 0), 0, 2);
+       if (is_meson_g12a_cpu() ||
+           is_meson_g12b_cpu() ||
+           is_meson_sm1_cpu())
+               dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfef7ff : 0));
+       else
+               dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfff7ff : 0));
+
+       dim_RDMA_WR_BITS(DI_PRE_CTRL, (mcdi_en ? 3 : 0), 16, 2);
+
+       dim_RDMA_WR_BITS(MCINFRD_SCOPE_X, mcinford_mif->size_x, 16, 13);
+       dim_RDMA_WR_BITS(MCINFRD_SCOPE_Y, mcinford_mif->size_y, 16, 13);
+       dim_RDMA_WR_BITS(MCINFRD_CTRL1, mcinford_mif->canvas_num, 16, 8);
+       dim_RDMA_WR_BITS(MCINFRD_CTRL1, 2, 0, 3);
+
+       dim_RDMA_WR_BITS(MCVECWR_X, mcvecwr_mif->size_x, 0, 13);
+       dim_RDMA_WR_BITS(MCVECWR_Y, mcvecwr_mif->size_y, 0, 13);
+       dim_RDMA_WR_BITS(MCVECWR_CTRL, mcvecwr_mif->canvas_num, 0, 8);
+       dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_y, 0, 13);
+       dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_x, 16, 13);
+
+       dim_RDMA_WR_BITS(MCINFWR_X, mcinfowr_mif->size_x, 0, 13);
+       dim_RDMA_WR_BITS(MCINFWR_Y, mcinfowr_mif->size_y, 0, 13);
+       dim_RDMA_WR_BITS(MCINFWR_CTRL, mcinfowr_mif->canvas_num, 0, 8);
+       dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_y, 0, 13);
+       dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_x, 16, 13);
+}
+
+void dimh_enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif,
+                          struct DI_MC_MIF_s *di_mcinfowr_mif,
+                          struct DI_MC_MIF_s *di_mcvecwr_mif,
+                          unsigned char mcdi_en)
+{
+       bool me_auto_en = true;
+       unsigned int ctrl_mode = 0;
+
+       dim_RDMA_WR_BITS(DI_MTN_CTRL1, (mcdi_en ? 3 : 0), 12, 2);
+       if (is_meson_gxlx_cpu() || is_meson_txhd_cpu())
+               me_auto_en = false;
+
+       ctrl_mode = (me_auto_en ? 0x1bfff7ff : 0x1bfe37ff);
+       dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? ctrl_mode : 0));
+       dim_RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en ? 3 : 0), 0, 2);
+
+       dim_RDMA_WR(MCDI_MCVECWR_X, di_mcvecwr_mif->size_x);
+       dim_RDMA_WR(MCDI_MCVECWR_Y, di_mcvecwr_mif->size_y);
+       dim_RDMA_WR(MCDI_MCINFOWR_X, di_mcinfowr_mif->size_x);
+       dim_RDMA_WR(MCDI_MCINFOWR_Y, di_mcinfowr_mif->size_y);
+
+       dim_RDMA_WR(MCDI_MCINFORD_X, di_mcinford_mif->size_x);
+       dim_RDMA_WR(MCDI_MCINFORD_Y, di_mcinford_mif->size_y);
+       dim_RDMA_WR(MCDI_MCVECWR_CANVAS_SIZE,
+                   (di_mcvecwr_mif->size_x << 16) + di_mcvecwr_mif->size_y);
+       dim_RDMA_WR(MCDI_MCINFOWR_CANVAS_SIZE,
+                   (di_mcinfowr_mif->size_x << 16) + di_mcinfowr_mif->size_y);
+       dim_RDMA_WR(MCDI_MCINFORD_CANVAS_SIZE,
+                   (di_mcinford_mif->size_x << 16) + di_mcinford_mif->size_y);
+
+       dim_RDMA_WR(MCDI_MCVECWR_CTRL,
+                   di_mcvecwr_mif->canvas_num  |
+                   (0 << 14)                   | /* sync latch en */
+                   (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */
+                   (1 << 12)                   | /*enable reset by frame rst*/
+                   (0x4031 << 16));
+       dim_RDMA_WR(MCDI_MCINFOWR_CTRL,
+                   di_mcinfowr_mif->canvas_num |
+                   (0 << 14)                   | /* sync latch en */
+                   (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */
+                   (1 << 12)                   | /*enable reset by frame rst*/
+                   (0x4042 << 16));
+       dim_RDMA_WR(MCDI_MCINFORD_CTRL,
+                   di_mcinford_mif->canvas_num |
+                   (0 << 10)                   |  /* sync latch en */
+                   (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */
+                   (1 << 9)                    | /*enable reset by frame rst*/
+                   (0x42 << 16));
+}
+
+void dimh_enable_mc_di_post_g12(struct DI_MC_MIF_s *mcvecrd_mif,
+                               int urgent, bool reverse, int invert_mv)
+{
+       unsigned int end_x;
+
+       dim_VSYNC_WR_MPEG_REG(MCVECRD_CTRL1,
+                             mcvecrd_mif->canvas_num << 16     |
+                             2 << 8                            |
+                             (reverse ? 3 : 0) << 4            |
+                             2);
+       end_x = mcvecrd_mif->size_x + mcvecrd_mif->start_x;
+       dim_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_X,
+                             mcvecrd_mif->start_x      |
+                             end_x << 16);
+       dim_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_Y,
+                             (reverse ? 1 : 0) << 30   |
+                             mcvecrd_mif->start_y      |
+                             mcvecrd_mif->end_y << 16);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL2, urgent, 16, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcvecrd_mif->vecrd_offset,
+                                  12, 3);
+       if (mcvecrd_mif->blend_en) {
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                          dimp_get(eDI_MP_mcen_mode), 0, 2);
+               if (!di_cfg_top_get(eDI_CFG_ref_2)) {
+                       /*(!dimp_get(eDI_MP_post_wr_en)) {*/
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 3, 18, 2);
+               } else {/*OTT-3210*/
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2);
+               }
+       } else {
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1);
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2);
+       }
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                  dimp_get(eDI_MP_mcuv_en), 10, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                  invert_mv, 17, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                  dimp_get(eDI_MP_mcdebug_mode), 2, 3);
+}
+
+void dimh_enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif,
+                           int urgent, bool reverse, int invert_mv)
+{
+       di_mcvecrd_mif->size_y =
+                       (di_mcvecrd_mif->end_y - di_mcvecrd_mif->start_y + 1);
+       dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_X,
+                             (reverse ? 1 : 0) << 30 |
+                             di_mcvecrd_mif->start_x << 16 |
+                             (di_mcvecrd_mif->size_x +
+                             di_mcvecrd_mif->start_x));
+       dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_Y,
+                             (reverse ? 1 : 0) << 30           |
+                             di_mcvecrd_mif->start_y << 16     |
+                             di_mcvecrd_mif->end_y);
+       dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CANVAS_SIZE,
+                             (di_mcvecrd_mif->size_x << 16) |
+                             di_mcvecrd_mif->size_y);
+       dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CTRL,
+                             di_mcvecrd_mif->canvas_num        |
+                             (urgent << 8)             | /* urgent */
+                             (1 << 9)                  | /* canvas enable */
+                             (0 << 10)                 |
+                             (0x31 << 16));
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, di_mcvecrd_mif->vecrd_offset,
+                                  12, 3);
+       if (di_mcvecrd_mif->blend_en)
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                          dimp_get(eDI_MP_mcen_mode), 0, 2);
+       else
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                          dimp_get(eDI_MP_mcuv_en), 10, 1);
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1);
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                  invert_mv, 17, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                  3, 18, 2);
+               }
+       } else
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                          dimp_get(eDI_MP_mcuv_en), 9, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                  dimp_get(eDI_MP_mcdebug_mode), 2, 3);
+}
+
+static void set_di_inp_fmt_more(unsigned int repeat_l0_en,
+                               int hz_yc_ratio,                /* 2bit */
+                               int hz_ini_phase,               /* 4bit */
+                               int vfmt_en,
+                               int vt_yc_ratio,                /* 2bit */
+                               int vt_ini_phase,               /* 4bit */
+                               int y_length,
+                               int c_length,
+                               int hz_rpt      /* 1bit */
+               )
+{
+       int hfmt_en = 1, nrpt_phase0_en = 0;
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_RDMA_WR(DI_INP_FMT_CTRL,
+                   (hz_rpt << 28)              | /* hz rpt pixel */
+                   (hz_ini_phase << 24)        | /* hz ini phase */
+                   (0 << 23)                   | /* repeat p0 enable */
+                   (hz_yc_ratio << 21)         | /* hz yc ratio */
+                   (hfmt_en << 20)             | /* hz enable */
+                   (nrpt_phase0_en << 17)      | /* nrpt_phase0 enable */
+                   (repeat_l0_en << 16)        | /* repeat l0 enable */
+                   (0 << 12)                   | /* skip line num */
+                   (vt_ini_phase << 8)         | /* vt ini phase */
+                   (vt_phase_step << 1)        | /* vt phase step (3.4) */
+                   (vfmt_en << 0)                /* vt enable */
+                   );
+
+       dim_RDMA_WR(DI_INP_FMT_W,
+                   (y_length << 16) |  /* hz format width */
+                   (c_length << 0)     /* vt format width */
+                   );
+}
+
+static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line)
+{
+       unsigned int bytes_per_pixel;
+       unsigned int demux_mode;
+       unsigned int chro_rpt_lastl_ctrl, vfmt_rpt_first = 0;
+       unsigned int luma0_rpt_loop_start;
+       unsigned int luma0_rpt_loop_end;
+       unsigned int luma0_rpt_loop_pat;
+       unsigned int chroma0_rpt_loop_start;
+       unsigned int chroma0_rpt_loop_end;
+       unsigned int chroma0_rpt_loop_pat;
+       unsigned int vt_ini_phase = 0;
+       unsigned int reset_on_gofield;
+
+       if (mif->set_separate_en != 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = mif->src_prog ? 0 : 1;
+               chroma0_rpt_loop_end = mif->src_prog ? 0 : 1;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = mif->src_prog ? 0 : 0x80;
+
+               vfmt_rpt_first = 1;
+               if (mif->output_field_num == 0)
+                       vt_ini_phase = 0xe;
+               else
+                       vt_ini_phase = 0xa;
+
+               if (mif->src_prog) {
+                       if (mif->output_field_num == 0) {
+                               vt_ini_phase = 0xc;
+                       } else {
+                               vt_ini_phase = 0x4;
+                               vfmt_rpt_first = 0;
+                       }
+               }
+
+       } else if (mif->set_separate_en != 0 && mif->src_field_mode == 0) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x0;
+               chroma0_rpt_loop_pat = 0x0;
+       } else if (mif->set_separate_en == 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = 1;
+               chroma0_rpt_loop_end = 1;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = 0x80;
+       } else {
+               chro_rpt_lastl_ctrl = 0;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x00;
+               chroma0_rpt_loop_pat = 0x00;
+       }
+
+       bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+       demux_mode = mif->video_mode;
+
+       /* ---------------------- */
+       /* General register */
+       /* ---------------------- */
+       reset_on_gofield = 1;/* default enable according to vlsi */
+       dim_RDMA_WR(DI_INP_GEN_REG,
+                   (reset_on_gofield << 29)    |
+                   (urgent << 28)              | /* chroma urgent bit */
+                   (urgent << 27)              | /* luma urgent bit. */
+                   (1 << 25)                   | /* no dummy data. */
+                   (hold_line << 19)           | /* hold lines */
+                   (1 << 18)                   | /* push dummy pixel */
+                   (demux_mode << 16)          | /* demux_mode */
+                   (bytes_per_pixel << 14)     |
+                   (1 << 12)                   | /*burst_size_cr*/
+                   (1 << 10)                   | /*burst_size_cb*/
+                   (3 << 8)                    | /*burst_size_y*/
+                   (chro_rpt_lastl_ctrl << 6)  |
+                   ((mif->set_separate_en != 0) << 1) |
+                   (0 << 0)/* cntl_enable */
+                   );
+       if (mif->set_separate_en == 2) {
+               /* Enable NV12 Display */
+               dim_RDMA_WR_BITS(DI_INP_GEN_REG2, 1, 0, 1);
+       } else {
+               dim_RDMA_WR_BITS(DI_INP_GEN_REG2, 0, 0, 1);
+       }
+
+       dim_RDMA_WR_BITS(DI_INP_GEN_REG3, mif->bit_mode & 0x3, 8, 2);
+       dim_RDMA_WR(DI_INP_CANVAS0,
+                   (mif->canvas0_addr2 << 16)  | /* cntl_canvas0_addr2 */
+                   (mif->canvas0_addr1 << 8)   | /* cntl_canvas0_addr1 */
+                   (mif->canvas0_addr0 << 0)     /* cntl_canvas0_addr0 */
+       );
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_INP_LUMA_X0, (mif->luma_x_end0 << 16) |
+                       /* cntl_luma_x_end0 */
+                       (mif->luma_x_start0 << 0)/* cntl_luma_x_start0 */
+               );
+       dim_RDMA_WR(DI_INP_LUMA_Y0, (mif->luma_y_end0 << 16) |
+                       /* cntl_luma_y_end0 */
+                       (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */
+               );
+       dim_RDMA_WR(DI_INP_CHROMA_X0, (mif->chroma_x_end0 << 16) |
+                       (mif->chroma_x_start0 << 0));
+       dim_RDMA_WR(DI_INP_CHROMA_Y0, (mif->chroma_y_end0 << 16) |
+                  (mif->chroma_y_start0 << 0));
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_INP_RPT_LOOP,
+                   (0 << 28) |
+                   (0 << 24) |
+                   (0 << 20) |
+                   (0 << 16) |
+                   (chroma0_rpt_loop_start << 12)      |
+                   (chroma0_rpt_loop_end << 8)         |
+                   (luma0_rpt_loop_start << 4)         |
+                   (luma0_rpt_loop_end << 0)
+                   );
+
+       dim_RDMA_WR(DI_INP_LUMA0_RPT_PAT, luma0_rpt_loop_pat);
+       dim_RDMA_WR(DI_INP_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat);
+
+       /* Dummy pixel value */
+       dim_RDMA_WR(DI_INP_DUMMY_PIXEL, 0x00808000);
+       if ((mif->set_separate_en != 0)) {/* 4:2:0 block mode.*/
+               set_di_inp_fmt_more(vfmt_rpt_first,/* hfmt_en */
+                                   1,/* hz_yc_ratio */
+                                   0,/* hz_ini_phase */
+                                   1,/* vfmt_en */
+                                   mif->src_prog ? 0 : 1,/* vt_yc_ratio */
+                                   vt_ini_phase,/* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   /* y_length */
+                               mif->chroma_x_end0 - mif->chroma_x_start0 + 1,
+                                   /* c length */
+                                   0); /* hz repeat. */
+       } else {
+               set_di_inp_fmt_more(vfmt_rpt_first,     /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   0,  /* vfmt_en */
+                                   0,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   ((mif->luma_x_end0 >> 1) -
+                                       (mif->luma_x_start0 >> 1) + 1),
+                                   0); /* hz repeat. */
+       }
+}
+
+static void set_di_mem_fmt_more(int hfmt_en,
+                               int hz_yc_ratio,        /* 2bit */
+                               int hz_ini_phase,       /* 4bit */
+                               int vfmt_en,
+                               int vt_yc_ratio,        /* 2bit */
+                               int vt_ini_phase,       /* 4bit */
+                               int y_length,
+                               int c_length,
+                               int hz_rpt      /* 1bit */
+               )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_RDMA_WR(DI_MEM_FMT_CTRL,
+                   (hz_rpt << 28)              | /* hz rpt pixel */
+                   (hz_ini_phase << 24)        | /* hz ini phase */
+                   (0 << 23)                   | /* repeat p0 enable */
+                   (hz_yc_ratio << 21)         | /* hz yc ratio */
+                   (hfmt_en << 20)             | /* hz enable */
+                   (1 << 17)                   | /* nrpt_phase0 enable */
+                   (0 << 16)                   | /* repeat l0 enable */
+                   (0 << 12)                   | /* skip line num */
+                   (vt_ini_phase << 8)         | /* vt ini phase */
+                   (vt_phase_step << 1)        | /* vt phase step (3.4) */
+                   (vfmt_en << 0)              /* vt enable */
+                   );
+
+       dim_RDMA_WR(DI_MEM_FMT_W,
+                   (y_length << 16) |  /* hz format width */
+                   (c_length << 0)     /* vt format width */
+                   );
+}
+
+static void set_di_chan2_fmt_more(int hfmt_en,
+                                 int hz_yc_ratio,/* 2bit */
+                                 int hz_ini_phase,/* 4bit */
+                                 int vfmt_en,
+                                 int vt_yc_ratio,/* 2bit */
+                                 int vt_ini_phase,/* 4bit */
+                                 int y_length,
+                                 int c_length,
+                                 int hz_rpt    /* 1bit */
+                                 )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_RDMA_WR(DI_CHAN2_FMT_CTRL,
+                   (hz_rpt << 28)              | /* hz rpt pixel */
+                   (hz_ini_phase << 24)        | /* hz ini phase */
+                   (0 << 23)                   | /* repeat p0 enable */
+                   (hz_yc_ratio << 21)         | /* hz yc ratio */
+                   (hfmt_en << 20)             | /* hz enable */
+                   (1 << 17)                   | /* nrpt_phase0 enable */
+                   (0 << 16)                   | /* repeat l0 enable */
+                   (0 << 12)                   | /* skip line num */
+                   (vt_ini_phase << 8)         | /* vt ini phase */
+                   (vt_phase_step << 1)        | /* vt phase step (3.4) */
+                   (vfmt_en << 0)              /* vt enable */
+                   );
+
+       dim_RDMA_WR(DI_CHAN2_FMT_W, (y_length << 16) | /* hz format width */
+                                       (c_length << 0) /* vt format width */
+                               );
+}
+
+static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line)
+{
+       unsigned int bytes_per_pixel;
+       unsigned int demux_mode;
+       unsigned int chro_rpt_lastl_ctrl;
+       unsigned int luma0_rpt_loop_start;
+       unsigned int luma0_rpt_loop_end;
+       unsigned int luma0_rpt_loop_pat;
+       unsigned int chroma0_rpt_loop_start;
+       unsigned int chroma0_rpt_loop_end;
+       unsigned int chroma0_rpt_loop_pat;
+       unsigned int reset_on_gofield;
+
+       if (mif->set_separate_en != 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = 1;
+               chroma0_rpt_loop_end = 1;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = 0x80;
+       } else if (mif->set_separate_en != 0 && mif->src_field_mode == 0) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x0;
+               chroma0_rpt_loop_pat = 0x0;
+       } else if (mif->set_separate_en == 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = 0x00;
+       } else {
+               chro_rpt_lastl_ctrl = 0;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x00;
+               chroma0_rpt_loop_pat = 0x00;
+       }
+
+       bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+       demux_mode = mif->video_mode;
+
+       /* ---------------------- */
+       /* General register */
+       /* ---------------------- */
+       reset_on_gofield = 1;/* default enable according to vlsi */
+       dim_RDMA_WR(DI_MEM_GEN_REG,
+                   (reset_on_gofield << 29)    | /* reset on go field */
+                   (urgent << 28)              | /* urgent bit. */
+                   (urgent << 27)              | /* urgent bit. */
+                   (1 << 25)                   | /* no dummy data. */
+                   (hold_line << 19)           | /* hold lines */
+                   (1 << 18)                   | /* push dummy pixel */
+                   (demux_mode << 16)          | /* demux_mode */
+                   (bytes_per_pixel << 14)     |
+                   (1 << 12)                   | /*burst_size_cr*/
+                   (1 << 10)                   | /*burst_size_cb*/
+                   (3 << 8)                    | /*burst_size_y*/
+                   (chro_rpt_lastl_ctrl << 6)  |
+                   ((mif->set_separate_en != 0) << 1)  |
+                   (0 << 0)                    /* cntl_enable */
+                   );
+       if (mif->set_separate_en == 2) {
+               /* Enable NV12 Display */
+               dim_RDMA_WR_BITS(DI_MEM_GEN_REG2, 1, 0, 1);
+       } else {
+               dim_RDMA_WR_BITS(DI_MEM_GEN_REG2, 0, 0, 1);
+       }
+       dim_RDMA_WR_BITS(DI_MEM_GEN_REG3, mif->bit_mode & 0x3, 8, 2);
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_MEM_CANVAS0,
+                   (mif->canvas0_addr2 << 16)  |
+                   /* cntl_canvas0_addr2 */
+                   (mif->canvas0_addr1 << 8)   |
+                   (mif->canvas0_addr0 << 0));
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_MEM_LUMA_X0,
+                   (mif->luma_x_end0 << 16) |
+                   (mif->luma_x_start0 << 0) /* cntl_luma_x_start0 */
+               );
+       dim_RDMA_WR(DI_MEM_LUMA_Y0,
+                   (mif->luma_y_end0 << 16) |
+                   (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */
+               );
+       dim_RDMA_WR(DI_MEM_CHROMA_X0,
+                   (mif->chroma_x_end0 << 16) |
+                   (mif->chroma_x_start0 << 0)
+               );
+       dim_RDMA_WR(DI_MEM_CHROMA_Y0,
+                   (mif->chroma_y_end0 << 16) |
+                   (mif->chroma_y_start0 << 0)
+               );
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_MEM_RPT_LOOP, (0 << 28) |
+                                       (0      << 24) |
+                                       (0      << 20) |
+                                       (0        << 16) |
+                                       (chroma0_rpt_loop_start << 12) |
+                                       (chroma0_rpt_loop_end << 8) |
+                                       (luma0_rpt_loop_start << 4) |
+                                       (luma0_rpt_loop_end << 0)
+               );
+
+       dim_RDMA_WR(DI_MEM_LUMA0_RPT_PAT, luma0_rpt_loop_pat);
+       dim_RDMA_WR(DI_MEM_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat);
+
+       /* Dummy pixel value */
+       dim_RDMA_WR(DI_MEM_DUMMY_PIXEL, 0x00808000);
+       if ((mif->set_separate_en != 0)) {/* 4:2:0 block mode.*/
+               set_di_mem_fmt_more(
+                                   1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   1,  /* vfmt_en */
+                                   1,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                       mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                               /* y_length */
+                       mif->chroma_x_end0 - mif->chroma_x_start0 + 1,
+                                               /* c length */
+                                               0);     /* hz repeat. */
+       } else {
+               set_di_mem_fmt_more(1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   0,  /* vfmt_en */
+                                   0,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   ((mif->luma_x_end0 >> 1)
+                                       - (mif->luma_x_start0 >> 1) + 1),
+                                   0); /* hz repeat. */
+       }
+}
+
+static void set_di_if0_fmt_more(int hfmt_en,
+                               int hz_yc_ratio,                /* 2bit */
+                               int hz_ini_phase,               /* 4bit */
+                               int vfmt_en,
+                               int vt_yc_ratio,                /* 2bit */
+                               int vt_ini_phase,               /* 4bit */
+                               int y_length,
+                               int c_length,
+                               int hz_rpt                      /* 1bit */
+                               )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL,
+                             (hz_rpt << 28)            | /* hz rpt pixel */
+                             (hz_ini_phase << 24)      | /* hz ini phase */
+                             (0 << 23)                 | /* repeat p0 enable*/
+                             (hz_yc_ratio << 21)       | /* hz yc ratio */
+                             (hfmt_en << 20)           | /* hz enable */
+                             (1 << 17)                 | /* nrpt_phase0 en*/
+                             (0 << 16)                 | /* repeat l0 en*/
+                             (0 << 12)                 | /* skip line num */
+                             (vt_ini_phase << 8)       | /* vt ini phase */
+                             (vt_phase_step << 1)      | /*vt phase step(3.4*/
+                             (vfmt_en << 0)            /* vt enable */
+                             );
+
+       dim_VSYNC_WR_MPEG_REG(VIU_VD1_FMT_W,
+                             (y_length << 16) |        /* hz format width */
+                             (c_length << 0)           /* vt format width */
+                                       );
+}
+
+static void set_di_if1_fmt_more(int hfmt_en,
+                               int hz_yc_ratio,/* 2bit */
+                               int hz_ini_phase,/* 4bit */
+                               int vfmt_en,
+                               int vt_yc_ratio,/* 2bit */
+                               int vt_ini_phase,/* 4bit */
+                               int y_length,
+                               int c_length,
+                               int hz_rpt      /* 1bit */
+                               )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_FMT_CTRL,
+                             (hz_rpt << 28)            /* hz rpt pixel */
+                             | (hz_ini_phase << 24)    /* hz ini phase */
+                             | (0 << 23)               /* repeat p0 enable */
+                             | (hz_yc_ratio << 21)     /* hz yc ratio */
+                             | (hfmt_en << 20)         /* hz enable */
+                             | (1 << 17)               /* nrpt_phase0 enable*/
+                             | (0 << 16)               /* repeat l0 enable */
+                             | (0 << 12)               /* skip line num */
+                             | (vt_ini_phase << 8)     /* vt ini phase */
+                             | (vt_phase_step << 1)    /* vt phase step_3.4*/
+                             | (vfmt_en << 0)          /* vt enable */
+                             );
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_FMT_W,
+                             (y_length << 16) | (c_length << 0));
+}
+
+static void set_di_if2_fmt_more(int hfmt_en,
+                               int hz_yc_ratio,/* 2bit */
+                               int hz_ini_phase,/* 4bit */
+                               int vfmt_en,
+                               int vt_yc_ratio,/* 2bit */
+                               int vt_ini_phase,/* 4bit */
+                               int y_length,
+                               int c_length,
+                               int hz_rpt      /* 1bit */
+                               )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_FMT_CTRL,
+                             (hz_rpt << 28)            /* hz rpt pixel */
+                             | (hz_ini_phase << 24)    /* hz ini phase */
+                             | (0 << 23)               /* repeat p0 enable */
+                             | (hz_yc_ratio << 21)     /* hz yc ratio */
+                             | (hfmt_en << 20)         /* hz enable */
+                             | (1 << 17)               /* nrpt_phase0 enable*/
+                             | (0 << 16)               /* repeat l0 enable */
+                             | (0 << 12)               /* skip line num */
+                             | (vt_ini_phase << 8)     /* vt ini phase */
+                             | (vt_phase_step << 1)    /* vt phase step(3.4)*/
+                             | (vfmt_en << 0)          /* vt enable */
+                             );
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_FMT_W,
+                             (y_length << 16) | (c_length << 0));
+}
+
+static const u32 vpat[] = {0, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+
+static void set_di_if2_mif(struct DI_MIF_s *mif, int urgent,
+                          int hold_line, int vskip_cnt)
+{
+       unsigned int bytes_per_pixel, demux_mode;
+       unsigned int pat, loop = 0, chro_rpt_lastl_ctrl = 0;
+
+       if (mif->set_separate_en == 1) {
+               pat = vpat[(vskip_cnt << 1) + 1];
+               /*top*/
+               if (mif->src_field_mode == 0) {
+                       chro_rpt_lastl_ctrl = 1;
+                       loop = 0x11;
+                       pat <<= 4;
+               }
+       } else {
+               loop = 0;
+               pat = vpat[vskip_cnt];
+       }
+       #if 0
+       bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+       #else
+       if (mif->set_separate_en) {
+               bytes_per_pixel = 0;
+       } else {
+               if (mif->video_mode)
+                       bytes_per_pixel = 2;
+               else
+                       bytes_per_pixel = 1;
+       }
+       #endif
+       demux_mode = mif->video_mode;
+
+       /* ---------------------- */
+       /* General register */
+       /* ---------------------- */
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG,
+                             (1 << 29)         | /* reset on go field */
+                             (urgent << 28)    | /* urgent */
+                             (urgent << 27)    | /* luma urgent */
+                             (1 << 25)         | /* no dummy data. */
+                             (hold_line << 19) | /* hold lines */
+                             (1 << 18)         | /* push dummy pixel */
+                             (demux_mode << 16)        | /* demux_mode */
+                             (bytes_per_pixel << 14)   |
+                             (1 << 12)         | /*burst_size_cr*/
+                             (1 << 10)         | /*burst_size_cb*/
+                             (3 << 8)          | /*burst_size_y*/
+                             (chro_rpt_lastl_ctrl << 6)                |
+                             ((mif->set_separate_en != 0) << 1)        |
+                             (1 << 0)/* cntl_enable */
+                             );
+       /* post bit mode config, if0 config in video.c
+        * dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG3, mif->bit_mode, 8, 2);
+        */
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_CANVAS0, (mif->canvas0_addr2 << 16) |
+               (mif->canvas0_addr1 << 8) | (mif->canvas0_addr0 << 0));
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_X0, (mif->luma_x_end0 << 16) |
+               (mif->luma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_Y0, (mif->luma_y_end0 << 16) |
+               (mif->luma_y_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_X0, (mif->chroma_x_end0 << 16) |
+               (mif->chroma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_Y0, (mif->chroma_y_end0 << 16) |
+               (mif->chroma_y_start0 << 0));
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_RPT_LOOP,
+                             (loop << 24)      |
+                             (loop << 16)      |
+                             (loop << 8)       |
+                             (loop << 0)
+                             );
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA0_RPT_PAT, pat);
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA0_RPT_PAT, pat);
+
+       /* Dummy pixel value */
+       dim_VSYNC_WR_MPEG_REG(DI_IF2_DUMMY_PIXEL, 0x00808000);
+       if (mif->set_separate_en != 0) { /* 4:2:0 block mode. */
+               set_di_if2_fmt_more(1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   1,  /* vfmt_en */
+                                   1,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   mif->chroma_x_end0 -
+                                   mif->chroma_x_start0 + 1,
+                                   0); /* hz repeat. */
+       } else {
+               set_di_if2_fmt_more(1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   0,  /* vfmt_en */
+                                   0,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   ((mif->luma_x_end0 >> 1) -
+                                   (mif->luma_x_start0 >> 1) + 1),
+                                   0); /* hz repeat */
+       }
+}
+
+static void set_di_if1_mif(struct DI_MIF_s *mif, int urgent,
+                          int hold_line, int vskip_cnt)
+{
+       unsigned int bytes_per_pixel, demux_mode;
+       unsigned int pat, loop = 0, chro_rpt_lastl_ctrl = 0;
+
+       if (mif->set_separate_en == 1) {
+               pat = vpat[(vskip_cnt << 1) + 1];
+               /*top*/
+               if (mif->src_field_mode == 0) {
+                       chro_rpt_lastl_ctrl = 1;
+                       loop = 0x11;
+                       pat <<= 4;
+               }
+       } else {
+               loop = 0;
+               pat = vpat[vskip_cnt];
+       }
+       #if 0
+       bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+       #else
+       if (mif->set_separate_en) {
+               bytes_per_pixel = 0;
+       } else {
+               if (mif->video_mode)
+                       bytes_per_pixel = 2;
+               else
+                       bytes_per_pixel = 1;
+       }
+       #endif
+       demux_mode = mif->video_mode;
+
+       /* ---------------------- */
+       /* General register */
+       /* ---------------------- */
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG,
+                             (1 << 29)         | /* reset on go field */
+                             (urgent << 28)    | /* urgent */
+                             (urgent << 27)    | /* luma urgent */
+                             (1 << 25)         | /* no dummy data. */
+                             (hold_line << 19) | /* hold lines */
+                             (1 << 18)         | /* push dummy pixel */
+                             (demux_mode << 16)        | /* demux_mode */
+                             (bytes_per_pixel << 14)   |
+                             (1 << 12)         | /*burst_size_cr*/
+                             (1 << 10)         | /*burst_size_cb*/
+                             (3 << 8)          | /*burst_size_y*/
+                             (chro_rpt_lastl_ctrl << 6)                |
+                             ((mif->set_separate_en != 0) << 1)        |
+                             (1 << 0)          /* cntl_enable */
+                             );
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_CANVAS0,
+                             (mif->canvas0_addr2 << 16)        |
+                             (mif->canvas0_addr1 << 8)         |
+                             (mif->canvas0_addr0 << 0));
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_X0,
+                             (mif->luma_x_end0 << 16) |
+                             (mif->luma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_Y0,
+                             (mif->luma_y_end0 << 16)          |
+                             (mif->luma_y_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_X0,
+                             (mif->chroma_x_end0 << 16)        |
+                             (mif->chroma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_Y0,
+                             (mif->chroma_y_end0 << 16)        |
+                             (mif->chroma_y_start0 << 0));
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_RPT_LOOP,
+                             (loop << 24)      |
+                             (loop << 16)      |
+                             (loop << 8)       |
+                             (loop << 0)
+                             );
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA0_RPT_PAT, pat);
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA0_RPT_PAT, pat);
+
+       /* Dummy pixel value */
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_DUMMY_PIXEL, 0x00808000);
+       if (mif->set_separate_en != 0) { /* 4:2:0 block mode. */
+               set_di_if1_fmt_more(1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   1,  /* vfmt_en */
+                                   1,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   mif->chroma_x_end0 -
+                                   mif->chroma_x_start0 + 1,
+                                   0); /* hz repeat. */
+       } else {
+               set_di_if1_fmt_more(1,  /* hfmt_en */
+                                   1,  /* hz_yc_ratio */
+                                   0,  /* hz_ini_phase */
+                                   0,  /* vfmt_en */
+                                   0,  /* vt_yc_ratio */
+                                   0,  /* vt_ini_phase */
+                                   mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                                   ((mif->luma_x_end0 >> 1) -
+                                   (mif->luma_x_start0 >> 1) + 1),
+                                   0); /* hz repeat */
+       }
+}
+
+static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line)
+{
+       unsigned int bytes_per_pixel;
+       unsigned int demux_mode;
+       unsigned int chro_rpt_lastl_ctrl;
+       unsigned int luma0_rpt_loop_start;
+       unsigned int luma0_rpt_loop_end;
+       unsigned int luma0_rpt_loop_pat;
+       unsigned int chroma0_rpt_loop_start;
+       unsigned int chroma0_rpt_loop_end;
+       unsigned int chroma0_rpt_loop_pat;
+       unsigned int reset_on_gofield;
+
+       if (mif->set_separate_en != 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = 1;
+               chroma0_rpt_loop_end = 1;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = 0x80;
+       } else if (mif->set_separate_en != 0 && mif->src_field_mode == 0) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x0;
+               chroma0_rpt_loop_pat = 0x0;
+       } else if (mif->set_separate_en == 0 && mif->src_field_mode == 1) {
+               chro_rpt_lastl_ctrl = 1;
+               luma0_rpt_loop_start = 1;
+               luma0_rpt_loop_end = 1;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x80;
+               chroma0_rpt_loop_pat = 0x00;
+       } else {
+               chro_rpt_lastl_ctrl = 0;
+               luma0_rpt_loop_start = 0;
+               luma0_rpt_loop_end = 0;
+               chroma0_rpt_loop_start = 0;
+               chroma0_rpt_loop_end = 0;
+               luma0_rpt_loop_pat = 0x00;
+               chroma0_rpt_loop_pat = 0x00;
+       }
+       #if 0
+       bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+       #else
+       if (mif->set_separate_en) {
+               bytes_per_pixel = 0;
+       } else {
+               if (mif->video_mode)
+                       bytes_per_pixel = 2;
+               else
+                       bytes_per_pixel = 1;
+       }
+       #endif
+       demux_mode = mif->video_mode;
+
+       /* ---------------------- */
+       /* General register */
+       /* ---------------------- */
+       reset_on_gofield = 1;/* default enable according to vlsi */
+       dim_RDMA_WR(DI_CHAN2_GEN_REG,
+                   (reset_on_gofield << 29)    |
+                   (urgent << 28)              |       /* urgent */
+                   (urgent << 27)              |       /* luma urgent */
+                   (1 << 25)                   |       /* no dummy data. */
+                   (hold_line << 19)           |       /* hold lines */
+                   (1 << 18)                   |       /* push dummy pixel */
+                   (demux_mode << 16)          |
+                   (bytes_per_pixel << 14)     |
+                   (1 << 12)                   |       /*burst_size_cr*/
+                   (1 << 10)                   |       /*burst_size_cb*/
+                   (3 << 8)                    |       /*burst_size_y*/
+                   (chro_rpt_lastl_ctrl << 6)  |
+                   ((mif->set_separate_en != 0) << 1)  |
+                   (0 << 0)                    /* cntl_enable */
+         );
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       if (mif->set_separate_en == 2) {
+               /* Enable NV12 Display */
+               dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 1, 0, 1);
+       } else {
+               dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 0, 0, 1);
+       }
+       dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG3, mif->bit_mode & 0x3, 8, 2);
+       dim_RDMA_WR(DI_CHAN2_CANVAS0, (mif->canvas0_addr2 << 16) |
+                               (mif->canvas0_addr1 << 8) |
+                               (mif->canvas0_addr0 << 0));
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_CHAN2_LUMA_X0, (mif->luma_x_end0 << 16) |
+               /* cntl_luma_x_end0 */
+               (mif->luma_x_start0 << 0));
+       dim_RDMA_WR(DI_CHAN2_LUMA_Y0, (mif->luma_y_end0 << 16) |
+                               (mif->luma_y_start0 << 0));
+       dim_RDMA_WR(DI_CHAN2_CHROMA_X0, (mif->chroma_x_end0 << 16) |
+                               (mif->chroma_x_start0 << 0));
+       dim_RDMA_WR(DI_CHAN2_CHROMA_Y0, (mif->chroma_y_end0 << 16) |
+                               (mif->chroma_y_start0 << 0));
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_RDMA_WR(DI_CHAN2_RPT_LOOP,
+                   (0 << 28)                   |
+                   (0   << 24)                 |
+                   (0   << 20)                 |
+                   (0   << 16)                 |
+                   (0   << 12)                 |
+                   (0   << 8)                  |
+                   (luma0_rpt_loop_start << 4) |
+                   (luma0_rpt_loop_end << 0)
+       );
+
+       dim_RDMA_WR(DI_CHAN2_LUMA0_RPT_PAT, luma0_rpt_loop_pat);
+
+       /* Dummy pixel value */
+       dim_RDMA_WR(DI_CHAN2_DUMMY_PIXEL, 0x00808000);
+
+       if ((mif->set_separate_en != 0)) {      /* 4:2:0 block mode. */
+               set_di_chan2_fmt_more(
+                                     1,        /* hfmt_en */
+                                     1,        /* hz_yc_ratio */
+                                     0,        /* hz_ini_phase */
+                                     1,        /* vfmt_en */
+                                     1,        /* vt_yc_ratio */
+                                     0,        /* vt_ini_phase */
+                                     mif->luma_x_end0 -
+                                     mif->luma_x_start0 + 1,   /* y_length */
+                                     mif->chroma_x_end0 -
+                                     mif->chroma_x_start0 + 1,/* c length */
+                                     0);       /* hz repeat. */
+       } else {
+               set_di_chan2_fmt_more(
+                                     1,        /* hfmt_en */
+                                     1,        /* hz_yc_ratio */
+                                     0,        /* hz_ini_phase */
+                                     0,        /* vfmt_en */
+                                     0,        /* vt_yc_ratio */
+                                     0,        /* vt_ini_phase */
+                                     mif->luma_x_end0 -
+                                     mif->luma_x_start0 + 1,   /* y_length */
+                                     ((mif->luma_x_end0 >> 1) -
+                                     (mif->luma_x_start0 >> 1) + 1),
+                                     0);       /* hz repeat. */
+       }
+}
+
+static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line,
+                          int vskip_cnt, int post_write_en)
+{
+       unsigned int pat, loop = 0;
+       unsigned int bytes_per_pixel, demux_mode;
+
+       if (mif->set_separate_en == 1) {
+               pat = vpat[(vskip_cnt << 1) + 1];
+               if (mif->src_field_mode == 0) {/* top */
+                       loop = 0x11;
+                       pat <<= 4;
+               }
+       } else {
+               loop = 0;
+       pat = vpat[vskip_cnt];
+
+       if (post_write_en) {
+               bytes_per_pixel =
+                       mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+               demux_mode = mif->video_mode;
+               dim_VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG,
+                       (1 << 29)               | /* reset on go field */
+                       (urgent << 28)          | /* urgent */
+                       (urgent << 27)          | /* luma urgent */
+                       (1 << 25)               | /* no dummy data. */
+                       (hold_line << 19)       | /* hold lines */
+                       (1 << 18)               | /* push dummy pixel */
+                       (demux_mode << 16)      | /* demux_mode */
+                       (bytes_per_pixel << 14) |
+                       (1 << 12)               |
+                       (1 << 10)               |
+                       (3 << 8)                |
+                       (0 << 6)                |
+                       ((mif->set_separate_en != 0) << 1)      |
+                       (1 << 0)                /* cntl_enable */
+               );
+       }
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0,
+                             (mif->canvas0_addr2 << 16)        |
+                             (mif->canvas0_addr1 << 8)         |
+                             (mif->canvas0_addr0 << 0));
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_X0, (mif->luma_x_end0 << 16) |
+               (mif->luma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_Y0, (mif->luma_y_end0 << 16) |
+               (mif->luma_y_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_X0, (mif->chroma_x_end0 << 16) |
+               (mif->chroma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_Y0, (mif->chroma_y_end0 << 16) |
+               (mif->chroma_y_start0 << 0));
+       }
+
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_RPT_LOOP,
+                             (loop << 24)      |
+                             (loop << 16)      |
+                             (loop << 8)       |
+                             (loop << 0));
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA0_RPT_PAT,   pat);
+       dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA0_RPT_PAT, pat);
+
+       if (post_write_en) {
+               /* 4:2:0 block mode. */
+               if (mif->set_separate_en != 0) {
+                       set_di_if0_fmt_more(
+                               1,      /* hfmt_en */
+                               1,      /* hz_yc_ratio */
+                               0,      /* hz_ini_phase */
+                               1,      /* vfmt_en */
+                               1,      /* vt_yc_ratio */
+                               0,      /* vt_ini_phase */
+                               /* y_length */
+                               mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                               /* c length */
+                               mif->chroma_x_end0 - mif->chroma_x_start0 + 1,
+                               0);     /* hz repeat. */
+               } else {
+                       set_di_if0_fmt_more(
+                               1,      /* hfmt_en */
+                               1,      /* hz_yc_ratio */
+                               0,      /* hz_ini_phase */
+                               0,      /* vfmt_en */
+                               0,      /* vt_yc_ratio */
+                               0,      /* vt_ini_phase */
+                                       /* y_length */
+                               mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                               /* c length */
+                               ((mif->luma_x_end0 >> 1) - (
+                               mif->luma_x_start0 >> 1) + 1),
+                               0);     /* hz repeat */
+               }
+       }
+}
+
+static void set_di_if0_fmt_more_g12(int hfmt_en,
+                                   int hz_yc_ratio,            /* 2bit */
+                                   int hz_ini_phase,           /* 4bit */
+                                   int vfmt_en,
+                                   int vt_yc_ratio,            /* 2bit */
+                                   int vt_ini_phase,           /* 4bit */
+                                   int y_length,
+                                   int c_length,
+                                   int hz_rpt                  /* 1bit */
+                                   )
+{
+       int vt_phase_step = (16 >> vt_yc_ratio);
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_FMT_CTRL,
+               (hz_rpt << 28)          |       /* hz rpt pixel */
+               (hz_ini_phase << 24)    |       /* hz ini phase */
+               (0 << 23)               |       /* repeat p0 enable */
+               (hz_yc_ratio << 21)     |       /* hz yc ratio */
+               (hfmt_en << 20)         |       /* hz enable */
+               (1 << 17)               |       /* nrpt_phase0 enable */
+               (0 << 16)               |       /* repeat l0 enable */
+               (0 << 12)               |       /* skip line num */
+               (vt_ini_phase << 8)     |       /* vt ini phase */
+               (vt_phase_step << 1)    |       /* vt phase step (3.4) */
+               (vfmt_en << 0)                  /* vt enable */
+                                       );
+
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_FMT_W,
+                             (y_length << 16)  |       /* hz format width */
+                             (c_length << 0)           /* vt format width */
+                                       );
+}
+
+static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, int hold_line,
+                              int vskip_cnt, int post_write_en)
+{
+       unsigned int pat, loop = 0;
+       unsigned int bytes_per_pixel, demux_mode;
+
+       if (mif->set_separate_en == 1) {
+               pat = vpat[(vskip_cnt << 1) + 1];
+               if (mif->src_field_mode == 0) {/* top */
+                       loop = 0x11;
+                       pat <<= 4;
+               }
+       } else {
+               loop = 0;
+               pat = vpat[vskip_cnt];
+
+               bytes_per_pixel =
+                       mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1);
+               demux_mode = mif->video_mode;
+               dim_VSYNC_WR_MPEG_REG(DI_IF0_GEN_REG,
+                       (1 << 29)               | /* reset on go field */
+                       (urgent << 28)          | /* urgent */
+                       (urgent << 27)          | /* luma urgent */
+                       (1 << 25)               | /* no dummy data. */
+                       (hold_line << 19)       | /* hold lines */
+                       (1 << 18)               | /* push dummy pixel */
+                       (demux_mode << 16)      | /* demux_mode */
+                       (bytes_per_pixel << 14) |
+                       (1 << 12)               |
+                       (1 << 10)               |
+                       (3 << 8)                |
+                       (0 << 6)                |
+                       ((mif->set_separate_en != 0) << 1)      |
+                       (1 << 0)                /* cntl_enable */
+               );
+       /* ---------------------- */
+       /* Canvas */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0,
+                             (mif->canvas0_addr2 << 16)        |
+                             (mif->canvas0_addr1 << 8)         |
+                             (mif->canvas0_addr0 << 0));
+       if (mif->set_separate_en == 2) {
+               /* Enable NV12 Display */
+               dim_RDMA_WR_BITS(DI_IF0_GEN_REG2, 1, 0, 1);
+       } else {
+               dim_RDMA_WR_BITS(DI_IF0_GEN_REG2, 0, 0, 1);
+       }
+
+       /* ---------------------- */
+       /* Picture 0 X/Y start,end */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_X0,
+                             (mif->luma_x_end0 << 16)  |
+                             (mif->luma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_Y0,
+                             (mif->luma_y_end0 << 16)  |
+                             (mif->luma_y_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_X0,
+                             (mif->chroma_x_end0 << 16)        |
+                             (mif->chroma_x_start0 << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_Y0,
+                             (mif->chroma_y_end0 << 16)        |
+                             (mif->chroma_y_start0 << 0));
+               }
+       /* ---------------------- */
+       /* Repeat or skip */
+       /* ---------------------- */
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_REPEAT_LOOP,
+                             (loop << 24)      |
+                             (loop << 16)      |
+                             (loop << 8)       |
+                             (loop << 0));
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA0_RPT_PAT,   pat);
+       dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA0_RPT_PAT, pat);
+
+       /* 4:2:0 block mode. */
+       if (mif->set_separate_en != 0) {
+               set_di_if0_fmt_more_g12(
+                       1, /* hfmt_en */
+                       1,      /* hz_yc_ratio */
+                       0,      /* hz_ini_phase */
+                       1,      /* vfmt_en */
+                       1, /* vt_yc_ratio */
+                       0, /* vt_ini_phase */
+                       /* y_length */
+                       mif->luma_x_end0 - mif->luma_x_start0 + 1,
+                       /* c length */
+                       mif->chroma_x_end0 - mif->chroma_x_start0 + 1,
+                       0); /* hz repeat. */
+       } else {
+               set_di_if0_fmt_more_g12(
+                                       1,      /* hfmt_en */
+                                       1,      /* hz_yc_ratio */
+                                       0,      /* hz_ini_phase */
+                                       0,      /* vfmt_en */
+                                       0,      /* vt_yc_ratio */
+                                       0,      /* vt_ini_phase */
+                                       /* y_length */
+                                       mif->luma_x_end0 -
+                                       mif->luma_x_start0 + 1,
+                                       /* c length */
+                                       ((mif->luma_x_end0 >> 1) -
+                                       (mif->luma_x_start0 >> 1) + 1),
+                                       0); /* hz repeat */
+       }
+}
+
+static unsigned int di_mc_update;
+void dimh_patch_post_update_mc(void)
+{
+       if (di_mc_update == DI_MC_SW_ON_MASK)
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1);
+}
+
+void dimh_patch_post_update_mc_sw(unsigned int cmd, bool on)
+{
+       unsigned int l_flg = di_mc_update;
+
+       switch (cmd) {
+       case DI_MC_SW_IC:
+               if (is_meson_gxtvbb_cpu()       ||
+                   is_meson_txl_cpu()          ||
+                   is_meson_txlx_cpu()         ||
+                   is_meson_txhd_cpu()) {
+                       di_mc_update |= DI_MC_SW_IC;
+               }
+               break;
+       case DI_MC_SW_REG:
+               if (on) {
+                       di_mc_update |= cmd;
+                       di_mc_update &= ~DI_MC_SW_OTHER;
+               } else {
+                       di_mc_update &= ~(cmd | DI_MC_SW_OTHER);
+               }
+               break;
+       case DI_MC_SW_OTHER:
+
+/*     case DI_MC_SW_POST:*/
+               if (on)
+                       di_mc_update |= cmd;
+               else
+                       di_mc_update &= ~cmd;
+
+               break;
+       }
+
+       if (l_flg !=  di_mc_update)
+               pr_debug("%s:0x%x->0x%x\n", __func__, l_flg, di_mc_update);
+}
+
+void dimh_post_ctrl(enum DI_HW_POST_CTRL contr, unsigned int post_write_en)
+{
+       unsigned int reg_val;
+
+       if (!post_write_en || !cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               return;
+
+       switch (contr) {
+       case DI_HW_POST_CTRL_INIT:
+               dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL,
+                                     0x80000000 |
+                                     dimp_get(eDI_MP_line_num_post_frst));
+               break;
+       case DI_HW_POST_CTRL_RESET:     /*replace post_frame_reset_g12a*/
+               reg_val = (0xc3200000 | dimp_get(eDI_MP_line_num_post_frst));
+               dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val);
+               reg_val = (0x83200000 | dimp_get(eDI_MP_line_num_post_frst));
+               dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val);
+
+               break;
+       }
+}
+
+void dimh_initial_di_post_2(int hsize_post, int vsize_post,
+                           int hold_line, bool post_write_en)
+{
+       di_post_set_flow(post_write_en, eDI_POST_FLOW_STEP1_STOP);/*dbg a*/
+       dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE,
+                             (hsize_post - 1) | ((vsize_post - 1) << 16));
+
+       /* if post size < MIN_POST_WIDTH, force old ei */
+       if (hsize_post < MIN_POST_WIDTH)
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 0, 31, 1);
+       else
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 1, 31, 1);
+
+       /* DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post >> 2) - 1); */
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_Y,
+                             ((vsize_post >> 2) << 16) |
+                             (2 * (vsize_post >> 2) - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_Y,
+                             ((2 * (vsize_post >> 2)) << 16) |
+                             (3 * (vsize_post >> 2) - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_Y,
+                             ((3 * (vsize_post >> 2)) << 16) |
+                             (vsize_post - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_X, (hsize_post - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_X, (hsize_post - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_X, (hsize_post - 1));
+       dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_X, (hsize_post - 1));
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if (post_write_en) {
+       #if 0
+                       dim_print("%s:VD1_AFBCD0_MISC_CTRL\n", __func__);
+       #endif
+                       /*di if0 mif to di post*/
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 4, 1);
+                       /*di_mif0_en:select mif to di*/
+                       #if 0
+                       DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL,
+                                                 1, 8, 1);
+                       #endif
+                       dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL,
+                                                  0, 8, 1);
+               } else {
+                       dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL,
+                                                  1, 8, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 4, 1);
+               }
+
+       } else {
+               /* enable ma,disable if0 to vpp */
+               if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3);
+                       if (post_write_en)
+                               dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0,
+                                                          1, 28, 1);
+               }
+       }
+       dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL,
+                             (0 << 0)                          |
+                             (0 << 1)                          |
+                             (0 << 2)                          |
+                             (0 << 3)                          |
+                             (0 << 4)                          |
+                             (0 << 5)                          |
+                             (0 << 6)                          |
+                             ((post_write_en ? 1 : 0) << 7)    |
+                             ((post_write_en ? 0 : 1) << 8)    |
+                             (0 << 9)                          |
+                             (0 << 10)                         |
+                             (0 << 11)                         |
+                             (0 << 12)                         |
+                             (hold_line << 16)                 |
+                             (0 << 29)                         |
+                             (0x3 << 30)
+               );
+}
+
+static void post_bit_mode_config(unsigned char if0,
+                                unsigned char if1,
+                                unsigned char if2,
+                                unsigned char post_wr)
+{
+       if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB))
+               return;
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dim_DI_Wr_reg_bits(DI_IF0_GEN_REG3, if0 & 0x3, 8, 2);
+       else
+               dim_DI_Wr_reg_bits(VD1_IF0_GEN_REG3, if0 & 0x3, 8, 2);
+       dim_DI_Wr_reg_bits(DI_IF1_GEN_REG3, if1 & 0x3, 8, 2);
+       dim_DI_Wr_reg_bits(DI_IF2_GEN_REG3, if2 & 0x3, 8, 2);
+       dim_DI_Wr_reg_bits(DI_DIWR_Y, post_wr & 0x1, 14, 1);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) && ((post_wr & 0x3) == 0x3))
+               dim_DI_Wr_reg_bits(DI_DIWR_CTRL, 0x3, 22, 2);
+}
+
+void dimh_post_switch_buffer(
+       struct DI_MIF_s            *di_buf0_mif,
+       struct DI_MIF_s            *di_buf1_mif,
+       struct DI_MIF_s            *di_buf2_mif,
+       struct DI_SIM_MIF_s    *di_diwr_mif,
+       struct DI_SIM_MIF_s    *di_mtnprd_mif,
+       struct DI_MC_MIF_s         *di_mcvecrd_mif,
+       int ei_en, int blend_en, int blend_mtn_en, int blend_mode,
+       int di_vpp_en, int di_ddr_en,
+       int post_field_num, int hold_line, int urgent,
+       int invert_mv, bool pd_enable, bool mc_enable,
+       int vskip_cnt
+)
+{
+       int ei_only, buf1_en;
+
+       ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en);
+       buf1_en =  (!ei_only && (di_ddr_en || di_vpp_en));
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               dim_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0,
+                       (di_buf0_mif->canvas0_addr2 << 16)      |
+                       (di_buf0_mif->canvas0_addr1 << 8)       |
+                       (di_buf0_mif->canvas0_addr0 << 0));
+                       if (!di_ddr_en) {
+                               dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG,
+                                                          0, 0, 1);
+                       }
+               if (mc_enable) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL1,
+                                                  di_mcvecrd_mif->canvas_num,
+                                                  16, 8);
+               }
+               /*motion for current display field.*/
+               if (blend_mtn_en) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1,
+                                                  di_mtnprd_mif->canvas_num,
+                                                  16, 8);
+                       /* current field mtn canvas index.*/
+               }
+       } else {
+               if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000)
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3);
+               if (di_ddr_en)
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 1, 28, 1);
+               if (ei_en || di_vpp_en || di_ddr_en)
+                       set_di_if0_mif(di_buf0_mif, urgent,
+                                      hold_line, vskip_cnt, di_ddr_en);
+               if (mc_enable) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL,
+                                                  /* canvas enable */
+                                                  (1 << 9)             |
+                                                  (urgent << 8)        |
+                                                  di_mcvecrd_mif->canvas_num,
+                                                  0, 10);
+               }
+               /*motion for current display field.*/
+               if (blend_mtn_en) {
+                       dim_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL,
+                               (di_mtnprd_mif->canvas_num << 8) |
+                               (urgent << 16));
+                       /*current field mtn canvas index.*/
+               }
+       }
+
+       if (!ei_only && (di_ddr_en || di_vpp_en)) {
+               dim_VSYNC_WR_MPEG_REG(DI_IF1_CANVAS0,
+                                     (di_buf1_mif->canvas0_addr2 << 16) |
+                                     (di_buf1_mif->canvas0_addr1 << 8)  |
+                                     (di_buf1_mif->canvas0_addr0 << 0));
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+                       dim_VSYNC_WR_MPEG_REG(DI_IF2_CANVAS0,
+                               (di_buf2_mif->canvas0_addr2 << 16)      |
+                               (di_buf2_mif->canvas0_addr1 << 8)       |
+                               (di_buf2_mif->canvas0_addr0 << 0));
+       }
+
+       if (di_ddr_en) {
+               dim_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL,
+                                     di_diwr_mif->canvas_num   |
+                                     (urgent << 16)            |
+                                     (2 << 26)                 |
+                                     (di_ddr_en << 30));
+               post_bit_mode_config(di_buf0_mif->bit_mode,
+                                    di_buf1_mif->bit_mode,
+                                    di_buf2_mif->bit_mode,
+                                    di_diwr_mif->bit_mode);
+       }
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2);
+       if ((dimp_get(eDI_MP_pldn_ctrl_rflsh) == 1) && pd_enable)
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3);
+
+       if (mc_enable) {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX))
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                  invert_mv,
+                                                  17, 1);/* invert mv */
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                       di_mcvecrd_mif->vecrd_offset, 12, 3);
+               if (di_mcvecrd_mif->blend_en) {
+                       if (blend_mode == 1) {
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                       dimp_get(eDI_MP_mcen_mode), 0, 2);
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          0, 11, 1);
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          2, 18, 2);
+                       } else {
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                       dimp_get(eDI_MP_mcen_mode), 0, 2);
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          1, 11, 1);
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          3, 18, 2);
+                       }
+               } else {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2);
+               }
+       }
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD,
+                                          hold_line, 16, 5);
+               hold_line = 0;
+       }
+
+       if (!is_meson_txlx_cpu())
+               invert_mv = 0;
+       if (dimp_get(eDI_MP_post_ctrl) != 0)
+               dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL,
+                                     dimp_get(eDI_MP_post_ctrl) |
+                                     (0x3 << 30));
+       else {
+               dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL,
+                       ((ei_en | blend_en) << 0) | /* line buf 0 enable */
+                       ((blend_mode == 1 ? 1 : 0) << 1)        |
+                       (ei_en << 2)            | /* ei  enable */
+                       (blend_mtn_en << 3)     | /* mtn line buffer enable */
+                       (blend_mtn_en << 4)     | /* mtnp read mif enable */
+                       (blend_en << 5)         |
+                       (1 << 6)                | /* di mux output enable */
+                       (di_ddr_en << 7)        | /* di wr to SDRAM enable.*/
+                       (di_vpp_en << 8)        | /* di to VPP enable. */
+                       (0 << 9)                | /* mif0 to VPP enable. */
+                       (0 << 10)               | /* post drop first. */
+                       (0 << 11)               |
+                       (di_vpp_en << 12)       | /* post viu link */
+                       (invert_mv << 14)       |
+                       (hold_line << 16)       | /* post hold line number */
+                       (post_field_num << 29)  | /* post field number. */
+                       (0x3 << 30) /* post soft rst  post frame rst. */
+                       );
+       }
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) {
+#if 0
+               post_frame_reset_g12a();
+#endif
+       } else if (di_ddr_en && mc_enable) {
+               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1);
+       }
+}
+
+static void set_post_mtnrd_mif(struct DI_SIM_MIF_s *mtnprd_mif,
+                              unsigned char urgent)
+{
+       dim_VSYNC_WR_MPEG_REG(DI_MTNPRD_X,
+                             (mtnprd_mif->start_x << 16) |
+                             (mtnprd_mif->end_x));
+       dim_VSYNC_WR_MPEG_REG(DI_MTNPRD_Y,
+                             (mtnprd_mif->start_y << 16) |
+                             (mtnprd_mif->end_y));
+       dim_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL,
+                             (mtnprd_mif->canvas_num << 8) |
+                             (urgent << 16)
+        );
+}
+
+static void set_post_mtnrd_mif_g12(struct DI_SIM_MIF_s *mtnprd_mif)
+{
+       dim_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_X,
+                             (mtnprd_mif->end_x << 16) |
+                             (mtnprd_mif->start_x));
+       dim_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_Y,
+                             (mtnprd_mif->end_y << 16) |
+                             (mtnprd_mif->start_y));
+       dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1,
+                                  mtnprd_mif->canvas_num, 16, 8);
+       dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 0, 0, 3);
+}
+
+void dimh_enable_di_post_2(
+       struct DI_MIF_s            *di_buf0_mif,
+       struct DI_MIF_s            *di_buf1_mif,
+       struct DI_MIF_s            *di_buf2_mif,
+       struct DI_SIM_MIF_s    *di_diwr_mif,
+       struct DI_SIM_MIF_s    *di_mtnprd_mif,
+       int ei_en, int blend_en, int blend_mtn_en, int blend_mode,
+       int di_vpp_en, int di_ddr_en, int post_field_num,
+       int hold_line, int urgent, int invert_mv,
+       int vskip_cnt
+)
+{
+       int ei_only;
+       int buf1_en;
+
+       ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en);
+       buf1_en =  (!ei_only && (di_ddr_en || di_vpp_en));
+
+       if (ei_en || di_vpp_en || di_ddr_en) {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+                       set_di_if0_mif_g12(di_buf0_mif, di_vpp_en,
+                                          hold_line, vskip_cnt, di_ddr_en);
+                       /* if di post vpp link disable vd1 for new if0 */
+                       if (!di_ddr_en) {
+                               dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG,
+                                                          0, 0, 1);
+                       }
+               } else
+                       set_di_if0_mif(di_buf0_mif, di_vpp_en,
+                                      hold_line, vskip_cnt, di_ddr_en);
+       }
+
+       set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line, vskip_cnt);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               set_di_if2_mif(di_buf2_mif,
+                              di_vpp_en, hold_line, vskip_cnt);
+       /* motion for current display field. */
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               set_post_mtnrd_mif_g12(di_mtnprd_mif);
+       else
+               set_post_mtnrd_mif(di_mtnprd_mif, urgent);
+       if (di_ddr_en) {
+               dim_VSYNC_WR_MPEG_REG(DI_DIWR_X,
+                                     (di_diwr_mif->start_x << 16)      |
+                                     (di_diwr_mif->end_x));
+               dim_VSYNC_WR_MPEG_REG(DI_DIWR_Y,
+                                     (3 << 30)                         |
+                                     (di_diwr_mif->start_y << 16)      |
+                                       /* wr ext en from gxtvbb */
+                                     (1 << 15)                         |
+                                     (di_diwr_mif->end_y));
+               dim_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL,
+                                     di_diwr_mif->canvas_num   |
+                                     (urgent << 16)            |
+                                     (2 << 26)                 |
+                                     (di_ddr_en << 30));
+               post_bit_mode_config(di_buf0_mif->bit_mode,
+                                    di_buf1_mif->bit_mode,
+                                    di_buf2_mif->bit_mode,
+                                    di_diwr_mif->bit_mode);
+       }
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+                                  blend_en & 0x1, 31, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+                                  blend_mode & 0x3, 20, 2);
+       if (!is_meson_txlx_cpu())
+               invert_mv = 0;
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD,
+                                          hold_line, 16, 5);
+               hold_line = 0;
+       }
+       dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL,
+               ((ei_en | blend_en) << 0)       | /* line buffer 0 enable */
+               ((blend_mode == 1 ? 1 : 0) << 1)        |
+               (ei_en << 2)                    | /* ei  enable */
+               (blend_mtn_en << 3)             | /* mtn line buffer enable */
+               (blend_mtn_en  << 4)            | /* mtnp read mif enable */
+               (blend_en << 5)                 |
+               (1 << 6)                        | /* di mux output enable */
+               /* di write to SDRAM enable. */
+               (di_ddr_en << 7)                |
+               (di_vpp_en << 8)                | /* di to VPP enable. */
+               (0 << 9)                        | /* mif0 to VPP enable. */
+               (0 << 10)                       | /* post drop first. */
+               (0 << 11)                       |
+               (di_vpp_en << 12)               | /* post viu link */
+               (invert_mv << 14)               | /* invert mv */
+               (hold_line << 16)               | /* post hold line number */
+               (post_field_num << 29)          | /* post field number. */
+               (0x3 << 30)             /* post soft rst  post frame rst. */
+               );
+}
+
+void dimh_pst_trig_resize(void)
+{
+       dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16));
+}
+
+void dimh_disable_post_deinterlace_2(void)
+{
+       dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL, 0x3 << 30);
+       dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16));
+       dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               dim_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, 0x3 << 30);
+       /* disable ma,enable if0 to vpp,enable afbc to vpp */
+       if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0)
+                       dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 0, 16, 4);
+               /* DI inp(current data) switch to memory */
+               dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 16, 1);
+       }
+       /* dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG,
+        * Rd(DI_IF1_GEN_REG) & 0xfffffffe);
+        */
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               /*dbg a dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0);*/
+               di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP);
+               dim_print("%s:VD1_AFBCD0_MISC_CTRL 0", __func__);
+               dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 8, 2);
+               dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 20, 2);
+       }
+}
+
+void dimh_enable_di_post_mif(enum gate_mode_e mode)
+{
+       unsigned char gate = 0;
+
+       switch (mode) {
+       case GATE_OFF:
+               gate = 1;
+               break;
+       case GATE_ON:
+               gate = 2;
+               break;
+       case GATE_AUTO:
+               gate = 2;
+               break;
+       default:
+               gate = 0;
+       }
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               /* enable if0 external gate freerun hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 2, 2);
+               /* enable if1 external gate freerun hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 4, 2);
+               /* enable if1 external gate freerun hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 6, 2);
+               /* enable di wr external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 8, 2);
+               /* enable mtn rd external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 10, 2);
+               /* enable mv rd external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 12, 2);
+       } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) {
+               /* enable if1 external gate freerun hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1,
+                                  ((gate == 0) ? 2 : gate), 2, 2);
+               /* enable if2 external gate freerun hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1,
+                                  ((gate == 0) ? 2 : gate), 4, 2);
+               /* enable di wr external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 6, 2);
+               /* enable mtn rd external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 8, 2);
+               /* enable mv rd external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 10, 2);
+       }
+}
+
+void dim_hw_disable(bool mc_enable)
+{
+       dimh_enable_di_pre_mif(false, mc_enable);
+       dim_DI_Wr(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16));
+       dim_DI_Wr_reg_bits(DI_IF1_GEN_REG, 0, 0, 1);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               dim_DI_Wr_reg_bits(DI_IF2_GEN_REG, 0, 0, 1);
+       /* disable ma,enable if0 to vpp,enable afbc to vpp */
+       if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 4) != 0)
+                       dim_DI_Wr_reg_bits(VIU_MISC_CTRL0, 0, 16, 4);
+               /* DI inp(current data) switch to memory */
+               dim_DI_Wr_reg_bits(VIUB_MISC_CTRL0, 0, 16, 1);
+       }
+       dim_DI_Wr(DI_POST_CTRL, 0);
+}
+
+/*
+ * old pulldown windows share below ctrl
+ * registers
+ * with new pulldown windows
+ */
+void dim_film_mode_win_config(unsigned int width, unsigned int height)
+{
+       unsigned int win0_start_x, win0_end_x, win0_start_y, win0_end_y;
+       unsigned int win1_start_x, win1_end_x, win1_start_y, win1_end_y;
+       unsigned int win2_start_x, win2_end_x, win2_start_y, win2_end_y;
+       unsigned int win3_start_x, win3_end_x, win3_start_y, win3_end_y;
+       unsigned int win4_start_x, win4_end_x, win4_start_y, win4_end_y;
+
+       win0_start_x = 0;
+       win1_start_x = 0;
+       win2_start_x = 0;
+       win3_start_x = 0;
+       win4_start_x = 0;
+       win0_end_x = width - 1;
+       win1_end_x = width - 1;
+       win2_end_x = width - 1;
+       win3_end_x = width - 1;
+       win4_end_x = width - 1;
+       win0_start_y = 0;
+       win1_start_y = (height >> 3); /* 1/8 */
+       win0_end_y = win1_start_y - 1;
+       win2_start_y = win1_start_y + (height >> 2); /* 1/4 */
+       win1_end_y = win2_start_y - 1;
+       win3_start_y = win2_start_y + (height >> 2); /* 1/4 */
+       win2_end_y = win3_start_y - 1;
+       win4_start_y = win3_start_y + (height >> 2); /* 1/4 */
+       win3_end_y = win4_start_y - 1;
+       win4_end_y = win4_start_y + (height >> 3) - 1; /* 1/8 */
+
+       dim_RDMA_WR(DI_MC_REG0_X, (win0_start_x << 16) | win0_end_x);
+       dim_RDMA_WR(DI_MC_REG0_Y, (win0_start_y << 16) | win0_end_y);
+       dim_RDMA_WR(DI_MC_REG1_X, (win1_start_x << 16) | win1_end_x);
+       dim_RDMA_WR(DI_MC_REG1_Y, (win1_start_y << 16) | win1_end_y);
+       dim_RDMA_WR(DI_MC_REG2_X, (win2_start_x << 16) | win2_end_x);
+       dim_RDMA_WR(DI_MC_REG2_Y, (win2_start_y << 16) | win2_end_y);
+       dim_RDMA_WR(DI_MC_REG3_X, (win3_start_x << 16) | win3_end_x);
+       dim_RDMA_WR(DI_MC_REG3_Y, (win3_start_y << 16) | win3_end_y);
+       dim_RDMA_WR(DI_MC_REG4_X, (win4_start_x << 16) | win4_end_x);
+       dim_RDMA_WR(DI_MC_REG4_Y, (win4_start_y << 16) | win4_end_y);
+}
+
+/*
+ * old pulldown detction module, global field diff/num & frame
+ * diff/numm and 5 window included
+ */
+void dim_read_pulldown_info(unsigned int *glb_frm_mot_num,
+                           unsigned int *glb_fid_mot_num)
+{
+       /*
+        * addr will increase by 1 automatically
+        */
+       dim_DI_Wr(DI_INFO_ADDR, 1);
+       *glb_frm_mot_num = (Rd(DI_INFO_DATA) & 0xffffff);
+       dim_DI_Wr(DI_INFO_ADDR, 4);
+       *glb_fid_mot_num = (Rd(DI_INFO_DATA) & 0xffffff);
+}
+
+#if 0  /*move from deinterlace_hw.c to pulldown_drv.c*/
+
+void read_new_pulldown_info(struct FlmModReg_t *pFMReg)
+{
+       int i = 0;
+
+       for (i = 0; i < 6; i++) {
+               pFMReg->rROFrmDif02[i] = Rd(DIPD_RO_COMB_0 + i);
+               pFMReg->rROFldDif01[i] = Rd(DIPD_RO_COMB_6 + i);
+       }
+
+       /* pFMReg->rROFrmDif02[0] = Rd(DIPD_RO_COMB_0); */
+       /* pFMReg->rROFldDif01[0] = Rd(DIPD_RO_COMB_6); */
+
+       for (i = 0; i < 9; i++)
+               pFMReg->rROCmbInf[i] = Rd(DIPD_RO_COMB_12 + i);
+}
+
+#endif
+/*
+ * DIPD_RO_COMB_0~DIPD_RO_COMB11 and DI_INFO_DATA
+ * will be reset, so call this function after all
+ * data have be fetched
+ */
+void dim_pulldown_info_clear_g12a(void)
+{
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 30, 1);
+}
+
+/*
+ * manual reset contrd, cont2rd, mcinford mif
+ * which fix after g12a
+ */
+static void reset_pre_simple_rd_mif_g12(unsigned char madi_en,
+                                       unsigned char mcdi_en)
+{
+       unsigned int reg_val = 0;
+
+       if (madi_en || mcdi_en) {
+               dim_RDMA_WR_BITS(CONTRD_CTRL2, 1, 31, 1);
+               dim_RDMA_WR_BITS(CONT2RD_CTRL2, 1, 31, 1);
+               dim_RDMA_WR_BITS(MCINFRD_CTRL2, 1, 31, 1);
+               reg_val = dim_RDMA_RD(DI_PRE_CTRL);
+               if (madi_en)
+                       reg_val |= (1 << 25);
+               if (mcdi_en)
+                       reg_val |= (1 << 10);
+               /* enable cont rd&mcinfo rd, manual start */
+               dim_RDMA_WR(DI_PRE_CTRL, reg_val);
+               dim_RDMA_WR_BITS(CONTRD_CTRL2, 0, 31, 1);
+               dim_RDMA_WR_BITS(CONT2RD_CTRL2, 0, 31, 1);
+               dim_RDMA_WR_BITS(MCINFRD_CTRL2, 0, 31, 1);
+       }
+}
+
+/*
+ * frame reset for pre which have nothing with encoder
+ * go field
+ */
+void dim_pre_frame_reset_g12(unsigned char madi_en,
+                            unsigned char mcdi_en)
+{
+       unsigned int reg_val = 0;
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) {
+               reset_pre_simple_rd_mif_g12(madi_en, mcdi_en);
+       } else {
+               reg_val = dim_RDMA_RD(DI_PRE_CTRL);
+               if (madi_en)
+                       reg_val |= (1 << 25);
+               if (mcdi_en)
+                       reg_val |= (1 << 10);
+               dim_RDMA_WR(DI_PRE_CTRL, reg_val);
+       }
+       /* reset simple mif which framereset not cover */
+       dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, 1, 14, 1);
+       dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, 1, 14, 1);
+       dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, 1, 14, 1);
+       dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, 1, 14, 1);
+
+       dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, 0, 14, 1);
+       dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, 0, 14, 1);
+       dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, 0, 14, 1);
+       dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, 0, 14, 1);
+
+       reg_val = 0xc3200000 | dimp_get(eDI_MP_line_num_pre_frst);
+       dim_RDMA_WR(DI_PRE_GL_CTRL, reg_val);
+       reg_val = 0x83200000 | dimp_get(eDI_MP_line_num_pre_frst);
+       dim_RDMA_WR(DI_PRE_GL_CTRL, reg_val);
+}
+
+/*
+ * frame + soft reset for the pre modules
+ */
+void dim_pre_frame_reset(void)
+{
+       dim_RDMA_WR_BITS(DI_PRE_CTRL, 3, 30, 2);
+}
+
+/*
+ * frame reset for post which have nothing with encoder
+ * go field
+ */
+void post_frame_reset_g12a(void)
+{
+       unsigned int reg_val = 0;
+
+       reg_val = (0xc0200000 | dimp_get(eDI_MP_line_num_post_frst));
+       dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val);
+       reg_val = (0x80200000 | dimp_get(eDI_MP_line_num_post_frst));
+       dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val);
+}
+
+void dim_post_read_reverse_irq(bool reverse, unsigned char mc_pre_flag,
+                              bool mc_enable)
+{
+       unsigned short flag_val = 1;
+
+       mc_pre_flag = dimp_get(eDI_MP_if2_disable) ? 1 : mc_pre_flag;
+       if (reverse) {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 3, 2, 2);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 3, 4, 2);
+               } else {
+                       dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0xf, 2, 4);
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0xf, 17, 4);
+               }
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2,    3, 2, 2);
+               dim_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0xf, 2, 4);
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2,  3, 2, 2);
+               if (mc_enable) {
+                       /* motion vector read reverse*/
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 1, 30, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 1, 30, 1);
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
+                               if (is_meson_txlx_cpu()) {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                       dimp_get(eDI_MP_pre_flag), 8, 2);
+                                       flag_val =
+                                       (dimp_get(eDI_MP_pre_flag) != 2) ?
+                                               0 : 1;
+                               } else {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                               mc_pre_flag, 8, 2);
+                                       flag_val = (mc_pre_flag != 2) ? 0 : 1;
+                               }
+                               dim_VSYNC_WR_MPEG_REG_BITS(
+                                       MCDI_MC_CRTL, flag_val, 11, 1);
+                               /* disable if2 for wave if1 case,
+                                *disable mc for pq issue
+                                */
+                               if (dimp_get(eDI_MP_if2_disable)) {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(
+                                               MCDI_MC_CRTL, 0, 11, 1);
+                                       dim_VSYNC_WR_MPEG_REG_BITS(
+                                               DI_IF2_GEN_REG, 0, 0, 1);
+                                       if (cpu_after_eq(
+                                               MESON_CPU_MAJOR_ID_GXLX))
+                                               dim_VSYNC_WR_MPEG_REG_BITS(
+                                                       MCDI_MC_CRTL, 0, 18, 1);
+                               }
+                       } else
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          mc_pre_flag, 8, 1);
+               }
+       } else {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 0, 2, 2);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 0, 4, 2);
+               } else {
+                       dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0, 2, 4);
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0, 17, 4);
+               }
+               dim_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2,  0, 2, 2);
+               dim_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0, 2, 4);
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+                       dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 0, 2, 2);
+               if (mc_enable) {
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 0, 30, 1);
+                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 0, 30, 1);
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
+                               if (is_meson_txlx_cpu()) {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                               dimp_get(eDI_MP_pre_flag),
+                                               8, 2);
+                                       flag_val =
+                                       (dimp_get(eDI_MP_pre_flag) != 2) ?
+                                       0 : 1;
+                               } else {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                               mc_pre_flag, 8, 2);
+                                       flag_val = (mc_pre_flag != 2) ? 0 : 1;
+                               }
+                               dim_VSYNC_WR_MPEG_REG_BITS(
+                                       MCDI_MC_CRTL, flag_val, 11, 1);
+                               /* disable if2 for wave if1 case */
+                               if (dimp_get(eDI_MP_if2_disable)) {
+                                       dim_VSYNC_WR_MPEG_REG_BITS(
+                                               MCDI_MC_CRTL, 0, 11, 1);
+                                       dim_VSYNC_WR_MPEG_REG_BITS(
+                                               DI_IF2_GEN_REG, 0, 0, 1);
+                                       if (cpu_after_eq(
+                                               MESON_CPU_MAJOR_ID_GXLX))
+                                               dim_VSYNC_WR_MPEG_REG_BITS(
+                                                       MCDI_MC_CRTL, 0, 18, 1);
+                               }
+                       } else
+                               dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL,
+                                                          mc_pre_flag, 8, 1);
+               }
+       }
+}
+
+void dim_set_power_control(unsigned char enable)
+{
+       ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1,
+               enable ? true : false);
+       ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+               enable ? true : false);
+}
+
+void dim_top_gate_control(bool top_en, bool mc_en)
+{
+       if (top_en) {
+               /* enable clkb input */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 0, 1);
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 15, 1);
+               /* enable slow clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, mc_en ? 1 : 0, 10, 1);
+               /* enable di arb */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 0, 2);
+       } else {
+               /* disable clkb input */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 0, 1);
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 15, 1);
+               /* disable slow clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 10, 1);
+               /* disable di arb */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 0, 2);
+       }
+}
+
+void dim_pre_gate_control(bool gate, bool mc_enable)
+{
+       if (gate) {
+               /* enable ma pre clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 8, 1);
+               /* enable mc clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 11, 1);
+               /* enable pd clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 2, 2);
+               /* enable motion clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 4, 2);
+               /* enable deband clk gate freerun for hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 6, 2);
+               /* enable input mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 16, 2);
+               /* enable mem mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 18, 2);
+               /* enable chan2 mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 20, 2);
+               /* enable nr wr mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 22, 2);
+               /* enable mtn wr mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 24, 2);
+               if (mc_enable) {
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+                               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 0, 12, 2);
+                       else
+                               /* enable me clk always run vlsi issue */
+                               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 3, 12, 2);
+                       /*
+                        * enable mc pre mv(wr) mcinfo w/r
+                        * mif external gate
+                        */
+                       dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1,
+                                          2, 26, 2);
+               }
+               /* cowork with auto gate to config reg */
+               dim_DI_Wr_reg_bits(DI_PRE_CTRL, 3, 2, 2);
+       } else {
+               /* disable ma pre clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 8, 1);
+               /* disable mc clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 11, 1);
+               /* disable pd clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 2, 2);
+               /* disable motion clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 4, 2);
+               /* disable deband clk gate freerun for hw issue */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 6, 2);
+               /* disable input mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 16, 2);
+               /* disable mem mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 18, 2);
+               /* disable chan2 mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 20, 2);
+               /* disable nr wr mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 22, 2);
+               /* disable mtn wr mif external gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 24, 2);
+               if (mc_enable) {
+                       /* disable mc pre mv(wr) mcinfo
+                        * w/r mif external gate
+                        */
+                       dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1,
+                                          1, 26, 2);
+                       /* disable me clk gate */
+                       dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 12, 2);
+               }
+       }
+}
+
+void dim_post_gate_control(bool gate)
+{
+       if (gate) {
+               /* enable clk post div */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 12, 1);
+               /* enable post line buf/fifo/mux clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 9, 1);
+               /* enable blend1 clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 0, 2);
+               /* enable ei clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 2, 2);
+               /* enable ei_0 clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 4, 2);
+       } else {
+               /* disable clk post div */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 12, 1);
+               /* disable post line buf/fifo/mux clk */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 9, 1);
+               /* disable blend1 clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 0, 2);
+               /* disable ei clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 2, 2);
+               /* disable ei_0 clk gate */
+               dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 4, 2);
+       }
+}
+
+static void di_async_reset(void)/*2019-01-17 add for debug*/
+{
+       /*wrmif async reset*/
+       dim_RDMA_WR_BITS(VIUB_SW_RESET, 1, 14, 1);
+       dim_RDMA_WR_BITS(VIUB_SW_RESET, 0, 14, 1);
+}
+
+static void di_pre_rst_frame(void)
+{
+       dim_RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | (1 << 31));
+}
+
+static void di_pre_nr_enable(bool on)
+{
+       if (on)
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 0, 1);
+       else
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1);
+}
+
+void dim_pre_nr_wr_done_sel(bool on)
+{
+       if (on) /*wait till response finish*/
+               dim_RDMA_WR_BITS(DI_CANVAS_URGENT0, 1, 8, 1);
+       else
+               dim_RDMA_WR_BITS(DI_CANVAS_URGENT0, 0, 0, 1);
+}
+
+void dim_rst_protect(bool on)
+{
+       if (on)
+               dim_RDMA_WR_BITS(DI_NRWR_Y, 1, 15, 1);
+       else
+               dim_RDMA_WR_BITS(DI_NRWR_Y, 0, 15, 1);
+}
+
+/*bit 10,12,16,18 [3:1]*/
+/*#define PRE_ID_MASK  (0x5140e) */
+#define PRE_ID_MASK    (0x51400)
+
+/*bit 8,10,14,16*/
+#define PRE_ID_MASK_TL1        (0x14500)
+
+static bool di_pre_idle(void)
+{
+       bool ret = false;
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if ((dim_RDMA_RD(DI_ARB_DBG_STAT_L1C1) &
+                       PRE_ID_MASK_TL1) == PRE_ID_MASK_TL1)
+                       ret = true;
+       } else {
+               if ((dim_RDMA_RD(DI_ARB_DBG_STAT_L1C1_OLD) &
+                       PRE_ID_MASK) == PRE_ID_MASK)
+                       ret = true;
+       }
+
+       return ret;
+}
+
+void dim_arb_sw(bool on)
+{
+       int i;
+       u32 REG_VPU_WRARB_REQEN_SLV_L1C1;
+       u32 REG_VPU_RDARB_REQEN_SLV_L1C1;
+       u32 REG_VPU_ARB_DBG_STAT_L1C1;
+       u32 WRARB_onval;
+       u32 WRARB_offval;
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               REG_VPU_WRARB_REQEN_SLV_L1C1 = DI_WRARB_REQEN_SLV_L1C1;
+               REG_VPU_RDARB_REQEN_SLV_L1C1 = DI_RDARB_REQEN_SLV_L1C1;
+               REG_VPU_ARB_DBG_STAT_L1C1 = DI_ARB_DBG_STAT_L1C1;
+               if (on)
+                       WRARB_onval = 0x3f;
+               else
+                       WRARB_offval = 0x3e;
+       } else {
+               REG_VPU_WRARB_REQEN_SLV_L1C1 = DI_WRARB_REQEN_SLV_L1C1_OLD;
+               REG_VPU_RDARB_REQEN_SLV_L1C1 = DI_RDARB_REQEN_SLV_L1C1_OLD;
+               REG_VPU_ARB_DBG_STAT_L1C1 = DI_ARB_DBG_STAT_L1C1_OLD;
+               if (on)
+                       WRARB_onval = 0x3f;
+               else
+                       WRARB_offval = 0x2b;
+       }
+
+       if (on) {
+               dim_RDMA_WR(REG_VPU_WRARB_REQEN_SLV_L1C1, WRARB_onval);
+               dim_RDMA_WR(REG_VPU_RDARB_REQEN_SLV_L1C1, 0xffff);
+       } else {
+               /*close arb:*/
+               dim_RDMA_WR(REG_VPU_WRARB_REQEN_SLV_L1C1, WRARB_offval);
+               dim_RDMA_WR(REG_VPU_RDARB_REQEN_SLV_L1C1, 0xf1f1);
+
+               di_pre_nr_enable(false); /*by Feijun*/
+               /*check status*/
+               if (!di_pre_idle()) {
+                       PR_ERR("%s:1:0x[%x]\n", __func__,
+                              dim_RDMA_RD(REG_VPU_ARB_DBG_STAT_L1C1));
+                       for (i = 0; i < 9; i++) {
+                               if (di_pre_idle())
+                                       break;
+                       }
+
+                       if (!di_pre_idle()) {
+                               di_pre_rst_frame();
+
+                               for (i = 0; i < 9; i++) {
+                                       if (di_pre_idle())
+                                               break;
+                               }
+                               if (!di_pre_idle())
+                                       PR_ERR("%s:2\n", __func__);
+                       }
+               }
+               if (di_pre_idle())
+                       di_async_reset();
+       }
+}
+
+/* keep 0x1700' bit8 bit9 bit11 bit28 : 1*/
+
+void dbg_set_DI_PRE_CTRL(void)
+{
+       unsigned int val;
+       unsigned int mask, tmp;
+
+       mask = 0x10000b00;
+
+       val = Rd(DI_PRE_CTRL);
+       tmp = (~mask) & val;
+       tmp = tmp | 0x10000000;
+
+       dim_DI_Wr(DI_PRE_CTRL, tmp);
+}
+
+/*************************************
+ *VIUB_SW_RESET's bits:
+ *     [1][2]
+ *     [10][11]
+ *     [12][13][14]
+ *     [16][17]
+ *     [27]
+ *     [28][31]
+ *     all bits set 1 and then set 0
+ *************************************/
+void di_async_reset2(void)/*2019-04-05 add for debug*/
+{
+       unsigned int mask, val1, val2, val3;
+
+       mask = 0x98037c06;
+       val1 = Rd(VIUB_SW_RESET);
+       val2 = val1 | mask;
+
+       dim_DI_Wr(VIUB_SW_RESET, val2);
+       val3 = val2 & (~mask);
+       dim_DI_Wr(VIUB_SW_RESET, val3);
+       pr_info("%s:0x%x,0x%x,0x%x\n", __func__, val1, val2, val3);
+}
+
+#define DI_NOP_REG1    (0x2fcb)
+#define DI_NOP_REG2    (0x2fcd)
+
+void h_dbg_reg_set(unsigned int val)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       enum eDI_PST_ST pst_st = pst->state;
+       unsigned int valb;
+
+       dim_DI_Wr(DI_NOP_REG1, val);
+
+       valb = pst_st;
+       if (pst->curr_ch)
+               valb = pst_st | 0x80000000;
+
+       dim_DI_Wr(DI_NOP_REG2, valb);
+}
+
+/*below for post */
+void post_mif_sw(bool on)
+{
+       if (on) {
+               dim_RDMA_WR_BITS(DI_IF0_GEN_REG, 1, 0, 1);
+               /*by feijun 2018-11-19*/
+               dim_RDMA_WR_BITS(DI_IF1_GEN_REG, 1, 0, 1);
+               /*by feijun 2018-11-19*/
+               dim_RDMA_WR_BITS(DI_IF2_GEN_REG, 1, 0, 1);
+
+               dim_RDMA_WR_BITS(DI_POST_CTRL, 1, 7, 1);
+       } else {
+               dim_RDMA_WR_BITS(DI_IF0_GEN_REG, 0, 0, 1);
+               /*by feijun 2018-11-19*/
+               dim_RDMA_WR_BITS(DI_IF1_GEN_REG, 0, 0, 1);
+               /*by feijun 2018-11-19*/
+               dim_RDMA_WR_BITS(DI_IF2_GEN_REG, 0, 0, 1);
+               dim_RDMA_WR_BITS(DI_POST_CTRL, 0, 7, 1);
+       }
+       dim_print("%s:%d\n", __func__, on);
+}
+
+void post_close_new(void)
+{
+       unsigned int data32;
+
+       post_mif_sw(false);
+       data32 = Rd(DI_INTR_CTRL);
+       /*intr_mode*/
+       dim_DI_Wr(DI_INTR_CTRL, (data32 & 0xffff0004) | (3 << 30));
+       di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP);  /*dbg a*/
+}
+
+/*asynchronous rest ,2018-11-19 from feijun: after set reset ,*/
+/*mif setting must set again*/
+void di_post_reset(void)
+{
+#if 0
+       0x2001 = 0x48300;
+       0x2001 = 0x0;
+       0x2002 = 0x30c1;
+       0x2002 = 0x0;
+
+       0x2001 = 0x483c0;
+       0x2001 = 0x0;
+       0x2002 = 0x3001;
+       0x2002 = 0x0;
+#endif
+       Wr(VIUB_SW_RESET, 0x483c0);
+       Wr(VIUB_SW_RESET, 0x0);
+
+       Wr(VIUB_SW_RESET0, 0x3001);
+       Wr(VIUB_SW_RESET0, 0x0);
+       pr_info("%s\n", __func__);
+}
+
+void post_dbg_contr(void)
+{
+       dim_RDMA_WR_BITS(DI_IF0_GEN_REG3, 1, 11, 1);
+       dim_RDMA_WR_BITS(DI_IF1_GEN_REG3, 1, 11, 1);
+       dim_RDMA_WR_BITS(DI_IF2_GEN_REG3, 1, 11, 1);
+}
+
+void di_post_set_flow(unsigned int post_wr_en, enum eDI_POST_FLOW step)
+{
+       unsigned int val;
+
+       if (!post_wr_en)
+               return;
+
+       switch (step) {
+       case eDI_POST_FLOW_STEP1_STOP:
+               /*val = (0xc0200000 | line_num_post_frst);*/
+               val = (0xc0000000 | 1);
+               dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, val);
+               break;
+       case eDI_POST_FLOW_STEP2_START:
+               /*val = (0x80200000 | line_num_post_frst);*/
+               val = (0x80200000 | 1);
+               dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, val);
+               break;
+       }
+}
+
+/*add 2019-04-25 for post crash debug*/
+void hpst_power_ctr(bool on)
+{
+       if (on) {
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       true);
+               dim_post_gate_control(true);
+               dimh_enable_di_post_mif(GATE_AUTO);
+       } else {
+               dimh_enable_di_post_mif(GATE_OFF);
+               dim_post_gate_control(false);
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       false);
+       }
+       pr_info("%s:%d\n", __func__, on);
+}
+
+void hpst_dbg_power_ctr_trig(unsigned int cmd)
+{
+       if (cmd)
+               hpst_power_ctr(true);
+       else
+               hpst_power_ctr(false);
+}
+
+void hpst_dbg_mem_pd_trig(unsigned int cmd)
+{
+       ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       false);
+       ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       true);
+/*     pr_info("%s\n", __func__);*/
+}
+
+void hpst_mem_pd_sw(unsigned int on)
+{
+       if (on)
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       true);
+       else
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST,
+                       false);
+}
+
+void hpst_vd1_sw(unsigned int on)
+{
+       if (on)
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1,
+                       true);
+       else
+               ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1,
+                       false);
+}
+
+void hpst_dbg_trig_gate(unsigned int cmd)
+{
+       dim_post_gate_control(false);
+       dim_post_gate_control(true);
+       pr_info("%s\n", __func__);
+}
+
+void hpst_dbg_trig_mif(unsigned int cmd)
+{
+       dimh_enable_di_post_mif(GATE_OFF);
+       dimh_enable_di_post_mif(GATE_AUTO);
+       pr_info("%s\n", __func__);
+}
+
+/**/
+/*
+ * enable/disable mc pre mif mcinfo&mv
+ */
+static void mc_pre_mif_ctrl_g12(bool enable)
+{
+       unsigned char mif_ctrl = 0;
+
+       mif_ctrl = enable ? 1 : 0;
+       /* enable mcinfo rd mif */
+       dim_RDMA_WR_BITS(DI_PRE_CTRL, mif_ctrl, 10, 1);
+       /* enable mv wr mif */
+       dim_RDMA_WR_BITS(MCVECWR_CTRL, mif_ctrl, 12, 1);
+       /* enable mcinfo wr mif */
+       dim_RDMA_WR_BITS(MCINFWR_CTRL, mif_ctrl, 12, 1);
+}
+
+static void mc_pre_mif_ctrl(bool enable)
+{
+       if (enable) {
+               /* gate clk */
+               dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 9, 1);
+               /* gate clk */
+               dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 9, 1);
+               /* mcinfo rd req en =1 */
+               dim_RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 1, 9, 1);
+               /* mv wr req en =1 */
+               dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 12, 1);
+               /* mcinfo wr req en =1 */
+               dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 12, 1);
+       } else {
+               /* no gate clk */
+               dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 9, 1);
+               /* no gate clk */
+               dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 9, 1);
+               /* mcvec wr req en =0 */
+               dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 12, 1);
+               /* mcinfo wr req en =0 */
+               dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 12, 1);
+               /* mcinfo rd req en = 0 */
+               dim_RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 0, 9, 1);
+       }
+}
+
+/*
+ * enable/disable madi pre mif, mtn&cont
+ */
+static void ma_pre_mif_ctrl_g12(bool enable)
+{
+       if (enable) {
+               /* enable cont wr mif */
+               dim_RDMA_WR_BITS(CONTWR_CTRL, 1, 12, 1);
+               /* enable mtn wr mif */
+               dim_RDMA_WR_BITS(MTNWR_CTRL, 1, 12, 1);
+               /* enable cont rd mif */
+       } else {
+               dim_RDMA_WR_BITS(MTNWR_CTRL, 0, 12, 1);
+               dim_RDMA_WR_BITS(CONTWR_CTRL, 0, 12, 1);
+               /* disable cont rd */
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1);
+       }
+}
+
+/*
+ * use logic enable/disable replace mif
+ */
+static void ma_pre_mif_ctrl(bool enable)
+{
+       if (!enable) {
+               /* mtn wr req en =0 */
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 1, 1);
+               /* cont wr req en =0 */
+               dim_RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1);
+               /* disable cont rd */
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1);
+       }
+}
+
+/*
+ * enable/disable inp&chan2&mem&nrwr mif
+ */
+static void di_pre_data_mif_ctrl(bool enable)
+{
+       if (enable) {
+               /* enable input mif*/
+               dim_DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) | 0x1);
+               dim_DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) | 0x1);
+               #if 0
+               if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1) {
+                       DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1);
+                       dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 1, 8, 1);
+               } else {
+                       DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1);
+                       dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1);
+               }
+               #else
+               if (afbc_is_used()) {
+                       dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1);
+                       afbc_input_sw(true);
+               } else {
+                       dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1);
+                       afbc_input_sw(false);
+               }
+               #endif
+               /* nrwr no clk gate en=0 */
+               /*dim_RDMA_WR_BITS(DI_NRWR_CTRL, 0, 24, 1);*/
+       } else {
+               /* nrwr no clk gate en=1 */
+               /*dim_RDMA_WR_BITS(DI_NRWR_CTRL, 1, 24, 1);*/
+               /* nr wr req en =0 */
+               dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1);
+               /* disable input mif*/
+               dim_DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) & ~0x1);
+               dim_DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) & ~0x1);
+               dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1);
+               #if 0
+               /* disable AFBC input */
+               if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1)
+                       dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1);
+               #else
+               /* disable AFBC input */
+               if (afbc_is_used())
+                       afbc_input_sw(false);
+
+               #endif
+       }
+}
+
+static atomic_t mif_flag;
+void dimh_enable_di_pre_mif(bool en, bool mc_enable)
+{
+       if (atomic_read(&mif_flag))
+               return;
+
+       if (dimp_get(eDI_MP_pre_mif_gate) && !en)
+               return;
+       atomic_set(&mif_flag, 1);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
+               if (mc_enable)
+                       mc_pre_mif_ctrl_g12(en);
+               ma_pre_mif_ctrl_g12(en);
+       } else {
+               if (mc_enable)
+                       mc_pre_mif_ctrl(en);
+               ma_pre_mif_ctrl(en);
+       }
+       di_pre_data_mif_ctrl(en);
+       atomic_set(&mif_flag, 0);
+}
+
+void dimh_combing_pd22_window_config(unsigned int width, unsigned int height)
+{
+       unsigned short y1 = 39, y2 = height - 41;
+
+       if (height >= 540) {
+               y1 = 79;
+               y2 = height - 81;
+       }
+       if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) {
+               dim_DI_Wr_reg_bits(DECOMB_WIND00, 0, 16, 13);/* dcomb x0 */
+               /* dcomb x1 */
+               dim_DI_Wr_reg_bits(DECOMB_WIND00, (width - 1), 0, 13);
+               dim_DI_Wr_reg_bits(DECOMB_WIND01, 0, 16, 13);/* dcomb y0 */
+               dim_DI_Wr_reg_bits(DECOMB_WIND01, y1, 0, 13);/* dcomb y1 */
+               dim_DI_Wr_reg_bits(DECOMB_WIND10, 0, 16, 13);/* dcomb x0 */
+               /* dcomb x1 */
+               dim_DI_Wr_reg_bits(DECOMB_WIND10, (width - 1), 0, 13);
+               /* dcomb y0 */
+               dim_DI_Wr_reg_bits(DECOMB_WIND11, (y1 + 1), 16, 13);
+               dim_DI_Wr_reg_bits(DECOMB_WIND11, y2, 0, 13);/* dcomb y1 */
+       }
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, 0, 0, 13);/* pd22 x0 */
+       /* pd22 x1 */
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, (width - 1), 16, 13);
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, 0, 0, 13);/* pd22 y0 */
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, y1, 16, 13);/* pd y1 */
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, 0, 0, 13);/* pd x0 */
+       /* pd x1 */
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, (width - 1), 16, 13);
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, (y1 + 1), 0, 13);/* pd y0 */
+       dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, y2, 16, 13);/* pd y2 */
+}
+
+void dimh_pulldown_vof_win_config(struct pulldown_detected_s *wins)
+{
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y,
+               wins->regs[0].win_vs, 17, 12);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y,
+               wins->regs[0].win_ve, 1, 12);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y,
+               wins->regs[1].win_vs, 17, 12);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y,
+               wins->regs[1].win_ve, 1, 12);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y,
+               wins->regs[2].win_vs, 17, 12);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y,
+               wins->regs[2].win_ve, 1, 12);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y,
+               wins->regs[3].win_vs, 17, 12);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y,
+               wins->regs[3].win_ve, 1, 12);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               (wins->regs[0].win_ve > wins->regs[0].win_vs)
+               ? 1 : 0, 16, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               wins->regs[0].blend_mode, 8, 2);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               (wins->regs[1].win_ve > wins->regs[1].win_vs)
+               ? 1 : 0, 17, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               wins->regs[1].blend_mode, 10, 2);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               (wins->regs[2].win_ve > wins->regs[2].win_vs)
+               ? 1 : 0, 18, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               wins->regs[2].blend_mode, 12, 2);
+
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+               (wins->regs[3].win_ve > wins->regs[3].win_vs)
+               ? 1 : 0, 19, 1);
+       dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL,
+                                  wins->regs[3].blend_mode, 14, 2);
+}
+
+void dimh_load_regs(struct di_pq_parm_s *di_pq_ptr)
+{
+       unsigned int i = 0, j = 0, addr = 0, value = 0, mask = 0, len;
+       unsigned int table_name = 0, nr_table = 0;
+       bool ctrl_reg_flag = false;
+       struct am_reg_s *regs_p = NULL;
+
+       if (dimp_get(eDI_MP_pq_load_dbg) == 1)
+               return;
+       if (dimp_get(eDI_MP_pq_load_dbg) == 2)
+               pr_info("[DI]%s hw load 0x%x pq table len %u.\n",
+                       __func__, di_pq_ptr->pq_parm.table_name,
+                       di_pq_ptr->pq_parm.table_len);
+       if (PTR_RET(di_pq_ptr->regs)) {
+               PR_ERR("[DI] table ptr error.\n");
+               return;
+       }
+       pr_info("[DI]%s hw load 0x%x pq table len %u.\n",
+               __func__, di_pq_ptr->pq_parm.table_name,
+               di_pq_ptr->pq_parm.table_len);
+       nr_table = TABLE_NAME_NR | TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO;
+       regs_p = (struct am_reg_s *)di_pq_ptr->regs;
+       len = di_pq_ptr->pq_parm.table_len;
+       table_name = di_pq_ptr->pq_parm.table_name;
+       for (i = 0; i < len; i++) {
+               ctrl_reg_flag = false;
+               addr = regs_p->addr;
+               value = regs_p->val;
+               mask = regs_p->mask;
+               if (dimp_get(eDI_MP_pq_load_dbg) == 2)
+                       pr_info("[%u][0x%x] = [0x%x]&[0x%x]\n",
+                               i, addr, value, mask);
+
+               for (j = 0; j < SKIP_CTRE_NUM; j++) {
+                       if (addr == ctrl_regs[j])
+                       break;
+               }
+
+               if (regs_p->mask != 0xffffffff) {
+                       value = ((Rd(addr) & (~(mask))) |
+                               (value & mask));
+               }
+               regs_p++;
+               if (j < SKIP_CTRE_NUM) {
+                       if (dimp_get(eDI_MP_pq_load_dbg) == 3)
+                               pr_info("%s skip [0x%x]=[0x%x].\n",
+                                       __func__, addr, value);
+                       continue;
+               }
+               if (table_name & nr_table)
+                       ctrl_reg_flag
+                       = get_ops_nr()->set_nr_ctrl_reg_table(addr, value);
+
+               if (!ctrl_reg_flag)
+                       dim_DI_Wr(addr, value);
+               if (dimp_get(eDI_MP_pq_load_dbg) == 2)
+                       pr_info("[%u][0x%x] = [0x%x] %s\n", i, addr,
+                               value, Rd(addr) != value ? "fail" : "success");
+       }
+}
+
+/*note:*/
+/*     function: patch for txl for progressive source  */
+/*             480p/576p/720p from hdmi will timeout   */
+/*     prog_flg: in:   1:progressive;                  */
+/*     cnt:    in:     di_pre_stru.field_count_for_cont*/
+/*     mc_en:  in:     mcpre_en*/
+void dimh_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en)
+{
+       unsigned int di_mtn_1_ctrl1 = 0; /*ary add tmp*/
+
+       if (!prog_flg || !is_meson_txl_cpu())
+               return;
+
+       /*printk("prog patch\n");*/
+       if (cnt >= 3) {
+               di_mtn_1_ctrl1 |= 1 << 29;/* enable txt */
+
+               if (mc_en) {
+                       dim_RDMA_WR(DI_MTN_CTRL1,
+                                   (0xffffcfff & dim_RDMA_RD(DI_MTN_CTRL1)));
+
+                       /* enable me(mc di) */
+                       if (cnt == 4) {
+                               di_mtn_1_ctrl1 &= (~(1 << 30));
+                               /* enable contp2rd and contprd */
+                               dim_RDMA_WR(MCDI_MOTINEN, 1 << 1 | 1);
+                       }
+                       if (cnt == 5)
+                               dim_RDMA_WR(MCDI_CTRL_MODE, 0x1bfff7ff);
+               }
+       } else {
+               if (mc_en) {
+                       /* txtdet_en mode */
+                       dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 1, 1);
+                       dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 9, 1);
+                       dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 16, 1);
+                       dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 28, 1);
+                       dim_RDMA_WR(MCDI_MOTINEN, 0);
+                       dim_RDMA_WR(DI_MTN_CTRL1,
+                                   (0xffffcfff & dim_RDMA_RD(DI_MTN_CTRL1)));
+                       /* disable me(mc di) */
+               }
+               dim_RDMA_WR(DNR_CTRL, 0);
+       }
+       dim_RDMA_WR(DI_MTN_1_CTRL1, di_mtn_1_ctrl1);
+}
+
+void dim_init_setting_once(void)
+{
+       if (di_get_flg_hw_int())
+               return;
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX))
+               dim_wr_cue_int();
+
+       di_set_flg_hw_int(true);
+}
+
+int dim_seq_file_module_para_hw(struct seq_file *seq)
+{
+       seq_puts(seq, "hw---------------\n");
+#if 0
+       seq_printf(seq, "%-15s:%d\n", "pq_load_dbg", pq_load_dbg);
+       seq_printf(seq, "%-15s:%d\n", "lmv_lock_win_en", lmv_lock_win_en);
+       seq_printf(seq, "%-15s:%d\n", "lmv_dist", lmv_dist);
+       seq_printf(seq, "%-15s:%d\n", "pr_mcinfo_cnt", pr_mcinfo_cnt);
+       seq_printf(seq, "%-15s:%d\n", "offset_lmv", offset_lmv);
+       seq_printf(seq, "%-15s:%d\n", "post_ctrl", post_ctrl);
+       seq_printf(seq, "%-15s:%d\n", "if2_disable", if2_disable);
+       seq_printf(seq, "%-15s:%d\n", "pre_flag", pre_flag);
+
+       seq_printf(seq, "%-15s:%d\n", "pre_mif_gate", pre_mif_gate);
+       seq_printf(seq, "%-15s:%d\n", "pre_urgent", pre_urgent);
+       seq_printf(seq, "%-15s:%d\n", "pre_hold_line", pre_hold_line);
+       seq_printf(seq, "%-15s:%d\n", "pre_ctrl, uint", pre_ctrl);
+       seq_printf(seq, "%-15s:%d\n", "line_num_post_frst",
+                  line_num_post_frst);
+       seq_printf(seq, "%-15s:%d\n", "line_num_pre_frst", line_num_pre_frst);
+       seq_printf(seq, "%-15s:%d\n", "pd22_flg_calc_en", pd22_flg_calc_en);
+
+       /***********************/
+       seq_printf(seq, "%-15s:%d\n", "mcen_mode", mcen_mode);
+       seq_printf(seq, "%-15s:%d\n", "mcuv_en", mcuv_en);
+       seq_printf(seq, "%-15s:%d\n", "mcdebug_mode", mcdebug_mode);
+       seq_printf(seq, "%-15s:%d\n", "pldn_ctrl_rflsh", pldn_ctrl_rflsh);
+#endif
+       return 0;
+}
+
diff --git a/drivers/amlogic/media/di_multi/deinterlace_hw.h b/drivers/amlogic/media/di_multi/deinterlace_hw.h
new file mode 100644 (file)
index 0000000..ed00b85
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * drivers/amlogic/media/di_multi/deinterlace_hw.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _DI_HW_H
+#define _DI_HW_H
+#include <linux/amlogic/media/amvecm/amvecm.h>
+
+#include "../deinterlace/di_pqa.h"
+
+/* if post size < 80, filter of ei can't work */
+#define MIN_POST_WIDTH 80
+#define MIN_BLEND_WIDTH        27
+
+#define        SKIP_CTRE_NUM   13
+/*move from deinterlace.c*/
+enum eAFBC_REG {
+       eAFBC_ENABLE,
+       eAFBC_MODE,
+       eAFBC_SIZE_IN,
+       eAFBC_DEC_DEF_COLOR,
+       eAFBC_CONV_CTRL,
+       eAFBC_LBUF_DEPTH,
+       eAFBC_HEAD_BADDR,
+       eAFBC_BODY_BADDR,
+       eAFBC_SIZE_OUT,
+       eAFBC_OUT_YSCOPE,
+       eAFBC_STAT,
+       eAFBC_VD_CFMT_CTRL,
+       eAFBC_VD_CFMT_W,
+       eAFBC_MIF_HOR_SCOPE,
+       eAFBC_MIF_VER_SCOPE,
+       eAFBC_PIXEL_HOR_SCOPE,
+       eAFBC_PIXEL_VER_SCOPE,
+       eAFBC_VD_CFMT_H,
+};
+
+enum eAFBC_DEC {
+       eAFBC_DEC0,
+       eAFBC_DEC1,
+};
+
+#define AFBC_REG_INDEX_NUB     (18)
+#define AFBC_DEC_NUB           (2)
+
+struct DI_MIF_s {
+       unsigned short  luma_x_start0;
+       unsigned short  luma_x_end0;
+       unsigned short  luma_y_start0;
+       unsigned short  luma_y_end0;
+       unsigned short  chroma_x_start0;
+       unsigned short  chroma_x_end0;
+       unsigned short  chroma_y_start0;
+       unsigned short  chroma_y_end0;
+       unsigned int    nocompress;
+       unsigned                set_separate_en:2;
+       unsigned                src_field_mode:1;
+       unsigned                src_prog:1;
+       unsigned                video_mode:1;
+       unsigned                output_field_num:1;
+       unsigned                bit_mode:2;
+       /*
+        * unsigned             burst_size_y:2; set 3 as default
+        * unsigned             burst_size_cb:2;set 1 as default
+        * unsigned             burst_size_cr:2;set 1 as default
+        */
+       unsigned                canvas0_addr0:8;
+       unsigned                canvas0_addr1:8;
+       unsigned                canvas0_addr2:8;
+};
+
+struct DI_SIM_MIF_s {
+       unsigned short  start_x;
+       unsigned short  end_x;
+       unsigned short  start_y;
+       unsigned short  end_y;
+       unsigned short  canvas_num;
+       unsigned short  bit_mode;
+};
+
+struct DI_MC_MIF_s {
+       unsigned short start_x;
+       unsigned short start_y;
+       unsigned short end_y;
+       unsigned short size_x;
+       unsigned short size_y;
+       unsigned short canvas_num;
+       unsigned short blend_en;
+       unsigned short vecrd_offset;
+};
+
+enum gate_mode_e {
+       GATE_AUTO,
+       GATE_ON,
+       GATE_OFF,
+};
+
+struct mcinfo_lmv_s {
+       unsigned char   lock_flag;
+       char            lmv;
+       unsigned short  lock_cnt;
+};
+
+struct di_pq_parm_s {
+       struct am_pq_parm_s pq_parm;
+       struct am_reg_s *regs;
+       struct list_head list;
+};
+
+void dim_read_pulldown_info(unsigned int *glb_frm_mot_num,
+                           unsigned int *glb_fid_mot_num);
+
+#if 0
+
+void read_new_pulldown_info(struct FlmModReg_t *pFMRegp);
+#endif
+void dim_pulldown_info_clear_g12a(void);
+void dimh_combing_pd22_window_config(unsigned int width, unsigned int height);
+void dimh_hw_init(bool pulldown_en, bool mc_enable);
+void dimh_hw_uninit(void);
+void dimh_enable_di_pre_aml(struct DI_MIF_s    *di_inp_mif,
+                           struct DI_MIF_s     *di_mem_mif,
+                           struct DI_MIF_s     *di_chan2_mif,
+                           struct DI_SIM_MIF_s *di_nrwr_mif,
+                           struct DI_SIM_MIF_s *di_mtnwr_mif,
+                           struct DI_SIM_MIF_s *di_contp2rd_mif,
+                           struct DI_SIM_MIF_s *di_contprd_mif,
+                           struct DI_SIM_MIF_s *di_contwr_mif,
+                           unsigned char madi_en,
+                           unsigned char pre_field_num,
+                           unsigned char pre_vdin_link);
+void dimh_enable_afbc_input(struct vframe_s *vf);
+
+void dimh_mc_pre_mv_irq(void);
+void dimh_enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif,
+                          struct DI_MC_MIF_s *di_mcinfowr_mif,
+                          struct DI_MC_MIF_s *di_mcvecwr_mif,
+                          unsigned char mcdi_en);
+void dimh_enable_mc_di_pre_g12(struct DI_MC_MIF_s *di_mcinford_mif,
+                              struct DI_MC_MIF_s *di_mcinfowr_mif,
+                              struct DI_MC_MIF_s *di_mcvecwr_mif,
+                              unsigned char mcdi_en);
+
+void dimh_enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif,
+                           int urgent, bool reverse, int invert_mv);
+void dimh_enable_mc_di_post_g12(struct DI_MC_MIF_s *di_mcvecrd_mif,
+                               int urgent, bool reverse, int invert_mv);
+
+void dimh_disable_post_deinterlace_2(void);
+void dimh_initial_di_post_2(int hsize_post, int vsize_post,
+                           int hold_line, bool write_en);
+void dimh_enable_di_post_2(
+       struct DI_MIF_s         *di_buf0_mif,
+       struct DI_MIF_s         *di_buf1_mif,
+       struct DI_MIF_s         *di_buf2_mif,
+       struct DI_SIM_MIF_s     *di_diwr_mif,
+       struct DI_SIM_MIF_s     *di_mtnprd_mif,
+       int ei_en, int blend_en, int blend_mtn_en, int blend_mode,
+       int di_vpp_en, int di_ddr_en,
+       int post_field_num, int hold_line, int urgent,
+       int invert_mv, int vskip_cnt
+);
+void dimh_post_switch_buffer(
+       struct DI_MIF_s         *di_buf0_mif,
+       struct DI_MIF_s         *di_buf1_mif,
+       struct DI_MIF_s         *di_buf2_mif,
+       struct DI_SIM_MIF_s     *di_diwr_mif,
+       struct DI_SIM_MIF_s     *di_mtnprd_mif,
+       struct DI_MC_MIF_s      *di_mcvecrd_mif,
+       int ei_en, int blend_en, int blend_mtn_en, int blend_mode,
+       int di_vpp_en, int di_ddr_en,
+       int post_field_num, int hold_line, int urgent,
+       int invert_mv, bool pd_en, bool mc_enable,
+       int vskip_cnt
+);
+void dim_post_read_reverse_irq(bool reverse,
+                              unsigned char mc_pre_flag, bool mc_enable);
+void dim_top_gate_control(bool top_en, bool mc_en);
+void dim_pre_gate_control(bool enable, bool mc_enable);
+void dim_post_gate_control(bool gate);
+void dim_set_power_control(unsigned char enable);
+void dim_hw_disable(bool mc_enable);
+void dimh_enable_di_pre_mif(bool enable, bool mc_enable);
+void dimh_enable_di_post_mif(enum gate_mode_e mode);
+
+void dimh_combing_pd22_window_config(unsigned int width, unsigned int height);
+void dimh_calc_lmv_init(void);
+void dimh_calc_lmv_base_mcinfo(unsigned int vf_height,
+                              unsigned long mcinfo_adr,
+                              unsigned int mcinfo_size);
+void dimh_init_field_mode(unsigned short height);
+void dim_film_mode_win_config(unsigned int width, unsigned int height);
+void dimh_pulldown_vof_win_config(struct pulldown_detected_s *wins);
+void dimh_load_regs(struct di_pq_parm_s *di_pq_ptr);
+void dim_pre_frame_reset_g12(unsigned char madi_en, unsigned char mcdi_en);
+void dim_pre_frame_reset(void);
+void dimh_interrupt_ctrl(unsigned char ma_en,
+                        unsigned char det3d_en, unsigned char nrds_en,
+                        unsigned char post_wr, unsigned char mc_en);
+void dimh_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en);
+bool dimh_afbc_is_supported(void);
+
+void dimh_afbc_reg_sw(bool on);
+
+void dump_vd2_afbc(void);
+
+u8 *dim_vmap(ulong addr, u32 size, bool *bflg);
+void dim_unmap_phyaddr(u8 *vaddr);
+int dim_print(const char *fmt, ...);
+
+#define DI_MC_SW_OTHER (1 << 0)
+#define DI_MC_SW_REG   (1 << 1)
+/*#define DI_MC_SW_POST        (1 << 2)*/
+#define DI_MC_SW_IC    (1 << 2)
+
+#define DI_MC_SW_ON_MASK       (DI_MC_SW_REG | DI_MC_SW_OTHER | DI_MC_SW_IC)
+
+void dimh_patch_post_update_mc(void);
+void dimh_patch_post_update_mc_sw(unsigned int cmd, bool on);
+
+void dim_rst_protect(bool on);
+void dim_pre_nr_wr_done_sel(bool on);
+void dim_arb_sw(bool on);
+void dbg_set_DI_PRE_CTRL(void);
+void di_async_reset2(void);    /*2019-04-05 add for debug*/
+
+enum DI_HW_POST_CTRL {
+       DI_HW_POST_CTRL_INIT,
+       DI_HW_POST_CTRL_RESET,
+};
+
+void dimh_post_ctrl(enum DI_HW_POST_CTRL contr,
+                   unsigned int post_write_en);
+void dimh_int_ctr(unsigned int set_mod, unsigned char ma_en,
+                 unsigned char det3d_en, unsigned char nrds_en,
+                 unsigned char post_wr, unsigned char mc_en);
+
+void h_dbg_reg_set(unsigned int val);
+
+enum eDI_POST_FLOW {
+       eDI_POST_FLOW_STEP1_STOP,
+       eDI_POST_FLOW_STEP2_START,
+/*     eDI_POST_FLOW_STEP3_RESET_INT,*/
+};
+
+void di_post_set_flow(unsigned int post_wr_en, enum eDI_POST_FLOW step);
+void post_mif_sw(bool on);
+void post_dbg_contr(void);
+void post_close_new(void);
+void di_post_reset(void);
+void dimh_pst_trig_resize(void);
+
+void hpst_power_ctr(bool on);
+void hpst_dbg_power_ctr_trig(unsigned int cmd);
+void hpst_dbg_mem_pd_trig(unsigned int cmd);
+void hpst_dbg_trig_gate(unsigned int cmd);
+void hpst_dbg_trig_mif(unsigned int cmd);
+void hpst_mem_pd_sw(unsigned int on);
+void hpst_vd1_sw(unsigned int on);
+
+void dim_init_setting_once(void);
+void dim_hw_init_reg(void);
+
+#endif
diff --git a/drivers/amlogic/media/di_multi/di_api.c b/drivers/amlogic/media/di_multi/di_api.c
new file mode 100644 (file)
index 0000000..554bdf1
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * drivers/amlogic/media/di_multi/di_api.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/amlogic/media/vpu/vpu.h>
+
+#include "di_api.h"
+/**********************************
+ * DI api is used for other module
+ *********************************/
+static const struct di_ext_ops di_ext = {
+       .di_post_reg_rd             = l_DI_POST_REG_RD,
+       .di_post_wr_reg_bits        = l_DI_POST_WR_REG_BITS,
+};
+
+void dim_attach_to_local(void)
+{
+       dil_attach_ext_api(&di_ext);
+}
+
+bool dim_attach_ext_api(struct di_ext_ops *di_api)
+{
+       #if 1
+       if (!di_api)
+               return false;
+
+       memcpy(di_api, &di_ext, sizeof(struct di_ext_ops));
+       #else
+       di_api = &di_ext;
+       #endif
+       return true;
+}
+
+/*EXPORT_SYMBOL(dim_attach_ext_api);*/
+
+/**********************************
+ * ext_api used by DI
+ ********************************/
+#define ARY_TEMP2
+#ifdef ARY_TEMP2
+void ext_switch_vpu_mem_pd_vmod(unsigned int vmod, bool on)
+{
+       switch_vpu_mem_pd_vmod(vmod,
+                              on ? VPU_MEM_POWER_ON : VPU_MEM_POWER_DOWN);
+}
+
+const struct ext_ops_s ext_ops = {
+       .switch_vpu_mem_pd_vmod         = ext_switch_vpu_mem_pd_vmod,
+       /*no use ?*/
+/*     .vf_get_receiver_name           = vf_get_receiver_name,*/
+       .switch_vpu_clk_gate_vmod       = switch_vpu_clk_gate_vmod,
+       .get_current_vscale_skip_count  = get_current_vscale_skip_count,
+       .canvas_pool_alloc_canvas_table = canvas_pool_alloc_canvas_table,
+};
+
+#else
+void n_switch_vpu_mem_pd_vmod(unsigned int vmod, bool on)
+{
+}
+
+char *n_vf_get_receiver_name(const char *provider_name)
+{
+       return "";
+}
+
+void n_switch_vpu_clk_gate_vmod(unsigned int vmod, int flag)
+{
+}
+
+int n_get_current_vscale_skip_count(struct vframe_s *vf)
+{
+       return 0;
+}
+
+u32 n_canvas_pool_alloc_canvas_table(const char *owner, u32 *tab,
+                                    int size,
+                                    enum canvas_map_type_e type)
+{
+       return 0;
+}
+
+const struct ext_ops_s ext_ops = {
+       .switch_vpu_mem_pd_vmod         = n_switch_vpu_mem_pd_vmod,
+       .vf_get_receiver_name           = n_vf_get_receiver_name,
+       .switch_vpu_clk_gate_vmod       = n_switch_vpu_clk_gate_vmod,
+       .get_current_vscale_skip_count  = n_get_current_vscale_skip_count,
+       .canvas_pool_alloc_canvas_table = n_canvas_pool_alloc_canvas_table,
+};
+
+#endif
+
diff --git a/drivers/amlogic/media/di_multi/di_api.h b/drivers/amlogic/media/di_multi/di_api.h
new file mode 100644 (file)
index 0000000..0cd08de
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * drivers/amlogic/media/di_multi/di_api.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_API_H__
+#define __DI_API_H__
+
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "../di_local/di_local.h"
+
+/*--------------------------*/
+unsigned int l_DI_POST_REG_RD(unsigned int addr);
+int l_DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len);
+
+/*--------------------------*/
+bool di_attach_ext_api(struct di_ext_ops *di_api);
+
+/*attach di_ops to di_local*/
+bool dil_attach_ext_api(const struct di_ext_ops *di_api);
+void dim_attach_to_local(void);
+
+/*--------------------------*/
+int get_current_vscale_skip_count(struct vframe_s *vf);
+
+struct ext_ops_s {
+       void (*switch_vpu_mem_pd_vmod)(unsigned int vmod, bool on);
+/*     char *(*vf_get_receiver_name)(const char *provider_name);*/
+       void (*switch_vpu_clk_gate_vmod)(unsigned int vmod, int flag);
+       int (*get_current_vscale_skip_count)(struct vframe_s *vf);
+       u32 (*canvas_pool_alloc_canvas_table)(const char *owner, u32 *tab,
+                                             int size,
+                                             enum canvas_map_type_e type);
+};
+
+extern const struct ext_ops_s ext_ops;
+
+/*--------------------------*/
+void dil_get_rev_mem(unsigned long *mstart, unsigned int *msize);
+void dil_get_flg(unsigned int *flg);
+
+#endif /*__DI_API_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_data.h b/drivers/amlogic/media/di_multi/di_data.h
new file mode 100644 (file)
index 0000000..d9ddb8f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * drivers/amlogic/media/di_multi/di_data.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_DATA_H__
+#define __DI_DATA_H__
+
+#endif /*__DI_DATA_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_data_l.h b/drivers/amlogic/media/di_multi/di_data_l.h
new file mode 100644 (file)
index 0000000..82a6682
--- /dev/null
@@ -0,0 +1,1372 @@
+/*
+ * drivers/amlogic/media/di_multi/di_data_l.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_DATA_L_H__
+#define __DI_DATA_L_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/kfifo.h>       /*ary add*/
+
+#include "../deinterlace/di_pqa.h"
+
+#define DI_CHANNEL_NUB (2)
+#define DI_CHANNEL_MAX  (4)
+
+#define TABLE_FLG_END  (0xfffffffe)
+#define TABLE_LEN_MAX  (1000)
+#define F_IN(x, a, b)  (((x) > (a)) && ((x) < (b)))
+#define COM_M(m, a, b) (((a) & (m)) == ((b) & (m)))
+#define COM_MV(a, m, v)        (((a) & (m)) == (v))
+#define COM_ME(a, m)   (((a) & (m)) == (m))
+
+#define DI_BIT0                0x01
+#define DI_BIT1                0x02
+#define DI_BIT2                0x04
+#define DI_BIT3                0x08
+
+/*****************************************
+ *
+ * vframe mask
+ *
+ *****************************************/
+
+#define DI_VFM_T_MASK_CHANGE           \
+       (VIDTYPE_VIU_422                \
+       | VIDTYPE_VIU_SINGLE_PLANE      \
+       | VIDTYPE_VIU_444               \
+       | VIDTYPE_INTERLACE             \
+       | VIDTYPE_COMPRESS              \
+       | VIDTYPE_MVC)
+
+/* ************************************** */
+/* *************** cfg top ************** */
+/* ************************************** */
+/* also see: di_cfg_top_ctr*/
+enum eDI_CFG_TOP_IDX {
+       /* cfg for top */
+       eDI_CFG_BEGIN,
+       eDI_CFG_first_bypass,
+       eDI_CFG_ref_2,
+       eDI_CFG_END,
+
+};
+
+#define K_DI_CFG_NUB   (eDI_CFG_END - eDI_CFG_BEGIN + 1)
+struct di_cfg_ctr_s {
+       char *name;
+       enum eDI_CFG_TOP_IDX id;
+       bool    default_val;
+};
+
+/* ************************************** */
+/* *************** cfg x *************** */
+/* ************************************** */
+/*also see di_cfgx_ctr*/
+enum eDI_CFGX_IDX {
+       /* cfg channel x*/
+       eDI_CFGX_BEGIN,
+       eDI_CFGX_BYPASS_ALL,    /*bypass_all*/
+       eDI_CFGX_END,
+
+       /* debug cfg x */
+       eDI_DBG_CFGX_BEGIN,
+       eDI_DBG_CFGX_IDX_VFM_IN,
+       eDI_DBG_CFGX_IDX_VFM_OT,
+       eDI_DBG_CFGX_END,
+};
+
+#define K_DI_CFGX_NUB  (eDI_DBG_CFGX_END - eDI_CFGX_BEGIN + 1)
+
+struct di_cfgx_ctr_s {
+       char *name;
+       enum eDI_CFGX_IDX id;
+       bool    default_val;
+};
+
+/* ****************************** */
+enum eDI_SUB_ID {
+       DI_SUB_ID_S0,   /*DI_SUB_ID_MARST,*/
+       DI_SUB_ID_S1,
+       DI_SUB_ID_S2,
+       DI_SUB_ID_S3,
+       /*DI_SUB_ID_NUB,*/
+};
+
+/*debug vframe type */
+struct di_vframe_type_info {
+       char *name;
+       unsigned int mask;
+       char *other;
+};
+
+struct di_dbg_datax_s {
+       struct vframe_s vfm_input;      /*debug input vframe*/
+       struct vframe_s *pfm_out;       /*debug di_get vframe*/
+
+};
+
+/*debug function*/
+enum eDI_DBG_F {
+       eDI_DBG_F_00,
+       eDI_DBG_F_01,
+       eDI_DBG_F_02,
+       eDI_DBG_F_03,
+       eDI_DBG_F_04,
+       eDI_DBG_F_05,
+       eDI_DBG_F_06,
+       eDI_DBG_F_07,
+       eDI_DBG_F_08,
+};
+
+struct di_dbg_func_s {
+       enum eDI_DBG_F index;
+       void (*func)(unsigned int para);
+       char *name;
+       char *info;
+};
+
+/*register*/
+struct reg_t {
+       unsigned int add;
+       unsigned int bit;
+       unsigned int wid;
+/*     unsigned int id;*/
+       unsigned int df_val;
+       char *name;
+       char *bname;
+       char *info;
+};
+
+struct reg_acc {
+       void (*wr)(unsigned int adr, unsigned int val);
+       unsigned int (*rd)(unsigned int adr);
+       unsigned int (*bwr)(unsigned int adr, unsigned int val,
+                           unsigned int start, unsigned int len);
+       unsigned int (*brd)(unsigned int adr, unsigned int start,
+                           unsigned int len);
+};
+
+/**************************************/
+/* time out */
+/**************************************/
+
+enum eDI_TOUT_CONTR {
+/*     eDI_TOUT_CONTR_INT,*/
+       eDI_TOUT_CONTR_EN,
+       eDI_TOUT_CONTR_FINISH,
+       eDI_TOUT_CONTR_CHECK,
+
+       eDI_TOUT_CONTR_CLEAR,
+       eDI_TOUT_CONTR_RESET,
+};
+
+struct di_time_out_s {
+       bool en;
+       unsigned long   timer_start;
+       unsigned int    timer_thd;
+       unsigned int    over_flow_cnt;
+       bool            flg_over;
+/*     bool (*do_func)(void);*/
+};
+
+struct di_func_tab_s {
+       unsigned int index;
+       bool (*func)(void);
+};
+
+/****************************************/
+/* do_table                            */
+/****************************************/
+
+/*for do_table_ops_s id*/
+#define K_DO_TABLE_ID_PAUSE            0
+#define K_DO_TABLE_ID_STOP             1
+#define K_DO_TABLE_ID_START            2
+
+/*for mark of do_table_ops_s id*/
+#define K_DO_TABLE_CAN_STOP            0x01
+
+/*for op ret*/
+#define K_DO_TABLE_R_B_FINISH          0x01/*bit 0: 0:not finish, 1:finish*/
+/*bit 1: 0: to other index; 1: to next*/
+#define K_DO_TABLE_R_B_NEXT            0x02
+#define K_DO_TABLE_R_B_OTHER           0xf0    /*bit [7:4]: other index*/
+#define K_DO_TABLE_R_B_OTHER_SHIFT     4       /*bit [7:4]: other index*/
+
+#define K_DO_R_FINISH  (K_DO_TABLE_R_B_FINISH | K_DO_TABLE_R_B_NEXT)
+#define K_DO_R_NOT_FINISH      (0)
+#define K_DO_R_JUMP(a) (K_DO_TABLE_R_B_FINISH |        \
+       (((a) << K_DO_TABLE_R_B_OTHER_SHIFT) & K_DO_TABLE_R_B_OTHER))
+
+enum eDO_TABLE_CMD {
+       eDO_TABLE_CMD_NONE,
+       eDO_TABLE_CMD_STOP,
+       eDO_TABLE_CMD_START,
+       eDO_TABLE_CMD_PAUSE,
+       eDO_TABLE_CMD_STEP,
+       eDO_TABLE_CMD_STEP_BACK,
+};
+
+struct do_table_ops_s {
+       /*bool stop_mark;*/
+       unsigned int id;
+       unsigned int mark;      /*stop / pause*/
+       bool (*con)(void *data);/*condition*/
+       unsigned int (*do_op)(void *data);
+       unsigned int (*do_stop_op)(void *data);
+       char *name;
+
+};
+
+struct do_table_s {
+       const struct do_table_ops_s *ptab;
+       unsigned int size;
+       unsigned int op_lst;
+       unsigned int op_crr;
+       void *data;
+       bool do_stop;   /*need do stops */
+       bool flg_stop;  /*have stop     */
+
+       bool do_pause;
+       bool do_step;   /*step mode*/
+
+       bool flg_repeat;
+       char *name;
+
+};
+
+/*************************************/
+
+/**********************/
+/* vframe info */
+/**********************/
+struct di_vinfo_s {
+       /*use this for judge type change or not */
+       unsigned int ch;
+       unsigned int vtype;
+       unsigned int src_type;
+       unsigned int trans_fmt;
+       unsigned int h;
+       unsigned int v;
+};
+
+/**************************************/
+/* PRE */
+/**************************************/
+enum eDI_PRE_ST {
+       eDI_PRE_ST_EXIT,
+       eDI_PRE_ST_IDLE,        /*swith to next channel?*/
+       eDI_PRE_ST_CHECK,
+       eDI_PRE_ST_SET,
+       eDI_PRE_ST_WAIT_INT,
+       eDI_PRE_ST_TIMEOUT,
+};
+
+enum eDI_PRE_ST4 {     /*use this for co work with do table*/
+       eDI_PRE_ST4_EXIT,
+       eDI_PRE_ST4_IDLE,       /*swith to next channel?*/
+       eDI_PRE_ST4_CHECK,      /*check mode do_table and set*/
+       eDI_PRE_ST4_DO_TABLE,   /* do table statue;*/
+};
+
+struct di_pre_set_s {
+       /*use to remember last hw pre setting;*/
+       /*cfg:  */
+       bool cfg_mcpre_en;      /*mcpre_en*/
+
+       unsigned int in_w;
+       unsigned int in_h;
+       unsigned int in_type;
+       unsigned int src_type;
+};
+
+struct di_hpre_s {
+       enum eDI_PRE_ST4 pre_st;
+       unsigned int curr_ch;
+       /*set when have vframe in; clear when int have get*/
+       bool hw_flg_busy_pre;
+/*     bool trig_unreg;*/      /*add for unreg flow;*/
+/*     enum eDI_SUB_ID hw_owner_pre;*/
+       bool flg_wait_int;
+       struct di_pre_stru_s *pres;
+       struct di_post_stru_s *psts;
+       struct di_time_out_s tout;      /*for time out*/
+       bool flg_int_done;
+       unsigned int check_recycle_buf_cnt;
+
+       struct di_pre_set_s set_lst;
+       struct di_pre_set_s set_curr;
+
+       struct di_vinfo_s vinf_lst;
+       struct di_vinfo_s vinf_curr;
+
+       /* use do table to swith mode*/
+       struct do_table_s sdt_mode;
+
+       unsigned int idle_cnt;  /*use this avoid repeat idle <->check*/
+       /*dbg flow:*/
+       bool dbg_f_en;
+       unsigned int dbg_f_lstate;
+       unsigned int dbg_f_cnt;
+};
+
+/**************************************/
+/* POST */
+/**************************************/
+enum eDI_PST_ST {
+       eDI_PST_ST_EXIT,
+       eDI_PST_ST_IDLE,        /*swith to next channel?*/
+       eDI_PST_ST_CHECK,
+       eDI_PST_ST_SET,
+       eDI_PST_ST_WAIT_INT,
+       eDI_PST_ST_TIMEOUT,
+       eDI_PST_ST_DONE,        /*use for bypass_all*/
+};
+
+struct di_hpst_s {
+       enum eDI_PST_ST state;
+       unsigned int curr_ch;
+       /*set when have vframe in; clear when int have get*/
+       bool hw_flg_busy_post;
+       struct di_pre_stru_s *pres;
+       struct di_post_stru_s *psts;
+       struct di_time_out_s tout;      /*for time out*/
+       bool flg_int_done;
+
+       /*dbg flow:*/
+       bool dbg_f_en;
+       unsigned int dbg_f_lstate;
+       unsigned int dbg_f_cnt;
+
+};
+
+/**************************************/
+/* channel status */
+/**************************************/
+enum eDI_TOP_STATE {
+       eDI_TOP_STATE_NOPROB,
+       eDI_TOP_STATE_IDLE,     /*idle not work*/
+       /* STEP1
+        * till peek vframe and set irq;before this state, event reg finish
+        */
+       eDI_TOP_STATE_REG_STEP1,
+       eDI_TOP_STATE_REG_STEP1_P1,     /*2019-05-21*/
+       eDI_TOP_STATE_REG_STEP2,        /*till alloc and ready*/
+       eDI_TOP_STATE_READY,            /*can do DI*/
+       eDI_TOP_STATE_BYPASS,           /*complet bypass*/
+       eDI_TOP_STATE_UNREG_STEP1,      /*till pre/post is finish;*/
+       /* do unreg and to IDLE.
+        * no need to wait cma release after  this unreg event finish
+        */
+       eDI_TOP_STATE_UNREG_STEP2,
+
+};
+
+/**************************************/
+/* thread and cmd */
+/**************************************/
+struct di_task {
+       bool flg_init;
+       struct semaphore sem;
+       wait_queue_head_t wait_queue;
+       struct task_struct *thread;
+       unsigned int status;
+
+       unsigned int wakeup;
+       unsigned int delay;
+       bool exit;
+#if 1  /*not use cmd*/
+
+       /*local event*/
+       struct kfifo    fifo_cmd;
+       spinlock_t     lock_cmd;
+       bool flg_cmd;
+       unsigned int err_cmd_cnt;
+#endif
+};
+
+#define MAX_KFIFO_L_CMD_NUB    32
+
+union   DI_L_CMD_BITS {
+       unsigned int cmd32;
+       struct {
+               unsigned int id:8,      /*low bit*/
+                            ch:8,      /*channel*/
+                            p2:8,
+                            p3:8;
+       } b;
+};
+
+#define LCMD1(id, ch)  ((id) | ((ch) << 8))
+
+enum eCMD_LOCAL {
+       eCMD_NONE,
+       eCMD_REG,
+       eCMD_UNREG,
+       eCMD_READY,
+       eCMD_CHG,
+       NR_FINISH,
+};
+
+/**************************************/
+/*QUE*/
+/**************************************/
+enum QUE_TYPE {        /*mast start from 0 */
+       QUE_IN_FREE,    /*5*/
+       QUE_PRE_READY,  /*6*/
+       QUE_POST_FREE,  /*7*/
+       QUE_POST_READY, /*8*/
+       QUE_POST_BACK,          /*new*/
+       /*----------------*/
+       QUE_DBG,
+       QUE_NUB,
+};
+
+/*#define QUE_NUB  (5)*/
+enum eDI_BUF_TYPE {
+       eDI_BUF_T_IN = 1,       /*VFRAME_TYPE_IN*/
+       eDI_BUF_T_LOCAL,        /*VFRAME_TYPE_LOCAL*/
+       eDI_BUF_T_POST,         /*VFRAME_TYPE_POST*/
+};
+
+#define MAX_FIFO_SIZE  (32)
+
+/**************************************
+ *
+ * summmary variable
+ * also see:di_sum_name_tab
+ **************************************/
+
+enum eDI_SUM {
+       eDI_SUM_O_PEEK_CNT,     /*video_peek_cnt*/
+       eDI_SUM_REG_UNREG_CNT,  /*di_reg_unreg_cnt*/
+       eDI_SUM_NUB,
+};
+
+struct di_sum_s {
+       char *name;
+       enum eDI_SUM    index;
+       unsigned int    default_val;
+};
+
+/**************************************
+ *
+ * module para
+ *     int
+ *     eDI_MP_SUB_DI_B
+ *     eDI_MP_SUB_NR_B
+ *     eDI_MP_SUB_PD_B
+ *     eDI_MP_SUB_MTN_B
+ *     eDI_MP_SUB_3D_B
+ **************************************/
+enum eDI_MP_UI_T {
+       /*keep same order with di_mp_ui_top*/
+       eDI_MP_UI_T_BEGIN,
+       /**************************************/
+       eDI_MP_SUB_DI_B,
+
+       eDI_MP_force_prog,      /*force_prog bool*/
+       eDI_MP_combing_fix_en,  /*combing_fix_en bool*/
+       eDI_MP_cur_lev,         /*cur_lev*/
+       eDI_MP_pps_dstw,        /*pps_dstw*/
+       eDI_MP_pps_dsth,        /*pps_dsth*/
+       eDI_MP_pps_en,          /*pps_en*/
+       eDI_MP_pps_position,    /*pps_position*/
+       eDI_MP_pre_enable_mask, /*pre_enable_mask*/
+       eDI_MP_post_refresh,    /*post_refresh*/
+       eDI_MP_nrds_en,         /*nrds_en*/
+       eDI_MP_bypass_3d,       /*bypass_3d*/
+       eDI_MP_bypass_trick_mode,       /*bypass_trick_mode*/
+       eDI_MP_invert_top_bot,  /*invert_top_bot */
+       eDI_MP_skip_top_bot,
+       eDI_MP_force_width,
+       eDI_MP_force_height,
+       eDI_MP_prog_proc_config,
+       eDI_MP_start_frame_drop_count,
+       eDI_MP_same_field_top_count,    /*long?*/
+       eDI_MP_same_field_bot_count,    /*long?*/
+       eDI_MP_vpp_3d_mode,
+       eDI_MP_force_recovery_count,
+       eDI_MP_pre_process_time,        /*no use?*/
+       eDI_MP_bypass_post,
+       eDI_MP_post_wr_en,
+       eDI_MP_post_wr_support,
+       eDI_MP_bypass_post_state,
+       eDI_MP_use_2_interlace_buff,
+       eDI_MP_debug_blend_mode,
+       eDI_MP_nr10bit_support,
+       eDI_MP_di_stop_reg_flag,
+       eDI_MP_mcpre_en,
+       eDI_MP_check_start_drop_prog,
+       eDI_MP_overturn,                        /*? in init*/
+       eDI_MP_full_422_pack,
+       eDI_MP_cma_print,
+       eDI_MP_pulldown_enable,
+       eDI_MP_di_force_bit_mode,
+       eDI_MP_calc_mcinfo_en,
+       eDI_MP_colcfd_thr,
+       eDI_MP_post_blend,
+       eDI_MP_post_ei,
+       eDI_MP_post_cnt,
+       eDI_MP_di_log_flag,
+       eDI_MP_di_debug_flag,
+       eDI_MP_buf_state_log_threshold,
+       eDI_MP_di_vscale_skip_enable,
+       eDI_MP_di_vscale_skip_count,
+       eDI_MP_di_vscale_skip_count_real,
+       eDI_MP_det3d_en,
+       eDI_MP_post_hold_line,
+       eDI_MP_post_urgent,
+       eDI_MP_di_printk_flag,
+       eDI_MP_force_recovery,
+/*     eDI_MP_debug_blend_mode,*/
+       eDI_MP_di_dbg_mask,
+       eDI_MP_nr_done_check_cnt,
+       eDI_MP_pre_hsc_down_en,
+       eDI_MP_pre_hsc_down_width,
+       eDI_MP_show_nrwr,
+       /********deinterlace_hw.c*********/
+       eDI_MP_pq_load_dbg,
+       eDI_MP_lmv_lock_win_en,
+       eDI_MP_lmv_dist,
+       eDI_MP_pr_mcinfo_cnt,
+       eDI_MP_offset_lmv,
+       eDI_MP_post_ctrl,
+       eDI_MP_if2_disable,
+       eDI_MP_pre_flag,
+       eDI_MP_pre_mif_gate,
+       eDI_MP_pre_urgent,
+       eDI_MP_pre_hold_line,
+       eDI_MP_pre_ctrl,
+       eDI_MP_line_num_post_frst,
+       eDI_MP_line_num_pre_frst,
+       eDI_MP_pd22_flg_calc_en,
+       eDI_MP_mcen_mode,
+       eDI_MP_mcuv_en,
+       eDI_MP_mcdebug_mode,
+       eDI_MP_pldn_ctrl_rflsh,
+
+       eDI_MP_SUB_DI_E,
+       /**************************************/
+       eDI_MP_SUB_NR_B,
+       eDI_MP_dnr_en,
+       eDI_MP_nr2_en,
+       eDI_MP_cue_en,
+       eDI_MP_invert_cue_phase,
+       eDI_MP_cue_pr_cnt,
+       eDI_MP_cue_glb_mot_check_en,
+       eDI_MP_glb_fieldck_en,
+       eDI_MP_dnr_pr,
+       eDI_MP_dnr_dm_en,
+       eDI_MP_SUB_NR_E,
+       /**************************************/
+       eDI_MP_SUB_PD_B,
+       eDI_MP_flm22_ratio,
+       eDI_MP_pldn_cmb0,
+       eDI_MP_pldn_cmb1,
+       eDI_MP_flm22_sure_num,
+       eDI_MP_flm22_glbpxlnum_rat,
+       eDI_MP_flag_di_weave,
+       eDI_MP_flm22_glbpxl_maxrow,
+       eDI_MP_flm22_glbpxl_minrow,
+       eDI_MP_cmb_3point_rnum,
+       eDI_MP_cmb_3point_rrat,
+       /******film_fw1.c**/
+       eDI_MP_pr_pd,
+       eDI_MP_prt_flg,
+       eDI_MP_flmxx_maybe_num,
+       eDI_MP_flm32_mim_frms,
+       eDI_MP_flm22_dif01a_flag,
+       eDI_MP_flm22_mim_frms,
+       eDI_MP_flm22_mim_smfrms,
+       eDI_MP_flm32_f2fdif_min0,
+       eDI_MP_flm32_f2fdif_min1,
+       eDI_MP_flm32_chk1_rtn,
+       eDI_MP_flm32_ck13_rtn,
+       eDI_MP_flm32_chk2_rtn,
+       eDI_MP_flm32_chk3_rtn,
+       eDI_MP_flm32_dif02_ratio,
+       eDI_MP_flm22_chk20_sml,
+       eDI_MP_flm22_chk21_sml,
+       eDI_MP_flm22_chk21_sm2,
+       eDI_MP_flm22_lavg_sft,
+       eDI_MP_flm22_lavg_lg,
+       eDI_MP_flm22_stl_sft,
+       eDI_MP_flm22_chk5_avg,
+       eDI_MP_flm22_chk6_max,
+       eDI_MP_flm22_anti_chk1,
+       eDI_MP_flm22_anti_chk3,
+       eDI_MP_flm22_anti_chk4,
+       eDI_MP_flm22_anti_ck140,
+       eDI_MP_flm22_anti_ck141,
+       eDI_MP_flm22_frmdif_max,
+       eDI_MP_flm22_flddif_max,
+       eDI_MP_flm22_minus_cntmax,
+       eDI_MP_flagdif01chk,
+       eDI_MP_dif01_ratio,
+       /*******vof_soft_top*****/
+       eDI_MP_cmb32_blw_wnd,
+       eDI_MP_cmb32_wnd_ext,
+       eDI_MP_cmb32_wnd_tol,
+       eDI_MP_cmb32_frm_nocmb,
+       eDI_MP_cmb32_min02_sft,
+       eDI_MP_cmb32_cmb_tol,
+       eDI_MP_cmb32_avg_dff,
+       eDI_MP_cmb32_smfrm_num,
+       eDI_MP_cmb32_nocmb_num,
+       eDI_MP_cmb22_gcmb_rnum,
+       eDI_MP_flmxx_cal_lcmb,
+       eDI_MP_flm2224_stl_sft,
+       eDI_MP_SUB_PD_E,
+       /**************************************/
+       eDI_MP_SUB_MTN_B,
+       eDI_MP_force_lev,
+       eDI_MP_dejaggy_flag,
+       eDI_MP_dejaggy_enable,
+       eDI_MP_cmb_adpset_cnt,
+       eDI_MP_cmb_num_rat_ctl4,
+       eDI_MP_cmb_rat_ctl4_minthd,
+       eDI_MP_small_local_mtn,
+       eDI_MP_di_debug_readreg,
+       eDI_MP_SUB_MTN_E,
+       /**************************************/
+       eDI_MP_SUB_3D_B,
+       eDI_MP_chessbd_vrate,
+       eDI_MP_det3d_debug,
+
+       eDI_MP_SUB_3D_E,
+       /**************************************/
+       eDI_MP_UI_T_END,
+};
+
+#define K_DI_MP_UIT_NUB (eDI_MP_UI_T_END - eDI_MP_UI_T_BEGIN + 1)
+
+struct di_mp_uit_s {
+       char *name;
+       enum eDI_MP_UI_T        id;
+       int     default_val;
+};
+
+/*also see: di_mpx*/
+enum eDI_MP_UIX_T {
+       eDI_MP_UIX_BEGIN,
+       eDI_MP_UIX_RUN_FLG, /*run_flag*/
+       eDI_MP_UIX_END,
+};
+
+#define K_DI_MP_UIX_NUB (eDI_MP_UIX_END - eDI_MP_UIX_BEGIN + 1)
+
+struct di_mp_uix_s {
+       char *name;
+       enum eDI_MP_UIX_T       id;
+       unsigned int    default_val;
+};
+
+/**************************************/
+/* DI WORKING MODE */
+/**************************************/
+enum eDI_WORK_MODE {
+       eDI_WORK_MODE_NONE,
+       eDI_WORK_MODE_bypass_complet,
+       eDI_WORK_MODE_bypass_all,       /*dim_is_bypass*/
+       eDI_WORK_MODE_bypass_pre,
+       eDI_WORK_MODE_bypass_post,
+       eDI_WORK_MODE_i,
+       eDI_WORK_MODE_p_as_i,
+       eDI_WORK_MODE_p_as_p,
+       eDI_WORK_MODE_p_use_ibuf,
+       eDI_WORK_MODE_all,
+
+};
+
+/**************************************/
+/* vframe                             */
+/**************************************/
+struct dev_vfram_t {
+       const char *name;
+       /*receiver:*/
+       struct vframe_receiver_s di_vf_recv;
+       /*provider:*/
+       struct vframe_provider_s di_vf_prov;
+
+       unsigned int indx;
+       /*status:*/
+       bool bypass_complete;
+       bool reg;       /*use this for vframe reg/unreg*/
+/*     unsigned int data[32]; */       /*null*/
+
+};
+
+struct di_ores_s {
+       /* same as ori */
+       struct di_pre_stru_s di_pre_stru;
+       struct di_post_stru_s di_post_stru;
+
+       struct di_buf_s di_buf_local[MAX_LOCAL_BUF_NUM * 2];
+       struct di_buf_s di_buf_in[MAX_IN_BUF_NUM];
+       struct di_buf_s di_buf_post[MAX_POST_BUF_NUM];
+
+       struct queue_s queue[QUEUE_NUM];
+       struct di_buf_pool_s di_buf_pool[VFRAME_TYPE_NUM];
+
+       struct vframe_s *vframe_in[MAX_IN_BUF_NUM];
+       struct vframe_s vframe_in_dup[MAX_IN_BUF_NUM];
+       struct vframe_s vframe_local[MAX_LOCAL_BUF_NUM * 2];
+       struct vframe_s vframe_post[MAX_POST_BUF_NUM];
+       /* ********** */
+};
+
+enum eDI_CMA_ST {
+       eDI_CMA_ST_IDL,
+       eDI_CMA_ST_ALLOC,       /*do*/
+       eDI_CMA_ST_READY,
+       eDI_CMA_ST_RELEASE,     /*do*/
+};
+
+/**********************************
+ * mem
+ *********************************/
+struct di_mm_cfg_s {
+       /*support di size*/
+       unsigned int di_h;
+       unsigned int di_w;
+       /**/
+       unsigned int num_local;
+       unsigned int num_post;
+};
+
+struct di_mm_st_s {
+       /* use for reserved and alloc all*/
+       unsigned long   mem_start;
+       unsigned int    mem_size;
+       struct page     *total_pages;
+
+       unsigned int    flag_cma;
+
+       unsigned int    size_local;
+       unsigned int    size_post;
+       int     num_local;
+       int     num_post;       /*ppost*/
+};
+
+struct di_mm_s {
+       struct di_mm_cfg_s cfg;
+       struct di_mm_st_s sts;
+};
+
+struct di_ch_s {
+       /*struct di_cfgx_s dbg_cfg;*/
+       bool cfgx_en[K_DI_CFGX_NUB];
+       unsigned int mp_uix[K_DI_MP_UIX_NUB];/*module para x*/
+
+       struct di_dbg_datax_s dbg_data;
+
+       struct dev_vfram_t vfm;
+       struct dentry *dbg_rootx;       /*dbg_fs*/
+
+       unsigned int ch_id;
+       struct di_ores_s rse_ori;
+       struct kfifo    fifo[QUE_NUB];
+       bool flg_fifo[QUE_NUB]; /*have ini: 1; else 0*/
+/*     bool sub_act_flg;*/
+       /************************/
+       /*old glob*/
+       /************************/
+       /*bypass_state*/
+       bool bypass_state;
+
+       /*video_peek_cnt*/
+       unsigned int sum[eDI_SUM_NUB + 1];
+       unsigned int sum_get;
+       unsigned int sum_put;
+
+};
+
+struct di_meson_data {
+       const char *name;
+       /*struct ic_ver icver;*/
+       /*struct ddemod_reg_off regoff;*/
+};
+
+struct di_mng_s {
+       /*workqueue*/
+       struct workqueue_struct *wq_cma;
+       struct work_struct wq_work;
+
+       /*use enum eDI_CMA_ST*/
+       atomic_t cma_mem_state[DI_CHANNEL_NUB];
+       /*1:alloc cma, 0:release cma set by mng, read by work que*/
+       unsigned char cma_reg_cmd[DI_CHANNEL_NUB];
+
+       /*task:*/
+       struct di_task          tsk;
+
+       /*channel state: use enum eDI_TOP_STATE */
+       atomic_t ch_state[DI_CHANNEL_NUB];
+
+       bool in_flg[DI_CHANNEL_NUB];
+       unsigned long      mem_start[DI_CHANNEL_NUB];
+       unsigned int       mem_size[DI_CHANNEL_NUB];
+
+       bool sub_act_flg[DI_CHANNEL_NUB];
+       /*struct        mutex      event_mutex[DI_CHANNEL_NUB];*/
+       bool init_flg[DI_CHANNEL_NUB];  /*init_flag*/
+       /*bool reg_flg[DI_CHANNEL_NUB];*/       /*reg_flag*/
+       unsigned int reg_flg_ch;        /*for x ch reg/unreg flg*/
+       bool trig_unreg[DI_CHANNEL_NUB];
+       bool hw_reg_flg;        /*for di_reg_setting/di_unreg_setting*/
+       bool act_flg            ;/*active_flag*/
+
+       bool flg_hw_int;        /*only once*/
+
+       struct di_mm_s  mm;
+};
+
+/*************************
+ *debug register:
+ *************************/
+#define K_DI_SIZE_REG_LOG      (1000)
+#define K_DI_LAB_MOD           (0xf001)
+/*also see: dbg_mode_name*/
+enum eDI_DBG_MOD {
+       eDI_DBG_MOD_REGB,       /* 0 */
+       eDI_DBG_MOD_REGE,       /* 1 */
+       eDI_DBG_MOD_UNREGB,     /* 2 */
+       eDI_DBG_MOD_UNREGE,     /* 3 */
+       eDI_DBG_MOD_PRE_SETB,   /* 4 */
+       eDI_DBG_MOD_PRE_SETE,   /* 5 */
+       eDI_DBG_MOD_PRE_DONEB,  /* 6 */
+       eDI_DBG_MOD_PRE_DONEE,  /* 7 */
+       eDI_DBG_MOD_POST_SETB,  /* 8 */
+       eDI_DBG_MOD_POST_SETE,  /* 9 */
+       eDI_DBG_MOD_POST_IRQB,  /* a */
+       eDI_DBG_MOD_POST_IRQE,  /* b */
+       eDI_DBG_MOD_POST_DB,    /* c */
+       eDI_DBG_MOD_POST_DE,    /* d */
+       eDI_DBG_MOD_POST_CH_CHG,        /* e */
+       eDI_DBG_MOD_POST_TIMEOUT,       /* F */
+
+       eDI_DBG_MOD_RVB,        /*10 */
+       eDI_DBG_MOD_RVE,        /*11 */
+
+       eDI_DBG_MOD_POST_RESIZE, /*0x12 */
+       eDI_DBG_MOD_END,
+
+};
+
+enum eDI_LOG_TYPE {
+       eDI_LOG_TYPE_ALL = 1,
+       eDI_LOG_TYPE_REG,
+       eDI_LOG_TYPE_MOD,
+};
+
+struct di_dbg_reg {
+       unsigned int addr;
+       unsigned int val;
+       unsigned int st_bit:8,
+               b_w:8,
+               res:16;
+};
+
+struct di_dbg_mod {
+       unsigned int lable;     /*0xf001: mean dbg mode*/
+       unsigned int ch:8,
+               mod:8,
+               res:16;
+       unsigned int cnt;/*frame cnt*/
+};
+
+union udbg_data {
+       struct di_dbg_reg reg;
+       struct di_dbg_mod mod;
+};
+
+struct di_dbg_reg_log {
+       bool en;
+       bool en_reg;
+       bool en_mod;
+       bool en_all;
+       bool en_notoverwrite;
+
+       union udbg_data log[K_DI_SIZE_REG_LOG];
+       unsigned int pos;
+       unsigned int wsize;
+       bool overflow;
+};
+
+struct di_dbg_data {
+       unsigned int vframe_type;       /*use for type info*/
+       unsigned int cur_channel;
+       struct di_dbg_reg_log reg_log;
+};
+
+struct di_data_l_s {
+       bool cfg_en[K_DI_CFG_NUB];      /*cfg_top*/
+       int mp_uit[K_DI_MP_UIT_NUB];    /*eDI_MP_UI_T*/
+       struct di_ch_s ch_data[DI_CHANNEL_NUB];
+       int plane[DI_CHANNEL_NUB];      /*use for debugfs*/
+
+       struct di_dbg_data dbg_data;
+       struct di_mng_s mng;
+       struct di_hpre_s hw_pre;
+       struct di_hpst_s hw_pst;
+       struct dentry *dbg_root_top;    /* dbg_fs*/
+       /*pq_ops*/
+       const struct pulldown_op_s *ops_pd;     /* pulldown */
+       const struct detect3d_op_s *ops_3d;     /* detect_3d */
+       const struct nr_op_s *ops_nr;   /* nr */
+       const struct mtn_op_s *ops_mtn; /* deinterlace_mtn */
+       /*di ops for other module */
+       /*struct di_ext_ops *di_api; */
+       const struct di_meson_data *mdata;
+};
+
+/**************************************
+ *
+ * DEBUG infor
+ *
+ *************************************/
+
+#define DBG_M_C_ALL            0x2000  /*all debug close*/
+#define DBG_M_O_ALL            0x1000  /*all debug open*/
+
+#define DBG_M_DT               0x01    /*do table work*/
+#define DBG_M_REG              0x02    /*reg/unreg*/
+#define DBG_M_POST_REF         0x04
+#define DBG_M_TSK              0x08
+#define DBG_M_INIT             0x10
+#define DBG_M_EVENT            0x20
+#define DBG_M_FIRSTFRAME       0x40
+#define DBG_M_DBG              0x80
+
+#define DBG_M_POLLING          0x100
+#define DBG_M_ONCE             0x200
+
+extern unsigned int di_dbg;
+
+#define dbg_m(mark, fmt, args ...)             \
+       do {                                    \
+               if (di_dbg & DBG_M_C_ALL)       \
+                       break;                  \
+               if ((di_dbg & DBG_M_O_ALL) ||   \
+                   (di_dbg & (mark))) {                \
+                       pr_info("dim:"fmt, ##args); \
+               }                               \
+       } while (0)
+
+#define PR_ERR(fmt, args ...)          pr_err("dim:err:"fmt, ## args)
+#define PR_WARN(fmt, args ...)         pr_err("dim:warn:"fmt, ## args)
+#define PR_INF(fmt, args ...)          pr_info("dim:"fmt, ## args)
+
+#define dbg_dt(fmt, args ...)          dbg_m(DBG_M_DT, fmt, ##args)
+#define dbg_reg(fmt, args ...)         dbg_m(DBG_M_REG, fmt, ##args)
+#define dbg_post_ref(fmt, args ...)    dbg_m(DBG_M_POST_REF, fmt, ##args)
+#define dbg_poll(fmt, args ...)                dbg_m(DBG_M_POLLING, fmt, ##args)
+#define dbg_tsk(fmt, args ...)         dbg_m(DBG_M_TSK, fmt, ##args)
+
+#define dbg_init(fmt, args ...)                dbg_m(DBG_M_INIT, fmt, ##args)
+#define dbg_ev(fmt, args ...)          dbg_m(DBG_M_EVENT, fmt, ##args)
+#define dbg_first_frame(fmt, args ...) dbg_m(DBG_M_FIRSTFRAME, fmt, ##args)
+#define dbg_dbg(fmt, args ...)         dbg_m(DBG_M_DBG, fmt, ##args)
+#define dbg_once(fmt, args ...)                dbg_m(DBG_M_ONCE, fmt, ##args)
+
+char *di_cfgx_get_name(enum eDI_CFGX_IDX idx);
+bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx);
+void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en);
+
+static inline struct di_data_l_s *get_datal(void)
+{
+       return (struct di_data_l_s *)get_dim_de_devp()->data_l;
+}
+
+static inline struct di_ch_s *get_chdata(unsigned int ch)
+{
+       return &get_datal()->ch_data[ch];
+}
+
+static inline struct di_mng_s *get_bufmng(void)
+{
+       return &get_datal()->mng;
+}
+
+static inline unsigned long di_get_mem_start(unsigned int ch)
+{
+       return get_datal()->mng.mem_start[ch];
+}
+
+static inline void di_set_mem_info(unsigned int ch,
+                                  unsigned long mstart, unsigned int size)
+{
+       get_datal()->mng.mem_start[ch] = mstart;
+       get_datal()->mng.mem_size[ch] = size;
+}
+
+static inline unsigned int *di_get_mem_size(unsigned int ch)
+{
+       return &get_datal()->mng.mem_size[ch];
+}
+
+static inline struct di_hpre_s  *get_hw_pre(void)
+{
+       return &get_datal()->hw_pre;
+}
+
+static inline struct di_hpst_s  *get_hw_pst(void)
+{
+       return &get_datal()->hw_pst;
+}
+
+/****************************************
+ * flg_hw_int
+ *     for hw set once
+ ****************************************/
+static inline bool di_get_flg_hw_int(void)
+{
+       return get_datal()->mng.flg_hw_int;
+}
+
+static inline void di_set_flg_hw_int(bool on)
+{
+       get_datal()->mng.flg_hw_int = on;
+}
+
+/**********************
+ *
+ *     reg log:
+ *********************/
+static inline struct di_dbg_reg_log *get_dbg_reg_log(void)
+{
+       return &get_datal()->dbg_data.reg_log;
+}
+
+/**********************
+ *
+ *     flg_wait_int
+ *********************/
+static inline void di_pre_wait_irq_set(bool on)
+{
+       get_hw_pre()->flg_wait_int = on;
+}
+
+static inline bool di_pre_wait_irq_get(void)
+{
+       return get_hw_pre()->flg_wait_int;
+}
+
+static inline struct di_ores_s *get_orsc(unsigned int ch)
+{
+       return &get_datal()->ch_data[ch].rse_ori;
+}
+
+static inline struct vframe_s **get_vframe_in(unsigned int ch)
+{
+       return &get_orsc(ch)->vframe_in[0];
+}
+
+static inline struct vframe_s *get_vframe_in_dup(unsigned int ch)
+{
+       return &get_orsc(ch)->vframe_in_dup[0];
+}
+
+static inline struct vframe_s *get_vframe_local(unsigned int ch)
+{
+       return &get_orsc(ch)->vframe_local[0];
+}
+
+static inline struct vframe_s *get_vframe_post(unsigned int ch)
+{
+       return &get_orsc(ch)->vframe_post[0];
+}
+
+static inline struct di_buf_s *get_buf_local(unsigned int ch)
+{
+       return &get_orsc(ch)->di_buf_local[0];
+}
+
+static inline struct di_buf_s *get_buf_in(unsigned int ch)
+{
+       return &get_orsc(ch)->di_buf_in[0];
+}
+
+static inline struct di_buf_s *get_buf_post(unsigned int ch)
+{
+       return &get_orsc(ch)->di_buf_post[0];
+}
+
+static inline struct queue_s *get_queue(unsigned int ch)
+{
+       return &get_orsc(ch)->queue[0];
+}
+
+static inline struct di_buf_pool_s *get_buf_pool(unsigned int ch)
+{
+       return &get_orsc(ch)->di_buf_pool[0];
+}
+
+static inline struct di_pre_stru_s *get_pre_stru(unsigned int ch)
+{
+       return &get_orsc(ch)->di_pre_stru;
+}
+
+static inline struct di_post_stru_s *get_post_stru(unsigned int ch)
+{
+       return &get_orsc(ch)->di_post_stru;
+}
+
+static inline enum eDI_SUB_ID get_current_channel(void)
+{
+       return get_datal()->dbg_data.cur_channel;
+}
+
+static inline void set_current_channel(unsigned int channel)
+{
+       get_datal()->dbg_data.cur_channel = channel;
+}
+
+static inline bool get_init_flag(unsigned char ch)
+{
+       return get_bufmng()->init_flg[ch];
+}
+
+static inline void set_init_flag(unsigned char ch, bool on)
+{
+       get_bufmng()->init_flg[ch] =  on;
+}
+
+extern const unsigned int di_ch2mask_table[DI_CHANNEL_MAX];
+/******************************************
+ *
+ *     reg / unreg
+ *
+ *****************************************/
+static inline bool get_reg_flag(unsigned char ch)
+{
+       unsigned int flg = get_bufmng()->reg_flg_ch;
+       bool ret = false;
+
+       if (di_ch2mask_table[ch] & flg)
+               ret = true;
+
+       /*dim_print("%s:%d\n", __func__, ret);*/
+       return ret;
+}
+
+static inline unsigned int get_reg_flag_all(void)
+{
+       return get_bufmng()->reg_flg_ch;
+}
+
+static inline void set_reg_flag(unsigned char ch, bool on)
+{
+       unsigned int flg = get_bufmng()->reg_flg_ch;
+
+       if (on)
+               get_bufmng()->reg_flg_ch = flg | di_ch2mask_table[ch];
+       else
+               get_bufmng()->reg_flg_ch = flg & (~di_ch2mask_table[ch]);
+       /*dim_print("%s:%d\n", __func__, get_bufmng()->reg_flg_ch);*/
+}
+
+/******************************************
+ *
+ *     trig unreg:
+ *             when unreg: set 1
+ *             when reg: set 0
+ *****************************************/
+
+static inline bool get_flag_trig_unreg(unsigned char ch)
+{
+       return get_bufmng()->trig_unreg[ch];
+}
+
+#if 0
+static inline unsigned int get_reg_flag_all(void)
+{
+       return get_bufmng()->reg_flg_ch;
+}
+#endif
+
+static inline void set_flag_trig_unreg(unsigned char ch, bool on)
+{
+       get_bufmng()->trig_unreg[ch] =  on;
+}
+
+static inline bool get_hw_reg_flg(void)
+{
+       return get_bufmng()->hw_reg_flg;
+}
+
+static inline void set_hw_reg_flg(bool on)
+{
+       get_bufmng()->hw_reg_flg =  on;
+}
+
+static inline bool get_or_act_flag(void)
+{
+       return get_bufmng()->act_flg;
+}
+
+static inline void set_or_act_flag(bool on)
+{
+       get_bufmng()->act_flg =  on;
+}
+
+/*sum*/
+static inline void di_sum_set_l(unsigned int ch, enum eDI_SUM id,
+                               unsigned int val)
+{
+       get_chdata(ch)->sum[id] = val;
+}
+
+static inline unsigned int di_sum_inc_l(unsigned int ch, enum eDI_SUM id)
+{
+       get_chdata(ch)->sum[id]++;
+       return get_chdata(ch)->sum[id];
+}
+
+static inline unsigned int di_sum_get_l(unsigned int ch, enum eDI_SUM id)
+{
+       return get_chdata(ch)->sum[id];
+}
+
+/*sum get and put*/
+static inline unsigned int get_sum_g(unsigned int ch)
+{
+       return get_datal()->ch_data[ch].sum_get;
+}
+
+static inline void sum_g_inc(unsigned int ch)
+{
+       get_datal()->ch_data[ch].sum_get++;
+}
+
+static inline void sum_g_clear(unsigned int ch)
+{
+       get_datal()->ch_data[ch].sum_get = 0;
+}
+
+static inline unsigned int get_sum_p(unsigned int ch)
+{
+       return get_datal()->ch_data[ch].sum_put;
+}
+
+static inline void sum_p_inc(unsigned int ch)
+{
+       get_datal()->ch_data[ch].sum_put++;
+}
+
+static inline void sum_p_clear(unsigned int ch)
+{
+       get_datal()->ch_data[ch].sum_put = 0;
+}
+
+/*bypass_state*/
+static inline bool di_bypass_state_get(unsigned int ch)
+{
+       return get_chdata(ch)->bypass_state;
+}
+
+static inline void di_bypass_state_set(unsigned int ch, bool on)
+{
+       get_chdata(ch)->bypass_state =  on;
+}
+
+#if 0
+static inline struct semaphore *get_sema(void)
+{
+       return &get_dim_de_devp()->sema;
+}
+#endif
+
+static inline struct di_task *get_task(void)
+{
+       return &get_bufmng()->tsk;
+}
+
+/******************************************
+ *     pq ops
+ *****************************************/
+
+static inline const struct pulldown_op_s *get_ops_pd(void)
+{
+       return get_datal()->ops_pd;
+}
+
+static inline const struct detect3d_op_s *get_ops_3d(void)
+{
+       return get_datal()->ops_3d;
+}
+
+static inline const struct nr_op_s *get_ops_nr(void)
+{
+       return get_datal()->ops_nr;
+}
+
+static inline const struct mtn_op_s *get_ops_mtn(void)
+{
+       return get_datal()->ops_mtn;
+}
+
+#if 0
+static inline struct di_ext_ops *get_ops_api(void)
+{
+       return get_datal()->di_api;
+}
+#endif
+
+/******************************************
+ *     module para for di
+ *****************************************/
+
+static inline int dimp_get(enum eDI_MP_UI_T idx)
+{
+       return get_datal()->mp_uit[idx];
+}
+
+static inline void dimp_set(enum eDI_MP_UI_T idx, int val)
+{
+       get_datal()->mp_uit[idx] = val;
+}
+
+static inline int dimp_inc(enum eDI_MP_UI_T idx)
+{
+       get_datal()->mp_uit[idx]++;
+       return get_datal()->mp_uit[idx];
+}
+
+static inline int dimp_dec(enum eDI_MP_UI_T idx)
+{
+       get_datal()->mp_uit[idx]--;
+       return get_datal()->mp_uit[idx];
+}
+
+/******************************************
+ *     mm
+ *****************************************/
+static inline struct di_mm_s *dim_mm_get(void)
+{
+       return &get_datal()->mng.mm;
+}
+
+/**/
+void di_tout_int(struct di_time_out_s *tout, unsigned int thd);
+bool di_tout_contr(enum eDI_TOUT_CONTR cmd, struct di_time_out_s *tout);
+
+#endif /*__DI_DATA_L_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_dbg.c b/drivers/amlogic/media/di_multi/di_dbg.c
new file mode 100644 (file)
index 0000000..9c7763b
--- /dev/null
@@ -0,0 +1,1632 @@
+/*
+ * drivers/amlogic/media/di_multi/di_dbg.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+
+#include "di_data.h"
+#include "di_dbg.h"
+
+#include "di_reg_tab.h"
+#include "deinterlace.h"
+#include "deinterlace_dbg.h"
+#include "deinterlace_hw.h"
+#include "di_data_l.h"
+#include "di_que.h"
+#include "di_task.h"
+#include "di_prc.h"
+#include "di_pre.h"
+#include "di_post.h"
+
+/********************************
+ *trace:
+ *******************************/
+#define CREATE_TRACE_POINTS
+#include "dim_trace.h"
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE dim_trace
+#include <trace/define_trace.h>
+
+/**********************/
+/* data get */
+static struct dentry **dich_get_dbgroot(unsigned int ch)
+{
+       return &get_datal()->ch_data[ch].dbg_rootx;
+}
+
+static struct dentry **dich_get_dbgroot_top(void)
+{
+       return &get_datal()->dbg_root_top;
+}
+
+static int *di_get_plane(void)
+{
+       return &get_datal()->plane[0];
+}
+
+static struct vframe_s *di_get_dbg_vframe_in(unsigned int ch)
+{
+       return &get_datal()->ch_data[ch].dbg_data.vfm_input;
+}
+
+static struct vframe_s **di_get_dbg_vframe_out(unsigned int ch)
+{
+       return &get_datal()->ch_data[ch].dbg_data.pfm_out;
+}
+
+/********************************
+ *timer:
+ *******************************/
+
+u64 cur_to_msecs(void)
+{
+       u64 cur = sched_clock();
+
+       do_div(cur, NSEC_PER_MSEC);
+       return cur;
+}
+
+u64 cur_to_usecs(void)/*2019*/
+{
+       u64 cur = sched_clock();
+
+       do_div(cur, NSEC_PER_USEC);
+       return cur;
+}
+
+/********************************
+ *trace:
+ *******************************/
+
+static void trace_pre(unsigned int index, unsigned long ctime)
+{
+       trace_dim_pre("PRE-IRQ-0", index, ctime);
+}
+
+static void trace_post(unsigned int index, unsigned long ctime)
+{
+       trace_dim_post("POST-IRQ-1", index, ctime);
+}
+
+#define DI_TRACE_LIMIT         8
+static void trace_pre_get(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pre_getxx("PRE-GET-01", index, ustime);
+}
+
+static void trace_pre_set(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pre_setxx("PRE-SET-01", index, ustime);
+}
+
+static void trace_pre_ready(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pre_ready("PRE-READY2", index, ustime);
+}
+
+static void trace_post_ready(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_ready("PST-READY3", index, ustime);
+}
+
+static void trace_post_get(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_getxx("PST-GET-04", index, ustime);
+}
+
+static void trace_post_get2(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_get2x("PST-GET-0a", index, ustime);
+}
+
+static void trace_post_set(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_setxx("PST-SET-05", index, ustime);
+}
+
+static void trace_post_irq(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_irxxx("PST-IRQ-06", index, ustime);
+}
+
+static void trace_post_doing(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_doing("PST-DOI-07", index, ustime);
+}
+
+static void trace_post_peek(unsigned int index)
+{
+       u64 ustime;
+
+       if (di_get_disp_cnt() > DI_TRACE_LIMIT)
+               return;
+
+       ustime = cur_to_usecs();
+       trace_dim_pst_peekx("PST-PEEK-8", index, ustime);
+}
+
+const struct dim_tr_ops_s dim_tr_ops = {
+       .pre = trace_pre,
+       .post = trace_post,
+
+       .pre_get = trace_pre_get,
+       .pre_set = trace_pre_set,
+       .pre_ready = trace_pre_ready,
+       .post_ready = trace_post_ready,
+       .post_get = trace_post_get,
+       .post_get2 = trace_post_get2,
+
+       .post_set = trace_post_set,
+       .post_ir = trace_post_irq,
+       .post_do = trace_post_doing,
+       .post_peek = trace_post_peek,
+};
+
+static unsigned int seq_get_channel(struct seq_file *s)
+{
+       int *pCh;
+
+       pCh = (int *)s->private;
+       return *pCh;
+}
+
+/********************************
+ *debug register:
+ *******************************/
+/* also see enum eDI_DBG_MOD */
+const char * const dbg_mode_name[] = {
+       "REGB",
+       "REGE",
+       "UNREGB",
+       "UNREGE",
+       "PRE_SETB",
+       "PRE_SETE",
+       "PRE_DONEB",
+       "PRE_DONEE",
+       "PST_SETB",
+       "PST_SETE",
+       "PST_IRQB",
+       "PST_IRQE",
+       "PST_DB",
+       "PST_DE",
+       "PST_CH_CHG",
+       "PST_TOUT",
+       "RVB",
+       "RVE",
+       "PST_RESIZE",
+};
+
+const char *ddbg_get_mod_name(unsigned int mod)
+{
+       if (mod >= eDI_DBG_MOD_END)
+               return "nothing!";
+
+       return dbg_mode_name[mod];
+}
+
+void ddbg_reg_save(unsigned int addr, unsigned int val,
+                  unsigned int st, unsigned int bw)
+{
+       struct di_dbg_reg dbg_reg;
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+       unsigned int pos;
+
+       if (!plog->en_reg)
+               return;
+       if (plog->en_notoverwrite && plog->overflow)
+               return;
+
+       pos = plog->pos;
+
+       dbg_reg.addr = addr;
+       dbg_reg.val = val;
+       dbg_reg.st_bit = st;
+       dbg_reg.b_w = bw;
+
+       plog->log[pos].reg = dbg_reg;
+       pos++;
+       if (pos >= (K_DI_SIZE_REG_LOG - 1)) {
+               if (plog->en_notoverwrite) {
+                       plog->overflow = 1;
+
+               } else {
+                       pos = 0;
+                       plog->overflow = 1;
+               }
+       }
+       plog->wsize++;
+       plog->pos = pos;
+}
+
+void dim_ddbg_mod_save(unsigned int mod, unsigned int ch, unsigned int cnt)
+{
+       struct di_dbg_mod dbg_mod;
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+       unsigned int pos;
+#if 1
+/*--------------------------*/
+       if (ch)
+               h_dbg_reg_set(mod | 0x80000000);
+       else
+               h_dbg_reg_set(mod);
+/*--------------------------*/
+#endif
+       if (!plog->en_mod)
+               return;
+       if (plog->en_notoverwrite && plog->overflow)
+               return;
+       pos = plog->pos;
+
+       dbg_mod.lable = K_DI_LAB_MOD;
+       dbg_mod.ch = ch;
+       dbg_mod.mod = mod;
+       dbg_mod.cnt = cnt;
+
+       plog->log[pos].mod = dbg_mod;
+       pos++;
+       if (pos >= (K_DI_SIZE_REG_LOG - 1)) {
+               if (plog->en_notoverwrite) {
+                       plog->overflow = 1;
+
+               } else {
+                       pos = 0;
+                       plog->overflow = 1;
+               }
+       }
+       plog->wsize++;
+       plog->pos = pos;
+}
+
+#if 0
+void ddbg_sw(bool on)
+{
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+
+       plog->en = on;
+}
+#else
+
+void ddbg_sw(enum eDI_LOG_TYPE mode, bool on)
+{
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+
+       switch (mode) {
+       case eDI_LOG_TYPE_ALL:
+               plog->en_all = on;
+               break;
+       case eDI_LOG_TYPE_REG:
+               plog->en_reg = on;
+               break;
+       case eDI_LOG_TYPE_MOD:
+               plog->en_mod = on;
+               break;
+       default:
+               PR_WARN("%s:mode overlow:%d\n", __func__, mode);
+               break;
+       }
+}
+#endif
+void ddbg_reg_clear(void)
+{
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+
+       memset(plog, 0, sizeof(struct di_dbg_reg_log));
+       plog->en_notoverwrite = 1;
+}
+
+static int ddbg_log_reg_show(struct seq_file *seq, void *v)
+{
+       struct di_dbg_reg_log *plog = get_dbg_reg_log();
+       unsigned int pos;
+       int i;
+
+       if (plog->overflow)
+               pos = K_DI_SIZE_REG_LOG;
+       else
+               pos = plog->pos;
+
+       seq_printf(seq, "%s:pos=%d,overflow=%d, size=%d\n",
+                  __func__, plog->pos, plog->overflow, plog->wsize);
+
+       for (i = 0; i < pos; i++) {
+               if (plog->log[i].mod.lable == K_DI_LAB_MOD) {
+                       seq_printf(seq, "%d,ch[%d]:cnt[%d]:%s\n",
+                                  i,
+                                  plog->log[i].mod.ch,
+                                  plog->log[i].mod.cnt,
+                                  ddbg_get_mod_name(plog->log[i].mod.mod));
+                       continue;
+               }
+
+               seq_printf(seq, "\t0x%x,0x%x,%d,%d\n",
+                          plog->log[i].reg.addr,
+                          plog->log[i].reg.val,
+                          plog->log[i].reg.st_bit,
+                          plog->log[i].reg.b_w);
+       }
+
+       return 0;
+}
+
+static ssize_t ddbg_log_reg_store(struct file *file, const char __user *userbuf,
+                                 size_t count, loff_t *ppos)
+{
+       unsigned int item, val;
+       char buf[80];
+       int ret;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       switch (ret) {
+       case 2:
+               if (item == 0 && val == 0) {
+                       /*help info:*/
+                       pr_info("help:\n");
+                       /*all:*/
+                       pr_info("\t1 0 : log all disable\n");
+                       pr_info("\t1 1 : log all enable\n");
+                       /*reg:*/
+                       pr_info("\t2 0 : log reg disable\n");
+                       pr_info("\t2 1 : log reg enable\n");
+                       /*mod:*/
+                       pr_info("\t3 0 : log mod disable\n");
+                       pr_info("\t3 1 : log mod enable\n");
+                       /*clean:*/
+                       pr_info("\t4 0 : clear\n");
+                       break;
+               }
+               switch (item) {
+               case 1:
+               case 2:
+               case 3:
+                       pr_info("ddbg_sw: %d\n", val);
+                       ddbg_sw(item, val);
+                       break;
+               case 4:
+                       pr_info("ddbg_reg_clear\n");
+                       ddbg_reg_clear();
+                       break;
+               };
+
+               break;
+       default:
+               pr_info("err:please enter: 0 x for help\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/**********************/
+static int seq_file_vframe(struct seq_file *seq, void *v, struct vframe_s *pVfm)
+{
+       if (!pVfm) {
+               seq_puts(seq, "war: dump vframe NULL\n");
+               return 0;
+       }
+       seq_printf(seq, "%-15s:0x%p\n", "addr", pVfm);
+       seq_printf(seq, "%-15s:%d\n", "index", pVfm->index);
+       seq_printf(seq, "%-15s:%d\n", "index_disp", pVfm->index_disp);
+       seq_printf(seq, "%-15s:%d\n", "omx_index", pVfm->omx_index);
+       seq_printf(seq, "%-15s:0x%x\n", "type", pVfm->type);
+       seq_printf(seq, "%-15s:0x%x\n", "type_backup", pVfm->type_backup);
+       seq_printf(seq, "%-15s:0x%x\n", "type_original", pVfm->type_original);
+       seq_printf(seq, "%-15s:%d\n", "blend_mode", pVfm->blend_mode);
+       seq_printf(seq, "%-15s:%d\n", "duration",  pVfm->duration);
+       seq_printf(seq, "%-15s:%d\n", "duration_pull", pVfm->duration_pulldown);
+       seq_printf(seq, "%-15s:%d\n", "pts", pVfm->pts);
+
+       seq_printf(seq, "%-15s:%lld\n", "pts_us64", pVfm->pts_us64);
+       seq_printf(seq, "%-15s:%d\n", "next_vf_pts_valid",
+                  pVfm->next_vf_pts_valid);
+       seq_printf(seq, "%-15s:%d\n", "next_vf_pts", pVfm->next_vf_pts);
+       seq_printf(seq, "%-15s:%d\n", "disp_pts", pVfm->disp_pts);
+       seq_printf(seq, "%-15s:%lld\n", "disp_pts_us64", pVfm->disp_pts_us64);
+       seq_printf(seq, "%-15s:%lld\n", "timestamp", pVfm->timestamp);
+       seq_printf(seq, "%-15s:%d\n", "flag", pVfm->flag);
+       seq_printf(seq, "%-15s:0x%x\n", "canvas0Addr", pVfm->canvas0Addr);
+       seq_printf(seq, "%-15s:0x%x\n", "canvas1Addr", pVfm->canvas1Addr);
+       seq_printf(seq, "%-15s:0x%x\n", "compHeadAddr", pVfm->compHeadAddr);
+       seq_printf(seq, "%-15s:0x%x\n", "compBodyAddr", pVfm->compBodyAddr);
+       seq_printf(seq, "%-15s:%d\n", "plane_num", pVfm->plane_num);
+
+       seq_printf(seq, "%-15s:%d\n", "bufWidth", pVfm->bufWidth);
+       seq_printf(seq, "%-15s:%d\n", "width", pVfm->width);
+       seq_printf(seq, "%-15s:%d\n", "height", pVfm->height);
+       seq_printf(seq, "%-15s:%d\n", "compWidth", pVfm->compWidth);
+       seq_printf(seq, "%-15s:%d\n", "compHeight", pVfm->compHeight);
+       seq_printf(seq, "%-15s:%d\n", "ratio_control", pVfm->ratio_control);
+       seq_printf(seq, "%-15s:%d\n", "bitdepth", pVfm->bitdepth);
+       seq_printf(seq, "%-15s:%d\n", "signal_type", pVfm->signal_type);
+
+       /*
+        *         bit 29: present_flag
+        *         bit 28-26: video_format
+        *         "component", "PAL", "NTSC", "SECAM",
+        *         "MAC", "unspecified"
+        *         bit 25: range "limited", "full_range"
+        *         bit 24: color_description_present_flag
+        *         bit 23-16: color_primaries
+        *         "unknown", "bt709", "undef", "bt601",
+        *         "bt470m", "bt470bg", "smpte170m", "smpte240m",
+        *         "film", "bt2020"
+        *         bit 15-8: transfer_characteristic
+        *         "unknown", "bt709", "undef", "bt601",
+        *         "bt470m", "bt470bg", "smpte170m", "smpte240m",
+        *         "linear", "log100", "log316", "iec61966-2-4",
+        *         "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12",
+        *         "smpte-st-2084", "smpte-st-428"
+        *         bit 7-0: matrix_coefficient
+        *         "GBR", "bt709", "undef", "bt601",
+        *         "fcc", "bt470bg", "smpte170m", "smpte240m",
+        *         "YCgCo", "bt2020nc", "bt2020c"
+        */
+       seq_printf(seq, "%-15s:0x%x\n", "orientation", pVfm->orientation);
+       seq_printf(seq, "%-15s:0x%x\n", "video_angle", pVfm->video_angle);
+       seq_printf(seq, "%-15s:0x%x\n", "source_type", pVfm->source_type);
+
+       seq_printf(seq, "%-15s:0x%x\n", "phase", pVfm->phase);
+       seq_printf(seq, "%-15s:0x%x\n", "source_mode", pVfm->source_mode);
+       seq_printf(seq, "%-15s:0x%x\n", "sig_fmt", pVfm->sig_fmt);
+       seq_printf(seq, "%-15s:0x%x\n", "trans_fmt", pVfm->trans_fmt);
+
+       seq_printf(seq, "%-15s:0x%x\n", "mode_3d_enable",
+                  pVfm->mode_3d_enable);
+
+       seq_printf(seq, "%-15s:0x%p\n", "early_process_fun",
+                  pVfm->early_process_fun);
+       seq_printf(seq, "%-15s:0x%p\n", "process_fun",
+                  pVfm->early_process_fun);
+       seq_printf(seq, "%-15s:0x%p\n", "private_data",
+                  pVfm->early_process_fun);
+
+#if 1
+       /* vframe properties */
+
+#endif
+
+       /* pixel aspect ratio */
+       seq_printf(seq, "%-15s:%d\n", "pixel_ratio", pVfm->pixel_ratio);
+
+       /* ready from decode on  jiffies_64 */
+       seq_printf(seq, "%-15s:%d\n", "use_cnt", atomic_read(&pVfm->use_cnt));
+       seq_printf(seq, "%-15s:%d\n", "frame_dirty", pVfm->frame_dirty);
+       /*
+        *prog_proc_config:
+        *1: process p from decoder as filed
+        *0: process p from decoder as frame
+        */
+       seq_printf(seq, "%-15s:0x%x\n", "prog_proc_config",
+                  pVfm->prog_proc_config);
+               /* used for indicate current video is motion or static */
+       seq_printf(seq, "%-15s:%d\n", "combing_cur_lev",
+                  pVfm->combing_cur_lev);
+       return 0;
+}
+
+/**********************/
+/* debug input vframe */
+/**********************/
+void didbg_vframe_in_copy(unsigned int ch, struct vframe_s *pvfm)
+{
+       struct vframe_s *pvfm_t;
+
+       if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_IN))
+               return;
+
+       pvfm_t = di_get_dbg_vframe_in(ch);
+
+       memcpy(pvfm_t, pvfm, sizeof(struct vframe_s));
+}
+
+static int seq_file_vframe_in_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+
+       ch = seq_get_channel(seq);
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+
+       if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_IN)) {
+               seq_puts(seq, "war: cfg[eDI_DBG_CFGX_IDX_VFM_IN] disable\n");
+               return 0;
+       }
+
+       seq_file_vframe(seq, v, di_get_dbg_vframe_in(ch));
+
+       return 0;
+}
+
+/***********************/
+/* debug output vframe */
+/***********************/
+void didbg_vframe_out_save(struct vframe_s *pvfm)
+{
+       unsigned int ch;
+       struct vframe_s **pvfm_t;
+
+       ch = DI_SUB_ID_S0;
+       if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_OT))
+               return;
+
+       pvfm_t = di_get_dbg_vframe_out(ch);
+       *pvfm_t = pvfm;
+}
+
+static int seq_file_vframe_out_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+
+       ch = seq_get_channel(seq);
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+
+       if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_OT)) {
+               seq_puts(seq, "war: cfg[eDI_DBG_CFGX_IDX_VFM_OT] disable\n");
+               return 0;
+       }
+
+       seq_file_vframe(seq, v, *di_get_dbg_vframe_out(ch));
+
+       return 0;
+}
+
+/**********************/
+/* debug vframe type  */
+/**********************/
+const struct di_vframe_type_info di_vtype_info[] = {
+       {"interlace", VIDTYPE_INTERLACE, NULL},
+       {"bottom", VIDTYPE_INTERLACE_BOTTOM, NULL},
+
+       {"interllace first", VIDTYPE_INTERLACE_FIRST, NULL},
+       {"mvc", VIDTYPE_MVC, NULL},
+       {"no video en", VIDTYPE_NO_VIDEO_ENABLE, NULL},
+       {"v422", VIDTYPE_VIU_422, NULL},
+       {"field", VIDTYPE_VIU_FIELD, NULL},
+
+       {"single plane", VIDTYPE_VIU_SINGLE_PLANE, NULL},
+       {"v444", VIDTYPE_VIU_444, NULL},
+       {"nv21", VIDTYPE_VIU_NV21, NULL},
+       {"vscale disable", VIDTYPE_VSCALE_DISABLE, NULL},
+       {"cvs toggle", VIDTYPE_CANVAS_TOGGLE, NULL},
+       {"pre interlace", VIDTYPE_PRE_INTERLACE, NULL},
+       {"high run", VIDTYPE_HIGHRUN, NULL},
+       {"compress", VIDTYPE_COMPRESS, NULL},
+       {"pic", VIDTYPE_PIC, NULL},
+       {"scatter", VIDTYPE_SCATTER, NULL},
+       {"vd2", VIDTYPE_VD2, NULL},
+       {"compress loss", VIDTYPE_COMPRESS_LOSS, NULL},
+       {"comb", VIDTYPE_COMB_MODE, NULL},
+       {"tb detect", TB_DETECT_MASK, NULL},
+
+       /*finish*/
+       {NULL, TABLE_FLG_END, NULL},
+};
+
+static void didbg_vtype_set(unsigned int type)
+{
+       get_datal()->dbg_data.vframe_type = type;
+}
+
+static unsigned int didbg_vtype_get(void)
+{
+       return get_datal()->dbg_data.vframe_type;
+}
+
+static int seq_file_vtype_show(struct seq_file *seq, void *v)
+{
+       unsigned int vtype;
+       int i;
+       unsigned int mask;
+
+       i = 0;
+       vtype = didbg_vtype_get();
+
+       seq_printf(seq, "%s:vtype[0x%x]\n", __func__, vtype);
+
+       while (di_vtype_info[i].name) {
+               mask = di_vtype_info[i].mask;
+
+               if ((vtype & mask) == mask) {
+                       seq_printf(seq, "\t%-15s:y\n", di_vtype_info[i].name);
+               } else {
+                       if (di_vtype_info[i].other) {
+                               seq_printf(seq, "\t%-15s:yes\n",
+                                          di_vtype_info[i].other);
+                       } else {
+                               seq_printf(seq, "\t%-15s:no\n",
+                                          di_vtype_info[i].name);
+                       }
+               }
+               i++;
+       }
+
+       return 0;
+}
+
+ssize_t seq_file_vtype_store(struct file *file, const char __user *userbuf,
+                            size_t count, loff_t *ppos)
+{
+       char buf[20];
+       int ret;
+
+       unsigned int vtype;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+       /*reg, bit, width, val*/
+       #if 1
+       ret = kstrtouint(buf, 0, &vtype);
+       if (ret) {
+               pr_info("war:please enter vtype\n");
+               return 0;
+       }
+       pr_info("save type:0x%x", vtype);
+       didbg_vtype_set(vtype);
+       #else
+
+       ret = sscanfxxx(buf, "%x", &vtype);
+
+       /*--------------------------*/
+
+       switch (ret) {
+       case 1:
+               pr_info("save type:0x%x", vtype);
+               didbg_vtype_set(vtype);
+               break;
+       default:
+               pr_info("war:please enter vtype\n");
+               break;
+       }
+       #endif
+       return count;
+}
+
+/**************************************
+ *
+ * show vframe current
+ *
+ **************************************/
+static int seq_file_curr_vframe_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+       struct di_buf_s *p = NULL;
+       struct vframe_s *pvfm;
+       char *splt = "---------------------------";
+       char *splt2 = "-------------";
+       int itmp;
+       unsigned int tmpa[MAX_FIFO_SIZE];
+       unsigned int psize;
+
+       ch = seq_get_channel(seq);
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* post_doing_list              */
+       /********************************/
+       seq_puts(seq, "vfm for: post_doing_list:\n");
+       queue_for_each_entry(p, ch, QUEUE_POST_DOING, list) {
+               pvfm = p->vframe;
+               seq_file_vframe(seq, v, pvfm);
+               seq_printf(seq, "%s\n", splt2);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* pre_ready_list               */
+       /********************************/
+       seq_puts(seq, "pre_ready_list:\n");
+       di_que_list(ch, QUE_PRE_READY, &tmpa[0], &psize);
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(ch, tmpa[itmp]);
+
+               pvfm = p->vframe;
+               seq_file_vframe(seq, v, pvfm);
+               seq_printf(seq, "%s\n", splt2);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* post_ready_list              */
+       /********************************/
+       di_que_list(ch, QUE_POST_READY, &tmpa[0], &psize);
+       seq_printf(seq, "post_ready_list: curr(%d)\n", psize);
+
+       for (itmp = 0; itmp < psize; itmp++) {
+               p = pw_qindex_2_buf(ch, tmpa[itmp]);
+               pvfm = p->vframe;
+               seq_file_vframe(seq, v, pvfm);
+               seq_printf(seq, "%s\n", splt2);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       /********************************/
+       /* display_list                 */
+       /********************************/
+       seq_puts(seq, "display_list:\n");
+       queue_for_each_entry(p, ch, QUEUE_DISPLAY, list) {
+               pvfm = p->vframe;
+               seq_file_vframe(seq, v, pvfm);
+               seq_printf(seq, "%s\n", splt2);
+       }
+       seq_printf(seq, "%s\n", splt);
+
+       return 0;
+}
+
+/**************************************
+ *
+ * summmary variable
+ *
+ **************************************/
+static int seq_file_sum_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+       char *sname;
+       unsigned int val;
+       unsigned int tsize;
+       int i;
+
+       ch = seq_get_channel(seq);
+
+       tsize = di_sum_get_tab_size();/*ARRAY_SIZE(di_sum_tab);*/
+
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+       for (i = 0; i < tsize; i++) {
+               if (!di_sum_check(ch, i))
+                       continue;
+               di_sum_get_info(ch, i, &sname, &val);
+               seq_printf(seq, "\t%-2d:%-15s:%d\n", i, sname, val);
+       }
+
+       seq_printf(seq, "%s:finish\n", __func__);
+
+       return 0;
+}
+
+/********************************/
+/* state */
+/********************************/
+
+static int seq_file_state_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+
+       ch = seq_get_channel(seq);
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+
+       dim_state_show(seq, v, ch);
+
+       return 0;
+}
+
+static int seq_file_mif_show(struct seq_file *seq, void *v)
+{
+       unsigned int ch;
+
+       ch = seq_get_channel(seq);
+       seq_printf(seq, "%s:ch[%d]\n", __func__, ch);
+
+       dim_dump_mif_size_state_show(seq, v, ch);
+
+       return 0;
+}
+
+/********************************/
+#define DEFINE_SEQ_SHOW_ONLY(__name) \
+static int __name ## _open(struct inode *inode, struct file *file)     \
+{ \
+       return single_open(file, __name ## _show, inode->i_private);    \
+} \
+                                                                       \
+static const struct file_operations __name ## _fops = {                        \
+       .owner = THIS_MODULE,           \
+       .open = __name ## _open,        \
+       .read = seq_read,               \
+       .llseek = seq_lseek,            \
+       .release = single_release,      \
+}
+
+/*--------------------------*/
+#if 1
+/*note: this define can't used for x*/
+#define DEFINE_SEQ_SHOW_STORE(__name) \
+static int __name ## _open(struct inode *inode, struct file *file)     \
+{ \
+       return single_open(file, __name ## _show, inode->i_private);    \
+} \
+                                                                       \
+static const struct file_operations __name ## _fops = {                        \
+       .owner = THIS_MODULE,           \
+       .open = __name ## _open,        \
+       .read = seq_read,               \
+       .write = __name ## _store,      \
+       .llseek = seq_lseek,            \
+       .release = single_release,      \
+}
+#endif
+/*--------------------------*/
+#define DEFINE_SHOW_STORE(__name) \
+static const struct file_operations __name ## _fops = {                        \
+       .owner = THIS_MODULE,           \
+       .open = simple_open,    \
+       .read = __name ## _show,                \
+       .write = __name ## _store,      \
+}
+
+/*--------------------------*/
+#define DEFINE_STORE_ONLY(__name) \
+static const struct file_operations __name ## _fops = {                        \
+       .owner = THIS_MODULE,           \
+       .open = simple_open,    \
+       .read = NULL,           \
+       .write = __name ## _store,      \
+}
+
+/**********************/
+
+static int rcfgx_show(struct seq_file *s, void *what)
+{
+       int i;
+       int *pCh;
+
+       pCh = (int *)s->private;
+
+       seq_printf(s, "%s:ch[%d]\n", __func__, *pCh);
+
+       for (i = eDI_CFGX_BEGIN; i < eDI_DBG_CFGX_END; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n", i,
+                          di_cfgx_get_name(i),
+                          di_cfgx_get(*pCh, i));
+       }
+
+       return 0;
+}
+
+/*************************************************************/
+static ssize_t wcfgx_store(struct file *file, const char __user *userbuf,
+                          size_t count, loff_t *ppos)
+{
+       unsigned int item, val;
+       char buf[80];
+       int ret;
+       int *pCh;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pCh = (int *)file->private_data;
+       pr_info("%s:ch[%d]\n", __func__, *pCh);
+
+       switch (ret) {
+       case 2:
+               if ((item <= eDI_CFGX_BEGIN)    ||
+                   (item >= eDI_DBG_CFGX_END)) {
+                       pr_info("war:cfg_item is overflow[%d,%d]:%d\n",
+                               eDI_CFGX_BEGIN,
+                               eDI_DBG_CFGX_END,
+                               item);
+                       break;
+               }
+               if (val > 1)
+                       pr_info("war:cfg value[%d] is not bool\n", val);
+
+               pr_info("change cfg:%s\n", di_cfgx_get_name(item));
+               pr_info("\t%d -> %d\n", di_cfgx_get(*pCh, item), val);
+               di_cfgx_set(*pCh, item, val);
+               break;
+       default:
+               pr_info("err:please enter: cfg_item, value(bool)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/***************************************************************
+ * parameter show and store for top : DI
+ **************************************************************/
+static int mpr_di_show(struct seq_file *s, void *what)
+{
+       int i;
+
+       seq_printf(s, "%s:\n", __func__);
+
+       for (i = eDI_MP_SUB_DI_B; i < eDI_MP_SUB_DI_E; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n",
+                          i - eDI_MP_SUB_DI_B,
+                          di_mp_uit_get_name(i),
+                          di_mp_uit_get(i));
+       }
+
+       return 0;
+}
+
+static ssize_t mpw_di_store(struct file *file, const char __user *userbuf,
+                           size_t count, loff_t *ppos)
+{
+       unsigned int item, rid;
+       char buf[80];
+       int ret, val;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pr_info("%s:\n", __func__);
+
+       switch (ret) {
+       case 2:
+               /*check []*/
+               if (item >= (eDI_MP_SUB_DI_E - eDI_MP_SUB_DI_B)) {
+                       PR_WARN("index is overflow[%d,%d]:%d\n",
+                               0,
+                               eDI_MP_SUB_DI_E - eDI_MP_SUB_DI_B,
+                               item);
+                       break;
+               }
+               rid = item + eDI_MP_SUB_DI_B;
+               pr_info("change mp :%s\n",
+                       di_mp_uit_get_name(rid));
+               pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val);
+               di_mp_uit_set(rid, val);
+               break;
+       default:
+               PR_ERR("please enter: id, value(int)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/***************************************************************
+ * parameter show and store for top : nr
+ **************************************************************/
+static int mpr_nr_show(struct seq_file *s, void *what)
+{
+       int i;
+
+       seq_printf(s, "%s:\n", __func__);
+
+       for (i = eDI_MP_SUB_NR_B; i < eDI_MP_SUB_NR_E; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n",
+                          i - eDI_MP_SUB_NR_B,
+                          di_mp_uit_get_name(i),
+                          di_mp_uit_get(i));
+       }
+
+       return 0;
+}
+
+static ssize_t mpw_nr_store(struct file *file, const char __user *userbuf,
+                           size_t count, loff_t *ppos)
+{
+       unsigned int item, rid;
+       char buf[80];
+       int ret, val;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pr_info("%s:\n", __func__);
+
+       switch (ret) {
+       case 2:
+               /*check []*/
+               if (item >= (eDI_MP_SUB_NR_E - eDI_MP_SUB_NR_B)) {
+                       PR_WARN("index is overflow[%d,%d]:%d\n",
+                               0,
+                               eDI_MP_SUB_NR_E - eDI_MP_SUB_NR_B,
+                               item);
+                       break;
+               }
+               rid = item + eDI_MP_SUB_NR_B;
+               pr_info("change mp:%s\n",
+                       di_mp_uit_get_name(rid));
+               pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val);
+               di_mp_uit_set(rid, val);
+               break;
+       default:
+               PR_ERR("please enter: id, value(int)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/***************************************************************
+ * parameter show and store for top : pulldown
+ **************************************************************/
+static int mpr_pd_show(struct seq_file *s, void *what)
+{
+       int i;
+
+       seq_printf(s, "%s:\n", __func__);
+
+       for (i = eDI_MP_SUB_PD_B; i < eDI_MP_SUB_PD_E; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n",
+                          i - eDI_MP_SUB_PD_B,
+                          di_mp_uit_get_name(i),
+                          di_mp_uit_get(i));
+       }
+
+       return 0;
+}
+
+static ssize_t mpw_pd_store(struct file *file, const char __user *userbuf,
+                           size_t count, loff_t *ppos)
+{
+       unsigned int item, rid;
+       char buf[80];
+       int ret, val;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pr_info("%s:\n", __func__);
+
+       switch (ret) {
+       case 2:
+               /*check []*/
+               if (item >= (eDI_MP_SUB_PD_E - eDI_MP_SUB_PD_B)) {
+                       PR_WARN("index is overflow[%d,%d]:%d\n",
+                               0,
+                               eDI_MP_SUB_PD_E - eDI_MP_SUB_PD_B,
+                               item);
+                       break;
+               }
+               rid = item + eDI_MP_SUB_PD_B;
+               pr_info("change mp:%s\n",
+                       di_mp_uit_get_name(rid));
+               pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val);
+               di_mp_uit_set(rid, val);
+               break;
+       default:
+               PR_ERR("please enter: id, value(int)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/***************************************************************
+ * parameter show and store for top : mtn
+ **************************************************************/
+static int mpr_mtn_show(struct seq_file *s, void *what)
+{
+       int i;
+
+       seq_printf(s, "%s:\n", __func__);
+
+       for (i = eDI_MP_SUB_MTN_B; i < eDI_MP_SUB_MTN_E; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n",
+                          i - eDI_MP_SUB_MTN_B,
+                          di_mp_uit_get_name(i),
+                          di_mp_uit_get(i));
+       }
+
+       return 0;
+}
+
+static ssize_t mpw_mtn_store(struct file *file, const char __user *userbuf,
+                            size_t count, loff_t *ppos)
+{
+       unsigned int item, rid;
+       char buf[80];
+       int ret, val;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pr_info("%s:\n", __func__);
+
+       switch (ret) {
+       case 2:
+               /*check []*/
+               if (item >= (eDI_MP_SUB_MTN_E - eDI_MP_SUB_MTN_B)) {
+                       PR_WARN("index is overflow[%d,%d]:%d\n",
+                               0,
+                               eDI_MP_SUB_MTN_E - eDI_MP_SUB_MTN_B,
+                               item);
+                       break;
+               }
+               rid = item + eDI_MP_SUB_MTN_B;
+               pr_info("change mp:%s\n",
+                       di_mp_uit_get_name(rid));
+               pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val);
+               di_mp_uit_set(rid, val);
+               break;
+       default:
+               PR_ERR("please enter: id, value(int)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/**********************/
+static int mpxr_show(struct seq_file *s, void *what)
+{
+       int i;
+       int *pCh;
+
+       pCh = (int *)s->private;
+
+       seq_printf(s, "%s:ch[%d]\n", __func__, *pCh);
+
+       for (i = eDI_MP_UIX_BEGIN; i < eDI_MP_UIX_END; i++) {
+               seq_printf(s, "\tidx[%2d]:%-15s:%d\n", i,
+                          di_mp_uix_get_name(i),
+                          di_mp_uix_get(*pCh, i));
+       }
+
+       return 0;
+}
+
+/*************************************************************/
+static ssize_t mpxw_store(struct file *file, const char __user *userbuf,
+                         size_t count, loff_t *ppos)
+{
+       unsigned int item, val;
+       char buf[80];
+       int ret;
+       int *pCh;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i", &item, &val);
+
+       pCh = (int *)file->private_data;
+       pr_info("%s:ch[%d]\n", __func__, *pCh);
+
+       switch (ret) {
+       case 2:
+               if ((item <= eDI_MP_UIX_BEGIN)  ||
+                   (item >= eDI_MP_UIX_END)) {
+                       PR_WARN("mpxw is overflow[%d,%d]:%d\n",
+                               eDI_MP_UIX_BEGIN,
+                               eDI_MP_UIX_END,
+                               item);
+                       break;
+               }
+
+               pr_info("change mp ch[%d]:%s\n", *pCh,
+                       di_mp_uix_get_name(item));
+               pr_info("\t%d -> %d\n", di_mp_uix_get(*pCh, item), val);
+               di_mp_uix_set(*pCh, item, val);
+               break;
+       default:
+               PR_ERR("please enter: mpxw, value(unsigned int)\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+static ssize_t buf_cnt_store(struct file *file, const char __user *userbuf,
+                            size_t count, loff_t *ppos)
+{
+       int w, h, pflg, mc;
+       char buf[80];
+       int ret, cnt_flg;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %i %i %i", &w, &h, &pflg, &mc);
+
+       pr_info("%s:\n", __func__);
+       cnt_flg = 0;
+       switch (ret) {
+       case 2:
+               cnt_flg = 1;
+               pflg = 0;
+               mc = 1;
+               break;
+       case 3:
+               cnt_flg = 1;
+               mc = 1;
+               break;
+       case 4:
+               cnt_flg = 1;
+               break;
+       default:
+               PR_ERR("please enter: w, h, pflg, mc\n");
+               return -EINVAL;
+       }
+
+       if (cnt_flg)
+               di_cnt_buf(w, h, pflg, mc, 1, 1);
+       return count;
+}
+
+/**********************/
+void dbg_f_post_disable(unsigned int para)
+{
+       dimh_disable_post_deinterlace_2();
+}
+
+void dbg_f_trig_task(unsigned int para)
+{
+       task_send_ready();
+}
+
+const struct di_dbg_func_s di_func_tab[] = {
+       {eDI_DBG_F_00, dbg_f_post_disable,
+               "dimh_disable_post_deinterlace_2", "no para"},
+       {eDI_DBG_F_01, dbg_f_trig_task,
+               "trig task", "no para"},
+       {eDI_DBG_F_02, dpre_dbg_f_trig,
+               "trig pre flow debug", "bit[4]:ddebug on/off;bi[3:0]:cnt"},
+       {eDI_DBG_F_03, dpst_dbg_f_trig,
+               "trig post flow debug", "bit[4]:ddebug on/off;bi[3:0]:cnt"},
+       {eDI_DBG_F_04, hpst_dbg_power_ctr_trig,
+               "trig post power", "1: on; 0: off"},
+
+       {eDI_DBG_F_05, hpst_dbg_mem_pd_trig,
+               "trig post mem pd", "no para"},
+       {eDI_DBG_F_06, hpst_dbg_trig_gate,
+               "trig post gate off/on", "no para"},
+       {eDI_DBG_F_07, hpst_dbg_trig_mif,
+               "trig post mif off/free", "no para"},
+};
+
+static ssize_t wfunc_store(struct file *file, const char __user *userbuf,
+                          size_t count, loff_t *ppos)
+{
+       unsigned int findex, para;
+       char buf[20];
+       int ret;
+
+       int i;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%i %x", &findex, &para);
+
+       switch (ret) {
+       case 2:
+               pr_info("func:%d,para=0x%x\n", findex, para);
+               for (i = 0; i < ARRAY_SIZE(di_func_tab); i++) {
+                       if (i == findex && di_func_tab[i].index == findex) {
+                               if (di_func_tab[i].func)
+                                       di_func_tab[i].func(para);
+                               pr_info("func:%s finish\n",
+                                       di_func_tab[i].name);
+                               break;
+                       }
+               }
+               break;
+       default:
+               pr_info("warn: please enter function index and para\n");
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+static int rfunc_show(struct seq_file *seq, void *v)
+{
+       int i;
+
+       seq_puts(seq, "debug function list:\n");
+
+       for (i = 0; i < ARRAY_SIZE(di_func_tab); i++) {
+               if (di_func_tab[i].index != i)
+                       seq_printf(seq, "warn: index(%d->%d) is not map\n",
+                                  i, di_func_tab[i].index);
+               seq_printf(seq, "index[%d]:%s:%s\n",
+                          di_func_tab[i].index,
+                          di_func_tab[i].name,
+                          di_func_tab[i].info);
+       }
+       return 0;
+}
+
+/**********************/
+static ssize_t reg_show(struct file *file, char __user *userbuf,
+                       size_t count, loff_t *ppos)
+{
+       char buf[80];
+
+       ssize_t len;
+       int *pInt;
+
+       pInt = (int *)file->private_data;
+       pr_info("pInt=0x%p,val=%d\n", pInt, *pInt);
+
+       len = snprintf(buf, sizeof(buf), "%s\n",
+                      __func__);
+
+       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static ssize_t reg_store(struct file *file, const char __user *userbuf,
+                        size_t count, loff_t *ppos)
+{
+       unsigned int reg, val;
+       char buf[80];
+       int ret;
+       int *pInt;
+
+       count = min_t(size_t, count, (sizeof(buf) - 1));
+       if (copy_from_user(buf, userbuf, count))
+               return -EFAULT;
+
+       buf[count] = 0;
+
+       ret = sscanf(buf, "%x %i", &reg, &val);
+
+       switch (ret) {
+       case 1:
+               pr_info("reg:0x%x\n", reg);
+
+               pInt = (int *)file->private_data;
+               pr_info("pInt=0x%p,val=%d\n", pInt, *pInt);
+               break;
+       case 2:
+               pr_info("reg:0x%x,val=%d\n", reg, val);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+/**********************/
+DEFINE_SEQ_SHOW_ONLY(dim_reg_cue_int);
+/**********************/
+DEFINE_SEQ_SHOW_ONLY(rcfgx);
+DEFINE_SEQ_SHOW_ONLY(seq_file_vframe_in);
+DEFINE_SEQ_SHOW_ONLY(seq_file_vframe_out);
+DEFINE_SEQ_SHOW_ONLY(seq_file_state);
+DEFINE_SEQ_SHOW_ONLY(seq_file_mif);
+DEFINE_SEQ_SHOW_ONLY(seq_file_sum);
+
+DEFINE_SEQ_SHOW_ONLY(reg_con);
+DEFINE_SEQ_SHOW_ONLY(rfunc);
+DEFINE_SEQ_SHOW_ONLY(mpxr);
+DEFINE_SEQ_SHOW_ONLY(mpr_di);
+DEFINE_SEQ_SHOW_ONLY(mpr_nr);
+DEFINE_SEQ_SHOW_ONLY(mpr_pd);
+DEFINE_SEQ_SHOW_ONLY(mpr_mtn);
+
+DEFINE_SEQ_SHOW_ONLY(seq_file_curr_vframe);
+
+DEFINE_STORE_ONLY(wcfgx);
+DEFINE_STORE_ONLY(wfunc);
+DEFINE_STORE_ONLY(mpxw);
+DEFINE_STORE_ONLY(mpw_di);
+DEFINE_STORE_ONLY(mpw_nr);
+DEFINE_STORE_ONLY(mpw_pd);
+DEFINE_STORE_ONLY(mpw_mtn);
+DEFINE_STORE_ONLY(buf_cnt);
+
+DEFINE_SHOW_STORE(reg);
+
+DEFINE_SEQ_SHOW_STORE(seq_file_vtype);
+DEFINE_SEQ_SHOW_STORE(ddbg_log_reg);
+
+/**********************/
+
+struct di_dbgfs_files_t {
+       const char *name;
+       const umode_t mode;
+       const struct file_operations *fops;
+};
+
+static const struct di_dbgfs_files_t di_debugfs_files_top[] = {
+       {"vtype", S_IFREG | 0644, &seq_file_vtype_fops},
+       {"reg_log", S_IFREG | 0644, &ddbg_log_reg_fops},
+       {"regctr", S_IFREG | 0644, &reg_con_fops},
+       {"rfunc", S_IFREG | 0644, &rfunc_fops},
+       {"wfunc", S_IFREG | 0644, &wfunc_fops},
+       {"reg_cue", S_IFREG | 0644, &dim_reg_cue_int_fops},
+       /*module parameter*/
+       {"mr_di", S_IFREG | 0644, &mpr_di_fops},
+       {"mw_di", S_IFREG | 0644, &mpw_di_fops},
+       {"mr_nr", S_IFREG | 0644, &mpr_nr_fops},
+       {"mw_nr", S_IFREG | 0644, &mpw_nr_fops},
+       {"mr_pd", S_IFREG | 0644, &mpr_pd_fops},
+       {"mw_pd", S_IFREG | 0644, &mpw_pd_fops},
+       {"mr_mtn", S_IFREG | 0644, &mpr_mtn_fops},
+       {"mw_mtn", S_IFREG | 0644, &mpw_mtn_fops},
+       {"buf_cnt", S_IFREG | 0644, &buf_cnt_fops},
+};
+
+static const struct di_dbgfs_files_t di_debugfs_files[] = {
+       {"rcfgx", S_IFREG | 0644, &rcfgx_fops},
+       {"wcfgx", S_IFREG | 0644, &wcfgx_fops},
+       {"rvfm_in", S_IFREG | 0644, &seq_file_vframe_in_fops},
+       {"rvfm_out", S_IFREG | 0644, &seq_file_vframe_out_fops},
+       {"state", S_IFREG | 0644, &seq_file_state_fops},
+       {"dumpmif", S_IFREG | 0644, &seq_file_mif_fops},
+       {"test_reg", S_IFREG | 0644, &reg_fops},
+       {"sum", S_IFREG | 0644, &seq_file_sum_fops},
+       {"mpxr", S_IFREG | 0644, &mpxr_fops},
+       {"mpxw", S_IFREG | 0644, &mpxw_fops},
+       {"vfmc", S_IFREG | 0644, &seq_file_curr_vframe_fops},
+};
+
+void didbg_fs_init(void)
+{
+       int i, j;
+       char name[5];
+       /*char buf[3];*/
+
+       struct dentry **root_ent;
+
+       struct dentry *ent;
+       int *pPlane = di_get_plane();
+
+       for (i = 0; i < DI_CHANNEL_NUB; i++) {
+#if 0
+               strcpy(name, "di");
+               sprintf(buf, "%01d", i);
+               strncat(name, buf, sizeof(buf) - 1);
+#endif
+               snprintf(name, sizeof(name), "di%01d", i);
+               root_ent = dich_get_dbgroot(i);
+               *root_ent = debugfs_create_dir(name, NULL);
+
+               *(pPlane + i) = i;
+               /*printk("plane 0x%p\n", &plane_ch[i]);*/
+               for (j = 0; j < ARRAY_SIZE(di_debugfs_files); j++) {
+                       ent = debugfs_create_file(di_debugfs_files[j].name,
+                                                 di_debugfs_files[j].mode,
+                                                 *root_ent, (pPlane + i),
+                                                 di_debugfs_files[j].fops);
+                       if (!ent)
+                               PR_ERR("debugfs create failed\n");
+               }
+       }
+       /*top*/
+       root_ent = dich_get_dbgroot_top();
+       *root_ent = debugfs_create_dir("di_top", NULL);
+       for (i = 0; i < ARRAY_SIZE(di_debugfs_files_top); i++) {
+               ent = debugfs_create_file(di_debugfs_files_top[i].name,
+                                         di_debugfs_files_top[i].mode,
+                                         *root_ent, NULL,
+                                         di_debugfs_files_top[i].fops);
+               if (!ent)
+                       PR_ERR("debugfs top [%d]create failed\n", i);
+       }
+}
+
+void didbg_fs_exit(void)
+{
+       struct dentry **root_ent;
+       int i;
+
+       for (i = 0; i < DI_CHANNEL_NUB; i++) {
+               root_ent = dich_get_dbgroot(i);
+               debugfs_remove_recursive(*root_ent);
+       }
+
+       /*top*/
+       root_ent = dich_get_dbgroot_top();
+       debugfs_remove_recursive(*root_ent);
+
+       pr_info("%s:finish\n", __func__);
+}
+
+/*-----------------------*/
+
diff --git a/drivers/amlogic/media/di_multi/di_dbg.h b/drivers/amlogic/media/di_multi/di_dbg.h
new file mode 100644 (file)
index 0000000..6636f5a
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * drivers/amlogic/media/di_multi/di_dbg.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_DBG_H__
+#define __DI_DBG_H__
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
+void didbg_fs_init(void);
+void didbg_fs_exit(void);
+
+void di_cfgx_init_val(void);
+
+void didbg_vframe_in_copy(unsigned int ch, struct vframe_s *pvfm);
+void didbg_vframe_out_save(struct vframe_s *pvfm);
+
+/********************************
+ *debug register:
+ *******************************/
+void ddbg_reg_save(unsigned int addr, unsigned int val,
+                  unsigned int st, unsigned int bw);
+void dim_ddbg_mod_save(unsigned int mod,
+                      unsigned int ch,
+                      unsigned int cnt);
+void ddbg_sw(unsigned int mode, bool on);
+
+/********************************
+ *time:
+ *******************************/
+u64 cur_to_msecs(void);
+u64 cur_to_usecs(void);        /*2019*/
+
+/********************************
+ *trace:
+ *******************************/
+struct dim_tr_ops_s {
+       void (*pre)(unsigned int index, unsigned long ctime);
+       void (*post)(unsigned int index, unsigned long ctime);
+       void (*pre_get)(unsigned int index);
+       void (*pre_set)(unsigned int index);
+       void (*pre_ready)(unsigned int index);
+       void (*post_ready)(unsigned int index);
+       void (*post_get)(unsigned int index);
+       void (*post_get2)(unsigned int index);
+       void (*post_set)(unsigned int index);
+       void (*post_ir)(unsigned int index);
+       void (*post_do)(unsigned int index);
+       void (*post_peek)(unsigned int index);
+};
+
+extern const struct dim_tr_ops_s dim_tr_ops;
+
+#endif /*__DI_DBG_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_post.c b/drivers/amlogic/media/di_multi/di_post.c
new file mode 100644 (file)
index 0000000..3451d2d
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * drivers/amlogic/media/di_multi/di_post.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "deinterlace.h"
+#include "deinterlace_dbg.h"
+
+#include "di_data_l.h"
+#include "di_data.h"
+#include "di_dbg.h"
+#include "di_vframe.h"
+#include "di_que.h"
+#include "di_task.h"
+
+#include "di_prc.h"
+#include "di_post.h"
+
+#include "nr_downscale.h"
+#include "register.h"
+
+void dpost_clear(void)/*not been called*/
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+
+       memset(pst, 0, sizeof(struct di_hpst_s));
+}
+
+void dpost_init(void)
+{/*reg:*/
+       struct di_hpst_s  *pst = get_hw_pst();
+
+       pst->state = eDI_PST_ST_IDLE;
+
+       /*timer out*/
+       di_tout_int(&pst->tout, 40);    /*ms*/
+}
+
+void pw_use_hw_post(enum eDI_SUB_ID channel, bool on)
+{
+       struct di_hpst_s  *post = get_hw_pst();
+
+       post->hw_flg_busy_post = on;
+       if (on)
+               post->curr_ch = channel;
+}
+
+static bool pw_try_sw_ch_next_post(enum eDI_SUB_ID channel)
+{
+       bool ret = false;
+
+       struct di_hpst_s *post = get_hw_pst();
+       enum eDI_SUB_ID lst_ch, nch;
+
+       lst_ch = channel;
+
+       nch = pw_ch_next_count(lst_ch);
+       if (!get_reg_flag(nch) || get_flag_trig_unreg(nch))
+               return false;
+
+       if (nch != channel)
+               dim_ddbg_mod_save(eDI_DBG_MOD_POST_CH_CHG, nch, 0);/*dbg*/
+
+       post->curr_ch = nch;
+       post->hw_flg_busy_post = true;
+       ret = true;
+
+       /*dim_print("%s:%d->%d:%d\n", __func__, lst_ch, nch, ret);*/
+       return ret;
+}
+
+/*****************************/
+/* debug */
+/*****************************/
+
+/*****************************/
+/* STEP */
+/*****************************/
+
+bool dpst_step_idle(void)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       bool reflesh = false;
+
+       if (!pw_try_sw_ch_next_post(pst->curr_ch))
+               return false;
+
+       pst->pres = get_pre_stru(pst->curr_ch);
+       pst->psts = get_post_stru(pst->curr_ch);
+       pst->state++;/*tmp*/
+       reflesh = true;
+
+       return reflesh;
+}
+
+bool dpst_step_check(void)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       unsigned int ch;
+       struct di_post_stru_s *ppost;
+       bool reflesh = false;
+
+       ch = pst->curr_ch;
+       ppost = get_post_stru(ch);
+
+       if (queue_empty(ch, QUEUE_POST_DOING)) {
+               ppost->post_peek_underflow++;
+               pst->state--;
+               return reflesh;
+       }
+
+       pst->state++;
+       reflesh = true;
+
+       return reflesh;
+}
+
+bool dpst_step_set(void)
+{
+       struct di_buf_s *di_buf = NULL;
+       vframe_t *vf_p = NULL;
+       struct di_post_stru_s *ppost;
+       struct di_hpst_s  *pst = get_hw_pst();
+       unsigned int ch;
+       bool reflesh = false;
+       ulong flags = 0;
+
+       ch = pst->curr_ch;
+       ppost = get_post_stru(ch);
+
+       di_buf = get_di_buf_head(ch, QUEUE_POST_DOING);
+       if (dim_check_di_buf(di_buf, 20, ch)) {
+               PR_ERR("%s:err1\n", __func__);
+               return reflesh;
+       }
+
+       vf_p = di_buf->vframe;
+       if (ppost->run_early_proc_fun_flag) {
+               if (vf_p->early_process_fun)
+                       vf_p->early_process_fun = dim_do_post_wr_fun;
+       }
+
+       dim_print("%s:pr_index=%d\n", __func__, di_buf->process_fun_index);
+       if (di_buf->process_fun_index) {        /*not bypass?*/
+
+               ppost->post_wr_cnt++;
+               spin_lock_irqsave(&plist_lock, flags);
+               dim_post_process(di_buf, 0, vf_p->width - 1,
+                                0, vf_p->height - 1, vf_p);
+               spin_unlock_irqrestore(&plist_lock, flags);
+
+               /*begin to count timer*/
+               di_tout_contr(eDI_TOUT_CONTR_EN, &pst->tout);
+
+               ppost->post_de_busy = 1;
+               ppost->irq_time = cur_to_msecs();
+
+               /*state*/
+               pst->state++;
+               /*reflesh = true;*/
+       } else {
+               ppost->de_post_process_done = 1;        /*trig done*/
+               pst->flg_int_done = 1;
+
+               /*state*/
+               pst->state++;/*pst->state = eDI_PST_ST_DONE;*/
+               reflesh = true;
+       }
+       ppost->cur_post_buf = di_buf;
+
+       return reflesh;
+}
+
+bool dpst_step_wait_int(void)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       unsigned int ch;
+       struct di_post_stru_s *ppost;
+       bool reflesh = false;
+       ulong flags = 0;
+
+       ch = pst->curr_ch;
+
+       dim_print("%s:ch[%d],done_flg[%d]\n", __func__,
+                 pst->curr_ch, pst->flg_int_done);
+       if (pst->flg_int_done) {
+               /*finish to count timer*/
+               di_tout_contr(eDI_TOUT_CONTR_FINISH, &pst->tout);
+               spin_lock_irqsave(&plist_lock, flags);
+               dim_post_de_done_buf_config(ch);
+               spin_unlock_irqrestore(&plist_lock, flags);
+               pst->flg_int_done = false;
+               /*state*/
+               pst->state = eDI_PST_ST_IDLE;
+               reflesh = true;
+       } else {
+               /*check if timeout:*/
+               if (di_tout_contr(eDI_TOUT_CONTR_CHECK, &pst->tout)) {
+                       ppost = get_post_stru(ch);
+                       PR_WARN("ch[%d]:post timeout[%d]\n", ch,
+                               ppost->cur_post_buf->seq);
+                       dim_ddbg_mod_save(eDI_DBG_MOD_POST_TIMEOUT, ch, 0);
+                       /*state*/
+                       pst->state = eDI_PST_ST_TIMEOUT;
+                       reflesh = true;
+               }
+       }
+       return reflesh;
+}
+
+void dpst_timeout(unsigned int ch)
+{
+       hpst_dbg_mem_pd_trig(0);
+       post_close_new();
+       #if 0
+       di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP);
+       di_post_reset();
+       #endif
+       dimh_pst_trig_resize();
+}
+
+bool dpst_step_timeout(void)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       unsigned int ch;
+       bool reflesh = false;
+       ulong flags = 0;
+
+       ch = pst->curr_ch;
+       dpst_timeout(ch);
+       spin_lock_irqsave(&plist_lock, flags);
+       dim_post_de_done_buf_config(ch);
+       spin_unlock_irqrestore(&plist_lock, flags);
+       pst->flg_int_done = false;
+
+       /*state*/
+       pst->state = eDI_PST_ST_IDLE;
+       reflesh = true;
+
+       return reflesh;
+}
+
+bool dpst_step_done(void)/*this step no use ?*/
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       unsigned int ch;
+       bool reflesh = false;
+
+       ch = pst->curr_ch;
+/*     dim_post_de_done_buf_config(ch);*/
+
+       /*state*/
+       pst->state = eDI_PST_ST_IDLE;
+       reflesh = true;
+
+       return reflesh;
+}
+
+const struct di_func_tab_s di_pst_func_tab[] = {
+       {eDI_PST_ST_EXIT, NULL},
+       {eDI_PST_ST_IDLE, dpst_step_idle},
+       {eDI_PST_ST_CHECK, dpst_step_check},
+       {eDI_PST_ST_SET, dpst_step_set},
+       {eDI_PST_ST_WAIT_INT, dpst_step_wait_int},
+       {eDI_PST_ST_TIMEOUT, dpst_step_timeout},
+       {eDI_PST_ST_DONE, dpst_step_done},
+};
+
+const char * const dpst_state_name[] = {
+       "EXIT",
+       "IDLE", /*swith to next channel?*/
+       "CHECK",
+       "SET",
+       "WAIT_INT",
+       "TIMEOUT",
+       "DONE",
+};
+
+const char *dpst_state_name_get(enum eDI_PST_ST state)
+{
+       if (state > eDI_PST_ST_DONE)
+               return "nothing";
+
+       return dpst_state_name[state];
+}
+
+bool dpst_can_exit(unsigned int ch)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       bool ret = false;
+
+       if (ch != pst->curr_ch) {
+               ret = true;
+       } else {
+               if (pst->state <= eDI_PST_ST_IDLE)
+                       ret = true;
+       }
+       pr_info("%s:ch[%d]:curr[%d]:stat[%s] ret[%d]\n",
+               __func__,
+               ch, pst->curr_ch,
+               dpst_state_name_get(pst->state),
+               ret);
+       return ret;
+}
+
+static bool dpst_process_step2(void)
+{
+       struct di_hpst_s  *pst = get_hw_pst();
+       enum eDI_PST_ST pst_st = pst->state;
+       unsigned int ch;
+
+       ch = pst->curr_ch;
+       if (pst_st > eDI_PST_ST_EXIT)
+               dim_recycle_post_back(ch);
+
+       if ((pst_st <= eDI_PST_ST_DONE) &&
+           di_pst_func_tab[pst_st].func)
+               return di_pst_func_tab[pst_st].func();
+       else
+               return false;
+}
+
+void dpst_dbg_f_trig(unsigned int cmd)
+{
+       struct di_task *tsk = get_task();
+
+       struct di_hpst_s *pst = get_hw_pst();
+
+       if (down_interruptible(&tsk->sem)) {
+               PR_ERR("%s:can't get sem\n", __func__);
+               return;
+       }
+
+       /*set on/off and trig*/
+       if (cmd & 0x10) {
+               pst->dbg_f_en = 1;
+               pst->dbg_f_cnt = cmd & 0xf;
+               pst->dbg_f_lstate = pst->state;
+       } else {
+               pst->dbg_f_en = 0;
+       }
+
+       up(&tsk->sem);
+}
+
+void dpst_process(void)
+{
+       bool reflesh;
+
+       struct di_hpst_s *pst = get_hw_pst();
+
+       if (pst->dbg_f_en) {
+               if (pst->dbg_f_cnt) {
+                       dpst_process_step2();
+                       pst->dbg_f_cnt--;
+               }
+               if (pst->dbg_f_lstate != pst->state) {
+                       pr_info("ch[%d]:state:%s->%s\n",
+                               pst->curr_ch,
+                               dpst_state_name_get(pst->dbg_f_lstate),
+                               dpst_state_name_get(pst->state));
+
+                       pst->dbg_f_lstate = pst->state;
+               }
+               return;
+       }
+
+       reflesh = true;
+
+       while (reflesh)
+               reflesh = dpst_process_step2();
+}
diff --git a/drivers/amlogic/media/di_multi/di_post.h b/drivers/amlogic/media/di_multi/di_post.h
new file mode 100644 (file)
index 0000000..1b4d88d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * drivers/amlogic/media/di_multi/di_post.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_POST_H__
+#define __DI_POST_H__
+
+void dpost_init(void);
+void dpst_process(void);
+const char *dpst_state_name_get(enum eDI_PST_ST state);
+void dpst_dbg_f_trig(unsigned int cmd);
+bool dpst_can_exit(unsigned int ch);
+
+#endif /*__DI_POST_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_pps.c b/drivers/amlogic/media/di_multi/di_pps.c
new file mode 100644 (file)
index 0000000..4f20941
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * drivers/amlogic/media/di_multi/di_pps.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/amlogic/media/registers/regs/di_regs.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "di_pps.h"
+#include "register.h"
+
+#include <linux/seq_file.h>
+
+#if 0
+/* pps filter coefficients */
+#define COEF_BICUBIC         0
+#define COEF_3POINT_TRIANGLE 1
+#define COEF_4POINT_TRIANGLE 2
+#define COEF_BILINEAR        3
+#define COEF_2POINT_BILINEAR 4
+#define COEF_BICUBIC_SHARP   5
+#define COEF_3POINT_TRIANGLE_SHARP   6
+#define COEF_3POINT_BSPLINE  7
+#define COEF_4POINT_BSPLINE  8
+#define COEF_3D_FILTER       9
+#define COEF_NULL            0xff
+#define TOTAL_FILTERS        10
+
+#define MAX_NONLINEAR_FACTOR    0x40
+
+const u32 vpp_filter_coefs_bicubic_sharp[] = {
+       3,
+       33 | 0x8000,
+       /* 0x01f80090, 0x01f80100, 0xff7f0200, 0xfe7f0300, */
+       0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
+       0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
+       0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
+       0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
+       0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
+       0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
+       0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
+       0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
+       0xf84848f8
+};
+
+const u32 vpp_filter_coefs_bicubic[] = {
+       4,
+       33,
+       0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300,
+       0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
+       0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
+       0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
+       0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
+       0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
+       0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
+       0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
+       0xf84848f8
+};
+
+const u32 vpp_filter_coefs_bilinear[] = {
+       4,
+       33,
+       0x00800000, 0x007e0200, 0x007c0400, 0x007a0600,
+       0x00780800, 0x00760a00, 0x00740c00, 0x00720e00,
+       0x00701000, 0x006e1200, 0x006c1400, 0x006a1600,
+       0x00681800, 0x00661a00, 0x00641c00, 0x00621e00,
+       0x00602000, 0x005e2200, 0x005c2400, 0x005a2600,
+       0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,
+       0x00503000, 0x004e3200, 0x004c3400, 0x004a3600,
+       0x00483800, 0x00463a00, 0x00443c00, 0x00423e00,
+       0x00404000
+};
+
+const u32 vpp_3d_filter_coefs_bilinear[] = {
+       2,
+       33,
+       0x80000000, 0x7e020000, 0x7c040000, 0x7a060000,
+       0x78080000, 0x760a0000, 0x740c0000, 0x720e0000,
+       0x70100000, 0x6e120000, 0x6c140000, 0x6a160000,
+       0x68180000, 0x661a0000, 0x641c0000, 0x621e0000,
+       0x60200000, 0x5e220000, 0x5c240000, 0x5a260000,
+       0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,
+       0x50300000, 0x4e320000, 0x4c340000, 0x4a360000,
+       0x48380000, 0x463a0000, 0x443c0000, 0x423e0000,
+       0x40400000
+};
+
+const u32 vpp_filter_coefs_3point_triangle[] = {
+       3,
+       33,
+       0x40400000, 0x3f400100, 0x3d410200, 0x3c410300,
+       0x3a420400, 0x39420500, 0x37430600, 0x36430700,
+       0x35430800, 0x33450800, 0x32450900, 0x31450a00,
+       0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00,
+       0x2b470e00, 0x29480f00, 0x28481000, 0x27481100,
+       0x26491100, 0x25491200, 0x24491300, 0x234a1300,
+       0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600,
+       0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900,
+       0x1a4c1a00
+};
+
+/* point_num =4, filt_len =4, group_num = 64, [1 2 1] */
+const u32 vpp_filter_coefs_4point_triangle[] = {
+       4,
+       33,
+       0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
+       0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
+       0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
+       0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
+       0x18382808, 0x18382808, 0x17372909, 0x17372909,
+       0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
+       0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
+       0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
+       0x10303010
+};
+
+/*
+ *4th order (cubic) b-spline
+ *filt_cubic point_num =4, filt_len =4, group_num = 64, [1 5 1]
+ */
+const u32 vpp_filter_coefs_4point_bspline[] = {
+       4,
+       33,
+       0x15561500, 0x14561600, 0x13561700, 0x12561800,
+       0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
+       0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
+       0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
+       0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
+       0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
+       0x05473301, 0x05463401, 0x04453601, 0x04433702,
+       0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
+       0x033d3d03
+};
+
+/*3rd order (quadratic) b-spline*/
+/*filt_quadratic, point_num =3, filt_len =3, group_num = 64, [1 6 1] */
+const u32 vpp_filter_coefs_3point_bspline[] = {
+       3,
+       33,
+       0x40400000, 0x3e420000, 0x3c440000, 0x3a460000,
+       0x38480000, 0x364a0000, 0x344b0100, 0x334c0100,
+       0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200,
+       0x2a540200, 0x29540300, 0x27560300, 0x26570300,
+       0x24580400, 0x23590400, 0x215a0500, 0x205b0500,
+       0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800,
+       0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00,
+       0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00,
+       0x10601000
+};
+
+/*filt_triangle, point_num =3, filt_len =2.6, group_num = 64, [1 7 1] */
+const u32 vpp_filter_coefs_3point_triangle_sharp[] = {
+       3,
+       33,
+       0x40400000, 0x3e420000, 0x3d430000, 0x3b450000,
+       0x3a460000, 0x38480000, 0x37490000, 0x354b0000,
+       0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000,
+       0x2e520000, 0x2c540000, 0x2b550000, 0x29570000,
+       0x28580000, 0x265a0000, 0x245c0000, 0x235d0000,
+       0x215f0000, 0x20600000, 0x1e620000, 0x1d620100,
+       0x1b620300, 0x19630400, 0x17630600, 0x15640700,
+       0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00,
+       0x0d660d00
+};
+
+const u32 vpp_filter_coefs_2point_binilear[] = {
+       2,
+       33,
+       0x80000000, 0x7e020000, 0x7c040000, 0x7a060000,
+       0x78080000, 0x760a0000, 0x740c0000, 0x720e0000,
+       0x70100000, 0x6e120000, 0x6c140000, 0x6a160000,
+       0x68180000, 0x661a0000, 0x641c0000, 0x621e0000,
+       0x60200000, 0x5e220000, 0x5c240000, 0x5a260000,
+       0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,
+       0x50300000, 0x4e320000, 0x4c340000, 0x4a360000,
+       0x48380000, 0x463a0000, 0x443c0000, 0x423e0000,
+       0x40400000
+};
+
+static const u32 *filter_table[] = {
+       vpp_filter_coefs_bicubic,
+       vpp_filter_coefs_3point_triangle,
+       vpp_filter_coefs_4point_triangle,
+       vpp_filter_coefs_bilinear,
+       vpp_filter_coefs_2point_binilear,
+       vpp_filter_coefs_bicubic_sharp,
+       vpp_filter_coefs_3point_triangle_sharp,
+       vpp_filter_coefs_3point_bspline,
+       vpp_filter_coefs_4point_bspline,
+       vpp_3d_filter_coefs_bilinear
+};
+
+static int chroma_filter_table[] = {
+       COEF_BICUBIC, /* bicubic */
+       COEF_3POINT_TRIANGLE,
+       COEF_4POINT_TRIANGLE,
+       COEF_4POINT_TRIANGLE, /* bilinear */
+       COEF_2POINT_BILINEAR,
+       COEF_3POINT_TRIANGLE, /* bicubic_sharp */
+       COEF_3POINT_TRIANGLE, /* 3point_triangle_sharp */
+       COEF_3POINT_TRIANGLE, /* 3point_bspline */
+       COEF_4POINT_TRIANGLE, /* 4point_bspline */
+       COEF_3D_FILTER            /* can not change */
+};
+
+static unsigned int vert_scaler_filter = 0xff;
+module_param(vert_scaler_filter, uint, 0664);
+MODULE_PARM_DESC(vert_scaler_filter, "vert_scaler_filter");
+
+static unsigned int vert_chroma_scaler_filter = 0xff;
+module_param(vert_chroma_scaler_filter, uint, 0664);
+MODULE_PARM_DESC(vert_chroma_scaler_filter, "vert_chroma_scaler_filter");
+
+static unsigned int horz_scaler_filter = 0xff;
+module_param(horz_scaler_filter, uint, 0664);
+MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter");
+
+bool pre_scaler_en = true;
+module_param(pre_scaler_en, bool, 0664);
+MODULE_PARM_DESC(pre_scaler_en, "pre_scaler_en");
+#endif
+/*bicubic*/
+static const unsigned int di_filt_coef0[] = {
+       0x00800000,
+       0x007f0100,
+       0xff7f0200,
+       0xfe7f0300,
+       0xfd7e0500,
+       0xfc7e0600,
+       0xfb7d0800,
+       0xfb7c0900,
+       0xfa7b0b00,
+       0xfa7a0dff,
+       0xf9790fff,
+       0xf97711ff,
+       0xf87613ff,
+       0xf87416fe,
+       0xf87218fe,
+       0xf8701afe,
+       0xf76f1dfd,
+       0xf76d1ffd,
+       0xf76b21fd,
+       0xf76824fd,
+       0xf76627fc,
+       0xf76429fc,
+       0xf7612cfc,
+       0xf75f2ffb,
+       0xf75d31fb,
+       0xf75a34fb,
+       0xf75837fa,
+       0xf7553afa,
+       0xf8523cfa,
+       0xf8503ff9,
+       0xf84d42f9,
+       0xf84a45f9,
+       0xf84848f8
+};
+
+/* 2 point bilinear */
+static const unsigned int di_filt_coef1[] = {
+       0x00800000,
+       0x007e0200,
+       0x007c0400,
+       0x007a0600,
+       0x00780800,
+       0x00760a00,
+       0x00740c00,
+       0x00720e00,
+       0x00701000,
+       0x006e1200,
+       0x006c1400,
+       0x006a1600,
+       0x00681800,
+       0x00661a00,
+       0x00641c00,
+       0x00621e00,
+       0x00602000,
+       0x005e2200,
+       0x005c2400,
+       0x005a2600,
+       0x00582800,
+       0x00562a00,
+       0x00542c00,
+       0x00522e00,
+       0x00503000,
+       0x004e3200,
+       0x004c3400,
+       0x004a3600,
+       0x00483800,
+       0x00463a00,
+       0x00443c00,
+       0x00423e00,
+       0x00404000
+};
+
+/* 2 point bilinear, bank_length == 2*/
+static const unsigned int di_filt_coef2[] = {
+        0x80000000,
+        0x7e020000,
+        0x7c040000,
+        0x7a060000,
+        0x78080000,
+        0x760a0000,
+        0x740c0000,
+        0x720e0000,
+        0x70100000,
+        0x6e120000,
+        0x6c140000,
+        0x6a160000,
+        0x68180000,
+        0x661a0000,
+        0x641c0000,
+        0x621e0000,
+        0x60200000,
+        0x5e220000,
+        0x5c240000,
+        0x5a260000,
+        0x58280000,
+        0x562a0000,
+        0x542c0000,
+        0x522e0000,
+        0x50300000,
+        0x4e320000,
+        0x4c340000,
+        0x4a360000,
+        0x48380000,
+        0x463a0000,
+        0x443c0000,
+        0x423e0000,
+        0x40400000
+};
+
+#define ZOOM_BITS       20
+#define PHASE_BITS      16
+
+static enum f2v_vphase_type_e top_conv_type = F2V_P2P;
+static enum f2v_vphase_type_e bot_conv_type = F2V_P2P;
+static unsigned int prehsc_en;
+static unsigned int prevsc_en;
+
+static const unsigned char f2v_420_in_pos_luma[F2V_TYPE_MAX] = {
+0, 2, 0, 2, 0, 0, 0, 2, 0};
+#if 0
+static const unsigned char f2v_420_in_pos_chroma[F2V_TYPE_MAX] = {
+       1, 5, 1, 5, 2, 2, 1, 5, 2};
+#endif
+static const unsigned char f2v_420_out_pos[F2V_TYPE_MAX] = {
+0, 2, 2, 0, 0, 2, 0, 0, 0};
+
+static void f2v_get_vertical_phase(unsigned int zoom_ratio,
+                                  enum f2v_vphase_type_e type,
+                                  unsigned char bank_length,
+                                  struct pps_f2v_vphase_s *vphase)
+{
+       int offset_in, offset_out;
+
+    /* luma */
+       offset_in = f2v_420_in_pos_luma[type] << PHASE_BITS;
+       offset_out = (f2v_420_out_pos[type] * zoom_ratio)
+               >> (ZOOM_BITS - PHASE_BITS);
+
+       vphase->rcv_num = bank_length;
+       if (bank_length == 4 || bank_length == 3)
+               vphase->rpt_num = 1;
+       else
+               vphase->rpt_num = 0;
+
+       if (offset_in > offset_out) {
+               vphase->rpt_num = vphase->rpt_num + 1;
+               vphase->phase =
+                       ((4 << PHASE_BITS) + offset_out - offset_in) >> 2;
+       } else {
+               while ((offset_in + (4 << PHASE_BITS)) <= offset_out) {
+                       if (vphase->rpt_num == 1)
+                               vphase->rpt_num = 0;
+                       else
+                               vphase->rcv_num++;
+                       offset_in += 4 << PHASE_BITS;
+               }
+               vphase->phase = (offset_out - offset_in) >> 2;
+       }
+}
+
+/*
+ * patch 1: inp scaler 0: di wr scaler
+ * support: TM2
+ * not support: SM1
+ */
+void dim_pps_config(unsigned char path, int src_w, int src_h,
+                   int dst_w, int dst_h)
+{
+       struct pps_f2v_vphase_s vphase;
+
+       int i;
+       int hsc_en = 0, vsc_en = 0;
+       int vsc_double_line_mode;
+       unsigned int p_src_w, p_src_h;
+       unsigned int vert_phase_step, horz_phase_step;
+       unsigned char top_rcv_num, bot_rcv_num;
+       unsigned char top_rpt_num, bot_rpt_num;
+       unsigned short top_vphase, bot_vphase;
+       unsigned char is_frame;
+       int vert_bank_length = 4;
+
+       const unsigned int *filt_coef0 = di_filt_coef0;
+       /*unsigned int *filt_coef1 = di_filt_coef1;*/
+       const unsigned int *filt_coef2 = di_filt_coef2;
+
+       vsc_double_line_mode = 0;
+
+       if (src_h != dst_h)
+               vsc_en = 1;
+       if (src_w != dst_w)
+               hsc_en = 1;
+       /* config hdr size */
+       Wr_reg_bits(DI_HDR_IN_HSIZE, dst_w, 0, 13);
+       Wr_reg_bits(DI_HDR_IN_VSIZE, dst_h, 0, 13);
+       p_src_w = (prehsc_en ? ((src_w + 1) >> 1) : src_w);
+       p_src_h = prevsc_en ? ((src_h + 1) >> 1) : src_h;
+
+       Wr(DI_SC_HOLD_LINE, 0x10);
+
+       if (p_src_w > 2048) {
+               /*force vert bank length = 2*/
+               vert_bank_length = 2;
+               vsc_double_line_mode = 1;
+       }
+
+       /*write vert filter coefs*/
+       Wr(DI_SC_COEF_IDX, 0x0000);
+       for (i = 0; i < 33; i++) {
+               if (vert_bank_length == 2)
+                       Wr(DI_SC_COEF, filt_coef2[i]); /*bilinear*/
+               else
+                       Wr(DI_SC_COEF, filt_coef0[i]); /*bicubic*/
+       }
+
+       /*write horz filter coefs*/
+       Wr(DI_SC_COEF_IDX, 0x0100);
+       for (i = 0; i < 33; i++)
+               Wr(DI_SC_COEF, filt_coef0[i]); /*bicubic*/
+
+       if (p_src_h > 2048)
+               vert_phase_step = ((p_src_h << 18) / dst_h) << 2;
+       else
+               vert_phase_step = (p_src_h << 20) / dst_h;
+       if (p_src_w > 2048)
+               horz_phase_step = ((p_src_w << 18) / dst_w) << 2;
+       else
+               horz_phase_step = (p_src_w << 20) / dst_w;
+
+       is_frame = ((top_conv_type == F2V_IT2P) ||
+                       (top_conv_type == F2V_IB2P) ||
+                       (top_conv_type == F2V_P2P));
+
+       if (is_frame) {
+               f2v_get_vertical_phase(vert_phase_step, top_conv_type,
+                                      vert_bank_length, &vphase);
+               top_rcv_num = vphase.rcv_num;
+               top_rpt_num = vphase.rpt_num;
+               top_vphase  = vphase.phase;
+
+               bot_rcv_num = 0;
+               bot_rpt_num = 0;
+               bot_vphase  = 0;
+       } else {
+               f2v_get_vertical_phase(vert_phase_step, top_conv_type,
+                                      vert_bank_length, &vphase);
+               top_rcv_num = vphase.rcv_num;
+               top_rpt_num = vphase.rpt_num;
+               top_vphase = vphase.phase;
+
+               f2v_get_vertical_phase(vert_phase_step, bot_conv_type,
+                                      vert_bank_length, &vphase);
+               bot_rcv_num = vphase.rcv_num;
+               bot_rpt_num = vphase.rpt_num;
+               bot_vphase = vphase.phase;
+       }
+       vert_phase_step = (vert_phase_step << 4);
+       horz_phase_step = (horz_phase_step << 4);
+
+       Wr(DI_SC_LINE_IN_LENGTH, src_w);
+       Wr(DI_SC_PIC_IN_HEIGHT, src_h);
+       Wr(DI_VSC_REGION12_STARTP,  0);
+       Wr(DI_VSC_REGION34_STARTP, ((dst_h << 16) | dst_h));
+       Wr(DI_VSC_REGION4_ENDP, (dst_h - 1));
+
+       Wr(DI_VSC_START_PHASE_STEP, vert_phase_step);
+       Wr(DI_VSC_REGION0_PHASE_SLOPE, 0);
+       Wr(DI_VSC_REGION1_PHASE_SLOPE, 0);
+       Wr(DI_VSC_REGION3_PHASE_SLOPE, 0);
+       Wr(DI_VSC_REGION4_PHASE_SLOPE, 0);
+
+       Wr(DI_VSC_PHASE_CTRL,
+          ((vsc_double_line_mode << 17)        |
+          (!is_frame) << 16)                   |
+          (0 << 15)                            |
+          (bot_rpt_num << 13)                  |
+          (bot_rcv_num << 8)                   |
+          (0 << 7)                             |
+          (top_rpt_num << 5)                   |
+          (top_rcv_num));
+       Wr(DI_VSC_INI_PHASE, (bot_vphase << 16) | top_vphase);
+       Wr(DI_HSC_REGION12_STARTP, 0);
+       Wr(DI_HSC_REGION34_STARTP, (dst_w << 16) | dst_w);
+       Wr(DI_HSC_REGION4_ENDP, dst_w - 1);
+
+       Wr(DI_HSC_START_PHASE_STEP, horz_phase_step);
+       Wr(DI_HSC_REGION0_PHASE_SLOPE, 0);
+       Wr(DI_HSC_REGION1_PHASE_SLOPE, 0);
+       Wr(DI_HSC_REGION3_PHASE_SLOPE, 0);
+       Wr(DI_HSC_REGION4_PHASE_SLOPE, 0);
+
+       Wr(DI_HSC_PHASE_CTRL, (1 << 21) | (4 << 16) | 0);
+       Wr_reg_bits(DI_SC_TOP_CTRL, (path ? 3 : 0), 29, 2);
+       Wr(DI_SC_MISC,
+          (prevsc_en << 21)    |
+          (prehsc_en << 20)    |       /* prehsc_en */
+          (prevsc_en << 19)    |       /* prevsc_en */
+          (vsc_en << 18)       |       /* vsc_en */
+          (hsc_en << 17)       |       /* hsc_en */
+          ((vsc_en | hsc_en) << 16)    |       /* sc_top_en */
+          (1 << 15)            |       /* vd1 sc out enable */
+          (0 << 12)            |       /* horz nonlinear 4region enable */
+          (4 << 8)             |       /* horz scaler bank length */
+          (0 << 5)             |       /* vert scaler phase field enable */
+          (0 << 4)             |       /* vert nonlinear 4region enable */
+          (vert_bank_length << 0)      /* vert scaler bank length */
+          );
+
+       pr_info("[pps] %s input %d %d output %d %d.\n",
+               path ? "pre" : "post", src_w, src_h, dst_w, dst_h);
+}
+
+/*
+ * 0x374e ~ 0x376d, 20 regs
+ */
+void dim_dump_pps_reg(unsigned int base_addr)
+{
+       unsigned int i = 0x374e;
+
+       pr_info("-----dump pps start-----\n");
+       for (i = 0x374e; i < 0x376e; i++) {
+               pr_info("[0x%x][0x%x]=0x%x\n",
+                       base_addr + (i << 2),
+                       i, dim_RDMA_RD(i));
+       }
+       pr_info("-----dump pps end-----\n");
+}
+
+/*
+ * di pre h scaling down function
+ * only have h scaling down
+ * support: sm1 tm2 ...
+ * 0x37b0 ~ 0x37b5
+ */
+void dim_inp_hsc_setting(u32 src_w, u32 dst_w)
+{
+       u32 i;
+       u32 hsc_en;
+       u32 horz_phase_step;
+       const int *filt_coef0 = di_filt_coef0;
+       /*int *filt_coef1 = di_filt_coef1;*/
+       /*int *filt_coef2 = di_filt_coef2;*/
+
+       if (src_w == dst_w) {
+               hsc_en = 0;
+       } else {
+               hsc_en = 1;
+               /*write horz filter coefs*/
+               dim_RDMA_WR(DI_VIU_HSC_COEF_IDX, 0x0100);
+               for (i = 0; i < 33; i++)        /*bicubic*/
+                       dim_RDMA_WR(DI_VIU_HSC_COEF, filt_coef0[i]);
+
+               horz_phase_step = (src_w << 20) / dst_w;
+               horz_phase_step = (horz_phase_step << 4);
+               dim_RDMA_WR(DI_VIU_HSC_WIDTHM1,
+                           (src_w - 1) << 16 | (dst_w - 1));
+               dim_RDMA_WR(DI_VIU_HSC_PHASE_STEP, horz_phase_step);
+               dim_RDMA_WR(DI_VIU_HSC_PHASE_CTRL, 0);
+       }
+       dim_RDMA_WR(DI_VIU_HSC_CTRL,
+                   (4 << 20)   |       /* initial receive number*/
+                   (0 << 12)   |       /* initial pixel ptr*/
+                   (1 << 10)   |       /* repeat first pixel number*/
+                   (0 << 8)    |       /* sp422 mode*/
+                   (4 << 4)    |       /* horz scaler bank length*/
+                   (0 << 2)    |       /* phase0 always en*/
+                   (0 << 1)    |       /* nearest_en*/
+                   (hsc_en << 0));     /* hsc_en*/
+}
+
+/*
+ * 0x37b0 ~ 0x37b5
+ */
+void dim_dump_hdownscler_reg(unsigned int base_addr)
+{
+       unsigned int i = 0x374e;
+
+       pr_info("-----dump hdownscler start-----\n");
+       for (i = 0x37b0; i < 0x37b5; i++) {
+               pr_info("[0x%x][0x%x]=0x%x\n",
+                       base_addr + (i << 2),
+                       i, dim_RDMA_RD(i));
+       }
+       pr_info("-----dump hdownscler end-----\n");
+}
+
+int dim_seq_file_module_para_pps(struct seq_file *seq)
+{
+       seq_puts(seq, "pps---------------\n");
+
+       return 0;
+}
+
diff --git a/drivers/amlogic/media/di_multi/di_pps.h b/drivers/amlogic/media/di_multi/di_pps.h
new file mode 100644 (file)
index 0000000..334db9d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * drivers/amlogic/media/di_multi/di_pps.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef DI_PPS_H
+#define DI_PPS_H
+#include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/video_sink/vpp.h>
+#if 0
+#define VPP_FLAG_WIDEMODE_MASK      0x0000000F
+#define VPP_FLAG_INTERLACE_OUT      0x00000010
+#define VPP_FLAG_INTERLACE_IN       0x00000020
+#define VPP_FLAG_CBCR_SEPARATE      0x00000040
+#define VPP_FLAG_ZOOM_SHORTSIDE     0x00000080
+#define VPP_FLAG_AR_MASK            0x0003ff00
+#define VPP_FLAG_AR_BITS            8
+#define VPP_FLAG_PORTRAIT_MODE      0x00040000
+#define VPP_FLAG_VSCALE_DISABLE     0x00080000
+
+#define IDX_H           (2 << 8)
+#define IDX_V_Y         (1 << 13)
+#define IDX_V_CBCR      ((1 << 13) | (1 << 8))
+
+#define ASPECT_4_3      ((3 << 8) / 4)
+#define ASPECT_16_9     ((9 << 8) / 16)
+
+#define SPEED_CHECK_DONE       0
+#define SPEED_CHECK_HSKIP      1
+#define SPEED_CHECK_VSKIP      2
+
+enum f2v_vphase_type_e {
+       F2V_IT2IT = 0,
+       F2V_IB2IB,
+       F2V_IT2IB,
+       F2V_IB2IT,
+       F2V_P2IT,
+       F2V_P2IB,
+       F2V_IT2P,
+       F2V_IB2P,
+       F2V_P2P,
+       F2V_TYPE_MAX
+}; /* frame to video conversion type */
+#endif
+
+enum hdr2_scaler_e {
+       hdr2_scaler_postdi = 0,
+       hdr2_scaler_predi = 1,
+};
+
+struct pps_f2v_vphase_s {
+       unsigned char rcv_num;
+       unsigned char rpt_num;
+       unsigned short phase;
+};
+
+struct ppsfilter_mode_s {
+       u32 pps_hf_start_phase_step;
+       u32 pps_hf_start_phase_slope;
+       u32 pps_hf_end_phase_slope;
+       const u32 *pps_vert_coeff;
+       const u32 *pps_horz_coeff;
+       u32 pps_sc_misc_;
+       u32 pps_vsc_start_phase_step;
+       u32 pps_hsc_start_phase_step;
+       bool pps_pre_vsc_en;
+       bool pps_pre_hsc_en;
+       u32 pps_vert_filter;
+       u32 pps_horz_filter;
+       const u32 *pps_chroma_coeff;
+       u32 pps_chroma_filter_en;
+};
+
+struct pps_frame_par_s {
+       u32 pps_vsc_startp;
+       u32 pps_vsc_endp;
+       u32 pps_hsc_startp;
+       u32 pps_hsc_linear_startp;
+       u32 pps_hsc_linear_endp;
+       u32 pps_hsc_endp;
+       u32 VPP_hf_ini_phase_;
+       struct f2v_vphase_s VPP_vf_ini_phase_[9];
+       u32 pps_pic_in_height_;
+       u32 pps_line_in_length_;
+       struct ppsfilter_mode_s pps_filter;
+       u32 pps_3d_mode;
+       u32 trans_fmt;
+       /* bit[1:0] 0: 1 pic,1:two pic one buf,2:tow pic two buf */
+       /* bit[2]0:select pic0,1:select pic1 */
+       /* bit[3]0:pic0 first,1:pic1 first */
+       bool pps_3d_scale;
+};
+
+void dim_pps_config(unsigned char path, int src_w, int src_h,
+                   int dst_w, int dst_h);
+void dim_dump_pps_reg(unsigned int base_addr);
+void dim_inp_hsc_setting(u32 src_w, u32 dst_w);
+void dim_dump_hdownscler_reg(unsigned int base_addr);
+
+#endif
diff --git a/drivers/amlogic/media/di_multi/di_prc.c b/drivers/amlogic/media/di_multi/di_prc.c
new file mode 100644 (file)
index 0000000..3a98e99
--- /dev/null
@@ -0,0 +1,1966 @@
+/*
+ * drivers/amlogic/media/di_multi/di_prc.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "deinterlace.h"
+
+#include "di_data_l.h"
+#include "di_data.h"
+#include "di_dbg.h"
+#include "di_vframe.h"
+#include "di_que.h"
+#include "di_task.h"
+
+#include "di_prc.h"
+#include "di_pre.h"
+#include "di_post.h"
+#include "di_api.h"
+
+/**************************************
+ *
+ * cfg ctr top
+ *     bool
+ **************************************/
+
+const struct di_cfg_ctr_s di_cfg_top_ctr[K_DI_CFG_NUB] = {
+       /*same order with enum eDI_DBG_CFG*/
+       /* cfg for top */
+       [eDI_CFG_BEGIN]  = {"cfg top begin ", eDI_CFG_BEGIN, 0},
+
+       [eDI_CFG_first_bypass]  = {"first_bypass",
+               eDI_CFG_first_bypass, 1},
+       [eDI_CFG_ref_2]  = {"ref_2",
+               eDI_CFG_ref_2, 0},
+       [eDI_CFG_END]  = {"cfg top end ", eDI_CFG_END, 0},
+
+};
+
+char *di_cfg_top_get_name(enum eDI_CFG_TOP_IDX idx)
+{
+       return di_cfg_top_ctr[idx].name;
+}
+
+void di_cfg_top_get_info(unsigned int idx, char **name)
+{
+       if (di_cfg_top_ctr[idx].id != idx)
+               PR_ERR("%s:err:idx not map [%d->%d]\n", __func__,
+                      idx, di_cfg_top_ctr[idx].id);
+
+       *name = di_cfg_top_ctr[idx].name;
+}
+
+bool di_cfg_top_check(unsigned int idx)
+{
+       unsigned int tsize;
+
+       tsize = ARRAY_SIZE(di_cfg_top_ctr);
+       if (idx >= tsize) {
+               PR_ERR("%s:err:overflow:%d->%d\n",
+                      __func__, idx, tsize);
+               return false;
+       }
+       if (idx != di_cfg_top_ctr[idx].id) {
+               PR_ERR("%s:err:not map:%d->%d\n",
+                      __func__, idx, di_cfg_top_ctr[idx].id);
+               return false;
+       }
+       pr_info("\t%-15s=%d\n", di_cfg_top_ctr[idx].name,
+               di_cfg_top_ctr[idx].default_val);
+       return true;
+}
+
+void di_cfg_top_init_val(void)
+{
+       int i;
+
+       pr_info("%s:\n", __func__);
+       for (i = eDI_CFG_BEGIN; i < eDI_CFG_END; i++) {
+               if (!di_cfg_top_check(i))
+                       continue;
+               di_cfg_top_set(i, di_cfg_top_ctr[i].default_val);
+       }
+       pr_info("%s:finish\n", __func__);
+}
+
+bool di_cfg_top_get(enum eDI_CFG_TOP_IDX id)
+{
+       return get_datal()->cfg_en[id];
+}
+
+void di_cfg_top_set(enum eDI_CFG_TOP_IDX id, bool en)
+{
+       get_datal()->cfg_en[id] = en;
+}
+
+/**************************************
+ *
+ * cfg ctr x
+ *     bool
+ **************************************/
+
+const struct di_cfgx_ctr_s di_cfgx_ctr[K_DI_CFGX_NUB] = {
+       /*same order with enum eDI_DBG_CFG*/
+
+       /* cfg channel x*/
+       [eDI_CFGX_BEGIN]  = {"cfg x begin ", eDI_CFGX_BEGIN, 0},
+       /* bypass_all */
+       [eDI_CFGX_BYPASS_ALL]  = {"bypass_all", eDI_CFGX_BYPASS_ALL, 0},
+       [eDI_CFGX_END]  = {"cfg x end ", eDI_CFGX_END, 0},
+
+       /* debug cfg x */
+       [eDI_DBG_CFGX_BEGIN]  = {"cfg dbg begin ", eDI_DBG_CFGX_BEGIN, 0},
+       [eDI_DBG_CFGX_IDX_VFM_IN] = {"vfm_in", eDI_DBG_CFGX_IDX_VFM_IN, 0},
+       [eDI_DBG_CFGX_IDX_VFM_OT] = {"vfm_out", eDI_DBG_CFGX_IDX_VFM_OT, 1},
+       [eDI_DBG_CFGX_END]    = {"cfg dbg end", eDI_DBG_CFGX_END, 0},
+};
+
+char *di_cfgx_get_name(enum eDI_CFGX_IDX idx)
+{
+       return di_cfgx_ctr[idx].name;
+}
+
+void di_cfgx_get_info(enum eDI_CFGX_IDX idx, char **name)
+{
+       if (di_cfgx_ctr[idx].id != idx)
+               PR_ERR("%s:err:idx not map [%d->%d]\n", __func__,
+                      idx, di_cfgx_ctr[idx].id);
+
+       *name = di_cfgx_ctr[idx].name;
+}
+
+bool di_cfgx_check(unsigned int idx)
+{
+       unsigned int tsize;
+
+       tsize = ARRAY_SIZE(di_cfgx_ctr);
+       if (idx >= tsize) {
+               PR_ERR("%s:err:overflow:%d->%d\n",
+                      __func__, idx, tsize);
+               return false;
+       }
+       if (idx != di_cfgx_ctr[idx].id) {
+               PR_ERR("%s:err:not map:%d->%d\n",
+                      __func__, idx, di_cfgx_ctr[idx].id);
+               return false;
+       }
+       pr_info("\t%-15s=%d\n", di_cfgx_ctr[idx].name,
+               di_cfgx_ctr[idx].default_val);
+       return true;
+}
+
+void di_cfgx_init_val(void)
+{
+       int i, ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               for (i = eDI_CFGX_BEGIN; i < eDI_DBG_CFGX_END; i++)
+                       di_cfgx_set(ch, i, di_cfgx_ctr[i].default_val);
+       }
+}
+
+bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx)
+{
+       return get_datal()->ch_data[ch].cfgx_en[idx];
+}
+
+void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en)
+{
+       get_datal()->ch_data[ch].cfgx_en[idx] = en;
+}
+
+/**************************************
+ *
+ * module para top
+ *     int
+ **************************************/
+
+const struct di_mp_uit_s di_mp_ui_top[] = {
+       /*same order with enum eDI_MP_UI*/
+       /* for top */
+       [eDI_MP_UI_T_BEGIN]  = {"module para top begin ",
+                       eDI_MP_UI_T_BEGIN, 0},
+       /**************************************/
+       [eDI_MP_SUB_DI_B]  = {"di begin ",
+                       eDI_MP_SUB_DI_B, 0},
+       [eDI_MP_force_prog]  = {"bool:force_prog:1",
+                       eDI_MP_force_prog, 1},
+       [eDI_MP_combing_fix_en]  = {"bool:combing_fix_en,def:1",
+                       eDI_MP_combing_fix_en, 1},
+       [eDI_MP_cur_lev]  = {"int cur_lev,def:2",
+                       eDI_MP_cur_lev, 2},
+       [eDI_MP_pps_dstw]  = {"pps_dstw:int",
+                       eDI_MP_pps_dstw, 0},
+       [eDI_MP_pps_dsth]  = {"pps_dsth:int",
+                       eDI_MP_pps_dsth, 0},
+       [eDI_MP_pps_en]  = {"pps_en:bool",
+                       eDI_MP_pps_en, 0},
+       [eDI_MP_pps_position]  = {"pps_position:uint:def:1",
+                       eDI_MP_pps_position, 1},
+       [eDI_MP_pre_enable_mask]  = {"pre_enable_mask:bit0:ma;bit1:mc:def:3",
+                       eDI_MP_pre_enable_mask, 3},
+       [eDI_MP_post_refresh]  = {"post_refresh:bool",
+                       eDI_MP_post_refresh, 0},
+       [eDI_MP_nrds_en]  = {"nrds_en:bool",
+                       eDI_MP_nrds_en, 0},
+       [eDI_MP_bypass_3d]  = {"bypass_3d:int:def:1",
+                       eDI_MP_bypass_3d, 1},
+       [eDI_MP_bypass_trick_mode]  = {"bypass_trick_mode:int:def:1",
+                       eDI_MP_bypass_trick_mode, 1},
+       [eDI_MP_invert_top_bot]  = {"invert_top_bot:int",
+                       eDI_MP_invert_top_bot, 0},
+       [eDI_MP_skip_top_bot]  = {"skip_top_bot:int:",
+                       /*1or2: may affect atv when bypass di*/
+                       eDI_MP_skip_top_bot, 0},
+       [eDI_MP_force_width]  = {"force_width:int",
+                       eDI_MP_force_width, 0},
+       [eDI_MP_force_height]  = {"force_height:int",
+                       eDI_MP_force_height, 0},
+       [eDI_MP_prog_proc_config]  = {"prog_proc_config:int:def:0x",
+/* prog_proc_config,
+ * bit[2:1]: when two field buffers are used,
+ * 0 use vpp for blending ,
+ * 1 use post_di module for blending
+ * 2 debug mode, bob with top field
+ * 3 debug mode, bot with bot field
+ * bit[0]:
+ * 0 "prog vdin" use two field buffers,
+ * 1 "prog vdin" use single frame buffer
+ * bit[4]:
+ * 0 "prog frame from decoder/vdin" use two field buffers,
+ * 1 use single frame buffer
+ * bit[5]:
+ * when two field buffers are used for decoder (bit[4] is 0):
+ * 1,handle prog frame as two interlace frames
+ * bit[6]:(bit[4] is 0,bit[5] is 0,use_2_interlace_buff is 0): 0,
+ * process progress frame as field,blend by post;
+ * 1, process progress frame as field,process by normal di
+ */
+                       eDI_MP_prog_proc_config, ((1 << 5) | (1 << 1) | 1)},
+       [eDI_MP_start_frame_drop_count]  = {"start_frame_drop_count:int:2",
+                       eDI_MP_start_frame_drop_count, 2},
+       [eDI_MP_same_field_top_count]  = {"same_field_top_count:long?",
+                       eDI_MP_same_field_top_count, 0},
+       [eDI_MP_same_field_bot_count]  = {"same_field_bot_count:long?",
+                       eDI_MP_same_field_bot_count, 0},
+       [eDI_MP_vpp_3d_mode]  = {"vpp_3d_mode:int",
+                       eDI_MP_vpp_3d_mode, 0},
+       [eDI_MP_force_recovery_count]  = {"force_recovery_count:uint",
+                       eDI_MP_force_recovery_count, 0},
+       [eDI_MP_pre_process_time]  = {"pre_process_time:int",
+                       eDI_MP_pre_process_time, 0},
+       [eDI_MP_bypass_post]  = {"bypass_post:int",
+                       eDI_MP_bypass_post, 0},
+       [eDI_MP_post_wr_en]  = {"post_wr_en:bool:1",
+                       eDI_MP_post_wr_en, 1},
+       [eDI_MP_post_wr_support]  = {"post_wr_support:uint",
+                       eDI_MP_post_wr_support, 0},
+       [eDI_MP_bypass_post_state]  = {"bypass_post_state:int",
+/* 0, use di_wr_buf still;
+ * 1, call dim_pre_de_done_buf_clear to clear di_wr_buf;
+ * 2, do nothing
+ */
+                       eDI_MP_bypass_post_state, 0},
+       [eDI_MP_use_2_interlace_buff]  = {"use_2_interlace_buff:int",
+                       eDI_MP_use_2_interlace_buff, 0},
+       [eDI_MP_debug_blend_mode]  = {"debug_blend_mode:int:-1",
+                       eDI_MP_debug_blend_mode, -1},
+       [eDI_MP_nr10bit_support]  = {"nr10bit_support:uint",
+               /* 0: not support nr10bit, 1: support nr10bit */
+                       eDI_MP_nr10bit_support, 0},
+       [eDI_MP_di_stop_reg_flag]  = {"di_stop_reg_flag:uint",
+                       eDI_MP_di_stop_reg_flag, 0},
+       [eDI_MP_mcpre_en]  = {"mcpre_en:bool:true",
+                       eDI_MP_mcpre_en, 1},
+       [eDI_MP_check_start_drop_prog]  = {"check_start_drop_prog:bool",
+                       eDI_MP_check_start_drop_prog, 0},
+       [eDI_MP_overturn]  = {"overturn:bool:?",
+                       eDI_MP_overturn, 0},
+       [eDI_MP_full_422_pack]  = {"full_422_pack:bool",
+                       eDI_MP_full_422_pack, 0},
+       [eDI_MP_cma_print]  = {"cma_print:bool:1",
+                       eDI_MP_cma_print, 0},
+       [eDI_MP_pulldown_enable]  = {"pulldown_enable:bool:1",
+                       eDI_MP_pulldown_enable, 1},
+       [eDI_MP_di_force_bit_mode]  = {"di_force_bit_mode:uint:10",
+                       eDI_MP_di_force_bit_mode, 10},
+       [eDI_MP_calc_mcinfo_en]  = {"calc_mcinfo_en:bool:1",
+                       eDI_MP_calc_mcinfo_en, 1},
+       [eDI_MP_colcfd_thr]  = {"colcfd_thr:uint:128",
+                       eDI_MP_colcfd_thr, 128},
+       [eDI_MP_post_blend]  = {"post_blend:uint",
+                       eDI_MP_post_blend, 0},
+       [eDI_MP_post_ei]  = {"post_ei:uint",
+                       eDI_MP_post_ei, 0},
+       [eDI_MP_post_cnt]  = {"post_cnt:uint",
+                       eDI_MP_post_cnt, 0},
+       [eDI_MP_di_log_flag]  = {"di_log_flag:uint",
+                       eDI_MP_di_log_flag, 0},
+       [eDI_MP_di_debug_flag]  = {"di_debug_flag:uint",
+                       eDI_MP_di_debug_flag, 0},
+       [eDI_MP_buf_state_log_threshold]  = {"buf_state_log_threshold:unit:16",
+                       eDI_MP_buf_state_log_threshold, 16},
+       [eDI_MP_di_vscale_skip_enable]  = {"di_vscale_skip_enable:int",
+/*
+ * bit[2]: enable bypass all when skip
+ * bit[1:0]: enable bypass post when skip
+ */
+                       eDI_MP_di_vscale_skip_enable, 0},
+       [eDI_MP_di_vscale_skip_count]  = {"di_vscale_skip_count:int",
+                       eDI_MP_di_vscale_skip_count, 0},
+       [eDI_MP_di_vscale_skip_count_real]  = {"di_vscale_skip_count_real:int",
+                       eDI_MP_di_vscale_skip_count_real, 0},
+       [eDI_MP_det3d_en]  = {"det3d_en:bool",
+                       eDI_MP_det3d_en, 0},
+       [eDI_MP_post_hold_line]  = {"post_hold_line:int:8",
+                       eDI_MP_post_hold_line, 8},
+       [eDI_MP_post_urgent]  = {"post_urgent:int:1",
+                       eDI_MP_post_urgent, 1},
+       [eDI_MP_di_printk_flag]  = {"di_printk_flag:uint",
+                       eDI_MP_di_printk_flag, 0},
+       [eDI_MP_force_recovery]  = {"force_recovery:uint:1",
+                       eDI_MP_force_recovery, 1},
+#if 0
+       [eDI_MP_debug_blend_mode]  = {"debug_blend_mode:int:-1",
+                       eDI_MP_debug_blend_mode, -1},
+#endif
+       [eDI_MP_di_dbg_mask]  = {"di_dbg_mask:uint:0x02",
+                       eDI_MP_di_dbg_mask, 2},
+       [eDI_MP_nr_done_check_cnt]  = {"nr_done_check_cnt:uint:5",
+                       eDI_MP_nr_done_check_cnt, 5},
+       [eDI_MP_pre_hsc_down_en]  = {"pre_hsc_down_en:bool:0",
+                       eDI_MP_pre_hsc_down_en, 0},
+       [eDI_MP_pre_hsc_down_width]  = {"pre_hsc_down_width:int:480",
+                               eDI_MP_pre_hsc_down_width, 480},
+       [eDI_MP_show_nrwr]  = {"show_nrwr:bool:0",
+                               eDI_MP_show_nrwr, 0},
+
+       /******deinterlace_hw.c**********/
+       [eDI_MP_pq_load_dbg]  = {"pq_load_dbg:uint",
+                       eDI_MP_pq_load_dbg, 0},
+       [eDI_MP_lmv_lock_win_en]  = {"lmv_lock_win_en:bool",
+                       eDI_MP_lmv_lock_win_en, 0},
+       [eDI_MP_lmv_dist]  = {"lmv_dist:short:5",
+                       eDI_MP_lmv_dist, 5},
+       [eDI_MP_pr_mcinfo_cnt]  = {"pr_mcinfo_cnt:ushort",
+                       eDI_MP_pr_mcinfo_cnt, 0},
+       [eDI_MP_offset_lmv]  = {"offset_lmv:short:100",
+                       eDI_MP_offset_lmv, 100},
+       [eDI_MP_post_ctrl]  = {"post_ctrl:uint",
+                       eDI_MP_post_ctrl, 0},
+       [eDI_MP_if2_disable]  = {"if2_disable:bool",
+                       eDI_MP_if2_disable, 0},
+       [eDI_MP_pre_flag]  = {"pre_flag:ushort:2",
+                       eDI_MP_pre_flag, 2},
+       [eDI_MP_pre_mif_gate]  = {"pre_mif_gate:bool",
+                       eDI_MP_pre_mif_gate, 0},
+       [eDI_MP_pre_urgent]  = {"pre_urgent:ushort",
+                       eDI_MP_pre_urgent, 0},
+       [eDI_MP_pre_hold_line]  = {"pre_hold_line:ushort:10",
+                       eDI_MP_pre_hold_line, 10},
+       [eDI_MP_pre_ctrl]  = {"pre_ctrl:uint",
+                       eDI_MP_pre_ctrl, 0},
+       [eDI_MP_line_num_post_frst]  = {"line_num_post_frst:ushort:5",
+                       eDI_MP_line_num_post_frst, 5},
+       [eDI_MP_line_num_pre_frst]  = {"line_num_pre_frst:ushort:5",
+                       eDI_MP_line_num_pre_frst, 5},
+       [eDI_MP_pd22_flg_calc_en]  = {"pd22_flg_calc_en:bool:true",
+                       eDI_MP_pd22_flg_calc_en, 1},
+       [eDI_MP_mcen_mode]  = {"mcen_mode:ushort:1",
+                       eDI_MP_mcen_mode, 1},
+       [eDI_MP_mcuv_en]  = {"mcuv_en:ushort:1",
+                       eDI_MP_mcuv_en, 1},
+       [eDI_MP_mcdebug_mode]  = {"mcdebug_mode:ushort",
+                       eDI_MP_mcdebug_mode, 0},
+       [eDI_MP_pldn_ctrl_rflsh]  = {"pldn_ctrl_rflsh:uint:1",
+                       eDI_MP_pldn_ctrl_rflsh, 1},
+
+       [eDI_MP_SUB_DI_E]  = {"di end-------",
+                               eDI_MP_SUB_DI_E, 0},
+       /**************************************/
+       [eDI_MP_SUB_NR_B]  = {"nr begin",
+                       eDI_MP_SUB_NR_B, 0},
+       [eDI_MP_dnr_en]  = {"dnr_en:bool:true",
+                       eDI_MP_dnr_en, 1},
+       [eDI_MP_nr2_en]  = {"nr2_en:uint:1",
+                       eDI_MP_nr2_en, 1},
+       [eDI_MP_cue_en]  = {"cue_en:bool:true",
+                       eDI_MP_cue_en, 1},
+       [eDI_MP_invert_cue_phase]  = {"invert_cue_phase:bool",
+                       eDI_MP_invert_cue_phase, 0},
+       [eDI_MP_cue_pr_cnt]  = {"cue_pr_cnt:uint",
+                       eDI_MP_cue_pr_cnt, 0},
+       [eDI_MP_cue_glb_mot_check_en]  = {"cue_glb_mot_check_en:bool:true",
+                       eDI_MP_cue_glb_mot_check_en, 1},
+       [eDI_MP_glb_fieldck_en]  = {"glb_fieldck_en:bool:true",
+                       eDI_MP_glb_fieldck_en, 1},
+       [eDI_MP_dnr_pr]  = {"dnr_pr:bool",
+                       eDI_MP_dnr_pr, 0},
+       [eDI_MP_dnr_dm_en]  = {"dnr_dm_en:bool",
+                       eDI_MP_dnr_dm_en, 0},
+       [eDI_MP_SUB_NR_E]  = {"nr end-------",
+                       eDI_MP_SUB_NR_E, 0},
+       /**************************************/
+       [eDI_MP_SUB_PD_B]  = {"pd begin",
+                       eDI_MP_SUB_PD_B, 0},
+       [eDI_MP_flm22_ratio]  = {"flm22_ratio:uint:200",
+                       eDI_MP_flm22_ratio, 200},
+       [eDI_MP_pldn_cmb0]  = {"pldn_cmb0:uint:1",
+                       eDI_MP_pldn_cmb0, 1},
+       [eDI_MP_pldn_cmb1]  = {"pldn_cmb1:uint",
+                       eDI_MP_pldn_cmb1, 0},
+       [eDI_MP_flm22_sure_num]  = {"flm22_sure_num:uint:100",
+                       eDI_MP_flm22_sure_num, 100},
+       [eDI_MP_flm22_glbpxlnum_rat]  = {"flm22_glbpxlnum_rat:uint:4",
+                       eDI_MP_flm22_glbpxlnum_rat, 4},
+       [eDI_MP_flag_di_weave]  = {"flag_di_weave:int:1",
+                       eDI_MP_flag_di_weave, 1},
+       [eDI_MP_flm22_glbpxl_maxrow]  = {"flm22_glbpxl_maxrow:uint:16",
+                       eDI_MP_flm22_glbpxl_maxrow, 16},
+       [eDI_MP_flm22_glbpxl_minrow]  = {"flm22_glbpxl_minrow:uint:3",
+                       eDI_MP_flm22_glbpxl_minrow, 3},
+       [eDI_MP_cmb_3point_rnum]  = {"cmb_3point_rnum:uint",
+                       eDI_MP_cmb_3point_rnum, 0},
+       [eDI_MP_cmb_3point_rrat]  = {"cmb_3point_rrat:unit:32",
+                       eDI_MP_cmb_3point_rrat, 32},
+       /********************************/
+       [eDI_MP_pr_pd]  = {"pr_pd:uint",
+                       eDI_MP_pr_pd, 0},
+       [eDI_MP_prt_flg]  = {"prt_flg:bool",
+                       eDI_MP_prt_flg, 0},
+       [eDI_MP_flmxx_maybe_num]  = {"flmxx_maybe_num:uint:15",
+       /* if flmxx level > flmxx_maybe_num */
+       /* mabye flmxx: when 2-2 3-2 not detected */
+                       eDI_MP_flmxx_maybe_num, 15},
+       [eDI_MP_flm32_mim_frms]  = {"flm32_mim_frms:int:6",
+                       eDI_MP_flm32_mim_frms, 6},
+       [eDI_MP_flm22_dif01a_flag]  = {"flm22_dif01a_flag:int:1",
+                       eDI_MP_flm22_dif01a_flag, 1},
+       [eDI_MP_flm22_mim_frms]  = {"flm22_mim_frms:int:60",
+                       eDI_MP_flm22_mim_frms, 60},
+       [eDI_MP_flm22_mim_smfrms]  = {"flm22_mim_smfrms:int:40",
+                       eDI_MP_flm22_mim_smfrms, 40},
+       [eDI_MP_flm32_f2fdif_min0]  = {"flm32_f2fdif_min0:int:11",
+                       eDI_MP_flm32_f2fdif_min0, 11},
+       [eDI_MP_flm32_f2fdif_min1]  = {"flm32_f2fdif_min1:int:11",
+                       eDI_MP_flm32_f2fdif_min1, 11},
+       [eDI_MP_flm32_chk1_rtn]  = {"flm32_chk1_rtn:int:25",
+                       eDI_MP_flm32_chk1_rtn, 25},
+       [eDI_MP_flm32_ck13_rtn]  = {"flm32_ck13_rtn:int:8",
+                       eDI_MP_flm32_ck13_rtn, 8},
+       [eDI_MP_flm32_chk2_rtn]  = {"flm32_chk2_rtn:int:16",
+                       eDI_MP_flm32_chk2_rtn, 16},
+       [eDI_MP_flm32_chk3_rtn]  = {"flm32_chk3_rtn:int:16",
+                       eDI_MP_flm32_chk3_rtn, 16},
+       [eDI_MP_flm32_dif02_ratio]  = {"flm32_dif02_ratio:int:8",
+                       eDI_MP_flm32_dif02_ratio, 8},
+       [eDI_MP_flm22_chk20_sml]  = {"flm22_chk20_sml:int:6",
+                       eDI_MP_flm22_chk20_sml, 6},
+       [eDI_MP_flm22_chk21_sml]  = {"flm22_chk21_sml:int:6",
+                       eDI_MP_flm22_chk21_sml, 6},
+       [eDI_MP_flm22_chk21_sm2]  = {"flm22_chk21_sm2:int:10",
+                       eDI_MP_flm22_chk21_sm2, 10},
+       [eDI_MP_flm22_lavg_sft]  = {"flm22_lavg_sft:int:4",
+                       eDI_MP_flm22_lavg_sft, 4},
+       [eDI_MP_flm22_lavg_lg]  = {"flm22_lavg_lg:int:24",
+                       eDI_MP_flm22_lavg_lg, 24},
+       [eDI_MP_flm22_stl_sft]  = {"flm22_stl_sft:int:7",
+                       eDI_MP_flm22_stl_sft, 7},
+       [eDI_MP_flm22_chk5_avg]  = {"flm22_chk5_avg:int:50",
+                       eDI_MP_flm22_chk5_avg, 50},
+       [eDI_MP_flm22_chk6_max]  = {"flm22_chk6_max:int:20",
+                       eDI_MP_flm22_chk6_max, 20},
+       [eDI_MP_flm22_anti_chk1]  = {"flm22_anti_chk1:int:61",
+                       eDI_MP_flm22_anti_chk1, 61},
+       [eDI_MP_flm22_anti_chk3]  = {"flm22_anti_chk3:int:140",
+                       eDI_MP_flm22_anti_chk3, 140},
+       [eDI_MP_flm22_anti_chk4]  = {"flm22_anti_chk4:int:128",
+                       eDI_MP_flm22_anti_chk4, 128},
+       [eDI_MP_flm22_anti_ck140]  = {"flm22_anti_ck140:int:32",
+                       eDI_MP_flm22_anti_ck140, 32},
+       [eDI_MP_flm22_anti_ck141]  = {"flm22_anti_ck141:int:80",
+                       eDI_MP_flm22_anti_ck141, 80},
+       [eDI_MP_flm22_frmdif_max]  = {"flm22_frmdif_max:int:50",
+                       eDI_MP_flm22_frmdif_max, 50},
+       [eDI_MP_flm22_flddif_max]  = {"flm22_flddif_max:int:100",
+                       eDI_MP_flm22_flddif_max, 100},
+       [eDI_MP_flm22_minus_cntmax]  = {"flm22_minus_cntmax:int:2",
+                       eDI_MP_flm22_minus_cntmax, 2},
+       [eDI_MP_flagdif01chk]  = {"flagdif01chk:int:1",
+                       eDI_MP_flagdif01chk, 1},
+       [eDI_MP_dif01_ratio]  = {"dif01_ratio:int:10",
+                       eDI_MP_dif01_ratio, 10},
+       /*************vof_soft_top**************/
+       [eDI_MP_cmb32_blw_wnd]  = {"cmb32_blw_wnd:int:180",
+                       eDI_MP_cmb32_blw_wnd, 180},
+       [eDI_MP_cmb32_wnd_ext]  = {"cmb32_wnd_ext:int:11",
+                       eDI_MP_cmb32_wnd_ext, 11},
+       [eDI_MP_cmb32_wnd_tol]  = {"cmb32_wnd_tol:int:4",
+                       eDI_MP_cmb32_wnd_tol, 4},
+       [eDI_MP_cmb32_frm_nocmb]  = {"cmb32_frm_nocmb:int:40",
+                       eDI_MP_cmb32_frm_nocmb, 40},
+       [eDI_MP_cmb32_min02_sft]  = {"cmb32_min02_sft:int:7",
+                       eDI_MP_cmb32_min02_sft, 7},
+       [eDI_MP_cmb32_cmb_tol]  = {"cmb32_cmb_tol:int:10",
+                       eDI_MP_cmb32_cmb_tol, 10},
+       [eDI_MP_cmb32_avg_dff]  = {"cmb32_avg_dff:int:48",
+                       eDI_MP_cmb32_avg_dff, 48},
+       [eDI_MP_cmb32_smfrm_num]  = {"cmb32_smfrm_num:int:4",
+                       eDI_MP_cmb32_smfrm_num, 4},
+       [eDI_MP_cmb32_nocmb_num]  = {"cmb32_nocmb_num:int:20",
+                       eDI_MP_cmb32_nocmb_num, 20},
+       [eDI_MP_cmb22_gcmb_rnum]  = {"cmb22_gcmb_rnum:int:8",
+                       eDI_MP_cmb22_gcmb_rnum, 8},
+       [eDI_MP_flmxx_cal_lcmb]  = {"flmxx_cal_lcmb:int:1",
+                       eDI_MP_flmxx_cal_lcmb, 1},
+       [eDI_MP_flm2224_stl_sft]  = {"flm2224_stl_sft:int:7",
+                       eDI_MP_flm2224_stl_sft, 7},
+       [eDI_MP_SUB_PD_E]  = {"pd end------",
+                       eDI_MP_SUB_PD_E, 0},
+       /**************************************/
+       [eDI_MP_SUB_MTN_B]  = {"mtn begin",
+                       eDI_MP_SUB_MTN_B, 0},
+       [eDI_MP_force_lev]  = {"force_lev:int:0xff",
+                       eDI_MP_force_lev, 0xff},
+       [eDI_MP_dejaggy_flag]  = {"dejaggy_flag:int:-1",
+                       eDI_MP_dejaggy_flag, -1},
+       [eDI_MP_dejaggy_enable]  = {"dejaggy_enable:int:1",
+                       eDI_MP_dejaggy_enable, 1},
+       [eDI_MP_cmb_adpset_cnt]  = {"cmb_adpset_cnt:int",
+                       eDI_MP_cmb_adpset_cnt, 0},
+       [eDI_MP_cmb_num_rat_ctl4]  = {"cmb_num_rat_ctl4:int:64:0~255",
+                       eDI_MP_cmb_num_rat_ctl4, 64},
+       [eDI_MP_cmb_rat_ctl4_minthd]  = {"cmb_rat_ctl4_minthd:int:64",
+                       eDI_MP_cmb_rat_ctl4_minthd, 64},
+       [eDI_MP_small_local_mtn]  = {"small_local_mtn:uint:70",
+                       eDI_MP_small_local_mtn, 70},
+       [eDI_MP_di_debug_readreg]  = {"di_debug_readreg:int",
+                       eDI_MP_di_debug_readreg, 0},
+       [eDI_MP_SUB_MTN_E]  = {"mtn end----",
+                       eDI_MP_SUB_MTN_E, 0},
+       /**************************************/
+       [eDI_MP_SUB_3D_B]  = {"3d begin",
+                       eDI_MP_SUB_3D_B, 0},
+       [eDI_MP_chessbd_vrate]  = {"chessbd_vrate:int:29",
+                               eDI_MP_chessbd_vrate, 29},
+       [eDI_MP_det3d_debug]  = {"det3d_debug:bool:0",
+                               eDI_MP_det3d_debug, 0},
+       [eDI_MP_SUB_3D_E]  = {"3d begin",
+                               eDI_MP_SUB_3D_E, 0},
+
+       /**************************************/
+       [eDI_MP_UI_T_END]  = {"module para top end ", eDI_MP_UI_T_END, 0},
+};
+
+bool di_mp_uit_check(unsigned int idx)
+{
+       unsigned int tsize;
+
+       tsize = ARRAY_SIZE(di_mp_ui_top);
+       if (idx >= tsize) {
+               PR_ERR("%s:err:overflow:%d->%d\n",
+                      __func__, idx, tsize);
+               return false;
+       }
+       if (idx != di_mp_ui_top[idx].id) {
+               PR_ERR("%s:err:not map:%d->%d\n",
+                      __func__, idx, di_mp_ui_top[idx].id);
+               return false;
+       }
+       dbg_init("\t%-15s=%d\n", di_mp_ui_top[idx].name,
+                di_mp_ui_top[idx].default_val);
+       return true;
+}
+
+char *di_mp_uit_get_name(enum eDI_MP_UI_T idx)
+{
+       return di_mp_ui_top[idx].name;
+}
+
+void di_mp_uit_init_val(void)
+{
+       int i;
+
+       for (i = eDI_MP_UI_T_BEGIN; i < eDI_MP_UI_T_END; i++) {
+               if (!di_mp_uit_check(i))
+                       continue;
+               di_mp_uit_set(i, di_mp_ui_top[i].default_val);
+       }
+}
+
+int di_mp_uit_get(enum eDI_MP_UI_T idx)
+{
+       return get_datal()->mp_uit[idx];
+}
+
+void di_mp_uit_set(enum eDI_MP_UI_T idx, int val)
+{
+       get_datal()->mp_uit[idx] = val;
+}
+
+/**************************************
+ *
+ * module para x
+ *     unsigned int
+ **************************************/
+
+const struct di_mp_uix_s di_mpx[] = {
+       /*same order with enum eDI_MP_UI*/
+
+       /* module para for channel x*/
+       [eDI_MP_UIX_BEGIN]  = {"module para x begin ", eDI_MP_UIX_BEGIN, 0},
+       /*debug:        run_flag*/
+       [eDI_MP_UIX_RUN_FLG]  = {"run_flag(0:run;1:pause;2:step)",
+                               eDI_MP_UIX_RUN_FLG, DI_RUN_FLAG_RUN},
+       [eDI_MP_UIX_END]  = {"module para x end ", eDI_MP_UIX_END, 0},
+
+};
+
+bool di_mp_uix_check(unsigned int idx)
+{
+       unsigned int tsize;
+
+       tsize = ARRAY_SIZE(di_mpx);
+       if (idx >= tsize) {
+               PR_ERR("%s:err:overflow:%d->%d\n",
+                      __func__, idx, tsize);
+               return false;
+       }
+       if (idx != di_mpx[idx].id) {
+               PR_ERR("%s:err:not map:%d->%d\n",
+                      __func__, idx, di_mpx[idx].id);
+               return false;
+       }
+       dbg_init("\t%-15s=%d\n", di_mpx[idx].name, di_mpx[idx].default_val);
+
+       return true;
+}
+
+char *di_mp_uix_get_name(enum eDI_MP_UIX_T idx)
+{
+       return di_mpx[idx].name;
+}
+
+void di_mp_uix_init_val(void)
+{
+       int i, ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               dbg_init("%s:ch[%d]\n", __func__, ch);
+               for (i = eDI_MP_UIX_BEGIN; i < eDI_MP_UIX_END; i++) {
+                       if (ch == 0) {
+                               if (!di_mp_uix_check(i))
+                                       continue;
+                       }
+                       di_mp_uix_set(ch, i, di_mpx[i].default_val);
+               }
+       }
+}
+
+unsigned int di_mp_uix_get(unsigned int ch, enum eDI_MP_UIX_T idx)
+{
+       return get_datal()->ch_data[ch].mp_uix[idx];
+}
+
+void di_mp_uix_set(unsigned int ch, enum eDI_MP_UIX_T idx, unsigned int val)
+{
+       get_datal()->ch_data[ch].mp_uix[idx] = val;
+}
+
+bool di_is_pause(unsigned int ch)
+{
+       unsigned int run_flag;
+
+       run_flag = di_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG);
+
+       if (run_flag == DI_RUN_FLAG_PAUSE       ||
+           run_flag == DI_RUN_FLAG_STEP_DONE)
+               return true;
+
+       return false;
+}
+
+void di_pause_step_done(unsigned int ch)
+{
+       unsigned int run_flag;
+
+       run_flag = di_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG);
+       if (run_flag == DI_RUN_FLAG_STEP) {
+               di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG,
+                             DI_RUN_FLAG_STEP_DONE);
+       }
+}
+
+void di_pause(unsigned int ch, bool on)
+{
+       pr_info("%s:%d\n", __func__, on);
+       if (on)
+               di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG,
+                             DI_RUN_FLAG_PAUSE);
+       else
+               di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG,
+                             DI_RUN_FLAG_RUN);
+}
+
+/**************************************
+ *
+ * summmary variable
+ *
+ **************************************/
+const struct di_sum_s di_sum_tab[] = {
+       /*video_peek_cnt*/
+       [eDI_SUM_O_PEEK_CNT] = {"o_peek_cnt", eDI_SUM_O_PEEK_CNT, 0},
+       /*di_reg_unreg_cnt*/
+       [eDI_SUM_REG_UNREG_CNT] = {
+                       "di_reg_unreg_cnt", eDI_SUM_REG_UNREG_CNT, 100},
+
+       [eDI_SUM_NUB] = {"end", eDI_SUM_NUB, 0},
+};
+
+unsigned int di_sum_get_tab_size(void)
+{
+       return ARRAY_SIZE(di_sum_tab);
+}
+
+bool di_sum_check(unsigned int ch, enum eDI_SUM id)
+{
+       unsigned int tsize;
+
+       tsize = ARRAY_SIZE(di_sum_tab);
+
+       if (id >= tsize) {
+               PR_ERR("%s:err:overflow:tsize[%d],id[%d]\n",
+                      __func__, tsize, id);
+               return false;
+       }
+       if (di_sum_tab[id].index != id) {
+               PR_ERR("%s:err:table:id[%d],tab_id[%d]\n",
+                      __func__, id, di_sum_tab[id].index);
+               return false;
+       }
+       return true;
+}
+
+void di_sum_reg_init(unsigned int ch)
+{
+       unsigned int tsize;
+       int i;
+
+       tsize = ARRAY_SIZE(di_sum_tab);
+
+       dbg_init("%s:ch[%d]\n", __func__, ch);
+       for (i = 0; i < tsize; i++) {
+               if (!di_sum_check(ch, i))
+                       continue;
+               dbg_init("\t:%d:name:%s,%d\n", i, di_sum_tab[i].name,
+                        di_sum_tab[i].default_val);
+               di_sum_set_l(ch, i, di_sum_tab[i].default_val);
+       }
+}
+
+void di_sum_get_info(unsigned int ch,  enum eDI_SUM id, char **name,
+                    unsigned int *pval)
+{
+       *name = di_sum_tab[id].name;
+       *pval = di_sum_get(ch, id);
+}
+
+void di_sum_set(unsigned int ch, enum eDI_SUM id, unsigned int val)
+{
+       if (!di_sum_check(ch, id))
+               return;
+
+       di_sum_set_l(ch, id, val);
+}
+
+unsigned int di_sum_inc(unsigned int ch, enum eDI_SUM id)
+{
+       if (!di_sum_check(ch, id))
+               return 0;
+       return di_sum_inc_l(ch, id);
+}
+
+unsigned int di_sum_get(unsigned int ch, enum eDI_SUM id)
+{
+       if (!di_sum_check(ch, id))
+               return 0;
+       return di_sum_get_l(ch, id);
+}
+
+/****************************/
+/*call by event*/
+/****************************/
+void dip_even_reg_init_val(unsigned int ch)
+{
+}
+
+void dip_even_unreg_val(unsigned int ch)
+{
+}
+
+/****************************/
+static void dip_cma_init_val(void)
+{
+       unsigned int ch;
+       struct di_mng_s *pbm = get_bufmng();
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               /* CMA state */
+               atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_IDL);
+
+               /* CMA reg/unreg cmd */
+               pbm->cma_reg_cmd[ch] = 0;
+       }
+}
+
+void dip_cma_close(void)
+{
+       unsigned int ch;
+       struct di_mng_s *pbm = get_bufmng();
+
+       if (dip_cma_st_is_idl_all())
+               return;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               if (!dip_cma_st_is_idle(ch)) {
+                       dim_cma_top_release(ch);
+                       pr_info("%s:force release ch[%d]", __func__, ch);
+                       atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_IDL);
+
+                       pbm->cma_reg_cmd[ch] = 0;
+               }
+       }
+}
+
+static void dip_wq_cma_handler(struct work_struct *work)
+{
+       unsigned int ch;
+       struct di_mng_s *pbm = get_bufmng();
+       enum eDI_CMA_ST cma_st;
+       bool do_flg;
+
+       pr_info("%s:start\n", __func__);
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               do_flg = false;
+               cma_st = dip_cma_get_st(ch);
+               switch (cma_st) {
+               case eDI_CMA_ST_IDL:
+                       if (pbm->cma_reg_cmd[ch]) {
+                               do_flg = true;
+                               /*set:alloc:*/
+                               atomic_set(&pbm->cma_mem_state[ch],
+                                          eDI_CMA_ST_ALLOC);
+                               if (dim_cma_top_alloc(ch)) {
+                                       atomic_set(&pbm->cma_mem_state[ch],
+                                                  eDI_CMA_ST_READY);
+                               }
+                       }
+                       break;
+               case eDI_CMA_ST_READY:
+                       if (!pbm->cma_reg_cmd[ch]) {
+                               do_flg = true;
+                               atomic_set(&pbm->cma_mem_state[ch],
+                                          eDI_CMA_ST_RELEASE);
+                               dim_cma_top_release(ch);
+                               atomic_set(&pbm->cma_mem_state[ch],
+                                          eDI_CMA_ST_IDL);
+                       }
+                       break;
+               case eDI_CMA_ST_ALLOC:  /*do*/
+               case eDI_CMA_ST_RELEASE:/*do*/
+               default:
+                       break;
+               }
+               if (!do_flg)
+                       pr_info("\tch[%d],do nothing[%d]\n", ch, cma_st);
+               else
+                       task_send_ready();
+       }
+       pr_info("%s:end\n", __func__);
+}
+
+static void dip_wq_prob(void)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       pbm->wq_cma = create_singlethread_workqueue("deinterlace");
+       INIT_WORK(&pbm->wq_work, dip_wq_cma_handler);
+}
+
+static void dip_wq_ext(void)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       cancel_work_sync(&pbm->wq_work);
+       destroy_workqueue(pbm->wq_cma);
+       pr_info("%s:finish\n", __func__);
+}
+
+void dip_wq_cma_run(unsigned char ch, bool reg_cmd)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       if (reg_cmd)
+               pbm->cma_reg_cmd[ch] = 1;
+       else
+               pbm->cma_reg_cmd[ch] = 0;
+
+       queue_work(pbm->wq_cma, &pbm->wq_work);
+}
+
+bool dip_cma_st_is_ready(unsigned int ch)
+{
+       struct di_mng_s *pbm = get_bufmng();
+       bool ret = false;
+
+       if (atomic_read(&pbm->cma_mem_state[ch]) == eDI_CMA_ST_READY)
+               ret = true;
+
+       return ret;
+}
+
+bool dip_cma_st_is_idle(unsigned int ch)
+{
+       struct di_mng_s *pbm = get_bufmng();
+       bool ret = false;
+
+       if (atomic_read(&pbm->cma_mem_state[ch]) == eDI_CMA_ST_IDL)
+               ret = true;
+
+       return ret;
+}
+
+bool dip_cma_st_is_idl_all(void)
+{
+       unsigned int ch;
+       struct di_mng_s *pbm = get_bufmng();
+       bool ret = true;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               if (atomic_read(&pbm->cma_mem_state[ch]) != eDI_CMA_ST_IDL) {
+                       ret = true;
+                       break;
+               }
+       }
+       return ret;
+}
+
+enum eDI_CMA_ST dip_cma_get_st(unsigned int ch)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       return atomic_read(&pbm->cma_mem_state[ch]);
+}
+
+const char * const di_cma_state_name[] = {
+       "IDLE",
+       "do_alloc",
+       "READY",
+       "do_release",
+};
+
+const char *di_cma_dbg_get_st_name(unsigned int ch)
+{
+       enum eDI_CMA_ST st = dip_cma_get_st(ch);
+       const char *p = "";
+
+       if (st <= eDI_CMA_ST_RELEASE)
+               p = di_cma_state_name[st];
+       return p;
+}
+
+void dip_cma_st_set_ready_all(void)
+{
+       unsigned int ch;
+       struct di_mng_s *pbm = get_bufmng();
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++)
+               atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_READY);
+}
+
+/****************************/
+/*channel STATE*/
+/****************************/
+void dip_chst_set(unsigned int ch, enum eDI_TOP_STATE chSt)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       atomic_set(&pbm->ch_state[ch], chSt);
+}
+
+enum eDI_TOP_STATE dip_chst_get(unsigned int ch)
+{
+       struct di_mng_s *pbm = get_bufmng();
+
+       return atomic_read(&pbm->ch_state[ch]);
+}
+
+void dip_chst_init(void)
+{
+       unsigned int ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++)
+               dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+}
+
+bool dip_event_reg_chst(unsigned int ch)
+{
+       enum eDI_TOP_STATE chst;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+       bool err_flg = false;
+       bool ret = true;
+
+       dbg_dbg("%s:ch[%d]\n", __func__, ch);
+
+       chst = dip_chst_get(ch);
+#if 0  /*move*/
+       if (chst > eDI_TOP_STATE_NOPROB)
+               set_flag_trig_unreg(ch, false);
+#endif
+       switch (chst) {
+       case eDI_TOP_STATE_IDLE:
+
+               queue_init2(ch);
+               di_que_init(ch);
+               di_vframe_reg(ch);
+
+               dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1);
+               task_send_cmd(LCMD1(eCMD_REG, ch));
+               dbg_dbg("reg ok\n");
+               break;
+       case eDI_TOP_STATE_REG_STEP1:
+       case eDI_TOP_STATE_REG_STEP1_P1:
+       case eDI_TOP_STATE_REG_STEP2:
+       case eDI_TOP_STATE_READY:
+       case eDI_TOP_STATE_BYPASS:
+               PR_WARN("have reg\n");
+               ret = false;
+               break;
+       case eDI_TOP_STATE_UNREG_STEP1:
+       case eDI_TOP_STATE_UNREG_STEP2:
+               /*wait*/
+               ppre->reg_req_flag_cnt = 0;
+               while (dip_chst_get(ch) != eDI_TOP_STATE_IDLE) {
+                       usleep_range(10000, 10001);
+                       if (ppre->reg_req_flag_cnt++ >
+                               dim_get_reg_unreg_cnt()) {
+                               dim_reg_timeout_inc();
+                               PR_ERR("%s,ch[%d] reg timeout!!!\n",
+                                      __func__, ch);
+                               err_flg = true;
+                               ret = false;
+                               break;
+                       }
+               }
+               if (!err_flg) {
+               /*same as IDLE*/
+                       queue_init2(ch);
+                       di_que_init(ch);
+                       di_vframe_reg(ch);
+
+                       dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1);
+                       task_send_cmd(LCMD1(eCMD_REG, ch));
+                       dbg_dbg("reg retry ok\n");
+               }
+               break;
+       case eDI_TOP_STATE_NOPROB:
+       default:
+               ret = false;
+               PR_ERR("err: not prob[%d]\n", chst);
+
+               break;
+       }
+
+       return ret;
+}
+
+bool dip_event_unreg_chst(unsigned int ch)
+{
+       enum eDI_TOP_STATE chst, chst2;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+       bool ret = false;
+       bool err_flg = false;
+       unsigned int cnt;
+
+       chst = dip_chst_get(ch);
+       dbg_reg("%s:ch[%d]:%s\n", __func__, ch, dip_chst_get_name(chst));
+       #if 0
+       if (chst > eDI_TOP_STATE_IDLE)
+               set_reg_flag(ch, false);/*set_flag_trig_unreg(ch, true);*/
+       #endif
+       if (chst > eDI_TOP_STATE_NOPROB)
+               set_flag_trig_unreg(ch, true);
+
+       switch (chst) {
+       case eDI_TOP_STATE_READY:
+
+               di_vframe_unreg(ch);
+               /*trig unreg*/
+               dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1);
+               task_send_cmd(LCMD1(eCMD_UNREG, ch));
+               /*debug only di_dbg = di_dbg|DBG_M_TSK;*/
+
+               /*wait*/
+               ppre->unreg_req_flag_cnt = 0;
+               chst2 = dip_chst_get(ch);
+
+               while (chst2 != eDI_TOP_STATE_IDLE) {
+                       task_send_ready();
+                       usleep_range(10000, 10001);
+                       /*msleep(5);*/
+                       if (ppre->unreg_req_flag_cnt++
+                               > dim_get_reg_unreg_cnt()) {
+                               dim_reg_timeout_inc();
+                               PR_ERR("%s:ch[%d] unreg timeout!!!\n",
+                                      __func__, ch);
+                               /*dim_unreg_process();*/
+                               err_flg = true;
+                               break;
+                       }
+                       #if 0   /*debug only*/
+                       dbg_reg("\tch[%d]:s[%s],ecnt[%d]\n",
+                               ch,
+                               dip_chst_get_name(chst2),
+                               ppre->unreg_req_flag_cnt);
+                       #endif
+                       chst2 = dip_chst_get(ch);
+               }
+
+               /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/
+               dbg_reg("%s:ch[%d] ready end\n", __func__, ch);
+               #if 0
+               if (!err_flg)
+                       set_reg_flag(ch, false);
+               #endif
+               break;
+       case eDI_TOP_STATE_BYPASS:
+               /*from bypass complet to unreg*/
+               di_vframe_unreg(ch);
+               di_unreg_variable(ch);
+
+               set_reg_flag(ch, false);
+               if (!get_reg_flag_all()) {
+                       di_unreg_setting();
+                       dpre_init();
+                       dpost_init();
+               }
+               dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+               ret = true;
+
+               break;
+       case eDI_TOP_STATE_IDLE:
+               PR_WARN("have unreg\n");
+               break;
+       case eDI_TOP_STATE_REG_STEP1:
+               dbg_dbg("%s:in reg step1\n", __func__);
+               di_vframe_unreg(ch);
+               set_reg_flag(ch, false);
+               dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+
+               ret = true;
+               break;
+       case eDI_TOP_STATE_REG_STEP1_P1:
+               /*wait:*/
+               cnt = 0;
+               while (chst2 == eDI_TOP_STATE_REG_STEP1_P1 || cnt < 5) {
+                       task_send_ready();
+                       usleep_range(3000, 3001);
+                       cnt++;
+               }
+               if (cnt >= 5)
+                       PR_ERR("%s:ch[%d] in p1 timeout\n", __func__, ch);
+
+               set_reg_flag(ch, false);
+
+               di_vframe_unreg(ch);
+               /*trig unreg*/
+               dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1);
+               task_send_cmd(LCMD1(eCMD_UNREG, ch));
+               /*debug only di_dbg = di_dbg|DBG_M_TSK;*/
+
+               /*wait*/
+               ppre->unreg_req_flag_cnt = 0;
+               chst2 = dip_chst_get(ch);
+
+               while (chst2 != eDI_TOP_STATE_IDLE) {
+                       task_send_ready();
+                       usleep_range(10000, 10001);
+                       /*msleep(5);*/
+                       if (ppre->unreg_req_flag_cnt++
+                               > dim_get_reg_unreg_cnt()) {
+                               dim_reg_timeout_inc();
+                               PR_ERR("%s:ch[%d] unreg timeout!!!\n",
+                                      __func__,
+                                      ch);
+                               /*di_unreg_process();*/
+                               err_flg = true;
+                               break;
+                       }
+
+                       chst2 = dip_chst_get(ch);
+               }
+
+               /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/
+               dbg_reg("%s:ch[%d] ready end\n", __func__, ch);
+               ret = true;
+
+               break;
+       case eDI_TOP_STATE_REG_STEP2:
+               di_vframe_unreg(ch);
+               di_unreg_variable(ch);
+               set_reg_flag(ch, false);
+               if (!get_reg_flag_all()) {
+                       di_unreg_setting();
+                       dpre_init();
+                       dpost_init();
+               }
+
+               dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+
+               ret = true;
+               break;
+       case eDI_TOP_STATE_UNREG_STEP1:
+       case eDI_TOP_STATE_UNREG_STEP2:
+               task_send_cmd(LCMD1(eCMD_UNREG, ch));
+
+               /*wait*/
+               ppre->unreg_req_flag_cnt = 0;
+               while (dip_chst_get(ch) != eDI_TOP_STATE_IDLE) {
+                       usleep_range(10000, 10001);
+                       if (ppre->unreg_req_flag_cnt++ >
+                               dim_get_reg_unreg_cnt()) {
+                               dim_reg_timeout_inc();
+                               PR_ERR("%s:unreg_reg_flag timeout!!!\n",
+                                      __func__);
+                               di_vframe_unreg(ch);
+                               err_flg = true;
+                               break;
+                       }
+               }
+               break;
+       case eDI_TOP_STATE_NOPROB:
+       default:
+               PR_ERR("err: not prob[%d]\n", chst);
+               break;
+       }
+       if (err_flg)
+               ret = false;
+
+       return ret;
+}
+
+/*process for reg and unreg cmd*/
+void dip_chst_process_reg(unsigned int ch)
+{
+       enum eDI_TOP_STATE chst;
+       struct vframe_s *vframe;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+       bool reflesh = true;
+
+       while (reflesh) {
+               reflesh = false;
+
+       chst = dip_chst_get(ch);
+
+       /*dbg_reg("%s:ch[%d]%s\n", __func__, ch, dip_chst_get_name(chst));*/
+
+       switch (chst) {
+       case eDI_TOP_STATE_NOPROB:
+       case eDI_TOP_STATE_IDLE:
+               break;
+       case eDI_TOP_STATE_REG_STEP1:/*wait peek*/
+               vframe = pw_vf_peek(ch);
+
+               if (vframe) {
+                       dim_tr_ops.pre_get(vframe->omx_index);
+                       set_flag_trig_unreg(ch, false);
+                       #if 0
+                       di_reg_variable(ch);
+
+                       /*?how  about bypass ?*/
+                       if (ppre->bypass_flag) {
+                               /* complete bypass */
+                               set_bypass2_complete(ch, true);
+                               if (!get_reg_flag_all()) {
+                                       /*first channel reg*/
+                                       dpre_init();
+                                       dpost_init();
+                                       di_reg_setting(ch, vframe);
+                               }
+                               dip_chst_set(ch, eDI_TOP_STATE_BYPASS);
+                               set_reg_flag(ch, true);
+                       } else {
+                               set_bypass2_complete(ch, false);
+                               if (!get_reg_flag_all()) {
+                                       /*first channel reg*/
+                                       dpre_init();
+                                       dpost_init();
+                                       di_reg_setting(ch, vframe);
+                               }
+                               dip_chst_set(ch, eDI_TOP_STATE_REG_STEP2);
+                       }
+                       #else
+                       dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1_P1);
+                       #endif
+
+                       reflesh = true;
+               }
+               break;
+       case eDI_TOP_STATE_REG_STEP1_P1:
+               vframe = pw_vf_peek(ch);
+               if (!vframe) {
+                       PR_ERR("%s:p1 vfm nop\n", __func__);
+                       dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1);
+
+                       break;
+               }
+               di_reg_variable(ch, vframe);
+               /*di_reg_process_irq(ch);*/ /*check if bypass*/
+
+               /*?how  about bypass ?*/
+               if (ppre->bypass_flag) {
+                       /* complete bypass */
+                       set_bypass2_complete(ch, true);
+                       if (!get_reg_flag_all()) {
+                               /*first channel reg*/
+                               dpre_init();
+                               dpost_init();
+                               di_reg_setting(ch, vframe);
+                       }
+                       dip_chst_set(ch, eDI_TOP_STATE_BYPASS);
+                       set_reg_flag(ch, true);
+               } else {
+                       set_bypass2_complete(ch, false);
+                       if (!get_reg_flag_all()) {
+                               /*first channel reg*/
+                               dpre_init();
+                               dpost_init();
+                               di_reg_setting(ch, vframe);
+                       }
+                       /*this will cause first local buf not alloc*/
+                       /*dim_bypass_first_frame(ch);*/
+                       dip_chst_set(ch, eDI_TOP_STATE_REG_STEP2);
+                       /*set_reg_flag(ch, true);*/
+               }
+
+               reflesh = true;
+               break;
+       case eDI_TOP_STATE_REG_STEP2:/*now no change to do*/
+               if (dip_cma_get_st(ch) == eDI_CMA_ST_READY) {
+                       if (di_cfg_top_get(eDI_CFG_first_bypass)) {
+                               if (get_sum_g(ch) == 0)
+                                       dim_bypass_first_frame(ch);
+                               else
+                                       PR_INF("ch[%d],g[%d]\n",
+                                              ch, get_sum_g(ch));
+                       }
+                       dip_chst_set(ch, eDI_TOP_STATE_READY);
+                       set_reg_flag(ch, true);
+                       /*move to step1 dim_bypass_first_frame(ch);*/
+               }
+               break;
+       case eDI_TOP_STATE_READY:
+
+               break;
+       case eDI_TOP_STATE_BYPASS:
+               /*do nothing;*/
+               break;
+       case eDI_TOP_STATE_UNREG_STEP1:
+
+#if 0
+               if (!get_reg_flag(ch)) {        /*need wait pre/post done*/
+                       dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2);
+                       reflesh = true;
+               }
+#else
+               /*debug only dbg_reg("%s:UNREG_STEP1\n", __func__);*/
+
+               if (dpre_can_exit(ch) && dpst_can_exit(ch)) {
+                       dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2);
+                       set_reg_flag(ch, false);
+                       reflesh = true;
+               }
+#endif
+               break;
+       case eDI_TOP_STATE_UNREG_STEP2:
+               /*debug only dbg_reg("%s:ch[%d]:UNREG_STEP2\n",__func__, ch);*/
+               di_unreg_variable(ch);
+               if (!get_reg_flag_all()) {
+                       di_unreg_setting();
+                       dpre_init();
+                       dpost_init();
+               }
+
+               dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+               /*debug only dbg_reg("ch[%d]UNREG_STEP2 end\n",ch);*/
+               break;
+       }
+       }
+}
+
+void dip_chst_process_ch(void)
+{
+       unsigned int ch;
+       unsigned int chst;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               chst = dip_chst_get(ch);
+               switch (chst) {
+               case eDI_TOP_STATE_REG_STEP2:
+                       if (dip_cma_get_st(ch) == eDI_CMA_ST_READY) {
+                               if (di_cfg_top_get(eDI_CFG_first_bypass)) {
+                                       if (get_sum_g(ch) == 0)
+                                               dim_bypass_first_frame(ch);
+                                       else
+                                               PR_INF("ch[%d],g[%d]\n",
+                                                      ch, get_sum_g(ch));
+                               }
+                               dip_chst_set(ch, eDI_TOP_STATE_READY);
+                               set_reg_flag(ch, true);
+                       }
+                       break;
+#if 1
+               case eDI_TOP_STATE_UNREG_STEP1:
+                       if (dpre_can_exit(ch) && dpst_can_exit(ch)) {
+                               dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2);
+                               set_reg_flag(ch, false);
+                       }
+
+                       break;
+#endif
+               case eDI_TOP_STATE_UNREG_STEP2:
+                       dbg_reg("%s:ch[%d]:at UNREG_STEP2\n", __func__, ch);
+                       di_unreg_variable(ch);
+                       if (!get_reg_flag_all()) {
+                               di_unreg_setting();
+                               dpre_init();
+                               dpost_init();
+                       }
+
+                       dip_chst_set(ch, eDI_TOP_STATE_IDLE);
+                       dbg_reg("ch[%d]STEP2 end\n", ch);
+                       break;
+               }
+       }
+}
+
+bool dip_chst_change_2unreg(void)
+{
+       unsigned int ch;
+       unsigned int chst;
+       bool ret = false;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               chst = dip_chst_get(ch);
+               dbg_poll("[%d]%d\n", ch, chst);
+               if (chst == eDI_TOP_STATE_UNREG_STEP1) {
+                       dbg_reg("%s:ch[%d]to UNREG_STEP2\n", __func__, ch);
+                       set_reg_flag(ch, false);
+                       dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2);
+                       ret = true;
+               }
+       }
+       return ret;
+}
+
+#if 0
+void di_reg_flg_check(void)
+{
+       int ch;
+       unsigned int chst;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++)
+               chst = dip_chst_get(ch);
+}
+#endif
+
+void dip_hw_process(void)
+{
+       di_dbg_task_flg = 5;
+       dpre_process();
+       di_dbg_task_flg = 6;
+       pre_mode_setting();
+       di_dbg_task_flg = 7;
+       dpst_process();
+       di_dbg_task_flg = 8;
+}
+
+const char * const di_top_state_name[] = {
+       "NOPROB",
+       "IDLE",
+       "REG_STEP1",
+       "REG_P1",
+       "REG_STEP2",
+       "READY",
+       "BYPASS",
+       "UNREG_STEP1",
+       "UNREG_STEP2",
+};
+
+const char *dip_chst_get_name_curr(unsigned int ch)
+{
+       const char *p = "";
+       enum eDI_TOP_STATE chst;
+
+       chst = dip_chst_get(ch);
+
+       if (chst < sizeof(di_top_state_name))
+               p = di_top_state_name[chst];
+
+       return p;
+}
+
+const char *dip_chst_get_name(enum eDI_TOP_STATE chst)
+{
+       const char *p = "";
+
+       if (chst < sizeof(di_top_state_name))
+               p = di_top_state_name[chst];
+
+       return p;
+}
+
+/**********************************/
+/* TIME OUT CHEKC api*/
+/**********************************/
+
+void di_tout_int(struct di_time_out_s *tout, unsigned int thd)
+{
+       tout->en = false;
+       tout->timer_start = 0;
+       tout->timer_thd = thd;
+}
+
+bool di_tout_contr(enum eDI_TOUT_CONTR cmd, struct di_time_out_s *tout)
+{
+       unsigned long ctimer;
+       unsigned long diff;
+       bool ret = false;
+
+       ctimer = cur_to_msecs();
+
+       switch (cmd) {
+       case eDI_TOUT_CONTR_EN:
+               tout->en = true;
+               tout->timer_start = ctimer;
+               break;
+       case eDI_TOUT_CONTR_FINISH:
+               if (tout->en) {
+                       diff = ctimer - tout->timer_start;
+
+                       if (diff > tout->timer_thd) {
+                               tout->over_flow_cnt++;
+
+                               if (tout->over_flow_cnt > 0xfffffff0) {
+                                       tout->over_flow_cnt = 0;
+                                       tout->flg_over = 1;
+                               }
+               #if 0
+                               if (tout->do_func)
+                                       tout->do_func();
+
+               #endif
+                               ret = true;
+                       }
+                       tout->en = false;
+               }
+               break;
+
+       case eDI_TOUT_CONTR_CHECK:      /*if time is overflow, disable timer*/
+               if (tout->en) {
+                       diff = ctimer - tout->timer_start;
+
+                       if (diff > tout->timer_thd) {
+                               tout->over_flow_cnt++;
+
+                               if (tout->over_flow_cnt > 0xfffffff0) {
+                                       tout->over_flow_cnt = 0;
+                                       tout->flg_over = 1;
+                               }
+                               #if 0
+                               if (tout->do_func)
+                                       tout->do_func();
+
+                               #endif
+                               ret = true;
+                               tout->en = false;
+                       }
+               }
+               break;
+       case eDI_TOUT_CONTR_CLEAR:
+               tout->en = false;
+               tout->timer_start = ctimer;
+               break;
+       case eDI_TOUT_CONTR_RESET:
+               tout->en = true;
+               tout->timer_start = ctimer;
+               break;
+       }
+
+       return ret;
+}
+
+const unsigned int di_ch2mask_table[DI_CHANNEL_MAX] = {
+       DI_BIT0,
+       DI_BIT1,
+       DI_BIT2,
+       DI_BIT3,
+};
+
+/****************************************/
+/* do_table                            */
+/****************************************/
+
+/*for do_table_working*/
+#define K_DO_TABLE_LOOP_MAX    15
+
+const struct do_table_s do_table_def = {
+       .ptab = NULL,
+       .data = NULL,
+       .size = 0,
+       .op_lst = K_DO_TABLE_ID_STOP,
+       .op_crr = K_DO_TABLE_ID_STOP,
+       .do_stop = 0,
+       .flg_stop = 0,
+       .do_pause = 0,
+       .do_step = 0,
+       .flg_repeat = 0,
+
+};
+
+void do_table_init(struct do_table_s *pdo,
+                  const struct do_table_ops_s *ptable,
+                  unsigned int size_tab)
+{
+       memcpy(pdo, &do_table_def, sizeof(struct do_table_s));
+
+       if (ptable) {
+               pdo->ptab = ptable;
+               pdo->size = size_tab;
+       }
+}
+
+/*if change to async?*/
+/* now only call in same thread */
+void do_talbe_cmd(struct do_table_s *pdo, enum eDO_TABLE_CMD cmd)
+{
+       switch (cmd) {
+       case eDO_TABLE_CMD_NONE:
+               pr_info("test:%s\n", __func__);
+               break;
+       case eDO_TABLE_CMD_STOP:
+               pdo->do_stop = true;
+               break;
+       case eDO_TABLE_CMD_START:
+               if (pdo->op_crr == K_DO_TABLE_ID_STOP) {
+                       pdo->op_lst = pdo->op_crr;
+                       pdo->op_crr = K_DO_TABLE_ID_START;
+                       pdo->do_stop = false;
+                       pdo->flg_stop = false;
+               } else if (pdo->op_crr == K_DO_TABLE_ID_PAUSE) {
+                       pdo->op_crr = pdo->op_lst;
+                       pdo->op_lst = K_DO_TABLE_ID_PAUSE;
+                       pdo->do_pause = false;
+               } else {
+                       pr_info("crr is [%d], not start\n", pdo->op_crr);
+               }
+               break;
+       case eDO_TABLE_CMD_PAUSE:
+               if (pdo->op_crr <= K_DO_TABLE_ID_STOP) {
+                       /*do nothing*/
+               } else {
+                       pdo->op_crr = pdo->op_lst;
+                       pdo->op_crr = K_DO_TABLE_ID_PAUSE;
+                       pdo->do_pause = true;
+               }
+               break;
+       case eDO_TABLE_CMD_STEP:
+               pdo->do_step = true;
+               break;
+       case eDO_TABLE_CMD_STEP_BACK:
+               pdo->do_step = false;
+               break;
+       default:
+               break;
+       }
+}
+
+bool do_table_is_crr(struct do_table_s *pdo, unsigned int state)
+{
+       if (pdo->op_crr == state)
+               return true;
+       return false;
+}
+
+void do_table_working(struct do_table_s *pdo)
+{
+       const struct do_table_ops_s *pcrr;
+       unsigned int ret = 0;
+       unsigned int next;
+       bool flash = false;
+       unsigned int cnt = 0;   /*proction*/
+       unsigned int lst_id;    /*dbg only*/
+       char *name = "";        /*dbg only*/
+       bool need_pr = false;   /*dbg only*/
+
+       if (!pdo                ||
+           !pdo->ptab          ||
+           pdo->op_crr >= pdo->size) {
+               PR_ERR("di:err:%s:ovflow:0x%p,0x%p,crr=%d,size=%d\n",
+                      __func__,
+                      pdo, pdo->ptab,
+                      pdo->op_crr,
+                      pdo->size);
+               return;
+       }
+
+       pcrr = pdo->ptab + pdo->op_crr;
+
+       if (pdo->name)
+               name = pdo->name;
+       /*stop ?*/
+       if (pdo->do_stop &&
+           (pcrr->mark & K_DO_TABLE_CAN_STOP)) {
+               dbg_dt("%s:do stop\n", name);
+
+               /*do stop*/
+               if (pcrr->do_stop_op)
+                       pcrr->do_stop_op(pdo->data);
+               /*set status*/
+               pdo->op_lst = pdo->op_crr;
+               pdo->op_crr = K_DO_TABLE_ID_STOP;
+               pdo->flg_stop = true;
+               pdo->do_stop = false;
+
+               return;
+       }
+
+       /*pause?*/
+       if (pdo->op_crr == K_DO_TABLE_ID_STOP   ||
+           pdo->op_crr == K_DO_TABLE_ID_PAUSE)
+               return;
+
+       do {
+               flash = false;
+               cnt++;
+               if (cnt > K_DO_TABLE_LOOP_MAX) {
+                       PR_ERR("di:err:%s:loop more %d\n", name, cnt);
+                       break;
+               }
+
+               /*stop again? */
+               if (pdo->do_stop &&
+                   (pcrr->mark & K_DO_TABLE_CAN_STOP)) {
+                       /*do stop*/
+                       dbg_dt("%s: do stop in loop\n", name);
+                       if (pcrr->do_stop_op)
+                               pcrr->do_stop_op(pdo->data);
+                       /*set status*/
+                       pdo->op_lst = pdo->op_crr;
+                       pdo->op_crr = K_DO_TABLE_ID_STOP;
+                       pdo->flg_stop = true;
+                       pdo->do_stop = false;
+
+                       break;
+               }
+
+               /*debug:*/
+               lst_id = pdo->op_crr;
+               need_pr = true;
+
+               if (pcrr->con) {
+                       if (pcrr->con(pdo->data))
+                               ret = pcrr->do_op(pdo->data);
+                       else
+                               break;
+
+               } else {
+                       ret = pcrr->do_op(pdo->data);
+                       dbg_dt("do_table:do:%d:ret=0x%x\n", pcrr->id, ret);
+               }
+
+               /*not finish, keep current status*/
+               if ((ret & K_DO_TABLE_R_B_FINISH) == 0) {
+                       dbg_dt("%s:not finish,wait\n", __func__);
+                       break;
+               }
+
+               /*fix to next */
+               if (ret & K_DO_TABLE_R_B_NEXT) {
+                       pdo->op_lst = pdo->op_crr;
+                       pdo->op_crr++;
+                       if (pdo->op_crr >= pdo->size) {
+                               pdo->op_crr = pdo->flg_repeat ?
+                                       K_DO_TABLE_ID_START
+                                       : K_DO_TABLE_ID_STOP;
+                               dbg_dt("%s:to end,%d\n", __func__,
+                                      pdo->op_crr);
+                               break;
+                       }
+                       /*return;*/
+                       flash = true;
+               } else {
+                       next = ((ret & K_DO_TABLE_R_B_OTHER) >>
+                                       K_DO_TABLE_R_B_OTHER_SHIFT);
+                       if (next < pdo->size) {
+                               pdo->op_lst = pdo->op_crr;
+                               pdo->op_crr = next;
+                               if (next > K_DO_TABLE_ID_STOP)
+                                       flash = true;
+                               else
+                                       flash = false;
+                       } else {
+                               PR_ERR("%s: next[%d] err:\n",
+                                      __func__, next);
+                       }
+               }
+               /*debug 1:*/
+               need_pr = false;
+               if (lst_id != pdo->op_crr) {
+                       dbg_dt("do_table:%s:%s->%s\n", pdo->name,
+                              pdo->ptab[lst_id].name,
+                              pdo->ptab[pdo->op_crr].name);
+               }
+
+               pcrr = pdo->ptab + pdo->op_crr;
+       } while (flash && !pdo->do_step);
+
+       /*debug 2:*/
+       if (need_pr) {
+               if (lst_id != pdo->op_crr) {
+                       dbg_dt("do_table2:%s:%s->%s\n", pdo->name,
+                              pdo->ptab[lst_id].name,
+                              pdo->ptab[pdo->op_crr].name);
+               }
+       }
+}
+
+/**********************************/
+
+/****************************/
+void dip_init_value_reg(unsigned int ch)
+{
+       struct di_post_stru_s *ppost;
+       struct di_buf_s *keep_post_buf;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+
+       pr_info("%s:\n", __func__);
+
+       /*post*/
+       ppost = get_post_stru(ch);
+       /*keep buf:*/
+       keep_post_buf = ppost->keep_buf_post;
+
+       memset(ppost, 0, sizeof(struct di_post_stru_s));
+       ppost->next_canvas_id = 1;
+       ppost->keep_buf_post = keep_post_buf;
+
+       /*pre*/
+       memset(ppre, 0, sizeof(struct di_pre_stru_s));
+}
+
+static bool dip_init_value(void)
+{
+       unsigned int ch;
+       struct di_post_stru_s *ppost;
+       struct di_mm_s *mm = dim_mm_get();
+       bool ret = false;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               ppost = get_post_stru(ch);
+               memset(ppost, 0, sizeof(struct di_post_stru_s));
+               ppost->next_canvas_id = 1;
+
+               /*que*/
+               ret = di_que_alloc(ch);
+       }
+       set_current_channel(0);
+
+       /*mm cfg*/
+       mm->cfg.di_h = 1080;
+       mm->cfg.di_w = 1920;
+       mm->cfg.num_local = MAX_LOCAL_BUF_NUM;
+       mm->cfg.num_post = MAX_POST_BUF_NUM;
+       /*mm sts*/
+       mm->sts.mem_start = 0;
+       mm->sts.mem_size = 0;
+       mm->sts.total_pages = NULL;
+       mm->sts.flag_cma = 0;
+
+       return ret;
+}
+
+/******************************************
+ *     pq ops
+ *****************************************/
+void dip_init_pq_ops(void)
+{
+       di_attach_ops_pulldown(&get_datal()->ops_pd);
+       di_attach_ops_3d(&get_datal()->ops_3d);
+       di_attach_ops_nr(&get_datal()->ops_nr);
+       di_attach_ops_mtn(&get_datal()->ops_mtn);
+
+       dim_attach_to_local();
+}
+
+/**********************************/
+void dip_clean_value(void)
+{
+       unsigned int ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               /*que*/
+               di_que_release(ch);
+       }
+}
+
+bool dip_prob(void)
+{
+       bool ret = true;
+
+       ret = dip_init_value();
+
+       di_cfgx_init_val();
+       di_cfg_top_init_val();
+       di_mp_uit_init_val();
+       di_mp_uix_init_val();
+
+       dev_vframe_init();
+       didbg_fs_init();
+       dip_wq_prob();
+       dip_cma_init_val();
+       dip_chst_init();
+
+       dpre_init();
+       dpost_init();
+
+       dip_init_pq_ops();
+
+       return ret;
+}
+
+void dip_exit(void)
+{
+       dip_wq_ext();
+       dev_vframe_exit();
+       dip_clean_value();
+       didbg_fs_exit();
+}
+
diff --git a/drivers/amlogic/media/di_multi/di_prc.h b/drivers/amlogic/media/di_multi/di_prc.h
new file mode 100644 (file)
index 0000000..8083bc4
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * drivers/amlogic/media/di_multi/di_prc.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_PRC_H__
+#define __DI_PRC_H__
+
+bool dip_prob(void);
+void dip_exit(void);
+
+void dip_even_reg_init_val(unsigned int ch);
+void dip_even_unreg_val(unsigned int ch);
+
+/************************/
+/* CMA */
+/************************/
+void dip_wq_cma_run(unsigned char ch, bool reg_cmd);
+bool dip_cma_st_is_ready(unsigned int ch);
+bool dip_cma_st_is_idle(unsigned int ch);
+bool dip_cma_st_is_idl_all(void);
+enum eDI_CMA_ST dip_cma_get_st(unsigned int ch);
+void dip_cma_st_set_ready_all(void);
+void dip_cma_close(void);
+const char *di_cma_dbg_get_st_name(unsigned int ch);
+
+/*************************/
+/* STATE*/
+/*************************/
+bool dip_event_reg_chst(unsigned int ch);
+bool dip_event_unreg_chst(unsigned int ch);
+void dip_chst_process_reg(unsigned int ch);
+
+void dip_hw_process(void);
+
+void dip_chst_process_ch(void);
+bool dip_chst_change_2unreg(void);
+
+enum eDI_TOP_STATE dip_chst_get(unsigned int ch);
+const char *dip_chst_get_name_curr(unsigned int ch);
+const char *dip_chst_get_name(enum eDI_TOP_STATE chst);
+
+/**************************************
+ *
+ * summmary variable
+ *
+ **************************************/
+void di_sum_reg_init(unsigned int ch);
+void di_sum_set(unsigned int ch, enum eDI_SUM id, unsigned int val);
+unsigned int di_sum_inc(unsigned int ch, enum eDI_SUM id);
+unsigned int di_sum_get(unsigned int ch, enum eDI_SUM id);
+void di_sum_get_info(unsigned int ch, enum eDI_SUM id, char **name,
+                    unsigned int *pval);
+unsigned int di_sum_get_tab_size(void);
+bool di_sum_check(unsigned int ch, enum eDI_SUM id);
+
+/**************************************
+ *
+ * cfg ctr top
+ *     bool
+ **************************************/
+char *di_cfg_top_get_name(enum eDI_CFG_TOP_IDX idx);
+void di_cfg_top_get_info(unsigned int idx, char **name);
+void di_cfg_top_init_val(void);
+bool di_cfg_top_get(enum eDI_CFG_TOP_IDX id);
+void di_cfg_top_set(enum eDI_CFG_TOP_IDX id, bool en);
+
+/**************************************
+ *
+ * cfg ctr x
+ *     bool
+ **************************************/
+char *di_cfgx_get_name(enum eDI_CFGX_IDX idx);
+void di_cfgx_get_info(enum eDI_CFGX_IDX idx, char **name);
+void di_cfgx_init_val(void);
+bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx);
+void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en);
+
+/**************************************
+ *
+ * module para top
+ *     int
+ **************************************/
+char *di_mp_uit_get_name(enum eDI_MP_UI_T idx);
+void di_mp_uit_init_val(void);
+int di_mp_uit_get(enum eDI_MP_UI_T idx);
+void di_mp_uit_set(enum eDI_MP_UI_T idx, int val);
+
+/**************************************
+ *
+ * module para x
+ *     unsigned int
+ **************************************/
+char *di_mp_uix_get_name(enum eDI_MP_UIX_T idx);
+void di_mp_uix_init_val(void);
+unsigned int di_mp_uix_get(unsigned int ch, enum eDI_MP_UIX_T idx);
+void di_mp_uix_set(unsigned int ch, enum eDI_MP_UIX_T idx,
+                  unsigned int val);
+
+/****************************************/
+/* do_table                            */
+/****************************************/
+void do_table_init(struct do_table_s *pdo,
+                  const struct do_table_ops_s *ptable,
+                  unsigned int size_tab);
+/* now only call in same thread */
+void do_talbe_cmd(struct do_table_s *pdo, enum eDO_TABLE_CMD cmd);
+void do_table_working(struct do_table_s *pdo);
+bool do_table_is_crr(struct do_table_s *pdo, unsigned int state);
+
+enum eDI_SUB_ID pw_ch_next_count(enum eDI_SUB_ID channel);
+
+void dip_init_value_reg(unsigned int ch);
+
+bool di_is_pause(unsigned int ch);
+void di_pause_step_done(unsigned int ch);
+void di_pause(unsigned int ch, bool on);
+
+#endif /*__DI_PRC_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_pre.c b/drivers/amlogic/media/di_multi/di_pre.c
new file mode 100644 (file)
index 0000000..2c47394
--- /dev/null
@@ -0,0 +1,985 @@
+/*
+ * drivers/amlogic/media/di_multi/di_pre.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "deinterlace.h"
+#include "deinterlace_dbg.h"
+
+#include "di_data_l.h"
+#include "di_data.h"
+#include "di_dbg.h"
+#include "di_vframe.h"
+#include "di_que.h"
+#include "di_task.h"
+
+#include "di_prc.h"
+#include "di_pre.h"
+
+#include "nr_downscale.h"
+#include "register.h"
+
+/****************************************
+ * 1. copy curr to last
+ * 2. set curr
+ ****************************************/
+void pre_vinfo_set(unsigned int ch,
+                  struct vframe_s *ori_vframe)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       struct di_vinfo_s *vc = &pre->vinf_curr;
+       struct di_vinfo_s *vl = &pre->vinf_lst;
+
+       memcpy(vl, vc, sizeof(struct di_vinfo_s));
+
+       vc->ch = ch;
+       vc->vtype = ori_vframe->type;
+       vc->src_type = ori_vframe->source_type;
+       vc->trans_fmt = ori_vframe->trans_fmt;
+
+       if (COM_ME(ori_vframe->type, VIDTYPE_COMPRESS)) {
+               vc->h = ori_vframe->compWidth;
+               vc->v = ori_vframe->compHeight;
+       } else {
+               vc->h = ori_vframe->width;
+               vc->v = ori_vframe->height;
+       }
+}
+
+/****************************************
+ * compare current vframe info with last
+ * return
+ *     0. no change
+ *     1. video format channge
+ *     2. scan mode channge?
+ ****************************************/
+unsigned int is_vinfo_change(unsigned int ch)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       struct di_vinfo_s *vc = &pre->vinf_curr;
+       struct di_vinfo_s *vl = &pre->vinf_lst;
+       struct di_pre_stru_s *ppre = get_pre_stru(ch);
+       unsigned int ret = 0;
+
+       if (vc->src_type != vl->src_type                        ||
+           !COM_M(DI_VFM_T_MASK_CHANGE, vc->vtype, vl->vtype)  ||
+           vc->v != vl->v                                      ||
+           vc->h != vl->h                                      ||
+           vc->trans_fmt != vl->trans_fmt) {
+               /* video format changed */
+               ret = 1;
+       } else if (!COM_M(VIDTYPE_VIU_FIELD, vc->vtype, vl->vtype))
+               /* just scan mode changed */
+               ret = 2;
+
+       if (ret) {
+               dim_print(
+               "%s:ch[%d]: %dth source change 2: 0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n",
+                       __func__,
+                       ch,
+                       /*jiffies_to_msecs(jiffies_64),*/
+                       ppre->in_seq,
+                       vl->vtype,
+                       vl->h,
+                       vl->v,
+                       vl->src_type,
+                       vc->vtype,
+                       vc->h,
+                       vc->v,
+                       vc->src_type);
+       }
+
+       return ret;
+}
+
+bool dim_bypass_detect(unsigned int ch, struct vframe_s *vfm)
+{
+       bool ret = false;
+
+       if (!vfm)
+               return ret;
+       pre_vinfo_set(ch, vfm);
+       if (is_vinfo_change(ch)) {
+               if (!is_bypass2(vfm, ch)) {
+                       set_bypass2_complete(ch, false);
+                       PR_INF("%s:\n", __func__);
+                       /*task_send_ready();*/
+                       task_send_cmd(LCMD1(eCMD_CHG, ch));
+                       ret = true;
+               }
+       }
+       return ret;
+}
+
+unsigned int di_get_other_ch(unsigned int curr)
+{
+       return curr ? 0 : 1;
+}
+
+bool is_bypass_i_p(void)
+{
+       bool ret = false;
+       struct di_hpre_s  *pre = get_hw_pre();
+       struct di_vinfo_s *vc = &pre->vinf_curr;
+       #if 0
+       struct di_vinfo_s *vl = &pre->vinf_lst;
+
+       if (vl->ch != vc->ch                    &&
+           vf_type_is_interlace(vl->vtype)     &&
+           vf_type_is_prog(vc->vtype)) {
+               ret = true;
+       }
+       #else
+       unsigned int ch_c, ch_l;
+
+       struct di_pre_stru_s *ppre_c, *ppre_l;
+
+       if (!get_reg_flag(0)    ||
+           !get_reg_flag(1))
+               return ret;
+
+       ch_c = vc->ch;
+       ch_l = (ch_c ? 0 : 1);
+       ppre_c = get_pre_stru(ch_c);
+       ppre_l = get_pre_stru(ch_l);
+       if (vf_type_is_interlace(ppre_l->cur_inp_type)  &&
+           vf_type_is_prog(ppre_c->cur_inp_type)) {
+               ret = true;
+               dim_print("ch[%d]:bypass p\n", ch_c);
+       }
+       #endif
+
+       return ret;
+}
+
+void dpre_clear(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       memset(pre, 0, sizeof(struct di_hpre_s));
+}
+
+void dpre_init(void)
+{/*reg:*/
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       pre->pre_st = eDI_PRE_ST_IDLE;
+
+       /*timer out*/
+       di_tout_int(&pre->tout, 40);    /*ms*/
+}
+
+void pw_use_hw_pre(enum eDI_SUB_ID channel, bool on)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       pre->hw_flg_busy_pre = on;
+       if (on)
+               pre->curr_ch = channel;
+}
+
+enum eDI_SUB_ID pw_ch_next_count(enum eDI_SUB_ID channel)
+{
+       int i;
+       unsigned int lch, nch;
+
+       nch = channel;
+       for (i = 0; i < DI_CHANNEL_NUB; i++) {
+               lch = channel + i + 1;
+               if (lch >= DI_CHANNEL_NUB)
+                       lch -= DI_CHANNEL_NUB;
+               #if 0
+               if (pbm->sub_act_flg[lch]) {
+                       nch = lch;
+                       break;
+               }
+               #else
+               if (get_reg_flag(lch)           &&
+                   !get_flag_trig_unreg(lch)   &&
+                   !is_bypss2_complete(lch)) {
+                       nch = lch;
+                       break;
+               }
+               #endif
+       }
+       return nch;
+}
+
+/****************************************/
+static bool pw_try_sw_ch_next_pre(enum eDI_SUB_ID channel)
+{
+       bool ret = false;
+       struct di_hpre_s  *pre = get_hw_pre();
+       enum eDI_SUB_ID lst_ch, nch;
+
+       lst_ch = channel;
+
+       nch = pw_ch_next_count(lst_ch);
+       if (!get_reg_flag(nch)          ||
+           get_flag_trig_unreg(nch)    ||
+           is_bypss2_complete(nch))
+               return false;
+
+       pre->curr_ch = nch;
+       pre->hw_flg_busy_pre = true;
+       ret = true;
+
+       /*dim_print("%s:%d->%d:%d\n", __func__, lst_ch, nch, ret);*/
+       return ret;
+}
+
+/*****************************/
+/* debug */
+/*****************************/
+
+unsigned int di_dbg_pre_cnt;
+
+void dbg_cnt_begin(void)
+{
+       di_dbg_pre_cnt = 0x10;
+}
+
+void dbg_cnt_print(void)
+{
+       if (di_dbg_pre_cnt < 0xf)
+               return;
+
+       if (di_dbg_pre_cnt > 0x10) {
+               di_dbg_pre_cnt++;
+               pr_info("di:[%d]\n", di_dbg_pre_cnt);
+       }
+
+       if (di_dbg_pre_cnt > 0x15)
+               di_dbg_pre_cnt = 0;
+}
+
+/*****************************/
+/* STEP */
+/*****************************/
+void dpre_recyc(unsigned int ch)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       pre->check_recycle_buf_cnt = 0;
+       while (dim_check_recycle_buf(ch) & 1) {
+               if (pre->check_recycle_buf_cnt++ > MAX_IN_BUF_NUM) {
+                       di_pr_info("%s: dim_check_recycle_buf time out!!\n",
+                                  __func__);
+                       break;
+               }
+       }
+}
+
+void dpre_vdoing(unsigned int ch)
+{
+       struct di_post_stru_s *ppost = get_post_stru(ch);
+
+       ppost->di_post_process_cnt = 0;
+       while (dim_process_post_vframe(ch)) {
+               if (ppost->di_post_process_cnt++ >
+                       MAX_POST_BUF_NUM) {
+                       di_pr_info("%s: dim_process_post_vframe time out!!\n",
+                                  __func__);
+                       break;
+               }
+       }
+}
+
+bool dpre_can_exit(unsigned int ch)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       bool ret = false;
+
+       if (ch != pre->curr_ch) {
+               ret = true;
+       } else {
+               if (pre->pre_st <= eDI_PRE_ST4_IDLE)
+                       ret = true;
+       }
+       pr_info("%s:ch[%d]:curr[%d]:stat[%s] ret[%d]\n",
+               __func__,
+               ch, pre->curr_ch,
+               dpre_state4_name_get(pre->pre_st),
+               ret);
+       return ret;
+}
+
+void dpre_dbg_f_trig(unsigned int cmd)
+{
+       struct di_task *tsk = get_task();
+
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       if (down_interruptible(&tsk->sem)) {
+               PR_ERR("%s:can't get sem\n", __func__);
+               return;
+       }
+
+       /*set on/off and trig*/
+       if (cmd & 0x10) {
+               pre->dbg_f_en = 1;
+               pre->dbg_f_cnt = cmd & 0xf;
+               pre->dbg_f_lstate = pre->pre_st;
+       } else {
+               pre->dbg_f_en = 0;
+       }
+
+       up(&tsk->sem);
+}
+
+void dpre_process(void)
+{
+       bool reflesh;
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       if (pre->dbg_f_en) {
+               if (pre->dbg_f_cnt) {
+                       dpre_process_step4();
+                       pre->dbg_f_cnt--;
+               }
+               if (pre->dbg_f_lstate != pre->pre_st) {
+                       pr_info("ch[%d]:state:%s->%s\n",
+                               pre->curr_ch,
+                               dpre_state4_name_get(pre->dbg_f_lstate),
+                               dpre_state4_name_get(pre->pre_st));
+
+                       pre->dbg_f_lstate = pre->pre_st;
+               }
+               return;
+       }
+
+       reflesh = true;
+
+       while (reflesh) {
+               reflesh = dpre_process_step4();
+               #if 0   /*debug only*/
+               dbg_tsk("ch[%d]:st[%s]r[%d]\n", pre->curr_ch,
+                       dpre_state4_name_get(pre->pre_st), reflesh);
+               #endif
+       }
+}
+
+enum eDI_PRE_MT {
+       eDI_PRE_MT_CHECK = K_DO_TABLE_ID_START,
+       eDI_PRE_MT_SET,
+       eDI_PRE_MT_WAIT_INT,
+       eDI_PRE_MT_TIME_OUT,
+};
+
+/*use do_table:*/
+unsigned int dpre_mtotal_check(void *data)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       if ((pre_run_flag == DI_RUN_FLAG_RUN)   ||
+           (pre_run_flag == DI_RUN_FLAG_STEP)) {
+               if (pre_run_flag == DI_RUN_FLAG_STEP)
+                       pre_run_flag = DI_RUN_FLAG_STEP_DONE;
+               /*dim_print("%s:\n", __func__);*/
+               if (dim_pre_de_buf_config(pre->curr_ch))
+                       ret = K_DO_R_FINISH;
+               else
+                       ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+
+               dim_dbg_pre_cnt(pre->curr_ch, "x");
+       }
+
+       return ret;
+}
+
+unsigned int dpre_mtotal_set(void *data)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       ulong flags = 0;
+
+       /*dim_print("%s:\n", __func__);*/
+       spin_lock_irqsave(&plist_lock, flags);
+       dim_pre_de_process(pre->curr_ch);
+       spin_unlock_irqrestore(&plist_lock, flags);
+       /*begin to count timer*/
+       di_tout_contr(eDI_TOUT_CONTR_EN, &pre->tout);
+
+       return K_DO_R_FINISH;
+}
+
+enum eDI_WAIT_INT {
+       eDI_WAIT_INT_NEED_WAIT,
+       eDI_WAIT_INT_HAVE_INT,
+       eDI_WAIT_INT_TIME_OUT,
+};
+
+/*
+ *return:      enum eDI_WAIT_INT
+ *
+ */
+enum eDI_WAIT_INT di_pre_wait_int(void *data)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       ulong flags = 0;
+       struct di_pre_stru_s *ppre;
+
+       enum eDI_WAIT_INT ret = eDI_WAIT_INT_NEED_WAIT;
+
+       if (pre->flg_int_done) {
+               /*have INT done flg*/
+               /*DI_INTR_CTRL[bit 0], NRWR_done, set by
+                * hardware when NRWR is done,clear by write 1
+                * by code;[bit 1]
+                * MTNWR_done, set by hardware when MTNWR
+                * is done, clear by write 1 by code;these two
+                * bits have nothing to do with
+                * DI_INTR_CTRL[16](NRW irq mask, 0 to enable
+                * irq) and DI_INTR_CTRL[17]
+                * (MTN irq mask, 0 to enable irq).two
+                * interrupts are raised if both
+                * DI_INTR_CTRL[16] and DI_INTR_CTRL[17] are 0
+                */
+#if 0
+               data32 = Rd(DI_INTR_CTRL);
+               if (((data32 & 0x1) &&
+                   ((ppre->enable_mtnwr == 0) || (data32 & 0x2))) ||
+                   (ppre->pre_de_clear_flag == 2)) {
+                       dim_RDMA_WR(DI_INTR_CTRL, data32);
+               }
+#endif
+               di_pre_wait_irq_set(false);
+               /*finish to count timer*/
+               di_tout_contr(eDI_TOUT_CONTR_FINISH, &pre->tout);
+               spin_lock_irqsave(&plist_lock, flags);
+
+               dim_pre_de_done_buf_config(pre->curr_ch, false);
+
+               pre->flg_int_done = 0;
+
+               dpre_recyc(pre->curr_ch);
+               dpre_vdoing(pre->curr_ch);
+
+               spin_unlock_irqrestore(&plist_lock, flags);
+
+               ppre = get_pre_stru(pre->curr_ch);
+#if 0
+               if (ppre->field_count_for_cont == 1) {
+                       usleep_range(2000, 2001);
+                       pr_info("delay 1ms\n");
+               }
+#endif
+
+               ret = eDI_WAIT_INT_HAVE_INT;
+
+       } else {
+               /*check if timeout:*/
+               if (di_tout_contr(eDI_TOUT_CONTR_CHECK, &pre->tout)) {
+                       di_pre_wait_irq_set(false);
+                       /*return K_DO_R_FINISH;*/
+                       ret = eDI_WAIT_INT_TIME_OUT;
+               }
+       }
+       /*debug:*/
+       if (dbg_first_cnt_pre)
+               dbg_first_frame("ch[%d],w_int[%d]\n", pre->curr_ch, ret);
+
+       return ret;
+}
+
+unsigned int dpre_mtotal_wait_int(void *data)
+{
+       enum eDI_WAIT_INT wret;
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       wret = di_pre_wait_int(NULL);
+       switch (wret) {
+       case eDI_WAIT_INT_NEED_WAIT:
+               ret = K_DO_R_NOT_FINISH;
+               break;
+       case eDI_WAIT_INT_HAVE_INT:
+               ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+               break;
+       case eDI_WAIT_INT_TIME_OUT:
+               ret = K_DO_R_FINISH;
+               break;
+       }
+       return ret;
+}
+
+void dpre_mtotal_timeout_contr(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       /*move from di_pre_trigger_work*/
+       if (dimp_get(eDI_MP_di_dbg_mask) & 4)
+               dim_dump_mif_size_state(pre->pres, pre->psts);
+
+       dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en));
+       if (di_get_dts_nrds_en())
+               dim_nr_ds_hw_ctrl(false);
+       pre->pres->pre_de_irq_timeout_count++;
+
+       pre->pres->pre_de_busy = 0;
+       pre->pres->pre_de_clear_flag = 2;
+       if ((dimp_get(eDI_MP_di_dbg_mask) & 0x2)) {
+               pr_info("DI:ch[%d]*****wait %d timeout 0x%x(%d ms)*****\n",
+                       pre->curr_ch,
+                       pre->pres->field_count_for_cont,
+                       Rd(DI_INTR_CTRL),
+                       (unsigned int)(cur_to_msecs() -
+                       pre->pres->irq_time[1]));
+       }
+       /*******************************/
+       dim_pre_de_done_buf_config(pre->curr_ch, true);
+
+       dpre_recyc(pre->curr_ch);
+       dpre_vdoing(pre->curr_ch);
+       /*******************************/
+       /*dpre_recyc(pre->curr_ch);*/
+}
+
+unsigned int dpre_mtotal_timeout(void *data)
+{
+       ulong flags = 0;
+
+       spin_lock_irqsave(&plist_lock, flags);
+       dpre_mtotal_timeout_contr();
+       spin_unlock_irqrestore(&plist_lock, flags);
+
+       return K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+}
+
+const struct do_table_ops_s pr_mode_total[] = {
+       /*fix*/
+       [K_DO_TABLE_ID_PAUSE] = {
+       .id = K_DO_TABLE_ID_PAUSE,
+       .mark = 0,
+       .con = NULL,
+       .do_op = NULL,
+       .do_stop_op = NULL,
+       .name = "pause",
+       },
+       [K_DO_TABLE_ID_STOP] = {
+       .id = K_DO_TABLE_ID_STOP,
+       .mark = 0,
+       .con = NULL,
+       .do_op = NULL,
+       .do_stop_op = NULL,
+       .name = "stop",
+       },
+       /******************/
+       [K_DO_TABLE_ID_START] = {       /*eDI_PRE_MT_CHECK*/
+       .id = K_DO_TABLE_ID_START,
+       .mark = 0,
+       .con = NULL,
+       .do_op = dpre_mtotal_check,
+       .do_stop_op = NULL,
+       .name = "start-check",
+       },
+       [eDI_PRE_MT_SET] = {
+       .id = eDI_PRE_MT_SET,
+       .mark = 0,
+       .con = NULL,
+       .do_op = dpre_mtotal_set,
+       .do_stop_op = NULL,
+       .name = "set",
+       },
+       [eDI_PRE_MT_WAIT_INT] = {
+       .id = eDI_PRE_MT_WAIT_INT,
+       .mark = 0,
+       .con = NULL,
+       .do_op = dpre_mtotal_wait_int,
+       .do_stop_op = NULL,
+       .name = "wait_int",
+       },
+       [eDI_PRE_MT_TIME_OUT] = {
+       .id = eDI_PRE_MT_TIME_OUT,
+       .mark = 0,
+       .con = NULL,
+       .do_op = dpre_mtotal_timeout,
+       .do_stop_op = NULL,
+       .name = "timeout",
+       },
+};
+
+/****************************
+ *
+ * mode for p
+ *
+ ****************************/
+enum eDI_PRE_MP {
+       eDI_PRE_MP_CHECK = K_DO_TABLE_ID_START,
+       eDI_PRE_MP_SET,
+       eDI_PRE_MP_WAIT_INT,
+       eDI_PRE_MP_TIME_OUT,
+       eDI_PRE_MP_CHECK2,
+       eDI_PRE_MP_SET2,
+       eDI_PRE_MP_WAIT_INT2,
+       eDI_PRE_MP_TIME_OUT2,
+};
+
+unsigned int dpre_mp_check(void *data)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       if ((pre_run_flag == DI_RUN_FLAG_RUN)   ||
+           (pre_run_flag == DI_RUN_FLAG_STEP)) {
+               if (pre_run_flag == DI_RUN_FLAG_STEP)
+                       pre_run_flag = DI_RUN_FLAG_STEP_DONE;
+                       /*dim_print("%s:\n", __func__);*/
+               if (dim_pre_de_buf_config(pre->curr_ch)) {
+                       /*pre->flg_wait_int = false;*/
+                       /*pre_p_asi_set_next(pre->curr_ch);*/
+                       ret = K_DO_R_FINISH;
+               } else {
+                       /*pre->flg_wait_int = false;*/
+                       ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+               }
+               dim_dbg_pre_cnt(pre->curr_ch, "x");
+       }
+
+       return ret;
+}
+
+unsigned int dpre_mp_check2(void *data)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       if (dim_pre_de_buf_config(pre->curr_ch)) {
+               /*pre->flg_wait_int = false;*/
+               ret = K_DO_R_FINISH;
+       }
+       #if 0
+       else {
+               PR_ERR("%s:not second?ch[%d]\n", __func__, pre->curr_ch);
+               ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+       }
+       #endif
+
+       return ret;
+}
+
+unsigned int dpre_mp_wait_int(void *data)
+{
+       enum eDI_WAIT_INT wret;
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       wret = di_pre_wait_int(NULL);
+       switch (wret) {
+       case eDI_WAIT_INT_NEED_WAIT:
+               ret = K_DO_R_NOT_FINISH;
+               break;
+       case eDI_WAIT_INT_HAVE_INT:
+               ret = K_DO_R_JUMP(eDI_PRE_MP_CHECK2);
+               break;
+       case eDI_WAIT_INT_TIME_OUT:
+               ret = K_DO_R_FINISH;
+               break;
+       }
+       return ret;
+}
+
+unsigned int dpre_mp_wait_int2(void *data)
+{
+       enum eDI_WAIT_INT wret;
+       unsigned int ret = K_DO_R_NOT_FINISH;
+
+       wret = di_pre_wait_int(NULL);
+       switch (wret) {
+       case eDI_WAIT_INT_NEED_WAIT:
+               ret = K_DO_R_NOT_FINISH;
+               break;
+       case eDI_WAIT_INT_HAVE_INT:
+               ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+               break;
+       case eDI_WAIT_INT_TIME_OUT:
+               ret = K_DO_R_FINISH;
+               break;
+       }
+       return ret;
+}
+
+unsigned int dpre_mp_timeout(void *data)
+{
+       dpre_mtotal_timeout_contr();
+
+       return K_DO_R_FINISH;
+}
+
+unsigned int dpre_mp_timeout2(void *data)
+{
+       dpre_mtotal_timeout_contr();
+
+       return K_DO_R_JUMP(K_DO_TABLE_ID_STOP);
+}
+
+const struct do_table_ops_s pre_mode_proc[] = {
+       /*fix*/
+       [K_DO_TABLE_ID_PAUSE] = {
+       .id = K_DO_TABLE_ID_PAUSE,
+       .mark = 0,
+       .con = NULL,
+       .do_op = NULL,
+       .do_stop_op = NULL,
+       .name = "pause",
+       },
+       [K_DO_TABLE_ID_STOP] = {
+       .id = K_DO_TABLE_ID_STOP,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,
+       .do_op = NULL,
+       .do_stop_op = NULL,
+       .name = "stop",
+       },
+       /******************/
+       [K_DO_TABLE_ID_START] = {       /*eDI_PRE_MP_CHECK*/
+       .id = K_DO_TABLE_ID_START,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,
+       .do_op = dpre_mp_check,
+       .do_stop_op = NULL,
+       .name = "start-check",
+       },
+       [eDI_PRE_MP_SET] = {
+       .id = eDI_PRE_MP_SET,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mtotal_set,
+       .do_stop_op = NULL,
+       .name = "pset",
+       },
+       [eDI_PRE_MP_WAIT_INT] = {
+       .id = eDI_PRE_MP_WAIT_INT,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mp_wait_int,
+       .do_stop_op = NULL,
+       .name = "pwait_int",
+       },
+       [eDI_PRE_MP_TIME_OUT] = {
+       .id = eDI_PRE_MP_TIME_OUT,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mp_timeout,
+       .do_stop_op = NULL,
+       .name = "ptimeout",
+       },
+       /******/
+       [eDI_PRE_MP_CHECK2] = {         /*eDI_PRE_MP_CHECK2*/
+       .id = eDI_PRE_MP_CHECK2,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mp_check2,
+       .do_stop_op = NULL,
+       .name = "start-check",
+       },
+       [eDI_PRE_MP_SET2] = {
+       .id = eDI_PRE_MP_SET2,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mtotal_set,
+       .do_stop_op = NULL,
+       .name = "psetp2",
+       },
+       [eDI_PRE_MP_WAIT_INT2] = {
+       .id = eDI_PRE_MP_WAIT_INT2,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mp_wait_int2,
+       .do_stop_op = NULL,
+       .name = "pwait_int2",
+       },
+       [eDI_PRE_MP_TIME_OUT2] = {
+       .id = eDI_PRE_MP_TIME_OUT2,
+       .mark = 0,                      /*stop / pause*/
+       .con = NULL,                    /*condition*/
+       .do_op = dpre_mp_timeout2,
+       .do_stop_op = NULL,
+       .name = "ptimeout2",
+       },
+
+};
+
+void pre_mode_setting(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+
+       if (pre->pre_st != eDI_PRE_ST4_DO_TABLE)
+               return;
+
+       do_table_working(&pre->sdt_mode);
+}
+
+/*--------------------------*/
+enum eDI_WORK_MODE pre_cfg_count_mode(unsigned int ch, struct vframe_s *vframe)
+{
+       enum eDI_WORK_MODE pmode;
+
+       if (is_bypass2(vframe, ch)) {
+               pmode = eDI_WORK_MODE_bypass_all;
+               return pmode;
+       }
+
+       if (COM_ME(vframe->type, VIDTYPE_INTERLACE)) {
+               /*interlace:*/
+               pmode = eDI_WORK_MODE_i;
+               return pmode;
+       }
+
+       if (dimp_get(eDI_MP_prog_proc_config) & 0x10)
+               pmode = eDI_WORK_MODE_p_as_p;
+       else if (is_from_vdin(vframe))
+               pmode = eDI_WORK_MODE_p_use_ibuf;
+       else
+               pmode = eDI_WORK_MODE_p_as_i;
+
+       return pmode;
+}
+
+unsigned int dpre_check_mode(unsigned int ch)
+{
+       struct vframe_s *vframe;
+       unsigned int mode;
+
+       vframe = pw_vf_peek(ch);
+
+       if (!vframe)
+               return eDI_WORK_MODE_NONE;
+       mode = pre_cfg_count_mode(ch, vframe);/*eDI_WORK_MODE_all;*/
+
+       return mode;
+}
+
+/*--------------------------*/
+bool dpre_step4_idle(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       bool reflesh = false;
+       unsigned int ch;
+
+       ch = pre->curr_ch;
+       if (!pw_try_sw_ch_next_pre(ch))
+               return false;
+
+       if (pre->idle_cnt >= DI_CHANNEL_NUB) {
+               pre->idle_cnt = 0;
+               return false;
+       }
+       pre->pres = get_pre_stru(pre->curr_ch);
+       pre->psts = get_post_stru(pre->curr_ch);
+
+       /*state*/
+       pre->pre_st++;/*tmp*/
+       reflesh = true;
+
+       return reflesh;
+}
+
+bool dpre_step4_check(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       bool reflesh = false;
+       unsigned int mode;
+
+       /*get vframe and select mode
+        * now: fix use total table
+        */
+
+       mode = dpre_check_mode(pre->curr_ch);
+
+       if (mode == eDI_WORK_MODE_NONE) {
+               pre->pre_st--;
+               pre->idle_cnt++;
+               return true;
+       }
+       pre->idle_cnt = 0;
+       if (mode == eDI_WORK_MODE_p_as_i) {
+               do_table_init(&pre->sdt_mode,
+                             &pre_mode_proc[0],
+                             ARRAY_SIZE(pre_mode_proc));
+
+       } else {
+               do_table_init(&pre->sdt_mode,
+                             &pr_mode_total[0],
+                             ARRAY_SIZE(pr_mode_total));
+       }
+       do_talbe_cmd(&pre->sdt_mode, eDO_TABLE_CMD_START);
+
+       /*state*/
+       pre->pre_st++;
+       reflesh = true;
+
+       return reflesh;
+}
+
+bool dpre_step4_do_table(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       bool reflesh = false;
+
+       if (do_table_is_crr(&pre->sdt_mode, K_DO_TABLE_ID_STOP)) {
+               pre->pre_st = eDI_PRE_ST4_IDLE;
+               reflesh = true;
+       }
+       return reflesh;
+}
+
+const struct di_func_tab_s di_pre_func_tab4[] = {
+       {eDI_PRE_ST4_EXIT, NULL},
+       {eDI_PRE_ST4_IDLE, dpre_step4_idle},
+       {eDI_PRE_ST4_CHECK, dpre_step4_check},
+       {eDI_PRE_ST4_DO_TABLE, dpre_step4_do_table},
+};
+
+const char * const dpre_state_name4[] = {
+       "EXIT",
+       "IDLE", /*swith to next channel?*/
+       "CHECK",
+       "DO_TABLE",
+};
+
+const char *dpre_state4_name_get(enum eDI_PRE_ST4 state)
+{
+       if (state > eDI_PRE_ST4_DO_TABLE)
+               return "nothing";
+
+       return dpre_state_name4[state];
+}
+
+bool dpre_process_step4(void)
+{
+       struct di_hpre_s  *pre = get_hw_pre();
+       enum eDI_PRE_ST4 pre_st = pre->pre_st;
+       ulong flags = 0;
+
+       if (pre_st > eDI_PRE_ST4_EXIT) {
+               spin_lock_irqsave(&plist_lock, flags);
+               dim_recycle_post_back(pre->curr_ch);
+               dpre_recyc(pre->curr_ch);
+               dpre_vdoing(pre->curr_ch);
+               spin_unlock_irqrestore(&plist_lock, flags);
+       }
+       if ((pre_st <= eDI_PRE_ST4_DO_TABLE)    &&
+           di_pre_func_tab4[pre_st].func) {
+               return di_pre_func_tab4[pre_st].func();
+       }
+
+       return false;
+}
diff --git a/drivers/amlogic/media/di_multi/di_pre.h b/drivers/amlogic/media/di_multi/di_pre.h
new file mode 100644 (file)
index 0000000..2f46b12
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * drivers/amlogic/media/di_multi/di_pre.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_PRE_H__
+#define __DI_PRE_H__
+
+void dpre_process(void);
+
+void dpre_init(void);
+
+const char *dpre_state_name_get(enum eDI_PRE_ST state);
+void dpre_dbg_f_trig(unsigned int cmd);
+void pre_vinfo_set(unsigned int ch,
+                  struct vframe_s *ori_vframe);
+unsigned int is_vinfo_change(unsigned int ch);
+bool dpre_can_exit(unsigned int ch);
+bool is_bypass_i_p(void);
+bool dim_bypass_detect(unsigned int ch, struct vframe_s *vfm);
+
+void pre_mode_setting(void);
+bool dpre_process_step4(void);
+const char *dpre_state4_name_get(enum eDI_PRE_ST4 state);
+
+#endif /*__DI_PRE_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_que.c b/drivers/amlogic/media/di_multi/di_que.c
new file mode 100644 (file)
index 0000000..1d96da9
--- /dev/null
@@ -0,0 +1,995 @@
+/*
+ * drivers/amlogic/media/di_multi/di_que.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+#include <linux/kfifo.h>
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "deinterlace.h"
+
+#include "di_data_l.h"
+#include "di_que.h"
+#include "di_vframe.h"
+
+#include "di_prc.h"
+
+const char * const di_name_new_que[QUE_NUB] = {
+       "QUE_IN_FREE",  /*0*/
+       "QUE_PRE_READY",        /*1*/
+       "QUE_POST_FREE",        /*2*/
+       "QUE_POST_READY",       /*3*/
+       "QUE_POST_BACK",        /*4*/
+       "QUE_DBG",
+/*     "QUE_NUB",*/
+
+};
+
+#define que_dbg                dim_print
+
+static void pw_queue_clear(unsigned int ch, enum QUE_TYPE qtype)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return;
+#endif
+       kfifo_reset(&pch->fifo[qtype]);
+}
+
+bool pw_queue_in(unsigned int ch, enum QUE_TYPE qtype, unsigned int buf_index)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return false;
+#endif
+       if (kfifo_in(&pch->fifo[qtype], &buf_index, sizeof(unsigned int))
+               != sizeof(unsigned int))
+               return false;
+#if 0
+
+       /*below for debug: save in que*/
+       if (qtype <= QUE_POST_RECYC) {
+               if (buf_index >= MAX_POST_BUF_NUM) {
+                       pr_err("%s:err:overflow?[%d]\n", __func__, buf_index);
+               } else {
+                       ppw = &pch->lpost_buf[buf_index];
+                       ppw->in_qtype = qtype;
+               }
+       }
+#endif
+       return true;
+}
+
+bool pw_queue_out(unsigned int ch, enum QUE_TYPE qtype,
+                 unsigned int *buf_index)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+       unsigned int index;
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return false;
+#endif
+       if (kfifo_out(&pch->fifo[qtype], &index, sizeof(unsigned int))
+               != sizeof(unsigned int))
+               return false;
+
+       *buf_index = index;
+
+       return true;
+}
+
+static bool pw_queue_peek(unsigned int ch, enum QUE_TYPE qtype,
+                         unsigned int *buf_index)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+       unsigned int index;
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return false;
+#endif
+
+       if (kfifo_out_peek(&pch->fifo[qtype], &index, sizeof(unsigned int))
+               != sizeof(unsigned int))
+               return false;
+
+       *buf_index = index;
+
+       return true;
+}
+
+bool pw_queue_move(unsigned int ch, enum QUE_TYPE qtypef, enum QUE_TYPE qtypet,
+                  unsigned int *oindex)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+       unsigned int index;
+
+       /*struct di_post_buf_s *ppw;*/ /*debug only*/
+
+#if 0
+       if (qtypef >= QUE_NUB || qtypet >= QUE_NUB)
+               return false;
+#endif
+       if (kfifo_out(&pch->fifo[qtypef], &index, sizeof(unsigned int))
+               != sizeof(unsigned int)) {
+               PR_ERR("qtypef[%d] is empty\n", qtypef);
+               return false;
+       }
+       if (kfifo_in(&pch->fifo[qtypet], &index, sizeof(unsigned int))
+                       != sizeof(unsigned int)) {
+               PR_ERR("qtypet[%d] is full\n", qtypet);
+               return false;
+       }
+
+       *oindex = index;
+#if 0
+       if (qtypet <= QUE_POST_RECYC) {
+               /*below for debug: save in que*/
+               if (index >= MAX_POST_BUF_NUM) {
+                       pr_err("%s:err:overflow?[%d]\n", __func__, index);
+               } else {
+               ppw = &pch->lpost_buf[index];
+               ppw->in_qtype = qtypet;
+               }
+       }
+#endif
+       return true;
+}
+
+bool pw_queue_empty(unsigned int ch, enum QUE_TYPE qtype)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+
+       if (kfifo_is_empty(&pch->fifo[qtype]))
+               return true;
+
+       return false;
+}
+
+int di_que_list_count(unsigned int ch, enum QUE_TYPE qtype)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+       unsigned int length;
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return -1;
+#endif
+       length = kfifo_len(&pch->fifo[qtype]);
+       length = length / sizeof(unsigned int);
+
+       return length;
+}
+
+/***************************************/
+/*outbuf : array size MAX_FIFO_SIZE*/
+/***************************************/
+bool di_que_list(unsigned int ch, enum QUE_TYPE qtype, unsigned int *outbuf,
+                unsigned int *rsize)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+/*     unsigned int tmp[MAX_FIFO_SIZE + 1];*/
+       int i;
+       unsigned int index;
+       bool ret = false;
+
+       /*que_dbg("%s:begin\n", __func__);*/
+       for (i = 0; i < MAX_FIFO_SIZE; i++)
+               outbuf[i] = 0xff;
+
+       if (kfifo_is_empty(&pch->fifo[qtype])) {
+               que_dbg("\t%d:empty\n", qtype);
+               *rsize = 0;
+               return true;
+       }
+
+       ret = true;
+       memcpy(&pch->fifo[QUE_DBG], &pch->fifo[qtype],
+              sizeof(pch->fifo[qtype]));
+
+#if 0
+       if (kfifo_is_empty(&pbm->fifo[QUE_DBG]))
+               pr_err("%s:err, kfifo can not copy?\n", __func__);
+
+#endif
+       i = 0;
+       *rsize = 0;
+
+       while (kfifo_out(&pch->fifo[QUE_DBG], &index, sizeof(unsigned int))
+               == sizeof(unsigned int)) {
+               outbuf[i] = index;
+               /*pr_info("%d->%d\n",i,index);*/
+               i++;
+       }
+       *rsize = di_que_list_count(ch, qtype);
+       #if 0   /*debug only*/
+       que_dbg("%s: size[%d]\n", di_name_new_que[qtype], *rsize);
+       for (i = 0; i < *rsize; i++)
+               que_dbg("%d,", outbuf[i]);
+
+       que_dbg("\n");
+       #endif
+       /*que_dbg("finish\n");*/
+
+       return ret;
+}
+
+int di_que_is_empty(unsigned int ch, enum QUE_TYPE qtype)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+
+#if 0
+       if (qtype >= QUE_NUB)
+               return -1;
+#endif
+       return kfifo_is_empty(&pch->fifo[qtype]);
+}
+
+void di_que_init(unsigned int ch)
+{
+       int i;
+
+       for (i = 0; i < QUE_NUB; i++)
+               pw_queue_clear(ch, i);
+}
+
+bool di_que_alloc(unsigned int ch)
+{
+       int i;
+       int ret;
+       bool flg_err;
+       struct di_ch_s *pch = get_chdata(ch);
+
+       /*kfifo----------------------------*/
+       flg_err = 0;
+       for (i = 0; i < QUE_NUB; i++) {
+               ret = kfifo_alloc(&pch->fifo[i],
+                                 sizeof(unsigned int) * MAX_FIFO_SIZE,
+                                 GFP_KERNEL);
+               if (ret < 0) {
+                       flg_err = 1;
+                       PR_ERR("%s:%d:can't get kfifo\n", __func__, i);
+                       break;
+               }
+               pch->flg_fifo[i] = 1;
+       }
+#if 0
+       /*canvas-----------------------------*/
+       canvas_alloc();
+#endif
+/*     pdp_clear();*/
+
+       if (!flg_err) {
+               /*pbm->flg_fifo = 1;*/
+               pr_info("%s:ok\n", __func__);
+               ret = true;
+       } else {
+               di_que_release(ch);
+               ret = false;
+       }
+
+       return ret;
+}
+
+void di_que_release(unsigned int ch)
+{
+       struct di_ch_s *pch = get_chdata(ch);
+       int i;
+
+/*     canvas_release();*/
+       for (i = 0; i < QUE_NUB; i++) {
+               if (pch->flg_fifo[i]) {
+                       kfifo_free(&pch->fifo[i]);
+                       pch->flg_fifo[i] = 0;
+               }
+       }
+
+       pr_info("%s:ok\n", __func__);
+}
+
+/********************************************
+ *get di_buf from index that same in que
+ *     (di_buf->type << 8) | (di_buf->index)
+ ********************************************/
+struct di_buf_s *pw_qindex_2_buf(unsigned int ch, unsigned int qindex)
+{
+       union uDI_QBUF_INDEX index;
+       struct di_buf_s *di_buf;
+       struct di_buf_pool_s *pbuf_pool = get_buf_pool(ch);
+
+       index.d32 = qindex;
+       di_buf = &pbuf_pool[index.b.type - 1].di_buf_ptr[index.b.index];
+
+       return di_buf;
+}
+
+/********************************************/
+/*get di_buf from index that same in que*/
+/*(di_buf->type << 8) | (di_buf->index)*/
+/********************************************/
+static unsigned int pw_buf_2_qindex(unsigned int ch, struct di_buf_s *pdi_buf)
+{
+       union   uDI_QBUF_INDEX index;
+
+       index.b.index = pdi_buf->index;
+       index.b.type = pdi_buf->type;
+       return index.d32;
+}
+
+/*di_buf is out*/
+struct di_buf_s *di_que_out_to_di_buf(unsigned int ch, enum QUE_TYPE qtype)
+{
+       unsigned int q_index;
+       struct di_buf_s *pdi_buf = NULL;
+
+       if (!pw_queue_peek(ch, qtype, &q_index))
+               return pdi_buf;
+
+       pdi_buf = pw_qindex_2_buf(ch, q_index);
+       if (!pdi_buf) {
+               PR_ERR("di:err:%s:buf is null[%d]\n", __func__, q_index);
+               return NULL;
+       }
+
+       pw_queue_out(ch, qtype, &q_index);
+       pdi_buf->queue_index = -1;
+
+       return pdi_buf;
+}
+
+/*di_buf is input*/
+bool di_que_out(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf)
+{
+       unsigned int q_index;
+       unsigned int q_index2;
+
+       if (!pw_queue_peek(ch, qtype, &q_index))
+               return false;
+
+       q_index2 = pw_buf_2_qindex(ch, di_buf);
+       if (q_index2 != q_index) {
+               PR_ERR("di:%s:not map[%d,%d]\n", __func__, q_index2, q_index);
+               return false;
+       }
+
+       pw_queue_out(ch, qtype, &q_index);
+       di_buf->queue_index = -1;
+       return true;
+}
+
+bool di_que_in(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf)
+{
+       unsigned int q_index;
+
+       if (!di_buf) {
+               PR_ERR("di:%s:err:di_buf is NULL,ch[%d],qtype[%d]\n",
+                      __func__, ch, qtype);
+               return false;
+       }
+       if (di_buf->queue_index != -1) {
+               PR_ERR("di:%s:buf in some que,ch[%d],qt[%d],qi[%d],bi[%d]\n",
+                      __func__,
+                      ch, qtype, di_buf->queue_index, di_buf->index);
+               return false;
+       }
+
+       q_index = pw_buf_2_qindex(ch, di_buf);
+
+       if (!pw_queue_in(ch, qtype, q_index)) {
+               PR_ERR("di:%s:err:can't que in,ch[%d],qtype[%d],q_index[%d]\n",
+                      __func__,
+                      ch, qtype, q_index);
+               return false;
+       }
+       di_buf->queue_index = qtype + QUEUE_NUM;
+
+       if (qtype == QUE_PRE_READY)
+               dim_print("di:pre_ready in %d\n", di_buf->index);
+
+       return true;
+}
+
+bool di_que_is_in_que(unsigned int ch, enum QUE_TYPE qtype,
+                     struct di_buf_s *di_buf)
+{
+       unsigned int q_index;
+       unsigned int arr[MAX_FIFO_SIZE + 1];
+       unsigned int asize = 0;
+       bool ret = false;
+       unsigned int i;
+
+       if (!di_buf)
+               return false;
+
+       q_index = pw_buf_2_qindex(ch, di_buf);
+
+       di_que_list(ch, qtype, &arr[0], &asize);
+
+       if (asize == 0)
+               return ret;
+
+       for (i = 0; i < asize; i++) {
+               if (arr[i] == q_index) {
+                       ret = true;
+                       break;
+               }
+       }
+       return ret;
+}
+
+/*same as get_di_buf_head*/
+struct di_buf_s *di_que_peek(unsigned int ch, enum QUE_TYPE qtype)
+{
+       struct di_buf_s *di_buf = NULL;
+       unsigned int q_index;
+
+       if (!pw_queue_peek(ch, qtype, &q_index))
+               return di_buf;
+       di_buf = pw_qindex_2_buf(ch, q_index);
+
+       return di_buf;
+}
+
+bool di_que_type_2_new(unsigned int q_type, enum QUE_TYPE *nqtype)
+{
+       if (!F_IN(q_type, QUEUE_NEW_THD_MIN, QUEUE_NEW_THD_MAX))
+               return false;
+       *nqtype = (enum QUE_TYPE)(q_type - QUEUE_NUM);
+
+       return true;
+}
+
+/**********************************************************/
+/**********************************************************/
+/*ary add this function for reg ini value, no need wait peek*/
+void queue_init2(unsigned int channel)
+{
+       int i, j;
+       struct queue_s *pqueue = get_queue(channel);
+
+       for (i = 0; i < QUEUE_NUM; i++) {
+               queue_t *q = &pqueue[i];
+
+               for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++)
+                       q->pool[j] = 0;
+
+               q->in_idx = 0;
+               q->out_idx = 0;
+               q->num = 0;
+               q->type = 0;
+               if ((i == QUEUE_RECYCLE) ||
+                   (i == QUEUE_DISPLAY) ||
+                   (i == QUEUE_TMP)     ||
+                   (i == QUEUE_POST_DOING))
+                       q->type = 1;
+
+#if 0
+               if ((i == QUEUE_LOCAL_FREE) && dim_get_use_2_int_buf())
+                       q->type = 2;
+#endif
+       }
+}
+
+void queue_init(unsigned int channel, int local_buffer_num)
+{
+       int i, j;
+       struct di_buf_s *pbuf_local = get_buf_local(channel);
+       struct di_buf_s *pbuf_in = get_buf_in(channel);
+       struct di_buf_s *pbuf_post = get_buf_post(channel);
+       struct queue_s *pqueue = get_queue(channel);
+       struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
+
+       for (i = 0; i < QUEUE_NUM; i++) {
+               queue_t *q = &pqueue[i];
+
+               for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++)
+                       q->pool[j] = 0;
+
+               q->in_idx = 0;
+               q->out_idx = 0;
+               q->num = 0;
+               q->type = 0;
+               if ((i == QUEUE_RECYCLE) ||
+                   (i == QUEUE_DISPLAY) ||
+                   (i == QUEUE_TMP)
+                   /*||(i == QUEUE_POST_DOING)*/
+                   )
+                       q->type = 1;
+
+               if ((i == QUEUE_LOCAL_FREE) &&
+                   dimp_get(eDI_MP_use_2_interlace_buff))
+                       q->type = 2;
+       }
+       if (local_buffer_num > 0) {
+               pbuf_pool[VFRAME_TYPE_IN - 1].di_buf_ptr = &pbuf_in[0];
+               pbuf_pool[VFRAME_TYPE_IN - 1].size = MAX_IN_BUF_NUM;
+
+               pbuf_pool[VFRAME_TYPE_LOCAL - 1].di_buf_ptr = &pbuf_local[0];
+               pbuf_pool[VFRAME_TYPE_LOCAL - 1].size = local_buffer_num;
+
+               pbuf_pool[VFRAME_TYPE_POST - 1].di_buf_ptr = &pbuf_post[0];
+               pbuf_pool[VFRAME_TYPE_POST - 1].size = MAX_POST_BUF_NUM;
+       }
+}
+
+struct di_buf_s *get_di_buf_head(unsigned int channel, int queue_idx)
+{
+       struct queue_s *pqueue = get_queue(channel);
+       queue_t *q = &pqueue[queue_idx];
+       int idx;
+       unsigned int pool_idx, di_buf_idx;
+       struct di_buf_s *di_buf = NULL;
+       struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel);
+       enum QUE_TYPE nqtype;/*new que*/
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s:<%d:%d,%d,%d>\n", __func__, queue_idx,
+                         q->num, q->in_idx, q->out_idx);
+       /* ****new que***** */
+       if (di_que_type_2_new(queue_idx, &nqtype))
+               return di_que_peek(channel, nqtype);
+
+       /* **************** */
+
+       if (q->num > 0) {
+               if (q->type == 0) {
+                       idx = q->out_idx;
+               } else {
+                       for (idx = 0; idx < MAX_QUEUE_POOL_SIZE; idx++)
+                               if (q->pool[idx] != 0)
+                                       break;
+               }
+               if (idx < MAX_QUEUE_POOL_SIZE) {
+                       pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1;
+                       di_buf_idx = q->pool[idx] & 0xff;
+
+       if (pool_idx < VFRAME_TYPE_NUM) {
+               if (di_buf_idx < pbuf_pool[pool_idx].size)
+                       di_buf = &pbuf_pool[pool_idx].di_buf_ptr[di_buf_idx];
+       }
+               }
+       }
+
+       if ((di_buf) && ((((pool_idx + 1) << 8) | di_buf_idx) !=
+                        ((di_buf->type << 8) | (di_buf->index)))) {
+               pr_dbg("%s: Error (%x,%x)\n", __func__,
+                      (((pool_idx + 1) << 8) | di_buf_idx),
+                      ((di_buf->type << 8) | (di_buf->index)));
+
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(2);
+                       dim_vcry_set_log_q_idx(queue_idx);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+               dim_vcry_flg_inc();
+               di_buf = NULL;
+       }
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) {
+               if (di_buf)
+                       dim_print("%s: %x(%d,%d)\n", __func__, di_buf,
+                                 pool_idx, di_buf_idx);
+               else
+                       dim_print("%s: %x\n", __func__, di_buf);
+       }
+
+       return di_buf;
+}
+
+/*ary: note:*/
+/*a. di_buf->queue_index = -1*/
+/*b. */
+void queue_out(unsigned int channel, struct di_buf_s *di_buf)
+{
+       int i;
+       queue_t *q;
+       struct queue_s *pqueue = get_queue(channel);
+       enum QUE_TYPE nqtype;/*new que*/
+
+       if (!di_buf) {
+               PR_ERR("%s:Error\n", __func__);
+
+               if (dim_vcry_get_flg() == 0)
+                       dim_vcry_set_log_reason(3);
+
+               dim_vcry_flg_inc();
+               return;
+       }
+       /* ****new que***** */
+       if (di_que_type_2_new(di_buf->queue_index, &nqtype)) {
+               di_que_out(channel, nqtype, di_buf);    /*?*/
+               return;
+       }
+       /* **************** */
+
+       if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) {
+               q = &pqueue[di_buf->queue_index];
+
+               if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+                       dim_print("%s:<%d:%d,%d,%d> %x\n", __func__,
+                                 di_buf->queue_index, q->num, q->in_idx,
+                                 q->out_idx, di_buf);
+
+               if (q->num > 0) {
+                       if (q->type == 0) {
+                               if (q->pool[q->out_idx] ==
+                                   ((di_buf->type << 8) | (di_buf->index))) {
+                                       q->num--;
+                                       q->pool[q->out_idx] = 0;
+                                       q->out_idx++;
+                                       if (q->out_idx >= MAX_QUEUE_POOL_SIZE)
+                                               q->out_idx = 0;
+                                       di_buf->queue_index = -1;
+                               } else {
+                                       PR_ERR(
+                                               "%s: Error (%d, %x,%x)\n",
+                                               __func__,
+                                               di_buf->queue_index,
+                                               q->pool[q->out_idx],
+                                               ((di_buf->type << 8) |
+                                               (di_buf->index)));
+
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(4);
+                               dim_vcry_set_log_q_idx(di_buf->queue_index);
+                               dim_vcry_set_log_di_buf(di_buf);
+                       }
+                                       dim_vcry_flg_inc();
+                               }
+                       } else if (q->type == 1) {
+                               int pool_val =
+                                       (di_buf->type << 8) | (di_buf->index);
+                               for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
+                                       if (q->pool[i] == pool_val) {
+                                               q->num--;
+                                               q->pool[i] = 0;
+                                               di_buf->queue_index = -1;
+                                               break;
+                                       }
+                               }
+                               if (i == MAX_QUEUE_POOL_SIZE) {
+                                       PR_ERR("%s: Error\n", __func__);
+
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(5);
+                               dim_vcry_set_log_q_idx(di_buf->queue_index);
+                               dim_vcry_set_log_di_buf(di_buf);
+                       }
+                                       dim_vcry_flg_inc();
+                               }
+                       } else if (q->type == 2) {
+                               int pool_val =
+                                       (di_buf->type << 8) | (di_buf->index);
+                               if ((di_buf->index < MAX_QUEUE_POOL_SIZE) &&
+                                   (q->pool[di_buf->index] == pool_val)) {
+                                       q->num--;
+                                       q->pool[di_buf->index] = 0;
+                                       di_buf->queue_index = -1;
+                               } else {
+                                       PR_ERR("%s: Error\n", __func__);
+
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(5);
+                       dim_vcry_set_log_q_idx(di_buf->queue_index);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+                                       dim_vcry_flg_inc();
+                               }
+                       }
+               }
+       } else {
+               PR_ERR("%s: Error, queue_index %d is not right\n",
+                      __func__, di_buf->queue_index);
+
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(6);
+                       dim_vcry_set_log_q_idx(0);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+               dim_vcry_flg_inc();
+       }
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s done\n", __func__);
+}
+
+void queue_out_dbg(unsigned int channel, struct di_buf_s *di_buf)
+{
+       int i;
+       queue_t *q;
+       struct queue_s *pqueue = get_queue(channel);
+       enum QUE_TYPE nqtype;/*new que*/
+
+       if (!di_buf) {
+               PR_ERR("%s:Error\n", __func__);
+
+               if (dim_vcry_get_flg() == 0)
+                       dim_vcry_set_log_reason(3);
+
+               dim_vcry_flg_inc();
+               return;
+       }
+       /* ****new que***** */
+       if (di_que_type_2_new(di_buf->queue_index, &nqtype)) {
+               di_que_out(channel, nqtype, di_buf);    /*?*/
+               pr_info("dbg1:nqtype=%d\n", nqtype);
+               return;
+       }
+       /* **************** */
+
+       if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) {
+               q = &pqueue[di_buf->queue_index];
+
+               if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+                       dim_print("%s:<%d:%d,%d,%d> %x\n", __func__,
+                                 di_buf->queue_index, q->num, q->in_idx,
+                                 q->out_idx, di_buf);
+
+               if (q->num > 0) {
+                       if (q->type == 0) {
+                               pr_info("dbg3\n");
+                               if (q->pool[q->out_idx] ==
+                                   ((di_buf->type << 8) | (di_buf->index))) {
+                                       q->num--;
+                                       q->pool[q->out_idx] = 0;
+                                       q->out_idx++;
+                                       if (q->out_idx >= MAX_QUEUE_POOL_SIZE)
+                                               q->out_idx = 0;
+                                       di_buf->queue_index = -1;
+                               } else {
+                                       PR_ERR(
+                                               "%s: Error (%d, %x,%x)\n",
+                                               __func__,
+                                               di_buf->queue_index,
+                                               q->pool[q->out_idx],
+                                               ((di_buf->type << 8) |
+                                               (di_buf->index)));
+
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(4);
+                               dim_vcry_set_log_q_idx(di_buf->queue_index);
+                               dim_vcry_set_log_di_buf(di_buf);
+                       }
+                                       dim_vcry_flg_inc();
+                               }
+                       } else if (q->type == 1) {
+                               int pool_val =
+                                       (di_buf->type << 8) | (di_buf->index);
+                               for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
+                                       if (q->pool[i] == pool_val) {
+                                               q->num--;
+                                               q->pool[i] = 0;
+                                               di_buf->queue_index = -1;
+                                               break;
+                                       }
+                               }
+                               pr_info("dbg2:i=%d,qindex=%d\n", i,
+                                       di_buf->queue_index);
+                               if (i == MAX_QUEUE_POOL_SIZE) {
+                                       PR_ERR("%s: Error\n", __func__);
+
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(5);
+                               dim_vcry_set_log_q_idx(di_buf->queue_index);
+                               dim_vcry_set_log_di_buf(di_buf);
+                       }
+                                       dim_vcry_flg_inc();
+                               }
+                       } else if (q->type == 2) {
+                               int pool_val =
+                                       (di_buf->type << 8) | (di_buf->index);
+
+                               pr_info("dbg4\n");
+                               if ((di_buf->index < MAX_QUEUE_POOL_SIZE) &&
+                                   (q->pool[di_buf->index] == pool_val)) {
+                                       q->num--;
+                                       q->pool[di_buf->index] = 0;
+                                       di_buf->queue_index = -1;
+                               } else {
+                                       PR_ERR("%s: Error\n", __func__);
+
+                                       if (dim_vcry_get_flg() == 0) {
+                                               dim_vcry_set(5,
+                                                       di_buf->queue_index,
+                                                       di_buf);
+                                       }
+                                       dim_vcry_flg_inc();
+                               }
+                       }
+               }
+       } else {
+               PR_ERR("%s: Error, queue_index %d is not right\n",
+                      __func__, di_buf->queue_index);
+
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(6);
+                       dim_vcry_set_log_q_idx(0);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+               dim_vcry_flg_inc();
+       }
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s done\n", __func__);
+}
+
+/***************************************/
+/* set di_buf->queue_index*/
+/***************************************/
+void queue_in(unsigned int channel, struct di_buf_s *di_buf, int queue_idx)
+{
+       queue_t *q = NULL;
+       struct queue_s *pqueue = get_queue(channel);
+       enum QUE_TYPE nqtype;/*new que*/
+
+       if (!di_buf) {
+               PR_ERR("%s:Error\n", __func__);
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(7);
+                       dim_vcry_set_log_q_idx(queue_idx);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+               dim_vcry_flg_inc();
+               return;
+       }
+       /* ****new que***** */
+       if (di_que_type_2_new(queue_idx, &nqtype)) {
+               di_que_in(channel, nqtype, di_buf);
+               return;
+       }
+       /* **************** */
+       if (di_buf->queue_index != -1) {
+               PR_ERR("%s:%s[%d] queue_index(%d) is not -1, to que[%d]\n",
+                      __func__, dim_get_vfm_type_name(di_buf->type),
+                      di_buf->index, di_buf->queue_index, queue_idx);
+               if (dim_vcry_get_flg() == 0) {
+                       dim_vcry_set_log_reason(8);
+                       dim_vcry_set_log_q_idx(queue_idx);
+                       dim_vcry_set_log_di_buf(di_buf);
+               }
+               dim_vcry_flg_inc();
+               return;
+       }
+       q = &pqueue[queue_idx];
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s:<%d:%d,%d,%d> %x\n", __func__, queue_idx,
+                         q->num, q->in_idx, q->out_idx, di_buf);
+
+       if (q->type == 0) {
+               q->pool[q->in_idx] = (di_buf->type << 8) | (di_buf->index);
+               di_buf->queue_index = queue_idx;
+               q->in_idx++;
+               if (q->in_idx >= MAX_QUEUE_POOL_SIZE)
+                       q->in_idx = 0;
+
+               q->num++;
+       } else if (q->type == 1) {
+               int i;
+
+               for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) {
+                       if (q->pool[i] == 0) {
+                               q->pool[i] =
+                                       (di_buf->type << 8) | (di_buf->index);
+                               di_buf->queue_index = queue_idx;
+                               q->num++;
+                               break;
+                       }
+               }
+               if (i == MAX_QUEUE_POOL_SIZE) {
+                       pr_dbg("%s: Error\n", __func__);
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(9);
+                               dim_vcry_set_log_q_idx(queue_idx);
+                       }
+                       dim_vcry_flg_inc();
+               }
+       } else if (q->type == 2) {
+               if ((di_buf->index < MAX_QUEUE_POOL_SIZE) &&
+                   (q->pool[di_buf->index] == 0)) {
+                       q->pool[di_buf->index] =
+                               (di_buf->type << 8) | (di_buf->index);
+                       di_buf->queue_index = queue_idx;
+                       q->num++;
+               } else {
+                       pr_dbg("%s: Error\n", __func__);
+                       if (dim_vcry_get_flg() == 0) {
+                               dim_vcry_set_log_reason(9);
+                               dim_vcry_set_log_q_idx(queue_idx);
+                       }
+                       dim_vcry_flg_inc();
+               }
+       }
+
+       if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE)
+               dim_print("%s done\n", __func__);
+}
+
+int list_count(unsigned int channel, int queue_idx)
+{
+       struct queue_s *pqueue;
+       enum QUE_TYPE nqtype;/*new que*/
+
+       /* ****new que***** */
+       if (di_que_type_2_new(queue_idx, &nqtype)) {
+               PR_ERR("%s:err: over flow\n", __func__);
+               return di_que_list_count(channel, nqtype);
+       }
+       /* **************** */
+
+       pqueue = get_queue(channel);
+       return pqueue[queue_idx].num;
+}
+
+bool queue_empty(unsigned int channel, int queue_idx)
+{
+       struct queue_s *pqueue;
+       bool ret;
+       enum QUE_TYPE nqtype;/*new que*/
+
+       /* ****new que***** */
+       if (di_que_type_2_new(queue_idx, &nqtype)) {
+               PR_ERR("%s:err: over flow\n", __func__);
+               return di_que_is_empty(channel, nqtype);
+       }
+       /* **************** */
+
+       pqueue = get_queue(channel);
+       ret = (pqueue[queue_idx].num == 0);
+
+       return ret;
+}
+
+bool is_in_queue(unsigned int channel, struct di_buf_s *di_buf, int queue_idx)
+{
+       bool ret = 0;
+       struct di_buf_s *p = NULL;
+       int itmp;
+       unsigned int overflow_cnt;
+       enum QUE_TYPE nqtype;/*new que*/
+
+       /* ****new que***** */
+       if (di_que_type_2_new(queue_idx, &nqtype))
+               return di_que_is_in_que(channel, nqtype, di_buf);
+
+       /* **************** */
+
+       overflow_cnt = 0;
+       if (!di_buf || (queue_idx < 0) || (queue_idx >= QUEUE_NUM)) {
+               ret = 0;
+               dim_print("%s: not in queue:%d!!!\n", __func__, queue_idx);
+               return ret;
+       }
+       queue_for_each_entry(p, channel, queue_idx, list) {
+               if (p == di_buf) {
+                       ret = 1;
+                       break;
+               }
+               if (overflow_cnt++ > MAX_QUEUE_POOL_SIZE) {
+                       ret = 0;
+                       dim_print("%s: overflow_cnt!!!\n", __func__);
+                       break;
+               }
+       }
+       return ret;
+}
+
diff --git a/drivers/amlogic/media/di_multi/di_que.h b/drivers/amlogic/media/di_multi/di_que.h
new file mode 100644 (file)
index 0000000..f2f35ab
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * drivers/amlogic/media/di_multi/di_que.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_QUE_H__
+#define __DI_QUE_H__
+
+void queue_init(unsigned int channel, int local_buffer_num);
+void queue_out(unsigned int channel, struct di_buf_s *di_buf);
+void queue_in(unsigned int channel, struct di_buf_s *di_buf,
+             int queue_idx);
+int list_count(unsigned int channel, int queue_idx);
+bool queue_empty(unsigned int channel, int queue_idx);
+bool is_in_queue(unsigned int channel, struct di_buf_s *di_buf,
+                int queue_idx);
+struct di_buf_s *get_di_buf_head(unsigned int channel,
+                                int queue_idx);
+
+void queue_init2(unsigned int channel);
+
+/*new buf:*/
+bool pw_queue_in(unsigned int ch, enum QUE_TYPE qtype,
+                unsigned int buf_index);
+bool pw_queue_out(unsigned int ch, enum QUE_TYPE qtype,
+                 unsigned int *buf_index);
+bool pw_queue_empty(unsigned int ch, enum QUE_TYPE qtype);
+
+/******************************************/
+/*new api*/
+/******************************************/
+union   uDI_QBUF_INDEX {
+       unsigned int d32;
+       struct {
+               unsigned int index:8,   /*low*/
+                            type:8,
+                            reserved0:16;
+       } b;
+};
+
+void di_que_init(unsigned int ch);
+bool di_que_alloc(unsigned int ch);
+void di_que_release(unsigned int ch);
+
+int di_que_is_empty(unsigned int ch, enum QUE_TYPE qtype);
+bool di_que_out(unsigned int ch, enum QUE_TYPE qtype,
+               struct di_buf_s *di_buf);
+
+struct di_buf_s *di_que_out_to_di_buf(unsigned int ch,
+                                     enum QUE_TYPE qtype);
+bool di_que_in(unsigned int ch, enum QUE_TYPE qtype,
+              struct di_buf_s *di_buf);
+bool di_que_is_in_que(unsigned int ch, enum QUE_TYPE qtype,
+                     struct di_buf_s *di_buf);
+struct di_buf_s *di_que_peek(unsigned int ch, enum QUE_TYPE qtype);
+bool di_que_type_2_new(unsigned int q_type, enum QUE_TYPE *nqtype);
+int di_que_list_count(unsigned int ch, enum QUE_TYPE qtype);
+bool di_que_list(unsigned int ch, enum QUE_TYPE qtype,
+                unsigned int *outbuf, unsigned int *rsize);
+
+struct di_buf_s *pw_qindex_2_buf(unsigned int ch, unsigned int qindex);
+
+void queue_out_dbg(unsigned int channel, struct di_buf_s *di_buf);
+#endif /*__DI_QUE_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_reg_tab.c b/drivers/amlogic/media/di_multi/di_reg_tab.c
new file mode 100644 (file)
index 0000000..750f106
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * drivers/amlogic/media/di_multi/di_reg_tab.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+
+#include <linux/amlogic/iomap.h>
+
+#include "deinterlace.h"
+#include "di_data_l.h"
+#include "register.h"
+
+static const struct reg_t rtab_contr[] = {
+       /*--------------------------*/
+       {VD1_AFBCD0_MISC_CTRL, 20, 2, 0, "VD1_AFBCD0_MISC_CTRL",
+               "vd1_go_field_sel",
+               "0: gofile;1: post;2: pre"},
+       {VD1_AFBCD0_MISC_CTRL, 9, 1, 0, "",
+               "afbc0_mux_vpp_mad",
+               "afbc0 to 0:vpp; 1:di"},
+       {VD1_AFBCD0_MISC_CTRL, 8, 1, 0, "",
+               "di_mif0_en",
+               ":mif to 0-vpp;1-di"},
+       /*--------------------------*/
+       {DI_POST_CTRL, 12, 1, 0, "DI_POST_CTRL",
+               "di_post_viu_link",
+               ""},
+       {DI_POST_CTRL, 8, 1, 0, "",
+               "di_vpp_out_en",
+               ""},
+       /*--------------------------*/
+       {VIU_MISC_CTRL0, 20, 1, 0, "VIU_MISC_CTRL0",
+               "?",
+               "?"},
+       {VIU_MISC_CTRL0, 18, 1, 0, "",
+               "Vdin0_wr_out_ctrl",
+               "0: nr_inp to vdin;  1: vdin wr dout"},
+       {VIU_MISC_CTRL0, 17, 1, 0, "",
+               "Afbc_inp_sel",
+               "0: mif to INP; 1: afbc to INP"},
+       {VIU_MISC_CTRL0, 16, 1, 0, "",
+               "di_mif0_en",
+               " vd1(afbc) to di post(if0) enable"},
+       /*--------------------------*/
+       {DI_IF1_GEN_REG, 0, 1, 0, "DI_IF1_GEN_REG",
+               "enable",
+               ""},
+
+       /*--------------------------*/
+       {DI_IF1_GEN_REG3, 8, 2, 0, "DI_IF1_GEN_REG3",
+               "cntl_bits_mode",
+               "0:8bit;1:10bit 422;2:10bit 444"},
+
+       /*--------------------------*/
+       {DI_IF2_GEN_REG3, 8, 2, 0, "DI_IF2_GEN_REG3",
+               "cntl_bits_mode",
+               "0:8bit;1:10bit 422;2:10bit 444"},
+
+       /*--------------------------*/
+       {DI_IF0_GEN_REG3, 8, 2, 0, "DI_IF0_GEN_REG3",
+               "cntl_bits_mode",
+               "0:8bit;1:10bit 422;2:10bit 444"},
+
+       /*--------------------------*/
+       {DI_POST_GL_CTRL, 31, 1, 0, "DI_POST_GL_CTRL",
+               "post count enable",
+               ""},
+       {DI_POST_GL_CTRL, 30, 1, 0, "",
+                       "post count reset",
+                       ""},
+       {DI_POST_GL_CTRL, 16, 14, 0, "",
+                       "total line number for post count",
+                       ""},
+       {DI_POST_GL_CTRL, 0, 14, 0, "",
+                       "the line number of post frame reset",
+                       ""},
+
+       {TABLE_FLG_END, 0, 0, 0, "end", "end", ""},
+
+};
+
+/**********************/
+/* debug register     */
+/**********************/
+static unsigned int get_reg_bits(unsigned int val, unsigned int bstart,
+                                unsigned int bw)
+{
+       return((val &
+              (((1L << bw) - 1) << bstart)) >> (bstart));
+}
+
+static void dbg_reg_tab(struct seq_file *s, const struct reg_t *pRegTab)
+{
+       struct reg_t creg;
+       int i;
+       unsigned int l_add;
+       unsigned int val32 = 1, val;
+       char *bname;
+       char *info;
+
+       i = 0;
+       l_add = 0;
+       creg = pRegTab[i];
+
+       do {
+               if (creg.add != l_add) {
+                       val32 = Rd(creg.add);           /*RD*/
+                       seq_printf(s, "add:0x%x = 0x%08x, %s\n",
+                                  creg.add, val32, creg.name);
+                       l_add = creg.add;
+               }
+               val = get_reg_bits(val32, creg.bit, creg.wid);  /*RD_B*/
+
+               if (creg.bname)
+                       bname = creg.bname;
+               else
+                       bname = "";
+               if (creg.info)
+                       info = creg.info;
+               else
+                       info = "";
+
+               seq_printf(s, "\tbit[%d,%d]:\t0x%x[%d]:\t%s:\t%s\n",
+                          creg.bit, creg.wid, val, val, bname, info);
+
+               i++;
+               creg = pRegTab[i];
+               if (i > TABLE_LEN_MAX) {
+                       pr_info("warn: too long, stop\n");
+                       break;
+               }
+       } while (creg.add != TABLE_FLG_END);
+}
+
+int reg_con_show(struct seq_file *seq, void *v)
+{
+       dbg_reg_tab(seq, &rtab_contr[0]);
+       return 0;
+}
+
+static const struct reg_t rtab_cue_int[] = {
+       /*--------------------------*/
+       {NR2_CUE_CON_DIF0, 0, 32, 0x1400, "NR2_CUE_CON_DIF0",
+                       NULL,
+                       NULL},
+       {NR2_CUE_CON_DIF1, 0, 32, 0x80064, "NR2_CUE_CON_DIF1",
+                       NULL,
+                       NULL},
+       {NR2_CUE_CON_DIF2, 0, 32, 0x80064, "NR2_CUE_CON_DIF2",
+                       NULL,
+                       NULL},
+       {NR2_CUE_CON_DIF3, 0, 32, 0x80a0a, "NR2_CUE_CON_DIF3",
+                       NULL,
+                       NULL},
+       {NR2_CUE_PRG_DIF, 0, 32, 0x80a0a, "NR2_CUE_PRG_DIF",
+                       NULL,
+                       NULL},
+       {TABLE_FLG_END, 0, 0, 0, "end", "end", ""},
+       /*--------------------------*/
+};
+
+/************************************************
+ * register table
+ ************************************************/
+static bool di_g_rtab_cue(const struct reg_t **tab, unsigned int *tabsize)
+{
+       *tab = &rtab_cue_int[0];
+       *tabsize = ARRAY_SIZE(rtab_cue_int);
+
+       return true;
+}
+
+static unsigned int dim_reg_read(unsigned int addr)
+{
+       return aml_read_vcbus(addr);
+}
+
+static const struct reg_acc di_pre_regset = {
+       .wr = dim_DI_Wr,
+       .rd = dim_reg_read,
+       .bwr = dim_RDMA_WR_BITS,
+       .brd = dim_RDMA_RD_BITS,
+};
+
+static bool di_wr_tab(const struct reg_acc *ops,
+                     const struct reg_t *ptab, unsigned int tabsize)
+{
+       int i;
+       const struct reg_t *pl;
+
+       pl = ptab;
+
+       if (!ops        ||
+           !tabsize    ||
+           !ptab)
+               return false;
+
+       for (i = 0; i < tabsize; i++) {
+               if (pl->add == TABLE_FLG_END ||
+                   i > TABLE_LEN_MAX) {
+                       break;
+               }
+
+               if (pl->wid == 32)
+                       ops->wr(pl->add, pl->df_val);
+               else
+                       ops->bwr(pl->add, pl->df_val, pl->bit, pl->wid);
+
+               pl++;
+       }
+
+       return true;
+}
+
+bool dim_wr_cue_int(void)
+{
+       const struct reg_t *ptab;
+       unsigned int tabsize;
+
+       di_g_rtab_cue(&ptab, &tabsize);
+       di_wr_tab(&di_pre_regset,
+                 ptab,
+                 tabsize);
+       PR_INF("%s:finish\n", __func__);
+
+       return true;
+}
+
+int dim_reg_cue_int_show(struct seq_file *seq, void *v)
+{
+       dbg_reg_tab(seq, &rtab_cue_int[0]);
+       return 0;
+}
+
diff --git a/drivers/amlogic/media/di_multi/di_reg_tab.h b/drivers/amlogic/media/di_multi/di_reg_tab.h
new file mode 100644 (file)
index 0000000..215d378
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * drivers/amlogic/media/di_multi/di_reg_tab.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_REG_TABL_H__
+#define __DI_REG_TABL_H__
+
+int reg_con_show(struct seq_file *seq, void *v);
+
+bool dim_wr_cue_int(void);
+int dim_reg_cue_int_show(struct seq_file *seq, void *v);
+
+#endif /*__DI_REG_TABL_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_sys.c b/drivers/amlogic/media/di_multi/di_sys.c
new file mode 100644 (file)
index 0000000..64be055
--- /dev/null
@@ -0,0 +1,754 @@
+/*
+ * drivers/amlogic/media/di_multi/di_sys.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/cdev.h>
+#include <linux/proc_fs.h>
+#include <linux/list.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_irq.h>
+#include <linux/uaccess.h>
+#include <linux/of_fdt.h>
+#include <linux/cma.h>
+#include <linux/dma-contiguous.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/of_device.h>
+
+#include <linux/amlogic/media/vfm/vframe.h>
+
+/*dma_get_cma_size_int_byte*/
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+
+#include "deinterlace_dbg.h"
+#include "deinterlace.h"
+#include "di_data_l.h"
+#include "di_data.h"
+#include "di_dbg.h"
+#include "di_vframe.h"
+#include "di_task.h"
+#include "di_prc.h"
+#include "di_sys.h"
+#include "di_api.h"
+
+#include "register.h"
+#include "nr_downscale.h"
+
+static di_dev_t *di_pdev;
+
+struct di_dev_s *get_dim_de_devp(void)
+{
+       return di_pdev;
+}
+
+unsigned int di_get_dts_nrds_en(void)
+{
+       return get_dim_de_devp()->nrds_enable;
+}
+
+/********************************************
+ * mem
+ *******************************************/
+
+/********************************************/
+static ssize_t
+show_config(struct device *dev,
+           struct device_attribute *attr, char *buf)
+{
+       int pos = 0;
+
+       return pos;
+}
+
+static ssize_t show_tvp_region(struct device *dev,
+                              struct device_attribute *attr, char *buff)
+{
+       ssize_t len = 0;
+       struct di_dev_s *de_devp = get_dim_de_devp();
+
+       len = sprintf(buff, "segment DI:%lx - %lx (size:0x%x)\n",
+                     de_devp->mem_start,
+                     de_devp->mem_start + de_devp->mem_size - 1,
+                     de_devp->mem_size);
+       return len;
+}
+
+static
+ssize_t
+show_log(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return dim_read_log(buf);
+}
+
+static ssize_t
+show_frame_format(struct device *dev,
+                 struct device_attribute *attr, char *buf)
+{
+       int ret = 0;
+       unsigned int channel = get_current_channel();   /*debug only*/
+       struct di_pre_stru_s *ppre = get_pre_stru(channel);
+
+       if (get_init_flag(channel))
+               ret += sprintf(buf + ret, "%s\n",
+                       ppre->cur_prog_flag
+                       ? "progressive" : "interlace");
+
+       else
+               ret += sprintf(buf + ret, "%s\n", "null");
+
+       return ret;
+}
+
+static DEVICE_ATTR(frame_format, 0444, show_frame_format, NULL);
+static DEVICE_ATTR(config, 0640, show_config, store_config);
+static DEVICE_ATTR(debug, 0200, NULL, store_dbg);
+static DEVICE_ATTR(dump_pic, 0200, NULL, store_dump_mem);
+static DEVICE_ATTR(log, 0640, show_log, store_log);
+static DEVICE_ATTR(provider_vframe_status, 0444, show_vframe_status, NULL);
+static DEVICE_ATTR(tvp_region, 0444, show_tvp_region, NULL);
+
+/********************************************/
+static int di_open(struct inode *node, struct file *file)
+{
+       di_dev_t *di_in_devp;
+
+/* Get the per-device structure that contains this cdev */
+       di_in_devp = container_of(node->i_cdev, di_dev_t, cdev);
+       file->private_data = di_in_devp;
+
+       return 0;
+}
+
+static int di_release(struct inode *node, struct file *file)
+{
+/* di_dev_t *di_in_devp = file->private_data; */
+
+/* Reset file pointer */
+
+/* Release some other fields */
+       file->private_data = NULL;
+       return 0;
+}
+
+static long di_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long ret = 0;
+
+       if (_IOC_TYPE(cmd) != _DI_) {
+               PR_ERR("%s invalid command: %u\n", __func__, cmd);
+               return -EFAULT;
+       }
+
+#if 0
+       dbg_reg("no pq\n");
+       return 0;
+#endif
+       switch (cmd) {
+       case AMDI_IOC_SET_PQ_PARM:
+               ret = dim_pq_load_io(arg);
+
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long di_compat_ioctl(struct file *file, unsigned int cmd,
+                           unsigned long arg)
+{
+       unsigned long ret;
+
+       arg = (unsigned long)compat_ptr(arg);
+       ret = di_ioctl(file, cmd, arg);
+       return ret;
+}
+#endif
+
+static const struct file_operations di_fops = {
+       .owner          = THIS_MODULE,
+       .open           = di_open,
+       .release        = di_release,
+       .unlocked_ioctl = di_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = di_compat_ioctl,
+#endif
+};
+
+static int dim_rev_mem(struct di_dev_s *di_devp)
+{
+       unsigned int ch;
+       unsigned int o_size;
+       unsigned long rmstart;
+       unsigned int rmsize;
+       unsigned int flg_map;
+
+       if (di_devp && !di_devp->flag_cma) {
+               dil_get_rev_mem(&rmstart, &rmsize);
+               dil_get_flg(&flg_map);
+               if (!rmstart) {
+                       PR_ERR("%s:reserved mem start add is 0\n", __func__);
+                       return -1;
+               }
+               di_devp->mem_start = rmstart;
+               di_devp->mem_size = rmsize;
+
+               if (!flg_map)
+                       di_devp->flags |= DI_MAP_FLAG;
+
+               o_size = rmsize / DI_CHANNEL_NUB;
+
+               for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+                       di_set_mem_info(ch,
+                                       di_devp->mem_start + (o_size * ch),
+                                       o_size);
+                       PR_INF("rmem:ch[%d]:start:0x%lx, size:%uB\n",
+                              ch,
+                              (di_devp->mem_start + (o_size * ch)),
+                              o_size);
+               }
+               PR_INF("rmem:0x%lx, size %uMB.\n",
+                      di_devp->mem_start, (di_devp->mem_size >> 20));
+
+               di_devp->mem_flg = true;
+               return 0;
+       }
+       PR_INF("%s:no dev or no rev mem\n", __func__);
+       return -1;
+}
+
+bool dim_rev_mem_check(void)/*tmp*/
+{
+       di_dev_t *di_devp = get_dim_de_devp();
+
+       if (di_devp && !di_devp->flag_cma && di_devp->mem_flg)
+               return true;
+
+       if (!di_devp) {
+               PR_ERR("%s:no dev\n", __func__);
+               return false;
+       }
+       PR_INF("%s\n", __func__);
+       dim_rev_mem(di_devp);
+
+       return true;
+}
+
+#define ARY_MATCH (1)
+#ifdef ARY_MATCH
+
+static const struct di_meson_data  data_g12a = {
+       .name = "dim_g12a",
+};
+
+static const struct di_meson_data  data_sm1 = {
+       .name = "dim_sm1",
+};
+
+/* #ifdef CONFIG_USE_OF */
+static const struct of_device_id amlogic_deinterlace_dt_match[] = {
+       /*{ .compatible = "amlogic, deinterlace", },*/
+       {       .compatible = "amlogic, dim-g12a",
+               .data = &data_g12a,
+       }, {    .compatible = "amlogic, dim-g12b",
+               .data = &data_sm1,
+       }, {    .compatible = "amlogic, dim-sm1",
+               .data = &data_sm1,
+       }, {}
+};
+#endif
+static int dim_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct di_dev_s *di_devp = NULL;
+       int i;
+#ifdef ARY_MATCH
+       const struct of_device_id *match;
+       struct di_data_l_s *pdata;
+#endif
+       PR_INF("%s:\n", __func__);
+
+#if 1  /*move from init to here*/
+
+       di_pdev = kzalloc(sizeof(*di_pdev), GFP_KERNEL);
+       if (!di_pdev) {
+               PR_ERR("%s fail to allocate memory.\n", __func__);
+               goto fail_kmalloc_dev;
+       }
+
+       /******************/
+       ret = alloc_chrdev_region(&di_pdev->devno, 0, DI_COUNT, DEVICE_NAME);
+       if (ret < 0) {
+               PR_ERR("%s: failed to allocate major number\n", __func__);
+               goto fail_alloc_cdev_region;
+       }
+       PR_INF("%s: major %d\n", __func__, MAJOR(di_pdev->devno));
+       di_pdev->pclss = class_create(THIS_MODULE, CLASS_NAME);
+       if (IS_ERR(di_pdev->pclss)) {
+               ret = PTR_ERR(di_pdev->pclss);
+               PR_ERR("%s: failed to create class\n", __func__);
+               goto fail_class_create;
+       }
+#endif
+
+       di_devp = di_pdev;
+       /* *********new********* */
+       di_pdev->data_l = NULL;
+       di_pdev->data_l = kzalloc(sizeof(struct di_data_l_s), GFP_KERNEL);
+       if (!di_pdev->data_l) {
+               PR_ERR("%s fail to allocate data l.\n", __func__);
+               goto fail_kmalloc_datal;
+       }
+       /*memset(di_pdev->data_l, 0, sizeof(struct di_data_l_s));*/
+       /*pr_info("\tdata size: %ld\n", sizeof(struct di_data_l_s));*/
+       /************************/
+       if (!dip_prob())
+               goto fail_cdev_add;
+
+       di_devp->flags |= DI_SUSPEND_FLAG;
+       cdev_init(&di_devp->cdev, &di_fops);
+       di_devp->cdev.owner = THIS_MODULE;
+       ret = cdev_add(&di_devp->cdev, di_devp->devno, DI_COUNT);
+       if (ret)
+               goto fail_cdev_add;
+
+       di_devp->devt = MKDEV(MAJOR(di_devp->devno), 0);
+       di_devp->dev = device_create(di_devp->pclss, &pdev->dev,
+               di_devp->devt, di_devp, "di%d", 0);
+
+       if (!di_devp->dev) {
+               pr_error("device_create create error\n");
+               goto fail_cdev_add;
+       }
+       dev_set_drvdata(di_devp->dev, di_devp);
+       platform_set_drvdata(pdev, di_devp);
+
+#ifdef ARY_MATCH
+       /************************/
+       match = of_match_device(amlogic_deinterlace_dt_match,
+                               &pdev->dev);
+       if (!match) {
+               PR_ERR("%s,no matched table\n", __func__);
+               goto fail_cdev_add;
+       }
+       pdata = (struct di_data_l_s *)di_pdev->data_l;
+       pdata->mdata = match->data;
+       PR_INF("match name: %s\n", pdata->mdata->name);
+#endif
+
+       ret = of_reserved_mem_device_init(&pdev->dev);
+       if (ret != 0)
+               PR_INF("no reserved mem.\n");
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "flag_cma", &di_devp->flag_cma);
+       if (ret)
+               PR_ERR("DI-%s: get flag_cma error.\n", __func__);
+       else
+               PR_INF("flag_cma=%d\n", di_devp->flag_cma);
+
+       dim_rev_mem(di_devp);
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "nrds-enable", &di_devp->nrds_enable);
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "pps-enable", &di_devp->pps_enable);
+
+       /*di pre h scaling down :sm1 tm2*/
+       /*pre_hsc_down_en;*/
+       di_devp->h_sc_down_en = di_mp_uit_get(eDI_MP_pre_hsc_down_en);
+
+       if (di_devp->flag_cma >= 1) {
+#ifdef CONFIG_CMA
+               di_devp->pdev = pdev;
+               di_devp->flags |= DI_MAP_FLAG;
+               #if 0
+               di_devp->mem_size = dma_get_cma_size_int_byte(&pdev->dev);
+               #else
+               if (di_devp->flag_cma == 1      ||
+                   di_devp->flag_cma == 2) {
+                       di_devp->mem_size
+                       = dma_get_cma_size_int_byte(&pdev->dev);
+                       PR_INF("mem size from dts:0x%x\n", di_devp->mem_size);
+               }
+
+               if (di_devp->mem_size <= 0x800000) {/*need check??*/
+                       di_devp->mem_size = 0x2800000;
+                       /*(flag_cma ? 3) reserved in*/
+                       /*codec mm : cma in codec mm*/
+                       if (di_devp->flag_cma != 3) {
+                               /*no di cma, try use*/
+                               /*cma from codec mm*/
+                               di_devp->flag_cma = 4;
+                       }
+               }
+               #endif
+               pr_info("DI: CMA size 0x%x.\n", di_devp->mem_size);
+               if (di_devp->flag_cma == 2) {
+                       if (dim_cma_alloc_total(di_devp))
+                               dip_cma_st_set_ready_all();
+               }
+#endif
+       } else {
+                       dip_cma_st_set_ready_all();
+       }
+       /* mutex_init(&di_devp->cma_mutex); */
+       INIT_LIST_HEAD(&di_devp->pq_table_list);
+
+       atomic_set(&di_devp->pq_flag, 0);
+
+       di_devp->pre_irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+       pr_info("pre_irq:%d\n",
+               di_devp->pre_irq);
+       di_devp->post_irq = irq_of_parse_and_map(pdev->dev.of_node, 1);
+       pr_info("post_irq:%d\n",
+               di_devp->post_irq);
+
+       di_pr_info("%s allocate rdma channel %d.\n", __func__,
+                  di_devp->rdma_handle);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
+               dim_get_vpu_clkb(&pdev->dev, di_devp);
+               #ifdef CLK_TREE_SUPPORT
+               clk_prepare_enable(di_devp->vpu_clkb);
+               pr_info("DI:enable vpu clkb.\n");
+               #else
+               aml_write_hiubus(HHI_VPU_CLKB_CNTL, 0x1000100);
+               #endif
+       }
+       di_devp->flags &= (~DI_SUSPEND_FLAG);
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "buffer-size", &di_devp->buffer_size);
+       if (ret)
+               PR_ERR("DI-%s: get buffer size error.\n", __func__);
+
+       /* set flag to indicate that post_wr is supportted */
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "post-wr-support",
+                                  &di_devp->post_wr_support);
+       if (ret)
+               dimp_set(eDI_MP_post_wr_support, 0);/*post_wr_support = 0;*/
+       else    /*post_wr_support = di_devp->post_wr_support;*/
+               dimp_set(eDI_MP_post_wr_support, di_devp->post_wr_support);
+
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "nr10bit-support",
+                                  &di_devp->nr10bit_support);
+       if (ret)
+               dimp_set(eDI_MP_nr10bit_support, 0);/*nr10bit_support = 0;*/
+       else    /*nr10bit_support = di_devp->nr10bit_support;*/
+               dimp_set(eDI_MP_nr10bit_support, di_devp->nr10bit_support);
+
+#ifdef DI_USE_FIXED_CANVAS_IDX
+       if (dim_get_canvas()) {
+               pr_dbg("DI get canvas error.\n");
+               ret = -EEXIST;
+               return ret;
+       }
+#endif
+
+       device_create_file(di_devp->dev, &dev_attr_config);
+       device_create_file(di_devp->dev, &dev_attr_debug);
+       device_create_file(di_devp->dev, &dev_attr_dump_pic);
+       device_create_file(di_devp->dev, &dev_attr_log);
+       device_create_file(di_devp->dev, &dev_attr_provider_vframe_status);
+       device_create_file(di_devp->dev, &dev_attr_frame_format);
+       device_create_file(di_devp->dev, &dev_attr_tvp_region);
+
+       /*pd_device_files_add*/
+       get_ops_pd()->prob(di_devp->dev);
+
+       get_ops_nr()->nr_drv_init(di_devp->dev);
+
+       for (i = 0; i < DI_CHANNEL_NUB; i++) {
+               set_init_flag(i, false);
+               set_reg_flag(i, false);
+       }
+
+       set_or_act_flag(true);
+       /*PR_INF("\t 11\n");*/
+       ret = devm_request_irq(&pdev->dev, di_devp->pre_irq, &dim_irq,
+                              IRQF_SHARED,
+                              "pre_di", (void *)"pre_di");
+       if (di_devp->post_wr_support) {
+               ret = devm_request_irq(&pdev->dev, di_devp->post_irq,
+                                      &dim_post_irq,
+                                      IRQF_SHARED, "post_di",
+                                      (void *)"post_di");
+       }
+
+       di_devp->sema_flg = 1;  /*di_sema_init_flag = 1;*/
+       dimh_hw_init(dimp_get(eDI_MP_pulldown_enable),
+                    dimp_get(eDI_MP_mcpre_en));
+
+       dim_set_di_flag();
+
+       task_start();
+
+       post_mif_sw(false);
+
+       dim_debugfs_init();     /*2018-07-18 add debugfs*/
+
+       dimh_patch_post_update_mc_sw(DI_MC_SW_IC, true);
+
+       pr_info("%s:ok\n", __func__);
+       return ret;
+
+fail_cdev_add:
+       pr_info("%s:fail_cdev_add\n", __func__);
+       kfree(di_devp->data_l);
+
+fail_kmalloc_datal:
+       pr_info("%s:fail_kmalloc datal\n", __func__);
+
+#if 1  /*move from init*/
+/*fail_pdrv_register:*/
+       class_destroy(di_pdev->pclss);
+fail_class_create:
+       unregister_chrdev_region(di_pdev->devno, DI_COUNT);
+fail_alloc_cdev_region:
+       kfree(di_pdev);
+fail_kmalloc_dev:
+
+       return ret;
+#endif
+       return ret;
+}
+
+static int dim_remove(struct platform_device *pdev)
+{
+       struct di_dev_s *di_devp = NULL;
+
+       PR_INF("%s:\n", __func__);
+       di_devp = platform_get_drvdata(pdev);
+
+       dimh_hw_uninit();
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
+               clk_disable_unprepare(di_devp->vpu_clkb);
+
+       di_devp->di_event = 0xff;
+
+       dim_uninit_buf(1, 0);/*channel 0*/
+       di_set_flg_hw_int(false);
+
+       task_stop();
+
+       dim_rdma_exit();
+
+/* Remove the cdev */
+       device_remove_file(di_devp->dev, &dev_attr_config);
+       device_remove_file(di_devp->dev, &dev_attr_debug);
+       device_remove_file(di_devp->dev, &dev_attr_log);
+       device_remove_file(di_devp->dev, &dev_attr_dump_pic);
+       device_remove_file(di_devp->dev, &dev_attr_provider_vframe_status);
+       device_remove_file(di_devp->dev, &dev_attr_frame_format);
+       device_remove_file(di_devp->dev, &dev_attr_tvp_region);
+       /*pd_device_files_del*/
+       get_ops_pd()->remove(di_devp->dev);
+       get_ops_nr()->nr_drv_uninit(di_devp->dev);
+       cdev_del(&di_devp->cdev);
+
+       if (di_devp->flag_cma == 2) {
+               if (dma_release_from_contiguous(&pdev->dev,
+                                               di_devp->total_pages,
+                               di_devp->mem_size >> PAGE_SHIFT)) {
+                       di_devp->total_pages = NULL;
+                       di_devp->mem_start = 0;
+                       pr_dbg("DI CMA total release ok.\n");
+               } else {
+                       pr_dbg("DI CMA total release fail.\n");
+               }
+               if (di_pdev->nrds_enable) {
+                       dim_nr_ds_buf_uninit(di_pdev->flag_cma,
+                                            &pdev->dev);
+               }
+       }
+       device_destroy(di_devp->pclss, di_devp->devno);
+
+/* free drvdata */
+
+       dev_set_drvdata(&pdev->dev, NULL);
+       platform_set_drvdata(pdev, NULL);
+
+#if 1  /*move to remove*/
+       class_destroy(di_pdev->pclss);
+
+       dim_debugfs_exit();
+
+       dip_exit();
+       unregister_chrdev_region(di_pdev->devno, DI_COUNT);
+#endif
+
+       kfree(di_devp->data_l);
+       kfree(di_pdev);
+
+       PR_INF("%s:finish\n", __func__);
+       return 0;
+}
+
+static void dim_shutdown(struct platform_device *pdev)
+{
+       struct di_dev_s *di_devp = NULL;
+       int i;
+
+       di_devp = platform_get_drvdata(pdev);
+
+       for (i = 0; i < DI_CHANNEL_NUB; i++)
+               set_init_flag(i, false);
+
+       if (is_meson_txlx_cpu())
+               dim_top_gate_control(true, true);
+       else
+               dim_DI_Wr(DI_CLKG_CTRL, 0x2);
+
+       if (!is_meson_txlx_cpu())
+               diext_clk_b_sw(false);
+
+       PR_INF("%s.\n", __func__);
+}
+
+#ifdef CONFIG_PM
+
+static void di_clear_for_suspend(struct di_dev_s *di_devp)
+{
+       unsigned int channel = get_current_channel();   /*tmp*/
+
+       pr_info("%s\n", __func__);
+
+       di_vframe_unreg(channel);/*have flag*/
+
+       if (dip_chst_get(channel) != eDI_TOP_STATE_IDLE)
+               dim_unreg_process_irq(channel);
+
+       dip_cma_close();
+       pr_info("%s end\n", __func__);
+}
+
+/* must called after lcd */
+static int di_suspend(struct device *dev)
+{
+       struct di_dev_s *di_devp = NULL;
+
+       di_devp = dev_get_drvdata(dev);
+       di_devp->flags |= DI_SUSPEND_FLAG;
+
+       di_clear_for_suspend(di_devp);
+
+       if (!is_meson_txlx_cpu())
+               diext_clk_b_sw(false);
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD))
+               clk_disable_unprepare(di_devp->vpu_clkb);
+       PR_INF("%s\n", __func__);
+       return 0;
+}
+
+/* must called before lcd */
+static int di_resume(struct device *dev)
+{
+       struct di_dev_s *di_devp = NULL;
+
+       PR_INF("%s\n", __func__);
+       di_devp = dev_get_drvdata(dev);
+
+       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL))
+               clk_prepare_enable(di_devp->vpu_clkb);
+
+       di_devp->flags &= ~DI_SUSPEND_FLAG;
+
+       /************/
+       PR_INF("%s finish\n", __func__);
+       return 0;
+}
+
+static const struct dev_pm_ops di_pm_ops = {
+       .suspend_late = di_suspend,
+       .resume_early = di_resume,
+};
+#endif
+#ifndef ARY_MATCH
+/* #ifdef CONFIG_USE_OF */
+static const struct of_device_id amlogic_deinterlace_dt_match[] = {
+       /*{ .compatible = "amlogic, deinterlace", },*/
+       { .compatible = "amlogic, dim-g12a", },
+       {}
+};
+#endif
+/* #else */
+/* #define amlogic_deinterlace_dt_match NULL */
+/* #endif */
+
+static struct platform_driver di_driver = {
+       .probe                  = dim_probe,
+       .remove                 = dim_remove,
+       .shutdown               = dim_shutdown,
+       .driver                 = {
+               .name           = DEVICE_NAME,
+               .owner          = THIS_MODULE,
+               .of_match_table = amlogic_deinterlace_dt_match,
+#ifdef CONFIG_PM
+               .pm                     = &di_pm_ops,
+#endif
+       }
+};
+
+static int __init dim_module_init(void)
+{
+       int ret = 0;
+
+       PR_INF("%s\n", __func__);
+
+       ret = platform_driver_register(&di_driver);
+       if (ret != 0) {
+               PR_ERR("%s: failed to register driver\n", __func__);
+               /*goto fail_pdrv_register;*/
+               return -ENODEV;
+       }
+       PR_INF("%s finish\n", __func__);
+       return 0;
+}
+
+static void __exit dim_module_exit(void)
+{
+       platform_driver_unregister(&di_driver);
+       PR_INF("%s: ok.\n", __func__);
+}
+
+module_init(dim_module_init);
+module_exit(dim_module_exit);
+
+MODULE_DESCRIPTION("AMLOGIC MULTI-DI driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("4.0.0");
+
diff --git a/drivers/amlogic/media/di_multi/di_sys.h b/drivers/amlogic/media/di_multi/di_sys.h
new file mode 100644 (file)
index 0000000..8aec249
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * drivers/amlogic/media/di_multi/di_sys.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_SYS_H__
+#define __DI_SYS_H__
+
+#define DEVICE_NAME            "di_multi"
+#define CLASS_NAME             "deinterlace"
+
+bool dim_rev_mem_check(void);
+
+#endif /*__DI_SYS_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_task.c b/drivers/amlogic/media/di_multi/di_task.c
new file mode 100644 (file)
index 0000000..9912fd4
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * drivers/amlogic/media/di_multi/di_task.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kthread.h>     /*ary add*/
+#include <linux/freezer.h>
+#include <linux/semaphore.h>
+#include <linux/kfifo.h>
+#include <linux/spinlock.h>
+
+#include "deinterlace.h"
+#include "di_data_l.h"
+
+#include "di_prc.h"
+
+#include "di_task.h"
+#include "di_vframe.h"
+
+static void task_wakeup(struct di_task *tsk);
+
+unsigned int di_dbg_task_flg;  /*debug only*/
+
+bool task_send_cmd(unsigned int cmd)
+{
+       struct di_task *tsk = get_task();
+       unsigned int val;
+
+       dbg_reg("%s:cmd[%d]:\n", __func__, cmd);
+       if (kfifo_is_full(&tsk->fifo_cmd)) {
+               if (kfifo_out(&tsk->fifo_cmd, &val, sizeof(unsigned int))
+                   != sizeof(unsigned int)) {
+                       PR_ERR("%s:can't out\n", __func__);
+                       return false;
+               }
+
+               PR_ERR("%s:lost cmd[%d]\n", __func__, val);
+               tsk->err_cmd_cnt++;
+               /*return false;*/
+       }
+       kfifo_in_spinlocked(&tsk->fifo_cmd, &cmd, sizeof(unsigned int),
+                           &tsk->lock_cmd);
+
+       task_wakeup(tsk);
+       return true;
+}
+
+void task_send_ready(void)
+{
+       struct di_task *tsk = get_task();
+
+       task_wakeup(tsk);
+}
+
+#if 0
+bool task_have_vf(unsigned int ch)
+{
+       struct di_task *tsk = get_task();
+
+       task_wakeup(tsk);
+}
+#endif
+bool task_get_cmd(unsigned int *cmd)
+{
+       struct di_task *tsk = get_task();
+       unsigned int val;
+
+       if (kfifo_is_empty(&tsk->fifo_cmd))
+               return false;
+
+       if (kfifo_out(&tsk->fifo_cmd, &val, sizeof(unsigned int))
+               != sizeof(unsigned int))
+               return false;
+
+       *cmd = val;
+       return true;
+}
+
+void task_polling_cmd(void)
+{
+       int i;
+       union DI_L_CMD_BITS cmdbyte;
+
+       for (i = 0; i < MAX_KFIFO_L_CMD_NUB; i++) {
+               if (!task_get_cmd(&cmdbyte.cmd32))
+                       break;
+               dip_chst_process_reg(cmdbyte.b.ch);
+       }
+}
+
+static int task_is_exiting(struct di_task *tsk)
+{
+       if (tsk->exit)
+               return 1;
+
+/*     if (afepriv->dvbdev->writers == 1)
+ *             if (time_after_eq(jiffies, fepriv->release_jiffies +
+ *                               dvb_shutdown_timeout * HZ))
+ *                     return 1;
+ */
+       return 0;
+}
+
+static int task_should_wakeup(struct di_task *tsk)
+{
+       if (tsk->wakeup) {
+               tsk->wakeup = 0;
+               /*dbg only dbg_tsk("wkg[%d]\n", di_dbg_task_flg);*/
+               return 1;
+       }
+       return task_is_exiting(tsk);
+}
+
+static void task_wakeup(struct di_task *tsk)
+{
+       tsk->wakeup = 1;
+       wake_up_interruptible(&tsk->wait_queue);
+       /*dbg_tsk("wks[%d]\n", di_dbg_task_flg);*/
+}
+
+static int di_test_thread(void *data)
+{
+       struct di_task *tsk = data;
+       bool semheld = false;
+
+       tsk->delay = HZ;
+       tsk->status = 0;
+       tsk->wakeup = 0;
+       #if 0
+       tsk->reinitialise = 0;
+       tsk->needfinish = 0;
+       tsk->finishflg = 0;
+       #endif
+       set_freezable();
+       while (1) {
+               up(&tsk->sem);/* is locked when we enter the thread... */
+restart:
+               wait_event_interruptible_timeout(tsk->wait_queue,
+                                                task_should_wakeup(tsk) ||
+                                                kthread_should_stop()   ||
+                                                freezing(current),
+                                                tsk->delay);
+               di_dbg_task_flg = 1;
+
+               if (kthread_should_stop() || task_is_exiting(tsk)) {
+                       /* got signal or quitting */
+                       if (!down_interruptible(&tsk->sem))
+                               semheld = true;
+                       tsk->exit = 1;
+                       break;
+               }
+
+               if (try_to_freeze())
+                       goto restart;
+
+               if (down_interruptible(&tsk->sem))
+                       break;
+#if 0
+               if (tsk->reinitialise) {
+                       /*dvb_frontend_init(fe);*/
+
+                       tsk->reinitialise = 0;
+               }
+#endif
+               di_dbg_task_flg = 2;
+               task_polling_cmd();
+               di_dbg_task_flg = 3;
+               dip_chst_process_ch();
+               di_dbg_task_flg = 4;
+               if (get_reg_flag_all())
+                       dip_hw_process();
+
+               di_dbg_task_flg = 0;
+       }
+
+       tsk->thread = NULL;
+       if (kthread_should_stop())
+               tsk->exit = 1;
+       else
+               tsk->exit = 0;
+       /*mb();*/
+
+       if (semheld)
+               up(&tsk->sem);
+
+       task_wakeup(tsk);/*?*/
+       return 0;
+}
+
+void task_stop(void/*struct di_task *tsk*/)
+{
+       struct di_task *tsk = get_task();
+
+#if 1  /*not use cmd*/
+       pr_info(".");
+       /*--------------------*/
+       /*cmd buf*/
+       if (tsk->flg_cmd) {
+               kfifo_free(&tsk->fifo_cmd);
+               tsk->flg_cmd = 0;
+       }
+       /*tsk->lock_cmd = SPIN_LOCK_UNLOCKED;*/
+       spin_lock_init(&tsk->lock_cmd);
+       tsk->err_cmd_cnt = 0;
+       /*--------------------*/
+#endif
+       tsk->exit = 1;
+       /*mb();*/
+
+       if (!tsk->thread)
+               return;
+
+       kthread_stop(tsk->thread);
+
+       sema_init(&tsk->sem, 1);
+       tsk->status = 0;
+
+       /* paranoia check in case a signal arrived */
+       if (tsk->thread)
+               PR_ERR("warning: thread %p won't exit\n", tsk->thread);
+}
+
+int task_start(void)
+{
+       int ret;
+       int flg_err;
+       struct di_task *tsk = get_task();
+
+       struct task_struct *fe_thread;
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+
+       pr_info(".");
+       flg_err = 0;
+#if 1  /*not use cmd*/
+       /*--------------------*/
+       /*cmd buf*/
+       /*tsk->lock_cmd = SPIN_LOCK_UNLOCKED;*/
+       spin_lock_init(&tsk->lock_cmd);
+       tsk->err_cmd_cnt = 0;
+       ret = kfifo_alloc(&tsk->fifo_cmd,
+                         sizeof(unsigned int) * MAX_KFIFO_L_CMD_NUB,
+                         GFP_KERNEL);
+       if (ret < 0) {
+               tsk->flg_cmd = false;
+               PR_ERR("%s:can't get kfifo\n", __func__);
+               return -1;
+       }
+       tsk->flg_cmd = true;
+
+#endif
+       /*--------------------*/
+       sema_init(&tsk->sem, 1);
+       init_waitqueue_head(&tsk->wait_queue);
+
+       if (tsk->thread) {
+               if (!tsk->exit)
+                       return 0;
+
+               task_stop();
+       }
+
+       if (signal_pending(current)) {
+               if (tsk->flg_cmd) {
+                       kfifo_free(&tsk->fifo_cmd);
+                       tsk->flg_cmd = 0;
+               }
+               return -EINTR;
+       }
+       if (down_interruptible(&tsk->sem)) {
+               if (tsk->flg_cmd) {
+                       kfifo_free(&tsk->fifo_cmd);
+                       tsk->flg_cmd = 0;
+               }
+               return -EINTR;
+       }
+
+       tsk->status = 0;
+       tsk->exit = 0;
+       tsk->thread = NULL;
+       /*mb();*/
+
+       fe_thread = kthread_run(di_test_thread, tsk, "aml-ditest-0");
+       if (IS_ERR(fe_thread)) {
+               ret = PTR_ERR(fe_thread);
+               PR_ERR(" failed to start kthread (%d)\n", ret);
+               up(&tsk->sem);
+               tsk->flg_init = 0;
+               return ret;
+       }
+
+       sched_setscheduler_nocheck(fe_thread, SCHED_FIFO, &param);
+       tsk->flg_init = 1;
+       tsk->thread = fe_thread;
+       return 0;
+}
+
+void dbg_task(void)
+{
+       struct di_task *tsk = get_task();
+
+       tsk->status = 1;
+       task_wakeup(tsk);
+}
diff --git a/drivers/amlogic/media/di_multi/di_task.h b/drivers/amlogic/media/di_multi/di_task.h
new file mode 100644 (file)
index 0000000..15cbced
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * drivers/amlogic/media/di_multi/di_task.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_TASK_H__
+#define __DI_TASK_H__
+
+extern unsigned int di_dbg_task_flg;   /*debug only*/
+
+enum eTSK_STATE {
+       eTSK_STATE_IDLE,
+       eTSK_STATE_WORKING,
+};
+
+void task_stop(void);
+int task_start(void);
+
+void dbg_task(void);
+
+bool task_send_cmd(unsigned int cmd);
+void task_send_ready(void);
+
+#endif /*__DI_TASK_H__*/
diff --git a/drivers/amlogic/media/di_multi/di_vframe.c b/drivers/amlogic/media/di_multi/di_vframe.c
new file mode 100644 (file)
index 0000000..caf2832
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * drivers/amlogic/media/di_multi/di_vframe.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/semaphore.h>
+#include <linux/kfifo.h>
+#include <linux/spinlock.h>
+
+#include "deinterlace.h"
+#include "di_data_l.h"
+#include "di_pre.h"
+#include "di_prc.h"
+#include "di_dbg.h"
+
+#include "di_vframe.h"
+
+struct dev_vfram_t *get_dev_vframe(unsigned int ch)
+{
+       if (ch < DI_CHANNEL_NUB)
+               return &get_datal()->ch_data[ch].vfm;
+
+       pr_info("err:%s ch overflow %d\n", __func__, ch);
+       return &get_datal()->ch_data[0].vfm;
+}
+
+const char * const di_rev_name[4] = {
+       "deinterlace",
+       "dimulti.1",
+       "dimulti.2",
+       "dimulti.3",
+};
+
+void dev_vframe_reg(struct dev_vfram_t *pvfm)
+{
+       if (pvfm->reg) {
+               PR_WARN("duplicate reg\n");
+               return;
+       }
+       vf_reg_provider(&pvfm->di_vf_prov);
+       vf_notify_receiver(pvfm->name, VFRAME_EVENT_PROVIDER_START, NULL);
+       pvfm->reg = 1;
+}
+
+void dev_vframe_unreg(struct dev_vfram_t *pvfm)
+{
+       if (pvfm->reg) {
+               vf_unreg_provider(&pvfm->di_vf_prov);
+               pvfm->reg = 0;
+       } else {
+               PR_WARN("duplicate ureg\n");
+       }
+}
+
+void di_vframe_reg(unsigned int ch)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+
+       dev_vframe_reg(pvfm);
+}
+
+void di_vframe_unreg(unsigned int ch)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+       dev_vframe_unreg(pvfm);
+}
+
+/*--------------------------*/
+
+const char * const di_receiver_event_cmd[] = {
+       "",
+       "_UNREG",
+       "_LIGHT_UNREG",
+       "_START",
+       NULL,   /* "_VFRAME_READY", */
+       NULL,   /* "_QUREY_STATE", */
+       "_RESET",
+       NULL,   /* "_FORCE_BLACKOUT", */
+       "_REG",
+       "_LIGHT_UNREG_RETURN_VFRAME",
+       NULL,   /* "_DPBUF_CONFIG", */
+       NULL,   /* "_QUREY_VDIN2NR", */
+       NULL,   /* "_SET_3D_VFRAME_INTERLEAVE", */
+       NULL,   /* "_FR_HINT", */
+       NULL,   /* "_FR_END_HINT", */
+       NULL,   /* "_QUREY_DISPLAY_INFO", */
+       NULL,   /* "_PROPERTY_CHANGED", */
+};
+
+#define VFRAME_EVENT_PROVIDER_CMD_MAX  16
+
+static int di_receiver_event_fun(int type, void *data, void *arg)
+{
+       struct dev_vfram_t *pvfm;
+       unsigned int ch;
+       int ret = 0;
+
+       ch = *(int *)arg;
+
+       pvfm = get_dev_vframe(ch);
+
+       if (type <= VFRAME_EVENT_PROVIDER_CMD_MAX       &&
+           di_receiver_event_cmd[type]) {
+               dbg_ev("ch[%d]:%s,%d:%s\n", ch, __func__,
+                      type,
+                      di_receiver_event_cmd[type]);
+       }
+
+       switch (type) {
+       case VFRAME_EVENT_PROVIDER_UNREG:
+               ret = di_ori_event_unreg(ch);
+/*             task_send_cmd(LCMD1(eCMD_UNREG, 0));*/
+               break;
+       case VFRAME_EVENT_PROVIDER_REG:
+               /*dev_vframe_reg(pvfm);*/
+               ret = di_ori_event_reg(data, ch);
+/*             task_send_cmd(LCMD1(eCMD_REG, 0));*/
+               break;
+       case VFRAME_EVENT_PROVIDER_START:
+               break;
+
+       case VFRAME_EVENT_PROVIDER_LIGHT_UNREG:
+               ret = di_ori_event_light_unreg(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_VFRAME_READY:
+               ret = di_ori_event_ready(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_QUREY_STATE:
+               ret = di_ori_event_qurey_state(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_RESET:
+               ret = di_ori_event_reset(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME:
+               ret = di_ori_event_light_unreg_revframe(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR:
+               ret = di_ori_event_qurey_vdin2nr(ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE:
+               di_ori_event_set_3D(type, data, ch);
+               break;
+       case VFRAME_EVENT_PROVIDER_FR_HINT:
+       case VFRAME_EVENT_PROVIDER_FR_END_HINT:
+               vf_notify_receiver(pvfm->name, type, data);
+               break;
+
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+static const struct vframe_receiver_op_s di_vf_receiver = {
+       .event_cb       = di_receiver_event_fun
+};
+
+bool vf_type_is_prog(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_TYPEMASK) == 0 ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_interlace(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_INTERLACE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_top(unsigned int type)
+{
+       bool ret = ((type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP)
+               ? true : false;
+       return ret;
+}
+
+bool vf_type_is_bottom(unsigned int type)
+{
+       bool ret = ((type & VIDTYPE_INTERLACE_BOTTOM)
+               == VIDTYPE_INTERLACE_BOTTOM)
+               ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_inter_first(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_INTERLACE_TOP) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_mvc(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_MVC) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_no_video_en(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_NO_VIDEO_ENABLE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_VIU422(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VIU_422) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_VIU_FIELD(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VIU_FIELD) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_VIU_SINGLE(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VIU_SINGLE_PLANE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_VIU444(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VIU_444) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_VIUNV21(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VIU_NV21) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_vscale_dis(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VSCALE_DISABLE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_canvas_toggle(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_CANVAS_TOGGLE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_pre_interlace(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_PRE_INTERLACE) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_highrun(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_HIGHRUN) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_compress(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_COMPRESS) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_pic(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_PIC) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_scatter(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_SCATTER) ? true : false;
+
+       return ret;
+}
+
+bool vf_type_is_vd2(unsigned int type)
+{
+       bool ret = (type & VIDTYPE_VD2) ? true : false;
+
+       return ret;
+}
+
+bool is_bypss_complete(struct dev_vfram_t *pvfm)
+{
+       return pvfm->bypass_complete;
+}
+
+#if 0
+bool is_reg(unsigned int ch)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+
+       return pvfm->reg;
+}
+#endif
+
+void set_bypass_complete(struct dev_vfram_t *pvfm, bool on)
+{
+       if (on)
+               pvfm->bypass_complete = true;
+       else
+               pvfm->bypass_complete = false;
+}
+
+void set_bypass2_complete(unsigned int ch, bool on)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+       set_bypass_complete(pvfm, on);
+}
+
+bool is_bypss2_complete(unsigned int ch)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+
+       return is_bypss_complete(pvfm);
+}
+
+#if 0
+static void set_reg(unsigned int ch, int on)
+{
+       struct dev_vfram_t *pvfm;
+
+       pvfm = get_dev_vframe(ch);
+
+       if (on)
+               pvfm->reg = true;
+       else
+               pvfm->reg = false;
+}
+#endif
+static struct vframe_s *di_vf_peek(void *arg)
+{
+       unsigned int ch = *(int *)arg;
+
+       /*dim_print("%s:ch[%d]\n",__func__,ch);*/
+       if (di_is_pause(ch))
+               return NULL;
+
+       if (is_bypss2_complete(ch))
+               return pw_vf_peek(ch);
+       else
+               return di_vf_l_peek(ch);
+}
+
+static struct vframe_s *di_vf_get(void *arg)
+{
+       unsigned int ch = *(int *)arg;
+       /*struct vframe_s *vfm;*/
+
+       dim_tr_ops.post_get2(5);
+       if (di_is_pause(ch))
+               return NULL;
+
+       di_pause_step_done(ch);
+
+       /*pvfm = get_dev_vframe(ch);*/
+
+       if (is_bypss2_complete(ch))
+       #if 0
+               vfm = pw_vf_peek(ch);
+               if (dim_bypass_detect(ch, vfm))
+                       return NULL;
+
+       #endif
+               return pw_vf_get(ch);
+
+       return di_vf_l_get(ch);
+}
+
+static void di_vf_put(struct vframe_s *vf, void *arg)
+{
+       unsigned int ch = *(int *)arg;
+
+       if (is_bypss2_complete(ch)) {
+               pw_vf_put(vf, ch);
+               pw_vf_notify_provider(ch,
+                                     VFRAME_EVENT_RECEIVER_PUT, NULL);
+               return;
+       }
+
+       di_vf_l_put(vf, ch);
+}
+
+static int di_event_cb(int type, void *data, void *private_data)
+{
+       if (type == VFRAME_EVENT_RECEIVER_FORCE_UNREG) {
+               pr_info("%s: RECEIVER_FORCE_UNREG return\n",
+                       __func__);
+               return 0;
+       }
+       return 0;
+}
+
+static int di_vf_states(struct vframe_states *states, void *arg)
+{
+       unsigned int ch = *(int *)arg;
+
+       if (!states)
+               return -1;
+
+       dim_print("%s:ch[%d]\n", __func__, ch);
+
+       di_vf_l_states(states, ch);
+       return 0;
+}
+
+static const struct vframe_operations_s deinterlace_vf_provider = {
+       .peek           = di_vf_peek,
+       .get            = di_vf_get,
+       .put            = di_vf_put,
+       .event_cb       = di_event_cb,
+       .vf_states      = di_vf_states,
+};
+
+#if 1
+struct vframe_s *pw_vf_get(unsigned int ch)
+{
+       sum_g_inc(ch);
+       return vf_get(di_rev_name[ch]);
+}
+
+struct vframe_s *pw_vf_peek(unsigned int ch)
+{
+       return vf_peek(di_rev_name[ch]);
+}
+
+void pw_vf_put(struct vframe_s *vf, unsigned int ch)
+{
+       sum_p_inc(ch);
+       vf_put(vf, di_rev_name[ch]);
+}
+
+int pw_vf_notify_provider(unsigned int channel, int event_type, void *data)
+{
+       return vf_notify_provider(di_rev_name[channel], event_type, data);
+}
+
+int pw_vf_notify_receiver(unsigned int channel, int event_type, void *data)
+{
+       return vf_notify_receiver(di_rev_name[channel], event_type, data);
+}
+
+void pw_vf_light_unreg_provider(unsigned int ch)
+{
+       struct dev_vfram_t *pvfm;
+       struct vframe_provider_s *prov;
+
+       pvfm = get_dev_vframe(ch);
+
+       prov = &pvfm->di_vf_prov;
+       vf_light_unreg_provider(prov);
+}
+
+#else
+struct vframe_s *pw_vf_get(unsigned int channel)
+{
+       return vf_get(VFM_NAME);
+}
+
+struct vframe_s *pw_vf_peek(unsigned int channel)
+{
+       return vf_peek(VFM_NAME);
+}
+
+void pw_vf_put(struct vframe_s *vf, unsigned int channel)
+{
+       vf_put(vf, VFM_NAME);
+}
+
+int pw_vf_notify_provider(unsigned int channel, int event_type, void *data)
+{
+       return vf_notify_provider(VFM_NAME, event_type, data);
+}
+
+int pw_vf_notify_receiver(unsigned int channel, int event_type, void *data)
+{
+       return vf_notify_receiver(VFM_NAME, event_type, data);
+}
+
+#endif
+
+void dev_vframe_exit(void)
+{
+       struct dev_vfram_t *pvfm;
+       int ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               pvfm = get_dev_vframe(ch);
+               vf_unreg_provider(&pvfm->di_vf_prov);
+               vf_unreg_receiver(&pvfm->di_vf_recv);
+       }
+       pr_info("%s finish\n", __func__);
+}
+
+void dev_vframe_init(void)
+{
+       struct dev_vfram_t *pvfm;
+       int ch;
+
+       for (ch = 0; ch < DI_CHANNEL_NUB; ch++) {
+               pvfm = get_dev_vframe(ch);
+               pvfm->name = di_rev_name[ch];
+               pvfm->indx = ch;
+               /*set_bypass_complete(pvfm, true);*/ /*test only*/
+
+               /*receiver:*/
+               vf_receiver_init(&pvfm->di_vf_recv, pvfm->name,
+                                &di_vf_receiver, &pvfm->indx);
+               vf_reg_receiver(&pvfm->di_vf_recv);
+
+               /*provider:*/
+               vf_provider_init(&pvfm->di_vf_prov, pvfm->name,
+                                &deinterlace_vf_provider, &pvfm->indx);
+       }
+       pr_info("%s finish\n", __func__);
+}
diff --git a/drivers/amlogic/media/di_multi/di_vframe.h b/drivers/amlogic/media/di_multi/di_vframe.h
new file mode 100644 (file)
index 0000000..f5eb0d8
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * drivers/amlogic/media/di_multi/di_vframe.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __DI_VFRAME_H__
+#define __DI_VFRAME_H__
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/vfm/vframe_provider.h>
+#include <linux/amlogic/media/vfm/vframe_receiver.h>
+
+void dev_vframe_init(void);
+void dev_vframe_exit(void);
+void di_vframe_reg(unsigned int ch);
+void di_vframe_unreg(unsigned int ch);
+
+bool vf_type_is_prog(unsigned int type);
+bool vf_type_is_interlace(unsigned int type);
+bool vf_type_is_top(unsigned int type);
+bool vf_type_is_bottom(unsigned int type);
+bool vf_type_is_inter_first(unsigned int type);
+bool vf_type_is_mvc(unsigned int type);
+bool vf_type_is_no_video_en(unsigned int type);
+bool vf_type_is_VIU422(unsigned int type);
+bool vf_type_is_VIU_FIELD(unsigned int type);
+bool vf_type_is_VIU_SINGLE(unsigned int type);
+bool vf_type_is_VIU444(unsigned int type);
+bool vf_type_is_VIUNV21(unsigned int type);
+bool vf_type_is_vscale_dis(unsigned int type);
+bool vf_type_is_canvas_toggle(unsigned int type);
+bool vf_type_is_pre_interlace(unsigned int type);
+bool vf_type_is_highrun(unsigned int type);
+bool vf_type_is_compress(unsigned int type);
+bool vf_type_is_pic(unsigned int type);
+bool vf_type_is_scatter(unsigned int type);
+bool vf_type_is_vd2(unsigned int type);
+
+extern const char * const di_rev_name[4];
+
+struct vframe_s *pw_vf_get(unsigned int ch);
+struct vframe_s *pw_vf_peek(unsigned int ch);
+void pw_vf_put(struct vframe_s *vf, unsigned int ch);
+int pw_vf_notify_provider(unsigned int channel,
+                         int event_type,
+                         void *data);
+int pw_vf_notify_receiver(unsigned int channel,
+                         int event_type,
+                         void *data);
+void pw_vf_light_unreg_provider(unsigned int ch);
+
+void set_bypass2_complete(unsigned int ch, bool on);
+bool is_bypss_complete(struct dev_vfram_t *pvfm);
+bool is_bypss2_complete(unsigned int ch);
+
+#endif /*__DI_VFRAME_H__*/
diff --git a/drivers/amlogic/media/di_multi/dim_trace.h b/drivers/amlogic/media/di_multi/dim_trace.h
new file mode 100644 (file)
index 0000000..59a5c00
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * drivers/amlogic/media/di_multi/dim_trace.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dim
+
+#if !defined(_DIM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _DIM_TRACE_H
+
+#include <linux/tracepoint.h>
+
+/* single lifecycle events */
+DECLARE_EVENT_CLASS(di_event_class,
+       TP_PROTO(const char *name, int field_cnt, unsigned long time),
+       TP_ARGS(name, field_cnt, time),
+       TP_STRUCT__entry(
+               __string(name, name)
+               __field(int, field_cnt)
+               __field(unsigned long, time)
+       ),
+       TP_fast_assign(
+               __assign_str(name, name);
+               __entry->field_cnt = field_cnt;
+               __entry->time = time;
+       ),
+       TP_printk("[%s-%-4dth-%lums]",  __get_str(name),
+                 __entry->field_cnt, __entry->time)
+);
+
+#define DEFINE_DI_EVENT(name) \
+DEFINE_EVENT(di_event_class, name, \
+       TP_PROTO(const char *name, int field_cnt, unsigned long time), \
+       TP_ARGS(name, field_cnt, time))
+
+DEFINE_DI_EVENT(dim_pre);
+DEFINE_DI_EVENT(dim_post);
+/*2019-06-18*/
+DEFINE_DI_EVENT(dim_pre_getxx);
+DEFINE_DI_EVENT(dim_pre_setxx);
+DEFINE_DI_EVENT(dim_pre_ready);
+DEFINE_DI_EVENT(dim_pst_ready);
+DEFINE_DI_EVENT(dim_pst_getxx);
+DEFINE_DI_EVENT(dim_pst_setxx);
+DEFINE_DI_EVENT(dim_pst_irxxx);
+DEFINE_DI_EVENT(dim_pst_doing);
+DEFINE_DI_EVENT(dim_pst_peekx);
+DEFINE_DI_EVENT(dim_pst_get2x);
+
+#endif /* _DIM_TRACE_H */
+
+#if 0
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE deinterlace_trace
+#include <trace/define_trace.h>
+#endif
diff --git a/drivers/amlogic/media/di_multi/nr_downscale.c b/drivers/amlogic/media/di_multi/nr_downscale.c
new file mode 100644 (file)
index 0000000..fc5e561
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * drivers/amlogic/media/di_multi/nr_downscale.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/dma-contiguous.h>
+#include <linux/amlogic/iomap.h>
+#include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include "register.h"
+#include "nr_downscale.h"
+#include "deinterlace.h"
+
+#include "di_data_l.h"
+#include "di_api.h"
+
+static struct nr_ds_s nrds_dev;
+
+static void nr_ds_hw_init(unsigned int width, unsigned int height)
+{
+       unsigned char h_step = 0, v_step = 0;
+       unsigned int width_out, height_out;
+
+       width_out = NR_DS_WIDTH;
+       height_out = NR_DS_HEIGHT;
+
+       h_step = width / width_out;
+       v_step = height / height_out;
+
+       /*Switch MIF to NR_DS*/
+       dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 3, 5, 2);
+       /* config dsbuf_ocol*/
+       dim_RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, width_out, 0, 8);
+       /* config dsbuf_orow*/
+       dim_RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, height_out, 8, 8);
+
+       dim_RDMA_WR_BITS(NRDSWR_X, (width_out - 1), 0, 13);
+       dim_RDMA_WR_BITS(NRDSWR_Y, (height_out - 1), 0, 13);
+
+       dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, (height_out - 1), 0, 13);
+       dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, (width_out - 1), 16, 13);
+       /* little endian */
+       dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, 1, 13, 1);
+
+       dim_RDMA_WR_BITS(NR_DS_CTRL, v_step, 16, 6);
+       dim_RDMA_WR_BITS(NR_DS_CTRL, h_step, 24, 6);
+}
+
+/*
+ * init nr ds buffer
+ */
+void dim_nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start,
+                       struct device *dev)
+{
+       unsigned int i = 0;
+       bool ret;
+       struct dim_mm_s omm;
+
+       if (cma_flag == 0) {
+               nrds_dev.nrds_addr = mem_start;
+       } else {
+               #if 0
+               nrds_dev.nrds_pages = dma_alloc_from_contiguous(dev,
+                       NR_DS_PAGE_NUM, 0);
+               if (nrds_dev.nrds_pages)
+                       nrds_dev.nrds_addr = page_to_phys(nrds_dev.nrds_pages);
+               else
+                       PR_ERR("DI: alloc nr ds mem error.\n");
+               #else
+               ret = dim_mm_alloc(cma_flag, NR_DS_PAGE_NUM, &omm);
+               if (ret) {
+                       nrds_dev.nrds_pages = omm.ppage;
+                       nrds_dev.nrds_addr = omm.addr;
+               } else {
+                       PR_ERR("alloc nr ds mem error.\n");
+               }
+
+               #endif
+       }
+       for (i = 0; i < NR_DS_BUF_NUM; i++)
+               nrds_dev.buf[i] = nrds_dev.nrds_addr + (NR_DS_BUF_SIZE * i);
+       nrds_dev.cur_buf_idx = 0;
+}
+
+void dim_nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev)
+{
+       unsigned int i = 0;
+
+       if (cma_flag == 0) {
+               nrds_dev.nrds_addr = 0;
+       } else {
+               if (nrds_dev.nrds_pages) {
+                       #if 0
+                       dma_release_from_contiguous(dev,
+                                                   nrds_dev.nrds_pages,
+                                                   NR_DS_PAGE_NUM);
+                       #else
+                       dim_mm_release(cma_flag,
+                                      nrds_dev.nrds_pages,
+                                      NR_DS_PAGE_NUM,
+                                      nrds_dev.nrds_addr);
+                       #endif
+                       nrds_dev.nrds_addr = 0;
+                       nrds_dev.nrds_pages = NULL;
+               } else
+                       pr_info("DI: no release nr ds mem.\n");
+       }
+       for (i = 0; i < NR_DS_BUF_NUM; i++)
+               nrds_dev.buf[i] = 0;
+       nrds_dev.cur_buf_idx = 0;
+}
+
+/*
+ * hw config, alloc canvas
+ */
+void dim_nr_ds_init(unsigned int width, unsigned int height)
+{
+       nr_ds_hw_init(width, height);
+       nrds_dev.field_num = 0;
+
+       if (nrds_dev.canvas_idx != 0)
+               return;
+
+       if (ext_ops.canvas_pool_alloc_canvas_table("nr_ds",
+           &nrds_dev.canvas_idx, 1, CANVAS_MAP_TYPE_1)) {
+               PR_ERR("%s alloc nrds canvas error.\n", __func__);
+               return;
+       }
+       pr_info("%s alloc nrds canvas %u.\n",
+               __func__, nrds_dev.canvas_idx);
+}
+
+/*
+ * config nr ds mif, switch buffer
+ */
+void dim_nr_ds_mif_config(void)
+{
+       unsigned long mem_addr = 0;
+
+       mem_addr = nrds_dev.buf[nrds_dev.cur_buf_idx];
+       canvas_config(nrds_dev.canvas_idx, mem_addr,
+                     NR_DS_WIDTH, NR_DS_HEIGHT, 0, 0);
+       dim_RDMA_WR_BITS(NRDSWR_CTRL,
+                        nrds_dev.canvas_idx, 0, 8);
+       dim_nr_ds_hw_ctrl(true);
+}
+
+/*
+ * enable/disable nr ds mif&hw
+ */
+void dim_nr_ds_hw_ctrl(bool enable)
+{
+       /*Switch MIF to NR_DS*/
+       dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, enable ? 3 : 2, 5, 2);
+       dim_RDMA_WR_BITS(NRDSWR_CTRL, enable ? 1 : 0, 12, 1);
+       dim_RDMA_WR_BITS(NR_DS_CTRL, enable ? 1 : 0, 30, 1);
+}
+
+/*
+ * process in irq
+ */
+void dim_nr_ds_irq(void)
+{
+       dim_nr_ds_hw_ctrl(false);
+       nrds_dev.field_num++;
+       nrds_dev.cur_buf_idx++;
+       if (nrds_dev.cur_buf_idx >= NR_DS_BUF_NUM)
+               nrds_dev.cur_buf_idx = 0;
+}
+
+/*
+ * get buf addr&size for dump
+ */
+void dim_get_nr_ds_buf(unsigned long *addr, unsigned long *size)
+{
+       *addr = nrds_dev.nrds_addr;
+       *size = NR_DS_BUF_SIZE;
+       pr_info("%s addr 0x%lx, size 0x%lx.\n",
+               __func__, *addr, *size);
+}
+
+/*
+ * 0x37f9 ~ 0x37fc 0x3740 ~ 0x3743 8 regs
+ */
+void dim_dump_nrds_reg(unsigned int base_addr)
+{
+       unsigned int i = 0x37f9;
+
+       pr_info("-----nrds reg start-----\n");
+       pr_info("[0x%x][0x%x]=0x%x\n",
+               base_addr + (0x2006 << 2), i, dim_RDMA_RD(0x2006));
+       for (i = 0x37f9; i < 0x37fd; i++)
+               pr_info("[0x%x][0x%x]=0x%x\n",
+                       base_addr + (i << 2), i, dim_RDMA_RD(i));
+       for (i = 0x3740; i < 0x3744; i++)
+               pr_info("[0x%x][0x%x]=0x%x\n",
+                       base_addr + (i << 2), i, dim_RDMA_RD(i));
+       pr_info("-----nrds reg end-----\n");
+}
diff --git a/drivers/amlogic/media/di_multi/nr_downscale.h b/drivers/amlogic/media/di_multi/nr_downscale.h
new file mode 100644 (file)
index 0000000..873ce70
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * drivers/amlogic/media/di_multi/nr_downscale.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _NR_DS_H
+#define _NR_DS_H
+
+#define NR_DS_WIDTH    128
+#define NR_DS_HEIGHT   96
+#define NR_DS_BUF_SIZE (96 << 7)
+#define NR_DS_BUF_NUM  6
+#define NR_DS_MEM_SIZE (NR_DS_BUF_SIZE * NR_DS_BUF_NUM)
+#define NR_DS_PAGE_NUM (NR_DS_MEM_SIZE >> PAGE_SHIFT)
+
+struct nr_ds_s {
+       unsigned int field_num;
+       unsigned long nrds_addr;
+       struct page     *nrds_pages;
+       unsigned int canvas_idx;
+       unsigned char cur_buf_idx;
+       unsigned long buf[NR_DS_BUF_NUM];
+};
+
+void dim_nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start,
+                       struct device *dev);
+void dim_nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev);
+void dim_nr_ds_init(unsigned int width, unsigned int height);
+void dim_nr_ds_mif_config(void);
+void dim_nr_ds_hw_ctrl(bool enable);
+void dim_nr_ds_irq(void);
+void dim_get_nr_ds_buf(unsigned long *addr, unsigned long *size);
+void dim_dump_nrds_reg(unsigned int base_addr);
+#endif
diff --git a/drivers/amlogic/media/di_multi/register.h b/drivers/amlogic/media/di_multi/register.h
new file mode 100644 (file)
index 0000000..b05814d
--- /dev/null
@@ -0,0 +1,4416 @@
+/*
+ * drivers/amlogic/media/di_multi/register.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __MACH_DEINTERLACE_REG_ADDR_H_
+#define __MACH_DEINTERLACE_REG_ADDR_H_
+#include <linux/amlogic/iomap.h>
+#include <linux/amlogic/media/registers/regs/di_regs.h>
+#include <linux/amlogic/media/registers/regs/viu_regs.h>
+#include <linux/amlogic/media/registers/regs/vdin_regs.h>
+
+#define Wr(adr, val) aml_write_vcbus(adr, val)
+#define Rd(adr) aml_read_vcbus(adr)
+#define Wr_reg_bits(adr, val, start, len)                      \
+       aml_vcbus_update_bits(adr,                              \
+       ((1 << (len)) - 1) << (start), (val) << (start))
+
+#define Rd_reg_bits(adr, start, len)                           \
+       ((aml_read_vcbus(adr) &                                 \
+       (((1UL << (len)) - 1UL) << (start))) >> (start))
+
+unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val);
+unsigned int dim_RDMA_RD(unsigned int adr);
+unsigned int dim_RDMA_WR_BITS(unsigned int adr, unsigned int val,
+                             unsigned int start, unsigned int len);
+unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start,
+                             unsigned int len);
+void dim_DI_Wr(unsigned int addr, unsigned int val);
+void dim_DI_Wr_reg_bits(unsigned int adr, unsigned int val,
+                       unsigned int start, unsigned int len);
+void dim_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val);
+void dim_VSYNC_WR_MPEG_REG_BITS(unsigned int addr,
+                               unsigned int val,
+                               unsigned int start,
+                               unsigned int len);
+
+#define HHI_VPU_CLKB_CNTL      0x83
+
+#define DI_WRARB_REQEN_SLV_L1C1_OLD    0x2795
+#define DI_RDARB_REQEN_SLV_L1C1_OLD    0x2791
+#define DI_ARB_DBG_STAT_L1C1_OLD               0x27b4
+
+#define VIUB_SW_RESET                                  0x2001
+#define VIUB_SW_RESET0                                 0x2002
+#define VIUB_MISC_CTRL0                                        0x2006
+               /* 0xd0108018 */
+#define VIUB_GCLK_CTRL0                                        0x2007
+#define VIUB_GCLK_CTRL1                                        0x2008
+#define VIUB_GCLK_CTRL2                                        0x2009
+#define VIUB_GCLK_CTRL3                                        0x200a
+/* g12a add debug reg */
+#define DI_DBG_CTRL                                            0x200b
+#define DI_DBG_CTRL1                                   0x200c
+#define DI_DBG_SRDY_INF                                        0x200d
+#define DI_DBG_RRDY_INF                                0x200e
+/* txl add if2 */
+#define DI_IF2_GEN_REG                                 0x2010
+#define DI_IF2_CANVAS0                                 0x2011
+#define DI_IF2_LUMA_X0                                 0x2012
+#define DI_IF2_LUMA_Y0                                 0x2013
+#define DI_IF2_CHROMA_X0                               0x2014
+#define DI_IF2_CHROMA_Y0                               0x2015
+#define DI_IF2_RPT_LOOP                                        0x2016
+#define DI_IF2_LUMA0_RPT_PAT                   0x2017
+#define DI_IF2_CHROMA0_RPT_PAT                 0x2018
+#define DI_IF2_DUMMY_PIXEL                             0x2019
+#define DI_IF2_LUMA_FIFO_SIZE                  0x201a
+#define DI_IF2_RANGE_MAP_Y                             0x201b
+#define DI_IF2_RANGE_MAP_CB                            0x201c
+#define DI_IF2_RANGE_MAP_CR                            0x201d
+#define DI_IF2_GEN_REG2                                        0x201e
+#define DI_IF2_FMT_CTRL                                        0x201f
+#define DI_IF2_FMT_W                                   0x2020
+#define DI_IF2_URGENT_CTRL                             0x2021
+#define DI_IF2_GEN_REG3                                        0x2022
+/*txl new add end*/
+
+/* g12 new added */
+/* IF0 MIF */
+#define DI_IF0_GEN_REG                                 0x2030
+#define DI_IF0_CANVAS0                                 0x2031
+#define DI_IF0_LUMA_X0                                 0x2032
+#define DI_IF0_LUMA_Y0                                 0x2033
+#define DI_IF0_CHROMA_X0                               0x2034
+#define DI_IF0_CHROMA_Y0                               0x2035
+#define DI_IF0_REPEAT_LOOP                             0x2036
+#define DI_IF0_LUMA0_RPT_PAT                   0x2037
+#define DI_IF0_CHROMA0_RPT_PAT                 0x2038
+#define DI_IF0_DUMMY_PIXEL                             0x2039
+#define DI_IF0_LUMA_FIFO_SIZE                  0x203A
+#define DI_IF0_RANGE_MAP_Y                             0x203B
+#define DI_IF0_RANGE_MAP_CB                            0x203C
+#define DI_IF0_RANGE_MAP_CR                            0x203D
+#define DI_IF0_GEN_REG2                                        0x203E
+#define DI_IF0_FMT_CTRL                                        0x203F
+#define DI_IF0_FMT_W                                   0x2040
+#define DI_IF0_FMT_W                                   0x2040
+#define DI_IF0_URGENT_CTRL                             0x2041
+#define DI_IF0_GEN_REG3                                        0x2042
+/* AXI ARB */
+#define DI_RDARB_MODE_L1C1                             0x2050
+#define DI_RDARB_REQEN_SLV_L1C1                        0x2051
+#define DI_RDARB_WEIGH0_SLV_L1C1               0x2052
+#define DI_RDARB_WEIGH1_SLV_L1C1               0x2053
+#define DI_WRARB_MODE_L1C1                             0x2054
+#define DI_WRARB_REQEN_SLV_L1C1                        0x2055
+#define DI_WRARB_WEIGH0_SLV_L1C1               0x2056
+#define DI_WRARB_WEIGH1_SLV_L1C1               0x2057
+#define DI_RDWR_ARB_STATUS_L1C1                        0x2058
+#define DI_ARB_DBG_CTRL_L1C1                   0x2059
+#define DI_ARB_DBG_STAT_L1C1                   0x205a
+#define DI_RDARB_UGT_L1C1                              0x205b
+#define DI_RDARB_LIMT0_L1C1                            0x205c
+#define DI_WRARB_UGT_L1C1                              0x205d
+#define DI_PRE_GL_CTRL                                 0x20ab
+#define DI_PRE_GL_THD                                  0x20ac
+#define DI_POST_GL_CTRL                                        0x20ad
+#define DI_POST_GL_THD                                 0x20ae
+
+#define DI_SUB_RDARB_MODE                              0x37c0
+#define DI_SUB_RDARB_REQEN_SLV                 0x37c1
+#define DI_SUB_RDARB_WEIGH0_SLV                        0x37c2
+#define DI_SUB_RDARB_WEIGH1_SLV                        0x37c3
+#define DI_SUB_RDARB_UGT                               0x37c4
+#define DI_SUB_RDARB_LIMT0                             0x37c5
+#define DI_SUB_WRARB_MODE                              0x37c6
+#define DI_SUB_WRARB_REQEN_SLV                 0x37c7
+#define DI_SUB_WRARB_WEIGH0_SLV                        0x37c8
+#define DI_SUB_WRARB_WEIGH1_SLV                        0x37c9
+#define DI_SUB_WRARB_UGT                               0x37ca
+#define DI_SUB_RDWR_ARB_STATUS                 0x37cb
+#define DI_SUB_ARB_DBG_CTRL                            0x37cc
+#define DI_SUB_ARB_DBG_STAT                            0x37cd
+#define CONTRD_CTRL1                                   0x37d0
+#define CONTRD_CTRL2                                   0x37d1
+#define CONTRD_SCOPE_X                                 0x37d2
+#define CONTRD_SCOPE_Y                                 0x37d3
+#define CONTRD_RO_STAT                                 0x37d4
+#define CONT2RD_CTRL1                                  0x37d5
+#define CONT2RD_CTRL2                                  0x37d6
+#define CONT2RD_SCOPE_X                                        0x37d7
+#define CONT2RD_SCOPE_Y                                        0x37d8
+#define CONT2RD_RO_STAT                                        0x37d9
+#define MTNRD_CTRL1                                            0x37da
+#define MTNRD_CTRL2                                            0x37db
+#define MTNRD_SCOPE_X                                  0x37dc
+#define MTNRD_SCOPE_Y                                  0x37dd
+#define MTNRD_RO_STAT                                  0x37de
+#define MCVECRD_CTRL1                                  0x37df
+#define MCVECRD_CTRL2                                  0x37e0
+#define MCVECRD_SCOPE_X                                        0x37e1
+#define MCVECRD_SCOPE_Y                                        0x37e2
+#define MCVECRD_RO_STAT                                        0x37e3
+#define MCINFRD_CTRL1                                  0x37e4
+#define MCINFRD_CTRL2                                  0x37e5
+#define MCINFRD_SCOPE_X                                        0x37e6
+#define MCINFRD_SCOPE_Y                                        0x37e7
+#define MCINFRD_RO_STAT                                        0x37e8
+#define CONTWR_X                                               0x37e9
+#define CONTWR_Y                                               0x37ea
+#define CONTWR_CTRL                                            0x37eb
+#define CONTWR_CAN_SIZE                                        0x37ec
+#define MTNWR_X                                                        0x37ed
+#define MTNWR_Y                                                        0x37ee
+#define MTNWR_CTRL                                             0x37ef
+#define MTNWR_CAN_SIZE                                 0x37f0
+#define MCVECWR_X                                              0x37f1
+#define MCVECWR_Y                                              0x37f2
+#define MCVECWR_CTRL                                   0x37f3
+#define MCVECWR_CAN_SIZE                               0x37f4
+#define MCINFWR_X                                              0x37f5
+#define MCINFWR_Y                                              0x37f6
+#define MCINFWR_CTRL                                   0x37f7
+#define MCINFWR_CAN_SIZE                               0x37f8
+/* DI SCALE */
+#define DI_SCO_FIFO_CTRL                               0x374e
+#define DI_SC_TOP_CTRL                                 0x374f
+#define DI_SC_DUMMY_DATA                               0x3750
+#define DI_SC_LINE_IN_LENGTH                   0x3751
+#define DI_SC_PIC_IN_HEIGHT                            0x3752
+#define DI_SC_COEF_IDX                                 0x3753
+#define DI_SC_COEF                                             0x3754
+#define DI_VSC_REGION12_STARTP                 0x3755
+#define DI_VSC_REGION34_STARTP                 0x3756
+#define DI_VSC_REGION4_ENDP                            0x3757
+#define DI_VSC_START_PHASE_STEP                        0x3758
+#define DI_VSC_REGION0_PHASE_SLOPE             0x3759
+#define DI_VSC_REGION1_PHASE_SLOPE             0x375a
+#define DI_VSC_REGION3_PHASE_SLOPE             0x375b
+#define DI_VSC_REGION4_PHASE_SLOPE             0x375c
+#define DI_VSC_PHASE_CTRL                              0x375d
+#define DI_VSC_INI_PHASE                               0x375e
+#define DI_HSC_REGION12_STARTP                 0x3760
+#define DI_HSC_REGION34_STARTP                 0x3761
+#define DI_HSC_REGION4_ENDP                            0x3762
+#define DI_HSC_START_PHASE_STEP                        0x3763
+#define DI_HSC_REGION0_PHASE_SLOPE             0x3764
+#define DI_HSC_REGION1_PHASE_SLOPE             0x3765
+#define DI_HSC_REGION3_PHASE_SLOPE             0x3766
+#define DI_HSC_REGION4_PHASE_SLOPE             0x3767
+#define DI_HSC_PHASE_CTRL                              0x3768
+#define DI_SC_MISC                                             0x3769
+#define DI_HSC_PHASE_CTRL1                             0x376a
+#define DI_HSC_INI_PAT_CTRL                            0x376b
+#define DI_SC_GCLK_CTRL                                        0x376c
+#define DI_SC_HOLD_LINE                                        0x376d
+
+/* DI H DOWN SCALER which IC? */
+#define DI_VIU_HSC_WIDTHM1                             0x37b0
+#define DI_VIU_HSC_PHASE_STEP                          0x37b1
+#define DI_VIU_HSC_CTRL                                        0x37b2
+#define DI_VIU_HSC_PHASE_CTRL                          0x37b3
+#define DI_VIU_HSC_COEF                                        0x37b4
+#define DI_VIU_HSC_COEF_IDX                            0x37b5
+
+/* NR DOWNSAMPLE */
+#define NRDSWR_X                                               0x37f9
+#define NRDSWR_Y                                               0x37fa
+#define NRDSWR_CTRL                                            0x37fb
+#define NRDSWR_CAN_SIZE                                        0x37fc
+#define NR_DS_BUF_SIZE_REG                             0x3740
+#define NR_DS_CTRL                                             0x3741
+#define NR_DS_OFFSET                                   0x3742
+#define NR_DS_BLD_COEF                                 0x3743
+/* di */
+#define DI_IF1_URGENT_CTRL                  (0x20a3)  /*  << 2 + 0xd0100000*/
+/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 ,
+ * low threshold  for di inp chroma path
+ * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 ,
+ * low threshold  for di inp luma path
+ */
+#define DI_INP_URGENT_CTRL                  (0x20a4)  /*  << 2 + 0xd0100000*/
+/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 ,
+ * low threshold  for di mem chroma path
+ * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 ,
+ * low threshold  for di mem luma path
+ */
+#define DI_MEM_URGENT_CTRL                  (0x20a5)  /*  << 2 + 0xd0100000*/
+/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 ,
+ * low threshold  for di chan2 chroma path
+ * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 ,
+ * low threshold  for di chan2 luma path
+ */
+#define DI_CHAN2_URGENT_CTRL                (0x20a6)  /*  << 2 + 0xd0100000*/
+
+#define DI_PRE_CTRL                        ((0x1700)) /* << 2) + 0xd0100000) */
+/* bit 31,      cbus_pre_frame_rst */
+/* bit 30,      cbus_pre_soft_rst */
+/* bit 29,      pre_field_num */
+/* bit 27:26,   mode_444c422 */
+/* bit 25,      di_cont_read_en */
+/* bit 24:23,   mode_422c444 */
+/* bit 22,      mtn_after_nr */
+/* bit 21:16,   pre_hold_fifo_lines */
+/* bit 15,      nr_wr_by */
+/* bit 14,      use_vdin_go_line */
+/* bit 13,      di_prevdin_en */
+/* bit 12,      di_pre_viu_link */
+/* bit 11,      di_pre_repeat */       /*ary : g12a: di_chan3_enable*/
+/* bit 10,      di_pre_drop_1st */
+/* bit  9,      di_buf2_en */
+/* bit  8,      di_chan2_en */
+/* bit  7,      prenr_hist_en */
+/* bit  6,      chan2_hist_en */
+/* bit  5,      hist_check_en */
+/* bit  4,      check_after_nr */
+/* bit  3,      check222p_en */
+/* bit  2,      check322p_en */
+/* bit  1,      mtn_en */
+/* bit  0,      nr_en */
+/* #define DI_POST_CTRL                      ((0x1701)) */
+/* bit 31,      cbus_post_frame_rst */
+/* bit 30,      cbus_post_soft_rst */
+/* bit 29,      post_field_num */
+/* bit 21:16,   post_hold_fifo_lines */
+/* bit 13,      prepost_link */
+/* bit 12,      di_post_viu_link */
+/* bit 11,      di_post_repeat */
+/* bit 10,      di_post_drop_1st */
+/* bit  9,      mif0_to_vpp_en */
+/* bit  8,      di_vpp_out_en */
+/* bit  7,      di_wr_bk_en */
+/* bit  6,      di_mux_en */
+/* bit  5,      di_blend_en */
+/* bit  4,      di_mtnp_read_en */
+/* bit  3,      di_mtn_buf_en */
+/* bit  2,      di_ei_en */
+/* bit  1,      di_buf1_en */
+/* bit  0,      di_buf0_en */
+/* #define DI_POST_SIZE                      ((0x1702)) */
+/* bit 28:16,    vsize1post */
+/* bit 12:0,     hsize1post */
+#define DI_PRE_SIZE                       ((0x1703)) /* << 2) + 0xd0100000) */
+/* bit 28:16,    vsize1pre */
+/* bit 12:0,     hsize1pre */
+#define DI_EI_CTRL0                       ((0x1704)) /* << 2) + 0xd0100000) */
+/* bit 23:16,    ei0_filter[2:+]  abs_diff_left>filter &&
+ * ...right>filter && ...top>filter && ...bot>filter -> filter
+ */
+/* bit 15:8,     ei0_threshold[2:+] */
+/* bit 3,        ei0_vertical */
+/* bit 2,        ei0_bpscf2 */
+/* bit 1,        ei0_bpsfar1 */
+#define DI_EI_CTRL1                       ((0x1705)) /* << 2) + 0xd0100000) */
+/* bit 31:24,    ei0_diff */
+/* bit 23:16,    ei0_angle45 */
+/* bit 15:8,     ei0_peak */
+/* bit 7:0,      ei0_cross */
+#define DI_EI_CTRL2                       ((0x1706)) /* << 2) + 0xd0100000) */
+/* bit 31:24,    ei0_close2 */
+/* bit 23:16,    ei0_close1 */
+/* bit 15:8,     ei0_far2 */
+/* bit 7:0,      ei0_far1 */
+#define DI_NR_CTRL0                       ((0x1707)) /* << 2) + 0xd0100000) */
+/* bit 26,       nr_cue_en */
+/* bit 25,       nr2_en */
+#define DI_NR_CTRL1                       ((0x1708)) /* << 2) + 0xd0100000) */
+/* bit 31:30,    mot_p1txtcore_mode */
+/* bit 29:24,    mot_p1txtcore_clmt */
+/* bit 21:16,    mot_p1txtcore_ylmt */
+/* bit 15:8,     mot_p1txtcore_crate */
+/* bit 7:0,      mot_p1txtcore_yrate */
+#define DI_NR_CTRL2                       ((0x1709)) /* << 2) + 0xd0100000) */
+/* bit 29:24,    mot_curtxtcore_clmt */
+/* bit 21:16,    mot_curtxtcore_ylmt */
+/* bit 15:8,     mot_curtxtcore_crate */
+/* bit 7:0,      mot_curtxtcore_yrate */
+/* `define DI_NR_CTRL3               8'h0a */
+/* no use */
+/* `define DI_MTN_CTRL               8'h0b */
+/* no use */
+#define DI_MTN_CTRL1                      ((0x170c)) /* << 2) + 0xd0100000) */
+/* bit 13 ,      me enable */
+/* bit 12 ,      me autoenable */
+/* bit 11:8,           mtn_paramtnthd */
+/* bit 7:0,      mtn_parafltthd */
+#define DI_BLEND_CTRL                     ((0x170d)) /* << 2) + 0xd0100000) */
+/* bit 31,      blend_1_en */
+/* bit 30,      blend_mtn_lpf */
+/* bit 28,      post_mb_en */
+/* bit 27,      blend_mtn3p_max */
+/* bit 26,      blend_mtn3p_min */
+/* bit 25,      blend_mtn3p_ave */
+/* bit 24,      blend_mtn3p_maxtb */
+/* bit 23,      blend_mtn_flt_en */
+/* bit 22,      blend_data_flt_en */
+/* bit 21:20,   blend_top_mode */
+/* bit 19,      blend_reg3_enable */
+/* bit 18,      blend_reg2_enable */
+/* bit 17,      blend_reg1_enable */
+/* bit 16,      blend_reg0_enable */
+/* bit 15:14,   blend_reg3_mode */
+/* bit 13:12,   blend_reg2_mode */
+/* bit 11:10,   blend_reg1_mode */
+/* bit 9:8,     blend_reg0_mode */
+/* bit 7:0,     kdeint */
+/* `define DI_BLEND_CTRL1            8'h0e */
+/* no use */
+/* `define DI_BLEND_CTRL2            8'h0f */
+/* no use */
+#define DI_ARB_CTRL                       ((0x170f)) /* << 2) + 0xd0100000) */
+/* bit 31:26,                  di_arb_thd1 */
+/* bit 25:20,                  di_arb_thd0 */
+/* bit 19,                     di_arb_tid_mode */
+/* bit 18,                     di_arb_arb_mode */
+/* bit 17,                     di_arb_acq_en */
+/* bit 16,                     di_arb_disable_clk */
+/* bit 15:0,                   di_arb_req_en */
+#define DI_BLEND_REG0_X                   ((0x1710)) /* << 2) + 0xd0100000) */
+/* bit 27:16,   blend_reg0_startx */
+/* bit 11:0,    blend_reg0_endx */
+#define DI_BLEND_REG0_Y                   ((0x1711)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG1_X                   ((0x1712)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG1_Y                   ((0x1713)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG2_X                   ((0x1714)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG2_Y                   ((0x1715)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG3_X                   ((0x1716)) /* << 2) + 0xd0100000) */
+#define DI_BLEND_REG3_Y                   ((0x1717)) /* << 2) + 0xd0100000) */
+#define DI_CLKG_CTRL                      ((0x1718)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   pre_gclk_ctrl     no clk gate control. if ==1,
+ * module clk is not gated (always on). [3] for pulldown,[2]
+ * for mtn_1,[1] for mtn_0,[0] for nr
+ * bit 23:16,   post_gclk_ctrl    no clk gate control. [4]
+ * for ei_1, [3] for ei_0,[2] for ei_top, [1] for blend_1, [0] for blend_0
+ * bit 1,       di_gate_all       clk shut down. if ==1 ,
+ * all di clock shut down
+ * bit 0,       di_no_clk_gate    no clk gate control.
+ * if di_gated_all==0 and di_no_clk_gate ==1, all di clock is always working.
+ */
+#define DI_EI_CTRL3                       ((0x1719)) /* << 2) + 0xd0100000) */
+/* bit 31,      reg_ei_1 */
+/* bit 30,      reg_demon_en */
+/* bit 26:24,   reg_demon_mux */
+/* bit 23:20,   reg_right_win */
+/* bit 19:16,   reg_left_win */
+/* bit 7:4,     reg_ei_sadm_quatize_margin */
+/* bit 1:0,     reg_ei_sad_relative_mode */
+#define DI_EI_CTRL4                       ((0x171a)) /* << 2) + 0xd0100000) */
+/* bit 29,      reg_ei_caldrt_ambliike2_biasvertical */
+/* bit 28:24,   reg_ei_caldrt_addxla2list_drtmax */
+/* bit 22:20,   reg_ei_caldrt_addxla2list_signm0th */
+/* bit 19,      reg_ei_caldrt_addxla2list_mode */
+/* bit 18:16,   reg_ei_signm_sad_cor_rate */
+/* bit 15:12,   reg_ei_signm_sadi_cor_rate */
+/* bit 11:6,    reg_ei_signm_sadi_cor_ofst */
+/* bit 5:0,     reg_ei_signm_sad_ofst */
+#define DI_EI_CTRL5                       ((0x171b)) /* << 2) + 0xd0100000) */
+/* bit 30:28,   reg_ei_caldrt_cnflcctchk_frcverthrd */
+/* bit 26:24,   reg_ei_caldrt_cnflctchk_mg */
+/* bit 23:22,   reg_ei_caldrt_cnflctchk_ws */
+/* bit 21,      reg_ei_caldrt_cnflctchk_en */
+/* bit 20,      reg_ei_caldrt_verfrc_final_en */
+/* bit 19,      reg_ei_caldrt_verfrc_retimflt_en */
+/* bit 18:16,   reg_ei_caldrt_verftc_eithratemth */
+/* bit 15,      reg_ei_caldrt_verfrc_retiming_en */
+/* bit 14:12,   reg_ei_caldrt_verfrc_bothratemth */
+/* bit 11:9,    reg_ei_caldrt_ver_thrd */
+/* bit 8:4,     reg_ei_caldrt_addxla2list_drtmin */
+/* bit 3:0,     reg_ei_caldrt_addxla2list_drtlimit */
+#define DI_EI_CTRL6                       ((0x171c)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   reg_ei_caldrt_abext_sad12thhig */
+/* bit 23:16,   reg_ei_caldrt_abext_sad00thlow */
+/* bit 15:8,    reg_ei_caldrt_abext_sad12thlow */
+/* bit 6:4,     reg_ei_caldrt_abext_ratemth */
+/* bit 2:0,     reg_ei_caldrt_abext_drtthrd */
+#define DI_EI_CTRL7                       ((0x171d)) /* << 2) + 0xd0100000) */
+/* bit 29,      reg_ei_caldrt_xlanopeak_codien */
+/* bit 28:24,   reg_ei_caldrt_xlanopeak_drtmax */
+/* bit 23,      reg_ei_caldrt_xlanopeak_en */
+/* bit 28:24,   reg_ei_caldrt_abext_monotrnd_alpha */
+/* bit 28:24,   reg_ei_caldrt_abext_mononum12_thrd */
+/* bit 28:24,   reg_ei_caldrt_abext_mononum00_thrd */
+/* bit 28:24,   reg_ei_caldrt_abext_sad00rate */
+/* bit 28:24,   reg_ei_caldrt_abext_sad12rate */
+/* bit 28:24,   reg_ei_caldrt_abext_sad00thhig */
+#define DI_EI_CTRL8                       ((0x171e)) /* << 2) + 0xd0100000) */
+/* bit 30:28,   reg_ei_assign_headtail_magin */
+/* bit 26:24,   reg_ei_retime_lastcurpncnfltchk_mode */
+/* bit 22:21,   reg_ei_retime_lastcurpncnfltchk_drtth */
+/* bit 20,      reg_ei_caldrt_histchk_cnfid */
+/* bit 19:16,   reg_ei_caldrt_histchk_thrd */
+/* bit 15,      reg_ei_caldrt_histchk_abext */
+/* bit 14,      reg_ei_caldrt_histchk_npen */
+/* bit 13:11,   reg_ei_caldrt_amblike2_drtmg */
+/* bit 10:8,    reg_ei_caldrt_amblike2_valmg */
+/* bit 7:4,     reg_ei_caldrt_amblike2_alpha */
+/* bit 3:0,     reg_ei_caldrt_amblike2_drtth */
+#define DI_EI_CTRL9                       ((0x171f)) /* << 2) + 0xd0100000) */
+/* bit 31:28,   reg_ei_caldrt_hcnfcheck_frcvert_xla_th3 */
+/* bit 27,      reg_ei_caldrt_hcnfcheck_frcvert_xla_en */
+/* bit 26:24,   reg_ei_caldrt_conf_drtth */
+/* bit 23:20,   reg_ei_caldrt_conf_absdrtth */
+/* bit 19:18,   reg_ei_caldrt_abcheck_mode1 */
+/* bit 17:16,   reg_ei_caldrt_abcheck_mode0 */
+/* bit 15:12,   reg_ei_caldrt_abcheck_drth1 */
+/* bit 11:8,    reg_ei_caldrt_abcheck_drth0 */
+/* bit 6:4,     reg_ei_caldrt_abpnchk1_th */
+/* bit 1,       reg_ei_caldrt_abpnchk1_en */
+/* bit 0,       reg_ei_caldrt_abpnchk0_en */
+#define DI_EI_CTRL10                      ((0x1793)) /* << 2) + 0xd0100000) */
+/* bit 31:28,   reg_ei_caldrt_hstrrgchk_drtth */
+/* bit 27:24,   reg_ei_caldrt_hstrrgchk_frcverthrd */
+/* bit 23:20,   reg_ei_caldrt_hstrrgchk_mg */
+/* bit 19,      reg_ei_caldrt_hstrrgchk_1sidnul */
+/* bit 18,      reg_ei_caldrt_hstrrgchk_excpcnf */
+/* bit 17:16,   reg_ei_caldrt_hstrrgchk_ws */
+/* bit 15,      reg_ei_caldrt_hstrrgchk_en */
+/* bit 14:13,   reg_ei_caldrt_hpncheck_mode */
+/* bit 12,      reg_ei_caldrt_hpncheck_mute */
+/* bit 11:9,    reg_ei_caldrt_hcnfcheck_mg2 */
+/* bit 8:6,     reg_ei_caldrt_hcnfcheck_mg1 */
+/* bit 5:4,     reg_ei_caldrt_hcnfcheck_mode */
+/* bit 3:0,     reg_ei_caldrt_hcnfcheck_mg2 */
+#define DI_EI_CTRL11                      ((0x179e)) /* << 2) + 0xd0100000) */
+/* bit 30:29,   reg_ei_amb_detect_mode */
+/* bit 28:24,   reg_ei_amb_detect_winth */
+/* bit 23:21,   reg_ei_amb_decide_rppth */
+/* bit 20:19,   reg_ei_retime_lastmappncnfltchk_drtth */
+/* bit 18:16,   reg_ei_retime_lastmappncnfltchk_mode */
+/* bit 15:14,   reg_ei_retime_lastmapvertfrcchk_mode */
+/* bit 13:12,   reg_ei_retime_lastvertfrcchk_mode */
+/* bit 11:8,    reg_ei_retime_lastpnchk_drtth */
+/* bit 6,       reg_ei_retime_lastpnchk_en */
+/* bit 5:4,     reg_ei_retime_mode */
+/* bit 3,       reg_ei_retime_last_en */
+/* bit 2,       reg_ei_retime_ab_en */
+/* bit 1,       reg_ei_caldrt_hstrvertfrcchk_en */
+/* bit 0,       reg_ei_caldrt_hstrrgchk_mode */
+#define DI_EI_CTRL12                      ((0x179f)) /* << 2) + 0xd0100000) */
+/* bit 31:28,   reg_ei_drtdelay2_lmt */
+/* bit 27:26,   reg_ei_drtdelay2_notver_lrwin */
+/* bit 25:24,   reg_ei_drtdelay_mode */
+/* bit 23,      reg_ei_drtdelay2_mode */
+/* bit 22:20,   reg_ei_assign_xla_signm0th */
+/* bit 19,      reg_ei_assign_pkbiasvert_en */
+/* bit 18,      reg_ei_assign_xla_en */
+/* bit 17:16,   reg_ei_assign_xla_mode */
+/* bit 15:12,   reg_ei_assign_nlfilter_magin */
+/* bit 11:8,    reg_ei_localsearch_maxrange */
+/* bit 7:4,     reg_ei_xla_drtth */
+/* bit 3:0,     reg_ei_flatmsad_thrd */
+#define DI_EI_CTRL13                      ((0x17a8)) /* << 2) + 0xd0100000) */
+/* bit 27:24,   reg_ei_int_drt2x_chrdrt_limit */
+/* bit 23:20,   reg_ei_int_drt16x_core */
+/* bit 19:16,   reg_ei_int_drtdelay2_notver_cancv */
+/* bit 15:8,    reg_ei_int_drtdelay2_notver_sadth */
+/* bit 7:0,     reg_ei_int_drtdelay2_vlddrt_sadth */
+#define DI_EI_XWIN0                       ((0x1798)) /* << 2) + 0xd0100000) */
+/* bit 27:16,   ei_xend0 */
+/* bit 11:0,    ei_xstart0 */
+#define DI_EI_XWIN1                       ((0x1799)) /* << 2) + 0xd0100000) */
+/* DEINTERLACE mode check. */
+#define DI_MC_REG0_X                      ((0x1720)) /* << 2) + 0xd0100000) */
+/* bit 27:16,   mc_reg0_start_x */
+/* bit 11:0,    mc_reg0_end_x */
+#define DI_MC_REG0_Y                      ((0x1721)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG1_X                      ((0x1722)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG1_Y                      ((0x1723)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG2_X                      ((0x1724)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG2_Y                      ((0x1725)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG3_X                      ((0x1726)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG3_Y                      ((0x1727)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG4_X                      ((0x1728)) /* << 2) + 0xd0100000) */
+#define DI_MC_REG4_Y                      ((0x1729)) /* << 2) + 0xd0100000) */
+#define DI_MC_32LVL0                      ((0x172a)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mc_reg2_32lvl */
+/* bit 23:16,   mc_reg1_32lvl */
+/* bit 15:8,    mc_reg0_32lvl */
+/* bit 7:0,     field_32lvl */
+#define DI_MC_32LVL1                      ((0x172b)) /* << 2) + 0xd0100000) */
+/* bit 15:8,    mc_reg3_32lvl */
+/* bit 7:0,     mc_reg4_32lvl */
+#define DI_MC_22LVL0                      ((0x172c)) /* << 2) + 0xd0100000) */
+/* bit 31:16,   mc_reg0_22lvl */
+/* bit 15:0,    field_22lvl */
+#define DI_MC_22LVL1                      ((0x172d)) /* << 2) + 0xd0100000) */
+/* bit 31:16,   mc_reg2_22lvl */
+/* bit 15:0,    mc_reg1_22lvl */
+#define DI_MC_22LVL2                      ((0x172e)) /* << 2) + 0xd0100000) */
+/* bit 31:16,   mc_reg4_22lvl */
+/* bit 15:0,    mc_reg3_22lvl */
+#define DI_MC_CTRL                        ((0x172f)) /* << 2) + 0xd0100000) */
+/* bit 4,       mc_reg4_en */
+/* bit 3,       mc_reg3_en */
+/* bit 2,       mc_reg2_en */
+/* bit 1,       mc_reg1_en */
+/* bit 0,       mc_reg0_en */
+#define DI_INTR_CTRL                      ((0x1730)) /* << 2) + 0xd0100000) */
+#define DI_INFO_ADDR                      ((0x1731)) /* << 2) + 0xd0100000) */
+#define DI_INFO_DATA                      ((0x1732)) /* << 2) + 0xd0100000) */
+#define DI_PRE_HOLD                       ((0x1733)) /* << 2) + 0xd0100000) */
+#define DI_MTN_1_CTRL1                    ((0x1740)) /* << 2) + 0xd0100000) */
+/* bit 31,      mtn_1_en */
+/* bit 30,      mtn_init */
+/* bit 29,      di2nr_txt_en */
+/* bit 28,      di2nr_txt_mode */
+/* bit 27:24,   mtn_def */
+/* bit 23:16,   mtn_adp_yc */
+/* bit 15:8,    mtn_adp_2c */
+/* bit 7:0,     mtn_adp_2y */
+#define DI_MTN_1_CTRL2                    ((0x1741)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_ykinter */
+/* bit 23:16,   mtn_ckinter */
+/* bit 15:8,    mtn_ykintra */
+/* bit  7:0,    mtn_ckintra */
+#define DI_MTN_1_CTRL3                    ((0x1742)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_tyrate */
+/* bit 23:16,   mtn_tcrate */
+/* bit 15: 8,   mtn_mxcmby */
+/* bit  7: 0,   mtn_mxcmbc */
+#define DI_MTN_1_CTRL4                    ((0x1743)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_tcorey */
+/* bit 23:16,   mtn_tcorec */
+/* bit 15: 8,   mtn_minth */
+/* bit  7: 0,   mtn_maxth */
+#define DI_MTN_1_CTRL5                    ((0x1744)) /* << 2) + 0xd0100000) */
+/* bit 31:28,   mtn_m1b_extnd */
+/* bit 27:24,   mtn_m1b_errod */
+/* bit 19:18,   mtn_replace_cbyy */
+/* bit 17:16,   mtn_replace_ybyc */
+/* bit 15: 8,   mtn_core_ykinter */
+/* bit  7: 0,   mtn_core_ckinter */
+#define DI_MTN_1_CTRL6                    ((0x17a9)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_m1b_extnd */
+/* bit 23:16,   mtn_m1b_errod */
+/* bit 15: 8,   mtn_core_ykinter */
+/* bit  7: 0,   mtn_core_ckinter */
+#define DI_MTN_1_CTRL7                    ((0x17aa)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_core_mxcmby */
+/* bit 23:16,   mtn_core_mxcmbc */
+/* bit 15: 8,   mtn_core_y */
+/* bit  7: 0,   mtn_core_c */
+#define DI_MTN_1_CTRL8                    ((0x17ab)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_fcore_ykinter */
+/* bit 23:16,   mtn_fcore_ckinter */
+/* bit 15: 8,   mtn_fcore_ykintra */
+/* bit  7: 0,   mtn_fcore_ckintra */
+#define DI_MTN_1_CTRL9                    ((0x17ac)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_fcore_2yrate */
+/* bit 23:16,   mtn_fcore_2crate */
+/* bit 15: 8,   mtn_fcore_y */
+/* bit  7: 0,   mtn_fcore_c */
+#define DI_MTN_1_CTRL10                   ((0x17ad)) /* << 2) + 0xd0100000) */
+/* bit 27:24,   mtn_motfld0 */
+/* bit 19:16,   mtn_stlfld0 */
+/* bit 11: 8,   mtn_motfld1 */
+/* bit  3: 0,   mtn_stlfld1 */
+#define DI_MTN_1_CTRL11                   ((0x17ae)) /* << 2) + 0xd0100000) */
+/* bit 27:24,   mtn_smotevn */
+/* bit 20:16,   mtn_smotodd */
+/* bit 11: 8,   mtn_sstlevn */
+/* bit  4: 0,   mtn_sstlodd */
+#define DI_MTN_1_CTRL12                   ((0x17af)) /* << 2) + 0xd0100000) */
+/* bit 31:24,   mtn_mgain */
+/* bit 17:16,   mtn_mmode */
+/* bit 15: 8,   mtn_sthrd */
+/* bit  4: 0,   mtn_sgain */
+/* // DET 3D REG DEFINE BEGIN //// */
+/* // 8'h34~8'h3f */
+#define DET3D_MOTN_CFG                    ((0x1734)) /* << 2) + 0xd0100000) */
+/* Bit 16,     reg_det3d_intr_en               Det3d interrupt enable
+ * Bit 9:8,    reg_Det3D_Motion_Mode
+ * U2  Different mode for Motion Calculation of Luma and Chroma:
+ *             0: MotY, 1: (2*MotY + (MotU + MotV))/4;
+ *             2: Max(MotY, MotU,MotV); 3:Max(MotY, (MotU+MotV)/2)
+ * Bit 7:4,    reg_Det3D_Motion_Core_Rate      U4  K Rate to Edge (HV) details
+ * for coring of Motion Calculations, normalized to 32
+ * Bit 3:0,    reg_Det3D_Motion_Core_Thrd
+ * U4  2X: static coring value for Motion Detection.
+ */
+#define DET3D_CB_CFG                      ((0x1735)) /* << 2) + 0xd0100000) */
+/* Bit 7:4,    reg_Det3D_ChessBd_NHV_ofst
+ * U4,  Noise immune offset for NON-Horizotnal or vertical combing detection.
+ *
+ * Bit 3:0,    reg_Det3D_ChessBd_HV_ofst
+ * U4,  Noise immune offset for Horizotnal or vertical combing detection.
+ */
+#define DET3D_SPLT_CFG                    ((0x1736)) /* << 2) + 0xd0100000) */
+/* Bit 7:4,    reg_Det3D_SplitValid_ratio
+ * U4,  Ratio between max_value and the avg_value of
+ * the edge mapping for split line valid detection.
+ * The smaller of this value, the easier of the split line detected.
+ * Bit 3:0,    reg_Det3D_AvgIdx_ratio      U4,Ratio to the avg_value of the
+ * edge mapping for split line position estimation.
+ */
+/* The smaller of this value,
+ * the more samples will be added to the estimation.
+ */
+#define DET3D_HV_MUTE                     ((0x1737)) /* << 2) + 0xd0100000) */
+/* Bit 23:20, reg_Det3D_Edge_Ver_Mute  U4  X2: Horizontal pixels to be mute
+ * from H/V Edge calculation Top and Bottom border part.
+ * Bit 19:16, reg_Det3D_Edge_Hor_Mute  U4  X2: Horizontal pixels to be mute
+ * from H/V Edge calculation Left and right border part.
+ * Bit 15:12, reg_Det3D_ChessBd_Ver_Mute       U4  X2: Horizontal pixels to
+ * be mute from ChessBoard statistics calculation in middle part
+ * Bit 11:8,    reg_Det3D_ChessBd_Hor_Mute     U4  X2: Horizontal pixels to
+ * be mute from ChessBoard statistics calculation in middle part
+ * Bit 7:4,     reg_Det3D_STA8X8_Ver_Mute      U4  1X: Vertical pixels to be
+ * mute from 8x8 statistics calculation in each block.
+ * Bit 3:0,     reg_Det3D_STA8X8_Hor_Mute      U4  1X: Horizontal pixels to
+ * be mute from 8x8 statistics calculation in each block.
+ */
+#define DET3D_MAT_STA_P1M1                ((0x1738)) /* << 2) + 0xd0100000) */
+/* Bit 31:24, reg_Det3D_STA8X8_P1_K0_R8        U8  SAD to SAI ratio to decide P1,
+ * normalized to 256 (0.8)
+ * Bit 23:16, reg_Det3D_STA8X8_P1_K1_R7        U8  SAD to ENG ratio to decide P1,
+ * normalized to 128 (0.5)
+ * Bit 15:8,    reg_Det3D_STA8X8_M1_K0_R6
+ * U8  SAD to SAI ratio to decide M1, normalized to 64  (1.1)
+ * Bit 7:0,     reg_Det3D_STA8X8_M1_K1_R6
+ * U8  SAD to ENG ratio to decide M1, normalized to 64  (0.8)
+ */
+#define DET3D_MAT_STA_P1TH                ((0x1739)) /* << 2) + 0xd0100000) */
+/* Bit 23:16, reg_Det3D_STAYUV_P1_TH_L4        U8  SAD to ENG Thrd offset to
+ * decide P1, X16         (100)
+ * Bit 15:8,    reg_Det3D_STAEDG_P1_TH_L4      U8  SAD to ENG Thrd
+ * offset to decide P1, X16         (80)
+ * Bit 7:0,     reg_Det3D_STAMOT_P1_TH_L4      U8  SAD to ENG Thrd
+ * offset to decide P1, X16         (48)
+ */
+#define DET3D_MAT_STA_M1TH                ((0x173a)) /* << 2) + 0xd0100000) */
+/* Bit 23:16, reg_Det3D_STAYUV_M1_TH_L4        U8  SAD to
+ * ENG Thrd offset to decide M1, X16         (100)
+ * Bit 15:8,    reg_Det3D_STAEDG_M1_TH_L4
+ * U8  SAD to ENG Thrd offset to decide M1, X16         (80)
+ * Bit 7:0,     reg_Det3D_STAMOT_M1_TH_L4
+ * U8  SAD to ENG Thrd offset to decide M1, X16         (64)
+ */
+#define DET3D_MAT_STA_RSFT                ((0x173b)) /* << 2) + 0xd0100000) */
+/* Bit 5:4,     reg_Det3D_STAYUV_RSHFT     U2  YUV statistics SAD and SAI
+ * calculation result right shift bits to accommodate the 12bits clipping:
+ *             0: mainly for images <=720x480:
+ *             1: mainly for images <=1366x768:
+ *             2: mainly
+ * for images <=1920X1080: 2; 3: other higher resolutions
+ * Bit 3:2,     reg_Det3D_STAEDG_RSHFT     U2  Horizontal and Vertical Edge
+ * Statistics SAD and SAI calculation result right shift bits to
+ * accommodate the 12bits clipping:
+ *             0: mainly for images <=720x480: 1: mainly for images <=1366x768:
+ *             2: mainly for images <=1920X1080: 2; 3: other higher resolutions
+ * Bit 1:0,     reg_Det3D_STAMOT_RSHFT     U2  Motion SAD and SAI
+ * calculation result right shift bits to accommodate the 12bits clipping:
+ *             0: mainly for images <=720x480: 1: mainly for images <=1366x768:
+ *             2: mainly for images <=1920X1080: 2; 3: other higher resolutions
+ */
+#define DET3D_MAT_SYMTC_TH                ((0x173c)) /* << 2) + 0xd0100000) */
+/* Bit 31:24, reg_Det3D_STALUM_symtc_Th          U8  threshold to decide
+ * if the Luma statistics is TB or LR symmetric.
+ * Bit 23:16, reg_Det3D_STACHR_symtc_Th          U8  threshold to decide
+ * if the Chroma (UV) statistics is TB or LR symmetric.
+ * Bit 15:8,    reg_Det3D_STAEDG_symtc_Th        U8  threshold to
+ * decide if the Horizontal and Vertical Edge statistics is TB or LR symmetric.
+ * Bit 7:0,     reg_Det3D_STAMOT_symtc_Th        U8  threshold to
+ * decide if the Motion statistics is TB or LR symmetric.
+ */
+#define DET3D_RO_DET_CB_HOR               ((0x173d)) /* << 2) + 0xd0100000) */
+/* Bit 31:16, RO_Det3D_ChessBd_NHor_value    U16  X64: number of Pixels
+ * of Horizontally Surely NOT matching Chessboard pattern.
+ * Bit 15:0,    RO_Det3D_ChessBd_Hor_value         U16  X64: number of
+ * Pixels of Horizontally Surely matching Chessboard pattern.
+ */
+#define DET3D_RO_DET_CB_VER               ((0x173e)) /* << 2) + 0xd0100000) */
+/* Bit 31:16, RO_Det3D_ChessBd_NVer_value      U16  X64: number of
+ * Pixels of Vertically Surely NOT matching Chessboard pattern.
+ * Bit 15:0,    RO_Det3D_ChessBd_Ver_value         U16  X64: number
+ * of Pixels of Vertically Surely matching Chessboard pattern.
+ */
+#define DET3D_RO_SPLT_HT                  ((0x173f)) /* << 2) + 0xd0100000) */
+/* Bit 24,      RO_Det3D_Split_HT_valid        U1  horizontal LR split border
+ * detected valid signal for top half picture
+ * Bit 20:16, RO_Det3D_Split_HT_pxnum  U5  number of pixels included for the
+ * LR split position estimation for top half picture
+ * Bit 9:0,     RO_Det3D_Split_HT_idxX4        S10  X4: horizontal pixel
+ * shifts of LR split position to the (ColMax/2) for top half picture
+ * // DET 3D REG DEFINE END ////
+ * // NR2 REG DEFINE BEGIN////
+ */
+#define NR2_MET_NM_CTRL                   ((0x1745)) /* << 2) + 0xd0100000) */
+/* Bit 28,        reg_NM_reset      Reset to the status of the Loop filter.
+ * Bit 27:24,   reg_NM_calc_length       Length mode of the Noise
+ * measurement sample number for statistics.
+ *             0:  256 samples;    1: 512 samples;    2: 1024 samples;
+ * Â¡Â­X: 2^(8+x) samples
+ * Bit 23:20,   reg_NM_inc_step              Loop filter input gain increase step.
+ * Bit 19:16,   reg_NM_dec_step              Loop filter input gain decrease step.
+ * Bit 15:8,      reg_NM_YHPmot_thrd     Luma channel HP portion motion
+ * for condition of pixels included in Luma Noise measurement.
+ * Bit 7:0,       reg_NM_CHPmot_thrd     Chroma channel HP portion motion
+ * for condition of pixels included in Chroma Noise measurement.
+ */
+#define NR2_MET_NM_YCTRL                  ((0x1746)) /* << 2) + 0xd0100000) */
+/* Bit 31:28,   reg_NM_YPLL_target           Target rate of
+ * NM_Ynoise_thrd to mean of the Luma Noise
+ * Bit 27:24,   reg_NM_YLPmot_thrd           Luma channel LP
+ * portion motion for condition of pixels included in Luma Noise measurement.
+ * Bit 23:16,   reg_NM_YHPmot_thrd_min   Minimum threshold for
+ * Luma channel HP portion motion to decide whether the pixel
+ * will be included in Luma noise measurement.
+ * Bit 15:8,      reg_NM_YHPmot_thrd_max         Maximum threshold for Luma
+ * channel HP portion motion to decide whether the pixel will be included in
+ * Luma noise measurement.
+ * Bit 7:0,       reg_NM_Ylock_rate          Rate to decide whether the
+ * Luma noise measurement is lock or not.
+ */
+#define NR2_MET_NM_CCTRL                  ((0x1747)) /* << 2) + 0xd0100000) */
+/* Bit 31:28,  reg_NM_CPLL_target
+ * Target rate of NM_Cnoise_thrd to mean of the Chroma Noise
+ * Bit 27:24,  reg_NM_CLPmot_thrd           Chroma channel LP portion motion
+ * for condition of pixels included in Chroma Noise measurement.
+ * Bit 23:16,  reg_NM_CHPmot_thrd_min   Minimum threshold for Chroma channel
+ * HP portion motion to decide whether the pixel will be
+ * included in Chroma noise measurement.
+ * Bit 15:8,       reg_NM_CHPmot_thrd_max       Maximum threshold for Chroma
+ * channel HP portion motion to decide whether the pixel will be included in
+ * Chroma noise measurement.
+ * Bit 7:0,        reg_NM_Clock_rate        Rate to decide whether the Chroma
+ * noise measurement is lock or not;
+ */
+#define NR2_MET_NM_TNR                    ((0x1748)) /* << 2) + 0xd0100000) */
+/* Bit 25,         ro_NM_TNR_Ylock              Read-only register to tell
+ * ifLuma channel noise measurement is locked or not.
+ * Bit 24,         ro_NM_TNR_Clock              Read-only register to tell
+ * if Chroma channel noise measurement is locked or not.
+ * Bit 23:12,  ro_NM_TNR_Ylevel             Read-only register to give Luma
+ * channel noise level. It was 16x of pixel difference in 8 bits of YHPmot.
+ * Bit 11:0,   ro_NM_TNR_ClevelRead-only register to give Chroma channel noise
+ * level.It was 16x of pixel difference in 8 bits of CHPmot.
+ */
+#define NR2_MET_NMFRM_TNR_YLEV            ((0x1749)) /* << 2) + 0xd0100000) */
+/* Bit 28:0,   ro_NMFrm_TNR_Ylevel              Frame based Read-only register
+ * to give Luma channel noise level within one frame/field.
+ */
+#define NR2_MET_NMFRM_TNR_YCNT            ((0x174a)) /* << 2) + 0xd0100000) */
+/* Bit 23:0,   ro_NMFrm_TNR_Ycount              Number ofLuma channel pixels
+ * included in Frame/Field based noise level measurement.
+ */
+#define NR2_MET_NMFRM_TNR_CLEV            ((0x174b)) /* << 2) + 0xd0100000) */
+/* Bit 28:0,   ro_NMFrm_TNR_Clevel              Frame based Read-only register
+ * to give Chroma channel noise level within one frame/field.
+ */
+#define NR2_MET_NMFRM_TNR_CCNT            ((0x174c)) /* << 2) + 0xd0100000) */
+/* Bit 23:0,   ro_NMFrm_TNR_Ccount              Number of Chroma channel pixels
+ * included in Frame/Field based noise level measurement.
+ */
+#define NR2_3DEN_MODE                     ((0x174d)) /* << 2) + 0xd0100000) */
+/* Bit 6:4,    Blend_3dnr_en_r */
+/* Bit 2:0,    Blend_3dnr_en_l */
+#define NR2_IIR_CTRL                      ((0x174e)) /* << 2) + 0xd0100000) */
+/* Bit 15:14, reg_LP_IIR_8bit_mode     LP IIR membitwidth mode:
+ *             0: 10bits will be store in memory;
+ *             1: 9bits will be store in memory;
+ *             2: 8bits will be store in memory;
+ *             3: 7bits will be store in memory;
+ * Bit 13:12, reg_LP_IIR_mute_mode     Mode for the LP IIR mute,
+ * Bit 11:8,reg_LP_IIR_mute_thrd Threshold of LP IIR mute to avoid ghost:
+ * Bit 7:6,     reg_HP_IIR_8bit_mode   IIR membitwidth mode:
+ *             0: 10bits will be store in memory;
+ *             1: 9bits will be store in memory;
+ *             2: 8bits will be store in memory;
+ *             3: 7bits will be store in memory;
+ * Bit 5:4,    reg_HP_IIR_mute_mode    Mode for theLP IIR mute
+ * Bit 3:0,reg_HP_IIR_mute_thrd        Threshold of HP IIR mute to avoid ghost
+ */
+#define NR2_SW_EN                         ((0x174f)) /* << 2) + 0xd0100000) */
+/* Bit 17:8,   Clk_gate_ctrl
+ * Bit 7,      Cfr_enable
+ * Bit 5,      Det3d_en
+ * Bit 4,      Nr2_proc_en
+ * Bit 0,      Nr2_sw_en
+ */
+#define NR2_FRM_SIZE                      ((0x1750)) /* << 2) + 0xd0100000) */
+/* Bit 27:16,  Frm_heigh       Frame/field height */
+/* Bit 11: 0,  Frm_width       Frame/field width */
+#define NR2_SNR_SAD_CFG                   ((0x1751)) /* << 2) + 0xd0100000) */
+/* Bit 12,     reg_MATNR_SNR_SAD_CenRPL        U1, Enable signal for Current
+ * pixel position SAD to be replaced by SAD_min.0: do not replace Current pixel
+ * position SAD by SAD_min;1: do replacements
+ * Bit 11:8,   reg_MATNR_SNR_SAD_coring        Coring value of the intra-frame
+ * SAD. sum = (sum - reg_MATNR_SNR_SAD_coring);
+ * sum = (sum<0) ? 0: (sum>255)? 255: sum;
+ * Bit 6:5,    reg_MATNR_SNR_SAD_WinMod        Unsigned, Intra-frame SAD
+ * matching window mode:0: 1x1; 1: [1 1 1] 2: [1 2 1]; 3: [1 2 2 2 1];
+ * Bit 4:0,    Sad_coef_num                Sad coeffient
+ */
+#define NR2_MATNR_SNR_OS                  ((0x1752)) /* << 2) + 0xd0100000) */
+/* Bit 7:4,    reg_MATNR_SNR_COS           SNR Filter overshoot control
+ * margin for UV channel (X2 to u10 scale)
+ * Bit 3:0,    reg_MATNR_SNR_YOS           SNR Filter overshoot control
+ * margin for luma channel (X2 to u10 scale)
+ */
+#define NR2_MATNR_SNR_NRM_CFG             ((0x1753)) /* << 2) + 0xd0100000) */
+/* Bit 23:16,  reg_MATNR_SNR_NRM_ofst  Edge based SNR
+ *             boosting normalization offset to SAD_max ;
+ * Bit 15:8,       reg_MATNR_SNR_NRM_max
+ *             Edge based SNR boosting normalization Max value
+ * Bit 7:0,        reg_MATNR_SNR_NRM_min
+ *             Edge based SNR boosting normalization Min value
+ */
+#define NR2_MATNR_SNR_NRM_GAIN            ((0x1754)) /* << 2) + 0xd0100000) */
+/* Bit 15:8,   reg_MATNR_SNR_NRM_Cgain Edge based SNR boosting
+ *             normalization Gain for Chrm channel (norm 32 as 1)
+ * Bit 7:0,    reg_MATNR_SNR_NRM_Ygain Edge based SNR boosting
+ *             normalization Gain for Luma channel (norm 32 as 1)
+ */
+#define NR2_MATNR_SNR_LPF_CFG             ((0x1755)) /* << 2) + 0xd0100000) */
+/* Bit 23:16,reg_MATNR_SNRLPF_SADmaxTH U8,  Threshold to SADmax to use TNRLPF
+ * to replace SNRLPF. i.e.if (SAD_max<reg_MATNR_SNRLPF_SADmaxTH)
+ * SNRLPF_yuv[k] = TNRLPF_yuv[k];
+ * Bit 13:11,reg_MATNR_SNRLPF_Cmode
+ * LPF based SNR filtering mode on CHRM channel:
+ *             0: gradient LPF [1 1]/2, 1: gradient LPF [2 1 1]/4;
+ *             2: gradient LPF [3 3 2]/8; 3: gradient LPF [5 4 4 3]/16;
+ *             4: TNRLPF;  5 : CurLPF3x3_yuv[];
+ *             6: CurLPF3o3_yuv[]  7: CurLPF3x5_yuv[]
+ * Bit 10:8,   reg_MATNR_SNRLPF_Ymode
+ * LPF based SNR filtering mode on LUMA channel:
+ *             0: gradient LPF //Bit [1 1]/2, 1: gradient LPF [2 1 1]/4;
+ *             2: gradient LPF [3 3 2]/8;3: gradient LPF [5 4 4 3]/16;
+ *             4: TNRLPF;               5 : CurLPF3x3_yuv[];
+ *             6: CurLPF3o3_yuv[]         7: CurLPF3x5_yuv[]
+ * Bit 7:4,    reg_MATNR_SNRLPF_SADmin3TH      Offset threshold to SAD_min to
+ * Discard SAD_min3 corresponding pixel in LPF SNR filtering. (X8 to u8 scale)
+ * Bit 3:0,    reg_MATNR_SNRLPF_SADmin2TH      Offset threshold to SAD_min to
+ * Discard SAD_min2 corresponding pixel in LPF SNR filtering. (X8 to u8 scale)
+ */
+#define NR2_MATNR_SNR_USF_GAIN           ((0x1756)) /* << 2) + 0xd0100000) */
+/* Bit 15:8,   reg_MATNR_SNR_USF_Cgain
+ * Un-sharp (HP) compensate back Chrm portion gain, (norm 64 as 1)
+ * Bit 7:0,    reg_MATNR_SNR_USF_Ygain
+ * Un-sharp (HP) compensate back Luma portion gain, (norm 64 as 1)
+ */
+#define NR2_MATNR_SNR_EDGE2B             ((0x1757)) /* << 2) + 0xd0100000) */
+/* Bit 15:8,   reg_MATNR_SNR_Edge2Beta_ofst    U8,
+ * Offset for Beta based on Edge.
+ * Bit 7:0,    reg_MATNR_SNR_Edge2Beta_gain    U8.
+ * Gain to SAD_min for Beta based on Edge. (norm 16 as 1)
+ */
+#define NR2_MATNR_BETA_EGAIN             ((0x1758)) /* << 2) + 0xd0100000) */
+/* Bit 15:8,   reg_MATNR_CBeta_Egain   U8,
+ * Gain to Edge based Beta for Chrm channel. (normalized to 32 as 1)
+ * Bit 7:0,    reg_MATNR_YBeta_Egain   U8,
+ * Gain to Edge based Beta for Luma channel. (normalized to 32 as 1)
+ */
+#define NR2_MATNR_BETA_BRT               ((0x1759)) /* << 2) + 0xd0100000) */
+/* Bit 31:28,  reg_MATNR_beta_BRT_limt_hi      U4,
+ * Beta adjustment based on Brightness high side Limit. (X16 to u8 scale)
+ * Bit 27:24,  reg_MATNR_beta_BRT_slop_hi      U4,
+ * Beta adjustment based on Brightness high side slope. Normalized to 16 as 1
+ * Bit 23:16,  reg_MATNR_beta_BRT_thrd_hi      U8,
+ * Beta adjustment based on Brightness high threshold.(u8 scale)
+ * Bit 15:12,  reg_MATNR_beta_BRT_limt_lo      U4,
+ * Beta adjustment based on Brightness low side Limit. (X16 to u8 scale)
+ * Bit 11:8,       reg_MATNR_beta_BRT_slop_lo  U4,
+ * Beta adjustment based on Brightness low side slope. Normalized to 16 as 1
+ * Bit 7:0,        reg_MATNR_beta_BRT_thrd_lo  U8,
+ * Beta adjustment based on Brightness low threshold.(u8 scale)
+ */
+#define NR2_MATNR_XBETA_CFG              ((0x175a)) /* << 2) + 0xd0100000) */
+/* Bit 19:18,  reg_MATNR_CBeta_use_mode        U2,
+ * Beta options (mux) from beta_motion and beta_edge for Chrm channel;
+ * Bit 17:16,  reg_MATNR_YBeta_use_mode        U2,
+ * Beta options (mux) from beta_motion and beta_edge for Luma channel;
+ * Bit 15: 8,  reg_MATNR_CBeta_Ofst        U8,
+ * Offset to Beta for Chrm channel.(after beta_edge and beta_motion mux)
+ * Bit  7: 0,  reg_MATNR_YBeta_Ofst        U8,
+ * Offset to Beta for Luma channel.(after beta_edge and beta_motion mux)
+ */
+#define NR2_MATNR_YBETA_SCL              ((0x175b)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_YBeta_scale_min       U8,
+ * Final step Beta scale low limit for Luma channel;
+ * Bit 23:16,  reg_MATNR_YBeta_scale_max       U8,
+ * Final step Beta scale high limit for Luma channe;
+ * Bit 15: 8,  reg_MATNR_YBeta_scale_gain      U8,
+ * Final step Beta scale Gain for Luma channel (normalized 32 to 1);
+ * Bit 7 : 0,  reg_MATNR_YBeta_scale_ofst      S8,
+ * Final step Beta scale offset for Luma channel ;
+ */
+#define NR2_MATNR_CBETA_SCL              ((0x175c)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_CBeta_scale_min
+ * Final step Beta scale low limit for Chrm channel.Similar to Y
+ * Bit 23:16,  reg_MATNR_CBeta_scale_max       U8,
+ * Final step Beta scale high limit for Chrm channel.Similar to Y
+ * Bit 15: 8,  reg_MATNR_CBeta_scale_gain      U8,
+ * Final step Beta scale Gain for Chrm channel Similar to Y
+ * Bit  7: 0,  reg_MATNR_CBeta_scale_ofst      S8,
+ * Final step Beta scale offset for Chrm channel Similar to Y
+ */
+#define NR2_SNR_MASK                     ((0x175d)) /* << 2) + 0xd0100000) */
+/* Bit 20:0,   SAD_MSK                  Valid signal in the 3x7 SAD surface */
+#define NR2_SAD2NORM_LUT0                ((0x175e)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_SAD2Norm_LUT_3
+ *             SAD convert normal LUT node 3
+ * Bit 23:16,  reg_MATNR_SAD2Norm_LUT_2
+ *             SAD convert normal LUT node 2
+ * Bit 15: 8,  reg_MATNR_SAD2Norm_LUT_1
+ *             SAD convert normal LUT node 1
+ * Bit  7: 0,  reg_MATNR_SAD2Norm_LUT_0
+ *             SAD convert normal LUT node 0
+ */
+#define NR2_SAD2NORM_LUT1                ((0x175f)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_SAD2Norm_LUT_7
+ *             SAD convert normal LUT node 7
+ * Bit 23:16,  reg_MATNR_SAD2Norm_LUT_6
+ *             SAD convert normal LUT node 6
+ * Bit 15: 8,  reg_MATNR_SAD2Norm_LUT_5
+ *             SAD convert normal LUT node 5
+ * Bit  7: 0,  reg_MATNR_SAD2Norm_LUT_4
+ *             SAD convert normal LUT node 4
+ */
+#define NR2_SAD2NORM_LUT2                ((0x1760)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_SAD2Norm_LUT_11
+ *             SAD convert normal LUT node 11
+ * Bit 23:16,  reg_MATNR_SAD2Norm_LUT_10
+ *             SAD convert normal LUT node 10
+ * Bit 15: 8,  reg_MATNR_SAD2Norm_LUT_9
+ *             SAD convert normal LUT node 9
+ * Bit  7: 0,  reg_MATNR_SAD2Norm_LUT_8
+ *             SAD convert normal LUT node 8
+ */
+#define NR2_SAD2NORM_LUT3                ((0x1761)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_SAD2Norm_LUT_15 SAD convert normal LUT node 15 */
+/* Bit 23:16,  reg_MATNR_SAD2Norm_LUT_14 SAD convert normal LUT node 14 */
+/* Bit 15:8,   reg_MATNR_SAD2Norm_LUT_13 SAD convert normal LUT node 13 */
+/* Bit 7:0,    reg_MATNR_SAD2Norm_LUT_12 SAD convert normal LUT node 12 */
+#define NR2_EDGE2BETA_LUT0               ((0x1762)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Edge2Beta_LUT_3 Edge convert beta LUT node 3 */
+/* Bit 23:16,  reg_MATNR_Edge2Beta_LUT_2 Edge convert beta LUT node 2 */
+/* Bit 15: 8,  reg_MATNR_Edge2Beta_LUT_1 Edge convert beta LUT node 1 */
+/* Bit  7: 0,  reg_MATNR_Edge2Beta_LUT_0 Edge convert beta LUT node 0 */
+#define NR2_EDGE2BETA_LUT1               ((0x1763)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Edge2Beta_LUT_7 Edge convert beta LUT node 7 */
+/* Bit 23:16,  reg_MATNR_Edge2Beta_LUT_6 Edge convert beta LUT node 6 */
+/* Bit 15: 8,  reg_MATNR_Edge2Beta_LUT_5 Edge convert beta LUT node 5 */
+/* Bit  7: 0,  reg_MATNR_Edge2Beta_LUT_4 Edge convert beta LUT node 4 */
+#define NR2_EDGE2BETA_LUT2               ((0x1764)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Edge2Beta_LUT_11 Edge convert beta LUT node 11 */
+/* Bit 23:16,  reg_MATNR_Edge2Beta_LUT_10 Edge convert beta LUT node 10 */
+/* Bit 15: 8,  reg_MATNR_Edge2Beta_LUT_9  Edge convert beta LUT node 9 */
+/* Bit  7: 0,  reg_MATNR_Edge2Beta_LUT_8  Edge convert beta LUT node 8 */
+#define NR2_EDGE2BETA_LUT3               ((0x1765)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Edge2Beta_LUT_15 Edge convert beta LUT node 15 */
+/* Bit 23:16,  reg_MATNR_Edge2Beta_LUT_14 Edge convert beta LUT node 14 */
+/* Bit 15: 8,  reg_MATNR_Edge2Beta_LUT_13 Edge convert beta LUT node 13 */
+/* Bit  7: 0,  reg_MATNR_Edge2Beta_LUT_12 Edge convert beta LUT node 12 */
+#define NR2_MOTION2BETA_LUT0             ((0x1766)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Mot2Beta_LUT_3 Motion convert beta LUT node 3 */
+/* Bit 23:16,  reg_MATNR_Mot2Beta_LUT_2 Motion convert beta LUT node 2 */
+/* Bit 15: 8,  reg_MATNR_Mot2Beta_LUT_1 Motion convert beta LUT node 1 */
+/* Bit  7: 0,  reg_MATNR_Mot2Beta_LUT_0 Motion convert beta LUT node 0 */
+#define NR2_MOTION2BETA_LUT1             ((0x1767)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Mot2Beta_LUT_7 Motion convert beta LUT node 7 */
+/* Bit 23:16,  reg_MATNR_Mot2Beta_LUT_6 Motion convert beta LUT node 6 */
+/* Bit 15: 8,  reg_MATNR_Mot2Beta_LUT_5 Motion convert beta LUT node 5 */
+/* Bit  7: 0,  reg_MATNR_Mot2Beta_LUT_4 Motion convert beta LUT node 4 */
+#define NR2_MOTION2BETA_LUT2             ((0x1768)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Mot2Beta_LUT_11 Motion convert beta LUT node 11 */
+/* Bit 23:16,  reg_MATNR_Mot2Beta_LUT_10 Motion convert beta LUT node 10 */
+/* Bit 15: 8,  reg_MATNR_Mot2Beta_LUT_9  Motion convert beta LUT node 9 */
+/* Bit  7: 0,  reg_MATNR_Mot2Beta_LUT_8  Motion convert beta LUT node 8 */
+#define NR2_MOTION2BETA_LUT3             ((0x1769)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_Mot2Beta_LUT_15 Motion convert beta LUT node 15 */
+/* Bit 23:16,  reg_MATNR_Mot2Beta_LUT_14 Motion convert beta LUT node 14 */
+/* Bit 15: 8,  reg_MATNR_Mot2Beta_LUT_13 Motion convert beta LUT node 13 */
+/* Bit  7: 0,  reg_MATNR_Mot2Beta_LUT_12 Motion convert beta LUT node 12 */
+#define NR2_MATNR_MTN_CRTL               ((0x176a)) /* << 2) + 0xd0100000) */
+/* Bit 25:24,  reg_MATNR_Vmtn_use_mode     Motion_yuvV channel motion selection
+ * mode:       0: Vmot;
+ *                     1:Ymot/2 + (Umot+Vmot)/4;
+ *                     2:Ymot/2 + max(Umot,Vmot)/2;
+ *                     3: max(Ymot,Umot, Vmot)
+ * Bit 21:20,  reg_MATNR_Umtn_use_mode     Motion_yuvU channel motion selection
+ * mode:       0:Umot;
+ *                     1:Ymot/2 + (Umot+Vmot)/4;
+ *                     2:Ymot/2 + max(Umot,Vmot)/2;
+ *                     3: max(Ymot,Umot, Vmot)
+ * Bit 17:16,  reg_MATNR_Ymtn_use_mode  Motion_yuvLuma channel motion selection
+ * mode:       0:  Ymot,
+ *                     1: Ymot/2 + (Umot+Vmot)/4;
+ *                     2: Ymot/2 + max(Umot,Vmot)/2;
+ *                     3:  max(Ymot,Umot, Vmot)
+ * Bit 13:12,  reg_MATNR_mtn_txt_mode
+ * Texture detection mode for adaptive coring of HP motion
+ * Bit  9: 8,  reg_MATNR_mtn_cor_mode
+ * Coring selection mode based on texture detection;
+ * Bit  6: 4,  reg_MATNR_mtn_hpf_mode
+ * video mode of current and previous frame/field for MotHPF_yuv[k] calculation:
+ * Bit  2: 0,  reg_MATNR_mtn_lpf_mode  LPF video mode of current and previous
+ * frame/field for MotLPF_yuv[k] calculation:
+ */
+#define NR2_MATNR_MTN_CRTL2              ((0x176b)) /* << 2) + 0xd0100000) */
+/* Bit 18:16,  reg_MATNR_iir_BS_Ymode      IIR TNR filter Band split filter
+ * mode for Luma LPF result generation (Cur and Prev);
+ * Bit 15: 8,  reg_MATNR_mtnb_alpLP_Cgain      Scale of motion_brthp_uv to
+ * motion_brtlp_uv, normalized to 32 as 1
+ * Bit  7: 0,  reg_MATNR_mtnb_alpLP_Ygain      Scale of motion_brthp_y to
+ * motion_brtlp_y, normalized to 32 as 1
+ */
+#define NR2_MATNR_MTN_COR                ((0x176c)) /* << 2) + 0xd0100000) */
+/* Bit 15:12,  reg_MATNR_mtn_cor_Cofst     Coring Offset for Chroma Motion.
+ * Bit 11: 8,  reg_MATNR_mtn_cor_Cgain     Gain to texture based coring for
+ * Chroma Motion. Normalized to 16 as 1
+ * Bit  7: 4,  reg_MATNR_mtn_cor_Yofst     Coring Offset for Luma Motion.
+ * Bit  3: 0,  reg_MATNR_mtn_cor_Ygain     Gain to texture based coring for
+ * Luma Motion. Normalized to 16 as 1
+ */
+#define NR2_MATNR_MTN_GAIN               ((0x176d)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_mtn_hp_Cgain  Gain to MotHPF_yuv[k] Chrm channel for
+ * motion calculation, normalized to 64 as 1
+ * Bit 23:16,  reg_MATNR_mtn_hp_Ygain  Gain to MotHPF_yuv[k] Luma channel for
+ * motion calculation, normalized to 64 as 1
+ * Bit 15: 8,  reg_MATNR_mtn_lp_Cgain  Gain to MotLPF_yuv[k] Chrm channel for
+ * motion calculation, normalized to 32 as 1
+ * Bit  7: 0,  reg_MATNR_mtn_lp_Ygain  Gain to MotLPF_yuv[k] Luma channel for
+ * motion calculation, normalized to 32 as 1
+ */
+#define NR2_MATNR_DEGHOST                ((0x176e)) /* << 2) + 0xd0100000) */
+/* Bit 8,      reg_MATNR_DeGhost_En
+ * Enable signal for DeGhost function:0: disable; 1: enable
+ * Bit 7:4,    reg_MATNR_DeGhost_COS
+ * DeGhost Overshoot margin for UV channel, (X2 to u10 scale)
+ * Bit 3:0,    reg_MATNR_DeGhost_YOS
+ * DeGhost Overshoot margin for Luma channel, (X2 to u10 scale)
+ */
+#define NR2_MATNR_ALPHALP_LUT0           ((0x176f)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaLP_LUT_3
+ * Matnr low-pass filter alpha LUT node 3
+ */
+/* Bit 23:16,  reg_MATNR_AlphaLP_LUT_2
+ * Matnr low-pass filter alpha LUT node 2
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaLP_LUT_1
+ * Matnr low-pass filter alpha LUT node 1
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaLP_LUT_0
+ *Matnr low-pass filter alpha LUT node 0
+ */
+#define NR2_MATNR_ALPHALP_LUT1           ((0x1770)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaLP_LUT_7
+ * Matnr low-pass filter alpha LUT node 7
+ */
+/* Bit 23:16,  reg_MATNR_AlphaLP_LUT_6
+ * Matnr low-pass filter alpha LUT node 6
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaLP_LUT_5
+ * Matnr low-pass filter alpha LUT node 5
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaLP_LUT_4
+ * Matnr low-pass filter alpha LUT node 4
+ */
+#define NR2_MATNR_ALPHALP_LUT2           ((0x1771)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaLP_LUT_11
+ * Matnr low-pass filter alpha LUT node 11
+ */
+/* Bit 23:16,  reg_MATNR_AlphaLP_LUT_10
+ * Matnr low-pass filter alpha LUT node 10
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaLP_LUT_9
+ * Matnr low-pass filter alpha LUT node 9
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaLP_LUT_8
+ * Matnr low-pass filter alpha LUT node 8
+ */
+#define NR2_MATNR_ALPHALP_LUT3           ((0x1772)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaLP_LUT_15
+ * Matnr low-pass filter alpha LUT node 15
+ */
+/* Bit 23:16,  reg_MATNR_AlphaLP_LUT_14
+ * Matnr low-pass filter alpha LUT node 14
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaLP_LUT_13
+ * Matnr low-pass filter alpha LUT node 13
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaLP_LUT_12
+ * Matnr low-pass filter alpha LUT node 12
+ */
+#define NR2_MATNR_ALPHAHP_LUT0           ((0x1773)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaHP_LUT_3
+ * Matnr high-pass filter alpha LUT node 3
+ */
+/* Bit 23:16,  reg_MATNR_AlphaHP_LUT_2
+ * Matnr high-pass filter alpha LUT node 2
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaHP_LUT_1
+ * Matnr high-pass filter alpha LUT node 1
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaHP_LUT_0
+ * Matnr high-pass filter alpha LUT node 0
+ */
+#define NR2_MATNR_ALPHAHP_LUT1           ((0x1774)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaHP_LUT_7
+ * Matnr high-pass filter alpha LUT node 7
+ */
+/* Bit 23:16,  reg_MATNR_AlphaHP_LUT_6
+ * Matnr high-pass filter alpha LUT node 6
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaHP_LUT_5
+ * Matnr high-pass filter alpha LUT node 5
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaHP_LUT_4
+ * Matnr high-pass filter alpha LUT node 4
+ */
+#define NR2_MATNR_ALPHAHP_LUT2           ((0x1775)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaHP_LUT_11
+ * Matnr high-pass filter alpha LUT node 11
+ */
+/* Bit 23:16,  reg_MATNR_AlphaHP_LUT_10
+ * Matnr high-pass filter alpha LUT node 10
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaHP_LUT_9
+ * Matnr high-pass filter alpha LUT node 9
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaHP_LUT_8
+ * Matnr high-pass filter alpha LUT node 8
+ */
+#define NR2_MATNR_ALPHAHP_LUT3           ((0x1776)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_MATNR_AlphaHP_LUT_15
+ * Matnr high-pass filter alpha LUT node 15
+ */
+/* Bit 23:16,  reg_MATNR_AlphaHP_LUT_14
+ * Matnr high-pass filter alpha LUT node 14
+ */
+/* Bit 15: 8,  reg_MATNR_AlphaHP_LUT_13
+ * Matnr high-pass filter alpha LUT node 13
+ */
+/* Bit  7: 0,  reg_MATNR_AlphaHP_LUT_12
+ *Matnr high-pass filter alpha LUT node 12
+ */
+#define NR2_MATNR_MTNB_BRT               ((0x1777)) /* << 2) + 0xd0100000) */
+/* Bit 31:28,  reg_MATNR_mtnb_BRT_limt_hi      Motion adjustment based on
+ * Brightness high side Limit. (X16 to u8 scale)
+ */
+/* Bit 27:24,  reg_MATNR_mtnb_BRT_slop_hi      Motion adjustment based on
+ * Brightness high side slope. Normalized to 16 as 1
+ */
+/* Bit 23:16,  reg_MATNR_mtnb_BRT_thrd_hi      Motion adjustment based on
+ * Brightness high threshold.(u8 scale)
+ */
+/* Bit 15:12,  reg_MATNR_mtnb_BRT_limt_lo      Motion adjustment based on
+ * Brightness low side Limit. (X16 to u8 scale)
+ */
+/* Bit 11: 8,  reg_MATNR_mtnb_BRT_slop_lo      Motion adjustment based on
+ * Brightness low side slope. Normalized to 16 as 1
+ */
+/* Bit  7: 0,  reg_MATNR_mtnb_BRT_thrd_lo      Motion adjustment based on
+ * Brightness low threshold.(u8 scale)
+ */
+#define NR2_CUE_MODE                     ((0x1778)) /* << 2) + 0xd0100000) */
+/* Bit 9,      Cue_enable_r            Cue right half frame enable */
+/* Bit 8,      Cue_enable_l            Cue left half frame enable */
+/* Bit 6:4,    reg_CUE_CON_RPLC_mode   U3, CUE pixel chroma replace mode; */
+/* Bit 2:0,    reg_CUE_CHRM_FLT_mode   U3, CUE improvement filter mode, */
+#define NR2_CUE_CON_MOT_TH               ((0x1779)) /* << 2) + 0xd0100000) */
+/* Bit 31:24,  reg_CUE_CON_Cmot_thrd2  U8,  Motion Detection threshold of
+ * up/down two rows,  Chroma channel in Chroma Up-sampling Error (CUE)
+ * Detection (tighter).
+ */
+/* Bit 23:16,  reg_CUE_CON_Ymot_thrd2  U8,  Motion Detection threshold of
+ * up/mid/down three rows,  Luma channel in Chroma Up-sampling Error (CUE)
+ * Detection (tighter).
+ */
+/* Bit 15: 8,  reg_CUE_CON_Cmot_thrd   U8,  Motion Detection threshold of
+ * up/down two rows, Chroma channel in Chroma Up-sampling Error (CUE) Detection.
+ */
+/* Bit  7: 0,  reg_CUE_CON_Ymot_thrd   U8,  Motion Detection threshold of
+ * up/mid/down three rows, Luma channel in
+ * Chroma Up-sampling Error (CUE) Detection.
+ */
+#define NR2_CUE_CON_DIF0                 ((0x177a)) /* << 2) + 0xd0100000) */
+/* Bit 15:8,   reg_CUE_CON_difP1_thrd      U8,  P1 field Intra-Field top/below
+ * line chroma difference threshold,
+ */
+/* Bit 7:0,    reg_CUE_CON_difCur_thrd     U8,  Current Field/Frame Intra-Field
+ * up/down line chroma difference threshold,
+ */
+#define NR2_CUE_CON_DIF1                 ((0x177b)) /* << 2) + 0xd0100000) */
+/* Bit 19:16,  reg_CUE_CON_rate0           U4,  The Krate to decide CUE by
+ * relationship between CUE_diflG and CUE_difEG
+ */
+/* Bit 15: 8,  reg_CUE_CON_difEG_thrd  U8,  Theshold to the difference between
+ * current Field/Frame middle line to down line color channel(CUE_difEG).
+ */
+/* Bit  7: 0,  reg_CUE_CON_diflG_thrd  U8,  Threshold to the difference between
+ * P1 field top line to current Field/Frame down line color channel (CUE_diflG).
+ */
+#define NR2_CUE_CON_DIF2                 ((0x177c)) /* << 2) + 0xd0100000) */
+/* Bit 19:16,  reg_CUE_CON_rate1           U4,  The Krate to decide CUE by
+ * relationship between CUE_difnC and CUE_difEC
+ */
+/* Bit 15: 8,  reg_CUE_CON_difEC_thrd  U8,  Theshold to the difference between
+ * current Field/Frame middle line to up line color channel(CUE_difEC).
+ */
+/* Bit  7: 0,  reg_CUE_CON_difnC_thrd  U8,  Threshold to the difference between
+ * P1 field bot line to current Field/Frame up line color channel (CUE_difnC).
+ */
+#define NR2_CUE_CON_DIF3                 ((0x177d)) /* << 2) + 0xd0100000) */
+/* Bit 19:16,  reg_CUE_CON_rate2           U4,  The Krate to decide CUE by
+ * relationship between CUE_difP1 and CUE_difEP1
+ */
+/* Bit 15: 8,  reg_CUE_CON_difEP1_thrd U8,  Inter-Field top/below line to
+ * current field/frame middle line chroma difference (CUE_difEP1) threshold.
+ */
+/* Bit  7: 0,  reg_CUE_CON_difP1_thrd2 U8,  P1 field Intra-Field top/below line
+ * chroma difference threshold (tighter),
+ */
+/* change from txlx */
+#define DI_EI_DRT_CTRL                  ((0x1778))
+
+#define DI_EI_DRT_PIXTH                 ((0x1779))
+
+#define DI_EI_DRT_CORRPIXTH             ((0x177a))
+
+#define DI_EI_DRT_RECTG_WAVE            ((0x177b))
+
+#define DI_EI_DRT_PIX_DIFFTH            ((0x177c))
+
+#define DI_EI_DRT_UNBITREND_TH          ((0x177d))
+
+#define NR2_CUE_PRG_DIF                  ((0x177e)) /* << 2) + 0xd0100000) */
+/* Bit 20,         reg_CUE_PRG_Enable      Enable bit for progressive video CUE
+ * detection.If interlace input video,
+ */
+/* Bit 19:16,  reg_CUE_PRG_rate            U3,  The Krate to decide CUE by
+ * relationship between CUE_difCur and (CUE_difEC+CUE_difEG)
+ */
+/* Bit 15: 8,  reg_CUE_PRG_difCEG_thrd U8, Current Frame Intra-Field up-mid and
+ * mid-down line chroma difference threshold
+ * for progressive video CUE detection,
+ */
+/* Bit  7: 0,  reg_CUE_PRG_difCur_thrd U8,  Current Frame Intra-Field up/down
+ * line chroma difference threshold,
+ */
+#define NR2_CONV_MODE                    ((0x177f)) /* << 2) + 0xd0100000) */
+/* Bit 3:2,    Conv_c444_mode
+ * The format convert mode about 422 to 444 when data read out line buffer
+ */
+/* Bit 1:0,    Conv_c422_mode
+ * the format convert mode about 444 to 422 when data write to line buffer
+ */
+/* // NR2 REG DEFINE END //// */
+/* // DET 3D REG DEFINE BEGIN //// */
+/* for gxlx */
+#define DI_EI_DRT_CTRL_GXLX                  ((0x2028))
+
+#define DI_EI_DRT_PIXTH_GXLX                 ((0x2029))
+
+#define DI_EI_DRT_CORRPIXTH_GXLX             ((0x202a))
+
+#define DI_EI_DRT_RECTG_WAVE_GXLX            ((0x202b))
+
+#define DI_EI_DRT_PIX_DIFFTH_GXLX            ((0x202c))
+
+#define DI_EI_DRT_UNBITREND_TH_GXLX          ((0x202d))
+#define DET3D_RO_SPLT_HB                 ((0x1780)) /* << 2) + 0xd0100000) */
+/* Bit 24,         RO_Det3D_Split_HB_valid
+ * U1   horizontal LR split border detected valid signal for top half picture
+ */
+/* Bit 20:16,  RO_Det3D_Split_HB_pxnum     U5   number of pixels included for
+ * the LR split position estimation for top half picture
+ */
+/* Bit  9: 0,  RO_Det3D_Split_HB_idxX4     S10  X4: horizontal pixel shifts of
+ * LR split position to the (ColMax/2) for top half picture
+ */
+#define DET3D_RO_SPLT_VL                 ((0x1781)) /* << 2) + 0xd0100000) */
+/* Bit 24,         RO_Det3D_Split_VL_valid         U1   horizontal LR split
+ * border detected valid signal for top half picture
+ */
+/* Bit 20:16,  RO_Det3D_Split_VL_pxnum     U5   number of pixels included for
+ * the LR split position estimation for top half picture
+ */
+/* Bit  9: 0,  RO_Det3D_Split_VL_idxX4     S10  X4: horizontal pixel shifts of
+ * LR split position to the (ColMax/2) for top half picture
+ */
+#define DET3D_RO_SPLT_VR                 ((0x1782)) /* << 2) + 0xd0100000) */
+/* Bit 24   ,  RO_Det3D_Split_VR_valid     U1   horizontal LR split border
+ * detected valid signal for top half picture
+ */
+/* Bit 20:16,  RO_Det3D_Split_VR_pxnum     U5   number of pixels included for
+ * the LR split position estimation for top half picture
+ */
+/* Bit  9: 0,  RO_Det3D_Split_VR_idxX4     S10  X4: horizontal pixel shifts of
+ * LR split position to the (ColMax/2) for top half picture
+ */
+#define DET3D_RO_MAT_LUMA_LR             ((0x1783)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Luma_LR_score         S2*8  LUMA statistics left right
+ * decision score for each band (8bands vertically),
+ */
+/* it can be -1/0/1:-1: most likely not LR symmetric 0: not sure
+ * 1: most likely LR symmetric
+ */
+/* Bit 7:0,    RO_Luma_LR_symtc         U1*8  Luma statistics left
+ * right pure symmetric for each band (8bands vertically),
+ */
+/* it can be 0/1: 0: not sure 1: most likely LR is pure symmetric */
+/* Bit 4:0,    RO_Luma_LR_sum       S5  Total score of 8x8 Luma
+ * statistics for LR like decision,
+ */
+/* the larger this score, the more confidence that this is a LR 3D video.
+ * It is sum of  RO_Luma_LR_score[0~7]
+ */
+#define DET3D_RO_MAT_LUMA_TB             ((0x1784)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Luma_TB_score         S2*8  LUMA statistics Top/Bottom
+ * decision score for each band (8bands Horizontally),
+ */
+/* Bit 7:0,    RO_Luma_TB_symtc         Luma statistics Top/Bottompure
+ * symmetric for each band (8bands Horizontally),
+ */
+/* Bit 4:0,    RO_Luma_TB_sum
+ * Total score of 8x8 Luma statistics for TB like decision,
+ */
+#define DET3D_RO_MAT_CHRU_LR             ((0x1785)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_ChrU_LR_score        S2*8  LUMA statistics left right
+ * decision score for each band (8bands vertically),
+ */
+/* Bit 7:0,    RO_ChrU_LR_symtc        CHRU statistics left right pure
+ * symmetric for each band (8bands vertically),
+ */
+/* Bit 4:0,    RO_ChrU_LR_sum
+ * Total score of 8x8 ChrU statistics for LR like decision,
+ */
+#define DET3D_RO_MAT_CHRU_TB             ((0x1786)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_ChrU_TB_score        S2*8  CHRU statistics Top/Bottom
+ * decision score for each band (8bands Horizontally)
+ */
+/* Bit 7:0,    RO_ChrU_TB_symtc        CHRU statistics Top/Bottompure symmetric
+ * for each band (8bands Horizontally)
+ */
+/* Bit 4:0,    RO_ChrU_TB_sum
+ * Total score of 8x8 ChrU statistics for TB like decision
+ */
+#define DET3D_RO_MAT_CHRV_LR             ((0x1787)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_ChrV_LR_score        S2*8  CHRUstatistics left right decision
+ * score for each band (8bands vertically)
+ */
+/* Bit 7:0,    RO_ChrV_LR_symtc        CHRV statistics left right pure
+ * symmetric for each band (8bands vertically)
+ */
+/* Bit 4:0,    RO_ChrV_LR_sum
+ * Total score of 8x8 ChrV statistics for LR like decision
+ */
+#define DET3D_RO_MAT_CHRV_TB             ((0x1788)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_ChrV_TB_score        CHRV statistics Top/Bottom decision
+ * score for each band (8bands Horizontally)
+ */
+/* Bit 7:0,    RO_ChrV_TB_symtc        CHRV statistics Top/Bottompure
+ * symmetric for each band (8bands Horizontally)
+ */
+/* Bit 4:0,    RO_ChrV_TB_sum      Total score of 8x8 ChrV statistics
+ * for TB like decision
+ */
+#define DET3D_RO_MAT_HEDG_LR             ((0x1789)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Hedg_LR_score        Horizontal Edge statistics left right
+ * decision score for each band (8bands vertically)
+ */
+/* Bit 7:0,    RO_Hedg_LR_symtc        Horizontal Edge statistics left right
+ * pure symmetric for each band (8bands vertically)
+ */
+/* Bit 4:0,    RO_Hedg_LR_sum      Total score of 8x8 Hedg statistics for
+ * LR like decision
+ */
+#define DET3D_RO_MAT_HEDG_TB             ((0x178a)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Hedg_TB_score        Horizontal Edge statistics Top/Bottom
+ * decision score for each band (8bands Horizontally)
+ */
+/* Bit 7:0,    RO_Hedg_TB_symtc        Horizontal Edge statistics
+ * Top/Bottompure symmetric for each band (8bands Horizontally)
+ */
+/* Bit 4:0,    RO_Hedg_TB_sum
+ * Total score of 8x8 Hedg statistics for TB like decision
+ */
+#define DET3D_RO_MAT_VEDG_LR             ((0x178b)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Vedg_LR_score        Vertical Edge statistics left right
+ * decision score for each band (8bands vertically)
+ */
+/* Bit 7:0,    RO_Vedg_LR_symtc        Vertical Edge statistics left right
+ * pure symmetric for each band (8bands vertically)
+ */
+/* Bit 4:0,    RO_Vedg_LR_sum
+ * Total score of 8x8 Vedg statistics for LR like decision
+ */
+#define DET3D_RO_MAT_VEDG_TB             ((0x178c)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Vedg_TB_score        Vertical Edge statistics Top/Bottom
+ * decision score for each band (8bands Horizontally)
+ */
+/* Bit 7:0,    RO_Vedg_TB_symtc        Vertical Edge statistics Top/Bottompure
+ * symmetric for each band (8bands Horizontally)
+ */
+/* Bit 4:0,    RO_Vedg_TB_sum
+ * Total score of 8x8 Vedg statistics for TB like decision
+ */
+#define DET3D_RO_MAT_MOTN_LR             ((0x178d)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Motn_LR_score        Motion statistics left right decision
+ * score for each band (8bands vertically)
+ */
+/* Bit 7:0,    RO_Motn_LR_symtc        Motion statistics left right pure
+ * symmetric for each band (8bands vertically)
+ */
+/* Bit 4:0,    RO_Motn_LR_sum      Total score of 8x8 Motion statistics for
+ * LR like decision
+ */
+#define DET3D_RO_MAT_MOTN_TB             ((0x178e)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Motn_TB_score        Motion statistics Top/Bottom decision
+ * score for each band (8bands Horizontally)
+ */
+/* Bit 7:0,    RO_Motn_TB_symtc        Motion statistics Top/Bottompure
+ * symmetric for each band (8bands Horizontally)
+ */
+/* Bit 4:0,    RO_Motn_TB_sum
+ * Total score of 8x8 Motion statistics for TB like decision
+ */
+#define DET3D_RO_FRM_MOTN                ((0x178f)) /* << 2) + 0xd0100000) */
+/* Bit 15:0,   RO_Det3D_Frame_Motion   U16  frame based motion value sum for
+ * still image decision in FW.
+ */
+/* mat ram read enter addr */
+#define DET3D_RAMRD_ADDR_PORT            ((0x179a)) /* << 2) + 0xd0100000) */
+#define DET3D_RAMRD_DATA_PORT            ((0x179b)) /* << 2) + 0xd0100000) */
+#define NR2_CFR_PARA_CFG0                ((0x179c)) /* << 2) + 0xd0100000) */
+/* Bit 8,      reg_CFR_CurDif_luma_mode        Current Field Top/Bot line Luma
+ * difference calculation mode
+ */
+/* Bit 7:6,    reg_MACFR_frm_phase             U2  This will be a field based
+ * phase register that need to be set by FW phase to phase:
+ */
+/* this will be calculated based on dbdr_phase of the
+ * specific line of this frame.
+ */
+/* u1: dbdr_phase=1, center line is DB in current line;  dbdr_phase=2, center
+ * line is Dr in current line;
+ */
+/* Bit 5:4,    reg_CFR_CurDif_tran_mode        U2  Current Field Top/Bot line
+ * Luma/Chroma transition level calculation mode,
+ */
+/* Bit 3:2,    reg_CFR_alpha_mode              U2  Alpha selection mode for
+ * CFR block from curAlp and motAlp i.e.
+ *             0: motAlp; 1: (motAlp+curAlp)/2;
+ *             2: min(motAlp,curAlp); 3: max(motAlp,curAlp);
+ */
+/* Bit 1:0,    reg_CFR_Motion_Luma_mode        U2  LumaMotion Calculation
+ * mode for MA-CFR.
+ *             0: top/bot Lumma motion;
+ *             1: middle Luma Motion
+ *             2: top/bot + middle motion;
+ *             3: max(top/tot motion, middle motion)
+ */
+#define NR2_CFR_PARA_CFG1                ((0x179d)) /* << 2) + 0xd0100000) */
+/* Bit 23:16,  reg_CFR_alpha_gain          gain to map muxed curAlp and motAlp
+ * to alpha that will be used for final blending.
+ */
+/* Bit 15: 8,  reg_CFR_Motion_ofst         Offset to Motion to calculate the
+ * motAlp, e,g:motAlp= reg_CFR_Motion_ofst- Motion;This register can be seen as
+ * the level of motion that we consider it at moving.
+ */
+/* Bit  7: 0,  reg_CFR_CurDif_gain
+ * gain to CurDif to map to alpha, normalized to 32;
+ */
+/* // DET 3D REG DEFINE END //// */
+#define DI_NR_1_CTRL0                    ((0x1794)) /* << 2) + 0xd0100000) */
+#define DI_NR_1_CTRL1                    ((0x1795)) /* << 2) + 0xd0100000) */
+#define DI_NR_1_CTRL2                    ((0x1796)) /* << 2) + 0xd0100000) */
+#define DI_NR_1_CTRL3                    ((0x1797)) /* << 2) + 0xd0100000) */
+#define DI_CONTWR_X                      ((0x17a0)) /* << 2) + 0xd0100000) */
+#define DI_CONTWR_Y                      ((0x17a1)) /* << 2) + 0xd0100000) */
+#define DI_CONTWR_CTRL                   ((0x17a2)) /* << 2) + 0xd0100000) */
+#define DI_CONTPRD_X                     ((0x17a3)) /* << 2) + 0xd0100000) */
+#define DI_CONTPRD_Y                     ((0x17a4)) /* << 2) + 0xd0100000) */
+#define DI_CONTP2RD_X                    ((0x17a5)) /* << 2) + 0xd0100000) */
+#define DI_CONTP2RD_Y                    ((0x17a6)) /* << 2) + 0xd0100000) */
+#define DI_CONTRD_CTRL                   ((0x17a7)) /* << 2) + 0xd0100000) */
+#define DI_NRWR_X                        ((0x17c0)) /* << 2) + 0xd0100000) */
+#define DI_NRWR_Y                        ((0x17c1)) /* << 2) + 0xd0100000) */
+/* bit 31:30                           nrwr_words_lim */
+/* bit 29                              nrwr_rev_y */
+/* bit 28:16                           nrwr_start_y */
+/* bit 15                              nrwr_ext_en */
+/* bit 14              Nrwr bit10 mode */
+/* bit 12:0                            nrwr_end_y */
+#define DI_NRWR_CTRL                     ((0x17c2)) /* << 2) + 0xd0100000) */
+/* bit 31                              pending_ddr_wrrsp_diwr */
+/* bit 30                              nrwr_reg_swap */
+/* bit 29:26                           nrwr_burst_lim */
+/* bit 25                              nrwr_canvas_syncen */
+/* bit 24                              nrwr_no_clk_gate */
+/* bit 23:22                           nrwr_rgb_mode
+ *                                     0:422 to one canvas;
+ *                                     1:4:4:4 to one canvas;
+ */
+/* bit 21:20                           nrwr_hconv_mode */
+/* bit 19:18                           nrwr_vconv_mode */
+/* bit 17                              nrwr_swap_cbcr */
+/* bit 16                              nrwr_urgent */
+/* bit 15:8                            nrwr_canvas_index_chroma */
+/* bit 7:0                             nrwr_canvas_index_luma */
+#define DI_MTNWR_X                       ((0x17c3)) /* << 2) + 0xd0100000) */
+#define DI_MTNWR_Y                       ((0x17c4)) /* << 2) + 0xd0100000) */
+#define DI_MTNWR_CTRL                    ((0x17c5)) /* << 2) + 0xd0100000) */
+#define DI_DIWR_X                        ((0x17c6)) /* << 2) + 0xd0100000) */
+#define DI_DIWR_Y                        ((0x17c7)) /* << 2) + 0xd0100000) */
+/* bit 31:30                           diwr_words_lim */
+/* bit 29                              diwr_rev_y */
+/* bit 28:16                           diwr_start_y */
+/* bit 15                              diwr_ext_en */
+/* bit 12:0                            diwr_end_y */
+#define DI_DIWR_CTRL                     ((0x17c8)) /* << 2) + 0xd0100000) */
+/* bit 31                              pending_ddr_wrrsp_diwr */
+/* bit 30                              diwr_reg_swap */
+/* bit 29:26                           diwr_burst_lim */
+/* bit 25                              diwr_canvas_syncen */
+/* bit 24                              diwr_no_clk_gate */
+/* bit 23:22                           diwr_rgb_mode  0:422 to one canvas;
+ * 1:4:4:4 to one canvas;
+ */
+/* bit 21:20                           diwr_hconv_mode */
+/* bit 19:18                           diwr_vconv_mode */
+/* bit 17                              diwr_swap_cbcr */
+/* bit 16                              diwr_urgent */
+/* bit 15:8                            diwr_canvas_index_chroma */
+/* bit 7:0                             diwr_canvas_index_luma */
+/* `define DI_MTNCRD_X               8'hc9 */
+/* `define DI_MTNCRD_Y               8'hca */
+#define DI_MTNPRD_X                      ((0x17cb)) /* << 2) + 0xd0100000) */
+#define DI_MTNPRD_Y                      ((0x17cc)) /* << 2) + 0xd0100000) */
+#define DI_MTNRD_CTRL                    ((0x17cd)) /* << 2) + 0xd0100000) */
+#define DI_INP_GEN_REG                   ((0x17ce)) /* << 2) + 0xd0100000) */
+#define DI_INP_CANVAS0                   ((0x17cf)) /* << 2) + 0xd0100000) */
+#define DI_INP_LUMA_X0                   ((0x17d0)) /* << 2) + 0xd0100000) */
+#define DI_INP_LUMA_Y0                   ((0x17d1)) /* << 2) + 0xd0100000) */
+#define DI_INP_CHROMA_X0                 ((0x17d2)) /* << 2) + 0xd0100000) */
+#define DI_INP_CHROMA_Y0                 ((0x17d3)) /* << 2) + 0xd0100000) */
+#define DI_INP_RPT_LOOP                  ((0x17d4)) /* << 2) + 0xd0100000) */
+#define DI_INP_LUMA0_RPT_PAT             ((0x17d5)) /* << 2) + 0xd0100000) */
+#define DI_INP_CHROMA0_RPT_PAT           ((0x17d6)) /* << 2) + 0xd0100000) */
+#define DI_INP_DUMMY_PIXEL               ((0x17d7)) /* << 2) + 0xd0100000) */
+#define DI_INP_LUMA_FIFO_SIZE            ((0x17d8)) /* << 2) + 0xd0100000) */
+#define DI_INP_RANGE_MAP_Y               ((0x17ba)) /* << 2) + 0xd0100000) */
+#define DI_INP_RANGE_MAP_CB              ((0x17bb)) /* << 2) + 0xd0100000) */
+#define DI_INP_RANGE_MAP_CR              ((0x17bc)) /* << 2) + 0xd0100000) */
+#define DI_INP_GEN_REG2                  ((0x1791)) /* << 2) + 0xd0100000) */
+#define DI_INP_FMT_CTRL                  ((0x17d9)) /* << 2) + 0xd0100000) */
+#define DI_INP_FMT_W                     ((0x17da)) /* << 2) + 0xd0100000) */
+#define DI_MEM_GEN_REG                   ((0x17db)) /* << 2) + 0xd0100000) */
+#define DI_MEM_CANVAS0                   ((0x17dc)) /* << 2) + 0xd0100000) */
+#define DI_MEM_LUMA_X0                   ((0x17dd)) /* << 2) + 0xd0100000) */
+#define DI_MEM_LUMA_Y0                   ((0x17de)) /* << 2) + 0xd0100000) */
+#define DI_MEM_CHROMA_X0                 ((0x17df)) /* << 2) + 0xd0100000) */
+#define DI_MEM_CHROMA_Y0                 ((0x17e0)) /* << 2) + 0xd0100000) */
+#define DI_MEM_RPT_LOOP                  ((0x17e1)) /* << 2) + 0xd0100000) */
+#define DI_MEM_LUMA0_RPT_PAT             ((0x17e2)) /* << 2) + 0xd0100000) */
+#define DI_MEM_CHROMA0_RPT_PAT           ((0x17e3)) /* << 2) + 0xd0100000) */
+#define DI_MEM_DUMMY_PIXEL               ((0x17e4)) /* << 2) + 0xd0100000) */
+#define DI_MEM_LUMA_FIFO_SIZE            ((0x17e5)) /* << 2) + 0xd0100000) */
+#define DI_MEM_RANGE_MAP_Y               ((0x17bd)) /* << 2) + 0xd0100000) */
+#define DI_MEM_RANGE_MAP_CB              ((0x17be)) /* << 2) + 0xd0100000) */
+#define DI_MEM_RANGE_MAP_CR              ((0x17bf)) /* << 2) + 0xd0100000) */
+#define DI_MEM_GEN_REG2                  ((0x1792)) /* << 2) + 0xd0100000) */
+#define DI_MEM_FMT_CTRL                  ((0x17e6)) /* << 2) + 0xd0100000) */
+#define DI_MEM_FMT_W                     ((0x17e7)) /* << 2) + 0xd0100000) */
+/* #define DI_IF1_GEN_REG                   ((0x17e8)) + 0xd0100000) */
+#define DI_IF1_CANVAS0                   ((0x17e9)) /* << 2) + 0xd0100000) */
+#define DI_IF1_LUMA_X0                   ((0x17ea)) /* << 2) + 0xd0100000) */
+#define DI_IF1_LUMA_Y0                   ((0x17eb)) /* << 2) + 0xd0100000) */
+#define DI_IF1_CHROMA_X0                 ((0x17ec)) /* << 2) + 0xd0100000) */
+#define DI_IF1_CHROMA_Y0                 ((0x17ed)) /* << 2) + 0xd0100000) */
+#define DI_IF1_RPT_LOOP                  ((0x17ee)) /* << 2) + 0xd0100000) */
+#define DI_IF1_LUMA0_RPT_PAT             ((0x17ef)) /* << 2) + 0xd0100000) */
+#define DI_IF1_CHROMA0_RPT_PAT           ((0x17f0)) /* << 2) + 0xd0100000) */
+#define DI_IF1_DUMMY_PIXEL               ((0x17f1)) /* << 2) + 0xd0100000) */
+#define DI_IF1_LUMA_FIFO_SIZE            ((0x17f2)) /* << 2) + 0xd0100000) */
+#define DI_IF1_RANGE_MAP_Y               ((0x17fc)) /* << 2) + 0xd0100000) */
+#define DI_IF1_RANGE_MAP_CB              ((0x17fd)) /* << 2) + 0xd0100000) */
+#define DI_IF1_RANGE_MAP_CR              ((0x17fe)) /* << 2) + 0xd0100000) */
+#define DI_IF1_GEN_REG2                  ((0x1790)) /* << 2) + 0xd0100000) */
+#define DI_IF1_FMT_CTRL                  ((0x17f3)) /* << 2) + 0xd0100000) */
+#define DI_IF1_FMT_W                     ((0x17f4)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_GEN_REG                 ((0x17f5)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_CANVAS0                 ((0x17f6)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_LUMA_X0                 ((0x17f7)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_LUMA_Y0                 ((0x17f8)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_CHROMA_X0               ((0x17f9)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_CHROMA_Y0               ((0x17fa)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_RPT_LOOP                ((0x17fb)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_LUMA0_RPT_PAT           ((0x17b0)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_CHROMA0_RPT_PAT         ((0x17b1)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_DUMMY_PIXEL             ((0x17b2)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_LUMA_FIFO_SIZE          ((0x17b3)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_RANGE_MAP_Y             ((0x17b4)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_RANGE_MAP_CB            ((0x17b5)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_RANGE_MAP_CR            ((0x17b6)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_GEN_REG2                ((0x17b7)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_FMT_CTRL                ((0x17b8)) /* << 2) + 0xd0100000) */
+#define DI_CHAN2_FMT_W                   ((0x17b9)) /* << 2) + 0xd0100000) */
+#define DI_CANVAS_URGENT0                ((0x170a)) /* << 2) + 0xd0100000) */
+#define DI_CANVAS_URGENT1                ((0x170b)) /* << 2) + 0xd0100000) */
+#define DI_MTN_CTRL                      ((0x170b)) /* << 2) + 0xd0100000) */
+#define DI_CANVAS_URGENT2                ((0x170e)) /* << 2) + 0xd0100000) */
+
+#define VD1_IF0_GEN_REG                                    0x1a50
+/* ((0x1a50  << 2) + 0xd0100000) */
+#define VD1_IF0_LUMA_FIFO_SIZE          0x1a63
+/* ((0x1a63  << 2) + 0xd0100000) */
+
+#define VIU_VD1_FMT_CTRL                           0x1a68
+/* ((0x1a68  << 2) + 0xd0100000) */
+/* Bit 31    it true, disable clock, otherwise enable clock        */
+/* Bit 30    soft rst bit */
+/* Bit 28    if true, horizontal formatter use repeating to */
+/* generete pixel, otherwise use bilinear interpolation */
+/* Bit 27:24 horizontal formatter initial phase */
+/* Bit 23    horizontal formatter repeat pixel 0 enable */
+/* Bit 22:21 horizontal Y/C ratio, 00: 1:1, 01: 2:1, 10: 4:1 */
+/* Bit 20    horizontal formatter enable */
+/* Bit 19    if true, always use phase0 while vertical formater, */
+/* meaning always repeat data, no interpolation */
+/* Bit 18    if true, disable vertical formatter chroma repeat last line */
+/* Bit 17    veritcal formatter dont need repeat */
+/* line on phase0, 1: enable, 0: disable */
+/* Bit 16    veritcal formatter repeat line 0 enable */
+/* Bit 15:12 vertical formatter skip line num at the beginning */
+/* Bit 11:8  vertical formatter initial phase */
+/* Bit 7:1   vertical formatter phase step (3.4) */
+/* Bit 0     vertical formatter enable */
+#define VIU_VD1_FMT_W                              0x1a69
+/* ((0x1a69  << 2) + 0xd0100000) */
+/* Bit 27:16  horizontal formatter width */
+/* Bit 11:0   vertical formatter width */
+
+#define VD1_IF0_GEN_REG2               0x1a6d
+
+#define DI_INP_GEN_REG3                 0x20a8
+               /* 0xd01082a0 */
+/*bit9:8       bit mode: 0 = 8bits, 1=10bits 422,  2 = 10bits 444 */
+#define DI_MEM_GEN_REG3                 0x20a9
+               /* 0xd01082a4 */
+/*bit9:8       bit mode: 0 = 8bits, 1=10bits 422,  2 = 10bits 444 */
+#define DI_CHAN2_GEN_REG3               0x20aa
+               /* 0xd01082a8 */
+/* dnr  Base Addr: 0xd0100000 */
+#define DNR_CTRL                         ((0x2d00))
+/* Bit 31:17,        reserved */
+/* Bit 16,            reg_dnr_en,
+ * dnr enable                  . unsigned  , default = 1
+ */
+/* Bit 15,            reg_dnr_db_vdbstep                          ,
+ * vdb step, 0: 4, 1: 8        . unsigned  , default = 1
+ */
+/* Bit 14,            reg_dnr_db_vdbprten                         ,
+ * vdb protectoin enable       . unsigned  , default = 1
+ */
+/* Bit 13,            reg_dnr_gbs_difen                           ,
+ * enable dif (between LR and LL/RR) condition for gbs stat..
+ * unsigned  , default = 0
+ */
+/* Bit 12,            reg_dnr_luma_en                             ,
+ * enable ycbcr2luma module    . unsigned  , default = 1
+ */
+/* Bit 11:10,        reg_dnr_db_mod                              ,
+ * deblocking mode, 0: disable, 1: horizontal deblocking, 2: vertical
+ * deblocking, 3: horizontal & vertical deblocking. unsigned  , default = 3
+ */
+/* Bit  9,            reg_dnr_db_chrmen                           ,
+ * enable chroma deblocking    . unsigned  , default = 1
+ */
+/* Bit  8,            reg_dnr_hvdif_mod                           ,
+ * 0: calc. difs by original Y, 1: by new luma. unsigned  , default = 1
+ */
+/* Bit  7,            reserved */
+/* Bit  6: 4,        reg_dnr_demo_lften                          ,
+ * b0: Y b1:U b2:V             . unsigned  , default = 7
+ */
+/* Bit  3,            reserved */
+/* Bit  2: 0,        reg_dnr_demo_rgten                          ,
+ * b0: Y b1:U b2:V             . unsigned  , default = 7
+ */
+#define DNR_HVSIZE                       ((0x2d01))
+/* Bit 31:29,        reserved */
+/* Bit 28:16,        reg_dnr_hsize                               ,
+ * hsize                       . unsigned  , default = 0
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 0,        reg_dnr_vsize                               ,
+ * vsize                       . unsigned  , default = 0
+ */
+#define DNR_DBLK_BLANK_NUM                         ((0x2d02))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_dblk_hblank_num                         ,
+ * deblock hor blank num       . unsigned  , default = 16
+ */
+/* Bit  7: 0,        reg_dblk_vblank_num                         ,
+ * deblock ver blank num       . unsigned  , default = 45
+ */
+#define DNR_BLK_OFFST                              ((0x2d03))
+/* Bit 31: 7,        reserved */
+/* Bit  6: 4,        reg_dnr_hbofst                              ,
+ * horizontal block offset may provide by software calc.. unsigned  ,
+ * default = 0
+ */
+/* Bit  3,            reserved */
+/* Bit  2: 0,        reg_dnr_vbofst                              ,
+ * vertical block offset may provide by software calc.. unsigned  , default = 0
+ */
+#define DNR_GBS                                    ((0x2d04))
+/* Bit 31: 2,        reserved */
+/* Bit  1: 0,        reg_dnr_gbs                                 ,
+ * global block strength may update by software calc.. unsigned  , default = 0
+ */
+#define DNR_HBOFFST_STAT                           ((0x2d05))
+/* Bit 31:24,        reg_dnr_hbof_difthd                         ,
+ * dif threshold (>=) between LR and LL/RR. unsigned  , default = 2
+ */
+/* Bit 23:16,        reg_dnr_hbof_edgethd                        ,
+ * edge threshold (<=) for LR  . unsigned  , default = 32
+ */
+/* Bit 15: 8,        reg_dnr_hbof_flatthd                        ,
+ * flat threshold (>=) for LR  . unsigned  , default = 0
+ */
+/* Bit  7,            reserved */
+/* Bit  6: 4,        reg_dnr_hbof_delta                          ,
+ * delta for weighted bin accumulator. unsigned  , default = 1
+ */
+/* Bit  3,            reserved */
+/* Bit  2: 0,        reg_dnr_hbof_statmod                        ,
+ * statistic mode for horizontal block offset, 0: count flags for 8-bin,
+ * 1: count LRs for 8-bin, 2: count difs for 8-bin,
+ * 3: count weighted flags for 8-bin, 4: count flags for first 32-bin,
+ * 5: count LRs for first 32-bin, 6 or 7: count difs for first 32-bin.
+ * unsigned  , default = 2
+ */
+#define DNR_VBOFFST_STAT                           ((0x2d06))
+/* Bit 31:24,        reg_dnr_vbof_difthd                         ,
+ * dif threshold (>=) between Up and Dw. unsigned  , default = 1
+ */
+/* Bit 23:16,        reg_dnr_vbof_edgethd                        ,
+ * edge threshold (<=) for Up/Dw. unsigned  , default = 16
+ */
+/* Bit 15: 8,        reg_dnr_vbof_flatthd                        ,
+ * flat threshold (>=) for Up/Dw. unsigned  , default = 0
+ */
+/* Bit  7,            reserved */
+/* Bit  6: 4,        reg_dnr_vbof_delta                          ,
+ * delta for weighted bin accumulator. unsigned  , default = 1
+ */
+/* Bit  3,            reserved */
+/* Bit  2: 0,        reg_dnr_vbof_statmod                        ,
+ * statistic mode for vertical block offset, 0: count flags for 8-bin,
+ * 1: count Ups for 8-bin, 2: count difs for 8-bin, 3: count weighted
+ * flags for 8-bin, 4: count flags for first 32-bin, 5: count Ups for
+ * first 32-bin, 6 or 7: count difs for first 32-bin. unsigned  , default = 2
+ */
+#define DNR_GBS_STAT                               ((0x2d07))
+/* Bit 31:24,        reg_dnr_gbs_edgethd                         ,
+ * edge threshold (<=) for LR  . unsigned  , default = 32
+ */
+/* Bit 23:16,        reg_dnr_gbs_flatthd                         ,
+ * flat threshold (>=) for LR  . unsigned  , default = 0
+ */
+/* Bit 15: 8,        reg_dnr_gbs_varthd                          ,
+ * variation threshold (<=) for Lvar/Rvar. unsigned  , default = 16
+ */
+/* Bit  7: 0,        reg_dnr_gbs_difthd                          ,
+ * dif threshold (>=) between LR and LL/RR. unsigned  , default = 2
+ */
+#define DNR_STAT_X_START_END                       ((0x2d08))
+/* Bit 31:30,        reserved */
+/* Bit 29:16,        reg_dnr_stat_xst    . unsigned  , default = 24 */
+/* Bit 15:14,        reserved */
+/* Bit 13: 0,        reg_dnr_stat_xed    . unsigned  , default = HSIZE - 25 */
+#define DNR_STAT_Y_START_END                       ((0x2d09))
+/* Bit 31:30,        reserved */
+/* Bit 29:16,        reg_dnr_stat_yst    . unsigned  , default = 24 */
+/* Bit 15:14,        reserved */
+/* Bit 13: 0,        reg_dnr_stat_yed    . unsigned  , default = VSIZE - 25 */
+#define DNR_LUMA                                   ((0x2d0a))
+/* Bit 31:27,        reserved */
+/* Bit 26:24,        reg_dnr_luma_sqrtshft                       ,
+ * left shift for fast squart of chroma, [0, 4]. unsigned  , default = 2
+ */
+/* Bit 23:21,        reserved */
+/* Bit 20:16,        reg_dnr_luma_sqrtoffst                      ,
+ * offset for fast squart of chroma. signed    , default = 0
+ */
+/* Bit 15,            reserved */
+/* Bit 14:12,        reg_dnr_luma_wcmod                          ,
+ * theta related to warm/cool segment line, 0: 0, 1: 45, 2: 90, 3: 135,
+ * 4: 180, 5: 225, 6: 270, 7: 315. . unsigned  , default = 3
+ */
+/* Bit 11: 8,        reg_dnr_luma_cshft                          ,
+ * shift for calc. delta part, 0~8,  . unsigned  , default = 8
+ */
+/* Bit  7: 6,        reserved */
+/* Bit  5: 0,        reg_dnr_luma_cgain                          ,
+ * final gain for delta part, 32 normalized to "1". unsigned  , default = 4
+ */
+#define DNR_DB_YEDGE_THD                           ((0x2d0b))
+/* Bit 31:24,        reg_dnr_db_yedgethd0                        ,
+ * edge threshold0 for luma    . unsigned  , default = 12
+ */
+/* Bit 23:16,        reg_dnr_db_yedgethd1                        ,
+ * edge threshold1 for luma    . unsigned  , default = 15
+ */
+/* Bit 15: 8,        reg_dnr_db_yedgethd2                        ,
+ * edge threshold2 for luma    . unsigned  , default = 18
+ */
+/* Bit  7: 0,        reg_dnr_db_yedgethd3                        ,
+ * edge threshold3 for luma    . unsigned  , default = 25
+ */
+#define DNR_DB_CEDGE_THD                           ((0x2d0c))
+/* Bit 31:24,        reg_dnr_db_cedgethd0                        ,
+ * edge threshold0 for chroma  . unsigned  , default = 12
+ */
+/* Bit 23:16,        reg_dnr_db_cedgethd1                        ,
+ * edge threshold1 for chroma  . unsigned  , default = 15
+ */
+/* Bit 15: 8,        reg_dnr_db_cedgethd2                        ,
+ * edge threshold2 for chroma  . unsigned  , default = 18
+ */
+/* Bit  7: 0,        reg_dnr_db_cedgethd3                        ,
+ * edge threshold3 for chroma  . unsigned  , default = 25
+ */
+#define DNR_DB_HGAP                                ((0x2d0d))
+/* Bit 31:24,        reserved */
+/* Bit 23:16,        reg_dnr_db_hgapthd                          ,
+ * horizontal gap thd (<=) for very sure blockiness . unsigned  , default = 8
+ */
+/* Bit 15: 8,        reg_dnr_db_hgapdifthd                       ,
+ * dif thd between hgap and lft/rgt hdifs. unsigned  , default = 1
+ */
+/* Bit  7: 1,        reserved */
+/* Bit  0,            reg_dnr_db_hgapmod                          ,
+ * horizontal gap calc. mode, 0: just use current col x,
+ * 1: find max between (x-1, x, x+1) . unsigned  , default = 0
+ */
+#define DNR_DB_HBS                                 ((0x2d0e))
+/* Bit 31: 6,        reserved */
+/* Bit  5: 4,        reg_dnr_db_hbsup                            ,
+ * horizontal bs up value      . unsigned  , default = 1
+ */
+/* Bit  3: 2,        reg_dnr_db_hbsmax                           ,
+ * max value of hbs for global control. unsigned  , default = 3
+ */
+/* Bit  1: 0,        reg_dnr_db_hgbsthd                          ,
+ * gbs thd (>=) for hbs calc.  . unsigned  , default = 1
+ */
+#define DNR_DB_HACT                                ((0x2d0f))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_dnr_db_hactthd0                         ,
+ * thd0 of hact, for block classification. unsigned  , default = 10
+ */
+/* Bit  7: 0,        reg_dnr_db_hactthd1                         ,
+ * thd1 of hact, for block classification. unsigned  , default = 32
+ */
+#define DNR_DB_YHDELTA_GAIN                        ((0x2d10))
+/* Bit 31:27,        reserved */
+/* Bit 26:24,        reg_dnr_db_yhdeltagain1                     ,
+ * (p1-q1) gain for Y's delta calc. when bs=1, normalized 8 as "1" .
+ * unsigned  , default = 2
+ */
+/* Bit 23,            reserved */
+/* Bit 22:20,        reg_dnr_db_yhdeltagain2                     ,
+ * (p1-q1) gain for Y's delta calc. when bs=2, normalized 8 as "1" .
+ * unsigned  , default = 0
+ */
+/* Bit 19,            reserved */
+/* Bit 18:16,        reg_dnr_db_yhdeltagain3                     ,
+ * (p1-q1) gain for Y's delta calc. when bs=3, normalized 8 as "1" .
+ * unsigned  , default = 0
+ */
+/* Bit 15,            reserved */
+/* Bit 14: 8,        reg_dnr_db_yhdeltaadjoffst                  ,
+ * offset for adjust Y's hdelta (-64, 63). signed    , default = 0
+ */
+/* Bit  7: 6,        reserved */
+/* Bit  5: 0,        reg_dnr_db_yhdeltaadjgain                   ,
+ * gain for adjust Y's hdelta, normalized 32 as "1" . unsigned  , default = 32
+ */
+#define DNR_DB_YHDELTA2_GAIN                       ((0x2d11))
+/* Bit 31:30,        reserved */
+/* Bit 29:24,        reg_dnr_db_yhdelta2gain2                    ,
+ * gain for bs=2's adjust Y's hdelta2, normalized 64 as "1" .
+ * unsigned  , default = 8
+ */
+/* Bit 23:21,        reserved */
+/* Bit 20:16,        reg_dnr_db_yhdelta2offst2                   ,
+ * offset for bs=2's adjust Y's hdelta2 (-16, 15). signed    , default = 0
+ */
+/* Bit 15:14,        reserved */
+/* Bit 13: 8,        reg_dnr_db_yhdelta2gain3                    ,
+ * gain for bs=3's adjust Y's hdelta2, normalized 64 as "1" .
+ * unsigned , default = 4
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_db_yhdelta2offst3                   ,
+ * offset for bs=3's adjust Y's hdelta2 (-16, 15). signed    , default = 0
+ */
+#define DNR_DB_CHDELTA_GAIN                        ((0x2d12))
+/* Bit 31:27,        reserved */
+/* Bit 26:24,        reg_dnr_db_chdeltagain1                     ,
+ * (p1-q1) gain for UV's delta calc. when bs=1, normalized 8 as "1".
+ * unsigned  , default = 2
+ */
+/* Bit 23,            reserved */
+/* Bit 22:20,        reg_dnr_db_chdeltagain2                     ,
+ * (p1-q1) gain for UV's delta calc. when bs=2,
+ * normalized 8 as "1". unsigned  , default = 0
+ */
+/* Bit 19,            reserved */
+/* Bit 18:16,        reg_dnr_db_chdeltagain3                     ,
+ * (p1-q1) gain for UV's delta calc. when bs=3, normalized 8 as "1".
+ * unsigned  , default = 0
+ */
+/* Bit 15,            reserved */
+/* Bit 14: 8,        reg_dnr_db_chdeltaadjoffst                  ,
+ * offset for adjust UV's hdelta (-64, 63). signed    , default = 0
+ */
+/* Bit  7: 6,        reserved */
+/* Bit  5: 0,        reg_dnr_db_chdeltaadjgain                   ,
+ * gain for adjust UV's hdelta, normalized 32 as "1". unsigned  , default = 32
+ */
+#define DNR_DB_CHDELTA2_GAIN                       ((0x2d13))
+/* Bit 31:30,        reserved */
+/* Bit 29:24,        reg_dnr_db_chdelta2gain2                    ,
+ * gain for bs=2's adjust UV's hdelta2, normalized 64 as "1" .
+ * unsigned  , default = 8
+ */
+/* Bit 23:21,        reserved */
+/* Bit 20:16,        reg_dnr_db_chdelta2offst2                   ,
+ * offset for bs=2's adjust UV's hdelta2 (-16, 15). signed    , default = 0
+ */
+/* Bit 15:14,        reserved */
+/* Bit 13: 8,        reg_dnr_db_chdelta2gain3                    ,
+ * gain for bs=2's adjust UV's hdelta2, normalized 64 as "1" .
+ * unsigned , default = 4
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_db_chdelta2offst3                   ,
+ * offset for bs=2's adjust UV's hdelta2 (-16, 15). signed    , default = 0
+ */
+#define DNR_DB_YC_VEDGE_THD                        ((0x2d14))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_dnr_db_yvedgethd                        ,
+ * special Y's edge thd for vdb. unsigned  , default = 12
+ */
+/* Bit  7: 0,        reg_dnr_db_cvedgethd                        ,
+ * special UV's edge thd for vdb. unsigned  , default = 12
+ */
+#define DNR_DB_VBS_MISC                            ((0x2d15))
+/* Bit 31:24,        reg_dnr_db_vgapthd                          ,
+ * vertical gap thd (<=) for very sure blockiness . unsigned  , default = 8
+ */
+/* Bit 23:16,        reg_dnr_db_vactthd                          ,
+ * thd of vact, for block classification . unsigned  , default = 10
+ */
+/* Bit 15: 8,        reg_dnr_db_vgapdifthd                       ,
+ * dif thd between vgap and vact. unsigned  , default = 4
+ */
+/* Bit  7: 4,        reserved */
+/* Bit  3: 2,        reg_dnr_db_vbsmax                           ,
+ * max value of vbs for global control. unsigned  , default = 2
+ */
+/* Bit  1: 0,        reg_dnr_db_vgbsthd                          ,
+ * gbs thd (>=) for vbs calc.  . unsigned  , default = 1
+ */
+#define DNR_DB_YVDELTA_GAIN                        ((0x2d16))
+/* Bit 31:30,        reserved */
+/* Bit 29:24,        reg_dnr_db_yvdeltaadjgain                   ,
+ * gain for adjust Y's vdelta, normalized 32 as "1". unsigned  , default = 32
+ */
+/* Bit 23,            reserved */
+/* Bit 22:16,        reg_dnr_db_yvdeltaadjoffst                  ,
+ * offset for adjust Y's vdelta (-64, 63). signed    , default = 0
+ */
+/* Bit 15:14,        reserved */
+/* Bit 13: 8,        reg_dnr_db_yvdelta2gain                     ,
+ * gain for adjust Y's vdelta2, normalized 64 as "1". unsigned  , default = 8
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_db_yvdelta2offst                    ,
+ * offset for adjust Y's vdelta2 (-16, 15). signed    , default = 0
+ */
+#define DNR_DB_CVDELTA_GAIN                        ((0x2d17))
+/* Bit 31:30,        reserved */
+/* Bit 29:24,        reg_dnr_db_cvdeltaadjgain                   ,
+ * gain for adjust UV's vdelta, normalized 32 as "1". unsigned  , default = 32
+ */
+/* Bit 23,            reserved */
+/* Bit 22:16,        reg_dnr_db_cvdeltaadjoffst                  ,
+ * offset for adjust UV's vdelta (-64, 63). signed    , default = 0
+ */
+/* Bit 15:14,        reserved */
+/* Bit 13: 8,        reg_dnr_db_cvdelta2gain                     ,
+ * gain for adjust UV's vdelta2, normalized 64 as "1". unsigned  , default = 8
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_db_cvdelta2offst                    ,
+ * offset for adjust UV's vdelta2 (-16, 15). signed    , default = 0
+ */
+#define DNR_RO_GBS_STAT_LR                         ((0x2d18))
+/* Bit 31: 0,        ro_gbs_stat_lr
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_GBS_STAT_LL                         ((0x2d19))
+/* Bit 31: 0,        ro_gbs_stat_ll
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_GBS_STAT_RR                         ((0x2d1a))
+/* Bit 31: 0,        ro_gbs_stat_rr
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_GBS_STAT_DIF                        ((0x2d1b))
+/* Bit 31: 0,        ro_gbs_stat_dif
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_GBS_STAT_CNT                        ((0x2d1c))
+/* Bit 31: 0,        ro_gbs_stat_cnt
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_HBOF_STAT_CNT_0                     ((0x2d1d))
+/* Bit 31: 0,        ro_hbof_stat_cnt0
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_HBOF_STAT_CNT_1                     ((0x2d1e))
+/* Bit 31: 0,        ro_hbof_stat_cnt1
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_HBOF_STAT_CNT_2                     ((0x2d1f))
+/* Bit 31: 0,        ro_hbof_stat_cnt2
+ * . unsigned  , default = 0
+ */
+#define DNR_RO_HBOF_STAT_CNT_3                     ((0x2d20))
+/* Bit 31: 0,        ro_hbof_stat_cnt3  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_4                     ((0x2d21))
+/* Bit 31: 0,        ro_hbof_stat_cnt4  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_5                     ((0x2d22))
+/* Bit 31: 0,        ro_hbof_stat_cnt5  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_6                     ((0x2d23))
+/* Bit 31: 0,        ro_hbof_stat_cnt6  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_7                     ((0x2d24))
+/* Bit 31: 0,        ro_hbof_stat_cnt7  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_8                     ((0x2d25))
+/* Bit 31: 0,        ro_hbof_stat_cnt8  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_9                     ((0x2d26))
+/* Bit 31: 0,        ro_hbof_stat_cnt9  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_10                    ((0x2d27))
+/* Bit 31: 0,        ro_hbof_stat_cnt10 . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_11                    ((0x2d28))
+/* Bit 31: 0,        ro_hbof_stat_cnt11 . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_12                    ((0x2d29))
+/* Bit 31: 0,        ro_hbof_stat_cnt12 . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_13                    ((0x2d2a))
+/* Bit 31: 0,        ro_hbof_stat_cnt13 . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_14                    ((0x2d2b))
+/* Bit 31: 0,        ro_hbof_stat_cnt14  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_15                    ((0x2d2c))
+/* Bit 31: 0,        ro_hbof_stat_cnt15  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_16                    ((0x2d2d))
+/* Bit 31: 0,        ro_hbof_stat_cnt16  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_17                    ((0x2d2e))
+/* Bit 31: 0,        ro_hbof_stat_cnt17  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_18                    ((0x2d2f))
+/* Bit 31: 0,        ro_hbof_stat_cnt18  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_19                    ((0x2d30))
+/* Bit 31: 0,        ro_hbof_stat_cnt19  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_20                    ((0x2d31))
+/* Bit 31: 0,        ro_hbof_stat_cnt20  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_21                    ((0x2d32))
+/* Bit 31: 0,        ro_hbof_stat_cnt21  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_22                    ((0x2d33))
+/* Bit 31: 0,        ro_hbof_stat_cnt22  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_23                    ((0x2d34))
+/* Bit 31: 0,        ro_hbof_stat_cnt23  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_24                    ((0x2d35))
+/* Bit 31: 0,        ro_hbof_stat_cnt24  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_25                    ((0x2d36))
+/* Bit 31: 0,        ro_hbof_stat_cnt25  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_26                    ((0x2d37))
+/* Bit 31: 0,        ro_hbof_stat_cnt26  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_27                    ((0x2d38))
+/* Bit 31: 0,        ro_hbof_stat_cnt27  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_28                    ((0x2d39))
+/* Bit 31: 0,        ro_hbof_stat_cnt28  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_29                    ((0x2d3a))
+/* Bit 31: 0,        ro_hbof_stat_cnt29  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_30                    ((0x2d3b))
+/* Bit 31: 0,        ro_hbof_stat_cnt30  . unsigned  , default = 0 */
+#define DNR_RO_HBOF_STAT_CNT_31                    ((0x2d3c))
+/* Bit 31: 0,        ro_hbof_stat_cnt31  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_0                     ((0x2d3d))
+/* Bit 31: 0,        ro_vbof_stat_cnt0  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_1                     ((0x2d3e))
+/* Bit 31: 0,        ro_vbof_stat_cnt1  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_2                     ((0x2d3f))
+/* Bit 31: 0,        ro_vbof_stat_cnt2  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_3                     ((0x2d40))
+/* Bit 31: 0,        ro_vbof_stat_cnt3  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_4                     ((0x2d41))
+/* Bit 31: 0,        ro_vbof_stat_cnt4  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_5                     ((0x2d42))
+/* Bit 31: 0,        ro_vbof_stat_cnt5  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_6                     ((0x2d43))
+/* Bit 31: 0,        ro_vbof_stat_cnt6  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_7                     ((0x2d44))
+/* Bit 31: 0,        ro_vbof_stat_cnt7  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_8                     ((0x2d45))
+/* Bit 31: 0,        ro_vbof_stat_cnt8  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_9                     ((0x2d46))
+/* Bit 31: 0,        ro_vbof_stat_cnt9  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_10                    ((0x2d47))
+/* Bit 31: 0,        ro_vbof_stat_cnt10  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_11                    ((0x2d48))
+/* Bit 31: 0,        ro_vbof_stat_cnt11  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_12                    ((0x2d49))
+/* Bit 31: 0,        ro_vbof_stat_cnt12  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_13                    ((0x2d4a))
+/* Bit 31: 0,        ro_vbof_stat_cnt13  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_14                    ((0x2d4b))
+/* Bit 31: 0,        ro_vbof_stat_cnt14  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_15                    ((0x2d4c))
+/* Bit 31: 0,        ro_vbof_stat_cnt15  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_16                    ((0x2d4d))
+/* Bit 31: 0,        ro_vbof_stat_cnt16  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_17                    ((0x2d4e))
+/* Bit 31: 0,        ro_vbof_stat_cnt17  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_18                    ((0x2d4f))
+/* Bit 31: 0,        ro_vbof_stat_cnt18  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_19                    ((0x2d50))
+/* Bit 31: 0,        ro_vbof_stat_cnt19  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_20                    ((0x2d51))
+/* Bit 31: 0,        ro_vbof_stat_cnt20  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_21                    ((0x2d52))
+/* Bit 31: 0,        ro_vbof_stat_cnt21  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_22                    ((0x2d53))
+/* Bit 31: 0,        ro_vbof_stat_cnt22  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_23                    ((0x2d54))
+/* Bit 31: 0,        ro_vbof_stat_cnt23  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_24                    ((0x2d55))
+/* Bit 31: 0,        ro_vbof_stat_cnt24  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_25                    ((0x2d56))
+/* Bit 31: 0,        ro_vbof_stat_cnt25  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_26                    ((0x2d57))
+/* Bit 31: 0,        ro_vbof_stat_cnt26  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_27                    ((0x2d58))
+/* Bit 31: 0,        ro_vbof_stat_cnt27  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_28                    ((0x2d59))
+/* Bit 31: 0,        ro_vbof_stat_cnt28  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_29                    ((0x2d5a))
+/* Bit 31: 0,        ro_vbof_stat_cnt29  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_30                    ((0x2d5b))
+/* Bit 31: 0,        ro_vbof_stat_cnt30  . unsigned  , default = 0 */
+#define DNR_RO_VBOF_STAT_CNT_31                    ((0x2d5c))
+/* Bit 31: 0,        ro_vbof_stat_cnt31  . unsigned  , default = 0 */
+#define DNR_DM_CTRL                                ((0x2d60))
+/* Bit 31:13,        reserved */
+/* Bit 12,            reg_dnr_dm_fedgeflg_en                      ,
+ * enable edge flag calc. of each frame. unsigned  , default = 1
+ */
+/* Bit 11,            reg_dnr_dm_fedgeflg_cl                      ,
+ * clear frame edge flag if needed. unsigned  , default = 1
+ */
+/* Bit 10,            reg_dnr_dm_fedgeflg_df                      ,
+ * user defined edge when reg_dnr_dm_fedgeflg_en=0, default = 1
+ */
+/* Bit  9,            reg_dnr_dm_en                               ,
+ * enable demosquito function  . unsigned  , default = 1
+ */
+/* Bit  8,            reg_dnr_dm_chrmen                           ,
+ * enable chrome processing for demosquito. unsigned  , default = 1
+ */
+/* Bit  7: 6,        reg_dnr_dm_level                            ,
+ * demosquito level            . unsigned  , default = 3
+ */
+/* Bit  5: 4,        reg_dnr_dm_leveldw0                         ,
+ * level down when gbs is small. unsigned  , default = 1
+ */
+/* Bit  3: 2,        reg_dnr_dm_leveldw1                         ,
+ * level down for no edge/flat blocks. unsigned  , default = 1
+ */
+/* Bit  1: 0,        reg_dnr_dm_gbsthd                           ,
+ * small/large threshold for gbs (<=). unsigned  , default = 0
+ */
+#define DNR_DM_NR_BLND                             ((0x2d61))
+/* Bit 31:25,        reserved */
+/* Bit 24,            reg_dnr_dm_defalpen                         ,
+ * enable user define alpha for dm & nr blend. unsigned  , default = 0
+ */
+/* Bit 23:16,        reg_dnr_dm_defalp                           ,
+ * user define alpha for dm & nr blend if enable. unsigned  , default = 0
+ */
+/* Bit 15:14,        reserved */
+/* Bit 13: 8,        reg_dnr_dm_alpgain                          ,
+ * gain for nr/dm alpha, normalized 32 as "1". unsigned  , default = 32
+ */
+/* Bit  7: 0,        reg_dnr_dm_alpoffst                         ,
+ * (-128, 127), offset for nr/dm alpha. signed    , default = 0
+ */
+#define DNR_DM_RNG_THD                             ((0x2d62))
+/* Bit 31:24,        reserved */
+/* Bit 23:16,        reg_dnr_dm_rngminthd  . unsigned  , default = 2 */
+/* Bit 15: 8,        reg_dnr_dm_rngmaxthd  . unsigned  , default = 64 */
+/* Bit  7: 0,        reg_dnr_dm_rngdifthd  . unsigned  , default = 4 */
+#define DNR_DM_RNG_GAIN_OFST                       ((0x2d63))
+/* Bit 31:14,        reserved */
+/* Bit 13: 8,        reg_dnr_dm_rnggain                          ,
+ * normalized 16 as "1"        . unsigned  , default = 16
+ */
+/* Bit  7: 6,        reserved */
+/* Bit  5: 0,        reg_dnr_dm_rngofst  . unsigned  , default = 0 */
+#define DNR_DM_DIR_MISC                            ((0x2d64))
+/* Bit 31:30,        reserved */
+/* Bit 29,            reg_dnr_dm_diralpen     . unsigned  , default = 1 */
+/* Bit 28:24,        reg_dnr_dm_diralpgain    . unsigned  , default = 0 */
+/* Bit 23:22,        reserved */
+/* Bit 21:16,        reg_dnr_dm_diralpofst    . unsigned  , default = 0 */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_diralpmin     . unsigned  , default = 0 */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_diralpmax     . unsigned  , default = 31 */
+#define DNR_DM_COR_DIF                             ((0x2d65))
+/* Bit 31: 4,        reserved */
+/* Bit  3: 1,        reg_dnr_dm_cordifshft    . unsigned  , default = 3 */
+/* Bit  0,            reg_dnr_dm_cordifmod                        ,
+ * 0:use max dir dif as cordif, 1: use max3x3 - min3x3 as cordif.
+ * unsigned  , default = 1
+ */
+#define DNR_DM_FLT_THD                             ((0x2d66))
+/* Bit 31:24,        reg_dnr_dm_fltthd00                         ,
+ * block flat threshold0 for block average difference when gbs is small,
+ * for flat block detection. unsigned  , default = 4
+ */
+/* Bit 23:16,        reg_dnr_dm_fltthd01                         ,
+ * block flat threshold1 for block average difference when gbs is small,
+ * for flat block detection. unsigned  , default = 6
+ */
+/* Bit 15: 8,        reg_dnr_dm_fltthd10                         ,
+ * block flat threshold0 for block average difference when gbs is large,
+ * for flat block detection. unsigned  , default = 9
+ */
+/* Bit  7: 0,        reg_dnr_dm_fltthd11                         ,
+ * block flat threshold1 for block average difference when gbs is large,
+ * for flat block detection. unsigned  , default = 12
+ */
+#define DNR_DM_VAR_THD                             ((0x2d67))
+/* Bit 31:24,        reg_dnr_dm_varthd00                         ,
+ * block variance threshold0 (>=) when gbs is small, for flat block
+ * detection. unsigned  , default = 2
+ */
+/* Bit 23:16,        reg_dnr_dm_varthd01                         ,
+ * block variance threshold1 (<=) when gbs is small, for flat block
+ * detection. unsigned  , default = 15
+ */
+/* Bit 15: 8,        reg_dnr_dm_varthd10                         ,
+ * block variance threshold0 (>=) when gbs is large, for flat block
+ * detection. unsigned  , default = 3
+ */
+/* Bit  7: 0,        reg_dnr_dm_varthd11                         ,
+ * block variance threshold1 (<=) when gbs is large, for flat block
+ * detection. unsigned  , default = 24
+ */
+#define DNR_DM_EDGE_DIF_THD                        ((0x2d68))
+/* Bit 31:24,        reg_dnr_dm_edgethd0                         ,
+ * block edge threshold (<=) when gbs is small, for flat block detection.
+ * unsigned  , default = 32
+ */
+/* Bit 23:16,        reg_dnr_dm_edgethd1                         ,
+ * block edge threshold (<=) when gbs is large, for flat block detection.
+ * unsigned  , default = 48
+ */
+/* Bit 15: 8,        reg_dnr_dm_difthd0                          ,
+ * block dif threshold (<=) when gbs is small, for flat block detection.
+ * unsigned  , default = 48
+ */
+/* Bit  7: 0,        reg_dnr_dm_difthd1                          ,
+ * block dif threshold (<=) when gbs is large, for flat block detection.
+ * unsigned  , default = 64
+ */
+#define DNR_DM_AVG_THD                             ((0x2d69))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_dnr_dm_avgthd0                          ,
+ * block average threshold (>=), for flat block detection.
+ * unsigned ,default = 160
+ */
+/* Bit  7: 0,        reg_dnr_dm_avgthd1                          ,
+ * block average threshold (<=), for flat block detection. unsigned
+ * , default = 128
+ */
+#define DNR_DM_AVG_VAR_DIF_THD                     ((0x2d6a))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_dnr_dm_avgdifthd                        ,
+ * block average dif threshold (<) between cur and up block, for flat
+ * block detection. unsigned  , default = 12
+ */
+/* Bit  7: 0,        reg_dnr_dm_vardifthd                        ,
+ * block variance dif threshold (>=) between cur and up block, for flat
+ * block detection. unsigned  , default = 1
+ */
+#define DNR_DM_VAR_EDGE_DIF_THD2                   ((0x2d6b))
+/* Bit 31:24,        reserved */
+/* Bit 23:16,        reg_dnr_dm_varthd2, block variance threshold (>=),
+ * for edge block detection.unsigned, default = 24
+ */
+/* Bit 15: 8,        reg_dnr_dm_edgethd2                         ,
+ * block edge threshold (>=), for edge block detection. unsigned  , default = 40
+ */
+/* Bit  7: 0,        reg_dnr_dm_difthd2                          ,
+ * block dif threshold (>=), for edge block detection. unsigned  , default = 80
+ */
+#define DNR_DM_DIF_FLT_MISC                        ((0x2d6c))
+/* Bit 31:28,        reg_dnr_dm_ldifoob                          ,
+ * pre-defined large dif when pixel out of blocks. unsigned  , default = 0
+ */
+/* Bit 27:24,        reg_dnr_dm_bdifoob                          ,
+ * pre-defined block dif when pixel out of blocks;. unsigned  , default = 0
+ */
+/* Bit 23:16,        reg_dnr_dm_fltalp                           ,
+ * pre-defined alpha for dm and nr blending, when block is flat
+ * with mos.. unsigned  , default = 200
+ */
+/* Bit 15:12,        reserved */
+/* Bit 11: 8,        reg_dnr_dm_fltminbdif                       ,
+ * pre-defined min block dif for dm filter,
+ * when block is flat with mos.. unsigned  , default = 12
+ */
+/* Bit  7,            reserved */
+/* Bit  6: 2,        reg_dnr_dm_difnormgain                      ,
+ * gain for pixel dif normalization for dm filter,
+ * normalized 16 as "1". unsigned  , default = 16
+ */
+/* Bit  1,            reg_dnr_dm_difnormen                        ,
+ * enable pixel dif normalization for dm filter. unsigned  , default = 1
+ */
+/* Bit  0,            reg_dnr_dm_difupden                         ,
+ * enable block dif update using max of left, cur, right difs.
+ * unsigned  , default = 0
+ */
+#define DNR_DM_SDIF_LUT0_2                         ((0x2d6d))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_sdiflut0                         ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_sdiflut1                         ,
+ * normally 0-16               . unsigned  , default = 14
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_sdiflut2                         ,
+ * normally 0-16               . unsigned  , default = 13
+ */
+#define DNR_DM_SDIF_LUT3_5                         ((0x2d6e))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_sdiflut3                         ,
+ * normally 0-16               . unsigned  , default = 10
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_sdiflut4                         ,
+ * normally 0-16               . unsigned  , default = 7
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_sdiflut5                         ,
+ * normally 0-16               . unsigned  , default = 5
+ */
+#define DNR_DM_SDIF_LUT6_8                         ((0x2d6f))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_sdiflut6                         ,
+ * normally 0-16               . unsigned  , default = 3
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_sdiflut7                         ,
+ * normally 0-16               . unsigned  , default = 1
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_sdiflut8                         ,
+ * normally 0-16               . unsigned  , default = 0
+ */
+#define DNR_DM_LDIF_LUT0_2                         ((0x2d70))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_ldiflut0                         ,
+ * normally 0-16               . unsigned  , default = 0
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_ldiflut1                         ,
+ * normally 0-16               . unsigned  , default = 4
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_ldiflut2                         ,
+ * normally 0-16               . unsigned  , default = 12
+ */
+#define DNR_DM_LDIF_LUT3_5                         ((0x2d71))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_ldiflut3                         ,
+ * normally 0-16               . unsigned  , default = 14
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_ldiflut4                         ,
+ * normally 0-16               . unsigned  , default = 15
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_ldiflut5                         ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+#define DNR_DM_LDIF_LUT6_8                         ((0x2d72))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_ldiflut6                         ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_ldiflut7                         ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_ldiflut8                         ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+#define DNR_DM_DIF2NORM_LUT0_2                     ((0x2d73))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_dif2normlut0                     ,
+ * normally 0-16               . unsigned  , default = 16
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_dif2normlut1                     ,
+ * normally 0-16               . unsigned  , default = 5
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_dif2normlut2                     ,
+ * normally 0-16               . unsigned  , default = 3
+ */
+#define DNR_DM_DIF2NORM_LUT3_5                     ((0x2d74))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_dif2normlut3                     ,
+ * normally 0-16               . unsigned  , default = 2
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_dif2normlut4                     ,
+ * normally 0-16               . unsigned  , default = 2
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_dif2normlut5                     ,
+ * normally 0-16               . unsigned  , default = 1
+ */
+#define DNR_DM_DIF2NORM_LUT6_8                     ((0x2d75))
+/* Bit 31:21,        reserved */
+/* Bit 20:16,        reg_dnr_dm_dif2normlut6                     ,
+ * normally 0-16               . unsigned  , default = 1
+ */
+/* Bit 15:13,        reserved */
+/* Bit 12: 8,        reg_dnr_dm_dif2normlut7                     ,
+ * normally 0-16               . unsigned  , default = 1
+ */
+/* Bit  7: 5,        reserved */
+/* Bit  4: 0,        reg_dnr_dm_dif2normlut8                     ,
+ * normally 0-16               . unsigned  , default = 1
+ */
+#define DNR_DM_GMS_THD                             ((0x2d76))
+/* Bit 31:16,        reserved */
+/* Bit 15: 8,        reg_gms_stat_thd0  . unsigned  , default = 0 */
+/* Bit  7: 0,        reg_gms_stat_thd1  . unsigned  , default = 128 */
+#define DNR_RO_DM_GMS_STAT_CNT                     ((0x2d77))
+/* Bit 31: 0,        ro_dm_gms_stat_cnt  . unsigned  , default = 0 */
+#define DNR_RO_DM_GMS_STAT_MS                      ((0x2d78))
+/* Bit 31: 0,        ro_dm_gms_stat_ms  . unsigned  , default = 0 */
+/* txl added */
+#define DECOMB_DET_VERT_CON0                           (0x2d80)
+#define DECOMB_DET_VERT_CON1                           (0x2d81)
+#define DECOMB_DET_EDGE_CON0                           (0x2d82)
+#define DECOMB_DET_EDGE_CON1                           (0x2d83)
+#define DECOMB_PARA                                                    (0x2d84)
+#define DECOMB_BLND_CON0                                       (0x2d85)
+#define DECOMB_BLND_CON1                                       (0x2d86)
+#define DECOMB_YC_THRD                                         (0x2d87)
+#define DECOMB_MTN_GAIN_OFST                           (0x2d88)
+#define DECOMB_CMB_SEL_GAIN_OFST                       (0x2d89)
+#define DECOMB_WIND00                                          (0x2d8a)
+#define DECOMB_WIND01                                          (0x2d8b)
+#define DECOMB_WIND10                                          (0x2d8c)
+#define DECOMB_WIND11                                          (0x2d8d)
+#define DECOMB_MODE                                                    (0x2d8e)
+#define DECOMB_FRM_SIZE                                                (0x2d8f)
+#define DECOMB_HV_BLANK                                                (0x2d90)
+#define NR2_POLAR3_MODE                                                (0x2d98)
+#define NR2_POLAR3_THRD                                                (0x2d99)
+#define NR2_POLAR3_PARA0                                       (0x2d9a)
+#define NR2_POLAR3_PARA1                                       (0x2d9b)
+#define NR2_POLAR3_CTRL                                                (0x2d9c)
+#define NR2_RO_POLAR3_NUMOFPIX                         (0x2d9d)
+#define NR2_RO_POLAR3_SMOOTHMV                         (0x2d9e)
+#define NR2_RO_POLAR3_M1                                       (0x2d9f)
+#define NR2_RO_POLAR3_P1                                       (0x2da0)
+#define NR2_RO_POLAR3_M2                                       (0x2da1)
+#define NR2_RO_POLAR3_P2                                       (0x2da2)
+#define NR2_RO_POLAR3_32                                       (0x2da3)
+/* txl end */
+
+#define VPU_VD1_MMC_CTRL                                       (0x2703)
+#define VPU_VD2_MMC_CTRL                                       (0x2704)
+#define VPU_DI_IF1_MMC_CTRL                                    (0x2705)
+#define VPU_DI_MEM_MMC_CTRL                                    (0x2706)
+#define VPU_DI_INP_MMC_CTRL                                    (0x2707)
+#define VPU_DI_MTNRD_MMC_CTRL                          (0x2708)
+#define VPU_DI_CHAN2_MMC_CTRL                          (0x2709)
+#define VPU_DI_MTNWR_MMC_CTRL                          (0x270a)
+#define VPU_DI_NRWR_MMC_CTRL                           (0x270b)
+#define VPU_DI_DIWR_MMC_CTRL                           (0x270c)
+
+#define MCDI_PD_22_CHK_WND0_X                          (0x2f59)
+#define MCDI_PD_22_CHK_WND0_Y                          (0x2f5a)
+#define MCDI_PD_22_CHK_WND1_X                          (0x2f5b)
+#define MCDI_PD_22_CHK_WND1_Y                          (0x2f5c)
+#define MCDI_PD_22_CHK_FLG_CNT                         (0x2f5e)
+/* mc di */
+/* //=================================================================//// */
+/* // memc di core 0 */
+/* //=================================================================//// */
+#define MCDI_HV_SIZEIN                             ((0x2f00))
+/* Bit 31:29, reserved */
+/* Bit 28:16, reg_mcdi_hsize
+ * image horizontal size (number of cols)   default=1024
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 0, reg_mcdi_vsize
+ * image vertical size   (number of rows)   default=1024
+ */
+#define MCDI_HV_BLKSIZEIN                          ((0x2f01))
+/* Bit    31, reg_mcdi_vrev                                     default = 0 */
+/* Bit    30, reg_mcdi_hrev                                     default = 0 */
+/* Bit 29:28, reserved */
+/* Bit 27:16, reg_mcdi_blkhsize
+ * image horizontal blk size (number of cols)   default=1024
+ */
+/* Bit 15:13, reserved */
+/* Bit 11: 0, reg_mcdi_blkvsize
+ * image vertical blk size   (number of rows)   default=1024
+ */
+#define MCDI_BLKTOTAL                              ((0x2f02))
+/* Bit 31:24, reserved */
+/* Bit 23: 0, reg_mcdi_blktotal */
+#define MCDI_MOTINEN                               ((0x2f03))
+/* Bit 31: 2, reserved */
+/* Bit     1, reg_mcdi_motionrefen.
+ * enable motion refinement of MA, default = 1
+ */
+/* Bit     0, reg_mcdi_motionparadoxen.
+ * enable motion paradox detection, default = 1
+ */
+#define MCDI_CTRL_MODE                             ((0x2f04))
+/* Bit 31:28, reserved */
+/* Bit 27:26, reg_mcdi_lmvlocken
+ * 0:disable, 1: use max Lmv, 2: use no-zero Lmv,
+ * lmv lock enable mode, default = 2
+ */
+/* Bit 25,    reg_mcdi_reldetrptchken */
+/* 0: unable; 1: enable, enable repeat pattern
+ * check (not repeat mv detection) in rel det part, default = 1
+ */
+/* Bit 24,    reg_mcdi_reldetgmvpd22chken */
+/* 0: unable; 1: enable, enable pull-down 22 mode
+ * check in gmv lock mode for rel det, default = 1
+ */
+/* Bit 23,    reg_mcdi_pd22chken */
+/* 0: unable; 1: enable, enable pull-down 22
+ * mode check (lock) function, default = 1
+ */
+/* Bit 22,    reg_mcdi_reldetlpfen */
+/* 0: unable; 1: enable, enable det value lpf, default = 1 */
+/* Bit 21,    reg_mcdi_reldetlmvpd22chken */
+/* 0: unable; 1: enable, enable pull-down 22
+ * mode check in lmv lock mode for rel det, default = 1
+ */
+/* Bit 20,    reg_mcdi_reldetlmvdifchken */
+/* 0: unable; 1: enable, enable lmv dif check
+ * in lmv lock mode for rel det, default = 1
+ */
+/* Bit 19,    reg_mcdi_reldetgmvdifchken */
+/* 0: unable; 1: enable, enable lmv dif check in
+ * lmv lock mode for rel det, default = 1
+ */
+/* Bit 18,    reg_mcdi_reldetpd22chken */
+/* 0: unable; 1: enable, enable pull-down 22
+ * mode check for rel det refinement, default = 1
+ */
+/* Bit 17,    reg_mcdi_reldetfrqchken */
+/* 0: unable; 1: enable, enable mv frequency check in rel det, default = 1 */
+/* Bit 16,    reg_mcdi_qmeen */
+/* 0: unable; 1: enable, enable quarter motion estimation, defautl = 1 */
+/* Bit 15,    reg_mcdi_refrptmven */
+/* 0: unable; 1: enable, use repeat mv in refinement, default = 1 */
+/* Bit 14,    reg_mcdi_refgmven */
+/* 0: unable; 1: enable, use gmv in refinement, default = 1 */
+/* Bit 13,    reg_mcdi_reflmven */
+/* 0: unable; 1: enable, use lmvs in refinement, default = 1 */
+/* Bit 12,    reg_mcdi_refnmven */
+/* 0: unable; 1: enable, use neighoring mvs in refinement, default = 1 */
+/* Bit 11,    reserved */
+/* Bit 10,    reg_mcdi_referrfrqchken */
+/* 0: unable; 1: enable, enable mv frquency
+ * check while finding min err in ref, default = 1
+ */
+/* Bit 9,     reg_mcdi_refen */
+/* 0: unable; 1: enable, enable mv refinement, default = 1
+ */
+/* Bit 8,     reg_mcdi_horlineen */
+/* 0: unable; 1: enable,enable horizontal lines
+ * detection by sad map, default = 1
+ */
+/* Bit 7,     reg_mcdi_highvertfrqdeten */
+/* 0: unable; 1: enable, enable high vertical
+ * frequency pattern detection, default = 1
+ */
+/* Bit 6,     reg_mcdi_gmvlocken */
+/* 0: unable; 1: enable, enable gmv lock mode, default = 1 */
+/* Bit 5,     reg_mcdi_rptmven */
+/* 0: unable; 1: enable, enable repeat pattern detection, default = 1 */
+/* Bit 4,     reg_mcdi_gmven */
+/* 0: unable; 1: enable, enable global motion estimation, default = 1 */
+/* Bit 3,     reg_mcdi_lmven */
+/* 0: unable; 1: enable, enable line mv estimation for hme, default = 1 */
+/* Bit 2,     reg_mcdi_chkedgeen */
+/* 0: unable; 1: enable, enable check edge function, default = 1 */
+/* Bit 1,     reg_mcdi_txtdeten */
+/* 0: unable; 1: enable, enable texture detection, default = 1 */
+/* Bit 0,     reg_mcdi_memcen */
+/* 0: unable; 1: enable, enable of memc di, default = 1 */
+#define MCDI_UNI_MVDST                             ((0x2f05))
+/* Bit 31:20, reserved */
+/* Bit 19:17, reg_mcdi_unimvdstabsseg0
+ * segment0 for uni-mv abs, default = 1
+ */
+/* Bit 16:12, reg_mcdi_unimvdstabsseg1
+ * segment1 for uni-mv abs, default = 15
+ */
+/* Bit 11: 8, reg_mcdi_unimvdstabsdifgain0
+ * 2/2, gain0 of uni-mv abs dif for segment0, normalized 2 to '1', default = 2
+ */
+/* Bit  7: 5, reg_mcdi_unimvdstabsdifgain1
+ * 2/2, gain1 of uni-mv abs dif for segment1, normalized 2 to '1', default = 2
+ */
+/* Bit  4: 2, reg_mcdi_unimvdstabsdifgain2
+ * 2/2, gain2 of uni-mv abs dif beyond segment1,normalized 2 to '1', default = 2
+ */
+/* Bit  1: 0, reg_mcdi_unimvdstsgnshft
+ * shift for neighboring distance of uni-mv, default = 0
+ */
+#define MCDI_BI_MVDST                              ((0x2f06))
+/* Bit 31:20, reserved */
+/* Bit 19:17, reg_mcdi_bimvdstabsseg0
+ * segment0 for bi-mv abs, default = 1
+ */
+/* Bit 16:12, reg_mcdi_bimvdstabsseg1
+ * segment1 for bi-mv abs, default = 9
+ */
+/* Bit 11: 8, reg_mcdi_bimvdstabsdifgain0
+ * 6/2, gain0 of bi-mv abs dif for segment0, normalized 2 to '1', default = 6
+ */
+/* Bit  7: 5, reg_mcdi_bimvdstabsdifgain1
+ * 3/2, gain1 of bi-mvabs dif for segment1, normalized 2 to '1', default = 3
+ */
+/* Bit  4: 2, reg_mcdi_bimvdstabsdifgain2
+ * 2/2, gain2 of bi-mvabs dif beyond segment1, normalized 2 to '1', default = 2
+ */
+/* Bit  1: 0, reg_mcdi_bimvdstsgnshft
+ * shift for neighboring distance of bi-mv, default = 0
+ */
+#define MCDI_SAD_GAIN                              ((0x2f07))
+/* Bit 31:19, reserved */
+/* Bit 18:17, reg_mcdi_unisadcorepxlgain
+ * uni-sad core pixels gain, default = 3
+ */
+/* Bit 16,    reg_mcdi_unisadcorepxlnormen
+ * enable uni-sad core pixels normalization, default = 0
+ */
+/* Bit 15:11, reserved */
+/* Bit 10: 9, reg_mcdi_bisadcorepxlgain
+ * bi-sad core pixels gain, default = 3
+ */
+/* Bit  8,    reg_mcdi_bisadcorepxlnormen
+ * enable bi-sad core pixels normalization, default = 1
+ */
+/* Bit  7: 3, reserved */
+/* Bit  2: 1, reg_mcdi_biqsadcorepxlgain
+ * bi-qsad core pixels gain, default = 3
+ */
+/* Bit  0,    reg_mcdi_biqsadcorepxlnormen
+ * enable bi-qsad core pixels normalization, default = 1
+ */
+#define MCDI_TXT_THD                               ((0x2f08))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_txtminmaxdifthd,
+ * min max dif threshold (>=) for texture detection, default = 24
+ */
+/* Bit 15: 8, reg_mcdi_txtmeandifthd,
+ * mean dif threshold (<) for texture detection, default = 9
+ */
+/* Bit  7: 3, reserved */
+/* Bit  2: 0, reg_mcdi_txtdetthd,
+ * texture detecting threshold, 0~4, default = 2
+ */
+#define MCDI_FLT_MODESEL                           ((0x2f09))
+/* Bit 31       reserved */
+/* Bit 30:28, reg_mcdi_flthorlineselmode
+ * mode for horizontal line detecting flat calculation,default = 1,same as below
+ */
+/* Bit 27       reserved */
+/* Bit 26:24, reg_mcdi_fltgmvselmode
+ * mode for gmv flat calculation, default = 4, same as below
+ */
+/* Bit 23,      reserved */
+/* Bit 22:20, reg_mcdi_fltsadselmode
+ * mode for sad flat calculation, default = 2, same as below
+ */
+/* Bit 19,      reserved */
+/* Bit 18:16, reg_mcdi_fltbadwselmode
+ * mode for badw flat calculation, default = 3, same as below
+ */
+/* Bit 15,      reserved */
+/* Bit 14:12, reg_mcdi_fltrptmvselmode
+ * mode for repeat mv flat calculation, default = 4, same as below
+ */
+/* Bit 11,      reserved */
+/* Bit 10: 8, reg_mcdi_fltbadrelselmode
+ * mode for bad rel flat calculation, default = 4, same as below
+ */
+/* Bit  7,      reserved */
+/* Bit  6: 4, reg_mcdi_fltcolcfdselmode
+ * mode for col cfd flat calculation, default = 2, same as below
+ */
+/* Bit  3,      reserved */
+/* Bit  2: 0, reg_mcdi_fltpd22chkselmode
+ * mode for pd22 check flat calculation, default = 2, #
+ * 0:cur dif h, 1: cur dif v, 2: pre dif h, 3: pre dif v,
+ * 4: cur flt, 5: pre flt, 6: cur+pre, 7: max all(cur,pre)
+ */
+#define MCDI_CHK_EDGE_THD                          ((0x2f0a))
+/* Bit 23:28, reserved. */
+/* Bit 27:24, reg_mcdi_chkedgedifsadthd.
+ * thd (<=) for sad dif check, 0~8, default = 1
+ */
+/* Bit 23:16, reserved. */
+/* Bit 15:12, reg_mcdi_chkedgemaxedgethd.
+ * max drt of edge, default = 15
+ */
+/* Bit 11: 8, reg_mcdi_chkedgeminedgethd.
+ * min drt of edge, default = 2
+ */
+/* Bit     7, reserved. */
+/* Bit  6: 0, reg_mcdi_chkedgevdifthd.
+ * thd for vertical dif in check edge, default = 14
+ */
+#define MCDI_CHK_EDGE_GAIN_OFFST                   ((0x2f0b))
+/* Bit 31:24, reserved. */
+/* Bit 23:20, reg_mcdi_chkedgedifthd1.
+ * thd1 for edge dif check (<=), default = 4
+ */
+/* Bit 19:16, reg_mcdi_chkedgedifthd0.
+ * thd0 for edge dif check (>=), default = 15
+ */
+/* Bit   :15, reserved. */
+/* Bit 14:10, reg_mcdi_chkedgechklen.
+ * total check length for edge check, 1~24 (>0), default = 24
+ */
+/* Bit  9: 8, reg_mcdi_chkedgeedgesel.
+ * final edge select mode, 0: original start edge, 1: lpf start edge,
+ * 2: orignal start+end edge, 3: lpf start+end edge, default = 1
+ */
+/* Bit  7: 3, reg_mcdi_chkedgesaddstgain.
+ * distance gain for sad calc while getting edges, default = 4
+ */
+/* Bit     2, reg_mcdi_chkedgechkmode.
+ * edge used in check mode, 0: original edge, 1: lpf edge, defautl = 1
+ */
+/* Bit     1, reg_mcdi_chkedgestartedge.
+ * edge mode for start edge, 0: original edge, 1: lpf edge, defautl = 0
+ */
+/* Bit     0, reg_mcdi_chkedgeedgelpf.
+ * edge lpf mode, 0:[0,2,4,2,0], 1:[1,2,2,2,1], default = 0
+ */
+#define MCDI_LMV_RT                                ((0x2f0c))
+/* BIt 31:15, reserved */
+/* Bit 14:12, reg_mcdi_lmvvalidmode
+ * valid mode for lmv calc., 100b:use char det, 010b: use flt,001b: use hori flg
+ */
+/* Bit 11:10, reg_mcdi_lmvgainmvmode
+ * four modes of mv selection for lmv weight calucluation, default = 1
+ */
+/* 0: cur(x-3), lst(x-1,x,x+1); 1: cur(x-4,x-3), lst(x,x+1);
+ * 2: cur(x-5,x-4,x-3), lst(x-1,x,x+1,x+2,x+3);
+ * 3: cur(x-6,x-5,x-4,x-3), lst(x-1,x,x+1,x+2);
+ */
+/* Bit  9,    reg_mcdi_lmvinitmode
+ * initial lmvs at first row of input field, 0: initial value = 0;
+ * 1: initial = 32 (invalid), default = 0
+ */
+/* Bit  8,    reserved */
+/* Bit  7: 4, reg_mcdi_lmvrt0      ratio of max mv, default = 5 */
+/* Bit  3: 0, reg_mcdi_lmvrt1      ratio of second max mv, default = 5 */
+#define MCDI_LMV_GAINTHD                           ((0x2f0d))
+/* Bit 31:24, reg_mcdi_lmvvxmaxgain    max gain of lmv weight, default = 96 */
+/* Bit 23,    reserved */
+/* Bit 22:20, reg_mcdi_lmvdifthd0
+ * dif threshold 0 (<) for small lmv, default = 1
+ */
+/* Bit 19:17, reg_mcdi_lmvdifthd1
+ * dif threshold 1 (<) for median lmv, default = 2
+ */
+/* Bit 16:14, reg_mcdi_lmvdifthd2
+ * dif threshold 2 (<) for large lmv, default = 3
+ */
+/* Bit 13: 8, reg_mcdi_lmvnumlmt
+ * least/limit number of (total number - max0), default = 20
+ */
+/* Bit  7: 0, reg_mcdi_lmvfltthd
+ * flt cnt thd (<) for lmv, default = 9
+ */
+#define MCDI_RPTMV_THD0                            ((0x2f0e))
+/* Bit 31:25, reg_mcdi_rptmvslpthd2
+ * slope thd (>=) between i and i+3/i-3 (i+4/i-4), default = 64
+ */
+/* Bit 24:20, reg_mcdi_rptmvslpthd1
+ * slope thd (>=) between i and i+2/i-2, default = 4
+ */
+/* Bit 19:10, reg_mcdi_rptmvampthd2
+ * amplitude thd (>=) between max and min, when count cycles, default = 300
+ */
+/* Bit  9: 0, reg_mcdi_rptmvampthd1
+ * amplitude thd (>=) between average of max and min, default = 400
+ */
+#define MCDI_RPTMV_THD1                            ((0x2f0f))
+/* Bit 31:28, reserved */
+/* Bit 27:25, reg_mcdi_rptmvcyccntthd
+ * thd (>=) of total cycles count, default = 2
+ */
+/* Bit 24:21, reg_mcdi_rptmvcycdifthd
+ * dif thd (<) of cycles length, default = 3
+ */
+/* Bit 20:18, reg_mcdi_rptmvcycvldthd
+ * thd (>) of valid cycles number, default = 1
+ */
+/* Bit 17:15, reg_mcdi_rptmvhalfcycminthd
+ * min length thd (>=) of half cycle, default = 2
+ */
+/* Bit 14:11, reg_mcdi_rptmvhalfcycdifthd
+ * neighboring half cycle length dif thd (<), default = 5
+ */
+/* Bit 10: 8, reg_mcdi_rptmvminmaxcntthd
+ * least number of valid max and min, default = 2
+ */
+/* Bit  7: 5, reg_mcdi_rptmvcycminthd
+ * min length thd (>=) of cycles, default = 2
+ */
+/* Bit  4: 0, reg_mcdi_rptmvcycmaxthd
+ * max length thd (<) of cycles, default = 17
+ */
+#define MCDI_RPTMV_THD2                            ((0x2f10))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_rptmvhdifthd0
+ * higher hdif thd (>=) (vertical edge) for rpt detection, default = 8
+ */
+/* Bit 15: 8, reg_mcdi_rptmvhdifthd1
+ * hdif thd (>=) (slope edge) for rpt detection, default = 4
+ */
+/* Bit  7: 0, reg_mcdi_rptmvvdifthd
+ * vdif thd (>=) (slope edge) for rpt detection, default = 1
+ */
+#define MCDI_RPTMV_SAD                             ((0x2f11))
+/* Bit 31:26, reserved */
+/* Bit 25:16, reg_mcdi_rptmvsaddifthdgain
+ * 7x3x(16/16), gain for sad dif thd in rpt mv detection,
+ * 0~672, normalized 16 as '1', default = 336
+ */
+/* Bit 15:10, reserved */
+/* Bit  9: 0, reg_mcdi_rptmvsaddifthdoffst
+ * offset for sad dif thd in rpt mv detection, -512~511, default = 16
+ */
+#define MCDI_RPTMV_FLG                             ((0x2f12))
+/* Bit 31:18,  reserved */
+/* Bit 17:16,  reg_mcdi_rptmvmode
+ * select mode of mvs for repeat motion estimation, 0: hmv,
+ * 1: qmv/2, 2 or 3: qmv/4, default = 2
+ */
+/* Bit 15: 8,  reg_mcdi_rptmvflgcntthd
+ * thd (>=) of min count number for rptmv of whole field,
+ * for rptmv estimation, default = 64
+ */
+/* Bit  7: 5,  reserved */
+/* Bit  4: 0,  reg_mcdi_rptmvflgcntrt
+ * 4/32, ratio for repeat mv flag count, normalized 32 as '1', set 31 to 32,
+ */
+#define MCDI_RPTMV_GAIN                            ((0x2f13))
+/* Bit 31:24, reg_mcdi_rptmvlftgain
+ * up repeat mv gain for hme, default = 96
+ */
+/* Bit 23:16, reg_mcdi_rptmvuplftgain
+ * up left repeat mv gain for hme, default = 32
+ */
+/* Bit 15: 8, reg_mcdi_rptmvupgain
+ * up repeat mv gain for hme, default = 64
+ */
+/* Bit  7: 0, reg_mcdi_rptmvuprightgain
+ * up right repeat mv gain for hme, default = 32
+ */
+#define MCDI_GMV_RT                                ((0x2f14))
+/* Bit 31,    reserved */
+/* Bit 30:24, reg_mcdi_gmvmtnrt0
+ * ratio 0 for motion senario, set 127 to 128, normalized 128 as '1',default =32
+ */
+/* Bit 23,    reserved */
+/* Bit 22:16, reg_mcdi_gmvmtnrt1
+ * ratio 1 for motion senario, set 127 to 128 normalized 128 as '1',default = 56
+ */
+/* Bit 15,    reserved */
+/* Bit 14: 8, reg_mcdi_gmvstlrt0
+ * ratio 0 for still senario, set 127 to 128,normalized 128 as '1', default = 56
+ */
+/* Bit  7,    reserved */
+/* Bit  6: 0, reg_mcdi_gmvstlrt1
+ * ratio 1 for still senario, set 127 to 128, normalized 128 as '1',default = 80
+ */
+#define MCDI_GMV_GAIN                              ((0x2f15))
+/* Bit 31:25, reg_mcdi_gmvzeromvlockrt0
+ * ratio 0 for locking zero mv, set 127 to 128,
+ * normalized 128 as '1', default = 100
+ */
+/* Bit 24:18, reg_mcdi_gmvzeromvlockrt1
+ * ratio 1 for locking zero mv, set 127 to 128,
+ * normalized 128 as '1', default = 112
+ */
+/* Bit 17:16, reg_mcdi_gmvvalidmode
+ * valid mode for gmv calc., 10b: use flt, 01b: use hori flg, default = 3
+ */
+/* Bit 15: 8, reg_mcdi_gmvvxgain
+ * gmv's vx gain when gmv locked for hme, default = 0
+ */
+/* Bit  7: 0, reg_mcdi_gmvfltthd
+ * flat thd (<) for gmv calc. default = 3
+ */
+#define MCDI_HOR_SADOFST                           ((0x2f16))
+/* Bit 31:25, reserved */
+/* Bit 24:16, reg_mcdi_horsaddifthdgain
+ * 21*1/8, gain/divisor for sad dif threshold in hor line detection,
+ * normalized 8 as '1', default = 21
+ */
+/* Bit 15: 8, reg_mcdi_horsaddifthdoffst
+ * offset for sad dif threshold in hor line detection, -128~127, default = 0
+ */
+/* Bit  7: 0, reg_mcdi_horvdifthd
+ * threshold (>=) of vertical dif of next block for
+ * horizontal line detection, default = 24
+ */
+#define MCDI_REF_MV_NUM                            ((0x2f17))
+/* Bit 31: 2, reserved */
+/* Bit  1: 0, reg_mcdi_refmcmode.         motion compensated mode used in
+ * refinement, 0: pre, 1: next, 2: (pre+next)/2, default = 0
+ */
+#define MCDI_REF_BADW_THD_GAIN                     ((0x2f18))
+/* Bit 31:28, reserved */
+/* Bit 27:24, reg_mcdi_refbadwcnt2gain.
+ * gain for badwv count num==3, default = 6
+ */
+/* Bit 23:20, reg_mcdi_refbadwcnt1gain.
+ * gain for badwv count num==2, default = 3
+ */
+/* Bit 19:16, reg_mcdi_refbadwcnt0gain.
+ * gain for badwv count num==1, default = 1
+ */
+/* Bit 15:12, reg_mcdi_refbadwthd3.
+ * threshold 3 for detect badweave with largest average luma, default = 4
+ */
+/* Bit 11: 8, reg_mcdi_refbadwthd2.
+ * threshold 2 for detect badweave with third smallest average luma, default = 3
+ */
+/* Bit  7: 4, reg_mcdi_refbadwthd1.
+ * threshold 1 for detect badweave with second smallest average luma,default = 2
+ */
+/* Bit  3: 0, reg_mcdi_refbadwthd0.
+ * threshold 0 for detect badweave with smallest average luma, default = 1
+ */
+#define MCDI_REF_BADW_SUM_GAIN                     ((0x2f19))
+/* Bit 31:13, reserved */
+/* Bit 12: 8, reg_mcdi_refbadwsumgain0.
+ * sum gain for r channel, 0~16, default = 8
+ */
+/* Bit  7: 5, reserved */
+/* Bit     4, reg_mcdi_refbadwcalcmode.
+ * mode for badw calculation, 0:sum, 1:max, default = 0
+ */
+/* Bit  3: 0, reserved */
+#define MCDI_REF_BS_THD_GAIN                       ((0x2f1a))
+/* Bit 31:28, reg_mcdi_refbsudgain1.
+ * up & down block stregth gain1, normalized to 8 as '1', default = 2
+ */
+/* Bit 27:24, reg_mcdi_refbsudgain0.
+ * up & down block stregth gain0, normalized to 8 as '1', default = 4
+ */
+/* Bit 23:19, reserved */
+/* Bit 18:16, reg_mcdi_refbslftgain.
+ * left block strength gain, default = 0
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_refbsthd1.
+ * threshold 1 for detect block stregth in refinment, default = 16
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_refbsthd0.
+ * threshold 0 for detect block stregth in refinment, default = 8
+ */
+#define MCDI_REF_ERR_GAIN0                         ((0x2f1b))
+/* Bit    31, reserved */
+/* Bit 30:24, reg_mcdi_referrnbrdstgain.
+ * neighoring mv distances gain for err calc. in ref,
+ * normalized to 8 as '1', default = 48
+ */
+/* Bit 23:20, reserved */
+/* Bit 19:16, reg_mcdi_referrbsgain.
+ * bs gain for err calc. in ref, normalized to 8 as '1', default = 4
+ */
+/* Bit    15, reserved */
+/* Bit 14: 8, reg_mcdi_referrbadwgain.
+ * badw gain for err calc. in ref, normalized to 8 as '1', default = 64
+ */
+/* Bit  7: 4, reserved */
+/* Bit  3: 0, reg_mcdi_referrsadgain.
+ * sad gain for err calc. in ref, normalized to 8 as '1', default = 4
+ */
+#define MCDI_REF_ERR_GAIN1                         ((0x2f1c))
+/* Bit 31:20, reserved */
+/* Bit 19:16, reg_mcdi_referrchkedgegain.
+ * check edge gain for err calc. in ref, normalized to 8 as '1', default = 4
+ */
+/* Bit 15:12, reserved */
+/* Bit 11: 8, reg_mcdi_referrlmvgain.
+ * (locked) lmv gain for err calc. in ref, normalized to 8 as '1', default = 0
+ */
+/* Bit  7: 4, reserved */
+/* Bit  3: 0, reg_mcdi_referrgmvgain.
+ * (locked) gmv gain for err calc. in ref, normalized to 8 as '1', default = 0
+ */
+#define MCDI_REF_ERR_FRQ_CHK                       ((0x2f1d))
+/* Bit 31:28, reserved */
+/* Bit 27:24, reg_mcdi_referrfrqgain.
+ * gain for mv frquency, normalized to 4 as '1', default = 10
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_referrfrqmax.
+ * max gain for mv frquency check, default = 31
+ */
+/* Bit    15, reserved */
+/* Bit 14:12, reg_mcdi_ref_errfrqmvdifthd2.
+ * mv dif threshold 2 (<) for mv frquency check, default = 3
+ */
+/* Bit    11, reserved */
+/* Bit 10: 8, reg_mcdi_ref_errfrqmvdifthd1.
+ * mv dif threshold 1 (<) for mv frquency check, default = 2
+ */
+/* Bit     7, reserved */
+/* Bit  6: 4, reg_mcdi_ref_errfrqmvdifthd0.
+ * mv dif threshold 0 (<) for mv frquency check, default = 1
+ */
+/* Bit  3: 0, reserved */
+#define MCDI_QME_LPF_MSK                           ((0x2f1e))
+/* Bit 31:28, reserved */
+/* Bit 27:24, reg_mcdi_qmechkedgelpfmsk0.
+ * lpf mask0 for chk edge in qme, 0~8, msk1 = (8-msk0),
+ * normalized to 8 as '1', default = 7
+ */
+/* Bit 23:20, reserved */
+/* Bit 19:16, reg_mcdi_qmebslpfmsk0.
+ * lpf mask0 for bs in qme, 0~8, msk1 = (8-msk0),
+ * normalized to 8 as '1', default = 7
+ */
+/* Bit 15:12, reserved */
+/* Bit 11: 8, reg_mcdi_qmebadwlpfmsk0.
+ * lpf mask0 for badw in qme, 0~8, msk1 = (8-msk0),
+ * normalized to 8 as '1', default = 7
+ */
+/* Bit  7: 4, reserved */
+/* Bit  3: 0, reg_mcdi_qmesadlpfmsk0.
+ * lpf mask0 for sad in qme, 0~8, msk1 = (8-msk0),
+ * normalized to 8 as '1', default = 7
+ */
+#define MCDI_REL_DIF_THD_02                        ((0x2f1f))
+/* Bit 31:24, reserved. */
+/* Bit 23:16, reg_mcdi_reldifthd2.
+ * thd (<) for (hdif+vdif), default = 9
+ */
+/* Bit 15: 8, reg_mcdi_reldifthd1.
+ * thd (<) for (vdif), default = 5
+ */
+/* Bit  7: 0, reg_mcdi_reldifthd0.
+ * thd (>=) for (hdif-vdif), default = 48
+ */
+#define MCDI_REL_DIF_THD_34                        ((0x2f20))
+/* Bit 31:16, reserved. */
+/* Bit 15: 8, reg_mcdi_reldifthd4.
+ * thd (<) for (hdif), default = 255
+ */
+/* Bit  7: 0, reg_mcdi_reldifthd3.
+ * thd (>=) for (vdif-hdif), default = 48
+ */
+#define MCDI_REL_BADW_GAIN_OFFST_01                ((0x2f21))
+/* Bit 31:24, reg_mcdi_relbadwoffst1.
+ * offset for badw adj, for flat block, -128~127, default = 0
+ */
+/* Bit 23:16, reg_mcdi_relbadwgain1.
+ * gain for badw adj, for flat block, default = 128
+ */
+/* Bit 15: 8, reg_mcdi_relbadwoffst0.
+ * offset for badw adj, for vertical block, -128~127, default = 0
+ */
+/* Bit  7: 0, reg_mcdi_relbadwgain0.
+ * gain for badw adj, for vertical block, default = 160
+ */
+#define MCDI_REL_BADW_GAIN_OFFST_23                ((0x2f22))
+/* Bit 31:24, reg_mcdi_relbadwoffst3.
+ * offset for badw adj, for other block, -128~127, default = 0
+ */
+/* Bit 23:16, reg_mcdi_relbadwgain3.
+ * gain for badw adj, for other block, default = 48
+ */
+/* Bit 15: 8, reg_mcdi_relbadwoffst2.
+ * offset for badw adj, for horizontal block, -128~127, default = 0
+ */
+/* Bit  7: 0, reg_mcdi_relbadwgain2.
+ * gain for badw adj, for horizontal block, default = 48
+ */
+#define MCDI_REL_BADW_THD_GAIN_OFFST               ((0x2f23))
+/* Bit 31:23, reserved. */
+/* Bit 22:16, reg_mcdi_relbadwoffst.
+ * offset for badw thd adj, -64~63, default = 0
+ */
+/* Bit 15: 8, reserved. */
+/* Bit  7: 0, reg_mcdi_relbadwthdgain.
+ * gain0 for badw thd adj, normalized to 16 as '1', default = 16
+ */
+#define MCDI_REL_BADW_THD_MIN_MAX                  ((0x2f24))
+/* Bit 31:18, reserved. */
+/* Bit 17: 8, reg_mcdi_relbadwthdmax.
+ * max for badw thd adj, default = 256
+ */
+/* Bit  7: 0, reg_mcdi_relbadwthdmin.
+ * min for badw thd adj, default = 16
+ */
+#define MCDI_REL_SAD_GAIN_OFFST_01                 ((0x2f25))
+/* Bit 31:24, reg_mcdi_relsadoffst1.
+ * offset for sad adj, for flat block, -128~127, default = 0
+ */
+/* Bit 23:20, reserved. */
+/* Bit 19:16, reg_mcdi_relsadgain1.
+ * gain for sad adj, for flat block, normalized to 8 as '1', default = 8
+ */
+/* Bit 15: 8, reg_mcdi_relsadoffst0.
+ * offset for sad adj, for vertical block, -128~127, default = 0
+ */
+/* Bit  7: 4, reserved. */
+/* Bit  3: 0, reg_mcdi_relsadgain0.
+ * gain for sad adj, for vertical block, normalized to 8 as '1', default = 6
+ */
+#define MCDI_REL_SAD_GAIN_OFFST_23                 ((0x2f26))
+/* Bit 31:24, reg_mcdi_relsadoffst3.
+ * offset for sad adj, for other block, -128~127, default = 0
+ */
+/* Bit 23:20, reserved. */
+/* Bit 19:16, reg_mcdi_relsadgain3.
+ * gain for sad adj, for other block, normalized to 8 as '1', default = 8
+ */
+/* Bit 15: 8, reg_mcdi_relsadoffst2.
+ * offset for sad adj, for horizontal block, -128~127, default = 0
+ */
+/* Bit  7: 4, reserved. */
+/* Bit  3: 0, reg_mcdi_relsadgain2.
+ * gain for sad adj, for horizontal block, normalized to 8 as '1', default = 12
+ */
+#define MCDI_REL_SAD_THD_GAIN_OFFST                ((0x2f27))
+/* Bit 31:24, reserved. */
+/* Bit 23:16, reg_mcdi_relsadoffst.
+ * offset for sad thd adj, -128~127, default = 0
+ */
+/* Bit 15:10, reserved. */
+/* Bit  9: 0, reg_mcdi_relsadthdgain.
+ * gain for sad thd adj, 21*2/16, normalized to 16 as '1', default = 42
+ */
+#define MCDI_REL_SAD_THD_MIN_MAX                   ((0x2f28))
+/* Bit 31:27, reserved. */
+/* Bit 26:16, reg_mcdi_relsadthdmax.
+ * max for sad thd adj, 21*32, default = 672
+ */
+/* Bit 15: 9, reserved. */
+/* Bit  8: 0, reg_mcdi_relsadthdmin.
+ * min for sad thd adj, 21*2, default = 42
+ */
+#define MCDI_REL_DET_GAIN_00                       ((0x2f29))
+/* Bit 31:21, reserved. */
+/* Bit 20:16, reg_mcdi_reldetbsgain0.
+ * gain0 (gmv locked) for bs, for det. calc. normalized to 16 as '1',
+ * default = 8
+ */
+/* Bit 15:14, reserved. */
+/* Bit 13: 8, reg_mcdi_reldetbadwgain0.
+ * gain0 (gmv locked) for badw, for det. calc.
+ * normalized to 16 as '1', default = 12
+ */
+/* Bit  7: 5, reserved. */
+/* Bit  4: 0, reg_mcdi_reldetsadgain0.
+ * gain0 (gmv locked) for qsad, for det. calc.
+ * normalized to 16 as '1', default = 8
+ */
+#define MCDI_REL_DET_GAIN_01                       ((0x2f2a))
+/* Bit 31:14, reserved. */
+/* Bit 12: 8, reg_mcdi_reldetchkedgegain0.
+ * gain0 (gmv locked) for chk_edge, for det. calc.
+ * normalized to 16 as '1', default = 2
+ */
+/* Bit     7, reserved. */
+/* Bit  6: 0, reg_mcdi_reldetnbrdstgain0.
+ * gain0 (gmv locked) for neighoring dist, for det.
+ * calc. normalized to 16 as '1', default = 24
+ */
+#define MCDI_REL_DET_GAIN_10                       ((0x2f2b))
+/* Bit 31:21, reserved. */
+/* Bit 20:16, reg_mcdi_reldetbsgain1.
+ * gain1 (lmv locked) for bs, for det. calc. normalized
+ * to 16 as '1', default = 0
+ */
+/* Bit 15:14, reserved. */
+/* Bit 13: 8, reg_mcdi_reldetbadwgain1.
+ * gain1 (lmv locked) for badw, for det. calc.
+ * normalized to 16 as '1', default = 8
+ */
+/* Bit  7: 5, reserved. */
+/* Bit  4: 0, reg_mcdi_reldetsadgain1.
+ * gain1 (lmv locked) for qsad, for det. calc.
+ * normalized to 16 as '1', default = 8
+ */
+#define MCDI_REL_DET_GAIN_11                       ((0x2f2c))
+/* Bit 31:14, reserved. */
+/* Bit 12: 8, reg_mcdi_reldetchkedgegain1.
+ * gain1 (lmv locked) for chk_edge, for det. calc.
+ * normalized to 16 as '1', default = 0
+ */
+/* Bit     7, reserved. */
+/* Bit  6: 0, reg_mcdi_reldetnbrdstgain1.
+ * gain1 (lmv locked) for neighoring dist, for det.
+ * calc. normalized to 16 as '1', default = 24
+ */
+#define MCDI_REL_DET_GAIN_20                       ((0x2f2d))
+/* Bit 31:21, reserved. */
+/* Bit 20:16, reg_mcdi_reldetbsgain2.
+ * gain2 (no locked) for bs, for det. calc.normalized to 16 as '1', default = 12
+ */
+/* Bit 15:14, reserved. */
+/* Bit 13: 8, reg_mcdi_reldetbadwgain2.
+ * gain2 (no locked) for badw, for det. calc.
+ * normalized to 16 as '1',default = 32
+ */
+/* Bit  7: 5, reserved. */
+/* Bit  4: 0, reg_mcdi_reldetsadgain2.
+ * gain2 (no locked) for qsad, for det. calc.
+ * normalized to 16 as '1', default = 16
+ */
+#define MCDI_REL_DET_GAIN_21                       ((0x2f2e))
+/* Bit 31:26, reserved */
+/* Bit 25:16, reg_mcdi_reldetoffst.
+ * offset for rel calculation, for det. calc. -512~511,  default = 0
+ */
+/* Bit 15:14, reserved. */
+/* Bit 12: 8, reg_mcdi_reldetchkedgegain2.
+ * gain2 (no locked) for chk_edge, for det. calc.
+ * normalized to 16 as '1', default = 10
+ */
+/* Bit     7, reserved. */
+/* Bit  6: 0, reg_mcdi_reldetnbrdstgain2.
+ * gain2 (no locked) for neighoring dist, for det. calc.
+ * normalized to 16 as '1', default = 32
+ */
+#define MCDI_REL_DET_GMV_DIF_CHK                   ((0x2f2f))
+/* Bit 31:24, reserved. */
+/* Bit 23:16, reg_mcdi_reldetgmvfltthd.
+ * flat thd (>=) for gmv lock decision, default = 0
+ */
+/* Bit    15, reserved. */
+/* Bit 14:12, reg_mcdi_reldetgmvdifthd.
+ * dif thd (>=) for current mv different from gmv for gmv dif check,
+ * actually used in Lmv lock check, default = 3
+ */
+/* Bit    11, reserved. */
+/* Bit 10: 8, reg_mcdi_reldetgmvdifmin.
+ * min mv dif for gmv dif check, default = 1, note: dif between
+ * reg_mcdi_rel_det_gmv_dif_max and reg_mcdi_rel_det_gmv_dif_min
+ * should be; 0,1,3,7, not work for others
+ */
+/* Bit  7: 4, reg_mcdi_reldetgmvdifmax.
+ * max mv dif for gmv dif check, default = 4
+ */
+/* Bit  3: 1, reserved */
+/* Bit     0, reg_mcdi_reldetgmvdifmvmode.
+ * mv mode used for gmv dif check, 0: use refmv, 1: use qmv, default = 0
+ */
+#define MCDI_REL_DET_LMV_DIF_CHK                   ((0x2f30))
+/* Bit 31:24, reserved. */
+/* Bit 23:16, reg_mcdi_reldetlmvfltthd.
+ * flat thd (>=) for lmv lock decision, default = 12
+ */
+/* Bit 15:14, reserved. */
+/* Bit 13:12, reg_mcdi_reldetlmvlockchkmode.
+ * lmv lock check mode, 0:cur Lmv, 1: cur & (last | next),
+ * 2: last & cur & next Lmv, default = 1
+ */
+/* Bit    11, reserved. */
+/* Bit 10: 8, reg_mcdi_reldetlmvdifmin.
+ * min mv dif for lmv dif check, default = 1, note: dif between
+ * reg_mcdi_rel_det_lmv_dif_max and reg_mcdi_rel_det_lmv_dif_min should be;
+ * 0,1,3,7, not work for others
+ */
+/* Bit  7: 4, reg_mcdi_reldetlmvdifmax.
+ * max mv dif for lmv dif check, default = 4
+ */
+/* Bit  3: 1, reserved */
+/* Bit     0, reg_mcdi_reldetlmvdifmvmode.
+ * mv mode used for lmv dif check, 0: use refmv, 1: use qmv, default = 0
+ */
+#define MCDI_REL_DET_FRQ_CHK                       ((0x2f31))
+/* Bit 31:12, reserved. */
+/* Bit 11: 8, reg_mcdi_reldetfrqgain.
+ * gain for frequency check, normalized to 4 as '1', default = 10
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetfrqmax.
+ * max value for frequency check, default = 31
+ */
+#define MCDI_REL_DET_PD22_CHK                      ((0x2f32))
+/* Bit 31:18, reserved. */
+/* Bit 17: 8, reg_mcdi_reldetpd22chkoffst.
+ * offset for pd22 check happened, default = 512
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetpd22chkgain.
+ * gain for pd22 check happened, normalized to 8 as '1', default = 12
+ */
+#define MCDI_REL_DET_RPT_CHK_ROW                   ((0x2f33))
+/* Bit 31:27, reserved */
+/* Bit 26:16, reg_mcdi_reldetrptchkendrow.
+ * end row (<) number for repeat check, default = 2047
+ */
+/* Bit 15:11, reserved */
+/* Bit 10: 0, reg_mcdi_reldetrptchkstartrow.
+ * start row (>=) number for repeat check, default = 0
+ */
+#define MCDI_REL_DET_RPT_CHK_GAIN_QMV              ((0x2f34))
+/* Bit 31:30, reserved */
+/* Bit 29:24, reg_mcdi_reldetrptchkqmvmax.
+ * max thd (<) of abs qmv for repeat check, default = 15,
+ * note that quarter mv's range is -63~63
+ */
+/* Bit 23:22, reserved */
+/* Bit 21:16, reg_mcdi_reldetrptchkqmvmin.
+ * min thd (>=) of abs qmv for repeat check, default = 10,
+ * note that quarter mv's range is -63~63
+ */
+/* Bit    15, reserved/ */
+/* Bit 14: 4, reg_mcdi_reldetrptchkoffst.
+ * offset for repeat check, default = 512
+ */
+/* Bit  3: 0, reg_mcdi_reldetrptchkgain.
+ * gain for repeat check, normalized to 8 as '1', default = 4
+ */
+#define MCDI_REL_DET_RPT_CHK_THD_0                 ((0x2f35))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_reldetrptchkzerosadthd.
+ * zero sad thd (<) for repeat check, default = 255
+ */
+/* Bit 15:14, reserved. */
+/* Bit 13: 8, reg_mcdi_reldetrptchkzerobadwthd.
+ * zero badw thd (>=) for repeat check, default = 16
+ */
+/* Bit  7: 4, reserved */
+/* Bit  3: 0, reg_mcdi_reldetrptchkfrqdifthd.
+ * frequency dif thd (<) for repeat check, 0~10, default = 5
+ */
+#define MCDI_REL_DET_RPT_CHK_THD_1                 ((0x2f36))
+/* Bit 31:16, reserved */
+/* Bit 15: 8, reg_mcdi_reldetrptchkvdifthd.
+ * vertical dif thd (<) for repeat check, default = 16
+ */
+/* Bit  7: 0, reg_mcdi_reldetrptchkhdifthd.
+ * horizontal dif thd (>=) for repeat check, default = 16
+ */
+#define MCDI_REL_DET_LPF_DIF_THD                   ((0x2f37))
+/* Bit 31:24, reg_mcdi_reldetlpfdifthd3.
+ * hdif thd (<) for lpf selection of horizontal block, default = 9
+ */
+/* Bit 23:16, reg_mcdi_reldetlpfdifthd2.
+ * vdif-hdif thd (>=) for lpf selection of horizontal block, default = 48
+ */
+/* Bit 15: 8, reg_mcdi_reldetlpfdifthd1.
+ * vdif thd (<) for lpf selection of vertical block, default = 9
+ */
+/* Bit  7: 0, reg_mcdi_reldetlpfdifthd0.
+ * hdif-vdif thd (>=) for lpf selection of vertical block, default = 48
+ */
+#define MCDI_REL_DET_LPF_MSK_00_03                 ((0x2f38))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_reldetlpfmsk03.
+ * det lpf mask03 for gmv/lmv locked mode, 0~16, default = 1
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_reldetlpfmsk02.
+ * det lpf mask02 for gmv/lmv locked mode, 0~16, default = 1
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_reldetlpfmsk01.
+ * det lpf mask01 for gmv/lmv locked mode, 0~16, default = 5
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetlpfmsk00.
+ * det lpf mask00 for gmv/lmv locked mode, 0~16, default = 8
+ */
+#define MCDI_REL_DET_LPF_MSK_04_12                 ((0x2f39))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_reldetlpfmsk12.
+ * det lpf mask12 for vertical blocks, 0~16, default = 0
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_reldetlpfmsk11.
+ * det lpf mask11 for vertical blocks, 0~16, default = 0
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_reldetlpfmsk10.
+ * det lpf mask10 for vertical blocks, 0~16, default = 16
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetlpfmsk04.
+ * det lpf mask04 for gmv/lmv locked mode, 0~16, default = 1
+ */
+#define MCDI_REL_DET_LPF_MSK_13_21                 ((0x2f3a))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_reldetlpfmsk21.
+ * det lpf mask21 for horizontal blocks, 0~16, default = 6
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_reldetlpfmsk20.
+ * det lpf mask20 for horizontal blocks, 0~16, default = 8
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_reldetlpfmsk14.
+ * det lpf mask14 for vertical blocks, 0~16, default = 0
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetlpfmsk13.
+ * det lpf mask13 for vertical blocks, 0~16, default = 0
+ */
+#define MCDI_REL_DET_LPF_MSK_22_30                 ((0x2f3b))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_reldetlpfmsk30.
+ * det lpf mask30 for other blocks, 0~16, default = 16
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_reldetlpfmsk24.
+ * det lpf mask24 for horizontal blocks, 0~16, default = 1
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_reldetlpfmsk23.
+ * det lpf mask23 for horizontal blocks, 0~16, default = 0
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetlpfmsk22.
+ * det lpf mask22 for horizontal blocks, 0~16, default = 1
+ */
+#define MCDI_REL_DET_LPF_MSK_31_34                 ((0x2f3c))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_reldetlpfmsk34.
+ * det lpf mask34 for other blocks, 0~16, default = 0
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_reldetlpfmsk33.
+ * det lpf mask33 for other blocks, 0~16, default = 0
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_reldetlpfmsk32.
+ * det lpf mask32 for other blocks, 0~16, default = 0
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_reldetlpfmsk31.
+ * det lpf mask31 for other blocks, 0~16, default = 0
+ */
+/* Note: there are four group lpf masks from addr 37~3b,
+ * each group sum equal to 16.
+ */
+#define MCDI_REL_DET_MIN                           ((0x2f3d))
+/* Bit 31: 7, reserved */
+/* Bit  6: 0, reg_mcdi_reldetmin.
+ * min of detected value, default = 16
+ */
+#define MCDI_REL_DET_LUT_0_3                       ((0x2f3e))
+/* Bit 31:24, reg_mcdi_reldetmaplut3.               default = 8 */
+/* Bit 23:16, reg_mcdi_reldetmaplut2.               default = 4 */
+/* Bit 15: 8, reg_mcdi_reldetmaplut1.               default = 2 */
+/* Bit  7: 0, reg_mcdi_reldetmaplut0.               default = 0 */
+#define MCDI_REL_DET_LUT_4_7                       ((0x2f3f))
+/* Bit 31:24, reg_mcdi_reldetmaplut7.               default = 64 */
+/* Bit 23:16, reg_mcdi_reldetmaplut6.               default = 48 */
+/* Bit 15: 8, reg_mcdi_reldetmaplut5.               default = 32 */
+/* Bit  7: 0, reg_mcdi_reldetmaplut4.               default = 16 */
+#define MCDI_REL_DET_LUT_8_11                      ((0x2f40))
+/* Bit 31:24, reg_mcdi_reldetmaplut11.              default = 160 */
+/* Bit 23:16, reg_mcdi_reldetmaplut10.              default = 128 */
+/* Bit 15: 8, reg_mcdi_reldetmaplut9.               default = 96 */
+/* Bit  7: 0, reg_mcdi_reldetmaplut8.               default = 80 */
+#define MCDI_REL_DET_LUT_12_15                     ((0x2f41))
+/* Bit 31:24, reg_mcdi_reldetmaplut15.              default = 255 */
+/* Bit 23:16, reg_mcdi_reldetmaplut14.              default = 240 */
+/* Bit 15: 8, reg_mcdi_reldetmaplut13.              default = 224 */
+/* Bit  7: 0, reg_mcdi_reldetmaplut12.              default = 192 */
+#define MCDI_REL_DET_COL_CFD_THD                   ((0x2f42))
+/* Bit 31:24, reg_mcdi_reldetcolcfdfltthd.
+ * thd for flat smaller than (<) of column cofidence, default = 5
+ */
+/* Bit 23:16, reg_mcdi_reldetcolcfdthd1.
+ * thd for rel larger than (>=) in rel calc.
+ * mode col confidence without gmv locking, default = 160
+ */
+/* Bit 15: 8, reg_mcdi_reldetcolcfdthd0.
+ * thd for rel larger than (>=) in rel calc.
+ * mode col confidence when gmv locked, default = 100
+ */
+/* Bit  7: 2, reg_mcdi_reldetcolcfdbadwthd.
+ * thd for badw larger than (>=) in qbadw calc.
+ * mode of column cofidence, default = 16
+ */
+/* Bit     1, reserved */
+/* Bit     0, reg_mcdi_reldetcolcfdcalcmode.        calc.
+ * mode for column cofidence, 0: use rel, 1: use qbadw, default = 0
+ */
+#define MCDI_REL_DET_COL_CFD_AVG_LUMA              ((0x2f43))
+/* Bit 31:24, reg_mcdi_reldetcolcfdavgmin1.
+ * avg luma min1 (>=) for column cofidence, valid between 16~235, default = 235
+ */
+/* Bit 23:16, reg_mcdi_reldetcolcfdavgmax1.
+ * avg luma max1 (<)  for column cofidence, valid between 16~235, default = 235
+ */
+/* Bit 15: 8, reg_mcdi_reldetcolcfdavgmin0.
+ * avg luma min0 (>=) for column cofidence, valid between 16~235, default = 16
+ */
+/* Bit  7: 0, reg_mcdi_reldetcolcfdavgmax0.
+ * avg luma max0 (<)  for column cofidence, valid between 16~235, default = 21
+ */
+#define MCDI_REL_DET_BAD_THD_0                     ((0x2f44))
+/* Bit 31:16, reserved */
+/* Bit 15: 8, reg_mcdi_reldetbadsadthd.
+ * thd (>=) for bad sad, default = 120 (480/4)
+ */
+/* Bit  7: 6, reserved */
+/* Bit  5: 0, reg_mcdi_reldetbadbadwthd.
+ * thd (>=) for bad badw, 0~42, default = 12
+ */
+#define MCDI_REL_DET_BAD_THD_1                     ((0x2f45))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_reldetbadrelfltthd.
+ * thd (>=) of flat for bad rel detection, default = 4
+ */
+/* Bit 15: 8, reg_mcdi_reldetbadrelthd1.
+ * thd (>=) for bad rel without gmv/lmv locked, default = 160
+ */
+/* Bit  7: 0, reg_mcdi_reldetbadrelthd0.
+ * thd (>=) for bad rel with gmv/lmv locked, default = 120
+ */
+#define MCDI_PD22_CHK_THD                          ((0x2f46))
+/* Bit 31:25, reserved */
+/* Bit 24:16, reg_mcdi_pd22chksaddifthd.
+ * sad dif thd (>=) for (pd22chksad - qsad) for pd22 check, default = 64
+ */
+/* Bit 15:14, reserved */
+/* Bit 13: 8, reg_mcdi_pd22chkqmvthd.
+ * thd (>=) of abs qmv for pd22 check, default = 2
+ */
+/* Bit  7: 0, reg_mcdi_pd22chkfltthd.
+ * thd (>=) of flat for pd22 check, default = 4
+ */
+#define MCDI_PD22_CHK_GAIN_OFFST_0                 ((0x2f47))
+/* Bit 31:24, reg_mcdi_pd22chkedgeoffst0.
+ * offset0 of pd22chkedge from right film22 phase, -128~127, default = 0
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_pd22chkedgegain0.
+ * gain0 of pd22chkedge from right film22 phase,
+ * normalized to 16 as '1', default = 16
+ */
+/* Bit 15:12, reserved */
+/* Bit 11: 8, reg_mcdi_pd22chkbadwoffst0.
+ * offset0 of pd22chkbadw from right film22 phase, -8~7, default = 0
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_pd22chkbadwgain0.
+ * gain0 of pd22chkbadw from right film22 phase,
+ * normalized to 16 as '1', default = 8
+ */
+#define MCDI_PD22_CHK_GAIN_OFFST_1                 ((0x2f48))
+/* Bit 31:24, reg_mcdi_pd22chkedgeoffst1.
+ * offset1 of pd22chkedge from right film22 phase, -128~127, default = 0
+ */
+/* Bit 23:21, reserved */
+/* Bit 20:16, reg_mcdi_pd22chkedgegain1.
+ * gain1 of pd22chkedge from right film22 phase,
+ * normalized to 16 as '1', default = 16
+ */
+/* Bit 15:12, reserved */
+/* Bit 11: 8, reg_mcdi_pd22chkbadwoffst1.
+ * offset1 of pd22chkbadw from right film22 phase, -8~7, default = 0
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_pd22chkbadwgain1.
+ * gain1 of pd22chkbadw from right film22 phase,
+ * normalized to 16 as '1', default = 12
+ */
+#define MCDI_LMV_LOCK_CNT_THD_GAIN                 ((0x2f49))
+/* Bit 31:20, reserved */
+/* Bit 19:16, reg_mcdi_lmvlockcntmax.
+ * max lmv lock count number, default = 6
+ */
+/* Bit 15:12, reg_mcdi_lmvlockcntoffst.
+ * offset for lmv lock count, -8~7, default =  0
+ */
+/* Bit 11: 8, reg_mcdi_lmvlockcntgain.
+ * gain for lmv lock count, normalized 8 as '1', 15 is set to 16, default = 8
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_lmvlockcntthd.
+ * lmv count thd (>=) before be locked, 1~31, default = 4
+ */
+#define MCDI_LMV_LOCK_ABS_DIF_THD                  ((0x2f4a))
+/* Bit 31:27, reserved */
+/* Bit 26:24, reg_mcdi_lmvlockdifthd2.
+ * lmv dif thd for third part, before locked, default = 1
+ */
+/* Bit    23, reserved */
+/* Bit 22:20, reg_mcdi_lmvlockdifthd1.
+ * lmv dif thd for second part, before locked, default = 1
+ */
+/* Bit    19, reserved */
+/* Bit 18:16, reg_mcdi_lmvlockdifthd0.
+ * lmv dif thd for first part, before locked, default = 1
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_lmvlockabsmax.
+ * max abs (<) of lmv to be locked, default = 24
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_lmvlockabsmin.
+ * min abs (>=) of lmv to be locked, default = 1
+ */
+#define MCDI_LMV_LOCK_ROW                          ((0x2f4b))
+/* Bit 31:27, reserved */
+/* Bit 26:16, reg_mcdi_lmvlockendrow.
+ * end row (<) for lmv lock, default = 2047
+ */
+/* Bit 15:11, reserved */
+/* Bit 10: 0, reg_mcdi_lmvlockstartrow.
+ * start row (>=) for lmv lock, default = 0
+ */
+#define MCDI_LMV_LOCK_RT_MODE                      ((0x2f4c))
+/* Bit 31:27, reserved */
+/* Bit 26:24, reg_mcdi_lmvlockextmode.
+ * extend lines for lmv lock check, check how many lines
+ * for lmv locking, default = 2
+ */
+/* Bit 23:16, reg_mcdi_lmvlockfltcntrt.
+ * ratio of flt cnt for lock check, normalized 256 as '1',
+ * 255 is set to 256, default = 32
+ */
+/* Bit 15: 8, reg_mcdi_lmvlocklmvcntrt1.
+ * ratio when use non-zero lmv for lock check,
+ * normalized 256 as '1', 255 is set to 256, default = 48
+ */
+/* Bit  7: 0, reg_mcdi_lmvlocklmvcntrt0.
+ * ratio when use max lmv for lock check, normalized 256 as '1',
+255 is set to 256, default = 106
+*/
+#define MCDI_GMV_LOCK_CNT_THD_GAIN                 ((0x2f4d))
+/* Bit 31:20, reserved */
+/* Bit 19:16, reg_mcdi_gmvlockcntmax.
+ * max gmv lock count number, default = 6
+ */
+/* Bit 15:12, reg_mcdi_gmvlockcntoffst.
+ * offset for gmv lock count, -8~7, default =  0
+ */
+/* Bit 11: 8, reg_mcdi_gmvlockcntgain.
+ * gain for gmv lock count, normalized 8 as '1', 15 is set to 16, default = 8
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_gmvlockcntthd.
+ * gmv count thd (>=) before be locked, 1~31, default = 4
+ */
+#define MCDI_GMV_LOCK_ABS_DIF_THD                  ((0x2f4e))
+/* Bit 31:27, reserved */
+/* Bit 26:24, reg_mcdi_gmvlockdifthd2.
+ * gmv dif thd for third part, before locked, default = 3
+ */
+/* Bit    23, reserved */
+/* Bit 22:20, reg_mcdi_gmvlockdifthd1.
+ * gmv dif thd for second part, before locked, default = 2
+ */
+/* Bit    19, reserved */
+/* Bit 18:16, reg_mcdi_gmvlockdifthd0.
+ * gmv dif thd for first part, before locked, default = 1
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_gmvlockabsmax.
+ * max abs of gmv to be locked, default = 15
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_gmvlockabsmin.
+ * min abs of gmv to be locked, default = 1
+ */
+#define MCDI_HIGH_VERT_FRQ_DIF_THD                 ((0x2f4f))
+/* Bit 31: 0, reg_mcdi_highvertfrqfldavgdifthd.
+ * high_vert_frq field average luma dif thd (>=), 3*Blk_Width*Blk_Height,
+ * set by software, default = 103680
+ */
+#define MCDI_HIGH_VERT_FRQ_DIF_DIF_THD             ((0x2f50))
+/* Bit 31: 0, reg_mcdi_highvertfrqfldavgdifdifthd.
+ * high_vert_frq field average luma dif's dif thd (<), 3*Blk_Width*Blk_Height,
+ * set by software, default = 103680
+ */
+#define MCDI_HIGH_VERT_FRQ_RT_GAIN                 ((0x2f51))
+/* Bit 31:20, reserved */
+/* Bit 19:16, reg_mcdi_highvertfrqcntthd.
+ * high_vert_frq count thd (>=) before locked, 1~31, default = 4
+ */
+/* Bit 15: 8, reg_mcdi_highvertfrqbadsadrt.
+ * ratio for high_vert_frq bad sad count, normalized 256 as '1',
+ * 255 is set to 256, default = 24
+ */
+/* Bit  7: 0, reg_mcdi_highvertfrqbadbadwrt.
+ * ratio for high_vert_frq badw count, normalized 256 as '1',
+ * 255 is set to 256, default = 130
+ */
+#define MCDI_MOTION_PARADOX_THD                    ((0x2f52))
+/* Bit 31:29, reserved */
+/* Bit 28:24, reg_mcdi_motionparadoxcntthd.
+ * motion paradox count thd (>=) before locked, 1~31, default = 4
+ */
+/* Bit 23:22, reserved */
+/* Bit 21:16, reg_mcdi_motionparadoxgmvthd.
+ * abs gmv thd (<) of motion paradox, 0~32, note that 32
+ * means invalid gmv, be careful, default = 32
+ */
+/* Bit 15: 0, reserved */
+#define MCDI_MOTION_PARADOX_RT                     ((0x2f53))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_motionparadoxbadsadrt.
+ * ratio for field bad sad count of motion paradox,
+ * normalized 256 as '1', 255 is set to 256, default = 24
+ */
+/* Bit 15: 8, reg_mcdi_motionparadoxbadrelrt.
+ * ratio for field bad reliabilty count of motion paradox,
+ * normalized 256 as '1', 255 is set to 256, default = 120
+ */
+/* Bit  7: 0, reg_mcdi_motionparadoxmtnrt.
+ * ratio for field motion count of motion paradox,
+ * normalized 256 as '1', 255 is set to 256, default = 218
+ */
+#define MCDI_MOTION_REF_THD                        ((0x2f54))
+/* Bit 31:24, reserved */
+/* Bit 23:20, reg_mcdi_motionrefoffst.
+ * motion ref additive offset, default = 15
+ */
+/* Bit 19:16, reg_mcdi_motionrefgain.
+ * motion ref gain, normalized 8 as '1', default = 8
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_motionrefrptmvthd.
+ * abs thd (>=) of rpt mv (0~31, 32 means invalid) for motion ref, default = 1
+ */
+/* Bit  7: 2, reg_mcdi_motionrefqmvthd.
+ * min thd (>=) of abs qmv for motion ref,
+ * note that quarter mv's range is -63~63, default = 2
+ */
+/* Bit  1: 0, reg_mcdi_motionreflpfmode.
+ * Mv and (8 x repeat flg) 's lpf mode of motion refinement,
+ * 0: no lpf, 1: [1 2 1], 2: [1 2 2 2 1], default = 1
+ */
+#define MCDI_REL_COL_REF_RT                        ((0x2f55))
+/* Bit 31: 8, reserved */
+/* Bit  7: 0, reg_mcdi_relcolrefrt.
+ * ratio for column cofidence level against column number,
+ * for refinement, default = 135
+ */
+#define MCDI_PD22_CHK_THD_RT                       ((0x2f56))
+/* Bit 31:27, reserved */
+/* Bit 26:16, reg_mcdi_pd22chkfltcntrt.
+ * ratio for flat count of field pulldown 22 check, normalized 2048 as '1',
+ * 2047 is set to 2048, default = 1
+ */
+/* Bit 15: 8, reg_mcdi_pd22chkcntrt.  ratio of pulldown 22 check count,
+ * normalized 256 as '1', 255 is set to 256, default = 100
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_pd22chkcntthd.
+ * thd (>=) for pd22 count before locked, 1~31, default = 4
+ */
+#define MCDI_CHAR_DET_DIF_THD                      ((0x2f57))
+/* Bit 31:24, reserved */
+/* Bit 23:16, reg_mcdi_chardetminmaxdifthd.
+ * thd (>=) for dif between min and max value, default = 64
+ */
+/* Bit 15: 8, reg_mcdi_chardetmaxdifthd.
+ * thd (<) for dif between max value, default = 17
+ */
+/* Bit  7: 0, reg_mcdi_chardetmindifthd.
+ * thd (<) for dif between min value, default = 17
+ */
+#define MCDI_CHAR_DET_CNT_THD                      ((0x2f58))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_chardettotcntthd.
+ * thd (>=) for total count, 0~21, default = 18
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_chardetmaxcntthd.
+ * thd (>=) for max count, 0~21, default = 1
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_chardetmincntthd.
+ * thd (>=) for min count, 0~21, default = 1
+ */
+#define MCDI_FIELD_MV                              ((0x2f60))
+/* Bit 31:24, reg_mcdi_pd22chkcnt */
+/* Bit 23:16, reg_mcdi_fieldgmvcnt */
+/* Bit    15, reg_mcdi_pd22chkflg */
+/* Bit    14, reg_mcdi_fieldgmvlock */
+/* Bit 13: 8, reg_mcdi_fieldrptmv.                last field rpt mv */
+/* Bit  7: 6, reserved */
+/* Bit  5: 0, reg_mcdi_fieldgmv.                    last field gmv */
+#define MCDI_FIELD_HVF_PRDX_CNT                    ((0x2f61))
+/* Bit 31:24, reg_mcdi_motionparadoxcnt. */
+/* Bit 23:17, reserved */
+/* Bit    16, reg_mcdi_motionparadoxflg. */
+/* Bit 15: 8, reg_mcdi_highvertfrqcnt. */
+/* Bit  7: 4, reserved */
+/* Bit  3: 2, reg_mcdi_highvertfrqphase. */
+/* Bit     1, reserved */
+/* Bit     0, reg_mcdi_highvertfrqflg. */
+#define MCDI_FIELD_LUMA_AVG_SUM_0                  ((0x2f62))
+/* Bit 31: 0, reg_mcdi_fld_luma_avg_sum0. */
+#define MCDI_FIELD_LUMA_AVG_SUM_1                  ((0x2f63))
+/* Bit 31: 0, reg_mcdi_fld_luma_avg_sum1. */
+#define MCDI_YCBCR_BLEND_CRTL                      ((0x2f64))
+/* Bit 31:16, reserved */
+/* Bit 15: 8, reg_mcdi_ycbcrblendgain.
+ * ycbcr blending gain for cbcr in ycbcr. default = 0
+ */
+/* Bit  7: 2, reserved. */
+/* Bit  1: 0, reg_mcdi_ycbcrblendmode.
+ * 0:y+cmb(cb,cr), 1:med(r,g,b), 2:max(r,g,b), default = 2
+ */
+#define MCDI_MCVECWR_CANVAS_SIZE                   ((0x2f65))
+#define MCDI_MCVECRD_CANVAS_SIZE                   ((0x2f66))
+#define MCDI_MCINFOWR_CANVAS_SIZE                  ((0x2f67))
+#define MCDI_MCINFORD_CANVAS_SIZE                  ((0x2f68))
+#define MCDI_LMVLCKSTEXT_0                         ((0x2f69))
+#define MCDI_LMVLCKSTEXT_1                         ((0x2f6a))
+#define MCDI_LMVLCKEDEXT_0                         ((0x2f6b))
+#define MCDI_LMVLCKEDEXT_1                         ((0x2f6c))
+#define MCDI_MCVECWR_X                             ((0x2f92))
+#define MCDI_MCVECWR_Y                             ((0x2f93))
+#define MCDI_MCVECWR_CTRL                          ((0x2f94))
+#define MCDI_MCVECRD_X                             ((0x2f95))
+#define MCDI_MCVECRD_Y                             ((0x2f96))
+#define MCDI_MCVECRD_CTRL                          ((0x2f97))
+#define MCDI_MCINFOWR_X                            ((0x2f98))
+#define MCDI_MCINFOWR_Y                            ((0x2f99))
+#define MCDI_MCINFOWR_CTRL                         ((0x2f9a))
+#define MCDI_MCINFORD_X                            ((0x2f9b))
+#define MCDI_MCINFORD_Y                            ((0x2f9c))
+#define MCDI_MCINFORD_CTRL                         ((0x2f9d))
+/* === MC registers ============================================ */
+#define MCDI_MC_CRTL                               ((0x2f70))
+/* Bit 31: 9, reserved */
+/* Bit     8, reg_mcdi_mcpreflg.
+ * flag to use previous field for MC, 0:forward field,
+ * 1: previous field, default = 1
+ */
+/* Bit     7, reg_mcdi_mcrelrefbycolcfden.
+ * enable rel refinement by column cofidence in mc blending, default = 1
+ */
+/* Bit  6: 5, reg_mcdi_mclpfen.
+ * enable mc pixles/rel lpf, 0:disable, 1: lpf rel,
+ * 2: lpf mc pxls, 3: lpf both rel and mc pxls, default = 0
+ */
+/* Bit  4: 2, reg_mcdi_mcdebugmode.
+ * enable mc debug mode, 0:disable, 1: split left/right,
+ * 2: split top/bottom, 3: debug mv, 4: debug rel, default = 0
+ */
+/* Bit  1: 0, reg_mcdi_mcen.
+ * mcdi enable mode, 0:disable, 1: blend with ma, 2: full mc, default = 1
+ */
+#define MCDI_MC_LPF_MSK_0                          ((0x2f71))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_mclpfmsk02.
+ * mc lpf coef. 2 for pixel 0 of current block,normalized 16 as '1', default = 0
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_mclpfmsk01.
+ * mc lpf coef. 1 for pixel 0 of current block,normalized 16 as '1', default = 9
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_mclpfmsk00.
+ * mc lpf coef. 0 for pixel 0 of current block,normalized 16 as '1', default = 7
+ */
+#define MCDI_MC_LPF_MSK_1                          ((0x2f72))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_mclpfmsk12.
+ * mc lpf coef. 2 for pixel 1 of current block,
+ * 0~16, normalized 16 as '1', default = 0
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_mclpfmsk11.
+ * mc lpf coef. 1 for pixel 1 of current block, 0~16,
+ * normalized 16 as '1', default = 11
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_mclpfmsk10.
+ * mc lpf coef. 0 for pixel 1 of current block, 0~16,
+ * normalized 16 as '1', default = 5
+ */
+#define MCDI_MC_LPF_MSK_2                          ((0x2f73))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_mclpfmsk22.
+ * mc lpf coef. 2 for pixel 2 of current block, 0~16,
+ * normalized 16 as '1', default = 1
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_mclpfmsk21.
+ * mc lpf coef. 1 for pixel 2 of current block, 0~16,
+ * normalized 16 as '1', default = 14
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_mclpfmsk20.
+ * mc lpf coef. 0 for pixel 2 of current block, 0~16,
+ * normalized 16 as '1', default = 1
+ */
+#define MCDI_MC_LPF_MSK_3                          ((0x2f74))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_mclpfmsk32.
+ * mc lpf coef. 2 for pixel 3 of current block, 0~16,
+ * normalized 16 as '1', default = 5
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_mclpfmsk31.
+ * mc lpf coef. 1 for pixel 3 of current block, 0~16,
+ * normalized 16 as '1', default = 11
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_mclpfmsk30.
+ * mc lpf coef. 0 for pixel 3 of current block, 0~16,
+ * normalized 16 as '1', default = 0
+ */
+#define MCDI_MC_LPF_MSK_4                          ((0x2f75))
+/* Bit 31:21, reserved */
+/* Bit 20:16, reg_mcdi_mclpfmsk42.
+ * mc lpf coef. 2 for pixel 4 of current block, 0~16,
+ * normalized 16 as '1', default = 7
+ */
+/* Bit 15:13, reserved */
+/* Bit 12: 8, reg_mcdi_mclpfmsk41.
+ * mc lpf coef. 1 for pixel 4 of current block, 0~16,
+ * normalized 16 as '1', default = 9
+ */
+/* Bit  7: 5, reserved */
+/* Bit  4: 0, reg_mcdi_mclpfmsk40.
+ * mc lpf coef. 0 for pixel 4 of current block, 0~16,
+ * normalized 16 as '1', default = 0
+ */
+#define MCDI_MC_REL_GAIN_OFFST_0                   ((0x2f76))
+/* Bit 31:26, reserved */
+/* Bit    25, reg_mcdi_mcmotionparadoxflg.
+ * flag of motion paradox, initial with 0 and read from software, default = 0
+ */
+/* Bit    24, reg_mcdi_mchighvertfrqflg.
+ * flag of high vert frq, initial with 0 and read from software, default = 0
+ */
+/* Bit 23:16, reg_mcdi_mcmotionparadoxoffst.
+ * offset (rel + offset) for rel (MC blending coef.)
+ * refinement if motion paradox
+ * detected before MC blending before MC blending, default = 128
+ */
+/* Bit 15:12, reserved */
+/* Bit 11: 8, reg_mcdi_mcmotionparadoxgain.
+ * gain for rel (MC blending coef.)
+ * refinement if motion paradox detected before MC
+ * blending, normalized 8 as '1', set 15 to 16, default = 8
+ */
+/* Bit  7: 4, reg_mcdi_mchighvertfrqoffst.          minus offset
+ * (alpha - offset) for motion (MA blending coef.) refinement if high vertical
+ * frequency detected before MA blending, default = 15
+ */
+/* Bit  3: 0, reg_mcdi_mchighvertfrqgain.
+ * gain for motion (MA blending coef.) refinement if high vertical frequency
+ * detected before MA blending, normalized 8 as '1', set 15 to 16, default = 8
+ */
+#define MCDI_MC_REL_GAIN_OFFST_1                   ((0x2f77))
+/* Bit 31:24, reg_mcdi_mcoutofboundrayoffst.
+ * offset (rel + offset) for rel (MC blending coef.) refinement
+ * if MC pointed out
+ * of boundray before MC blending before MC blending, default = 255
+ */
+/* Bit 23:20, reserved*/
+/* Bit 19:16, reg_mcdi_mcoutofboundraygain.
+ * gain for rel (MC blending coef.) refinement
+ * if MC pointed out of boundray before
+ * MC blending, normalized 8 as '1', set 15 to 16, default = 8
+ */
+/* Bit 15: 8, reg_mcdi_mcrelrefbycolcfdoffst.
+ * offset (rel + offset) for rel (MC blending coef.) refinement
+ * if motion paradox
+ * detected before MC blending before MC blending, default = 255
+ */
+/* Bit  7: 4, reserved. */
+/* Bit  3: 0, reg_mcdi_mcrelrefbycolcfdgain.
+ * gain for rel (MC blending coef.) refinement
+ * if column cofidence failed before MC
+ * blending, normalized 8 as '1', set 15 to 16, default = 8
+ */
+#define MCDI_MC_COL_CFD_0                          ((0x2f78))
+/* Bit 31: 0, mcdi_mc_col_cfd_0.
+ * column cofidence value 0 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_1                          ((0x2f79))
+/* Bit 31: 0, mcdi_mc_col_cfd_1.
+ * column cofidence value 1 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_2                          ((0x2f7a))
+/* Bit 31: 0, mcdi_mc_col_cfd_2.
+ * column cofidence value 2 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_3                          ((0x2f7b))
+/* Bit 31: 0, mcdi_mc_col_cfd_3.
+ * column cofidence value 3 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_4                          ((0x2f7c))
+/* Bit 31: 0, mcdi_mc_col_cfd_4.
+ * column cofidence value 4 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_5                          ((0x2f7d))
+/* Bit 31: 0, mcdi_mc_col_cfd_5.
+ * column cofidence value 5 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_6                          ((0x2f7e))
+/* Bit 31: 0, mcdi_mc_col_cfd_6.
+ * column cofidence value 6 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_7                          ((0x2f7f))
+/* Bit 31: 0, mcdi_mc_col_cfd_7.
+ * column cofidence value 7 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_8                          ((0x2f80))
+/* Bit 31: 0, mcdi_mc_col_cfd_8.
+ * column cofidence value 8 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_9                          ((0x2f81))
+/* Bit 31: 0, mcdi_mc_col_cfd_9.
+ * column cofidence value 9 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_10                         ((0x2f82))
+/* Bit 31: 0, mcdi_mc_col_cfd_10.
+ * column cofidence value 10 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_11                         ((0x2f83))
+/* Bit 31: 0, mcdi_mc_col_cfd_11.
+ * column cofidence value 11 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_12                         ((0x2f84))
+/* Bit 31: 0, mcdi_mc_col_cfd_12.
+ * column cofidence value 12 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_13                         ((0x2f85))
+/* Bit 31: 0, mcdi_mc_col_cfd_13.
+ * column cofidence value 13 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_14                         ((0x2f86))
+/* Bit 31: 0, mcdi_mc_col_cfd_14.
+ * column cofidence value 14 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_15                         ((0x2f87))
+/* Bit 31: 0, mcdi_mc_col_cfd_15.
+ * column cofidence value 15 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_16                         ((0x2f88))
+/* Bit 31: 0, mcdi_mc_col_cfd_16.
+ * column cofidence value 16 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_17                         ((0x2f89))
+/* Bit 31: 0, mcdi_mc_col_cfd_17.
+ * column cofidence value 17 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_18                         ((0x2f8a))
+/* Bit 31: 0, mcdi_mc_col_cfd_18.
+ * column cofidence value 18 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_19                         ((0x2f8b))
+/* Bit 31: 0, mcdi_mc_col_cfd_19.
+ * column cofidence value 19 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_20                         ((0x2f8c))
+/* Bit 31: 0, mcdi_mc_col_cfd_20.
+ * column cofidence value 20 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_21                         ((0x2f8d))
+/* Bit 31: 0, mcdi_mc_col_cfd_21.
+ * column cofidence value 21 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_22                         ((0x2f8e))
+/* Bit 31: 0, mcdi_mc_col_cfd_22.
+ * column cofidence value 22 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_23                         ((0x2f8f))
+/* Bit 31: 0, mcdi_mc_col_cfd_23.
+ * column cofidence value 23 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_24                         ((0x2f90))
+/* Bit 31: 0, mcdi_mc_col_cfd_24.
+ * column cofidence value 24 read from software. initial = 0
+ */
+#define MCDI_MC_COL_CFD_25                         ((0x2f91))
+/* Bit 31: 0, mcdi_mc_col_cfd_25.
+ * column cofidence value 25 read from software. initial = 0
+ */
+/* ======= PRE RO Registers ==================================== */
+#define MCDI_RO_FLD_LUMA_AVG_SUM                   ((0x2fa0))
+/* Bit 31: 0, ro_mcdi_fldlumaavgsum.
+ * block's luma avg sum of current filed (block based). initial = 0
+ */
+#define MCDI_RO_GMV_VLD_CNT                        ((0x2fa1))
+/* Bit 31: 0, ro_mcdi_gmvvldcnt.
+ * valid gmv's count of pre one filed (block based). initial = 0
+ */
+#define MCDI_RO_RPT_FLG_CNT                        ((0x2fa2))
+/* Bit 31: 0, ro_mcdi_rptflgcnt.
+ * repeat mv's count of pre one filed (block based). initial = 0
+ */
+#define MCDI_RO_FLD_BAD_SAD_CNT                    ((0x2fa3))
+/* Bit 31: 0, ro_mcdi_fldbadsadcnt.
+ * bad sad count of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_FLD_BAD_BADW_CNT                   ((0x2fa4))
+/* Bit 31: 0, ro_mcdi_fldbadbadwcnt.
+ * bad badw count of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_FLD_BAD_REL_CNT                    ((0x2fa5))
+/* Bit 31: 0, ro_mcdi_fldbadrelcnt.
+ * bad rel count of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_FLD_MTN_CNT                        ((0x2fa6))
+/* Bit 31: 0, ro_mcdi_fldmtncnt.
+ * motion count of whole pre one field (pixel based). initial = 0
+ */
+#define MCDI_RO_FLD_VLD_CNT                        ((0x2fa7))
+/* Bit 31: 0, ro_mcdi_fldvldcnt.
+ * valid motion count of whole pre one field (pixel based). initial = 0
+ */
+#define MCDI_RO_FLD_PD_22_PRE_CNT                  ((0x2fa8))
+/* Bit 31: 0, ro_mcdi_fldpd22precnt.
+ * prevoius pd22 check count of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_FLD_PD_22_FOR_CNT                  ((0x2fa9))
+/* Bit 31: 0, ro_mcdi_fldpd22forcnt.
+ * forward pd22 check count of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_FLD_PD_22_FLT_CNT                  ((0x2faa))
+/* Bit 31: 0, ro_mcdi_fldpd22fltcnt.
+ * flat count (for pd22 check) of whole pre one field (block based). initial = 0
+ */
+#define MCDI_RO_HIGH_VERT_FRQ_FLG                  ((0x2fab))
+/* Bit 31:16, reserved. */
+/* Bit 15: 8, ro_mcdi_highvertfrqcnt.
+ * high vertical frequency count till prevoius one field. initial = 0
+ */
+/* Bit  7: 3, reserved. */
+/* Bit  2: 1, ro_mcdi_highvertfrqphase.
+ * high vertical frequency phase of prevoius one field. initial = 2
+ */
+/* Bit     0, ro_mcdi_highvertfrqflg.
+ * high vertical frequency flag of prevoius one field. initial = 0
+ */
+#define MCDI_RO_GMV_LOCK_FLG                       ((0x2fac))
+/* Bit 31:16, reserved. */
+/* Bit 15: 8, ro_mcdi_gmvlckcnt.
+ * global mv lock count till prevoius one field. initial = 0
+ */
+/* Bit  7: 2, ro_mcdi_gmv.
+ * global mv of prevoius one field. -31~31, initial = 32 (invalid value)
+ */
+/* Bit     1, ro_mcdi_zerogmvlckflg.
+ * zero global mv lock flag of prevoius one field. initial = 0
+ */
+/* Bit     0, ro_mcdi_gmvlckflg.
+ * global mv lock flag of prevoius one field. initial = 0
+ */
+#define MCDI_RO_RPT_MV                             ((0x2fad))
+/* Bit 5: 0, ro_mcdi_rptmv.
+ * repeate mv of prevoius one field. -31~31, initial = 32 (invalid value)
+ */
+#define MCDI_RO_MOTION_PARADOX_FLG                 ((0x2fae))
+/* Bit 31:16, reserved. */
+/* Bit 15: 8, ro_mcdi_motionparadoxcnt.
+ * motion paradox count till prevoius one field. initial = 0
+ */
+/* Bit  7: 1, reserved. */
+/* Bit     0, ro_mcdi_motionparadoxflg.
+ * motion paradox flag of prevoius one field. initial = 0
+ */
+#define MCDI_RO_PD_22_FLG                          ((0x2faf))
+/* Bit 31:16, reserved. */
+/* Bit 15: 8, ro_mcdi_pd22cnt.
+ * pull down 22 count till prevoius one field. initial = 0
+ */
+/* Bit  7: 1, reserved. */
+/* Bit     0, ro_mcdi_pd22flg.
+ * pull down 22 flag of prevoius one field. initial = 0
+ */
+#define MCDI_RO_COL_CFD_0                          ((0x2fb0))
+/* Bit 31: 0, ro_mcdi_col_cfd_0.
+ * column cofidence value 0. initial = 0
+ */
+#define MCDI_RO_COL_CFD_1                          ((0x2fb1))
+/* Bit 31: 0, ro_mcdi_col_cfd_1.
+ * column cofidence value 1. initial = 0
+ */
+#define MCDI_RO_COL_CFD_2                          ((0x2fb2))
+/* Bit 31: 0, ro_mcdi_col_cfd_2.
+ * column cofidence value 2. initial = 0
+ */
+#define MCDI_RO_COL_CFD_3                          ((0x2fb3))
+/* Bit 31: 0, ro_mcdi_col_cfd_3.
+ * column cofidence value 3. initial = 0
+ */
+#define MCDI_RO_COL_CFD_4                          ((0x2fb4))
+/* Bit 31: 0, ro_mcdi_col_cfd_4.
+ * column cofidence value 4. initial = 0
+ */
+#define MCDI_RO_COL_CFD_5                          ((0x2fb5))
+/* Bit 31: 0, ro_mcdi_col_cfd_5.
+ * column cofidence value 5. initial = 0
+ */
+#define MCDI_RO_COL_CFD_6                          ((0x2fb6))
+/* Bit 31: 0, ro_mcdi_col_cfd_6.      column cofidence value 6. initial = 0 */
+#define MCDI_RO_COL_CFD_7                          ((0x2fb7))
+/* Bit 31: 0, ro_mcdi_col_cfd_7.      column cofidence value 7. initial = 0 */
+#define MCDI_RO_COL_CFD_8                          ((0x2fb8))
+/* Bit 31: 0, ro_mcdi_col_cfd_8.      column cofidence value 8. initial = 0 */
+#define MCDI_RO_COL_CFD_9                          ((0x2fb9))
+/* Bit 31: 0, ro_mcdi_col_cfd_9.      column cofidence value 9. initial = 0 */
+#define MCDI_RO_COL_CFD_10                         ((0x2fba))
+/* Bit 31: 0, ro_mcdi_col_cfd_10.     column cofidence value 10. initial = 0 */
+#define MCDI_RO_COL_CFD_11                         ((0x2fbb))
+/* Bit 31: 0, ro_mcdi_col_cfd_11.     column cofidence value 11. initial = 0 */
+#define MCDI_RO_COL_CFD_12                         ((0x2fbc))
+/* Bit 31: 0, ro_mcdi_col_cfd_12.     column cofidence value 12. initial = 0 */
+#define MCDI_RO_COL_CFD_13                         ((0x2fbd))
+/* Bit 31: 0, ro_mcdi_col_cfd_13.     column cofidence value 13. initial = 0 */
+#define MCDI_RO_COL_CFD_14                         ((0x2fbe))
+/* Bit 31: 0, ro_mcdi_col_cfd_14.     column cofidence value 14. initial = 0 */
+#define MCDI_RO_COL_CFD_15                         ((0x2fbf))
+/* Bit 31: 0, ro_mcdi_col_cfd_15.     column cofidence value 15. initial = 0 */
+#define MCDI_RO_COL_CFD_16                         ((0x2fc0))
+/* Bit 31: 0, ro_mcdi_col_cfd_16.     column cofidence value 16. initial = 0 */
+#define MCDI_RO_COL_CFD_17                         ((0x2fc1))
+/* Bit 31: 0, ro_mcdi_col_cfd_17.     column cofidence value 17. initial = 0 */
+#define MCDI_RO_COL_CFD_18                         ((0x2fc2))
+/* Bit 31: 0, ro_mcdi_col_cfd_18.     column cofidence value 18. initial = 0 */
+#define MCDI_RO_COL_CFD_19                         ((0x2fc3))
+/* Bit 31: 0, ro_mcdi_col_cfd_19.     column cofidence value 19. initial = 0 */
+#define MCDI_RO_COL_CFD_20                         ((0x2fc4))
+/* Bit 31: 0, ro_mcdi_col_cfd_20.     column cofidence value 20. initial = 0 */
+#define MCDI_RO_COL_CFD_21                         ((0x2fc5))
+/* Bit 31: 0, ro_mcdi_col_cfd_21.     column cofidence value 21. initial = 0 */
+#define MCDI_RO_COL_CFD_22                         ((0x2fc6))
+/* Bit 31: 0, ro_mcdi_col_cfd_22.     column cofidence value 22. initial = 0 */
+#define MCDI_RO_COL_CFD_23                         ((0x2fc7))
+/* Bit 31: 0, ro_mcdi_col_cfd_23.     column cofidence value 23. initial = 0 */
+#define MCDI_RO_COL_CFD_24                         ((0x2fc8))
+/* Bit 31: 0, ro_mcdi_col_cfd_24.     column cofidence value 24. initial = 0 */
+#define MCDI_RO_COL_CFD_25                         ((0x2fc9))
+/* Bit 31: 0, ro_mcdi_col_cfd_25.     column cofidence value 25. initial = 0 */
+
+#define DIPD_COMB_CTRL0                                        0x2fd0
+/* Bit 31: 24, cmb_v_dif_min */
+/* Bit 23: 16, cmb_v_dif_max */
+/* Bit 15:  8, cmb_crg_mi */
+/* Bit  7:  0, cmb_crg_max */
+#define DIPD_COMB_CTRL1                                        0x2fd1
+/* Bit 31: 31, pd_check_en */
+/* Bit 29: 24, cmb_wv_min3 */
+/* Bit 21: 16, cmb_wv_min2 */
+/* Bit 13:  8, cmb_wv_min1 */
+/* Bit  5:  0, cmb_wv_min0 */
+#define DIPD_COMB_CTRL2                                        0x2fd2
+/* Bit 31: 28, cmb_wnd_cnt1 */
+/* Bit 25: 20, ccnt_cmmin1 */
+/* Bit 19: 16, ccnt_mtmin */
+/* Bit 13:  8, ccnt_cmmin */
+/* Bit  5:  0, cmb_wv_min4 */
+#define DIPD_COMB_CTRL3                                        0x2fd3
+/* Bit 31: 31, cmb32spcl */
+/* Bit 17: 12, cmb_wnd_mthd */
+/* Bit 11:  4, cmb_abs_nocmb */
+/* Bit  3:  0, cnt_minlen */
+#define DIPD_COMB_CTRL4                                        0x2fd4
+/* Bit 30: 30, flm_stamtn_en */
+/* Bit 29: 28, in_horflt */
+/* Bit 27: 20, alpha */
+/* Bit 19: 16, thtran_ctmtd */
+/* Bit 15:  8, htran_mnth1 */
+/* Bit  7:  0, htran_mnth0 */
+#define DIPD_COMB_CTRL5                                        0x2fd5
+/* Bit 31: 24, fld_mindif */
+/* Bit 23: 16, frm_mindif */
+/* Bit 13:  8, flm_smp_mtn_cnt */
+/* Bit  7:  0, flm_smp_mtn_thd */
+#define DIPD_RO_COMB_0                                 0x2fd6
+#define DIPD_RO_COMB_1                                 0x2fd7
+#define DIPD_RO_COMB_2                                 0x2fd8
+#define DIPD_RO_COMB_3                                 0x2fd9
+#define DIPD_RO_COMB_4                                 0x2fda
+#define DIPD_RO_COMB_5                                 0x2fdb
+#define DIPD_RO_COMB_6                                 0x2fdc
+#define DIPD_RO_COMB_7                                 0x2fdd
+#define DIPD_RO_COMB_8                                 0x2fde
+#define DIPD_RO_COMB_9                                 0x2fdf
+#define DIPD_RO_COMB_10                                        0x2fe0
+#define DIPD_RO_COMB_11                                        0x2fe1
+#define DIPD_RO_COMB_12                                        0x2fe2
+#define DIPD_RO_COMB_13                                        0x2fe3
+#define DIPD_RO_COMB_14                                        0x2fe4
+#define DIPD_RO_COMB_15                                        0x2fe5
+#define DIPD_RO_COMB_16                                        0x2fe6
+#define DIPD_RO_COMB_17                                        0x2fe7
+#define DIPD_RO_COMB_18                                        0x2fe8
+#define DIPD_RO_COMB_19                                        0x2fe9
+#define DIPD_RO_COMB_20                                        0x2fea
+#define DIPD_COMB_CTRL6                                        0x2feb
+/* nr3 */
+#define NR3_MODE                                       0x2ff0
+               /* d010bfc0 */
+#define NR3_COOP_PARA                                  0x2ff1
+#define NR3_CNOOP_GAIN                                 0x2ff2
+#define NR3_YMOT_PARA                                  0x2ff3
+#define NR3_CMOT_PARA                                  0x2ff4
+#define NR3_SUREMOT_YGAIN                              0x2ff5
+#define NR3_SUREMOT_CGAIN                              0x2ff6
+
+#endif
diff --git a/drivers/amlogic/media/di_multi/register_nr4.h b/drivers/amlogic/media/di_multi/register_nr4.h
new file mode 100644 (file)
index 0000000..71d3ace
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * drivers/amlogic/media/di_multi/register_nr4.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#define NR4_DRT_CTRL                   ((0x2da4))
+#define NR4_DRT_YSAD_GAIN               ((0x2da5))
+#define NR4_DRT_CSAD_GAIN               ((0x2da6))
+#define NR4_DRT_SAD_ALP_CORE            ((0x2da7))
+#define NR4_DRT_ALP_MINMAX              ((0x2da8))
+#define NR4_SNR_CTRL_REG                ((0x2da9))
+#define NR4_SNR_ALPHA0_MAX_MIN          ((0x2daa))
+#define NR4_ALP0C_ERR2CURV_LIMIT0       ((0x2dab))
+#define NR4_ALP0C_ERR2CURV_LIMIT1       ((0x2dac))
+#define NR4_ALP0Y_ERR2CURV_LIMIT0       ((0x2dad))
+#define NR4_ALP0Y_ERR2CURV_LIMIT1       ((0x2dae))
+#define NR4_SNR_ALPA1_RATE_AND_OFST     ((0x2daf))
+#define NR4_SNR_ALPHA1_MAX_MIN          ((0x2db0))
+#define NR4_ALP1C_ERR2CURV_LIMIT0       ((0x2db1))
+#define NR4_ALP1C_ERR2CURV_LIMIT1       ((0x2db2))
+#define NR4_ALP1Y_ERR2CURV_LIMIT0       ((0x2db3))
+#define NR4_ALP1Y_ERR2CURV_LIMIT1       ((0x2db4))
+#define NR4_MTN_CTRL                    ((0x2db5))
+#define NR4_MTN_REF_PAR0                ((0x2db6))
+#define NR4_MTN_REF_PAR1                ((0x2db7))
+#define NR4_MCNR_LUMA_ENH_CTRL          ((0x2db8))
+#define NR4_MCNR_LUMA_STAT_LIMTX        ((0x2db9))
+#define NR4_MCNR_LUMA_STAT_LIMTY        ((0x2dba))
+#define NR4_MCNR_LUMA_DIF_CALC          ((0x2dbb))
+#define NR4_MCNR_LUMAPRE_CAL_PRAM       ((0x2dbc))
+#define NR4_MCNR_LUMACUR_CAL_PRAM       ((0x2dbd))
+#define NR4_MCNR_MV_CTRL_REG            ((0x2dbe))
+#define NR4_MCNR_MV_GAIN0               ((0x2dbf))
+#define NR4_MCNR_LMV_PARM               ((0x2dc0))
+#define   NR4_MCNR_ALP0_REG             (0x2dc1)
+#define   NR4_MCNR_ALP1_AND_BET0_REG    (0x2dc2)
+#define   NR4_MCNR_BET1_AND_BET2_REG    (0x2dc3)
+#define   NR4_MCNR_AC_DC_CRTL           (0x2dc4)
+#define   NR4_MCNR_CM_CTRL0             (0x2dc5)
+#define   NR4_MCNR_CM_PRAM              (0x2dc6)
+#define   NR4_MCNR_CM_RSHFT_ALP0        (0x2dc7)
+#define   NR4_MCNR_BLUE_CENT            (0x2dc8)
+#define   NR4_MCNR_BLUE_GAIN_PAR0       (0x2dc9)
+#define   NR4_MCNR_BLUE_GAIN_PAR1       (0x2dca)
+#define   NR4_MCNR_CM_BLUE_CLIP0        (0x2dcb)
+#define   NR4_MCNR_CM_BLUE_CLIP1        (0x2dcc)
+#define   NR4_MCNR_GREEN_CENT           (0x2dcd)
+#define   NR4_MCNR_GREEN_GAIN_PAR0      (0x2dce)
+#define   NR4_MCNR_GREEN_GAIN_PAR1      (0x2dcf)
+#define   NR4_MCNR_GREEN_CLIP0          (0x2dd0)
+#define   NR4_MCNR_GREEN_CLIP2          (0x2dd1)
+#define   NR4_MCNR_SKIN_CENT            (0x2dd2)
+#define   NR4_MCNR_SKIN_GAIN_PAR0       (0x2dd3)
+#define   NR4_MCNR_SKIN_GAIN_PAR1       (0x2dd4)
+#define   NR4_MCNR_SKIN_CLIP0           (0x2dd5)
+#define   NR4_MCNR_SKIN_CLIP1           (0x2dd6)
+#define   NR4_MCNR_ALP1_GLB_CTRL        (0x2dd7)
+#define   NR4_MCNR_DC2NORM_LUT0         (0x2dd8)
+#define   NR4_MCNR_DC2NORM_LUT1         (0x2dd9)
+#define   NR4_MCNR_DC2NORM_LUT2         (0x2dda)
+#define   NR4_MCNR_AC2NORM_LUT0         (0x2ddb)
+#define   NR4_MCNR_AC2NORM_LUT1         (0x2ddc)
+#define   NR4_MCNR_AC2NORM_LUT2         (0x2ddd)
+#define   NR4_MCNR_SAD2ALP0_LUT0        (0x2dde)
+#define   NR4_MCNR_SAD2ALP0_LUT1        (0x2ddf)
+#define   NR4_MCNR_SAD2ALP0_LUT2        (0x2de0)
+#define   NR4_MCNR_SAD2ALP0_LUT3        (0x2de1)
+#define   NR4_MCNR_SAD2ALP1_LUT0        (0x2de2)
+#define   NR4_MCNR_SAD2ALP1_LUT1        (0x2de3)
+#define   NR4_MCNR_SAD2ALP1_LUT2        (0x2de4)
+#define   NR4_MCNR_SAD2ALP1_LUT3        (0x2de5)
+#define   NR4_MCNR_SAD2BET0_LUT0        (0x2de6)
+#define   NR4_MCNR_SAD2BET0_LUT1        (0x2de7)
+#define   NR4_MCNR_SAD2BET0_LUT2        (0x2de8)
+#define   NR4_MCNR_SAD2BET0_LUT3        (0x2de9)
+#define   NR4_MCNR_SAD2BET1_LUT0        (0x2dea)
+#define   NR4_MCNR_SAD2BET1_LUT1        (0x2deb)
+#define   NR4_MCNR_SAD2BET1_LUT2        (0x2dec)
+#define   NR4_MCNR_SAD2BET1_LUT3        (0x2ded)
+#define   NR4_MCNR_SAD2BET2_LUT0        (0x2dee)
+#define   NR4_MCNR_SAD2BET2_LUT1        (0x2def)
+#define   NR4_MCNR_SAD2BET2_LUT2        (0x2df0)
+#define   NR4_MCNR_SAD2BET2_LUT3        (0x2df1)
+#define   NR4_MCNR_RO_U_SUM             (0x2df2)
+#define   NR4_MCNR_RO_V_SUM             (0x2df3)
+#define   NR4_MCNR_RO_GRDU_SUM          (0x2df4)
+#define   NR4_MCNR_RO_GRDV_SUM          (0x2df5)
+#define   NR4_TOP_CTRL                  (0x2dff)
+#define   NR4_MCNR_SAD_GAIN             (0x3700)
+#define   NR4_MCNR_LPF_CTRL             (0x3701)
+#define   NR4_MCNR_BLD_VS3LUT0          (0x3702)
+#define   NR4_MCNR_BLD_VS3LUT1          (0x3703)
+#define   NR4_MCNR_BLD_VS3LUT2          (0x3704)
+#define   NR4_MCNR_BLD_VS2LUT0          (0x3705)
+#define   NR4_MCNR_BLD_VS2LUT1          (0x3706)
+#define   NR4_COEFBLT_LUT10             (0x3707)
+#define   NR4_COEFBLT_LUT11             (0x3708)
+#define   NR4_COEFBLT_LUT12             (0x3709)
+#define   NR4_COEFBLT_LUT20             (0x370a)
+#define   NR4_COEFBLT_LUT21             (0x370b)
+#define   NR4_COEFBLT_LUT22             (0x370c)
+#define   NR4_COEFBLT_LUT30             (0x370d)
+#define   NR4_COEFBLT_LUT31             (0x370e)
+#define   NR4_COEFBLT_LUT32             (0x370f)
+#define   NR4_COEFBLT_CONV              (0x3710)
+#define   NR4_DBGWIN_YX0                (0x3711)
+#define   NR4_DBGWIN_YX1                (0x3712)
+#define   NR4_NM_X_CFG                  (0x3713)
+#define   NR4_NM_Y_CFG                  (0x3714)
+#define   NR4_NM_SAD_THD                (0x3715)
+#define   NR4_MCNR_BANDSPLIT_PRAM       (0x3716)
+#define   NR4_MCNR_ALP1_SGN_COR         (0x3717)
+#define   NR4_MCNR_ALP1_SGN_PRAM        (0x3718)
+#define   NR4_MCNR_ALP1_MVX_LUT1        (0x3719)
+#define   NR4_MCNR_ALP1_MVX_LUT2        (0x371a)
+#define   NR4_MCNR_ALP1_MVX_LUT3        (0x371b)
+#define   NR4_MCNR_ALP1_LP_PRAM         (0x371c)
+#define   NR4_MCNR_ALP1_SGN_LUT1        (0x371d)
+#define   NR4_MCNR_ALP1_SGN_LUT2        (0x371e)
+#define   NR4_RO_NM_SAD_SUM             (0x371f)
+#define   NR4_RO_NM_SAD_CNT             (0x3720)
+#define   NR4_RO_NM_VAR_SUM             (0x3721)
+#define   NR4_RO_NM_VAR_SCNT            (0x3722)
+#define   NR4_RO_NM_VAR_MIN_MAX         (0x3723)
+#define   NR4_RO_NR4_DBGPIX_NUM         (0x3724)
+#define   NR4_RO_NR4_BLDVS2_SUM         (0x3725)
+#define   NR4_BLDVS3_SUM                (0x3726)
+#define   NR4_COEF12_SUM                (0x3727)
+#define   NR4_COEF123_SUM               (0x3728)
+#define   NR_DB_FLT_CTRL                (0x3738)
+#define   NR_DB_FLT_YC_THRD             (0x3739)
+#define   NR_DB_FLT_RANDLUT             (0x373a)
+#define   NR_DB_FLT_PXI_THRD            (0x373b)
+#define   NR_DB_FLT_SEED_Y              (0x373c)
+#define   NR_DB_FLT_SEED_V              (0x373e)
+#define   NR_DB_FLT_SEED3               (0x373f)
+#define   LBUF_TOP_CTRL                 (0x2fff)
index 009d49e..1335fe3 100644 (file)
@@ -52,6 +52,8 @@
 #define VIDTYPE_PRE_DI_AFBC            0x10000000
 #define VIDTYPE_RGB_444                        0x20000000
 
+/* 2019-04-22 Suggestions from brian.zhu*/
+#define VIDTYPE_DI_PW                  0x40000000
 #define DISP_RATIO_FORCECONFIG          0x80000000
 #define DISP_RATIO_FORCE_NORMALWIDE     0x40000000
 #define DISP_RATIO_FORCE_FULL_STRETCH   0x20000000