deinterlace: add deinterlace,dnr,field-detection,vof

PD#138714: initial add deinterlace,dnr,field-detection,vof drivers
1. merge deinterlace driver from 3.14
2. current commit is PD#136044
3. remove old pulldown algorithm

Change-Id: Ie36991cdcdfeda2b644619d72f8403d2dc44e17a
Signed-off-by: KeLe Bai <kele.bai@amlogic.com>
This commit is contained in:
KeLe Bai
2016-11-09 14:35:37 +08:00
committed by Jianxin Pan
parent c95bdc054a
commit 10b6bcbcb9
28 changed files with 21132 additions and 10 deletions

View File

@@ -13580,12 +13580,6 @@ F: arch/arm64/boot/dts/amlogic/mesongxm.dtsi
AMLOGIC SD/MMC DIRVER SUPPORT
M: Nan Li <nan.li@amlogic.com>
F: arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
F: arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
F: arch/arm64/boot/dts/amlogic/mesongxl.dtsi
F: arch/arm64/configs/meson64_defconfig
F: drivers/amlogic/Kconfig
F: drivers/amlogic/Makefile
F: drivers/amlogic/mmc/Kconfig
F: drivers/amlogic/mmc/Makefile
F: drivers/amlogic/mmc/aml_sd_emmc.c
@@ -13604,3 +13598,8 @@ F: include/linux/mmc/host.h
AMLOGIC VRTC DRIVER
M: Yun Cai <yun.cai@amlogic.com>
F: drivers/amlogic/vrtc/
AMLOGIC DEINTERLACE, DNR, Field Detection, VOF DRIVERS
M: Kele Bai <kele.bai@amlogic.com>
F: drivers/amlogic/deinterlace/*

View File

@@ -69,7 +69,8 @@
di_reserved:linux,di {
compatible = "amlogic, di-mem";
size = <0x0 0x1e00000>; //10x1920x1088x3/2=30M
/** 10x3133440=30M(0x1e) support 8bit **/
size = <0x0 0x1e00000>;
//no-map;
};
@@ -606,6 +607,25 @@
mask = <4>;
};
};
deinterlace {
compatible = "amlogic, deinterlace";
status = "okay";
flag_cma = <0>;/*0:use reserved;1:use cma*/
memory-region = <&di_reserved>;
interrupts = <0 46 1 0 6 1>;
interrupt-names = "de_irq", "timerc";
/*
* nr_size(byte) = 1920*544*2(yuv422 8bit) |
* 1920*544*2*12/8(yuv422 10bit)
* | 1920*544*2*10/8(yuv422 10bit full pack mode)
*/
/* mtn_size(byte) = 1920*544/2 */
/* count_size(byte) = 1920*544/2 */
buffer-size = <3133440>;
hw-version = <2>;
};
};
&efuse {
status = "ok";

View File

@@ -70,7 +70,8 @@
di_reserved:linux,di {
compatible = "amlogic, di-mem";
size = <0x0 0x1e00000>; //10x1920x1088x3/2=30M
/** 10x3133440=30M(0x1e) support 8bit **/
size = <0x0 0x1e00000>;
//no-map;
};
@@ -604,6 +605,25 @@
mask = <4>;
};
};
deinterlace {
compatible = "amlogic, deinterlace";
status = "okay";
flag_cma = <0>;/*0:use reserved;1:use cma*/
memory-region = <&di_reserved>;
interrupts = <0 46 1 0 6 1>;
interrupt-names = "de_irq", "timerc";
/*
* nr_size(byte) = 1920*544*2(yuv422 8bit) |
* 1920*544*2*12/8(yuv422 10bit)
* | 1920*544*2*10/8(yuv422 10bit full pack mode)
*/
/* mtn_size(byte) = 1920*544/2 */
/* count_size(byte) = 1920*544/2 */
buffer-size = <3133440>;
hw-version = <2>;
};
};
&efuse {
status = "ok";

View File

@@ -69,7 +69,8 @@
di_reserved:linux,di {
compatible = "amlogic, di-mem";
size = <0x0 0x1e00000>; //10x1920x1088x3/2=30M
/** 10x3133440=30M(0x1e) support 8bit **/
size = <0x0 0x1e00000>;
//no-map;
};
@@ -605,6 +606,25 @@
mask = <4>;
};
};
deinterlace {
compatible = "amlogic, deinterlace";
status = "okay";
flag_cma = <0>;/*0:use reserved;1:use cma*/
memory-region = <&di_reserved>;
interrupts = <0 46 1 0 6 1>;
interrupt-names = "de_irq", "timerc";
/*
* nr_size(byte) = 1920*544*2(yuv422 8bit) |
* 1920*544*2*12/8(yuv422 10bit)
* | 1920*544*2*10/8(yuv422 10bit full pack mode)
*/
/* mtn_size(byte) = 1920*544/2 */
/* count_size(byte) = 1920*544/2 */
buffer-size = <3133440>;
hw-version = <2>;
};
};
&efuse {
status = "ok";

View File

@@ -70,7 +70,8 @@
di_reserved:linux,di {
compatible = "amlogic, di-mem";
size = <0x0 0x1e00000>; //10x1920x1088x3/2=30M
/** 10x3133440=30M(0x1e) support 8bit **/
size = <0x0 0x1e00000>;
//no-map;
};
@@ -410,6 +411,7 @@
interrupt-names = "rdma";
};
partitions: partitions{
parts = <11>;
part-0 = <&logo>;
@@ -484,6 +486,25 @@
mask = <4>;
};
};
deinterlace {
compatible = "amlogic, deinterlace";
status = "okay";
flag_cma = <0>;/*0:use reserved;1:use cma*/
memory-region = <&di_reserved>;
interrupts = <0 46 1 0 6 1>;
interrupt-names = "de_irq", "timerc";
/*
* nr_size(byte) = 1920*544*2(yuv422 8bit) |
* 1920*544*2*12/8(yuv422 10bit)
* | 1920*544*2*10/8(yuv422 10bit full pack mode)
*/
/* mtn_size(byte) = 1920*544/2 */
/* count_size(byte) = 1920*544/2 */
buffer-size = <3133440>;
hw-version = <2>;
};
};
&efuse {
status = "ok";

View File

@@ -170,6 +170,7 @@ CONFIG_AMLOGIC_I2C_MASTER=y
CONFIG_AMLOGIC_SEC=y
CONFIG_AMLOGIC_CPU_VERSION=y
CONFIG_AMLOGIC_MESON64_VERSION=y
CONFIG_AMLOGIC_MEDIA_DEINTERLACE=y
CONFIG_AMLOGIC_CPU_INFO=y
CONFIG_AMLOGIC_MHU_MBOX=y
CONFIG_AMLOGIC_REG_ACCESS=y

View File

@@ -45,6 +45,7 @@ source "drivers/amlogic/media/vout/Kconfig"
source "drivers/amlogic/media/osd/Kconfig"
source "drivers/amlogic/media/osd_ext/Kconfig"
source "drivers/amlogic/media/logo/Kconfig"
source "drivers/amlogic/media/deinterlace/Kconfig"
endif
endmenu

View File

@@ -5,3 +5,4 @@ obj-$(CONFIG_AMLOGIC_VOUT) += vout/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += osd/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += osd_ext/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += logo/
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/

View File

@@ -0,0 +1,15 @@
#
# Deinterlace driver configuration
#
menu "Deinterlace driver"
config AMLOGIC_MEDIA_DEINTERLACE
tristate "DEINTERLACE 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

View File

@@ -0,0 +1,19 @@
#
# Makefile for the Post Process Manager device
#
ifeq ($(TARGET_BUILD_VARIANT),userdebug)
ccflags-y := -D DEBUG_SUPPORT
endif
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += di.o
di-objs += deinterlace.o
di-objs += deinterlace_hw.o
di-objs += deinterlace_mtn.o
di-objs += deinterlace_dbg.o
di-objs += nr.o
di-objs += vof_soft_top.o
di-objs += film_fw1.o
di-objs += flm_mod_xx.o
di-objs += detect3d.o
di-objs += tffbff_check.o
ccflags-y += -Idrivers/amlogic/media/common/rdma/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,597 @@
/*
* drivers/amlogic/media/deinterlace/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/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/video_sink/video.h>
#include <linux/atomic.h>
#include "film_vof_soft.h"
/* di hardware version m8m2*/
#define NEW_DI_V1 0x00000002 /* from m6tvc */
#define NEW_DI_V2 0x00000004 /* from m6tvd */
#define NEW_DI_V3 0x00000008 /* from gx */
#define NEW_DI_V4 0x00000010 /* dnr added */
/*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_TIMERC 'T'
#define TRIGGER_PRE_BY_PROVERDER_REG 'R'
#define BYPASS_GET_MAX_BUF_NUM 4
/*vframe define*/
#define vframe_t struct vframe_s
/* canvas defination */
#define DI_USE_FIXED_CANVAS_IDX
#undef USE_LIST
/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
#define NEW_KEEP_LAST_FRAME
/* #endif */
#define DET3D
#undef SUPPORT_MPEG_TO_VDIN /* for all ic after m6c@20140731 */
#ifndef CONFIG_AMLOGIC_MEDIA_VSYNC_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
/************************************
* di hardware level interface
*************************************/
#define MAX_WIN_NUM 5
/* if post size < 80, filter of ei can't work */
#define MIN_POST_WIDTH 80
#define MIN_BLEND_WIDTH 27
struct pulldown_detect_info_s {
unsigned int field_diff;
/* total pixels difference between current field and previous field */
unsigned int field_diff_num;
/* the number of pixels with big difference between
* current field and previous field
*/
unsigned int frame_diff;
/*total pixels difference between current field and previouse-previouse field*/
unsigned int frame_diff_num;
/* the number of pixels with big difference between current
* field and previouse-previous field
*/
unsigned int frame_diff_skew;
/* the difference between current frame_diff and previous frame_diff */
unsigned int frame_diff_num_skew;
/* the difference between current frame_diff_num and previous frame_diff_num*/
/* parameters for detection */
unsigned int field_diff_by_pre;
unsigned int field_diff_by_next;
unsigned int field_diff_num_by_pre;
unsigned int field_diff_num_by_next;
unsigned int frame_diff_by_pre;
unsigned int frame_diff_num_by_pre;
unsigned int frame_diff_skew_ratio;
unsigned int frame_diff_num_skew_ratio;
/* matching pattern */
unsigned int field_diff_pattern;
unsigned int field_diff_num_pattern;
unsigned int frame_diff_pattern;
unsigned int frame_diff_num_pattern;
};
#define pulldown_detect_info_t struct pulldown_detect_info_s
struct pd_win_prop_s {
unsigned int pixels_num;
};
#define pd_win_prop_t struct pd_win_prop_s
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 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 */
};
enum canvas_idx_e {
NR_CANVAS,
MTN_CANVAS,
MV_CANVAS,
};
#define pulldown_mode_t enum pulldown_mode_e
struct di_buf_s {
#ifdef USE_LIST
struct list_head list;
#endif
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;
#ifdef NEW_DI_V1
unsigned long cnt_adr;
int cnt_canvas_idx;
#endif
#ifdef NEW_DI_V3
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;
#endif
/* blend window */
unsigned short reg0_s;
unsigned short reg0_e;
unsigned short reg0_bmode;
unsigned short reg1_s;
unsigned short reg1_e;
unsigned short reg1_bmode;
unsigned short reg2_s;
unsigned short reg2_e;
unsigned short reg2_bmode;
unsigned short reg3_s;
unsigned short reg3_e;
unsigned short reg3_bmode;
/* 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_width[3];/* nr/mtn/mv */
/*bit [31~16] width; bit [15~0] height*/
pulldown_detect_info_t field_pd_info;
pulldown_detect_info_t win_pd_info[MAX_WIN_NUM];
pulldown_mode_t pulldown_mode;
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*/
struct di_buf_s *di_wr_linked_buf;
/* debug for di-vf-get/put
* 1: after get
* 0: after put
*/
atomic_t di_cnt;
};
#ifdef DET3D
extern bool det3d_en;
#endif
extern uint mtn_ctrl1;
extern pd_win_prop_t pd_win_prop[MAX_WIN_NUM];
extern int pd_enable;
extern void di_hw_init(void);
extern void di_hw_uninit(void);
extern void enable_di_pre_mif(int enable);
extern int di_vscale_skip_count;
extern unsigned int di_force_bit_mode;
/*
* di hardware internal
*/
#define RDMA_DET3D_IRQ 0x20
/* vdin0 rdma irq */
#define RDMA_DEINT_IRQ 0x2
#define RDMA_TABLE_SIZE ((PAGE_SIZE)<<1)
#if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
#define MAX_CANVAS_WIDTH 720
#define MAX_CANVAS_HEIGHT 576
#else
#define MAX_CANVAS_WIDTH 1920
#define MAX_CANVAS_HEIGHT 1088
#endif
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 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 size_x;
unsigned short size_y;
unsigned short canvas_num;
unsigned short blend_mode;
unsigned short vecrd_offset;
};
void disable_deinterlace(void);
void disable_pre_deinterlace(void);
void disable_post_deinterlace(void);
int get_di_pre_recycle_buf(void);
void disable_post_deinterlace_2(void);
void enable_film_mode_check(unsigned int width, unsigned int height,
enum vframe_source_type_e);
void 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,
#ifdef NEW_DI_V1
struct DI_SIM_MIF_s *di_contp2rd_mif,
struct DI_SIM_MIF_s *di_contprd_mif,
struct DI_SIM_MIF_s *di_contwr_mif,
#endif
int nr_en, int mtn_en, int pd32_check_en, int pd22_check_en,
int hist_check_en, int pre_field_num, int pre_vdin_link,
int hold_line, int urgent);
void enable_afbc_input(struct vframe_s *vf);
#ifdef NEW_DI_V3
void 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, int urgent);
void enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif,
int urgent, bool reverse);
#endif
void read_new_pulldown_info(struct FlmModReg_t *pFMRegp);
void initial_di_pre_aml(int hsize_pre, int vsize_pre, int hold_line);
void initial_di_post_2(int hsize_post, int vsize_post, int hold_line);
void 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,
#ifndef NEW_DI_V2
struct DI_SIM_MIF_s *di_mtncrd_mif,
#endif
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
#ifndef NEW_DI_V1
, unsigned long *reg_mtn_info
#endif
);
void di_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,
#ifndef NEW_DI_V2
struct DI_SIM_MIF_s *di_mtncrd_mif,
#endif
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
#ifndef NEW_DI_V1
, unsigned long *reg_mtn_info
#endif
);
bool read_pulldown_info(pulldown_detect_info_t *field_pd_info,
pulldown_detect_info_t *win_pd_info);
/* for video reverse */
void di_post_read_reverse(bool reverse);
void di_post_read_reverse_irq(bool reverse);
extern void recycle_keep_buffer(void);
/* #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
extern unsigned int di_log_flag;
extern unsigned int di_debug_flag;
extern bool mcpre_en;
extern bool dnr_reg_update;
extern bool dnr_dm_en;
extern int mpeg2vdin_flag;
extern int di_vscale_skip_count_real;
extern unsigned int pulldown_enable;
extern bool post_wr_en;
extern unsigned int post_wr_surpport;
extern int cmb_adpset_cnt;
extern unsigned int field_diff_rate;
int di_print(const char *fmt, ...);
int get_current_vscale_skip_count(struct vframe_s *vf);
void di_set_power_control(unsigned char type, unsigned char enable);
void diwr_set_power_control(unsigned char enable);
unsigned char di_get_power_control(unsigned char type);
void config_di_bit_mode(vframe_t *vframe, unsigned int bypass_flag);
void combing_pd22_window_config(unsigned int width, unsigned int height);
int tff_bff_check(int height, int width);
void tbff_init(void);
void DI_Wr(unsigned int addr, unsigned int val);
void DI_Wr_reg_bits(unsigned int adr, unsigned int val,
unsigned int start, unsigned int len);
void DI_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val);
void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val,
unsigned int start, unsigned int len);
#define DI_COUNT 1
#define DI_MAP_FLAG 0x1
struct di_dev_s {
dev_t devt;
struct cdev cdev; /* The cdev structure */
struct device *dev;
struct platform_device *pdev;
struct task_struct *task;
unsigned char di_event;
unsigned int di_irq;
unsigned int flags;
unsigned int timerc_irq;
unsigned long mem_start;
unsigned int mem_size;
unsigned int buffer_size;
unsigned int buf_num_avail;
unsigned int hw_version;
int rdma_handle;
/* is surpport nr10bit */
unsigned int nr10bit_surpport;
/* is DI surpport post wr to mem for OMX */
unsigned int post_wr_surpport;
unsigned int flag_cma;
unsigned int cma_alloc[10];
unsigned int buffer_addr[10];
struct page *pages[10];
};
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;
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;
#ifdef NEW_DI_V1
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
*/
#endif
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_busy_timer_count;
int pre_de_process_done; /* flag when irq done */
int pre_de_clear_flag;
/* flag is set when VFRAME_EVENT_PROVIDER_UNREG*/
int unreg_req_flag;
int unreg_req_flag_irq;
int reg_req_flag;
int reg_req_flag_irq;
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;
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
*/
unsigned char buf_alloc_mode;
/* alloc di buf as p or i;0: alloc buf as i;
* 1: alloc buf as p;
*/
unsigned char enable_mtnwr;
unsigned char enable_pulldown_check;
int same_field_source_flag;
int left_right;/*1,left eye; 0,right eye in field alternative*/
/*input2pre*/
int bypass_start_count;
/* need discard some vframe when input2pre => bypass */
int 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;
#ifdef DET3D
int vframe_interleave_flag;
#endif
int pre_de_irq_timeout_count;
int pre_throw_flag;
/*for static pic*/
int static_frame_count;
bool force_interlace;
bool bypass_pre;
bool invert_flag;
int nr_size;
int count_size;
int mcinfo_size;
int mv_size;
int mtn_size;
int cma_alloc_req;
int cma_alloc_done;
int cma_release_req;
};
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;
struct di_buf_s *cur_post_buf;
int update_post_reg_flag;
int post_process_fun_index;
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;
};
#define MAX_QUEUE_POOL_SIZE 256
struct queue_s {
int num;
int in_idx;
int out_idx;
int type; /* 0, first in first out;
* 1, general;2, fix position for di buf
*/
unsigned int pool[MAX_QUEUE_POOL_SIZE];
};
#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)
#endif

View File

