summaryrefslogtreecommitdiff
authorJihong Sui <jihong.sui@amlogic.com>2019-08-05 06:17:07 (GMT)
committer Tao Zeng <tao.zeng@amlogic.com>2019-08-19 02:26:00 (GMT)
commitb391eea3dbb159c2ef441996b630a01438376823 (patch)
tree145336b74029511513c991cd7f0baa246e249300
parent433ca763908b77f7fd381fea8e618a46baeb9382 (diff)
downloadcommon-b391eea3dbb159c2ef441996b630a01438376823.zip
common-b391eea3dbb159c2ef441996b630a01438376823.tar.gz
common-b391eea3dbb159c2ef441996b630a01438376823.tar.bz2
deinterlace: add di-multi folder v2 [2/3]
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>
Diffstat
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/amlogic/media/Kconfig1
-rw-r--r--drivers/amlogic/media/Makefile1
-rw-r--r--drivers/amlogic/media/di_multi/Kconfig15
-rw-r--r--drivers/amlogic/media/di_multi/Makefile34
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace.c8401
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace.h656
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace_dbg.c1214
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace_dbg.h43
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace_hw.c4236
-rw-r--r--drivers/amlogic/media/di_multi/deinterlace_hw.h277
-rw-r--r--drivers/amlogic/media/di_multi/di_api.c106
-rw-r--r--drivers/amlogic/media/di_multi/di_api.h55
-rw-r--r--drivers/amlogic/media/di_multi/di_data.h21
-rw-r--r--drivers/amlogic/media/di_multi/di_data_l.h1372
-rw-r--r--drivers/amlogic/media/di_multi/di_dbg.c1632
-rw-r--r--drivers/amlogic/media/di_multi/di_dbg.h69
-rw-r--r--drivers/amlogic/media/di_multi/di_post.c389
-rw-r--r--drivers/amlogic/media/di_multi/di_post.h27
-rw-r--r--drivers/amlogic/media/di_multi/di_pps.c628
-rw-r--r--drivers/amlogic/media/di_multi/di_pps.h112
-rw-r--r--drivers/amlogic/media/di_multi/di_prc.c1966
-rw-r--r--drivers/amlogic/media/di_multi/di_prc.h131
-rw-r--r--drivers/amlogic/media/di_multi/di_pre.c985
-rw-r--r--drivers/amlogic/media/di_multi/di_pre.h38
-rw-r--r--drivers/amlogic/media/di_multi/di_que.c995
-rw-r--r--drivers/amlogic/media/di_multi/di_que.h76
-rw-r--r--drivers/amlogic/media/di_multi/di_reg_tab.c249
-rw-r--r--drivers/amlogic/media/di_multi/di_reg_tab.h26
-rw-r--r--drivers/amlogic/media/di_multi/di_sys.c754
-rw-r--r--drivers/amlogic/media/di_multi/di_sys.h26
-rw-r--r--drivers/amlogic/media/di_multi/di_task.c315
-rw-r--r--drivers/amlogic/media/di_multi/di_task.h36
-rw-r--r--drivers/amlogic/media/di_multi/di_vframe.c556
-rw-r--r--drivers/amlogic/media/di_multi/di_vframe.h68
-rw-r--r--drivers/amlogic/media/di_multi/dim_trace.h71
-rw-r--r--drivers/amlogic/media/di_multi/nr_downscale.c218
-rw-r--r--drivers/amlogic/media/di_multi/nr_downscale.h46
-rw-r--r--drivers/amlogic/media/di_multi/register.h4416
-rw-r--r--drivers/amlogic/media/di_multi/register_nr4.h149
-rw-r--r--include/linux/amlogic/media/vfm/vframe.h2
41 files changed, 30416 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6b64651..2e0f76a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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/*
diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig
index 46220fa..6159286a 100644
--- a/drivers/amlogic/media/Kconfig
+++ b/drivers/amlogic/media/Kconfig
@@ -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"
diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile
index c72ece4..fe43ed7 100644
--- a/drivers/amlogic/media/Makefile
+++ b/drivers/amlogic/media/Makefile
@@ -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
index 0000000..8670046
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/Kconfig
@@ -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
index 0000000..23df552
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/Makefile
@@ -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
index 0000000..daa6e1a
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace.c
@@ -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
index 0000000..8a1cac0
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace.h
@@ -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
index 0000000..153f6e0
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace_dbg.c
@@ -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
index 0000000..7aa2ed2
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace_dbg.h
@@ -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
index 0000000..5fa6bfb
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace_hw.c
@@ -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
index 0000000..ed00b85
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/deinterlace_hw.h
@@ -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
index 0000000..554bdf1
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_api.c
@@ -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
index 0000000..0cd08de
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_api.h
@@ -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
index 0000000..d9ddb8f
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_data.h
@@ -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
index 0000000..82a6682
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_data_l.h
@@ -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
index 0000000..9c7763b
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_dbg.c
@@ -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
index 0000000..6636f5a
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_dbg.h
@@ -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
index 0000000..3451d2d1
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_post.c
@@ -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
index 0000000..1b4d88d
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_post.h
@@ -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
index 0000000..4f20941
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_pps.c
@@ -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
index 0000000..334db9d
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_pps.h
@@ -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
index 0000000..3a98e99
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_prc.c
@@ -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
index 0000000..8083bc4
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_prc.h
@@ -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
index 0000000..2c47394
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_pre.c
@@ -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
index 0000000..2f46b12
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_pre.h
@@ -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
index 0000000..1d96da9
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_que.c
@@ -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
index 0000000..f2f35ab
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_que.h
@@ -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
index 0000000..750f106
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_reg_tab.c
@@ -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
index 0000000..215d378
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_reg_tab.h
@@ -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
index 0000000..64be055
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_sys.c
@@ -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
index 0000000..8aec249
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_sys.h
@@ -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
index 0000000..9912fd4
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_task.c
@@ -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
index 0000000..15cbced
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_task.h
@@ -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
index 0000000..caf2832
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_vframe.c
@@ -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
index 0000000..f5eb0d8
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/di_vframe.h
@@ -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
index 0000000..59a5c00
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/dim_trace.h
@@ -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
index 0000000..fc5e561
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/nr_downscale.c
@@ -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
index 0000000..873ce70
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/nr_downscale.h
@@ -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
index 0000000..b05814d
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/register.h
@@ -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
index 0000000..71d3ace
--- a/dev/null
+++ b/drivers/amlogic/media/di_multi/register_nr4.h
@@ -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)
diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h
index 009d49e..1335fe3 100644
--- a/include/linux/amlogic/media/vfm/vframe.h
+++ b/include/linux/amlogic/media/vfm/vframe.h
@@ -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