summaryrefslogtreecommitdiff
authorJihong Sui <jihong.sui@amlogic.com>2019-08-05 05:33:34 (GMT)
committer Jianxin Pan <jianxin.pan@amlogic.com>2019-08-16 12:32:32 (GMT)
commit449e9c627885dcd970ca876687e99dcb1fc551b5 (patch)
treea3a5c5c08d11210df765a4e17ac4dca2c6b5958d
parent701d12f0533f72c8de05a6008c653973592105ec (diff)
downloadcommon-449e9c627885dcd970ca876687e99dcb1fc551b5.zip
common-449e9c627885dcd970ca876687e99dcb1fc551b5.tar.gz
common-449e9c627885dcd970ca876687e99dcb1fc551b5.tar.bz2
deinterlace: add di-multi v2 [1/3]
PD#SWPL-10064 Problem: Prepare for adding multi-di Solution: 1. add di_local for reserved mem alloc; 2. add dil_attach_ext_api for di_api; 3. move some setting to prob; 4. add interface for di pq; Verify: U212 Change-Id: I023694dffabed47fd62ec3fa90b8de9302ac341e Signed-off-by: Jihong Sui <jihong.sui@amlogic.com>
Diffstat
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/amlogic/media/Kconfig1
-rw-r--r--drivers/amlogic/media/Makefile1
-rw-r--r--drivers/amlogic/media/deinterlace/deinterlace.c83
-rw-r--r--drivers/amlogic/media/deinterlace/deinterlace.h4
-rw-r--r--drivers/amlogic/media/deinterlace/deinterlace_hw.h2
-rw-r--r--drivers/amlogic/media/deinterlace/deinterlace_mtn.c24
-rw-r--r--drivers/amlogic/media/deinterlace/detect3d.c21
-rw-r--r--drivers/amlogic/media/deinterlace/di_pqa.h131
-rw-r--r--drivers/amlogic/media/deinterlace/nr_drv.c29
-rw-r--r--drivers/amlogic/media/deinterlace/pulldown_drv.c24
-rw-r--r--drivers/amlogic/media/deinterlace/pulldown_drv.h4
-rw-r--r--drivers/amlogic/media/di_local/Kconfig15
-rw-r--r--drivers/amlogic/media/di_local/Makefile12
-rw-r--r--drivers/amlogic/media/di_local/di_local.c327
-rw-r--r--drivers/amlogic/media/di_local/di_local.h26
16 files changed, 698 insertions, 11 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 38e55b4..6b64651 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15099,3 +15099,8 @@ AMLOGIC ADD DTS FOR AC223 PLATFORM
M: huijie huang <huijie.huang@amlogic.com>
F: arch/arm/boot/dts/amlogic/sm1_s905y3_ac223.dts
F: arch/arm64/boot/dts/amlogic/sm1_s905y3_ac223.dts
+
+AMLOGIC DEINTERLACE DRIVER
+M: Jihong Sui <jihong.sui@amlogic.com>
+F: drivers/amlogic/media/deinterlace/di_pqa.h
+F: drivers/amlogic/media/di_local/*
diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig
index ded82c0..46220fa 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_local/Kconfig"
source "drivers/amlogic/media/vin/Kconfig"
source "drivers/amlogic/media/video_processor/Kconfig"
source "drivers/amlogic/media/enhancement/Kconfig"
diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile
index 12f643b..c72ece4 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_local/
obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/
obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR) += video_processor/
obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/
diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c
index 9e5568d..a29a43a 100644
--- a/drivers/amlogic/media/deinterlace/deinterlace.c
+++ b/drivers/amlogic/media/deinterlace/deinterlace.c
@@ -66,6 +66,8 @@
#include "deinterlace_dbg.h"
#include "nr_downscale.h"
#include "di_pps.h"
+#include "di_pqa.h"
+
#define CREATE_TRACE_POINTS
#include "deinterlace_trace.h"
@@ -410,6 +412,7 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val,
VSYNC_WR_MPEG_REG_BITS(addr, val, start, len);
}
+#if 0
unsigned int DI_POST_REG_RD(unsigned int addr)
{
if (IS_ERR_OR_NULL(de_devp))
@@ -433,6 +436,35 @@ int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
}
EXPORT_SYMBOL(DI_POST_WR_REG_BITS);
+#else
+static unsigned int lDI_POST_REG_RD(unsigned int addr)
+{
+ if (IS_ERR_OR_NULL(de_devp))
+ return 0;
+ if (de_devp->flags & DI_SUSPEND_FLAG) {
+ pr_err("[DI] REG 0x%x access prohibited.\n", addr);
+ return 0;
+ }
+ return VSYNC_RD_MPEG_REG(addr);
+}
+
+static int lDI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
+{
+ if (IS_ERR_OR_NULL(de_devp))
+ return 0;
+ if (de_devp->flags & DI_SUSPEND_FLAG) {
+ pr_err("[DI] REG 0x%x access prohibited.\n", adr);
+ return -1;
+ }
+ return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
+}
+
+static const struct di_ext_ops di_ext = {
+ .di_post_reg_rd = lDI_POST_REG_RD,
+ .di_post_wr_reg_bits = lDI_POST_WR_REG_BITS,
+};
+
+#endif
/**********************************/
/*****************************
@@ -716,7 +748,7 @@ static int __init di_read_canvas_reverse(char *str)
{
unsigned char *ptr = str;
- pr_dbg("%s: bootargs is %s.\n", __func__, str);
+ di_pr_info("%s: bootargs is %s.\n", __func__, str);
if (strstr(ptr, "1")) {
invert_top_bot |= 0x1;
overturn = true;
@@ -8051,6 +8083,7 @@ show_frame_format(struct device *dev,
}
static DEVICE_ATTR(frame_format, 0444, show_frame_format, NULL);
+#if 0 /*move to di_local.c*/
static int __init rmem_di_device_init(struct reserved_mem *rmem,
struct device *dev)
{
@@ -8081,6 +8114,7 @@ static void rmem_di_device_release(struct reserved_mem *rmem,
di_devp->mem_size = 0;
}
}
+#endif
#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
unsigned int RDMA_RD_BITS(unsigned int adr, unsigned int start,
unsigned int len)
@@ -8229,6 +8263,7 @@ static void set_di_flag(void)
mtn_int_combing_glbmot();
}
+#if 0 /*move to di_local.c*/
static const struct reserved_mem_ops rmem_di_ops = {
.device_init = rmem_di_device_init,
.device_release = rmem_di_device_release,
@@ -8246,7 +8281,7 @@ static int __init rmem_di_setup(struct reserved_mem *rmem)
return 0;
}
RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup);
-
+#endif
static void di_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev)
{
@@ -8298,6 +8333,23 @@ static int di_probe(struct platform_device *pdev)
int ret = 0;
struct di_dev_s *di_devp = NULL;
+ di_pr_info("%s:\n", __func__);
+
+#if 1 /*move from init*/
+ ret = alloc_chrdev_region(&di_devno, 0, DI_COUNT, DEVICE_NAME);
+ if (ret < 0) {
+ pr_err("%s: failed to allocate major number\n", __func__);
+ goto fail_alloc_cdev_region;
+ }
+ di_pr_info("%s: major %d\n", __func__, MAJOR(di_devno));
+ di_clsp = class_create(THIS_MODULE, CLASS_NAME);
+ if (IS_ERR(di_clsp)) {
+ ret = PTR_ERR(di_clsp);
+ pr_err("%s: failed to create class\n", __func__);
+ goto fail_class_create;
+ }
+#endif
+
di_devp = kmalloc(sizeof(struct di_dev_s), GFP_KERNEL);
if (!di_devp) {
pr_err("%s fail to allocate memory.\n", __func__);
@@ -8484,7 +8536,9 @@ static int di_probe(struct platform_device *pdev)
di_debugfs_init(); /*2018-07-18 add debugfs*/
di_patch_post_update_mc_sw(DI_MC_SW_IC, true);
- pr_info("%s:ok\n", __func__);
+ dil_attach_ext_api(&di_ext);
+
+ di_pr_info("%s:ok\n", __func__);
return ret;
fail_cdev_add:
@@ -8492,13 +8546,20 @@ fail_cdev_add:
kfree(di_devp);
fail_kmalloc_dev:
+#if 1 /*move from init*/
+ class_destroy(di_clsp);
+fail_class_create:
+ unregister_chrdev_region(di_devno, DI_COUNT);
+fail_alloc_cdev_region:
return ret;
+#endif
}
static int di_remove(struct platform_device *pdev)
{
struct di_dev_s *di_devp = NULL;
+ di_pr_info("%s:\n", __func__);
di_devp = platform_get_drvdata(pdev);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
@@ -8549,11 +8610,17 @@ static int di_remove(struct platform_device *pdev)
}
device_destroy(di_clsp, di_devno);
+#if 1 /*move from exit*/
+ class_destroy(di_clsp);
+ di_debugfs_exit();
+ unregister_chrdev_region(di_devno, DI_COUNT);
+#endif
kfree(di_devp);
/* free drvdata */
dev_set_drvdata(&pdev->dev, NULL);
platform_set_drvdata(pdev, NULL);
+ di_pr_info("%s:ok\n", __func__);
return 0;
}
@@ -8701,7 +8768,7 @@ static int __init di_module_init(void)
int ret = 0;
di_pr_info("%s ok.\n", __func__);
-
+#if 0 /*move to prob*/
ret = alloc_chrdev_region(&di_devno, 0, DI_COUNT, DEVICE_NAME);
if (ret < 0) {
pr_err("%s: failed to allocate major number\n", __func__);
@@ -8714,26 +8781,30 @@ static int __init di_module_init(void)
pr_err("%s: failed to create class\n", __func__);
goto fail_class_create;
}
-
+#endif
ret = platform_driver_register(&di_driver);
if (ret != 0) {
pr_err("%s: failed to register driver\n", __func__);
- goto fail_pdrv_register;
+ return -ENODEV;//goto fail_pdrv_register;
}
return 0;
+#if 0 /*move to prob*/
fail_pdrv_register:
class_destroy(di_clsp);
fail_class_create:
unregister_chrdev_region(di_devno, DI_COUNT);
fail_alloc_cdev_region:
return ret;
+#endif
}
static void __exit di_module_exit(void)
{
+#if 0 /*move to remove*/
class_destroy(di_clsp);
di_debugfs_exit();
unregister_chrdev_region(di_devno, DI_COUNT);
+#endif
platform_driver_unregister(&di_driver);
}
diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h
index 581e5dc..b55699f 100644
--- a/drivers/amlogic/media/deinterlace/deinterlace.h
+++ b/drivers/amlogic/media/deinterlace/deinterlace.h
@@ -25,9 +25,8 @@
#include <linux/clk.h>
#include <linux/atomic.h>
#include "deinterlace_hw.h"
-#include "pulldown_drv.h"
#include "nr_drv.h"
-
+#include "../di_local/di_local.h"
/*trigger_pre_di_process param*/
#define TRIGGER_PRE_BY_PUT 'p'
#define TRIGGER_PRE_BY_DE_IRQ 'i'
@@ -454,6 +453,7 @@ u32 di_requeset_afbc(u32 onoff);
extern bool di_wr_cue_int(void);
extern int reg_cue_int_show(struct seq_file *seq, void *v);
+bool dil_attach_ext_api(const struct di_ext_ops *di_api);
/*---------------------*/
struct di_buf_s *get_di_buf(int queue_idx, int *start_pos);
diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h
index d69bb1e..bf1fa6a 100644
--- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h
+++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h
@@ -18,7 +18,7 @@
#ifndef _DI_HW_H
#define _DI_HW_H
#include <linux/amlogic/media/amvecm/amvecm.h>
-#include "pulldown_drv.h"
+#include "di_pqa.h"
#include "nr_drv.h"
/* if post size < 80, filter of ei can't work */
diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c
index 0e51ee0..6c3681fa 100644
--- a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c
+++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c
@@ -41,6 +41,7 @@
#include "register.h"
#include "deinterlace_mtn.h"
+#include "di_pqa.h"
#define MAX_NUM_DI_REG 32
#define GXTVBB_REG_START 12
static unsigned int combing_setting_registers[MAX_NUM_DI_REG] = {
@@ -812,3 +813,26 @@ int adaptive_combing_fixing(
#ifdef DEBUG_SUPPORT
module_param_named(cmb_adpset_cnt, cmb_adpset_cnt, int, 0644);
#endif
+static const struct mtn_op_s di_ops_mtn = {
+ .mtn_int_combing_glbmot = mtn_int_combing_glbmot,
+ .adpative_combing_exit = adpative_combing_exit,
+ .fix_tl1_1080i_sawtooth_patch = fix_tl1_1080i_sawtooth_patch,
+ .adaptive_combing_fixing = adaptive_combing_fixing,
+ .adpative_combing_config = adpative_combing_config,
+ /*.module_para = dim_seq_file_module_para_mtn,*/
+};
+
+bool di_attach_ops_mtn(const struct mtn_op_s **ops)
+{
+ #if 0
+ if (!ops)
+ return false;
+
+ memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
+ #else
+ *ops = &di_ops_mtn;
+ #endif
+
+ return true;
+}
+EXPORT_SYMBOL(di_attach_ops_mtn);
diff --git a/drivers/amlogic/media/deinterlace/detect3d.c b/drivers/amlogic/media/deinterlace/detect3d.c
index 6a0bacb..7f50ba1 100644
--- a/drivers/amlogic/media/deinterlace/detect3d.c
+++ b/drivers/amlogic/media/deinterlace/detect3d.c
@@ -26,6 +26,7 @@
#include "register_nr4.h"
#include "detect3d.h"
+#include "di_pqa.h"
/*******************Local defines**********************/
#define DET3D_REG_NUM 9
/* the number of total register */
@@ -442,3 +443,23 @@ MODULE_PARM_DESC(chessbd_vrate, "\n the chessboard 3d fmt vertical rate\n");
module_param(det3d_debug, bool, 0644);
MODULE_PARM_DESC(det3d_debug, "\n print the information of 3d detection\n");
+static const struct detect3d_op_s di_ops_3d = {
+ .det3d_config = det3d_config,
+ .det3d_fmt_detect = det3d_fmt_detect,
+ /*.module_para = dim_seq_file_module_para_3d,*/
+};
+
+bool di_attach_ops_3d(const struct detect3d_op_s **ops)
+{
+ #if 0
+ if (!ops)
+ return false;
+
+ memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
+ #else
+ *ops = &di_ops_3d;
+ #endif
+
+ return true;
+}
+EXPORT_SYMBOL(di_attach_ops_3d);
diff --git a/drivers/amlogic/media/deinterlace/di_pqa.h b/drivers/amlogic/media/deinterlace/di_pqa.h
new file mode 100644
index 0000000..0f26472
--- a/dev/null
+++ b/drivers/amlogic/media/deinterlace/di_pqa.h
@@ -0,0 +1,131 @@
+/*
+ * drivers/amlogic/media/deinterlace/di_pqa.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_PQA_H__
+#define __DI_PQA_H__
+
+#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/device.h>
+#include "../deinterlace/pulldown_drv.h"
+#include "../deinterlace/deinterlace_mtn.h"
+#if 0 /*move from pulldown_drv.h to di_pq.h*/
+enum pulldown_mode_e {
+ PULL_DOWN_BLEND_0 = 0,/* buf1=dup[0] */
+ PULL_DOWN_BLEND_2 = 1,/* buf1=dup[2] */
+ PULL_DOWN_MTN = 2,/* mtn only */
+ PULL_DOWN_BUF1 = 3,/* do wave with dup[0] */
+ PULL_DOWN_EI = 4,/* ei only */
+ PULL_DOWN_NORMAL = 5,/* normal di */
+ PULL_DOWN_NORMAL_2 = 6,/* di */
+};
+
+struct pulldown_vof_win_s {
+ unsigned short win_vs;
+ unsigned short win_ve;
+ enum pulldown_mode_e blend_mode;
+};
+
+struct pulldown_detected_s {
+ enum pulldown_mode_e global_mode;
+ struct pulldown_vof_win_s regs[4];
+};
+#endif
+
+#if 0 /*move from deinterlace_mtn.h*/
+struct combing_status_s {
+ unsigned int frame_diff_avg;
+ unsigned int cmb_row_num;
+ unsigned int field_diff_rate;
+ int like_pulldown22_flag;
+ unsigned int cur_level;
+};
+#endif
+/**************************
+ * pulldown
+ *************************/
+struct pulldown_op_s {
+ unsigned char (*init)(unsigned short width, unsigned short height);
+ unsigned int (*detection)(struct pulldown_detected_s *res,
+ struct combing_status_s *cmb_sts,
+ bool reverse,
+ struct vframe_s *vf);
+ void (*vof_win_vshift)(struct pulldown_detected_s *wins,
+ unsigned short v_offset);
+ int (*module_para)(struct seq_file *seq);
+ void (*prob)(struct device *dev);
+ void (*remove)(struct device *dev);
+};
+
+bool di_attach_ops_pulldown(const struct pulldown_op_s **ops);
+
+/**************************
+ * detect3d
+ *************************/
+struct detect3d_op_s {
+ void (*det3d_config)(bool flag);
+ enum tvin_trans_fmt (*det3d_fmt_detect)(void);
+ int (*module_para)(struct seq_file *seq);
+};
+
+bool di_attach_ops_3d(const struct detect3d_op_s **ops);
+
+/**************************
+ * nr_drv
+ *************************/
+struct nr_op_s {
+ void (*nr_hw_init)(void);
+ void (*nr_gate_control)(bool gate);
+ void (*nr_drv_init)(struct device *dev);
+ void (*nr_drv_uninit)(struct device *dev);
+ void (*nr_process_in_irq)(void);
+ void (*nr_all_config)(unsigned short nCol, unsigned short nRow,
+ unsigned short type);
+ bool (*set_nr_ctrl_reg_table)(unsigned int addr, unsigned int value);
+ void (*cue_int)(void);
+ void (*adaptive_cue_adjust)(unsigned int frame_diff,
+ unsigned int field_diff);
+ int (*module_para)(struct seq_file *seq);
+
+};
+
+bool di_attach_ops_nr(const struct nr_op_s **ops);
+
+/**************************
+ * deinterlace_mtn
+ *************************/
+struct mtn_op_s {
+ void (*mtn_int_combing_glbmot)(void);
+ void (*adpative_combing_exit)(void);
+ void (*fix_tl1_1080i_sawtooth_patch)(void);
+ int (*adaptive_combing_fixing)(
+ struct combing_status_s *cmb_status,
+ unsigned int field_diff, unsigned int frame_diff,
+ int bit_mode);
+ /*adpative_combing_config*/
+ struct combing_status_s *
+ (*adpative_combing_config)(unsigned int width,
+ unsigned int height,
+ enum vframe_source_type_e src_type,
+ bool prog,
+ enum tvin_sig_fmt_e fmt);
+ int (*module_para)(struct seq_file *seq);
+};
+
+bool di_attach_ops_mtn(const struct mtn_op_s **ops);
+
+#endif /*__DI_PQA_H__*/
diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c
index d29ea48..1b6d453 100644
--- a/drivers/amlogic/media/deinterlace/nr_drv.c
+++ b/drivers/amlogic/media/deinterlace/nr_drv.c
@@ -27,6 +27,7 @@
#include "register_nr4.h"
#include "nr_drv.h"
#include "deinterlace.h"
+#include "di_pqa.h"
static DNR_PRM_t dnr_param;
static struct NR_PARM_s nr_param;
@@ -1366,3 +1367,31 @@ void nr_drv_init(struct device *dev)
else
dnr_dm_en = false;
}
+
+static const struct nr_op_s di_ops_nr = {
+ .nr_hw_init = nr_hw_init,
+ .nr_gate_control = nr_gate_control,
+ .nr_drv_init = nr_drv_init,
+ .nr_drv_uninit = nr_drv_uninit,
+ .nr_process_in_irq = nr_process_in_irq,
+ .nr_all_config = nr_all_config,
+ .set_nr_ctrl_reg_table = set_nr_ctrl_reg_table,
+ .cue_int = cue_int,
+ .adaptive_cue_adjust = adaptive_cue_adjust,
+ /*.module_para = dim_seq_file_module_para_nr,*/
+};
+
+bool di_attach_ops_nr(const struct nr_op_s **ops)
+{
+ #if 0
+ if (!ops)
+ return false;
+
+ memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
+ #else
+ *ops = &di_ops_nr;
+ #endif
+
+ return true;
+}
+EXPORT_SYMBOL(di_attach_ops_nr);
diff --git a/drivers/amlogic/media/deinterlace/pulldown_drv.c b/drivers/amlogic/media/deinterlace/pulldown_drv.c
index bdee815..ea29319 100644
--- a/drivers/amlogic/media/deinterlace/pulldown_drv.c
+++ b/drivers/amlogic/media/deinterlace/pulldown_drv.c
@@ -22,6 +22,7 @@
#include "deinterlace_hw.h"
#include "deinterlace_dbg.h"
+#include "di_pqa.h"
static unsigned int field_diff_rate;
static unsigned int flm22_sure_num = 100;
@@ -534,3 +535,26 @@ module_param_named(flm22_sure_num, flm22_sure_num, uint, 0644);
module_param_named(flm22_glbpxlnum_rat, flm22_glbpxlnum_rat, uint, 0644);
module_param_named(flag_di_weave, flag_di_weave, int, 0644);
#endif
+static const struct pulldown_op_s di_pd_ops = {
+ .init = pulldown_init, /*call when size change*/
+ .detection = pulldown_detection, /*call after pre nrwrite*/
+ .vof_win_vshift = pulldown_vof_win_vshift, /*in post process*/
+ /*.module_para = dim_seq_file_module_para_pulldown,*/ /*for debug*/
+ .prob = pd_device_files_add, /*prob*/
+ .remove = pd_device_files_del, /*remove*/
+};
+
+bool di_attach_ops_pulldown(const struct pulldown_op_s **ops)
+{
+ #if 0
+ if (!ops)
+ return false;
+
+ memcpy(ops, &di_pd_ops, sizeof(struct pulldown_op_s));
+ #else
+ *ops = &di_pd_ops;
+ #endif
+
+ return true;
+}
+EXPORT_SYMBOL(di_attach_ops_pulldown);
diff --git a/drivers/amlogic/media/deinterlace/pulldown_drv.h b/drivers/amlogic/media/deinterlace/pulldown_drv.h
index e670f0f..fa1da26 100644
--- a/drivers/amlogic/media/deinterlace/pulldown_drv.h
+++ b/drivers/amlogic/media/deinterlace/pulldown_drv.h
@@ -17,8 +17,8 @@
#ifndef _DI_PULLDOWN_H
#define _DI_PULLDOWN_H
-#include "film_mode_fmw/film_vof_soft.h"
-#include "deinterlace_mtn.h"
+#include "../deinterlace/film_mode_fmw/film_vof_soft.h"
+#include "../deinterlace/deinterlace_mtn.h"
#define MAX_VOF_WIN_NUM 4
diff --git a/drivers/amlogic/media/di_local/Kconfig b/drivers/amlogic/media/di_local/Kconfig
new file mode 100644
index 0000000..7b623e6
--- a/dev/null
+++ b/drivers/amlogic/media/di_local/Kconfig
@@ -0,0 +1,15 @@
+#
+# Deinterlace driver configuration
+#
+
+menu "DI_LOCAL driver"
+
+config AMLOGIC_MEDIA_DEINTERLACE
+ tristate "DI_LOCAL 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_local/Makefile b/drivers/amlogic/media/di_local/Makefile
new file mode 100644
index 0000000..4fdaaba
--- a/dev/null
+++ b/drivers/amlogic/media/di_local/Makefile
@@ -0,0 +1,12 @@
+# # 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
+CFLAGS_dil.o := -I$(src)
+obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += dil.o
+dil-objs += di_local.o
+#ccflags-y += -Idrivers/amlogic/media/deinterlace/
+
diff --git a/drivers/amlogic/media/di_local/di_local.c b/drivers/amlogic/media/di_local/di_local.c
new file mode 100644
index 0000000..18fb0e5
--- a/dev/null
+++ b/drivers/amlogic/media/di_local/di_local.c
@@ -0,0 +1,327 @@
+/*
+ * drivers/amlogic/media/di_local/di_local.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>
+
+/*for di_ext_ops*/
+/*#include <linux/amlogic/media/video_sink/video.h> */
+#include "di_local.h"
+/***************************************
+ * deinterlace in linux kernel
+ **************************************/
+
+#define DEVICE_NAME "di_local"
+/*#define CLASS_NAME "dev_pl_demo" */
+#define DEV_COUNT 1
+
+#define PR_ERR(fmt, args ...) pr_err("dil:err:"fmt, ## args)
+#define PR_WARN(fmt, args ...) pr_err("dil:warn:"fmt, ## args)
+#define PR_INF(fmt, args ...) pr_info("dil:"fmt, ## args)
+
+struct dil_dev_s {
+ struct platform_device *pdev;
+ unsigned long mem_start;
+ unsigned int mem_size;
+ unsigned int flg_map;/*?*/
+
+};
+
+static struct dil_dev_s *pdv;
+
+static const struct di_ext_ops *dil_api; //temp
+
+/***************************************
+ * di api for other module *
+ **************************************/
+bool dil_attach_ext_api(const struct di_ext_ops *di_api)
+{
+ #if 0
+ if (!di_api) {
+ PR_ERR("%s:null\n", __func__);
+ return false;
+ }
+
+ memcpy(di_api, &di_ext, sizeof(struct di_ext_ops));
+ #else
+
+ dil_api = di_api;
+ #endif
+ return true;
+}
+EXPORT_SYMBOL(dil_attach_ext_api);
+
+unsigned int DI_POST_REG_RD(unsigned int addr)
+{
+ #if 0
+ if (IS_ERR_OR_NULL(de_devp))
+ return 0;
+ if (de_devp->flags & DI_SUSPEND_FLAG) {
+ pr_err("[DI] REG 0x%x access prohibited.\n", addr);
+ return 0;
+ }
+ return VSYNC_RD_MPEG_REG(addr);
+ #endif
+ if (dil_api && dil_api->di_post_reg_rd)
+ return dil_api->di_post_reg_rd(addr);
+
+ PR_ERR("%s:not attach\n", __func__);
+ return 0;
+}
+EXPORT_SYMBOL(DI_POST_REG_RD);
+
+int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
+{
+ #if 0
+ if (IS_ERR_OR_NULL(de_devp))
+ return 0;
+ if (de_devp->flags & DI_SUSPEND_FLAG) {
+ pr_err("[DI] REG 0x%x access prohibited.\n", adr);
+ return -1;
+ }
+ return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len);
+ #endif
+ if (dil_api && dil_api->di_post_wr_reg_bits)
+ return dil_api->di_post_wr_reg_bits(adr, val, start, len);
+
+ PR_ERR("%s:not attach\n", __func__);
+
+ return 0;
+}
+EXPORT_SYMBOL(DI_POST_WR_REG_BITS);
+
+/***************************************
+ * reserved mem for di *
+ **************************************/
+void dil_get_rev_mem(unsigned long *mstart, unsigned int *msize)
+{
+ if (pdv) {
+ *mstart = pdv->mem_start;
+ *msize = pdv->mem_size;
+ } else {
+ *mstart = 0;
+ *msize = 0;
+ }
+}
+EXPORT_SYMBOL(dil_get_rev_mem);
+void dil_get_flg(unsigned int *flg)
+{
+ if (pdv)
+ *flg = pdv->flg_map;
+ else
+ *flg = 0;
+}
+EXPORT_SYMBOL(dil_get_flg);
+
+/***************************************
+ * reserved mem for di *
+ **************************************/
+
+static int __init rmem_dil_init(struct reserved_mem *rmem,
+ struct device *dev)
+{
+ struct dil_dev_s *devp = dev_get_drvdata(dev);
+
+ if (devp) {
+ devp->mem_start = rmem->base;
+ devp->mem_size = rmem->size;
+ if (!of_get_flat_dt_prop(rmem->fdt_node, "no-map", NULL))
+ devp->flg_map = 1;
+
+#if 0
+ o_size = rmem->size / 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);
+ }
+#endif
+ PR_INF("%s:0x%lx, size %uMB.\n",
+ __func__,
+ devp->mem_start, (devp->mem_size >> 20));
+ return 0;
+ }
+ PR_ERR("%s:no devp\n", __func__);
+ return 1;
+}
+
+static void rmem_dil_release(struct reserved_mem *rmem,
+ struct device *dev)
+{
+ struct dil_dev_s *devp = dev_get_drvdata(dev);
+
+ if (devp) {
+ devp->mem_start = 0;
+ devp->mem_size = 0;
+ }
+ PR_INF("%s:ok\n", __func__);
+}
+
+static const struct reserved_mem_ops rmem_di_ops = {
+ .device_init = rmem_dil_init,
+ .device_release = rmem_dil_release,
+};
+
+static int __init rmem_dil_setup(struct reserved_mem *rmem)
+{
+ rmem->ops = &rmem_di_ops;
+/* rmem->priv = cma; */
+
+ PR_INF("%s %pa, size %ld MiB\n",
+ __func__,
+ &rmem->base, (unsigned long)rmem->size / SZ_1M);
+
+ return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_dil_setup);
+
+/***************************************
+ *
+ ***************************************/
+static int dil_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ PR_INF("%s.\n", __func__);
+
+ /*alloc data*/
+ pdv = kzalloc(sizeof(*pdv), GFP_KERNEL);
+ if (!pdv) {
+ PR_ERR("%s fail to alloc pdv.\n", __func__);
+ return -ENOMEM;/*goto fail_alloc_data;*/
+ }
+ pdv->pdev = pdev;
+ platform_set_drvdata(pdev, pdv);
+
+ ret = of_reserved_mem_device_init(&pdev->dev);
+ if (ret != 0)
+ PR_INF("%s no reserved mem.\n", __func__);
+
+ PR_INF("%s ok.\n", __func__);
+ return 0;
+}
+
+static int dil_remove(struct platform_device *pdev)
+{
+ PR_INF("%s.\n", __func__);
+
+ /*data*/
+ kfree(pdv);
+
+ PR_INF("%s ok.\n", __func__);
+ return 0;
+}
+
+static void dil_shutdown(struct platform_device *pdev)
+{
+ PR_INF("%s.\n", __func__);
+}
+
+static const struct of_device_id dil_match[] = {
+ {
+ .compatible = "amlogic, di-local",
+ .data = NULL,
+ },
+ {},
+};
+
+static struct platform_driver dev_driver_tab = {
+ .driver = {
+ .name = DEVICE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = dil_match,
+ },
+
+ .probe = dil_probe,
+ .remove = dil_remove,
+ .shutdown = dil_shutdown,
+
+};
+
+#if 1
+static int __init dil_init(void)
+{
+ PR_INF("%s.\n", __func__);
+ if (platform_driver_register(&dev_driver_tab)) {
+ PR_ERR("%s: can't register\n", __func__);
+ return -ENODEV;
+ }
+ PR_INF("%s ok.\n", __func__);
+ return 0;
+}
+
+static void __exit dil_exit(void)
+{
+ platform_driver_unregister(&dev_driver_tab);
+ PR_INF("%s: ok.\n", __func__);
+}
+
+module_init(dil_init);
+module_exit(dil_exit);
+
+MODULE_DESCRIPTION("AMLOGIC DI_LOCAL driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("4.0.0");
+
+#else
+int dil_init(void)
+{
+ PR_INF("%s.\n", __func__);
+ if (platform_driver_register(&dev_driver_tab)) {
+ PR_ERR("%s: can't register\n", __func__);
+ return -ENODEV;
+ }
+ PR_INF("%s ok.\n", __func__);
+ return 0;
+}
+
+void dil_exit(void)
+{
+ platform_driver_unregister(&dev_driver_tab);
+ PR_INF("%s: ok.\n", __func__);
+}
+
+#endif
diff --git a/drivers/amlogic/media/di_local/di_local.h b/drivers/amlogic/media/di_local/di_local.h
new file mode 100644
index 0000000..b956011
--- a/dev/null
+++ b/drivers/amlogic/media/di_local/di_local.h
@@ -0,0 +1,26 @@
+/*
+ * drivers/amlogic/media/di_local/di_local.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_LOCAL_H__
+#define __DI_LOCAL_H__
+
+struct di_ext_ops {
+ unsigned int (*di_post_reg_rd)(unsigned int addr);
+ int (*di_post_wr_reg_bits)(u32 adr, u32 val, u32 start, u32 len);
+};
+
+#endif /*__DI_LOCAL_H__*/