@@ -0,0 +1,295 @@
/*
* drivers/amlogic/media/deinterlace/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 "deinterlace_dbg.h"
#include "register.h"
void parse_cmd_params(char *buf_orig, char **parm)
{
char *ps, *token;
char delim1[2] = " ";
char delim2[2] = "\n";
unsigned int n = 0;
strcat(delim1, delim2);
ps = buf_orig;
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
}
void dump_di_reg(void)
{
unsigned int i = 0;
pr_info("----dump di reg----\n");
for (i = 0; i < 255; i++) {
if (i == 0x45)
pr_info("----nr reg----");
if (i == 0x80)
pr_info("----3d reg----");
if (i == 0x9e)
pr_info("---nr reg done---");
if (i == 0x9c)
pr_info("---3d reg done---");
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + ((0x1700 + i) << 2),
0x1700 + i, RDMA_RD(0x1700 + i));
}
pr_info("----dump mcdi reg----\n");
for (i = 0; i < 201; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + ((0x2f00 + i) << 2),
0x2f00 + i, RDMA_RD(0x2f00 + i));
pr_info("----dump pulldown reg----\n");
for (i = 0; i < 26; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + ((0x2fd0 + i) << 2),
0x2fd0 + i, RDMA_RD(0x2fd0 + i));
pr_info("----dump bit mode reg----\n");
for (i = 0; i < 4; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + ((0x20a7 + i) << 2),
0x20a7 + i, RDMA_RD(0x20a7 + i));
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + (0x2022 << 2),
0x2022, RDMA_RD(0x2022));
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + (0x17c1 << 2),
0x17c1, RDMA_RD(0x17c1));
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + (0x17c2 << 2),
0x17c2, RDMA_RD(0x17c2));
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + (0x1aa7 << 2),
0x1aa7, RDMA_RD(0x1aa7));
pr_info("----dump dnr reg----\n");
for (i = 0; i < 29; i++)
pr_info("[0x%x][0x%x]=0x%x\n",
0xd0100000 + ((0x2d00 + i) << 2),
0x2d00 + i, RDMA_RD(0x2d00 + i));
pr_info("----dump reg done----\n");
}
void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p)
{
pr_info("di_pre_stru:\n");
pr_info("di_mem_buf_dup_p = 0x%p\n",
di_pre_stru_p->di_mem_buf_dup_p);
pr_info("di_chan2_buf_dup_p = 0x%p\n",
di_pre_stru_p->di_chan2_buf_dup_p);
pr_info("in_seq = %d\n",
di_pre_stru_p->in_seq);
pr_info("recycle_seq = %d\n",
di_pre_stru_p->recycle_seq);
pr_info("pre_ready_seq = %d\n",
di_pre_stru_p->pre_ready_seq);
pr_info("pre_de_busy = %d\n",
di_pre_stru_p->pre_de_busy);
pr_info("pre_de_busy_timer_count= %d\n",
di_pre_stru_p->pre_de_busy_timer_count);
pr_info("pre_de_process_done = %d\n",
di_pre_stru_p->pre_de_process_done);
pr_info("pre_de_irq_timeout_count=%d\n",
di_pre_stru_p->pre_de_irq_timeout_count);
pr_info("unreg_req_flag = %d\n",
di_pre_stru_p->unreg_req_flag);
pr_info("unreg_req_flag_irq = %d\n",
di_pre_stru_p->unreg_req_flag_irq);
pr_info("reg_req_flag = %d\n",
di_pre_stru_p->reg_req_flag);
pr_info("reg_req_flag_irq = %d\n",
di_pre_stru_p->reg_req_flag_irq);
pr_info("cur_width = %d\n",
di_pre_stru_p->cur_width);
pr_info("cur_height = %d\n",
di_pre_stru_p->cur_height);
pr_info("cur_inp_type = 0x%x\n",
di_pre_stru_p->cur_inp_type);
pr_info("cur_source_type = %d\n",
di_pre_stru_p->cur_source_type);
pr_info("cur_prog_flag = %d\n",
di_pre_stru_p->cur_prog_flag);
pr_info("source_change_flag = %d\n",
di_pre_stru_p->source_change_flag);
pr_info("prog_proc_type = %d\n",
di_pre_stru_p->prog_proc_type);
pr_info("enable_mtnwr = %d\n",
di_pre_stru_p->enable_mtnwr);
pr_info("enable_pulldown_check = %d\n",
di_pre_stru_p->enable_pulldown_check);
pr_info("same_field_source_flag = %d\n",
di_pre_stru_p->same_field_source_flag);
#ifdef DET3D
pr_info("vframe_interleave_flag = %d\n",
di_pre_stru_p->vframe_interleave_flag);
#endif
pr_info("left_right = %d\n",
di_pre_stru_p->left_right);
pr_info("force_interlace = %s\n",
di_pre_stru_p->force_interlace ? "true" : "false");
pr_info("vdin2nr = %d\n",
di_pre_stru_p->vdin2nr);
pr_info("bypass_pre = %s\n",
di_pre_stru_p->bypass_pre ? "true" : "false");
pr_info("invert_flag = %s\n",
di_pre_stru_p->invert_flag ? "true" : "false");
}
void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p)
{
di_pr_info("\ndi_post_stru:\n");
di_pr_info("run_early_proc_fun_flag = %d\n",
di_post_stru_p->run_early_proc_fun_flag);
di_pr_info("cur_disp_index = %d\n",
di_post_stru_p->cur_disp_index);
di_pr_info("post_de_busy = %d\n",
di_post_stru_p->post_de_busy);
di_pr_info("de_post_process_done = %d\n",
di_post_stru_p->de_post_process_done);
di_pr_info("cur_post_buf = 0x%p\n,",
di_post_stru_p->cur_post_buf);
}
void 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->pulldown_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 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 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 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);
}
}
}

View File

@@ -0,0 +1,29 @@
/*
* drivers/amlogic/media/deinterlace/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.
*
*/
#include <linux/amlogic/media/vfm/vframe.h>
#include "deinterlace.h"
void parse_cmd_params(char *buf_orig, char **parm);
void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p);
void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p);
void dump_di_buf(struct di_buf_s *di_buf);
void dump_pool(struct queue_s *q);
void dump_vframe(vframe_t *vf);
void dump_di_reg(void);
void print_di_buf(struct di_buf_s *di_buf, int format);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,992 @@
/*
* drivers/amlogic/media/deinterlace/deinterlace_mtn.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/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/uaccess.h>
#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/iomap.h>
#include "register.h"
#include "deinterlace.h"
#include "deinterlace_mtn.h"
#define MAX_NUM_DI_REG 32
#define GXTVBB_REG_START 12
static unsigned int combing_setting_registers[MAX_NUM_DI_REG] = {
DI_MTN_1_CTRL1,
DI_MTN_1_CTRL2,
DI_MTN_1_CTRL3,
DI_MTN_1_CTRL4,
DI_MTN_1_CTRL5,
DI_MTN_1_CTRL6,
DI_MTN_1_CTRL7,
DI_MTN_1_CTRL8,
DI_MTN_1_CTRL9,
DI_MTN_1_CTRL10,
DI_MTN_1_CTRL11,
DI_MTN_1_CTRL12,
/* below reg are gxtvbb only, offset defined in GXTVBB_REG_START */
MCDI_REL_DET_PD22_CHK,
MCDI_PD22_CHK_THD,
MCDI_PD22_CHK_THD_RT,
NR2_MATNR_DEGHOST,
0
};
/* decide the levels based on glb_mot[0:4]
* or with patches like Hist, smith trig logic
* level: 0->1 1->2 2->3 3->4
* from low motion to high motion level
* take 720x480 as example
*/
static unsigned int combing_glb_mot_thr_LH[4] = {1440, 2880, 4760, 9520};
/* >> 4 */
static unsigned int combing_glbmot_radprat[4] = {32, 48, 64, 80};
static unsigned int num_glbmot_radprat = 4;
module_param_array(combing_glbmot_radprat, uint, &num_glbmot_radprat, 0664);
/* level: 0<-1 1<-2 2<-3 3<-4
* from high motion to low motion level
*/
static unsigned int combing_glb_mot_thr_HL[4] = {720, 1440, 2880, 5760};
static unsigned int num_glb_mot_thr_LH = 4;
module_param_array(combing_glb_mot_thr_LH, uint, &num_glb_mot_thr_LH, 0664);
static unsigned int num_glb_mot_thr_HL = 4;
module_param_array(combing_glb_mot_thr_HL, uint, &num_glb_mot_thr_HL, 0664);
int last_lev = -1;
static int force_lev = 0xff;
module_param_named(combing_force_lev, force_lev, int, 0664);
static int dejaggy_flag = -1;
module_param_named(combing_dejaggy_flag, dejaggy_flag, int, 0664);
int dejaggy_enable = 1;
module_param_named(combing_dejaggy_enable, dejaggy_enable, int, 0664);
static uint num_dejaggy_setting = 5;
/* 0:off 1:1-14-1 2:1-6-1 3:3-10-3 4:100% */
/* current setting dejaggy always on when interlace source */
static int combing_dejaggy_setting[5] = {1, 1, 1, 2, 3};
module_param_array(combing_dejaggy_setting, uint,
&num_dejaggy_setting, 0664);
#ifdef CONFIG_AM_ATVDEMOD
static int atv_snr_val = 30;
module_param_named(atv_snr_val, atv_snr_val, int, 0664);
static int atv_snr_cnt;
module_param_named(atv_snr_cnt, atv_snr_cnt, int, 0664);
static int atv_snr_cnt_limit = 30;
module_param_named(atv_snr_cnt_limit, atv_snr_cnt_limit, int, 0664);
#endif
static struct combing_param_s cmb_param;
static unsigned int combing_setting_masks[MAX_NUM_DI_REG] = {
0x0fffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0x0003ff1f,
0x01ff3fff,
0x07ffff1f,
0x000001ff,
0
};
static unsigned int combing_pure_still_setting[MAX_NUM_DI_REG] = {
0x00141410,
0x1A1A3A62,
0x15200A0A,
0x01800880,
0x74200D0D,
0x0D5A1520,
0x0A800480,
0x1A1A2662,
0x0D200302,
0x02020202,
0x06090708,
0x40020A04,
0x0001FF0C,
0x00400204,
0x00016404,
0x00000199
};
static unsigned int combing_bias_static_setting[MAX_NUM_DI_REG] = {
0x00141410,
0x1A1A3A62,
0x15200A0A,
0x01800880,
0x74200D0D,
0x0D5A1520,
0x0A800480,
0x1A1A2662,
0x0D200302,
0x02020202,
0x06090708,
0x40020A04,
0x0001FF0C,
0x00400204,
0x00016404,
0x00000166
};
static unsigned int combing_normal_setting[MAX_NUM_DI_REG] = {
0x00202015,
0x1A1A3A62,
0x15200a0a,
0x01000880,
0x74200D0D,
0x0D5A1520,
0x0A0A0201,
0x1A1A2662,
0x0D200302,
0x02020606,
0x05080304,
0x40020a04,
0x0001FF0C,
0x00400204,
0x00016404,
0x00000153
};
static unsigned int combing_bias_motion_setting[MAX_NUM_DI_REG] = {
0x00202015,
0x1A1A3A62,
0x15200101,
0x01200440,
0x74200D0D,
0x0D5A1520,
0x0A0A0201,
0x1A1A2662,
0x0D200302,
0x02020606,
0x05080304,
0x40020a04,
0x0001ff0c, /* 0x0001FF12 */
0x00400204, /* 0x00200204 */
0x00016404, /* 0x00012002 */
0x00000142
};
static unsigned int combing_very_motion_setting[MAX_NUM_DI_REG] = {
0x00202015,
0x1A1A3A62,
0x15200101,
0x01200440,
0x74200D0D,
0x0D5A1520,
0x0A0A0201,
0x1A1A2662,
0x0D200302,
0x02020606,
0x05080304,
0x40020a04, /* 0x60000404,*/
0x0001ff0c, /* 0x0001FF12 */
0x00400204, /* 0x00200204 */
0x00016404, /* 0x00012002 */
0x00000131
};
/*special for resolution test file*/
static unsigned int combing_resolution_setting[MAX_NUM_DI_REG] = {
0x00202015,
0x141a3a62,
0x15200a0a,
0x01800880,
0x74200d0d,
0x0d5a1520,
0x0a800480,
0x1a1a2662,
0x0d200302,
0x01010101,
0x06090708,
0x40020a04,
0x0001ff0c,
0x00400204,
0x00016404,
0x00000131
};
static unsigned int num_combing_setting_registers = MAX_NUM_DI_REG;
module_param_array(combing_setting_registers, uint,
&num_combing_setting_registers, 0664);
static unsigned int num_combing_setting_masks = MAX_NUM_DI_REG;
module_param_array(combing_setting_masks, uint,
&num_combing_setting_masks, 0664);
static unsigned int num_combing_pure_still_setting = MAX_NUM_DI_REG;
module_param_array(combing_pure_still_setting, uint,
&num_combing_pure_still_setting, 0664);
static unsigned int num_combing_bias_static_setting = MAX_NUM_DI_REG;
module_param_array(combing_bias_static_setting, uint,
&num_combing_bias_static_setting, 0664);
static unsigned int num_combing_normal_setting = MAX_NUM_DI_REG;
module_param_array(combing_normal_setting, uint, &num_combing_normal_setting,
0664);
static unsigned int num_combing_bias_motion_setting = MAX_NUM_DI_REG;
module_param_array(combing_bias_motion_setting, uint,
&num_combing_bias_motion_setting, 0664);
static unsigned int num_combing_very_motion_setting = MAX_NUM_DI_REG;
module_param_array(combing_very_motion_setting, uint,
&num_combing_very_motion_setting, 0664);
/* 0: pure still; 1: bias static; 2: normal; 3: bias motion, 4: very motion */
static unsigned int (*combing_setting_values[6])[MAX_NUM_DI_REG] = {
&combing_pure_still_setting,
&combing_bias_static_setting,
&combing_normal_setting,
&combing_bias_motion_setting,
&combing_very_motion_setting,
&combing_resolution_setting
};
void 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 i = 0;
for (i = 0; i < 4; i++) {
combing_glb_mot_thr_LH[i] =
((width * combing_glbmot_radprat[i] + 8) >> 4);
combing_glb_mot_thr_HL[i] =
combing_glb_mot_thr_LH[i] - width;
}
last_lev = -1;
cmb_param.width = width;
cmb_param.height = height;
cmb_param.src_type = src_type;
cmb_param.fmt = fmt;
cmb_param.prog_flag = prog;
di_apply_reg_cfg(0);
}
void adpative_combing_exit(void)
{
if (is_meson_gxtvbb_cpu() && dejaggy_enable) {
dejaggy_flag = -1;
DI_Wr_reg_bits(SRSHARP0_SHARP_DEJ1_MISC, 0, 3, 1);
}
}
unsigned int adp_set_level(unsigned int diff, unsigned int field_diff_num)
{
unsigned int rst = 0;
char tlog[] = "LHM";
if (diff <= combing_glb_mot_thr_LH[0])
rst = 0;
else if (diff >= combing_glb_mot_thr_LH[3])
rst = 1;
else
rst = 2;
pr_info("%s rst=%u.", __func__, rst);
if (cmb_adpset_cnt > 0) {
pr_info("\field-num=%04d frame-num=%04d lvl=%c\n",
field_diff_num, diff, tlog[rst]);
cmb_adpset_cnt--;
}
return rst;
}
unsigned int adp_set_mtn_ctrl3(unsigned int diff, unsigned int dlvel)
{
int istp = 0;
int idats = 0;
int idatm = 0;
int idatr = 0;
unsigned int rst = 0;
if (dlvel == 0)
rst = combing_pure_still_setting[2];
else if (dlvel == 1)
rst = combing_very_motion_setting[2];
else {
rst = 0x1520;
istp = 64 * (diff - combing_glb_mot_thr_LH[0]) /
(combing_glb_mot_thr_LH[3] -
combing_glb_mot_thr_LH[0] + 1);
idats = (combing_pure_still_setting[2] >> 8) & 0xff;
idatm = (combing_very_motion_setting[2] >> 8) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[2]) & 0xff;
idatm = (combing_very_motion_setting[2]) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
}
/*
*if (cmb_adpset_cnt > 0)
*pr_info("mtn_ctrl3=%8x\n", rst);
*/
return rst;
}
int cmb_num_rat_ctl4 = 64; /* 0~255 */
module_param(cmb_num_rat_ctl4, int, 0644);
MODULE_PARM_DESC(cmb_num_rat_ctl4, "cmb_num_rat_ctl4");
int cmb_rat_ctl4_minthd = 64;
module_param(cmb_rat_ctl4_minthd, int, 0644);
MODULE_PARM_DESC(cmb_rat_ctl4_minthd, "cmb_rat_ctl4_minthd");
unsigned int adp_set_mtn_ctrl4(unsigned int diff, unsigned int dlvel,
unsigned int height, int cmb_cnt)
{
int hHeight = height;
int istp = 0, idats = 0, idatm = 0, idatr = 0;
unsigned int rst = 0;
if (dlvel == 0)
rst = combing_pure_still_setting[3];
else if (dlvel == 1)
rst = combing_very_motion_setting[3];
else {
rst = 1;
istp = 64 * (diff - combing_glb_mot_thr_LH[0]) /
(combing_glb_mot_thr_LH[3] -
combing_glb_mot_thr_LH[0] + 1);
idats = (combing_pure_still_setting[3] >> 16) & 0xff;
idatm = (combing_very_motion_setting[3] >> 16) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
idatr = idatr >> 1;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[3] >> 8) & 0xff;
idatm = (combing_very_motion_setting[3] >> 8) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[3]) & 0xff;
idatm = (combing_very_motion_setting[3]) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst << 8) | (idatr & 0xff);
}
istp = ((cmb_num_rat_ctl4 * hHeight + 128) >> 8);
if (cmb_adpset_cnt > 0)
pr_info("mtn_ctrl4=%8x %03d (%03d)\n",
rst, istp, cmb_cnt);
if (cmb_cnt > istp) {
istp = 64 * (hHeight - cmb_cnt) / (hHeight - istp + 1);
if (istp < 4)
istp = 4;
idatm = 1;
idats = (rst >> 16) & 0xff;
idatr = ((idats * istp + 32) >> 6);
idatr = idatr >> 1; /*color*/
if (idatr < (cmb_rat_ctl4_minthd >> 1))
idatr = (cmb_rat_ctl4_minthd >> 1);
idatm = (idatm<<8) | (idatr & 0xff);
idats = (rst >> 8) & 0xff;
idatr = ((idats * istp + 32) >> 6);
if (idatr < 4)
idatr = 4;
idatm = (idatm<<8) | (idatr & 0xff);
idats = rst & 0xff;
idatr = ((idats * istp + 32) >> 6);
if (idatr < cmb_rat_ctl4_minthd)
idatr = cmb_rat_ctl4_minthd;
idatm = (idatm<<8) | (idatr & 0xff);
rst = idatm;
if (cmb_adpset_cnt > 0)
pr_info("%03d (%03d)=%8x\n",
cmb_cnt, hHeight, rst);
}
return rst;
}
unsigned int adp_set_mtn_ctrl7(unsigned int diff, unsigned int dlvel)
{
int istp = 0, idats = 0, idatm = 0, idatr = 0;
unsigned int rst = 0;
if (dlvel == 0)
rst = combing_pure_still_setting[6];
else if (dlvel == 1)
rst = combing_very_motion_setting[6];
else {
rst = 10;
istp = 64 * (diff - combing_glb_mot_thr_LH[0]) /
(combing_glb_mot_thr_LH[3] -
combing_glb_mot_thr_LH[0] + 1);
idats = (combing_pure_still_setting[6] >> 16) & 0xff;
idatm = (combing_very_motion_setting[6] >> 16) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[6] >> 8) & 0xff;
idatm = (combing_very_motion_setting[6] >> 8) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[6]) & 0xff;
idatm = (combing_very_motion_setting[6]) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
}
/*
*if (cmb_adpset_cnt > 0) {
* pr_info("mtn_ctrl7=%8x\n", rst);
*}
*/
return rst;
}
static unsigned int small_local_mtn = 70;
module_param(small_local_mtn, uint, 0644);
MODULE_PARM_DESC(small_local_mtn, "small_local_mtn");
unsigned int adp_set_mtn_ctrl10(unsigned int diff, unsigned int dlvel,
unsigned int *frame_diff_avg)
{
int istp = 0, idats = 0, idatm = 0, idatr = 0;
unsigned int rst = 0;
if (*frame_diff_avg < small_local_mtn)
rst = combing_very_motion_setting[9];
else if (dlvel == 0)
rst = combing_pure_still_setting[9];
else if (dlvel == 1)
rst = combing_very_motion_setting[9];
else {
istp = 64 * (diff - combing_glb_mot_thr_LH[0]) /
(combing_glb_mot_thr_LH[3] -
combing_glb_mot_thr_LH[0] + 1);
idats = (combing_very_motion_setting[9] >> 24) & 0xff;
idatm = (combing_pure_still_setting[9] >> 24) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_very_motion_setting[9] >> 16) & 0xff;
idatm = (combing_pure_still_setting[9] >> 16) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_very_motion_setting[9] >> 8) & 0xff;
idatm = (combing_pure_still_setting[9] >> 8) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_very_motion_setting[9]) & 0xff;
idatm = (combing_pure_still_setting[9]) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
}
if (cmb_adpset_cnt > 0) {
pr_info("mtn_ctr10=0x%08x (frame_dif_avg=%03d)\n",
rst, *frame_diff_avg);
}
return rst;
}
unsigned int adp_set_mtn_ctrl11(unsigned int diff, unsigned int dlvel)
{
int istp = 0, idats = 0, idatm = 0, idatr = 0;
unsigned int rst = 0;
if (dlvel == 0)
rst = combing_pure_still_setting[10];
else if (dlvel == 1)
rst = combing_very_motion_setting[10];
else {
istp = 64 * (diff - combing_glb_mot_thr_LH[0]) /
(combing_glb_mot_thr_LH[3] -
combing_glb_mot_thr_LH[0] + 1);
idats = (combing_pure_still_setting[10] >> 24) & 0xff;
idatm = (combing_very_motion_setting[10] >> 24) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[10] >> 16) & 0xff;
idatm = (combing_very_motion_setting[10] >> 16) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[10] >> 8) & 0xff;
idatm = (combing_very_motion_setting[10] >> 8) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
idats = (combing_pure_still_setting[10]) & 0xff;
idatm = (combing_very_motion_setting[10]) & 0xff;
idatr = ((idats - idatm) * istp >> 6) + idatm;
rst = (rst<<8) | (idatr & 0xff);
}
/*
*if (cmb_adpset_cnt > 0) {
* pr_info("mtn_ctr11=%8x\n", rst);
*}
*/
return rst;
}
static void set_combing_regs(int lvl, int bit_mode)
{
int i;
unsigned int ndat = 0;
for (i = 0; i < MAX_NUM_DI_REG; i++) {
if ((combing_setting_registers[i] == 0)
|| (combing_setting_masks[i] == 0))
break;
if (bit_mode != 10 &&
combing_setting_registers[i] == NR2_MATNR_DEGHOST)
break;
else if (i < GXTVBB_REG_START) {
/* TODO: need change to check if
* register only in GCTVBB
*/
ndat = (*combing_setting_values[lvl])[i];
DI_Wr(combing_setting_registers[i], ndat);
} else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB))
DI_Wr(combing_setting_registers[i],
((*combing_setting_values[lvl])[i] &
combing_setting_masks[i]) |
(Rd(
combing_setting_registers[i])
& ~combing_setting_masks[i]));
}
}
static int di_debug_readreg;
module_param(di_debug_readreg, int, 0644);
MODULE_PARM_DESC(di_debug_readreg, "di_debug_readreg");
static int dejaggy_4p = true;
module_param_named(dejaggy_4p, dejaggy_4p, int, 0664);
int adaptive_combing_fixing(
unsigned int field_diff,
unsigned int frame_diff,
int cur_lev, int bit_mode,
int cmb_cnt, int like_pulldown22_flag,
unsigned int *frame_diff_avg)
{
unsigned int glb_mot_avg2;
unsigned int glb_mot_avg3;
unsigned int glb_mot_avg5;
unsigned int diff = 0;
unsigned int wt_dat = 0;
unsigned int dlvl = 0;
static unsigned int pre_dat[5];
bool prt_flg = (cmb_adpset_cnt > 0);
unsigned int i = 0;
static unsigned int pre_num;
unsigned int crt_num = field_diff;
unsigned int drat = 0;
static int still_field_count;
static int glb_mot[5] = {0, 0, 0, 0, 0};
if (pre_num > crt_num)
diff = pre_num - crt_num;
else
diff = crt_num - pre_num;
if (diff >= cmb_param.width)
field_diff_rate = 0;
else {
drat = (diff << 8) / (cmb_param.width + 1);
if (drat > 255)
field_diff_rate = 0;
else
field_diff_rate = 256 - drat;
}
pre_num = crt_num;
if (di_debug_readreg > 1) {
for (i = 0; i < 12; i++) {
wt_dat = Rd(combing_setting_registers[i]);
pr_info("mtn_ctrl%02d = 0x%08x\n",
i+1, wt_dat);
}
pr_info("\n");
di_debug_readreg--;
}
glb_mot[4] = glb_mot[3];
glb_mot[3] = glb_mot[2];
glb_mot[2] = glb_mot[1];
glb_mot[1] = glb_mot[0];
glb_mot[0] = frame_diff;
glb_mot_avg5 =
(glb_mot[0] + glb_mot[1] + glb_mot[2] + glb_mot[3] +
glb_mot[4]) / 5;
glb_mot_avg3 = (glb_mot[0] + glb_mot[1] + glb_mot[2]) / 3;
glb_mot_avg2 = (glb_mot[0] + glb_mot[1]) / 2;
if (glb_mot[0] > combing_glb_mot_thr_LH[0])
still_field_count = 0;
else
if (still_field_count < 16)
still_field_count++;
if (glb_mot_avg3 > combing_glb_mot_thr_LH[min(cur_lev, 3)]) {
if (cur_lev < 4)
cur_lev++;
} else {
if (glb_mot_avg5 <
combing_glb_mot_thr_HL[max(cur_lev - 1, 0)]) {
if (cur_lev <= 1 && still_field_count > 5)
cur_lev = 0;
else
cur_lev = max(cur_lev - 1, 1);
}
}
if ((force_lev >= 0) & (force_lev < 6))
cur_lev = force_lev;
if (cur_lev != last_lev) {
set_combing_regs(cur_lev, bit_mode);
if (pr_pd & 0x400)
pr_dbg("\t%5d: from %d to %d: di_mtn_1_ctrl1 = %08x\n",
field_count, last_lev, cur_lev, Rd(DI_MTN_1_CTRL1));
last_lev = cur_lev;
}
if ((force_lev > 5) && (glb_mot[1] != glb_mot[0])) {
dlvl = adp_set_level(glb_mot[0], field_diff);
diff = glb_mot[0];
pre_dat[0] = Rd(DI_MTN_1_CTRL3);
if (prt_flg)
pr_info("%s dlevel=%d.\n", __func__, dlvl);
wt_dat = adp_set_mtn_ctrl3(diff, dlvl);
if (pre_dat[0] != wt_dat) {
DI_Wr(DI_MTN_1_CTRL3, wt_dat);
pre_dat[0] = wt_dat;
if (prt_flg)
pr_info("set mtn03 0x%08x.\n", wt_dat);
}
pre_dat[1] = Rd(DI_MTN_1_CTRL4);
wt_dat = adp_set_mtn_ctrl4(diff, dlvl, cmb_param.height,
cmb_cnt);
if (pre_dat[1] != wt_dat) {
DI_Wr(DI_MTN_1_CTRL4, wt_dat);
if (prt_flg)
pr_info("set mtn04 %08x -> %08x.\n",
pre_dat[1], wt_dat);
pre_dat[1] = wt_dat;
}
pre_dat[2] = Rd(DI_MTN_1_CTRL7);
wt_dat = adp_set_mtn_ctrl7(diff, dlvl);
if (pre_dat[2] != wt_dat) {
DI_Wr(DI_MTN_1_CTRL7, wt_dat);
pre_dat[2] = wt_dat;
if (prt_flg)
pr_info("set mtn07 0x%08x.\n", wt_dat);
}
pre_dat[3] = Rd(DI_MTN_1_CTRL10);
wt_dat = adp_set_mtn_ctrl10(diff, dlvl, frame_diff_avg);
if (pre_dat[3] != wt_dat) {
DI_Wr(DI_MTN_1_CTRL10, wt_dat);
pre_dat[3] = wt_dat;
if (prt_flg)
pr_info("set mtn10 0x%08x.\n", wt_dat);
}
pre_dat[4] = Rd(DI_MTN_1_CTRL11);
wt_dat = adp_set_mtn_ctrl11(diff, dlvl);
if (pre_dat[4] != wt_dat) {
DI_Wr(DI_MTN_1_CTRL11, wt_dat);
pre_dat[4] = wt_dat;
if (prt_flg)
pr_info("set mtn11 0x%08x.\n\n", wt_dat);
}
}
if (is_meson_gxtvbb_cpu() && dejaggy_enable) {
/* only enable dejaggy for interlace */
if (cmb_param.prog_flag &&
!dejaggy_4p) {
if (dejaggy_flag != -1) {
dejaggy_flag = -1;
DI_Wr_reg_bits(SRSHARP0_SHARP_DEJ1_MISC,
0, 3, 1);
}
} else {
if ((dejaggy_flag == -1)
|| ((Rd(SRSHARP0_SHARP_SR2_CTRL) & (1 << 24)) == 0)) {
/* enable dejaggy module */
DI_Wr_reg_bits(SRSHARP0_SHARP_SR2_CTRL,
1, 24, 1);
/* first time set default */
DI_Wr_reg_bits(SRSHARP0_SHARP_DEJ2_PRC,
0xff, 24, 8);
DI_Wr(SRSHARP0_SHARP_DEJ1_PRC,
(0xff<<24)|(0xd1<<16)|(0xe<<8)|0x31);
DI_Wr(
SRSHARP0_SHARP_DEJ2_MISC, 0x30);
DI_Wr(
SRSHARP0_SHARP_DEJ1_MISC, 0x02f4);
dejaggy_flag = 0;
}
if (dejaggy_enable) {
/* dejaggy alpha according to motion level */
dejaggy_flag =
combing_dejaggy_setting[cur_lev];
/* TODO: check like_pulldown22_flag and ATV
* noise_level
*/
#ifdef CONFIG_AM_ATVDEMOD
if ((aml_atvdemod_get_snr_ex() < atv_snr_val)
&& cmb_param.src_type == VFRAME_SOURCE_TYPE_TUNER) {
if (atv_snr_cnt++ > atv_snr_cnt_limit)
dejaggy_flag += 3;
} else if (atv_snr_cnt)
atv_snr_cnt = 0;
#endif
if (like_pulldown22_flag && (cur_lev > 2))
dejaggy_flag += 1;
/* overwrite dejaggy alpha */
if (dejaggy_enable >= 2)
dejaggy_flag = dejaggy_enable;
if (dejaggy_flag > 4)
dejaggy_flag = 4;
if (dejaggy_flag)
DI_Wr_reg_bits(
SRSHARP0_SHARP_DEJ1_MISC,
(1<<3)|dejaggy_flag, 0, 4);
else
DI_Wr_reg_bits(
SRSHARP0_SHARP_DEJ1_MISC,
0, 3, 1);
} else
dejaggy_flag = 0;
}
} else if (is_meson_gxtvbb_cpu()) {
dejaggy_flag = -1;
DI_Wr_reg_bits(SRSHARP0_SHARP_DEJ1_MISC, 0, 3, 1);
}
return cur_lev;
}
static reg_cfg_t *reg_cfg_head;
/* new pre and post di setting */
reg_cfg_t di_default_pre = {
NULL,
((1 << VFRAME_SOURCE_TYPE_OTHERS) |
(1 << VFRAME_SOURCE_TYPE_TUNER) |
(1 << VFRAME_SOURCE_TYPE_CVBS) |
(1 << VFRAME_SOURCE_TYPE_COMP) |
(1 << VFRAME_SOURCE_TYPE_HDMI)
),
0,
0,
{
(
(TVIN_SIG_FMT_COMP_480P_60HZ_D000 << 16) |
TVIN_SIG_FMT_CVBS_SECAM),
0
},
{
{DI_EI_CTRL3, 0x0000013, 0, 27},
{DI_EI_CTRL4, 0x151b3084, 0, 31},
{DI_EI_CTRL5, 0x5273204f, 0, 31},
{DI_EI_CTRL6, 0x50232815, 0, 31},
{DI_EI_CTRL7, 0x2fb56650, 0, 31},
{DI_EI_CTRL8, 0x230019a4, 0, 31},
{DI_EI_CTRL9, 0x7cb9bb33, 0, 31},
/* #define DI_EI_CTRL10 */
{0x1793, 0x0842c6a9, 0, 31},
/* #define DI_EI_CTRL11 */
{0x179e, 0x486ab07a, 0, 31},
/* #define DI_EI_CTRL12 */
{0x179f, 0xdb0c2503, 0, 32},
/* #define DI_EI_CTRL13 */
{0x17a8, 0x0f021414, 0, 31},
{ 0 },
}
};
reg_cfg_t di_default_post = {
NULL,
((1 << VFRAME_SOURCE_TYPE_OTHERS) |
(1 << VFRAME_SOURCE_TYPE_TUNER) |
(1 << VFRAME_SOURCE_TYPE_CVBS) |
(1 << VFRAME_SOURCE_TYPE_COMP) |
(1 << VFRAME_SOURCE_TYPE_HDMI)
),
1,
2,
{
(
(TVIN_SIG_FMT_COMP_480P_60HZ_D000 << 16) |
TVIN_SIG_FMT_CVBS_SECAM),
0
},
{
{DI_MTN_1_CTRL1, 0, 30, 1},
{DI_MTN_1_CTRL1, 0x0202015, 0, 27},
{DI_MTN_1_CTRL2, 0x141a2062, 0, 31},
{DI_MTN_1_CTRL3, 0x1520050a, 0, 31},
{DI_MTN_1_CTRL4, 0x08800840, 0, 31},
{DI_MTN_1_CTRL5, 0x74200d0d, 0, 31},
/* #define DI_MTN_1_CTRL6 */
{DI_MTN_1_CTRL6, 0x0d5a1520, 0, 31},
/* #define DI_MTN_1_CTRL7 */
{DI_MTN_1_CTRL7, 0x0a0a0201, 0, 31},
/* #define DI_MTN_1_CTRL8 */
{DI_MTN_1_CTRL8, 0x1a1a2662, 0, 31},
/* #define DI_MTN_1_CTRL9 */
{DI_MTN_1_CTRL9, 0x0d200302, 0, 31},
/* #define DI_MTN_1_CTRL10 */
{DI_MTN_1_CTRL10, 0x02020606, 0, 31},
/* #define DI_MTN_1_CTRL11 */
{DI_MTN_1_CTRL11, 0x05080304, 0, 31},
/* #define DI_MTN_1_CTRL12 */
{DI_MTN_1_CTRL12, 0x40020a04, 0, 31},
{ 0 },
}
};
void di_add_reg_cfg(reg_cfg_t *reg_cfg)
{
reg_cfg->next = reg_cfg_head;
reg_cfg_head = reg_cfg;
}
void di_add_reg_cfg_init(void)
{
di_add_reg_cfg(&di_default_pre);
di_add_reg_cfg(&di_default_post);
}
static int use_reg_cfg = 1;
MODULE_PARM_DESC(use_reg_cfg, "\n use_reg_cfg\n");
module_param(use_reg_cfg, uint, 0664);
void di_apply_reg_cfg(unsigned char pre_post_type)
{
reg_cfg_t *reg_cfg = reg_cfg_head;
int ii;
unsigned char set_flag = 0;
if (!use_reg_cfg)
return;
while (reg_cfg) {
if ((pre_post_type == reg_cfg->pre_post_type) &&
((1 << cmb_param.src_type) &
reg_cfg->source_types_enable)) {
if (cmb_param.src_type ==
VFRAME_SOURCE_TYPE_OTHERS &&
(reg_cfg->dtv_definition_type != 2)) {
/* if:dtv stand definition
* else if:high definition
*/
if ((cmb_param.height<<1) < 720 &&
reg_cfg->dtv_definition_type)
set_flag = 1;
else if ((cmb_param.height<<1) >= 720
&& (!reg_cfg->dtv_definition_type))
set_flag = 1;
} else {
for (ii = 0; ii < FMT_MAX_NUM; ii++) {
if (reg_cfg->
sig_fmt_range[ii] == 0)
break;
else if (
(cmb_param.fmt >=
((reg_cfg->sig_fmt_range[ii]
>> 16) & 0xffff))
&& (cmb_param.fmt <=
(reg_cfg->sig_fmt_range[ii] &
0xffff))) {
set_flag = 1;
break;
}
}
}
}
if (set_flag) {
for (ii = 0; ii < REG_SET_MAX_NUM; ii++) {
if (reg_cfg->reg_set[ii].adr == 0)
break;
if (pre_post_type) {
DI_VSYNC_WR_MPEG_REG_BITS(
reg_cfg->reg_set[ii].adr,
reg_cfg->reg_set[ii].val,
reg_cfg->reg_set[ii].start,
reg_cfg->reg_set[ii].len);
} else {
RDMA_WR_BITS(
reg_cfg->reg_set[ii].adr,
reg_cfg->reg_set[ii].val,
reg_cfg->reg_set[ii].start,
reg_cfg->reg_set[ii].len);
}
}
break;
}
reg_cfg = reg_cfg->next;
}
}

