mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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> Conflicts: MAINTAINERS
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -409,6 +411,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))
|
||||
@@ -432,6 +435,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
|
||||
/**********************************/
|
||||
|
||||
/*****************************
|
||||
@@ -677,7 +709,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;
|
||||
@@ -8007,6 +8039,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)
|
||||
{
|
||||
@@ -8037,6 +8070,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)
|
||||
@@ -8185,6 +8219,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,
|
||||
@@ -8202,7 +8237,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)
|
||||
{
|
||||
|
||||
@@ -8254,6 +8289,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__);
|
||||
@@ -8440,7 +8492,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:
|
||||
@@ -8448,13 +8502,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))
|
||||
@@ -8505,11 +8566,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;
|
||||
}
|
||||
|
||||
@@ -8656,7 +8723,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__);
|
||||
@@ -8669,26 +8736,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
131
drivers/amlogic/media/deinterlace/di_pqa.h
Normal file
131
drivers/amlogic/media/deinterlace/di_pqa.h
Normal file
@@ -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__*/
|
||||
@@ -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;
|
||||
@@ -1343,3 +1344,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
15
drivers/amlogic/media/di_local/Kconfig
Normal file
15
drivers/amlogic/media/di_local/Kconfig
Normal file
@@ -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
|
||||
12
drivers/amlogic/media/di_local/Makefile
Normal file
12
drivers/amlogic/media/di_local/Makefile
Normal file
@@ -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/
|
||||
|
||||
327
drivers/amlogic/media/di_local/di_local.c
Normal file
327
drivers/amlogic/media/di_local/di_local.c
Normal file
@@ -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
|
||||
26
drivers/amlogic/media/di_local/di_local.h
Normal file
26
drivers/amlogic/media/di_local/di_local.h
Normal file
@@ -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__*/
|
||||
Reference in New Issue
Block a user