From 449e9c627885dcd970ca876687e99dcb1fc551b5 Mon Sep 17 00:00:00 2001 From: Jihong Sui Date: Mon, 5 Aug 2019 13:33:34 +0800 Subject: [PATCH] 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 --- MAINTAINERS | 5 + drivers/amlogic/media/Kconfig | 1 + drivers/amlogic/media/Makefile | 1 + drivers/amlogic/media/deinterlace/deinterlace.c | 83 +++++- drivers/amlogic/media/deinterlace/deinterlace.h | 4 +- drivers/amlogic/media/deinterlace/deinterlace_hw.h | 2 +- .../amlogic/media/deinterlace/deinterlace_mtn.c | 24 ++ drivers/amlogic/media/deinterlace/detect3d.c | 21 ++ drivers/amlogic/media/deinterlace/di_pqa.h | 131 +++++++++ drivers/amlogic/media/deinterlace/nr_drv.c | 29 ++ drivers/amlogic/media/deinterlace/pulldown_drv.c | 24 ++ drivers/amlogic/media/deinterlace/pulldown_drv.h | 4 +- drivers/amlogic/media/di_local/Kconfig | 15 + drivers/amlogic/media/di_local/Makefile | 12 + drivers/amlogic/media/di_local/di_local.c | 327 +++++++++++++++++++++ drivers/amlogic/media/di_local/di_local.h | 26 ++ 16 files changed, 698 insertions(+), 11 deletions(-) create mode 100644 drivers/amlogic/media/deinterlace/di_pqa.h create mode 100644 drivers/amlogic/media/di_local/Kconfig create mode 100644 drivers/amlogic/media/di_local/Makefile create mode 100644 drivers/amlogic/media/di_local/di_local.c create mode 100644 drivers/amlogic/media/di_local/di_local.h 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 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 +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 #include #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 -#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 --- /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 +#include +#include +#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 --- /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 --- /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 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*for di_ext_ops*/ +/*#include */ +#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 --- /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__*/ -- 2.7.4