View File

@@ -0,0 +1,63 @@
/*
* drivers/amlogic/media/deinterlace/deinterlace_mtn.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.
*
*/
struct combing_param_s {
unsigned int width;
unsigned int height;
enum vframe_source_type_e src_type;
enum tvin_sig_fmt_e fmt;
bool prog_flag;
};
struct reg_set_s {
unsigned int adr;
unsigned int val;
unsigned short start;
unsigned short len;
};
#define reg_set_t struct reg_set_s
#define REG_SET_MAX_NUM 128
#define FMT_MAX_NUM 32
struct reg_cfg_ {
struct reg_cfg_ *next;
unsigned int source_types_enable;
/* each bit corresponds to one source type */
unsigned int pre_post_type; /* pre, 0; post, 1 */
unsigned int dtv_definition_type;
/*high definition,0; stand definition ,1;common,2*/
unsigned int sig_fmt_range[FMT_MAX_NUM];
/* {bit[31:16]~bit[15:0]}, include bit[31:16] and bit[15:0] */
reg_set_t reg_set[REG_SET_MAX_NUM];
};
#define reg_cfg_t struct reg_cfg_
extern int last_lev;
extern int dejaggy_enable;
void 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 adaptive_combing_fixing(
unsigned int field_diff, unsigned int frame_diff,
int cur_lev, int bit_mode, int cmb_cnt,
int like_pulldown22_flag, unsigned int *frame_diff_avg);
void adpative_combing_exit(void);
#ifdef CONFIG_AM_ATVDEMOD
extern int aml_atvdemod_get_snr_ex(void);
#endif
void di_apply_reg_cfg(unsigned char pre_post_type);
void di_add_reg_cfg_init(void);

View File

@@ -0,0 +1,439 @@
/*
* drivers/amlogic/media/deinterlace/detect3d.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/module.h>
/* Amlogic Headers */
#include <linux/amlogic/iomap.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <linux/amlogic/iomap.h>
#include "register.h"
#include "detect3d.h"
#include "deinterlace.h"
/*******************Local defines**********************/
#define DET3D_REG_NUM 9
/* the number of total register */
#define FRAME_MAX (1<<15)
/* Frame cnt max value */
#define LR_FMT_SCORE_MAX (2047)
/* range of score in LR detection */
#define LR_FMT_SCORE_MIN (-2047)
#define TB_FMT_SCORE_MAX (2047)
/* range of score in TB detection */
#define TB_FMT_SCORE_MIN (-2047)
#define INTERLACE_FMT_SCORE_MAX (63)
/* range of score in interlace detection */
#define INTERLACE_FMT_SCORE_MIN (-63)
#define CHESSBOAD_FMT_SCORE_MAX (63)
/* range of score in chessboard detection */
#define CHESSBOAD_FMT_SCORE_MIN (-63)
#define LR_SCORE_LOWER_LIMIT 128
/* if score > this limit, input is sure to be LR format */
#define TB_SCORE_LOWER_LIMIT 128
/* if score > this limit, input is sure to be TB format */
#define INTERLACE_SCORE_LOWER_LIMIT 30
/* if score > this limit, input is sure to be interlace format */
#define CHESSBOADE_SCORE_LOWER_LIMIT 30
/* if score > this limit, input is sure to be chessboard format */
#define NOT_LR_SCORE_UPPER_LIMIT (-24)
/* if score < this limit, input is sure to be not LR format */
#define NOT_TB_SCORE_UPPER_LIMIT (-24)
/* if score < this limit, input is sure to be not TB format */
#define NOT_INTERLACE_SCORE_UPPER_LIMIT (-12)
/* if score < this limit, input is sure to be not interlace format */
#define NOT_CHESSBOAD_SCORE_UPPER_LIMIT (-12)
/* if score < this limit, input is sure to be not chessboard format */
#define LR_SYMMETRY_LOWER_LIMIT 44
/* if > this limit,input is translational-symmety in left half and right half */
#define TB_SYMMETRY_LOWER_LIMIT 44
/* if > this limit,input is translational-symmety in top half and bottom half */
static int chessbd_vrate = 29;
static bool det3d_debug;
/***************************Local variables **********************************/
const unsigned int det3d_table[DET3D_REG_NUM] = {
0x00000002, 0x00000027, 0x00000065, 0x00444400,
0xc8404733, 0x00060606, 0x00060606, 0x0000002a,
0x0c0c0c0a
};
static struct det3d_info_s det3d_info = {
-1, /* nfrm */
DET3D_FMT_NULL, /* tfw_det3d_fmt */
0, /* score_3d_lr */
0, /* score_3d_tb */
{0, 0, 0, 0, 0, 0, 0, 0}, /* tscore_3d_lr[8] */
{0, 0, 0, 0, 0, 0, 0, 0}, /* tscore_3d_tb[8] */
0, /* tscore_3d_lr_accum */
0, /* tscore_3d_tb_accum */
0, /* score_3d_chs */
0, /* score_3d_int */
{0, 0, 0, 0, 0, 0, 0, 0}, /* chs_valid_his[8] */
{0, 0, 0, 0, 0, 0, 0, 0}, /* int_valid_his[8] */
};
/*
* Enable and Disable det3d
* flag == true, enable det3d; flag == false, disable det3d;
*/
void det3d_enable(bool flag)
{
int i;
if (flag == 1) {
/* disable 3D detection */
DI_Wr_reg_bits(NR2_SW_EN, 0, DET3D_EN_BIT, DET3D_EN_WID);
/* initialize the registers */
for (i = 0; i < DET3D_REG_NUM; i++)
DI_Wr((DET3D_BASE_ADD + i), det3d_table[i]);
/* Det 3D interrupt enble */
DI_Wr_reg_bits(DET3D_MOTN_CFG, 1,
DET3D_INTR_EN_BIT, DET3D_INTR_EN_WID);
/* enable 3D detection */
DI_Wr_reg_bits(NR2_SW_EN, 1, DET3D_EN_BIT, DET3D_EN_WID);
} else{
/* Det 3D interrupt disable */
DI_Wr_reg_bits(DET3D_MOTN_CFG, 0,
DET3D_INTR_EN_BIT, DET3D_INTR_EN_WID);
/* disable 3D detection */
DI_Wr_reg_bits(NR2_SW_EN, 0, DET3D_EN_BIT, DET3D_EN_WID);
memset(&det3d_info, 0, sizeof(det3d_info));
}
}
/*
* Read cbus reg signed bits
* length must be <= 31
*/
int read_cbus_reg_signed_bits(unsigned int reg, unsigned int startbit,
unsigned int length)
{
int val;
int tmp = 1;
if (length > 31)
length = 31;
val = Rd_reg_bits(reg, startbit, length);
tmp = tmp << (length - 1);
/* pr_dbg("len = %d, unsigned value = %d,
* signed value = %d",length,val,((val >= tmp )?
* (val - (tmp << 1)):val));
*/
return (val >= tmp)?(val - (tmp << 1)):val;
}
/*
* accumulate the frame to frame scores
*/
static void det3d_accumulate_score(int lr_score, int tb_score,
int int_score, int chessbd_score)
{
int tmp1 = 0;
int tmp2 = 0;
int m;
/* accumulate the frame to frame scores */
if (det3d_info.nfrm < 1) {
det3d_info.score_3d_lr = lr_score;
det3d_info.score_3d_tb = tb_score;
/* initialize the temporary score buffer */
det3d_info.tscore_3d_lr[0] = lr_score;
det3d_info.tscore_3d_tb[0] = tb_score;
det3d_info.chs_valid_his[0] = chessbd_score;
det3d_info.int_valid_his[0] = int_score;
det3d_info.tscore_3d_lr_accum = (lr_score <= 0) ? 1 : 0;
det3d_info.tscore_3d_tb_accum = (tb_score <= 0) ? 1 : 0;
} else{
det3d_info.score_3d_lr = det3d_info.score_3d_lr + lr_score;
det3d_info.score_3d_tb = det3d_info.score_3d_tb + tb_score;
for (m = 7; m > 0; m--) {
det3d_info.tscore_3d_lr[m] =
det3d_info.tscore_3d_lr[m - 1]; /* optimized needed??? */
det3d_info.tscore_3d_tb[m] =
det3d_info.tscore_3d_tb[m - 1];
det3d_info.chs_valid_his[m] =
(chessbd_score == det3d_info.chs_valid_his[0]) ?
det3d_info.chs_valid_his[m - 1]:0;
det3d_info.int_valid_his[m] =
(int_score == det3d_info.int_valid_his[0]) ? det3d_info.int_valid_his[m - 1]:0;
}
/* -------------------------------------------- */
/* detection result agreement in frame to frame */
/* -------------------------------------------- */
det3d_info.tscore_3d_lr[0] = lr_score;
det3d_info.tscore_3d_tb[0] = tb_score;
det3d_info.tscore_3d_lr_accum =
det3d_info.tscore_3d_lr_accum + (lr_score <= 0) -
(det3d_info.tscore_3d_lr[5] <= 0);
det3d_info.tscore_3d_tb_accum =
det3d_info.tscore_3d_tb_accum + (tb_score <= 0) -
(det3d_info.tscore_3d_tb[5] <= 0);
/* Clip to s12 */
det3d_info.score_3d_lr =
(det3d_info.score_3d_lr > LR_FMT_SCORE_MAX) ? 1800 : det3d_info.score_3d_lr;
det3d_info.score_3d_lr =
(det3d_info.score_3d_lr < LR_FMT_SCORE_MIN) ? -1800 : det3d_info.score_3d_lr;
det3d_info.score_3d_tb =
(det3d_info.score_3d_tb > TB_FMT_SCORE_MAX) ? 1800 : det3d_info.score_3d_tb;
det3d_info.score_3d_tb =
(det3d_info.score_3d_tb < TB_FMT_SCORE_MIN) ? -1800 : det3d_info.score_3d_tb;
/* ------------------------------------- */
/* Chessboard frame to frame agreement */
/* ------------------------------------- */
det3d_info.score_3d_chs =
((chessbd_score == det3d_info.chs_valid_his[0])) ? det3d_info.score_3d_chs : 0;
/* det3d_info.score_3d_int =
* ((int_score == det3d_info.int_valid_his[0]))?
* det3d_info.score_3d_int: 0;
*/
det3d_info.chs_valid_his[0] = chessbd_score;
det3d_info.int_valid_his[0] = int_score;
for (m = 0; m < 8; m++) {
tmp1 = tmp1 + (det3d_info.chs_valid_his[m]);
tmp2 = tmp2 + (det3d_info.int_valid_his[m]);
}
det3d_info.score_3d_chs = det3d_info.score_3d_chs + tmp1;
det3d_info.score_3d_int = det3d_info.score_3d_int + tmp2;
if (det3d_debug)
pr_dbg("%s input(%d,%d),output (%d,%d).\n",
__func__, chessbd_score, int_score,
det3d_info.score_3d_chs, det3d_info.score_3d_int);
/* cliping to s7 */
det3d_info.score_3d_chs =
(det3d_info.score_3d_chs > CHESSBOAD_FMT_SCORE_MAX) ?
CHESSBOAD_FMT_SCORE_MAX : det3d_info.score_3d_chs;
det3d_info.score_3d_chs =
(det3d_info.score_3d_chs < CHESSBOAD_FMT_SCORE_MIN) ?
CHESSBOAD_FMT_SCORE_MIN : det3d_info.score_3d_chs;
det3d_info.score_3d_int =
(det3d_info.score_3d_int > INTERLACE_FMT_SCORE_MAX) ?
INTERLACE_FMT_SCORE_MAX : det3d_info.score_3d_int;
det3d_info.score_3d_int =
(det3d_info.score_3d_int < INTERLACE_FMT_SCORE_MIN) ?
INTERLACE_FMT_SCORE_MIN : det3d_info.score_3d_int;
}
}
/*
* detect 3D format
* execute one or more frame after init;
*/
enum tvin_trans_fmt det3d_fmt_detect(void)
{
/* FW registers */
int chessbd_hor_rate = 31;/* 8bits: norm to 16 */
/* int chessbd_ver_rate = 31;// 8bits: norm to 16 */
int chessbd_hor_thrd = 4; /* 8bits: */
int chessbd_ver_thrd = 4; /* 8bits: */
/* local FW variables */
int m;
int tmp_sp_lr, tmp_sp_tb;
int tmp_lr, tmp_tb, tmp1, tmp2;
int tmp_chs, tmp_int;
int tmp_symtc_lr, tmp_symtc_tb, tmp_frmstill;
int chessbd_hor_valid, chessbd_ver_valid;
/* int dump_valid = 0; */
/* static int call_first = 1; */
if (det3d_info.nfrm < (FRAME_MAX))
det3d_info.nfrm++;
else
det3d_info.nfrm = 256; /* reset to smaller number */
/* Split line contribution */
tmp_sp_lr =
Rd_reg_bits(DET3D_RO_SPLT_HT,
DET3D_SPLIT_HT_VAILID_BIT, DET3D_SPLIT_HT_VAILID_WID)
+ Rd_reg_bits(DET3D_RO_SPLT_HB,
DET3D_SPLIT_HB_VAILID_BIT, DET3D_SPLIT_HB_VAILID_WID);
tmp_sp_tb =
Rd_reg_bits(DET3D_RO_SPLT_VL,
DET3D_SPLIT_VL_VAILID_BIT, DET3D_SPLIT_VL_VAILID_WID)
+ Rd_reg_bits(DET3D_RO_SPLT_VR,
DET3D_SPLIT_VR_VAILID_BIT, DET3D_SPLIT_VR_VAILID_WID);
/* protect static graphics pattern */
if ((tmp_sp_lr == 2) && (tmp_sp_tb == 2)) {
tmp_sp_lr = -1;
tmp_sp_tb = -1;
/* -1: bias towards 2D; 0: keep previous status */
}
/* 8x8 statistics scores for being LR and TB */
tmp_lr = tmp_sp_lr
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_LUMA_LR,
DET3D_LUMA_LR_SUM_BIT, DET3D_LUMA_LR_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_CHRV_LR,
DET3D_CHRV_LR_SUM_BIT, DET3D_CHRV_LR_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_CHRU_LR,
DET3D_CHRU_LR_SUM_BIT, DET3D_CHRU_LR_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_HEDG_LR,
DET3D_HEDG_LR_SUM_BIT, DET3D_HEDG_LR_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_VEDG_LR,
DET3D_VEDG_LR_SUM_BIT, DET3D_VEDG_LR_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_MOTN_LR,
DET3D_MOTN_LR_SUM_BIT, DET3D_MOTN_LR_SUM_WID);
tmp_tb = tmp_sp_tb
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_LUMA_TB,
DET3D_LUMA_TB_SUM_BIT, DET3D_LUMA_TB_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_CHRV_TB,
DET3D_CHRV_TB_SUM_BIT, DET3D_CHRV_TB_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_CHRU_TB,
DET3D_CHRU_TB_SUM_BIT, DET3D_CHRU_TB_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_HEDG_TB,
DET3D_HEDG_TB_SUM_BIT, DET3D_HEDG_TB_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_VEDG_TB,
DET3D_VEDG_TB_SUM_BIT, DET3D_VEDG_TB_SUM_WID)
+ read_cbus_reg_signed_bits(DET3D_RO_MAT_MOTN_TB,
DET3D_MOTN_TB_SUM_BIT, DET3D_MOTN_TB_SUM_WID);
/* 8x8 statistics for being purely symetrical */
tmp_symtc_lr = 0;
tmp_symtc_tb = 0;
for (m = 0; m < 8; m++) {
tmp_symtc_lr = tmp_symtc_lr
+ Rd_reg_bits(DET3D_RO_MAT_LUMA_LR, (DET3D_LUMA_LR_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_CHRU_LR, (DET3D_CHRU_LR_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_CHRV_LR, (DET3D_CHRV_LR_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_HEDG_LR, (DET3D_HEDG_LR_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_VEDG_LR, (DET3D_VEDG_LR_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_MOTN_LR, (DET3D_MOTN_LR_SYMTC_BIT + m), 1);
tmp_symtc_tb = tmp_symtc_tb
+ Rd_reg_bits(DET3D_RO_MAT_LUMA_TB, (DET3D_LUMA_TB_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_CHRU_TB, (DET3D_CHRU_TB_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_CHRV_TB, (DET3D_CHRV_TB_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_HEDG_TB, (DET3D_HEDG_TB_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_VEDG_TB, (DET3D_VEDG_TB_SYMTC_BIT + m), 1)
+ Rd_reg_bits(DET3D_RO_MAT_MOTN_TB, (DET3D_MOTN_TB_SYMTC_BIT + m), 1);
}
tmp_symtc_lr = tmp_symtc_lr > LR_SYMMETRY_LOWER_LIMIT;
tmp_symtc_tb = tmp_symtc_tb > TB_SYMMETRY_LOWER_LIMIT;
tmp_frmstill = Rd_reg_bits(DET3D_RO_FRM_MOTN,
DET3D_FRAME_MOTION_BIT, DET3D_FRAME_MOTION_WID) < 100;
/* if FrmStill && score>=0, force score decrease 1 */
if (tmp_frmstill && (tmp_lr >= -1))
tmp_lr = tmp_lr - 1;
if (tmp_frmstill && (tmp_tb >= -1))
tmp_tb = tmp_tb - 1;
/* if FrmStill && symtc && score>=0, force score to 0/-1 */
/* if (tmp_frmstill&&tmp_symtc_lr&&(tmp_lr>=0)) tmp_lr = 0; */
/* if (tmp_frmstill&&tmp_symtc_tb&&(tmp_tb>=0)) tmp_tb = 0; */
/* ChessBoard/interlace mode score */
tmp1 = Rd_reg_bits(DET3D_RO_DET_CB_HOR,
DET3D_CHESSBD_HOR_VALUE_BIT, DET3D_CHESSBD_HOR_VALUE_WID);
tmp2 = Rd_reg_bits(DET3D_RO_DET_CB_HOR,
DET3D_CHESSBD_NHOR_VALUE_BIT, DET3D_CHESSBD_NHOR_VALUE_WID);
chessbd_hor_valid = tmp1 >
(((tmp2 * chessbd_hor_rate) >> 4) + chessbd_hor_thrd);
tmp1 = Rd_reg_bits(DET3D_RO_DET_CB_VER,
DET3D_CHESSBD_VER_VALUE_BIT, DET3D_CHESSBD_VER_VALUE_WID);
tmp2 = Rd_reg_bits(DET3D_RO_DET_CB_VER,
DET3D_CHESSBD_NVER_VALUE_BIT, DET3D_CHESSBD_NVER_VALUE_WID);
chessbd_ver_valid = tmp1 > (((tmp2 * chessbd_vrate) >> 4) +
chessbd_ver_thrd);
tmp_chs = chessbd_hor_valid & chessbd_ver_valid;
tmp_chs = 2 * tmp_chs - 1;
tmp_int = (chessbd_hor_valid == 0) & chessbd_ver_valid;
tmp_int = 2 * tmp_int - 1;
det3d_accumulate_score(tmp_lr, tmp_tb, tmp_int, tmp_chs);
/* quick reset to get faster converse */
if (((tmp_lr > 8) && (tmp_tb < -8) &&
(det3d_info.score_3d_lr < -127)) || ((det3d_info.tscore_3d_lr_accum >= 4) &&
(det3d_info.score_3d_lr > 63)))
det3d_info.score_3d_lr = 0;
if (((tmp_tb > 8) && (tmp_lr < -8) &&
(det3d_info.score_3d_tb < -127)) || ((det3d_info.tscore_3d_tb_accum >= 4) &&
(det3d_info.score_3d_tb > 63)))
det3d_info.score_3d_tb = 0;
#if 0 /*mark chessboard 3d detection*/
if ((det3d_info.score_3d_chs > CHESSBOADE_SCORE_LOWER_LIMIT) &&
(det3d_info.score_3d_int < NOT_INTERLACE_SCORE_UPPER_LIMIT)) {
det3d_info.tfw_det3d_fmt = TVIN_TFMT_3D_DET_CHESSBOARD;
det3d_info.score_3d_lr = 0;
det3d_info.score_3d_tb = 0;
} else
#endif
if ((det3d_info.score_3d_int > INTERLACE_SCORE_LOWER_LIMIT) &&
(det3d_info.score_3d_chs < NOT_CHESSBOAD_SCORE_UPPER_LIMIT)) {
det3d_info.tfw_det3d_fmt = TVIN_TFMT_3D_DET_INTERLACE;
det3d_info.score_3d_lr = 0;
det3d_info.score_3d_tb = 0;
} else if ((det3d_info.score_3d_lr > LR_SCORE_LOWER_LIMIT) &&
(det3d_info.score_3d_lr > det3d_info.score_3d_tb)) {
det3d_info.tfw_det3d_fmt = TVIN_TFMT_3D_LRH_OLOR;
} else if ((det3d_info.score_3d_tb > TB_SCORE_LOWER_LIMIT) &&
(det3d_info.score_3d_lr < det3d_info.score_3d_tb)) {
det3d_info.tfw_det3d_fmt = TVIN_TFMT_3D_TB;
} else if ((det3d_info.score_3d_tb < NOT_LR_SCORE_UPPER_LIMIT) &&
(det3d_info.score_3d_lr < NOT_TB_SCORE_UPPER_LIMIT)) {
det3d_info.tfw_det3d_fmt = TVIN_TFMT_2D;
} else{
/* keep previous status */
det3d_info.tfw_det3d_fmt = det3d_info.tfw_det3d_fmt;
if ((det3d_info.score_3d_lr > LR_SCORE_LOWER_LIMIT) &&
(det3d_info.score_3d_tb > TB_SCORE_LOWER_LIMIT)) {
/* if both LR and TB detected, reset the score */
det3d_info.score_3d_lr = 0;
det3d_info.score_3d_tb = 0;
}
}
if (det3d_debug) {
pr_dbg("det3d:frame = %d, 3D_fmt = %d, score_3d_lr = %d,",
det3d_info.nfrm, det3d_info.tfw_det3d_fmt, det3d_info.score_3d_lr);
pr_dbg("score_3d_tb = %d, score_3d_int = %d, score_3d_chs = %d",
det3d_info.score_3d_tb, det3d_info.score_3d_int, det3d_info.score_3d_chs);
}
return det3d_info.tfw_det3d_fmt;
}
module_param(chessbd_vrate, int, 0644);
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");

View File

@@ -0,0 +1,325 @@
/*
* drivers/amlogic/media/deinterlace/detect3d.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 _DET3D_H
#define _DET3D_H
/* ************************************************ */
/* ******** DET3D REGISTERS ******** */
/* ************************************************ */
#define DET3D_BASE_ADD 0x1734
/* #define NR2_SW_EN 0x174f */
#define DET3D_EN_BIT 5
#define DET3D_EN_WID 1
/* #define DET3D_MOTN_CFG 0x1734 */
#define DET3D_INTR_EN_BIT 16
#define DET3D_INTR_EN_WID 1
#define DET3D_MOTION_MODE_BIT 8
#define DET3D_MOTION_MODE_WID 2
#define DET3D_MOTION_CORE_RATE_BIT 4
#define DET3D_MOTION_CORE_RATE_WID 4
#define DET3D_MOTION_CORE_THRD_BIT 0
#define DET3D_MOTION_CORE_THRD_WID 4
/* #define DET3D_CB_CFG 0x1735 */
#define DET3D_CHESSBD_NHV_OFST_BIT 4
#define DET3D_CHESSBD_NHV_OFST_WID 4
#define DET3D_CHESSBD_HV_OFST_BIT 0
#define DET3D_CHESSBD_HV_OFST_WID 4
/* #define DET3D_SPLT_CFG 0x1736 */
#define DET3D_SPLITVALID_RATIO_BIT 4
#define DET3D_SPLITVALID_RATIO_WID 4
#define DET3D_AVGLDX_RATIO_BIT 0
#define DET3D_AVGLDX_RATIO_WID 4
/* #define DET3D_HV_MUTE 0x1737 */
#define DET3D_EDGE_VER_MUTE_BIT 20
#define DET3D_EDGE_VER_MUTE_WID 4
#define DET3D_EDGE_HOR_MUTE_BIT 16
#define DET3D_EDGE_HOR_MUTE_WID 4
#define DET3D_CHESSBD_VER_MUTE_BIT 12
#define DET3D_CHESSBD_VER_MUTE_WID 4
#define DET3D_CHESSBD_HOR_MUTE_BIT 8
#define DET3D_CHESSBD_HOR_MUTE_WID 4
#define DET3D_STA8X8_VER_MUTE_BIT 4
#define DET3D_STA8X8_VER_MUTE_WID 4
#define DET3D_STA8X8_HOR_MUTE_BIT 0
#define DET3D_STA8X8_HOR_MUTE_WID 4
/* #define DET3D_MAT_STA_P1M1 0x1738 */
#define DET3D_STA8X8_P1_K0_R8_BIT 24
#define DET3D_STA8X8_P1_K0_R8_WID 8
#define DET3D_STA8X8_P1_K1_R7_BIT 16
#define DET3D_STA8X8_P1_K1_R7_WID 8
#define DET3D_STA8X8_M1_K0_R6_BIT 8
#define DET3D_STA8X8_M1_K0_R6_WID 8
#define DET3D_STA8X8_M1_K1_R6_BIT 0
#define DET3D_STA8X8_M1_K1_R6_WID 8
/* #define DET3D_MAT_STA_P1TH 0x1739 */
#define DET3D_STAYUV_P1_TH_L4_BIT 16
#define DET3D_STAYUV_P1_TH_L4_WID 8
#define DET3D_STAEDG_P1_TH_L4_BIT 8
#define DET3D_STAEDG_P1_TH_L4_WID 8
#define DET3D_STAMOT_P1_TH_L4_BIT 0
#define DET3D_STAMOT_P1_TH_L4_WID 8
/* #define DET3D_MAT_STA_M1TH 0x173a */
#define DET3D_STAYUV_M1_TH_L4_BIT 16
#define DET3D_STAYUV_M1_TH_L4_WID 8
#define DET3D_STAEDG_M1_TH_L4_BIT 8
#define DET3D_STAEDG_M1_TH_L4_WID 8
#define DET3D_STAMOT_M1_TH_L4_BIT 0
#define DET3D_STAMOT_M1_TH_L4_WID 8
/* #define DET3D_MAT_STA_RSFT 0x173b */
#define DET3D_STAYUV_RSHFT_BIT 4
#define DET3D_STAYUV_RSHFT_WID 2
#define DET3D_STAEDG_RSHFT_BIT 2
#define DET3D_STAEDG_RSHFT_WID 2
#define DET3D_STAMOT_RSHFT_BIT 0
#define DET3D_STAMOT_RSHFT_WID 2
/* #define DET3D_MAT_SYMTC_TH 0x173c */
#define DET3D_STALUM_SYMTC_TH_BIT 24
#define DET3D_STALUM_SYMTC_TH_WID 8
#define DET3D_STACHR_SYMTC_TH_BIT 16
#define DET3D_STACHR_SYMTC_TH_WID 8
#define DET3D_STAEDG_SYMTC_TH_BIT 8
#define DET3D_STAEDG_SYMTC_TH_WID 8
#define DET3D_STAMOT_SYMTC_TH_BIT 0
#define DET3D_STAMOT_SYMTC_TH_WID 8
/* #define DET3D_RO_DET_CB_HOR 0x173d */
#define DET3D_CHESSBD_NHOR_VALUE_BIT 16
#define DET3D_CHESSBD_NHOR_VALUE_WID 16
#define DET3D_CHESSBD_HOR_VALUE_BIT 0
#define DET3D_CHESSBD_HOR_VALUE_WID 16
/* #define DET3D_RO_DET_CB_VER 0x173e */
#define DET3D_CHESSBD_NVER_VALUE_BIT 16
#define DET3D_CHESSBD_NVER_VALUE_WID 16
#define DET3D_CHESSBD_VER_VALUE_BIT 0
#define DET3D_CHESSBD_VER_VALUE_WID 16
/* #define DET3D_RO_SPLT_HT 0x173f */
#define DET3D_SPLIT_HT_VAILID_BIT 24
#define DET3D_SPLIT_HT_VAILID_WID 1
#define DET3D_SPLIT_HT_PXNUM_BIT 16
#define DET3D_SPLIT_HT_PXNUM_WID 5
#define DET3D_SPLIT_HT_IDXX4_BIT 0
#define DET3D_SPLIT_HT_IDXX4_WID 10
/* #define DET3D_RO_SPLT_HB 0x1780 */
#define DET3D_SPLIT_HB_VAILID_BIT 24
#define DET3D_SPLIT_HB_VAILID_WID 1
#define DET3D_SPLIT_HB_PXNUM_BIT 16
#define DET3D_SPLIT_HB_PXNUM_WID 5
#define DET3D_SPLIT_HB_IDXX4_BIT 0
#define DET3D_SPLIT_HB_IDXX4_WID 10
/* #define DET3D_RO_SPLT_VL 0x1781 */
#define DET3D_SPLIT_VL_VAILID_BIT 24
#define DET3D_SPLIT_VL_VAILID_WID 1
#define DET3D_SPLIT_VL_PXNUM_BIT 16
#define DET3D_SPLIT_VL_PXNUM_WID 5
#define DET3D_SPLIT_VL_IDXX4_BIT 0
#define DET3D_SPLIT_VL_IDXX4_WID 10
/* #define DET3D_RO_SPLT_VR 0x1782 */
#define DET3D_SPLIT_VR_VAILID_BIT 24
#define DET3D_SPLIT_VR_VAILID_WID 1
#define DET3D_SPLIT_VR_PXNUM_BIT 16
#define DET3D_SPLIT_VR_PXNUM_WID 5
#define DET3D_SPLIT_VR_IDXX4_BIT 0
#define DET3D_SPLIT_VR_IDXX4_WID 10
/* #define DET3D_RO_MAT_LUMA_LR 0x1783 */
#define DET3D_LUMA_LR_SUM_BIT 24
#define DET3D_LUMA_LR_SUM_WID 5
#define DET3D_LUMA_LR_SYMTC_BIT 16
#define DET3D_LUMA_LR_SYMTC_WID 8
#define DET3D_LUMA_LR_SCORE_BIT 0
#define DET3D_LUMA_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_LUMA_TB 0x1784 */
#define DET3D_LUMA_TB_SUM_BIT 24
#define DET3D_LUMA_TB_SUM_WID 5
#define DET3D_LUMA_TB_SYMTC_BIT 16
#define DET3D_LUMA_TB_SYMTC_WID 8
#define DET3D_LUMA_TB_SCORE_BIT 0
#define DET3D_LUMA_TB_SCORE_WID 16
/* #define DET3D_RO_MAT_CHRU_LR 0x1785 */
#define DET3D_CHRU_LR_SUM_BIT 24
#define DET3D_CHRU_LR_SUM_WID 5
#define DET3D_CHRU_LR_SYMTC_BIT 16
#define DET3D_CHRU_LR_SYMTC_WID 8
#define DET3D_CHRU_LR_SCORE_BIT 0
#define DET3D_CHRU_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_CHRU_TB 0x1786 */
#define DET3D_CHRU_TB_SUM_BIT 24
#define DET3D_CHRU_TB_SUM_WID 5
#define DET3D_CHRU_TB_SYMTC_BIT 16
#define DET3D_CHRU_TB_SYMTC_WID 8
#define DET3D_CHRU_TB_SCORE_BIT 0
#define DET3D_CHRU_TB_SCORE_WID 16
/* #define DET3D_RO_MAT_CHRV_LR 0x1787 */
#define DET3D_CHRV_LR_SUM_BIT 24
#define DET3D_CHRV_LR_SUM_WID 5
#define DET3D_CHRV_LR_SYMTC_BIT 16
#define DET3D_CHRV_LR_SYMTC_WID 8
#define DET3D_CHRV_LR_SCORE_BIT 0
#define DET3D_CHRV_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_CHRV_TB 0x1788 */
#define DET3D_CHRV_TB_SUM_BIT 24
#define DET3D_CHRV_TB_SUM_WID 5
#define DET3D_CHRV_TB_SYMTC_BIT 16
#define DET3D_CHRV_TB_SYMTC_WID 8
#define DET3D_CHRV_TB_SCORE_BIT 0
#define DET3D_CHRV_TB_SCORE_WID 16
/* #define DET3D_RO_MAT_HEDG_LR 0x1789 */
#define DET3D_HEDG_LR_SUM_BIT 24
#define DET3D_HEDG_LR_SUM_WID 5
#define DET3D_HEDG_LR_SYMTC_BIT 16
#define DET3D_HEDG_LR_SYMTC_WID 8
#define DET3D_HEDG_LR_SCORE_BIT 0
#define DET3D_HEDG_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_HEDG_TB 0x178a */
#define DET3D_HEDG_TB_SUM_BIT 24
#define DET3D_HEDG_TB_SUM_WID 5
#define DET3D_HEDG_TB_SYMTC_BIT 16
#define DET3D_HEDG_TB_SYMTC_WID 8
#define DET3D_HEDG_TB_SCORE_BIT 0
#define DET3D_HEDG_TB_SCORE_WID 16
/* #define DET3D_RO_MAT_VEDG_LR 0x178b */
#define DET3D_VEDG_LR_SUM_BIT 24
#define DET3D_VEDG_LR_SUM_WID 5
#define DET3D_VEDG_LR_SYMTC_BIT 16
#define DET3D_VEDG_LR_SYMTC_WID 8
#define DET3D_VEDG_LR_SCORE_BIT 0
#define DET3D_VEDG_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_VEDG_TB 0x178c */
#define DET3D_VEDG_TB_SUM_BIT 24
#define DET3D_VEDG_TB_SUM_WID 5
#define DET3D_VEDG_TB_SYMTC_BIT 16
#define DET3D_VEDG_TB_SYMTC_WID 8
#define DET3D_VEDG_TB_SCORE_BIT 0
#define DET3D_VEDG_TB_SCORE_WID 16
/* #define DET3D_RO_MAT_MOTN_LR 0x178d */
#define DET3D_MOTN_LR_SUM_BIT 24
#define DET3D_MOTN_LR_SUM_WID 5
#define DET3D_MOTN_LR_SYMTC_BIT 16
#define DET3D_MOTN_LR_SYMTC_WID 8
#define DET3D_MOTN_LR_SCORE_BIT 0
#define DET3D_MOTN_LR_SCORE_WID 16
/* #define DET3D_RO_MAT_MOTN_TB 0x178e */
#define DET3D_MOTN_TB_SUM_BIT 24
#define DET3D_MOTN_TB_SUM_WID 5
#define DET3D_MOTN_TB_SYMTC_BIT 16
#define DET3D_MOTN_TB_SYMTC_WID 8
#define DET3D_MOTN_TB_SCORE_BIT 0
#define DET3D_MOTN_TB_SCORE_WID 16
/* #define DET3D_RO_FRM_MOTN 0x178f */
#define DET3D_FRAME_MOTION_BIT 0
#define DET3D_FRAME_MOTION_WID 16
/* #define DET3D_RAMRD_ADDR_PORT 0x179a */
/* #define DET3D_RAMRD_DATA_PORT 0x179b */
/* *********************************************************** */
/* *** STRUCTURE DEFINATIONS ********************************* */
/* *********************************************************** */
struct det3d_info_s {
/* Frame counter, max number is defined in FRAME_MAX macro */
int nfrm;
/* 3D format */
int tfw_det3d_fmt;
/* signed number, when the score is close to 0,
* it is means we can not confirm if input is LR format;
*/
/* the smaller this score is (when < 0),
* the more likely input is not LR format;
*/
/* the larger this score is (when > 0),
* the more likely input is LR format;
*/
int score_3d_lr;
int score_3d_tb;
/* the last 8 frame score_3d_lr, tscore_3d_lr[0]
* is caculated from current frame data;
*/
int tscore_3d_lr[8];
int tscore_3d_tb[8];
int tscore_3d_lr_accum;
int tscore_3d_tb_accum;
int score_3d_chs;
int score_3d_int;
/* the last 8 frame valid score_3d_chs, chs_valid_his[0]
* is caculated from current frame data;
*/
int chs_valid_his[8];
int int_valid_his[8];
};
#define det3d_info_t struct det3d_info_s
/* **************************************** */
/* ****ENUM DEFINATIONS ******************* */
/* **************************************** */
/*@to modify if it is defined in tvin.h*/
enum det3d_fmt_e {
DET3D_FMT_NULL = 0,
DET3D_FMT_LR,
DET3D_FMT_TB,
DET3D_FMT_INTERLACE,
DET3D_FMT_CHESSBOARD,
};
#define det3d_fmt_t enum det3d_fmt_e
/* *************************************** */
/* ******** GLOBAL FUNCTION CLAIM ******** */
/* *************************************** */
extern void det3d_enable(bool flag);
extern enum tvin_trans_fmt det3d_fmt_detect(void);
#define WRITE_DET3D_REG(x, val) aml_write_vcbus(x, val)
#define WRITE_DET3D_REG_BITS(x, val, start, length) \
aml_vcbus_update_bits(x, ((1<<(length))-1)<<(start), val)
#define READ_DET3D_REG(x) aml_read_vcbus(x)
#define READ_DET3D_REG_BITS(x, start, length) \
(aml_read_vcbus(x)&(((1<<(length))-1)<<(start)))
#endif /* _DET3D_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
/*
* drivers/amlogic/media/deinterlace/film_vof_soft.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 _FLMVOFSFT_H_
#define _FLMVOFSFT_H_
/* Film Detection and VOF detection Software implementation */
/* Designer: Xin.Hu@amlogic.com */
/* Date: 12/06/13 */
/* Difference Windows Number (Last one is the global/total dif) */
/* 5wind+global */
/* #define DIFWNDNUM 6 */
#define HISDIFNUM 10
#define HISCMBNUM 10
/* detection history information */
#define HISDETNUM 6
/* The number of VOF window */
#define VOFWNDNUM 4
#define PDXX_PT_NUM 7
/* 288Row, 1bit/row -> (288/32)=9 */
#define ROWCMBNUM 288
#define ROWCMBLEN 9
#ifndef UINT32
#define UINT32 unsigned int
#endif
#ifndef UINT8
#define UINT8 unsigned char
#endif
#ifndef UShort
#define UShort unsigned short
#endif
extern uint pr_pd;
extern bool prt_flg;
extern char debug_str[];
/* Software: Film Detection and VOF parameters */
struct sFlmDatSt {
UINT8 pFlg32[HISDETNUM]; /* history information */
UINT8 pMod32[HISDETNUM];
UINT8 mNum32[HISDETNUM];
UINT8 pFld32[HISDETNUM];
UINT8 pFrm32[HISDETNUM];
UINT8 pFrm32t[HISDETNUM]; /* history information: spacial processing */
UINT8 pFlg22[HISDETNUM];
UINT8 pMod22[HISDETNUM];
UINT8 mNum22[HISDETNUM];
UINT8 pStp22[HISDETNUM];
UINT8 pSmp22[HISDETNUM];
UINT8 pModXx[HISDETNUM]; /* mode */
UINT8 pFlgXx[HISDETNUM]; /* pre-1, nxt-0 */
UINT8 pLvlXx[HISDETNUM]; /* mode level */
int TCNm[HISCMBNUM];/* history: the number of combing-rows */
UINT32 *rROFrmDif02;
/* size of the image */
int iHeight;
int iWidth;
};
/* Software parameters */
struct sFlmSftPar {
/* software */
int sFrmDifAvgRat; /* 16; //0~32 */
/* 4096; //The Large Decision should be: (large>average+LgDifThrd) */
int sFrmDifLgTDif;
int sF32StpWgt01; /* 15; */
int sF32StpWgt02; /* 15; */
int sF32DifLgRat; /* 16; //Dif>Rat*Min --> Larger */
int sFlm2MinAlpha; /* = 32; // [0~63] */
int sFlm2MinBelta; /* = 32; // [0~63] */
int sFlm20ftAlpha; /* = 16; // [0~63] */
int sFlm2LgDifThd; /* = 4096; // [0~63] %LgDifThrd */
int sFlm2LgFlgThd; /* = 8; */
int sF32Dif01A1; /* 65; */
int sF32Dif01T1; /* 128; */
int sF32Dif01A2; /* 65; */
int sF32Dif01T2; /* 128; */
int rCmbRwMinCt0; /* 8; //for film 3-2 */
int rCmbRwMinCt1; /* =7; //for film 2-2 */
UINT8 sFlm32NCmb; /* absolute no combing for film 32 */
/* pre-processing (t-0), post-processing f(t-mPstDlyPre); // No RTL */
int mPstDlyPre;
/* pre-processing (t-0), pre-processing f(t+mNxtDlySft); default=1 */
int mNxtDlySft;
UINT32 sF32Dif02M0; /* mpeg-4096, cvbs-8192 */
UINT32 sF32Dif02M1; /* mpeg-4096, cvbs-8192 */
};
struct FlmModReg_t {
UINT32 rROFrmDif02[6]; /* Read only */
UINT32 rROFldDif01[6]; /* Read only */
UINT32 rROCmbInf[9];/* Inf[0]-[31:0], First-[31], Lst-[0] (Only 0/1) */
};
struct FlmDectRes {
UINT8 rCmb32Spcl;
UINT8 rFlmPstGCm;
UINT8 rFlmSltPre;
UINT8 rFlmPstMod;
UShort rPstCYWnd0[3];
UShort rPstCYWnd1[3];
UShort rPstCYWnd2[3];
UShort rPstCYWnd3[3];
UShort rPstCYWnd4[3];
UShort rF22Flag;
};
UINT8 FlmVOFSftInt(struct sFlmSftPar *pPar);
/* Get 1-Row combing information, 1bit */
/* iHSCMB[9]; 9x32=288 */
UINT8 Get1RCmb(UINT32 *iHSCMB, UINT32 iRow);
int FlmModsDet(struct sFlmDatSt *pRDat, int nDif01, int nDif02);
/* */
int FlmVOFSftTop(UINT8 *rCmb32Spcl, UShort *rPstCYWnd0, UShort *rPstCYWnd1,
UShort *rPstCYWnd2, UShort *rPstCYWnd3, UShort *rPstCYWnd4,
UINT8 *rFlmPstGCm, UINT8 *rFlmSltPre, UINT8 *rFlmPstMod,
UINT32 *rROFldDif01, UINT32 *rROFrmDif02, UINT32 *rROCmbInf,
UINT32 glb_frame_mot_num, UINT32 glb_field_mot_num, int *tTCNm,
struct sFlmSftPar *pPar, int nROW, int nCOL,
unsigned int *frame_diff_avg);
/* length of pFlm01/nDif01: [0:5]; */
/* iDx: index of minimum dif02 ([0:5] */
int Cal32Flm01(UINT8 *pFlm01, int *nDif01, int iDx, struct sFlmSftPar *pPar);
/* Film Detection Software implementation */
/* nDif01: Fild Difference */
/* nDif02: Frame Difference */
/* WND: The index of Window */
int FlmDetSft(struct sFlmDatSt *pRDat, int *nDif01, int *nDif02, int WND,
struct sFlmSftPar *pPar);
int VOFDetSub1(int *PREWV, int *nCNum, int nMod, UINT32 *nRCmb, int nROW,
struct sFlmSftPar *pPar);
/* Video on Film Detection Software implementaion */
int VOFDetSft(int *VOFWnd, int *nCNum, int *nGCmb,
UINT32 HSCMB[HISCMBNUM][ROWCMBLEN], int nMod, UINT8 *PREWV,
int nROW, struct sFlmSftPar *pPar);
/* */
int Flm32DetSft(struct sFlmDatSt *pRDat, int *nDif02, int *nDif01,
struct sFlmSftPar *pPar);
/* Film2-2 Detection */
int Flm22DetSft(struct sFlmDatSt *pRDat, int *nDif02,
int *nDif01, struct sFlmSftPar *pPar);
/* length: [0:5] */
/* MIX: [1~5] */
int Flm32DetSub1(struct sFlmDatSt *pRDat, UINT8 *nFlg12, UINT8 *pFlm02t,
UINT8 *nFlg01, UINT8 *nFlg02, UINT8 MIX);
int VOFSftTop(UINT8 *rFlmPstGCm, UINT8 *rFlmSltPre, UINT8 *rFlmPstMod,
UShort *rPstCYWnd0, UShort *rPstCYWnd1, UShort *rPstCYWnd2,
UShort *rPstCYWnd3, int nMod, UINT32 *rROCmbInf,
struct sFlmDatSt *pRDat, struct sFlmSftPar *pPar,
int nROW, int nCOL);
extern UINT32 field_count;
#endif

View File

@@ -0,0 +1,538 @@
/*
* drivers/amlogic/media/deinterlace/flm_mod_xx.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/module.h>
#include "film_vof_soft.h"
/* dif02 < (size >> sft) => static */
int flm2224_stl_sft = 7; /*10*/
module_param(flm2224_stl_sft, int, 0644);
MODULE_PARM_DESC(flm2224_stl_sft, "flm2224_stl_sft");
int aMax02[15]; /* maximum 4 */
int aXId02[15];
int aMin02[15]; /* minimum 4 */
int aNId02[15];
int aXMI02[15];
int GetMaxNIdx(int *nMax4, int *nXId4, int N, int *nQt01, int nLen)
{
int nT1 = 0;
int nT3 = 0;
int nT4 = 0;
int nTmp = 0;
for (nT1 = 0; nT1 < N; nT1++) {
nMax4[nT1] = 0;
nXId4[nT1] = 0;
}
for (nT1 = 0; nT1 < nLen; nT1++) {
nTmp = nQt01[nT1];
/* maximum */
for (nT3 = 0; nT3 < N; nT3++) {
if (nTmp > nMax4[nT3]) {
for (nT4 = 3; nT4 >= nT3+1; nT4--) {
nMax4[nT4] = nMax4[nT4-1];
nXId4[nT4] = nXId4[nT4-1];
}
nMax4[nT3] = nTmp;
nXId4[nT3] = nT1;
break;
}
}
}
return 0;
}
int GetMinNIdx(int *nMax4, int *nXId4, int N, int *nQt01, int nLen)
{
int nT1 = 0;
int nT3 = 0;
int nT4 = 0;
int nTmp = 0;
for (nT1 = 0; nT1 < N; nT1++) {
nMax4[nT1] = 17;
nXId4[nT1] = 0;
}
for (nT1 = 0; nT1 < nLen; nT1++) {
nTmp = nQt01[nT1];
/* minimum */
for (nT3 = 0; nT3 < N; nT3++) {
if (nTmp < nMax4[nT3]) {
for (nT4 = 3; nT4 >= nT3+1; nT4--) {
nMax4[nT4] = nMax4[nT4-1];
nXId4[nT4] = nXId4[nT4-1];
}
nMax4[nT3] = nTmp;
nXId4[nT3] = nT1;
break;
}
}
}
return 0;
}
/* 15: 8-7 */
/* 12: 3-2-3-2-2 */
/* 10: 6-4 */
/* 10: 5-5 */
/* 10: 2-2-2-4 */
/* 10: 2-3-3-2 */
/* 10: 3-2-3-2 */
/* pulldown pattern number */
int FlmModsDet(struct sFlmDatSt *pRDat, int nDif01, int nDif02)
{
int iWidth = pRDat->iWidth;
int iHeight = pRDat->iHeight;
int iSIZE = (iWidth * iHeight);
int iMxDif = (iSIZE >> 6);
int nPrtLog[PDXX_PT_NUM] = {87, 32322, 64, 55, 2224, 2332, 3232};
/* HISDETNUM hist */
UINT8 *pModXx = pRDat->pModXx;
UINT8 *pFlgXx = pRDat->pFlgXx; /* pre-1, nxt-0 */
UINT8 *pLvlXx = pRDat->pLvlXx; /* mode level */
static unsigned int sModFlg01[PDXX_PT_NUM]; /* flags */
static unsigned int sModFlg02[PDXX_PT_NUM]; /* flags */
static int nModCnt[PDXX_PT_NUM]; /* mode counter */
unsigned int tModFlg01[PDXX_PT_NUM]; /* current flags */
unsigned int tModFlg02[PDXX_PT_NUM]; /* current flags */
int nMxMn[PDXX_PT_NUM][2] = { {2, 4}, {-2, -2}, {2, 4},
{2, 4}, {4, -2}, {4, -2}, {4, -2} };
int nModLvl[PDXX_PT_NUM] = {0, 0, 0, 0, 0, 0, 0}; /* mode level */
int nQt01[15];
int nQt02[15];
int aMax01[15]; /* maximum 4 */
int aXId01[15];
int aMin01[15]; /* minimum 4 */
int aNId01[15];
int aXMI01[15];
int nT0 = 0;
int nT1 = 0;
int nT2 = 0;
int nT3 = 0;
int nT4 = 0;
int tT0 = 0;
int tT1 = 0;
int tT2 = 0;
int tT3 = 0;
unsigned int uT01 = 0;
unsigned int uT02 = 0;
unsigned int uT03 = 0;
int nS01[PDXX_PT_NUM] = {0, 0, 0, 0, 0, 0, 0};
int nS02[PDXX_PT_NUM] = {0, 0, 0, 0, 0, 0, 0};
int nStp[PDXX_PT_NUM] = {15, 12, 10, 10, 10, 10};
static int pDif01[30];
static int pDif02[30];
int nLen1 = 0;
int nLen2 = 0;
int nMin01 = 0;
int nMax01 = 0;
int nMin02 = 0;
int nMax02 = 0;
int tModLvl = 0;
iMxDif = (iMxDif >> 4) + 1;
prt_flg = ((pr_pd >> 4) & 0x1);
if (prt_flg)
sprintf(debug_str, "#DbgXx:\n");
for (nT0 = 1; nT0 < HISDETNUM; nT0++) {
pFlgXx[nT0 - 1] = pFlgXx[nT0];
pLvlXx[nT0 - 1] = pLvlXx[nT0];
pModXx[nT0 - 1] = pModXx[nT0];
}
for (nT0 = 0; nT0 < 29; nT0++) {
pDif01[nT0] = pDif01[nT0 + 1];
pDif02[nT0] = pDif02[nT0 + 1];
}
pDif01[29] = (nDif01 >> 6);
pDif02[29] = (nDif02 >> 6);
for (nT0 = 0; nT0 < 3; nT0++) {
nT2 = nStp[nT0];
nT3 = pDif01[29];
nT4 = pDif02[29];
nMin01 = nT3;
nMax01 = nT3;
nMin02 = nT4;
nMax02 = nT4;
nT3 = pDif01[29] - pDif01[29 - nT2];
nT4 = pDif02[29] - pDif02[29 - nT2];
if (nT3 < 0)
nT3 = -nT3;
if (nT4 < 0)
nT4 = -nT4;
nS01[nT0] = nT3;
nS02[nT0] = nT4;
/* nS01, nS02: sum of difference */
for (nT1 = 1; nT1 < nT2; nT1++) {
nT3 = pDif01[29 - nT1];
nT4 = pDif02[29 - nT1];
if (nT3 > nMax01)
nMax01 = nT3;
if (nT3 < nMin01)
nMin01 = nT3;
if (nT4 > nMax02)
nMax02 = nT4;
if (nT4 < nMin02)
nMin02 = nT4;
/* diff max */
nT3 = pDif01[29 - nT1] - pDif01[29 - nT1 - nT2];
nT4 = pDif02[29 - nT1] - pDif02[29 - nT1 - nT2];
if (nT3 < 0)
nT3 = -nT3;
if (nT4 < 0)
nT4 = -nT4;
if (nT3 > nS01[nT0])
nS01[nT0] = nT3;
if (nT4 > nS02[nT0])
nS02[nT0] = nT4;
}
for (nT1 = 0; nT1 < nT2; nT1++) {
nT3 = pDif01[29 - nT1] - nMin01;
nT4 = nMax01 - nMin01 + 32;
nT3 = (16 * nT3) + (nT4 / 2);
nQt01[nT1] = (nT3 / nT4);
nT3 = pDif02[29 - nT1] - nMin02;
nT4 = nMax02 - nMin02 + 32;
nT3 = (16 * nT3) + (nT4 / 2);
nQt02[nT1] = (nT3 / nT4);
}
if (nT0 == 2)
tT2 = PDXX_PT_NUM - 2;
else
tT2 = 1;
for (tT1 = 0; tT1 < tT2; tT1++) {
tT0 = nT0 + tT1;
tModLvl = ((nModCnt[tT0] + 2) >> 2);
if (tModLvl > 64)
tModLvl = 64;
if (nS01[nT0] > nMax01)
nT3 = 8;
else {
nT3 = (nS01[nT0] << 3);
nT3 = nT3 + (nMax01 >> 1);
nT3 = nT3 / (nMax01 + 1);
if (nT3 > 8)
nT3 = 8;
}
tModLvl -= nT3;
if (nS02[nT0] > nMax02)
nT4 = 8;
else {
nT4 = (nS02[nT0] << 3);
nT4 = nT4 + (nMax02 >> 1);
nT4 = nT4 / (nMax02 + 1);
if (nT4 > 8)
nT4 = 8;
}
tModLvl -= nT4;
if (nMxMn[tT0][0] > 0) {
nLen1 = nMxMn[tT0][0];
GetMaxNIdx(aMax01, aXId01, nLen1, nQt01, nT2);
nT4 = 0;
for (tT3 = 0; tT3 < nLen1; tT3++) {
aXMI01[tT3] = aXId01[tT3];
nT4 += (16 - aMax01[tT3]);
}
nT4 /= nLen1;
tModLvl -= nT4;
} else {
nLen1 = -nMxMn[tT0][0];
GetMinNIdx(aMin01, aNId01, nLen1, nQt01, nT2);
nT4 = 0;
for (tT3 = 0; tT3 < nLen1; tT3++) {
aXMI01[tT3] = aNId01[tT3];
nT4 += aMin01[tT3];
}
nT4 /= nLen1;
tModLvl -= nT4;
}
if (nMxMn[tT0][1] > 0) {
nLen2 = nMxMn[tT0][1];
GetMaxNIdx(aMax02, aXId02, nLen2, nQt02, nT2);
nT4 = 0;
for (tT3 = 0; tT3 < nLen2; tT3++) {
aXMI02[tT3] = aXId02[tT3];
nT4 += (16 - aMax02[tT3]);
}
nT4 /= nLen1;
tModLvl -= nT4;
} else {
nLen2 = -nMxMn[tT0][1];
GetMinNIdx(aMin02, aNId02, nLen2, nQt02, nT2);
nT3 = 0;
nT4 = 0;
for (tT3 = 0; tT3 < nLen2; tT3++) {
aXMI02[tT3] = aNId02[tT3];
nT4 += aMin02[tT3];
nT3 = pDif02[29 - aNId02[tT3]];
if (nT3 > iMxDif)
nT4 += 8;
else {
nT3 = (nT3 << 3) +
(iMxDif >> 1);
nT3 /= (iMxDif + 1);
nT4 += nT3;
}
}
nT4 /= (2 * nLen2);
tModLvl -= nT4;
}
tModFlg01[tT0] = 0;
for (tT3 = 0; tT3 < nLen1; tT3++)
tModFlg01[tT0] |= (1 << aXMI01[tT3]);
tModFlg02[tT0] = 0;
for (tT3 = 0; tT3 < nLen2; tT3++)
tModFlg02[tT0] |= (1 << aXMI02[tT3]);
uT03 = (1 << nT2) - 1;
tModFlg01[tT0] &= uT03;
tModFlg02[tT0] &= uT03;
uT01 = (sModFlg01[tT0] << 1);
uT01 |= (uT01 >> nT2);
uT01 &= uT03;
uT02 = (sModFlg02[tT0] << 1);
uT02 |= (uT02 >> nT2);
uT02 &= uT03;
/* minimum check */
nLen2 = 0;
if (tT0 == 0) { /* 8-7 */
nLen2 = 11;
} else if (tT0 == 2) { /* 6-4 */
nLen2 = 6;
} else if (tT0 == 3) { /* 5-5 */
nLen2 = 6;
}
if (nLen2 > 0) {
GetMinNIdx(aMin02, aNId02, nLen2, nQt02, nT2);
nT4 = 0;
for (tT3 = 0; tT3 < nLen2; tT3++) {
nT3 = pDif02[29 - aNId02[tT3]];
if (nT3 > iMxDif)
nT4 += 8;
else {
nT3 = (nT3 << 3)
+ (iMxDif >> 1);
nT3 /= (iMxDif + 1);
nT4 += nT3;
}
}
nT4 /= nLen2;
tModLvl -= nT4;
}
if (nMin02 > iMxDif) {
tModLvl -= 16;
nModCnt[tT0] = 0;
} else {
nT4 = (nMin02 << 4);
nT4 = nT4 / iMxDif;
tModLvl -= nT4;
}
/*
* nT4 = (nMin02 << 6) + (iMxDif >> 1);
* nT4 = nT4 / iMxDif;
* if (nModCnt[tT0] > nT4)
* nModCnt[tT0] -= nT4;
* else
* nModCnt[tT0] = 0;
*/
/* Distance between maximum-2 dif01*/
if (aXMI01[1] > aXMI01[0])
nT3 = aXMI01[1] - aXMI01[0];
else
nT3 = aXMI01[0] - aXMI01[1];
/* Distance between minimium-2 dif02 */
if (aXMI02[1] > aXMI02[0])
nT4 = aXMI02[1] - aXMI02[0];
else
nT4 = aXMI02[0] - aXMI02[1];
if ((uT01 == tModFlg01[tT0]) &&
(uT02 == tModFlg02[tT0]) &&
(nT3 > 0) && (uT01 > 0) &&
(uT02 > 0)) {
if (tT0 == 0) {
if (nT3 == 7 || nT3 == 8) {
nModCnt[tT0] += 1;
tModLvl += 2;
} else
nModCnt[tT0] = 0;
} else if (tT0 == 2) {
if (nT3 == 4 || nT3 == 6) {
nModCnt[tT0] += 1;
tModLvl += 2;
} else
nModCnt[tT0] = 0;
} else if (tT0 == 3) {
if (nT3 == 5) {
nModCnt[tT0] += 1;
tModLvl += 2;
} else
nModCnt[tT0] = 0;
}
}
if ((uT02 == tModFlg02[tT0]) &&
(nT4 > 0) && (uT02 > 0)) {
if ((uT01 == tModFlg01[tT0]) && (uT01 > 0))
tModLvl += 1;
if (tT0 == 1) {
if (nT4 == 5 || nT4 == 7) {
nModCnt[tT0] += 1;
tModLvl += 1;
} else
nModCnt[tT0] = 0;
} else if (tT0 == 4) {
if (nT4 == 1 || nT4 == 9) {
nModCnt[tT0] += 1;
tModLvl += 1;
} else
nModCnt[tT0] = 0;
} else if (tT0 == 5) {
if (nT4 == 3 || nT4 == 7) {
nModCnt[tT0] += 1;
tModLvl += 1;
} else
nModCnt[tT0] = 0;
} else if (tT0 == 6) {
if (nT4 == 5) {
nModCnt[tT0] += 1;
tModLvl += 1;
} else
nModCnt[tT0] = 0;
}
}
if (nModCnt[tT0] > 254)
nModCnt[tT0] = 254;
if (tModLvl < 0)
tModLvl = 0;
nModLvl[tT0] = tModLvl;
sModFlg01[tT0] = tModFlg01[tT0];
sModFlg02[tT0] = tModFlg02[tT0];
} /* 2-3-4-5*/
}
tModLvl = nModLvl[0];
nT1 = 0;
for (nT0 = 1; nT0 < PDXX_PT_NUM; nT0++) {
if (nModLvl[nT0] > tModLvl) {
tModLvl = nModLvl[nT0];
nT1 = nT0;
}
}
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"nMax02(10)=%4d < (%4d)\n",
nMax02, (iSIZE >> flm2224_stl_sft));
if ((nT1 == 4) &&
(nMax02 <= (iSIZE >> flm2224_stl_sft)))
nModCnt[nT1] = 0;
pModXx[HISDETNUM - 1] = nT1;
pLvlXx[HISDETNUM - 1] = tModLvl;
pFlgXx[HISDETNUM - 1] = (pDif01[29] < pDif01[28]);
/* recheck */
if ((pFlgXx[HISDETNUM - 2] == 0) &&
(pDif01[29] > pDif01[28]))
pFlgXx[HISDETNUM - 2] = 1;
if (prt_flg && tModLvl > 0) {
sprintf(debug_str + strlen(debug_str),
"#FM%5d detected ct(%3d) lvl(%2d)\n",
nPrtLog[nT1], nModCnt[nT1], nModLvl[nT1]);
if (pDif01[29] < pDif01[28])
sprintf(debug_str + strlen(debug_str),
"#Pre: A<-A\n");
else
sprintf(debug_str + strlen(debug_str),
"#Nxt: A B->\n");
}
if (prt_flg) {
sprintf(debug_str + strlen(debug_str),
"Mod=%5d, Flg=%d, Lvl=%3d\n",
nT1, pFlgXx[HISDETNUM - 1],
tModLvl);
pr_info("%s", debug_str);
}
return nT1;
}

View File

@@ -0,0 +1,602 @@
/*
* drivers/amlogic/media/deinterlace/nr.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/amlogic/iomap.h>
#include "register.h"
#include "nr.h"
#include "deinterlace.h"
static DNR_PRM_t dnr_param;
static DNR_PRM_t *pDnrPrm = &dnr_param;
static bool dnr_pr;
module_param(dnr_pr, bool, 0644);
MODULE_PARM_DESC(dnr_pr, "/n print dnr debug information /n");
bool dnr_dm_en;/*gxtvbb can't work normal,must set to 0*/
module_param(dnr_dm_en, bool, 0644);
MODULE_PARM_DESC(dnr_dm_en, "/n dnr dm enable debug /n");
bool dnr_reg_update = 1;/*gxtvbb can't work normal,must set to 0*/
module_param(dnr_reg_update, bool, 0644);
MODULE_PARM_DESC(dnr_reg_update, "/n dnr dm enable debug /n");
static unsigned int dnr_stat_coef = 3;/*gxtvbb default is 3*/
module_param(dnr_stat_coef, uint, 0644);
MODULE_PARM_DESC(dnr_stat_coef, "/n dnr stat coef /n");
static int dnr_prm_init(DNR_PRM_t *pPrm)
{
pPrm->prm_sw_gbs_ctrl = 0;
/* 0: update gbs, 1: update hoffst & gbs,
* 2: update voffst & gbs, 3: update all (hoffst & voffst & gbs).
*/
pPrm->prm_gbs_vldcntthd = 4;
pPrm->prm_gbs_cnt_min = 32;
pPrm->prm_gbs_ratcalcmod = 1;/* 0: use LR, 1: use Dif */
pPrm->prm_gbs_ratthd[0] = 40;
pPrm->prm_gbs_ratthd[1] = 80;
pPrm->prm_gbs_ratthd[2] = 120;
pPrm->prm_gbs_difthd[0] = 25;
pPrm->prm_gbs_difthd[1] = 75;
pPrm->prm_gbs_difthd[2] = 125;
pPrm->prm_gbs_bsdifthd = 1;
pPrm->prm_gbs_calcmod = 1; /* 0:dif0, 1:dif1, 2: dif2 */
pPrm->sw_gbs = 0;
pPrm->sw_gbs_vld_flg = 0;
pPrm->sw_gbs_vld_cnt = 0;
pPrm->prm_hbof_minthd = 32;
pPrm->prm_hbof_ratthd0 = 150;
pPrm->prm_hbof_ratthd1 = 150;
pPrm->prm_hbof_vldcntthd = 4;
pPrm->sw_hbof = 0;
pPrm->sw_hbof_vld_flg = 0;
pPrm->sw_hbof_vld_cnt = 0;
pPrm->prm_vbof_minthd = 32;
pPrm->prm_vbof_ratthd0 = 150;
pPrm->prm_vbof_ratthd1 = 120;
pPrm->prm_vbof_vldcntthd = 4;
pPrm->sw_vbof = 0;
pPrm->sw_vbof_vld_flg = 0;
pPrm->sw_vbof_vld_cnt = 0;
return 0;
}
int global_bs_calc_sw(int *pGbsVldCnt,
int *pGbsVldFlg,
int *pGbs,
int nGbsStatLR,
int nGbsStatLL,
int nGbsStatRR,
int nGbsStatDif,
int nGbsStatCnt,
int prm_gbs_vldcntthd, /* prm below */
int prm_gbs_cnt_min,
int prm_gbs_ratcalcmod,
int prm_gbs_ratthd[3],
int prm_gbs_difthd[3],
int prm_gbs_bsdifthd,
int prm_gbs_calcmod)
{
int nMax, nMin;
int nDif0, nDif1, nDif2;
int nDif, nRat;
int nCurGbs;
nMax = max(max(nGbsStatLR, nGbsStatLL), nGbsStatRR);
nMin = min(min(nGbsStatLR, nGbsStatLL), nGbsStatRR);
nDif0 = nMax == 0 ? 0 : ((nMax - nMin) << 9)/nMax;
nDif0 = min(511, nDif0);
nDif1 = nGbsStatLR == 0 ? 0 :
(abs(nGbsStatLR - (nGbsStatLL + nGbsStatRR)/2) << 9)/nGbsStatLR;
nDif1 = min(511, nDif1);
nDif2 = nGbsStatLR == 0 ? 0 :
(abs(nGbsStatLR - max(nGbsStatLL, nGbsStatRR)) << 9)/nGbsStatLR;
nDif2 = min(511, nDif2);
if (prm_gbs_ratcalcmod == 0)
nRat = (nGbsStatLR << 4) / max(prm_gbs_cnt_min, nGbsStatCnt);
else
nRat = (nGbsStatDif << 4) / max(prm_gbs_cnt_min, nGbsStatCnt);
nDif = (prm_gbs_calcmod == 0) ? nDif0 :
(prm_gbs_calcmod == 1 ? nDif1 : nDif2);
if (nGbsStatLR < max(nGbsStatLL, nGbsStatRR)) {
if (nGbsStatCnt <= prm_gbs_cnt_min || nRat <= prm_gbs_ratthd[0])
nCurGbs = 0;
else if (nRat <= prm_gbs_ratthd[1])
nCurGbs = 1;
else if (nRat <= prm_gbs_ratthd[2])
nCurGbs = 2;
else
nCurGbs = 3;
} else {
if (nGbsStatCnt <= prm_gbs_cnt_min || nDif <= prm_gbs_difthd[0])
nCurGbs = 0;
else if (nDif <= prm_gbs_difthd[1])
nCurGbs = 1;
else if (nDif <= prm_gbs_difthd[2])
nCurGbs = 2;
else
nCurGbs = 3;
}
/* */
if ((nCurGbs != 0 && 0 == *pGbs) ||
(nCurGbs != 0 && abs(nCurGbs - *pGbs) <= prm_gbs_bsdifthd))
(*pGbsVldCnt)++;
else
*pGbsVldCnt = 0;
if (*pGbsVldCnt >= prm_gbs_vldcntthd)
*pGbsVldFlg = 1;
else
*pGbsVldFlg = 0;
*pGbs = nCurGbs;
/* print debug info. */
/* printk("GBS info at Field: LR = %6d, LL = %6d, RR = %6d.\n",
* nGbsStatLR, nGbsStatLL, nGbsStatRR;
*/
return 0;
}
#ifdef DNR_HV_SHIFT
int hor_blk_ofst_calc_sw(int *pHbOfVldCnt,
int *pHbOfVldFlg,
int *pHbOfst,
int nHbOfStatCnt[32],
int nXst,
int nXed,
int prm_hbof_minthd,
int prm_hbof_ratthd0,
int prm_hbof_ratthd1,
int prm_hbof_vldcntthd,
int nRow,
int nCol)
{
int i = 0;
int nCurHbOfst = 0;
int nRat0 = 0, nRat1 = 0;
int nMax1 = 0;
int nMax2 = 0;
int nMaxIdx = 0;
/* get 2 maximum, move to RTL part */
nMax1 = nMax2 = 0;
for (i = 0; i < 8; i++) {
if (nHbOfStatCnt[i] > nMax1) {
nMax2 = nMax1;
nMax1 = nHbOfStatCnt[i];
nMaxIdx = i;
} else if (nHbOfStatCnt[i] > nMax2) {
nMax2 = nHbOfStatCnt[i];
}
} /* i */
/* decide if offset valid */
nCurHbOfst = -1;
nRat0 = 256*nMax1/((nXed - nXst)/8)/nRow;
nRat1 = 128*nMax1/max(nMax2, prm_hbof_minthd);
if (nRat0 >= prm_hbof_ratthd0 && nRat1 >= prm_hbof_ratthd1)
nCurHbOfst = (nMaxIdx+1)%8;
if (nCurHbOfst == *pHbOfst)
(*pHbOfVldCnt)++;
else
*pHbOfVldCnt = 0;
if (*pHbOfVldCnt >= prm_hbof_vldcntthd)
*pHbOfVldFlg = 1;
else
*pHbOfVldFlg = 0;
*pHbOfst = (nCurHbOfst == -1) ? 0 : nCurHbOfst;
/* print for debug
* printk("Hoff info at Field: ");
* for ( i = 0; i < 32; i++ ) {
* printk("%5d, ", nHbOfStatCnt[i]);
* }
*/
if (dnr_pr) {
pr_dbg("Max1 = %5d, Max2 = %5d, MaxIdx = %5d, Rat0 = %5d,Rat1 = %5d.\n",
nMax1, nMax2, nMaxIdx, nRat0, nRat1);
pr_dbg("CurHbOfst = %5d, HbOfVldFlg = %d, HbOfVldCnt = %d.\n",
nCurHbOfst, *pHbOfVldFlg, *pHbOfVldCnt);
}
return 0;
}
int ver_blk_ofst_calc_sw(int *pVbOfVldCnt,
int *pVbOfVldFlg,
int *pVbOfst,
int nVbOfStatCnt[32],
int nYst,
int nYed,
int prm_vbof_minthd,
int prm_vbof_ratthd0,
int prm_vbof_ratthd1,
int prm_vbof_vldcntthd,
int nRow,
int nCol)
{
int i = 0;
int nCurVbOfst = 0;
int nRat0 = 0, nRat1 = 0;
int nMax1 = 0;
int nMax2 = 0;
int nMaxIdx = 0;
/* get 2 maximum, move to RTL part */
nMax1 = nMax2 = 0;
for (i = 0; i < 8; i++) {
if (nVbOfStatCnt[i] > nMax1) {
nMax2 = nMax1;
nMax1 = nVbOfStatCnt[i];
nMaxIdx = i;
}
else if (nVbOfStatCnt[i] > nMax2) {
nMax2 = nVbOfStatCnt[i];
}
}
/* decide if offset valid */
nCurVbOfst = -1;
nRat0 = 256*nMax1/((nYed - nYst)/8)/nCol;
nRat1 = 128*nMax1/max(nMax2, prm_vbof_minthd);
if (nRat0 >= prm_vbof_ratthd0 && nRat1 >= prm_vbof_ratthd1)
nCurVbOfst = (nMaxIdx+1)%8;
if (nCurVbOfst == *pVbOfst)
(*pVbOfVldCnt)++;
else
*pVbOfVldCnt = 0;
if (*pVbOfVldCnt >= prm_vbof_vldcntthd)
*pVbOfVldFlg = 1;
else
*pVbOfVldFlg = 0;
*pVbOfst = (nCurVbOfst == -1) ? 0 : nCurVbOfst;
/* print for debug
* printk("Voff info at Field: ");
* for ( i = 0; i < 32; i++ ) {
* printk("%5d, ", nVbOfStatCnt[i]);
* }//i
* //printk("Max1 = %5d, Max2 = %5d, MaxIdx = %5d, Rat0 = %5d,
* Rat1 = %5d, CurVbOfst = %5d, VbOfVldFlg = %d, VbOfVldCnt = %d.\n"
* nMax1, nMax2, nMaxIdx, nRat0, nRat1, nCurVbOfst, *pVbOfVldFlg,
* *pVbOfVldCnt);
*/
return 0;
}
#endif
void run_dnr_in_irq(unsigned short nCol, unsigned short nRow)
{
static int ro_gbs_stat_lr = 0, ro_gbs_stat_ll = 0, ro_gbs_stat_rr = 0,
ro_gbs_stat_dif = 0, ro_gbs_stat_cnt = 0;
/* int reg_dnr_stat_xst=0,reg_dnr_stat_xed=0,
* reg_dnr_stat_yst=0,reg_dnr_stat_yed=0;
*/
#ifdef DNR_HV_SHIFT
int ro_hbof_stat_cnt[32], ro_vbof_stat_cnt[32], i = 0;
#endif
if (dnr_reg_update == 0)
return;
DI_Wr(DNR_CTRL, 0x1df00);
DI_Wr(DNR_DM_CTRL, Rd(DNR_DM_CTRL)|(1 << 11));
/* dm for sd, hd will slower */
if (nCol >= 1920)
DI_Wr_reg_bits(DNR_DM_CTRL, 0, 9, 1);
else
DI_Wr_reg_bits(DNR_DM_CTRL, dnr_dm_en, 9, 1);
DI_Wr(DNR_HVSIZE, nCol<<16|nRow);
DI_Wr(DNR_STAT_X_START_END, (((dnr_stat_coef<<3)&0x3fff) << 16)
|((nCol-((dnr_stat_coef<<3)+1))&0x3fff));
DI_Wr(DNR_STAT_Y_START_END, (((dnr_stat_coef<<3)&0x3fff) << 16)
|((nRow-((dnr_stat_coef<<3)+1))&0x3fff));
if (ro_gbs_stat_lr != Rd(DNR_RO_GBS_STAT_LR) ||
ro_gbs_stat_ll != Rd(DNR_RO_GBS_STAT_LL) ||
ro_gbs_stat_rr != Rd(DNR_RO_GBS_STAT_RR) ||
ro_gbs_stat_dif != Rd(DNR_RO_GBS_STAT_DIF) ||
ro_gbs_stat_cnt != Rd(DNR_RO_GBS_STAT_CNT)) {
ro_gbs_stat_lr = Rd(DNR_RO_GBS_STAT_LR);
ro_gbs_stat_ll = Rd(DNR_RO_GBS_STAT_LL);
ro_gbs_stat_rr = Rd(DNR_RO_GBS_STAT_RR);
ro_gbs_stat_dif = Rd(DNR_RO_GBS_STAT_DIF);
ro_gbs_stat_cnt = Rd(DNR_RO_GBS_STAT_CNT);
} else {
return;
}
global_bs_calc_sw(&pDnrPrm->sw_gbs_vld_cnt,
&pDnrPrm->sw_gbs_vld_flg,
&pDnrPrm->sw_gbs,
ro_gbs_stat_lr,
ro_gbs_stat_ll,
ro_gbs_stat_rr,
ro_gbs_stat_dif,
ro_gbs_stat_cnt,
pDnrPrm->prm_gbs_vldcntthd, /* prm below */
pDnrPrm->prm_gbs_cnt_min,
pDnrPrm->prm_gbs_ratcalcmod,
pDnrPrm->prm_gbs_ratthd,
pDnrPrm->prm_gbs_difthd,
pDnrPrm->prm_gbs_bsdifthd,
pDnrPrm->prm_gbs_calcmod);
#ifdef DNR_HV_SHIFT
for (i = 0; i < 32; i++)
ro_hbof_stat_cnt[i] = Rd(DNR_RO_HBOF_STAT_CNT_0+i);
for (i = 0; i < 32; i++)
ro_vbof_stat_cnt[i] = Rd(DNR_RO_VBOF_STAT_CNT_0+i);
hor_blk_ofst_calc_sw(&pDnrPrm->sw_hbof_vld_cnt,
&pDnrPrm->sw_hbof_vld_flg,
&pDnrPrm->sw_hbof,
ro_hbof_stat_cnt,
0,
nCol-1,
pDnrPrm->prm_hbof_minthd,
pDnrPrm->prm_hbof_ratthd0,
pDnrPrm->prm_hbof_ratthd1,
pDnrPrm->prm_hbof_vldcntthd,
nRow,
nCol);
ver_blk_ofst_calc_sw(&pDnrPrm->sw_vbof_vld_cnt,
&pDnrPrm->sw_vbof_vld_flg,
&pDnrPrm->sw_vbof,
ro_vbof_stat_cnt,
0,
nRow-1,
pDnrPrm->prm_vbof_minthd,
pDnrPrm->prm_vbof_ratthd0,
pDnrPrm->prm_vbof_ratthd1,
pDnrPrm->prm_vbof_vldcntthd,
nRow,
nCol);
#endif
/* update hardware registers */
if (pDnrPrm->prm_sw_gbs_ctrl == 0) {
DI_Wr(DNR_GBS,
(pDnrPrm->sw_gbs_vld_flg == 1)?pDnrPrm->sw_gbs : 0);
} else if (pDnrPrm->prm_sw_gbs_ctrl == 1) {
DI_Wr_reg_bits(DNR_BLK_OFFST,
(pDnrPrm->sw_hbof_vld_flg == 1)?pDnrPrm->sw_hbof:0, 4, 3);
DI_Wr(DNR_GBS, (pDnrPrm->sw_hbof_vld_flg == 1 &&
pDnrPrm->sw_gbs_vld_flg == 1)?pDnrPrm->sw_gbs:0);
} else if (pDnrPrm->prm_sw_gbs_ctrl == 2) {
DI_Wr_reg_bits(DNR_BLK_OFFST,
(pDnrPrm->sw_vbof_vld_flg == 1)?pDnrPrm->sw_vbof:0, 0, 3);
DI_Wr(DNR_GBS, (pDnrPrm->sw_vbof_vld_flg == 1 &&
pDnrPrm->sw_gbs_vld_flg == 1)?pDnrPrm->sw_gbs:0);
} else if (pDnrPrm->prm_sw_gbs_ctrl == 1) {
DI_Wr_reg_bits(DNR_BLK_OFFST,
pDnrPrm->sw_hbof_vld_flg == 1 ? pDnrPrm->sw_hbof : 0, 4, 3);
DI_Wr_reg_bits(DNR_BLK_OFFST,
pDnrPrm->sw_vbof_vld_flg == 1 ? pDnrPrm->sw_vbof : 0, 0, 3);
DI_Wr(DNR_GBS, (pDnrPrm->sw_hbof_vld_flg == 1 &&
pDnrPrm->sw_vbof_vld_flg == 1 &&
pDnrPrm->sw_gbs_vld_flg == 1)?pDnrPrm->sw_gbs:0);
}
}
static void parse_cmd_params(char *buf_orig, char **parm)
{
char *ps, *token;
char delim1[2] = " ";
char delim2[2] = "\n";
unsigned int n = 0;
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
}
static dnr_param_t dnr_params[] = {
{"prm_sw_gbs_ctrl", &(dnr_param.prm_sw_gbs_ctrl)},
{"prm_gbs_vldcntthd", &(dnr_param.prm_gbs_vldcntthd)},
{"prm_gbs_cnt_min", &(dnr_param.prm_gbs_cnt_min)},
{"prm_gbs_ratcalcmod", &(dnr_param.prm_gbs_ratcalcmod)},
{"prm_gbs_ratthd[0]", &(dnr_param.prm_gbs_ratthd[0])},
{"prm_gbs_ratthd[1]", &(dnr_param.prm_gbs_ratthd[1])},
{"prm_gbs_ratthd[2]", &(dnr_param.prm_gbs_ratthd[2])},
{"prm_gbs_difthd[0]", &(dnr_param.prm_gbs_difthd[0])},
{"prm_gbs_difthd[1]", &(dnr_param.prm_gbs_difthd[1])},
{"prm_gbs_difthd[2]", &(dnr_param.prm_gbs_difthd[2])},
{"prm_gbs_bsdifthd", &(dnr_param.prm_gbs_bsdifthd)},
{"prm_gbs_calcmod", &(dnr_param.prm_gbs_calcmod)},
{"sw_gbs", &(dnr_param.sw_gbs)},
{"sw_gbs_vld_flg", &(dnr_param.sw_gbs_vld_flg)},
{"sw_gbs_vld_cnt", &(dnr_param.sw_gbs_vld_cnt)},
{"prm_hbof_minthd", &(dnr_param.prm_hbof_minthd)},
{"prm_hbof_ratthd0", &(dnr_param.prm_hbof_ratthd0)},
{"prm_hbof_ratthd1", &(dnr_param.prm_hbof_ratthd1)},
{"prm_hbof_vldcntthd", &(dnr_param.prm_hbof_vldcntthd)},
{"sw_hbof", &(dnr_param.sw_hbof)},
{"sw_hbof_vld_flg", &(dnr_param.sw_hbof_vld_flg)},
{"sw_hbof_vld_cnt", &(dnr_param.sw_hbof_vld_cnt)},
{"prm_vbof_minthd", &(dnr_param.prm_vbof_minthd)},
{"prm_vbof_ratthd0", &(dnr_param.prm_vbof_ratthd0)},
{"prm_vbof_ratthd1", &(dnr_param.prm_vbof_ratthd1)},
{"prm_vbof_vldcntthd", &(dnr_param.prm_vbof_vldcntthd)},
{"sw_vbof", &(dnr_param.sw_vbof)},
{"sw_vbof_vld_flg", &(dnr_param.sw_vbof_vld_flg)},
{"sw_vbof_vld_cnt", &(dnr_param.sw_vbof_vld_cnt)},
{"", NULL}
};
static ssize_t dnr_param_store(struct device *dev,
struct device_attribute *attr,
const char *buff, size_t count)
{
int i = 0, value = 0;
char *parm[2] = {NULL}, *buf_orig;
buf_orig = kstrdup(buff, GFP_KERNEL);
parse_cmd_params(buf_orig, (char **)(&parm));
for (i = 0; dnr_params[i].addr; i++) {
if (!strcmp(parm[0], dnr_params[i].name)) {
value = kstrtol(parm[1], 10, NULL);
*(dnr_params[i].addr) = value;
pr_dbg("%s=%d.\n", dnr_params[i].name,
*(dnr_params[i].addr));
}
}
return count;
}
static ssize_t dnr_param_show(struct device *dev,
struct device_attribute *attr,
char *buff)
{
ssize_t len = 0;
int i = 0;
for (i = 0; dnr_params[i].addr; i++)
len += sprintf(buff+len, "%s=%d.\n",
dnr_params[i].name,
*(dnr_params[i].addr));
return len;
}
static DEVICE_ATTR(dnr_param, 0664, dnr_param_show, dnr_param_store);
void di_nr_init(void)
{
#if 0
DI_Wr(DI_NR_CTRL0, 0xc60c0804);
DI_Wr(DI_NR_CTRL1, 0x403e3c3a);
DI_Wr(DI_NR_CTRL2, 0x08010a01);
DI_Wr(NR2_MET_NM_CCTRL, 0x45056410);
DI_Wr(NR2_MATNR_SNR_NRM_GAIN, 0x4);
DI_Wr(NR2_MATNR_SNR_LPF_CFG, 0xc2b64);
DI_Wr(NR2_MATNR_SNR_EDGE2B, 0xcff08);
DI_Wr(NR2_MATNR_YBETA_SCL, 0x00ff2000);
DI_Wr(NR2_MATNR_MTN_CRTL2, 0x32020);
DI_Wr(NR2_MATNR_MTN_COR, 0x3333);
DI_Wr(NR2_MATNR_DEGHOST, 0x133);
DI_Wr(NR2_MATNR_ALPHALP_LUT0, 0x99999a9a);
DI_Wr(NR2_MATNR_ALPHALP_LUT1, 0x9aa0a6e3);
DI_Wr(NR2_MATNR_ALPHALP_LUT2, 0x90808080);
DI_Wr(NR2_MATNR_ALPHALP_LUT3, 0xffe0c0a4);
DI_Wr(NR2_MATNR_ALPHAHP_LUT1, 0x80805040);
DI_Wr(NR2_MATNR_ALPHAHP_LUT2, 0x90808080);
DI_Wr(NR2_MATNR_ALPHAHP_LUT3, 0xffe0c0a4);
#endif
DI_Wr(NR3_MODE, 0x3);
DI_Wr(NR3_COOP_PARA, 0x28ff00);
DI_Wr(NR3_CNOOP_GAIN, 0x881900);
DI_Wr(NR3_YMOT_PARA, 0x0c0a1e);
DI_Wr(NR3_CMOT_PARA, 0x08140f);
DI_Wr(NR3_SUREMOT_YGAIN, 0x100c4014);
DI_Wr(NR3_SUREMOT_CGAIN, 0x22264014);
DI_Wr(0x1745, 0x5056410);
DI_Wr(0x1746, 0x45056410);
DI_Wr(0x1747, 0x45056410);
DI_Wr(0x1748, 0x1);
DI_Wr(0x1749, 0x7c3a);
DI_Wr(0x174a, 0x29e77);
DI_Wr(0x174b, 0x9f1a);
DI_Wr(0x174c, 0x2822c);
DI_Wr(0x174d, 0x77);
DI_Wr(0x174e, 0x3030);
DI_Wr(0x174f, 0x20030);
DI_Wr(0x1750, 0xf002d0);
DI_Wr(0x1751, 0x132f);
DI_Wr(0x1752, 0x8d);
DI_Wr(0x1753, 0x40ff00);
DI_Wr(0x1754, 0x4);
DI_Wr(0x1755, 0xc2b64);
DI_Wr(0x1756, 0x0);
DI_Wr(0x1757, 0x3608);
DI_Wr(0x1758, 0x420);
DI_Wr(0x1759, 0xa06664);
DI_Wr(0x175a, 0xe0000);
DI_Wr(0x175b, 0x991c00);
DI_Wr(0x175c, 0x991000);
DI_Wr(0x175d, 0xf9f3e);
DI_Wr(0x175e, 0x7292abcd);
DI_Wr(0x175f, 0x1c23314f);
DI_Wr(0x1760, 0xf111317);
DI_Wr(0x1761, 0x8090a0c);
DI_Wr(0x1762, 0x80a0e0ff);
DI_Wr(0x1763, 0x4102050);
DI_Wr(0x1764, 0x2);
DI_Wr(0x1765, 0x0);
DI_Wr(0x1766, 0x20100400);
DI_Wr(0x1767, 0xc4804030);
DI_Wr(0x1768, 0xfffff0e0);
DI_Wr(0x1769, 0xffffffff);
DI_Wr(0x176a, 0x1132);
DI_Wr(0x176b, 0x32020);
DI_Wr(0x176c, 0x3333);
DI_Wr(0x176d, 0x4b4e4b4d);
DI_Wr(0x176e, 0x111);
DI_Wr(0x176f, 0x32181818);
DI_Wr(0x1770, 0x80644032);
DI_Wr(0x1771, 0x9e808080);
DI_Wr(0x1772, 0xffffffff);
DI_Wr(0x1773, 0x32181818);
DI_Wr(0x1774, 0x80644032);
DI_Wr(0x1775, 0xa5808080);
DI_Wr(0x1776, 0xffffffff);
DI_Wr(0x1777, 0xa06663);
DI_Wr(0x1778, 0x372);
DI_Wr(0x1779, 0x14141414);
DI_Wr(0x177a, 0x1400);
DI_Wr(0x177b, 0x80064);
DI_Wr(0x177c, 0x80064);
DI_Wr(0x177d, 0x80a0a);
DI_Wr(0x177e, 0x4281e);
DI_Wr(0x177f, 0x0);
DI_Wr(0x179c, 0x11b);
DI_Wr(0x179d, 0x202220);
}
void nr_init(struct device *dev)
{
dnr_prm_init(&dnr_param);
device_create_file(dev, &dev_attr_dnr_param);
}

View File

@@ -0,0 +1,115 @@
/*
* drivers/amlogic/media/deinterlace/nr.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 _DNR_H
#define _DNR_H
struct dnr_param_s {
char *name;
int *addr;
};
#define dnr_param_t struct dnr_param_s
struct DNR_PRM_s {
int prm_sw_gbs_ctrl;
int prm_gbs_vldcntthd;
int prm_gbs_cnt_min;
int prm_gbs_ratcalcmod;
int prm_gbs_ratthd[3];
int prm_gbs_difthd[3];
int prm_gbs_bsdifthd;
int prm_gbs_calcmod;
int sw_gbs;
int sw_gbs_vld_flg;
int sw_gbs_vld_cnt;
int prm_hbof_minthd;
int prm_hbof_ratthd0;
int prm_hbof_ratthd1;
int prm_hbof_vldcntthd;
int sw_hbof;
int sw_hbof_vld_flg;
int sw_hbof_vld_cnt;
int prm_vbof_minthd;
int prm_vbof_ratthd0;
int prm_vbof_ratthd1;
int prm_vbof_vldcntthd;
int sw_vbof;
int sw_vbof_vld_flg;
int sw_vbof_vld_cnt;
};/* used for software */
#define DNR_PRM_t struct DNR_PRM_s
/* software parameters initialization£¬ initializing before used */
void nr_init(struct device *dev);
void di_nr_init(void);
int global_bs_calc_sw(int *pGbsVldCnt,
int *pGbsVldFlg,
int *pGbs,
int nGbsStatLR,
int nGbsStatLL,
int nGbsStatRR,
int nGbsStatDif,
int nGbsStatCnt,
int prm_gbs_vldcntthd, /* prm below */
int prm_gbs_cnt_min,
int prm_gbs_ratcalcmod,
int prm_gbs_ratthd[3],
int prm_gbs_difthd[3],
int prm_gbs_bsdifthd,
int prm_gbs_calcmod);
int hor_blk_ofst_calc_sw(int *pHbOfVldCnt,
int *pHbOfVldFlg,
int *pHbOfst,
int nHbOfStatCnt[32],
int nXst,
int nXed,
int prm_hbof_minthd,
int prm_hbof_ratthd0,
int prm_hbof_ratthd1,
int prm_hbof_vldcntthd,
int nRow,
int nCol);
int hor_blk_ofst_calc_sw(int *pHbOfVldCnt,
int *pHbOfVldFlg,
int *pHbOfst,
int nHbOfStatCnt[32],
int nXst,
int nXed,
int prm_hbof_minthd,
int prm_hbof_ratthd0,
int prm_hbof_ratthd1,
int prm_hbof_vldcntthd,
int nRow,
int nCol);
int ver_blk_ofst_calc_sw(int *pVbOfVldCnt,
int *pVbOfVldFlg,
int *pVbOfst,
int nVbOfStatCnt[32],
int nYst,
int nYed,
int prm_vbof_minthd,
int prm_vbof_ratthd0,
int prm_vbof_ratthd1,
int prm_vbof_vldcntthd,
int nRow,
int nCol);
void run_dnr_in_irq(unsigned short nCol, unsigned short nRow);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,229 @@
/*
* drivers/amlogic/media/deinterlace/tffbff_check.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 "deinterlace.h"
#include "register.h"
/* define the length of history */
#define TBFF_DLEN 20
/* parameters */
/* valid data: only pixel_num > size*rat >> 8 */
/* u8: [0,255] */
static int tbff_pixel_minnum = 16;
/* x3 / row > rat */
/* => x3 > (row * rat >> 5) */
/* u10: [0 ~ 1023] => [0, 16] */
static int tbff_x3_minrow = 64;
/* m1/p1/m2/p2 changing 0/1/0/1... as 2-2 mode */
/* (max)/ min > (rat): define it max, else min */
/* u8: [0,31] */
static int tbff_mp_lgrat[4] = {16, 16, 16, 16};
/* tbff check length */
/* [0, 31] */
static int tbff_chk_len[4] = {4, 4, 4, 4};
static int calc_tbff_pixel_minnum = 16;
static int calc_tbff_x3_minrow = 64;
static int calc_tbff_mp_lgrat[4] = {16, 16, 16, 16};
static int nTmp0;
static bool tbff_pr, tffbff_en = true;
static int mode_count;
void tbff_init(void)
{
int i = 0;
mode_count = 0;
calc_tbff_pixel_minnum = tbff_pixel_minnum;
calc_tbff_x3_minrow = tbff_x3_minrow;
for (i = 0; i < 4; i++)
calc_tbff_mp_lgrat[i] = tbff_mp_lgrat[i];
}
static int tbff_get_rate(int t0, int t1)
{
int nmax = t1;
int nmin = t0;
int nrst = 0;
if (t0 > t1) {
nmax = t0;
nmin = t1;
}
nrst = (8 * nmax) + (nmin >> 1);
nrst /= (nmin+1);
if (nrst > 31)
nrst = 31;
if (nmax == t1) /* current is small */
nrst = 0;
return nrst;
}
static int tbff_get_minrate(int *pLen)
{
int iT0 = 0;
int aTLn[4] = {0, 0, 0, 0};
int nrst = 255;
int nP0 = pLen[TBFF_DLEN - 1];
int nP1 = pLen[TBFF_DLEN - 2];
if (nP0 < nP1) {
for (iT0 = 0; iT0 < 4; (iT0 += 2)) {
aTLn[iT0] = 31 - pLen[TBFF_DLEN - iT0 - 1];
aTLn[iT0 + 1] = pLen[TBFF_DLEN - iT0 - 2];
}
} else {
for (iT0 = 0; iT0 < 4; (iT0 += 2)) {
aTLn[iT0] = pLen[TBFF_DLEN - iT0 - 1];
aTLn[iT0 + 1] = 31 - pLen[TBFF_DLEN - iT0 - 2];
}
}
for (iT0 = 0; iT0 < 4; iT0++) {
if (aTLn[iT0] < nrst)
nrst = aTLn[iT0];
}
return nrst;
}
/* update param according to detection count */
static void calc_tbff_param(int mode_cnt, int step_max)
{
int delt_num, delt_row, delt_lgrat, i;
delt_num = tbff_pixel_minnum - 4;
delt_row = tbff_x3_minrow;
delt_lgrat = tbff_mp_lgrat[0] - 6;
calc_tbff_pixel_minnum =
tbff_pixel_minnum - (delt_num * mode_cnt)/step_max;
calc_tbff_x3_minrow = tbff_x3_minrow - (delt_row * mode_cnt)/step_max;
calc_tbff_mp_lgrat[0] =
tbff_mp_lgrat[0] - (delt_lgrat * mode_cnt)/step_max;
for (i = 1; i < 4; i++)
calc_tbff_mp_lgrat[i] = calc_tbff_mp_lgrat[0];
}
/* TFF / BFF error check */
/* polar3[0]: num of pixels */
/* polar3[1]: smooth motion vector */
/* polar3[2]: m1 */
/* polar3[3]: p1 */
/* polar3[4]: m2 */
/* polar3[5]: p2 */
/* polar3[6]: x3 */
int tff_bff_check(int nROW, int nCOL)
{
int iT0 = 0, iT1 = 0, nTmp1 = 0;
int nTmp2 = 0, tbfalse = 0, nSIZE = nROW * nCOL;
/* int nMin0 = 0; */
unsigned int uTp0 = 0;
int polar3[7];
/* top/bot field first error */
static int pPolar3[7]; /* previous polar3 */
static int sDat[4][TBFF_DLEN]; /* history infor */
static unsigned int stc_pp3[4];
for (iT0 = 0; iT0 < 7; iT0++)
polar3[iT0] = Rd_reg_bits(NR2_RO_POLAR3_NUMOFPIX+iT0, 0, 24);
if (tbff_pr)
pr_info("polar3=%8d %8d %8d %8d %8d %8d %8d.\n",
polar3[0], polar3[1], polar3[2], polar3[3],
polar3[4], polar3[5], polar3[6]);
/* history */
for (iT0 = 0; iT0 < 4; iT0++) {
for (iT1 = 0; iT1 < (TBFF_DLEN - 1); iT1++)
sDat[iT0][iT1] = sDat[iT0][iT1 + 1];
stc_pp3[iT0] = (stc_pp3[iT0] << 1);
sDat[iT0][TBFF_DLEN - 1] = 0;
}
/* only valid pixel is enough */
nTmp0 = ((nSIZE * calc_tbff_pixel_minnum + 128) >> 8);
if (polar3[0] > nTmp0) {
/* only x3 pixel is enough */
nTmp1 = ((nROW * calc_tbff_x3_minrow + 16) >> 5);
if (polar3[6] > nTmp1) {
/* nMin0 = 255; */
for (iT1 = 0; iT1 < 4; iT1++) {
nTmp2 =
tbff_get_rate(polar3[iT1 + 2], pPolar3[iT1 + 2]);
sDat[iT1][TBFF_DLEN - 1] = nTmp2;
}
}
}
for (iT1 = 0; iT1 < 4; iT1++) {
nTmp2 = tbff_get_minrate(sDat[iT1]);
if (nTmp2 >= calc_tbff_mp_lgrat[iT1])
stc_pp3[iT1] |= 0x1;
}
for (iT1 = 0; iT1 < 4; iT1++) {
uTp0 = stc_pp3[iT1];
nTmp0 = 0;
for (iT0 = 0; iT0 < 31; iT0++) {
if (uTp0 & 0x1)
nTmp0++;
else
break;
uTp0 = (uTp0 >> 1);
}
if (nTmp0 >= tbff_chk_len[iT1])
tbfalse += 1;
}
/* m1/p1/m2/p2 all 2-2 mode */
/* return (tbfalse==4); */
nTmp0 = (tbfalse == 4);
if (nTmp0 == 1)
nTmp0 += (polar3[2] < pPolar3[2]);
if (nTmp0 != 0)
mode_count = mode_count > 32 ? 32 : (mode_count+1);
else
mode_count = mode_count > 0 ? (mode_count-1) : 0;
calc_tbff_param(mode_count, 32);
for (iT0 = 0; iT0 < 7; iT0++)
pPolar3[iT0] = polar3[iT0];
if (tbff_pr)
pr_info("num %d, x3 %d, lgrat %d, result is %d.\n",
calc_tbff_pixel_minnum, calc_tbff_x3_minrow,
calc_tbff_mp_lgrat[0], nTmp0);
return tffbff_en?nTmp0:0;
}
module_param_named(tffbff_en, tffbff_en, bool, 0664);
module_param_named(tbff_pixel_minnum, tbff_pixel_minnum, int, 0664);
module_param_named(tbff_x3_minrow, tbff_x3_minrow, int, 0664);
module_param_named(tbff_pr, tbff_pr, bool, 0664);

View File

@@ -0,0 +1,656 @@
/*
* drivers/amlogic/media/deinterlace/vof_soft_top.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/module.h>
#include "film_vof_soft.h"
int cmb32_blw_wnd = 180; /*192 */
module_param(cmb32_blw_wnd, int, 0644);
MODULE_PARM_DESC(cmb32_blw_wnd, "cmb32_blw_wnd");
static int cmb32_wnd_ext = 11;
module_param(cmb32_wnd_ext, int, 0644);
MODULE_PARM_DESC(cmb32_wnd_ext, "cmb32_wnd_ext");
int cmb32_wnd_tol = 4;
module_param(cmb32_wnd_tol, int, 0644);
MODULE_PARM_DESC(cmb32_wnd_tol, "cmb32_wnd_tol");
int cmb32_frm_nocmb = 40;
module_param(cmb32_frm_nocmb, int, 0644);
MODULE_PARM_DESC(cmb32_frm_nocmb, "cmb32_frm_nocmb");
int cmb32_min02_sft = 7;
module_param(cmb32_min02_sft, int, 0644);
MODULE_PARM_DESC(cmb32_min02_sft, "cmb32_min02_sft");
int cmb32_cmb_tol = 10;
module_param(cmb32_cmb_tol, int, 0644);
MODULE_PARM_DESC(cmb32_cmb_tol, "cmb32_cmb_tol");
int cmb32_avg_dff = 48; /* if avg dif32 > dff>>4 */
module_param(cmb32_avg_dff, int, 0644);
MODULE_PARM_DESC(cmb32_avg_dff, "cmb32_avg_dff");
int cmb32_smfrm_num = 4;
module_param(cmb32_smfrm_num, int, 0644);
MODULE_PARM_DESC(cmb32_smfrm_num, "cmb32_smfrm_num");
int cmb32_nocmb_num = 20;
module_param(cmb32_nocmb_num, int, 0644);
MODULE_PARM_DESC(cmb32_nocmb_num, "cmb32_nocmb_num");
int cmb22_gcmb_rnum = 8;
module_param(cmb22_gcmb_rnum, int, 0644);
MODULE_PARM_DESC(cmb22_gcmb_rnum, "cmb22_gcmb_rnum");
int flmxx_cal_lcmb = 1;
module_param(flmxx_cal_lcmb, int, 0644);
MODULE_PARM_DESC(flmxx_cal_lcmb, "flmxx_cal_lcmb");
/* 15: 8-7 */
/* 12: 3-2-3-2-2 */
/* 10: 6-4 */
/* 10: 5-5 */
/* 10: 2-2-2-4 */
/* 10: 2-3-3-2 */
/* 10: 3-2-3-2 */
/* row * flmxx_no_cmb >> 6 */
static unsigned int flmxx_no_cmb[7] = {8, 32, 8, 8, 8, 32, 32};
static unsigned int flmxx_nn_cmb = 7;
module_param_array(flmxx_no_cmb, uint, &flmxx_nn_cmb, 0664);
int VOFSftTop(UINT8 *rFlmPstGCm, UINT8 *rFlmSltPre, UINT8 *rFlmPstMod,
UShort *rPstCYWnd0, UShort *rPstCYWnd1,
UShort *rPstCYWnd2, UShort *rPstCYWnd3, int nMod,
UINT32 *rROCmbInf, struct sFlmDatSt *pRDat,
struct sFlmSftPar *pPar, int nROW, int nCOL)
{
/* HSCMB[hist10][9(32bit)] */
static UINT32 HSCMB[HISCMBNUM][ROWCMBLEN];
/* 6-history,10-5Wnd(bgn/end) */
static int CWND[HISDETNUM][2 * VOFWNDNUM];
static UINT8 BGN;
static UINT8 frmNoCmb; /* counter from No combing */
static UINT8 CmbFlds; /* counter of combing field */
static UINT8 NumSmFd; /* counter for same field */
int mDly = pPar->mPstDlyPre;
/* UINT8 *PREWV = pRDat.pFlg32; or pRDat.pFlg22 */
/* static int TCNm[HISCMBNUM]; history: the number of combing-rows */
int *TCNm = pRDat->TCNm;
static int NWND[HISDETNUM];/* 6-history,the number of combing windows */
static int WGlb[HISDETNUM]; /* Global combing */
static unsigned int pFlgXx;
static UINT8 pCmbXx[PDXX_PT_NUM];
UINT8 *pFlg32 = pRDat->pFlg32; /* [HISDETNUM]; //history information */
UINT8 *pMod32 = pRDat->pMod32; /* [HISDETNUM]; */
UINT8 *pFlg22 = pRDat->pFlg22;
UINT8 *pMod22 = pRDat->pMod22;
UINT8 *mNum32 = pRDat->mNum32;
UINT32 *DIF02 = pRDat->rROFrmDif02; /* windows */
int VOFWnd[2 * VOFWNDNUM]; /* VOF windows 5*(bgn/end) */
int nCSum = 0; /* Combine sum */
int nWCmb = 0; /* Total Window combing */
int nBCmb = 0; /* combing line of below */
UINT32 nCb32 = 0;
UINT32 nRCmbAd[ROWCMBLEN];
int nDif02Min = ((nROW * nCOL) >> cmb32_min02_sft);
int nT0 = 0;
int nT1 = 0;
int nT2 = 0;
int nT3 = 0;
pFlgXx = (((pFlgXx >> 1) << 2) |
(pRDat->pFlgXx[HISDETNUM - 2] << 1) |
(pRDat->pFlgXx[HISDETNUM - 1]));
/* Initialization */
if (BGN == 0) {
for (nT0 = 0; nT0 < HISCMBNUM; nT0++) {
/* (288/32) */
for (nT1 = 0; nT1 < ROWCMBLEN; nT1++) {
/* 32-bit (all 1) */
HSCMB[nT0][nT1] = 0xffffffff;
}
TCNm[nT0] = 0;
}
for (nT0 = 0; nT0 < HISDETNUM; nT0++) {
NWND[nT0] = 15;
WGlb[nT0] = 0;
for (nT1 = 0; nT1 < 2 * VOFWNDNUM; nT1++)
CWND[nT0][nT1] = 0;
}
BGN = 1;
}
for (nT0 = 1; nT0 < HISCMBNUM; nT0++) {
for (nT1 = 0; nT1 < ROWCMBLEN; nT1++)
HSCMB[nT0 - 1][nT1] = HSCMB[nT0][nT1];
TCNm[nT0 - 1] = TCNm[nT0];
}
/* static int CWND[6][10]; */
/* 6-history, 10-5Wnd(bgn/end) */
for (nT0 = 0; nT0 < HISDETNUM - 1; nT0++) {
for (nT1 = 0; nT1 < 2 * VOFWNDNUM; nT1++)
CWND[nT0][nT1] = CWND[nT0 + 1][nT1];
}
for (nT1 = 0; nT1 < 2 * VOFWNDNUM; nT1++) {
CWND[HISDETNUM - 1][nT1] = 0;/* f(t-0) vs f(t-1) */
VOFWnd[nT1] = 0; /* initialization */
}
/* nS0 = 0; */
nCSum = 0;
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++) {
nCb32 = rROCmbInf[nT0];
/* Inf[0]-[31:0], First-[31], Lst-[0] */
HSCMB[HISCMBNUM - 1][nT0] = nCb32;
for (nT1 = 0; nT1 < 32; nT1++) {
nCSum += (nCb32 & 0x1);
nCb32 = nCb32 >> 1;
}
}
if (nCSum > nROW)
nCSum = nROW;
TCNm[HISCMBNUM - 1] = nCSum; /* the number of combing row */
for (nT0 = 0; nT0 < HISDETNUM-1; nT0++) {
NWND[nT0] = NWND[nT0+1];
WGlb[nT0] = WGlb[nT0+1];
}
prt_flg = ((pr_pd >> 5) & 0x1);
if (prt_flg)
sprintf(debug_str, "#CMB-Dbg\nnCSum=%03d\n", nCSum);
nT1 = 0;
if (pMod32[HISDETNUM - 1] == 3) {
if (pFlg32[HISDETNUM - 1] & 0x1)
nT1 = 1;
else
nT1 = 2;
/* TODO: Check here */
WGlb[HISDETNUM-1] = 0;
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
nRCmbAd[nT0] = HSCMB[HISCMBNUM - nT1][nT0];
for (nT1 = nT1 + 1; nT1 <= 5; nT1++) {
if (pFlg32[HISDETNUM - nT1] & 0x1) {
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++) {
nRCmbAd[nT0] =
(nRCmbAd[nT0] &
HSCMB[HISCMBNUM - nT1][nT0]);
}
}
}
if (prt_flg)
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
sprintf(debug_str + strlen(debug_str),
"nCmd32([%d])=[%08x]\n",
nT0, nRCmbAd[nT0]);
/* return: the number of windows */
nT1 = VOFDetSub1(VOFWnd, &nCSum, 3, nRCmbAd, nROW, pPar);
nWCmb = 0;
nBCmb = 0;
for (nT0 = 0; nT0 < nT1; nT0++) {
if (VOFWnd[2 * nT0] > (cmb32_blw_wnd * nROW >> 8)) {
CWND[HISDETNUM - 1][2 * nT0] =
VOFWnd[2 * nT0] - cmb32_wnd_ext;
CWND[HISDETNUM - 1][2 * nT0 + 1] =
VOFWnd[2 * nT0 + 1] + cmb32_wnd_ext;
nBCmb = VOFWnd[2*nT0+1]-VOFWnd[2*nT0]+1;
/* patch for MIT32Mix ending vof */
if (CWND[4][2*nT0] < CWND[5][2*nT0])
nT2 = CWND[5][2*nT0] - CWND[4][2*nT0];
else
nT2 = CWND[4][2*nT0] - CWND[5][2*nT0];
if (CWND[4][2*nT0+1] < CWND[5][2*nT0+1])
nT3 = CWND[5][2*nT0+1]
- CWND[4][2*nT0+1];
else
nT3 = CWND[4][2*nT0+1]
- CWND[5][2*nT0+1];
if ((nT2 <= cmb32_wnd_tol) &&
(nT3 <= cmb32_wnd_tol)) {
if (CWND[4][2*nT0] < CWND[5][2*nT0])
CWND[5][2*nT0] = CWND[4][2*nT0];
if (CWND[4][2*nT0+1]
> CWND[5][2*nT0+1])
CWND[5][2*nT0+1]
= CWND[4][2*nT0+1];
}
/* patch for MIT32Mix ending vof */
}
nWCmb += VOFWnd[2*nT0+1]-VOFWnd[2*nT0]+1;
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"Wnd32[%d]=[%3d~%3d]\n", nT0,
VOFWnd[2 * nT0], VOFWnd[2 * nT0 + 1]);
}
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"frmNoCm=%02d CmbFld=%02d\n",
frmNoCmb, CmbFlds);
/* VOF using last ones */
if (nBCmb == 0) {
if ((frmNoCmb > cmb32_frm_nocmb) ||
(DIF02[0] < nDif02Min))
CmbFlds = 0;
if (frmNoCmb < 255)
frmNoCmb = frmNoCmb+1;
} else {
/* noCombing => combing => noCombing */
if (frmNoCmb >= cmb32_cmb_tol)
CmbFlds = 0;
frmNoCmb = 0;
if (CmbFlds < 255)
CmbFlds = CmbFlds+1;
}
/* parameter setting */
if ((nBCmb == 0) && (frmNoCmb < cmb32_frm_nocmb) &&
(CmbFlds > (cmb32_cmb_tol >> 1)) &&
(DIF02[0] > nDif02Min))
for (nT0 = 0; nT0 < 2 * VOFWNDNUM; nT0++)
CWND[HISDETNUM-1][nT0] = CWND[HISDETNUM-2][nT0];
/* VOF using last ones */
/* patch for cadence-32 */
if ((NumSmFd > cmb32_smfrm_num) &&
(mNum32[HISDETNUM-1] > cmb32_nocmb_num)) {
for (nT0 = 0; nT0 < 2*VOFWNDNUM; nT0++)
CWND[HISDETNUM-1][nT0] = 0;
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"NumSmFd=%03d\n", NumSmFd);
}
/* patch for cadence-32 */
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"nCSum32=%03d, nWndCmb=%03d\n",
nCSum, nWCmb);
/*
* if ( nCSum > (nROW>>1) ) {
* WGlb[HISDETNUM-1] = 1;
* }
*/
/* here for vertical moving VOF */
/* HQV: Mix32- piano+vertical VOF */
/* here can be set as parameters */
if (pFlg32[HISDETNUM-1] == 5) {
/* patch for cadence-32 */
if (DIF02[0] < nDif02Min) {
if (NumSmFd < 255)
NumSmFd = NumSmFd+1;
} else
NumSmFd = 0;
/* patch for cadence-32 */
/* 256/16 = 16 */
/* 64/16 = 4 for 8-bit */
/* vertical vof copyright */
if (nWCmb < 10)
nWCmb = 10;
nT1 = (nWCmb * nCOL * cmb32_avg_dff + 8) >> 4;
if ((DIF02[0] >= nT1) && (nWCmb > nBCmb+10))
mNum32[HISDETNUM-1] = 0;
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"AvgDif=%d (%d > (%d + 10)\n",
DIF02[0]/nCOL/nWCmb, nWCmb, nBCmb);
} /* here for vertical moving VOF */
} else if ((pMod22[HISDETNUM-1] == 2) &&
(pFlg22[HISDETNUM-1] & 0x1)) {
nT2 = ((nROW * cmb22_gcmb_rnum + 8) >> 4);
if (nCSum > nT2)
WGlb[HISDETNUM-1] = 1; /*global combing*/
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"WGlb22=%d\n", WGlb[HISDETNUM-1]);
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
nRCmbAd[nT0] = HSCMB[HISCMBNUM-1][nT0];
for (nT1 = 3; nT1 <= 5; nT1 += 2)
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
nRCmbAd[nT0] = (nRCmbAd[nT0]
& HSCMB[HISCMBNUM-nT1][nT0]);
if (prt_flg)
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
sprintf(debug_str + strlen(debug_str),
"nCmd22([%d])=[%08x]\n",
nT0, nRCmbAd[nT0]);
/* return: the number of windows */
nT1 = VOFDetSub1(VOFWnd, &nCSum, 2, nRCmbAd, nROW, pPar);
for (nT0 = 0; nT0 < nT1; nT0++) {
CWND[HISDETNUM-1][2*nT0] = VOFWnd[2*nT0];
CWND[HISDETNUM-1][2*nT0+1] = VOFWnd[2*nT0+1];
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"Wnd22[%d]=[%3d~%3d]\n",
nT0, VOFWnd[2*nT0], VOFWnd[2*nT0+1]);
}
}
if (prt_flg)
pr_info("%s", debug_str);
if ((pRDat->pLvlXx[HISDETNUM - 1] > flmxx_cal_lcmb) &&
(pRDat->pModXx[HISDETNUM - 1] != 6)) {
if ((pFlgXx & 0x1) || (DIF02[0] < nDif02Min))
nT1 = 1;
else
nT1 = 2;
if (prt_flg)
sprintf(debug_str, "ModXx=%d, LvlXx=%d, FlgXx=%08x\n",
pRDat->pModXx[HISDETNUM - 1],
pRDat->pLvlXx[HISDETNUM - 1],
pFlgXx);
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
nRCmbAd[nT0] = HSCMB[HISCMBNUM - nT1][nT0];
for (nT1 = nT1 + 1; nT1 <= 10; nT1++) {
if ((pFlgXx >> (nT1 - 1)) & 0x1) {
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++) {
nRCmbAd[nT0] =
(nRCmbAd[nT0] &
HSCMB[HISCMBNUM - nT1][nT0]);
}
}
}
if (prt_flg)
for (nT0 = 0; nT0 < ROWCMBLEN; nT0++)
sprintf(debug_str + strlen(debug_str),
"nCmdXx([%d])=[%08x]\n",
nT0, nRCmbAd[nT0]);
nT0 = 4 + pRDat->pModXx[HISDETNUM - 1];
/* return: the number of windows */
nT1 = VOFDetSub1(VOFWnd, &nCSum, nT0, nRCmbAd, nROW, pPar);
nWCmb = 0;
for (nT0 = 0; nT0 < nT1; nT0++) {
CWND[HISDETNUM-1][2*nT0] = VOFWnd[2*nT0];
CWND[HISDETNUM-1][2*nT0+1] = VOFWnd[2*nT0+1];
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"WndXx[%d]=[%3d~%3d]\n",
nT0, VOFWnd[2*nT0], VOFWnd[2*nT0+1]);
nWCmb += VOFWnd[2*nT0+1]-VOFWnd[2*nT0]+1;
}
nT1 = pRDat->pModXx[HISDETNUM - 1];
for (nT0 = 0; nT0 < HISDETNUM; nT0++) {
if ((nT0 == nT1) &&
(nWCmb < ((flmxx_no_cmb[nT1] * nROW) >> 6)))
pCmbXx[nT0] = pCmbXx[nT0] + 1;
else
pCmbXx[nT0] = 0;
}
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"nCSum=%3d, nWCmb=%3d, pCmbXx=%d\n",
nCSum, nWCmb, pCmbXx[nT1]);
nT1 = pRDat->pLvlXx[HISDETNUM - 1] + pCmbXx[nT1];
if (nT1 > 255)
nT1 = 255;
pRDat->pLvlXx[HISDETNUM - 1] = nT1;
if (prt_flg)
pr_info("%s", debug_str);
}
prt_flg = ((pr_pd >> 1) & 0x1);
if (prt_flg)
sprintf(debug_str, "#Pre-VOF:\n");
/* film-mode: pMod22[5-mDly] or pMod32[5-mDly] */
if ((*rFlmPstMod == 1) || (*rFlmPstMod == 2)) {
/* weaver with pre-field */
if (*rFlmSltPre == 1) {
/* Interpolation method:0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd0[0] = CWND[HISDETNUM - 1 - mDly][0];/* bgn */
rPstCYWnd0[1] = CWND[HISDETNUM - 1 - mDly][1];/* end */
rPstCYWnd0[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd1[0] = CWND[HISDETNUM - 1 - mDly][2];/* bgn */
rPstCYWnd1[1] = CWND[HISDETNUM - 1 - mDly][3];/* end */
rPstCYWnd1[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd2[0] = CWND[HISDETNUM - 1 - mDly][4];/* bgn */
rPstCYWnd2[1] = CWND[HISDETNUM - 1 - mDly][5];/* end */
rPstCYWnd2[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd3[0] = CWND[HISDETNUM - 1 - mDly][6];/* bgn */
rPstCYWnd3[1] = CWND[HISDETNUM - 1 - mDly][7];/* end */
rPstCYWnd3[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
/* pFMReg->rFlmPstGCm = WGlb[5-mDly]; */
*rFlmPstGCm = WGlb[HISDETNUM - 1 - mDly];
if (prt_flg) {
sprintf(debug_str + strlen(debug_str),
"rFlmPstGCm-5=%d\n", *rFlmPstGCm);
sprintf(debug_str + strlen(debug_str),
"pFlg32=%d, pFlg22=%d\n",
pFlg32[HISDETNUM - 1 - mDly],
pFlg22[HISDETNUM - 1 - mDly]);
}
} else {
/* weaver with nxt-field */
/* Interpolation method: 0-EI,1-MTN,2-MA,3-Weaver */
rPstCYWnd0[0] = CWND[HISDETNUM - mDly][0];/* bgn */
rPstCYWnd0[1] = CWND[HISDETNUM - mDly][1];/* end */
rPstCYWnd0[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd1[0] = CWND[HISDETNUM - mDly][2];/* bgn */
rPstCYWnd1[1] = CWND[HISDETNUM - mDly][3];/* end */
rPstCYWnd1[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd2[0] = CWND[HISDETNUM - mDly][4];/* bgn */
rPstCYWnd2[1] = CWND[HISDETNUM - mDly][5];/* end */
rPstCYWnd2[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd3[0] = CWND[HISDETNUM - mDly][6];/* bgn */
rPstCYWnd3[1] = CWND[HISDETNUM - mDly][7];/* end */
rPstCYWnd3[2] = 3;/* 0-mtn,1-with-buffer,2-ei,3-di */
*rFlmPstGCm = WGlb[HISDETNUM - mDly];
if (prt_flg) {
sprintf(debug_str + strlen(debug_str),
"rFlmPstGCm-6=%d\n", *rFlmPstGCm);
sprintf(debug_str + strlen(debug_str),
"pFlg32=%d, pFlg22=%d\n",
pFlg32[HISDETNUM - 1 - mDly],
pFlg22[HISDETNUM - 1 - mDly]);
}
}
} else {
rPstCYWnd0[0] = 0; /* bgn */
rPstCYWnd0[1] = 0; /* end */
rPstCYWnd0[2] = 3; /* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd1[0] = 0; /* bgn */
rPstCYWnd1[1] = 0; /* end */
rPstCYWnd1[2] = 3; /* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd2[0] = 0; /* bgn */
rPstCYWnd2[1] = 0; /* end */
rPstCYWnd2[2] = 3; /* 0-mtn,1-with-buffer,2-ei,3-di */
rPstCYWnd3[0] = 0; /* bgn */
rPstCYWnd3[1] = 0; /* end */
rPstCYWnd3[2] = 3; /* 0-mtn,1-with-buffer,2-ei,3-di */
*rFlmPstGCm = 1;
if (prt_flg)
sprintf(debug_str + strlen(debug_str),
"rFlmPstGCm-1=%d\n", *rFlmPstGCm);
}
if (prt_flg) {
sprintf(debug_str + strlen(debug_str),
"rPstCYWnd=(%d, %d), (%d, %d), (%d, %d), (%d, %d)\n\n",
rPstCYWnd0[0], rPstCYWnd0[1],
rPstCYWnd1[0], rPstCYWnd1[1],
rPstCYWnd2[0], rPstCYWnd2[1],
rPstCYWnd3[0], rPstCYWnd3[1]);
pr_info("%s", debug_str);
}
return nWCmb;
}
/* int *PREWV:5*2 */
/* nCNum: total rows of combing */
int VOFDetSub1(int *VOFWnd, int *nCNum, int nMod, UINT32 *nRCmb, int nROW,
struct sFlmSftPar *pPar)
{
int rCmbRwMinCt0 = pPar->rCmbRwMinCt0; /* 8; //for film 3-2 */
int rCmbRwMinCt1 = pPar->rCmbRwMinCt1; /* =7; //for film 2-2 */
/* int rCmbRwMaxStp=1; //fill in the hole */
int rCmbRwMinCt = rCmbRwMinCt1;
int nCSUM = 0; /* Combing sum (nCSUM>rCmbRwMinCt0) */
int nMIN = 0;
int nT0 = 0;
int nT1 = 0;
int nT2 = 0;
int nCNM = 0;
int nBgn = 0;
int nEnd = 0;
int fEND = 0;
int pIDx[VOFWNDNUM + 1][2]; /* Maximum-5windows */
int nIDx = 0;
if (nMod == 3)
rCmbRwMinCt = rCmbRwMinCt0;
for (nT0 = 0; (nT0 < nROW) && (nIDx <= VOFWNDNUM); nT0++) {
fEND = 0;
nT1 = nROW - 1 - nT0;
/* if(nRCmb[nT0]==1) */
if (Get1RCmb(nRCmb, nT1)) {
nCSUM += 1; /* Total */
if (nT0 == 0)
nBgn = nT0;
else if (nT0 == nROW - 1) {
if (Get1RCmb(nRCmb, 1)) {
/* at least (2-Row combing) */
nEnd = nT0;
fEND = 1;
}
} else if (!Get1RCmb(nRCmb, nT1 + 1)) {
/* (nRCmb[nT0-1]==0) */
nBgn = nT0;
}
} else {
/* nRCmb[nT0]==0 */
if (nT0 != 0 && Get1RCmb(nRCmb, nT1 + 1)) {
nEnd = nT0; /* nT0-1 */
fEND = 1;
}
}
if (fEND == 0)
continue;
nCNM = nEnd - nBgn + 1;
if (nCNM > rCmbRwMinCt || nEnd == nROW - 1) {
if (nIDx == VOFWNDNUM) {
nMIN = nCNM;
nT2 = VOFWNDNUM;
for (nT1 = 0; nT1 < VOFWNDNUM; nT1++)
if ((pIDx[nT1][1] -
pIDx[nT1][0] + 1) < nMIN) {
nMIN = pIDx[nT1][1]
- pIDx[nT1][0] + 1;
nT2 = nT1;
}
if (nT2 != VOFWNDNUM) {
pIDx[nT2][0] = nBgn;
pIDx[nT2][1] = nEnd;
}
} else {
pIDx[nIDx][0] = nBgn;
pIDx[nIDx][1] = nEnd;
nIDx += 1;
}
}
}
*nCNum = nCSUM;
for (nT0 = 0; nT0 < nIDx; nT0++) {
VOFWnd[2 * nT0] = pIDx[nT0][0];/* nBgn */
VOFWnd[2 * nT0 + 1] = pIDx[nT0][1];/* nEnd */
}
return nIDx;
}
/* Get 1-Row combing information, 1bit */
/* iHSCMB[9]; 9x32=288 */
UINT8 Get1RCmb(UINT32 *iHSCMB, UINT32 iRow)
{
UINT8 nR1 = 0;
UINT8 nBt = 0;
nR1 = ((iRow >> 5) & 0xf);/* iRow/32; 0--8 */
nBt = (iRow & 0x1f);/* iRow%32 */
return (iHSCMB[nR1] >> nBt) & 0x1;
}

View File

@@ -71,6 +71,15 @@
#define VFRAME_FLAG_SWITCHING_FENSE 2
#define VFRAME_FLAG_HIGH_BANDWIDTH 4
#define TB_DETECT_MASK 0x00000040
#define TB_DETECT_MASK_BIT 6
#define TB_DETECT_NONE 0
#define TB_DETECT_INVERT 1
#define TB_DETECT_NC 0
#define TB_DETECT_TFF 1
#define TB_DETECT_BFF 2
#define TB_DETECT_TBF 3
enum pixel_aspect_ratio_e {
PIXEL_ASPECT_RATIO_1_1,
PIXEL_ASPECT_RATIO_8_9,